Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
107 commits
Select commit Hold shift + click to select a range
1aaead4
fix: auto-scaffold Fact Checker agent during init and cast (#1222)
tamirdresher Jun 7, 2026
010f6fc
fix(upgrade): auto-scaffold Rai + Fact Checker on squad upgrade (#1222)
tamirdresher Jun 7, 2026
d41b046
Merge pull request #1223 from tamirdresher/fix/1222-fact-checker-auto…
bradygaster Jun 7, 2026
e5c1800
fix(permissions): use 'approve-once' for Copilot CLI v1.0.54+ contrac…
bradygaster Jun 9, 2026
a081832
feat: Squad.Agents.AI - Microsoft Agent Framework adapter for the Squ…
tamirdresher Jun 9, 2026
28962e2
ci(Squad.Agents.AI): switch NuGet publish to Trusted Publishing (OIDC…
tamirdresher Jun 9, 2026
647f337
fix(Squad.Agents.AI): expose SessionConfig + default OnPermissionRequ…
tamirdresher Jun 10, 2026
cc37a2f
Squad.Agents.AI 0.2.0: bump to MAF 1.10.0-rc1 / SDK 1.0.0 GA — file-I…
tamirdresher Jun 10, 2026
39ee9c7
fix: address pre-existing Copilot review comments from PR #1212 (#1258)
bradygaster Jun 11, 2026
611a82b
fix: expose memory tools via MCP + route writes through governed pipe…
bradygaster Jun 11, 2026
eeb68f2
docs(skills): update path references from .squad/skills/ to .copilot/…
bradygaster Jun 11, 2026
c11274d
feat(init): prompt to add @copilot as a team member during squad init…
bradygaster Jun 11, 2026
5824b60
docs: align skills path + state-backend upgrade flow (#1241, #1226) (…
bradygaster Jun 11, 2026
152bbf0
Squad.Agents.AI 0.3.0: first-class subagent observability (#1265)
tamirdresher Jun 11, 2026
d3c2d84
chore(lockfile): sync package-lock with package.json after v0.10.0 bu…
tamirdresher Jun 11, 2026
f79b03a
fix(bump-build): also update package-lock workspace entries (#1267)
tamirdresher Jun 11, 2026
da17eef
fix: release pipeline version pinning (#1203, #1204) (#1250)
bradygaster Jun 11, 2026
ce15d6b
chore: include CHANGELOG.md in published npm tarball (#1257)
bradygaster Jun 11, 2026
c076ffb
Squad.Agents.AI 0.4.0: default-on subagent observability + Aspire-sty…
tamirdresher Jun 11, 2026
dfc5b94
Squad.Agents.AI 0.5.0: auto-inject --agent squad (CLI parity by defau…
tamirdresher Jun 11, 2026
edcc39d
Squad.Agents.AI 0.5.1: fix 0.5.0 regression — use --agent CLI flag (n…
tamirdresher Jun 11, 2026
217e0bd
Add squad registry add/list/remove for discovery-only peer squads (#1…
tamirdresher Jun 12, 2026
2ca906d
fix(cli): stop writing squad_state to ~/.copilot/mcp-config.json on e…
tamirdresher Jun 13, 2026
84ce747
fix(sdk): wire team.md/routing.md/casting state on \squad preset appl…
tamirdresher Jun 13, 2026
68e2774
fix(docs): tell coordinator to roster Fact Checker on first-time cast…
tamirdresher Jun 13, 2026
16c6b25
fix(sdk): plumb Fact Checker like Rai — rich charter at init + .squad…
tamirdresher Jun 13, 2026
76ba4e7
fix(skills): rename squad disambiguation skill to squad-help (superse…
tamirdresher Jun 13, 2026
918cbd4
fix(prompt): coordinator must probe for squad_state/memory tools befo…
tamirdresher Jun 13, 2026
608f858
feat(skills): make /squad a real slash command (user-invocable: true …
tamirdresher Jun 13, 2026
40f78f2
fix(skills): install bundled skills to .github/skills/ (closes #1126)…
tamirdresher Jun 13, 2026
6afd067
feat(sdk): bundle cross-squad-communication skill (#5 cross-squad pro…
tamirdresher Jun 13, 2026
b79e64a
fix(coordinator): route "spawn a squad" / "another squad" prompts thr…
tamirdresher Jun 13, 2026
89a1b96
fix(sdk,cli): bundle missing skills on init + strip fabricated tiered…
tamirdresher Jun 13, 2026
942270b
docs: add feature pages for preset, cross-squad discover/delegate, an…
tamirdresher Jun 14, 2026
f9f77c0
docs: add feature pages for remaining 8 v0.10 features (tiered-memory…
tamirdresher Jun 14, 2026
caef438
docs(state-backends): document pre-commit hook, post-upgrade flow, an…
tamirdresher Jun 14, 2026
ae6f4e7
docs: clarify that .squad/casting/* files are identity, not two-layer…
tamirdresher Jun 14, 2026
567f447
fix(state-backend): conditional .gitignore entries for two-layer/orph…
tamirdresher Jun 14, 2026
264b876
feat(sdk): thread reasoningEffort through agent spawning pipeline (#1…
ahhlun Jun 15, 2026
6278510
deps: Bump xunit from 2.9.2 to 2.9.3 (#1237)
dependabot[bot] Jun 15, 2026
ca3fdd6
fix(test): anchor docs fence-parity regex to line start (#1319)
tamirdresher Jun 15, 2026
937665a
deps: Bump Microsoft.Extensions.Configuration and 8 others (#1317)
dependabot[bot] Jun 15, 2026
89bf31f
ci(dependabot): add npm ecosystem coverage for JS workspaces (#1320)
tamirdresher Jun 15, 2026
0b38155
deps: Bump GitHub.Copilot.SDK from 1.0.0 to 1.0.1 (#1316)
dependabot[bot] Jun 15, 2026
eb57b87
ci: bump the github-actions group across 1 directory with 8 updates (…
dependabot[bot] Jun 15, 2026
8418ef8
deps: Bump xunit.runner.visualstudio from 2.8.2 to 3.1.5 (#1238)
dependabot[bot] Jun 15, 2026
9a5babc
deps: bump the minor-patch group in /docs with 7 updates (#1330)
dependabot[bot] Jun 15, 2026
a137f9b
deps: Bump Microsoft.Extensions.AI from 10.6.0 to 10.7.0 (#1331)
dependabot[bot] Jun 15, 2026
03bc88a
deps: bump eslint-plugin-n from 17.24.0 to 18.1.0 (#1336)
dependabot[bot] Jun 15, 2026
6643897
deps: bump astro from 5.18.0 to 6.4.7 in /docs (#1332)
dependabot[bot] Jun 15, 2026
8fe1096
chore(deps): bump flask in /test-fixtures/dogfood/python-flask (#1341)
dependabot[bot] Jun 15, 2026
0df0bb0
chore(deps): bump black in /test-fixtures/dogfood/python-flask (#1340)
dependabot[bot] Jun 15, 2026
0024464
chore(deps): bump pytest in /test-fixtures/dogfood/mixed-lang/backend…
dependabot[bot] Jun 15, 2026
a23e9b2
fix(docs): migrate to astro 6 content collection config (#1345)
tamirdresher Jun 15, 2026
0796216
chore(deps-dev): bump vite in /samples/streaming-chat (#1344)
dependabot[bot] Jun 16, 2026
3ac4731
chore(deps): bump esbuild, tsx and vitest in /samples/streaming-chat …
dependabot[bot] Jun 16, 2026
daef99a
deps: bump typedoc-plugin-markdown from 4.11.0 to 4.12.0 in /packages…
dependabot[bot] Jun 16, 2026
616cf9f
deps: bump markdown-it from 14.1.1 to 14.2.0 (#1346)
dependabot[bot] Jun 16, 2026
e97ed62
deps: bump the minor-patch group across 1 directory with 13 updates (…
dependabot[bot] Jun 16, 2026
9ea067f
chore: bump @types/node to 25.9.3 (cli + sdk) (#1349)
tamirdresher Jun 16, 2026
f45f856
chore: adapt CLI to ink 7 (#1350)
tamirdresher Jun 16, 2026
f020c8f
deps: bump vscode-jsonrpc from 8.2.1 to 9.0.0 in /packages/squad-cli …
dependabot[bot] Jun 16, 2026
be0c7df
chore: upgrade to TypeScript 6 (cli + sdk + root) and align @typescri…
tamirdresher Jun 16, 2026
04c80ab
chore: upgrade vitest to v4 (coordinated with @vitest/coverage-v8 v4)…
tamirdresher Jun 16, 2026
d5ada48
deps: bump vscode-jsonrpc from 8.2.1 to 9.0.0 in /packages/squad-sdk …
dependabot[bot] Jun 16, 2026
9bb88c6
deps: bump sharp from 0.35.1 to 0.35.2 in /docs in the minor-patch gr…
dependabot[bot] Jun 23, 2026
79ead09
deps: bump the minor-patch group with 2 updates (#1360)
dependabot[bot] Jun 23, 2026
af128fd
deps: Bump GitHub.Copilot.SDK from 1.0.1 to 1.0.3 (#1359)
dependabot[bot] Jun 23, 2026
9329802
deps: bump hono from 4.12.22 to 4.12.26 (#1355)
dependabot[bot] Jun 23, 2026
e76a21d
fix(coordinator): restore always-on inline-dispatch gate (#1378)
tamirdresher Jun 24, 2026
bcdd2e5
chore(deps): bump flask in /test-fixtures/dogfood/mixed-lang/backend …
dependabot[bot] Jun 24, 2026
bcc1d8b
chore(deps): bump pytest in /test-fixtures/dogfood/python-flask (#1376)
dependabot[bot] Jun 24, 2026
df5686d
fix(docs): rephrase 'fenced code block' row in skill-security-scanner…
tamirdresher Jun 24, 2026
1166b8f
docs(Squad.Agents.AI): update README header to 0.5.1 and multi-target…
tamirdresher Jun 24, 2026
0250d5f
ci(release): stop publishing on test-only dep bumps (#1342)
bradygaster Jun 24, 2026
3cfd2c5
ci: bump actions/checkout from 6 to 7 in the github-actions group (#1…
dependabot[bot] Jun 24, 2026
fc057de
fix: respect SQUAD_HOME env var, implement SQUAD_PERSONAL_DIR, fix Wi…
bradygaster Jun 25, 2026
389f147
docs: fix platform paths and explain global squad.agent.md (#1381)
bradygaster Jun 25, 2026
b563251
fix: CLI and upgrade bug fixes (#1050, #1048, #1047, #1052, #1029, #1…
bradygaster Jun 25, 2026
ae6f5c9
fix(sdk): export gitignore-state helpers; bump Squad.Agents.AI to 0.5…
bradygaster Jun 25, 2026
9eda638
feat(tracing): capture task-tool dispatch + tool requests for subagen…
tamirdresher Jun 25, 2026
dff05c4
fix: escape args for cmd.exe shell on Windows (DEP0190) (#1388)
tamirdresher Jun 25, 2026
78c48ca
feat(coordinator): spawn cast members as sub-sessions in Copilot App …
bradygaster Jun 25, 2026
7e49eb7
fix(coordinator): address #1385 review follow-ups (#1390)
bradygaster Jun 25, 2026
d407b82
Rename .NET Aspire references to Aspire (#1239)
Meir017 Jun 25, 2026
ea48282
chore: simplify workflow files by removing .ai-team fallback logic (#…
bradygaster Jun 25, 2026
45080ad
fix(routing): strip surrounding quotes from routing.md examples (#1357)
duongau Jun 25, 2026
ee1870d
fix(cli): add externalize/internalize to top-level squad --help (#1232)
primetimetank21 Jun 25, 2026
54ded23
deps: bump @types/node from 25.9.4 to 26.0.0 in /packages/squad-cli (…
dependabot[bot] Jun 25, 2026
a61f950
deps: bump @types/node from 25.9.4 to 26.0.0 in /packages/squad-sdk (…
dependabot[bot] Jun 25, 2026
5b9db05
ci: bump esbuild and tsx in /samples/storage-provider-sqlite (#1380)
dependabot[bot] Jun 25, 2026
918bbe8
deps: bump @opentelemetry/sdk-trace-base from 1.30.1 to 2.8.0 in /pac…
dependabot[bot] Jun 26, 2026
63ab588
deps: bump @opentelemetry/resources from 1.30.1 to 2.8.0 in /packages…
dependabot[bot] Jun 26, 2026
173880a
deps: bump @github/copilot-sdk from 0.3.0 to 1.0.4 (#1361)
dependabot[bot] Jun 26, 2026
98542a6
deps: bump @github/copilot-sdk from 0.3.0 to 1.0.4 in /packages/squad…
dependabot[bot] Jun 26, 2026
606840a
deps: bump cspell from 9.7.0 to 10.0.1 (#1362)
dependabot[bot] Jun 26, 2026
097c2fa
docs(casting): add spoiler-awareness to casting/naming rules (#1196)
obit91 Jun 26, 2026
f69cb03
feat(prompt): slim squad.agent.md by extracting 3 sections to satelli…
tamirdresher Jun 26, 2026
62c5249
feat(cli): rename hire to cast (#1394)
bradygaster Jun 26, 2026
89c36ab
Add OSS release checklist files (#1217)
bradygaster Jun 28, 2026
dc3bcf4
feat: add 'squad preset install <source>' for sharing presets via rep…
tamirdresher Jun 28, 2026
04682c6
fix: update adapter/client.ts for @github/copilot-sdk 1.0.4 API chang…
bradygaster Jun 28, 2026
6c7e110
deps: bump @opentelemetry/sdk-metrics and sdk-trace-node to 2.8.0 (#1…
bradygaster Jun 29, 2026
4ef3282
fix(cli): pin squad-sdk to workspace:* (fixes prerelease build crash)…
bradygaster Jun 29, 2026
897d883
Fix green test suite (#1416)
bradygaster Jun 29, 2026
6e6f1aa
Stage 0.11.0 release (#1420)
bradygaster Jun 30, 2026
7e01965
Guard symlink test for Windows/restricted environments (#1418)
bradygaster Jun 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
5 changes: 5 additions & 0 deletions .changeset/bump-otel-sdk-2x.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@bradygaster/squad-sdk": patch
---

deps: bump @opentelemetry/sdk-metrics and @opentelemetry/sdk-trace-node from 1.x to 2.8.0
39 changes: 39 additions & 0 deletions .changeset/bundle-missing-skills-1289-1264.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
"@bradygaster/squad-cli": patch
"@bradygaster/squad-sdk": patch
---

Fix #1289, #1264: Bundle missing skills on `squad init` and strip fabricated provenance from tiered-memory SKILL.md

**Problem**

Two regressions shipped in v0.10.0 caused several skills to silently never reach users:

1. **#1289** — `squad-commands` and `squad-version-check` were in `MANIFEST_SKILL_NAMES` (sdk-init.ts) but missing from `packages/squad-sdk/templates/skills/`. The install loop silently skipped them with `if (storage.existsSync(srcSkill))`, so every `squad init` produced an install with these two skills absent. The trigger phrase `squad commands` was a dead no-op for every v0.10.0 user.

2. **#1264** — `tiered-memory`, `iterative-retrieval`, and `reflect` skill files existed in both templates dirs but were never added to `MANIFEST_SKILL_NAMES`, so they never installed either. Additionally, `tiered-memory/SKILL.md` claimed `confidence: high` and `source: earned (production measurements in tamirdresher/tamresearch1, 34-74KB baseline payloads)` — the referenced repository does not exist and the measurement table at the bottom of the SKILL contained fabricated numbers. The SKILL also referenced `docs/tiered-memory-guide.md`, which does not exist.

3. The previously-merged cross-squad fix (#1291) updated `cross-squad/SKILL.md` content but never added it to `MANIFEST_SKILL_NAMES`, so it also never installed.

**Fix**

- **Source of truth.** Added the 5 missing skill directories to `.squad/skills/` (`squad-commands`, `squad-version-check`, `tiered-memory`, `iterative-retrieval`, `reflect`). The pre-existing `sync-skill-templates.mjs` runs in `prebuild` and propagates them to both `packages/squad-cli/templates/skills/` and `packages/squad-sdk/templates/skills/`.

- **`MANIFEST_SKILL_NAMES`** grew from 10 → 14 entries: added `tiered-memory`, `iterative-retrieval`, `reflect`, `cross-squad`.

- **Anti-regression guard.** The install loop in `sdk-init.ts` now collects missing skill source dirs and `throw`s with a clear remediation message (`Run \`node scripts/sync-skill-templates.mjs\``) instead of silently skipping. This is what would have surfaced #1289 at build time instead of in user installs.

- **Provenance honesty.** `tiered-memory/SKILL.md` rewritten to:
- Frontmatter: `confidence: design (runtime not yet implemented)` + `source: design proposal`
- Added prominent "Status (v0.10.0)" callout linking to #1264 for the runtime gap
- Removed the fabricated `tamirdresher/tamresearch1` measurement table
- Removed reference to non-existent `docs/tiered-memory-guide.md`
- References section now points to real issues (#1264, #686, #600)

- **Test guard.** New regression test in `test/init.test.ts` (`should install every manifest-curated skill`) asserts every entry in the expected manifest list ends up at `.copilot/skills/{name}/SKILL.md` after `initSquad()`.

**Out of scope (tracked separately)**

The tiered-memory runtime (storage scaffolding under `.squad/memory/hot|cold|wiki/`, Scribe promotion logic, spawn-template tier-aware reads) remains tracked in #1264. This change lands the install-time fixes; runtime work follows in a separate PR.

The comprehensive `cross-squad-communication` plugin from `tamirdresher/squad-skills` is also separate; this change just adds the existing upstream `cross-squad` skill to the manifest so users get the registry-aware version that landed with #1291.
5 changes: 5 additions & 0 deletions .changeset/casting-identity-not-state.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@bradygaster/squad-sdk": patch
---

docs: clarify in `init.ts` and `.gitattributes` / `.gitignore` generators that `.squad/casting/*` files are authoritative identity (registry + history), NOT mutable two-layer state. They belong on `main`, must be committed, and should NOT receive a `merge=union` driver or be added to `.gitignore`. Pure comment additions — no runtime behavior change.
12 changes: 12 additions & 0 deletions .changeset/cli-upgrade-fixes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
"@bradygaster/squad-cli": patch
"@bradygaster/squad-sdk": patch
---

Fix CLI and upgrade bugs:
- `squad externalize` and `squad internalize` now appear in `squad --help` output (#1050)
- `squad build` writes files to the externalized state directory when applicable (#1048)
- `squad new agent` correctly adds agent definitions to `squad.config.ts` (#1047)
- `squad upgrade` backs up customized `squad.agent.md` before overwriting; supports `--dry-run` (#1052)
- Explicit `@agent` mentions bypass direct-response handler and route to named agent (#1029)
- `state-mcp` server uses lazy initialization to avoid blocking multi-MCP startup (#1353)
10 changes: 10 additions & 0 deletions .changeset/conditional-state-gitignore.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
"@bradygaster/squad-sdk": patch
"@bradygaster/squad-cli": patch
---

fix: conditional .gitignore entries for two-layer/orphan state backends

When the state backend is `two-layer` or `orphan`, `squad init` and `squad upgrade` now add `.squad/decisions.md` and `.squad/agents/*/history.md` to `.gitignore` (delimited by `# Squad: state owned by squad-state branch` marker comments). When the backend is switched back to `local`, the marker block is removed so those files become committable again.

Defense-in-depth complement to the existing pre-commit hook — prevents `git add .`, IDE "stage all", and `git add -A` from silently staging two-layer state into the working tree.
6 changes: 6 additions & 0 deletions .changeset/docs-platform-path-fixes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@bradygaster/squad-sdk": patch
"@bradygaster/squad-cli": patch
---

Fix platform-specific path examples in personal squad docs, JSDoc, and bundled skill templates.
60 changes: 60 additions & 0 deletions .changeset/feat-preset-install.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
"@bradygaster/squad-cli": minor
"@bradygaster/squad-sdk": minor
---

feat: add `squad preset install <source>` for sharing presets via repo URL or local path (#1224)

Closes #1224. Adds a new subcommand that installs a single preset from a GitHub URL or local path into `$SQUAD_HOME/presets/<name>/` — the peer-to-peer preset sharing flow that was missing in v0.10.0.

### CLI

```bash
# From a GitHub repo (preset at <repo-root>/preset.json or <repo-root>/presets/<name>/)
squad preset install https://github.com/tamir/my-presets#my-awesome-team

# From a sub-path
squad preset install https://github.com/tamir/my-presets/tree/main/presets/my-awesome-team

# From SSH URL
squad preset install git@github.com:tamir/my-presets.git#my-awesome-team

# From a local path
squad preset install ./my-awesome-team

# Override the installed name
squad preset install https://github.com/tamir/my-presets#my-awesome-team --name corp-team

# Overwrite an existing preset
squad preset install <source> --force
```

After install, the preset is a normal entry in `$SQUAD_HOME/presets/` — `squad preset list`, `squad preset apply <name>`, and `squad init --preset <name>` all work as today.

### Why

The existing `squad preset init --remote` flow is for syncing your *whole* `$SQUAD_HOME` repo across machines (single-user, multi-machine use case). There was no built-in way to install just *one* preset from someone else's repo. Users had to:
1. Manually clone the repo to a temp dir
2. `cp -r <clone>/presets/<name> $SQUAD_HOME/presets/`
3. Then `squad preset apply <name>`

…or hijack `SQUAD_HOME` (which collides with their own personal squad config).

### What it does

1. Resolves source — GitHub URL → shallow `git clone --depth 1` to a temp dir; local path → use as-is
2. Locates the preset within the source via 3 patterns:
- Source dir contains `preset.json` → single-preset source
- Source dir contains a `presets/` collection → require `--name` (or `#name` fragment) to pick
- Source dir IS the `presets/` dir → require `--name`, or auto-pick if only one preset
3. Validates the preset's `preset.json` manifest (name, agents[]) before any destructive action
4. Verifies `agents/` directory exists
5. Copies `preset.json` (with optional rename) + `agents/` into `$SQUAD_HOME/presets/<name>/`
6. Fail-stops if destination exists, unless `--force` is passed
7. Cleans up the temp clone whether install succeeds or fails

### What's NOT in scope (deferred to follow-ups)

- `squad preset uninstall` — `rm -rf $SQUAD_HOME/presets/<name>` works for now
- `squad preset update <name>` to pull a fresh version from origin
- Public preset registry / discovery catalog
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.
40 changes: 40 additions & 0 deletions .changeset/fix-1296-stop-mcp-home-pollution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
"@bradygaster/squad-cli": patch
---

Fix #1296: stop writing `squad_state_<hash>` to `~/.copilot/mcp-config.json` on every `squad init` / `squad upgrade`

`squad init` (line 408 of `packages/squad-cli/src/cli/core/init.ts`) and `squad upgrade` (line 738 of `upgrade.ts`) unconditionally called `ensureSquadStateMcpInUserConfig`, which wrote a `squad_state_<hash>` entry to `~/.copilot/mcp-config.json` keyed by a stable hash of the project path. Every new `squad init` accumulated another entry in HOME with no garbage collection.

This contradicted the explicit iter-8 design intent documented at `packages/squad-cli/src/cli/core/mcp-root.ts:1-27`:

> *iter-7: wrote `squad_state_<hash>` into the user's HOME `~/.copilot/mcp-config.json`. That polluted HOME with one entry per Squad project and required a stale-entry GC that we never built. It also touched a file outside the project, which is surprising for `squad init` / `squad upgrade`.*
>
> *iter-8 flips it back inside the project: we write `squad_state` to a repo-root `.mcp.json` ... **No HOME modifications.***

The repo-root `.mcp.json` writes (init.ts:403 / upgrade.ts:728) already cover all documented Copilot CLI launch modes:

- ``copilot`` from the project root → walks up from cwd to git root, auto-loads `.mcp.json`
- ``copilot -p`` from the project root → same `.mcp.json` is found

For ``copilot -p`` invocations launched from **outside** the project root, the right pattern is `--additional-mcp-config @.mcp.json` (already documented as the recommended pattern at init.ts:494).

**Changes**

- Removed the unconditional `ensureSquadStateMcpInUserConfig` call from `init.ts:408` and `upgrade.ts:738`. Replaced both with comments explaining the iter-8 design and pointing at #1296.
- Removed the now-unused import from both files.
- The function definition itself (`mcp-root.ts:178-228`) is **kept** — a future `squad doctor --mcp-prune` cleanup helper may want to inspect HOME for orphan entries. It's just no longer called from the init/upgrade auto-flow.

**Tests**

New regression test in `test/cli/init.test.ts`:

> `should NOT write any squad_state entries to ~/.copilot/mcp-config.json (regression: #1296)`

Isolates the developer's real HOME by setting `USERPROFILE`/`HOME` to a temp dir before init, then asserts no `squad_state*` keys appear under that temp HOME after init. The test passes only because the unconditional write is gone — previously this assertion would have failed.

All 40 existing init tests still pass; `npm run lint` clean.

**Cleanup**

A follow-up could add `squad doctor --mcp-prune` to walk `~/.copilot/mcp-config.json`, find `squad_state_<hash>` entries whose target directory no longer exists, and remove them. Out of scope for this fix.
Loading
Loading