@bradygaster/squad-sdk 0.9.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/README.md +296 -296
  2. package/dist/agents/history-shadow.js +30 -30
  3. package/dist/build/github-dist.js +42 -42
  4. package/dist/config/init.js +173 -173
  5. package/dist/sharing/consult.js +78 -78
  6. package/package.json +1 -1
  7. package/templates/casting/Futurama.json +9 -9
  8. package/templates/casting-history.json +4 -4
  9. package/templates/casting-policy.json +37 -37
  10. package/templates/casting-reference.md +104 -104
  11. package/templates/casting-registry.json +3 -3
  12. package/templates/ceremonies.md +41 -41
  13. package/templates/charter.md +53 -53
  14. package/templates/constraint-tracking.md +38 -38
  15. package/templates/cooperative-rate-limiting.md +229 -229
  16. package/templates/copilot-instructions.md +46 -46
  17. package/templates/history.md +10 -10
  18. package/templates/identity/now.md +9 -9
  19. package/templates/identity/wisdom.md +15 -15
  20. package/templates/issue-lifecycle.md +412 -412
  21. package/templates/keda-scaler.md +164 -164
  22. package/templates/machine-capabilities.md +74 -74
  23. package/templates/mcp-config.md +90 -90
  24. package/templates/multi-agent-format.md +28 -28
  25. package/templates/plugin-marketplace.md +49 -49
  26. package/templates/ralph-circuit-breaker.md +313 -313
  27. package/templates/raw-agent-output.md +37 -37
  28. package/templates/roster.md +60 -60
  29. package/templates/routing.md +39 -39
  30. package/templates/run-output.md +50 -50
  31. package/templates/schedule.json +19 -19
  32. package/templates/scribe-charter.md +119 -119
  33. package/templates/skill.md +24 -24
  34. package/templates/skills/agent-collaboration/SKILL.md +42 -42
  35. package/templates/skills/agent-conduct/SKILL.md +24 -24
  36. package/templates/skills/architectural-proposals/SKILL.md +151 -151
  37. package/templates/skills/ci-validation-gates/SKILL.md +84 -84
  38. package/templates/skills/cli-wiring/SKILL.md +47 -47
  39. package/templates/skills/client-compatibility/SKILL.md +89 -89
  40. package/templates/skills/cross-squad/SKILL.md +114 -114
  41. package/templates/skills/distributed-mesh/SKILL.md +287 -287
  42. package/templates/skills/distributed-mesh/mesh.json.example +30 -30
  43. package/templates/skills/distributed-mesh/sync-mesh.ps1 +111 -111
  44. package/templates/skills/distributed-mesh/sync-mesh.sh +104 -104
  45. package/templates/skills/docs-standards/SKILL.md +71 -71
  46. package/templates/skills/economy-mode/SKILL.md +114 -114
  47. package/templates/skills/external-comms/SKILL.md +329 -329
  48. package/templates/skills/gh-auth-isolation/SKILL.md +183 -183
  49. package/templates/skills/git-workflow/SKILL.md +204 -204
  50. package/templates/skills/github-multi-account/SKILL.md +95 -95
  51. package/templates/skills/history-hygiene/SKILL.md +36 -36
  52. package/templates/skills/humanizer/SKILL.md +105 -105
  53. package/templates/skills/init-mode/SKILL.md +102 -102
  54. package/templates/skills/model-selection/SKILL.md +117 -117
  55. package/templates/skills/nap/SKILL.md +24 -24
  56. package/templates/skills/personal-squad/SKILL.md +57 -57
  57. package/templates/skills/project-conventions/SKILL.md +56 -56
  58. package/templates/skills/release-process/SKILL.md +423 -423
  59. package/templates/skills/reskill/SKILL.md +92 -92
  60. package/templates/skills/reviewer-protocol/SKILL.md +79 -79
  61. package/templates/skills/secret-handling/SKILL.md +200 -200
  62. package/templates/skills/session-recovery/SKILL.md +155 -155
  63. package/templates/skills/squad-conventions/SKILL.md +69 -69
  64. package/templates/skills/test-discipline/SKILL.md +37 -37
  65. package/templates/skills/windows-compatibility/SKILL.md +74 -74
  66. package/templates/workflows/squad-ci.yml +24 -24
  67. package/templates/workflows/squad-docs.yml +54 -54
  68. package/templates/workflows/squad-heartbeat.yml +171 -171
  69. package/templates/workflows/squad-insider-release.yml +61 -61
  70. package/templates/workflows/squad-issue-assign.yml +161 -161
  71. package/templates/workflows/squad-label-enforce.yml +181 -181
  72. package/templates/workflows/squad-preview.yml +55 -55
  73. package/templates/workflows/squad-promote.yml +120 -120
  74. package/templates/workflows/squad-release.yml +77 -77
  75. package/templates/workflows/squad-triage.yml +260 -260
  76. package/templates/workflows/sync-squad-labels.yml +169 -169
@@ -1,155 +1,155 @@
1
- ---
2
- name: "session-recovery"
3
- description: "Find and resume interrupted Copilot CLI sessions using session_store queries"
4
- domain: "workflow-recovery"
5
- confidence: "high"
6
- source: "earned"
7
- tools:
8
- - name: "sql"
9
- description: "Query session_store database for past session history"
10
- when: "Always — session_store is the source of truth for session history"
11
- ---
12
-
13
- ## Context
14
-
15
- Squad agents run in Copilot CLI sessions that can be interrupted — terminal crashes, network drops, machine restarts, or accidental window closes. When this happens, in-progress work may be left in a partially-completed state: branches with uncommitted changes, issues marked in-progress with no active agent, or checkpoints that were never finalized.
16
-
17
- Copilot CLI stores session history in a SQLite database called `session_store` (read-only, accessed via the `sql` tool with `database: "session_store"`). This skill teaches agents how to query that store to detect interrupted sessions and resume work.
18
-
19
- ## Patterns
20
-
21
- ### 1. Find Recent Sessions
22
-
23
- Query the `sessions` table filtered by time window. Include the last checkpoint to understand where the session stopped:
24
-
25
- ```sql
26
- SELECT
27
- s.id,
28
- s.summary,
29
- s.cwd,
30
- s.branch,
31
- s.updated_at,
32
- (SELECT title FROM checkpoints
33
- WHERE session_id = s.id
34
- ORDER BY checkpoint_number DESC LIMIT 1) AS last_checkpoint
35
- FROM sessions s
36
- WHERE s.updated_at >= datetime('now', '-24 hours')
37
- ORDER BY s.updated_at DESC;
38
- ```
39
-
40
- ### 2. Filter Out Automated Sessions
41
-
42
- Automated agents (monitors, keep-alive, heartbeat) create high-volume sessions that obscure human-initiated work. Exclude them:
43
-
44
- ```sql
45
- SELECT s.id, s.summary, s.cwd, s.updated_at,
46
- (SELECT title FROM checkpoints
47
- WHERE session_id = s.id
48
- ORDER BY checkpoint_number DESC LIMIT 1) AS last_checkpoint
49
- FROM sessions s
50
- WHERE s.updated_at >= datetime('now', '-24 hours')
51
- AND s.id NOT IN (
52
- SELECT DISTINCT t.session_id FROM turns t
53
- WHERE t.turn_index = 0
54
- AND (LOWER(t.user_message) LIKE '%keep-alive%'
55
- OR LOWER(t.user_message) LIKE '%heartbeat%')
56
- )
57
- ORDER BY s.updated_at DESC;
58
- ```
59
-
60
- ### 3. Search by Topic (FTS5)
61
-
62
- Use the `search_index` FTS5 table for keyword search. Expand queries with synonyms since this is keyword-based, not semantic:
63
-
64
- ```sql
65
- SELECT DISTINCT s.id, s.summary, s.cwd, s.updated_at
66
- FROM search_index si
67
- JOIN sessions s ON si.session_id = s.id
68
- WHERE search_index MATCH 'auth OR login OR token OR JWT'
69
- AND s.updated_at >= datetime('now', '-48 hours')
70
- ORDER BY s.updated_at DESC
71
- LIMIT 10;
72
- ```
73
-
74
- ### 4. Search by Working Directory
75
-
76
- ```sql
77
- SELECT s.id, s.summary, s.updated_at,
78
- (SELECT title FROM checkpoints
79
- WHERE session_id = s.id
80
- ORDER BY checkpoint_number DESC LIMIT 1) AS last_checkpoint
81
- FROM sessions s
82
- WHERE s.cwd LIKE '%my-project%'
83
- AND s.updated_at >= datetime('now', '-48 hours')
84
- ORDER BY s.updated_at DESC;
85
- ```
86
-
87
- ### 5. Get Full Session Context Before Resuming
88
-
89
- Before resuming, inspect what the session was doing:
90
-
91
- ```sql
92
- -- Conversation turns
93
- SELECT turn_index, substr(user_message, 1, 200) AS ask, timestamp
94
- FROM turns WHERE session_id = 'SESSION_ID' ORDER BY turn_index;
95
-
96
- -- Checkpoint progress
97
- SELECT checkpoint_number, title, overview
98
- FROM checkpoints WHERE session_id = 'SESSION_ID' ORDER BY checkpoint_number;
99
-
100
- -- Files touched
101
- SELECT file_path, tool_name
102
- FROM session_files WHERE session_id = 'SESSION_ID';
103
-
104
- -- Linked PRs/issues/commits
105
- SELECT ref_type, ref_value
106
- FROM session_refs WHERE session_id = 'SESSION_ID';
107
- ```
108
-
109
- ### 6. Detect Orphaned Issue Work
110
-
111
- Find sessions that were working on issues but may not have completed:
112
-
113
- ```sql
114
- SELECT DISTINCT s.id, s.branch, s.summary, s.updated_at,
115
- sr.ref_type, sr.ref_value
116
- FROM sessions s
117
- JOIN session_refs sr ON s.id = sr.session_id
118
- WHERE sr.ref_type = 'issue'
119
- AND s.updated_at >= datetime('now', '-48 hours')
120
- ORDER BY s.updated_at DESC;
121
- ```
122
-
123
- Cross-reference with `gh issue list --label "status:in-progress"` to find issues that are marked in-progress but have no active session.
124
-
125
- ### 7. Resume a Session
126
-
127
- Once you have the session ID:
128
-
129
- ```bash
130
- # Resume directly
131
- copilot --resume SESSION_ID
132
- ```
133
-
134
- ## Examples
135
-
136
- **Recovering from a crash during PR creation:**
137
- 1. Query recent sessions filtered by branch name
138
- 2. Find the session that was working on the PR
139
- 3. Check its last checkpoint — was the code committed? Was the PR created?
140
- 4. Resume or manually complete the remaining steps
141
-
142
- **Finding yesterday's work on a feature:**
143
- 1. Use FTS5 search with feature keywords
144
- 2. Filter to the relevant working directory
145
- 3. Review checkpoint progress to see how far the session got
146
- 4. Resume if work remains, or start fresh with the context
147
-
148
- ## Anti-Patterns
149
-
150
- - ❌ Searching by partial session IDs — always use full UUIDs
151
- - ❌ Resuming sessions that completed successfully — they have no pending work
152
- - ❌ Using `MATCH` with special characters without escaping — wrap paths in double quotes
153
- - ❌ Skipping the automated-session filter — high-volume automated sessions will flood results
154
- - ❌ Assuming FTS5 is semantic search — it's keyword-based; always expand queries with synonyms
155
- - ❌ Ignoring checkpoint data — checkpoints show exactly where the session stopped
1
+ ---
2
+ name: "session-recovery"
3
+ description: "Find and resume interrupted Copilot CLI sessions using session_store queries"
4
+ domain: "workflow-recovery"
5
+ confidence: "high"
6
+ source: "earned"
7
+ tools:
8
+ - name: "sql"
9
+ description: "Query session_store database for past session history"
10
+ when: "Always — session_store is the source of truth for session history"
11
+ ---
12
+
13
+ ## Context
14
+
15
+ Squad agents run in Copilot CLI sessions that can be interrupted — terminal crashes, network drops, machine restarts, or accidental window closes. When this happens, in-progress work may be left in a partially-completed state: branches with uncommitted changes, issues marked in-progress with no active agent, or checkpoints that were never finalized.
16
+
17
+ Copilot CLI stores session history in a SQLite database called `session_store` (read-only, accessed via the `sql` tool with `database: "session_store"`). This skill teaches agents how to query that store to detect interrupted sessions and resume work.
18
+
19
+ ## Patterns
20
+
21
+ ### 1. Find Recent Sessions
22
+
23
+ Query the `sessions` table filtered by time window. Include the last checkpoint to understand where the session stopped:
24
+
25
+ ```sql
26
+ SELECT
27
+ s.id,
28
+ s.summary,
29
+ s.cwd,
30
+ s.branch,
31
+ s.updated_at,
32
+ (SELECT title FROM checkpoints
33
+ WHERE session_id = s.id
34
+ ORDER BY checkpoint_number DESC LIMIT 1) AS last_checkpoint
35
+ FROM sessions s
36
+ WHERE s.updated_at >= datetime('now', '-24 hours')
37
+ ORDER BY s.updated_at DESC;
38
+ ```
39
+
40
+ ### 2. Filter Out Automated Sessions
41
+
42
+ Automated agents (monitors, keep-alive, heartbeat) create high-volume sessions that obscure human-initiated work. Exclude them:
43
+
44
+ ```sql
45
+ SELECT s.id, s.summary, s.cwd, s.updated_at,
46
+ (SELECT title FROM checkpoints
47
+ WHERE session_id = s.id
48
+ ORDER BY checkpoint_number DESC LIMIT 1) AS last_checkpoint
49
+ FROM sessions s
50
+ WHERE s.updated_at >= datetime('now', '-24 hours')
51
+ AND s.id NOT IN (
52
+ SELECT DISTINCT t.session_id FROM turns t
53
+ WHERE t.turn_index = 0
54
+ AND (LOWER(t.user_message) LIKE '%keep-alive%'
55
+ OR LOWER(t.user_message) LIKE '%heartbeat%')
56
+ )
57
+ ORDER BY s.updated_at DESC;
58
+ ```
59
+
60
+ ### 3. Search by Topic (FTS5)
61
+
62
+ Use the `search_index` FTS5 table for keyword search. Expand queries with synonyms since this is keyword-based, not semantic:
63
+
64
+ ```sql
65
+ SELECT DISTINCT s.id, s.summary, s.cwd, s.updated_at
66
+ FROM search_index si
67
+ JOIN sessions s ON si.session_id = s.id
68
+ WHERE search_index MATCH 'auth OR login OR token OR JWT'
69
+ AND s.updated_at >= datetime('now', '-48 hours')
70
+ ORDER BY s.updated_at DESC
71
+ LIMIT 10;
72
+ ```
73
+
74
+ ### 4. Search by Working Directory
75
+
76
+ ```sql
77
+ SELECT s.id, s.summary, s.updated_at,
78
+ (SELECT title FROM checkpoints
79
+ WHERE session_id = s.id
80
+ ORDER BY checkpoint_number DESC LIMIT 1) AS last_checkpoint
81
+ FROM sessions s
82
+ WHERE s.cwd LIKE '%my-project%'
83
+ AND s.updated_at >= datetime('now', '-48 hours')
84
+ ORDER BY s.updated_at DESC;
85
+ ```
86
+
87
+ ### 5. Get Full Session Context Before Resuming
88
+
89
+ Before resuming, inspect what the session was doing:
90
+
91
+ ```sql
92
+ -- Conversation turns
93
+ SELECT turn_index, substr(user_message, 1, 200) AS ask, timestamp
94
+ FROM turns WHERE session_id = 'SESSION_ID' ORDER BY turn_index;
95
+
96
+ -- Checkpoint progress
97
+ SELECT checkpoint_number, title, overview
98
+ FROM checkpoints WHERE session_id = 'SESSION_ID' ORDER BY checkpoint_number;
99
+
100
+ -- Files touched
101
+ SELECT file_path, tool_name
102
+ FROM session_files WHERE session_id = 'SESSION_ID';
103
+
104
+ -- Linked PRs/issues/commits
105
+ SELECT ref_type, ref_value
106
+ FROM session_refs WHERE session_id = 'SESSION_ID';
107
+ ```
108
+
109
+ ### 6. Detect Orphaned Issue Work
110
+
111
+ Find sessions that were working on issues but may not have completed:
112
+
113
+ ```sql
114
+ SELECT DISTINCT s.id, s.branch, s.summary, s.updated_at,
115
+ sr.ref_type, sr.ref_value
116
+ FROM sessions s
117
+ JOIN session_refs sr ON s.id = sr.session_id
118
+ WHERE sr.ref_type = 'issue'
119
+ AND s.updated_at >= datetime('now', '-48 hours')
120
+ ORDER BY s.updated_at DESC;
121
+ ```
122
+
123
+ Cross-reference with `gh issue list --label "status:in-progress"` to find issues that are marked in-progress but have no active session.
124
+
125
+ ### 7. Resume a Session
126
+
127
+ Once you have the session ID:
128
+
129
+ ```bash
130
+ # Resume directly
131
+ copilot --resume SESSION_ID
132
+ ```
133
+
134
+ ## Examples
135
+
136
+ **Recovering from a crash during PR creation:**
137
+ 1. Query recent sessions filtered by branch name
138
+ 2. Find the session that was working on the PR
139
+ 3. Check its last checkpoint — was the code committed? Was the PR created?
140
+ 4. Resume or manually complete the remaining steps
141
+
142
+ **Finding yesterday's work on a feature:**
143
+ 1. Use FTS5 search with feature keywords
144
+ 2. Filter to the relevant working directory
145
+ 3. Review checkpoint progress to see how far the session got
146
+ 4. Resume if work remains, or start fresh with the context
147
+
148
+ ## Anti-Patterns
149
+
150
+ - ❌ Searching by partial session IDs — always use full UUIDs
151
+ - ❌ Resuming sessions that completed successfully — they have no pending work
152
+ - ❌ Using `MATCH` with special characters without escaping — wrap paths in double quotes
153
+ - ❌ Skipping the automated-session filter — high-volume automated sessions will flood results
154
+ - ❌ Assuming FTS5 is semantic search — it's keyword-based; always expand queries with synonyms
155
+ - ❌ Ignoring checkpoint data — checkpoints show exactly where the session stopped
@@ -1,69 +1,69 @@
1
- ---
2
- name: "squad-conventions"
3
- description: "Core conventions and patterns used in the Squad codebase"
4
- domain: "project-conventions"
5
- confidence: "high"
6
- source: "manual"
7
- ---
8
-
9
- ## Context
10
- These conventions apply to all work on the Squad CLI tool (`create-squad`). Squad is a zero-dependency Node.js package that adds AI agent teams to any project. Understanding these patterns is essential before modifying any Squad source code.
11
-
12
- ## Patterns
13
-
14
- ### Zero Dependencies
15
- Squad has zero runtime dependencies. Everything uses Node.js built-ins (`fs`, `path`, `os`, `child_process`). Do not add packages to `dependencies` in `package.json`. This is a hard constraint, not a preference.
16
-
17
- ### Node.js Built-in Test Runner
18
- Tests use `node:test` and `node:assert/strict` — no test frameworks. Run with `npm test`. Test files live in `test/`. The test command is `node --test test/`.
19
-
20
- ### Error Handling — `fatal()` Pattern
21
- All user-facing errors use the `fatal(msg)` function which prints a red `✗` prefix and exits with code 1. Never throw unhandled exceptions or print raw stack traces. The global `uncaughtException` handler calls `fatal()` as a safety net.
22
-
23
- ### ANSI Color Constants
24
- Colors are defined as constants at the top of `index.js`: `GREEN`, `RED`, `DIM`, `BOLD`, `RESET`. Use these constants — do not inline ANSI escape codes.
25
-
26
- ### File Structure
27
- - `.squad/` — Team state (user-owned, never overwritten by upgrades)
28
- - `.squad/templates/` — Template files copied from `templates/` (Squad-owned, overwritten on upgrade)
29
- - `.github/agents/squad.agent.md` — Coordinator prompt (Squad-owned, overwritten on upgrade)
30
- - `templates/` — Source templates shipped with the npm package
31
- - `.squad/skills/` — Team skills in SKILL.md format (user-owned)
32
- - `.squad/decisions/inbox/` — Drop-box for parallel decision writes
33
-
34
- ### Windows Compatibility
35
- Always use `path.join()` for file paths — never hardcode `/` or `\` separators. Squad must work on Windows, macOS, and Linux. All tests must pass on all platforms.
36
-
37
- ### Init Idempotency
38
- The init flow uses a skip-if-exists pattern: if a file or directory already exists, skip it and report "already exists." Never overwrite user state during init. The upgrade flow overwrites only Squad-owned files.
39
-
40
- ### Copy Pattern
41
- `copyRecursive(src, target)` handles both files and directories. It creates parent directories with `{ recursive: true }` and uses `fs.copyFileSync` for files.
42
-
43
- ## Examples
44
-
45
- ```javascript
46
- // Error handling
47
- function fatal(msg) {
48
- console.error(`${RED}✗${RESET} ${msg}`);
49
- process.exit(1);
50
- }
51
-
52
- // File path construction (Windows-safe)
53
- const agentDest = path.join(dest, '.github', 'agents', 'squad.agent.md');
54
-
55
- // Skip-if-exists pattern
56
- if (!fs.existsSync(ceremoniesDest)) {
57
- fs.copyFileSync(ceremoniesSrc, ceremoniesDest);
58
- console.log(`${GREEN}✓${RESET} .squad/ceremonies.md`);
59
- } else {
60
- console.log(`${DIM}ceremonies.md already exists — skipping${RESET}`);
61
- }
62
- ```
63
-
64
- ## Anti-Patterns
65
- - **Adding npm dependencies** — Squad is zero-dep. Use Node.js built-ins only.
66
- - **Hardcoded path separators** — Never use `/` or `\` directly. Always `path.join()`.
67
- - **Overwriting user state on init** — Init skips existing files. Only upgrade overwrites Squad-owned files.
68
- - **Raw stack traces** — All errors go through `fatal()`. Users see clean messages, not stack traces.
69
- - **Inline ANSI codes** — Use the color constants (`GREEN`, `RED`, `DIM`, `BOLD`, `RESET`).
1
+ ---
2
+ name: "squad-conventions"
3
+ description: "Core conventions and patterns used in the Squad codebase"
4
+ domain: "project-conventions"
5
+ confidence: "high"
6
+ source: "manual"
7
+ ---
8
+
9
+ ## Context
10
+ These conventions apply to all work on the Squad CLI tool (`create-squad`). Squad is a zero-dependency Node.js package that adds AI agent teams to any project. Understanding these patterns is essential before modifying any Squad source code.
11
+
12
+ ## Patterns
13
+
14
+ ### Zero Dependencies
15
+ Squad has zero runtime dependencies. Everything uses Node.js built-ins (`fs`, `path`, `os`, `child_process`). Do not add packages to `dependencies` in `package.json`. This is a hard constraint, not a preference.
16
+
17
+ ### Node.js Built-in Test Runner
18
+ Tests use `node:test` and `node:assert/strict` — no test frameworks. Run with `npm test`. Test files live in `test/`. The test command is `node --test test/`.
19
+
20
+ ### Error Handling — `fatal()` Pattern
21
+ All user-facing errors use the `fatal(msg)` function which prints a red `✗` prefix and exits with code 1. Never throw unhandled exceptions or print raw stack traces. The global `uncaughtException` handler calls `fatal()` as a safety net.
22
+
23
+ ### ANSI Color Constants
24
+ Colors are defined as constants at the top of `index.js`: `GREEN`, `RED`, `DIM`, `BOLD`, `RESET`. Use these constants — do not inline ANSI escape codes.
25
+
26
+ ### File Structure
27
+ - `.squad/` — Team state (user-owned, never overwritten by upgrades)
28
+ - `.squad/templates/` — Template files copied from `templates/` (Squad-owned, overwritten on upgrade)
29
+ - `.github/agents/squad.agent.md` — Coordinator prompt (Squad-owned, overwritten on upgrade)
30
+ - `templates/` — Source templates shipped with the npm package
31
+ - `.squad/skills/` — Team skills in SKILL.md format (user-owned)
32
+ - `.squad/decisions/inbox/` — Drop-box for parallel decision writes
33
+
34
+ ### Windows Compatibility
35
+ Always use `path.join()` for file paths — never hardcode `/` or `\` separators. Squad must work on Windows, macOS, and Linux. All tests must pass on all platforms.
36
+
37
+ ### Init Idempotency
38
+ The init flow uses a skip-if-exists pattern: if a file or directory already exists, skip it and report "already exists." Never overwrite user state during init. The upgrade flow overwrites only Squad-owned files.
39
+
40
+ ### Copy Pattern
41
+ `copyRecursive(src, target)` handles both files and directories. It creates parent directories with `{ recursive: true }` and uses `fs.copyFileSync` for files.
42
+
43
+ ## Examples
44
+
45
+ ```javascript
46
+ // Error handling
47
+ function fatal(msg) {
48
+ console.error(`${RED}✗${RESET} ${msg}`);
49
+ process.exit(1);
50
+ }
51
+
52
+ // File path construction (Windows-safe)
53
+ const agentDest = path.join(dest, '.github', 'agents', 'squad.agent.md');
54
+
55
+ // Skip-if-exists pattern
56
+ if (!fs.existsSync(ceremoniesDest)) {
57
+ fs.copyFileSync(ceremoniesSrc, ceremoniesDest);
58
+ console.log(`${GREEN}✓${RESET} .squad/ceremonies.md`);
59
+ } else {
60
+ console.log(`${DIM}ceremonies.md already exists — skipping${RESET}`);
61
+ }
62
+ ```
63
+
64
+ ## Anti-Patterns
65
+ - **Adding npm dependencies** — Squad is zero-dep. Use Node.js built-ins only.
66
+ - **Hardcoded path separators** — Never use `/` or `\` directly. Always `path.join()`.
67
+ - **Overwriting user state on init** — Init skips existing files. Only upgrade overwrites Squad-owned files.
68
+ - **Raw stack traces** — All errors go through `fatal()`. Users see clean messages, not stack traces.
69
+ - **Inline ANSI codes** — Use the color constants (`GREEN`, `RED`, `DIM`, `BOLD`, `RESET`).
@@ -1,37 +1,37 @@
1
- ---
2
- name: "test-discipline"
3
- description: "Update tests when changing APIs — no exceptions"
4
- domain: "quality"
5
- confidence: "high"
6
- source: "earned (Fenster/Hockney incident, test assertion sync violations)"
7
- ---
8
-
9
- ## Context
10
-
11
- When APIs or public interfaces change, tests must be updated in the same commit. When test assertions reference file counts or expected arrays, they must be kept in sync with disk reality. Stale tests block CI for other contributors.
12
-
13
- ## Patterns
14
-
15
- - **API changes → test updates (same commit):** If you change a function signature, public interface, or exported API, update the corresponding tests before committing
16
- - **Test assertions → disk reality:** When test files contain expected counts (e.g., `EXPECTED_FEATURES`, `EXPECTED_SCENARIOS`), they must match the actual files on disk
17
- - **Add files → update assertions:** When adding docs pages, features, or any counted resource, update the test assertion array in the same commit
18
- - **CI failures → check assertions first:** Before debugging complex failures, verify test assertion arrays match filesystem state
19
-
20
- ## Examples
21
-
22
- ✓ **Correct:**
23
- - Changed auth API signature → updated auth.test.ts in same commit
24
- - Added `distributed-mesh.md` to features/ → added `'distributed-mesh'` to EXPECTED_FEATURES array
25
- - Deleted two scenario files → removed entries from EXPECTED_SCENARIOS
26
-
27
- ✗ **Incorrect:**
28
- - Changed spawn parameters → committed without updating casting.test.ts (CI breaks for next person)
29
- - Added `built-in-roles.md` → left EXPECTED_FEATURES at old count (PR blocked)
30
- - Test says "expected 7 files" but disk has 25 (assertion staleness)
31
-
32
- ## Anti-Patterns
33
-
34
- - Committing API changes without test updates ("I'll fix tests later")
35
- - Treating test assertion arrays as static (they evolve with content)
36
- - Assuming CI passing means coverage is correct (stale assertions can pass while being wrong)
37
- - Leaving gaps for other agents to discover
1
+ ---
2
+ name: "test-discipline"
3
+ description: "Update tests when changing APIs — no exceptions"
4
+ domain: "quality"
5
+ confidence: "high"
6
+ source: "earned (Fenster/Hockney incident, test assertion sync violations)"
7
+ ---
8
+
9
+ ## Context
10
+
11
+ When APIs or public interfaces change, tests must be updated in the same commit. When test assertions reference file counts or expected arrays, they must be kept in sync with disk reality. Stale tests block CI for other contributors.
12
+
13
+ ## Patterns
14
+
15
+ - **API changes → test updates (same commit):** If you change a function signature, public interface, or exported API, update the corresponding tests before committing
16
+ - **Test assertions → disk reality:** When test files contain expected counts (e.g., `EXPECTED_FEATURES`, `EXPECTED_SCENARIOS`), they must match the actual files on disk
17
+ - **Add files → update assertions:** When adding docs pages, features, or any counted resource, update the test assertion array in the same commit
18
+ - **CI failures → check assertions first:** Before debugging complex failures, verify test assertion arrays match filesystem state
19
+
20
+ ## Examples
21
+
22
+ ✓ **Correct:**
23
+ - Changed auth API signature → updated auth.test.ts in same commit
24
+ - Added `distributed-mesh.md` to features/ → added `'distributed-mesh'` to EXPECTED_FEATURES array
25
+ - Deleted two scenario files → removed entries from EXPECTED_SCENARIOS
26
+
27
+ ✗ **Incorrect:**
28
+ - Changed spawn parameters → committed without updating casting.test.ts (CI breaks for next person)
29
+ - Added `built-in-roles.md` → left EXPECTED_FEATURES at old count (PR blocked)
30
+ - Test says "expected 7 files" but disk has 25 (assertion staleness)
31
+
32
+ ## Anti-Patterns
33
+
34
+ - Committing API changes without test updates ("I'll fix tests later")
35
+ - Treating test assertion arrays as static (they evolve with content)
36
+ - Assuming CI passing means coverage is correct (stale assertions can pass while being wrong)
37
+ - Leaving gaps for other agents to discover