Toolkit and template for keeping one set of agent instructions across machines
and CLIs (Claude Code, Codex CLI, PI, Hermes, and anything listed in
agents.toml). Create a private config repo from this template, edit there,
agents sync, done.
This repo can be used as the tool/template source. Each user should keep their actual agent instructions in a separate config repo, usually private:
TOOL_REPO="${TOOL_REPO:-$HOME/projects/agents}"
gh repo clone OverseedAI/agents "$TOOL_REPO"
"$TOOL_REPO/apply.sh" init "$HOME/projects/my-agents-config"Then edit shared/core.md in the new config repo, delete the TEMPLATE-FILL-ME
comment, and apply it:
cd "$HOME/projects/my-agents-config"
./apply.sh apply$HOME/projects/my-agents-config is just an example. The repo can live anywhere; after
apply, agents repo prints the clone path the installed CLI is using. If you
move the repo later, run ./apply.sh apply from the new location to refresh
the symlinks.
If the machine isn't recognized, apply asks you interactively to register it
(non-interactive runs get the manual one-liner instead). After that, the agents
command is on your PATH (via ~/.local/bin).
If the new machine has hand-written CLAUDE.md/AGENTS.md, a first plain apply
won't overwrite them blind: it salvages each pre-existing file to
~/.local/state/agents/drift/ before rendering the shared config over it, and
agents status nags until you deal with them. Diff the salvaged copy against what
got deployed and fold anything machine-specific into your host layer:
diff <(agents render claude) ~/.local/state/agents/drift/claude-*.md
agents edit host # paste machine-specific bits into hosts/<host>/host.md
agents sync
rm ~/.local/state/agents/drift/* # once you've folded in what you wantagents init ~/projects/my-agents-config # create a private config repo from the template
agents add "never use emojis" # capture an instruction → rendered + synced, one command
agents add -a codex "…" # scope to one agent; -H laptop scopes to one machine
agents skill list # shared skills + local-only ones worth importing
agents skill show <name> # print a skill's full SKILL.md
agents skill add <name|path> # scaffold a new shared skill, or import an existing dir
agents skill rm <name> # remove everywhere; offers to delete stray local copies
agents sync # pull → re-render → commit local edits → push (the one command)
agents update # pull latest changes → re-render, without committing/pushing
agents status # drift check + ahead/behind origin
agents edit # edit shared/core.md in $EDITOR + sync (also: edit <agent>|host|<path>; edit repo = whole repo)
agents doctor # environment checks (auth, PATH, host mapping) + status
agents publish-check # conservative preflight before making a repo public
agents auto on # hourly auto-pull via crontab — set-and-forget for always-on machinesagents help lists everything; agents help <command> (or agents <command> --help)
explains any command in detail, with examples.
agents add drops captures under a ## Quick notes section in the right layer file —
fold them into proper sections whenever you're in the editor anyway.
agents update (alias: agents pull, used by auto mode) only pulls and
re-renders — it never commits or pushes, so automation can't publish half-finished
edits; publishing stays manual via sync.
Agents themselves know this procedure too: the shared agent-config skill routes
"remember this / update your config" requests to this repo instead of their own folders.
You shouldn't configure each AI agent separately, and an agent shouldn't forget who you are because you switched tools or machines. Preferences are stated once, in plain markdown, in one versioned place — and every agent everywhere renders from it. The translation layer stays deliberately dumb (concatenation + symlinks), because the value is in the discipline, not the tooling: global vs agent-specific vs machine-specific is a directory, not a judgment call buried in some agent's dotfile.
shared/
core.md # agent-agnostic instructions — true everywhere, for every agent
skills/ # canonical skills dir; ~/.agents/skills symlinks here
agents/
<agent>/extra.md # instructions only that agent should see (quirks, plugin notes)
hosts/
<host>/host.md # instructions only this machine/environment should see
<host>/<agent>.md# optional: one agent on one machine (e.g. hosts/laptop/codex.md)
<host>/hostnames # hostnames that map to this host (one per line)
<host>/snapshots # optional committed redacted snapshots, for cross-machine compare
agents.toml # agent outputs and per-agent skill directories
apply.sh # deploys everything; see below
Where something lives answers "is this global or specific": shared/ = everywhere,
agents/ = that CLI on every machine, hosts/ = that machine for every CLI.
agents apply (idempotent, safe to re-run):
-
Instruction files are rendered by concatenation — for each agent listed in
agents.toml:shared/core.md+agents/<agent>/extra.md+hosts/<host>/{host.md,<agent>.md}→- Claude Code:
~/.claude/CLAUDE.md - Codex CLI:
~/.codex/AGENTS.md - PI:
~/.pi/agent/AGENTS.md - Hermes:
~/.hermes/GLOBAL.md— Hermes curates its own SOUL/USER/MEMORY files, which we never write; a one-line pointer in itsUSER.md(added once) tells it to read GLOBAL.md at session start.
Rendered files carry a
GENERATEDheader — never edit them in place. If something edits one anyway, the next apply salvages the edited copy to~/.local/state/agents/drift/before overwriting (it never destroys bytes it didn't write), andagents statusnags until you review and delete it. Agents whose config dir doesn't exist on the machine are skipped automatically. - Claude Code:
-
Skills are symlinked:
~/.agents/skills → shared/skills, and every shared skill is linked into each agent's skills dir (~/.claude/skills— Claude + PI,~/.codex/skills— Codex,~/.hermes/skills— Hermes). Existing entries are never overwritten, so an agent's own skills always win; links whose skill was removed from the repo are pruned. Manage the set withagents skill list|add|rm(or just drop a dir intoshared/skills/and apply). -
The
agentsCLI is installed:~/.local/bin/agents → apply.sh.
Other commands:
agents init <dir>— create a clean personal config repo from the template.agents snapshot— copies machine-local configs (settings.json,config.toml, …) into~/.local/state/agents/snapshots/<host>/with secrets redacted. Useagents snapshot --commitonly when you deliberately want redacted copies inhosts/<host>/snapshots/for cross-machine comparison.agents apply --dry-run(or-n) — preview exactly what apply would do (creates, updates, salvages, skill links) without touching anything.agents compare <host1> <host2>— diff two hosts' committed redacted snapshots.agents render <agent>— print what would be deployed.agents publish-check— fail on personal config layers, hostnames, snapshots, absolute home paths, email addresses in config layers, and common secret-shaped values before making a repo public. Personal config repos should usually fail; exported templates should pass.agents export-template <dir>— emit a clean, personal-content-free copy of the whole system (template README, placeholder core.md, scrubbed skill, git-initialized) ready to publish:gh repo create <name> --public --source <dir> --push.- Host detection reads
hosts/*/hostnames; override withAGENT_HOST=<name>if needed.
- Structured configs (
~/.claude/settings.json,~/.codex/config.toml,~/.codex/hooks.json, PIsettings.json): these mix authored config with runtime state the tools write themselves (permission grants, project trust, hook hashes) and host-specific wiring (herdr hooks). Deploying them from the repo would fight the tools. They're observed via localsnapshot, not deployed. - Secrets (
auth.json, API keys, the bearer token in codex'sconfig.toml). Snapshots are redacted and local by default; eyeball them before usingsnapshot --commitanyway. - Runtime state: history, sessions, caches, sqlite files.
- New agent CLI: add an
[agents.<name>]block toagents.toml, then createagents/<name>/extra.mdif it needs agent-specific instructions. - New machine: clone +
./apply.sh applythere — it asks you to name the machine and registers it. - Changing the mechanism: run
tests/run.shafter editingapply.sh— full e2e in a sandboxed HOME, never touches real config. - New shared instruction:
agents add "…"for one-liners, or editshared/core.mdandagents sync. - New shared skill:
agents skill add <name>scaffolds one (opens$EDITOR);agents skill add <path>imports an existing dir — importing from an agent's own skills dir swaps the local copy for the shared link. add/rm then walk the agent skills dirs and interactively offer to swap/delete same-name local copies, which would otherwise mask the shared skill (or survive its removal).
agents add "…" (or agents edit + agents sync) # on any machine
agents update # on the others (or: agents auto on)
agents status # am I in sync?