# agent-skills Single source of truth for custom agent skills + commands. Shared across **Claude Code** and **Codex**, every machine. ## Layout ``` skills/ # SKILL.md dirs — Claude Code AND Codex both read these (open Agent Skills standard) commands/ # slash commands — Claude Code only (Codex ignores) hooks/ # Claude Code hooks — see hooks/README.md, wiring is manual claude-md/ # CLAUDE.md fragments — linked to ~/.claude/, imported via @name.md bin/link.sh # bootstrap symlinks for non-Nix machines nix/home.nix # home-manager module for NixOS machines flake.nix # exposes homeModules.default ``` Skills are portable: only `name`+`description` frontmatter is required by both tools; Claude-only fields (`user-invocable`, `args`) are ignored by Codex. Cross-skill refs use root-relative paths (`linear-common/COMMON.md`), so they resolve under `~/.claude/skills` and `~/.agents/skills` alike. ## Install ### Non-Nix machine (e.g. dev VM) ```sh git clone https://git.naps.pt/yolo/agent-skills.git ~/tea/yolo/agent-skills ~/tea/yolo/agent-skills/bin/link.sh ``` Symlinks each skill into `~/.claude/skills/` and `~/.agents/skills/`, commands into `~/.claude/commands/`, hooks into `~/.claude/hooks/`, `claude-md/` fragments into `~/.claude/`. Idempotent; any pre-existing real dir is moved to `~/.agent-skills-backup/` (outside the discovery path, so it isn't picked up as a duplicate skill). Re-run after adding a skill. Hooks and fragments need one manual step each: the `settings.json` snippet in `hooks/README.md`, and an `@writing.md` import line in your `~/.claude/CLAUDE.md`. Codex needs no step — `~/.agents/AGENTS.md` is linked directly. ### NixOS machine (home-manager) ```nix # flake inputs inputs.agent-skills.url = "git+https://git.naps.pt/yolo/agent-skills.git"; # home config imports imports = [ inputs.agent-skills.homeModules.default ]; ``` `recursive = true` links files individually, so machine-local skills can coexist in the same dir. `nixos-rebuild switch` to apply/update. ## Shared machine, many sessions Several autonomous runs share one box. `skills/linear-common/scripts/gate.sh` is a machine-wide semaphore for heavy commands (full test suites, whole-project builds): bounded slots, memory + CPU cap via a systemd user scope, pinned build/test parallelism. Skills run scoped checks in the inner loop and put only the once-per-push full suite through the gate; exit 75 means it never ran and CI takes over. Policy lives in `linear-common/COMMON.md` under "Local verification budget". ```sh ~/.claude/skills/linear-common/scripts/gate.sh --status AGENT_GATE_SLOTS=3 AGENT_GATE_MEM_MAX=4G ~/.claude/skills/linear-common/scripts/gate.sh -- cargo test ``` ## Adding a skill Drop a new `skills//SKILL.md` (+ optional `scripts/`, `references/`, `assets/`). Commit. Non-Nix: re-run `bin/link.sh`. Nix: rebuild. ## Skills | skill | what | |-------|------| | `work` | tracker issue → worktree → PR → hands off to `land` | | `yolo` | quick ship; optional `land` handoff | | `land` | drive an open PR to green + ready-to-merge; user clicks merge (canonical CI/review loop) | | `blitz` | drive a whole milestone to done | | `nightshift` | hours-long unattended build; architect delegating to subagents, backs off before the 5h limit | | `linear-common` | shared config/setup/worktree conventions + local verification budget (dependency of work/yolo/blitz/nightshift) | | `crit`, `humanizer`, `impeccable`, `improve-codebase-architecture` | misc | ## Writing contract One contract, `claude-md/writing.md`, linked three ways: `~/.claude/writing.md` (imported via `@writing.md`), `~/.agents/AGENTS.md` (Codex, which has no `@import`), and the nix module for NixOS machines. The rule it encodes is **selection, not compression**: keep output short by cutting whole ideas that don't change what the reader does next, then write what survives as plain sentences. Not by dropping articles, abbreviating, or writing fragments — that is shorter and worse. Anthropic's Fable 5 and Opus 5 prompting guides both say this explicitly. Two enforcers in `hooks/`: | enforcer | scope | |----------|-------| | `comms-lint.py` | GitHub issues/PRs/review comments — 150 words (hard cap 300), evidence in `
`, no reviewer-addressing opener, plain diction | | `comment-lint.py` | code comments — 1-3 lines, volume and purpose, not wording | Written in the voice it asks for, and leads with a worked example of each. Prompt style leaks into output style, and examples steer harder than prohibitions, so the file is short and shows rather than forbids. Prose alone drifts; the linters make it binding. Details in `hooks/README.md`.