Compare commits

60 Commits

Author SHA1 Message Date
aner 858f68f9c6 Lazily retry lichess token fetch; demand-load lichess package
gpg-agent may not have a cached passphrase yet when the top-level setq
runs at Emacs startup, so a cold agent makes 'pass' fail silently
(stderr redirected) and leaves lichess-token permanently empty for the
session. Retry the fetch right before each use instead of only once
at startup.
2026-10-06 00:30:30 +03:00
aner 8578e23114 Bump azos-core: org-roam-resync hook, no-Emacs-dependency 2026-10-06 00:30:00 +03:00
aner 98b2f461cd Leetcode and chess overhaul 2026-10-05 11:31:04 +03:00
aner f80ed5863e Yay fixes and stuff 2026-10-05 09:33:01 +03:00
aner 1d9784877b Better chess, cuda maintainers fix, elfeed update 2026-09-29 10:45:24 +03:00
aner e5455f35f9 Bugfix 2026-09-09 10:06:13 +03:00
aner fc41d9aef3 agent-shell-math-render update 2026-09-09 09:35:18 +03:00
aner d6916a3fa3 Maildir shortcuts, maildir fix 2026-09-07 07:04:05 +03:00
aner a9b5cd2847 Bump 2026-09-06 17:26:12 +03:00
aner 177963b64e Fixes! 2026-09-06 14:40:40 +03:00
aner e5cc25eb49 Fixy 2026-09-06 13:54:15 +03:00
aner 8fde1cd5fe FIx 2026-09-06 13:47:09 +03:00
aner 21be2b0c87 Version bump 2026-09-06 13:29:20 +03:00
aner e27b7cb777 Fixy fix 2026-09-06 13:24:45 +03:00
aner f4923cbcad Experimental features bump 2026-09-06 11:59:39 +03:00
aner 630054fb8d azos-core bump 2026-09-06 11:57:29 +03:00
aner 9909fb411b Pinentry update 2026-09-06 11:55:47 +03:00
aner 9c64e1513e Remote run skill, mu4e change 2026-09-06 11:49:54 +03:00
aner 943498ce52 Homey alert! 2026-09-03 11:37:12 +03:00
aner df97c76527 Added 8bitdo 2026-08-26 20:25:27 +03:00
aner 8be92183bb Headphone mechanism change 2026-08-20 10:18:57 +03:00
aner 4ea2421734 Beacon updated 2026-07-26 10:51:18 +03:00
aner fa2c62e2f4 azos-core bump 2026-07-26 01:20:47 +03:00
aner a6ff616c2d azos-core version bump 2026-07-26 00:53:03 +03:00
aner 6e0f938e65 New beacon config, redone passwords 2026-07-25 11:45:17 +03:00
aner 59c05832b1 New encryption key 2026-07-25 00:00:39 +03:00
aner b8eb351e6c Interim fix, no gpg key 2026-07-15 20:47:04 +03:00
aner 78afc9e5bf azos-core bump 2026-06-18 22:26:02 +03:00
aner ebdee10fba Bump azos-core, configuration limit. 2026-06-18 21:05:46 +03:00
aner 890f39079b Updated skills and lock and lichess 2026-06-17 07:36:21 +03:00
aner e0a5891cd8 Bump azos-core 2026-06-08 22:01:51 +03:00
aner 7f27339312 Bump azos-core: org-roam-mcp direct SQLite writes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-07 22:55:40 +03:00
aner bd64633454 Bump azos-core: org-roam-mcp fork with db-sync fix
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-07 22:47:49 +03:00
aner 7c187d1c3d Updated azos-core and org roam stuff. 2026-06-07 08:01:40 +03:00
aner 1adc0439ea Updated roam backup 2026-06-07 01:27:09 +03:00
aner 2254fd419d Claude as preffered agent, azos-core bump. 2026-06-07 01:18:12 +03:00
aner cf976ae14a Claude memory, second brain, skills 2026-06-07 00:48:20 +03:00
aner c928f5f748 Update lock, more azos-core 2026-06-03 23:49:41 +03:00
aner 8d0f541fbe WTTR 2026-06-02 10:49:52 +03:00
aner c0f72be869 Beacon config, beacon integration into emacs 2026-06-01 11:43:42 +03:00
aner e271872cae Qutebrowser fix, attic setup, beacon usb live setup 2026-05-30 13:22:18 +03:00
aner 27fafdc111 Better suite dependencies 2026-05-28 22:59:22 +03:00
aner fcb7e0b884 Refractor to dendritic approach. 2026-05-24 19:24:38 +03:00
aner d4dee59413 Package lint inclusion 2026-05-24 17:22:54 +03:00
aner cf57b3eb4a Bugfix for dashboard 2026-05-19 22:44:11 +03:00
aner e5bf9c0a41 Updated 2026-05-17 11:48:46 +03:00
aner 00f62d61eb Fix 2026-05-17 11:23:27 +03:00
aner c4066da976 New azos-core 2026-05-12 23:33:55 +03:00
aner 6751554982 Better exfat support 2026-05-12 10:28:18 +03:00
aner 83c279ded4 Moved autmounting to core 2026-05-12 09:01:11 +03:00
aner f89e04d898 Fix even more things 2026-05-11 15:02:51 +03:00
aner a89f5ca015 Added hl-line externally plus automount 2026-05-11 14:50:45 +03:00
aner 9780d69f25 Updated azos core for safety. 2026-05-08 23:20:11 +03:00
aner 4cd4114f7c Send us back a little bit - I just exernalized evil hl line. 2026-05-08 23:15:15 +03:00
aner ea550d2e8c Updated azos-core, nextcloud client, better zoom for qutebrowser 2026-05-04 14:52:08 +03:00
aner 29a351845b Updated azos-core, cladav sync, arch64 emulation 2026-04-29 20:21:48 +03:00
aner 2d72c3e7df Fixed flake lock submodule things 2026-04-26 00:13:20 +03:00
aner 315e73c63c Fixed git config. 2026-04-25 21:59:10 +03:00
aner 8a8e63b095 Fixed shell handling 2026-04-25 21:40:20 +03:00
aner b68932f516 Fixed submodule handling 2026-04-25 21:39:54 +03:00
92 changed files with 2390 additions and 1199 deletions
+120 -56
View File
@@ -22,9 +22,9 @@ nix build .#formatter.x86_64-linux
### Deploying ### Deploying
```bash ```bash
# Rebuild the azos environment for lauretta (this machine) — use this when asked to "rebuild" # Rebuild the azos environment for lauretta (this machine) — use this when asked to "rebuild"
sudo nixos-rebuild switch --flake '.?submodules=1#lauretta' azos-lauretta-update
nix flake update # Update all inputs nix flake update --flake '.?submodules=1' # Update all inputs
nix flake lock --update-input X # Update specific input nix flake lock --flake '.?submodules=1' --update-input X # Update specific input
``` ```
> **Note**: When the user asks to "rebuild", they mean rebuilding the lauretta environment with the command above — NOT building the VM. > **Note**: When the user asks to "rebuild", they mean rebuilding the lauretta environment with the command above — NOT building the VM.
@@ -70,76 +70,111 @@ emacsclient -c -e '(switch-to-buffer (get-buffer-create "test"))'
emacsclient -e '(message "hello")' emacsclient -e '(message "hello")'
``` ```
## Code Style Guidelines ## Repository Structure
### File Organization ```
- **Home-manager modules**: `modules/home-manager/<name>.nix` azos/
- **NixOS modules**: `modules/nixos/<name>.nix` ├── flake.nix # Main flake
- **Imports**: All modules in `modules/home-manager/default.nix` and `modules/nixos/default.nix` (alphabetical order) ├── home-manager/home.nix # Home-manager entry point; manually imports all modules
- **Home config**: `home-manager/home.nix` - main home-manager user config ├── _machines/ # Per-machine NixOS configs (pass suiteModules as specialArgs)
- **Custom packages**: `pkgs/` - custom package definitions ├── nixos/ # NixOS system configs (configuration.nix, configuration-vm.nix, etc.)
- **Overlays**: `overlays/` - package overlays (addpkgs, modifications, unstable-packages) ├── features/ # Machine-specific home-manager features (auto-discovered)
├── overlays/ # Package overlays
├── shells/ # Dev shells
└── azos-core/ # Shared feature library (git submodule)
├── flake.nix
├── features/ # Shared/reusable features (auto-discovered)
├── overlays/ # Core overlays
└── _lib/ # Module schema helpers
```
Features are auto-discovered by `import-tree` — no central imports file. Each feature's
`default.nix` registers itself via `config.flake.modules.homeManager.<name>`. Modules are
then explicitly imported in `home-manager/home.nix` via `suiteModules.homeManager.<name>`.
**Where to put a new feature:**
- Shared / reusable across machines → `azos-core/features/<name>/default.nix`
- Machine-specific → `azos/features/<name>/default.nix`
## Code Style Guidelines
### Nix Module Template ### Nix Module Template
All features follow this flake-parts registration pattern:
```nix ```nix
{ {...}: {
config.flake.modules.homeManager.<name> = {
lib, lib,
config, config,
pkgs, pkgs,
... ...
}: let }: {
isEnabled = options.azos.<name>.enable = lib.mkOption {
config.azos.<module-name>.enable; default = false;
in {
options.azos.<module-name>.enable = lib.mkOption {
default = true;
example = true; example = true;
type = lib.types.bool; type = lib.types.bool;
}; };
config = lib.mkIf isEnabled { config = lib.mkIf config.azos.<name>.enable {
home.packages = with pkgs; [ pkg1 pkg2 ]; home.packages = with pkgs; [pkg1 pkg2];
};
}; };
} }
``` ```
### Naming Conventions ### Naming Conventions
- Option paths: `config.azos.<module-name>.<option>` - Option paths: `azos.<module-name>.<option>`
- Enable option: `enable` (bool), default `true` - Module names: kebab-case (`git-config`, `claude-memory`)
- Module names: kebab-case (`libreoffice.nix`, `git-config.nix`) - Feature directories: kebab-case, one `default.nix` per feature
- Option names: may differ from filename (e.g., `git.nix` uses `azos.git-config`) - Variables: kebab-case
- Variables: kebab-case (`isEnabled`)
### Formatting ### Formatting
- Indentation: 2 spaces - Indentation: 2 spaces
- Let bindings: multi-line with `isEnabled` on its own line - Packages: `with pkgs; [pkg1 pkg2]` (no trailing semicolon inside list)
- Packages: Use `with pkgs; [ ... ]` syntax
### Imports ### Imports
- Always include `{...}` for module args - Always include `{...}` for the outer module args
- Standard args: `lib, config, pkgs, ...` - Inner module args: `lib, config, pkgs, ...`
- NixOS config args: `inputs, outputs, lib, config, pkgs, ...`
- Use `./relative/path.nix` for local imports
### Option Patterns ### Option Patterns
- Boolean enable: `lib.mkOption { default = true; example = true; type = lib.types.bool; }` - Boolean enable: `lib.mkOption { default = false; example = true; type = lib.types.bool; }`
- Conditional config: `lib.mkIf isEnabled { ... }` - Conditional config: `lib.mkIf config.azos.<name>.enable { ... }`
- User-overridable: `lib.mkDefault` - Auto-enable a dependency: `azos.<dep>.enable = lib.mkDefault true;`
- Force value: `lib.mkForce` (sparingly) - Force value: `lib.mkForce` (sparingly)
### Extensible Options
For options that multiple modules should be able to contribute to, use attrset options:
```nix
options.azos.<name>.things = lib.mkOption {
default = {};
type = lib.types.attrsOf lib.types.path; # or lines, str, etc.
};
```
Any module can then add entries without modifying the owning feature. Examples in use:
- `azos.claude.globalSkills` — attrset of skill name → markdown file path
- `azos.claude.globalMdSections` — attrset of key → markdown string (merged into `~/.claude/CLAUDE.md`)
### Home-Manager vs NixOS ### Home-Manager vs NixOS
- Home-manager: `home.packages`, `home.file`, `programs.<program>` - Home-manager: `home.packages`, `home.file`, `programs.<program>`
- NixOS: `config.services`, `environment.systemPackages` - NixOS: `config.services`, `environment.systemPackages`
### Deploying Files
- Static file: `home.file."dest".source = ./file;`
- Generated text: `home.file."dest".text = "...";`
- Runtime script (e.g. merging JSON at activation): `home.activation.<name> = lib.hm.dag.entryAfter ["writeBoundary"] ''...'';`
### Suites System ### Suites System
Modules are organized into suites (defined in `azos-core/`): Top-level suites group related features (defined in `azos-core/`):
- `azos.suites.base` - Base packages and config - `azos.suites.base` — base packages and config
- `azos.suites.editor` - Editor tools - `azos.suites.editor` — editor tools
- `azos.suites.dev` - Development tools - `azos.suites.dev` — development tools
- `azos.suites.station` - Desktop applications - `azos.suites.station` — desktop applications
- `azos.suites.exwm` - EXWM window manager - `azos.suites.exwm` — EXWM window manager
- Enable in `home-manager/home.nix` with `azos.suites.<name>.enable = true;`
The machine suite (`azos.suites.lauretta`) enables the relevant suites for this machine.
### Specializations ### Specializations
NixOS supports specializations for alternative configurations: NixOS supports specializations for alternative configurations:
@@ -158,33 +193,62 @@ specialisation = {
## Adding New Modules ## Adding New Modules
1. Create file in `modules/home-manager/` or `modules/nixos/` 1. Create `features/<name>/default.nix` (machine-specific) or `azos-core/features/<name>/default.nix` (shared)
2. Add import to `modules/<type>/default.nix` (alphabetical) 2. Use the module template above
3. Use module template above 3. Add `suiteModules.homeManager.<name>` to the imports list in `home-manager/home.nix`
4. Run `nix fmt` 4. Run `nix fmt`
> **Submodule gotcha**: New files in `azos-core/` must be `git add`-ed inside the submodule
> before `nix build` will see them — Nix flakes only evaluate git-tracked files.
> ```bash
> cd azos-core && git add features/<name>/
> ```
## Claude Integration
Claude Code is integrated with this environment via several azos-core features:
| Feature | Option | What it does |
|---------|--------|--------------|
| `azos-core/features/claude-memory` | `azos.claude-memory.enable` | Registers org-roam-mcp as a global MCP server in `~/.claude.json` |
| `azos-core/features/claude-skills` | `azos.claude-skills.enable` | Deploys skills to `~/.claude/commands/` and content to `~/.claude/CLAUDE.md` |
| `azos/features/claude` | `azos.claude.enable` | Installs claude-code, auto-enables the above two |
### Adding Claude skills or standing instructions
From any module — no need to touch azos-core:
```nix
azos.claude.globalSkills.my-skill = ./skills/my-skill.md;
azos.claude.globalMdSections.my-rule = ''
# My Rule
Always do X when Y.
'';
```
See `azos-core/features/claude-skills/README.md` for full documentation.
## Key Files ## Key Files
| File | Purpose | | File | Purpose |
|------|---------| |------|---------|
| `flake.nix` | Main flake, defines systems, overlays | | `flake.nix` | Main flake, defines systems and overlays |
| `modules/home-manager/default.nix` | Home-manager imports | | `home-manager/home.nix` | Home-manager entry point, imports all modules |
| `modules/nixos/default.nix` | NixOS imports | | `_machines/lauretta.nix` | Lauretta machine config, passes `suiteModules` as specialArgs |
| `home-manager/home.nix` | User home-manager config, enables suites | | `nixos/configuration.nix` | Lauretta NixOS system config |
| `nixos/configuration.nix` | Lauretta laptop config |
| `nixos/configuration-vm.nix` | Test VM config | | `nixos/configuration-vm.nix` | Test VM config |
| `overlays/` | Custom package overlays | | `overlays/` | Package overlays |
| `pkgs/` | Custom packages | | `azos-core/` | Shared feature library (git submodule) |
| `azos-core/` | Shared modules (submodule) | | `azos-core/features/` | Shared features (auto-discovered by import-tree) |
| `features/` | Machine-specific features (auto-discovered by import-tree) |
| `azos-core/features/editor/emacs/config.org` | Literate Emacs config |
| `azos-core/features/claude-skills/README.md` | Claude skills extensibility docs |
## Common Tasks ## Common Tasks
**Add system package**: Edit NixOS module, add to `environment.systemPackages = with pkgs; [ pkg ]` **Add system package**: Edit a NixOS feature, add to `environment.systemPackages = with pkgs; [ pkg ]`
**Add home-manager package**: Edit module, add to `home.packages = with pkgs; [ pkg ]` **Add home-manager package**: Edit a feature's config block, add to `home.packages = with pkgs; [ pkg ]`
**Add system service**: Edit NixOS module, add under `services.<service>` **Add system service**: Edit a NixOS feature, add under `services.<service>`
**Add custom package**: Create file in `pkgs/`, add to `pkgs/default.nix`, use via overlay **Add custom package**: Add to `azos-core/overlays/` via `config.flake.overlayPkgs.<name>`, then use as `pkgs.<name>`
**Access unstable packages**: Use `pkgs.unstable.<package>` (via unstable-packages overlay) **Access unstable packages**: Use `pkgs.unstable.<package>` (via unstable-packages overlay)
Symlink
+1
View File
@@ -0,0 +1 @@
AGENTS.md
+17
View File
@@ -0,0 +1,17 @@
{
config,
inputs,
...
}: {
config.flake.nixosConfigurations.beacon-wsl = inputs.nixpkgs.lib.nixosSystem {
specialArgs = {
inherit inputs;
outputs = config.flake;
suiteModules = config.flake.modules;
};
modules = [../nixos/configuration-beacon-wsl.nix];
};
config.flake.packages.x86_64-linux.beacon-wsl-tarball =
config.flake.nixosConfigurations.beacon-wsl.config.system.build.tarballBuilder;
}
+17
View File
@@ -0,0 +1,17 @@
{
config,
inputs,
...
}: {
config.flake.nixosConfigurations.beacon = inputs.nixpkgs.lib.nixosSystem {
specialArgs = {
inherit inputs;
outputs = config.flake;
suiteModules = config.flake.modules;
};
modules = [../nixos/configuration-beacon.nix];
};
config.flake.packages.x86_64-linux.beacon-image =
config.flake.nixosConfigurations.beacon.config.system.build.image;
}
+14
View File
@@ -0,0 +1,14 @@
{
config,
inputs,
...
}: {
config.flake.nixosConfigurations.lauretta = inputs.nixpkgs.lib.nixosSystem {
specialArgs = {
inherit inputs;
outputs = config.flake;
suiteModules = config.flake.modules;
};
modules = [../nixos/configuration.nix];
};
}
+14
View File
@@ -0,0 +1,14 @@
{
config,
inputs,
...
}: {
config.flake.nixosConfigurations.vm = inputs.nixpkgs.lib.nixosSystem {
specialArgs = {
inherit inputs;
outputs = config.flake;
suiteModules = config.flake.modules;
};
modules = [../nixos/configuration-vm.nix];
};
}
+33
View File
@@ -0,0 +1,33 @@
{...}: {
config.flake.modules.nixos.attic = {
lib,
config,
pkgs,
...
}: {
options.azos.attic.enable = lib.mkOption {
default = false;
example = true;
type = lib.types.bool;
};
config = lib.mkIf config.azos.attic.enable {
environment.systemPackages = [pkgs.attic-client];
nix.settings = {
extra-substituters = ["https://attic.zakobar.com/main"];
extra-trusted-public-keys = ["main:9SZt/6plBU7jjQzz90J7O011I13hmJvOMYouxNqExNQ="];
netrc-file = "/etc/nix/attic-netrc";
};
environment.etc."nix/attic-netrc" = {
mode = "0600";
text = ''
machine attic.zakobar.com
login token
password eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjIwOTU3MDk0NDEsIm5iZiI6MTc4MDEzMzQ0MSwic3ViIjoibml4b3MtY2xpZW50IiwiaHR0cHM6Ly9qd3QuYXR0aWMucnMvdjEiOnsiY2FjaGVzIjp7IioiOnsiciI6MX19fX0.lqT_m2otoJQtA_AeJu62NT87u8cMWxgN-JhqtEtZ88s
'';
};
};
};
}
+41
View File
@@ -0,0 +1,41 @@
{...}: {
config.flake.modules.homeManager.audio = {
lib,
config,
...
}: {
options.azos.home-audio.enable = lib.mkOption {
default = true;
type = lib.types.bool;
};
config = lib.mkIf config.azos.home-audio.enable {};
};
config.flake.modules.nixos.audio = {
lib,
config,
pkgs,
...
}: {
options.azos.hardware-audio.enable = lib.mkOption {
default = true;
type = lib.types.bool;
};
config = lib.mkIf config.azos.hardware-audio.enable {
services = {
pipewire = {
enable = true;
audio.enable = true;
pulse.enable = true;
alsa = {
enable = true;
support32Bit = true;
};
jack.enable = true;
};
};
environment.systemPackages = with pkgs; [pavucontrol];
musnix.enable = true;
};
};
}
+15
View File
@@ -0,0 +1,15 @@
{...}: {
config.flake.modules.nixos.binfmt = {
lib,
config,
...
}: {
options.azos.binfmt.enable = lib.mkOption {
default = true;
type = lib.types.bool;
};
config = lib.mkIf config.azos.binfmt.enable {
boot.binfmt.emulatedSystems = ["aarch64-linux"];
};
};
}
+22
View File
@@ -0,0 +1,22 @@
{...}: {
config.flake.modules.nixos.bluetooth = {
lib,
config,
...
}: {
options.azos.bluetooth.enable = lib.mkOption {
default = true;
type = lib.types.bool;
};
config = lib.mkIf config.azos.bluetooth.enable {
services.blueman.enable = true;
hardware.bluetooth.enable = true;
environment.etc."bluetooth/input.conf" = lib.mkForce {
text = ''
[General]
ClassicBondedOnly=false
'';
};
};
};
}
+39
View File
@@ -0,0 +1,39 @@
{...}: {
config.flake.overlayPkgs.emacs-lichess = pkgs: let
epkgs = pkgs.emacs.pkgs;
in
epkgs.trivialBuild {
pname = "lichess";
version = "1.0";
src = pkgs.fetchFromGitHub {
owner = "tmythicator";
repo = "lichess.el";
rev = "572a6a353e2113c8a95564b9bea1f2896e6d3dab";
sha256 = "1d87qjmdpizggkrzq39i9vqgvbpjf5mv97vm7zy28ksbqxmfasqa";
};
# trivialBuild's installPhase only installs *.el/*.elc; the piece SVGs
# under assets/ must be copied alongside so the default
# lichess-board-gui-asset-path (relative to the installed .el file) resolves.
postInstall = ''
cp -r assets $out/share/emacs/site-lisp/
'';
};
config.flake.modules.homeManager.chess = {
lib,
config,
pkgs,
...
}: {
options.azos.chess.enable = lib.mkOption {
default = false;
example = true;
type = lib.types.bool;
};
config = lib.mkIf config.azos.chess.enable {
azos.emacs.pkgs = [pkgs.azos-emacs-chess];
azos.emacs.enabledSuites = ["azos-emacs-chess"];
};
};
}
+14
View File
@@ -0,0 +1,14 @@
{
orgTrivialBuild,
epkgs,
pkgs,
}:
orgTrivialBuild {
pname = "azos-emacs-chess";
version = "0.1.0";
src = ./config.org;
packageRequires = with epkgs; [
pkgs.azos-emacs-base
pkgs.emacs-lichess
];
}
+30
View File
@@ -0,0 +1,30 @@
#+title: Aner's Emacs Chess Configuration
#+property: header-args :results silent
* Base setup
** Require
#+begin_src emacs-lisp
(require 'azos-emacs-base)
#+end_src
* Lichess
#+begin_src emacs-lisp
(use-package lichess
:demand t
:init
(defun azos/chess/open ()
"Open lichess in its dedicated \"chess\" tab."
(interactive)
(azos/tab-bar/open-singleton-tab "chess" #'lichess))
:bind
(:map azos/global-minor-mode/open-keymap
("k" . azos/chess/open)))
#+end_src
* Provide
#+begin_src emacs-lisp
(provide 'azos-emacs-chess)
#+end_src
+3
View File
@@ -0,0 +1,3 @@
{...}: {
config.flake.overlayPkgs.azos-emacs-chess = pkgs: pkgs.localEmacsPkg ./_pkg.nix;
}
+18
View File
@@ -0,0 +1,18 @@
{...}: {
config.flake.modules.homeManager.claude = {
lib,
config,
pkgs,
...
}: {
options.azos.claude.enable = lib.mkOption {
default = true;
type = lib.types.bool;
};
config = lib.mkIf config.azos.claude.enable {
home.packages = with pkgs; [claude-code claude-agent-acp];
azos.claude-memory.enable = lib.mkDefault true;
azos.claude-skills.enable = lib.mkDefault true;
};
};
}
+53
View File
@@ -0,0 +1,53 @@
{...}: {
config.flake.modules.homeManager.encryption = {
lib,
config,
pkgs,
...
}: {
options.azos.encryption.enable = lib.mkOption {
default = true;
type = lib.types.bool;
};
config = lib.mkIf config.azos.encryption.enable {
programs.password-store = {
enable = true;
settings = {
PASSWORD_STORE_KEY = "26B851F81F8F7C55";
};
};
home.packages = with pkgs; [
yubikey-personalization
];
programs.gpg = {
enable = true;
};
programs.browserpass = {
enable = true;
browsers = ["chromium"];
};
services.gpg-agent = {
enable = true;
enableSshSupport = true;
grabKeyboardAndMouse = false;
pinentry.package = pkgs.pinentry-emacs;
extraConfig = ''
allow-emacs-pinentry
allow-loopback-pinentry
'';
};
home.file.".ssh/config".source = ./ssh-config;
home.file.".ssh/gpg-as-ssh.pub".source = ./gpg-as-ssh.pub;
home.file.".gnupg/sshcontrol".source = ./sshcontrol;
# home-manager creates ~/.gnupg (via the files above) with the default
# umask, which can leave it group/other-readable. gpg refuses to trust
# a homedir like that and prints an "unsafe permissions" warning on
# every invocation, which pollutes anything that captures gpg/pass
# output (e.g. shell-command-to-string). Enforce 700 on every switch.
home.activation.gnupgPerms = lib.hm.dag.entryAfter ["writeBoundary"] ''
$DRY_RUN_CMD chmod 700 "$HOME/.gnupg"
'';
};
};
}
+1
View File
@@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDMdozJewuuqG4VuwGhI5Uw2xDIUrkQwyPGQ2q3tvnPq/VoV+zfdnou42I6XYEfOGd6xfLR0byOGCk1Ia1F/picBsxADEaJFBnTny5MWNA5MxwJIYUPW5+kFN1TmxdNGmj0WJ8qZeKkS3ffixdHlHTVu4Rzrlu8qDdw8TmgcvD7sHpNaBB+hwG9B/s5BAozfXvyXtW51lLLrEZdmUXJxAP51ubVgysZ985PA89o4G7LUE20IKAj3rgylLwq+Lz2PoGmVCptPTknLLzGlxTy2mU/tESJtS4iUvshSYiKak73BSen88xLWL/eZGFzOLW4TNem/qT0ykqK1s1BaGWCcQiDWN+Lpa3XqTbFN054MfhLdEMp+NjrdsCbZORzp9p2ZPDqi5jI1Hy7IN/8VzzB+T13MX6YhW7CBBqUZaivGhVQGsNjrFusPGhCaZrzNJ1l4qssLAlOh9qdaYzqDe+BIHsty55vw4Ph+Axou82babpLoiQzkCol2TWjPr7JSfHFkm6CmoTQ7mK8m7jRCodmxF+BEe4Usr+HrTKDc9fr5P4mdfL0O+ZPrlkPuG1zBTMal9MPxeCk4emzOZf7vBMNzb0aKHbOtSdVk/IcjatlDd2EIo34e5A6anLRMAdxb7901mnCAcjvCn6+ArNV8nr+NBk1+UvumZ+Q59LTrAkgRt3rBw== openpgp:0x13E0C25D
+1
View File
@@ -0,0 +1 @@
37710BAB5F6DC9878A450CDA8A4661D932C04ACB
+32
View File
@@ -0,0 +1,32 @@
{...}: {
config.flake.modules.homeManager.git-config = {
lib,
config,
pkgs,
...
}: {
options.azos.git-config.enable = lib.mkOption {
default = true;
type = lib.types.bool;
};
config = lib.mkIf config.azos.git-config.enable {
home.packages = with pkgs; [pass-git-helper unzip];
programs.git = {
enable = true;
signing = {
key = "BB141234A3DD953D";
signByDefault = true;
};
settings = {
credential.helper = "!pass-git-helper $@";
user = {
name = "Aner Zakobar";
email = "aner@zakobar.com";
};
};
};
home.file.".config/pass-git-helper/git-pass-mapping.ini".source =
./pass-git-mapping.ini;
};
};
}
+2
View File
@@ -0,0 +1,2 @@
[*git.zakobar.com*]
target=zakobar.com
+56
View File
@@ -0,0 +1,56 @@
{...}: {
config.flake.modules.homeManager.headphones = {
lib,
config,
pkgs,
...
}: {
options.azos.headphones = {
enable = lib.mkOption {
default = false;
example = true;
type = lib.types.bool;
};
devices = lib.mkOption {
default = [];
type = lib.types.listOf (lib.types.submodule {
options = {
mac = lib.mkOption {type = lib.types.str;};
name = lib.mkOption {type = lib.types.str;};
};
});
description = "Headphone devices; first entry is the default connect target.";
};
};
config = lib.mkIf config.azos.headphones.enable {
home.packages = let
deviceEntries =
lib.concatMapStrings
(d: " ${lib.escapeShellArg "${d.mac} ${d.name}"}\n")
config.azos.headphones.devices;
defaultMac =
if config.azos.headphones.devices == []
then ""
else (lib.head config.azos.headphones.devices).mac;
in [
(pkgs.writeShellScriptBin "azos-connect-headphones" ''
DEVICES=(
${deviceEntries})
case "$1" in
--list)
printf '%s\n' "''${DEVICES[@]}"
;;
--mac)
echo "connect $2" | bluetoothctl
;;
*)
echo "connect ${defaultMac}" | bluetoothctl
;;
esac
'')
];
};
};
}
+16
View File
@@ -0,0 +1,16 @@
{...}: {
config.flake.modules.homeManager.hfsprogs = {
lib,
config,
pkgs,
...
}: {
options.azos.hfsprogs.enable = lib.mkOption {
default = true;
type = lib.types.bool;
};
config = lib.mkIf config.azos.hfsprogs.enable {
home.packages = with pkgs; [hfsprogs];
};
};
}
+98
View File
@@ -0,0 +1,98 @@
{...}: {
config.flake.modules.homeManager.homey-alert = {
lib,
config,
pkgs,
...
}: {
options.azos.homey-alert.enable = lib.mkOption {
default = false;
example = true;
type = lib.types.bool;
};
config = lib.mkIf config.azos.homey-alert.enable {
azos.claude.globalSkills.notify = ./notify-skill.md;
home.packages = [
(pkgs.writeShellApplication {
name = "homey-alert";
runtimeInputs = with pkgs; [curl pass];
text = ''
usage() {
cat <<EOF
Usage: homey-alert [OPTIONS] [MESSAGE]
Send a notification to the homey ntfy server (ntfy.zakobar.com/alerts).
MESSAGE can be given as a positional argument or piped via stdin.
Options:
-t, --title TITLE notification title
-p, --priority PRIO priority: min|low|default|high|urgent (default: default)
-T, --tags TAGS comma-separated emoji shortcodes (e.g. warning,rotating_light)
-r, --print-remote print the curl command instead of running it
(for pasting into SSH commands to remote machines)
-h, --help show this help
Examples:
# Local
long_cmd && homey-alert -t "Training" -p high -T white_check_mark "done"
# Remote — expands locally, runs on the remote machine
ssh user@host "python train.py && \$(homey-alert -r -t 'Training' 'done')"
EOF
}
TITLE=""
PRIORITY="default"
TAGS=""
PRINT_REMOTE=false
while [[ $# -gt 0 ]]; do
case "$1" in
-t|--title) TITLE="$2"; shift 2 ;;
-p|--priority) PRIORITY="$2"; shift 2 ;;
-T|--tags) TAGS="$2"; shift 2 ;;
-r|--print-remote) PRINT_REMOTE=true; shift ;;
-h|--help) usage; exit 0 ;;
--) shift; break ;;
-*) echo "Unknown option: $1" >&2; usage >&2; exit 1 ;;
*) break ;;
esac
done
if [[ $# -gt 0 ]]; then
MESSAGE="$*"
elif [[ ! -t 0 ]]; then
MESSAGE="$(cat)"
else
echo "homey-alert: no message provided" >&2
usage >&2
exit 1
fi
TOKEN="$(pass zakobar-homecenter/ntfy-token)"
# Build the curl invocation as an array — single source of truth for both modes
CMD=(
curl -sf
-H "Authorization: Bearer $TOKEN"
-H "Priority: $PRIORITY"
)
[[ -n "$TITLE" ]] && CMD+=(-H "Title: $TITLE")
[[ -n "$TAGS" ]] && CMD+=(-H "Tags: $TAGS")
CMD+=(-d "$MESSAGE" https://ntfy.zakobar.com/alerts)
if $PRINT_REMOTE; then
# Shell-quote each element so the output is safe to embed in SSH commands
printf '%q ' "''${CMD[@]}"
printf '\n'
else
"''${CMD[@]}"
fi
'';
})
];
};
};
}
+48
View File
@@ -0,0 +1,48 @@
# Homey Alert — sending ntfy notifications when tasks finish
Use `homey-alert` to push notifications to Aner's homelab ntfy server when long tasks complete.
## When to use proactively
When running (or suggesting) a command that will take more than ~30 seconds — training runs,
builds, deploys, downloads, test suites — append a notification automatically. Don't wait to
be asked.
## Local commands
Append after the command so it fires on success only (`&&`) or always (`;`):
```bash
# Notify on success only
long_cmd && homey-alert "Task done"
# Always notify (even on failure) — prefer this for deploys/training
long_cmd; homey-alert -t "Training" -p high -T "$([ $? -eq 0 ] && echo white_check_mark || echo x)" "Exited $?"
```
## Remote commands (SSH / training machines)
Remote machines don't have `homey-alert`. Use `-r`/`--print-remote` to get a self-contained
`curl` command with the token already embedded. The `$(...)` expands **locally**; the resulting
command string is what the remote machine executes.
```bash
ssh user@host "python train.py && $(homey-alert -r -t 'Training' -p high -T white_check_mark 'Model finished')"
```
The remote machine only needs `curl` (universally available).
## Flags
| Flag | Short | Values / notes |
|------|-------|----------------|
| `--title TITLE` | `-t` | Notification title |
| `--priority PRIO` | `-p` | `min` / `low` / `default` / `high` / `urgent` |
| `--tags TAGS` | `-T` | Comma-separated emoji shortcodes: `white_check_mark`, `x`, `warning`, `rotating_light`, `tada` |
| `--print-remote` | `-r` | Print curl command instead of running (embed token locally, run remotely) |
## Choosing priority and tags
- Routine completion (backup, build): `default` priority, `white_check_mark`
- Training / long job: `high` priority, `white_check_mark` on success / `x` on failure
- Something broke: `urgent` priority, `rotating_light`
+38
View File
@@ -0,0 +1,38 @@
{...}: {
config.flake.modules.homeManager.hyprland = {
lib,
config,
pkgs,
...
}: {
options.azos.suites.hyprland.enable = lib.mkOption {
default = false;
type = lib.types.bool;
};
config = lib.mkIf config.azos.suites.hyprland.enable {
azos.suites.base.enable = lib.mkDefault true;
home.packages = with pkgs; [
hyprland
waybar
wofi
kitty
grim
slurp
swappy
networkmanagerapplet
xwayland
];
azos.emacs.enabledSuites = ["azos-emacs-hyprland"];
azos.emacs.pkgs = [pkgs.azos-emacs-hyprland];
azos.emacs.emacspkg = pkgs.emacs-pgtk;
home.file.".login.sh" = {
text = ''
#!/usr/bin/env bash
${pkgs.hyprland}/bin/Hyprland
'';
executable = true;
};
};
};
}
@@ -6,7 +6,7 @@
orgTrivialBuild { orgTrivialBuild {
pname = "azos-emacs-hyprland"; pname = "azos-emacs-hyprland";
version = "0.1.6"; version = "0.1.6";
src = ./elisp/azos-emacs-hyprland.org; src = ./config.org;
packageRequires = with epkgs; [ packageRequires = with epkgs; [
pkgs.azos-emacs-base pkgs.azos-emacs-base
]; ];
+3
View File
@@ -0,0 +1,3 @@
{...}: {
config.flake.overlayPkgs.azos-emacs-hyprland = pkgs: pkgs.localEmacsPkg ./_pkg.nix;
}
+16
View File
@@ -0,0 +1,16 @@
{...}: {
config.flake.modules.homeManager.kubernetes = {
lib,
config,
pkgs,
...
}: {
options.azos.kubectl.enable = lib.mkOption {
default = true;
type = lib.types.bool;
};
config = lib.mkIf config.azos.kubectl.enable {
home.packages = with pkgs; [kubectl kubernetes-helm velero];
};
};
}
+22
View File
@@ -0,0 +1,22 @@
{...}: {
config.flake.modules.homeManager.lauretta = {
lib,
config,
pkgs,
...
}: {
options.azos.suites.lauretta.enable = lib.mkOption {
default = false;
type = lib.types.bool;
};
config = lib.mkIf (config.azos.suites.lauretta.enable) {
azos.suites.exwm.enable = lib.mkDefault true;
azos.suites.editor.enable = lib.mkDefault true;
azos.suites.dev.enable = lib.mkDefault true;
azos.emacs.enabledSuites = ["azos-emacs-lauretta"];
azos.emacs.pkgs = [pkgs.azos-emacs-lauretta];
home.packages = with pkgs; [nix-search-cli];
};
};
}
@@ -6,7 +6,7 @@
orgTrivialBuild { orgTrivialBuild {
pname = "azos-emacs-lauretta"; pname = "azos-emacs-lauretta";
version = "0.1.6"; version = "0.1.6";
src = ./elisp/azos-emacs-lauretta.org; src = ./config.org;
packageRequires = with epkgs; [ packageRequires = with epkgs; [
pkgs.azos-emacs-base pkgs.azos-emacs-base
pkgs.azos-emacs-dev pkgs.azos-emacs-dev
@@ -15,5 +15,8 @@ orgTrivialBuild {
pkgs.azos-emacs-station pkgs.azos-emacs-station
agent-shell agent-shell
elfeed-protocol
org-caldav
pinentry
]; ];
} }
+533
View File
@@ -0,0 +1,533 @@
#+title: Aner's Emacs Lauretta Configuration
#+property: header-args :results silent
* Base setup
** Require
#+begin_src emacs-lisp
(require 'azos-emacs-base)
(require 'azos-emacs-dev)
(require 'azos-emacs-editor)
(require 'azos-emacs-exwm)
(require 'azos-emacs-station)
#+end_src
* Lauretta specific
** Weather
#+begin_src emacs-lisp
(setq wttrin-default-cities '("Meitar, Israel"))
#+end_src
** LLM
#+begin_src emacs-lisp
(setq
gptel-model 'openai/gpt-oss-120b
gptel-backend
(gptel-make-openai "Groq"
:host "api.groq.com"
:endpoint "/openai/v1/chat/completions"
:stream t
:key "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"
:models '(openai/gpt-oss-120b)))
#+end_src
** GPG Pinentry
gpg-agent is configured with =pinentry.package = pkgs.pinentry-emacs=, which
needs a running Emacs-side pinentry service to hand it prompts over a
loopback socket. Without =pinentry-start=, the pinentry-emacs binary can't
reach Emacs and falls back to the curses pinentry (visible as a TUI prompt
when committing from vterm) or hangs entirely (as seen from Magit).
#+begin_src emacs-lisp
(require 'pinentry)
(pinentry-start)
#+end_src
** Agent Shell
#+begin_src emacs-lisp
(setq agent-shell-preferred-agent-config 'claude-code)
#+end_src
** Headphones
#+begin_src emacs-lisp
(defun azos/connect-headphones (&optional arg)
"Connect to headphones via bluetoothctl.
Without prefix ARG, connects to the first device in the list.
With prefix ARG, prompts to choose from all configured devices."
(interactive "P")
(if (not arg)
(start-process-shell-command "connect-headphones" nil "azos-connect-headphones")
(let* ((raw (shell-command-to-string "azos-connect-headphones --list"))
(lines (split-string (string-trim raw) "\n" t))
(choices (mapcar (lambda (line)
(let ((space (string-match " " line)))
(cons (substring line (1+ space))
(substring line 0 space))))
lines))
(name (completing-read "Connect headphones: " (mapcar #'car choices) nil t))
(mac (cdr (assoc name choices))))
(start-process-shell-command "connect-headphones" nil
(concat "azos-connect-headphones --mac " mac)))))
(define-key azos/global-minor-mode/open-keymap
(kbd "h") 'azos/connect-headphones)
#+end_src
** Tab bar setup
#+begin_src emacs-lisp
(when (fboundp #'azos/bat/enable-tab-display)
(azos/bat/enable-tab-display))
(when (fboundp #'azos/network/enable-tab-display)
(azos/network/enable-tab-display))
(when (fboundp #'azos/audio/enable-tab-display)
(azos/audio/enable-tab-display))
#+end_src
** Nixpkgs Search
#+begin_src emacs-lisp
(defun azos/nixpkgs-parse-json-lines (str)
"Parse JSON Lines format (one JSON object per line) from STR."
(mapcar (lambda (line)
(and (not (string-empty-p line))
(string-match "^{" line)
(condition-case nil
(json-parse-string line)
(error nil))))
(split-string (string-trim str) "\n" t)))
(defun azos/nixpkgs-g (key hash)
"Get KEY from HASH table."
(when (hash-table-p hash)
(gethash key hash)))
(defun azos/nixpkgs-search ()
"Search for a nixpkgs package and show its info."
(interactive)
(let* ((pattern (read-string "Search pattern: "))
(json-output (shell-command-to-string
(format "nix-search --json --max-results 50 '%s'" pattern)))
(results (and json-output
(not (string-empty-p json-output))
(azos/nixpkgs-parse-json-lines json-output)))
(packages (delq nil (mapcar (lambda (item)
(let ((pname (azos/nixpkgs-g "package_pname" item)))
(when pname
(cons pname item))))
results))))
(if packages
(let* ((selected (completing-read "Package: " (mapcar #'car packages) nil t))
(package-data (cdr (assoc-string selected packages))))
(let ((buf (get-buffer-create "*nixpkgs-package-info*")))
(with-current-buffer buf
(erase-buffer)
(if package-data
(progn
(insert (format "Package: %s\n\n" selected))
(insert (format "Version: %s\n" (or (azos/nixpkgs-g "package_pversion" package-data) "unknown")))
(insert (format "Attr: %s\n" (or (azos/nixpkgs-g "package_attr_name" package-data) "unknown")))
(insert (format "\nDescription: %s\n"
(or (azos/nixpkgs-g "package_description" package-data) "none")))
(let ((programs (azos/nixpkgs-g "package_programs" package-data)))
(when (vectorp programs)
(insert (format "\nPrograms: %s\n"
(mapconcat #'identity (append programs nil) " ")))))
(let ((homepage (let ((h (azos/nixpkgs-g "package_homepage" package-data)))
(when (vectorp h) (aref h 0)))))
(when homepage
(insert (format "\nHomepage: %s\n" homepage))))
(let ((licenses (azos/nixpkgs-g "package_license" package-data)))
(when (vectorp licenses)
(insert (format "\nLicense: %s\n"
(mapconcat (lambda (l)
(or (azos/nixpkgs-g "fullName" l) ""))
(append licenses nil) ", ")))))
(insert (format "Package: %s\n\n" selected)
"\nNo additional info available.")))
(goto-char (point-min)))
(display-buffer buf)))
(message "No packages found matching '%s'" pattern))))
(define-key azos/global-minor-mode/open-keymap
(kbd "n") 'azos/nixpkgs-search)
#+end_src
** CalDAV / Org Sync
#+begin_src emacs-lisp
(require 'org-caldav)
(defvar azos/lauretta/nextcloud-user "aner"
"Nextcloud username for CalDAV sync.")
(setq org-caldav-url "https://nextcloud.zakobar.com/remote.php/dav/calendars/1ddd03a6-4c2d-103c-9f7b-27b20313341d"
org-caldav-calendar-id "personal"
org-caldav-inbox "~/org/caldav-inbox.org"
org-caldav-files '("~/org/todo.org")
org-icalendar-timezone "Asia/Jerusalem")
(defun azos/caldav-sync ()
"Sync org-caldav with Nextcloud calendar, reading password from pass."
(interactive)
(let* ((password (string-trim
(shell-command-to-string
"pass zakobar.com | head -1")))
(url-http-real-basic-auth-storage
(list (list "nextcloud.zakobar.com:443"
(cons azos/lauretta/nextcloud-user password)))))
(org-caldav-sync)))
(define-key azos/global-minor-mode/open-keymap
(kbd "C") 'azos/caldav-sync)
#+end_src
** Elfeed Nextcloud News Sync
[[https://github.com/fasheng/elfeed-protocol][elfeed-protocol]] adds an =owncloud+= protocol that speaks the
ownCloud News API, which the Nextcloud News app also implements, so
it syncs elfeed's feed list and read/unread state with the Nextcloud
News app instead of just reading a local feed list one-way.
Reuses the same =zakobar.com= pass entry as the CalDAV sync above,
since it's the same Nextcloud account.
As of elfeed-protocol 1.0.0 (paired with elfeed >= 4.0.0), the
credentials go directly on =elfeed-feeds= — the older
=elfeed-protocol-feeds= variable is dead: setting it only logs a
deprecation warning, and =elfeed-feeds= ends up with the bare URL
and no =:password=, so requests silently authenticate with an empty
password and nothing ever lands in the db.
This =:config= block runs synchronously the first time =elfeed= is
loaded (i.e. the first =M-x elfeed= of the session), with no user
keypress behind it the way =azos/caldav-sync= has. Fetching the
password with =shell-command-to-string= there used to deadlock
Emacs whenever the GPG PIN cache had expired: that call blocks
Emacs's single thread on the =pass|gpg= subprocess, but
=pinentry-emacs= (see the GPG Pinentry section above) needs Emacs's
command loop running to answer its loopback prompt — so Emacs waits
on gpg-agent while gpg-agent waits on Emacs. Fetching the password
with =make-process= instead keeps the command loop alive, so
=pinentry-emacs= can prompt normally; =elfeed-feeds= and
=elfeed-protocol-enable= are only set once the process sentinel
fires. Same stderr-redirect reasoning as before, to keep a stray
gpg/pass warning off the captured password.
#+begin_src emacs-lisp
(use-package elfeed-protocol
:after elfeed
:config
(setq elfeed-protocol-enabled-protocols '(owncloud))
(make-process
:name "elfeed-protocol-pass"
:command '("sh" "-c" "pass zakobar.com 2>/dev/null | head -1")
:noquery t
:filter (lambda (proc chunk)
(process-put proc 'output (concat (or (process-get proc 'output) "") chunk)))
:sentinel (lambda (proc _event)
(setq elfeed-feeds
`(("owncloud+https://aner@nextcloud.zakobar.com"
:password ,(string-trim (process-get proc 'output)))))
(elfeed-protocol-enable))))
#+end_src
** Elfeed Full Article Fetch
Many feeds only publish a short excerpt. elfeed >= 4.0 has built-in
commands for this — =f= (=elfeed-show-fetch-link=) fetches the
linked page and appends it to the show buffer, =R=
(=elfeed-show-readable=) strips the fetched page down to
article text via eww's readability scorer — and both can run
automatically via =elfeed-show-update-hook=, gated on a feed's
=:fetch-link=/=:readable= metadata.
That gating keys off an exact match on the feed's URL/id in
=elfeed-feeds=, which breaks for ownCloud/Nextcloud subfeeds:
elfeed-protocol synthesizes a per-subfeed id of the form
=<host-url>::<subfeed-url>= that never appears in =elfeed-feeds=
(only the bare host URL does), so the metadata lookup always misses
and the stock hooks never fire. Replacing them with unconditional
versions makes full-text + readable-mode the default for every
entry instead.
#+begin_src emacs-lisp
(defun azos/elfeed-show-auto-readable ()
"Like `elfeed-show-auto-readable', but unconditional."
(unless (local-variable-p 'elfeed-transform-html-functions)
(let ((inhibit-message t))
(elfeed-show-readable))))
(defun azos/elfeed-show-auto-fetch-link ()
"Like `elfeed-show-auto-fetch-link', but unconditional."
(elfeed-show-fetch-link))
(setq elfeed-show-update-hook
(list #'azos/elfeed-show-auto-readable #'azos/elfeed-show-auto-fetch-link))
#+end_src
** Lichess
=lichess.org= in pass already holds the website login password, and
lichess.el's =auth-source-pass= lookup resolves by bare hostname, so
the API token can't live under that same entry without colliding.
Store it separately under =lichess.org/token= (=pass insert
lichess.org/token=) and set the =lichess-token= variable directly —
=lichess-token= (the function) checks this variable before falling
back to =auth-source=, so this takes precedence without disturbing
the existing =lichess.org= entry or its consumers (e.g. browserpass).
=shell-command-to-string= merges stderr into its return value, so any
gpg/pass warning on stderr (e.g. an unsafe-permissions notice) would
otherwise get concatenated onto the token and break auth silently.
Redirect stderr away so only the token itself is ever captured.
#+begin_src emacs-lisp
(setq lichess-token
(string-trim (shell-command-to-string "pass lichess.org/token 2>/dev/null | head -1")))
#+end_src
=gpg-agent= may not have a cached passphrase yet when the =setq= above
runs at Emacs startup, in which case =pass= fails silently (stderr is
redirected away) and =lichess-token= is left as =""=. Retry the fetch
lazily right before each actual use, so a cold agent at startup
doesn't permanently wedge the token for the rest of the session.
#+begin_src emacs-lisp
(with-eval-after-load 'lichess
(advice-add 'lichess-token :before
(lambda ()
(when (string-empty-p lichess-token)
(setq lichess-token
(string-trim (shell-command-to-string "pass lichess.org/token 2>/dev/null | head -1")))))))
#+end_src
** Beacon Remote Jobs
#+begin_src emacs-lisp
(defvar azos/beacon/host "aner@192.168.1.200"
"SSH connection for beacon machine.")
(defvar azos/beacon/max-logs 5
"Number of most-recent logs to keep per project on beacon.")
(defvar azos/beacon/keymap (make-sparse-keymap)
"Keymap for beacon remote job commands (M-o b prefix).")
(define-key azos/global-minor-mode/open-keymap (kbd "b") azos/beacon/keymap)
(defun azos/beacon--project-root ()
(or (and (fboundp 'projectile-project-root) (projectile-project-root))
(error "Not in a projectile project")))
(defun azos/beacon--project-name (root)
(file-name-nondirectory (directory-file-name root)))
(defun azos/beacon--list-python-files (root)
(split-string
(shell-command-to-string
(format "cd %s && git ls-files | grep '\\.py$'" (shell-quote-argument root)))
"\n" t))
(defun azos/beacon--list-executables (root)
(split-string
(shell-command-to-string
(format "cd %s && git ls-files | while IFS= read -r f; do [ -x \"$f\" ] && echo \"$f\"; done"
(shell-quote-argument root)))
"\n" t))
(defun azos/beacon--ssh-run (script)
"Pipe SCRIPT as bash to beacon over SSH stdin. Error on non-zero exit."
(with-temp-buffer
(insert script)
(let ((ret (call-process-region (point-min) (point-max) "ssh" nil t nil
azos/beacon/host "bash")))
(unless (zerop ret)
(error "Beacon SSH error (exit %d): %s" ret (string-trim (buffer-string)))))))
(defun azos/beacon--ssh-query (cmd &optional allow-exit-one)
"Run CMD on beacon, return output string. Error on failure.
With ALLOW-EXIT-ONE, exit code 1 is also treated as success (for tmux ls)."
(with-temp-buffer
(let ((ret (call-process "ssh" nil t nil azos/beacon/host cmd)))
(unless (or (zerop ret) (and allow-exit-one (= ret 1)))
(error "Beacon SSH error (exit %d): %s" ret (string-trim (buffer-string)))))
(buffer-string)))
(defun azos/beacon--dispatch (root cmd label)
"Sync ROOT to beacon and run CMD in project dir under direnv.
LABEL names the tmux session and log file."
(let* ((project-name (azos/beacon--project-name root))
(timestamp (format-time-string "%Y%m%d-%H%M%S"))
(session (format "%s-%s-%s" project-name label timestamp))
(log-name (format "%s-%s.log" label timestamp)))
(message "Syncing %s to beacon..." project-name)
(azos/beacon--ssh-run (format "mkdir -p ~/beacon-projects/%s\n" project-name))
(with-temp-buffer
(let ((ret (call-process-shell-command
(format "bash -c %s"
(shell-quote-argument
(format "cd %s && git ls-files | rsync -avz --files-from=- . %s:~/beacon-projects/%s/"
root azos/beacon/host project-name)))
nil t nil)))
(unless (zerop ret)
(error "Beacon rsync failed (exit %d): %s" ret (string-trim (buffer-string))))))
(azos/beacon--ssh-run
(format "RDIR=~/beacon-projects/%s
LDIR=~/beacon-logs/%s
mkdir -p \"$LDIR\"
direnv allow \"$RDIR\"
tmux new-session -d -s %s -- bash -c \"cd $RDIR && direnv exec . %s 2>&1 | tee $LDIR/%s\"
"
project-name project-name
(shell-quote-argument session)
cmd log-name))
(azos/beacon--ssh-run
(format "find ~/beacon-logs/%s -name '*.log' -printf '%%T@ %%p\\n' 2>/dev/null | sort -rn | tail -n +%d | cut -d' ' -f2- | xargs -r rm -f\n"
project-name (1+ azos/beacon/max-logs)))
(message "Beacon job started: %s" session)))
(defun azos/beacon/run-python ()
"Sync current project to beacon and run a selected Python file."
(interactive)
(let* ((root (azos/beacon--project-root))
(files (azos/beacon--list-python-files root))
(file (completing-read "Python file: " files nil t))
(label (file-name-sans-extension (file-name-nondirectory file))))
(azos/beacon--dispatch root (format "python3 %s" file) label)))
(defun azos/beacon/run-exec ()
"Sync current project to beacon and run a selected executable."
(interactive)
(let* ((root (azos/beacon--project-root))
(files (azos/beacon--list-executables root))
(file (completing-read "Executable: " files nil t))
(label (file-name-sans-extension (file-name-nondirectory file))))
(azos/beacon--dispatch root (format "./%s" file) label)))
(defun azos/beacon/run-command ()
"Sync current project to beacon and run an arbitrary command."
(interactive)
(let* ((root (azos/beacon--project-root))
(cmd (read-string "Command: "))
(label (replace-regexp-in-string
"[^a-zA-Z0-9-]" "-"
(substring cmd 0 (min 20 (length cmd))))))
(azos/beacon--dispatch root cmd label)))
(defun azos/beacon/list-jobs ()
"Show all running beacon tmux sessions."
(interactive)
(async-shell-command
(format "ssh %s 'tmux ls 2>/dev/null || echo \"No jobs running\"'" azos/beacon/host)
"*beacon-jobs*"))
(defun azos/beacon/kill-job ()
"Kill a beacon tmux session selected interactively."
(interactive)
(let* ((output (azos/beacon--ssh-query "tmux ls -F '#S' 2>/dev/null" t))
(sessions (split-string (string-trim output) "\n" t))
(session (completing-read "Kill job: " sessions nil t)))
(azos/beacon--ssh-run (format "tmux kill-session -t %s\n" (shell-quote-argument session)))
(message "Killed beacon job: %s" session)))
(defun azos/beacon--tail-path (path)
(async-shell-command
(format "ssh %s %s" azos/beacon/host
(shell-quote-argument (format "tail -f %s" path)))
(format "*beacon-tail-%s*" (file-name-nondirectory path))))
(defun azos/beacon/tail-log (&optional arg)
"Tail the most recent beacon log.
With prefix ARG, prompt for a pattern then select from matches."
(interactive "P")
(let* ((sorted-output (azos/beacon--ssh-query
"find ~/beacon-logs -name '*.log' -printf '%T@ %P\n' 2>/dev/null | sort -rn | cut -d' ' -f2-"))
(logs (split-string (string-trim sorted-output) "\n" t)))
(when (null logs) (error "No logs found on beacon"))
(if (not arg)
(azos/beacon--tail-path (format "~/beacon-logs/%s" (car logs)))
(let* ((pattern (read-string "Log pattern: "))
(matches (seq-filter (lambda (l) (string-match-p pattern l)) logs))
(log (if (= (length matches) 1)
(car matches)
(completing-read "Tail log: " matches nil t))))
(azos/beacon--tail-path (format "~/beacon-logs/%s" log))))))
(define-key azos/beacon/keymap (kbd "p") #'azos/beacon/run-python)
(define-key azos/beacon/keymap (kbd "e") #'azos/beacon/run-exec)
(define-key azos/beacon/keymap (kbd "c") #'azos/beacon/run-command)
(define-key azos/beacon/keymap (kbd "l") #'azos/beacon/list-jobs)
(define-key azos/beacon/keymap (kbd "k") #'azos/beacon/kill-job)
(define-key azos/beacon/keymap (kbd "t") #'azos/beacon/tail-log)
#+end_src
** Roam Backup
=roam-backup= signs its commit with gpg, which can prompt for the YubiKey PIN
via pinentry. =async-shell-command= spawns the process with =TERM=dumb= and
no real controlling tty, so pinentry's curses fallback fails with
\"Inappropriate ioctl for device\" whenever the PIN cache has expired. Run it
in a =vterm= instead, which gives pinentry a real pty to prompt on.
#+begin_src emacs-lisp
(defun azos/roam/backup ()
"Commit and push ~/roam to the remote git repo."
(interactive)
(let ((vterm-buffer-name "*roam-backup*"))
(with-current-buffer (vterm-other-window)
(vterm-send-string "roam-backup")
(vterm-send-return))))
(define-key azos/roam-keymap (kbd "B") #'azos/roam/backup)
#+end_src
** Printing
#+begin_src emacs-lisp
(defun azos/print-buffer (&optional arg)
"Print the current buffer.
For image/PDF/doc buffers, sends the file path to lp directly.
For text buffers, uses lpr-buffer.
With C-u, interactively prompt for scaling, B&W, and orientation options."
(interactive "P")
(let* ((image-p (derived-mode-p 'image-mode 'pdf-view-mode 'doc-view-mode))
(scale (when arg (y-or-n-p "Fit to page? ")))
(bw (when arg (y-or-n-p "Black and white? ")))
(landscape (when (and arg image-p) (y-or-n-p "Landscape? ")))
(lp-opts (concat
(when scale " -o fit-to-page")
(when bw " -o print-color-mode=monochrome")
(when landscape " -o landscape"))))
(if image-p
(if buffer-file-name
(progn
(shell-command
(concat "lp" lp-opts " " (shell-quote-argument buffer-file-name)))
(message "Sent %s to printer%s%s%s."
(file-name-nondirectory buffer-file-name)
(if scale " [scaled]" "")
(if bw " [B&W]" "")
(if landscape " [landscape]" "")))
(error "Buffer has no associated file"))
(let ((lpr-switches
(append lpr-switches
(when bw '("-o print-color-mode=monochrome")))))
(lpr-buffer)))))
(define-key azos/global-minor-mode/open-keymap (kbd "P") #'azos/print-buffer)
#+end_src
* Provide
#+begin_src emacs-lisp
(provide 'azos-emacs-lauretta)
#+end_src
+3
View File
@@ -0,0 +1,3 @@
{...}: {
config.flake.overlayPkgs.azos-emacs-lauretta = pkgs: pkgs.localEmacsPkg ./_pkg.nix;
}
+19
View File
@@ -0,0 +1,19 @@
{...}: {
config.flake.modules.homeManager.leetcode = {
lib,
config,
pkgs,
...
}: {
options.azos.leetcode.enable = lib.mkOption {
default = false;
example = true;
type = lib.types.bool;
};
config = lib.mkIf config.azos.leetcode.enable {
azos.emacs.pkgs = [pkgs.azos-emacs-leetcode];
azos.emacs.enabledSuites = ["azos-emacs-leetcode"];
};
};
}
+14
View File
@@ -0,0 +1,14 @@
{
orgTrivialBuild,
epkgs,
pkgs,
}:
orgTrivialBuild {
pname = "azos-emacs-leetcode";
version = "0.1.0";
src = ./config.org;
packageRequires = with epkgs; [
pkgs.azos-emacs-base
leetcode
];
}
+29
View File
@@ -0,0 +1,29 @@
#+title: Aner's Emacs Leetcode Configuration
#+property: header-args :results silent
* Base setup
** Require
#+begin_src emacs-lisp
(require 'azos-emacs-base)
#+end_src
* Leetcode
#+begin_src emacs-lisp
(use-package leetcode
:init
(defun azos/leetcode/open ()
"Open leetcode in its dedicated \"leetcode\" tab."
(interactive)
(azos/tab-bar/open-singleton-tab "leetcode" #'leetcode))
:bind
(:map azos/global-minor-mode/open-keymap
("L" . azos/leetcode/open)))
#+end_src
* Provide
#+begin_src emacs-lisp
(provide 'azos-emacs-leetcode)
#+end_src
+3
View File
@@ -0,0 +1,3 @@
{...}: {
config.flake.overlayPkgs.azos-emacs-leetcode = pkgs: pkgs.localEmacsPkg ./_pkg.nix;
}
+83
View File
@@ -0,0 +1,83 @@
{...}: {
config.flake.modules.homeManager.mail = {
lib,
config,
pkgs,
...
}: let
default_account_params = {
realName = "Aner Zakobar";
mbsync = {
enable = true;
create = "maildir";
};
msmtp.enable = true;
};
default_gmail_params =
default_account_params
// {
flavor = "gmail.com";
};
default_smtp = {
tls = {
enable = true;
useStartTls = true;
certificatesFile = "/etc/ssl/certs/ca-certificates.crt";
};
};
in {
options.azos.mail.enable = lib.mkOption {
default = true;
type = lib.types.bool;
};
config = lib.mkIf config.azos.mail.enable {
programs = {
mu.enable = true;
mbsync.enable = true;
msmtp.enable = true;
lieer.enable = true;
};
home.activation.muInit = lib.hm.dag.entryAfter ["writeBoundary"] ''
if [ ! -d "$HOME/.cache/mu" ]; then
$DRY_RUN_CMD ${pkgs.mu}/bin/mu init \
--maildir="$HOME/Maildir" \
--my-address=aner@zakobar.com \
--my-address=anerisgreat@gmail.com \
--my-address=anerz@post.bgu.ac.il
fi
'';
services.lieer.enable = true;
accounts.email.accounts = {
gmail =
default_gmail_params
// {
address = "anerisgreat@gmail.com";
userName = "anerisgreat";
passwordCommand = "pass mbsync/anerisgreat@gmail.com | head -1";
};
bgu =
default_gmail_params
// {
address = "anerz@post.bgu.ac.il";
userName = "anerz@post.bgu.ac.il";
passwordCommand = "pass mbsync/anerz@post.bgu.ac.il | head -1";
};
zakobar =
default_account_params
// {
address = "aner@zakobar.com";
primary = true;
userName = "aner@zakobar.com";
imap = {host = "mail.privateemail.com";};
smtp =
default_smtp
// {
port = 587;
host = "mail.privateemail.com";
};
passwordCommand = "pass privateemail.com | head -1";
};
};
};
};
}
+15
View File
@@ -0,0 +1,15 @@
{...}: {
config.flake.modules.homeManager.mpris-proxy = {
lib,
config,
...
}: {
options.azos.mpris-proxy.enable = lib.mkOption {
default = true;
type = lib.types.bool;
};
config = lib.mkIf config.azos.mpris-proxy.enable {
services.mpris-proxy.enable = true;
};
};
}
+20
View File
@@ -0,0 +1,20 @@
{...}: {
config.flake.modules.homeManager.nextcloud = {
lib,
config,
pkgs,
...
}: {
options.azos.nextcloud-client.enable = lib.mkOption {
default = true;
type = lib.types.bool;
};
config = lib.mkIf config.azos.nextcloud-client.enable {
home.packages = with pkgs; [nextcloud-client];
services.nextcloud-client = {
enable = true;
startInBackground = false;
};
};
};
}
+15
View File
@@ -0,0 +1,15 @@
{...}: {
config.flake.modules.homeManager.opencode = {
lib,
config,
...
}: {
options.azos.opencode.enable = lib.mkOption {
default = true;
type = lib.types.bool;
};
config = lib.mkIf config.azos.opencode.enable {
programs.opencode.enable = true;
};
};
}
+55
View File
@@ -0,0 +1,55 @@
{...}: {
config.flake.modules.nixos.printing = {
lib,
config,
pkgs,
...
}: let
webpFilter = pkgs.writeShellScript "webptopdf" ''
if [ $# -ge 6 ]; then
INPUT="$6"
TMPFILE=""
else
TMPFILE=$(mktemp /tmp/cups-webp-XXXXXX.webp)
cat > "$TMPFILE"
INPUT="$TMPFILE"
fi
TMPOUT=$(mktemp /tmp/cups-webp-XXXXXX.pdf)
${pkgs.imagemagick}/bin/magick "$INPUT" "$TMPOUT"
cat "$TMPOUT"
rm -f "$TMPOUT"
[ -n "$TMPFILE" ] && rm -f "$TMPFILE"
'';
webpCupsMime = pkgs.runCommand "webp-cups-mime" {} ''
mkdir -p $out/lib/cups/filter $out/share/cups/mime
cp ${webpFilter} $out/lib/cups/filter/webptopdf
chmod +x $out/lib/cups/filter/webptopdf
echo 'image/webp webp string(0,"RIFF") string(8,"WEBP")' > $out/share/cups/mime/webp.types
echo 'image/webp application/pdf 0 webptopdf' > $out/share/cups/mime/webp.convs
'';
in {
options.azos.printing.enable = lib.mkOption {
default = false;
example = true;
type = lib.types.bool;
};
config = lib.mkIf config.azos.printing.enable {
services.printing = {
enable = true;
drivers = [pkgs.hplip webpCupsMime];
};
environment.systemPackages = [pkgs.hplip];
services.avahi = {
enable = true;
nssmdns4 = true;
openFirewall = true;
};
users.users.aner.extraGroups = ["lp"];
};
};
}
@@ -43,7 +43,7 @@ c.downloads.location.prompt = False
c.editor.command = ['emacsclient', '-e', '(find-file "{}")'] c.editor.command = ['emacsclient', '-e', '(find-file "{}")']
monospace = "10pt 'DejaVu Sans Mono'" monospace = "10pt 'DejaVu Sans Mono'"
c.fonts.completion.category = f"bold{monospace}" c.fonts.completion.category = f"bold {monospace}"
c.fonts.completion.entry = monospace c.fonts.completion.entry = monospace
c.fonts.debug_console = monospace c.fonts.debug_console = monospace
c.fonts.downloads = monospace c.fonts.downloads = monospace
@@ -54,3 +54,10 @@ c.fonts.messages.warning = monospace
c.fonts.prompts = monospace c.fonts.prompts = monospace
c.fonts.statusbar = monospace c.fonts.statusbar = monospace
c.fonts.hints = "bold 13px 'LiberationMono'" c.fonts.hints = "bold 13px 'LiberationMono'"
#Set highdpi
c.qt.highdpi = True
c.zoom.default = 70
c.qt.args = ['--disable-gpu']
c.qt.environ = {'QT_XCB_GL_INTEGRATION': 'none', 'LIBGL_ALWAYS_SOFTWARE': '1'}
+15
View File
@@ -0,0 +1,15 @@
{...}: {
config.flake.modules.homeManager.qutebrowser = {
lib,
config,
...
}: {
options.azos.qutebrowser-config.enable = lib.mkOption {
default = true;
type = lib.types.bool;
};
config = lib.mkIf config.azos.qutebrowser-config.enable {
home.file.".config/qutebrowser/config.py".source = ./config.py;
};
};
}
+21
View File
@@ -0,0 +1,21 @@
{...}: {
config.flake.modules.homeManager.reaper = {
lib,
config,
pkgs,
...
}: {
options.azos.reaper.enable = lib.mkOption {
default = true;
type = lib.types.bool;
};
config = lib.mkIf config.azos.reaper.enable {
home.packages = with pkgs; [
reaper
helm
lsp-plugins
vital
];
};
};
}
+30
View File
@@ -0,0 +1,30 @@
{...}: {
config.flake.modules.homeManager.roam-backup = {
lib,
config,
pkgs,
...
}: {
options.azos.roam-backup.enable = lib.mkOption {
default = false;
example = true;
type = lib.types.bool;
};
config = lib.mkIf config.azos.roam-backup.enable {
home.packages = [
(pkgs.writeShellScriptBin "roam-backup" ''
set -e
cd "$HOME/roam"
git add -A
if git diff --cached --quiet; then
echo "Nothing to commit."
else
git commit -m "backup: $(date '+%Y-%m-%d %H:%M')"
fi
git push --set-upstream origin HEAD
'')
];
};
};
}
+61
View File
@@ -0,0 +1,61 @@
{...}: {
config.flake.modules.homeManager.snx-rs = {
lib,
config,
pkgs,
...
}: let
cfg = config.azos.snx-rs;
in {
options.azos.snx-rs = {
enable = lib.mkOption {
default = true;
type = lib.types.bool;
};
server = lib.mkOption {
default = "vpn.bgu.ac.il";
type = lib.types.str;
description = "VPN server address";
};
username = lib.mkOption {
default = "anerz@vpn";
type = lib.types.str;
description = "VPN username";
};
loginType = lib.mkOption {
default = "vpn";
type = lib.types.str;
description = "Login type";
};
ignoreServerCert = lib.mkOption {
default = true;
type = lib.types.bool;
description = "Ignore server certificate validation";
};
};
config = lib.mkIf cfg.enable {
home.packages = with pkgs; [
snx-rs
(pkgs.writeShellScriptBin "snx-connect" ''
#!/bin/sh
sudo ${pkgs.snx-rs}/bin/snx-rs -m command &
sleep 1
${pkgs.snx-rs}/bin/snxctl connect
'')
(pkgs.writeShellScriptBin "snx-disconnect" ''
#!/bin/sh
${pkgs.snx-rs}/bin/snxctl disconnect
pkill -x snx-rs 2>/dev/null || true
'')
];
home.file.".config/snx-rs/snx-rs.conf" = {
text = ''
server ${cfg.server}
username ${cfg.username}
login-type ${cfg.loginType}
ignore-server-cert ${lib.boolToString cfg.ignoreServerCert}
'';
};
};
};
}
+15
View File
@@ -0,0 +1,15 @@
{...}: {
config.flake.modules.nixos.steam = {
lib,
config,
...
}: {
options.azos.steam.enable = lib.mkOption {
default = true;
type = lib.types.bool;
};
config = lib.mkIf config.azos.steam.enable {
programs.steam.enable = true;
};
};
}
+30
View File
@@ -0,0 +1,30 @@
{...}: {
config.flake.modules.nixos.virtualization = {
lib,
config,
pkgs,
...
}: {
options.azos.virtualization.enable = lib.mkOption {
default = true;
type = lib.types.bool;
};
config = lib.mkIf config.azos.virtualization.enable {
virtualisation.libvirtd = {
enable = true;
qemu = {
swtpm.enable = true;
};
};
environment.systemPackages = with pkgs; [
qemu_kvm
libvirt
virt-manager
virt-viewer
];
services.spice-vdagentd.enable = true;
networking.firewall.allowedTCPPorts = [5900 5901];
networking.firewall.allowedUDPPorts = [5900 5901];
};
};
}
+16
View File
@@ -0,0 +1,16 @@
{...}: {
config.flake.modules.homeManager.ytdl = {
lib,
config,
pkgs,
...
}: {
options.azos.ytdl.enable = lib.mkOption {
default = true;
type = lib.types.bool;
};
config = lib.mkIf config.azos.ytdl.enable {
home.packages = with pkgs; [yt-dlp];
};
};
}
Generated
+221 -96
View File
@@ -3,8 +3,9 @@
"azos-core": { "azos-core": {
"inputs": { "inputs": {
"cabata": "cabata", "cabata": "cabata",
"nix-search-cli": "nix-search-cli", "evil-hl-line": "evil-hl-line",
"nixpkgs": "nixpkgs_3" "flake-parts": "flake-parts",
"import-tree": "import-tree"
}, },
"locked": { "locked": {
"path": "./azos-core", "path": "./azos-core",
@@ -23,11 +24,11 @@
"systems": "systems" "systems": "systems"
}, },
"locked": { "locked": {
"lastModified": 1771368993, "lastModified": 1779008956,
"narHash": "sha256-mWcLaCViNfUMPcqCvQRed4kR20Ifs8aaHcjMlVbF2tQ=", "narHash": "sha256-jpJ30XX1pAH+Mpsyj92K8t6812Qs+P4J31wO7RS/e+Y=",
"owner": "anerisgreat", "owner": "anerisgreat",
"repo": "cabata", "repo": "cabata",
"rev": "4fa661795527fa437698409395dc4363fbc0adf0", "rev": "ff1871152ffb635e18e1a9804750192c6969d1cb",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -36,14 +37,33 @@
"type": "github" "type": "github"
} }
}, },
"evil-hl-line": {
"inputs": {
"flake-utils": "flake-utils_2",
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1778617640,
"narHash": "sha256-bG1hjyLIOiRB+M1rXm8ch0ftHPvV43lRtzQ8qWcus5s=",
"owner": "anerisgreat",
"repo": "evil-hl-line",
"rev": "7cf5a11bdca2abd9516f0ce572e1e03bb541507f",
"type": "github"
},
"original": {
"owner": "anerisgreat",
"repo": "evil-hl-line",
"type": "github"
}
},
"flake-compat": { "flake-compat": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1673956053, "lastModified": 1767039857,
"narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", "narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=",
"owner": "edolstra", "owner": "edolstra",
"repo": "flake-compat", "repo": "flake-compat",
"rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", "rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -52,6 +72,42 @@
"type": "github" "type": "github"
} }
}, },
"flake-parts": {
"inputs": {
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1778716662,
"narHash": "sha256-m1Yf0wZ8j1OHjTc2UwHwyQRSnNeSgLJOd7q5Y45hzi4=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "f7c1a2d347e4c52d5fb8d10cb4d94b5884e546fb",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-parts_2": {
"inputs": {
"nixpkgs-lib": "nixpkgs-lib_2"
},
"locked": {
"lastModified": 1788450739,
"narHash": "sha256-glZLQlzIn1fXH6PazR2iUmTo7kzzyYSshrWhLS9TqCU=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "31729ca8cbdb4fa927b34e5f4353e6a83f39e993",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-utils": { "flake-utils": {
"inputs": { "inputs": {
"systems": [ "systems": [
@@ -75,12 +131,15 @@
} }
}, },
"flake-utils_2": { "flake-utils_2": {
"inputs": {
"systems": "systems_2"
},
"locked": { "locked": {
"lastModified": 1676283394, "lastModified": 1731533236,
"narHash": "sha256-XX2f9c3iySLCw54rJ/CZs+ZK6IQy7GXNY4nSOyu2QG4=", "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide", "owner": "numtide",
"repo": "flake-utils", "repo": "flake-utils",
"rev": "3db36a8b464d0c4532ba1c7dda728f4576d6d073", "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -96,11 +155,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1774647770, "lastModified": 1788651960,
"narHash": "sha256-UNNi14XiqRWWjO8ykbFwA5wRwx7EscsC+GItOVpuGjc=", "narHash": "sha256-v9wJd32eZ2bvhBzVOd7TIjLQd011P7nwOhjKtWlci5I=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "02371c05a04a2876cf92e2d67a259e8f87399068", "rev": "2c0350c759688177331b8f5242311fae8877bdb3",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -110,16 +169,46 @@
"type": "github" "type": "github"
} }
}, },
"import-tree": {
"locked": {
"lastModified": 1778781969,
"narHash": "sha256-Jjuz5CmSkur8KvLDoGa+vylEp+RkQtv4mt/qcMznpH0=",
"owner": "vic",
"repo": "import-tree",
"rev": "d321337efd0f23a9eb14a42adb7b2c29313ab274",
"type": "github"
},
"original": {
"owner": "vic",
"repo": "import-tree",
"type": "github"
}
},
"import-tree_2": {
"locked": {
"lastModified": 1788467110,
"narHash": "sha256-ljEMTXP/rH0tOvDzc9gzwww6KcHRPRnEHzd9lK48V7s=",
"owner": "vic",
"repo": "import-tree",
"rev": "eb1b52eaecc57f7c136d07ae8a93e724dfecac46",
"type": "github"
},
"original": {
"owner": "vic",
"repo": "import-tree",
"type": "github"
}
},
"musnix": { "musnix": {
"inputs": { "inputs": {
"nixpkgs": "nixpkgs_4" "nixpkgs": "nixpkgs_3"
}, },
"locked": { "locked": {
"lastModified": 1773185476, "lastModified": 1777848538,
"narHash": "sha256-COuJkFg669oalmEN3T61gD3gM9SfUsiGvDS9pCOphZY=", "narHash": "sha256-Dj51C0NWsglqRrCpdmMr2nFiYacFOid1Tor4H9yG2HY=",
"owner": "musnix", "owner": "musnix",
"repo": "musnix", "repo": "musnix",
"rev": "739e2a1f94c87d5f4c8b880a12480185cf0d7620", "rev": "8548782f0d1d0928daa3fffde8a008f72219a3f3",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -128,49 +217,16 @@
"type": "github" "type": "github"
} }
}, },
"nix-filter": {
"locked": {
"lastModified": 1710156097,
"narHash": "sha256-1Wvk8UP7PXdf8bCCaEoMnOT1qe5/Duqgj+rL8sRQsSM=",
"owner": "numtide",
"repo": "nix-filter",
"rev": "3342559a24e85fc164b295c3444e8a139924675b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "nix-filter",
"type": "github"
}
},
"nix-search-cli": {
"inputs": {
"flake-compat": "flake-compat",
"flake-utils": "flake-utils_2",
"nix-filter": "nix-filter",
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1762187737,
"narHash": "sha256-NGL9jj4y16+d0Es7aK1oxqAimZn7sdJDAxVkcY3CTcg=",
"owner": "peterldowns",
"repo": "nix-search-cli",
"rev": "ab0d5156c1e3b383c250ff273639cd3dea6de2d9",
"type": "github"
},
"original": {
"owner": "peterldowns",
"repo": "nix-search-cli",
"type": "github"
}
},
"nixos-hardware": { "nixos-hardware": {
"inputs": {
"nixpkgs": "nixpkgs_4"
},
"locked": { "locked": {
"lastModified": 1774567711, "lastModified": 1788335262,
"narHash": "sha256-uVlOHBvt6Vc/iYNJXLPa4c3cLXwMllOCVfAaLAcphIo=", "narHash": "sha256-3jBEq8avfzlrsY4UpW4d5TOmm7ocseZfnitEJhqauyc=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixos-hardware", "repo": "nixos-hardware",
"rev": "3f6f874dfc34d386d10e434c48ad966c4832243e", "rev": "44d95795ee2d475b3d687325e26dcf4ca9104557",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -180,6 +236,27 @@
"type": "github" "type": "github"
} }
}, },
"nixos-wsl": {
"inputs": {
"flake-compat": "flake-compat",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1784642409,
"narHash": "sha256-hcbDqFuySAJawljt5r0sKBCJKYnbtGD0T/ZIozH1Dq0=",
"owner": "nix-community",
"repo": "nixos-wsl",
"rev": "eaeb18da90024448a60eb1ec7132eafa4003404e",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixos-wsl",
"type": "github"
}
},
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1769421245, "lastModified": 1769421245,
@@ -194,13 +271,43 @@
"type": "indirect" "type": "indirect"
} }
}, },
"nixpkgs-lib": {
"locked": {
"lastModified": 1777168982,
"narHash": "sha256-GOkGPcboWE9BmGCRMLX3worL4EMnsnG8MyKmXNeYuhQ=",
"owner": "nix-community",
"repo": "nixpkgs.lib",
"rev": "f5901329dade4a6ea039af1433fb087bd9c1fe14",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixpkgs.lib",
"type": "github"
}
},
"nixpkgs-lib_2": {
"locked": {
"lastModified": 1788057806,
"narHash": "sha256-DTQSMxzDWmT0zhguthvegnVkn7CFqGCv4IHCzk5ZUpM=",
"owner": "nix-community",
"repo": "nixpkgs.lib",
"rev": "596e2e3940e09b2abbeb03f75fa1828c57fcd72c",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixpkgs.lib",
"type": "github"
}
},
"nixpkgs-unstable": { "nixpkgs-unstable": {
"locked": { "locked": {
"lastModified": 1774386573, "lastModified": 1788614874,
"narHash": "sha256-4hAV26quOxdC6iyG7kYaZcM3VOskcPUrdCQd/nx8obc=", "narHash": "sha256-7QYjT2vHLuX9Z1pdxHXDKCbh1CR3D/2rywB9Tx0MPRg=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "46db2e09e1d3f113a13c0d7b81e2f221c63b8ce9", "rev": "c043004d1c6985732bcc1cbc5a9c9aecbbb4e0f0",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -212,40 +319,11 @@
}, },
"nixpkgs_2": { "nixpkgs_2": {
"locked": { "locked": {
"lastModified": 1761752004, "lastModified": 1779508470,
"narHash": "sha256-z83uhYagfW6ZnH5Svvaxx6O0a305sBLGCCJZBJnMD9w=", "narHash": "sha256-Ap9KJX+5xHIn3bPIpfNgT6MEXdAECECwo4/rmlQD74M=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "ddf56acbeb53825b79b82c13a657806774bfd137",
"type": "github"
},
"original": {
"owner": "nixos",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_3": {
"locked": {
"lastModified": 1774273680,
"narHash": "sha256-a++tZ1RQsDb1I0NHrFwdGuRlR5TORvCEUksM459wKUA=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "fdc7b8f7b30fdbedec91b71ed82f36e1637483ed", "rev": "29916453413845e54a65b8a1cf996842300cd299",
"type": "github"
},
"original": {
"id": "nixpkgs",
"type": "indirect"
}
},
"nixpkgs_4": {
"locked": {
"lastModified": 1772198003,
"narHash": "sha256-I45esRSssFtJ8p/gLHUZ1OUaaTaVLluNkABkk6arQwE=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "dd9b079222d43e1943b6ebd802f04fd959dc8e61",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -255,13 +333,42 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_5": { "nixpkgs_3": {
"locked": { "locked": {
"lastModified": 1774273680, "lastModified": 1777268161,
"narHash": "sha256-a++tZ1RQsDb1I0NHrFwdGuRlR5TORvCEUksM459wKUA=", "narHash": "sha256-bxrdOn8SCOv8tN4JbTF/TXq7kjo9ag4M+C8yzzIRYbE=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "fdc7b8f7b30fdbedec91b71ed82f36e1637483ed", "rev": "1c3fe55ad329cbcb28471bb30f05c9827f724c76",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_4": {
"locked": {
"lastModified": 1767892417,
"narHash": "sha256-8bW3q88CEg2u4hSP66Vf4lpbLonHz7hqDNBMcCY7E9U=",
"rev": "3497aa5c9457a9d88d71fa93a4a8368816fbeeba",
"type": "tarball",
"url": "https://releases.nixos.org/nixos/unstable/nixos-26.05pre924538.3497aa5c9457/nixexprs.tar.xz"
},
"original": {
"type": "tarball",
"url": "https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz"
}
},
"nixpkgs_5": {
"locked": {
"lastModified": 1788549839,
"narHash": "sha256-kOrCcSIA6w9J1hX5DqHy2k9pDTJymExTsbV74U9UtCA=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "17de0b976395537756f30a3e78f2f06e5cec89ed",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -274,9 +381,12 @@
"root": { "root": {
"inputs": { "inputs": {
"azos-core": "azos-core", "azos-core": "azos-core",
"flake-parts": "flake-parts_2",
"home-manager": "home-manager", "home-manager": "home-manager",
"import-tree": "import-tree_2",
"musnix": "musnix", "musnix": "musnix",
"nixos-hardware": "nixos-hardware", "nixos-hardware": "nixos-hardware",
"nixos-wsl": "nixos-wsl",
"nixpkgs": "nixpkgs_5", "nixpkgs": "nixpkgs_5",
"nixpkgs-unstable": "nixpkgs-unstable" "nixpkgs-unstable": "nixpkgs-unstable"
} }
@@ -295,6 +405,21 @@
"repo": "x86_64-linux", "repo": "x86_64-linux",
"type": "github" "type": "github"
} }
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
} }
}, },
"root": "root", "root": "root",
+28 -44
View File
@@ -3,13 +3,8 @@
inputs = { inputs = {
self.submodules = true; self.submodules = true;
# Nixpkgs
#Temporarily
# nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
#Need unstable for opencode and agent-shell
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
# Unused unstable nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable"; nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable";
home-manager = { home-manager = {
@@ -19,59 +14,48 @@
nixos-hardware.url = "github:NixOS/nixos-hardware/master"; nixos-hardware.url = "github:NixOS/nixos-hardware/master";
#Music production nix
musnix = {url = "github:musnix/musnix";}; musnix = {url = "github:musnix/musnix";};
azos-core = { azos-core = {
url = "./azos-core"; url = "./azos-core";
flake = true; flake = true;
}; };
nixos-wsl = {
url = "github:nix-community/nixos-wsl";
inputs.nixpkgs.follows = "nixpkgs";
}; };
outputs = { flake-parts.url = "github:hercules-ci/flake-parts";
self, import-tree.url = "github:vic/import-tree";
nixpkgs, };
home-manager,
... outputs = inputs:
} @ inputs: let inputs.flake-parts.lib.mkFlake {inherit inputs;} {
inherit (self) outputs; imports = [
inputs.azos-core.flakeModules.default
./overlays/default.nix
(inputs.import-tree ./features)
./_machines/lauretta.nix
./_machines/vm.nix
./_machines/beacon.nix
./_machines/beacon-wsl.nix
];
systems = [ systems = [
"aarch64-linux" "aarch64-linux"
"x86_64-linux" "x86_64-linux"
"aarch64-darwin" "aarch64-darwin"
"x86_64-darwin" "x86_64-darwin"
]; ];
forAllSystems = nixpkgs.lib.genAttrs systems;
in {
formatter = forAllSystems (system: nixpkgs.legacyPackages.${system}.alejandra);
overlays = import ./overlays {inherit inputs;}; perSystem = {
azos-core.nixosModules = inputs.azos-core.nixosModules.nixosModules; system,
nixosModules = import ./modules/nixos; pkgs,
azos-core.homeManagerModules = inputs.azos-core.nixosModules.homeManagerModules; ...
homeManagerModules = import ./modules/home-manager; }: {
formatter = pkgs.alejandra;
#Systems configured devShells = (import ./shells) {inherit pkgs;};
nixosConfigurations = {
#Lauretta - laptop
lauretta = nixpkgs.lib.nixosSystem {
specialArgs = {inherit inputs outputs;};
modules = [
./nixos/configuration.nix
];
}; };
#Test VM
vm = nixpkgs.lib.nixosSystem {
specialArgs = {inherit inputs outputs;};
modules = [
./nixos/configuration-vm.nix
];
};
};
#TODO this is probably unsupported
#TODO the devshells do not know of the new packages.
devShells = forAllSystems (system: ((import ./shells) {pkgs = nixpkgs.legacyPackages.${system};}));
}; };
} }
+49 -11
View File
@@ -1,36 +1,74 @@
# This is your home-manager configuration file
# Use this to configure your home environment (it replaces ~/.config/nixpkgs/home.nix)
{ {
inputs, inputs,
outputs, outputs,
suiteModules,
lib, lib,
config, config,
pkgs, pkgs,
... ...
}: { }: {
imports = [ imports = [
outputs.homeManagerModules suiteModules.homeManager.base
outputs.azos-core.homeManagerModules suiteModules.homeManager.dev
suiteModules.homeManager.editor
suiteModules.homeManager.station
suiteModules.homeManager.exwm
suiteModules.homeManager.lauretta
suiteModules.homeManager.audio
suiteModules.homeManager.claude
suiteModules.homeManager.claude-memory
suiteModules.homeManager.claude-skills
suiteModules.homeManager.encryption
suiteModules.homeManager.git-config
suiteModules.homeManager.hfsprogs
suiteModules.homeManager.headphones
suiteModules.homeManager.hyprland
suiteModules.homeManager.kubernetes
suiteModules.homeManager.mail
suiteModules.homeManager.mpris-proxy
suiteModules.homeManager.nextcloud
suiteModules.homeManager.opencode
suiteModules.homeManager.qutebrowser
suiteModules.homeManager.reaper
suiteModules.homeManager.snx-rs
suiteModules.homeManager.roam-backup
suiteModules.homeManager.ytdl
suiteModules.homeManager.chess
suiteModules.homeManager.homey-alert
suiteModules.homeManager.leetcode
]; ];
programs.home-manager.enable = true; programs.home-manager.enable = true;
azos.suites.base.enable = true;
azos.suites.editor.enable = true;
azos.suites.dev.enable = true;
azos.suites.station.enable = true;
azos.suites.exwm.enable = true;
azos.suites.lauretta.enable = true; azos.suites.lauretta.enable = true;
azos.chess.enable = true;
azos.leetcode.enable = true;
azos.name = "Aner Zakobar"; azos.name = "Aner Zakobar";
azos.headphones.enable = true;
azos.headphones.devices = [
{
mac = "AC:80:0A:AF:E1:C2";
name = "Aner's Headphones";
}
{
mac = "AC:80:0A:A1:5F:53";
name = "Chen's Headphones";
}
{
mac = "E4:17:D8:29:9B:16";
name = "8bitdo";
}
];
azos.roam-backup.enable = true;
azos.homey-alert.enable = true;
home = { home = {
username = "aner"; username = "aner";
homeDirectory = "/home/aner"; homeDirectory = "/home/aner";
}; };
# Nicely reload system units when changing configs
systemd.user.startServices = "sd-switch"; systemd.user.startServices = "sd-switch";
# https://nixos.wiki/wiki/FAQ/When_do_I_update_stateVersion
home.stateVersion = "25.11"; home.stateVersion = "25.11";
} }
-19
View File
@@ -1,19 +0,0 @@
{
lib,
config,
pkgs,
...
}: let
isEnabled =
config.azos.home-audio.enable;
in {
options.azos.home-audio.enable = lib.mkOption {
default = true;
example = true;
type = lib.types.bool;
};
config = lib.mkIf isEnabled {
# home.packages = with pkgs; [pavucontrol];
};
}
-19
View File
@@ -1,19 +0,0 @@
{
lib,
config,
pkgs,
...
}: let
isEnabled =
config.azos.claude.enable;
in {
options.azos.claude.enable = lib.mkOption {
default = true;
example = true;
type = lib.types.bool;
};
config = lib.mkIf isEnabled {
home.packages = with pkgs; [claude-code claude-agent-acp];
};
}
-22
View File
@@ -1,22 +0,0 @@
{
imports = [
./audio.nix
./claude.nix
./encryption.nix
./git.nix
./hfsprogs.nix
./headphones-whmx4000.nix
./hyprland-suite.nix
./kubernetes.nix
./lauretta-emacs.nix
./mail.nix
./mpris-proxy.nix
./opencode.nix
# ./printing.nix
# ./gnuradio.nix
./qutebrowser-config.nix
./reaper.nix
./snx-rs.nix
./ytdl.nix
];
}
-41
View File
@@ -1,41 +0,0 @@
{
lib,
config,
pkgs,
...
}: let
isEnabled =
config.azos.encryption.enable;
in {
options.azos.encryption.enable = lib.mkOption {
default = true;
example = true;
type = lib.types.bool;
};
config = lib.mkIf isEnabled {
programs.password-store = {
enable = true;
settings = {
PASSWORD_STORE_KEY = "076AA297579A0064";
};
};
home.packages = with pkgs; [
yubikey-personalization
pinentry-gtk2
];
programs.gpg = {
enable = true;
};
services.gpg-agent = {
enable = true;
enableSshSupport = true;
pinentry.package = pkgs.pinentry-gtk2;
};
home.file.".ssh/config".source = ./ssh-config;
home.file.".ssh/gpg-as-ssh.pub".source = ./gpg-as-ssh.pub;
home.file.".gnupg/sshcontrol".source = ./sshcontrol;
};
}
-40
View File
@@ -1,40 +0,0 @@
{
lib,
config,
pkgs,
...
}: let
isEnabled =
config.azos.git-config.enable;
in {
options.azos.git-config.enable = lib.mkOption {
default = true;
example = true;
type = lib.types.bool;
};
config = lib.mkIf isEnabled {
home.packages = with pkgs; [pass-git-helper unzip];
programs.git = {
enable = true;
signing = {
key = "6D17E295C70E2674";
signByDefault = true;
};
settings = {
extraConfig = {
credential.helper = "!pass-git-helper $@";
};
user = {
name = "Aner Zakobar";
email = "aner@zakobar.com";
};
};
};
home.file.".config/pass-git-helper/git-pass-mapping.ini".source =
./pass-git-mapping.ini;
};
}
-29
View File
@@ -1,29 +0,0 @@
{
lib,
config,
pkgs,
...
}: let
isEnabled =
config.azos.gnuradio.enable;
in {
options.azos.gnuradio.enable = lib.mkOption {
default = true;
example = true;
type = lib.types.bool;
};
config = lib.mkIf isEnabled {
home.packages = with pkgs; [
gnuradio
uhd
gmp
boost
volk
libxcursor
cmake
pkg-config
spdlog
];
};
}
-1
View File
@@ -1 +0,0 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDBFZRqiTsOCAJPMqUyMeLd2MbyjdGoyqDVq5/Inhb6EOaM1NUGG4b6FPmYgFLyJIm5LC9BOo6M7npiaiOs/zMqp+hoGLNQUNwm5/G0uy1bjkEfKdUTdGnJ2+M9rkxrR1c+KXrjkiqECqTbnPE4mJbGyVxBW2MwMeP5w8c0DB5KO528PetvHMPPQuEdXyZzDI4kKtVpMlJoPIrIGlNFX0G/wrgXcM4zU1snOTuYGqZnWW++4kBsgIlRKpf/bLJyUMTp30eLVr0fQ6OMBtj1tzUUBaaowU6VGYQQDU/rIh/NpkA2cEVPXZegM4OohkAqrJBFPIAg90WD9Z/SyQlz0Jn8PpAloP0Cuq2vVRr+QLEwxqGiFq91YQ2VtwksMHwJGVrXRCNegpxTZQijWMEd+o0FD2cEd7Ftw6v2L6g12GJ3QGX/q0d/u0GongLLa9fPXl4VoAu7AL+cUcbX/SS7RCG8kYAR3DwOazVbK0NWEdwvWdoSU4lZ3j2at1xqMGjHjyLiTeUqZBjm+Sl5MJWIYNg+8hnONljvggg4SzDFDAkgVLZtOCaZibsMA1ucGR7VRCM09uoaEI4/ZS5pCBtYcp8X67Bv67Og8s2NFf5sUfYBPPKpdBSs+dEPycNVff6JlmzfNiyzLawacGKIDWYSgkOl43N/5ehtpsL3HMZ+5SVNIw== (none)
@@ -1,23 +0,0 @@
{
lib,
config,
pkgs,
...
}: let
isEnabled =
config.azos.headphones-whmx4000.enable;
in {
options.azos.headphones-whmx4000.enable = lib.mkOption {
default = true;
example = true;
type = lib.types.bool;
};
config = lib.mkIf isEnabled {
home.packages = with pkgs; [
(pkgs.writeShellScriptBin
"azos-connect-headphones-whmx4000"
"echo \"connect AC:80:0A:AF:E1:C2\" | bluetoothctl")
];
};
}
-20
View File
@@ -1,20 +0,0 @@
{
lib,
config,
pkgs,
...
}: let
isEnabled =
config.azos.hfsprogs.enable;
in {
options.azos.hfsprogs.enable = lib.mkOption {
default = true;
type = lib.types.bool;
};
config = lib.mkIf isEnabled {
home.packages = with pkgs; [
hfsprogs
];
};
}
-58
View File
@@ -1,58 +0,0 @@
{
lib,
config,
pkgs,
options,
azos-utils,
...
}: let
isEnabled =
config.azos.suites.hyprland.enable;
in {
options.azos.suites.hyprland.enable = lib.mkOption {
default = false;
example = true;
type = lib.types.bool;
};
#TODO shutdown reboot commands
config = lib.mkIf isEnabled {
home.packages = with pkgs; [
hyprland
waybar # status bar
wofi # application launcher
kitty
grim # screenshot utility
slurp # region selector
swappy # screenshot editor
networkmanagerapplet
xwayland
];
azos.emacs.enabledSuites = ["azos-emacs-hyprland"];
azos.emacs.pkgs = [pkgs.azos-emacs-hyprland];
azos.emacs.emacspkg = pkgs.emacs-pgtk;
home.file.".login.sh" = {
text = ''
#!/usr/bin/env bash
${pkgs.hyprland}/bin/Hyprland
'';
#Make executable
executable = true;
};
# systemd.user.services.xwayland = {
# Unit.Description = "XWayland server";
# Install.WantedBy = [ "default.target" ];
# Service = {
# ExecStart = "${pkgs.xwayland}/bin/Xwayland :0 -rootless -terminate -listen tcp";
# Restart = "on-failure";
# RestartSec = "1s";
# StandardInput = "null";
# StandardOutput = "null";
# StandardError = "journal";
# };
# };
};
}
-23
View File
@@ -1,23 +0,0 @@
{
lib,
config,
pkgs,
...
}: let
isEnabled =
config.azos.kubectl.enable;
in {
options.azos.kubectl.enable = lib.mkOption {
default = true;
example = true;
type = lib.types.bool;
};
config = lib.mkIf isEnabled {
home.packages = with pkgs; [
kubectl
kubernetes-helm
velero
];
};
}
-23
View File
@@ -1,23 +0,0 @@
{
lib,
config,
pkgs,
azos-utils,
...
}: let
isEnabled =
config.azos.emacs.enable && config.azos.suites.lauretta.enable;
emacspkgs = config.azos.emacs.emacspkg.pkgs;
localPkgName = "azos-emacs-lauretta";
in {
#Set config
options.azos.suites.lauretta.enable = azos-utils.mkSuiteEnableOption {};
config = lib.mkIf isEnabled {
azos.emacs.enabledSuites = [localPkgName];
#Base emacs suite definition
azos.emacs.pkgs = [pkgs.azos-emacs-lauretta];
home.packages = with pkgs; [pkgs.nix-search-cli];
};
}
-108
View File
@@ -1,108 +0,0 @@
#https://xeiaso.net/talks/asg-2023-nixos/ example
{
lib,
config,
pkgs,
...
}: let
isEnabled =
config.azos.mail.enable;
default_account_params = {
realName = "Aner Zakobar";
notmuch.enable = true;
mbsync = {
enable = true;
create = "maildir";
};
};
default_gmail_params =
default_account_params
// {
# lieer.enable = true;
# lieer.sync.enable = true;
flavor = "gmail.com";
# imap = {
# host = "mail.privateemail.com";
# };
};
default_smtp = {
tls = {
enable = true;
certificatesFile = "/etc/ssl/certs/ca-certificates.crt";
};
};
default_gmail_smtp =
default_smtp
// {
host = "smtp.gmail.com";
};
in {
options.azos.mail.enable = lib.mkOption {
default = true;
example = true;
type = lib.types.bool;
};
config = lib.mkIf isEnabled {
programs = {
notmuch = {
enable = true;
hooks = {
preNew = "mbsync -a";
};
};
mbsync = {
enable = true;
};
msmtp = {
enable = true;
};
lieer = {
enable = true;
};
};
services.lieer.enable = true;
accounts.email.accounts = {
gmail =
default_gmail_params
// {
address = "anerisgreat@gmail.com";
userName = "anerisgreat";
# smtp = default_gmail_smtp;
passwordCommand = "pass gmail.com/mbsync-anerisgreat";
};
bgu =
default_gmail_params
// {
address = "anerz@post.bgu.ac.il";
userName = "anerz@post.bgu.ac.il";
# smtp = default_gmail_smtp;
passwordCommand = "pass post.bgu.ac.il/mbsync-anerz";
};
zakobar =
default_account_params
// {
address = "aner@zakobar.com";
msmtp.enable = true;
primary = true;
userName = "aner@zakobar.com";
imap = {
host = "mail.privateemail.com";
};
# mbsync = {
# enable = true;
# create = "maildir";
# };
smtp =
default_smtp
// {
port = 587;
host = "mail.privateemail.com";
};
passwordCommand = "pass zakobar.com/mail/aner";
};
};
};
}
-20
View File
@@ -1,20 +0,0 @@
#https://xeiaso.net/talks/asg-2023-nixos/ example
{
lib,
config,
pkgs,
...
}: let
isEnabled =
config.azos.mpris-proxy.enable;
in {
options.azos.mpris-proxy.enable = lib.mkOption {
default = true;
example = true;
type = lib.types.bool;
};
config = lib.mkIf isEnabled {
services.mpris-proxy.enable = true;
};
}
-19
View File
@@ -1,19 +0,0 @@
{
lib,
config,
pkgs,
...
}: let
isEnabled =
config.azos.opencode.enable;
in {
options.azos.opencode.enable = lib.mkOption {
default = true;
example = true;
type = lib.types.bool;
};
config = lib.mkIf isEnabled {
programs.opencode.enable = true;
};
}
@@ -1,2 +0,0 @@
[*git.zakobar.com*]
target=zakobar.com/users/aner
-22
View File
@@ -1,22 +0,0 @@
{
lib,
config,
pkgs,
...
}: let
isEnabled =
config.azos.printing.enable;
in {
options.azos.printing.enable = lib.mkOption {
default = true;
example = true;
type = lib.types.bool;
};
config = lib.mkIf isEnabled {
services.printing.enable = true;
home.packages = with pkgs; [
hplip
];
};
}
@@ -1,19 +0,0 @@
{
lib,
config,
pkgs,
...
}: let
isEnabled =
config.azos.qutebrowser-config.enable;
in {
options.azos.qutebrowser-config.enable = lib.mkOption {
default = true;
example = true;
type = lib.types.bool;
};
config = lib.mkIf isEnabled {
home.file.".config/qutebrowser/config.py".source = ./qutebrowser-config.py;
};
}
-25
View File
@@ -1,25 +0,0 @@
{
lib,
config,
pkgs,
...
}: let
isEnabled =
config.azos.reaper.enable;
in {
options.azos.reaper.enable = lib.mkOption {
default = true;
example = true;
type = lib.types.bool;
};
config = lib.mkIf isEnabled {
home.packages = with pkgs; [
reaper
helm #TODO this synth had better work
# surge
lsp-plugins
vital
];
};
}
-63
View File
@@ -1,63 +0,0 @@
{
lib,
config,
pkgs,
...
}: let
isEnabled =
config.azos.snx-rs.enable;
cfg = config.azos.snx-rs;
in {
options.azos.snx-rs = {
enable = lib.mkOption {
default = true;
type = lib.types.bool;
};
server = lib.mkOption {
default = "vpn.bgu.ac.il";
type = lib.types.str;
description = "VPN server address";
};
username = lib.mkOption {
default = "anerz@vpn";
type = lib.types.str;
description = "VPN username";
};
loginType = lib.mkOption {
default = "vpn";
type = lib.types.str;
description = "Login type (e.g., vpn, vpn_Microsoft_Authenticator)";
};
ignoreServerCert = lib.mkOption {
default = true;
type = lib.types.bool;
description = "Ignore server certificate validation";
};
};
config = lib.mkIf isEnabled {
home.packages = with pkgs; [
snx-rs
(pkgs.writeShellScriptBin "snx-connect" ''
#!/bin/sh
sudo ${pkgs.snx-rs}/bin/snx-rs -m command &
sleep 1
${pkgs.snx-rs}/bin/snxctl connect
'')
(pkgs.writeShellScriptBin "snx-disconnect" ''
#!/bin/sh
${pkgs.snx-rs}/bin/snxctl disconnect
pkill -x snx-rs 2>/dev/null || true
'')
];
home.file.".config/snx-rs/snx-rs.conf" = {
text = ''
server ${cfg.server}
username ${cfg.username}
login-type ${cfg.loginType}
ignore-server-cert ${lib.boolToString cfg.ignoreServerCert}
'';
};
};
}
-1
View File
@@ -1 +0,0 @@
61D809B46CEE2A0AF799C4C2FADB0F61A19EEABD
-21
View File
@@ -1,21 +0,0 @@
{
lib,
config,
pkgs,
...
}: let
isEnabled =
config.azos.ytdl.enable;
in {
options.azos.ytdl.enable = lib.mkOption {
default = true;
example = true;
type = lib.types.bool;
};
config = lib.mkIf isEnabled {
home.packages = with pkgs; [
yt-dlp
];
};
}
-33
View File
@@ -1,33 +0,0 @@
{
lib,
config,
pkgs,
...
}: let
isEnabled =
config.azos.hardware-audio.enable;
in {
options.azos.hardware-audio.enable = lib.mkOption {
default = true;
example = true;
type = lib.types.bool;
};
config = lib.mkIf isEnabled {
services = {
pipewire = {
enable = true;
audio.enable = true;
pulse.enable = true;
alsa = {
enable = true;
support32Bit = true;
};
jack.enable = true;
};
};
# hardware.pulseaudio.enable = true;
environment.systemPackages = with pkgs; [pavucontrol];
musnix.enable = true;
};
}
-19
View File
@@ -1,19 +0,0 @@
{
lib,
config,
pkgs,
...
}: let
isEnabled =
config.azos.binfmt.enable;
in {
options.azos.binfmt.enable = lib.mkOption {
default = true;
example = true;
type = lib.types.bool;
};
config = lib.mkIf isEnabled {
boot.binfmt.emulatedSystems = ["aarch64-linux"];
};
}
-20
View File
@@ -1,20 +0,0 @@
{
lib,
config,
pkgs,
...
}: let
isEnabled =
config.azos.bluetooth.enable;
in {
options.azos.bluetooth.enable = lib.mkOption {
default = true;
example = true;
type = lib.types.bool;
};
config = lib.mkIf isEnabled {
services.blueman.enable = true;
hardware.bluetooth.enable = true;
};
}
-3
View File
@@ -1,3 +0,0 @@
{
imports = [./audio.nix ./binfmt.nix ./bluetooth.nix ./steam.nix ./virtualization.nix];
}
-19
View File
@@ -1,19 +0,0 @@
{
lib,
config,
pkgs,
...
}: let
isEnabled =
config.azos.steam.enable;
in {
options.azos.steam.enable = lib.mkOption {
default = true;
example = true;
type = lib.types.bool;
};
config = lib.mkIf isEnabled {
programs.steam.enable = true;
};
}
-40
View File
@@ -1,40 +0,0 @@
{
lib,
config,
pkgs,
...
}: let
isEnabled =
config.azos.virtualization.enable;
in {
options.azos.virtualization.enable = lib.mkOption {
default = true;
example = true;
type = lib.types.bool;
};
config = lib.mkIf isEnabled {
virtualisation.libvirtd = {
enable = true; # start / run libvirtd as a system service
# optional: expose the default NAT network (virbr0) – libvirtd creates it
# automatically when the daemon is on, but we make sure the bridge is
# allowed through the firewall.
qemu = {
swtpm.enable = true; # (optional) enable software TPM for guests
};
};
environment.systemPackages = with pkgs; [
# QEMU (KVM‑accelerated)
qemu_kvm # same as pkgs.qemu (but with KVM support explicitly enabled)
# CLI utilities
libvirt # provides virsh, virt-install, virt-manager (cli bits)
# GUI front‑end
virt-manager # graphical manager (uses libvirt + spice)
virt-viewer # Spice/VNC client that virt‑manager calls under the hood
];
services.spice-vdagentd.enable = true; # makes copy‑paste & auto‑resize work in Spice windows
networking.firewall.allowedTCPPorts = [5900 5901]; # Spice ports (adjust if you expose elsewhere)
networking.firewall.allowedUDPPorts = [5900 5901];
};
}
+78
View File
@@ -0,0 +1,78 @@
{
lib,
config,
pkgs,
inputs,
suiteModules,
...
}: {
imports = [
inputs.nixos-wsl.nixosModules.default
suiteModules.nixos.attic
];
wsl.enable = true;
wsl.defaultUser = "aner";
nixpkgs.hostPlatform = "x86_64-linux";
nixpkgs.config.allowUnfree = true;
nix.settings = {
experimental-features = ["nix-command" "flakes"];
auto-optimise-store = true;
substituters = [
"https://cache.nixos.org"
"https://cuda-maintainers.cachix.org"
];
trusted-public-keys = [
"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
"cuda-maintainers.cachix.org-1:0dq3bujKpuEPMCX6U4WylrUDZ9JyUG0VpVZa7CNfq5E="
];
};
security.sudo.wheelNeedsPassword = false;
networking.hostName = "beacon";
networking.firewall.allowedTCPPorts = [ 22 ];
programs.nix-ld.enable = true;
time.timeZone = "Asia/Jerusalem";
# GPU is exposed through WSL2 paravirtualization; no Linux NVIDIA KM needed
hardware.graphics.enable = true;
services.openssh = {
enable = true;
settings = {
PermitRootLogin = "no";
PasswordAuthentication = false;
};
};
users.users.aner = {
isNormalUser = true;
extraGroups = ["wheel" "video"];
openssh.authorizedKeys.keys = [
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDMdozJewuuqG4VuwGhI5Uw2xDIUrkQwyPGQ2q3tvnPq/VoV+zfdnou42I6XYEfOGd6xfLR0byOGCk1Ia1F/picBsxADEaJFBnTny5MWNA5MxwJIYUPW5+kFN1TmxdNGmj0WJ8qZeKkS3ffixdHlHTVu4Rzrlu8qDdw8TmgcvD7sHpNaBB+hwG9B/s5BAozfXvyXtW51lLLrEZdmUXJxAP51ubVgysZ985PA89o4G7LUE20IKAj3rgylLwq+Lz2PoGmVCptPTknLLzGlxTy2mU/tESJtS4iUvshSYiKak73BSen88xLWL/eZGFzOLW4TNem/qT0ykqK1s1BaGWCcQiDWN+Lpa3XqTbFN054MfhLdEMp+NjrdsCbZORzp9p2ZPDqi5jI1Hy7IN/8VzzB+T13MX6YhW7CBBqUZaivGhVQGsNjrFusPGhCaZrzNJ1l4qssLAlOh9qdaYzqDe+BIHsty55vw4Ph+Axou82babpLoiQzkCol2TWjPr7JSfHFkm6CmoTQ7mK8m7jRCodmxF+BEe4Usr+HrTKDc9fr5P4mdfL0O+ZPrlkPuG1zBTMal9MPxeCk4emzOZf7vBMNzb0aKHbOtSdVk/IcjatlDd2EIo34e5A6anLRMAdxb7901mnCAcjvCn6+ArNV8nr+NBk1+UvumZ+Q59LTrAkgRt3rBw== cardno:29_109_265"
];
};
environment.systemPackages = with pkgs; [
git
rsync
tmux
vim
wget
rclone
pciutils
nvtopPackages.nvidia
cudaPackages.cudatoolkit
cudaPackages.cudnn
cudaPackages.nccl
python3
direnv
];
azos.attic.enable = true;
system.stateVersion = "25.11";
}
+146
View File
@@ -0,0 +1,146 @@
{
lib,
config,
pkgs,
modulesPath,
suiteModules,
...
}: {
imports = [
"${modulesPath}/virtualisation/disk-image.nix"
suiteModules.nixos.attic
];
image.format = "raw";
boot.initrd.availableKernelModules = [
"xhci_pci"
"usb_storage"
"uas"
"ahci"
"nvme"
"usbhid"
"sd_mod"
];
nixpkgs.hostPlatform = "x86_64-linux";
nixpkgs.config.allowUnfree = true;
nixpkgs.config.cudaSupport = true;
nix.settings = {
experimental-features = ["nix-command" "flakes"];
auto-optimise-store = true;
substituters = [
"https://cache.nixos.org"
"https://cuda-maintainers.cachix.org"
];
trusted-public-keys = [
"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
"cuda-maintainers.cachix.org-1:0dq3bujKpuEPMCX6U4WylrUDZ9JyUG0VpVZa7CNfq5E="
];
};
security.sudo.wheelNeedsPassword = false;
networking.hostName = "beacon";
time.timeZone = "Asia/Jerusalem";
networking.networkmanager.enable = true;
hardware.enableRedistributableFirmware = true;
networking.useDHCP = false;
environment.etc."NetworkManager/system-connections/Zakobar.nmconnection" = {
mode = "0600";
text = ''
[connection]
id=Zakobar
type=wifi
autoconnect=true
[wifi]
mode=infrastructure
ssid=Zakobar
[wifi-security]
auth-alg=open
key-mgmt=wpa-psk
psk=0502711157
[ipv4]
method=manual
address1=192.168.1.200/24,192.168.1.1
dns=8.8.8.8;1.1.1.1;
ignore-auto-dns=true
[ipv6]
method=disabled
'';
};
# Swap is created on first boot after boot.growPartition expands the root
# partition to the full drive size. Non-blocking: a failure just means no
# swap on this boot (retried next boot once the partition has grown).
systemd.services.beacon-swap = {
description = "Create and activate swapfile";
after = ["systemd-growfs@-.service" "local-fs.target"];
wantedBy = ["multi-user.target"];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
if [ ! -f /swapfile ]; then
dd if=/dev/zero of=/swapfile bs=1M count=16384 status=progress
chmod 600 /swapfile
${pkgs.util-linux}/bin/mkswap /swapfile
fi
${pkgs.util-linux}/bin/swapon /swapfile
'';
};
# NVIDIA RTX 4050 — Ada Lovelace supports open kernel modules
services.xserver.videoDrivers = ["nvidia"];
hardware.nvidia = {
open = true;
modesetting.enable = true;
package = config.boot.kernelPackages.nvidiaPackages.stable;
};
hardware.graphics.enable = true;
services.getty.autologinUser = "aner";
services.openssh = {
enable = true;
settings = {
PermitRootLogin = "no";
PasswordAuthentication = false;
};
};
users.users.aner = {
isNormalUser = true;
extraGroups = ["wheel" "video"];
openssh.authorizedKeys.keys = [
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDfzDDO5juINctECmWlsYtGghEiX/RnTJ1cazLvOWSrPfsTyEd+B1+Ig8kFefNryjkpApfRXqj5KtLPNlpLfdVBrOIfhIveEp2MGqhgOGZFNVxQyXnZgii8Zdh4cqZ2O3pZpMsaAQBaJ9nH6dK0dJjicWT5f6TqwrVcInywRc5SuyizoSxoFmg7ch2rnlVi0j5XMVqdh8XLzHXZ7yWCzXy7+hWl/d7pwpyuzoK8dBw2EU9TauhgRDruom5Q9vWJTLStALC9pAIb0v9UFj9y+1zwx7pXsXp5F1g73EYrE4QR+QQ6z2LebuK280W0t+VA/fSCEB13DnkmofgqZQxX5MSCmrxZ5lTFp1FjW6yJo7As9FheF/GECowYkMRIx4IiQsjjHjZqlLRpLas11yAp6tGoZnw59hFo6Lu0Kva39jGVVmioYHtAeE5rD5w+v5kseJR4jlQ8aKB5yOjYUQOIz2AHQyoidgaeR2jPWqZUeRQbACI+/p3CHO45r3hrjATtGloBg0xF95Qws7Be3mjHVhbBLOoob8MdZ8nYAGnhlWrZphlkvXsHC6OUkuDJW00tmMjWXRlFwhFJ+nqUQCgLVjxVHQJ5rq9GeXBUuNXAeCm5BKBsdq+9qqVlt7D9iGyfr0lcZ7peKz/96KwPCWpG2En1Ur0/cVcbWnXEfG/xWO10tQ== openpgp:0xFA67FAB0"
];
};
environment.systemPackages = with pkgs; [
git
rsync
tmux
vim
wget
rclone
pciutils
nvtopPackages.nvidia
cudaPackages.cudatoolkit
cudaPackages.cudnn
cudaPackages.nccl
python3
direnv
];
azos.attic.enable = true;
system.stateVersion = "25.11";
}
+6 -31
View File
@@ -1,53 +1,42 @@
# This is your system's configuration file.
# Use this to configure your system environment (it replaces /etc/nixos/configuration.nix)
{ {
inputs, inputs,
outputs, outputs,
suiteModules,
lib, lib,
config, config,
pkgs, pkgs,
... ...
}: { }: {
# You can import other NixOS modules here
virtualisation.vmVariant = { virtualisation.vmVariant = {
virtualisation.resolution = { virtualisation.resolution = {
x = 1280; x = 1280;
y = 1024; y = 1024;
}; };
virtualisation.qemu.options = [ virtualisation.qemu.options = [
# Better display option
"-vga virtio" "-vga virtio"
"-display gtk,zoom-to-fit=false" "-display gtk,zoom-to-fit=false"
# Enable copy/paste
# https://www.kraxel.org/blog/2021/05/qemu-cut-paste/
"-chardev qemu-vdagent,id=ch1,name=vdagent,clipboard=on" "-chardev qemu-vdagent,id=ch1,name=vdagent,clipboard=on"
"-device virtio-serial-pci" "-device virtio-serial-pci"
"-device virtserialport,chardev=ch1,id=ch1,name=com.redhat.spice.0" "-device virtserialport,chardev=ch1,id=ch1,name=com.redhat.spice.0"
]; ];
}; };
imports = [ imports = [
inputs.home-manager.nixosModules.home-manager inputs.home-manager.nixosModules.home-manager
outputs.nixosModules
]; ];
nixpkgs.hostPlatform = "x86_64-linux"; nixpkgs.hostPlatform = "x86_64-linux";
nixpkgs = { nixpkgs = {
overlays = [ overlays = [
inputs.azos-core.overlays.addpkgs outputs.overlays.addpkgs
# outputs.overlays.additions
# outputs.overlays.modifications
# outputs.overlays.unstable-packages
]; ];
# Configure your nixpkgs instance
config = { config = {
allowUnfree = true; allowUnfree = true;
}; };
}; };
nix.registry = (lib.mapAttrs (_: flake: {inherit flake;})) ((lib.filterAttrs (_: lib.isType "flake")) inputs); nix.registry = (lib.mapAttrs (_: flake: {inherit flake;})) ((lib.filterAttrs (_: lib.isType "flake")) inputs);
nix.nixPath = ["/etc/nix/path"]; nix.nixPath = ["/etc/nix/path"];
environment.etc = environment.etc =
lib.mapAttrs' lib.mapAttrs'
@@ -58,22 +47,18 @@
config.nix.registry; config.nix.registry;
nix.settings = { nix.settings = {
experimental-features = "nix-command flakes"; experimental-features = ["nix-command" "flakes"];
# Deduplicate and optimize nix store
auto-optimise-store = true; auto-optimise-store = true;
}; };
# TODO: Set your hostname
networking.hostName = "test-vm"; networking.hostName = "test-vm";
# TODO: This is just an example, be sure to use whatever bootloader you prefer
boot.loader.systemd-boot.enable = true; boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true; boot.loader.efi.canTouchEfiVariables = true;
home-manager = { home-manager = {
extraSpecialArgs = {inherit inputs outputs;}; extraSpecialArgs = {inherit inputs outputs suiteModules pkgs;};
users = { users = {
# Import your home-manager configuration
aner = import ../home-manager/home.nix; aner = import ../home-manager/home.nix;
}; };
}; };
@@ -82,28 +67,18 @@
aner = { aner = {
initialPassword = "password"; initialPassword = "password";
isNormalUser = true; isNormalUser = true;
openssh.authorizedKeys.keys = [ openssh.authorizedKeys.keys = [];
# TODO: Add your SSH public key(s) here, if you plan on using SSH to connect
];
# TODO: Be sure to add any other groups you need (such as networkmanager, audio, docker, etc)
extraGroups = ["wheel" "libvirtd"]; extraGroups = ["wheel" "libvirtd"];
}; };
}; };
# This setups a SSH server. Very important if you're setting up a headless system.
# Feel free to remove if you don't need it.
services.openssh = { services.openssh = {
enable = true; enable = true;
settings = { settings = {
# Forbid root login through SSH.
PermitRootLogin = "no"; PermitRootLogin = "no";
# Use keys only. Remove if you want to SSH using password (not recommended)
PasswordAuthentication = true; PasswordAuthentication = true;
}; };
}; };
#Graphical environment
# services.xserver.desktopManager.xfce.enable = true;
# https://nixos.wiki/wiki/FAQ/When_do_I_update_stateVersion
system.stateVersion = "24.05"; system.stateVersion = "24.05";
} }
+58 -28
View File
@@ -1,6 +1,7 @@
{ {
inputs, inputs,
outputs, outputs,
suiteModules,
lib, lib,
config, config,
pkgs, pkgs,
@@ -11,19 +12,29 @@
inputs.nixos-hardware.nixosModules.lenovo-thinkpad-t480 inputs.nixos-hardware.nixosModules.lenovo-thinkpad-t480
inputs.musnix.nixosModules.musnix inputs.musnix.nixosModules.musnix
inputs.home-manager.nixosModules.home-manager inputs.home-manager.nixosModules.home-manager
outputs.nixosModules suiteModules.nixos.base
outputs.azos-core.nixosModules suiteModules.nixos.exwm
suiteModules.nixos.audio
suiteModules.nixos.bluetooth
suiteModules.nixos.steam
suiteModules.nixos.virtualization
suiteModules.nixos.binfmt
suiteModules.nixos.attic
suiteModules.nixos.printing
]; ];
# Bootloader. boot.loader.grub = {
boot.loader.systemd-boot.enable = true; enable = true;
efiSupport = true;
device = "nodev";
configurationLimit = 5;
};
boot.loader.efi.canTouchEfiVariables = true; boot.loader.efi.canTouchEfiVariables = true;
nixpkgs = { nixpkgs = {
overlays = [ overlays = [
inputs.azos-core.overlays.addpkgs
outputs.overlays.addpkgs outputs.overlays.addpkgs
inputs.azos-core.overlays.qutebrowserdrm outputs.overlays.qutebrowserdrm
outputs.overlays.modifications outputs.overlays.modifications
outputs.overlays.unstable-packages outputs.overlays.unstable-packages
]; ];
@@ -33,20 +44,14 @@
}; };
nix.registry = (lib.mapAttrs (_: flake: {inherit flake;})) ((lib.filterAttrs (_: lib.isType "flake")) inputs); nix.registry = (lib.mapAttrs (_: flake: {inherit flake;})) ((lib.filterAttrs (_: lib.isType "flake")) inputs);
nix.nixPath = ["/etc/nix/path"]; nix.nixPath = ["/etc/nix/path"];
networking.hostName = "lauretta"; # Define your hostname. networking.hostName = "lauretta";
# Enable networking
networking.networkmanager.enable = true; networking.networkmanager.enable = true;
# Set your time zone.
time.timeZone = "Asia/Jerusalem"; time.timeZone = "Asia/Jerusalem";
# Select internationalisation properties.
i18n.defaultLocale = "en_IL"; i18n.defaultLocale = "en_IL";
i18n.extraLocaleSettings = { i18n.extraLocaleSettings = {
LC_ADDRESS = "he_IL.UTF-8"; LC_ADDRESS = "he_IL.UTF-8";
LC_IDENTIFICATION = "he_IL.UTF-8"; LC_IDENTIFICATION = "he_IL.UTF-8";
@@ -59,7 +64,6 @@
LC_TIME = "he_IL.UTF-8"; LC_TIME = "he_IL.UTF-8";
}; };
# Configure keymap in X11
services.xserver = { services.xserver = {
xkb = { xkb = {
layout = "us,il"; layout = "us,il";
@@ -68,51 +72,77 @@
xkb.options = "grp:alt_shift_toggle"; xkb.options = "grp:alt_shift_toggle";
}; };
# Configure console keymap
console.keyMap = "il"; console.keyMap = "il";
# Define a user account. Don't forget to set a password with ‘passwd’.
users.users.aner = { users.users.aner = {
isNormalUser = true; isNormalUser = true;
description = "Aner Zakobar"; description = "Aner Zakobar";
#Audio group for audio config, video group necessary for backlight. extraGroups = ["networkmanager" "wheel" "audio" "video" "seat" "input"];
extraGroups = ["networkmanager" "wheel" "audio" "video"];
packages = with pkgs; []; packages = with pkgs; [];
}; };
nix.settings = { nix.settings = {
experimental-features = "nix-command flakes"; experimental-features = ["nix-command" "flakes"];
auto-optimise-store = true; auto-optimise-store = true;
substituters = [
"https://cache.nixos.org"
];
trusted-public-keys = [
"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
];
}; };
azos.suites.exwm.enable = true;
azos.attic.enable = true;
azos.printing.enable = true;
home-manager = { home-manager = {
extraSpecialArgs = {inherit inputs outputs pkgs;}; extraSpecialArgs = {inherit inputs outputs suiteModules pkgs;};
users = { users = {
aner = import ../home-manager/home.nix; aner = import ../home-manager/home.nix;
}; };
}; };
# Specializations
specialisation = { specialisation = {
hyprland = { steam-big-picture = {
configuration = { configuration = {
# Override home‑manager options for this specialization environment.systemPackages = [pkgs.sway];
home-manager.users.aner = {pkgs, ...}: { environment.etc."sway-steam.conf".text = ''
output * bg #000000 solid_color
default_border none
default_floating_border none
exec ${pkgs.dbus}/bin/dbus-run-session -- ${pkgs.bash}/bin/bash -c "steam -tenfoot; ${pkgs.sway}/bin/swaymsg exit"
'';
services.seatd.enable = true;
services.greetd.settings = lib.mkForce {
terminal.vt = 1;
default_session = {
command = "${pkgs.tuigreet}/bin/tuigreet --time --user-menu --user-menu-min-uid 1000 --user-menu-max-uid 29999 --cmd '/home/aner/.login.sh'";
user = "greeter";
};
initial_session = {
command = "${pkgs.sway}/bin/sway --config /etc/sway-steam.conf";
user = "aner";
};
};
home-manager.users.aner = {lib, ...}: {
azos.suites.exwm.enable = lib.mkForce false; azos.suites.exwm.enable = lib.mkForce false;
azos.suites.hyprland.enable = true;
}; };
}; };
}; };
}; };
# List packages installed in system profile. To search, run: boot.supportedFilesystems = ["exfat"];
# $ nix search wget boot.kernelModules = ["exfat"];
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
vim vim
git git
tmux tmux
killall killall
brightnessctl brightnessctl
exfatprogs
gamescope
]; ];
fonts.enableDefaultPackages = true; fonts.enableDefaultPackages = true;
@@ -124,5 +154,5 @@
systemd.targets.hibernate.enable = false; systemd.targets.hibernate.enable = false;
systemd.targets.hybrid-sleep.enable = false; systemd.targets.hybrid-sleep.enable = false;
system.stateVersion = "25.11"; # Did you read the comment? system.stateVersion = "25.11";
} }
+4 -15
View File
@@ -1,22 +1,11 @@
# This file defines overlays
{inputs, ...}: { {inputs, ...}: {
addpkgs = final: _prev: (import ../pkgs {pkgs = final.pkgs;}); config.flake.overlays.modifications = _final: prev: {
helm = prev.helm.overrideAttrs (oldAttrs: {
#Current overlay is for helm, to disable binary, so no conflict patches = oldAttrs.patches or [] ++ [./helm.patch];
modifications = final: prev: {
helm = prev.helm.overrideAttrs (oldAttrs: rec {
patches =
oldAttrs.patches
or []
++ [
./helm.patch
];
}); });
}; };
# When applied, the unstable nixpkgs set (declared in the flake inputs) will config.flake.overlays.unstable-packages = final: _prev: {
# be accessible through 'pkgs.unstable'
unstable-packages = final: _prev: {
unstable = import inputs.nixpkgs-unstable { unstable = import inputs.nixpkgs-unstable {
system = final.system; system = final.system;
config.allowUnfree = true; config.allowUnfree = true;
-7
View File
@@ -1,7 +0,0 @@
{pkgs} @ args: let
inherit args;
localEmacsPkg = pkgs.localEmacsPkg;
in {
azos-emacs-lauretta = localEmacsPkg ./azos-emacs-lauretta.nix;
azos-emacs-hyprland = localEmacsPkg ./azos-emacs-hyprland.nix;
}
-135
View File
@@ -1,135 +0,0 @@
#+title: Aner's Emacs Lauretta Configuration
#+property: header-args :results silent
* Base setup
** Require
#+begin_src emacs-lisp
(require 'azos-emacs-base)
(require 'azos-emacs-dev)
(require 'azos-emacs-editor)
(require 'azos-emacs-exwm)
(require 'azos-emacs-station)
#+end_src
* Lauretta specific
** LLM
#+begin_src emacs-lisp
(setq
gptel-model 'openai/gpt-oss-120b
gptel-backend
(gptel-make-openai "Groq"
:host "api.groq.com"
:endpoint "/openai/v1/chat/completions"
:stream t
:key "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"
:models '(openai/gpt-oss-120b)))
#+end_src
** Agent Shell
#+begin_src emacs-lisp
(setq agent-shell-opencode-default-model-id "opencode/big-pickle")
;; (setq agent-shell-preferred-agent-config (agent-shell-opencode-make-agent-config))
#+end_src
** Headphones
#+begin_src emacs-lisp
(defun azos/connect-headphones ()
(interactive)
(start-process-shell-command "connect-headphones" nil "azos-connect-headphones-whmx4000"))
(define-key azos/global-minor-mode/open-keymap
(kbd "h") 'azos/connect-headphones)
#+end_src
** Tab bar setup
#+begin_src emacs-lisp
(when (fboundp #'azos/bat/enable-tab-display)
(azos/bat/enable-tab-display))
(when (fboundp #'azos/network/enable-tab-display)
(azos/network/enable-tab-display))
(when (fboundp #'azos/audio/enable-tab-display)
(azos/audio/enable-tab-display))
#+end_src
** Nixpkgs Search
#+begin_src emacs-lisp
(defun azos/nixpkgs-parse-json-lines (str)
"Parse JSON Lines format (one JSON object per line) from STR."
(mapcar (lambda (line)
(and (not (string-empty-p line))
(string-match "^{" line)
(condition-case nil
(json-parse-string line)
(error nil))))
(split-string (string-trim str) "\n" t)))
(defun azos/nixpkgs-g (key hash)
"Get KEY from HASH table."
(when (hash-table-p hash)
(gethash key hash)))
(defun azos/nixpkgs-search ()
"Search for a nixpkgs package and show its info."
(interactive)
(let* ((pattern (read-string "Search pattern: "))
(json-output (shell-command-to-string
(format "nix-search --json --max-results 50 '%s'" pattern)))
(results (and json-output
(not (string-empty-p json-output))
(azos/nixpkgs-parse-json-lines json-output)))
(packages (delq nil (mapcar (lambda (item)
(let ((pname (azos/nixpkgs-g "package_pname" item)))
(when pname
(cons pname item))))
results))))
(if packages
(let* ((selected (completing-read "Package: " (mapcar #'car packages) nil t))
(package-data (cdr (assoc-string selected packages))))
(let ((buf (get-buffer-create "*nixpkgs-package-info*")))
(with-current-buffer buf
(erase-buffer)
(if package-data
(progn
(insert (format "Package: %s\n\n" selected))
(insert (format "Version: %s\n" (or (azos/nixpkgs-g "package_pversion" package-data) "unknown")))
(insert (format "Attr: %s\n" (or (azos/nixpkgs-g "package_attr_name" package-data) "unknown")))
(insert (format "\nDescription: %s\n"
(or (azos/nixpkgs-g "package_description" package-data) "none")))
(let ((programs (azos/nixpkgs-g "package_programs" package-data)))
(when (vectorp programs)
(insert (format "\nPrograms: %s\n"
(mapconcat #'identity (append programs nil) " ")))))
(let ((homepage (let ((h (azos/nixpkgs-g "package_homepage" package-data)))
(when (vectorp h) (aref h 0)))))
(when homepage
(insert (format "\nHomepage: %s\n" homepage))))
(let ((licenses (azos/nixpkgs-g "package_license" package-data)))
(when (vectorp licenses)
(insert (format "\nLicense: %s\n"
(mapconcat (lambda (l)
(or (azos/nixpkgs-g "fullName" l) ""))
(append licenses nil) ", ")))))
(insert (format "Package: %s\n\n" selected)
"\nNo additional info available.")))
(goto-char (point-min)))
(display-buffer buf)))
(message "No packages found matching '%s'" pattern))))
(define-key azos/global-minor-mode/open-keymap
(kbd "n") 'azos/nixpkgs-search)
#+end_src
* Provide
#+begin_src emacs-lisp
(provide 'azos-emacs-lauretta)
#+end_src
-2
View File
@@ -1,5 +1,3 @@
{pkgs} @ args: { {pkgs} @ args: {
#TODO since I do not pass along packages, this cannot work
# debugTex = import ./debugTex args;
default = import ./defaultShell.nix args; default = import ./defaultShell.nix args;
} }
+10 -3
View File
@@ -2,14 +2,21 @@
pkgs.mkShell { pkgs.mkShell {
buildInputs = with pkgs; [ buildInputs = with pkgs; [
alejandra alejandra
nh
(pkgs.writeShellScriptBin (pkgs.writeShellScriptBin
"azos-lauretta-update" "azos-lauretta-update"
"sudo nixos-rebuild switch --flake .#lauretta") "nh os switch '.?submodules=1#lauretta'")
(pkgs.writeShellScriptBin (pkgs.writeShellScriptBin
"azos-update-azos-core" "azos-update-azos-core"
"nix flake update azos-core") "nix flake update --flake '.?submodules=1' azos-core")
(pkgs.writeShellScriptBin (pkgs.writeShellScriptBin
"azos-update" "azos-update"
"nix flake update") "nix flake update --flake '.?submodules=1'")
(pkgs.writeShellScriptBin
"azos-beacon-build-image"
"nix build '.?submodules=1#packages.x86_64-linux.beacon-image'")
(pkgs.writeShellScriptBin
"azos-beacon-remote-update"
"nixos-rebuild switch --flake '.?submodules=1#beacon' --target-host aner@192.168.1.200 --build-host aner@192.168.1.200 --sudo")
]; ];
} }