Summary. If .claude/agents is a symlink to a directory elsewhere in the repo, the agent install step fails and argent-environment-inspector.md is never written. Everything else installs fine, so it's easy to miss — but rules/argent.md then points at a subagent that doesn't exist.
Why the symlink layout. Agent definitions — skills, subagents, rules — are increasingly the same content across harnesses, but every harness wants them under its own vendor directory. Keeping the canonical copy in a neutral .agents/ and symlinking each harness's expected path at it means one definition, edited in one place, with no duplication or drift between copies. It's the same motivation behind AGENTS.md as a cross-tool file, applied to skills and subagents. Claude Code supports this directly: .claude/rules/ explicitly documents symlinks ("The .claude/rules/ directory supports symlinks, so you can maintain a shared set of rules and link them into multiple projects"), and .claude/skills / .claude/agents symlinks resolve fine for loading — Claude Code picks up the argent skills through exactly this symlink today.
So the ask is just that argent's writer tolerate what the host tool already tolerates: treat a symlinked .claude/agents as a valid destination rather than a thing to overwrite.
Repro
# canonical, harness-neutral definitions in .agents/ — each harness's path symlinked at it
mkdir -p .agents/agents .agents/skills
ln -s ../.agents/agents .claude/agents
ln -s ../.agents/skills .claude/skills
argent update # or init
Error
Could not copy agents to /Users/me/repo/.claude/agents: Error: Cannot overwrite non-directory
/Users/me/repo/.claude/agents with directory
/path/to/node/lib/node_modules/@swmansion/argent/agents
Root cause. The agents step looks like a single recursive directory copy onto .claude/agents. Node's fs.cp refuses to overwrite a non-directory (the symlink) with a directory. Isolated repro on Node v24.18.0:
await fs.promises.cp('src', 'link', { recursive: true });
// ERR_FS_CP_DIR_TO_NON_DIR
// Cannot overwrite non-directory with directory: cp returned EISDIR
Resolving the destination first works:
const dest = await fs.promises.realpath('link');
await fs.promises.cp('src', dest, { recursive: true }); // ok
Why skills aren't affected. Skills are written per-file from each skillPath in skills-lock.json. Writing through a symlink into its target is fine — it's only replacing the symlink itself with a directory that fails. So skills install correctly into the symlinked location and only agents break.
Impact. rules/argent.md tells the agent to use argent-environment-inspector in two places (<subagents> and <react_native_detection>, the latter saying to run it "first before proceeding"), but it isn't installed. <subagents> has a fallback — "Never call gather-workspace-data yourself - do only if subagent is not available" — so behaviour degrades rather than breaking, which is also why the failed copy is easy to overlook. The install summary reports success apart from the one warning line.
Suggested fix. realpath the destination before the copy (or write agents file-by-file the way skills already are). Either would make symlinked .claude/ layouts work.
Workaround. Copy the files into the real directory by hand:
ARGENT=$(dirname $(dirname $(readlink -f $(which argent))))/agents # package agents dir
cp $ARGENT/argent-environment-inspector.md .agents/agents/
mkdir -p .agents/agents/references
cp $ARGENT/references/quality-control-checklist.md .agents/agents/references/
The warning still prints on every update, but the agent is there and resolves through the symlink.
Env. argent 0.18.0 · Node v24.18.0 · macOS 15 (Darwin 25.5.0) · Claude Code 2.1.220 · global install on PATH.
Summary. If
.claude/agentsis a symlink to a directory elsewhere in the repo, the agent install step fails andargent-environment-inspector.mdis never written. Everything else installs fine, so it's easy to miss — butrules/argent.mdthen points at a subagent that doesn't exist.Why the symlink layout. Agent definitions — skills, subagents, rules — are increasingly the same content across harnesses, but every harness wants them under its own vendor directory. Keeping the canonical copy in a neutral
.agents/and symlinking each harness's expected path at it means one definition, edited in one place, with no duplication or drift between copies. It's the same motivation behindAGENTS.mdas a cross-tool file, applied to skills and subagents. Claude Code supports this directly:.claude/rules/explicitly documents symlinks ("The.claude/rules/directory supports symlinks, so you can maintain a shared set of rules and link them into multiple projects"), and.claude/skills/.claude/agentssymlinks resolve fine for loading — Claude Code picks up the argent skills through exactly this symlink today.So the ask is just that argent's writer tolerate what the host tool already tolerates: treat a symlinked
.claude/agentsas a valid destination rather than a thing to overwrite.Repro
Error
Root cause. The agents step looks like a single recursive directory copy onto
.claude/agents. Node'sfs.cprefuses to overwrite a non-directory (the symlink) with a directory. Isolated repro on Node v24.18.0:Resolving the destination first works:
Why skills aren't affected. Skills are written per-file from each
skillPathinskills-lock.json. Writing through a symlink into its target is fine — it's only replacing the symlink itself with a directory that fails. So skills install correctly into the symlinked location and only agents break.Impact.
rules/argent.mdtells the agent to useargent-environment-inspectorin two places (<subagents>and<react_native_detection>, the latter saying to run it "first before proceeding"), but it isn't installed.<subagents>has a fallback — "Never callgather-workspace-datayourself - do only if subagent is not available" — so behaviour degrades rather than breaking, which is also why the failed copy is easy to overlook. The install summary reports success apart from the one warning line.Suggested fix.
realpaththe destination before the copy (or write agents file-by-file the way skills already are). Either would make symlinked.claude/layouts work.Workaround. Copy the files into the real directory by hand:
The warning still prints on every
update, but the agent is there and resolves through the symlink.Env. argent 0.18.0 · Node v24.18.0 · macOS 15 (Darwin 25.5.0) · Claude Code 2.1.220 · global install on PATH.