I tried to drive one repo from a Claude Code session rooted in a different repo. The plan was simple enough that I didn’t think it needed a plan: open Claude in my operational repo, point it at the code repo with /add-dir, and let that repo’s own skill do the orchestration. Two surprises killed that, back to back.
Surprise one: in the VS Code-extension build of Claude Code (I run it inside Cursor), /add-dir mid-session isn’t there. The very first thing I typed when I opened that session was “do you have access to the code repo? i tried doing /add-dir but only worked in the cli”. The CLI supports /add-dir. The editor extension build, at least the one I was on, does not. It comes back telling you the command isn’t available in this environment. If your mental model is “Claude Code is Claude Code, the surface doesn’t matter,” this is the first place that model cracks. Skills, settings, and slash commands are mostly portable across the CLI and the extension, but /add-dir is a CLI feature, and assuming parity breaks you silently right at the start of a cross-repo workflow.
Fine. Drop to the CLI, where /add-dir works. That fixed access. It did not fix the thing I actually wanted.
The deeper one: skills don’t follow the added directory
Here’s what I expected. I have a repo-local skill living in the code repo, under that repo’s .claude/skills/. It’s the runbook for closing out work in that codebase: merge order, the JIRA transition screen, the verification steps, all of it. My theory was that if I /add-dir’d that repo into a session rooted elsewhere, its skills would come along for the ride. Add the directory, get the directory’s skills. That’s the intuitive reading of what “add a directory” means.
It is not what happens. Skill discovery in Claude Code is rooted at the session cwd, not at your added directories. /add-dir grants file access. It does not extend skill discovery. So the session could read every file in the added repo, could open and follow the skill markdown as a document, but the skill was never a skill in that session. It never showed up as something I could invoke. The directory was added; the behavior was not.
Once you see it, it’s obvious why it has to work this way. Skills change what the agent can do, not just what it can read. If /add-dir silently pulled in the skill set of every directory you added, you’d be loading arbitrary executable behavior from any folder you glanced at, with no clear scoping of which skills are live in this session. Read access and capability injection are different trust levels and the tool keeps them separate. The cost is that the intuitive thing (added dir = added skills) is wrong, and nothing tells you so. The skill just quietly isn’t there, and if you don’t go looking for it specifically you’ll assume it loaded.
Why this matters for cross-repo orchestration
I run more than one repo and more than one machine, and a fair amount of my work is one surface driving another: an operational session reaching into a code repo to merge, push, transition the ticket, verify in a browser, without ever opening a session in the repo where the code lives. The whole point of that pattern is that the orchestration logic is reusable. Write the close-out runbook once, invoke it from wherever I happen to be sitting.
The /add-dir route says: keep the runbook as a skill inside the code repo, and reach into it from the outside. That’s the natural place to put it. The code-specific procedure lives with the code. Clean.
It doesn’t work, for exactly the reason above. A repo-local skill is only discoverable when that repo is your session root. You cannot reach across into it. So a cross-repo orchestrator can’t be a per-repo skill you /add-dir your way into. It has to live one tier up.
The version that actually works: put the orchestrator at the user level, in ~/.claude/skills/. That one is always discoverable, in every session, regardless of cwd, because it’s scoped to me, not to a repo. It reads the state it needs from a shared reference store, and when it needs the target repo’s procedure, it opens that repo’s runbook by absolute path and follows it as documentation. The repo’s own skill stops being an invokable skill and becomes a runbook the user-level skill reads. The code-specific knowledge still lives with the code. The orchestration that has to span repos lives where it can actually see across them.
The split I landed on:
- Behavior that’s specific to one repo and only ever runs while you’re rooted in that repo → a repo-local skill in
<repo>/.claude/skills/. It’s discoverable exactly when you want it, and invisible everywhere else. - Behavior that spans repos, or drives one repo from a session rooted in another → a user-level skill in
~/.claude/skills/, addressing the other repos by absolute path and reading their runbooks as docs. Don’t try to/add-diryour way into a repo-local skill; the added directory gives you its files but not its skills, and nothing warns you.
Related
- Scope Is the Unit, Not Persona: Rethinking How You Load Context Into AI Agents: how session-root scope determines what an agent can see and do
- Writing an AI_CONTEXT.md So Your Assistant Stops Rediscovering Your Codebase: the file-based context pattern that does survive across sessions
- My AI agent’s memory was per-folder, so my parallel clones never learned from each other: another scope-boundary surprise with per-directory agent state
- Teaching the AI to Find the Real Source File: .cursor/rules as a Compiled-Asset Map: repo-local rules as a compiled asset map accessible to the session
- Capability Gates Beat Risk Labels in Autonomous Agent Design: designing around what an agent can reach, not what it’s told not to do
- Encoding Hard-Won Corrections as Code Defaults Instead of Trusting Yourself to Remember: making agent behavior correct by default at the right scope level