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
68 changes: 68 additions & 0 deletions .changeset/fix-1126-skills-to-github-skills.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
"@bradygaster/squad-sdk": minor
"@bradygaster/squad-cli": minor
---

Move bundled skills from `.copilot/skills/` to `.github/skills/` so they're visible to all Copilot surfaces (closes #1126)

## Symptom (per #1126)

Squad-bundled skills installed at `.copilot/skills/` are **invisible to every Copilot surface except Squad itself**:
- ❌ GitHub Copilot cloud agent
- ❌ Copilot CLI (outside Squad sessions)
- ❌ VS Code Copilot extension (agent mode)
- ❌ `@copilot` coding agent on issues
- ❌ Any future Copilot surface

Per the [official Agent Skills docs](https://docs.github.com/en/copilot/concepts/agents/about-agent-skills), [add-skills docs](https://docs.github.com/en/copilot/how-tos/use-copilot-agents/cloud-agent/add-skills), and [VS Code docs](https://code.visualstudio.com/docs/copilot/customization/agent-skills), the canonical **project-level** custom-skills location is `.github/skills/`. `.copilot/skills/` at repo root is not recognized by any Copilot surface — the home-directory equivalent `~/.copilot/skills/` IS recognized for **personal** skills, which is the source of the original mistake.

## Fix

1. **`squad init`** writes bundled skills to `.github/skills/{name}/SKILL.md` (was `.copilot/skills/`).
2. **`squad upgrade`** does the same AND auto-migrates legacy `.copilot/skills/{manifest-skill}/` into `.github/skills/{manifest-skill}/` (best-effort, preserves user-added non-manifest skills at `.copilot/skills/`, tombstones the legacy dir when empty).
3. **`TEMPLATE_MANIFEST`** destinations rewritten: all 10 skill entries now target `../.github/skills/` instead of `../.copilot/skills/`.
4. **`ENSURE_DIRECTORIES`** (upgrade.ts) updated so existing squads get `.github/skills/` created on upgrade.
5. **squad.agent.md** narrative updated: 5-path scan order now lists `.github/skills/` as path #2 (Copilot CLI's canonical custom-skills location) and `.copilot/skills/` as path #3 (Legacy install path; `squad upgrade` migrates). Personal scope (`~/.copilot/skills/`) preserved as-is.
6. **All other docs** (`spawn-reference.md`, `README.md`, `squad-commands` skill, `release-process` skill, `build.ts`, SDK type comments) updated to reference `.github/skills/` as the install destination.

## Migration semantics (`squad upgrade`)

`migrateLegacyCopilotSkills()` runs **before** `syncAllSkills`:

| Scenario | Migration action | User-added skills at `.copilot/skills/` |
|---|---|---|
| `.copilot/skills/{manifest-skill}/` exists, `.github/skills/{manifest-skill}/` does NOT | Move legacy → new; remove legacy | Untouched |
| `.copilot/skills/{manifest-skill}/` exists AND `.github/skills/{manifest-skill}/` exists | Tombstone legacy (new wins) | Untouched |
| `.copilot/skills/my-custom-skill/` (NOT in TEMPLATE_MANIFEST) | Left alone | Preserved |
| `.copilot/skills/` becomes empty after migration | Directory removed | n/a |

All migration steps are best-effort with try/catch — disk-write failures don't block upgrade.

## Tests

New regression tests:
- `test/init.test.ts > should install Squad-bundled skills at .github/skills/...` — asserts canonical path, asserts legacy path is NOT created
- `test/cli/upgrade.test.ts > should migrate manifest skills from .copilot/skills/ to .github/skills/` — asserts manifest skill moves, user-added skill preserved
- `test/cli/upgrade.test.ts > should NOT clobber a customized .github/skills/{name} if the legacy copy exists` — asserts both-locations case tombstones legacy without losing the new

Updated existing tests:
- `test/builtin-skills.test.ts` regex now matches `.github/skills/`
- `test/cli/init.test.ts`, `test/init.test.ts`, `test/init-sdk.test.ts`, `test/cli/upgrade.test.ts`, `test/human-journeys.test.ts`, `test/repl-ux-fixes.test.ts`, `test/cli/init-upgrade-parity.test.ts` — install-path assertions updated to `.github/skills/`

**188/188 init/upgrade/builtin tests pass; `npm run lint` clean.**

## What's NOT changed (intentional)

- **`.copilot/skills/` scan path stays in `squad.agent.md`'s 5-path skill discovery** — the coordinator still discovers user-added skills at the legacy location for backward compat; only Squad-installed (manifest) skills migrate.
- **`~/.copilot/skills/` (personal scope) is unchanged** — that's Copilot CLI's official personal-skills location and remains valid.
- **`test/skill-source.test.ts`, `test/skills-export-import.test.cjs`, `test/tools.test.ts`, `test/skill-script-loader.test.ts`** are NOT touched — they test the runtime skill loader and tool behavior, which still supports `.copilot/skills/` as a valid scan path.

## Composability

- **Disjoint from #1292, #1293, #1295, #1297, #1298, #1300, #1301, #1302, #1303** — touches the same `TEMPLATE_MANIFEST` array as #1292/#1295/#1303 but only modifies the destination path, not the source or entry list. Conflicts on `MANIFEST_SKILL_NAMES` are trivial: take the union of skill names with the `../.github/skills/` destination from this PR.
- This is the **canonical fix** for #1126; closes that issue.

## Out of scope (separate follow-ups)

- Backward-compat shim that adds a `.copilot/skills -> .github/skills` symlink. Not needed because users won't be looking at `.copilot/skills/` anymore once their tools find skills at `.github/skills/`. Filed as a follow-up if anyone reports broken muscle memory.
- A `squad doctor --skills` check that warns when `.copilot/skills/` still has manifest skills after upgrade (suggesting the migration silently failed). Worth adding to the next maintenance pass.
8 changes: 4 additions & 4 deletions .github/agents/squad.agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -298,19 +298,19 @@ The routing table determines **WHO** handles work. After routing, use Response M
| PRD intake ("here's the PRD", "read the PRD at X", pastes spec) | Follow PRD Mode (see that section) |
| Human member management ("add {name} as PM", routes to human) | Follow Human Team Members (see that section) |
| Ralph commands ("Ralph, go", "keep working", "Ralph, status", "Ralph, idle") | Follow Ralph — Work Monitor (see that section) |
| "squad commands", "what can squad do", "show me squad options", "slash commands", "what commands are available" | Read `.copilot/skills/squad/SKILL.md`, present categorized menu (see squad skill). Users can also invoke this directly via `/squad`. |
| "squad commands", "what can squad do", "show me squad options", "slash commands", "what commands are available" | Read `.github/skills/squad/SKILL.md`, present categorized menu (see squad skill). Users can also invoke this directly via `/squad`. |
| "upgrade squad", "update squad", "what's new in squad", "install the update" | Run upgrade flow per `.squad/templates/session-init-reference.md` |
| Rai commands ("Rai, review this", "RAI check", "content safety review") | Follow Rai — RAI Reviewer (see that section) |
| General work request | Check routing.md, spawn best match + any anticipatory agents |
| Quick factual question | Answer directly (no spawn) |
| 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 |

<!-- 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. -->
<!-- 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/ (team-earned) and .copilot/skills/ (legacy install path; new installs use .github/skills/ which is Copilot CLI's canonical custom-skills location). 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.
2. `.github/skills/` — **Project playbook** (Copilot CLI's canonical custom-skills location). Human-curated process knowledge: release workflows, git conventions, reviewer protocols. Sits alongside `.github/workflows/` and `.github/copilot-instructions.md`. `squad init` and `squad upgrade` install Squad's bundled skills here.
3. `.copilot/skills/` — **Legacy install path** (pre-1304). Older squads may have skills here; `squad upgrade` migrates them to `.github/skills/`. Still scanned for any user-added or unmigrated 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.

Expand Down
2 changes: 1 addition & 1 deletion .squad-templates/spawn-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +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 project skill directories (.squad/skills/, .copilot/skills/, .github/skills/, .claude/skills/, .agents/skills/) for any SKILL.md the coordinator attached to your prompt.
Check project skill directories (.squad/skills/, .github/skills/, .copilot/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
8 changes: 4 additions & 4 deletions .squad-templates/squad.agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -329,19 +329,19 @@ The routing table determines **WHO** handles work. After routing, use Response M
| PRD intake ("here's the PRD", "read the PRD at X", pastes spec) | Follow PRD Mode (see that section) |
| Human member management ("add {name} as PM", routes to human) | Follow Human Team Members (see that section) |
| Ralph commands ("Ralph, go", "keep working", "Ralph, status", "Ralph, idle") | Follow Ralph — Work Monitor (see that section) |
| "squad commands", "what can squad do", "show me squad options", "slash commands", "what commands are available" | Read `.copilot/skills/squad/SKILL.md`, present categorized menu (see squad skill). Users can also invoke this directly via `/squad`. |
| "squad commands", "what can squad do", "show me squad options", "slash commands", "what commands are available" | Read `.github/skills/squad/SKILL.md`, present categorized menu (see squad skill). Users can also invoke this directly via `/squad`. |
| "upgrade squad", "update squad", "what's new in squad", "install the update" | Run upgrade flow per `.squad/templates/session-init-reference.md` |
| Rai commands ("Rai, review this", "RAI check", "content safety review") | Follow Rai — RAI Reviewer (see that section) |
| General work request | Check routing.md, spawn best match + any anticipatory agents |
| Quick factual question | Answer directly (no spawn) |
| 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 |

<!-- 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. -->
<!-- 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/ (team-earned) and .copilot/skills/ (legacy install path; new installs use .github/skills/ which is Copilot CLI's canonical custom-skills location). 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.
2. `.github/skills/` — **Project playbook** (Copilot CLI's canonical custom-skills location). Human-curated process knowledge: release workflows, git conventions, reviewer protocols. Sits alongside `.github/workflows/` and `.github/copilot-instructions.md`. `squad init` and `squad upgrade` install Squad's bundled skills here.
3. `.copilot/skills/` — **Legacy install path** (pre-1304). Older squads may have skills here; `squad upgrade` migrates them to `.github/skills/`. Still scanned for any user-added or unmigrated 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.

Expand Down
4 changes: 2 additions & 2 deletions .squad/skills/release-process/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ source: "earned"
# Release Process

> Earned knowledge from the v0.9.0→v0.9.1 and v0.9.4 incidents. Every agent involved in releases MUST read this before starting release work.
> See also: `.copilot/skills/release-process/SKILL.md` for the Copilot-facing runbook.
> See also: `.github/skills/release-process/SKILL.md` for the Copilot-facing runbook.

## SCOPE

Expand Down Expand Up @@ -213,5 +213,5 @@ See `.github/workflows/squad-ci.yml` → `publish-policy` job for implementation
- v0.9.4 fixes: PR #1042 (CHANGELOG), PR #1043 (root package.json), PR #1044 (lockfile integrity)
- Retro: `.squad/decisions/inbox/surgeon-v091-retrospective.md`
- CI audit: `.squad/decisions/inbox/booster-ci-audit.md`
- Copilot-level skill: `.copilot/skills/release-process/SKILL.md`
- Copilot-level skill: `.github/skills/release-process/SKILL.md`
- Playbook: `PUBLISH-README.md` (repo root)
4 changes: 2 additions & 2 deletions .squad/skills/squad/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,9 +214,9 @@ Proceed? (yes / no)
### List Installed Skills

- **intent:** list skills, show skills, what skills are installed, skill catalog
- **summary:** List all skills installed in .squad/skills/ and .copilot/skills/
- **summary:** List all skills installed in .squad/skills/ and .github/skills/
- **action:** coordinator
- **command:** Direct Mode — list .squad/skills/ and .copilot/skills/ directories
- **command:** Direct Mode — list .squad/skills/ and .github/skills/ directories
- **args:** (none)
- **confirm:** false

Expand Down
10 changes: 5 additions & 5 deletions packages/squad-cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ When you run `squad init`, Squad creates a `.squad/` directory with this structu

## Built-in Skills

When you run `squad init`, Squad installs **8 curated skills** into `.copilot/skills/`. These skills teach your agents best practices and conventions:
When you run `squad init`, Squad installs **8 curated skills** into `.github/skills/`. These skills teach your agents best practices and conventions:

| Skill | Purpose |
|-------|---------|
Expand All @@ -236,19 +236,19 @@ When you run `squad init`, Squad installs **8 curated skills** into `.copilot/sk
| `test-discipline` | Test-first discipline and coverage expectations |
| `agent-collaboration` | Multi-agent collaboration and handoff patterns |

Each skill is a `SKILL.md` file inside `.copilot/skills/<skill-name>/`.
Each skill is a `SKILL.md` file inside `.github/skills/<skill-name>/`.

### Skill lifecycle

- **`squad init`** — Installs the 8 manifest skills on first run. If `.copilot/skills/` already has content, init skips skill installation (idempotent).
- **`squad init`** — Installs the 8 manifest skills on first run. If `.github/skills/` already has content, init skips skill installation (idempotent).
- **`squad upgrade`** — Refreshes manifest skills to their latest versions. Skills marked `overwriteOnUpgrade: true` (all built-in skills) are always updated to pick up fixes and improvements.

### Adding custom skills

You can add your own skills by creating a new directory under `.copilot/skills/`:
You can add your own skills by creating a new directory under `.github/skills/`:

```
.copilot/skills/my-custom-skill/
.github/skills/my-custom-skill/
└── SKILL.md
```

Expand Down
6 changes: 3 additions & 3 deletions packages/squad-cli/src/cli/commands/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ function generateCeremoniesDispatchTable(ceremonies: readonly CeremonyDefinition
const schedule = c.schedule ?? '—';
const participants = c.participants?.join(', ') ?? '—';
const slug = c.name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '');
const skillPath = `.copilot/skills/ceremony-${slug}/SKILL.md`;
const skillPath = `.github/skills/ceremony-${slug}/SKILL.md`;
lines.push(`| ${c.name} | ${trigger} | ${schedule} | ${participants} | \`${skillPath}\` |`);
}

Expand Down Expand Up @@ -383,7 +383,7 @@ function buildFilePlan(config: SquadSDKConfig): GeneratedFile[] {
for (const c of config.ceremonies) {
const slug = c.name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '');
files.push({
relPath: `.copilot/skills/ceremony-${slug}/SKILL.md`,
relPath: `.github/skills/ceremony-${slug}/SKILL.md`,
content: generateCeremonySkillFile(c),
});
}
Expand All @@ -400,7 +400,7 @@ function buildFilePlan(config: SquadSDKConfig): GeneratedFile[] {
if (config.skills && config.skills.length > 0) {
for (const skill of config.skills) {
files.push({
relPath: `.copilot/skills/${skill.name}/SKILL.md`,
relPath: `.github/skills/${skill.name}/SKILL.md`,
content: generateSkillFile(skill),
});
}
Expand Down
Loading
Loading