@bradygaster/squad-sdk 0.6.1 → 0.7.0

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 (2) hide show
  1. package/README.md +266 -20
  2. package/package.json +25 -1
package/README.md CHANGED
@@ -1,50 +1,296 @@
1
1
  # @bradygaster/squad-sdk
2
2
 
3
- Programmable multi-agent runtime for GitHub Copilot. Resolves squad configuration, loads agent teams, and manages the SDK lifecycle.
3
+ **Programmable multi-agent runtime for GitHub Copilot.** Build AI teams that persist, learn, and coordinate with real governance, not vibes.
4
4
 
5
- ## Installation
5
+ [![Status](https://img.shields.io/badge/status-production-brightgreen)](#requirements)
6
+ [![Node](https://img.shields.io/badge/node-%E2%89%A520-green)](#requirements)
7
+ [![ESM](https://img.shields.io/badge/module-ESM--only-blue)](#requirements)
8
+
9
+ ---
10
+
11
+ ## Install
6
12
 
7
13
  ```bash
8
14
  npm install @bradygaster/squad-sdk
9
15
  ```
10
16
 
11
- ## Quick Example
17
+ ---
18
+
19
+ ## What Makes This Different
20
+
21
+ Most multi-agent setups are prompt engineering. You write a wall of text describing who each agent is, what they can do, and hope the model follows the rules. It works — until it doesn't. Agents ignore routing. They write files they shouldn't. They leak data. There's no enforcement, just suggestions.
22
+
23
+ Squad's SDK moves orchestration out of prompts and into code:
24
+
25
+ **Prompt-only orchestration** stuffs everything into a single context window. The coordinator is text. Agents read it, interpret it, maybe follow it.
26
+
27
+ ```
28
+ Prompt says:
29
+ "If the agent is Backend, route auth tasks to it."
30
+ Agent reads it (consumes tokens), decides what to do (might ignore it).
31
+ ```
32
+
33
+ **SDK orchestration** compiles rules into typed functions. Sessions are objects. Routing is deterministic. Tools are validated before execution.
34
+
35
+ ```typescript
36
+ Router.matchRoute(message) → { agent: 'Backend', priority: 'high' }
37
+ // TypeScript knows exactly which agent runs, with what permissions.
38
+ // HookPipeline runs file-write guards BEFORE the tool executes.
39
+ // No interpretation. No ambiguity. Just code.
40
+ ```
41
+
42
+ ---
43
+
44
+ ## Architecture
45
+
46
+ ```
47
+ ┌─────────────────────────────────────────────┐
48
+ │ Your Code (TypeScript) │
49
+ │ - createSession(), spawnParallel() │
50
+ │ - SquadClient, EventBus, HookPipeline │
51
+ └─────────────────────────────────────────────┘
52
+
53
+ ┌─────────────────────────────────────────────┐
54
+ │ Agent Orchestration Runtime │
55
+ │ - Router (matchRoute, compileRoutingRules) │
56
+ │ - Charter Compiler (permissions, voice) │
57
+ │ - Tool Registry (squad_route, etc.) │
58
+ │ - Hook Pipeline (governance enforcement) │
59
+ └─────────────────────────────────────────────┘
60
+
61
+ ┌─────────────────────────────────────────────┐
62
+ │ Session Pool + Event Bus │
63
+ │ - Each agent gets a persistent session │
64
+ │ - Cross-session event pub/sub │
65
+ │ - Crash recovery via session state │
66
+ └─────────────────────────────────────────────┘
67
+
68
+ ┌─────────────────────────────────────────────┐
69
+ │ @github/copilot-sdk │
70
+ │ - Real-time agent streaming │
71
+ │ - Tool execution │
72
+ └─────────────────────────────────────────────┘
73
+ ```
74
+
75
+ Your code sits at the top. The runtime handles routing, permissions, and governance. Sessions are persistent and recoverable. Everything runs on top of the official Copilot SDK.
76
+
77
+ ---
78
+
79
+ ## Custom Tools
80
+
81
+ Five tools let agents coordinate without calling you back. Here are the three you'll reach for first.
82
+
83
+ ### `squad_route` — Hand off work between agents
84
+
85
+ ```typescript
86
+ const tool = toolRegistry.getTool('squad_route');
87
+ await tool.handler({
88
+ targetAgent: 'McManus',
89
+ task: 'Write a blog post on the new casting system',
90
+ priority: 'high',
91
+ context: 'Feature launches next week',
92
+ });
93
+ ```
94
+
95
+ The lead routes a task to DevRel. A new session is created, context is passed, and the task is queued with priority. No human in the loop.
96
+
97
+ ### `squad_decide` — Record a team decision
98
+
99
+ ```typescript
100
+ await tool.handler({
101
+ author: 'Keaton',
102
+ summary: 'Use PostgreSQL, not MongoDB',
103
+ body: 'Chose PostgreSQL for: (1) transactions, (2) team expertise, (3) JSONB flexibility.',
104
+ references: ['architecture-spike'],
105
+ });
106
+ ```
107
+
108
+ Writes to the shared decision log. Every agent reads decisions before working — one call propagates context to the entire team.
109
+
110
+ ### `squad_memory` — Teach an agent something permanent
111
+
112
+ ```typescript
113
+ await tool.handler({
114
+ agent: 'Frontend',
115
+ section: 'learnings',
116
+ content: 'Project uses Tailwind v4 with dark mode plugin. Config at .styles/theme.config.ts',
117
+ });
118
+ ```
119
+
120
+ Agents learn as they work. Next session, Frontend reads this and knows immediately. No context hunting, no re-explaining.
121
+
122
+ > Two more tools — `squad_status` (query the session pool) and `squad_skill` (read/write compressed learnings) — round out the coordination layer. See the [full docs](https://github.com/bradygaster/squad-pr#the-custom-tools) for details.
123
+
124
+ ---
125
+
126
+ ## Hook Pipeline
127
+
128
+ Rules don't live in prompts. They run as code, before tools execute.
129
+
130
+ ### File-Write Guards
131
+
132
+ ```typescript
133
+ const pipeline = new HookPipeline({
134
+ allowedWritePaths: ['src/**/*.ts', '.squad/**', 'docs/**'],
135
+ });
136
+
137
+ // An agent tries to write to /etc/passwd
138
+ // → Blocked. "File write blocked: '/etc/passwd' does not match allowed paths"
139
+ ```
140
+
141
+ No agent — compromised or confused — can write outside your safe zones. Not because you asked nicely in the prompt. Because code won't let them.
142
+
143
+ ### PII Scrubbing
144
+
145
+ ```typescript
146
+ const pipeline = new HookPipeline({
147
+ scrubPii: true,
148
+ });
149
+
150
+ // Agent logs: "contact brady@example.com about deploy"
151
+ // Output becomes: "contact [EMAIL_REDACTED] about deploy"
152
+ ```
153
+
154
+ Sensitive data never escapes. Automatic, invisible to the agent, applied to every tool output.
155
+
156
+ ### Reviewer Lockout
157
+
158
+ ```typescript
159
+ const lockout = pipeline.getReviewerLockout();
160
+ lockout.lockout('src/auth.ts', 'Backend');
161
+
162
+ // Backend tries to re-write auth.ts after a review rejection
163
+ // → Blocked. "Agent 'Backend' is locked out of artifact 'src/auth.ts'"
164
+ ```
165
+
166
+ When a reviewer says "no," it sticks. The original author can't sneak a fix in. Protocol enforced by code, not convention.
167
+
168
+ ### Ask-User Rate Limiter
169
+
170
+ ```typescript
171
+ const pipeline = new HookPipeline({
172
+ maxAskUserPerSession: 3,
173
+ });
174
+
175
+ // Fourth attempt to prompt the user → Blocked.
176
+ // "ask_user rate limit exceeded: 3/3 calls used. Proceed without user input."
177
+ ```
178
+
179
+ Agents don't stall waiting for you. They decide or move on.
180
+
181
+ ---
182
+
183
+ ## Persistent Sessions & Crash Recovery
184
+
185
+ Sessions aren't ephemeral. They're durable objects that survive failures.
186
+
187
+ ```typescript
188
+ const session = await client.createSession({
189
+ agentName: 'Backend',
190
+ task: 'Implement user auth endpoints',
191
+ persistPath: '.squad/sessions/backend-auth-001.json',
192
+ });
193
+
194
+ // Agent dies mid-work — network hiccup, model timeout, anything.
195
+ // Later:
196
+
197
+ const resumed = await client.resumeSession(
198
+ '.squad/sessions/backend-auth-001.json'
199
+ );
200
+
201
+ // Backend wakes up knowing:
202
+ // - What the task was
203
+ // - What it already wrote
204
+ // - Where it left off
205
+ // No repetition, no lost context.
206
+ ```
207
+
208
+ ---
209
+
210
+ ## The Casting Engine
211
+
212
+ Agents aren't `role-1`, `role-2`. They have names, personalities, and persistent identities across sessions. The casting engine assigns them automatically from a thematic universe.
12
213
 
13
214
  ```typescript
14
- import { resolveSquad, loadConfig } from '@bradygaster/squad-sdk';
215
+ const casting = new CastingEngine({
216
+ universe: 'usual-suspects',
217
+ agentCount: 5,
218
+ });
219
+
220
+ const cast = casting.castTeam({
221
+ roles: ['lead', 'frontend', 'backend', 'tester', 'scribe'],
222
+ });
223
+ // → [
224
+ // { role: 'lead', agentName: 'Keaton' },
225
+ // { role: 'frontend', agentName: 'McManus' },
226
+ // { role: 'backend', agentName: 'Verbal' },
227
+ // { role: 'tester', agentName: 'Fenster' },
228
+ // { role: 'scribe', agentName: 'Kobayashi' },
229
+ // ]
230
+ ```
231
+
232
+ Names are memorable ("Keaton handles routing"), persistent (same name every session), and extensible (add a sixth agent — the casting engine picks the next name from the universe). You build a relationship with your agents over time.
233
+
234
+ ---
15
235
 
16
- // Find the .squad/ directory by walking up from cwd
17
- const squadDir = await resolveSquad();
236
+ ## Event-Driven Monitoring
18
237
 
19
- // Load squad configuration
20
- const config = await loadConfig();
238
+ Ralph is the built-in work monitor — a persistent agent session that subscribes to everything happening on the team.
21
239
 
22
- console.log('Loaded team:', config.team.name);
240
+ ```typescript
241
+ const ralph = new RalphMonitor({
242
+ teamRoot: '.squad',
243
+ healthCheckInterval: 30000,
244
+ statePath: '.squad/ralph-state.json',
245
+ });
246
+
247
+ ralph.subscribe('agent:task-complete', (event) => {
248
+ console.log(`✅ ${event.agentName} finished: ${event.task}`);
249
+ });
250
+
251
+ ralph.subscribe('agent:error', (event) => {
252
+ console.log(`❌ ${event.agentName} failed: ${event.error}`);
253
+ });
254
+
255
+ await ralph.start();
23
256
  ```
24
257
 
25
- ## API Overview
258
+ When agents complete work, record decisions, or hit errors — Ralph knows. If an agent crashes, Ralph remembers where it left off.
259
+
260
+ ---
261
+
262
+ ## API Reference
26
263
 
27
264
  | Module | Key Exports | Purpose |
28
265
  |--------|------------|---------|
29
- | `resolution` | `resolveSquad()`, `resolveGlobalSquadPath()`, `ensureSquadPath()` | Walk-up to find `.squad/` directory; platform-specific global squad path; validate paths stay inside `.squad/` |
266
+ | `resolution` | `resolveSquad()`, `resolveGlobalSquadPath()`, `ensureSquadPath()` | Find `.squad/` directory; platform-specific global path; path validation |
30
267
  | `config` | `loadConfig()`, `loadConfigSync()` | Load and parse squad configuration from disk |
31
268
  | `agents` | Agent onboarding utilities | Register and initialize agents; manage team discovery |
32
- | `casting` | Casting engine | Universe selection, name allocation, registry management |
33
- | `skills` | Skills system | Load SKILL.md lifecycle, manage confidence levels |
269
+ | `casting` | `CastingEngine` | Universe selection, name allocation, persistent registry |
270
+ | `skills` | Skills system | SKILL.md lifecycle, confidence levels |
34
271
  | `coordinator` | `selectResponseTier()`, `getTier()` | Route requests to Direct/Lightweight/Standard/Full tiers |
35
- | `runtime` | Streaming pipeline, cost tracker, telemetry, offline mode | Core async execution, event streaming, i18n support |
272
+ | `runtime` | Streaming pipeline, cost tracker, telemetry | Core async execution, event streaming, i18n |
36
273
  | `cli` | `checkForUpdate()`, `performUpgrade()` | SDK version management and update checking |
37
- | `cli` | Output helpers, GitHub utilities | `success()`, `error()`, `warn()`, `info()`, GitHub issue management |
38
- | `marketplace` | Plugin marketplace management | Discover and manage plugins |
274
+ | `marketplace` | Plugin marketplace | Discover and manage plugins |
275
+
276
+ ---
39
277
 
40
278
  ## Requirements
41
279
 
42
- - **Node.js:** ≥20
43
- - **TypeScript:** ≥5.0 (for type definitions)
44
- - **Module system:** ESM-only (no CommonJS)
280
+ - **Node.js** 20.0.0
281
+ - **TypeScript** 5.0
282
+ - **ESM-only** no CommonJS. Set `"type": "module"` in your `package.json`.
283
+
284
+ ---
45
285
 
46
286
  ## Links
47
287
 
48
288
  - **Repository:** [github.com/bradygaster/squad-pr](https://github.com/bradygaster/squad-pr)
289
+ - **CLI package:** [@bradygaster/squad-cli](https://www.npmjs.com/package/@bradygaster/squad-cli)
49
290
  - **Issues:** [github.com/bradygaster/squad-pr/issues](https://github.com/bradygaster/squad-pr/issues)
50
- - **Main README:** [github.com/bradygaster/squad-pr#readme](https://github.com/bradygaster/squad-pr#readme)
291
+
292
+ ---
293
+
294
+ ## License
295
+
296
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bradygaster/squad-sdk",
3
- "version": "0.6.1",
3
+ "version": "0.7.0",
4
4
  "description": "Squad SDK — Programmable multi-agent runtime for GitHub Copilot",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -9,6 +9,30 @@
9
9
  ".": {
10
10
  "types": "./dist/index.d.ts",
11
11
  "import": "./dist/index.js"
12
+ },
13
+ "./parsers": {
14
+ "types": "./dist/parsers.d.ts",
15
+ "import": "./dist/parsers.js"
16
+ },
17
+ "./types": {
18
+ "types": "./dist/types.d.ts",
19
+ "import": "./dist/types.js"
20
+ },
21
+ "./config": {
22
+ "types": "./dist/config/index.d.ts",
23
+ "import": "./dist/config/index.js"
24
+ },
25
+ "./skills": {
26
+ "types": "./dist/skills/index.d.ts",
27
+ "import": "./dist/skills/index.js"
28
+ },
29
+ "./agents": {
30
+ "types": "./dist/agents/index.d.ts",
31
+ "import": "./dist/agents/index.js"
32
+ },
33
+ "./cli": {
34
+ "types": "./dist/cli/index.d.ts",
35
+ "import": "./dist/cli/index.js"
12
36
  }
13
37
  },
14
38
  "files": [