@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.
- package/README.md +296 -296
- package/dist/adapter/client.d.ts +17 -0
- package/dist/adapter/client.d.ts.map +1 -1
- package/dist/adapter/client.js +101 -1
- package/dist/adapter/client.js.map +1 -1
- package/dist/agents/history-shadow.d.ts.map +1 -1
- package/dist/agents/history-shadow.js +129 -62
- package/dist/agents/history-shadow.js.map +1 -1
- package/dist/agents/index.d.ts +1 -0
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +2 -0
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/model-selector.d.ts +2 -0
- package/dist/agents/model-selector.d.ts.map +1 -1
- package/dist/agents/model-selector.js +41 -35
- package/dist/agents/model-selector.js.map +1 -1
- package/dist/agents/personal.d.ts +35 -0
- package/dist/agents/personal.d.ts.map +1 -0
- package/dist/agents/personal.js +67 -0
- package/dist/agents/personal.js.map +1 -0
- package/dist/build/github-dist.js +42 -42
- package/dist/builders/index.d.ts +3 -2
- package/dist/builders/index.d.ts.map +1 -1
- package/dist/builders/index.js +28 -0
- package/dist/builders/index.js.map +1 -1
- package/dist/builders/types.d.ts +13 -0
- package/dist/builders/types.d.ts.map +1 -1
- package/dist/config/init.d.ts +8 -0
- package/dist/config/init.d.ts.map +1 -1
- package/dist/config/init.js +304 -193
- package/dist/config/init.js.map +1 -1
- package/dist/config/models.d.ts +112 -0
- package/dist/config/models.d.ts.map +1 -1
- package/dist/config/models.js +329 -18
- package/dist/config/models.js.map +1 -1
- package/dist/coordinator/index.js +2 -2
- package/dist/coordinator/index.js.map +1 -1
- package/dist/index.d.ts +8 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -2
- package/dist/index.js.map +1 -1
- package/dist/platform/azure-devops.d.ts +42 -0
- package/dist/platform/azure-devops.d.ts.map +1 -1
- package/dist/platform/azure-devops.js +75 -0
- package/dist/platform/azure-devops.js.map +1 -1
- package/dist/platform/comms-file-log.d.ts.map +1 -1
- package/dist/platform/comms-file-log.js +2 -1
- package/dist/platform/comms-file-log.js.map +1 -1
- package/dist/platform/index.d.ts +2 -1
- package/dist/platform/index.d.ts.map +1 -1
- package/dist/platform/index.js +1 -0
- package/dist/platform/index.js.map +1 -1
- package/dist/ralph/capabilities.d.ts +67 -0
- package/dist/ralph/capabilities.d.ts.map +1 -0
- package/dist/ralph/capabilities.js +111 -0
- package/dist/ralph/capabilities.js.map +1 -0
- package/dist/ralph/index.d.ts +2 -0
- package/dist/ralph/index.d.ts.map +1 -1
- package/dist/ralph/index.js +6 -5
- package/dist/ralph/index.js.map +1 -1
- package/dist/ralph/rate-limiting.d.ts +99 -0
- package/dist/ralph/rate-limiting.d.ts.map +1 -0
- package/dist/ralph/rate-limiting.js +170 -0
- package/dist/ralph/rate-limiting.js.map +1 -0
- package/dist/resolution.d.ts +24 -2
- package/dist/resolution.d.ts.map +1 -1
- package/dist/resolution.js +106 -6
- package/dist/resolution.js.map +1 -1
- package/dist/roles/catalog-categories.d.ts +146 -0
- package/dist/roles/catalog-categories.d.ts.map +1 -0
- package/dist/roles/catalog-categories.js +374 -0
- package/dist/roles/catalog-categories.js.map +1 -0
- package/dist/roles/catalog-engineering.d.ts +212 -0
- package/dist/roles/catalog-engineering.d.ts.map +1 -0
- package/dist/roles/catalog-engineering.js +549 -0
- package/dist/roles/catalog-engineering.js.map +1 -0
- package/dist/roles/catalog.d.ts +24 -0
- package/dist/roles/catalog.d.ts.map +1 -0
- package/dist/roles/catalog.js +28 -0
- package/dist/roles/catalog.js.map +1 -0
- package/dist/roles/index.d.ts +69 -0
- package/dist/roles/index.d.ts.map +1 -0
- package/dist/roles/index.js +197 -0
- package/dist/roles/index.js.map +1 -0
- package/dist/roles/types.d.ts +87 -0
- package/dist/roles/types.d.ts.map +1 -0
- package/dist/roles/types.js +14 -0
- package/dist/roles/types.js.map +1 -0
- package/dist/runtime/benchmarks.js +5 -5
- package/dist/runtime/benchmarks.js.map +1 -1
- package/dist/runtime/constants.d.ts +2 -2
- package/dist/runtime/constants.d.ts.map +1 -1
- package/dist/runtime/constants.js +5 -3
- package/dist/runtime/constants.js.map +1 -1
- package/dist/runtime/cross-squad.d.ts +118 -0
- package/dist/runtime/cross-squad.d.ts.map +1 -0
- package/dist/runtime/cross-squad.js +234 -0
- package/dist/runtime/cross-squad.js.map +1 -0
- package/dist/runtime/otel-init.d.ts +24 -17
- package/dist/runtime/otel-init.d.ts.map +1 -1
- package/dist/runtime/otel-init.js +29 -20
- package/dist/runtime/otel-init.js.map +1 -1
- package/dist/runtime/otel-metrics.d.ts +5 -0
- package/dist/runtime/otel-metrics.d.ts.map +1 -1
- package/dist/runtime/otel-metrics.js +54 -0
- package/dist/runtime/otel-metrics.js.map +1 -1
- package/dist/runtime/rework.d.ts +71 -0
- package/dist/runtime/rework.d.ts.map +1 -0
- package/dist/runtime/rework.js +107 -0
- package/dist/runtime/rework.js.map +1 -0
- package/dist/runtime/scheduler.d.ts +128 -0
- package/dist/runtime/scheduler.d.ts.map +1 -0
- package/dist/runtime/scheduler.js +427 -0
- package/dist/runtime/scheduler.js.map +1 -0
- package/dist/runtime/squad-observer.d.ts.map +1 -1
- package/dist/runtime/squad-observer.js +4 -0
- package/dist/runtime/squad-observer.js.map +1 -1
- package/dist/runtime/streaming.d.ts +2 -0
- package/dist/runtime/streaming.d.ts.map +1 -1
- package/dist/runtime/streaming.js +6 -0
- package/dist/runtime/streaming.js.map +1 -1
- package/dist/runtime/telemetry.d.ts +2 -0
- package/dist/runtime/telemetry.d.ts.map +1 -1
- package/dist/runtime/telemetry.js +6 -0
- package/dist/runtime/telemetry.js.map +1 -1
- package/dist/sharing/consult.d.ts +2 -2
- package/dist/sharing/consult.js +83 -83
- package/dist/sharing/consult.js.map +1 -1
- package/dist/sharing/export.d.ts.map +1 -1
- package/dist/sharing/export.js +17 -4
- package/dist/sharing/export.js.map +1 -1
- package/dist/skills/handler-types.d.ts +271 -0
- package/dist/skills/handler-types.d.ts.map +1 -0
- package/dist/skills/handler-types.js +31 -0
- package/dist/skills/handler-types.js.map +1 -0
- package/dist/skills/index.d.ts +3 -0
- package/dist/skills/index.d.ts.map +1 -1
- package/dist/skills/index.js +3 -0
- package/dist/skills/index.js.map +1 -1
- package/dist/skills/skill-script-loader.d.ts +65 -0
- package/dist/skills/skill-script-loader.d.ts.map +1 -0
- package/dist/skills/skill-script-loader.js +227 -0
- package/dist/skills/skill-script-loader.js.map +1 -0
- package/dist/skills/skill-source.d.ts.map +1 -1
- package/dist/skills/skill-source.js +5 -1
- package/dist/skills/skill-source.js.map +1 -1
- package/dist/tools/index.d.ts +10 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +49 -8
- package/dist/tools/index.js.map +1 -1
- package/dist/upstream/resolver.d.ts.map +1 -1
- package/dist/upstream/resolver.js +14 -5
- package/dist/upstream/resolver.js.map +1 -1
- package/package.json +34 -3
- package/templates/casting/Futurama.json +10 -0
- package/templates/casting-history.json +4 -4
- package/templates/casting-policy.json +37 -35
- package/templates/casting-reference.md +104 -0
- package/templates/casting-registry.json +3 -3
- package/templates/ceremonies.md +41 -41
- package/templates/charter.md +53 -53
- package/templates/constraint-tracking.md +38 -38
- package/templates/cooperative-rate-limiting.md +229 -0
- package/templates/copilot-instructions.md +46 -46
- package/templates/history.md +10 -10
- package/templates/identity/now.md +9 -9
- package/templates/identity/wisdom.md +15 -15
- package/templates/issue-lifecycle.md +412 -0
- package/templates/keda-scaler.md +164 -0
- package/templates/machine-capabilities.md +75 -0
- package/templates/mcp-config.md +90 -98
- package/templates/multi-agent-format.md +28 -28
- package/templates/orchestration-log.md +27 -27
- package/templates/package.json +3 -0
- package/templates/plugin-marketplace.md +49 -49
- package/templates/ralph-circuit-breaker.md +313 -0
- package/templates/ralph-triage.js +543 -0
- package/templates/raw-agent-output.md +37 -37
- package/templates/roster.md +60 -60
- package/templates/routing.md +39 -54
- package/templates/run-output.md +50 -50
- package/templates/schedule.json +19 -0
- package/templates/scribe-charter.md +119 -119
- package/templates/skill.md +24 -24
- package/templates/skills/agent-collaboration/SKILL.md +42 -0
- package/templates/skills/agent-conduct/SKILL.md +24 -0
- package/templates/skills/architectural-proposals/SKILL.md +151 -0
- package/templates/skills/ci-validation-gates/SKILL.md +84 -0
- package/templates/skills/cli-wiring/SKILL.md +47 -0
- package/templates/skills/client-compatibility/SKILL.md +89 -0
- package/templates/skills/cross-squad/SKILL.md +114 -0
- package/templates/skills/distributed-mesh/SKILL.md +287 -0
- package/templates/skills/distributed-mesh/mesh.json.example +30 -0
- package/templates/skills/distributed-mesh/sync-mesh.ps1 +111 -0
- package/templates/skills/distributed-mesh/sync-mesh.sh +104 -0
- package/templates/skills/docs-standards/SKILL.md +71 -0
- package/templates/skills/economy-mode/SKILL.md +114 -0
- package/templates/skills/external-comms/SKILL.md +329 -0
- package/templates/skills/gh-auth-isolation/SKILL.md +183 -0
- package/templates/skills/git-workflow/SKILL.md +204 -0
- package/templates/skills/github-multi-account/SKILL.md +95 -0
- package/templates/skills/history-hygiene/SKILL.md +36 -0
- package/templates/skills/humanizer/SKILL.md +105 -0
- package/templates/skills/init-mode/SKILL.md +102 -0
- package/templates/skills/model-selection/SKILL.md +117 -0
- package/templates/skills/nap/SKILL.md +24 -0
- package/templates/skills/personal-squad/SKILL.md +57 -0
- package/templates/skills/project-conventions/SKILL.md +56 -56
- package/templates/skills/release-process/SKILL.md +423 -0
- package/templates/skills/reskill/SKILL.md +92 -0
- package/templates/skills/reviewer-protocol/SKILL.md +79 -0
- package/templates/skills/secret-handling/SKILL.md +200 -0
- package/templates/skills/session-recovery/SKILL.md +155 -0
- package/templates/skills/squad-conventions/SKILL.md +69 -0
- package/templates/skills/test-discipline/SKILL.md +37 -0
- package/templates/skills/windows-compatibility/SKILL.md +74 -0
- package/templates/squad.agent.md +1287 -1146
- package/templates/workflows/squad-ci.yml +24 -24
- package/templates/workflows/squad-docs.yml +54 -50
- package/templates/workflows/squad-heartbeat.yml +171 -316
- package/templates/workflows/squad-insider-release.yml +61 -61
- package/templates/workflows/squad-issue-assign.yml +161 -161
- package/templates/workflows/squad-label-enforce.yml +181 -181
- package/templates/workflows/squad-preview.yml +55 -55
- package/templates/workflows/squad-promote.yml +120 -120
- package/templates/workflows/squad-release.yml +77 -77
- package/templates/workflows/squad-triage.yml +260 -260
- package/templates/workflows/sync-squad-labels.yml +169 -169
package/dist/config/init.js
CHANGED
|
@@ -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
|
-
|
|
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(
|
|
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 —
|
|
482
|
-
//
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
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' ?
|
|
511
|
-
configFormat === '
|
|
512
|
-
|
|
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(
|
|
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('.
|
|
757
|
+
createdFiles.push('.copilot/skills');
|
|
647
758
|
}
|
|
648
759
|
}
|
|
649
760
|
// -------------------------------------------------------------------------
|