Compare commits

..

13 Commits

Author SHA1 Message Date
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
13 changed files with 343 additions and 79 deletions
+118 -54
View File
@@ -22,7 +22,7 @@ nix build .#formatter.x86_64-linux
### Deploying
```bash
# 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 --flake '.?submodules=1' # Update all inputs
nix flake lock --flake '.?submodules=1' --update-input X # Update specific input
```
@@ -70,76 +70,111 @@ emacsclient -c -e '(switch-to-buffer (get-buffer-create "test"))'
emacsclient -e '(message "hello")'
```
## Code Style Guidelines
## Repository Structure
### File Organization
- **Home-manager modules**: `modules/home-manager/<name>.nix`
- **NixOS modules**: `modules/nixos/<name>.nix`
- **Imports**: All modules in `modules/home-manager/default.nix` and `modules/nixos/default.nix` (alphabetical order)
- **Home config**: `home-manager/home.nix` - main home-manager user config
- **Custom packages**: `pkgs/` - custom package definitions
- **Overlays**: `overlays/` - package overlays (addpkgs, modifications, unstable-packages)
```
azos/
├── flake.nix # Main flake
├── home-manager/home.nix # Home-manager entry point; manually imports all modules
├── _machines/ # Per-machine NixOS configs (pass suiteModules as specialArgs)
├── nixos/ # NixOS system configs (configuration.nix, configuration-vm.nix, etc.)
├── 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
All features follow this flake-parts registration pattern:
```nix
{
{...}: {
config.flake.modules.homeManager.<name> = {
lib,
config,
pkgs,
...
}: let
isEnabled =
config.azos.<module-name>.enable;
in {
options.azos.<module-name>.enable = lib.mkOption {
default = true;
}: {
options.azos.<name>.enable = lib.mkOption {
default = false;
example = true;
type = lib.types.bool;
};
config = lib.mkIf isEnabled {
home.packages = with pkgs; [ pkg1 pkg2 ];
config = lib.mkIf config.azos.<name>.enable {
home.packages = with pkgs; [pkg1 pkg2];
};
};
}
```
### Naming Conventions
- Option paths: `config.azos.<module-name>.<option>`
- Enable option: `enable` (bool), default `true`
- Module names: kebab-case (`libreoffice.nix`, `git-config.nix`)
- Option names: may differ from filename (e.g., `git.nix` uses `azos.git-config`)
- Variables: kebab-case (`isEnabled`)
- Option paths: `azos.<module-name>.<option>`
- Module names: kebab-case (`git-config`, `claude-memory`)
- Feature directories: kebab-case, one `default.nix` per feature
- Variables: kebab-case
### Formatting
- Indentation: 2 spaces
- Let bindings: multi-line with `isEnabled` on its own line
- Packages: Use `with pkgs; [ ... ]` syntax
- Packages: `with pkgs; [pkg1 pkg2]` (no trailing semicolon inside list)
### Imports
- Always include `{...}` for module args
- Standard args: `lib, config, pkgs, ...`
- NixOS config args: `inputs, outputs, lib, config, pkgs, ...`
- Use `./relative/path.nix` for local imports
- Always include `{...}` for the outer module args
- Inner module args: `lib, config, pkgs, ...`
### Option Patterns
- Boolean enable: `lib.mkOption { default = true; example = true; type = lib.types.bool; }`
- Conditional config: `lib.mkIf isEnabled { ... }`
- User-overridable: `lib.mkDefault`
- Boolean enable: `lib.mkOption { default = false; example = true; type = lib.types.bool; }`
- Conditional config: `lib.mkIf config.azos.<name>.enable { ... }`
- Auto-enable a dependency: `azos.<dep>.enable = lib.mkDefault true;`
- 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: `home.packages`, `home.file`, `programs.<program>`
- 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
Modules are organized into suites (defined in `azos-core/`):
- `azos.suites.base` - Base packages and config
- `azos.suites.editor` - Editor tools
- `azos.suites.dev` - Development tools
- `azos.suites.station` - Desktop applications
- `azos.suites.exwm` - EXWM window manager
- Enable in `home-manager/home.nix` with `azos.suites.<name>.enable = true;`
Top-level suites group related features (defined in `azos-core/`):
- `azos.suites.base` — base packages and config
- `azos.suites.editor` — editor tools
- `azos.suites.dev` — development tools
- `azos.suites.station` — desktop applications
- `azos.suites.exwm` EXWM window manager
The machine suite (`azos.suites.lauretta`) enables the relevant suites for this machine.
### Specializations
NixOS supports specializations for alternative configurations:
@@ -158,33 +193,62 @@ specialisation = {
## Adding New Modules
1. Create file in `modules/home-manager/` or `modules/nixos/`
2. Add import to `modules/<type>/default.nix` (alphabetical)
3. Use module template above
1. Create `features/<name>/default.nix` (machine-specific) or `azos-core/features/<name>/default.nix` (shared)
2. Use the module template above
3. Add `suiteModules.homeManager.<name>` to the imports list in `home-manager/home.nix`
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
| File | Purpose |
|------|---------|
| `flake.nix` | Main flake, defines systems, overlays |
| `modules/home-manager/default.nix` | Home-manager imports |
| `modules/nixos/default.nix` | NixOS imports |
| `home-manager/home.nix` | User home-manager config, enables suites |
| `nixos/configuration.nix` | Lauretta laptop config |
| `flake.nix` | Main flake, defines systems and overlays |
| `home-manager/home.nix` | Home-manager entry point, imports all modules |
| `_machines/lauretta.nix` | Lauretta machine config, passes `suiteModules` as specialArgs |
| `nixos/configuration.nix` | Lauretta NixOS system config |
| `nixos/configuration-vm.nix` | Test VM config |
| `overlays/` | Custom package overlays |
| `pkgs/` | Custom packages |
| `azos-core/` | Shared modules (submodule) |
| `overlays/` | Package overlays |
| `azos-core/` | Shared feature library (git 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
**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)
Symlink
+1
View File
@@ -0,0 +1 @@
AGENTS.md
+33
View File
@@ -0,0 +1,33 @@
{...}: {
config.flake.overlayPkgs.emacs-lichess = pkgs: let
epkgs = pkgs.emacs.pkgs;
in
epkgs.trivialBuild {
pname = "lichess";
version = "0.8";
src = pkgs.fetchFromGitHub {
owner = "tmythicator";
repo = "lichess.el";
rev = "1dd8a25ede7144c5d6be1f45f4ae3d07903783cd";
sha256 = "157l4crbz37x367m69sxwvnd1pd8cqa6w0lcvyyvs27cm021d2gr";
};
};
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.emacs-lichess];
azos.emacs.enabledSuites = ["lichess"];
};
};
}
+2
View File
@@ -11,6 +11,8 @@
};
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;
};
};
}
+1 -1
View File
@@ -15,7 +15,7 @@
enable = true;
signing = {
key = "6D17E295C70E2674";
signByDefault = true;
signByDefault = false;
};
settings = {
credential.helper = "!pass-git-helper $@";
+54 -2
View File
@@ -14,6 +14,12 @@
* Lauretta specific
** Weather
#+begin_src emacs-lisp
(setq wttrin-default-cities '("Meitar, Israel"))
#+end_src
** LLM
#+begin_src emacs-lisp
@@ -31,8 +37,7 @@
** 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))
(setq agent-shell-preferred-agent-config 'claude-code)
#+end_src
** Headphones
@@ -317,6 +322,53 @@ With prefix ARG, prompt for a pattern then select from matches."
(define-key azos/beacon/keymap (kbd "t") #'azos/beacon/tail-log)
#+end_src
** Roam Backup
#+begin_src emacs-lisp
(defun azos/roam/backup ()
"Commit and push ~/roam to the remote git repo."
(interactive)
(async-shell-command "roam-backup" "*roam-backup*"))
(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
+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"];
};
};
}
+2
View File
@@ -58,3 +58,5 @@ c.fonts.hints = "bold 13px 'LiberationMono'"
#Set highdpi
c.qt.highdpi = True
c.zoom.default = 70
c.qt.args = ['renderer-process-limit=6']
+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
'')
];
};
};
}
Generated
+29 -13
View File
@@ -139,11 +139,11 @@
]
},
"locked": {
"lastModified": 1779969295,
"narHash": "sha256-HwIJ3tOcwSMiV75L7KqJXciXR9UfT+d7rwOZMX7cTnA=",
"lastModified": 1781642113,
"narHash": "sha256-mAR7KTS9rjreTcXCNqfCbN96mnhJO8lDQq1vl7GviBQ=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "61e2c9659324181e0f0ed911958c536333b1d4f6",
"rev": "df4e0465717a2d34f05b8ccd967275aaf3ceaa01",
"type": "github"
},
"original": {
@@ -202,12 +202,15 @@
}
},
"nixos-hardware": {
"inputs": {
"nixpkgs": "nixpkgs_4"
},
"locked": {
"lastModified": 1779826373,
"narHash": "sha256-3sRzgLX86qV5NlhWUAufLmHwkyP03tmL3VdZIM13dEo=",
"lastModified": 1781622756,
"narHash": "sha256-JrPh4M6S7aPsEE9tOENuZrxC6o2szSLlK+t4+nLke9s=",
"owner": "NixOS",
"repo": "nixos-hardware",
"rev": "ef4efb84766a166c906bd55759574676bf91267c",
"rev": "08018c72174a4df5657f8d94178ac69fb9c243e5",
"type": "github"
},
"original": {
@@ -263,11 +266,11 @@
},
"nixpkgs-unstable": {
"locked": {
"lastModified": 1779560665,
"narHash": "sha256-tpyBcxPpcQb8ukyNF7DoCwfSY3VPsxHoYwj00Cayv5o=",
"lastModified": 1781577229,
"narHash": "sha256-lrp67w8AulE9Ks53n27I45ADSzbOCn4H+CNW1Ck8B+8=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "64c08a7ca051951c8eae34e3e3cb1e202fe36786",
"rev": "567a49d1913ce81ac6e9582e3553dd90a955875f",
"type": "github"
},
"original": {
@@ -311,11 +314,24 @@
},
"nixpkgs_4": {
"locked": {
"lastModified": 1779877693,
"narHash": "sha256-NOF9NAREhxr50bbBfVcVOq+ArCMSoe8dP79Pk2uyARk=",
"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": 1781607440,
"narHash": "sha256-rxO+uc/KFbSJp+pgyXRuAX6QlG9hJdnt0BXpEQRXY+U=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "4100e830e085863741bc69b156ec4ccd53ab5be0",
"rev": "3e41b24abd260e8f71dbe2f5737d24122f972158",
"type": "github"
},
"original": {
@@ -333,7 +349,7 @@
"import-tree": "import-tree_2",
"musnix": "musnix",
"nixos-hardware": "nixos-hardware",
"nixpkgs": "nixpkgs_4",
"nixpkgs": "nixpkgs_5",
"nixpkgs-unstable": "nixpkgs-unstable"
}
},
+6
View File
@@ -16,6 +16,8 @@
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
@@ -29,13 +31,17 @@
suiteModules.homeManager.qutebrowser
suiteModules.homeManager.reaper
suiteModules.homeManager.snx-rs
suiteModules.homeManager.roam-backup
suiteModules.homeManager.ytdl
suiteModules.homeManager.chess
];
programs.home-manager.enable = true;
azos.suites.lauretta.enable = true;
azos.chess.enable = true;
azos.name = "Aner Zakobar";
azos.roam-backup.enable = true;
home = {
username = "aner";
+3
View File
@@ -20,12 +20,14 @@
suiteModules.nixos.virtualization
suiteModules.nixos.binfmt
suiteModules.nixos.attic
suiteModules.nixos.printing
];
boot.loader.grub = {
enable = true;
efiSupport = true;
device = "nodev";
configurationLimit = 5;
};
boot.loader.efi.canTouchEfiVariables = true;
@@ -86,6 +88,7 @@
azos.suites.exwm.enable = true;
azos.attic.enable = true;
azos.printing.enable = true;
home-manager = {
extraSpecialArgs = {inherit inputs outputs suiteModules pkgs;};