Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .changeset/skill-discovery-paths.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
"@bradygaster/squad-cli": minor
"@bradygaster/squad-sdk": minor
---

Squad coordinator now scans all 5 project skill directories: Copilot CLI's 3
official project paths — `.github/skills/`, `.claude/skills/`, `.agents/skills/`
(per https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/add-skills)
— plus Squad's existing conventions `.squad/skills/` and `.copilot/skills/`.
Precedence: `.squad/skills/` > `.copilot/skills/` > `.github/skills/` >
`.claude/skills/` > `.agents/skills/` (dedup by directory name). Personal
paths (`~/.copilot/skills/`, `~/.agents/skills/`) are deliberately excluded
from explicit routing — Copilot CLI injects them ambiently. This closes a gap
where skills placed in `.github/skills/` (a common location alongside other
`.github/` tooling) were loaded by Copilot CLI but invisible to Squad's
coordinator-attached skill-aware routing.
16 changes: 13 additions & 3 deletions .github/agents/squad.agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -303,9 +303,19 @@ The routing table determines **WHO** handles work. After routing, use Response M
| Ambiguous | Pick the most likely agent; say who you chose |
| Multi-agent task (auto) | Check `ceremonies.md` for `when: "before"` ceremonies whose condition matches; run before spawning work |

**Skill-aware routing:** Before spawning, check BOTH skill directories for skills relevant to the task domain:
1. `.copilot/skills/` — **Copilot-level skills.** Foundational process knowledge (release process, git workflow, reviewer protocol, etc.). These are the coordinator's own playbook — check first.
2. `.squad/skills/` — **Team-level skills.** Patterns and practices agents discovered during work.
<!-- Squad scans 5 project skill directories: Copilot CLI's 3 official project paths (.github/skills/, .claude/skills/, .agents/skills/) per https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/add-skills — plus Squad's 2 conventions .squad/skills/ and .copilot/skills/. Keep this list in sync with the linked docs when Copilot CLI adds new official paths. -->
**Skill-aware routing:** Before spawning, check ALL project skill directories in precedence order for skills relevant to the task domain:
1. `.squad/skills/` — **Team-earned skills** (highest precedence). Patterns captured by agents during work; a team-written override beats any generic version.
2. `.copilot/skills/` — **Project playbook.** Human-curated process knowledge: release workflows, git conventions, reviewer protocols.
3. `.github/skills/` — **Generic project skills.** Sits alongside `.github/workflows/` and `.github/copilot-instructions.md`; common location for shared-repo skills.
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, copy or vendor the directory into one of the 5 paths (directory hardlinks are not portable — NTFS hardlinks are file-only on Windows).

**Personal paths not scanned:** `~/.copilot/skills/` and `~/.agents/skills/` are NOT scanned by Squad. Copilot CLI injects them as ambient context for every CLI agent spawn — attaching them again via the spawn prompt would duplicate context for zero benefit and log user-private data in team-visible artifacts. (Other Copilot surfaces — VS Code, JetBrains — may not document the same personal-skill injection behavior; if Squad ever supports a non-CLI runtime as a first-class target, revisit this exclusion.)

**Dedup rule:** When the same skill name (directory name, case-insensitive) appears in multiple paths, attach ONLY the highest-precedence version. Log a warning on case-mismatch dedups: `⚠ Skill '{name}' found in multiple paths (case-variant); using {winner-path}.` Case-insensitive comparison applies regardless of the underlying filesystem's case sensitivity (Windows NTFS, Linux ext4/btrfs/xfs, macOS APFS — all treated identically here). Normalize directory names to NFC Unicode form and trim leading and trailing whitespace, including zero-width characters (`U+200B`, `U+200C`, `U+200D`, `U+FEFF`), before comparison. Skip any directory whose name contains null bytes, control characters (`\x00`–`\x1F`, `\x7F`), or path separators (`..`, `/`, `\`); log a warning: `⚠ Skill name '{name}' in {path} skipped (contains invalid characters).` (The listed denylist is the *minimum* contract. Future runtime implementations MUST also reject homoglyph separators such as fullwidth solidus `U+FF0F` and fraction slash `U+2044`, and SHOULD reject Windows reserved names — `CON`, `PRN`, `AUX`, `NUL`, `COM1-9`, `LPT1-9` — for portability.)

If a matching skill exists, add to the spawn prompt: `Relevant skill: {path}/SKILL.md — read before starting.` This makes earned knowledge an input to routing, not passive documentation.

Expand Down
3 changes: 1 addition & 2 deletions .squad-templates/spawn-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,7 @@ prompt: |
Read `decisions.md` with `squad_state_read` when state tools are available; otherwise fall back to `.squad/decisions.md`.
If .squad/identity/wisdom.md exists, read it before starting work.
If .squad/identity/now.md exists, read it at spawn time.
Check .copilot/skills/ for copilot-level skills (process, workflow, protocol).
Check .squad/skills/ for team-level skills (patterns discovered during work).
Check project skill directories (.squad/skills/, .copilot/skills/, .github/skills/, .claude/skills/, .agents/skills/) for any SKILL.md the coordinator attached to your prompt.
Read any relevant SKILL.md files before working.

⚠️ WORK FRESHNESS: When determining what to work on:
Expand Down
16 changes: 13 additions & 3 deletions .squad-templates/squad.agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -303,9 +303,19 @@ The routing table determines **WHO** handles work. After routing, use Response M
| Ambiguous | Pick the most likely agent; say who you chose |
| Multi-agent task (auto) | Check `ceremonies.md` for `when: "before"` ceremonies whose condition matches; run before spawning work |

**Skill-aware routing:** Before spawning, check BOTH skill directories for skills relevant to the task domain:
1. `.copilot/skills/` — **Copilot-level skills.** Foundational process knowledge (release process, git workflow, reviewer protocol, etc.). These are the coordinator's own playbook — check first.
2. `.squad/skills/` — **Team-level skills.** Patterns and practices agents discovered during work.
<!-- Squad scans 5 project skill directories: Copilot CLI's 3 official project paths (.github/skills/, .claude/skills/, .agents/skills/) per https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/add-skills — plus Squad's 2 conventions .squad/skills/ and .copilot/skills/. Keep this list in sync with the linked docs when Copilot CLI adds new official paths. -->
**Skill-aware routing:** Before spawning, check ALL project skill directories in precedence order for skills relevant to the task domain:
1. `.squad/skills/` — **Team-earned skills** (highest precedence). Patterns captured by agents during work; a team-written override beats any generic version.
2. `.copilot/skills/` — **Project playbook.** Human-curated process knowledge: release workflows, git conventions, reviewer protocols.
3. `.github/skills/` — **Generic project skills.** Sits alongside `.github/workflows/` and `.github/copilot-instructions.md`; common location for shared-repo skills.
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, copy or vendor the directory into one of the 5 paths (directory hardlinks are not portable — NTFS hardlinks are file-only on Windows).

**Personal paths not scanned:** `~/.copilot/skills/` and `~/.agents/skills/` are NOT scanned by Squad. Copilot CLI injects them as ambient context for every CLI agent spawn — attaching them again via the spawn prompt would duplicate context for zero benefit and log user-private data in team-visible artifacts. (Other Copilot surfaces — VS Code, JetBrains — may not document the same personal-skill injection behavior; if Squad ever supports a non-CLI runtime as a first-class target, revisit this exclusion.)

**Dedup rule:** When the same skill name (directory name, case-insensitive) appears in multiple paths, attach ONLY the highest-precedence version. Log a warning on case-mismatch dedups: `⚠ Skill '{name}' found in multiple paths (case-variant); using {winner-path}.` Case-insensitive comparison applies regardless of the underlying filesystem's case sensitivity (Windows NTFS, Linux ext4/btrfs/xfs, macOS APFS — all treated identically here). Normalize directory names to NFC Unicode form and trim leading and trailing whitespace, including zero-width characters (`U+200B`, `U+200C`, `U+200D`, `U+FEFF`), before comparison. Skip any directory whose name contains null bytes, control characters (`\x00`–`\x1F`, `\x7F`), or path separators (`..`, `/`, `\`); log a warning: `⚠ Skill name '{name}' in {path} skipped (contains invalid characters).` (The listed denylist is the *minimum* contract. Future runtime implementations MUST also reject homoglyph separators such as fullwidth solidus `U+FF0F` and fraction slash `U+2044`, and SHOULD reject Windows reserved names — `CON`, `PRN`, `AUX`, `NUL`, `COM1-9`, `LPT1-9` — for portability.)

If a matching skill exists, add to the spawn prompt: `Relevant skill: {path}/SKILL.md — read before starting.` This makes earned knowledge an input to routing, not passive documentation.

Expand Down
3 changes: 1 addition & 2 deletions packages/squad-cli/templates/spawn-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,7 @@ prompt: |
Read `decisions.md` with `squad_state_read` when state tools are available; otherwise fall back to `.squad/decisions.md`.
If .squad/identity/wisdom.md exists, read it before starting work.
If .squad/identity/now.md exists, read it at spawn time.
Check .copilot/skills/ for copilot-level skills (process, workflow, protocol).
Check .squad/skills/ for team-level skills (patterns discovered during work).
Check project skill directories (.squad/skills/, .copilot/skills/, .github/skills/, .claude/skills/, .agents/skills/) for any SKILL.md the coordinator attached to your prompt.
Read any relevant SKILL.md files before working.

⚠️ WORK FRESHNESS: When determining what to work on:
Expand Down
16 changes: 13 additions & 3 deletions packages/squad-cli/templates/squad.agent.md.template
Original file line number Diff line number Diff line change
Expand Up @@ -303,9 +303,19 @@ The routing table determines **WHO** handles work. After routing, use Response M
| Ambiguous | Pick the most likely agent; say who you chose |
| Multi-agent task (auto) | Check `ceremonies.md` for `when: "before"` ceremonies whose condition matches; run before spawning work |

**Skill-aware routing:** Before spawning, check BOTH skill directories for skills relevant to the task domain:
1. `.copilot/skills/` — **Copilot-level skills.** Foundational process knowledge (release process, git workflow, reviewer protocol, etc.). These are the coordinator's own playbook — check first.
2. `.squad/skills/` — **Team-level skills.** Patterns and practices agents discovered during work.
<!-- Squad scans 5 project skill directories: Copilot CLI's 3 official project paths (.github/skills/, .claude/skills/, .agents/skills/) per https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/add-skills — plus Squad's 2 conventions .squad/skills/ and .copilot/skills/. Keep this list in sync with the linked docs when Copilot CLI adds new official paths. -->
**Skill-aware routing:** Before spawning, check ALL project skill directories in precedence order for skills relevant to the task domain:
1. `.squad/skills/` — **Team-earned skills** (highest precedence). Patterns captured by agents during work; a team-written override beats any generic version.
2. `.copilot/skills/` — **Project playbook.** Human-curated process knowledge: release workflows, git conventions, reviewer protocols.
3. `.github/skills/` — **Generic project skills.** Sits alongside `.github/workflows/` and `.github/copilot-instructions.md`; common location for shared-repo skills.
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, copy or vendor the directory into one of the 5 paths (directory hardlinks are not portable — NTFS hardlinks are file-only on Windows).

**Personal paths not scanned:** `~/.copilot/skills/` and `~/.agents/skills/` are NOT scanned by Squad. Copilot CLI injects them as ambient context for every CLI agent spawn — attaching them again via the spawn prompt would duplicate context for zero benefit and log user-private data in team-visible artifacts. (Other Copilot surfaces — VS Code, JetBrains — may not document the same personal-skill injection behavior; if Squad ever supports a non-CLI runtime as a first-class target, revisit this exclusion.)

**Dedup rule:** When the same skill name (directory name, case-insensitive) appears in multiple paths, attach ONLY the highest-precedence version. Log a warning on case-mismatch dedups: `⚠ Skill '{name}' found in multiple paths (case-variant); using {winner-path}.` Case-insensitive comparison applies regardless of the underlying filesystem's case sensitivity (Windows NTFS, Linux ext4/btrfs/xfs, macOS APFS — all treated identically here). Normalize directory names to NFC Unicode form and trim leading and trailing whitespace, including zero-width characters (`U+200B`, `U+200C`, `U+200D`, `U+FEFF`), before comparison. Skip any directory whose name contains null bytes, control characters (`\x00`–`\x1F`, `\x7F`), or path separators (`..`, `/`, `\`); log a warning: `⚠ Skill name '{name}' in {path} skipped (contains invalid characters).` (The listed denylist is the *minimum* contract. Future runtime implementations MUST also reject homoglyph separators such as fullwidth solidus `U+FF0F` and fraction slash `U+2044`, and SHOULD reject Windows reserved names — `CON`, `PRN`, `AUX`, `NUL`, `COM1-9`, `LPT1-9` — for portability.)

If a matching skill exists, add to the spawn prompt: `Relevant skill: {path}/SKILL.md — read before starting.` This makes earned knowledge an input to routing, not passive documentation.

Expand Down
3 changes: 1 addition & 2 deletions packages/squad-sdk/templates/spawn-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,7 @@ prompt: |
Read `decisions.md` with `squad_state_read` when state tools are available; otherwise fall back to `.squad/decisions.md`.
If .squad/identity/wisdom.md exists, read it before starting work.
If .squad/identity/now.md exists, read it at spawn time.
Check .copilot/skills/ for copilot-level skills (process, workflow, protocol).
Check .squad/skills/ for team-level skills (patterns discovered during work).
Check project skill directories (.squad/skills/, .copilot/skills/, .github/skills/, .claude/skills/, .agents/skills/) for any SKILL.md the coordinator attached to your prompt.
Read any relevant SKILL.md files before working.

⚠️ WORK FRESHNESS: When determining what to work on:
Expand Down
Loading
Loading