symlink-agents
v0.2.0
Published
Declarative symlink generation for AI agent harnesses.
Downloads
39
Maintainers
Readme
symlink-agents
Keep one shared agent setup in .agents/, then project it into the files and
folders that other tools expect.
By default, symlink-agents treats these as the committed source of truth:
AGENTS.md
.agents/and creates generated compatibility links here:
CLAUDE.md -> AGENTS.md
.claude/... -> .agents/...Generated links are ignored by Git and hidden from supported editors unless you
turn that off. Real vendor-specific files, such as .claude/settings.json, stay
real and can be committed.
Install
Requires Node.js 22 or newer.
npx symlink-agentsRun it from the root of your repo.
For an existing repo, preview the changes first:
npx symlink-agents --checkOn the first write run it creates any missing core files:
AGENTS.md
.agents/
.claude/
CLAUDE.md
symlink-agents.jsoncIt also manages generated-link entries in .gitignore, .vscode/settings.json,
and .zed/settings.json unless you turn those integrations off.
After that, rerun the command whenever files move around or your config changes.
What It Does
symlink-agents reconciles three things:
- The canonical files in
AGENTS.mdand.agents/. - The generated compatibility links in
CLAUDE.mdand.claude/. - The managed entries in
.gitignore, VS Code, and Zed.
It also adopts shared files that were created directly in a vendor directory.
For example, if .claude/skills/review/SKILL.md exists as a real file and
skills is included, symlink-agents moves it to
.agents/skills/review/SKILL.md and replaces the Claude path with a symlink.
Adoption is conservative. It does not overwrite an existing canonical file. If a file is vendor-specific, exclude it and it will be left where it is.
Configuration
The config file is symlink-agents.jsonc. It is JSONC, so comments and trailing
commas are allowed. The scaffolded file opens with a short comment that explains
the mental model and how to decide what is safe to share, so whoever extends it
next — including an AI agent working in another tool — can reason about it
without leaving the file:
{
"symlinkToDirectory": ".agents",
"symlinkToFile": "AGENTS.md",
"symlinkFromDirectories": [".claude"],
"symlinkFromFiles": ["CLAUDE.md"],
"default": "exclude",
"include": ["skills", "agents", "commands"],
"exclude": [
".claude/CLAUDE.md",
".claude/settings.json",
".claude/rules",
".claude/output-styles",
".claude/workflows",
".claude/agent-memory",
".claude/agent-memory-local",
"**/*.local.*",
"**/settings.local.json"
],
"gitignore": true,
"vscode": true,
"zed": true,
"noteDefaultIncludeDrift": true
}Unknown keys are ignored, but known keys are validated strictly so typos in paths, booleans, or pattern arrays fail before filesystem changes are made.
Link Settings
symlinkToDirectoryis the shared directory that should be committed.symlinkToFileis the shared instruction file that should be committed.symlinkFromDirectoriesare vendor directories that receive generated links.symlinkFromFilesare vendor files that become generated links.
In plain ln -s terms, the link lives at each symlinkFrom* path and points to
the matching symlinkTo* path.
Include And Exclude
include and exclude decide which files inside a vendor directory are shared.
Patterns use gitignore-style globs. By default, a pattern matches paths relative
to the shared directory. You can prefix a pattern with a symlinkFromDirectory
to scope it to one vendor target.
Examples:
{
"include": ["skills", "agents", "commands"],
"exclude": [
".claude/CLAUDE.md",
".claude/settings.json",
".claude/rules",
".claude/output-styles",
".claude/workflows",
".claude/agent-memory",
".claude/agent-memory-local",
".claude/claude-only/**",
"**/*.local.*"
]
}What those mean:
skills,agents, andcommandsshare those prompt/agent authoring subtrees for every vendor target you configure..claude/CLAUDE.mdkeeps Claude-specific instruction addenda real..claude/settings.jsonkeeps Claude's shared project settings real..claude/rules,.claude/output-styles,.claude/workflows, and.claude/agent-memorykeep Claude-specific or mutable surfaces real..claude/agent-memory-localkeeps local subagent memory real..claude/claude-only/**applies only inside.claude/.**/*.local.*keeps local files vendor-specific at any depth.
Matching checks both the unqualified path and the vendor-qualified path. For
.claude/settings.json, symlink-agents checks:
settings.json
.claude/settings.jsonSo settings.json would apply to every vendor target, while
.claude/settings.json applies only to Claude.
If both include and exclude match, the more specific pattern wins. If they
are equally specific, exclude wins.
default is used only when no pattern matches:
"default": "exclude"means files are vendor-specific unless included."default": "include"means files are shared unless excluded.
The default shared set is limited to skills, agents, and commands, because
those are portable prompt/agent authoring surfaces that other tools can read
unchanged. Claude-specific rules, output styles, workflows, memory, and settings
stay real by default. When you add another target to symlinkFromDirectories,
check that tool's docs before sharing a directory: include only surfaces that
stay valid when read through the symlink, and leave tool-specific formats,
config, and mutable state real.
Managed Integrations
gitignorecontrols whether generated links are added to.gitignore.vscodecontrols generated-link hiding in.vscode/settings.json.zedcontrols generated-link hiding in.zed/settings.json.noteDefaultIncludeDriftcontrols an informational note when this package version's defaultincludeset contains entries missing from your config'sinclude. It is only a heads-up; it also fires when you narrowincludeon purpose.
CLI flags such as --no-gitignore, --no-vscode, and --no-zed override the
config for that run. Use --gitignore, --vscode, or --zed to turn
an integration back on when the config disables it.
Git Behavior
By default, symlink-agents writes a managed block to .gitignore:
# symlink-agents start
/.claude/skills
/.claude/agents
/.claude/commands
/CLAUDE.md
# symlink-agents endOnly generated links are added to that block. symlink-agents does not ignore an
entire vendor directory such as .claude/, because real files inside that
directory may need to be committed.
Set "gitignore": false or use --no-gitignore if you want generated symlinks
to be tracked by Git.
If a generated symlink was committed before you started ignoring it, Git will
keep tracking it. Remove it from the index once with git rm --cached <path>.
Editor Behavior
Generated links are hidden in supported editors by default:
- VS Code:
.vscode/settings.json - Zed:
.zed/settings.json
When a vendor directory contains only generated links, symlink-agents may hide the whole directory in the editor. When it contains real files, it switches to hiding only the generated links so the real files remain visible.
Set "vscode": false / "zed": false or use --no-vscode /
--no-zed to remove symlink-agents' managed editor exclusions.
Windows
symlink-agents creates real relative symlinks.
On Windows, creating symlinks requires Developer Mode or an elevated terminal. The tool checks this before writing links and explains what to do if symlinks are unavailable.
If you use --no-gitignore on Windows, make sure Git can check out symlinks:
git config core.symlinks trueCLI
symlink-agents [options]
--check Verify without writing; nonzero exit if changes are needed
--yes, -y Run non-interactively with safe defaults
--force Replace conflicting generated targets
--gitignore Add generated links to .gitignore
--no-gitignore Do not add generated links to .gitignore
--vscode Hide generated links in VS Code
--no-vscode Do not hide generated links in VS Code
--zed Hide generated links in Zed
--no-zed Do not hide generated links in Zed
--note-default-include-drift
Note default include drift
--no-note-default-include-drift
Suppress the default include drift note
--cwd <path> Run from this root (defaults to the current directory)
--json Machine-readable output
--quiet Errors only
--verbose Show every action, including no-ops
--help, -h Show help
--version, -v Show versionRelease Notes
See CHANGELOG.md.
License
MIT
