@bradygaster/squad-sdk 0.9.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/README.md +296 -296
  2. package/dist/agents/history-shadow.js +30 -30
  3. package/dist/build/github-dist.js +42 -42
  4. package/dist/config/init.js +173 -173
  5. package/dist/sharing/consult.js +78 -78
  6. package/package.json +1 -1
  7. package/templates/casting/Futurama.json +9 -9
  8. package/templates/casting-history.json +4 -4
  9. package/templates/casting-policy.json +37 -37
  10. package/templates/casting-reference.md +104 -104
  11. package/templates/casting-registry.json +3 -3
  12. package/templates/ceremonies.md +41 -41
  13. package/templates/charter.md +53 -53
  14. package/templates/constraint-tracking.md +38 -38
  15. package/templates/cooperative-rate-limiting.md +229 -229
  16. package/templates/copilot-instructions.md +46 -46
  17. package/templates/history.md +10 -10
  18. package/templates/identity/now.md +9 -9
  19. package/templates/identity/wisdom.md +15 -15
  20. package/templates/issue-lifecycle.md +412 -412
  21. package/templates/keda-scaler.md +164 -164
  22. package/templates/machine-capabilities.md +74 -74
  23. package/templates/mcp-config.md +90 -90
  24. package/templates/multi-agent-format.md +28 -28
  25. package/templates/plugin-marketplace.md +49 -49
  26. package/templates/ralph-circuit-breaker.md +313 -313
  27. package/templates/raw-agent-output.md +37 -37
  28. package/templates/roster.md +60 -60
  29. package/templates/routing.md +39 -39
  30. package/templates/run-output.md +50 -50
  31. package/templates/schedule.json +19 -19
  32. package/templates/scribe-charter.md +119 -119
  33. package/templates/skill.md +24 -24
  34. package/templates/skills/agent-collaboration/SKILL.md +42 -42
  35. package/templates/skills/agent-conduct/SKILL.md +24 -24
  36. package/templates/skills/architectural-proposals/SKILL.md +151 -151
  37. package/templates/skills/ci-validation-gates/SKILL.md +84 -84
  38. package/templates/skills/cli-wiring/SKILL.md +47 -47
  39. package/templates/skills/client-compatibility/SKILL.md +89 -89
  40. package/templates/skills/cross-squad/SKILL.md +114 -114
  41. package/templates/skills/distributed-mesh/SKILL.md +287 -287
  42. package/templates/skills/distributed-mesh/mesh.json.example +30 -30
  43. package/templates/skills/distributed-mesh/sync-mesh.ps1 +111 -111
  44. package/templates/skills/distributed-mesh/sync-mesh.sh +104 -104
  45. package/templates/skills/docs-standards/SKILL.md +71 -71
  46. package/templates/skills/economy-mode/SKILL.md +114 -114
  47. package/templates/skills/external-comms/SKILL.md +329 -329
  48. package/templates/skills/gh-auth-isolation/SKILL.md +183 -183
  49. package/templates/skills/git-workflow/SKILL.md +204 -204
  50. package/templates/skills/github-multi-account/SKILL.md +95 -95
  51. package/templates/skills/history-hygiene/SKILL.md +36 -36
  52. package/templates/skills/humanizer/SKILL.md +105 -105
  53. package/templates/skills/init-mode/SKILL.md +102 -102
  54. package/templates/skills/model-selection/SKILL.md +117 -117
  55. package/templates/skills/nap/SKILL.md +24 -24
  56. package/templates/skills/personal-squad/SKILL.md +57 -57
  57. package/templates/skills/project-conventions/SKILL.md +56 -56
  58. package/templates/skills/release-process/SKILL.md +423 -423
  59. package/templates/skills/reskill/SKILL.md +92 -92
  60. package/templates/skills/reviewer-protocol/SKILL.md +79 -79
  61. package/templates/skills/secret-handling/SKILL.md +200 -200
  62. package/templates/skills/session-recovery/SKILL.md +155 -155
  63. package/templates/skills/squad-conventions/SKILL.md +69 -69
  64. package/templates/skills/test-discipline/SKILL.md +37 -37
  65. package/templates/skills/windows-compatibility/SKILL.md +74 -74
  66. package/templates/workflows/squad-ci.yml +24 -24
  67. package/templates/workflows/squad-docs.yml +54 -54
  68. package/templates/workflows/squad-heartbeat.yml +171 -171
  69. package/templates/workflows/squad-insider-release.yml +61 -61
  70. package/templates/workflows/squad-issue-assign.yml +161 -161
  71. package/templates/workflows/squad-label-enforce.yml +181 -181
  72. package/templates/workflows/squad-preview.yml +55 -55
  73. package/templates/workflows/squad-promote.yml +120 -120
  74. package/templates/workflows/squad-release.yml +77 -77
  75. package/templates/workflows/squad-triage.yml +260 -260
  76. package/templates/workflows/sync-squad-labels.yml +169 -169
@@ -13,27 +13,27 @@ const DEFAULT_CONFIG = {
13
13
  */
14
14
  export function generateInstallScript(config) {
15
15
  const c = resolveConfig(config);
16
- return `#!/usr/bin/env bash
17
- set -euo pipefail
18
-
19
- OWNER="${c.owner}"
20
- REPO="${c.repo}"
21
- BINARY="${c.binaryName}"
22
-
23
- # Detect latest version from GitHub API
24
- VERSION=\${1:-$(curl -sL "https://api.github.com/repos/\${OWNER}/\${REPO}/releases/latest" | grep '"tag_name"' | sed -E 's/.*"v?([^"]+)".*/\\1/')}
25
-
26
- echo "Installing \${BINARY} v\${VERSION}..."
27
-
28
- DOWNLOAD_URL="https://github.com/\${OWNER}/\${REPO}/releases/download/v\${VERSION}/\${BINARY}-\${VERSION}.tar.gz"
29
- INSTALL_DIR="\${HOME}/.local/bin"
30
-
31
- mkdir -p "\${INSTALL_DIR}"
32
- curl -sL "\${DOWNLOAD_URL}" | tar xz -C "\${INSTALL_DIR}"
33
- chmod +x "\${INSTALL_DIR}/\${BINARY}"
34
-
35
- echo "\${BINARY} v\${VERSION} installed to \${INSTALL_DIR}/\${BINARY}"
36
- echo "Make sure \${INSTALL_DIR} is in your PATH."
16
+ return `#!/usr/bin/env bash
17
+ set -euo pipefail
18
+
19
+ OWNER="${c.owner}"
20
+ REPO="${c.repo}"
21
+ BINARY="${c.binaryName}"
22
+
23
+ # Detect latest version from GitHub API
24
+ VERSION=\${1:-$(curl -sL "https://api.github.com/repos/\${OWNER}/\${REPO}/releases/latest" | grep '"tag_name"' | sed -E 's/.*"v?([^"]+)".*/\\1/')}
25
+
26
+ echo "Installing \${BINARY} v\${VERSION}..."
27
+
28
+ DOWNLOAD_URL="https://github.com/\${OWNER}/\${REPO}/releases/download/v\${VERSION}/\${BINARY}-\${VERSION}.tar.gz"
29
+ INSTALL_DIR="\${HOME}/.local/bin"
30
+
31
+ mkdir -p "\${INSTALL_DIR}"
32
+ curl -sL "\${DOWNLOAD_URL}" | tar xz -C "\${INSTALL_DIR}"
33
+ chmod +x "\${INSTALL_DIR}/\${BINARY}"
34
+
35
+ echo "\${BINARY} v\${VERSION} installed to \${INSTALL_DIR}/\${BINARY}"
36
+ echo "Make sure \${INSTALL_DIR} is in your PATH."
37
37
  `;
38
38
  }
39
39
  /**
@@ -75,27 +75,27 @@ export function getInstallCommand(config) {
75
75
  * Generate the bin script that runs when npx invokes the package.
76
76
  */
77
77
  export function generateNpxEntryPoint() {
78
- return `#!/usr/bin/env node
79
- import { createRequire } from 'node:module';
80
- import { fileURLToPath } from 'node:url';
81
- import { dirname, join } from 'node:path';
82
-
83
- const __filename = fileURLToPath(import.meta.url);
84
- const __dirname = dirname(__filename);
85
-
86
- async function main() {
87
- try {
88
- const { main: run } = await import(join(__dirname, 'index.js'));
89
- if (typeof run === 'function') {
90
- await run();
91
- }
92
- } catch (err) {
93
- console.error('squad: failed to start —', err instanceof Error ? err.message : err);
94
- process.exit(1);
95
- }
96
- }
97
-
98
- main();
78
+ return `#!/usr/bin/env node
79
+ import { createRequire } from 'node:module';
80
+ import { fileURLToPath } from 'node:url';
81
+ import { dirname, join } from 'node:path';
82
+
83
+ const __filename = fileURLToPath(import.meta.url);
84
+ const __dirname = dirname(__filename);
85
+
86
+ async function main() {
87
+ try {
88
+ const { main: run } = await import(join(__dirname, 'index.js'));
89
+ if (typeof run === 'function') {
90
+ await run();
91
+ }
92
+ } catch (err) {
93
+ console.error('squad: failed to start —', err instanceof Error ? err.message : err);
94
+ process.exit(1);
95
+ }
96
+ }
97
+
98
+ main();
99
99
  `;
100
100
  }
101
101
  /**
@@ -95,82 +95,82 @@ function formatModelArray(chain) {
95
95
  */
96
96
  function generateTypeScriptConfig(options) {
97
97
  const { projectName, projectDescription, agents } = options;
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;
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;
174
174
  `;
175
175
  }
176
176
  /**
@@ -367,26 +367,26 @@ function generateCharter(agent, projectName, projectDescription) {
367
367
  const template = AGENT_TEMPLATES[agent.role];
368
368
  const displayName = agent.displayName || template?.displayName || titleCase(agent.name);
369
369
  const description = template?.description || 'Team member focused on their assigned responsibilities.';
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
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
390
390
  `;
391
391
  }
392
392
  /**
@@ -395,22 +395,22 @@ ${projectDescription ? `**Description:** ${projectDescription}\n` : ''}
395
395
  function generateInitialHistory(agent, projectName, projectDescription, userName) {
396
396
  const displayName = agent.displayName || AGENT_TEMPLATES[agent.role]?.displayName || titleCase(agent.name);
397
397
  const now = new Date().toISOString().split('T')[0];
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.
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.
414
414
  `;
415
415
  }
416
416
  /**
@@ -650,27 +650,27 @@ export async function initSquad(options) {
650
650
  const identityDir = join(squadDir, 'identity');
651
651
  const nowMdPath = join(identityDir, 'now.md');
652
652
  const wisdomMdPath = join(identityDir, 'wisdom.md');
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.
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.
662
662
  `;
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. -->
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. -->
674
674
  `;
675
675
  await writeIfNotExists(nowMdPath, nowContent);
676
676
  await writeIfNotExists(wisdomMdPath, wisdomContent);
@@ -685,42 +685,42 @@ Reusable patterns and heuristics learned through work. NOT transcripts — each
685
685
  // Create decisions.md (canonical location at squad root)
686
686
  // -------------------------------------------------------------------------
687
687
  const decisionsPath = join(squadDir, 'decisions.md');
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
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
699
699
  `;
700
700
  await writeIfNotExists(decisionsPath, decisionsContent);
701
701
  // -------------------------------------------------------------------------
702
702
  // Create team.md (required by shell lifecycle)
703
703
  // -------------------------------------------------------------------------
704
704
  const teamPath = join(squadDir, 'team.md');
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]}
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]}
724
724
  `;
725
725
  await writeIfNotExists(teamPath, teamContent);
726
726
  // -------------------------------------------------------------------------
@@ -731,17 +731,17 @@ ${projectDescription ? `- **Description:** ${projectDescription}\n` : ''}- **Cre
731
731
  await copyIfNotExists(join(templatesDir, 'routing.md'), routingPath);
732
732
  }
733
733
  else {
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
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
745
745
  `;
746
746
  await writeIfNotExists(routingPath, routingContent);
747
747
  }