@bradygaster/squad-sdk 0.8.25 → 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 (228) hide show
  1. package/README.md +296 -296
  2. package/dist/adapter/client.d.ts +17 -0
  3. package/dist/adapter/client.d.ts.map +1 -1
  4. package/dist/adapter/client.js +101 -1
  5. package/dist/adapter/client.js.map +1 -1
  6. package/dist/agents/history-shadow.d.ts.map +1 -1
  7. package/dist/agents/history-shadow.js +129 -62
  8. package/dist/agents/history-shadow.js.map +1 -1
  9. package/dist/agents/index.d.ts +1 -0
  10. package/dist/agents/index.d.ts.map +1 -1
  11. package/dist/agents/index.js +2 -0
  12. package/dist/agents/index.js.map +1 -1
  13. package/dist/agents/model-selector.d.ts +2 -0
  14. package/dist/agents/model-selector.d.ts.map +1 -1
  15. package/dist/agents/model-selector.js +41 -35
  16. package/dist/agents/model-selector.js.map +1 -1
  17. package/dist/agents/personal.d.ts +35 -0
  18. package/dist/agents/personal.d.ts.map +1 -0
  19. package/dist/agents/personal.js +67 -0
  20. package/dist/agents/personal.js.map +1 -0
  21. package/dist/build/github-dist.js +42 -42
  22. package/dist/builders/index.d.ts +3 -2
  23. package/dist/builders/index.d.ts.map +1 -1
  24. package/dist/builders/index.js +28 -0
  25. package/dist/builders/index.js.map +1 -1
  26. package/dist/builders/types.d.ts +13 -0
  27. package/dist/builders/types.d.ts.map +1 -1
  28. package/dist/config/init.d.ts +8 -0
  29. package/dist/config/init.d.ts.map +1 -1
  30. package/dist/config/init.js +304 -193
  31. package/dist/config/init.js.map +1 -1
  32. package/dist/config/models.d.ts +112 -0
  33. package/dist/config/models.d.ts.map +1 -1
  34. package/dist/config/models.js +329 -18
  35. package/dist/config/models.js.map +1 -1
  36. package/dist/coordinator/index.js +2 -2
  37. package/dist/coordinator/index.js.map +1 -1
  38. package/dist/index.d.ts +8 -3
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +7 -2
  41. package/dist/index.js.map +1 -1
  42. package/dist/platform/azure-devops.d.ts +42 -0
  43. package/dist/platform/azure-devops.d.ts.map +1 -1
  44. package/dist/platform/azure-devops.js +75 -0
  45. package/dist/platform/azure-devops.js.map +1 -1
  46. package/dist/platform/comms-file-log.d.ts.map +1 -1
  47. package/dist/platform/comms-file-log.js +2 -1
  48. package/dist/platform/comms-file-log.js.map +1 -1
  49. package/dist/platform/index.d.ts +2 -1
  50. package/dist/platform/index.d.ts.map +1 -1
  51. package/dist/platform/index.js +1 -0
  52. package/dist/platform/index.js.map +1 -1
  53. package/dist/ralph/capabilities.d.ts +67 -0
  54. package/dist/ralph/capabilities.d.ts.map +1 -0
  55. package/dist/ralph/capabilities.js +111 -0
  56. package/dist/ralph/capabilities.js.map +1 -0
  57. package/dist/ralph/index.d.ts +2 -0
  58. package/dist/ralph/index.d.ts.map +1 -1
  59. package/dist/ralph/index.js +6 -5
  60. package/dist/ralph/index.js.map +1 -1
  61. package/dist/ralph/rate-limiting.d.ts +99 -0
  62. package/dist/ralph/rate-limiting.d.ts.map +1 -0
  63. package/dist/ralph/rate-limiting.js +170 -0
  64. package/dist/ralph/rate-limiting.js.map +1 -0
  65. package/dist/resolution.d.ts +24 -2
  66. package/dist/resolution.d.ts.map +1 -1
  67. package/dist/resolution.js +106 -6
  68. package/dist/resolution.js.map +1 -1
  69. package/dist/roles/catalog-categories.d.ts +146 -0
  70. package/dist/roles/catalog-categories.d.ts.map +1 -0
  71. package/dist/roles/catalog-categories.js +374 -0
  72. package/dist/roles/catalog-categories.js.map +1 -0
  73. package/dist/roles/catalog-engineering.d.ts +212 -0
  74. package/dist/roles/catalog-engineering.d.ts.map +1 -0
  75. package/dist/roles/catalog-engineering.js +549 -0
  76. package/dist/roles/catalog-engineering.js.map +1 -0
  77. package/dist/roles/catalog.d.ts +24 -0
  78. package/dist/roles/catalog.d.ts.map +1 -0
  79. package/dist/roles/catalog.js +28 -0
  80. package/dist/roles/catalog.js.map +1 -0
  81. package/dist/roles/index.d.ts +69 -0
  82. package/dist/roles/index.d.ts.map +1 -0
  83. package/dist/roles/index.js +197 -0
  84. package/dist/roles/index.js.map +1 -0
  85. package/dist/roles/types.d.ts +87 -0
  86. package/dist/roles/types.d.ts.map +1 -0
  87. package/dist/roles/types.js +14 -0
  88. package/dist/roles/types.js.map +1 -0
  89. package/dist/runtime/benchmarks.js +5 -5
  90. package/dist/runtime/benchmarks.js.map +1 -1
  91. package/dist/runtime/constants.d.ts +2 -2
  92. package/dist/runtime/constants.d.ts.map +1 -1
  93. package/dist/runtime/constants.js +5 -3
  94. package/dist/runtime/constants.js.map +1 -1
  95. package/dist/runtime/cross-squad.d.ts +118 -0
  96. package/dist/runtime/cross-squad.d.ts.map +1 -0
  97. package/dist/runtime/cross-squad.js +234 -0
  98. package/dist/runtime/cross-squad.js.map +1 -0
  99. package/dist/runtime/otel-init.d.ts +24 -17
  100. package/dist/runtime/otel-init.d.ts.map +1 -1
  101. package/dist/runtime/otel-init.js +29 -20
  102. package/dist/runtime/otel-init.js.map +1 -1
  103. package/dist/runtime/otel-metrics.d.ts +5 -0
  104. package/dist/runtime/otel-metrics.d.ts.map +1 -1
  105. package/dist/runtime/otel-metrics.js +54 -0
  106. package/dist/runtime/otel-metrics.js.map +1 -1
  107. package/dist/runtime/rework.d.ts +71 -0
  108. package/dist/runtime/rework.d.ts.map +1 -0
  109. package/dist/runtime/rework.js +107 -0
  110. package/dist/runtime/rework.js.map +1 -0
  111. package/dist/runtime/scheduler.d.ts +128 -0
  112. package/dist/runtime/scheduler.d.ts.map +1 -0
  113. package/dist/runtime/scheduler.js +427 -0
  114. package/dist/runtime/scheduler.js.map +1 -0
  115. package/dist/runtime/squad-observer.d.ts.map +1 -1
  116. package/dist/runtime/squad-observer.js +4 -0
  117. package/dist/runtime/squad-observer.js.map +1 -1
  118. package/dist/runtime/streaming.d.ts +2 -0
  119. package/dist/runtime/streaming.d.ts.map +1 -1
  120. package/dist/runtime/streaming.js +6 -0
  121. package/dist/runtime/streaming.js.map +1 -1
  122. package/dist/runtime/telemetry.d.ts +2 -0
  123. package/dist/runtime/telemetry.d.ts.map +1 -1
  124. package/dist/runtime/telemetry.js +6 -0
  125. package/dist/runtime/telemetry.js.map +1 -1
  126. package/dist/sharing/consult.d.ts +2 -2
  127. package/dist/sharing/consult.js +83 -83
  128. package/dist/sharing/consult.js.map +1 -1
  129. package/dist/sharing/export.d.ts.map +1 -1
  130. package/dist/sharing/export.js +17 -4
  131. package/dist/sharing/export.js.map +1 -1
  132. package/dist/skills/handler-types.d.ts +271 -0
  133. package/dist/skills/handler-types.d.ts.map +1 -0
  134. package/dist/skills/handler-types.js +31 -0
  135. package/dist/skills/handler-types.js.map +1 -0
  136. package/dist/skills/index.d.ts +3 -0
  137. package/dist/skills/index.d.ts.map +1 -1
  138. package/dist/skills/index.js +3 -0
  139. package/dist/skills/index.js.map +1 -1
  140. package/dist/skills/skill-script-loader.d.ts +65 -0
  141. package/dist/skills/skill-script-loader.d.ts.map +1 -0
  142. package/dist/skills/skill-script-loader.js +227 -0
  143. package/dist/skills/skill-script-loader.js.map +1 -0
  144. package/dist/skills/skill-source.d.ts.map +1 -1
  145. package/dist/skills/skill-source.js +5 -1
  146. package/dist/skills/skill-source.js.map +1 -1
  147. package/dist/tools/index.d.ts +10 -1
  148. package/dist/tools/index.d.ts.map +1 -1
  149. package/dist/tools/index.js +49 -8
  150. package/dist/tools/index.js.map +1 -1
  151. package/dist/upstream/resolver.d.ts.map +1 -1
  152. package/dist/upstream/resolver.js +14 -5
  153. package/dist/upstream/resolver.js.map +1 -1
  154. package/package.json +34 -3
  155. package/templates/casting/Futurama.json +10 -0
  156. package/templates/casting-history.json +4 -4
  157. package/templates/casting-policy.json +37 -35
  158. package/templates/casting-reference.md +104 -0
  159. package/templates/casting-registry.json +3 -3
  160. package/templates/ceremonies.md +41 -41
  161. package/templates/charter.md +53 -53
  162. package/templates/constraint-tracking.md +38 -38
  163. package/templates/cooperative-rate-limiting.md +229 -0
  164. package/templates/copilot-instructions.md +46 -46
  165. package/templates/history.md +10 -10
  166. package/templates/identity/now.md +9 -9
  167. package/templates/identity/wisdom.md +15 -15
  168. package/templates/issue-lifecycle.md +412 -0
  169. package/templates/keda-scaler.md +164 -0
  170. package/templates/machine-capabilities.md +75 -0
  171. package/templates/mcp-config.md +90 -98
  172. package/templates/multi-agent-format.md +28 -28
  173. package/templates/orchestration-log.md +27 -27
  174. package/templates/package.json +3 -0
  175. package/templates/plugin-marketplace.md +49 -49
  176. package/templates/ralph-circuit-breaker.md +313 -0
  177. package/templates/ralph-triage.js +543 -0
  178. package/templates/raw-agent-output.md +37 -37
  179. package/templates/roster.md +60 -60
  180. package/templates/routing.md +39 -54
  181. package/templates/run-output.md +50 -50
  182. package/templates/schedule.json +19 -0
  183. package/templates/scribe-charter.md +119 -119
  184. package/templates/skill.md +24 -24
  185. package/templates/skills/agent-collaboration/SKILL.md +42 -0
  186. package/templates/skills/agent-conduct/SKILL.md +24 -0
  187. package/templates/skills/architectural-proposals/SKILL.md +151 -0
  188. package/templates/skills/ci-validation-gates/SKILL.md +84 -0
  189. package/templates/skills/cli-wiring/SKILL.md +47 -0
  190. package/templates/skills/client-compatibility/SKILL.md +89 -0
  191. package/templates/skills/cross-squad/SKILL.md +114 -0
  192. package/templates/skills/distributed-mesh/SKILL.md +287 -0
  193. package/templates/skills/distributed-mesh/mesh.json.example +30 -0
  194. package/templates/skills/distributed-mesh/sync-mesh.ps1 +111 -0
  195. package/templates/skills/distributed-mesh/sync-mesh.sh +104 -0
  196. package/templates/skills/docs-standards/SKILL.md +71 -0
  197. package/templates/skills/economy-mode/SKILL.md +114 -0
  198. package/templates/skills/external-comms/SKILL.md +329 -0
  199. package/templates/skills/gh-auth-isolation/SKILL.md +183 -0
  200. package/templates/skills/git-workflow/SKILL.md +204 -0
  201. package/templates/skills/github-multi-account/SKILL.md +95 -0
  202. package/templates/skills/history-hygiene/SKILL.md +36 -0
  203. package/templates/skills/humanizer/SKILL.md +105 -0
  204. package/templates/skills/init-mode/SKILL.md +102 -0
  205. package/templates/skills/model-selection/SKILL.md +117 -0
  206. package/templates/skills/nap/SKILL.md +24 -0
  207. package/templates/skills/personal-squad/SKILL.md +57 -0
  208. package/templates/skills/project-conventions/SKILL.md +56 -56
  209. package/templates/skills/release-process/SKILL.md +423 -0
  210. package/templates/skills/reskill/SKILL.md +92 -0
  211. package/templates/skills/reviewer-protocol/SKILL.md +79 -0
  212. package/templates/skills/secret-handling/SKILL.md +200 -0
  213. package/templates/skills/session-recovery/SKILL.md +155 -0
  214. package/templates/skills/squad-conventions/SKILL.md +69 -0
  215. package/templates/skills/test-discipline/SKILL.md +37 -0
  216. package/templates/skills/windows-compatibility/SKILL.md +74 -0
  217. package/templates/squad.agent.md +1287 -1146
  218. package/templates/workflows/squad-ci.yml +24 -24
  219. package/templates/workflows/squad-docs.yml +54 -50
  220. package/templates/workflows/squad-heartbeat.yml +171 -316
  221. package/templates/workflows/squad-insider-release.yml +61 -61
  222. package/templates/workflows/squad-issue-assign.yml +161 -161
  223. package/templates/workflows/squad-label-enforce.yml +181 -181
  224. package/templates/workflows/squad-preview.yml +55 -55
  225. package/templates/workflows/squad-promote.yml +120 -120
  226. package/templates/workflows/squad-release.yml +77 -77
  227. package/templates/workflows/squad-triage.yml +260 -260
  228. package/templates/workflows/sync-squad-labels.yml +169 -169
@@ -13,6 +13,7 @@ import { fileURLToPath } from 'url';
13
13
  import { existsSync, cpSync, statSync, mkdirSync, readFileSync, readdirSync } from 'fs';
14
14
  import { execFileSync } from 'node:child_process';
15
15
  import { MODELS } from '../runtime/constants.js';
16
+ import { getRoleById } from '../roles/index.js';
16
17
  // ============================================================================
17
18
  // Template Resolution
18
19
  // ============================================================================
@@ -94,82 +95,82 @@ function formatModelArray(chain) {
94
95
  */
95
96
  function generateTypeScriptConfig(options) {
96
97
  const { projectName, projectDescription, agents } = options;
97
- return `import type { SquadConfig } from '@bradygaster/squad';
98
-
99
- /**
100
- * Squad Configuration for ${projectName}
101
- * ${projectDescription ? `\n * ${projectDescription}` : ''}
102
- */
103
- const config: SquadConfig = {
104
- version: '1.0.0',
105
-
106
- models: {
107
- defaultModel: '${MODELS.DEFAULT}',
108
- defaultTier: 'standard',
109
- fallbackChains: {
110
- premium: ${formatModelArray(MODELS.FALLBACK_CHAINS.premium)},
111
- standard: ${formatModelArray(MODELS.FALLBACK_CHAINS.standard)},
112
- fast: ${formatModelArray(MODELS.FALLBACK_CHAINS.fast)}
113
- },
114
- preferSameProvider: true,
115
- respectTierCeiling: true,
116
- nuclearFallback: {
117
- enabled: false,
118
- model: '${MODELS.NUCLEAR_FALLBACK}',
119
- maxRetriesBeforeNuclear: ${MODELS.NUCLEAR_MAX_RETRIES}
120
- }
121
- },
122
-
123
- routing: {
124
- rules: [
125
- {
126
- workType: 'feature-dev',
127
- agents: ['@${agents[0]?.name || 'coordinator'}'],
128
- confidence: 'high'
129
- },
130
- {
131
- workType: 'bug-fix',
132
- agents: ['@${agents.find(a => a.role === 'developer')?.name || agents[0]?.name || 'coordinator'}'],
133
- confidence: 'high'
134
- },
135
- {
136
- workType: 'testing',
137
- agents: ['@${agents.find(a => a.role === 'tester')?.name || agents[0]?.name || 'coordinator'}'],
138
- confidence: 'high'
139
- },
140
- {
141
- workType: 'documentation',
142
- agents: ['@${agents.find(a => a.role === 'scribe')?.name || agents[0]?.name || 'coordinator'}'],
143
- confidence: 'high'
144
- }
145
- ],
146
- governance: {
147
- eagerByDefault: true,
148
- scribeAutoRuns: false,
149
- allowRecursiveSpawn: false
150
- }
151
- },
152
-
153
- casting: {
154
- allowlistUniverses: [
155
- 'The Usual Suspects',
156
- 'Breaking Bad',
157
- 'The Wire',
158
- 'Firefly'
159
- ],
160
- overflowStrategy: 'generic',
161
- universeCapacity: {}
162
- },
163
-
164
- platforms: {
165
- vscode: {
166
- disableModelSelection: false,
167
- scribeMode: 'sync'
168
- }
169
- }
170
- };
171
-
172
- export default config;
98
+ return `import type { SquadConfig } from '@bradygaster/squad';
99
+
100
+ /**
101
+ * Squad Configuration for ${projectName}
102
+ * ${projectDescription ? `\n * ${projectDescription}` : ''}
103
+ */
104
+ const config: SquadConfig = {
105
+ version: '1.0.0',
106
+
107
+ models: {
108
+ defaultModel: '${MODELS.DEFAULT}',
109
+ defaultTier: 'standard',
110
+ fallbackChains: {
111
+ premium: ${formatModelArray(MODELS.FALLBACK_CHAINS.premium)},
112
+ standard: ${formatModelArray(MODELS.FALLBACK_CHAINS.standard)},
113
+ fast: ${formatModelArray(MODELS.FALLBACK_CHAINS.fast)}
114
+ },
115
+ preferSameProvider: true,
116
+ respectTierCeiling: true,
117
+ nuclearFallback: {
118
+ enabled: false,
119
+ model: '${MODELS.NUCLEAR_FALLBACK}',
120
+ maxRetriesBeforeNuclear: ${MODELS.NUCLEAR_MAX_RETRIES}
121
+ }
122
+ },
123
+
124
+ routing: {
125
+ rules: [
126
+ {
127
+ workType: 'feature-dev',
128
+ agents: ['@${agents[0]?.name || 'coordinator'}'],
129
+ confidence: 'high'
130
+ },
131
+ {
132
+ workType: 'bug-fix',
133
+ agents: ['@${agents.find(a => a.role === 'developer')?.name || agents[0]?.name || 'coordinator'}'],
134
+ confidence: 'high'
135
+ },
136
+ {
137
+ workType: 'testing',
138
+ agents: ['@${agents.find(a => a.role === 'tester')?.name || agents[0]?.name || 'coordinator'}'],
139
+ confidence: 'high'
140
+ },
141
+ {
142
+ workType: 'documentation',
143
+ agents: ['@${agents.find(a => a.role === 'scribe')?.name || agents[0]?.name || 'coordinator'}'],
144
+ confidence: 'high'
145
+ }
146
+ ],
147
+ governance: {
148
+ eagerByDefault: true,
149
+ scribeAutoRuns: false,
150
+ allowRecursiveSpawn: false
151
+ }
152
+ },
153
+
154
+ casting: {
155
+ allowlistUniverses: [
156
+ 'The Usual Suspects',
157
+ 'Breaking Bad',
158
+ 'The Wire',
159
+ 'Firefly'
160
+ ],
161
+ overflowStrategy: 'generic',
162
+ universeCapacity: {}
163
+ },
164
+
165
+ platforms: {
166
+ vscode: {
167
+ disableModelSelection: false,
168
+ scribeMode: 'sync'
169
+ }
170
+ }
171
+ };
172
+
173
+ export default config;
173
174
  `;
174
175
  }
175
176
  /**
@@ -279,6 +280,83 @@ function generateSDKBuilderConfig(options) {
279
280
  code += `});\n`;
280
281
  return code;
281
282
  }
283
+ /** Default starter roles used when --sdk --roles is specified. */
284
+ const SDK_ROLES_STARTER_TEAM = ['lead', 'backend', 'frontend', 'tester'];
285
+ /**
286
+ * Generate SDK builder config using useRole() for base roles.
287
+ *
288
+ * Produces a squad.config.ts that imports useRole from the SDK and
289
+ * references built-in base role definitions instead of plain
290
+ * defineAgent() calls.
291
+ */
292
+ function generateSDKBuilderConfigWithRoles(options) {
293
+ const { projectName, projectDescription, agents } = options;
294
+ // Partition agents into base-role agents and non-role agents
295
+ const roleAgents = agents.filter(a => getRoleById(a.role));
296
+ const plainAgents = agents.filter(a => !getRoleById(a.role));
297
+ // If caller didn't provide any base-role agents, generate a
298
+ // starter team from the default set.
299
+ const effectiveRoleAgents = roleAgents.length > 0
300
+ ? roleAgents
301
+ : SDK_ROLES_STARTER_TEAM.map(id => {
302
+ const role = getRoleById(id);
303
+ return { name: id, role: id, displayName: role.title };
304
+ });
305
+ const needsDefineAgent = plainAgents.length > 0;
306
+ const needsUseRole = effectiveRoleAgents.length > 0;
307
+ // Build import list
308
+ const imports = ['defineSquad', 'defineTeam'];
309
+ if (needsDefineAgent)
310
+ imports.push('defineAgent');
311
+ if (needsUseRole)
312
+ imports.push('useRole');
313
+ let code = `import {\n${imports.map(i => ` ${i},`).join('\n')}\n} from '@bradygaster/squad-sdk';\n\n`;
314
+ code += `/**\n * Squad Configuration — ${projectName}\n`;
315
+ if (projectDescription) {
316
+ code += ` *\n * ${projectDescription}\n`;
317
+ }
318
+ code += ` *\n * Uses built-in base roles from the role catalog.\n`;
319
+ code += ` * Customize names and overrides for your project.\n`;
320
+ code += ` */\n\n`;
321
+ // Generate useRole() definitions
322
+ for (const agent of effectiveRoleAgents) {
323
+ const varName = agent.name.replace(/-/g, '_');
324
+ code += `const ${varName} = useRole('${agent.role}', {\n`;
325
+ code += ` name: '${agent.name}',\n`;
326
+ code += `});\n\n`;
327
+ }
328
+ // Generate plain defineAgent() definitions (for system agents like scribe/ralph)
329
+ for (const agent of plainAgents) {
330
+ const displayName = agent.displayName || titleCase(agent.name);
331
+ code += `const ${agent.name} = defineAgent({\n`;
332
+ code += ` name: '${agent.name}',\n`;
333
+ code += ` role: '${agent.role}',\n`;
334
+ code += ` description: '${displayName}',\n`;
335
+ code += ` status: 'active',\n`;
336
+ code += `});\n\n`;
337
+ }
338
+ // All agent variable names in order
339
+ const allVarNames = [
340
+ ...effectiveRoleAgents.map(a => a.name.replace(/-/g, '_')),
341
+ ...plainAgents.map(a => a.name),
342
+ ];
343
+ const allNames = [
344
+ ...effectiveRoleAgents.map(a => `'${a.name}'`),
345
+ ...plainAgents.map(a => `'${a.name}'`),
346
+ ];
347
+ code += `export default defineSquad({\n`;
348
+ code += ` version: '1.0.0',\n\n`;
349
+ code += ` team: defineTeam({\n`;
350
+ code += ` name: '${projectName}',\n`;
351
+ if (projectDescription) {
352
+ code += ` description: '${projectDescription.replace(/'/g, "\\'")}',\n`;
353
+ }
354
+ code += ` members: [${allNames.join(', ')}],\n`;
355
+ code += ` }),\n\n`;
356
+ code += ` agents: [${allVarNames.join(', ')}],\n`;
357
+ code += `});\n`;
358
+ return code;
359
+ }
282
360
  // ============================================================================
283
361
  // Agent Template Generation
284
362
  // ============================================================================
@@ -289,26 +367,26 @@ function generateCharter(agent, projectName, projectDescription) {
289
367
  const template = AGENT_TEMPLATES[agent.role];
290
368
  const displayName = agent.displayName || template?.displayName || titleCase(agent.name);
291
369
  const description = template?.description || 'Team member focused on their assigned responsibilities.';
292
- return `# ${displayName} — ${titleCase(agent.role)}
293
-
294
- ${description}
295
-
296
- ## Project Context
297
-
298
- **Project:** ${projectName}
299
- ${projectDescription ? `**Description:** ${projectDescription}\n` : ''}
300
-
301
- ## Responsibilities
302
-
303
- - Collaborate with team members on assigned work
304
- - Maintain code quality and project standards
305
- - Document decisions and progress in history
306
-
307
- ## Work Style
308
-
309
- - Read project context and team decisions before starting work
310
- - Communicate clearly with team members
311
- - Follow established patterns and conventions
370
+ return `# ${displayName} — ${titleCase(agent.role)}
371
+
372
+ ${description}
373
+
374
+ ## Project Context
375
+
376
+ **Project:** ${projectName}
377
+ ${projectDescription ? `**Description:** ${projectDescription}\n` : ''}
378
+
379
+ ## Responsibilities
380
+
381
+ - Collaborate with team members on assigned work
382
+ - Maintain code quality and project standards
383
+ - Document decisions and progress in history
384
+
385
+ ## Work Style
386
+
387
+ - Read project context and team decisions before starting work
388
+ - Communicate clearly with team members
389
+ - Follow established patterns and conventions
312
390
  `;
313
391
  }
314
392
  /**
@@ -317,22 +395,22 @@ ${projectDescription ? `**Description:** ${projectDescription}\n` : ''}
317
395
  function generateInitialHistory(agent, projectName, projectDescription, userName) {
318
396
  const displayName = agent.displayName || AGENT_TEMPLATES[agent.role]?.displayName || titleCase(agent.name);
319
397
  const now = new Date().toISOString().split('T')[0];
320
- return `# Project Context
321
-
322
- ${userName ? `- **Owner:** ${userName}\n` : ''}- **Project:** ${projectName}
323
- ${projectDescription ? `- **Description:** ${projectDescription}\n` : ''}- **Created:** ${now}
324
-
325
- ## Core Context
326
-
327
- Agent ${displayName} initialized and ready for work.
328
-
329
- ## Recent Updates
330
-
331
- 📌 Team initialized on ${now}
332
-
333
- ## Learnings
334
-
335
- Initial setup complete.
398
+ return `# Project Context
399
+
400
+ ${userName ? `- **Owner:** ${userName}\n` : ''}- **Project:** ${projectName}
401
+ ${projectDescription ? `- **Description:** ${projectDescription}\n` : ''}- **Created:** ${now}
402
+
403
+ ## Core Context
404
+
405
+ Agent ${displayName} initialized and ready for work.
406
+
407
+ ## Recent Updates
408
+
409
+ 📌 Team initialized on ${now}
410
+
411
+ ## Learnings
412
+
413
+ Initial setup complete.
336
414
  `;
337
415
  }
338
416
  /**
@@ -349,9 +427,16 @@ function titleCase(str) {
349
427
  // ============================================================================
350
428
  /**
351
429
  * Stamp version into squad.agent.md content.
430
+ * Replaces three locations: HTML comment, Identity Version line, and {version} placeholder.
352
431
  */
353
432
  function stampVersionInContent(content, version) {
354
- return content.replace(/<!-- version: [^>]* -->/, `<!-- version: ${version} -->`);
433
+ // HTML comment: <!-- version: X.Y.Z -->
434
+ content = content.replace(/<!-- version: [^>]* -->/, `<!-- version: ${version} -->`);
435
+ // Identity section: - **Version:** X.Y.Z
436
+ content = content.replace(/- \*\*Version:\*\* [0-9.]+(?:-[a-z]+(?:\.\d+)?)?/m, `- **Version:** ${version}`);
437
+ // Greeting placeholder: `Squad v{version}`
438
+ content = content.replace(/`Squad v\{version\}`/g, `\`Squad v${version}\``);
439
+ return content;
355
440
  }
356
441
  /**
357
442
  * Initialize a new Squad project.
@@ -442,7 +527,7 @@ export async function initSquad(options) {
442
527
  join(squadDir, 'casting'),
443
528
  join(squadDir, 'decisions'),
444
529
  join(squadDir, 'decisions', 'inbox'),
445
- join(squadDir, 'skills'),
530
+ join(teamRoot, '.copilot', 'skills'),
446
531
  join(squadDir, 'plugins'),
447
532
  join(squadDir, 'identity'),
448
533
  join(squadDir, 'orchestration-log'),
@@ -472,24 +557,49 @@ export async function initSquad(options) {
472
557
  }
473
558
  const squadConfig = {
474
559
  version: 1,
475
- teamRoot: teamRoot,
476
560
  };
477
561
  if (detectedPlatform) {
478
562
  squadConfig.platform = detectedPlatform;
479
563
  }
480
564
  if (detectedPlatform === 'azure-devops') {
481
- // ADO work item defaults — users can customize these:
482
- // - org/project: set when work items live in a different project than the repo
483
- // - defaultWorkItemType: "User Story", "Scenario", "Bug", etc.
484
- // - areaPath: e.g. "MyProject\\Team A" (backslash-separated)
485
- // - iterationPath: e.g. "MyProject\\Sprint 1"
486
- squadConfig.ado = {
487
- // org: "my-org", // uncomment if work items are in a different org
488
- // project: "my-project", // uncomment if work items are in a different project
489
- // defaultWorkItemType: "User Story",
490
- // areaPath: "",
491
- // iterationPath: "",
492
- };
565
+ // ADO work item defaults — attempt to introspect the process template
566
+ // to discover available work item types for the project.
567
+ let introspectedTypes;
568
+ try {
569
+ const remoteUrl = execFileSync('git', ['remote', 'get-url', 'origin'], { cwd: teamRoot, encoding: 'utf-8' }).trim();
570
+ // Parse org/project from remote URL for introspection
571
+ const httpsMatch = remoteUrl.match(/dev\.azure\.com\/([^/]+)\/([^/]+)\/_git/i);
572
+ const sshMatch = remoteUrl.match(/ssh\.dev\.azure\.com:v3\/([^/]+)\/([^/]+)\//i);
573
+ const vsMatch = remoteUrl.match(/([^/.]+)\.visualstudio\.com\/([^/]+)\/_git/i);
574
+ const parsed = httpsMatch ?? sshMatch ?? vsMatch;
575
+ if (parsed && parsed[1] && parsed[2]) {
576
+ const { getAvailableWorkItemTypes } = await import('../platform/azure-devops.js');
577
+ const types = getAvailableWorkItemTypes(parsed[1], parsed[2]);
578
+ const enabled = types.filter((t) => !t.disabled).map((t) => t.name);
579
+ if (enabled.length > 0) {
580
+ introspectedTypes = enabled;
581
+ }
582
+ }
583
+ }
584
+ catch {
585
+ // Introspection failed — skip and use commented-out defaults
586
+ }
587
+ // Build the ADO config section: explicit options > introspected > commented defaults
588
+ const adoSection = {};
589
+ if (options.adoConfig?.defaultWorkItemType) {
590
+ adoSection.defaultWorkItemType = options.adoConfig.defaultWorkItemType;
591
+ }
592
+ if (options.adoConfig?.areaPath) {
593
+ adoSection.areaPath = options.adoConfig.areaPath;
594
+ }
595
+ if (options.adoConfig?.iterationPath) {
596
+ adoSection.iterationPath = options.adoConfig.iterationPath;
597
+ }
598
+ squadConfig.ado = adoSection;
599
+ // If introspection found types, store them so the user knows what's available
600
+ if (introspectedTypes?.length) {
601
+ adoSection._availableTypes = introspectedTypes;
602
+ }
493
603
  }
494
604
  // Only include extractionDisabled if explicitly set
495
605
  if (options.extractionDisabled) {
@@ -507,9 +617,10 @@ export async function initSquad(options) {
507
617
  const configFileName = configFormat === 'sdk' ? 'squad.config.ts' :
508
618
  configFormat === 'typescript' ? 'squad.config.ts' : 'squad.config.json';
509
619
  configPath = join(teamRoot, configFileName);
510
- const configContent = configFormat === 'sdk' ? generateSDKBuilderConfig(options) :
511
- configFormat === 'typescript' ? generateTypeScriptConfig(options) :
512
- generateJsonConfig(options);
620
+ const configContent = (configFormat === 'sdk' && options.roles) ? generateSDKBuilderConfigWithRoles(options) :
621
+ configFormat === 'sdk' ? generateSDKBuilderConfig(options) :
622
+ configFormat === 'typescript' ? generateTypeScriptConfig(options) :
623
+ generateJsonConfig(options);
513
624
  await writeIfNotExists(configPath, configContent);
514
625
  }
515
626
  else {
@@ -539,27 +650,27 @@ export async function initSquad(options) {
539
650
  const identityDir = join(squadDir, 'identity');
540
651
  const nowMdPath = join(identityDir, 'now.md');
541
652
  const wisdomMdPath = join(identityDir, 'wisdom.md');
542
- const nowContent = `---
543
- updated_at: ${new Date().toISOString()}
544
- focus_area: Initial setup
545
- active_issues: []
546
- ---
547
-
548
- # What We're Focused On
549
-
550
- Getting started. Updated by coordinator at session start.
653
+ const nowContent = `---
654
+ updated_at: ${new Date().toISOString()}
655
+ focus_area: Initial setup
656
+ active_issues: []
657
+ ---
658
+
659
+ # What We're Focused On
660
+
661
+ Getting started. Updated by coordinator at session start.
551
662
  `;
552
- const wisdomContent = `---
553
- last_updated: ${new Date().toISOString()}
554
- ---
555
-
556
- # Team Wisdom
557
-
558
- Reusable patterns and heuristics learned through work. NOT transcripts — each entry is a distilled, actionable insight.
559
-
560
- ## Patterns
561
-
562
- <!-- Append entries below. Format: **Pattern:** description. **Context:** when it applies. -->
663
+ const wisdomContent = `---
664
+ last_updated: ${new Date().toISOString()}
665
+ ---
666
+
667
+ # Team Wisdom
668
+
669
+ Reusable patterns and heuristics learned through work. NOT transcripts — each entry is a distilled, actionable insight.
670
+
671
+ ## Patterns
672
+
673
+ <!-- Append entries below. Format: **Pattern:** description. **Context:** when it applies. -->
563
674
  `;
564
675
  await writeIfNotExists(nowMdPath, nowContent);
565
676
  await writeIfNotExists(wisdomMdPath, wisdomContent);
@@ -574,42 +685,42 @@ Reusable patterns and heuristics learned through work. NOT transcripts — each
574
685
  // Create decisions.md (canonical location at squad root)
575
686
  // -------------------------------------------------------------------------
576
687
  const decisionsPath = join(squadDir, 'decisions.md');
577
- const decisionsContent = `# Squad Decisions
578
-
579
- ## Active Decisions
580
-
581
- No decisions recorded yet.
582
-
583
- ## Governance
584
-
585
- - All meaningful changes require team consensus
586
- - Document architectural decisions here
587
- - Keep history focused on work, decisions focused on direction
688
+ const decisionsContent = `# Squad Decisions
689
+
690
+ ## Active Decisions
691
+
692
+ No decisions recorded yet.
693
+
694
+ ## Governance
695
+
696
+ - All meaningful changes require team consensus
697
+ - Document architectural decisions here
698
+ - Keep history focused on work, decisions focused on direction
588
699
  `;
589
700
  await writeIfNotExists(decisionsPath, decisionsContent);
590
701
  // -------------------------------------------------------------------------
591
702
  // Create team.md (required by shell lifecycle)
592
703
  // -------------------------------------------------------------------------
593
704
  const teamPath = join(squadDir, 'team.md');
594
- const teamContent = `# Squad Team
595
-
596
- > ${projectDescription || projectName}
597
-
598
- ## Coordinator
599
-
600
- | Name | Role | Notes |
601
- |------|------|-------|
602
- | Squad | Coordinator | Routes work, enforces handoffs and reviewer gates. |
603
-
604
- ## Members
605
-
606
- | Name | Role | Charter | Status |
607
- |------|------|---------|--------|
608
-
609
- ## Project Context
610
-
611
- - **Project:** ${projectName}
612
- ${projectDescription ? `- **Description:** ${projectDescription}\n` : ''}- **Created:** ${new Date().toISOString().split('T')[0]}
705
+ const teamContent = `# Squad Team
706
+
707
+ > ${projectDescription || projectName}
708
+
709
+ ## Coordinator
710
+
711
+ | Name | Role | Notes |
712
+ |------|------|-------|
713
+ | Squad | Coordinator | Routes work, enforces handoffs and reviewer gates. |
714
+
715
+ ## Members
716
+
717
+ | Name | Role | Charter | Status |
718
+ |------|------|---------|--------|
719
+
720
+ ## Project Context
721
+
722
+ - **Project:** ${projectName}
723
+ ${projectDescription ? `- **Description:** ${projectDescription}\n` : ''}- **Created:** ${new Date().toISOString().split('T')[0]}
613
724
  `;
614
725
  await writeIfNotExists(teamPath, teamContent);
615
726
  // -------------------------------------------------------------------------
@@ -620,30 +731,30 @@ ${projectDescription ? `- **Description:** ${projectDescription}\n` : ''}- **Cre
620
731
  await copyIfNotExists(join(templatesDir, 'routing.md'), routingPath);
621
732
  }
622
733
  else {
623
- const routingContent = `# Squad Routing
624
-
625
- ## Work Type Rules
626
-
627
- | Work Type | Primary Agent | Fallback |
628
- |-----------|---------------|----------|
629
-
630
- ## Governance
631
-
632
- - Route based on work type and agent expertise
633
- - Update this file as team capabilities evolve
734
+ const routingContent = `# Squad Routing
735
+
736
+ ## Work Type Rules
737
+
738
+ | Work Type | Primary Agent | Fallback |
739
+ |-----------|---------------|----------|
740
+
741
+ ## Governance
742
+
743
+ - Route based on work type and agent expertise
744
+ - Update this file as team capabilities evolve
634
745
  `;
635
746
  await writeIfNotExists(routingPath, routingContent);
636
747
  }
637
748
  // -------------------------------------------------------------------------
638
749
  // Copy starter skills
639
750
  // -------------------------------------------------------------------------
640
- const skillsDir = join(squadDir, 'skills');
751
+ const skillsDir = join(teamRoot, '.copilot', 'skills');
641
752
  if (templatesDir && existsSync(join(templatesDir, 'skills'))) {
642
753
  const skillsSrc = join(templatesDir, 'skills');
643
754
  const existingSkills = existsSync(skillsDir) ? readdirSync(skillsDir) : [];
644
755
  if (existingSkills.length === 0) {
645
756
  cpSync(skillsSrc, skillsDir, { recursive: true });
646
- createdFiles.push('.squad/skills');
757
+ createdFiles.push('.copilot/skills');
647
758
  }
648
759
  }
649
760
  // -------------------------------------------------------------------------