Skip to content

feat(skills): scan all 5 Copilot CLI skill paths (not just .copilot/skills + .squad/skills)#1209

Merged
bradygaster merged 3 commits into
bradygaster:devfrom
tamirdresher:feat/skill-discovery-paths
Jun 3, 2026
Merged

feat(skills): scan all 5 Copilot CLI skill paths (not just .copilot/skills + .squad/skills)#1209
bradygaster merged 3 commits into
bradygaster:devfrom
tamirdresher:feat/skill-discovery-paths

Conversation

@tamirdresher

Copy link
Copy Markdown
Collaborator

Why

Squad's coordinator currently scans only .copilot/skills/ and .squad/skills/ for skill-aware routing. But Copilot CLI loads skills from 5 project paths plus 2 personal paths. Skills placed in .github/skills/ — a common location alongside .github/workflows/ and .github/copilot-instructions.md — are loaded ambiently by the CLI but invisible to Squad's coordinator-attached routing. Agents don't get them in their spawn prompts.

This PR closes that gap.

What

Ports the design from the skill-discovery-paths workstream into the upstream templates that ship via squad upgrade. Governance-doc / prompt change only — no runtime code changes (a future runtime gate will be a separate workstream).

Precedence (5 paths, descending)

  1. .squad/skills/ — team-earned skills, highest precedence
  2. .copilot/skills/ — project playbook
  3. .github/skills/ — generic project skills (the gap this closes)
  4. .claude/skills/ — Claude-ecosystem
  5. .agents/skills/ — generic agents path, lowest

Traversal rule

  • One-level only (do not descend past a skill's top-level directory)
  • Skip symlinks and reparse points (NTFS junctions, FILE_ATTRIBUTE_REPARSE_POINT)
  • No per-session cache — rely on filesystem freshness
  • Rationale shipped inline (Windows compat, symlink-traversal attack vectors, monorepo legitimate-symlink silent-skip behavior)

Dedup rule

  • NFC Unicode normalization
  • Leading + trailing whitespace trim (including zero-width chars U+200B, U+200C, U+200D, U+FEFF)
  • Case-insensitive (consistent across NTFS / ext4 / APFS — no per-FS divergence)
  • Denylist of .., /, \, null bytes, control chars (\x00-\x1F/\x7F) — stated as a minimum runtime contract; future runtime MUST also reject homoglyph separators (U+FF0F, U+2044) and SHOULD reject Windows reserved names (CON, PRN, AUX, NUL, COM1-9, LPT1-9)

Personal paths excluded

~/.copilot/skills/ and ~/.agents/skills/ are NOT scanned by Squad — Copilot CLI injects them ambiently for every CLI agent spawn. Attaching them again via the spawn prompt would (1) duplicate context and (2) log user-private data in team-visible artifacts. (Caveat shipped: other Copilot surfaces — VS Code, JetBrains — may not document the same behavior; revisit if Squad ever targets a non-CLI runtime first-class.)

Quick Check

git fetch origin pull/<this-pr>/head:test-skill-discovery && git checkout test-skill-discovery
npm install
npx vitest run test/template-sync.test.ts test/agent-doc.test.ts test/skills.test.ts test/builtin-skills.test.ts
# expected: 261 passed

Inspect the new "Skill-aware routing" block:

grep -A 30 "Skill-aware routing" .squad-templates/squad.agent.md

Verify mirror invariant (should all match SHA-256 C5C8E633…):

Get-FileHash .squad-templates/squad.agent.md, .github/agents/squad.agent.md, packages/squad-cli/templates/squad.agent.md.template, packages/squad-sdk/templates/squad.agent.md.template, templates/squad.agent.md.template

Readiness Checklist

  • Tests: 261/261 across template-sync / agent-doc / skills / builtin-skills suites
  • No runtime code changes — pure governance/template change
  • No new dependencies
  • 5 squad.agent.md mirrors + 4 spawn-reference.md mirrors stay byte-identical via scripts/sync-templates.mjs --sync
  • Changeset present: .changeset/skill-discovery-paths.md (minor for @bradygaster/squad-cli + @bradygaster/squad-sdk)
  • Reviewed by Worf (security): traversal rule + dedup contract + personal-paths exclusion all signed off
  • No breaking changes — additive: existing .copilot/skills/ and .squad/skills/ continue to work; the other 3 paths are newly discoverable

Commits

SHA Subject
fe1e7e8c feat(skills): expand coordinator skill-aware routing to all 5 Copilot CLI paths
8a62093a fix(skills): apply Worf review conditions C-0..C-4 — port traversal rule from design

Happy to squash on merge.

Source

GitHub Copilot CLI docs — Add skills


Queued behind #1200, #1202, #1207, #1208 — review whenever you've caught up.

tamirdresher and others added 2 commits June 3, 2026 07:04
… CLI paths

Squad's coordinator previously scanned only .copilot/skills/ and
.squad/skills/ — but Copilot CLI loads skills from 5 project paths AND 2
personal paths. Skills placed in .github/skills/ (a common location
alongside other .github/ tooling) were loaded ambiently by the CLI but
invisible to Squad's skill-aware routing, so agents didn't get them
attached to spawn prompts.

This PR ports Picard's 5-decision skill-discovery design from
squad-squad's governance doc into the upstream templates that ship via
`squad upgrade`:

1. Precedence: .squad/skills/ > .copilot/skills/ > .github/skills/ >
   .claude/skills/ > .agents/skills/
2. Personal paths (~/.copilot/skills/, ~/.agents/skills/) excluded —
   Copilot CLI already injects them ambiently
3. One-level traversal, no symlinks, no per-session cache
4. Dedup by directory name (case-insensitive, NFC-normalized,
   whitespace-trimmed)
5. Invalid-char skip (null bytes, control chars, path separators)

Updates 5 template-mirror files (squad.agent.md) and 4 mirror files
(spawn-reference.md) via scripts/sync-templates.mjs --sync.

Source: GitHub Copilot CLI docs — https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/add-skills

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ule from design

Per Worf review on workstream skill-discovery-paths
(.squad/workstreams/active/skill-discovery-paths/decisions/inbox/worf-skill-discovery-review.md):

- C-0 BLOCKING: add Traversal rule paragraph (one-level only, skip
  symlinks AND reparse points, no per-session cache, with rationale)
- C-1: dedup denylist is minimum contract; runtime MUST reject
  homoglyph separators (U+FF0F, U+2044); SHOULD reject Windows
  reserved names (CON, PRN, AUX, NUL, COM1-9, LPT1-9)
- C-2: whitespace trim includes leading AND trailing AND zero-width
  chars (U+200B, U+200C, U+200D, U+FEFF)
- C-3: case-insensitive comparison applies regardless of filesystem
  case sensitivity
- C-4: personal-paths rationale scoped explicitly to CLI surface

Source: Decision 3 in workstream decisions.md (one-level / no-symlinks
/ no-cache), which was omitted from the prior implementation commit.

Reviewed by: Worf (re-review pending)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 3, 2026 04:18

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates Squad’s shipped governance/templates to make “skill-aware routing” consider additional project skill directories so that skills placed in .github/skills/, .claude/skills/, and .agents/skills/ can be surfaced to agents via coordinator-attached prompts.

Changes:

  • Expanded the “Skill-aware routing” guidance to cover 5 skill directories with an explicit precedence order and detailed traversal/dedup rules.
  • Updated spawn reference templates to point agents at the expanded set of skill directories.
  • Added a changeset for @bradygaster/squad-cli and @bradygaster/squad-sdk describing the skill discovery behavior change.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
templates/squad.agent.md.template Updates skill-aware routing guidance to include 5 directories + traversal/dedup rules.
templates/spawn-reference.md Updates spawn guidance to reference the expanded skill directories.
packages/squad-sdk/templates/squad.agent.md.template Mirrors the updated skill-aware routing block for SDK templates.
packages/squad-sdk/templates/spawn-reference.md Mirrors the updated spawn-reference guidance for SDK templates.
packages/squad-cli/templates/squad.agent.md.template Mirrors the updated skill-aware routing block for CLI templates.
packages/squad-cli/templates/spawn-reference.md Mirrors the updated spawn-reference guidance for CLI templates.
.squad-templates/squad.agent.md Primary template updated with expanded skill-aware routing guidance.
.squad-templates/spawn-reference.md Primary spawn-reference updated to mention expanded skill directories.
.github/agents/squad.agent.md Mirrors the updated skill-aware routing block for GitHub Agents.
.changeset/skill-discovery-paths.md Records the change as a minor bump for CLI + SDK.

Comment thread .squad-templates/squad.agent.md Outdated
4. `.claude/skills/` — **Claude-ecosystem skills.** Vendor-specific path; less common in multi-tool projects.
5. `.agents/skills/` — **Generic agents path** (lowest project precedence). Least-specific convention.

**Traversal rule:** For each of the 5 directories above, (a) scan ONE level only — a skill is `{skill-dir}/{skill-name}/SKILL.md`; do NOT descend past a skill's top-level directory (nested `{skill-dir}/foo/bar/SKILL.md` is ignored); (b) SKIP symbolic links AND any other reparse points (NTFS junctions via `mklink /J`, mount points, and other Windows reparse-point types) — never follow them, even if the target appears to be inside the repo; (c) do NOT maintain a per-session cache — re-`readdir` on every spawn and rely on filesystem freshness (5 small directory listings is <5ms on any modern FS). **Rationale:** Windows compatibility (symlinks require elevated privileges or developer mode; reparse points are not POSIX symlinks and need a separate `FILE_ATTRIBUTE_REPARSE_POINT` check), defense against symlink-traversal attacks (a malicious or careless skill placing a symlink target like `../../.env` outside the repo would otherwise be read into a spawn prompt), and debugging simplicity (no stale-cache surprises when a user adds a skill mid-session). **Legitimate monorepo case:** a symlink like `.claude/skills/shared-tools -> ../../shared/skills/tools` is silently skipped by policy; if you want a shared skill to be Squad-discoverable, use a hardlink or copy the directory into one of the 5 paths.
Comment thread .squad-templates/squad.agent.md Outdated
Comment on lines +306 to +307
<!-- Sync with Copilot CLI skill paths: https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/add-skills -->
**Skill-aware routing:** Before spawning, check ALL project skill directories in precedence order for skills relevant to the task domain:
Comment thread .changeset/skill-discovery-paths.md Outdated
Comment on lines +6 to +8
Squad coordinator now scans all 5 official Copilot CLI project skill paths:
`.squad/skills/` > `.copilot/skills/` > `.github/skills/` > `.claude/skills/`
> `.agents/skills/` (in precedence order, dedup by directory name). Personal
- Drop hardlink suggestion (directory hardlinks not supported on Windows NTFS);
  recommend copy/vendor instead
- Update HTML sync comment + changeset wording to clarify that Squad scans 5
  directories total: Copilot CLI's 3 official project paths (.github/skills,
  .claude/skills, .agents/skills) plus Squad's 2 conventions (.squad/skills,
  .copilot/skills) — not all 5 are "official Copilot CLI paths"

Reviewed by: copilot-pull-request-reviewer[bot] (PR bradygaster#1209)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@bradygaster bradygaster merged commit 0c409b6 into bradygaster:dev Jun 3, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants