1 Commits
Author SHA1 Message Date
jackos1998 479cdfbdc4 home-manager/gui: Manage Codex with mutable settings
CI / Check, build and cache nixfiles (push) Failing after 17m9s
Update docs / update (push) Successful in 57s
Pin Codex independently through `llm-agents.nix` and update unstable
home-manager for `programs.codex.mutableSettings`.

Declare the status line, including both usage windows, while preserving
imperative settings during activation.
2026-10-03 22:08:19 +01:00
11 changed files with 43 additions and 113 deletions
+6 -19
View File
@@ -35,7 +35,7 @@ see its help, or browse `devshell/commands.nix` / `devshell/install.nix` / `devs
Common ones: Common ones:
- `fmt` — format Nix with `nixpkgs-fmt` (the canonical formatter here). - `fmt` — format Nix with `nixpkgs-fmt` (the canonical formatter here).
- `build-system <host> [nix args]` — build a NixOS system's `toplevel`. - `build-system <host> [nix args]` — build a NixOS system's `toplevel`.
- `build-n-switch <args>` — wraps `doas nixos-rebuild --accept-flake-config --flake .`. - `build-n-switch <args>` — wraps `doas nixos-rebuild --flake .`.
- `build-home <name>` / `home-switch` — build / switch a home-manager config. - `build-home <name>` / `home-switch` — build / switch a home-manager config.
- `run-vm <host>` — build & boot a system as a dev VM (installs `.keys/dev.key` into the VM). - `run-vm <host>` — build & boot a system as a dev VM (installs `.keys/dev.key` into the VM).
- `build-iso` / `build-kexec` / `build-netboot <host>` — alternate build outputs via `config.my.buildAs.*`. - `build-iso` / `build-kexec` / `build-netboot <host>` — alternate build outputs via `config.my.buildAs.*`.
@@ -116,11 +116,6 @@ Four pkgs sets are threaded everywhere as `pkgsFlakes` / `pkgs'` (and `hmFlakes`
channel via `nixpkgs` / `home-manager` / `hmNixpkgs` options (e.g. `nixpkgs = "mine-stable"`). channel via `nixpkgs` / `home-manager` / `hmNixpkgs` options (e.g. `nixpkgs = "mine-stable"`).
Modules receive `pkgs'` = an attrset of all channels for the current system. Modules receive `pkgs'` = an attrset of all channels for the current system.
For options absent from older channels, omit the attribute with `optionalAttrs` guarded by
the module's `options` argument. `mkIf false` still checks option existence. Add a `TODO`
comment explaining which older release needs the guard and which release upgrade allows
its removal, matching the existing release-gated TODOs.
### `lib.my` and the `my` option namespace ### `lib.my` and the `my` option namespace
`lib/default.nix` extends `lib` with a `my` attrset (helpers like `mkOpt'`, `mkBoolOpt'`, `lib/default.nix` extends `lib` with a `my` attrset (helpers like `mkOpt'`, `mkBoolOpt'`,
`mkDefault'`, `inlineModule'`, `mkDefaultSystemsPkgs`, `homeStateVersion`). It also pulls in: `mkDefault'`, `inlineModule'`, `mkDefaultSystemsPkgs`, `homeStateVersion`). It also pulls in:
@@ -192,13 +187,6 @@ in churn.
## Conventions ## Conventions
- Prefer `jj` for status, diffs, history, commits, rebases and remote operations when it is
available and the checkout has a Jujutsu workspace. Use Git when `jj` is unavailable or the
checkout is Git-only, and for Git-specific tooling. The shared home config and devshell install
`jujutsu`; see [`docs/deployment.md#version-control`](docs/deployment.md#version-control) for
setup and the workflow. Inspect `jj status`, `jj diff` and `jj log` before editing; `jj`
snapshots working-copy changes automatically, so preserve existing user changes and use
explicit revisions when rewriting history or moving bookmarks.
- Format with `nixpkgs-fmt` (`fmt`). 2-space indent, `inherit (...)` blocks at the top of `let` — - Format with `nixpkgs-fmt` (`fmt`). 2-space indent, `inherit (...)` blocks at the top of `let` —
prefer `inherit (lib) mkOption ...;` (and bare use) over qualifying inline as `lib.mkOption`. prefer `inherit (lib) mkOption ...;` (and bare use) over qualifying inline as `lib.mkOption`.
**Ask before running `fmt`** — some files aren't canonically formatted, so `fmt` can reindent a **Ask before running `fmt`** — some files aren't canonically formatted, so `fmt` can reindent a
@@ -224,12 +212,11 @@ in churn.
command, option or upstream technical term such as QEMU's machine type. command, option or upstream technical term such as QEMU's machine type.
- Commit subjects follow `area/scope: Capitalized summary` (e.g. `nixos/home: ...`); keep logically - Commit subjects follow `area/scope: Capitalized summary` (e.g. `nixos/home: ...`); keep logically
distinct changes in separate commits. Aim for 50-character subjects and do not exceed 72 distinct changes in separate commits. Aim for 50-character subjects and do not exceed 72
characters. Hard-wrap commit body lines at 72 characters; `-m` preserves unwrapped text, so characters. Hard-wrap commit body lines at 72 characters; Git preserves an unwrapped `-m`
include literal line breaks or use a commit-message file. Before reporting a commit, inspect argument as one long line, so include literal line breaks or use a commit-message file. Before
`jj log --no-graph -r <revision> -T description` (or `git show -s --format=%B HEAD` in a Git-only reporting a commit, inspect `git show -s --format=%B HEAD` and amend it if any line exceeds 72
checkout) and amend its description if any line exceeds 72 characters. A concise body describing characters. A concise body describing the change and its rationale is welcome when the subject
the change and its rationale is welcome when the subject alone does not provide enough context — alone does not provide enough context — keep it to the essentials rather than restating the diff.
keep it to the essentials rather than restating the diff.
`Co-Authored-By` is the only trailer used here; do **not** add a `Claude-Session` link (or any `Co-Authored-By` is the only trailer used here; do **not** add a `Claude-Session` link (or any
other session/tooling trailer). other session/tooling trailer).
- **"Logically distinct" means unrelated** — two different applications, two boxes that have nothing - **"Logically distinct" means unrelated** — two different applications, two boxes that have nothing
+1 -2
View File
@@ -106,8 +106,7 @@ in
# HACK: Upstream changes in Git + Nix makes this necessary # HACK: Upstream changes in Git + Nix makes this necessary
# https://github.com/NixOS/nix/issues/10202 # https://github.com/NixOS/nix/issues/10202
doas git config --global --add safe.directory "$PWD" doas git config --global --add safe.directory "$PWD"
# doas drops the devshell's NIX_USER_CONF_FILES, including accept-flake-config. doas nixos-rebuild --flake . "$@"
doas nixos-rebuild --accept-flake-config --flake . "$@"
''; '';
} }
{ {
-1
View File
@@ -32,6 +32,5 @@ in
exec ${deploy-rs.deploy-rs}/bin/deploy --skip-checks "$@" exec ${deploy-rs.deploy-rs}/bin/deploy --skip-checks "$@"
'') '')
home-manager home-manager
jujutsu
]; ];
} }
+1 -1
View File
@@ -24,7 +24,7 @@ Not every box fits this pattern, but **colony** and **home** are organised this
nixpkgs channels, shared module inventory. nixpkgs channels, shared module inventory.
- [`networking.md`](networking.md) — network assignments, domains, site topologies, router HA, - [`networking.md`](networking.md) — network assignments, domains, site topologies, router HA,
the AS211024 L2 mesh, BGP, WireGuard, Tailscale. the AS211024 L2 mesh, BGP, WireGuard, Tailscale.
- [`deployment.md`](deployment.md) — deploy-rs, devshell commands, `jj` workflow, secrets, CI. - [`deployment.md`](deployment.md) — deploy-rs, devshell commands, secrets workflow, CI.
- [`nixpkgs-upgrade.md`](nixpkgs-upgrade.md) — guided procedure for the periodic upgrade of the four - [`nixpkgs-upgrade.md`](nixpkgs-upgrade.md) — guided procedure for the periodic upgrade of the four
nixpkgs channels and home-manager (fork rebase, stable bumps, input review). nixpkgs channels and home-manager (fork rebase, stable bumps, input review).
- [`install-box.md`](install-box.md) — guided procedure for installing a new box, from the booted - [`install-box.md`](install-box.md) — guided procedure for installing a new box, from the booted
+3 -44
View File
@@ -68,10 +68,6 @@ The shared GUI home-manager module installs Codex from the `llm-agents` input, r
that input's tested nixpkgs pin. Run `nix flake update llm-agents`, then switch the system that input's tested nixpkgs pin. Run `nix flake update llm-agents`, then switch the system
or home configuration to use the updated package. or home configuration to use the updated package.
The shared cache settings in `lib.my.c.nix.cache` and the flake's `nixConfig` include
the [Numtide binary cache](https://github.com/numtide/llm-agents.nix#binary-cache), so
Codex can be downloaded prebuilt. Keep the input's tested nixpkgs pin to preserve cache hits.
`programs.codex.mutableSettings` merges the declared status-line settings into the writable `programs.codex.mutableSettings` merges the declared status-line settings into the writable
`~/.codex/config.toml` during activation. Declared values take precedence on each switch; `~/.codex/config.toml` during activation. Declared values take precedence on each switch;
other settings, including model selection, providers and project trust, remain imperative. other settings, including model selection, providers and project trust, remain imperative.
@@ -86,7 +82,7 @@ command with no arguments for its help. From
|---|---| |---|---|
| `check-system <host> [nix args]` | Evaluates `.#nixosConfigurations."<host>".config.system.build.toplevel.drvPath` — catches module/option errors without building. Prefer this to validate a config change. | | `check-system <host> [nix args]` | Evaluates `.#nixosConfigurations."<host>".config.system.build.toplevel.drvPath` — catches module/option errors without building. Prefer this to validate a config change. |
| `build-system <host> [nix args]` | Builds the system's `toplevel` (extra args pass through to `nix build`). | | `build-system <host> [nix args]` | Builds the system's `toplevel` (extra args pass through to `nix build`). |
| `build-n-switch <args>` | `doas nixos-rebuild --accept-flake-config --flake .` (accepts the flake's cache settings and adds the repo as a git `safe.directory` for root first). | | `build-n-switch <args>` | `doas nixos-rebuild --flake .` (adds the repo as a git `safe.directory` for root first). |
| `build-home <name> [nix args]` | Builds `.#homeConfigurations."<name>".activationPackage`. | | `build-home <name> [nix args]` | Builds `.#homeConfigurations."<name>".activationPackage`. |
| `home-switch [args]` | `home-manager switch --flake .`. | | `home-switch [args]` | `home-manager switch --flake .`. |
| `deploy [args]` | `deploy-rs --skip-checks` (wrapper package in `devshell/default.nix`). | | `deploy [args]` | `deploy-rs --skip-checks` (wrapper package in `devshell/default.nix`). |
@@ -124,43 +120,6 @@ VM's unix sockets from `/run/vms/<vm>/` on `<host>` over SSH):
| `vm-monitor <host> <vm>` | QEMU monitor socket in `minicom`. | | `vm-monitor <host> <vm>` | QEMU monitor socket in `minicom`. |
| `vm-viewer <host> <vm>` | SPICE display in `virt-viewer` (not on Darwin). | | `vm-viewer <host> <vm>` | SPICE display in `virt-viewer` (not on Darwin). |
## Version control
The shared [Home Manager module](../home-manager/modules/common.nix) enables `programs.git`
and `programs.jujutsu`, including Git LFS and `diff-so-fancy`, for graphical and non-graphical
homes. Jujutsu uses the identity declared in `programs.git.settings.user`; Home Manager writes
its `jj/config.toml`. The [devshell](../devshell/default.nix) also installs `jujutsu`, which
provides `jj`. Prefer `jj` when it is available and the checkout has a Jujutsu workspace;
use Git for Git-only checkouts and Git-specific tooling such as the installer-tag command
and CI scripts.
To use an existing Git checkout with both tools, run `jj git init --colocate` at its root.
This creates local `.jj` metadata and keeps `.git` for Nix flake source discovery and existing
Git tooling. Switch the home configuration to install the managed identity. When using only
the devshell, configure your identity with `jj config set --user user.name '<name>'` and
`jj config set --user user.email '<email>'` before creating commits.
| Task | Command |
|---|---|
| Inspect the working copy and history | `jj status`, `jj diff`, `jj log` |
| Describe the current change | `jj describe -m 'area/scope: Capitalized summary'` |
| Start the next change | `jj new` |
| Inspect a completed description | `jj log --no-graph -r <revision> -T description` |
| Fetch remote history | `jj git fetch` |
| Name a revision for publishing | `jj bookmark create <name> -r <revision>` |
| Move an existing bookmark | `jj bookmark set <name> -r <revision>` |
| Publish a bookmark | `jj git push --bookmark <name>` |
`@` is the working-copy revision; after `jj new`, the completed change is normally `@-`.
Working-copy edits are snapshotted automatically, without a staging step. Inspect existing
changes before editing, keep unrelated work separate, and check the target revision before
rewriting history or moving a bookmark. Follow the commit-message conventions in
[`AGENTS.md`](../AGENTS.md#conventions).
See the upstream [Jujutsu CLI reference](https://docs.jj-vcs.dev/latest/cli-reference/)
for command options and [Git compatibility](https://docs.jj-vcs.dev/latest/git-compatibility/)
for colocation details.
## Nix implementation ## Nix implementation
Every context uses **Determinate Nix** as its `nix.package`, for its performance features Every context uses **Determinate Nix** as its `nix.package`, for its performance features
@@ -182,8 +141,8 @@ are unchanged, and the Determinate NixOS module is deliberately not imported.
Determinate without further change. Determinate without further change.
- **`accept-flake-config`.** Set true only in the devshell `nix.conf`, `.envrc` (as - **`accept-flake-config`.** Set true only in the devshell `nix.conf`, `.envrc` (as
`--accept-flake-config`, for direnv) and CI — the contexts that build this flake — so its `--accept-flake-config`, for direnv) and CI — the contexts that build this flake — so its
`nixConfig` (the Harmonia and Numtide caches) is trusted without an interactive prompt. It is `nixConfig` (the Harmonia cache) is trusted without an interactive prompt. It is deliberately not
deliberately not set system-wide: boxes already trust those caches via `nix.settings`, so a global setting would only set system-wide: boxes already trust that cache via `nix.settings`, so a global setting would only
blanket-trust every flake's `nixConfig` for no gain. blanket-trust every flake's `nixConfig` for no gain.
## Secrets ## Secrets
Generated
+12 -12
View File
@@ -695,11 +695,11 @@
"treefmt-nix": "treefmt-nix_2" "treefmt-nix": "treefmt-nix_2"
}, },
"locked": { "locked": {
"lastModified": 1793435943, "lastModified": 1791001326,
"narHash": "sha256-kl4L50m8mMMyQLjH2d46ljtdzR+9vlgpoDmOrpNV/SU=", "narHash": "sha256-pwJhtpRcNX1pJ9luUy3Eh1EYUFsZjv5m2xSqZ1hEhMU=",
"owner": "numtide", "owner": "numtide",
"repo": "llm-agents.nix", "repo": "llm-agents.nix",
"rev": "b14f9d18b6d127221bd9f63817a40e1cca2b344b", "rev": "83984ebbbe5322b261d9fdc24eb15cf44f23abec",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -919,11 +919,11 @@
}, },
"nixpkgs_6": { "nixpkgs_6": {
"locked": { "locked": {
"lastModified": 1793345420, "lastModified": 1790600678,
"narHash": "sha256-e/yiZ31gXRROBDcnOtT3YwDQ73NVG9Cepccbt86LIn8=", "narHash": "sha256-6k3n7X2UsZ6tAlWTz99RimiZab+17tMUrw9sRUcELiA=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "885ba4d038f10c3d17d7a92e8c3cc185b99c9158", "rev": "f45c6f04c2f013f004bf94e284e95d72898d9393",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1163,11 +1163,11 @@
}, },
"systems_6": { "systems_6": {
"locked": { "locked": {
"lastModified": 1791244623, "lastModified": 1681028828,
"narHash": "sha256-uuanbkFk8a313Zfrxdcz8Us/yQtaxNnKJtX8v0ZPpd8=", "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems", "owner": "nix-systems",
"repo": "default", "repo": "default",
"rev": "d36eeed142f88b5a636f2e3856a53c61654cf29b", "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1250,11 +1250,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1791885023, "lastModified": 1786901030,
"narHash": "sha256-C3alQ2MEt0zVrUSho5NUDo3jmhbff72++bfwoqT9Omo=", "narHash": "sha256-WSFCsDSE5ffgD2MqzkM2CYjeFiKhRF/dJUN8uedb6YE=",
"owner": "numtide", "owner": "numtide",
"repo": "treefmt-nix", "repo": "treefmt-nix",
"rev": "0d6d739a833ba9a9c93034862e4a7b061a062a1c", "rev": "27b3b12a8e6375f28ebe122f07d230ca5459bbfa",
"type": "github" "type": "github"
}, },
"original": { "original": {
+1 -3
View File
@@ -1,18 +1,16 @@
{ {
description = "System configs"; description = "System configs";
# Offer our Harmonia and Numtide caches when building the flake, so `nix develop` / `nix build` don't # Offer our Harmonia cache when building the flake itself, so `nix develop` / `nix build` don't
# rebuild from source. Nix reads `nixConfig` before the flake evaluates and rejects any computed # rebuild from source. Nix reads `nixConfig` before the flake evaluates and rejects any computed
# value (imports/thunks), so these must stay literal — keep them in sync with `lib.my.c.nix.cache`. # value (imports/thunks), so these must stay literal — keep them in sync with `lib.my.c.nix.cache`.
# Consumers must trust these (accept-flake-config / a trusted user) for them to take effect. # Consumers must trust these (accept-flake-config / a trusted user) for them to take effect.
nixConfig = { nixConfig = {
extra-substituters = [ extra-substituters = [
"https://nix-cache.nul.ie" "https://nix-cache.nul.ie"
"https://cache.numtide.com"
]; ];
extra-trusted-public-keys = [ extra-trusted-public-keys = [
"nix-cache.nul.ie-1:BzH5yMfF4HbzY1C977XzOxoPhEc9Zbu39ftPkUbH+m4=" "nix-cache.nul.ie-1:BzH5yMfF4HbzY1C977XzOxoPhEc9Zbu39ftPkUbH+m4="
"niks3.numtide.com-1:DTx8wZduET09hRmMtKdQDxNNthLQETkc/yaX7M4qK0g="
]; ];
}; };
-19
View File
@@ -67,24 +67,6 @@ in
# never care about. # never care about.
home-manager.enable = true; home-manager.enable = true;
git = {
enable = true;
settings = {
user = {
email = "jackos1998@gmail.com";
name = "Jack O'Sullivan";
};
pull.rebase = true;
};
lfs.enable = true;
};
diff-so-fancy.enable = true;
jujutsu = {
enable = true;
settings.user = config.programs.git.settings.user;
};
lsd = { lsd = {
enable = mkDefault true; enable = mkDefault true;
enableFishIntegration = mkDefault true; enableFishIntegration = mkDefault true;
@@ -220,7 +202,6 @@ in
file file
tree tree
pwgen pwgen
python3
minicom minicom
iperf3 iperf3
+19 -9
View File
@@ -1,6 +1,6 @@
{ lib, pkgs', pkgs, inputs, config, options, ... }: { lib, pkgs', pkgs, inputs, config, ... }:
let let
inherit (lib) genAttrs mkIf mkMerge mkForce mapAttrs mkOptionDefault mkDefault optional optionalAttrs; inherit (lib) genAttrs mkIf mkMerge mkForce mapAttrs mkOptionDefault mkDefault optional;
inherit (lib.my) mkOpt' mkBoolOpt'; inherit (lib.my) mkOpt' mkBoolOpt';
inherit (lib.my.c) pubDomain; inherit (lib.my.c) pubDomain;
@@ -84,7 +84,7 @@ in
grim grim
slurp slurp
satty swappy
python3Packages.python-lsp-server python3Packages.python-lsp-server
nil # nix language server nil # nix language server
@@ -187,11 +187,10 @@ in
}; };
}; };
# TODO: Remove mutableSettings guard when Home Manager 26.11 releases; 26.05 lacks it.
codex = { codex = {
enable = true; enable = true;
package = inputs.llm-agents.packages.${pkgs.stdenv.hostPlatform.system}.codex; package = inputs.llm-agents.packages.${pkgs.stdenv.hostPlatform.system}.codex;
settings.sandbox_workspace_write.network_access = true; mutableSettings = true;
settings.tui = { settings.tui = {
status_line = [ status_line = [
"model-with-reasoning" "model-with-reasoning"
@@ -206,8 +205,6 @@ in
]; ];
status_line_use_colors = true; status_line_use_colors = true;
}; };
} // optionalAttrs (options.programs.codex ? mutableSettings) {
mutableSettings = true;
}; };
claude-code = { claude-code = {
@@ -410,8 +407,8 @@ in
"${mod}+Shift+n" = "exec ${clearWsName}"; "${mod}+Shift+n" = "exec ${clearWsName}";
# Screenshots # Screenshots
"${mod}+Shift+d" = ''exec grim - | satty -f -''; "${mod}+Shift+d" = ''exec grim - | swappy -f -'';
"${mod}+Shift+s" = ''exec grim -g "$(slurp)" - | satty -f -''; "${mod}+Shift+s" = ''exec grim -g "$(slurp)" - | swappy -f -'';
"XF86MonBrightnessDown" = "exec ${pkgs.brightnessctl}/bin/brightnessctl set 5%-"; "XF86MonBrightnessDown" = "exec ${pkgs.brightnessctl}/bin/brightnessctl set 5%-";
"XF86MonBrightnessUp" = "exec ${pkgs.brightnessctl}/bin/brightnessctl set +5%"; "XF86MonBrightnessUp" = "exec ${pkgs.brightnessctl}/bin/brightnessctl set +5%";
@@ -508,6 +505,19 @@ in
}; };
programs = { programs = {
git = {
enable = true;
settings = {
user = {
email = "jackos1998@gmail.com";
name = "Jack O'Sullivan";
};
pull.rebase = true;
};
lfs.enable = true;
};
diff-so-fancy.enable = true;
waybar = import ./waybar.nix { inherit lib pkgs config font; }; waybar = import ./waybar.nix { inherit lib pkgs config font; };
rofi = { rofi = {
enable = true; enable = true;
-2
View File
@@ -102,11 +102,9 @@ rec {
cache = rec { cache = rec {
substituters = [ substituters = [
"https://nix-cache.${pubDomain}" "https://nix-cache.${pubDomain}"
"https://cache.numtide.com"
]; ];
keys = [ keys = [
"nix-cache.nul.ie-1:BzH5yMfF4HbzY1C977XzOxoPhEc9Zbu39ftPkUbH+m4=" "nix-cache.nul.ie-1:BzH5yMfF4HbzY1C977XzOxoPhEc9Zbu39ftPkUbH+m4="
"niks3.numtide.com-1:DTx8wZduET09hRmMtKdQDxNNthLQETkc/yaX7M4qK0g="
]; ];
conf = '' conf = ''
extra-substituters = ${concatStringsSep " " substituters} extra-substituters = ${concatStringsSep " " substituters}
-1
View File
@@ -147,7 +147,6 @@ in
[ [
bash-completion bash-completion
git git
python3
unzip unzip
tcpdump tcpdump
] ]