@bradygaster/squad-sdk 0.8.19 → 0.8.21

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 (105) hide show
  1. package/README.md +296 -296
  2. package/dist/adapter/client.js +1 -1
  3. package/dist/adapter/client.js.map +1 -1
  4. package/dist/agents/charter-compiler.d.ts +4 -0
  5. package/dist/agents/charter-compiler.d.ts.map +1 -1
  6. package/dist/agents/charter-compiler.js +8 -0
  7. package/dist/agents/charter-compiler.js.map +1 -1
  8. package/dist/agents/history-shadow.js +30 -30
  9. package/dist/agents/index.js +1 -1
  10. package/dist/agents/index.js.map +1 -1
  11. package/dist/agents/lifecycle.js +1 -1
  12. package/dist/agents/lifecycle.js.map +1 -1
  13. package/dist/build/github-dist.js +42 -42
  14. package/dist/builders/index.d.ts +156 -0
  15. package/dist/builders/index.d.ts.map +1 -0
  16. package/dist/builders/index.js +404 -0
  17. package/dist/builders/index.js.map +1 -0
  18. package/dist/builders/types.d.ts +187 -0
  19. package/dist/builders/types.d.ts.map +1 -0
  20. package/dist/builders/types.js +12 -0
  21. package/dist/builders/types.js.map +1 -0
  22. package/dist/config/init.d.ts +6 -22
  23. package/dist/config/init.d.ts.map +1 -1
  24. package/dist/config/init.js +273 -185
  25. package/dist/config/init.js.map +1 -1
  26. package/dist/coordinator/coordinator.js +1 -1
  27. package/dist/coordinator/coordinator.js.map +1 -1
  28. package/dist/coordinator/index.js +1 -1
  29. package/dist/coordinator/index.js.map +1 -1
  30. package/dist/index.d.ts +3 -0
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +3 -0
  33. package/dist/index.js.map +1 -1
  34. package/dist/runtime/otel-api.d.ts +38 -0
  35. package/dist/runtime/otel-api.d.ts.map +1 -0
  36. package/dist/runtime/otel-api.js +94 -0
  37. package/dist/runtime/otel-api.js.map +1 -0
  38. package/dist/runtime/otel-bridge.js +1 -1
  39. package/dist/runtime/otel-bridge.js.map +1 -1
  40. package/dist/runtime/otel.d.ts +1 -1
  41. package/dist/runtime/otel.d.ts.map +1 -1
  42. package/dist/runtime/otel.js +28 -12
  43. package/dist/runtime/otel.js.map +1 -1
  44. package/dist/runtime/squad-observer.js +1 -1
  45. package/dist/runtime/squad-observer.js.map +1 -1
  46. package/dist/sharing/consult.js +78 -78
  47. package/dist/streams/filter.d.ts +33 -0
  48. package/dist/streams/filter.d.ts.map +1 -0
  49. package/dist/streams/filter.js +29 -0
  50. package/dist/streams/filter.js.map +1 -0
  51. package/dist/streams/index.d.ts +9 -0
  52. package/dist/streams/index.d.ts.map +1 -0
  53. package/dist/streams/index.js +9 -0
  54. package/dist/streams/index.js.map +1 -0
  55. package/dist/streams/resolver.d.ts +40 -0
  56. package/dist/streams/resolver.d.ts.map +1 -0
  57. package/dist/streams/resolver.js +162 -0
  58. package/dist/streams/resolver.js.map +1 -0
  59. package/dist/streams/types.d.ts +44 -0
  60. package/dist/streams/types.d.ts.map +1 -0
  61. package/dist/streams/types.js +10 -0
  62. package/dist/streams/types.js.map +1 -0
  63. package/dist/tools/index.js +1 -1
  64. package/dist/tools/index.js.map +1 -1
  65. package/dist/types.d.ts +20 -0
  66. package/dist/types.d.ts.map +1 -1
  67. package/package.json +208 -207
  68. package/templates/casting-history.json +4 -4
  69. package/templates/casting-policy.json +35 -35
  70. package/templates/casting-registry.json +3 -3
  71. package/templates/ceremonies.md +41 -41
  72. package/templates/charter.md +53 -53
  73. package/templates/constraint-tracking.md +38 -38
  74. package/templates/copilot-instructions.md +46 -46
  75. package/templates/history.md +10 -10
  76. package/templates/identity/now.md +9 -9
  77. package/templates/identity/wisdom.md +15 -15
  78. package/templates/mcp-config.md +98 -98
  79. package/templates/multi-agent-format.md +28 -28
  80. package/templates/orchestration-log.md +27 -27
  81. package/templates/plugin-marketplace.md +49 -49
  82. package/templates/raw-agent-output.md +37 -37
  83. package/templates/roster.md +60 -60
  84. package/templates/routing.md +54 -54
  85. package/templates/run-output.md +50 -50
  86. package/templates/scribe-charter.md +119 -119
  87. package/templates/skill.md +24 -24
  88. package/templates/skills/project-conventions/SKILL.md +56 -56
  89. package/templates/squad.agent.md +1146 -1146
  90. package/templates/workflows/squad-ci.yml +24 -24
  91. package/templates/workflows/squad-docs.yml +50 -50
  92. package/templates/workflows/squad-heartbeat.yml +316 -316
  93. package/templates/workflows/squad-insider-release.yml +61 -61
  94. package/templates/workflows/squad-issue-assign.yml +161 -161
  95. package/templates/workflows/squad-label-enforce.yml +181 -181
  96. package/templates/workflows/squad-preview.yml +55 -55
  97. package/templates/workflows/squad-promote.yml +120 -121
  98. package/templates/workflows/squad-release.yml +77 -77
  99. package/templates/workflows/squad-triage.yml +260 -260
  100. package/templates/workflows/sync-squad-labels.yml +169 -169
  101. package/dist/runtime/event-bus-otel-bridge.d.ts +0 -19
  102. package/dist/runtime/event-bus-otel-bridge.d.ts.map +0 -1
  103. package/dist/runtime/event-bus-otel-bridge.js +0 -61
  104. package/dist/runtime/event-bus-otel-bridge.js.map +0 -1
  105. package/templates/workflows/squad-main-guard.yml +0 -129
@@ -7,6 +7,7 @@
7
7
  *
8
8
  * @module config/init
9
9
  */
10
+ import type { WorkstreamDefinition } from '../streams/types.js';
10
11
  /**
11
12
  * Get the SDK templates directory path.
12
13
  */
@@ -34,15 +35,15 @@ export interface InitOptions {
34
35
  projectDescription?: string;
35
36
  /** Agents to create */
36
37
  agents: InitAgentSpec[];
37
- /** Config format (typescript or json) */
38
- configFormat?: 'typescript' | 'json';
38
+ /** Config format (typescript or json for old format, sdk for new builder syntax, markdown for no config file) */
39
+ configFormat?: 'typescript' | 'json' | 'sdk' | 'markdown';
39
40
  /** User name for initial history entries */
40
41
  userName?: string;
41
42
  /** Skip files that already exist (default: true) */
42
43
  skipExisting?: boolean;
43
44
  /** Include GitHub workflows (default: true) */
44
45
  includeWorkflows?: boolean;
45
- /** Include .squad-templates/ copy (default: true) */
46
+ /** Include .squad/templates/ copy (default: true) */
46
47
  includeTemplates?: boolean;
47
48
  /** Include sample MCP config (default: true) */
48
49
  includeMcpConfig?: boolean;
@@ -54,6 +55,8 @@ export interface InitOptions {
54
55
  prompt?: string;
55
56
  /** If true, disable extraction from consult sessions (read-only consultations) */
56
57
  extractionDisabled?: boolean;
58
+ /** Optional workstream definitions — generates .squad/workstreams.json when provided */
59
+ streams?: WorkstreamDefinition[];
57
60
  }
58
61
  /**
59
62
  * Initialization result.
@@ -72,25 +75,6 @@ export interface InitResult {
72
75
  /** Path to .squad/ directory */
73
76
  squadDir: string;
74
77
  }
75
- /**
76
- * Initialize a new Squad project.
77
- *
78
- * Creates:
79
- * - .squad/ directory structure (agents, casting, decisions, skills, identity, etc.)
80
- * - squad.config.ts or squad.config.json
81
- * - Agent directories with charter.md and history.md
82
- * - .gitattributes for merge drivers
83
- * - .gitignore entries for logs
84
- * - .github/agents/squad.agent.md
85
- * - .github/workflows/ (optional)
86
- * - .squad-templates/ (optional)
87
- * - .copilot/mcp-config.json (optional)
88
- * - Identity files (now.md, wisdom.md)
89
- * - ceremonies.md
90
- *
91
- * @param options - Initialization options
92
- * @returns Result with created file paths
93
- */
94
78
  export declare function initSquad(options: InitOptions): Promise<InitResult>;
95
79
  /**
96
80
  * Clean up orphan .init-prompt file.
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/config/init.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAaH;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,IAAI,CAiBlD;AA0BD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,qCAAqC;IACrC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,uBAAuB;IACvB,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,yCAAyC;IACzC,YAAY,CAAC,EAAE,YAAY,GAAG,MAAM,CAAC;IACrC,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oDAAoD;IACpD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,+CAA+C;IAC/C,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,qDAAqD;IACrD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,gDAAgD;IAChD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,8CAA8C;IAC9C,WAAW,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;IAChF,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kFAAkF;IAClF,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,wDAAwD;IACxD,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,mDAAmD;IACnD,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,8BAA8B;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,4BAA4B;IAC5B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,6BAA6B;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,gCAAgC;IAChC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAoSD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAkbzE;AAED;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAK7E"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/config/init.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAQH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAMhE;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,IAAI,CAiBlD;AA0BD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,qCAAqC;IACrC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,uBAAuB;IACvB,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,iHAAiH;IACjH,YAAY,CAAC,EAAE,YAAY,GAAG,MAAM,GAAG,KAAK,GAAG,UAAU,CAAC;IAC1D,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oDAAoD;IACpD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,+CAA+C;IAC/C,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,qDAAqD;IACrD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,gDAAgD;IAChD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,8CAA8C;IAC9C,WAAW,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;IAChF,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kFAAkF;IAClF,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,wFAAwF;IACxF,OAAO,CAAC,EAAE,oBAAoB,EAAE,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,wDAAwD;IACxD,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,mDAAmD;IACnD,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,8BAA8B;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,4BAA4B;IAC5B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,6BAA6B;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,gCAAgC;IAChC,QAAQ,EAAE,MAAM,CAAC;CAClB;AA6WD,wBAAsB,SAAS,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CA+dzE;AAED;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAK7E"}
@@ -93,82 +93,82 @@ function formatModelArray(chain) {
93
93
  */
94
94
  function generateTypeScriptConfig(options) {
95
95
  const { projectName, projectDescription, agents } = options;
96
- return `import type { SquadConfig } from '@bradygaster/squad';
97
-
98
- /**
99
- * Squad Configuration for ${projectName}
100
- * ${projectDescription ? `\n * ${projectDescription}` : ''}
101
- */
102
- const config: SquadConfig = {
103
- version: '1.0.0',
104
-
105
- models: {
106
- defaultModel: '${MODELS.DEFAULT}',
107
- defaultTier: 'standard',
108
- fallbackChains: {
109
- premium: ${formatModelArray(MODELS.FALLBACK_CHAINS.premium)},
110
- standard: ${formatModelArray(MODELS.FALLBACK_CHAINS.standard)},
111
- fast: ${formatModelArray(MODELS.FALLBACK_CHAINS.fast)}
112
- },
113
- preferSameProvider: true,
114
- respectTierCeiling: true,
115
- nuclearFallback: {
116
- enabled: false,
117
- model: '${MODELS.NUCLEAR_FALLBACK}',
118
- maxRetriesBeforeNuclear: ${MODELS.NUCLEAR_MAX_RETRIES}
119
- }
120
- },
121
-
122
- routing: {
123
- rules: [
124
- {
125
- workType: 'feature-dev',
126
- agents: ['@${agents[0]?.name || 'coordinator'}'],
127
- confidence: 'high'
128
- },
129
- {
130
- workType: 'bug-fix',
131
- agents: ['@${agents.find(a => a.role === 'developer')?.name || agents[0]?.name || 'coordinator'}'],
132
- confidence: 'high'
133
- },
134
- {
135
- workType: 'testing',
136
- agents: ['@${agents.find(a => a.role === 'tester')?.name || agents[0]?.name || 'coordinator'}'],
137
- confidence: 'high'
138
- },
139
- {
140
- workType: 'documentation',
141
- agents: ['@${agents.find(a => a.role === 'scribe')?.name || agents[0]?.name || 'coordinator'}'],
142
- confidence: 'high'
143
- }
144
- ],
145
- governance: {
146
- eagerByDefault: true,
147
- scribeAutoRuns: false,
148
- allowRecursiveSpawn: false
149
- }
150
- },
151
-
152
- casting: {
153
- allowlistUniverses: [
154
- 'The Usual Suspects',
155
- 'Breaking Bad',
156
- 'The Wire',
157
- 'Firefly'
158
- ],
159
- overflowStrategy: 'generic',
160
- universeCapacity: {}
161
- },
162
-
163
- platforms: {
164
- vscode: {
165
- disableModelSelection: false,
166
- scribeMode: 'sync'
167
- }
168
- }
169
- };
170
-
171
- export default config;
96
+ return `import type { SquadConfig } from '@bradygaster/squad';
97
+
98
+ /**
99
+ * Squad Configuration for ${projectName}
100
+ * ${projectDescription ? `\n * ${projectDescription}` : ''}
101
+ */
102
+ const config: SquadConfig = {
103
+ version: '1.0.0',
104
+
105
+ models: {
106
+ defaultModel: '${MODELS.DEFAULT}',
107
+ defaultTier: 'standard',
108
+ fallbackChains: {
109
+ premium: ${formatModelArray(MODELS.FALLBACK_CHAINS.premium)},
110
+ standard: ${formatModelArray(MODELS.FALLBACK_CHAINS.standard)},
111
+ fast: ${formatModelArray(MODELS.FALLBACK_CHAINS.fast)}
112
+ },
113
+ preferSameProvider: true,
114
+ respectTierCeiling: true,
115
+ nuclearFallback: {
116
+ enabled: false,
117
+ model: '${MODELS.NUCLEAR_FALLBACK}',
118
+ maxRetriesBeforeNuclear: ${MODELS.NUCLEAR_MAX_RETRIES}
119
+ }
120
+ },
121
+
122
+ routing: {
123
+ rules: [
124
+ {
125
+ workType: 'feature-dev',
126
+ agents: ['@${agents[0]?.name || 'coordinator'}'],
127
+ confidence: 'high'
128
+ },
129
+ {
130
+ workType: 'bug-fix',
131
+ agents: ['@${agents.find(a => a.role === 'developer')?.name || agents[0]?.name || 'coordinator'}'],
132
+ confidence: 'high'
133
+ },
134
+ {
135
+ workType: 'testing',
136
+ agents: ['@${agents.find(a => a.role === 'tester')?.name || agents[0]?.name || 'coordinator'}'],
137
+ confidence: 'high'
138
+ },
139
+ {
140
+ workType: 'documentation',
141
+ agents: ['@${agents.find(a => a.role === 'scribe')?.name || agents[0]?.name || 'coordinator'}'],
142
+ confidence: 'high'
143
+ }
144
+ ],
145
+ governance: {
146
+ eagerByDefault: true,
147
+ scribeAutoRuns: false,
148
+ allowRecursiveSpawn: false
149
+ }
150
+ },
151
+
152
+ casting: {
153
+ allowlistUniverses: [
154
+ 'The Usual Suspects',
155
+ 'Breaking Bad',
156
+ 'The Wire',
157
+ 'Firefly'
158
+ ],
159
+ overflowStrategy: 'generic',
160
+ universeCapacity: {}
161
+ },
162
+
163
+ platforms: {
164
+ vscode: {
165
+ disableModelSelection: false,
166
+ scribeMode: 'sync'
167
+ }
168
+ }
169
+ };
170
+
171
+ export default config;
172
172
  `;
173
173
  }
174
174
  /**
@@ -242,6 +242,42 @@ function generateJsonConfig(options) {
242
242
  };
243
243
  return JSON.stringify(config, null, 2);
244
244
  }
245
+ /**
246
+ * Generate SDK builder config file content (new defineSquad() format).
247
+ */
248
+ function generateSDKBuilderConfig(options) {
249
+ const { projectName, projectDescription, agents } = options;
250
+ // Generate imports
251
+ let code = `import {\n defineSquad,\n defineTeam,\n defineAgent,\n} from '@bradygaster/squad-sdk';\n\n`;
252
+ code += `/**\n * Squad Configuration — ${projectName}\n`;
253
+ if (projectDescription) {
254
+ code += ` *\n * ${projectDescription}\n`;
255
+ }
256
+ code += ` */\n`;
257
+ // Generate agent definitions
258
+ for (const agent of agents) {
259
+ const displayName = agent.displayName || titleCase(agent.name);
260
+ code += `const ${agent.name} = defineAgent({\n`;
261
+ code += ` name: '${agent.name}',\n`;
262
+ code += ` role: '${agent.role}',\n`;
263
+ code += ` description: '${displayName}',\n`;
264
+ code += ` status: 'active',\n`;
265
+ code += `});\n\n`;
266
+ }
267
+ // Generate squad config
268
+ code += `export default defineSquad({\n`;
269
+ code += ` version: '1.0.0',\n\n`;
270
+ code += ` team: defineTeam({\n`;
271
+ code += ` name: '${projectName}',\n`;
272
+ if (projectDescription) {
273
+ code += ` description: '${projectDescription.replace(/'/g, "\\'")}',\n`;
274
+ }
275
+ code += ` members: [${agents.map(a => `'${a.name}'`).join(', ')}],\n`;
276
+ code += ` }),\n\n`;
277
+ code += ` agents: [${agents.map(a => a.name).join(', ')}],\n`;
278
+ code += `});\n`;
279
+ return code;
280
+ }
245
281
  // ============================================================================
246
282
  // Agent Template Generation
247
283
  // ============================================================================
@@ -252,26 +288,26 @@ function generateCharter(agent, projectName, projectDescription) {
252
288
  const template = AGENT_TEMPLATES[agent.role];
253
289
  const displayName = agent.displayName || template?.displayName || titleCase(agent.name);
254
290
  const description = template?.description || 'Team member focused on their assigned responsibilities.';
255
- return `# ${displayName} — ${titleCase(agent.role)}
256
-
257
- ${description}
258
-
259
- ## Project Context
260
-
261
- **Project:** ${projectName}
262
- ${projectDescription ? `**Description:** ${projectDescription}\n` : ''}
263
-
264
- ## Responsibilities
265
-
266
- - Collaborate with team members on assigned work
267
- - Maintain code quality and project standards
268
- - Document decisions and progress in history
269
-
270
- ## Work Style
271
-
272
- - Read project context and team decisions before starting work
273
- - Communicate clearly with team members
274
- - Follow established patterns and conventions
291
+ return `# ${displayName} — ${titleCase(agent.role)}
292
+
293
+ ${description}
294
+
295
+ ## Project Context
296
+
297
+ **Project:** ${projectName}
298
+ ${projectDescription ? `**Description:** ${projectDescription}\n` : ''}
299
+
300
+ ## Responsibilities
301
+
302
+ - Collaborate with team members on assigned work
303
+ - Maintain code quality and project standards
304
+ - Document decisions and progress in history
305
+
306
+ ## Work Style
307
+
308
+ - Read project context and team decisions before starting work
309
+ - Communicate clearly with team members
310
+ - Follow established patterns and conventions
275
311
  `;
276
312
  }
277
313
  /**
@@ -280,22 +316,22 @@ ${projectDescription ? `**Description:** ${projectDescription}\n` : ''}
280
316
  function generateInitialHistory(agent, projectName, projectDescription, userName) {
281
317
  const displayName = agent.displayName || AGENT_TEMPLATES[agent.role]?.displayName || titleCase(agent.name);
282
318
  const now = new Date().toISOString().split('T')[0];
283
- return `# Project Context
284
-
285
- ${userName ? `- **Owner:** ${userName}\n` : ''}- **Project:** ${projectName}
286
- ${projectDescription ? `- **Description:** ${projectDescription}\n` : ''}- **Created:** ${now}
287
-
288
- ## Core Context
289
-
290
- Agent ${displayName} initialized and ready for work.
291
-
292
- ## Recent Updates
293
-
294
- 📌 Team initialized on ${now}
295
-
296
- ## Learnings
297
-
298
- Initial setup complete.
319
+ return `# Project Context
320
+
321
+ ${userName ? `- **Owner:** ${userName}\n` : ''}- **Project:** ${projectName}
322
+ ${projectDescription ? `- **Description:** ${projectDescription}\n` : ''}- **Created:** ${now}
323
+
324
+ ## Core Context
325
+
326
+ Agent ${displayName} initialized and ready for work.
327
+
328
+ ## Recent Updates
329
+
330
+ 📌 Team initialized on ${now}
331
+
332
+ ## Learnings
333
+
334
+ Initial setup complete.
299
335
  `;
300
336
  }
301
337
  /**
@@ -327,7 +363,7 @@ function stampVersionInContent(content, version) {
327
363
  * - .gitignore entries for logs
328
364
  * - .github/agents/squad.agent.md
329
365
  * - .github/workflows/ (optional)
330
- * - .squad-templates/ (optional)
366
+ * - .squad/templates/ (optional)
331
367
  * - .copilot/mcp-config.json (optional)
332
368
  * - Identity files (now.md, wisdom.md)
333
369
  * - ceremonies.md
@@ -335,6 +371,16 @@ function stampVersionInContent(content, version) {
335
371
  * @param options - Initialization options
336
372
  * @returns Result with created file paths
337
373
  */
374
+ /**
375
+ * Workflow files that are part of the Squad framework and should always be installed.
376
+ * Other workflows in templates/workflows/ are generic CI/CD scaffolding and are opt-in.
377
+ */
378
+ const FRAMEWORK_WORKFLOWS = [
379
+ 'squad-heartbeat.yml',
380
+ 'squad-issue-assign.yml',
381
+ 'squad-triage.yml',
382
+ 'sync-squad-labels.yml',
383
+ ];
338
384
  export async function initSquad(options) {
339
385
  const { teamRoot, projectName, projectDescription, agents, configFormat = 'typescript', userName, skipExisting = true, includeWorkflows = true, includeTemplates = true, includeMcpConfig = true, projectType = 'unknown', version = '0.0.0', } = options;
340
386
  const createdFiles = [];
@@ -425,12 +471,21 @@ export async function initSquad(options) {
425
471
  // -------------------------------------------------------------------------
426
472
  // Create configuration file
427
473
  // -------------------------------------------------------------------------
428
- const configFileName = configFormat === 'typescript' ? 'squad.config.ts' : 'squad.config.json';
429
- const configPath = join(teamRoot, configFileName);
430
- const configContent = configFormat === 'typescript'
431
- ? generateTypeScriptConfig(options)
432
- : generateJsonConfig(options);
433
- await writeIfNotExists(configPath, configContent);
474
+ // When configFormat is 'markdown', skip config file generation entirely
475
+ let configPath;
476
+ if (configFormat !== 'markdown') {
477
+ const configFileName = configFormat === 'sdk' ? 'squad.config.ts' :
478
+ configFormat === 'typescript' ? 'squad.config.ts' : 'squad.config.json';
479
+ configPath = join(teamRoot, configFileName);
480
+ const configContent = configFormat === 'sdk' ? generateSDKBuilderConfig(options) :
481
+ configFormat === 'typescript' ? generateTypeScriptConfig(options) :
482
+ generateJsonConfig(options);
483
+ await writeIfNotExists(configPath, configContent);
484
+ }
485
+ else {
486
+ // No config file for markdown-only mode
487
+ configPath = '';
488
+ }
434
489
  // -------------------------------------------------------------------------
435
490
  // Create agent directories and files
436
491
  // -------------------------------------------------------------------------
@@ -454,27 +509,27 @@ export async function initSquad(options) {
454
509
  const identityDir = join(squadDir, 'identity');
455
510
  const nowMdPath = join(identityDir, 'now.md');
456
511
  const wisdomMdPath = join(identityDir, 'wisdom.md');
457
- const nowContent = `---
458
- updated_at: ${new Date().toISOString()}
459
- focus_area: Initial setup
460
- active_issues: []
461
- ---
462
-
463
- # What We're Focused On
464
-
465
- Getting started. Updated by coordinator at session start.
512
+ const nowContent = `---
513
+ updated_at: ${new Date().toISOString()}
514
+ focus_area: Initial setup
515
+ active_issues: []
516
+ ---
517
+
518
+ # What We're Focused On
519
+
520
+ Getting started. Updated by coordinator at session start.
466
521
  `;
467
- const wisdomContent = `---
468
- last_updated: ${new Date().toISOString()}
469
- ---
470
-
471
- # Team Wisdom
472
-
473
- Reusable patterns and heuristics learned through work. NOT transcripts — each entry is a distilled, actionable insight.
474
-
475
- ## Patterns
476
-
477
- <!-- Append entries below. Format: **Pattern:** description. **Context:** when it applies. -->
522
+ const wisdomContent = `---
523
+ last_updated: ${new Date().toISOString()}
524
+ ---
525
+
526
+ # Team Wisdom
527
+
528
+ Reusable patterns and heuristics learned through work. NOT transcripts — each entry is a distilled, actionable insight.
529
+
530
+ ## Patterns
531
+
532
+ <!-- Append entries below. Format: **Pattern:** description. **Context:** when it applies. -->
478
533
  `;
479
534
  await writeIfNotExists(nowMdPath, nowContent);
480
535
  await writeIfNotExists(wisdomMdPath, wisdomContent);
@@ -489,42 +544,42 @@ Reusable patterns and heuristics learned through work. NOT transcripts — each
489
544
  // Create decisions.md (canonical location at squad root)
490
545
  // -------------------------------------------------------------------------
491
546
  const decisionsPath = join(squadDir, 'decisions.md');
492
- const decisionsContent = `# Squad Decisions
493
-
494
- ## Active Decisions
495
-
496
- No decisions recorded yet.
497
-
498
- ## Governance
499
-
500
- - All meaningful changes require team consensus
501
- - Document architectural decisions here
502
- - Keep history focused on work, decisions focused on direction
547
+ const decisionsContent = `# Squad Decisions
548
+
549
+ ## Active Decisions
550
+
551
+ No decisions recorded yet.
552
+
553
+ ## Governance
554
+
555
+ - All meaningful changes require team consensus
556
+ - Document architectural decisions here
557
+ - Keep history focused on work, decisions focused on direction
503
558
  `;
504
559
  await writeIfNotExists(decisionsPath, decisionsContent);
505
560
  // -------------------------------------------------------------------------
506
561
  // Create team.md (required by shell lifecycle)
507
562
  // -------------------------------------------------------------------------
508
563
  const teamPath = join(squadDir, 'team.md');
509
- const teamContent = `# Squad Team
510
-
511
- > ${projectDescription || projectName}
512
-
513
- ## Coordinator
514
-
515
- | Name | Role | Notes |
516
- |------|------|-------|
517
- | Squad | Coordinator | Routes work, enforces handoffs and reviewer gates. |
518
-
519
- ## Members
520
-
521
- | Name | Role | Charter | Status |
522
- |------|------|---------|--------|
523
-
524
- ## Project Context
525
-
526
- - **Project:** ${projectName}
527
- ${projectDescription ? `- **Description:** ${projectDescription}\n` : ''}- **Created:** ${new Date().toISOString().split('T')[0]}
564
+ const teamContent = `# Squad Team
565
+
566
+ > ${projectDescription || projectName}
567
+
568
+ ## Coordinator
569
+
570
+ | Name | Role | Notes |
571
+ |------|------|-------|
572
+ | Squad | Coordinator | Routes work, enforces handoffs and reviewer gates. |
573
+
574
+ ## Members
575
+
576
+ | Name | Role | Charter | Status |
577
+ |------|------|---------|--------|
578
+
579
+ ## Project Context
580
+
581
+ - **Project:** ${projectName}
582
+ ${projectDescription ? `- **Description:** ${projectDescription}\n` : ''}- **Created:** ${new Date().toISOString().split('T')[0]}
528
583
  `;
529
584
  await writeIfNotExists(teamPath, teamContent);
530
585
  // -------------------------------------------------------------------------
@@ -535,17 +590,17 @@ ${projectDescription ? `- **Description:** ${projectDescription}\n` : ''}- **Cre
535
590
  await copyIfNotExists(join(templatesDir, 'routing.md'), routingPath);
536
591
  }
537
592
  else {
538
- const routingContent = `# Squad Routing
539
-
540
- ## Work Type Rules
541
-
542
- | Work Type | Primary Agent | Fallback |
543
- |-----------|---------------|----------|
544
-
545
- ## Governance
546
-
547
- - Route based on work type and agent expertise
548
- - Update this file as team capabilities evolve
593
+ const routingContent = `# Squad Routing
594
+
595
+ ## Work Type Rules
596
+
597
+ | Work Type | Primary Agent | Fallback |
598
+ |-----------|---------------|----------|
599
+
600
+ ## Governance
601
+
602
+ - Route based on work type and agent expertise
603
+ - Update this file as team capabilities evolve
549
604
  `;
550
605
  await writeIfNotExists(routingPath, routingContent);
551
606
  }
@@ -584,12 +639,16 @@ ${projectDescription ? `- **Description:** ${projectDescription}\n` : ''}- **Cre
584
639
  createdFiles.push(toRelativePath(gitattributesPath));
585
640
  }
586
641
  // -------------------------------------------------------------------------
587
- // Create .gitignore entries for logs
642
+ // Create .gitignore entries for runtime state (logs, inbox, sessions)
643
+ // These paths are written during normal squad operation but should not be
644
+ // committed to version control (they are runtime state).
588
645
  // -------------------------------------------------------------------------
589
646
  const gitignorePath = join(teamRoot, '.gitignore');
590
647
  const ignoreEntries = [
591
648
  '.squad/orchestration-log/',
592
649
  '.squad/log/',
650
+ '.squad/decisions/inbox/',
651
+ '.squad/sessions/',
593
652
  ];
594
653
  let existingIgnore = '';
595
654
  if (existsSync(gitignorePath)) {
@@ -598,7 +657,7 @@ ${projectDescription ? `- **Description:** ${projectDescription}\n` : ''}- **Cre
598
657
  const missingIgnore = ignoreEntries.filter(entry => !existingIgnore.includes(entry));
599
658
  if (missingIgnore.length > 0) {
600
659
  const block = (existingIgnore && !existingIgnore.endsWith('\n') ? '\n' : '')
601
- + '# Squad: ignore generated logs\n'
660
+ + '# Squad: ignore runtime state (logs, inbox, sessions)\n'
602
661
  + missingIgnore.join('\n') + '\n';
603
662
  await appendFile(gitignorePath, block);
604
663
  createdFiles.push(toRelativePath(gitignorePath));
@@ -620,10 +679,10 @@ ${projectDescription ? `- **Description:** ${projectDescription}\n` : ''}- **Cre
620
679
  skippedFiles.push(toRelativePath(agentFile));
621
680
  }
622
681
  // -------------------------------------------------------------------------
623
- // Copy .squad-templates/ (optional)
682
+ // Copy .squad/templates/ (optional)
624
683
  // -------------------------------------------------------------------------
625
684
  if (includeTemplates && templatesDir) {
626
- const templatesDest = join(teamRoot, '.squad-templates');
685
+ const templatesDest = join(teamRoot, '.squad', 'templates');
627
686
  if (!existsSync(templatesDest)) {
628
687
  cpSync(templatesDir, templatesDest, { recursive: true });
629
688
  createdFiles.push(toRelativePath(templatesDest));
@@ -639,7 +698,8 @@ ${projectDescription ? `- **Description:** ${projectDescription}\n` : ''}- **Cre
639
698
  const workflowsSrc = join(templatesDir, 'workflows');
640
699
  const workflowsDest = join(teamRoot, '.github', 'workflows');
641
700
  if (statSync(workflowsSrc).isDirectory()) {
642
- const workflowFiles = readdirSync(workflowsSrc).filter(f => f.endsWith('.yml'));
701
+ const allWorkflowFiles = readdirSync(workflowsSrc).filter(f => f.endsWith('.yml'));
702
+ const workflowFiles = allWorkflowFiles.filter(f => FRAMEWORK_WORKFLOWS.includes(f));
643
703
  await mkdir(workflowsDest, { recursive: true });
644
704
  for (const file of workflowFiles) {
645
705
  const destFile = join(workflowsDest, file);
@@ -680,6 +740,34 @@ ${projectDescription ? `- **Description:** ${projectDescription}\n` : ''}- **Cre
680
740
  }
681
741
  }
682
742
  // -------------------------------------------------------------------------
743
+ // Generate .squad/workstreams.json (when streams provided)
744
+ // -------------------------------------------------------------------------
745
+ if (options.streams && options.streams.length > 0) {
746
+ const workstreamsConfig = {
747
+ workstreams: options.streams,
748
+ defaultWorkflow: 'branch-per-issue',
749
+ };
750
+ const workstreamsPath = join(squadDir, 'workstreams.json');
751
+ await writeIfNotExists(workstreamsPath, JSON.stringify(workstreamsConfig, null, 2) + '\n');
752
+ }
753
+ // -------------------------------------------------------------------------
754
+ // Add .squad-workstream to .gitignore
755
+ // -------------------------------------------------------------------------
756
+ {
757
+ const workstreamIgnoreEntry = '.squad-workstream';
758
+ let currentIgnore = '';
759
+ if (existsSync(gitignorePath)) {
760
+ currentIgnore = readFileSync(gitignorePath, 'utf-8');
761
+ }
762
+ if (!currentIgnore.includes(workstreamIgnoreEntry)) {
763
+ const block = (currentIgnore && !currentIgnore.endsWith('\n') ? '\n' : '')
764
+ + '# Squad: workstream activation file (local to this machine)\n'
765
+ + workstreamIgnoreEntry + '\n';
766
+ await appendFile(gitignorePath, block);
767
+ createdFiles.push(toRelativePath(gitignorePath));
768
+ }
769
+ }
770
+ // -------------------------------------------------------------------------
683
771
  // Create .first-run marker
684
772
  // -------------------------------------------------------------------------
685
773
  const firstRunMarker = join(squadDir, '.first-run');