[FEATURE] skills/, agents/, commands/ should traverse parent directories like CLAUDE.md does

Open 💬 15 comments Opened Feb 18, 2026 by brendan-sherrin

Preflight Checklist

  • [x] I have searched existing requests and this feature hasn't been requested yet
  • [x] This is a single feature request (not multiple features)

Problem Statement

[Feature Request] Consistent Parent Directory Traversal for Skills, Agents, and Commands

Summary

CLAUDE.md and settings.json correctly traverse parent directories when Claude Code is launched from a subdirectory. However, skills/, agents/, and commands/ do not—they currently only resolve from the immediate project's .claude/ folder. This asymmetry forces manual symlinking or duplication in monorepo and devcontainer patterns.

Use Case: Centralized Pipeline

I maintain a centralized Claude Code pipeline for a devcontainer with multiple repositories under a shared root. The intent is to define logic once at /src/.claude/ and have all child repos inherit them automatically.

Workspace Structure

/src/                           ← non-git workspace root
├── .claude/
│   ├── settings.json           ← hooks, permissions (shared)
│   ├── skills/                 ← writing-plans, codex-review
│   ├── agents/                 ← explore, bash
│   └── commands/               ← retro, plan-close
├── my-app/                     ← git repo A
│   └── .claude/skillbook/            ← localskillbook + retros
└── my-service/                 ← git repo B
    └── .claude/skillbook/            ← local skillbook + retros

Current Capability Matrix

| Component | Traverses to Parent? | Notes |
| :--- | :---: | :--- |
| CLAUDE.md / rules/ | ✅ Yes | Documented; works correctly |
| settings.json | ✅ Yes | Merges additively with local |
| hooks/ | ✅ Yes | Inherited via settings.json |
| skills/ | ❌ No | Only resolves from immediate project |
| agents/ | ❌ No | Only resolves from immediate project |
| commands/ | ❌ No | Only resolves from immediate project |

The Issue: When a session opens at /src/my-app, Claude finds the parent settings.json but fails to find Skill: writing-plans because it only searches /src/my-app/.claude/skills/.

Current Workaround (and its problems)

I currently force inheritance using symlinks:

ln -s /src/.claude/skills   /src/my-app/.claude/skills
ln -s /src/.claude/agents   /src/my-app/.claude/agents
ln -s /src/.claude/commands /src/my-app/.claude/commands

Pain Points:

  • Requires custom setup scripts to manage links.
  • Breaks if the parent path changes or during container rebuilds.
  • Introduces circular-symlink risks if the pipeline root is misconfigured.

Expected Behavior

The Skill tool, Task subagent resolver, and slash-command resolver should walk up the directory tree exactly as CLAUDE.md does, stopping at the home directory or filesystem root.

  • Precedence: Deeper directories (local) should take precedence over parent directories (global/shared), matching the existing override logic for rules.

Related Issues

  • #12962 — Settings.json parent directory traversal (open)
  • #10061 — Sub-agents load skills from global dir instead of project dir (closed)
  • #10145, #10443 — Skills not loading from project/git root

Proposed Solution

Proposed Solution

Extend the same parent directory traversal that already works for CLAUDE.md to cover skills/, agents/, and commands/ resolution.

Resolution order (most specific wins):

  1. Immediate project: <cwd>/.claude/skills/<name>/
  2. Parent directories: walk up the tree, checking <parent>/.claude/skills/<name>/ at each level
  3. Global user: ~/.claude/skills/<name>/

This mirrors how CLAUDE.md files are already composed — deeper files take precedence, parent files fill in the gaps.

Scope

The same logic should apply consistently to all three lookup paths:

  • skills/ — Skill tool invocation
  • agents/ — Task tool subagent type resolution
  • commands/ — slash command resolution

All three currently share the same "immediate project only" limitation, so the fix should be applied uniformly rather than piecemeal.

Traversal boundary

Stop at the user's home directory (same boundary as CLAUDE.md traversal), or at the first directory where no .claude/ folder exists. Do not cross into unrelated filesystem roots.

No breaking changes

Projects that already have a full local skills/ are unaffected — local definitions take precedence. The traversal only activates when a definition is not found locally.

---
Short, concrete, matches the pattern they already ship for CLAUDE.md. Should slot straight in.

Alternative Solutions

What have I tried / Alternative Solutions

Symlinks per child repo

Our current workaround: cc-work (our pipeline setup tool) creates symlinks in each child repo pointing to the parent pipeline:

ln -s /src/.claude/skills /src/my-app/.claude/skills
ln -s /src/.claude/agents /src/my-app/.claude/agents
ln -s /src/.claude/commands /src/my-app/.claude/commands

This works but has several drawbacks:

  • Requires setup tooling to create and manage the symlinks on every new repo
  • Silent failure mode: if the symlink is missing (e.g. new developer, fresh clone), skills resolve from global ~/.claude/ without any error — wrong behaviour with no diagnostic
  • Circular symlink risk: if the pipeline root itself is accidentally included in the setup loop, skills -> skills (self-referential). I had to add explicit guard logic to detect and skip this case
  • Repos with custom local skills (e.g. a project-specific code reviewer) cannot use a directory-level symlink — they need the real directory, which then loses access to all parent skills entirely

Copying skills into every child repo

Rejected: creates multiple out-of-sync copies. Every pipeline update requires re-copying to all downstream repos. Defeats the purpose of a centralised pipeline.

Global ~/.claude/skills/

Rejected: global skills apply to every project on the machine, not just repos under the shared pipeline. Breaks isolation between unrelated projects

Priority

Medium - Would be very helpful

Feature Category

CLI commands and flags

Use Case Example

_No response_

Additional Context

Use Case Example

A devcontainer workspace with multiple repos under a shared root:

/src/ ← non-git workspace root
├── .claude/
│ ├── CLAUDE.md ← inherited ✅ (traversal works today)
│ ├── settings.json ← inherited ✅ (traversal works today)
│ ├── hooks/ ← inherited ✅ (via settings.json)
│ ├── skills/
│ │ ├── planning-skill/ ← NOT inherited ❌
│ │ └── code-review-skill/ ← NOT inherited ❌
│ ├── agents/
│ │ ├── fast-search.md ← NOT inherited ❌
│ │ └── test-runner.md ← NOT inherited ❌
│ └── commands/
│ ├── retrospective.md ← NOT inherited ❌
│ └── close-task.md ← NOT inherited ❌

├── my-app/ ← git repo, session opened here
│ └── .claude/
│ └── project-data/

└── my-service/ ← git repo
└── .claude/
└── project-data/

A Claude Code session opened at /src/my-app correctly picks up /src/.claude/CLAUDE.md and /src/.claude/settings.json. However:

> Skill: planning-skill
Error: skill not found

The skill exists at /src/.claude/skills/planning-skill/ but Claude only checks /src/my-app/.claude/skills/ — which doesn't exist. The session falls back to ~/.claude/skills/ (global), finds nothing, and fails.

The same applies to custom agents and slash commands. A session at /src/my-app cannot use fast-search as a Task subagent type, and /retrospective is not available as a command — despite both being defined one directory level up.

With the proposed fix, all three would resolve through parent traversal exactly as CLAUDE.md does today. No symlinks, no duplication, no setup tooling required.

View original on GitHub ↗

This issue has 15 comments on GitHub. Read the full discussion on GitHub ↗