diff --git a/.changeset/loop-command.md b/.changeset/loop-command.md new file mode 100644 index 000000000..80097834d --- /dev/null +++ b/.changeset/loop-command.md @@ -0,0 +1,9 @@ +--- +"@bradygaster/squad-cli": minor +--- + +feat(cli): Add `squad loop` command — prompt-driven continuous work loop + +New `squad loop` command reads a `loop.md` file and runs it as a continuous work loop. +No GitHub issues required — the prompt is the work driver. Includes `--init` to scaffold +a boilerplate loop file, frontmatter validation, and composable capability flags. diff --git a/.squad/agents/eecom/history.md b/.squad/agents/eecom/history.md index de1038df9..2b4ee011a 100644 --- a/.squad/agents/eecom/history.md +++ b/.squad/agents/eecom/history.md @@ -4,6 +4,32 @@ ## Learnings +### Loop command: second-round review fixes (#767) (2025-07-26) + +**Context:** Three Copilot review comments on PR #767: (1) `teamRoot` was set to `workTreeRoot` but `.squad/` may live in the main checkout when running inside a git worktree — should derive from `detectSquadDir().path`, (2) `generateLoopFile()` hardcoded the full loop.md scaffold inline, duplicating `templates/loop.md`, (3) docs said `gh` was optional but code hard-requires `gh copilot` unless `--agent-cmd` is passed. + +**Fixes:** +1. **teamRoot:** Changed `const teamRoot = workTreeRoot` to `path.dirname(squadDirInfo.path)` — `.squad/`-relative operations now always use the directory where `.squad/` was actually found. +2. **Template dedup:** Replaced 48-line hardcoded template with `readFileSync` reading from `templates/loop.md`. Used `import.meta.url` + `fileURLToPath` to resolve the path from the compiled file (3 levels up to package root). Created `packages/squad-cli/templates/loop.md` since it was missing from the CLI package's templates dir. +3. **Docs:** Updated prerequisites to state `gh` + `gh copilot` are required by default, with `--agent-cmd` as the escape hatch. + +**Test impact:** Tests mock `node:fs` globally, so `readFileSync` in `generateLoopFile()` needed mock setup. Added `beforeAll` using `vi.importActual('node:fs')` to read the REAL template file, then `beforeEach` to set the mock return value. This keeps tests validating the actual template content. + +**Pattern:** When reading template files in code that has mocked `node:fs` tests, use `vi.importActual('node:fs')` in `beforeAll` to get real filesystem access for loading test fixtures. + +### Loop command: streaming output, worktree CWD, docs alignment (#767) (2025-07-25) + +**Context:** Copilot code review on PR #767 flagged three issues in the loop command: (1) `execFile` buffered stdout/stderr but never printed it — users saw no Copilot output during loop rounds, (2) `loop.md` was resolved relative to `dest` but execution used `teamRoot` (derived from `.squad/` parent), creating a CWD mismatch in worktree scenarios, (3) docs said `description` defaults to `""` but code uses `'Squad Loop'`. + +**Fixes:** +1. **Streaming:** Added `.on('data')` listeners to `currentChild.stdout` and `currentChild.stderr` after `execFile` spawn. Since output streams in real-time, the callback no longer re-writes buffered stdout/stderr on error (would duplicate). +2. **Worktree CWD:** Introduced `workTreeRoot = path.resolve(dest)` and set `teamRoot = workTreeRoot`. Both file resolution and execution CWD now use the same root. +3. **Docs:** Updated `docs/src/content/docs/features/loop.md` description default from `""` to `"Squad Loop"`. + +**Key file:** `packages/squad-cli/src/cli/commands/loop.ts` — `runLoop()` entry point (~line 302), `executeRound()` inner function (~line 427). + +**Pattern:** When using Node's `execFile` for interactive/long-running child processes, always attach stream listeners for real-time output. The callback's `stdout`/`stderr` args are the same buffered content — writing both duplicates output. + ### archiveDecisions() count-based fallback (#626) (2025-07-24) **Context:** `archiveDecisions()` in `packages/squad-cli/src/cli/core/nap.ts` silently returned `null` when all `###` entries were <30 days old (`old.length === 0`), even if the file was well over 20KB. Active projects generating many decisions per session could hit 145KB+ — 35K tokens burned per agent spawn. diff --git a/.squad/decisions-archive.md b/.squad/decisions-archive.md index 3d75e459f..d44f3a31e 100644 --- a/.squad/decisions-archive.md +++ b/.squad/decisions-archive.md @@ -1,4290 +1,7852 @@ -# Decisions Archive +# Decisions Archive + +> Old decisions (2026-02-21 through 2026-03-25) preserved append-only. Managed by Scribe. For active decisions, see .squad/decisions.md. + +--- +### 2026-02-21: User directive — no temp/memory files in repo root +**By:** Brady (via Copilot) +**What:** NEVER write temp files, issue files, or memory files to the repo root. All squad state/scratch files belong in .squad/ and ONLY .squad/. Root tree of a user's repo is sacred. +**Why:** User request — hard rule. Captured for all agents. + +### 2026-02-21: npm workspace protocol for monorepo +**By:** Edie (TypeScript Engineer) +**What:** Use npm-native workspace resolution (version-string references) instead of `workspace:*` protocol for cross-package dependencies. +**Why:** The `workspace:*` protocol is pnpm/Yarn-specific. npm workspaces resolve workspace packages automatically. +**Impact:** All inter-package dependencies in `packages/*/package.json` should use the actual version string, not `workspace:*`. + +### 2026-02-21: Distribution is npm-only (GitHub-native removed) +**By:** Rabin (Distribution) + Fenster (Core Dev) +**What:** Squad packages (`@bradygaster/squad-sdk` and `@bradygaster/squad-cli`) are distributed exclusively via npmjs.com. The GitHub-native `npx github:bradygaster/squad` path has been removed. +**Why:** npm is the standard distribution channel. One distribution path reduces confusion and maintenance burden. Root `cli.js` prints deprecation warning if anyone still hits the old path. + +### 2026-02-21: Coordinator prompt structure — three routing modes +**By:** Verbal (Prompt Engineer) +**What:** Coordinator uses structured response format: `DIRECT:` (answer inline), `ROUTE:` + `TASK:` + `CONTEXT:` (single agent), `MULTI:` (fan-out). Unrecognized formats fall back to `DIRECT`. +**Why:** Keyword prefixes are cheap to parse and reliable. Fallback-to-direct prevents silent failures. +### `.squad/` Directory Scope — Owner Directive +**By:** Brady (project owner, PR #326 review) +**Date:** 2026-03-10 + +**Directive:** The `.squad/` directory is **reserved for team state only** — roster, routing, decisions, agent histories, casting, and orchestration logs. Non-team data (adoption tracking, community metrics, reports) must NOT live in `.squad/`. Use `.github/` for GitHub platform integration or `docs/` for documentation artifacts. + +**Source:** [PR #326 comment](https://github.com/bradygaster/squad/pull/326#issuecomment-4029193833) -> Archived from decisions.md on 2026-02-28 by Keaton (Lead). -> These entries are historical record - superseded, completed, or one-time decisions. -> Active decisions remain in decisions.md. --- -# Decisions +### No Individual Repo Listing Without Consent — Owner Directive +**By:** Brady (project owner, PR #326 review) +**Date:** 2026-03-10 -> Team decisions that all agents must respect. Managed by Scribe. +**Directive:** Growth metrics must report **aggregate numbers only** (e.g., "78+ repositories found via GitHub code search") — never name or link to individual community repos without explicit opt-in consent. The monitoring script and GitHub Action concepts are approved, but any public showcase or tracking list that identifies specific repos is blocked until a community consent plan exists. -### 2026-02-21: SDK distribution stays on GitHub -**By:** Keaton (carried from beta) -**What:** Distribution is `npx github:bradygaster/squad` — never move to npmjs.com. -**Why:** GitHub-native distribution aligns with the Copilot ecosystem. No registry dependency. +**Source:** [PR #326 comment](https://github.com/bradygaster/squad/pull/326#issuecomment-4029222967) -### 2026-02-21: v1 docs are internal only -**By:** Keaton (carried from beta) -**What:** No published docs site for v1. Documentation is team-facing only. -**Why:** Ship the runtime first. Public docs come later when the API surface stabilizes. -### 2026-02-21: Type safety — strict mode non-negotiable -**By:** Edie (carried from beta) -**What:** `strict: true`, `noUncheckedIndexedAccess: true`, no `@ts-ignore` allowed. -**Why:** Types are contracts. If it compiles, it works. Strict mode catches entire categories of bugs. +--- -### 2026-02-21: Hook-based governance over prompt instructions -**By:** Baer (carried from beta) -**What:** Security, PII, and file-write guards are implemented via the hooks module, NOT prompt instructions. -**Why:** Prompts can be ignored or overridden. Hooks are code — they execute deterministically. +### Adoption Tracking — Opt-In Architecture +**By:** Flight (implementing Brady's directives above) +**Date:** 2026-03-09 -### 2026-02-21: Node.js ≥20, ESM-only, streaming-first -**By:** Fortier (carried from beta) -**What:** Runtime target is Node.js 20+. ESM-only (no CJS shims, no dual-package hazards). Async iterators over buffers. -**Why:** Modern Node.js features enable cleaner async patterns. ESM-only eliminates CJS interop complexity. +### 2026-02-21: CLI entry point split — src/index.ts is a pure barrel +**By:** Edie (TypeScript Engineer) +**What:** `src/index.ts` is a pure re-export barrel with ZERO side effects. `src/cli-entry.ts` contains `main()` and all CLI routing. +**Why:** Library consumers importing `@bradygaster/squad` were triggering CLI argument parsing and `process.exit()` on import. -### 2026-02-21: Casting — The Usual Suspects, permanent -**By:** Squad Coordinator (carried from beta) -**What:** Team names drawn from The Usual Suspects (1995). Scribe is always Scribe. Ralph is always Ralph. Names persist across repos and replatforms. -**Why:** Names are team identity. The team rebuilt Squad beta with these names. +### 2026-02-21: Process.exit() refactor — library-safe CLI functions +**By:** Kujan (SDK Expert) +**What:** `fatal()` throws `SquadError` instead of `process.exit(1)`. Only `cli-entry.ts` may call `process.exit()`. +**Pattern:** Library functions throw `SquadError`. CLI entry catches and exits. Library consumers catch for structured error handling. -### 2026-02-21: Proposal-first workflow -**By:** Keaton (carried from beta) -**What:** Meaningful changes require a proposal in `docs/proposals/` before execution. -**Why:** Proposals create alignment before code is written. Cheaper to change a doc than refactor code. +### 2026-02-21: User directive — docs as you go +**By:** bradygaster (via Copilot) +**What:** Doc and blog as you go during SquadUI integration work. Doesn't have to be perfect — keep docs updated incrementally. -### 2026-02-21: Tone ceiling — always enforced -**By:** McManus (carried from beta) -**What:** No hype, no hand-waving, no claims without citations. Every public-facing statement must be substantiated. -**Why:** Trust is earned through accuracy, not enthusiasm. +### 2026-02-22: Runtime EventBus as canonical bus +**By:** Fortier +**What:** `runtime/event-bus.ts` (colon-notation: `session:created`, `subscribe()` API) is the canonical EventBus for all orchestration classes. The `client/event-bus.ts` (dot-notation) remains for backward-compat but should not be used in new code. +**Why:** Runtime EventBus has proper error isolation — one handler failure doesn't crash others. -### 2026-02-21: Zero-dependency scaffolding preserved -**By:** Rabin (carried from beta) -**What:** CLI remains thin (`cli.js`), runtime stays modular. Zero runtime dependencies for the CLI scaffolding path. -**Why:** Users should be able to run `npx` without downloading a dependency tree. +### 2026-02-22: Subpath exports in @bradygaster/squad-sdk +**By:** Edie (TypeScript Engineer) +**What:** SDK declares subpath exports (`.`, `./parsers`, `./types`, and module paths). Each uses types-first condition ordering. +**Constraints:** Every subpath needs a source barrel. `"types"` before `"import"`. ESM-only: no `"require"` condition. -### 2026-02-21: Merge driver for append-only files -**By:** Kobayashi (carried from beta) -**What:** `.gitattributes` uses `merge=union` for `.squad/decisions.md`, `agents/*/history.md`, `log/**`, `orchestration-log/**`. -**Why:** Enables conflict-free merging of team state across branches. Both sides only append content. +### 2026-02-22: User directive — Aspire testing requirements +**By:** Brady (via Copilot) +**What:** Integration tests must launch the Aspire dashboard and validate OTel telemetry shows up. Use Playwright. Use latest Aspire bits. Reference aspire.dev (NOT learn.microsoft.com). It's "Aspire" not ".NET Aspire". -### 2026-02-21T20:25:35Z: User directive — Interactive Shell as Primary UX +### 2026-02-23: User directive — code fences **By:** Brady (via Copilot) -**What:** Squad becomes its own interactive CLI shell. `squad` with no args enters a REPL where users talk directly to the team. Copilot SDK is the LLM backend — Squad shells out to it for completions, not the other way around. -**Why:** Copilot CLI has usability issues (unreliable agent handoffs, no visibility into background work). Squad needs to own the full interactive experience with real-time status and direct coordination UX. -**How:** Terminal UI with `ink` (React for CLIs), SDK session management with streaming, direct agent spawning (one session per agent). This becomes Wave 0 (foundation). -**Decisions needed:** Terminal UI library (ink vs. blessed), streaming (event-driven vs. polling), session lifecycle (per-agent vs. pool), background cleanup (explicit vs. timeout). +**What:** Never use / or \ as code fences in GitHub issues, PRs, or comments. Only use backticks to format code. -### 2026-02-21T21:22:47Z: User directive — rename `squad watch` to `squad triage` +### 2026-02-23: User Directive — Docs Overhaul & Publication Pause **By:** Brady (via Copilot) -**What:** "squad watch" should be renamed to "squad triage" — user feedback that the command name should reflect active categorization/routing, not passive observation. -**Why:** User request — captured for team memory. +**What:** Pause docs publication until Brady explicitly gives go-ahead. Tone: lighthearted, welcoming, fun (NOT stuffy). First doc should be "first experience" with squad CLI. All docs: brief, prompt-first, action-oriented, fun. Human tone throughout. + +### 2026-02-23: Use sendAndWait for streaming dispatch +**By:** Kovash (REPL Expert) +**What:** `dispatchToAgent()` and `dispatchToCoordinator()` use `sendAndWait()` instead of `sendMessage()`. Fallback listens for `turn_end`/`idle` if unavailable. +**Why:** `sendMessage()` is fire-and-forget — resolves before streaming deltas arrive. +**Impact:** Never parse `accumulated` after a bare `sendMessage()`. Always use `awaitStreamedResponse`. + +### 2026-02-23: extractDelta field priority — deltaContent first +**By:** Kovash (REPL Expert) +**What:** `extractDelta` priority: `deltaContent` > `delta` > `content`. Matches SDK actual format. +**Impact:** Use `deltaContent` as the canonical field name for streamed text chunks. + +### 2026-02-24: Per-command --help/-h: intercept-before-dispatch pattern +**By:** Fenster (Core Dev) +**What:** All CLI subcommands support `--help` and `-h`. Help intercepted before command routing prevents destructive commands from executing. +**Convention:** New CLI commands MUST have a `getCommandHelp()` entry with usage, description, options, and 2+ examples. -### 2026-02-21T21:35:22Z: User directive — CLI command naming: `squad loop` +### 2026-02-25: REPL cancellation and configurable timeout +**By:** Kovash (REPL Expert) +**What:** Ctrl+C immediately resets `processing` state. Timeout: `SQUAD_REPL_TIMEOUT` (seconds) > `SQUAD_SESSION_TIMEOUT_MS` (ms) > 600000ms default. CLI `--timeout` flag sets env var. + +### 2026-02-24: Shell Observability Metrics +**By:** Saul (Aspire & Observability) +**What:** Four metrics under `squad.shell.*` namespace, gated behind `SQUAD_TELEMETRY=1`. +**Convention:** Shell metrics require explicit consent via `SQUAD_TELEMETRY=1`, separate from OTLP endpoint activation. + +### 2026-02-23: Telemetry in both CLI and agent modes **By:** Brady (via Copilot) -**What:** The work monitor CLI command should be `squad loop`, not `squad ralph` or `squad monitor`. "Loop" is universally understood — no Squad lore needed. Finalized preference (supersedes Keaton's recommendations in favor of `squad monitor`). Update issue #269 accordingly. -**Why:** User request — final naming decision. Brady prefers `squad loop` for clarity and universal understanding. +**What:** Squad should pump telemetry during BOTH modes: (1) standalone Squad CLI, and (2) running as an agent inside GitHub Copilot CLI. + +### 2026-02-27: ASCII-only separators and NO_COLOR +**By:** Cheritto (TUI Engineer) +**What:** All separators use ASCII hyphens. Text-over-emoji principle: text status is primary, emoji is supplementary. +**Convention:** Use ASCII hyphens for separators. Keep emoji out of status/system messages. + +### 2026-02-24: Version format — bare semver canonical +**By:** Fenster +**What:** Bare semver (e.g., `0.8.5.1`) for version commands. Display contexts use `squad v{VERSION}`. + +### 2026-02-25: Help text — progressive disclosure +**By:** Fenster +**What:** Default `/help` shows 4 essential lines. `/help full` shows complete reference. + +### 2026-02-24: Unified status vocabulary +**By:** Marquez (CLI UX Designer) +**What:** Use `[WORK]` / `[STREAM]` / `[ERR]` / `[IDLE]` across ALL status surfaces. +**Why:** Most granular, NO_COLOR compatible, text-over-emoji, consistent across contexts. + +### 2026-02-24: Pick one tagline +**By:** Marquez (CLI UX Designer) +**What:** Use "Team of AI agents at your fingertips" everywhere. -### 2026-02-21T21:35:22Z: User directive — `squad hire` CLI command +### 2026-02-24: User directive — experimental messaging **By:** Brady (via Copilot) -**What:** Add a `squad hire` CLI command. This is the team creation entry point — the init experience with personality. "squad hire" instead of "squad init". -**Why:** User request — Brady wants CLI commands that feel natural and match Squad's identity. +**What:** CLI docs should note the project is experimental and ask users to file issues. -### 2026-02-21: CLI rename — `watch` → `triage` (recommended) (consolidated) -**By:** Keaton (Lead) -**What:** Rename `squad watch` to `squad triage`. Keep `watch` as silent alias for backward compatibility. Explicitly recommend against `squad ralph` as a CLI command. Suggest `squad monitor` or `squad loop` instead to describe the persistent monitoring function. -**Why:** "Triage" is 40% more semantically accurate (matches GitHub's own terminology and incident-management patterns). "Ralph" is internal lore — opaque to new users and violates CLI UX conventions (all user-facing commands are action verbs or domain nouns). `squad monitor` is self-describing and professional. -**Details:** Change is low-risk. Silent alias prevents breakage. Confidence 85% for triage rename, 90% confidence Ralph shouldn't be user-facing. -**Reference:** Keaton analysis in `.squad/decisions/inbox/keaton-cli-rename.md` - -### 2026-02-21: SDK M0 blocker — upgrade from `file:` to npm reference (resolved) -**By:** Kujan (SDK Expert), Edie (implementation) -**What:** Change `optionalDependencies` from `file:../copilot-sdk/nodejs` to `"@github/copilot-sdk": "^0.1.25"`. The SDK is published on npm (28 versions, SLSA attestations). This one-line change unblocks npm publish and removes CI dependency on sibling directory. -**Why:** The `file:` reference is the only M0 blocker. Squad's SDK surface is minimal (1 runtime import: `CopilotClient`). Keep SDK in `optionalDependencies` to preserve zero-dependency scaffolding guarantee (Rabin decision). -**Verified:** Build passes (0 errors), all 1592 tests pass with npm reference. No tests require live Copilot CLI server. PR #271 merged successfully. -**Reference:** Kujan audit + Edie implementation in `.squad/decisions/inbox/edie-sdk-swap.md` -**Closes:** #190, #193, #194 - -### 2026-02-21T21:35:22Z: User directive — no temp/memory files in repo root +### 2026-02-28: User directive — DO NOT merge PR #547 **By:** Brady (via Copilot) -**What:** NEVER write temp files, issue files, or memory files to the repo root. All squad state/scratch files belong in .squad/ and ONLY .squad/. Root tree of a user's repo is sacred — don't clutter it. -**Why:** User request — hard rule. Captured for all agents. +**What:** DO NOT merge PR #547 (Squad Remote Control). Do not touch #547 at all. +**Why:** User request — captured for team memory -### 2026-02-21: npm workspace protocol for monorepo -**By:** Edie (TypeScript Engineer) -**Date:** 2026-02-21 -**PR:** #274 -**What:** Use npm-native workspace resolution (version-string references like `"0.6.0-alpha.0"`) instead of `workspace:*` protocol for cross-package dependencies. -**Why:** The `workspace:*` protocol is pnpm/Yarn-specific. npm workspaces resolve workspace packages automatically by matching the package name in the `workspaces` glob — a version-string reference is all that's needed. Using npm-native semantics avoids toolchain lock-in and keeps the monorepo compatible with stock npm. -**Impact:** All future inter-package dependencies in `packages/*/package.json` should use the actual version string, not `workspace:*`. +### 2026-02-28: CLI Critical Gap Issues Filed +**By:** Keaton (Lead) +**What:** 4 critical CLI gaps filed as GitHub issues #554–#557 for explicit team tracking: +- #554: `--preview` flag undocumented and untested +- #556: `--timeout` flag undocumented and untested +- #557: `upgrade --self` is dead code +- #555: `run` subcommand is a stub (non-functional) + +**Why:** Orchestration logs captured gaps but they lacked actionable GitHub tracking and ownership. Filed issues now have explicit assignment to Fenster, clear acceptance criteria, and visibility in Wave E planning. + +### 2026-02-28: Test Gap Issues Filed (10 items) +**By:** Hockney (Tester) +**What:** 10 moderate CLI/test gaps filed as issues #558–#567: +- #558: Exit code consistency untested +- #559: Timeout edge cases untested +- #560: Missing per-command help +- #561: Shell-specific flag behavior untested +- #562: Env var fallback paths untested +- #563: REPL mode transitions untested +- #564: Config file precedence untested +- #565: Agent spawn flags undocumented +- #566: Untested flag aliases +- #567: Flag parsing error handling untested + +**Why:** Each gap identified in coverage analysis but lacked explicit GitHub tracking for prioritization and team visibility. + +### 2026-02-28: Documentation Audit Results (10 issues) +**By:** McManus (DevRel) +**What:** Docs audit filed 10 GitHub issues (#568–#575, #577–#578) spanning: +- Feature documentation lag (#568 `squad run`, #570 consult mode, #572 Ralph smart triage) +- Terminology inconsistency (#569 triage/watch/loop naming) +- Brand compliance (#571 experimental banner on 40+ docs) +- Clarity/UX gaps (#573 response modes, #575 dual-root, #577 VS Code, #578 session examples) +- Reference issue (#574 README command count) + +**Why:** Features shipped faster than documentation. PR #552, #553 merged without doc updates. No automation to enforce experimental banner. Users discover advanced features accidentally. + +**Root cause:** Feature-docs lag, decision-doc drift, no brand enforcement in CI. + +### 2026-02-28: Dogfood UX Issues Filed (4 items) +**By:** Waingro (Dogfooder) +**What:** Dogfood testing against 8 realistic scenarios surfaced 4 UX issues (filed as #576, #579–#581): +- #576 (P1): Shell launch fails in non-TTY piped mode (Blocks CI) +- #580 (P1): Help text overwhelms new users (44 lines, no tiering) +- #579 (P2): Status shows parent `.squad/` as local (confusing in multi-project workspaces) +- #581 (P2): Error messages show debug output always (noisy production logs) + +**Why:** CLI is solid for happy path but first-time user experience and CI/CD integration have friction points. All 4 block either new user onboarding or automation workflows. + +**Priority:** #576 > #580 > #581 > #579. All should be fixed before next public release. + +### 2026-02-28: decisions.md Aggressive Cleanup +**By:** Keaton (Lead) +**What:** Trimmed `decisions.md` from 226KB (223 entries) to 10.3KB (35 entries) — 95% reduction. +- Kept: Core architectural decisions, active process rules, active user directives, current UX conventions, runtime patterns +- Archived: Implementation details, one-time setup, PR reviews, audit reports, wave planning, superseded decisions, duplicates +- Created: `decisions-archive.md` with full original content preserved + +**Why:** Context window bloat during release push. Every agent loads 95% less decisions context. Full history preserved append-only. -### 2026-02-21: Resolution module placement and API separation +**Impact:** File size reduced, agent context efficiency improved, all decisions preserved in archive. + +### 2026-02-28: Backlog Gap Issues Filed (8 items) +**By:** Keaton (Lead) +**Approval:** Brady (via directive in issue request) +**What:** Filed 8 missing backlog items from `.squad/identity/now.md` as GitHub issues. These items were identified as "should-fix" polish or "post-M1" improvements but lacked explicit GitHub tracking until now. + +**Why:** Brady requested: "Cross-reference the known backlog against filed issues and file anything missing." The team had filed 28 issues this session (#554–#581), but 8 known items from `now.md` remained unfiled. Without GitHub issues, these lack ownership assignment, visibility for Wave E planning, trackability in automated workflows, and routing to squad members. + +**Issues Filed:** +- #583 (squad:rabin): Add `homepage` and `bugs` fields to package.json +- #584 (squad:mcmanus): Document alpha→v1.0 breaking change policy in README +- #585 (squad:edie): Add `noUncheckedIndexedAccess` to tsconfig +- #586 (squad:edie): Tighten ~26 `any` types in SDK +- #587 (squad:mcmanus): Add architecture overview doc +- #588 (squad:kujan): Implement SQUAD_DEBUG env var test +- #589 (squad:kujan): One real Copilot SDK integration test +- #590 (squad:baer): `npm audit fix` for dev-dependency ReDoS warnings +- #591 (squad:hockney, type:bug): Aspire dashboard test fails — docker pull in test suite +- #592 (squad:rabin): Replace workspace:* protocol with version string + +**Impact:** Full backlog now visible with explicit issues. No unmapped items. Each issue routed to the squad member domain expert. Issues are independent; can be executed in any order. + +### 2026-02-28: Codebase Scan — Unfiled Issues Audit **By:** Fenster (Core Dev) -**Date:** 2026-02-21 -**Re:** #210, #211 -**What:** -- `resolveSquad()` and `resolveGlobalSquadPath()` live in `src/resolution.ts` at the repo root, not in `packages/squad-sdk/`. -- The two functions are independent — `resolveSquad()` does NOT automatically fall back to `resolveGlobalSquadPath()`. -**Why:** -1. **Placement:** Code hasn't migrated to the monorepo packages yet. Putting it in `packages/squad-sdk/src/` would create a split that doesn't match the current build pipeline (`tsc` compiles `src/` to `dist/`). When the monorepo migration happens, `src/resolution.ts` moves with everything else. -2. **Separation of concerns:** Issue #210 says "repo squad always wins over personal squad" — that's a *policy* decision for the consumer, not for the resolution primitives. Keeping the two functions independent lets CLI/runtime compose them however needed (e.g., try repo first, fall back to global, or merge both). -**Impact:** Low. When packages split happens, move `src/resolution.ts` into `packages/squad-sdk/src/`. The public API shape stays the same. - -### 2026-02-21: Changesets setup — independent versioning for squad-sdk and squad-cli -**By:** Kobayashi (Git & Release) -**Date:** 2026-02-21 -**Re:** #208 -**What:** Installed and configured @changesets/cli v2 for independent package versioning across the monorepo. -**Configuration:** -- `access`: `"public"` (both packages will be published) -- `baseBranch`: `"main"` (release branch for changesets) -- `fixed`: `[]` (empty — no linked releases) -- `linked`: `[]` (empty — no linked releases) -- `updateInternalDependencies`: `"patch"` (default, appropriate for SDK→CLI dependency) -**Why:** Squad is a monorepo with two distinct packages (squad-sdk and squad-cli) with different release cadences and audiences. Independent versioning prevents unnecessary releases and version inflation when only one package changes. -**Implementation:** `.changeset/config.json` created, npm script `changeset:check` added to `package.json` for CI validation. -**Next Steps:** Contributors use `npx changeset add` before merge; release workflow runs `changeset publish` to GitHub. - -### 2026-02-21: --global flag and status command pattern +**Requested by:** Brady +**Date:** 2026-02-28T22:05:00Z +**Status:** Complete — 2 new issues filed + +**What:** Systematic scan of the codebase to identify known issues that haven't been filed as GitHub issues. Checked: +1. TODO/FIXME/HACK/XXX comments in code +2. TypeScript strict mode violations (@ts-ignore/@ts-expect-error) +3. Skipped/todo tests (.skip() or .todo()) +4. Errant console.log statements +5. Missing package.json metadata fields + +**Findings:** +- Type safety violations: ✅ CLEAN — Zero @ts-ignore/@ts-expect-error found. Strict mode compliance excellent. +- Workspace protocol: ❌ VIOLATION — 1 issue filed (#592): `workspace:*` in squad-cli violates npm workspace convention +- Skipped tests: ❌ GAP — 1 issue filed (#588): SQUAD_DEBUG test is .todo() placeholder +- Console.log: ✅ INTENTIONAL — All are user-facing output (status, errors) +- TODO comments: ✅ TEMPLATES — TODOs in generated workflow templates, not code +- Package.json: ✅ TRACKED — Missing homepage/bugs already filed as #583 + +**Code Quality Assessment:** +- Type Safety (Excellent): Zero violations of strict mode or type suppression. Team decision being followed faithfully. +- TODO/FIXME Comments (Clean): All TODOs in upgrade.ts and workflows.ts are template strings for generated GitHub Actions YAML, intentionally scoped. +- Console Output (Intentional): All are user-facing (dashboard startup, OTLP endpoint, issue labeling, shell loading) — no debug debris. +- Dead Code (None Found): No unreachable code, orphaned functions, or unused exports detected. + +**Recommendations:** +1. Immediate: Fix workspace protocol violation (#592) — violates established team convention +2. Soon: Implement SQUAD_DEBUG test (#588) — fills observable test gap +3. Going forward: Maintain type discipline; review package.json metadata during SDK/CLI version bumps + +**Conclusion:** Codebase in good health. Type safety discipline strong. No hidden technical debt. Conventions mostly followed (one npm workspace exception). Test coverage has minor gaps in observability. + +### 2026-02-28: Auto-link detection for preview builds **By:** Fenster (Core Dev) -**Date:** 2026-02-21 -**Re:** #212, #213 -**What:** -- `--global` flag on `init` and `upgrade` routes to `resolveGlobalSquadPath()` instead of `process.cwd()`. -- `squad status` composes both `resolveSquad()` and `resolveGlobalSquadPath()` to show which squad is active and why. -- All routing logic stays in `src/index.ts` main() — init.ts and upgrade.ts are path-agnostic (they take a `dest` string). -**Why:** -1. **Thin CLI contract:** init and upgrade already accept a destination directory. The `--global` flag is a CLI concern, not a runtime concern — so it lives in the CLI routing layer only. -2. **Composition over fallback:** `squad status` demonstrates the intended consumer pattern from #210/#211: try repo resolution first, then check global path. The resolution primitives stay independent. -3. **Debugging UX:** Status shows repo resolution, global path, and global squad existence — all the info needed to debug "why isn't my squad loading?" issues. -**Impact:** Low. Single-file change to `src/index.ts`. No changes to resolution algorithms or init/upgrade internals. +**Date:** 2026-02-28 +**What:** When running from source (`VERSION` contains `-preview`), the CLI checks if `@bradygaster/squad-cli` is globally npm-linked. If not, it prompts the developer to link it. Declining creates `~/.squad/.no-auto-link` to suppress future prompts. +**Why:** Dev convenience — saves contributors from forgetting `npm link` after cloning. Non-interactive commands (help, version, export, import, doctor, scrub-emails) skip the check. Everything is wrapped in try/catch so failures are silent. +**Impact:** Only affects `-preview` builds in interactive TTY sessions. No effect on published releases or CI. + +### 2026-03-01T00:34Z: User directive — Full scrollback support in REPL shell +**By:** Brady (via Copilot) +**What:** The REPL shell must support full scrollback — users should be able to scroll up and down to see all text (paste, run output, rendered content, logs) over time, like GitHub Copilot CLI does. The current Ink-based rendering loses/hides content and that's unacceptable. +**Why:** User request — captured for team memory. This is a P0 UX requirement for the shell. +**Status:** P0 blocking issue. Requires rendering architecture review (Cheritto, Kovash, Marquez). + +### 2026-03-01T04:47Z: User directive — Auto-incrementing build numbers +**By:** Brady (via Copilot) +**What:** Add auto-incrementing build numbers to versions. Format: `0.8.6.{N}-preview` where N increments each local build. Tracks build-to-release cadence. +**Why:** User request — captured for team memory. -### 2026-02-21: No repo root clutter — ensureSquadPath() guard +### 2026-03-01: Nap engine — dual sync/async export pattern **By:** Fenster (Core Dev) -**Date:** 2026-02-21 -**Re:** #273 +**What:** The nap engine (`cli/core/nap.ts`) exports both `runNap` (async, for CLI entry) and `runNapSync` (sync, for REPL). All internal operations use sync fs calls. The async wrapper exists for CLI convention consistency. +**Why:** REPL `executeCommand` is synchronous and cannot await. ESM forbids `require()`. Exporting a sync variant keeps the REPL integration clean without changing the shell architecture. +**Impact:** Future commands that need both CLI and REPL support should follow this pattern if they only do sync fs work. -**What:** -- Added `ensureSquadPath(filePath, squadRoot)` in `src/resolution.ts` — a guard that validates a target path is inside `.squad/` or the system temp directory before any write occurs. Throws with a descriptive error if the path is outside both. -- Exported from the public API (`src/index.ts`). +### 2026-03-01: First-run gating test strategy +**By:** Hockney (Tester) +**Date:** 2026-03-01 +**Issue:** #607 +**What:** Created `test/first-run-gating.test.ts` with 25 tests covering 6 categories of Init Mode gating. Tests use logic-level extraction from App.tsx conditionals, filesystem marker lifecycle via `loadWelcomeData`, and source-code structural assertions for render ordering. No full App component rendering — SDK dependencies make that impractical for unit tests. +**Why:** 3059 tests existed with zero enforcement of first-run gating behavior. The `.first-run` marker, banner uniqueness, assembled-message gating, warning suppression, session-scoped keys, and terminal clear ordering were all untested paths that could regress silently. +**Impact:** All squad members: if you modify `loadWelcomeData`, the `firstRunElement` conditional in App.tsx, or the terminal clear sequence in `runShell`, these tests will catch regressions. The warning suppression tests replicate the `cli-entry.ts` pattern — if that pattern changes, update both locations. -**Why:** -Brady's hard rule: ALL squad scratch/temp/state files MUST go in `.squad/` only. During issue creation, 20+ temp files were written directly to the repo root. This guard provides a single validation function that any file-writing code path can call to enforce the policy deterministically (per the hooks-over-prompts decision). +### Verbal's Analysis: "nap" Skill — Context Window Optimization +**By:** Verbal (Prompt Engineer) +**Requested by:** Brady +**Date:** 2026-03-01 +**Scope:** Approved. Build it. Current context budget analysis: +- Agent spawn loads charter (~500t) + history + decisions.md (4,852t) + team.md (972t) +- Hockney: 25,940t history (worst offender) +- Fenster: 22,574t (history + CLI inventory) +- Coherence cliff: 40-50K tokens on non-task context + +**Key Recommendations:** +1. **Decision distillation:** Keep decisions.md as single source of truth (don't embed in charters — creates staleness/duplication) +2. **History compression — 12KB rule insufficient:** Six agents blow past threshold. Target **4KB ceiling per history** (~1,000t) with assertions not stories. +3. **Nap should optimize:** Deduplication (strip decisions.md content echoed in histories), staleness (flag closed PRs, merged work), charter bloat (stay <600t), skill pruning (archive high-confidence, no-recent-invocation skills), demand-loading for extra files (CLI inventory, UX catalog, fragility catalog). +4. **Enforcement:** Nap runs periodically or on-demand, enforces hard ceilings without silent quality degradation. + +### ShellApi.clearMessages() for terminal state reset +**By:** Kovash (REPL Expert) +**Date:** 2026-03-01 +**What:** `ShellApi` now exposes `clearMessages()` which resets both `messages` and `archivedMessages` React state. Used in session restore and `/clear` command. +**Why:** Without clearing archived messages, old content bleeds through when restoring sessions or clearing the shell. The `/clear` command previously only reset `messages`, leaving `archivedMessages` in the Static render list. +**Impact:** Any code calling `shellApi` to reset shell state should use `clearMessages()` rather than manually manipulating message arrays. -**Audit findings:** -- 30+ file write calls across `src/` — most already write into `.squad/` subdirectories or user-requested destinations. -- The `tools/index.ts` write_file tool and `cli/commands/export.ts` write to user-specified paths (intentional, user-requested). -- No existing code paths were changed — this is a new guard utility for future enforcement. +### 2026-03-01: Prompt placeholder hints must not duplicate header banner +**By:** Kovash (REPL Expert) +**Date:** 2026-03-01 +**Issue:** #606 +**What:** The InputPrompt placeholder text must provide *complementary* guidance, never repeat what the header banner already shows. The header banner is the single source of truth for @agent routing and /help discovery. Placeholder hints should surface lesser-known features (tab completion, history navigation, utility commands). +**Why:** Two elements showing "Type @agent or /help" simultaneously creates visual noise and a confusing UX. One consistent prompt style throughout the session. +**Impact:** `getHintText()` in InputPrompt.tsx now has two tiers instead of three. Any future prompt hints should check the header banner first to avoid duplication. -**Impact:** Low. Additive-only change. Existing behavior unchanged. Future code that writes temp/scratch files should call `ensureSquadPath()` before writing. +### 2026-03-02: Paste detection via debounce in InputPrompt +**By:** Kovash (REPL Expert) +**Date:** 2026-03-02 +**What:** InputPrompt uses a 10ms debounce on `key.return` to distinguish paste from intentional Enter. If more input arrives within 10ms → paste detected → newline preserved. If timer fires without input → real Enter → submit. A `valueRef` (React ref) mirrors mutations synchronously since closure-captured `value` is stale during rapid `useInput` calls. In disabled state, `key.return` appends `\n` to buffer instead of being ignored. +**Why:** Multi-line paste was garbled because `useInput` fires per-character and `key.return` triggered immediate submission. +**Impact:** 10ms delay on single-line submit is imperceptible. UX: multi-line paste preserved. Testing: Hockney should verify paste scenarios use `jest.useFakeTimers()` or equivalent. Future: if Ink adds native bracketed-paste support, debounce can be replaced. + +### 2026-03-01: First-run init messaging — single source of truth +**By:** Kovash (REPL & Interactive Shell) +**Date:** 2026-03-01 +**Issue:** #625 +**What:** When no roster exists, only the header banner tells the user about `squad init` / `/init`. The `firstRunElement` block returns `null` for the empty-roster case instead of showing a duplicate message. `firstRunElement` is reserved for the "Your squad is assembled" onboarding when a roster already exists. +**Why:** Two competing UI elements both said "run squad init" — visual noise that confuses the information hierarchy. Banner is persistent and visible; it owns the no-roster guidance. `firstRunElement` owns the roster-present first-run experience. +**Impact:** App.tsx only. No API or prop changes. Banner text reworded to prioritize `/init` (in-shell path) over exit-and-run. + +### 2026-03-01: NODE_NO_WARNINGS for subprocess warning suppression +**By:** Cheritto (TUI Engineer) +**Date:** 2026-03-01 +**Issue:** #624 +**What:** `process.env.NODE_NO_WARNINGS = '1'` is set as the first executable line in `cli-entry.ts` (line 2, after shebang). This supplements the existing `process.emitWarning` override. +**Why:** The Copilot SDK spawns child processes that inherit environment variables but NOT in-process monkey-patches like `process.emitWarning` overrides. `NODE_NO_WARNINGS=1` is the Node.js-native mechanism for suppressing warnings across an entire process tree. Without it, `ExperimentalWarning` messages (e.g., SQLite) leak into the terminal via the SDK's subprocess stderr forwarding. +**Pattern:** When suppressing Node.js warnings, use BOTH: (1) `process.env.NODE_NO_WARNINGS = '1'` — covers child processes (env var inheritance); (2) `process.emitWarning` override — covers main process (belt-and-suspenders). +**Impact:** Eliminates `ExperimentalWarning` noise in terminal for all Squad CLI users, including when the Copilot SDK spawns subprocesses. + +### 2026-03-01: No content suppression based on terminal width +**By:** Cheritto (TUI Engineer) +**Date:** 2026-03-01 +**What:** Terminal width tiers (compact ≤60, standard, wide ≥100) may adjust *layout* (e.g., wrapping, column arrangement) but must NOT suppress or truncate *content*. Every piece of information shown at 120 columns must also be shown at 40 columns. +**Why:** Users can scroll. Hiding roster names, spacing, help text, or routing hints on narrow terminals removes information the user needs. Layout adapts to width; content does not. +**Convention:** `compact` variable may be used for layout decisions (flex direction, column vs. row) but must NOT gate visibility of text, spacing, or UI sections. `wide` may add supplementary content but narrow must not remove it. -### 2026-02-21: CLI routing logic is testable via composition, not process spawning -**By:** Hockney (Tester) -**Date:** 2026-02-21 -**Re:** #214 +### 2026-03-01: Multi-line user message rendering pattern +**By:** Cheritto (TUI Engineer) +**Date:** 2026-03-01 +**What:** Multi-line user messages in the Static scrollback use `split('\n')` with a column layout: first line gets the `❯` prefix, subsequent lines get `paddingLeft={2}` for alignment. +**Why:** Ink's horizontal `` layout doesn't handle embedded `\n` in `` children predictably when siblings exist. Explicit line splitting with column flex direction gives deterministic multi-line rendering. +**Impact:** Any future changes to user message prefix width must update the `paddingLeft={2}` on continuation lines to match. -**What:** Integration tests for `squad status` and `--global` flag test the *routing logic* (the conditional expressions from `main()`) directly, rather than spawning a child process and parsing stdout. +### 2026-03-01: Elapsed time display — inline after message content +**By:** Cheritto (TUI Engineer) +**Date:** 2026-03-01 +**Issue:** #605 +**What:** Elapsed time annotations on completed agent messages are always rendered inline after the message content as `(X.Xs)` in dimColor. This applies to the Static scrollback block in App.tsx, which is the canonical render path for all completed messages. +**Why:** After the Static scrollback refactor, MessageStream receives `messages=[]` and only renders live streaming content. The duration code in MessageStream was dead. Moving duration display into the Static block ensures it always appears consistently. +**Convention:** `formatDuration()` from MessageStream.tsx is the shared formatter. Format is `Xms` for <1s, `X.Xs` for ≥1s. Always inline, always dimColor, always after content text. -**Why:** -1. `main()` in `src/index.ts` calls `process.exit()` and is not exported — spawning would be flaky and slow. -2. The routing logic is simple conditionals over `resolveSquad()` and `resolveGlobalSquadPath()` — testing those compositions directly is deterministic and fast. -3. If `main()` is ever refactored to export a testable function, these tests can be upgraded — the assertions stay the same. +### 2026-03-01: Banner usage line separator convention +**By:** Cheritto (TUI Engineer) +**Date:** 2026-03-01 +**What:** Banner hint/usage lines use middle dot `·` as inline separator. Init messages use single CTA (no dual-path instructions). +**Why:** Consistent visual rhythm. Middle dot is lighter than em-dash or hyphen for inline command lists. Single CTA reduces cognitive load for new users. +**Impact:** App.tsx headerElement. Future banner copy should follow same separator and single-CTA pattern. -**Impact:** Low. Sets a pattern for future CLI integration tests: test the logic, not the process. +### 2026-03-02: REPL casting engine design +**By:** Fenster (Core Dev) +**Date:** 2026-03-02 +**Status:** Implemented +**Issue:** #638 +**What:** Created `packages/squad-cli/src/cli/core/cast.ts` as a self-contained casting engine with four exports: +1. `parseCastResponse()` — parses the `INIT_TEAM:` format from coordinator output +2. `createTeam()` — scaffolds all `.squad/agents/` directories, writes charters, updates team.md and routing.md, writes casting state JSON +3. `roleToEmoji()` — maps role strings to emoji, reusable across the CLI +4. `formatCastSummary()` — renders a padded roster summary for terminal display -### 2026-02-21: Ink + React dependency versions -**By:** Edie (TypeScript Engineer) -**Date:** 2026-02-21 -**Re:** #233 -**PR:** #281 +Scribe and Ralph are always injected if missing from the proposal. Casting state is written to `.squad/casting/` (registry.json, history.json, policy.json). +**Why:** Enables coordinator to propose and create teams from within the REPL session after `squad init`. +**Implications:** -**What:** -- **ink@6.8.0** — latest stable, ESM-native, no CJS shims required -- **react@19.2.4** — required by ink 6.x (peer dependency); React 19 is ESM-friendly -- **ink-testing-library@4.0.0** — matches ink 6.x major version pairing -- **@types/react@19.2.14** — TypeScript types for React 19 +### 2026-03-02: Beta → Origin Migration: Version Path (v0.5.4 → v0.8.17) -**Why:** ink 6.x + React 19 are fully ESM-native — aligns with our ESM-only policy. ink-testing-library enables unit-testing ink components without a real terminal. All added as root-level deps for now; can be scoped to `packages/squad-cli` during monorepo migration. +**By:** Kobayashi (Git & Release) +**Date:** 2026-03-02 +**Context:** Analyzed migration from beta repo (`bradygaster/squad`, v0.5.4) to origin repo (`bradygaster/squad-pr`, v0.8.18-preview). Version gap spans 0.6.x, 0.7.x, 0.8.0–0.8.16 (internal origin development only). -**Impact:** Low. No source changes — dependency additions only. Build passes (tsc strict), all 1621 tests pass. +**What:** Beta will jump directly from v0.5.4 to v0.8.17 (skip all intermediate versions). Rationale: +1. **Semantic versioning allows gaps** — version numbers are labels, not counters +2. **Users care about features, not numbers** — comprehensive changelog is more valuable than version sequence +3. **Simplicity reduces risk** — single migration release is easier to execute and communicate +4. **Precedent exists** — major refactors/rewrites commonly skip versions (Angular 2→4, etc) -### 2026-02-21: GitHub-native distribution deprecated in favor of npm -**By:** Fenster (Core Dev) -**Date:** 2026-02-21 -**Re:** #219 +**Risks & Mitigations:** +- Risk: Version jump confuses users. Mitigation: Clear release notes explaining the gap + comprehensive changelog +- Risk: Intermediate versions were never public (no user expectations). Mitigation: This is actually a benefit — no backfill needed -**What:** -- Root `cli.js` now prints a deprecation warning to stderr when invoked via `npx github:bradygaster/squad`. -- Users are directed to `npm install -g @bradygaster/squad-cli` or `npx @bradygaster/squad-cli`. -- The warning is non-blocking — existing behavior continues after the notice. +**Impact:** After merge, beta repo version jumps from v0.5.4 to v0.8.17. All intermediate work is included in the 0.8.17 release. Next release after v0.8.17 may be v0.8.18 or v0.9.0 (team decision post-merge). -**Why:** The `@bradygaster/squad-cli` and `@bradygaster/squad-sdk` packages are now published to npm. The GitHub-native distribution (`npx github:bradygaster/squad`) was the original entry point but is now superseded. This deprecation notice gives users a migration path before the GitHub-native entry point is eventually removed. +**Why:** Avoids maintenance burden of backfilling 12+ fake versions. Users get complete feature set in one migration release. -**Supersedes:** The earlier "SDK distribution stays on GitHub" decision (Keaton, carried from beta). npm is now the primary distribution channel. +### 2026-03-02: Beta → Origin Migration: Package Naming -**Impact:** Low. Additive-only change to the bundled `cli.js`. No behavior change — just a stderr warning. +**By:** Kobayashi (Git & Release) +**Date:** 2026-03-02 -### 2026-02-21: Shell chrome patterns and session registry design -**By:** Fenster (Core Dev) -**Date:** 2026-02-21 -**Re:** #236, #237 +**What:** Deprecate `@bradygaster/create-squad` (beta's package name). All future releases use: +- `@bradygaster/squad-cli` (user-facing CLI) +- `@bradygaster/squad-sdk` (programmatic SDK for integrations) -**Shell Chrome:** The interactive shell header uses box-drawing characters (`╭╰│─`) for visual chrome. Version is read from `package.json` at runtime via `createRequire(import.meta.url)` — no hardcoded version strings. Box-drawing chrome is universally supported in modern terminals and provides clear visual framing without external dependencies. Using `createRequire` for JSON import follows the existing pattern in `src/build/github-dist.ts` and avoids ESM JSON import assertions. +**Why:** Origin's naming is more accurate and supports independent versioning if needed. Monorepo structure benefits from clear package separation. -**Exit handling:** Three exit paths — `exit` command, `/quit` command, and Ctrl+C (SIGINT). All produce the same cleanup message ("👋 Squad out.") for consistency. +**Action:** When v0.8.17 is ready to publish, release a final version of `@bradygaster/create-squad` with deprecation notice: "This package has been renamed to @bradygaster/squad-cli. Install with: npm install -g @bradygaster/squad-cli" -**Session Registry:** `SessionRegistry` is a simple Map-backed class with no persistence, no event emitting, and no external dependencies. It tracks agent sessions by name with status lifecycle: `idle` → `working` → `streaming` → `idle`/`error`. Designed as a pure state container that the ink UI will consume. The Map-based approach allows O(1) lookup by agent name, which is the primary access pattern for status display. +**Impact:** Package ecosystem clarity. No breaking change for users upgrading (CLI handles detection and warnings). -**Impact:** Low. Two files changed. No API surface changes outside the shell module. SessionRegistry is exported for future consumption but has no current consumers. +### 2026-03-02: Beta → Origin Migration: Retroactive v0.8.17 Tag -### 2026-02-21: TSX compilation enabled in root tsconfig -**By:** Fenster (Core Dev) -**Date:** 2026-02-21 -**Re:** #242, #243, #244 +**By:** Kobayashi (Git & Release) +**Date:** 2026-03-02 -**What:** Added `"jsx": "react-jsx"` to the root `tsconfig.json` to enable TSX compilation for ink-based React components in `src/cli/shell/components/`. +**What:** Retroactively tag commit `5b57476` ("chore(release): prep v0.8.16 for npm publish") as v0.8.17. This commit and v0.8.16 have identical code. -**Why:** The shell UI uses ink (React for CLIs), which requires JSX support. `react-jsx` is the modern transform — no need to import React in every file for JSX (though we do for explicitness). This is a project-wide setting because all TSX files live under `src/` which is the root `rootDir`. +**Rationale:** +- Commit `6fdf9d5` jumped directly to v0.8.17-preview (no v0.8.17 release tag exists) +- Commit `87e4f1c` bumps to v0.8.18-preview "after 0.8.17 release" (implying v0.8.17 was released) +- Retroactive tagging is less disruptive than creating a new prep commit and rebasing -**Components created:** -- `AgentPanel.tsx` — agent status display (consumes `AgentSession` from `types.ts`) -- `MessageStream.tsx` — streaming message output (consumes `ShellMessage` from `types.ts`) -- `InputPrompt.tsx` — readline input with history navigation -- `components/index.ts` — barrel export +**Action:** When banana gate clears, tag origin commit `5b57476` as v0.8.17. -All components are pure presentational — no SDK calls, no side effects. State management is the responsibility of the shell orchestrator. +**Why:** Completes the missing link in origin's tag history. Indicates to users which commit was released as v0.8.17. -**Impact:** Low. Only affects `.tsx` files. No existing `.ts` files are impacted. The setting is compatible with strict mode and NodeNext module resolution. +### 2026-03-02: npx Distribution Migration: Error-Only Shim Strategy -### 2026-02-21: Shell module structure and entry point routing -**By:** Fenster (Core Dev) -**Date:** 2026-02-21 -**Re:** #234, #235 -**PR:** #282 +**By:** Rabin (Distribution) +**Date:** 2026-03-02 +**Context:** Beta repo currently uses GitHub-native distribution (`npx github:bradygaster/squad`). Origin uses npm distribution (`npm install -g @bradygaster/squad-cli`). After merge, old path will break. -**What:** -- `src/cli/shell/` module created with `index.ts`, `types.ts`, and `components/` placeholder directory. -- `squad` with no args now launches `runShell()` (interactive shell) instead of `runInit()`. -- `squad init` remains available as an explicit subcommand — no functionality removed. +**Problem:** After migration, `npx github:bradygaster/squad` fails (root `package.json` has no `bin` entry). Users hitting the old path get cryptic npm error. -**Why:** -1. **Entry point change:** Brady's directive makes the interactive shell the primary UX. Running `squad` with no args should enter the shell, not re-run init. Init is still available via `squad init`. -2. **Placeholder over premature implementation:** `runShell()` is console.log-only. Ink dependency is handled separately (#233). This keeps the shell module structure ready without coupling to the UI library. -3. **Types first:** `ShellState`, `ShellMessage`, and `AgentSession` interfaces define the shell's data model before any UI code exists. This lets other agents (ink wiring, agent spawning) code against stable types. +**Solution — Option 5 (Error-only shim):** +1. Add root `bin` entry pointing to `cli.js` +2. `cli.js` detects GitHub-native invocation and prints **bold, clear error** with migration instructions +3. Exit with code 1 (fail fast, no hidden redirection) -**Impact:** Low. No existing tests broken (1621/1621 pass). The only behavior change is `squad` (no args) prints a shell header and exits instead of running init. `squad init` and `squad --help` / `squad help` continue to work as before. +**Implementation:** +```json +{ + "bin": { + "squad": "./cli.js" + } +} +``` -### 2026-02-21: Agent spawn infrastructure pattern -**By:** Fenster (Core Dev) -**Date:** 2026-02-21 -**Re:** #238 +Update `cli.js` to print error message with new install instructions: +``` +npm install -g @bradygaster/squad-cli +``` -**What:** Created `src/cli/shell/spawn.ts` with three exported functions: -- `loadAgentCharter(name, teamRoot?)` — filesystem charter loading via `resolveSquad()` -- `buildAgentPrompt(charter, options?)` — system prompt construction from charter + context -- `spawnAgent(name, task, registry, options?)` — full spawn lifecycle with SessionRegistry integration +**Pros:** +- ✅ Clear, actionable error message (not cryptic npm error) +- ✅ Aligns with npm-only team decision (no perpetuation of GitHub-native path) +- ✅ Low maintenance burden (simple error script, no complex shim) +- ✅ Can be removed in v1.0.0 when beta users have migrated -SDK session creation (CopilotClient) is intentionally stubbed. The spawn infrastructure is complete; session wiring comes when we understand the SDK's session management API. +**Cons:** +- Immediate breakage (no grace period) — but users get clear guidance -**Why:** -1. **Separation of concerns:** Charter loading, prompt building, and session lifecycle are independent functions. This lets stream bridge and coordinator reuse `buildAgentPrompt` and `spawnAgent` without coupling. -2. **Testability:** `teamRoot` parameter on `loadAgentCharter` allows tests to point at a fixture directory without mocking `resolveSquad()`. -3. **Stub-first:** Rather than guessing the CopilotClient session API shape, we built the surrounding infrastructure. The TODO is a single integration point — when the SDK surface is clear, the change is surgical. +**Why This Over Others:** +- Option 1 (keep working) contradicts npm-only decision +- Option 2 (exit early) same as this, but explicit error format needed +- Option 3 (time-limited) best UX but maintenance burden +- Option 4 (just break) user-hostile without error message +- **Option 5 balances user experience + team decision** -**Impact:** Low. Additive-only. No existing behavior changed. Two files modified: `spawn.ts` (new), `index.ts` (barrel exports added). +**Related Decision:** See 2026-02-21 decision "Distribution is npm-only (GitHub-native removed)" -### 2026-02-21: Session lifecycle owns team discovery -**By:** Fortier (Node.js Runtime) -**Date:** 2026-02-21 -**Re:** #240 +**User Impact:** +- Users running `npx github:bradygaster/squad` see bold error with `npm install -g @bradygaster/squad-cli` instruction +- Existing projects running `squad upgrade` work seamlessly (upgrade logic built-in) +- No data loss or silent breakage -**What:** `ShellLifecycle.initialize()` is the single entry point for team discovery in the interactive shell. It reads `.squad/team.md`, parses the Members table, and registers active agents in `SessionRegistry`. No other shell component should independently parse `team.md` or discover agents. +**Upgrade Path (existing beta users):** +```bash +npm install -g @bradygaster/squad-cli +cd /path/to/project +squad upgrade +squad upgrade --migrate-directory # Optional: .ai-team/ → .squad/ +``` -**Why:** -1. **Single responsibility:** Team discovery is a lifecycle concern — it happens once at shell startup. Scattering `team.md` parsing across components would create divergent interpretations of the manifest format. -2. **Testability:** By owning initialization, `ShellLifecycle` can be tested with a mock filesystem (or temp `.squad/` directory) without touching the registry or renderer. -3. **State consistency:** The lifecycle class is the source of truth for shell state. If initialization fails (missing `.squad/`, missing `team.md`), the state transitions to `error` and downstream components can check `getState().status` rather than catching exceptions everywhere. +**Why:** Rabin's principle: "If users have to think about installation, install is broken." A clear error message respects users better than a cryptic npm error. -**Impact:** Low. Additive-only. Future shell features (command routing, agent spawning) should call `lifecycle.getDiscoveredAgents()` instead of re-parsing `team.md`. +### 2026-02-28: Init flow reliability — proposal-first before code -### 2026-02-21: StreamBridge is an event sink, not a subscriber -**By:** Fortier (Node.js Runtime) -**Date:** 2026-02-21 -**Re:** #239 +**By:** Keaton (Lead) +**Date:** 2026-02-28 +**What:** Init/onboarding fixes require a proposal review before implementation. Proposal at `docs/proposals/reliable-init-flow.md`. Two confirmed bugs (race condition in auto-cast, Ctrl+C doesn't abort init session) plus UX gaps (empty-roster messaging, `/init` no-op). P0 bugs are surgical — don't expand scope. +**Why:** Four PRs (#637–#640) patched init iteratively without a unified design. Before writing more patches, the team needs to agree on the golden path. Proposal-first (per team decision 2026-02-21). +**Impact:** Blocks init-related code changes until Brady reviews the proposal. +- Kovash (REPL): Can call `parseCastResponse` + `createTeam` to wire up casting flow in shell dispatcher +- Verbal (Prompts): INIT_TEAM format is now the contract — coordinator prompt should emit this +- Hockney (Tests): cast.ts needs unit tests for parser edge cases, emoji mapping, file creation + +### 2026-03-02: REPL empty-roster gate — dual check pattern +**By:** Fenster (Core Dev) +**Date:** 2026-03-02 +**What:** REPL dispatch is now gated on *populated* roster, not just team.md existence. `hasRosterEntries()` in `coordinator.ts` checks for table data rows in the `## Members` section. Two layers: `handleDispatch` blocks with user guidance, `buildCoordinatorPrompt` injects refusal prompt. +**Why:** After `squad init`, team.md exists but is empty. Coordinator received a "route to agents" prompt with no agents listed, causing silent generic AI behavior. Users never got told to cast their team. +**Convention:** Post-init message references "Copilot session" (works in VS Code, github.com, and Copilot CLI). The `/init` slash command provides same guidance inside REPL. +**Impact:** All agents — if you modify the `## Members` table format in team.md templates, update `hasRosterEntries()` to match. -**What:** `StreamBridge` receives `StreamingEvent` objects via `handleEvent()` but does not register itself with `StreamingPipeline`. The wiring (`pipeline.onDelta(e => bridge.handleEvent(e))`) is the caller's responsibility. +### 2026-03-02: Connection promise dedup in SquadClient +**By:** Fenster (Core Dev) +**Date:** 2026-03-02 +**What:** `SquadClient.connect()` now uses a promise dedup pattern — concurrent callers share the same in-flight `connectPromise` instead of throwing "Connection already in progress". +**Why:** Eager warm-up and auto-cast both call `createSession()` → `connect()` at REPL startup, racing on the connection. The throw crashed auto-cast every time. +**Impact:** `packages/squad-sdk/src/adapter/client.ts` only. No API surface change. -**Why:** -1. **Testability:** The bridge can be tested with plain event objects — no pipeline instance needed. -2. **Flexibility:** The shell entry point controls which events reach the bridge (e.g., filtering by session, throttling for UI frame rate). -3. **Single responsibility:** The bridge translates events to callbacks; it doesn't manage subscriptions or lifecycle. +### 2026-03-01: CLI UI Polish PRD — Alpha Shipment Over Perfection +**By:** Keaton (Lead) +**Date:** 2026-03-01 +**Context:** Team image review identified 20+ UX issues ranging from P0 blockers to P3 future polish -**Impact:** Low. Pattern applies to all future bridges between the pipeline and UI layers (ink components, web sockets, etc.). +**What:** CLI UI polish follows pragmatic alpha shipment strategy: fix P0 blockers + P1 quick wins, defer grand redesign to post-alpha. 20 discrete issues created with clear priority tiers (P0/P1/P2/P3). -### 2026-02-21: Shell module test patterns — fixtures over mocks -**By:** Hockney (Tester) -**Date:** 2026-02-21 -**Re:** #248 +**Why:** Brady confirmed "alpha-level shipment acceptable — no grand redesign today." Team converged on 3 P0 blockers (blank screens, static spinner, missing alpha banner) that would embarrass us vs. 15+ polish items that can iterate post-ship. -**What:** Shell module tests use `test-fixtures/.squad/` with real files (team.md, routing.md, agent charters) instead of mocking fs calls. The `loadAgentCharter` and `buildCoordinatorPrompt` functions accept a `teamRoot` parameter that enables this pattern. +**Trade-off:** Shipping with known layout quirks (input positioning, responsive tables) rather than blocking on 1-2 week TUI refactor. Users expect alpha rough edges IF we warn them upfront. -**Why:** -1. Real file reads catch encoding issues, path resolution bugs, and parsing edge cases that mocks hide. -2. The `teamRoot` parameter was already designed into the API — tests should use it. -3. StreamBridge tests use callback spies (arrays capturing calls) rather than vi.fn() — simpler to assert on and read. +**Priority Rationale:** +- **P0 (must fix):** User-facing broken states — blank screens, no feedback, looks crashed +- **P1 (quick wins):** Accessibility (contrast), usability (copy clarity), visual hierarchy — high ROI, low effort +- **P2 (next sprint):** Layout architecture, responsive design — important but alpha-acceptable if missing +- **P3 (future):** Fixed bottom input, alt screen buffer, creative spinner — delightful but not blockers -**Impact:** Low. Establishes fixture patterns for future shell module tests. test-fixtures/.squad/ is now a shared test resource. +**Architectural Implications:** +1. **Quick win discovered:** App.tsx overrides ThinkingIndicator's native rotation with static hints (~5 line fix) +2. **Debt acknowledged:** 3 separate separator implementations need consolidation (P2 work) +3. **Layout strategy:** Ink's layout model fights bottom-anchored input. Alt screen buffer is the real solution (P3 deferred). +4. **Issue granularity:** 20 discrete issues vs. 1 monolithic "fix UI" epic — enables parallel work by Cheritto (11 issues), Kovash (4), Redfoot (2), Fenster (1), Marquez (1 review) -### 2026-02-21: Branch protection configuration -**By:** Kobayashi (Git & Release) -**Date:** 2026-02-21 -**Re:** #209 +**Success Gate:** "Brady says it doesn't embarrass us" — qualitative gate appropriate for alpha software. Quantitative gates: zero blank screens >500ms, contrast ≥4.5:1, spinner rotates every 3s. -**Main Branch Protection:** Require PR + passing build status checks. All changes to main require a PR (not direct push). PR cannot be merged until `build` check passes (CI/CD gate). Zero approving reviews required — allows team to use PR merge buttons freely (no blocking review workflow needed). Admins not exempted (same rules apply to everyone, strengthens process integrity). +**Impact:** +- **Team routing:** Clear ownership — Cheritto (TUI), Kovash (shell), Redfoot (design), Marquez (UX review) +- **Timeline transparency:** P0 (1-2 days) → P1 (2-3 days) → P2 (1 week) — alpha ship when P0+P1 done +- **Expectation management:** Out of Scope section explicitly lists grand redesign, advanced features, WCAG audit — prevents scope creep -**Insider Branch:** No protection — allows direct pushes. Insider releases are automation-driven; direct branch push is the automation's path. +### 2026-03-01: Cast confirmation required for freeform REPL casts +**By:** Fenster (Core Dev) +**Date:** 2026-03-01 +**Context:** P2 from Keaton's reliable-init-flow proposal -**Implementation:** Used GitHub API (REST v3): `PUT /repos/{owner}/{repo}/branches/main/protection` with required_status_checks + required_pull_request_reviews. `DELETE /repos/{owner}/{repo}/branches/insider/protection` confirmed no-op (no existing rule). +**What:** When a user types a freeform message in the REPL and the roster is empty, the cast proposal is shown and the user must confirm (y/yes) before team files are created. Auto-cast from .init-prompt and /init "prompt" skip confirmation since the user explicitly provided the prompt. -**Note:** Status check context name is `"build"` — must match the exact check name from CI workflow. If CI workflow renames the check, branch protection must be updated to match. +**Why:** Prevents garbage casts from vague or accidental first messages (e.g., "hello", "what can you do?"). Matches the squad.agent.md Init Mode pattern where confirmation is required before creating team files. -### 2026-02-21: Insider publish package scaffolds -**By:** Kobayashi (Git & Release) -**Date:** 2026-02-21 -**Re:** #215 -**PR:** #283 +**Pattern:** pendingCastConfirmation state in shell/index.ts. handleDispatch intercepts y/n at the top before normal routing. inalizeCast() is the shared helper for both auto-confirmed and user-confirmed paths. -**What:** Added minimal publishable entry points to `packages/squad-sdk/` and `packages/squad-cli/` so the insider publish workflow can produce valid npm packages. +### 2026-03-01: Expose setProcessing on ShellApi +**By:** Kovash (REPL Expert) +**Date:** 2026-03-01 +**Context:** Init auto-cast path bypassed App.tsx handleSubmit, so processing state was never set — spinner invisible during team casting. -**squad-sdk:** -- `src/index.ts`: exports `VERSION` constant (placeholder — full source migration comes later) -- `tsconfig.json`: extends root, outputs to `dist/` with declarations -- `package.json`: added `files`, `scripts.build` +**What:** ShellApi now exposes setProcessing(processing: boolean) so that any code path in index.ts that triggers async work outside of handleSubmit can properly bracket it with processing state. This enables ThinkingIndicator and InputPrompt spinner without duplicating React state management. -**squad-cli:** -- `src/cli.ts`: placeholder binary (`#!/usr/bin/env node`) -- `tsconfig.json`: extends root, outputs to `dist/` with declarations -- `package.json`: added `files`, `scripts.build`; `bin` already pointed to `./dist/cli.js` +**Rule:** Any new async dispatch path in index.ts that bypasses handleSubmit **must** call shellApi.setProcessing(true) before the async work and shellApi.setProcessing(false) in a inally block covering all exit paths. -**Root:** `build` script updated: `tsc && npm run build --workspaces --if-present` +**Files Changed:** +- packages/squad-cli/src/cli/shell/components/App.tsx — added setProcessing to ShellApi interface + wired in onReady +- packages/squad-cli/src/cli/shell/index.ts — added setProcessing calls in handleInitCast (entry, pendingCastConfirmation return, finally block) -**Why:** The insider publish pipeline triggers on push to `insider` branch but both workspace packages were empty scaffolds — no source, no build output, nothing to publish. This adds the minimum viable content so `npm publish` succeeds and the insider channel can be verified end-to-end. +### 2026-03-01T20:13:16Z: User directives — UI polish and shipping priorities +**By:** Brady (via Copilot) +**Date:** 2026-03-01 +Ampersands (&) are prohibited in user-facing documentation headings and body text, per Microsoft Style Guide. -**Constraints respected:** ESM-only, TypeScript strict mode, Node.js >=20, squad-cli depends on squad-sdk via version string, `files` lists ensure only `dist/` and `README.md` ship in the published package. +**Rule:** Use "and" instead. -**Impact:** Low. Does not migrate real source code — these are placeholders. Does not add tests for workspace packages (nothing to test yet). +**Why:** Microsoft Style Guide prioritizes clarity and professionalism. Ampersands feel informal and reduce accessibility. -### 2026-02-21: Distribution moves to npm for production -**By:** Rabin (Distribution) -**Date:** 2026-02-21 -**Re:** #216 +**Exceptions:** +- Brand names (AT&T, Barnes & Noble) +- UI element names matching exact product text +- Code samples and technical syntax +- Established product naming conventions -**What:** Squad packages (`@bradygaster/squad-sdk` and `@bradygaster/squad-cli`) are now distributed via npmjs.com. This supersedes the beta-era decision "Distribution is `npx github:bradygaster/squad` — never move to npmjs.com." +**Scope:** Applies to docs pages, README files, blog posts, community-facing content. Internal files (.squad/** memory files, decision docs, agent history) have flexibility. -**Why:** The project has matured from beta to production. npm is the standard distribution channel for Node.js packages. The insider publish (`0.6.0-alpha.0`) validated the pipeline. Production publish (`0.6.0`) is the natural next step. +**Reference:** https://learn.microsoft.com/en-us/style-guide/punctuation/ampersands -**Workflow:** Tag push `v*` on `main` triggers `.github/workflows/squad-publish.yml`. Auth is CI-only via `setup-node` + `NODE_AUTH_TOKEN`. No root `.npmrc` needed. No `--provenance` (private repo limitation). -**Impact:** Users install via `npm install @bradygaster/squad-cli` (or `npx @bradygaster/squad-cli`). The GitHub-native `npx github:bradygaster/squad` path may still work but is no longer the primary distribution channel. +--- -### 2026-02-21: Coordinator prompt structure — three routing modes -**By:** Verbal (Prompt Engineer) -**Date:** 2026-02-21 -**Re:** #241 +## Adoption & Community -**What:** The coordinator system prompt (`buildCoordinatorPrompt()`) uses a structured response format with three routing modes: -- `DIRECT:` — coordinator answers inline, no agent spawn -- `ROUTE:` + `TASK:` + `CONTEXT:` — single agent delegation -- `MULTI:` with bullet list — fan-out to multiple agents +### `.squad/` Directory Scope — Owner Directive +**By:** Brady (project owner, PR #326 review) +**Date:** 2026-03-10 -The parser (`parseCoordinatorResponse()`) extracts a `RoutingDecision` from the LLM response. Unrecognized formats fall back to `DIRECT` (safe default — never silently drops input). +**Directive:** The `.squad/` directory is **reserved for team state only** — roster, routing, decisions, agent histories, casting, and orchestration logs. Non-team data (adoption tracking, community metrics, reports) must NOT live in `.squad/`. Use `.github/` for GitHub platform integration or `docs/` for documentation artifacts. -**Why:** -1. **Structured output over free-form:** Keyword prefixes (`ROUTE:`, `DIRECT:`, `MULTI:`) are cheap to parse and reliable across model temperatures. No JSON parsing needed. -2. **Fallback-to-direct:** If the LLM doesn't follow the format, the response is surfaced to the user rather than lost. This prevents silent failures in the routing layer. -3. **Prompt composition from files:** team.md and routing.md are read at prompt-build time, not baked in. This means the coordinator adapts to team changes without code changes. +**Source:** [PR #326 comment](https://github.com/bradygaster/squad/pull/326#issuecomment-4029193833) -**Impact:** Low. Additive module. No changes to existing shell behavior. Future work will wire this into the readline loop and SDK session. -### 2026-02-21: CRLF normalization — single utility, applied at parser entry points -**By:** Fenster (Core Dev) -**Re:** #220, #221 (Epic #181) +--- -**What:** -- Created `src/utils/normalize-eol.ts` exporting `normalizeEol(content: string): string` — replaces `\r\n` and `\r` with `\n`. -- Applied as the first line of 8 parser functions across 6 files: markdown-migration.ts (3 parsers), routing.ts, charter-compiler.ts, skill-loader.ts, agent-doc.ts, doc-sync.ts. +### No Individual Repo Listing Without Consent — Owner Directive +**By:** Brady (project owner, PR #326 review) +**Date:** 2026-03-10 -**Why:** -On Windows with `core.autocrlf=true`, file reads return `\r\n` line endings. Every parser that calls `.split('\n')` would leave stray `\r` characters in parsed values — breaking regex matches, table parsing, and string comparisons. Normalizing at the parser entry point is the minimal defensive guard: one line per function, no behavioral change on LF-only systems. +**Directive:** Growth metrics must report **aggregate numbers only** (e.g., "78+ repositories found via GitHub code search") — never name or link to individual community repos without explicit opt-in consent. The monitoring script and GitHub Action concepts are approved, but any public showcase or tracking list that identifies specific repos is blocked until a community consent plan exists. -**Pattern:** -Always normalize at the *entry* of the parsing function, not at the file-read callsite. This ensures parsers are self-contained and safe regardless of how content arrives (file read, API response, test fixture). +**Source:** [PR #326 comment](https://github.com/bradygaster/squad/pull/326#issuecomment-4029222967) -**Impact:** -Low. Additive-only. No test changes needed. Existing tests pass because test strings are already LF-only. The guard is transparent for LF inputs. +--- -### 2026-02-21: CLI entry point split — src/index.ts is a pure barrel -**By:** Edie (TypeScript Engineer) -**Re:** #187 +### Adoption Tracking — Opt-In Architecture +**By:** Flight (implementing Brady's directives above) +**Date:** 2026-03-09 -**What:** -- `src/index.ts` is now a pure re-export barrel with ZERO side effects. No `main()`, no `process.exit()`, no argument parsing. -- `src/cli-entry.ts` contains the full `main()` function and all CLI routing logic. -- `VERSION` is exported from `index.ts` (public API constant); `cli-entry.ts` imports it. -- `SquadError` is now explicitly exported from the barrel. +Privacy-first adoption monitoring using a three-tier system: -**Why:** -Anyone importing `@bradygaster/squad` as a library (e.g., SquadUI) was triggering CLI argument parsing and `process.exit()` on import. This poisoned the library entry point. The split makes `dist/index.js` safe for library consumption while `dist/cli-entry.js` remains the CLI binary. +**Tier 1: Aggregate monitoring (SHIPPED)** +- GitHub Action + monitoring script collect metrics +- Reports moved to `.github/adoption/reports/{YYYY-MM-DD}.md` +- Reports show ONLY aggregate numbers (no individual repo names): + - "78+ repositories found via code search" + - Total stars/forks across all discovered repos + - npm weekly downloads -**Impact:** -Low. Two files changed. Build passes (tsc strict), all 1683 tests pass. No changes to package.json `bin` or `main`. +**Tier 2: Opt-in registry (DESIGN NEXT)** +- Create `SHOWCASE.md` in repo root with submission instructions +- Opted-in projects listed in `.github/adoption/registry.json` +- Monitoring script reads registry, reports only on opted-in repos -**Future:** -When source migrates to `packages/squad-cli/`, the CLI entry point moves with it. The barrel (`packages/squad-sdk/src/index.ts`) stays side-effect-free. +**Tier 3: Public showcase (LAUNCH LATER)** +- `docs/community/built-with-squad.md` shows opted-in projects only +- README link added when ≥5 opted-in projects exist -### 2026-02-21: Process.exit() refactor — library-safe CLI functions -**By:** Kujan (SDK Expert) -**Re:** #189 +**Rationale:** +- Aggregate metrics safe (public code search results) +- Individual projects only listed with explicit owner consent +- Prevents surprise listings, respects privacy +- Incremental rollout maintains team capacity + +**Implementation (PR #326):** +- ✅ Moved `.squad/adoption/` → `.github/adoption/` +- ✅ Stripped tracking.md to aggregate-only metrics +- ✅ Removed individual repo names, URLs, metadata +- ✅ Updated adoption-report.yml and scripts/adoption-monitor.mjs +- ✅ Removed "Built with Squad" showcase link from README (Tier 2 feature) -**What:** -- `fatal()` now throws `SquadError` instead of calling `process.exit(1)`. -- `src/index.ts` is a pure barrel export with zero side effects (no `main()`, no `process.exit()`). -- `src/cli-entry.ts` is the sole CLI entry point — it catches `SquadError` and calls `process.exit(1)`. -- `runWatch()` resolves its Promise on SIGINT/SIGTERM instead of `process.exit(0)`. -- `runShell()` closes readline on SIGINT instead of `process.exit(0)`. -- `SquadError` class is exported from the public API. +--- -**Why:** -SquadUI (VS Code extension) imports CLI functions as a library. `process.exit()` kills the entire VS Code extension host. All library-consumable functions must throw errors or return results, never call `process.exit()`. Only the CLI entry point (the thin presentation layer) may call `process.exit()`. +### Adoption Tracking Location & Privacy +**By:** EECOM +**Date:** 2026-03-10 -**Pattern established:** -- Library functions: throw `SquadError` or return result objects -- CLI entry point: catches errors, formats output, calls `process.exit()` -- Library consumers: catch `SquadError` for structured error handling +Implementation decision confirming Tier 1 adoption tracking changes. -**Impact:** -Medium. Changes error handling contract for all functions that used `fatal()`. Backwards-compatible for CLI users (same behavior). Library consumers now get catchable errors instead of process termination. +**What:** Move adoption tracking from `.squad/adoption/` to `.github/adoption/` -### 2026-02-21: User directive — docs as you go -**By:** bradygaster (via Copilot) -**What:** Doc and blog as you go during SquadUI integration work. Doesn't have to be perfect — a proper docs pass comes later — but keep docs updated incrementally. -**Why:** User request — captured for team memory +**Why:** +1. **GitHub integration:** `.github/adoption/` aligns with GitHub convention (workflows, CODEOWNERS, issue templates) +2. **Privacy-first:** Aggregate metrics only; defer individual repo showcase to Tier 2 (opt-in) +3. **Clear separation:** `.squad/` = team internal; `.github/` = GitHub platform integration +4. **Future-proof:** When Tier 2 opt-in launches, `.github/adoption/` is the natural home -### 2026-02-23: Aspire Dashboard Scenario Documentation -**By:** Saul (Aspire & Observability) -**Date:** 2026-02-23 -**Status:** COMPLETED +**Impact:** +- GitHub Action reports write to `.github/adoption/reports/{YYYY-MM-DD}.md` +- No individual repo information published until Tier 2 +- Monitoring continues collecting aggregate metrics via public APIs +- Team sees trends without publishing sensitive adoption data -### 2026-02-23: Make sendAndWait timeout configurable -**Author:** Cheritto (TUI Engineer) -**Date:** 2026-02-23 -**Status:** Implemented -**Issue:** #325 -**PR:** #347 +--- + +### Append-Only File Governance +**By:** Flight +**Date:** 2026-03-09 -Added `TIMEOUTS.SESSION_RESPONSE_MS` to `packages/squad-sdk/src/runtime/constants.ts` — default 600,000ms (10 minutes), overridable via `SQUAD_SESSION_TIMEOUT_MS` env var. Updated `packages/squad-cli/src/cli/shell/index.ts` to use the constant instead of hard-coded 120,000ms timeout. All 41 streaming tests pass. Users can now set `SQUAD_SESSION_TIMEOUT_MS=900000` for 15-minute timeouts. +Feature branches must never modify append-only team state files except to append new content. -### 2026-02-23: E2E Test Coverage Expansion -**By:** Breedan (E2E Test Engineer) -**Date:** 2026-02-23 -**Status:** Accepted -**PR:** #348 (closes #326) +**What:** If a PR diff shows deletions in `.squad/agents/*/history.md` or `.squad/decisions.md`, the PR is blocked until deletions are reverted. -Added 14 new Gherkin scenarios across 6 new feature files, bringing total to 21 acceptance scenarios + 6 UX gate tests (27 total). New harness capabilities: `cwd` option on `spawnWithArgs()`, absolute path resolution, `mkdtempSync` temp dir creation, negative assertion step. Coverage areas: init-command, status-extended, doctor-extended, help-comprehensive, error-paths, exit-codes. +**Why:** Session state drift causes agents to reset append-only files to stale branch state, destroying team knowledge. PR #326 deleted entire history files and trimmed ~75 lines of decisions, causing data loss. -### 2026-02-23: Hostile QA Bug Catalog — Issue #327 -**By:** Waingro -**Date:** 2026-02-23 -**Status:** Reported — awaiting triage +**Enforcement:** Code review + future CI check candidate. -Found 2 P1/P2 bugs: (1) `--version` output omits "squad" prefix (P1, location: packages/squad-cli/src/cli-entry.ts:48), (2) Empty/whitespace args launch interactive shell in non-TTY (P2, location: packages/squad-cli/src/cli-entry.ts:102). Added 32 hostile QA Gherkin scenarios across 7 feature files and 80+ adversarial string corpus. All corrupt config scenarios handled gracefully; unicode edge cases pass cleanly. +--- -### 2026-02-23: Accessibility Audit — Squad CLI -**By:** Nate (Accessibility Reviewer) -**Date:** 2026-02-23 -**Issue:** #328 — Accessibility Audit -**Verdict:** CONDITIONAL PASS +### Documentation Style: No Ampersands +**By:** PAO +**Date:** 2026-03-09 -Summary: 2 passes (Keyboard Navigation ✅, Help Text ✅), 2 failures (Color Contrast & NO_COLOR ❌, Error Guidance ❌). Priority fixes: (1) P1 — Respect `NO_COLOR` in terminal.ts and gate ANSI codes in output.ts. (2) P1 — Add remediation hints to missing team.md error (lifecycle.ts) and charter-not-found error (spawn.ts). Nice-to-have: P2 Wire Tab autocomplete, add remediation to SDK-not-connected errors; P3 Add Escape key, include keyboard shortcuts in /help output. +Ampersands (&) are prohibited in user-facing documentation headings and body text, per Microsoft Style Guide. -**What:** Created `docs/scenarios/aspire-dashboard.md` — a single, focused scenario doc for using Squad with the Aspire dashboard. Covers what Aspire is, how to launch it via Docker, how to connect Squad SDK to it, what traces/metrics appear in the UI, troubleshooting, and pro tips. Updated `docs/build.js` to include the new scenario in the explicit ordering (added to SECTION_ORDER for scenarios). +**Rule:** Use "and" instead. -**Tone:** Action-oriented, welcoming, prompt-first — matches existing Squad docs (see `solo-dev.md` for reference style). +**Why:** Microsoft Style Guide prioritizes clarity and professionalism. Ampersands feel informal and reduce accessibility. -**Key Sections:** -1. What Is Aspire (standalone OTel dashboard, not .NET-specific) -2. Launch the container (docker run command + squad aspire convenience) -3. Connect Squad to Aspire (CLI env var + SDK programmatic) -4. Dashboard content (traces, metrics, resources with concrete examples) -5. Example workflow (start, run, observe) -6. Troubleshooting (no traces, slow dashboard, connection refused) -7. Pro tips (metric export frequency, custom service names, batch sizing) +**Exceptions:** +- Brand names (AT&T, Barnes & Noble) +- UI element names matching exact product text +- Code samples and technical syntax +- Established product naming conventions -**Implementation Details:** Reviewed `packages/squad-sdk/src/runtime/otel-*.ts` and `test/aspire-integration.test.ts` for accurate coverage of OTel integration. Aspire ports (18888 UI, 4317 OTLP gRPC), UNSECURED_ALLOW_ANONYMOUS mode, and gRPC-only protocol constraints all documented accurately. +**Scope:** Applies to docs pages, README files, blog posts, community-facing content. Internal files (.squad/** memory files, decision docs, agent history) have flexibility. -**Verification:** Docs build verified — `npm run docs:build` generates 39 pages with `aspire-dashboard.html` correctly included in scenarios nav. Navigation in all scenario pages (e.g., solo-dev.html) correctly links to the new scenario. +**Reference:** https://learn.microsoft.com/en-us/style-guide/punctuation/ampersands -**Why:** Brady requested a "try it now" guide for Aspire integration — single doc that covers launch AND connection, written for immediate action. This replaces scattered documentation and provides a clean entry point for developers wanting to observe Squad telemetry in real time. +--- -### 2026-02-22: SDK/CLI File Split Plan — Definitive Mapping -**By:** Keaton (Lead) -**Status:** Decision -**Scope:** Monorepo restructure — move `src/` into `packages/squad-sdk/` and `packages/squad-cli/` +## Sprint Directives -**Overview:** All 114 `.ts` files in root `src/` must be split between two workspace packages. The dependency direction is **one-way: CLI → SDK**. No SDK module imports from CLI. This is clean and the split is mechanical. +### Secret handling — agents must never persist secrets +**By:** RETRO (formerly Baer), v0.8.24 +**What:** Agents must NEVER write secrets, API keys, tokens, or credentials into conversational history, commit messages, logs, or any persisted file. Acknowledge receipt without echoing values. +**Why:** Secrets in logs or history are a security incident waiting to happen. -**SDK Package (`packages/squad-sdk/src/`):** -- **Directories:** adapter, agents, build, casting, client, config, coordinator, hooks, marketplace, ralph, runtime, sharing, skills, tools, utils (15 total) -- **Standalone files:** index.ts, resolution.ts, parsers.ts, types.ts -- **Exports:** Expanded to 18 subpath exports matching directory structure -- **Dependencies:** `@github/copilot-sdk` only (zero UI deps) -**CLI Package (`packages/squad-cli/src/`):** -- **Directories:** cli/ (all CLI submodules: core/, commands/, shell/, components/) -- **Standalone files:** cli-entry.ts (becomes `bin.squad` target) -- **Dependencies:** `@bradygaster/squad-sdk`, ink, react, esbuild +--- -**Root Package:** -- **Role:** Workspace orchestrator only (not publishable) -- **Preserved:** `package.json` (workspace def), tsconfig.json (base config), vitest.config.ts, test/, test-fixtures/, templates/, docs/, .squad/ -- **Removed:** main, types, bin, runtime dependencies +## Squad Ecosystem Boundaries & Content Governance -**Key Call — SDK Barrel Cleanup:** Remove CLI utilities (`success`, `error`, `warn`, `fatal`, etc.) from SDK exports. CLI re-exports in `src/index.ts` were a mistake — those are CLI implementation details, not SDK API. This is a breaking change that's correct and intentional. +### Squad Docs vs Squad IRL Boundary (consolidated) +**By:** PAO (via Copilot), Flight +**Date:** 2026-03-10 +**Status:** Active pattern for all documentation PRs -**Import Rewriting Rules:** -- CLI → SDK relative imports become package imports (`from '../config/'` → `from '@bradygaster/squad-sdk/config'`) -- Intra-SDK and intra-CLI imports stay relative (unchanged) +**Litmus test:** If Squad doesn't ship the code or configuration, the documentation belongs in Squad IRL, not the Squad framework docs. -### 2026-02-22: CharterCompiler reuses parseCharterMarkdown — no duplicate parsing +**Categories:** -**By:** Edie +1. **Squad docs** — Features Squad ships (routing, charters, reviewer protocol, config, behavior) +2. **Squad IRL** — Infrastructure around Squad (webhooks, deployment patterns, logging, external tools, operational patterns) +3. **Gray area:** Platform features (GitHub Issue Templates) → Squad docs if framed as "how to configure X for Squad" -**What:** `CharterCompiler.compile()` delegates to the existing `parseCharterMarkdown()` function from `charter-compiler.ts` rather than implementing its own markdown parser. The legacy class is a thin filesystem wrapper around the already-tested parsing logic. +**Examples applied (PR #331):** -**Why:** Single source of truth for charter parsing. The `parseCharterMarkdown` function already handles all `## Identity` and `## Model` field extraction with tested regex patterns. Duplicating that logic would create drift risk. +| Document | Decision | Reason | +|----------|----------|--------| +| ralph-operations.md | DELETE → IRL | Infrastructure (deployment, logging) around Squad, not Squad itself | +| proactive-communication.md | DELETE → IRL | External tools (Teams, WorkIQ) configured by community, not built into Squad | +| issue-templates.md | KEEP, reframe | GitHub platform feature; clarify scope: "a GitHub feature configured for Squad" | +| reviewer-protocol.md (Trust Levels) | KEEP | Documents user choice spectrum within Squad's existing review system | -### 2026-02-22: AgentSessionManager uses optional EventBus injection +**Enforcement:** Code review + reframe pattern ("GitHub provides X. Here's how to configure it for Squad's needs."). Mark suspicious deletions for restore (append-only governance). -**By:** Edie +**Future use:** Apply this pattern to all documentation PRs to maintain clean boundaries. -**What:** `AgentSessionManager` constructor accepts an optional `EventBus` parameter. When present, `spawn()` emits `session.created` and `destroy()` emits `session.destroyed`. When absent, the manager works silently (no events). -**Why:** Keeps the manager testable without requiring a full event bus setup. Coordinator can wire the bus when available; unit tests can omit it. +--- -### 2026-02-22: Ink Shell Wiring — ShellApi callback pattern +### Content Triage Skill — External Content Integration +**By:** Flight +**Date:** 2026-03-10 +**Status:** Skill created at `.squad/skills/content-triage/SKILL.md` -**By:** Fenster +**Pattern:** External content (blog posts, sample repos, videos, conference talks) that helps Squad adoption must be triaged using the "Squad Ships It" boundary heuristic before incorporation. -**Date:** 2026-02-22 +**Workflow:** +1. Triggered by `content-triage` label or external content reference in issue +2. Flight performs boundary analysis +3. Sub-issues generated for Squad-ownable content extraction (PAO responsibility) +4. FIDO verifies docs-test sync on extracted content +5. Scribe manages IRL references in `.github/irl/references.yml` (YAML schema) -**Status:** Implemented +**Label convention:** `content:blog`, `content:sample`, `content:video`, `content:talk` -**Context:** The shell needed to move from a readline echo loop to an Ink-based UI using the three existing components (AgentPanel, MessageStream, InputPrompt). The key challenge was connecting the StreamBridge (which pushes events from the streaming pipeline) into React component state. +**Why:** Pattern from PR #331 (Tamir Dresher blog) shows parallel extraction of Squad-ownable patterns (scenario guides, reviewer protocol) and infrastructure patterns (Ralph ops, proactive comms). Without clear boundary, teams pollute Squad docs with operational content or miss valuable patterns that should be generalized. -**Decision:** **ShellApi callback pattern:** The `App` component accepts an `onReady` prop that fires once on mount, delivering a `ShellApi` object with three methods: `addMessage`, `setStreamingContent`, `refreshAgents`. The host (`runShell()`) captures this API and wires it to StreamBridge callbacks. +**Impact:** Enables community content to accelerate Squad adoption without polluting core docs. Flight's boundary analysis becomes reusable decision framework. Prevents scope creep as adoption grows. -This keeps the Ink component decoupled from StreamBridge internals — the component doesn't import or know about the bridge. The host is the only place where both meet. -**`React.createElement` in index.ts:** Rather than renaming `index.ts` to `index.tsx` (which would ripple through exports maps and imports), `runShell()` uses `React.createElement(App, props)` directly. This keeps the file extension stable. +--- -**Streaming content accumulation:** StreamBridge's `onContent` callback delivers deltas. The host maintains a `streamBuffers` Map to accumulate content per agent and pushes the full accumulated string to `setStreamingContent`. On `onComplete`, the buffer is cleared and the final message is added. +### PR #331 Quality Gate — Test Assertion Sync +**By:** FIDO (Quality Owner) +**Date:** 2026-03-10 +**Status:** 🟢 CLEARED (test fix applied, commit 6599db6) -**Consequences:** StreamBridge is ready for coordinator wiring — call `_bridge.handleEvent(event)` when the coordinator emits streaming events. Direct agent messages and coordinator routing show placeholders until coordinator integration (Phase 3). All existing exports from `shell/index.ts` are preserved. New exports: `App`, `ShellApi`, `AppProps`. +**What was blocked:** Merge blocked on stale test assertions in `test/docs-build.test.ts`. -### 2026-02-22: Runtime EventBus as canonical bus for orchestration classes +**Critical violations resolved:** +1. `EXPECTED_SCENARIOS` array stale (7 vs 25 disk files) — ✅ Updated to 25 entries +2. `EXPECTED_FEATURES` constant undefined (32 feature files) — ✅ Created array with 32 entries +3. Test assertion incomplete — ✅ Updated to validate features section -**By:** Fortier +**Why this matters:** Stale assertions that don't reflect filesystem state cause silent test skips. Regression: If someone deletes a scenario file, the test won't catch it. CI passing doesn't guarantee test coverage — only that the test didn't crash. -**Date:** 2026-02-22 +**Lessons:** +- Test arrays must be refreshed when filesystem content changes +- Incomplete commits break the test-reality sync contract +- FIDO's charter: When adding test count assertions, must keep in sync with disk state -**Scope:** Coordinator, Ralph, and future orchestration components +**Outcome:** Test suite: 6/6 passing. Assertions synced to filesystem. No regression risk from stale assertions. -**Decision:** The `runtime/event-bus.ts` (colon-notation: `session:created`, `subscribe()` API, built-in error isolation via `executeHandler()`) is the canonical EventBus for all orchestration classes. The `client/event-bus.ts` (dot-notation: `session.created`, `on()` API) remains for backward-compat but should not be used in new code. -**Rationale:** -- Runtime EventBus has proper error isolation — one handler failure doesn't crash others -- SquadCoordinator (M3-1) tests already use RuntimeEventBus -- Consistent API surface (`subscribe`/`subscribeAll`/`unsubscribe`) is cleaner than `on`/`onAny` -- Event type strings use colon-notation which avoids ambiguity with property access patterns +--- -**Impact:** -- Coordinator and RalphMonitor now import from `../runtime/event-bus.js` -- All new EventBus consumers should follow this pattern -- Client EventBus remains exported for external consumers +### Communication Patterns and PR Trust Models +**By:** PAO +**Date:** 2026-03-10 +**Status:** Documented in features/reviewer-protocol.md (trust levels section) and scenarios/proactive-communication.md (infrastructure pattern) -### 2026-02-22: Runtime Module Test Patterns +**Decision:** Document emerging patterns in real Squad usage: proactive communication loops and PR review trust spectrum. -**By:** Hockney (Tester) +**Components:** -**Date:** 2026-02-22 +1. **Proactive communication patterns** — Outbound notifications (Teams webhooks), inbound scanning (Teams/email for work items), two-way feedback loop connecting external sources to Squad workflow -**Status:** Adopted +2. **PR trust levels spectrum:** + - **Full review** (default for team repos) — All PRs require human review + - **Selective review** (personal projects with patterns) — Domain-expert or routine PRs can auto-merge + - **Self-managing** (solo personal repos only) — PRs auto-merge; Ralph's work monitoring provides retroactive visibility -**Context:** Writing proactive tests for runtime modules (CharterCompiler, AgentSessionManager, Coordinator, RalphMonitor) being built in parallel by multiple team members. +**Why:** Ralph 24/7 autonomous deployment creates an awareness gap — how does the human stay informed? Outbound notifications solve visibility. Inbound scanning solves "work lives in multiple places." Trust levels let users tune oversight to their context (full review for team repos, selective for personal projects, self-managing for solo work only). -**Decisions:** +**Important caveat:** Self-managing ≠ unmonitored; Ralph's work monitoring and notifications provide retroactive visibility. -1. **Two EventBus APIs require different mocks.** The client EventBus uses `on()`/`emit()` while the runtime EventBus uses `subscribe()`/`emit()`. Tests must use the correct mock depending on which bus the module under test consumes. AgentSessionManager uses the client bus (`on`); Coordinator uses the runtime bus (`subscribe`). +**Anti-spam expectations:** Don't spam yourself outbound (notification fatigue), don't spam GitHub inbound (volume controls). -2. **CharterCompiler tests use real test-fixtures.** Instead of mocking the filesystem, we read from `test-fixtures/.squad/agents/` for `compile()` and `compileAll()` tests. This gives integration-level confidence. Only `parseCharterMarkdown` uses inline string fixtures for unit isolation. -3. **Coordinator routing priority is: direct > @mention > team keyword > default.** Tests explicitly verify this ordering. Any change to routing logic must preserve this priority chain. +--- -4. **RalphMonitor tests are future-proof stubs.** Since Ralph is mostly TODO stubs, tests validate current behavior (empty arrays, no-throw lifecycle) and will automatically exercise real logic once implemented — no test changes needed. +### Remote Squad Access — Phased Rollout (Proposed) +**By:** Flight +**Date:** 2026-03-10 +**Status:** Proposed — awaits proposal document in `docs/proposals/remote-squad-access.md` -**Impact:** -- 105 new tests across 4 files, all passing -- Test count: 1727 → 1832 across 61 files -- No circular dependencies verified (clean DAG) +**Context:** Squad currently requires a local clone to answer questions. Users want remote access from mobile, browser, or different machine without checking out repo. -**Migration Order:** -1. **Phase 1 (SDK first):** Copy 15 dirs + 4 files, update exports, build in isolation -2. **Phase 2 (CLI second):** Copy cli/ + cli-entry.ts, rewrite imports to SDK packages, build against SDK -3. **Phase 3 (root cleanup):** Delete root src/, update test imports, finalize structure +**Phases:** -**Templates:** Copy into CLI package (Option A — self-contained packages). +**Phase 1: GitHub Discussions Bot (Ship First)** +- Surface: GitHub Discussions +- Trigger: `/squad` command or `@squad` mention +- Context: GitHub Actions workflow checks out repo → full `.squad/` state +- Response: Bot replies to thread +- Feasibility: 1 day +- Why first: Easy to build, zero hosting, respects repo privacy, async Q&A, immediately useful -**Why:** One-way dependency graphs enable independent package evolution. SDK stays pure library; CLI stays thin consumer. Future features only touch the relevant package. +**Phase 2: GitHub Copilot Extension (High Value)** +- Surface: GitHub Copilot chat (VS Code, CLI, web, mobile) +- Trigger: `/squad ask {question}` in any Copilot client +- Context: Extension fetches `.squad/` files via GitHub API (no clone) +- Response: Answer inline in Copilot +- Feasibility: 1 week +- Why second: Works everywhere Copilot exists, instant response, natural UX -### 2026-02-22: Version Alignment — 0.7.0 stubs → 0.8.0 real packages -**By:** Kobayashi (Git & Release) -**Status:** APPROVED & EXECUTED +**Phase 3: Slack/Teams Bot (Enterprise Value)** +- Surface: Slack or Teams channel +- Trigger: `@squad` mention in channel +- Context: Webhook fetches `.squad/` via GitHub API +- Response: Bot replies in thread +- Feasibility: 2 weeks +- Why third: Enterprise teams live in chat; high value for companies using Squad -**Context:** -- **0.7.0 npm stubs:** Placeholder packages published on npmjs.com (no real code) -- **Goal:** Publish real, working code under new version +**Constraint:** Squad's intelligence lives in `.squad/` (roster, routing, decisions, histories). Any remote solution must solve context access. GitHub Actions workflows provide checkout for free. Copilot Extension and chat bots use GitHub API to fetch files. -**Decision: Bump to 0.8.0** -- **Rationale:** Clear break from stubs (0.7.0 is placeholder; 0.8.0 is functional code). Pre-1.0 signal appropriate for alpha software. +**Implementation:** Before Phase 1 execution, write proposal document. New CLI command: `squad answer --context discussions --question "..."`. New workflow: `.github/workflows/squad-answer.yml`. -**Changes Executed:** -1. SDK `package.json`: version `0.7.0` → `0.8.0` -2. CLI `package.json`: version `0.7.0` → `0.8.0`, SDK dependency locked to `@bradygaster/squad-sdk@0.8.0` -3. SDK `src/index.ts`: `VERSION` export `0.7.0` → `0.8.0` -4. Root `package.json`: added `"private": true` (prevent accidental npm publish of workspace coordinator) +**Privacy:** All approaches respect repo visibility or require authentication. Most teams want private by default. -**Verification:** ✅ All version strings aligned, CLI dependency on SDK pinned, root marked private. +### Test assertion discipline — mandatory +**By:** FIDO (formerly Hockney), v0.8.24 +**What:** All code agents must update tests when changing APIs. FIDO has PR blocking authority on quality grounds. +**Why:** APIs changed without test updates caused CI failures and blocked external contributors. -### 2026-02-22: Defer test import migration until root src/ removal -**By:** Hockney (Tester) -**Status:** Proposed +### Docs-test sync — mandatory +**By:** PAO (formerly McManus), v0.8.24 +**What:** New docs pages require corresponding test assertion updates in the same commit. +**Why:** Stale test assertions block CI and frustrate contributors. -**Context:** After SDK/CLI workspace split, all 56 test files still import from root `../src/`. Build and all 1719 tests pass cleanly because root `src/` still exists. +### Contributor recognition — every release +**By:** PAO, v0.8.24 +**What:** Each release includes an update to the Contributors Guide page. +**Why:** No contribution goes unappreciated. -**Decision:** Defer migrating test imports from `../src/` to `@bradygaster/squad-sdk` / `@bradygaster/squad-cli` until root `src/` is actually removed. +### API-test sync cross-check +**By:** FIDO + Booster, v0.8.24 +**What:** Booster adds CI check for stale test assertions. FIDO enforces via PR review. +**Why:** Prevents the pattern of APIs changing without test updates. -**Rationale:** -1. **Exports map gap:** SDK exposes 18 subpath exports; tests import ~40+ distinct deep internal paths not in exports map -2. **CLI no exports:** cli/shell/ tests have no package-level export path to migrate to -3. **Barrel divergence:** Root `src/index.ts` still exports CLI functions SDK package correctly does not -4. **Risk/reward:** 150+ import lines for zero functional benefit while root `src/` exists is pure risk +### Doc-impact review — every PR +**By:** PAO, v0.8.25 +**What:** Every PR must be evaluated for documentation impact. PAO reviews PRs for missing or outdated docs. +**Why:** Code changes without doc updates lead to stale guides and confused users. -**When to revisit:** When root `src/` is deleted (blocker at that point). Options: expand exports maps, add vitest resolve.alias, or move tests into workspace packages. -### 2026-02-22: Build System Migration — tsconfig + package.json -**By:** Edie (TypeScript Engineer) -**Status:** Decision -**Scope:** Monorepo build configuration for SDK/CLI workspace packages +--- -**What Changed:** -1. **Root tsconfig.json:** Base config only, shared compiler options, `files: []` (compiles nothing), project references to both packages -2. **SDK tsconfig.json:** Extends root, `composite: true`, declarations + maps, no JSX -3. **CLI tsconfig.json:** Extends root, `composite: true`, `jsx: "react-jsx"`, references SDK package -4. **Root package.json:** `private: true`, workspace orchestrator, stripped main/types/bin/runtime deps -5. **SDK package.json:** 18 subpath exports, `@github/copilot-sdk` as direct dependency -6. **CLI package.json:** `bin.squad` → `./dist/cli-entry.js`, ink/react runtime deps, templates in files array +## Release v0.8.24 -**Why `composite: true`:** TypeScript project references require this. Without it, cross-package type information fails to resolve. +### CLI Packaging Smoke Test: Release Gate Decision +**By:** FIDO, v0.8.24 +**Date:** 2026-03-08 -**Build Order:** `npm run build --workspaces` builds SDK first (no deps), then CLI (depends on SDK). npm respects topological order automatically. +The CLI packaging smoke test is APPROVED as the quality gate for npm releases. -**Verified:** Both packages compile with zero errors. All dist artifacts (`.js`, `.d.ts`, `.d.ts.map`) emitted correctly. +**What:** +1. Text box preference: bottom-aligned, squared off (like Copilot CLI / Claude CLI) — future work, not today +2. Alpha-level shipment acceptable for now — no grand UI redesign today +3. CLI must show "experimental, please file issues" banner +4. Spinner/wait messages should rotate every ~3 seconds — use codebase facts, project trivia, vulnerability info, or creative "-ing" words. Never just spin silently. +5. Use wait time to inform or entertain users -### 2026-02-22: Subpath exports in @bradygaster/squad-sdk -**By:** Edie (TypeScript Engineer) -**Issue:** #227 +**Why:** User request — captured for team memory and crash recovery -**What:** `packages/squad-sdk/package.json` declares 18 subpath exports (`.`, `./parsers`, `./types`, and 15 module paths). Each uses types-first condition ordering. +### 2026-03-01T20:16:00Z: User directive — CLI timeout too low +**By:** Brady (via Copilot) +**Date:** 2026-03-01 -**Why:** Enables tree-shaking and focused imports. Consumers can `import { … } from '@bradygaster/squad-sdk/config'` instead of pulling the entire barrel. Type-only consumers can import from `./types` with zero runtime cost. +**What:** The CLI timeout is set too low — Brady tried using Squad CLI in this repo and it didn't work well. Timeout needs to be increased. Not urgent but should be captured as a CLI improvement opportunity. -**Constraints:** -- Every subpath must have a corresponding source barrel (`src/.ts` or `src//index.ts`) -- `"types"` condition must appear before `"import"` — Node.js evaluates top-to-bottom -- ESM-only: no `"require"` condition per team decision -- Adding a new subpath requires both source barrel and exports entry; removing one without the other breaks resolution +**Why:** User request — captured for team memory and PRD inclusion -### 2026-02-22: Barrel file conventions for parsers and types +### 2026-03-01: Multi-Squad Storage & Resolution Design +**By:** Keaton (Lead) +**What:** +- New directory structure: ~/.config/squad/squads/{name}/.squad/ with ~/.config/squad/config.json for registry +- Keep +esolveGlobalSquadPath() unchanged; add +esolveNamedSquadPath(name?: string) and listPersonalSquads() on top +- Auto-migration: existing single personal squad moves to squads/default/ on first run +- Resolution priority: explicit (CLI flag) > project config > env var > git remote mapping > path mapping > default +- Global config.json schema: { version, defaultSquad, squads, mappings } + +**Why:** +- squads/ container avoids collisions with existing files at global root +- Backward-compatible: legacy layout detected and auto-migrated; existing code continues to work +- Clean separation: global config lives alongside squads, not inside any one squad +- Resolution chain enables flexible mapping without breaking existing workflows + +### 2026-03-01: Multi-Squad SDK Functions **By:** Kujan (SDK Expert) -**Issues:** #225, #226 (Epic #181) +**What:** +- New SDK exports: +esolveNamedSquadPath(), listSquads(), createSquad(), deleteSquad(), switchSquad(), +esolveSquadForProject() +- New type: SquadEntry { name, path, isDefault, createdAt } +- squads.json registry (separate file, not config.json) with squad metadata and mappings +- SquadDirConfig v2 addition: optional personalSquad?: string field (v1 configs unaffected) +- Consult mode updated: setupConsultMode(options?: { squad?: string }) with explicit selection or auto-resolution + +**Why:** +- Lazy migration with fallback chain ensures zero breaking changes to existing users +- Separate squads.json is single source of truth for routing; keeps project config focused +- Version handling allows incremental adoption; v1 configs work unchanged +- SDK resolution functions can be called from CLI and library code without duplication +### 2026-03-01: Multi-Squad CLI Commands & REPL +**By:** Kovash (REPL) **What:** -- `src/parsers.ts` re-exports all parser functions AND their types using `export { ... } from` and `export type { ... } from` -- `src/types.ts` re-exports ONLY types using `export type { ... } from` exclusively — guaranteed zero runtime imports -- Both follow the existing ESM barrel pattern from `src/index.ts` +- New commands: squad list, squad create , squad switch , squad delete +- Modified commands: squad consult --squad=, squad extract --squad=, squad init --global --name= +- Interactive picker for squad selection: arrow keys (↑/↓), Enter to confirm, Ctrl+C to cancel +- REPL integration: /squad and /squads slash commands with riggerSquadReload signal +- .active file stores current active squad name (plain text) +- Status command enhanced to show active squad and squad list **Why:** -1. **Consumer convenience:** SquadUI and others can import parsers or types from a single module instead of reaching into internal paths -2. **Separation of concerns:** `types.ts` is safe for type-only contexts (declaration files). `parsers.ts` includes runtime functions for consumers that need them -3. **No existing modifications:** Both are additive-only new files — zero risk to existing behavior +- Picker only shows when needed (multiple squads) and TTY available; non-TTY gracefully uses active squad +- Slash commands follow existing pattern (/init, /agents, etc.); seamless REPL integration +- .active file is simple and atomic; suitable for concurrent CLI access +- Squad deletion safety: cannot delete active squad; requires confirmation -**Impact:** Low. Two new files, no changes to existing source. Build passes, all 1683 tests pass. +### 2026-03-01: Multi-Squad UX & Interaction Design +**By:** Marquez (UX Designer) +**What:** +- Visual indicator: current squad marked with ●, others with ○; non-default squads tagged [switched] +- Squad name always visible in REPL header and prompt: ◆ Squad (client-acme) +- Picker interactions: ↑/↓ navigate, Enter select, Esc/Ctrl+C cancel; 5-7 squads displayed, wrap around +- Error states: clear copy with next actions (e.g., "Squad not found. Try @squad:personal." or "Run /squads to list.") +- Copy style: active verbs (Create, Switch, List), human-readable nouns (no jargon), 3-5 words per line +- Onboarding: fresh install defaults to "personal"; existing single-squad users see migration notice -### 2026-02-22: Use npm-native workspace resolution (not pnpm `workspace:*`) -**By:** Edie (TypeScript Engineer) -**Date:** 2026-02-22 -**Status:** Applied +**Why:** +- Persistent context (squad name in header/prompt) prevents "Which squad am I in?" confusion +- Interactive picker is discoverable and non-blocking; minimal cognitive load +- Error messages with next actions reduce support friction +- Onboarding defaults and migration notices ensure smooth upgrade path for existing users -**Context:** Brady's task requested using `workspace:*` for the CLI→SDK dependency. However, this project uses npm workspaces (not pnpm or Yarn). The `workspace:` protocol is a pnpm/Yarn feature and npm rejects it with `EUNSUPPORTEDPROTOCOL`. +# Decision: Separator component is canonical for horizontal rules -**Decision:** Use `"*"` as the version specifier instead. Under npm workspaces, when a dependency name matches a local workspace package, npm automatically resolves to the local package regardless of the version specifier. `"*"` accepts any version, ensuring the local SDK is always used during development. +**By:** Cheritto (TUI Engineer) +**Date:** 2026-03-02 +**Issues:** #655, #670, #671, #677 -**Trade-off:** `"*"` will be published as-is to npm (unlike pnpm's `workspace:*` which gets replaced with the real version at publish time). Before publishing the CLI package, the SDK dependency version should be pinned to the actual release version. A `prepublishOnly` script or CI step could automate this. +## What -### 2026-02-22: Test import migration to workspace packages -**By:** Fenster (Core Dev) -**Date:** 2026-02-22 -**Status:** Implemented +- All horizontal separator lines in shell components must use the shared `Separator` component (`components/Separator.tsx`), not inline `box.h.repeat()` calls. +- The `Separator` component handles terminal capability detection, box-drawing character degradation, and width computation internally. +- Information hierarchy convention: **bold** for primary CTAs (commands, actions) > normal for content > **dim** for metadata (timestamps, status, hints). +- `flexGrow` should not be used on containers that may be empty — it creates dead space in Ink layouts. -**Context:** All 56 test files imported from root `src/` via relative paths (`../src/...`). With the SDK/CLI workspace split, tests needed to import from `@bradygaster/squad-sdk` and `@bradygaster/squad-cli` packages instead. +## Why -**Decision:** -1. **Barrel-first imports:** Where a barrel/index file re-exports symbols from sub-modules, tests import from the barrel path (e.g., `@bradygaster/squad-sdk/config` instead of individual files). -2. **New subpath exports for orphaned modules:** 8 runtime/adapter modules not covered by existing barrels got new subpath exports in the SDK package.json. -3. **Missing barrel re-exports fixed:** `selectResponseTier`/`getTier` added to coordinator barrel; `onboardAgent`/`addAgentToConfig` added to agents barrel. -4. **CLI functions correctly located:** Consumer imports test updated to import CLI functions from `@bradygaster/squad-cli` (not SDK), reflecting intentional separation. +Duplicated separator logic was found in 3 files (App.tsx, AgentPanel.tsx, MessageStream.tsx). Consolidation to a single component prevents drift and makes it trivial to change separator style globally. The info hierarchy and whitespace conventions ensure visual consistency as new components are added. +### 2026-03-01: PR #547 Remote Control Feature — Architectural Review +**By:** Fenster +**Date:** 2026-03-01 +**PR:** #547 "Squad Remote Control - PTY mirror + devtunnel for phone access" by tamirdresher (external) -**Consequence:** Zero `grep -r "from '../src/" test/` results. All 1727 tests pass. SDK has 26 subpath exports, CLI has 17. +## Context -### 2026-02-22: CI/CD & Release Readiness Assessment -**By:** Kobayashi (Git & Release) -**Date:** 2026-02-22 -**Status:** ASSESSMENT COMPLETE +External contributor Tamir Dresher submitted a PR adding `squad start --tunnel` command to run Copilot in a PTY and mirror terminal output to phone/browser via WebSocket + Microsoft Dev Tunnels. -**Summary:** All 13 CI/CD workflows are production-ready and correctly configured. Merge drivers are in place. Branch protection is working. Publishing infrastructure works both for stable releases (v* tags) and pre-releases (insider branch). +## Architectural Question -**Version Status:** -- SDK `package.json`: 0.8.0 -- CLI `package.json`: 0.8.1 (intentional patch for bin entry fix) -- CHANGELOG: 0.6.0-alpha.0 (root workspace marker) +Is remote terminal access via devtunnel + PTY mirroring in scope for Squad v1 core? -**Workflow Audit:** -- ✅ Core CI validates on PR/push to main, dev, insider -- ✅ squad-publish.yml: Publishes both packages on v* tags with public access -- ✅ squad-insider-publish.yml: Auto-publishes on insider push with `--tag insider` -- ✅ Release/promote workflows fully functional +## Technical Assessment -**Merge Drivers:** Union merge configured for append-only files (decisions.md, agents/*/history.md, log/**, orchestration-log/**). +**What works:** +- RemoteBridge WebSocket server architecture is sound +- PTY mirroring approach is technically correct +- Session management dashboard is useful +- Security headers and CSP are present +- Test coverage exists (18 tests, though failing due to build issues) -**Release Readiness:** Insider channel ready now. Stable release ready after version alignment if desired. +**Critical blockers:** +1. **Build broken** — TypeScript errors in `start.ts`, all tests failing +2. **Command injection vulnerability** — `execFileSync` with string interpolation in `rc-tunnel.ts` +3. **Native dependency** — `node-pty` requires C++ compiler (install friction) +4. **Windows-only effectively** — hardcoded paths, devtunnel CLI Windows-centric +5. **No cross-platform strategy** — macOS/Linux support unclear -**Recommendation:** Version alignment (SDK 0.8.0, CLI 0.8.0) simplifies CHANGELOG during pre-1.0. Separate versioning can be deferred post-1.0 if needed. +**Architectural concerns:** -### 2026-02-22: Fix npx bin resolution for squad-cli -**By:** Rabin (Distribution) -**Date:** 2026-02-22 -**Status:** Implemented & Published +### 2026-03-02T23:36:00Z: Version target — v0.6.0 for public migration **[SUPERSEDED — see line 1046]** +**By:** Brady (via Copilot) +**What:** The public migration from squad-pr to squad should target v0.6.0, not v0.8.17. This overrides Kobayashi's Phase 5 Option A recommendation. The public repo (bradygaster/squad) goes from v0.5.4 → v0.6.0 — a clean minor bump. +**Why:** User directive. v0.6.0 is the logical next public version from v0.5.4. Internal version numbers (0.6.x–0.8.x) were private development milestones. +**[CORRECTION — 2026-03-03]:** This decision was REVERSED by Brady. Brady explicitly stated: "0.6.0 should NOT appear as the goal for ANY destination. I want the beta to become 0.8.17." The actual migration target is v0.8.17. See the superseding "Versioning Model: npm packages vs Public Repo Tags" decision at line 1046 which clarifies that v0.6.0 is a public repo tag only, while npm packages remain at 0.8.17. Current migration documentation correctly references v0.8.17 throughout. +1. **Not integrated with Squad runtime** — doesn't use EventBus, Coordinator, or agent orchestration. Isolated feature. +2. **Two separate modes** — PTY mode (`start.ts`) vs. ACP passthrough mode (`rc.ts`). Why both? +3. **New CLI paradigm** — "start" implies daemon/server, not interactive mirroring. Command naming collision risk. +4. **External dependency** — requires `devtunnel` CLI installed + authenticated. Not bundled, not auto-installed. +5. **Audit logs** — go to `~/.cli-tunnel/audit/` instead of `.squad/log/` (inconsistent with Squad state location). -**Context:** `npx @bradygaster/squad-cli@0.8.0` printed placeholder text instead of running the real CLI. The bin entry was `"squad": "./dist/cli-entry.js"` but npx resolves by unscoped package name (`squad-cli`), not by custom bin names. +## Recommendation -**Decision:** -1. Added `"squad-cli"` as second bin entry pointing to `./dist/cli-entry.js` -2. Replaced orphaned placeholder `dist/cli.js` with redirect to `cli-entry.js` -3. Bumped version to 0.8.1 (0.8.0 immutable on npm) -4. Published @bradygaster/squad-cli@0.8.1 to npm +**Request Changes** — Do not merge until: +1. TypeScript build errors fixed +2. Command injection vulnerability patched (use array args, no interpolation) +3. Tests passing (currently 18/18 failing) +4. Cross-platform support documented or Windows-only label added +5. Architectural decision on scope: Is this core or plugin? -**Consequence:** -- `npx @bradygaster/squad-cli` now runs the real CLI -- `squad` command still works for global installs -- Both bin names resolve to the same entry point -- Future releases must keep both bin entries +**If approved as core feature:** +- Extract to plugin first, prove value, then consider core integration +- Unify PTY vs. ACP modes (pick one) +- Integrate with EventBus/Coordinator (or explain why isolated is correct) +- Rename command to `squad remote` or `squad tunnel` (avoid `start` collision) +- Move audit logs to `.squad/log/` +**If approved as plugin:** +- This is the right path — keeps core small, proves value independently +- Still fix security issues before merge to plugin repo +## For Brady +You requested a runtime review. Here's the verdict: -### OpenTelemetry version alignment: pin core packages to 1.30.x line -**By:** Edie -**Issue:** #254 -**What:** All OTel optional dependencies in `packages/squad-sdk/package.json` must stay version-aligned: `sdk-node@^0.57.x` requires `sdk-trace-base@^1.30.0`, `sdk-trace-node@^1.30.0`, `sdk-metrics@^1.30.0`, `resources@^1.30.0`. These must be explicit optional dependencies, not left to transitive resolution. -**Why:** Without explicit pins, npm hoists the latest versions (2.x) of `sdk-trace-base`, `sdk-metrics`, and `resources` to the top-level `node_modules`. The 2.x types are structurally incompatible with the 1.x types that `sdk-node@0.57.x` transitively depends on, causing TS2345/TS2741 type errors (e.g., missing `instrumentationScope` on `ReadableSpan`, missing `getRawAttributes` on `Resource`). Explicit pins at `^1.30.0` force npm to deduplicate on the 1.x line, eliminating the type conflicts. +- **Concept is cool** — phone access to Copilot is a real use case. +- **Implementation needs work** — build broken, security issues, Windows-only. +- **Architectural fit unclear** — not in any Squad v1 PRD. No integration with agent orchestration. +- **Native dependency risk** — `node-pty` adds install friction (C++ compiler required). +**My take:** This belongs in a plugin, not core. External contributor did solid work on the WebSocket bridge, but Squad v1 needs to ship agent orchestration first. Remote access is a nice-to-have, not a v1 must-have. -# Decision: OpenTelemetry Tracing for Agent Lifecycle & Coordinator Routing +If you want this in v1, we need a proposal (docs/proposals/) first. -**Date:** 2026-02-22 -**By:** Fenster -**Issues:** #257, #258 -**Status:** Implemented +### 2026-03-02: Multi-squad test contract — squads.json schema +**By:** Hockney (Tester) +**Date:** 2026-03-02 +**Issue:** #652 ## What -Added OpenTelemetry trace instrumentation to four files in `packages/squad-sdk/src/`: +Tests for multi-squad (PR #690) encode a specific squads.json contract: + +```typescript +interface SquadsJson { + version: 1; + defaultSquad: string; + squads: Record; +} +``` -1. **`agents/index.ts`** — AgentSessionManager: `spawn()`, `resume()`, `destroy()` wrapped with spans (`squad.agent.spawn`, `squad.agent.resume`, `squad.agent.destroy`). -2. **`agents/lifecycle.ts`** — AgentLifecycleManager: `spawnAgent()`, `destroyAgent()` wrapped with spans (`squad.lifecycle.spawnAgent`, `squad.lifecycle.destroyAgent`). -3. **`coordinator/index.ts`** — Coordinator: `initialize()`, `route()`, `execute()`, `shutdown()` wrapped with spans (`squad.coordinator.initialize`, `squad.coordinator.route`, `squad.coordinator.execute`, `squad.coordinator.shutdown`). -4. **`coordinator/coordinator.ts`** — SquadCoordinator: `handleMessage()` wrapped with span (`squad.coordinator.handleMessage`). +Squad name validation regex: `^[a-z0-9]([a-z0-9-]{0,38}[a-z0-9])?$` (kebab-case, 1-40 chars). ## Why -- Observability is foundational for debugging multi-agent orchestration at runtime. -- Using `@opentelemetry/api` only — no-ops without a registered provider, so zero cost in production unless OTel is configured. -- Trace hierarchy: `coordinator.handleMessage → coordinator.route → coordinator.execute → lifecycle.spawnAgent → agent.spawn`. +Fenster's implementation should match this schema. If the schema changes, tests need updating. Recording so the team knows the contract is encoded in tests. + +## Impact -## Convention Established +Fenster: Align `multi-squad.ts` types with this schema, or flag if different — Hockney will adjust tests. -- **Tracer name:** `trace.getTracer('squad-sdk')` — one tracer per package. -- **Span naming:** `squad.{module}.{method}` (e.g., `squad.agent.spawn`). -- **Attributes:** Use descriptive keys like `agent.name`, `routing.tier`, `target.agents`, `spawn.mode`. -- **Error handling:** `span.setStatus({ code: SpanStatusCode.ERROR })` + `span.recordException(err)` in catch blocks. Always `span.end()` in `finally`. -- **Import only from `@opentelemetry/api`** — never from SDK packages directly. +### 2026-03-02: PR #582 Review — Consult Mode Implementation +**By:** Keaton (Lead) +**Date:** 2026-03-01 +**Context:** External contributor PR from James Sturtevant (jsturtevant) +## Decision -# Decision: OTel Foundation — NodeSDK over individual providers +**Do not merge PR #582 in its current form.** -**Author:** Fortier (Node.js Runtime) -**Date:** 2026-02-22 -**Issues:** #255, #256 -**Status:** Implemented +This is a planning document (PRD) masquerading as implementation. The PR contains: +- An excellent 854-line PRD for consult mode +- Test stubs for non-existent functions +- Zero actual implementation code +- A history entry claiming work is done (aspirational, not factual) -## Context +## Required Actions -Issues #255 and #256 require OTel provider initialization and a bridge from the existing TelemetryCollector to OTel spans. The OpenTelemetry JS ecosystem has multiple packages (`sdk-trace-base`, `sdk-trace-node`, `sdk-metrics`, `resources`, `exporter-*`) that frequently ship with incompatible transitive versions, causing TypeScript type errors even when runtime behavior is correct. +1. **Extract PRD to proper location:** + - Move `.squad/identity/prd-consult-mode.md` → `docs/proposals/consult-mode.md` + - PRDs belong in proposals/, not identity/ -## Decision +2. **Close this PR with conversion label:** + - Label: "converted-to-proposal" + - Comment: Acknowledge excellent design work, explain missing implementation + +3. **Create implementation issues from PRD phases:** + - Phase 1: SDK changes (SquadDirConfig, resolution helpers) + - Phase 2: CLI command implementation + - Phase 3: Extraction workflow + - Each phase: discrete PR with actual code + tests + +4. **Architecture discussion needed before implementation:** + - How does consult mode integrate with existing sharing/ module? + - Session learnings vs agent history — conceptual model mismatch + - Remote mode (teamRoot pointer) vs copy approach — PRD contradicts itself + +## Architectural Guidance + +**What's right:** +- `consult: true` flag in config.json ✅ +- `.git/info/exclude` for git invisibility ✅ +- `git rev-parse --git-path info/exclude` for worktree compatibility ✅ +- Separate extraction command (`squad extract`) ✅ +- License risk detection (copyleft) ✅ + +**What needs rethinking:** +- Reusing `sharing/` module (history split vs learnings extraction — different domains) +- PRD flip-flops between "copy squad" and "remote mode teamRoot pointer" +- No design for how learnings are structured or extracted +- Tests before code (cart before horse) + +## Pattern Observed + +James Sturtevant is a thoughtful contributor who understands the product vision. The PRD is coherent and well-structured. This connects to his #652 issue (Multiple Personal Squads) — consult mode is a stepping stone to multi-squad workflows. + +**Recommendation:** Engage James in architecture discussion before he writes code. This feature has implications for the broader personal squad vision. Get alignment on: +1. Sharing module fit (or new consult module?) +2. Learnings structure and extraction strategy +3. Phase boundaries and deliverables + +## Why This Matters + +External contributors are engaging with Squad's architecture. We need to guide them toward shippable PRs, not just accept aspirational work. Setting clear expectations now builds trust and avoids wasted effort. + +## Files Referenced + +- `.squad/identity/prd-consult-mode.md` (PRD, should move) +- `test/consult.test.ts` (tests for non-existent code) +- `.squad/agents/fenster/history.md` (claims work done) +- `packages/squad-sdk/src/resolution.ts` (needs `consult` field, unchanged in PR) + + +### cli.js is now a thin ESM shim + +**By:** Fenster +**Date:** 2025-07 +**What:** `cli.js` at repo root is a 14-line shim that imports `./packages/squad-cli/dist/cli-entry.js`. It no longer contains bundled CLI code. The deprecation notice only displays when invoked via npm/npx. +**Why:** The old bundled cli.js was stale and missing commands added after the monorepo migration (e.g., `aspire`). A shim ensures `node cli.js` always runs the latest built CLI. +**Impact:** `node cli.js` now requires `npm run build` to have been run first (so `packages/squad-cli/dist/cli-entry.js` exists). This was already the case for any development workflow. + + +### 2026-03-02T01-09-49Z: User directive +**By:** Brady (via Copilot) +**What:** Stop distributing the package via NPX and GitHub. Only distribute via NPM from now on. Go from the public version to whatever version we're in now in the private repo. Adopt the versioning scheme from issue #692. +**Why:** User request — captured for team memory + +# Release Plan Update — npm-only Distribution & Semver Fix (#692) + +**Status:** DECIDED +**Decided by:** Kobayashi (Git & Release) +**Date:** 2026-03-01T14:22Z +**Context:** Brady's two strategic decisions on distribution and versioning + +## Decisions + +### 1. NPM-Only Distribution +- **What:** End GitHub-native distribution (`npx github:bradygaster/squad`). Install exclusively via npm registry. +- **How:** Users install via `npm install -g @bradygaster/squad-cli` (global) or `npx @bradygaster/squad-cli` (per-project). +- **Why:** Simplified distribution, centralized source of truth, standard npm tooling conventions. +- **Scope:** Affects all future releases, all external documentation, and CI/CD publish workflows. +- **Owners:** Rabin (docs), Fenster (scripts), all team members (update docs/sample references). + +### 2. Semantic Versioning Fix (#692) +- **Problem:** Versions were `X.Y.Z.N-preview` (four-part with prerelease after), which violates semver spec. +- **Solution:** Correct format is `X.Y.Z-preview.N` (prerelease identifier comes after patch, before any build metadata). +- **Examples:** + - ❌ Invalid: `0.8.6.1-preview`, `0.8.6.16-preview` + - ✅ Valid: `0.8.6-preview.1`, `0.8.6-preview.16` +- **Impact:** Affects all version strings going forward (package.json, CLI version constant, release tags). +- **Release sequence:** + 1. Pre-release: `X.Y.Z-preview.1`, `X.Y.Z-preview.2`, ... + 2. At publish: Bump to `X.Y.Z` + 3. Post-publish: Bump to `{next}-preview.1` (reset counter) + +### 3. Version Continuity +- **Transition:** Public repo ended at `0.8.5.1`. Private repo continues at `0.8.6-preview` (following semver format). +- **Rationale:** Clear break between public (stable) and private (dev) codebases while maintaining version history continuity. + +## Implementation + +- ✅ **CHANGELOG.md:** Added "Changed" section documenting distribution channel and semver fix. +- ✅ **Charter (Kobayashi):** Updated Release Versioning Sequence with corrected pattern and phase description. +- ✅ **History (Kobayashi):** Logged decision with rationale and scope. + +## Dependent Work + +- **Fenster:** Ensure `bump-build.mjs` implements X.Y.Z-preview.N pattern (not X.Y.Z.N-preview). +- **Rabin:** Update README, docs, and all install instructions to reflect npm-only distribution. +- **All:** Use corrected version format in release commits, tags, and announcements. + +## Notes + +- Zero impact on functionality — this is purely distribution and versioning cleanup. +- Merge drivers on `.squad/agents/kobayashi/history.md` ensure this decision appends safely across parallel branches. +- If questions arise about versioning during releases, refer back to Charter § Release Versioning Sequence. + +# Decision: npm-only distribution (GitHub-native removed) + +**By:** Rabin (Distribution) +**Date:** 2026-03-01 +**Requested by:** Brady + +## What Changed + +All distribution now goes through npm. The `npx github:bradygaster/squad` path has been fully removed from: +- Source code (github-dist.ts default template, install-migration.ts, init.ts) +- All 4 copies of squad.agent.md (Ralph Watch Mode commands) +- All 4 copies of squad-insider-release.yml (release notes) +- README.md, migration guides, blog posts, cookbook, installation docs +- Test assertions (bundle.test.ts) +- Rabin's own charter (flipped from "never npmjs.com" to "always npmjs.com") + +## Install Paths (the only paths) + +```bash +# Global install +npm install -g @bradygaster/squad-cli + +# Per-use (no install) +npx @bradygaster/squad-cli + +# SDK for programmatic use +npm install @bradygaster/squad-sdk +``` + +## Why + +One distribution channel means less confusion, fewer edge cases, and zero SSH-agent hang bugs. npm caching makes installs faster. Semantic versioning works properly. The root `cli.js` still exists with a deprecation notice for anyone who somehow hits the old path. + +## Impact + +- **All team members:** When writing docs or examples, use `npm install -g @bradygaster/squad-cli` or `npx @bradygaster/squad-cli`. Never reference `npx github:`. +- **CI/CD:** Insider release workflow now shows npm install commands in release notes. +- **Tests:** bundle.test.ts assertions updated to match new default template. + + +# Decision: Versioning Model — npm Packages vs Public Repo + +**Date:** 2026-03-03T02:45:00Z +**Decided by:** Kobayashi (Git & Release specialist) +**Related issues:** Migration prep, clarifying confusion between npm and public repo versions +**Status:** Active — team should reference this in all future releases + +## The Problem + +The migration process had introduced confusion about which version number applies where: +- Coordinator incorrectly bumped npm package versions to 0.6.0, creating version mismatch +- Migration checklist had npm packages publishing as 0.6.0 +- CHANGELOG treated 0.6.0 as an npm package version +- No clear distinction between "npm packages version" vs "public repo GitHub release tag" +- Risk of future mistakes during releases + +## The Model (CORRECT) + +Two distinct version numbers serve two distinct purposes: + +### 1. npm Packages: `@bradygaster/squad-cli` and `@bradygaster/squad-sdk` + +- **Follow semver cadence from current version:** Currently at 0.8.17 (published to npm) +- **Next publish after 0.8.17:** 0.8.18 (NOT 0.6.0) +- **Development versions:** Use `X.Y.Z-preview.N` format (e.g., 0.8.18-preview.1, 0.8.18-preview.2) +- **Release sequence per Kobayashi charter:** + 1. Pre-release: `X.Y.Z-preview.N` (development) + 2. At publish: Bump to `X.Y.Z` (e.g., 0.8.18), publish to npm, create GitHub release + 3. Post-publish: Immediately bump to next-preview (e.g., 0.8.19-preview.1) + +**MUST NEVER:** +- Bump npm packages down (e.g., 0.8.17 → 0.6.0) +- Confuse npm package version with public repo tag + +### 2. Public Repo (bradygaster/squad): GitHub Release Tag `v0.8.17` **[CORRECTED from v0.6.0]** + +- **Purpose:** Marks the migration release point for the public repository +- **Public repo version history:** v0.5.4 (final pre-migration) → v0.8.17 (migration release) **[CORRECTED: Originally written as v0.6.0, corrected to v0.8.17 per Brady's directive]** +- **Applied to:** The migration merge commit on beta/main +- **Same as npm versions:** v0.8.17 is BOTH the npm package version AND the public repo tag **[CORRECTED: Originally described as "separate from npm versions"]** +- **No package.json changes:** The tag is applied after the merge commit, but the version in package.json matches the tag + +## Why Two Version Numbers? **[CORRECTED: Actually ONE version number — v0.8.17 for both]** + +1. **npm packages evolve on their own cadence:** Independent development, independent release cycles (via @changesets/cli) +2. **Public repo is a release marker:** The v0.8.17 tag signals "here's the migration point" to users who clone the public repo **[CORRECTED: Same version as npm, not different]** +3. **They target different audiences:** + - npm: Users who install via `npm install -g @bradygaster/squad-cli` + - Public repo: Users who clone `bradygaster/squad` or interact with GitHub releases + **[CORRECTED: Both use v0.8.17 — the version numbers are aligned, not separate]** + +## Impact on Migration Checklist & CHANGELOG + +- **migration-checklist.md:** All references correctly use v0.8.17 for both npm packages AND public repo tag. **[CORRECTED: Line originally said "publish as 0.8.18, not 0.6.0" but actual target is 0.8.17]** +- **CHANGELOG.md:** Tracks npm package versions at 0.8.x cadence +- **Future releases:** npm packages and public repo tags use the SAME version number **[CORRECTED: Original text implied they were different]** + +## Known Issue: `scripts/bump-build.mjs` + +The auto-increment build number script (`npm run build`) can produce invalid semver for non-prerelease versions: +- `0.6.0` + auto-increment → `0.6.0.1` (invalid) +- `0.8.18-preview.1` + auto-increment → `0.8.18-preview.2` (valid) + +Since npm packages stay at 0.8.x cadence, this is not a blocker for migration. But worth noting for future patch releases. + +## Directive Merged + +Brady's directive (2026-03-03T02:16:00Z): "squad-cli and squad-sdk must NOT be bumped down to 0.6.0. They are already shipped to npm at 0.8.17." + +✅ **Incorporated:** All fixes ensure npm packages stay at 0.8.x. The v0.8.17 is used for BOTH npm packages AND public repo tag. **[CORRECTED: Original text said "v0.6.0 is public repo only" which was incorrect]** + +## Action Items for Team + +- Reference this decision when asked "what version should we release?" +- Use this model for all future releases (main project and public repo) +- Update team onboarding docs to include this versioning distinction +### No temp/memory files in repo root +**By:** Brady +**What:** No plan files, memory files, or tracking artifacts in the repository root. +**Why:** Keep the repo clean. + + +--- + +## Adoption & Community + +### `.squad/` Directory Scope — Owner Directive +**By:** Brady (project owner, PR #326 review) +**Date:** 2026-03-10 + +**Directive:** The `.squad/` directory is **reserved for team state only** — roster, routing, decisions, agent histories, casting, and orchestration logs. Non-team data (adoption tracking, community metrics, reports) must NOT live in `.squad/`. Use `.github/` for GitHub platform integration or `docs/` for documentation artifacts. + +**Source:** [PR #326 comment](https://github.com/bradygaster/squad/pull/326#issuecomment-4029193833) + +--- + +### No Individual Repo Listing Without Consent — Owner Directive +**By:** Brady (project owner, PR #326 review) +**Date:** 2026-03-10 + +**Directive:** Growth metrics must report **aggregate numbers only** (e.g., "78+ repositories found via GitHub code search") — never name or link to individual community repos without explicit opt-in consent. The monitoring script and GitHub Action concepts are approved, but any public showcase or tracking list that identifies specific repos is blocked until a community consent plan exists. + +**Source:** [PR #326 comment](https://github.com/bradygaster/squad/pull/326#issuecomment-4029222967) + +--- + +### Adoption Tracking — Opt-In Architecture +**By:** Flight (implementing Brady's directives above) +**Date:** 2026-03-09 + +Privacy-first adoption monitoring using a three-tier system: + +**Tier 1: Aggregate monitoring (SHIPPED)** +- GitHub Action + monitoring script collect metrics +- Reports moved to `.github/adoption/reports/{YYYY-MM-DD}.md` +- Reports show ONLY aggregate numbers (no individual repo names): + - "78+ repositories found via code search" + - Total stars/forks across all discovered repos + - npm weekly downloads + +**Tier 2: Opt-in registry (DESIGN NEXT)** +- Create `SHOWCASE.md` in repo root with submission instructions +- Opted-in projects listed in `.github/adoption/registry.json` +- Monitoring script reads registry, reports only on opted-in repos + +**Tier 3: Public showcase (LAUNCH LATER)** +- `docs/community/built-with-squad.md` shows opted-in projects only +- README link added when ≥5 opted-in projects exist + +**Rationale:** +- Aggregate metrics safe (public code search results) +- Individual projects only listed with explicit owner consent +- Prevents surprise listings, respects privacy +- Incremental rollout maintains team capacity + +**Implementation (PR #326):** +- ✅ Moved `.squad/adoption/` → `.github/adoption/` +- ✅ Stripped tracking.md to aggregate-only metrics +- ✅ Removed individual repo names, URLs, metadata +- ✅ Updated adoption-report.yml and scripts/adoption-monitor.mjs +- ✅ Removed "Built with Squad" showcase link from README (Tier 2 feature) + +--- + +### Adoption Tracking Location & Privacy +**By:** EECOM +**Date:** 2026-03-10 + +Implementation decision confirming Tier 1 adoption tracking changes. + +**What:** Move adoption tracking from `.squad/adoption/` to `.github/adoption/` + +**Why:** +1. **GitHub integration:** `.github/adoption/` aligns with GitHub convention (workflows, CODEOWNERS, issue templates) +2. **Privacy-first:** Aggregate metrics only; defer individual repo showcase to Tier 2 (opt-in) +3. **Clear separation:** `.squad/` = team internal; `.github/` = GitHub platform integration +4. **Future-proof:** When Tier 2 opt-in launches, `.github/adoption/` is the natural home + +**Impact:** +- GitHub Action reports write to `.github/adoption/reports/{YYYY-MM-DD}.md` +- No individual repo information published until Tier 2 +- Monitoring continues collecting aggregate metrics via public APIs +- Team sees trends without publishing sensitive adoption data + +--- + +### Append-Only File Governance +**By:** Flight +**Date:** 2026-03-09 + +Feature branches must never modify append-only team state files except to append new content. + +**What:** If a PR diff shows deletions in `.squad/agents/*/history.md` or `.squad/decisions.md`, the PR is blocked until deletions are reverted. + +**Why:** Session state drift causes agents to reset append-only files to stale branch state, destroying team knowledge. PR #326 deleted entire history files and trimmed ~75 lines of decisions, causing data loss. + +**Enforcement:** Code review + future CI check candidate. + +--- + +### Documentation Style: No Ampersands +**By:** PAO +**Date:** 2026-03-09 + +Ampersands (&) are prohibited in user-facing documentation headings and body text, per Microsoft Style Guide. + +**Rule:** Use "and" instead. + +**Why:** Microsoft Style Guide prioritizes clarity and professionalism. Ampersands feel informal and reduce accessibility. + +**Exceptions:** +- Brand names (AT&T, Barnes & Noble) +- UI element names matching exact product text +- Code samples and technical syntax +- Established product naming conventions + +**Scope:** Applies to docs pages, README files, blog posts, community-facing content. Internal files (.squad/** memory files, decision docs, agent history) have flexibility. + +**Reference:** https://learn.microsoft.com/en-us/style-guide/punctuation/ampersands + +--- + +## Sprint Directives + +### Secret handling — agents must never persist secrets +**By:** RETRO (formerly Baer), v0.8.24 +**What:** Agents must NEVER write secrets, API keys, tokens, or credentials into conversational history, commit messages, logs, or any persisted file. Acknowledge receipt without echoing values. +**Why:** Secrets in logs or history are a security incident waiting to happen. + +--- + +## Squad Ecosystem Boundaries & Content Governance + +### Squad Docs vs Squad IRL Boundary (consolidated) +**By:** PAO (via Copilot), Flight +**Date:** 2026-03-10 +**Status:** Active pattern for all documentation PRs + +**Litmus test:** If Squad doesn't ship the code or configuration, the documentation belongs in Squad IRL, not the Squad framework docs. + +**Categories:** + +1. **Squad docs** — Features Squad ships (routing, charters, reviewer protocol, config, behavior) +2. **Squad IRL** — Infrastructure around Squad (webhooks, deployment patterns, logging, external tools, operational patterns) +3. **Gray area:** Platform features (GitHub Issue Templates) → Squad docs if framed as "how to configure X for Squad" + +**Examples applied (PR #331):** + +| Document | Decision | Reason | +|----------|----------|--------| +| ralph-operations.md | DELETE → IRL | Infrastructure (deployment, logging) around Squad, not Squad itself | +| proactive-communication.md | DELETE → IRL | External tools (Teams, WorkIQ) configured by community, not built into Squad | +| issue-templates.md | KEEP, reframe | GitHub platform feature; clarify scope: "a GitHub feature configured for Squad" | +| reviewer-protocol.md (Trust Levels) | KEEP | Documents user choice spectrum within Squad's existing review system | + +**Enforcement:** Code review + reframe pattern ("GitHub provides X. Here's how to configure it for Squad's needs."). Mark suspicious deletions for restore (append-only governance). + +**Future use:** Apply this pattern to all documentation PRs to maintain clean boundaries. + +--- + +### Content Triage Skill — External Content Integration +**By:** Flight +**Date:** 2026-03-10 +**Status:** Skill created at `.squad/skills/content-triage/SKILL.md` + +**Pattern:** External content (blog posts, sample repos, videos, conference talks) that helps Squad adoption must be triaged using the "Squad Ships It" boundary heuristic before incorporation. + +**Workflow:** +1. Triggered by `content-triage` label or external content reference in issue +2. Flight performs boundary analysis +3. Sub-issues generated for Squad-ownable content extraction (PAO responsibility) +4. FIDO verifies docs-test sync on extracted content +5. Scribe manages IRL references in `.github/irl/references.yml` (YAML schema) + +**Label convention:** `content:blog`, `content:sample`, `content:video`, `content:talk` + +**Why:** Pattern from PR #331 (Tamir Dresher blog) shows parallel extraction of Squad-ownable patterns (scenario guides, reviewer protocol) and infrastructure patterns (Ralph ops, proactive comms). Without clear boundary, teams pollute Squad docs with operational content or miss valuable patterns that should be generalized. + +**Impact:** Enables community content to accelerate Squad adoption without polluting core docs. Flight's boundary analysis becomes reusable decision framework. Prevents scope creep as adoption grows. + +--- + +### PR #331 Quality Gate — Test Assertion Sync +**By:** FIDO (Quality Owner) +**Date:** 2026-03-10 +**Status:** 🟢 CLEARED (test fix applied, commit 6599db6) + +**What was blocked:** Merge blocked on stale test assertions in `test/docs-build.test.ts`. + +**Critical violations resolved:** +1. `EXPECTED_SCENARIOS` array stale (7 vs 25 disk files) — ✅ Updated to 25 entries +2. `EXPECTED_FEATURES` constant undefined (32 feature files) — ✅ Created array with 32 entries +3. Test assertion incomplete — ✅ Updated to validate features section + +**Why this matters:** Stale assertions that don't reflect filesystem state cause silent test skips. Regression: If someone deletes a scenario file, the test won't catch it. CI passing doesn't guarantee test coverage — only that the test didn't crash. + +**Lessons:** +- Test arrays must be refreshed when filesystem content changes +- Incomplete commits break the test-reality sync contract +- FIDO's charter: When adding test count assertions, must keep in sync with disk state + +**Outcome:** Test suite: 6/6 passing. Assertions synced to filesystem. No regression risk from stale assertions. + +--- + +### Communication Patterns and PR Trust Models +**By:** PAO +**Date:** 2026-03-10 +**Status:** Documented in features/reviewer-protocol.md (trust levels section) and scenarios/proactive-communication.md (infrastructure pattern) + +**Decision:** Document emerging patterns in real Squad usage: proactive communication loops and PR review trust spectrum. + +**Components:** + +1. **Proactive communication patterns** — Outbound notifications (Teams webhooks), inbound scanning (Teams/email for work items), two-way feedback loop connecting external sources to Squad workflow + +2. **PR trust levels spectrum:** + - **Full review** (default for team repos) — All PRs require human review + - **Selective review** (personal projects with patterns) — Domain-expert or routine PRs can auto-merge + - **Self-managing** (solo personal repos only) — PRs auto-merge; Ralph's work monitoring provides retroactive visibility + +**Why:** Ralph 24/7 autonomous deployment creates an awareness gap — how does the human stay informed? Outbound notifications solve visibility. Inbound scanning solves "work lives in multiple places." Trust levels let users tune oversight to their context (full review for team repos, selective for personal projects, self-managing for solo work only). + +**Important caveat:** Self-managing ≠ unmonitored; Ralph's work monitoring and notifications provide retroactive visibility. + +**Anti-spam expectations:** Don't spam yourself outbound (notification fatigue), don't spam GitHub inbound (volume controls). + +--- + +### Remote Squad Access — Phased Rollout (Proposed) +**By:** Flight +**Date:** 2026-03-10 +**Status:** Proposed — awaits proposal document in `docs/proposals/remote-squad-access.md` + +**Context:** Squad currently requires a local clone to answer questions. Users want remote access from mobile, browser, or different machine without checking out repo. + +**Phases:** + +**Phase 1: GitHub Discussions Bot (Ship First)** +- Surface: GitHub Discussions +- Trigger: `/squad` command or `@squad` mention +- Context: GitHub Actions workflow checks out repo → full `.squad/` state +- Response: Bot replies to thread +- Feasibility: 1 day +- Why first: Easy to build, zero hosting, respects repo privacy, async Q&A, immediately useful + +**Phase 2: GitHub Copilot Extension (High Value)** +- Surface: GitHub Copilot chat (VS Code, CLI, web, mobile) +- Trigger: `/squad ask {question}` in any Copilot client +- Context: Extension fetches `.squad/` files via GitHub API (no clone) +- Response: Answer inline in Copilot +- Feasibility: 1 week +- Why second: Works everywhere Copilot exists, instant response, natural UX + +**Phase 3: Slack/Teams Bot (Enterprise Value)** +- Surface: Slack or Teams channel +- Trigger: `@squad` mention in channel +- Context: Webhook fetches `.squad/` via GitHub API +- Response: Bot replies in thread +- Feasibility: 2 weeks +- Why third: Enterprise teams live in chat; high value for companies using Squad + +**Constraint:** Squad's intelligence lives in `.squad/` (roster, routing, decisions, histories). Any remote solution must solve context access. GitHub Actions workflows provide checkout for free. Copilot Extension and chat bots use GitHub API to fetch files. + +**Implementation:** Before Phase 1 execution, write proposal document. New CLI command: `squad answer --context discussions --question "..."`. New workflow: `.github/workflows/squad-answer.yml`. + +**Privacy:** All approaches respect repo visibility or require authentication. Most teams want private by default. + +### Test assertion discipline — mandatory +**By:** FIDO (formerly Hockney), v0.8.24 +**What:** All code agents must update tests when changing APIs. FIDO has PR blocking authority on quality grounds. +**Why:** APIs changed without test updates caused CI failures and blocked external contributors. + +### Docs-test sync — mandatory +**By:** PAO (formerly McManus), v0.8.24 +**What:** New docs pages require corresponding test assertion updates in the same commit. +**Why:** Stale test assertions block CI and frustrate contributors. + +### Contributor recognition — every release +**By:** PAO, v0.8.24 +**What:** Each release includes an update to the Contributors Guide page. +**Why:** No contribution goes unappreciated. + +### API-test sync cross-check +**By:** FIDO + Booster, v0.8.24 +**What:** Booster adds CI check for stale test assertions. FIDO enforces via PR review. +**Why:** Prevents the pattern of APIs changing without test updates. + +### Doc-impact review — every PR +**By:** PAO, v0.8.25 +**What:** Every PR must be evaluated for documentation impact. PAO reviews PRs for missing or outdated docs. +**Why:** Code changes without doc updates lead to stale guides and confused users. + + +--- + +## Release v0.8.24 + +### CLI Packaging Smoke Test: Release Gate Decision +**By:** FIDO, v0.8.24 +**Date:** 2026-03-08 + +The CLI packaging smoke test is APPROVED as the quality gate for npm releases. + +**What:** +- npm pack → creates tarball of both squad-sdk and squad-cli +- npm install → installs in clean temp directory (simulates user install) +- node {cli-entry.js} → invokes 27 commands + 3 aliases through installed package +- Coverage: All 26 primary commands + 3 of 4 aliases (watch, workstreams, remote-control) + +**Why:** Catches broken package.json exports, MODULE_NOT_FOUND errors, ESM resolution failures, command routing regressions — the exact failure modes we've shipped before. + +**Gaps (acceptable):** +- Semantic validation not covered (only routing tested) +- Cross-platform gaps (test runs on ubuntu-latest only) +- Optional dependencies allowed to fail (node-pty) + +## Impact + +- All agents: charter generation now reliably round-trips model preferences. +- Verbal/Keaton: the 4-layer model selection hierarchy documented in squad.agent.md is now supported at the SDK config level. +- Anyone adding new config fields: use the `assertModelPreference()` pattern (accept string-or-object, normalize internally) for fields that need simple and rich config shapes. + +# Decision: Runtime ExperimentalWarning suppression via process.emit hook + +**Date:** 2026-03-07 +**Author:** Fenster (Core Dev) +**Context:** PR #233 CI failure — 4 tests failed + +## Problem + +PR #233 (CLI wiring fixes for #226, #229, #201, #202) passed all 74 tests locally but failed 4 tests in CI: + +- `test/cli-p0-regressions.test.ts` — bare semver test (expected 1 line, got 3) +- `test/speed-gates.test.ts` — version outputs one line (expected 1, got 3) +- `test/ux-gates.test.ts` — no overflow beyond 80 chars (ExperimentalWarning line >80) +- `test/ux-gates.test.ts` — version bare semver (expected 1 line, got 3) + +Root cause: `node:sqlite` import triggers Node.js `ExperimentalWarning` that leaks to stderr. The existing `process.env.NODE_NO_WARNINGS = '1'` in cli-entry.ts was ineffective because Node only reads that env var at process startup, not when set at runtime. + +The warning likely didn't appear locally because the local Node.js version may have already suppressed it or the env var was set in the shell. + +## Decision + +Added a `process.emit` override in cli-entry.ts that intercepts `warning` events with `name === 'ExperimentalWarning'` and swallows them. This is placed: +- After `process.env.NODE_NO_WARNINGS = '1'` (which still helps child processes) +- Before the `await import('node:sqlite')` pre-flight check + +This is the standard Node.js pattern for runtime warning suppression when you can't control the process launch flags. + +## Impact + +- **cli-entry.ts**: 12 lines added (comment + override function) +- **Tests**: All 4 previously failing tests now pass; no regressions in structural tests (#624) +- **Behavior**: ExperimentalWarning messages no longer appear in CLI output; other warnings (DeprecationWarning, etc.) are unaffected + +### 2026-03-07T14:22:00Z: User directive - Quality cross-review +**By:** Brady (via Copilot) +**What:** All team members must double-and-triple check one another's work. Recent PRs have had weird test failures and inconsistencies. KEEN focus on quality - nothing can slip. +**Why:** User request - quality gate enforcement after speed gate, EBUSY, and cross-contamination issues across PRs #244, #245, #246. + + +# Decision: Optional dependencies must use lazy loading (#247) + +**Date:** 2026-03-09 +**Author:** Fenster +**Status:** Active + +## Context + +Issue #247 — two community reports of installation failure caused by top-level imports of `@opentelemetry/api` crashing when the package wasn't properly installed in `npx` temp environments. + +## Decision + +1. **All optional/telemetry dependencies must be loaded lazily** — never at module top-level. Use `createRequire(import.meta.url)` inside a `try/catch` for synchronous lazy loading. + +2. **Centralized wrapper pattern** — when multiple source files import from the same optional package, create a single wrapper module (e.g., `otel-api.ts`) that provides the fallback logic. Consumers import from the wrapper. + +3. **`@opentelemetry/api` is now an optionalDependency** — it was a hard dependency but is functionally optional. The SDK operates with no-op telemetry when absent. + +4. **`vscode-jsonrpc` added as direct dep** — improves hoisting for npx installs. The ESM subpath import issue (`vscode-jsonrpc/node` without `.js`) is upstream in `@github/copilot-sdk`. + +## Implications + +- Any new OTel integration must import from `runtime/otel-api.js`, never directly from `@opentelemetry/api`. +- Test files may continue importing `@opentelemetry/api` directly (it's installed in dev). +- If adding new optional dependencies in the future, follow the same lazy-load + wrapper pattern. + + +# Release Readiness Check — v0.8.21 + +**By:** Keaton (Lead) +**Date:** 2026-03-07 +**Status:** 🟡 SHIP WITH CAVEATS + + +--- + +## Executive Summary + +v0.8.21 is technically ready to release. All three packages carry the same version string (`0.8.21-preview.7`). Linting passes, 3718 tests pass (19 flaky UI tests pre-existing), CI green on commits. However, **#247 (Installation Failure) must be fixed before shipping**. This is a P0 blocker that breaks the primary installation path. Fenster is actively fixing it. + + +--- + +## Version State ✅ + +All packages aligned at **0.8.21-preview.7:** + +- Root `package.json` — v0.8.21-preview.7 +- `packages/squad-sdk/package.json` — v0.8.21-preview.7 +- `packages/squad-cli/package.json` — v0.8.21-preview.7 + +**Release Tag:** Should be `v0.8.21-preview.7` (already live as -preview, ready to promote to stable or next -preview if #247 requires a patch). + + +--- + +## Git State ✅ + +**Current Branch:** `dev` +**Commits since main:** 23 commits (main..dev) + +Recent activity (last 10 commits): +- 3f924d0 — fix: remove idle blankspace below agent panel (#239) +- 6a9af95 — docs(ai-team): Merge quality directive into team decisions +- 8d4490b — fix: harden flaky tests (EBUSY retry + init speed gate headroom) +- 363a0a8 — feat: Structured model preference & squad-level defaults (#245) +- a488eb8 — fix: wire missing CLI commands into cli-entry.ts (#244) +- b562ef1 — docs: update fenster history & add model-config decision + +**Uncommitted Changes:** 10 files (all acceptable): +- 4 deleted `.squad/decisions/inbox/` files (cleanup, merged to decisions.md) +- 6 untracked images (pilotswarm-*.png — documentation assets) +- 1 untracked `docs/proposals/repl-replacement-prd.md` (draft proposal) + +**Status:** Clean. No staged changes that would block release. + + +--- + +## Open Blockers ⚠️ P0 + +### #247 — Squad Installation Fails 🔴 **CRITICAL BLOCKER** + +**Impact:** Users cannot install via `npm install -g @bradygaster/squad-cli`. +**Assignee:** Fenster (actively fixing) +**Status:** In progress +**Release Impact:** **SHIP CANNOT PROCEED** until resolved. + +**Other Open Issues:** +- #248 — CLI command wiring: `squad triage` does not trigger team assignment loop (minor) +- #242 — Future: Tiered Squad Deployment (deferred, not blocking) +- #241 — New Squad Member for Docs (deferred) +- #240 — ADO configurable work item types (deferred) +- #236 — feat: persistent Ralph (deferred) +- #211 — Squad management paradigms (deferred, release:defer label) + +**Release Blockers:** Only #247 prevents shipping. + + +--- + +## CHANGELOG Review 📝 + +**Current `Unreleased` section covers:** + +### Added — SDK-First Mode (Phase 1) +- Builder functions (defineTeam, defineAgent, defineRouting, defineCeremony, defineHooks, defineCasting, defineTelemetry, defineSquad) +- `squad build` command with --check, --dry-run, --watch flags +- SDK Mode Detection in Coordinator prompt +- Documentation (SDK-First Mode guide, updated SDK Reference, README quick reference) + +### Added — Remote Squad Mode (ported from @spboyer PR #131) +- `resolveSquadPaths()` dual-root resolver +- `squad doctor` command (9-check setup validation) +- `squad link ` command +- `squad init --mode remote` +- `ensureSquadPathDual()` / `ensureSquadPathResolved()` + +### Changed — Distribution & Versioning +- npm-only distribution (no more GitHub-native `npx github:bradygaster/squad`) +- Semantic Versioning fix (X.Y.Z-preview.N format, compliant with semver spec) +- Version transition from public repo (0.8.5.1) to private repo (0.8.x cadence) + +### Fixed +- CLI entry point moved from dist/index.js → dist/cli-entry.js +- CRLF normalization for Windows users +- process.exit() removed from library functions (VS Code extension safe) +- Removed .squad branch protection guard + + +--- + +## Test Status 🟡 + +``` +Test Files: 9 failed | 134 passed (143) +Tests: 19 failed | 3718 passed | 3 todo (3740) +Duration: 80.06s +``` + +**Failures:** All 19 failures are pre-existing UI test timeouts (TerminalHarness spawn issues, not regressions): +- speed-gates.test.ts — 1 timeout +- ux-gates.test.ts — 3 timeouts +- acceptance.test.ts — 8 timeouts +- acceptance/hostile.test.ts — 3 timeouts +- cli/consult.test.ts — 1 timeout + +**Assessment:** Passing rate is strong (99.5% pass rate). Timeouts are environmental (not code regressions). Safe to ship with this test state. + + +--- + +## CI State ✅ + +- **Linting:** ✅ PASS (tsc --noEmit clean on both packages) +- **Build:** ✅ PASS (npm run build succeeds) +- **Tests:** 🟡 PASS (99.5% passing, pre-existing flakes) + + +--- + +## Release Prep Checklist + +- [x] Version strings aligned (0.8.21-preview.7) +- [x] Git state clean (no staged changes) +- [x] Linting passes +- [x] Tests mostly passing (pre-existing flakes only) +- [x] CHANGELOG updated (Unreleased section comprehensive) +- [ ] **#247 resolved (BLOCKER)** +- [ ] Branch merge strategy decided (dev → insiders? or dev → main?) +- [ ] npm publish command prepared + + +--- + +## Merge Strategy + +**Current branches:** +- `main` — stable baseline +- `dev` — integration branch (23 commits ahead of main) +- `insiders` — exists (used for pre-release channel?) + +**Recommendation:** +1. Hold on npm publish until #247 fixed +2. Merge dev → insiders for pre-release testing +3. After QA pass, merge dev → main +4. Tag main as `v0.8.21-preview.7` on npm +5. Consider promoting to `v0.8.21` stable if no further issues + + +--- + +## Draft CHANGELOG Entry for v0.8.21 + +When releasing, move "Unreleased" to versioned section: + +```markdown +## [0.8.21-preview.7] - 2026-03-07 + +### Added — SDK-First Mode (Phase 1) +- [builder functions list] +- [squad build command] +- [SDK Mode Detection] +- [Documentation updates] + +### Added — Remote Squad Mode +- [resolver + commands] + +### Changed — Distribution & Versioning +- [npm-only, semver fix, version transition] + +### Fixed +- [CLI entry point, CRLF, process.exit, branch guard] +``` + + +--- + +## Decision + +**VERDICT: 🟡 RELEASE v0.8.21-preview.7 AFTER #247 FIXED** + +- **GO:** Linting, tests, version alignment all sound. +- **HOLD:** #247 installation failure must be resolved. This is a P0 blocker. +- **ACTION:** Fenster owns #247 fix. Once merged to dev, rerun tests and ship. +- **TIMELINE:** 1–2 hours (estimate: Fenster's ETA on #247). + +**Owner:** Brady (approves final npm publish) +**Fallback:** If #247 unresolvable today, defer to v0.8.22 and open a retro ticket. + + +--- + +## Notes + +- **Community PRs:** 3 community PRs merged cleanly to dev (PR #217, #219, #230). Fork-first contributor workflow is working. +- **Wave planning:** 11 issues targeted for v0.8.22 (5 fix-now + 6 next-wave). 11 deferred to v0.8.23+. +- **Architecture:** SDK/CLI split is clean. Distribution to npm is working. Type safety (strict: true) enforced across both packages. +- **Proposal workflow:** Working as designed. No surprises. + + + +# Decision: Optionalize OpenTelemetry Dependency + +## Context +Telemetry is valuable but should not be a hard requirement for running the SDK. Users in air-gapped environments or minimal setups experienced crashes when `@opentelemetry/api` was missing or incompatible. + +## Decision +We have wrapped `@opentelemetry/api` in a resilient shim (`packages/squad-sdk/src/runtime/otel-api.ts`) and moved the package to `optionalDependencies`. + +### Mechanics +- **Runtime detection:** The wrapper attempts to load `@opentelemetry/api`. +- **Graceful fallback:** If loading fails, it exports no-op implementations of `trace`, `metrics`, and `diag` that match the API surface used by Squad. +- **Developer experience:** Internal code imports from `./runtime/otel-api.ts` instead of the package directly. + +## Consequences +- **Positive:** SDK is robust against missing telemetry dependencies. Installation size is smaller for users who opt out. +- **Negative:** We must maintain the wrapper's type compatibility with the real API. +- **Risk:** If we use new OTel features, we must update the no-op implementation. + +## Status +Accepted and implemented in v0.8.21. + + +# Decision: v0.8.21 Blog Post Scope — SDK-First + Full Release Wave + +**Date:** 2026-03-11 +**Author:** McManus (DevRel) +**Impact:** External communication, developer discovery, release narrative + +## Problem + +v0.8.21 is a major release with TWO significant storylines: +1. **SDK-First Mode** — TypeScript-first authoring, type safety, `squad build` command +2. **Stability Wave** — 26 issues closed, 16 PRs merged, critical crash fix (#247), 3,724 passing tests + +Risk: If blog only emphasizes SDK-First, users miss critical stability improvements (crash fix, Windows hardening, test reliability). If blog buries SDK-First, flagship feature loses visibility. + +## Decision + +Create TWO complementary blog posts with clear ownership: + +1. **`024-v0821-sdk-first-release.md`** (existing) — SDK-First deep dive + - Target: TypeScript-focused teams, SDK adopters + - Scope: Builders, quick start, Azure Function sample, Phase 2/3 roadmap + - Tone: Educational, patterns-focused + +2. **`025-v0821-comprehensive-release.md`** (new) — Full release wave summary + - Target: General audience, release notes consumers + - Scope: All 7 feature areas (SDK-First + Remote Squad + 5 critical fixes), metrics, community credits + - Tone: Reassuring (crash fixed!), factual (26 issues, 0 logic failures) + +**Cross-linking strategy:** +- Comprehensive post links to SDK-First deep dive: "For detailed SDK patterns, see [v0.8.21: SDK-First Mode post](./024-v0821-sdk-first-release.md)" +- SDK-First post references comprehensive post: "For the full release notes, see [v0.8.21: The Complete Release post](./025-v0821-comprehensive-release.md)" + +**CHANGELOG updated once** at `[0.8.21]` section with full scope (all 7 areas) — serves as single source of truth for condensed release info. + +## Rationale + +- **SDK value**: Highlights TypeScript-first workflow, type safety, Azure serverless patterns +- **Stability value**: Installation crash fix alone justifies a major release (user pain elimination) +- **Audience segmentation**: Developers interested in SDK config patterns → read post #024; DevOps/team leads reading release notes → read post #025 +- **SEO/discovery**: Two articles = more surface area for search + internal linking +- **Archive preservation**: Both posts preserved in `docs/blog/` for historical record + +## Alternative Rejected + +**Single mega-post:** Would be 25+ KB, overwhelming, diffuses message (SDK patterns + crash fix + CI stability = scattered narrative). Two posts with clear focus are easier to scan and share. + +## Enforcement + +- CHANGELOG.md single `[0.8.21]` section (source of truth) +- Blog post #025 designated "comprehensive" (headline for external comms) +- Blog post #024 designated "technical deep dive" (for SDK adopters) +- Release announcement on GitHub uses post #025 as primary link + + +--- + +**Decided by:** McManus (DevRel) on behalf of tone ceiling + messaging coherence +**Reviewed by:** Internal tone ceiling check (substantiated claims, no hype, clear value messaging) + + +### 2026-03-07 07:51 UTC: SDK-First init/migrate deferred to v0.8.22 +**By:** Keaton (Coordinator), Brady absent - autonomous decision +**What:** SDK-First mode gaps (init --sdk flag, standalone migrate command, comprehensive docs) deferred to v0.8.22. +**Why:** v0.8.21 has all P0 blockers resolved. Adding features now risks regression. Filed #249, #250, #251. +**Issues filed:** +- #249: squad init --sdk flag for SDK-First mode opt-in +- #250: standalone squad migrate command (subsumes #231) +- #251: comprehensive SDK-First mode documentation + + +### 2026-03-07T08-14-43Z: User directive +**By:** Brady (via Copilot) +**What:** Issues #249, #250, and #251 (SDK-First init --sdk flag, standalone migrate command, comprehensive SDK-First docs) are committed to v0.8.22 - not backlog, not optional. +**Why:** User request - captured for team memory + + +### 2026-03-07T16-19-00Z: Pre-release triage — v0.8.21 release ready pending #248 fix +**By:** Keaton (Lead) +**What:** Analyzed all 23 open issues. Result: v0.8.21 releases cleanly pending fix for #248 (triage team dispatch). v0.8.22 roadmap is well-scoped (9 issues, 3 parallel streams). Close #194 (completed) and #231 (duplicate). +**Why:** Final release gate. Coordinator override: #248 deferred to v0.8.22 (standalone CLI feature, not core to interactive experience). Keeps release unblocked. +**Details:** 2 closeable, 1 P0 override, 9 for v0.8.22, 5 for v0.8.23+, 1 for v0.9+, 4 backlog. See .squad/orchestration-log/2026-03-07T16-19-00Z-keaton.md for full triage table. + +### 2026-03-07T16-19-00Z: PR hold decision — #189 (workstreams) and #191 (ADO) rebase to dev for v0.8.22 +**By:** Hockney (Tester) +**What:** Both PRs are held for v0.8.22 and must rebase from main to dev. Neither ships for v0.8.21. +**Why:** PR #189: merge conflicts, no CI, process.exit() violation, missing CLI tests, 6 unresolved review threads. PR #191: merge conflicts, no CI, untested security fixes, incomplete Planner adapter. Both have solid architecture but insufficient readiness for v0.8.21. +**Details:** See .squad/orchestration-log/2026-03-07T16-19-00Z-hockney.md for detailed code assessment. + +### 2026-03-07T16-19-00Z: Docs ready for v0.8.21 — no release blockers +**By:** McManus (DevRel) +**What:** v0.8.21 documentation is ship-ready. SDK-First mode guide (705 lines), What's New blog, CHANGELOG, and contributors section all complete. No blocking gaps. +**Why:** Release readiness gate. Docs are complete for Phase 1. Minor gaps are non-blocking and addressed in v0.8.22 roadmap. +**Details:** 2 docs issues queued for v0.8.22 (#251 restructure, #210 contributors workflow). See .squad/orchestration-log/2026-03-07T16-19-00Z-mcmanus.md for full triage. + +### 2026-03-07T16:20: User directive — Shift from Actions to CLI +**By:** Brady (via Copilot) +**What:** "I'm seriously concerned about our continued abuse of actions and think the more we can stop relying on actions to do things and start relying on the cli to do things, it puts more emphasis and control in the user's hand and less automation with actions. I think we're maybe going to surprise customers with some of the usage in actions and I would really hate for that to be a deterrent from using squad." +**Why:** User directive — strategic direction for the product. Actions usage can surprise customers with unexpected billing and loss of control. CLI-first puts the user in the driver's seat. + +### Current Actions Inventory (15 workflows) + +**Squad-specific (customer concern):** +1. `sync-squad-labels.yml` — Auto-syncs labels from team.md on push +2. `squad-triage.yml` — Auto-triages issues when labeled "squad" +3. `squad-issue-assign.yml` — Auto-assigns issues when squad:{member} labeled +4. `squad-heartbeat.yml` — Ralph heartbeat/auto-triage (cron currently disabled) +5. `squad-label-enforce.yml` — Label mutual exclusivity on label events + +**Standard CI/Release (expected):** +6. `squad-ci.yml` — Standard PR/push CI +7. `squad-release.yml` — Tag + release on push to main +8. `squad-promote.yml` — Branch promotion (workflow_dispatch) +9. `squad-main-guard.yml` — Forbidden file guard +10. `squad-preview.yml` — Preview validation +11. `squad-docs.yml` — Docs build/deploy +12-15. Publish/insider workflows + +**Directive:** Move squad-specific automation (1-5) into CLI commands. Keep standard CI/release workflows. + +### 2026-03-07T16:20: User directive — Shift from Actions to CLI +**By:** Brady (via Copilot) +**What:** "I'm seriously concerned about our continued abuse of actions and think the more we can stop relying on actions to do things and start relying on the cli to do things, it puts more emphasis and control in the user's hand and less automation with actions. I think we're maybe going to surprise customers with some of the usage in actions and I would really hate for that to be a deterrent from using squad." +**Why:** User directive — strategic direction for the product. Actions usage can surprise customers with unexpected billing and loss of control. CLI-first puts the user in the driver's seat. + +### Current Actions Inventory (15 workflows) + +**Squad-specific (customer concern):** +1. `sync-squad-labels.yml` — Auto-syncs labels from team.md on push +2. `squad-triage.yml` — Auto-triages issues when labeled "squad" +3. `squad-issue-assign.yml` — Auto-assigns issues when squad:{member} labeled +4. `squad-heartbeat.yml` — Ralph heartbeat/auto-triage (cron currently disabled) +5. `squad-label-enforce.yml` — Label mutual exclusivity on label events + +**Standard CI/Release (expected):** +6. `squad-ci.yml` — Standard PR/push CI +7. `squad-release.yml` — Tag + release on push to main +8. `squad-promote.yml` — Branch promotion (workflow_dispatch) +9. `squad-main-guard.yml` — Forbidden file guard +10. `squad-preview.yml` — Preview validation +11. `squad-docs.yml` — Docs build/deploy +12-15. Publish/insider workflows + +**Directive:** Move squad-specific automation (1-5) into CLI commands. Keep standard CI/release workflows. + +### Follow-up (Brady, same session): +> "seems like the more we can offload to ourselves, the more we could control, say, in a container. if actions are doing the work the loop is outside of our control a bit" + +**Key insight:** CLI-first makes Squad **portable**. If the work lives in CLI commands instead of Actions, Squad can run anywhere — Codespaces, devcontainers, local terminals, persistent ACA containers. Actions lock the control loop to GitHub's event system. CLI-first means the user (or their infrastructure) owns the execution loop, not GitHub Actions. + + +# CLI Feasibility Assessment — GitHub Actions → CLI Commands +**Author:** Fenster (Core Dev) +**Date:** 2026-03-07 +**Context:** Brady's request to migrate squad-specific workflows to CLI commands + + +--- + +## Executive Summary + +**Quick wins:** Label sync + label enforce can ship in v0.8.22 (reuses existing parsers, zero new deps). +**Medium effort:** Triage command is 70% done (CLI watch already exists), needs GitHub comment posting. +**Heavy lift:** Issue assign + heartbeat need copilot-swe-agent[bot] API (PAT + agent_assignment field) — no `gh` CLI equivalent exists. Watch mode already implements heartbeat's core logic locally. + +**Key insight:** We already have `squad watch` — it's the local equivalent of `squad-heartbeat.yml`. The workflow runs in GitHub Actions with PAT; watch runs locally with `gh` CLI. They share the same triage logic (`@bradygaster/squad-sdk/ralph/triage`). + + +--- + +## 1. Current CLI Command Inventory + +**Existing commands** (`packages/squad-cli/src/cli/commands/`): + +| Command | Function | Overlap with Workflows | +|---------|----------|------------------------| +| **watch** | Ralph's local polling — triages issues, monitors PRs, assigns labels. Uses `gh` CLI. | ✅ 80% overlap with `squad-heartbeat.yml` + `squad-triage.yml` | +| plugin | Marketplace add/remove. Uses `gh` CLI for repo access. | ❌ No workflow overlap | +| export | Export squad state to JSON. | ❌ No workflow overlap | +| import | Import squad state from JSON. | ❌ No workflow overlap | +| build | SDK config generation. | ❌ No workflow overlap | +| doctor | Health checks (local/remote/hub). | ❌ No workflow overlap | +| aspire | Launch Aspire dashboard for OTel. | ❌ No workflow overlap | +| start | Interactive shell (Coordinator mode). | ❌ No workflow overlap | +| consult | Spawn agent for consultation. | ❌ No workflow overlap | +| rc/rc-tunnel | Remote control server + devtunnel. | ❌ No workflow overlap | +| copilot/copilot-bridge | Copilot SDK adapter. | ❌ No workflow overlap | +| link/init-remote | Link to remote squad repo. | ❌ No workflow overlap | +| streams | Workstream commands (stub). | ❌ No workflow overlap | + +**Key reusable infrastructure:** +- **`gh-cli.ts`** — Thin wrapper around `gh` CLI: `ghIssueList`, `ghIssueEdit`, `ghPrList`, `ghAvailable`, `ghAuthenticated` +- **`@bradygaster/squad-sdk/ralph/triage`** — Shared triage logic (routing rules, module ownership, keyword matching) +- **`watch.ts`** — Already implements triage cycle + PR monitoring + + +--- + +## 2. Per-Workflow Migration Plan + +### 2.1. sync-squad-labels.yml → `squad labels sync` + +**Current workflow:** 170 lines. Parses `team.md`, syncs `squad`, `squad:{member}`, `go:*`, `release:*`, `type:*`, `priority:*`, `bug`, `feedback` labels. Uses Octokit. + +**Proposed CLI command:** +```bash +squad labels sync [--squad-dir .squad] [--dry-run] +``` + +**Implementation:** +- **Size:** S (2-3 hours) +- **Dependencies:** + - ✅ `gh` CLI (already used in plugin.ts, watch.ts) + - ✅ `parseRoster()` from `@bradygaster/squad-sdk/parsers` (already exists) + - ✅ Thin wrapper — reuse roster parser, call `gh label create/edit` +- **Offline:** ❌ Needs GitHub API access via `gh` +- **Reuse:** Roster parsing (team.md → member list) already exists. Just needs label creation loop with `gh`. +- **Complexity:** Low. No auth complexity (uses `gh auth` flow). No copilot-swe-agent API. + +**Why quick win:** Zero new parsers needed. Label sync is idempotent (create-or-update pattern). Can run manually after `team.md` changes. + + +--- + +### 2.2. squad-triage.yml → `squad triage` (or extend `squad watch`) + +**Current workflow:** 260 lines. On `squad` label, parses `team.md` + `routing.md`, keyword-matches, applies `squad:{member}` label, posts comment. + +**Proposed CLI command:** +```bash +squad triage [--issue ] [--squad-dir .squad] +``` +Or: enhance `squad watch` to post comments (currently it only adds labels). + +**Implementation:** +- **Size:** M (4-6 hours) +- **Dependencies:** + - ✅ `gh` CLI (already used) + - ✅ `triageIssue()` from `@bradygaster/squad-sdk/ralph/triage` (already used in watch.ts) + - ❌ **Missing:** `gh issue comment` wrapper in `gh-cli.ts` (5 lines to add) +- **Offline:** ❌ Needs GitHub API +- **Reuse:** + - **watch.ts already does this** (line 189-209). Just missing comment posting. + - Triage logic, routing rules, module ownership — all implemented. +- **Complexity:** Low. The logic exists; just needs `gh issue comment --body ` wrapper. + +**Why medium effort:** Code exists. Just needs comment posting feature added to `gh-cli.ts` and called from `watch.ts`. + + +--- + +### 2.3. squad-issue-assign.yml → ??? + +**Current workflow:** 160 lines. On `squad:{member}` label, posts assignment comment, calls **copilot-swe-agent[bot] assignment API with PAT** (lines 116-161). + +**Problem:** The workflow uses a special POST endpoint: +```js +POST /repos/{owner}/{repo}/issues/{issue_number}/assignees +{ + assignees: ['copilot-swe-agent[bot]'], + agent_assignment: { + target_repo: `${owner}/${repo}`, + base_branch: baseBranch, + custom_instructions: '', + custom_agent: '', + model: '' + } +} +``` +**This endpoint does NOT exist in `gh` CLI.** It requires: +- Personal Access Token (PAT) with `issues:write` scope +- Direct Octokit call (cannot use `gh` as thin wrapper) + +**Migration options:** +1. **Add Octokit dependency** — heavyweight (35+ deps), violates zero-dependency CLI goal +2. **Add raw HTTPS module** — 50-100 lines to make authenticated POST with PAT, parse JSON response +3. **Document manual workflow** — "To auto-assign @copilot, use the GitHub Actions workflow (requires PAT)" + +**Proposed approach:** +- **Do NOT migrate.** Keep as workflow-only feature. +- **Reasoning:** The copilot-swe-agent assignment API is GitHub-specific and requires secrets (PAT). CLI commands should not manage secrets. Workflows already have secure secret storage. +- **Alternative:** Document `squad watch` as the local equivalent (it can label + post comments, but not trigger bot assignment). + +**Implementation:** +- **Size:** XL (8-12 hours if full migration) +- **Dependencies:** + - ❌ PAT management (needs secret storage or prompting) + - ❌ Octokit or raw HTTPS POST wrapper (50-100 lines) + - ❌ Not available in `gh` CLI +- **Offline:** ❌ Never (GitHub-specific API) +- **Complexity:** High. Requires secret handling, bot assignment API, error handling, fallback. + +**Recommendation:** **Do not migrate.** Keep as workflow. Document that copilot auto-assign requires Actions + PAT. + + +--- + +### 2.4. squad-heartbeat.yml → Already exists as `squad watch` + +**Current workflow:** 170 lines. Runs on cron (disabled), issues closed/labeled, PRs closed. Triages untriaged issues, assigns @copilot to `squad:copilot` issues. + +**CLI equivalent:** **Already shipped as `squad watch`** (`packages/squad-cli/src/cli/commands/watch.ts`, 356 lines). + +**What `squad watch` does:** +- Polls open issues with `squad` label +- Triages untriaged issues (adds `squad:{member}` label) +- Monitors PRs (draft/needs-review/changes-requested/CI failures/ready-to-merge) +- Runs on interval (default: 30 minutes) +- Uses `gh` CLI for auth + API access +- Uses shared `@bradygaster/squad-sdk/ralph/triage` logic + +**What `squad watch` does NOT do (that heartbeat.yml does):** +- ❌ Post triage comments (workflow posts "Ralph — Auto-Triage" comments) +- ❌ Auto-assign copilot-swe-agent[bot] (requires PAT + bot API, same issue as #2.3) + +**Implementation gap:** +- **Comment posting:** M (4-6 hours) — add `gh issue comment` wrapper to `gh-cli.ts`, call it from `runCheck()` in watch.ts +- **Copilot auto-assign:** Do not migrate (same as #2.3) + +**Migration plan:** +- ✅ **Already done.** `squad watch` is the local heartbeat. +- **Add comment posting** to match workflow behavior (quick win, 4-6 hours). +- **Document copilot auto-assign** as workflow-only (requires PAT). + +**Recommendation:** Enhance `squad watch` with comment posting. Keep copilot auto-assign in workflow. + + +--- + +### 2.5. squad-label-enforce.yml → `squad labels enforce` + +**Current workflow:** 180 lines. On label applied, removes conflicting labels from mutual-exclusivity namespaces (`go:`, `release:`, `type:`, `priority:`). Posts update comment. + +**Proposed CLI command:** +```bash +squad labels enforce [--issue ] [--squad-dir .squad] +``` + +**Implementation:** +- **Size:** S (2-4 hours) +- **Dependencies:** + - ✅ `gh` CLI (already used) + - ❌ `gh issue edit --remove-label