diff --git a/.agents/skills/nix-config-debug/SKILL.md b/.agents/skills/nix-config-debug/SKILL.md index 75db5889..45b10001 100644 --- a/.agents/skills/nix-config-debug/SKILL.md +++ b/.agents/skills/nix-config-debug/SKILL.md @@ -8,9 +8,10 @@ description: >- # Debugging this repository -Follow the global `systematic-debugging` skill for the process (root cause before any fix). This -skill is only the map: which layer failed, and where to look. Rolling back, isolating a bad input -bump, and the commands that destroy rollback points are in the `nix-config-update` skill. +Follow the global `diagnosing-bugs` skill for the process (a reproducible signal and root cause +before any fix). This skill is only the map: which layer failed, and where to look. Rolling back, +isolating a bad input bump, and the commands that destroy rollback points are in the +`nix-config-update` skill. ## Core rules @@ -18,27 +19,38 @@ bump, and the commands that destroy rollback points are in the `nix-config-updat investigation. Rolling back the machine you are on needs `sudo`, so the user does it. 2. **Name the layer before touching code.** Eval, build, activation, and runtime failures have different causes; a green `just test` says nothing about activation. -3. **Never get to green by weakening a check**: no disabled test, dropped assertion, or `mkForce` - over the failing value. -4. **Preserve existing user changes.** Do not discard or stash them without authorization. If a - clean baseline is needed, record the current diff and ask before isolating it. ## 1. Localize by layer -| Layer | Symptom | Look with | -| ------------- | ---------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| eval | `just test` fails, an eval error | `just eval-host ` (already passes `--show-trace`) | -| build | build error, hash mismatch, "marked as broken" | `just build-host `, then `nix log ` | -| activation | the deploy fails after building | the deploy output; `journalctl -u home-manager-$USER -b` for Home Manager | -| runtime | a unit is failed or restarting | `just list-failed`, `systemctl status `, `journalctl -u -b` | -| proxy/DNS | proxied sites time out, or DNS still resolves after mihomo stops | `dig +short ` must return a fake-ip (`198.18.x.x`); a real IP means the resolver bypasses `dns-hijack`; on `ai` the `resolvectl dns`/`revert` hook in `hosts/idols-ai/default.nix` ties link DNS to mihomo's lifecycle and other mihomo hosts have no such hook, so read `resolvectl status` before concluding; a statically set link DNS would outlive a dead mihomo. Config and gotchas: [mihomo README](../../../modules/nixos/desktop/networking/mihomo/README.md); regenerate with `just mihomo-gen`, then restart `mihomo.service` | -| boot | errors at boot, wrong kernel | `journalctl -b -p err`; `just history` for what is booted | -| session | desktop or app misbehaves | `journalctl --user -b -p err`; the `nix-config-desktop` skill | -| remote host | anything on a Colmena host | `ssh root@ journalctl -b -p err`, same commands over SSH | -| MicroVM guest | guest down or unreachable | on the VM host: `systemctl status microvm@` and `microvm-tap-interfaces@`; then `br0` | -| secrets | missing or unreadable `/run/agenix/` | the `nix-config-secrets` skill | -| shell | nushell exits 1 with `File not found` | whether `~/.secrets/` exists on the host; the `nix-config-secrets` skill | -| CI | a GitHub Action keeps failing | `gh run list --workflow `, `gh run view --log-failed` | +Each layer: symptom, then where to look. + +- **eval** (`just test` fails, an eval error): `just eval-host ` (already passes + `--show-trace`) +- **build** (build error, hash mismatch, "marked as broken"): `just build-host `, then + `nix log ` +- **activation** (the deploy fails after building): the deploy output; + `journalctl -u home-manager-$USER -b` for Home Manager +- **runtime** (a unit is failed or restarting): `just list-failed`, `systemctl status `, + `journalctl -u -b` +- **proxy/DNS** (proxied sites time out, or DNS still resolves after mihomo stops): + `dig +short ` must return a fake-ip (`198.18.x.x`); a real IP means the resolver bypasses + `dns-hijack`; on `ai` the `resolvectl dns`/`revert` hook in `hosts/idols-ai/default.nix` ties link + DNS to mihomo's lifecycle and other mihomo hosts have no such hook, so read `resolvectl status` + before concluding; a statically set link DNS would outlive a dead mihomo. Config and gotchas: + [mihomo README](../../../modules/nixos/desktop/networking/mihomo/README.md); regenerate with + `just mihomo-gen`, then restart `mihomo.service` +- **boot** (errors at boot, wrong kernel): `journalctl -b -p err`; `just history` for what is booted +- **session** (desktop or app misbehaves): `journalctl --user -b -p err`; the `nix-config-desktop` + skill +- **remote host** (anything on a Colmena host): `ssh root@ journalctl -b -p err`, same + commands over SSH +- **MicroVM guest** (guest down or unreachable): on the VM host: `systemctl status microvm@` + and `microvm-tap-interfaces@`; then `br0` +- **secrets** (missing or unreadable `/run/agenix/`): the `nix-config-secrets` skill +- **shell** (nushell exits 1 with `File not found`): whether `~/.secrets/` exists on the host; the + `nix-config-secrets` skill +- **CI** (a GitHub Action keeps failing): `gh run list --workflow `, + `gh run view --log-failed` ## 2. Read the evaluated value diff --git a/.agents/skills/nix-config-desktop/SKILL.md b/.agents/skills/nix-config-desktop/SKILL.md index 6e6ad4ca..fd779ca5 100644 --- a/.agents/skills/nix-config-desktop/SKILL.md +++ b/.agents/skills/nix-config-desktop/SKILL.md @@ -36,20 +36,27 @@ back with git, and needs no rebuild. Only the store layer needs one. ## 1. Pick the layer -| Change | Where it lives | Applies | -| --------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ------------------------ | -| Niri compositor (binds, layout, window rules) | `home/linux/gui/niri/conf/*.kdl` | live | -| Niri per-host outputs | `hosts//niri-hardware.kdl` | live | -| Noctalia shared baseline | `home/linux/gui/base/noctalia/config/config.toml` | live | -| Noctalia per-host override | `home/hosts/linux//noctalia.toml` (`host-.toml`) | store: needs `just niri` | -| Noctalia value saved by the Settings UI | `~/.local/state/noctalia/settings.toml` (not in the repo) | live, wins over the rest | -| Mozc dictionary | `home/linux/gui/base/fcitx5/mozc-config1.db` | live | -| fcitx5 profile and addons | `home/linux/gui/base/fcitx5/` | store: needs `just niri` | -| vinput (voice input) | `home/linux/gui/base/vinput/` (tag-pinned: the `fcitx5-vinput` row in WORKAROUNDS.md §Pins) | store: needs `just niri` | -| Interface a net-speed widget reads | `home/hosts/linux//noctalia.toml` (`[widget.net_rx]`/`[widget.net_tx]` `interface`) | store: needs `just niri` | -| `$HOME` state that must survive | `hosts//preservation.nix` (tmpfs root; `12kingdoms-shoukei` imports `hosts/idols-ai/preservation.nix`) | store: needs `just niri` | -| Theme (catppuccin), fonts | `home/base/core/theme.nix`, `modules/nixos/desktop/fonts.nix` | store: needs `just niri` | -| Session, portal, and systemd wiring | `modules/nixos/desktop/**`, `home/linux/gui/base/xdg/` | store: needs `just niri` | +Live (out-of-store, applies on save): + +- Niri compositor (binds, layout, window rules): `home/linux/gui/niri/conf/*.kdl` +- Niri per-host outputs: `hosts//niri-hardware.kdl` +- Noctalia shared baseline: `home/linux/gui/base/noctalia/config/config.toml` +- Mozc dictionary: `home/linux/gui/base/fcitx5/mozc-config1.db` +- Noctalia value saved by the Settings UI: `~/.local/state/noctalia/settings.toml` (not in the repo; + wins over the rest) + +Store (needs the user to run `just niri`): + +- Noctalia per-host override: `home/hosts/linux//noctalia.toml` (`host-.toml`) +- fcitx5 profile and addons: `home/linux/gui/base/fcitx5/` +- vinput (voice input): `home/linux/gui/base/vinput/` (tag-pinned: the `fcitx5-vinput` row in + WORKAROUNDS.md §Pins) +- Interface a net-speed widget reads: `home/hosts/linux//noctalia.toml` + (`[widget.net_rx]`/`[widget.net_tx]` `interface`) +- `$HOME` state that must survive: `hosts//preservation.nix` (tmpfs root; `12kingdoms-shoukei` + imports `hosts/idols-ai/preservation.nix`) +- Theme (catppuccin), fonts: `home/base/core/theme.nix`, `modules/nixos/desktop/fonts.nix` +- Session, portal, and systemd wiring: `modules/nixos/desktop/**`, `home/linux/gui/base/xdg/` Noctalia's merge order and `[include]` are in [home/linux/gui/base/README.md](../../../home/linux/gui/base/README.md). A per-host difference goes diff --git a/AGENTS.md b/AGENTS.md index 9d8fed3a..8fa0b81d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,8 +1,8 @@ # Repository Agent Guide This flake manages NixOS hosts, macOS via nix-darwin, shared Home Manager profiles, and Colmena -deployments. Keep repository guidance here; reusable global rules live in `agents/AGENTS.md`. See -[agents/README.md](./agents/README.md) for their scope and deployment targets. +deployments. Keep repository guidance here; the global rules and global skills shared across +projects live in [agents/](./agents/README.md). ## Where Changes Belong @@ -18,7 +18,7 @@ deployments. Keep repository guidance here; reusable global rules live in `agent the `nix-config-secrets` skill. - `overlays/` and `hardening/` hold package overlays and hardened (nixpak/bwrap) wrappers. - Desktop (Niri and Noctalia) config is mostly out-of-store symlinks that hot-reload without a - rebuild; see the desktop skill below before changing it. + rebuild; use the `nix-config-desktop` skill before changing it. ## Commands and Platforms @@ -100,29 +100,8 @@ introduces one, and re-evaluate entries when their `Revisit` trigger comes up. ## Task Skills -Reusable, repo-scoped task procedures live in `.agents/skills/`. Note the leading dot: `agents/` is -the global rules source shared across projects, while `.agents/` applies only to this repository and -is discovered by OpenCode and compatible tools. - -- [`.agents/skills/nix-config-update/SKILL.md`](./.agents/skills/nix-config-update/SKILL.md) — - updating flake inputs and rolling the result out to hosts safely. -- [`.agents/skills/nix-config-desktop/SKILL.md`](./.agents/skills/nix-config-desktop/SKILL.md) — - which layer owns a Niri/Noctalia, input-method, or autostart setting, live reload vs a rebuild, - and on-screen verification. -- [`.agents/skills/nix-config-secrets/SKILL.md`](./.agents/skills/nix-config-secrets/SKILL.md) — - adding, changing, or removing an agenix secret, and verifying it without reading it. -- [`.agents/skills/nix-config-new-host/SKILL.md`](./.agents/skills/nix-config-new-host/SKILL.md) — - wiring a new host into `hosts/`, `outputs/`, networking, secrets, and the eval tests. -- [`.agents/skills/nix-config-debug/SKILL.md`](./.agents/skills/nix-config-debug/SKILL.md) — mapping - a broken eval, build, activation, unit, proxy or DNS outage, host, MicroVM guest, or CI job to the - command that localizes it. -- [`.agents/skills/nix-config-umu-game/SKILL.md`](./.agents/skills/nix-config-umu-game/SKILL.md) — - installing a Windows game launcher via the umu installer it bundles; per-game fixes stay under - `~/Games/`. -- [`.agents/skills/nixpkgs-review/SKILL.md`](./.agents/skills/nixpkgs-review/SKILL.md) — reviewing - nixpkgs PRs locally first, with GHA for cross-architecture or larger reviews. -- [`.agents/skills/nixpkgs-patched/SKILL.md`](./.agents/skills/nixpkgs-patched/SKILL.md) — carrying - selected unmerged nixpkgs changes through the personal patched fork safely. +Repo-scoped task procedures live in `.agents/skills/` (leading dot; agents discover them and list +them in their skill catalog). `agents/` without the dot holds the global rules and skills. ## Related Repositories @@ -136,8 +115,9 @@ repository, and cross-link them — no need to be told. change. - `~/codes/nix-secrets` — the private agenix store behind `secrets/` and the `mysecrets` input: ciphertext and recipient rules for the secrets declared here. -- `wallpapers`, `nur-ryan4yin`, `pyclipsync`, `nu_scripts` — flake inputs; bump with - `just upp ` after their source changes, do not edit them from here. +- `wallpapers`, `nur-ryan4yin`, `pyclipsync`, `nu_scripts`, `mattpocock-skills`, `i-have-adhd` — + flake inputs from the user's own repositories; bump with `just upp ` after their source + changes, do not edit them from here. ## Further Context diff --git a/agents/README.md b/agents/README.md index cc1f58a3..d1d4cd39 100644 --- a/agents/README.md +++ b/agents/README.md @@ -1,14 +1,14 @@ # Agents -Portable agent resources shared across projects: the global baseline rules, custom global skills, +Portable agent resources shared across projects: the global baseline rules, the global skills, behavioral scenarios, and reference snippets for external tooling. -Home Manager links the rules and each custom skill into the agents' config locations. The resource -files here remain portable Markdown; deployment lives in the Home Manager module. +Home Manager links the rules and skills into the agents' config locations. The resource files here +remain portable Markdown; deployment lives in the Home Manager module. -It is shared across projects. Repo-scoped task procedures for one repository belong elsewhere: put -them in that repository's `.agents/skills/` (note the leading dot), which OpenCode and compatible -tools discover automatically. In a repository, use the layers this way: +Repo-scoped task procedures for one repository belong elsewhere: put them in that repository's +`.agents/skills/` (note the leading dot), which agents discover automatically. In a repository, use +the layers this way: - `AGENTS.md`: always-loaded map and hard safety rules; keep it short. - `agents/skills/*/SKILL.md`: custom global procedures reused across repositories. @@ -20,30 +20,34 @@ Keep one canonical home for each fact; link between layers instead of copying pa ## What this directory contains -- `AGENTS.md`: global baseline rules for coding agents. -- `skills/`: custom global skills, e.g. [`git-delivery`](skills/git-delivery/SKILL.md) for commit - messages, PR descriptions, review replies, and cleanup after merge. +- `global-rules.md`: global baseline rules for coding agents. It is deliberately not named + `AGENTS.md`: agents working in this checkout would load it a second time as nested instructions + for `agents/`. +- `skills/`: global skills kept in this repository, e.g. + [`git-delivery`](skills/git-delivery/SKILL.md) for commit messages, PR descriptions, review + replies, and cleanup after merge; its [README](skills/README.md) records every global skill and + its source. - `evals/global-rules.md`: how to size and run evaluations for changes to the rules or skills, and the behavioral scenarios. -- `install-tooling.md`: curated install snippets for external agent tooling (`npx skills`, - `npx ctx7`, tuios integration). +- `install-tooling.md`: install snippets for project-scoped skills and other external agent tooling. -The Nix side of the agents — deploying these rules, the agent CLIs, and their environment — lives in -the Home Manager module [`home/base/tui/agents/`](../home/base/tui/agents/README.md). +The Nix side of the agents — deploying the rules and skills, the agent CLIs, and their environment — +lives in the Home Manager module [`home/base/tui/agents/`](../home/base/tui/agents/README.md). ## Core workflow -1. Maintain shared boundaries in `agents/AGENTS.md` and task procedures in `agents/skills/`. +1. Maintain shared boundaries in `agents/global-rules.md` and task procedures in skills. 2. Configure permissions directly in the agent runtime; auto-approval is generally used. -3. Content changes reach the next agent session through out-of-store links; a running harness may - need a reload. Adding or removing deployed links requires a Home Manager switch, run by the user. -4. Use `install-tooling.md` as a reference when installing external agent tooling. +3. Content changes to the rules and to skills in `agents/skills/` reach the next agent session + through out-of-store links; a running harness may need a reload. Adding or removing a skill, or + moving a skill flake input, requires a Home Manager switch, run by the user. +4. Use `install-tooling.md` as a reference when installing project-scoped tooling. ## Maintaining global rules Before adding or expanding a rule, read the current rules and identify the decision boundary that -needs to change. Keep reusable boundaries in `AGENTS.md`; put concrete incidents, bypass attempts, -and counterexamples in [behavioral scenarios](evals/global-rules.md). +needs to change. Keep reusable boundaries in `global-rules.md`; put concrete incidents, bypass +attempts, and counterexamples in [behavioral scenarios](evals/global-rules.md). - If an existing rule already covers the incident, add or refine a scenario instead of another rule. - If the boundary is missing or ambiguous, amend the relevant rule rather than append a special @@ -59,44 +63,65 @@ the PR. ## Deployment -[`home/base/tui/agents/rules.nix`](../home/base/tui/agents/rules.nix) links `AGENTS.md` into every -supported agent config directory as an out-of-store symlink, so edits apply without a rebuild. The -per-agent target list lives in that module's +[`rules.nix`](../home/base/tui/agents/rules.nix) links `global-rules.md` into every supported agent +config directory as `AGENTS.md`, out-of-store, so edits apply without a rebuild. The per-agent +target list lives in that module's [README](../home/base/tui/agents/README.md#deployed-rule-targets). +[`skills.nix`](../home/base/tui/agents/skills.nix) links every directory under `agents/skills/` and +the skills selected from pinned flake inputs into `~/.agents/skills/`; see the module's +[global skills](../home/base/tui/agents/README.md#global-skills) section. To add a local skill, +create `agents/skills//SKILL.md`; the user activates it with a Home Manager switch. Links +point at the canonical checkout, so changes in another worktree deploy only after they are merged +there. + The module is imported through `home/base/tui`, so it covers the hosts that import `home/linux/gui.nix` or the macOS `home/darwin` stack; core-only servers are unchanged. -[`home/base/tui/agents/skills.nix`](../home/base/tui/agents/skills.nix) links each custom skill -directory into `~/.agents/skills/`, leaving third-party skills unmanaged; see the module's -[global skills](../home/base/tui/agents/README.md#global-skills) section. To add a skill, create -`agents/skills//SKILL.md` and add its link there; the user activates it with a Home Manager -switch. Links point at the canonical checkout, so changes in another worktree deploy only after they -are merged there. - -The repository-root `AGENTS.md` contains guidance for this Nix configuration repository. It is not -the global rules source and is not deployed. +Permission configuration is not managed by Nix. The repository-root `AGENTS.md` contains guidance +for this Nix configuration repository only; it is not deployed. Auto-approval controls tool prompting. The global rules still define task authorization, safety, and secret handling. -## About `install-tooling.md` - -Use it as a snippet library: - -- review the commands -- select what you need -- run selected commands manually - ## TODO -Ideas worth adopting once a concrete need appears; nothing here is implemented yet. +Remaining work on the agent context, ordered by expected payoff. The goal is fewer tokens per +session and closer adherence to these rules. Done so far: the rules source rename, the move of +global skills to flake inputs (dropping superpowers, `find-skills`, and `caveman`), the i-have-adhd +always-on block, and the table-padding and duplication cleanup in the repo skills. -- **Unified third-party skill and MCP management.** Third-party skills are installed with - `npx skills` and MCP servers are configured by hand per harness; custom global skills already have - Home Manager links. A single source for the remaining tools would be nicer, though MCP config - formats differ per client. Reference: `mirkolenz/infra` `options/home-manager/agents.nix` (custom - `programs.agents`, follows the Agent Skills spec). +- **Compress the global rules** and run the Smoke scenarios afterwards. Tool execution (~600 tokens) + repeats its code-mode, Bun, and heredoc guidance; move counterexample nuance such as evidence + reuse in impactful changes into [behavioral scenarios](evals/global-rules.md). +- **Fold `mattpocock/skills` `pr` into `git-delivery`**: before/after evidence, one-way or two-way + door, and blast radius for PR bodies. +- **Write a `testing-strategy` skill**: E2E of real workflows first, unit tests for logic and edge + cases E2E cannot reach. +- **Merge `ponytail-review` with a comment and doc pruning pass** (reference: + `MidAutumnMoon/TaysiTsuki` `home/agents/skills/prune-comments-and-docs`). Worth borrowing from + `garrytan/gstack` `review/checklist.md`: a critical pass before an informational one, reading + consumers outside the diff for a new enum value or loosened validator, a do-not-flag list, and + "zero findings is valid". Keep review report-only. +- **Adapt `wayfinder` in the fork** so its map and tickets default to local Markdown and research + stays local, instead of GitHub issues and pushed `research/` branches. +- **Adapt `domain-modeling` in the fork** to record decisions in the repository's existing documents + (here `AGENTS.md`, `WORKAROUNDS.md`, `SECURITY.md`, READMEs) and create `GLOSSARY.md` or ADRs only + where none exist. +- **Trim `find-docs`**: its description (~930 characters) is the longest in the catalog and says + "always use", and its body runs `npx ctx7@latest` unpinned and suggests `npm install -g`. +- **Borrow small gstack ideas into the rules**: completion statuses (done, done with concerns, + blocked, needs context); never call a failure pre-existing without running the same check on the + base branch; a subagent with no one to ask takes the recommended option but never a destructive or + publishing one. +- **Use progressive disclosure for large repo skills.** `nix-config-umu-game` (~3.5k tokens) keeps + its troubleshooting inline; move it to a reference file. Lower priority: `nix-config-secrets` §7 + and `nixpkgs-review` §3. +- **Budget the always-loaded context in CI**: cap skill description length and rules size, as gstack + does for its catalog. +- **MCP servers** are still configured by hand per harness; they could come from the same Nix + source, though config formats differ per client. Reference: `mirkolenz/infra` + `options/home-manager/agents.nix`. ## Conventions diff --git a/agents/evals/global-rules.md b/agents/evals/global-rules.md index 5962e347..7a417987 100644 --- a/agents/evals/global-rules.md +++ b/agents/evals/global-rules.md @@ -1,7 +1,7 @@ # Global rules and skills evaluation -Use these scenarios after changing `agents/AGENTS.md` or a custom skill in `agents/skills/`, and -keep them in sync with the text they test — a stale scenario is worse than none. Formatting or +Use these scenarios after changing `agents/global-rules.md` or a custom skill in `agents/skills/`, +and keep them in sync with the text they test — a stale scenario is worse than none. Formatting or keyword checks are supplemental; they do not replace behavioral scenarios. Before adding rules or scenarios, follow the [global rule maintenance guidance](../README.md#maintaining-global-rules). diff --git a/agents/AGENTS.md b/agents/global-rules.md similarity index 91% rename from agents/AGENTS.md rename to agents/global-rules.md index c0ff4e31..25af0b9e 100644 --- a/agents/AGENTS.md +++ b/agents/global-rules.md @@ -192,7 +192,26 @@ For an impactful change, follow these steps in order, scaled to its risk: - Agents MUST respond in the user's language (default English); use English for code, commands, identifiers, comments, commit messages, PR text, and repository documentation, and keep literal UI strings and match patterns in their original language. -- Be concise, concrete, and action-oriented: lead with the next action or the answer, number - multi-step work, restate state and the requested scope across turns, suppress tangents, and make - progress visible. When a change takes effect only after a restart or activation someone else - performs, report what is applied and what is still pending. +- Restate the requested scope across turns. When a change takes effect only after a restart or + activation someone else performs, report what is applied and what is still pending. + + + +## Output style + +The reader has ADHD. Shape every response so it can be acted on: + +1. Lead with the answer or next action: command, path, or snippet first. +2. Number multi-step work; one bounded action per step. +3. End with one next action doable in under two minutes. +4. Finish the current issue before raising a new one. +5. Restate progress each turn ("step 3 of 5 done"). +6. Give time estimates in concrete units, never "a bit". +7. After a change, show what now works. +8. Errors: state location, cause, and fix. No drama. +9. Cap lists to 5 items. +10. No preamble, no recaps, no closers. + +Exceptions: explain fully when asked to explain. Confirm before destructive actions. After three failed fixes, stop and name the doubtful assumption. If the request is ambiguous, ask one short question. + diff --git a/agents/install-tooling.md b/agents/install-tooling.md index a79a48e4..e295bb8f 100644 --- a/agents/install-tooling.md +++ b/agents/install-tooling.md @@ -1,64 +1,20 @@ # Agent Tooling Commands -Reference commands for installing external agent tooling: skills via `npx skills`, the `ctx7` docs -tool, and the tuios harness integration. Keep the global set small and install task-specific skills -in the relevant project. +Reference commands for project-scoped skills and other external agent tooling. Global skills are not +installed here: they are pinned flake inputs or live in `agents/skills/`, deployed by Home Manager; +see [skills/README.md](skills/README.md). Do not install global skills with `npx skills add -g`; its +copies collide with the Home Manager links in `~/.agents/skills`. This repository's own skills live in `.agents/skills/`: they are tracked in git and discovered -automatically, so do not install, overwrite, or remove them with `npx skills`. The commands below -are for external and global skills. - -## Inspect and update installed skills - -```bash -# list all installed skills (project + global) -npx skills list - -# list only global skills -npx skills ls -g - -# check for updates -npx skills check - -# update all installed skills -npx skills update -``` +automatically, so do not install, overwrite, or remove them with `npx skills`. ## Discover skills from repositories ```bash -# list skills in a repository +# list skills in a repository without installing anything npx skills add anthropics/skills --list ``` -## Global baseline - -```bash -# structured planning, testing, debugging, review, and verification workflows -npx skills add -g obra/superpowers --skill '*' - -# discover task-specific skills when needed -npx skills add -g vercel-labs/skills --skill 'find-skills' -``` - -`find-docs` is also installed globally from a local source, so it has no upstream install command. - -## Optional global skills - -```bash -# rewrite prose to sound natural while preserving claims and technical meaning -npx skills add -g blader/humanizer --skill 'humanizer' - -# review code for unnecessary abstractions and over-engineering -npx skills add -g DietrichGebert/ponytail --skill 'ponytail-review' - -# enable a terse response mode when context or token usage matters -npx skills add -g JuliusBrussee/caveman --skill 'caveman' - -# shape replies for an ADHD reader: next action first, numbered steps, restated state -npx skills add -g ayghri/i-have-adhd --skill 'i-have-adhd' -``` - ## Optional project skills Run these commands from the project root. They intentionally omit `-g`, so the skills apply only to @@ -76,15 +32,13 @@ npx skills add anthropics/skills --skill 'webapp-testing' npx skills add anthropics/skills --skill 'pdf' # run CodeQL and Semgrep on repositories written in supported languages; not for pure Nix projects +# (CC-BY-SA-4.0: copies and modifications carry attribution and the same license) npx skills add trailofbits/skills --skill 'codeql' --skill 'semgrep' ``` ## Other agent tooling ```bash -# context7: up-to-date library docs and code examples for LLMs and agents -npx ctx7 setup - # tuios: register it as an MCP server for the harness (read-only, or --mcp-write # for typing tools); also reports agent state into the tuios pane tuios integration install opencode --mcp-write @@ -92,12 +46,7 @@ tuios integration install opencode --mcp-write References: -- https://github.com/obra/superpowers - https://github.com/vercel-labs/skills -- https://github.com/blader/humanizer -- https://github.com/DietrichGebert/ponytail -- https://github.com/JuliusBrussee/caveman -- https://github.com/ayghri/i-have-adhd - https://github.com/Gaurav-Gosain/tuios - https://github.com/anthropics/skills - https://github.com/trailofbits/skills diff --git a/agents/skills/README.md b/agents/skills/README.md new file mode 100644 index 00000000..1ce458d7 --- /dev/null +++ b/agents/skills/README.md @@ -0,0 +1,55 @@ +# Global skills + +Agent Skills shared by every agent on this machine, deployed into `~/.agents/skills/` by +[`skills.nix`](../../home/base/tui/agents/skills.nix). They come from two places: + +- **Flake inputs** (pinned in `flake.lock`): linked from the Nix store, so an update is a lock bump + plus a Home Manager switch. +- **This directory** (`agents/skills//`): skills iterated on locally, linked out-of-store so + an edit applies on the next agent session; adding or removing one needs a switch. + +Repository-scoped skills do not belong here; they live in the owning repository's `.agents/skills/`. + +## Skills from flake inputs + +| Skill | Input | Source | +| -------------------------- | ------------------- | ----------------------------------------------------------------------------------------- | +| `diagnosing-bugs` | `mattpocock-skills` | [ryan4yin/mattpocock-skills](https://github.com/ryan4yin/mattpocock-skills) `main` (fork) | +| `domain-modeling` | `mattpocock-skills` | same | +| `grill-with-docs` | `mattpocock-skills` | same | +| `grilling` | `mattpocock-skills` | same | +| `prototype` | `mattpocock-skills` | same | +| `research` | `mattpocock-skills` | same | +| `retro` | `mattpocock-skills` | same | +| `setup-matt-pocock-skills` | `mattpocock-skills` | same | +| `wayfinder` | `mattpocock-skills` | same | +| `writing-for-agents` | `mattpocock-skills` | same | +| `i-have-adhd` | `i-have-adhd` | [ryan4yin/i-have-adhd](https://github.com/ryan4yin/i-have-adhd) `main` (fork) | +| `humanizer` | `humanizer` | [blader/humanizer](https://github.com/blader/humanizer) `v3.1.0` | +| `find-docs` | `context7` | [upstash/context7](https://github.com/upstash/context7) commit `522c4db4` | +| `ponytail-review` | `ponytail` | [DietrichGebert/ponytail](https://github.com/DietrichGebert/ponytail) `v5.1.0` | + +Dependencies travel together: `grill-with-docs` and `wayfinder` call `grilling` and +`domain-modeling`; `wayfinder` also calls `research` and `prototype`, and points at +`setup-matt-pocock-skills` for the issue-tracker convention; `retro` calls `writing-for-agents`. + +User-invoked skills (`disable-model-invocation: true`, plus `allow_implicit_invocation: false` in +`agents/openai.yaml` for Codex) stay out of the model's skill catalog: `grill-with-docs`, +`wayfinder`, `retro`, `setup-matt-pocock-skills`, and `i-have-adhd`. The global rules embed the +i-have-adhd always-on snippet, so the skill is only needed for its full ruleset. + +The global rules take precedence over these skills. In particular, `wayfinder` defaults to GitHub +issues and pushes research branches; both are GitHub writes that need authorization, and a public +repository is the wrong place for an infrastructure decision map. + +To update one: review the upstream diff as untrusted input, then `nix flake update ` (or move +the pinned tag/commit in `flake.nix`) and check `git diff flake.lock`. + +## Skills in this directory + +`git-delivery` is maintained here rather than pulled from an input: commit messages, PR text, review +replies, and cleanup after merge, all following the target repository's conventions. Edit it in +place; the change reaches the next agent session without a switch. + +A third-party skill starts here only when it is being rewritten. Until then, pin it as a flake input +so the license and provenance stay with the upstream repository and the diff stays reviewable. diff --git a/flake.lock b/flake.lock index ea36a9d6..eeec27f4 100644 --- a/flake.lock +++ b/flake.lock @@ -109,6 +109,23 @@ "type": "github" } }, + "context7": { + "flake": false, + "locked": { + "lastModified": 1791560179, + "narHash": "sha256-cChMAOd8cYTcNZt0AaUcJ4G+tT0w/64PRsbKJ3ADeY8=", + "owner": "upstash", + "repo": "context7", + "rev": "522c4db4fa2e1e31f1b320f09fa8c8fab376987a", + "type": "github" + }, + "original": { + "owner": "upstash", + "repo": "context7", + "rev": "522c4db4fa2e1e31f1b320f09fa8c8fab376987a", + "type": "github" + } + }, "crane": { "locked": { "lastModified": 1781825982, @@ -536,6 +553,39 @@ "type": "github" } }, + "humanizer": { + "flake": false, + "locked": { + "lastModified": 1790574878, + "narHash": "sha256-n8cbTzhlGf8VnWpPukq7XD2mucIrqyE1XMpAAc5oA8A=", + "owner": "blader", + "repo": "humanizer", + "rev": "225a6f39ac85f76ee48dbad772ea4abe4ed6c9d8", + "type": "github" + }, + "original": { + "owner": "blader", + "ref": "v3.1.0", + "repo": "humanizer", + "type": "github" + } + }, + "i-have-adhd": { + "flake": false, + "locked": { + "lastModified": 1791329026, + "narHash": "sha256-5EYLKtrg0RQN0CHR51Sc2qSkgYklu6lqzuH87Dp3gv4=", + "owner": "ryan4yin", + "repo": "i-have-adhd", + "rev": "723af7d9afaf43eb871dbcce6129e2bf80de90d5", + "type": "github" + }, + "original": { + "owner": "ryan4yin", + "repo": "i-have-adhd", + "type": "github" + } + }, "lanzaboote": { "inputs": { "crane": "crane", @@ -584,6 +634,22 @@ "type": "github" } }, + "mattpocock-skills": { + "flake": false, + "locked": { + "lastModified": 1791543409, + "narHash": "sha256-NljCSZNI3sZ+vbCw7pRdrwR7try4BxOFp4gdjuWYtzs=", + "owner": "ryan4yin", + "repo": "mattpocock-skills", + "rev": "49dd158d1076134a641b33efb035946536778336", + "type": "github" + }, + "original": { + "owner": "ryan4yin", + "repo": "mattpocock-skills", + "type": "github" + } + }, "microvm": { "inputs": { "nixpkgs": [ @@ -975,6 +1041,23 @@ "type": "github" } }, + "ponytail": { + "flake": false, + "locked": { + "lastModified": 1791476378, + "narHash": "sha256-diYM3gqcEboVi7OQff/SvlE0TKAIPTJDIggX7rZWslY=", + "owner": "DietrichGebert", + "repo": "ponytail", + "rev": "9cc65d03aa2da1db7121b912d03596409ee340b8", + "type": "github" + }, + "original": { + "owner": "DietrichGebert", + "ref": "v5.1.0", + "repo": "ponytail", + "type": "github" + } + }, "pre-commit": { "inputs": { "flake-compat": "flake-compat_2", @@ -1060,12 +1143,16 @@ "agenix": "agenix", "catppuccin": "catppuccin", "colmena": "colmena", + "context7": "context7", "disko": "disko", "fcitx5-vinput": "fcitx5-vinput", "haumea": "haumea", "home-manager": "home-manager", + "humanizer": "humanizer", + "i-have-adhd": "i-have-adhd", "lanzaboote": "lanzaboote", "llm-agents": "llm-agents", + "mattpocock-skills": "mattpocock-skills", "microvm": "microvm", "my-asahi-firmware": "my-asahi-firmware", "mysecrets": "mysecrets", @@ -1083,6 +1170,7 @@ "nixpkgs-stable": "nixpkgs-stable", "nu_scripts": "nu_scripts", "nur-ryan4yin": "nur-ryan4yin", + "ponytail": "ponytail", "pre-commit-hooks": "pre-commit-hooks", "preservation": "preservation", "pyclipsync": "pyclipsync", diff --git a/flake.nix b/flake.nix index a220937b..b0ffa8d8 100644 --- a/flake.nix +++ b/flake.nix @@ -173,6 +173,32 @@ flake = false; }; + # Global agent skills, linked into ~/.agents/skills by + # home/base/tui/agents/skills.nix. The ryan4yin forks track main; a fork sync + # pulls upstream changes, so review the lock diff before deploying it. + mattpocock-skills = { + url = "github:ryan4yin/mattpocock-skills"; + flake = false; + }; + i-have-adhd = { + url = "github:ryan4yin/i-have-adhd"; + flake = false; + }; + # Third-party skills pinned to a tag or commit; bump deliberately. + humanizer = { + url = "github:blader/humanizer/v3.1.0"; + flake = false; + }; + ponytail = { + url = "github:DietrichGebert/ponytail/v5.1.0"; + flake = false; + }; + # context7's release tags predate skills/find-docs, so pin a commit. + context7 = { + url = "github:upstash/context7/522c4db4fa2e1e31f1b320f09fa8c8fab376987a"; + flake = false; + }; + ######################## My own repositories ######################################### # my private secrets, it's a private repository, you need to replace it with your own. diff --git a/home/base/tui/agents/README.md b/home/base/tui/agents/README.md index c85a09a4..b469863c 100644 --- a/home/base/tui/agents/README.md +++ b/home/base/tui/agents/README.md @@ -3,14 +3,16 @@ Home Manager module that owns the Nix side of the AI coding agents: deploying the global rules and custom global skills, the agent CLIs, and their environment. -The canonical rules text, behavioral scenarios, and external-tool snippets live in the top-level -[`agents/`](../../../../agents/README.md) directory. That directory stays portable Markdown with no -Nix dependency; this module only wires it into place. +The canonical rules text, local skills, behavioral scenarios, and external-tool snippets live in the +top-level [`agents/`](../../../../agents/README.md) directory. That directory stays portable +Markdown with no Nix dependency; this module only wires it into place. ## Files - `rules.nix`: links the global rules to every agent's config location. -- `skills.nix`: links individual custom global skills into `~/.agents/skills/`. +- `skills.nix`: links the global skills into `~/.agents/skills/`, from pinned flake inputs and + from `agents/skills/`; the inventory is + [agents/skills/README.md](../../../../agents/skills/README.md). - `packages.nix`: agent CLIs (`codex`, `opencode2`, `pi`) from the `llm-agents` flake input, plus `pkgs.mcp-grafana` for the Grafana MCP server. - `env.nix`: telemetry and auto-update opt-outs for the agents. @@ -22,7 +24,7 @@ settings that bite. ## Deployed rule targets `rules.nix` creates one out-of-store symlink per target, all pointing at -`~/nix-config/agents/AGENTS.md`: +`~/nix-config/agents/global-rules.md`: | Agent | Target | | ---------- | ------------------------------ | @@ -35,17 +37,18 @@ settings that bite. dsh reads both `~/.dsh/AGENTS.md` (`$DSH_HOME`) and, from `0.2.1-alpha.2` on, `~/.agents/AGENTS.md` (`$DSH_AGENTS_HOME`); identical content renders once. -Out-of-store means an edit to `agents/AGENTS.md` takes effect on the next agent session without a -Home Manager switch. The trade-off is that the rules stay writable in the checkout; use a store -symlink (`home.file..source = ../../../../agents/AGENTS.md`) if immutability matters more -than fast iteration. +Out-of-store means an edit to `agents/global-rules.md` takes effect on the next agent session +without a Home Manager switch. The trade-off is that the rules stay writable in the checkout; use a +store symlink (`home.file..source = ../../../../agents/global-rules.md`) if immutability +matters more than fast iteration. ## Global skills -`skills.nix` links `~/nix-config/agents/skills/git-delivery` into `~/.agents/skills/git-delivery` -using the same out-of-store mechanism. Each custom skill gets an explicit link; the parent directory -and third-party skills remain unmanaged. Home Manager's normal collision checks apply: do not force -replacement of an existing same-name skill. +`skills.nix` links every directory under `agents/skills/` out-of-store, so an edit applies on the +next session, and the skills selected from pinned flake inputs as store paths, which change only +with a lock bump and a switch. Home Manager's normal collision checks apply: do not force +replacement of an existing same-name skill, and do not install global skills with +`npx skills add -g` alongside these links. The installed releases support the shared root and symlinked skill directories, so no agent-specific compatibility links are needed: @@ -63,4 +66,4 @@ them. After activation, verify the link target and that `git-delivery` appears i Custom root overrides or disabled discovery still need runtime configuration. The rules include a direct checkout fallback for `git-delivery` before its link is installed. -Third-party skills and runtime permissions are not managed by this module. +Runtime permissions are not managed by this module. diff --git a/home/base/tui/agents/dsh.md b/home/base/tui/agents/dsh.md index 30c0b6b2..da3b5657 100644 --- a/home/base/tui/agents/dsh.md +++ b/home/base/tui/agents/dsh.md @@ -43,8 +43,8 @@ In this repository, `just dsh-web` boots the web profile through mihomo's mixed ## Global rules `dsh-base` already mounts `dsh-agent-instructions` (`maxBytes: 65536`) and `rules.nix` links -`agents/AGENTS.md` into both scopes it reads — `$DSH_HOME/AGENTS.md` and, from `0.2.1-alpha.2` on, -`$DSH_AGENTS_HOME/AGENTS.md` — so no patch row is needed; identical content renders once. +`agents/global-rules.md` into both scopes it reads — `$DSH_HOME/AGENTS.md` and, from `0.2.1-alpha.2` +on, `$DSH_AGENTS_HOME/AGENTS.md` — so no patch row is needed; identical content renders once. - The scopes come from the environment: `0.2.1-alpha.2` removed the row's `dshHome` / `agentsHome`. - Nested `AGENTS.md` files are discovered by `read` / `write` / `edit`, not by `cd` inside `bash`, diff --git a/home/base/tui/agents/rules.nix b/home/base/tui/agents/rules.nix index 7d1f2e34..ec18559e 100644 --- a/home/base/tui/agents/rules.nix +++ b/home/base/tui/agents/rules.nix @@ -3,8 +3,9 @@ let # The global rules are edited often, so link them out-of-store: an edit reaches # the next agent session without a Home Manager switch. Same rationale as # `home/base/tui/tuios`; the checkout path is hardcoded, like the repo's other - # out-of-store links. - rules = "${config.home.homeDirectory}/nix-config/agents/AGENTS.md"; + # out-of-store links. The source is not named AGENTS.md, so agents working in + # this checkout do not load it a second time as nested instructions for agents/. + rules = "${config.home.homeDirectory}/nix-config/agents/global-rules.md"; link = config.lib.file.mkOutOfStoreSymlink rules; in { diff --git a/home/base/tui/agents/skills.nix b/home/base/tui/agents/skills.nix index d3464fb0..c4558cee 100644 --- a/home/base/tui/agents/skills.nix +++ b/home/base/tui/agents/skills.nix @@ -1,8 +1,75 @@ -{ config, ... }: +{ + config, + lib, + mattpocock-skills, + i-have-adhd, + humanizer, + ponytail, + context7, + ... +}: let - skill = config.lib.file.mkOutOfStoreSymlink "${config.home.homeDirectory}/nix-config/agents/skills/git-delivery"; + # Skills kept in this repository (agents/skills/) are linked + # out-of-store, like the rules, so an edit reaches the next agent session + # without a switch; adding or removing one still needs a switch. + local = ../../../../agents/skills; + checkout = "${config.home.homeDirectory}/nix-config/agents/skills"; + localNames = lib.attrNames ( + lib.filterAttrs (name: type: type == "directory") (builtins.readDir local) + ); + + # Skills taken from flake inputs: name -> directory in the input. Dependencies + # travel together: grill-with-docs and wayfinder call grilling and + # domain-modeling, wayfinder also calls research and prototype and points at + # setup-matt-pocock-skills, and retro calls writing-for-agents. + upstream = + let + mp = "${mattpocock-skills}/skills"; + in + { + diagnosing-bugs = "${mp}/engineering/diagnosing-bugs"; + domain-modeling = "${mp}/engineering/domain-modeling"; + grill-with-docs = "${mp}/engineering/grill-with-docs"; + grilling = "${mp}/productivity/grilling"; + prototype = "${mp}/engineering/prototype"; + research = "${mp}/engineering/research"; + retro = "${mp}/engineering/retro"; + setup-matt-pocock-skills = "${mp}/engineering/setup-matt-pocock-skills"; + wayfinder = "${mp}/engineering/wayfinder"; + writing-for-agents = "${mp}/productivity/writing-for-agents"; + + i-have-adhd = "${i-have-adhd}/skills/i-have-adhd"; + find-docs = "${context7}/skills/find-docs"; + ponytail-review = "${ponytail}/skills/ponytail-review"; + }; + + # humanizer's skill is its repository root, which also carries an AGENTS.md + # meant for its own contributors; link only the files the skill uses. + humanizerFiles = { + ".agents/skills/humanizer/SKILL.md".source = "${humanizer}/SKILL.md"; + ".agents/skills/humanizer/agents".source = "${humanizer}/agents"; + }; in { - # Link each custom skill separately so third-party skills remain unmanaged. - home.file.".agents/skills/git-delivery".source = skill; + assertions = [ + { + assertion = lib.all (name: !(upstream ? ${name}) && name != "humanizer") localNames; + message = "agents/skills and the upstream skill set define the same skill name"; + } + ]; + + # ~/.agents/skills is the cross-tool Agent Skills scope. + home.file = + lib.listToAttrs ( + map ( + name: + lib.nameValuePair ".agents/skills/${name}" { + source = config.lib.file.mkOutOfStoreSymlink "${checkout}/${name}"; + } + ) localNames + ) + // lib.mapAttrs' ( + name: path: lib.nameValuePair ".agents/skills/${name}" { source = path; } + ) upstream + // humanizerFiles; }