This repository lives at ~/.agents. It selects community skills and deploys
harness configuration. Personal skills and prompts live outside this checkout,
in ~/profile. Each harness keeps its own writable home and runtime state.
~/.agents/
├── agents apply, sync, doctor, and skill commands
├── skills.json community skill selections
├── skills.lock exact upstream Git commits
├── skills/ generated community content, ignored by Git
├── pi/ Pi configuration and bootstrap
├── org/ Org agent system: dispatcher, prompts, herdr-link, skills
├── opencode/ OpenCode configuration and bootstrap
├── hermes/ Hermes configuration and bootstrap
├── claude/ Claude preferences, instructions, and managed-entry adapter
├── lib/ resolver and deployment helpers
├── tests/ isolated local fixtures
├── flake.nix harness packages
└── flake.lock
~/profile/
├── skills/ personal authored skills and supporting files
└── prompts/ personal user-invoked templates
Commit community selections and their lock, not downloaded skills. Do not edit
skills/ by hand. Personal content has its own ownership and synchronization;
this repository does not pull, commit, or push ~/profile. The exceptions
are project-org-tasks and org-triage: they live in org/skills/, and
~/profile/skills links to them. See org/README.org. There is no
~/profile/agents/ layer. The recall-history personal skill remains a symlink
to its independently maintained Recall checkout. That checkout must be present
on any machine using that link.
| Harness | Default writable home | Shared skill discovery |
|---|---|---|
| Pi | ~/.pi/agent | settings.json skills paths |
| OpenCode | ~/.config/opencode | opencode.json skills.paths |
| Hermes | ~/.hermes | config.yaml skills.external_dirs |
| Claude Code | ~/.claude | Managed individual links under skills/ |
Pi, OpenCode, and Hermes refer to ~/.agents/skills and ~/profile/skills
in place. Their native local skill directories remain active and untouched.
Claude Code has no arbitrary skill-root setting. Its adapter installs individual
links to these same sources, not a link over the whole native skills/ directory.
Native skills, synced skills, plugins, auth, sessions, and memories remain
harness-owned. Shared names must not collide with personal or native skill names.
The executable resolves its checkout from its own path, not the working directory.
~/.agents/agents apply
~/.agents/agents doctor
~/.agents/agents sync
~/.agents/agents skill list
~/.agents/agents skill add pdf https://github.com/anthropics/skills.git --path skills/pdf --ref main
~/.agents/agents skill remove pdf
~/.agents/agents skill updateapply validates the manifest/lock, personal layout, duplicate skill names,
prompt contract, and enabled harness destinations before writing. It reuses a
materialization whose recorded revisions, contents, and modes match the lock.
If that tree is missing or changed, it fetches exact locked commits into a
staging directory, validates every selected skill, and replaces only the generated
tree. It never advances upstream refs or changes the lock. Valid repeat applies
need no network and leave unchanged files in place. A first or repaired apply
needs upstream access. Failed fetches preserve the existing tree, lock, and homes.
The generated skills/.state.json records selected revisions and file hashes
and modes. It detects accidental drift without fetching; it is not a signature
or protection against someone changing both the files and that record. The
resolver rejects nested skills, submodules, symlinks, and special files in
community selections. It runs no upstream installers, build scripts, or helpers.
Git sources must retain locked commits for future reproduction.
sync requires a clean attached branch with a tracking upstream and no pending
Git operation. It refuses local-only or diverged commits before pulling, then
runs git pull --ff-only. A stale tracking ref cannot permit a merge: the actual
pull must also fast-forward. It never stashes, resets, rebases, merges, or pushes.
After a successful pull, it executes the newly pulled agents apply entrypoint.
A failed pull never applies configuration. Skill revisions still do not advance.
doctor performs read-only checks. It reports repository state, lock agreement,
materialized drift, personal roots, names, prompts, dependencies, enabled harnesses,
and deployed files. Missing or mismatched deployment returns nonzero. It does not
fetch, create roots, repair configuration, contact services, or refresh the Git
index. An absent personal root is optional; a malformed existing root is an error.
Missing harness binaries are reported without preventing config-only deployment.
This checks deployment, not login, provider availability, or live skill invocation.
All four adapters are enabled by default. Limit local deployment with:
AGENTS_HARNESSES=pi,claude ~/.agents/agents applyAGENTS_HARNESSES accepts unique comma- or space-separated harness names. The
same setting controls doctor. Invalid or empty selections fail. Bootstrap
helpers need Bash, GNU coreutils, Python 3, Git, jq for Pi/OpenCode, and Mike
Farah’s yq v4 for Hermes. On NixOS, use nix shell when a tool is missing.
name and git are required. Names must match upstream SKILL.md frontmatter,
use lowercase letters/digits separated by single hyphens, and be at most 64
characters. --path defaults to . and --ref defaults to HEAD. A ref can
be a branch, tag, or commit. Sources may be Git URLs, SSH sources, or absolute
local repository paths. Paths must stay inside the upstream repository.
Unknown fields, duplicate JSON keys, duplicate selections, invalid layouts,
collisions, and fetch failures leave source files and materialization unchanged.
skill add and skill remove update selection, lock, and tree together after
preflight. Other selected skills remain at their existing locked revisions.
skill update explicitly advances all selected refs and rebuilds the lock;
it also resolves deliberate edits to skills.json. These commands do not
apply runtime configuration. Run agents apply afterward.
Current upstream selections are Impeccable, Superpowers’ systematic-debugging,
Vercel’s web-design-guidelines, and Unslop from Cursor’s pstack plugin.
The former local name ui-guidelines-review is retired. No local maintained
forks are kept active.
Unslop’s upstream skill sets disable-model-invocation: true. Harnesses that
honor this field require explicit invocation rather than automatic selection.
Impeccable’s Git skill is pinned, but its launcher may download a separate
versioned engine into ~/.impeccable/ when used. That engine is not pinned by
skills.lock and has not been tested here. Review upstream instructions before
running it. Vercel’s skill fetches current web-interface guidelines during a
review, so pinning the skill does not freeze those guidelines either.
Store flat, regular <lowercase-name>.md files in ~/profile/prompts/. Nested
files and symlinks are rejected. Begin with exactly these three frontmatter lines:
---
description: Review changes
---Descriptions must start with a letter and contain plain letters, digits, spaces,
commas, periods, slashes, parentheses, underscores, or hyphens, with no trailing
spaces. YAML boolean/null words are rejected. Use $ARGUMENTS for optional input.
Do not use numbered placeholders, $@, shell interpolation, @file imports,
or harness-only metadata in shared templates.
Pi copies templates into prompts/ and OpenCode into commands/. Both make
writable atomic copies and preserve unrelated commands. They do not delete
retired personal copies automatically. Claude copies them into commands/ and
adds disable-model-invocation: true so templates remain user-invoked. Hermes
has no shared slash-command prompt adapter. Keep harness-only templates under
pi/prompts/, opencode/commands/, or claude/commands/. Shared/specific filename
collisions fail instead of relying on copy order.
Claude gives a skill priority over a same-name command file. For example,
/impeccable uses its linked upstream skill even when the personal alias is
installed. Pi supports /skill:impeccable as well as the personal prompt alias.
Use /reload in Pi or start a new harness session after resource changes.
~/.agents/pi/bootstrap
~/.agents/opencode/bootstrap
~/.agents/hermes/bootstrap
~/.agents/claude/bootstrapEach bootstrap handles its own declared configuration and local preflight. It
does not run the shared resolver, fetch skills, or certify global lock agreement.
Use agents apply for complete deployment. bootstrap --check is a read-only
adapter preflight. Claude also supports bootstrap --verify.
Override destinations with PI_CODING_AGENT_DIR, OPENCODE_CONFIG_DIR,
OPENCODE_DIR, HERMES_HOME, or CLAUDE_CONFIG_DIR. OpenCode also honors
XDG_CONFIG_HOME. Tests set a temporary HOME with isolated profile roots.
Source-tree destinations, the home root, and managed directory symlinks are
rejected before writes. Named file symlinks become writable copies without
changing their targets. There are no whole-home source/store symlinks.
Pi deep-merges declared settings and preserves unknown keys. It retires the
old subagents setting and MCP-adapter cache files. Declared files, extensions,
prompts, and themes are refreshed without removing unrelated entries. A
machine-generated themes/stylix.json survives. pi/fix-dcp-package repairs
pi-dcp’s incorrectly published TypeBox dependency without changing extension
code. Pi packages and package-provided skills remain Pi-managed.
OpenCode refreshes its named config, agents, commands, and themes. Existing native skills, Git metadata, local commands, and other files stay in place.
Hermes deep-merges YAML maps. Declared scalars and whole lists win; unrelated
settings and comments survive. Invalid, non-mapping, or multi-document YAML
fails without overwriting it. SOUL.md remains a writable declared copy.
Hermes uses the named custom:codex-lb Responses provider, native Camofox browser,
and its native web/vision tools. Services, browser profiles, secrets, and the
Herdr/Pi launch integration remain separate machine configuration.
Claude merges claude/settings.json into the writable user settings at
~/.claude/settings.json, or under CLAUDE_CONFIG_DIR when set. Declared
preferences win; unrelated keys, hooks, environment variables, plugin options,
and model selections survive. Per-model effort entries are defaults only:
existing effort levels and compaction preferences take precedence. Repeat
applies leave unchanged files in place. Before changing existing settings or
instruction content, the adapter saves a private 0600 copy in the destination’s
backups/agents-<filename>.*. Settings keep their existing mode with owner
read/write access ensured, or use 0600 when first created. No credentials,
caches, or session state enter this checkout.
The Claude adapter also pre-trusts existing ~/src and ~/org directories and
Git repositories beneath them. Paths come from the current user’s home directory,
not a fixed username. Each agents apply scans again, so new clones are picked
up on the next apply. Directory symlinks are not traversed. Worktrees use their
main checkout’s trust entry, as Claude requires. This grants workspace trust to
projects in those trees, including their project hooks and other startup code.
Trust is separate from the permission mode. The adapter merges only
projects["<path>"].hasTrustDialogAccepted: true into ~/.claude.json, or
$CLAUDE_CONFIG_DIR/.claude.json when set. Existing auth, MCP configuration,
project history, and other state survive. Before a change, it saves a private
backup under the Claude destination’s backups/ directory and writes the state
atomically with mode 0600. Repeat applies leave unchanged state alone.
agents doctor checks trust without changing it. No live state is copied into
this repository. See Claude’s workspace trust rules.
claude/AGENTS.md holds the existing global instructions. The deployed
~/.claude/CLAUDE.md contains only @AGENTS.md because Claude’s global user
instruction loader requires that filename. It imports the adjacent writable
AGENTS.md copy, without repeating its prose. Project AGENTS.md files load
through Claude’s built-in plugin, alongside any existing CLAUDE.md. The plugin
skips instructions already imported or linked by path or content. The adapter
does not create project CLAUDE.md files or install third-party plugins.
Claude records only its own skill links and prompt copies in
~/.claude/.agents-managed.json. It removes deselected entries only when they
still match that record. If a managed entry was changed locally or a native
entry occupies its name, apply fails without overwriting it. Rename or preserve
the conflicting entry explicitly. Curated Claude-only commands can live in
claude/commands/.
The declared settings target Claude Code 2.1.291. They use user scope, which built-in plugin options require.
- Start in
automode. Use--permission-modeor the normal session controls to change modes temporarily. No allowlist or permission wrapper is added. - Set
attributionto emptycommitandprstrings andsessionUrl: falseto omit commit trailers, PR attribution, and session links. This is the form Claude stores;attribution: falseis equivalent on 2.1.281 or later. - Use
tui: "fullscreen"andCLAUDE_CODE_DISABLE_TERMINAL_TITLEset to1. Pi’s existing fullscreen setting remains unchanged. - Disable auto memory, built-in Git instructions and the initial Git snapshot, spinner tips, prompt suggestions, and feedback drafts.
- Retain transcripts for 365 days. Automatic compaction, session history, and file checkpoints remain enabled by default.
- Use high effort without selecting a model. Top-level
effortLevelcovers older models. User-level preferences for Opus 5.5 and Sonnet 5.5 need canonicalmodelSettingsentries. Existing per-model choices survive apply. For later models, run/effort highonce to save the preference for that model. - Enable
cc-plugin-agents-md@builtinand set itsinstructionFilesoption toclaude-md-and-agents-md. The plugin was renamed in 2.1.285. The oldagents-md@builtinoption key still works, but this configuration uses the installed version’s ID.
See Claude’s settings reference,
model and effort settings, and
instruction loading. Run claude doctor to check installation and settings,
and /memory in a session to inspect loaded instruction paths. On a new machine,
start claude and complete login and first-run confirmations. Keep auth and
interactive application state in Claude’s writable home, not in this repository.
The existing NixOS Home Manager module at
/etc/nixos/modules/home/default/options/claude-code.nix supplies this flake’s
package and persists writable ~/.claude/ and ~/.claude.json. No new machine
module or runtime-file declaration is needed for these preferences.
The flake exports pi, opencode, hermes-agent, and claude-code from the
existing Numtide llm-agents input. Pi remains default and uses its Node build so
codemode’s worker is available. The wrapper pins its own package asset directory.
nix build .#pi .#opencode .#hermes-agent .#claude-code
nix run .#claude-code -- --versionHome Manager owns package installation, persistence, secrets, services, and
machine integrations. Mutable agents apply and agents sync are interactive
operations, not activation prerequisites. Activation must not fetch this
checkout or validate mutable skill/profile content. Missing checkouts, absent
personal roots, and stale locks must not block a NixOS rebuild.
The system repository has not been changed by this refactor. Its old
harnesses/ paths and activation bootstrap calls require a separate migration.
That handoff is recorded in the Agents Org project, outside this repository.
Until it is applied, do not assume the existing activation uses this new layout.
For default Claude Code paths, persist ~/.claude/ and ~/.claude.json.
The directory holds settings, skills, commands, plugins, Linux login credentials,
transcripts, prompt history, file snapshots, and auto memory. The separate JSON
file holds application state including project trust, OAuth-related state, and
personal MCP configuration. A custom CLAUDE_CONFIG_DIR changes the directory;
verify actual paths before persisting an override. These are mutable private
files, never repository files or read-only store links.
See Claude’s skill locations and symlink support, directory and application-data reference, and instruction and memory locations. Authenticated sessions and provider access are not part of credential-free deployment tests.
python3 -B tests/test_skills.py
python3 -B tests/test_agents.py
pi/test-bootstrap
opencode/test-bootstrap
hermes/test-bootstrap
tests/test-prompts
tests/test-update-flake-lock
org/tests/test-org-dispatchFixtures use temporary homes and local Git repositories. They cover locked
reproduction, failed fetches, malformed inputs, collisions, state preservation,
repeat runs, read-only doctor, and conservative sync. No test depends on personal
content being present on the CI host. pi/test-codemode separately checks the
packaged codemode worker. The daily lock-update workflow also builds and smoke
tests all four packages before publishing a package-lock change.