Instructions files
The problem
Claude reads ~/.claude/CLAUDE.md, Gemini ~/.gemini/GEMINI.md, Codex ~/.codex/AGENTS.md, OMP ~/.omp/agent/AGENTS.md, and so on for every harness with a stable user scope instructions file. Keep them as copies and they drift within a week, and you notice when one harness follows a rule the others never heard of. syncAgentsFiles makes each of them a symlink to one master file, so an edit made through any harness lands in the single physical copy.
Config
~/.config/agntn/agents.jsonc, optional. Without it the source is ~/.config/agntn/AGENTS.md and nothing is excluded.
{
"source": "bundle/AGENTS.md", // relative to the config directory, or absolute
"companions": ["RULES.md"], // relative to the source's directory
"excludes": ["codex"]
}
Companions are linked at the same relative path beside each harness target. With the example above, ~/.omp/agent/RULES.md becomes a link to bundle/RULES.md, next to the AGENTS.md link. A companion that would collide with the target itself, or that does not exist beside the source, fails the whole run before any link is made.
Run it
import { getAllHarnesses, syncAgentsFiles } from "@agntn/harnesses";
const report = syncAgentsFiles(getAllHarnesses(), false);
for (const target of report.targets) {
target.id; // "claude"
target.path; // "/home/dev/.claude/CLAUDE.md"
target.action; // "linked" | "relinked" | "adopted" | "unchanged" | "skipped"
target.detail; // backup path for "adopted", reason for "skipped"
}
| Action | When |
|---|---|
linked | Nothing was there; a symlink was created |
relinked | A symlink pointed elsewhere, or a regular file identical to the source or empty; now a link, no backup |
adopted | A regular file with different content; moved to ~/.config/agntn/diverged/<id>-<name>-<timestamp>.md, then linked |
unchanged | Already a link to the source |
skipped | Excluded, or the harness has no agentsFile |
Nothing is deleted. The diverged copy is where you go to merge what that harness had.
The second argument is check. In check mode every action is reported and nothing is written, so harnesses agents sync --check is a doctor you can run in a shell prompt or a cron.
Which harnesses
Only harnesses with an agentsFile take part. Cursor, Copilot, Grok and Mastra Code have none, because they have no single user scope file the CLI reads on every run; their pages say what they read instead. readAgentsConfig() returns the effective config if you want to show it.
In the CLI
harnesses agents sync --check # report only
harnesses agents sync # link everything
harnesses agents sync gemini # one harness
harnesses agents sync --json