feat(nix): install the CLI unconditionally, gate context per harness (task 0046)
All checks were successful
CI / test (22) (pull_request) Successful in 52s
CI / test (true, 24) (pull_request) Successful in 1m4s
CI / flake (pull_request) Successful in 3s
CI / test (22) (push) Successful in 48s
CI / test (true, 24) (push) Successful in 1m2s
CI / flake (push) Successful in 3s

Reshape the home-manager module so `programs.gitea-axi.enable` installs the
binary always, and the Claude Code context follows the harness. The two
per-artefact toggles and their assertion are replaced by one per-harness
toggle, `enableClaudeCodeIntegration` (default true); its artefacts land only
when `programs.claude-code.enable` is also on, silently absent otherwise.

The Agent Skill is now written through home.file into Claude Code's skills
directory, rather than contributed to `programs.claude-code.skills`, so it
composes with both the attribute-set and whole-directory forms of an operator's
own skills option. The Skill write is gated on `claude-code.enable` explicitly
(keeping package realisation lazy); the hook keeps its sibling-module gate for
free, and the asymmetry is commented. Supersedes three decisions of ADR 0020;
recorded in ADR 0021.

INSTALL.md is updated to the new option surface and the path-form limitation
paragraph removed. Adds the parent spec and the follow-up task 0047 (the flake
check proving composition, implemented separately).
This commit was merged in pull request #55.
This commit is contained in:
2026-07-20 19:50:44 -04:00
parent e77a1f5e22
commit 534097121d
7 changed files with 395 additions and 73 deletions

View File

@@ -68,32 +68,26 @@ Use the module instead ([ADR 0020](.claude/adr/0020-home-manager-module-for-decl
}
```
That installs the package, declares the Agent Skill, and registers the SessionStart hook.
`programs.gitea-axi.enable` installs the CLI, always.
The Claude Code context — the Agent Skill and the SessionStart hook — follows the harness: it is declared under a single toggle, `programs.gitea-axi.enableClaudeCodeIntegration`, on by default, and lands only when `programs.claude-code.enable` is also on.
Enable gitea-axi on a host without Claude Code and you get the CLI and nothing else — no assertion, no toggles to turn off.
Importing the module without setting `enable` changes nothing at all.
It declares both pieces through `programs.claude-code`'s own options, so a configuration that already sets `programs.claude-code.skills` or its own `settings.hooks.SessionStart` gets gitea-axi's merged in alongside rather than colliding with it.
That module must be enabled; if it is not, the declarations would be silently dropped, so this is an assertion failure instead.
Two requirements on the surrounding configuration:
- Your home-manager must be recent enough to have `programs.claude-code.skills`.
- You must be using the *attribute-set* form of that option, `skills.<name> = ...`.
Home-manager also accepts a single path there, standing for a whole skills directory, and that form takes over the option outright — a configuration using it cannot have gitea-axi's skill merged in, and gets a type-merge error rather than composition.
Switch to the attribute-set form, or set `programs.gitea-axi.skill.enable = false` and place the Skill in your own directory.
The hook is declared through `programs.claude-code`'s own settings option, so a configuration that already sets its own `settings.hooks.SessionStart` gets gitea-axi's merged in alongside rather than colliding.
The Skill is written straight into Claude Code's skills directory, so it composes with your own skills whether you declare them as `programs.claude-code.skills.<name> = ...` or as a single path standing for a whole directory — there is no form you have to switch to.
#### Options
| Option | Default | Meaning |
| --- | --- | --- |
| `programs.gitea-axi.enable` | `false` | Switches everything below on. |
| `programs.gitea-axi.package` | your `pkgs`' build of the package | The package to install, or `null` to install nothing. |
| `programs.gitea-axi.skill.enable` | `true` | Declare the Agent Skill. |
| `programs.gitea-axi.sessionStartHook.enable` | `true` | Declare the SessionStart hook. |
| `programs.gitea-axi.enable` | `false` | Install the CLI. |
| `programs.gitea-axi.package` | your `pkgs`' build of the package | The package to install, or `null` to declare the context without the binary. |
| `programs.gitea-axi.enableClaudeCodeIntegration` | `true` | Declare the Agent Skill and SessionStart hook when Claude Code is enabled. |
`package = null` is the documented way to declare the context without installing the binary — for instance when you install gitea-axi system-wide through `environment.systemPackages`.
The hook records the bare name `gitea-axi` and lets `PATH` resolve it ([ADR 0019](.claude/adr/0019-hook-records-search-path-name.md)), so a binary installed anywhere on `PATH` satisfies it.
`package = null` declares the context without installing the binary — for instance when you install gitea-axi system-wide through `environment.systemPackages`.
The hook records the bare name `gitea-axi` and lets `PATH` resolve it ([ADR 0019](.claude/adr/0019-hook-records-search-path-name.md)), so a binary installed anywhere on `PATH` satisfies it, and the Skill is still taken from the default build.
The two toggles let you mix the paths: turn one off and write that piece with `setup` while the module manages the other.
Turn `enableClaudeCodeIntegration` off to keep the CLI declarative while writing the Skill and hook yourself with `setup`.
#### What the module does not cover