@os-eco/overstory-cli 0.6.1 → 0.6.5

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 (110) hide show
  1. package/README.md +8 -7
  2. package/package.json +12 -4
  3. package/src/agents/checkpoint.test.ts +2 -2
  4. package/src/agents/hooks-deployer.test.ts +131 -16
  5. package/src/agents/hooks-deployer.ts +33 -1
  6. package/src/agents/identity.test.ts +27 -27
  7. package/src/agents/identity.ts +10 -10
  8. package/src/agents/lifecycle.test.ts +6 -6
  9. package/src/agents/lifecycle.ts +2 -2
  10. package/src/agents/manifest.test.ts +86 -0
  11. package/src/agents/overlay.test.ts +9 -9
  12. package/src/agents/overlay.ts +4 -4
  13. package/src/commands/agents.test.ts +8 -8
  14. package/src/commands/agents.ts +62 -91
  15. package/src/commands/clean.test.ts +36 -51
  16. package/src/commands/clean.ts +28 -49
  17. package/src/commands/completions.ts +14 -0
  18. package/src/commands/coordinator.test.ts +133 -26
  19. package/src/commands/coordinator.ts +101 -64
  20. package/src/commands/costs.test.ts +47 -47
  21. package/src/commands/costs.ts +96 -75
  22. package/src/commands/dashboard.test.ts +2 -2
  23. package/src/commands/dashboard.ts +75 -95
  24. package/src/commands/doctor.test.ts +2 -2
  25. package/src/commands/doctor.ts +92 -79
  26. package/src/commands/errors.test.ts +2 -2
  27. package/src/commands/errors.ts +56 -50
  28. package/src/commands/feed.test.ts +2 -2
  29. package/src/commands/feed.ts +86 -83
  30. package/src/commands/group.ts +167 -177
  31. package/src/commands/hooks.test.ts +2 -2
  32. package/src/commands/hooks.ts +52 -42
  33. package/src/commands/init.test.ts +19 -19
  34. package/src/commands/init.ts +7 -16
  35. package/src/commands/inspect.test.ts +18 -18
  36. package/src/commands/inspect.ts +55 -58
  37. package/src/commands/log.test.ts +26 -31
  38. package/src/commands/log.ts +97 -91
  39. package/src/commands/logs.test.ts +1 -1
  40. package/src/commands/logs.ts +101 -104
  41. package/src/commands/mail.test.ts +5 -5
  42. package/src/commands/mail.ts +157 -169
  43. package/src/commands/merge.test.ts +28 -66
  44. package/src/commands/merge.ts +21 -51
  45. package/src/commands/metrics.test.ts +8 -8
  46. package/src/commands/metrics.ts +34 -35
  47. package/src/commands/monitor.test.ts +3 -3
  48. package/src/commands/monitor.ts +57 -62
  49. package/src/commands/nudge.test.ts +1 -1
  50. package/src/commands/nudge.ts +41 -89
  51. package/src/commands/prime.test.ts +19 -51
  52. package/src/commands/prime.ts +13 -50
  53. package/src/commands/replay.test.ts +2 -2
  54. package/src/commands/replay.ts +79 -86
  55. package/src/commands/run.test.ts +1 -1
  56. package/src/commands/run.ts +97 -77
  57. package/src/commands/sling.test.ts +201 -5
  58. package/src/commands/sling.ts +37 -64
  59. package/src/commands/spec.test.ts +14 -40
  60. package/src/commands/spec.ts +32 -101
  61. package/src/commands/status.test.ts +97 -1
  62. package/src/commands/status.ts +63 -58
  63. package/src/commands/stop.test.ts +22 -40
  64. package/src/commands/stop.ts +18 -33
  65. package/src/commands/supervisor.test.ts +12 -14
  66. package/src/commands/supervisor.ts +144 -165
  67. package/src/commands/trace.test.ts +15 -15
  68. package/src/commands/trace.ts +59 -82
  69. package/src/commands/watch.test.ts +2 -2
  70. package/src/commands/watch.ts +38 -45
  71. package/src/commands/worktree.test.ts +213 -37
  72. package/src/commands/worktree.ts +110 -55
  73. package/src/config.test.ts +96 -0
  74. package/src/doctor/consistency.test.ts +14 -14
  75. package/src/doctor/databases.test.ts +22 -2
  76. package/src/doctor/databases.ts +16 -0
  77. package/src/doctor/dependencies.test.ts +55 -1
  78. package/src/doctor/dependencies.ts +113 -18
  79. package/src/doctor/merge-queue.test.ts +4 -4
  80. package/src/e2e/init-sling-lifecycle.test.ts +8 -8
  81. package/src/errors.ts +1 -1
  82. package/src/index.ts +223 -213
  83. package/src/logging/color.test.ts +74 -91
  84. package/src/logging/color.ts +52 -46
  85. package/src/logging/reporter.test.ts +10 -10
  86. package/src/logging/reporter.ts +6 -5
  87. package/src/mail/broadcast.test.ts +1 -1
  88. package/src/mail/client.test.ts +6 -6
  89. package/src/mail/store.test.ts +3 -3
  90. package/src/merge/queue.test.ts +73 -7
  91. package/src/merge/queue.ts +17 -2
  92. package/src/merge/resolver.test.ts +159 -7
  93. package/src/merge/resolver.ts +46 -2
  94. package/src/metrics/store.test.ts +44 -44
  95. package/src/metrics/store.ts +2 -2
  96. package/src/metrics/summary.test.ts +35 -35
  97. package/src/mulch/client.test.ts +1 -1
  98. package/src/schema-consistency.test.ts +239 -0
  99. package/src/sessions/compat.test.ts +3 -3
  100. package/src/sessions/compat.ts +2 -2
  101. package/src/sessions/store.test.ts +41 -4
  102. package/src/sessions/store.ts +13 -2
  103. package/src/types.ts +14 -14
  104. package/src/watchdog/daemon.test.ts +10 -10
  105. package/src/watchdog/daemon.ts +1 -1
  106. package/src/watchdog/health.test.ts +1 -1
  107. package/src/worktree/manager.test.ts +20 -20
  108. package/src/worktree/manager.ts +120 -4
  109. package/src/worktree/tmux.test.ts +98 -9
  110. package/src/worktree/tmux.ts +18 -0
@@ -10,7 +10,8 @@
10
10
  */
11
11
 
12
12
  import { join } from "node:path";
13
- import { AgentError, ValidationError } from "../errors.ts";
13
+ import { Command } from "commander";
14
+ import { AgentError } from "../errors.ts";
14
15
  import { createEventStore } from "../events/store.ts";
15
16
  import { openSessionStore } from "../sessions/compat.ts";
16
17
  import type { EventStore } from "../types.ts";
@@ -21,44 +22,6 @@ const MAX_RETRIES = 3;
21
22
  const RETRY_DELAY_MS = 500;
22
23
  const DEBOUNCE_MS = 500;
23
24
 
24
- /**
25
- * Parse a named flag value from args.
26
- */
27
- function getFlag(args: string[], flag: string): string | undefined {
28
- const idx = args.indexOf(flag);
29
- if (idx === -1 || idx + 1 >= args.length) {
30
- return undefined;
31
- }
32
- return args[idx + 1];
33
- }
34
-
35
- /** Boolean flags that do NOT consume the next arg. */
36
- const BOOLEAN_FLAGS = new Set(["--json", "--force", "--help", "-h"]);
37
-
38
- /**
39
- * Extract positional arguments, skipping flag-value pairs.
40
- */
41
- function getPositionalArgs(args: string[]): string[] {
42
- const positional: string[] = [];
43
- let i = 0;
44
- while (i < args.length) {
45
- const arg = args[i];
46
- if (arg?.startsWith("-")) {
47
- if (BOOLEAN_FLAGS.has(arg)) {
48
- i += 1;
49
- } else {
50
- i += 2;
51
- }
52
- } else {
53
- if (arg !== undefined) {
54
- positional.push(arg);
55
- }
56
- i += 1;
57
- }
58
- }
59
- return positional;
60
- }
61
-
62
25
  /**
63
26
  * Load the orchestrator's registered tmux session name.
64
27
  *
@@ -317,56 +280,45 @@ export async function nudgeAgent(
317
280
  /**
318
281
  * Entry point for `overstory nudge <agent-name> [message]`.
319
282
  */
320
- const NUDGE_HELP = `overstory nudge — Send a text nudge to an agent
321
-
322
- Usage: overstory nudge <agent-name> [message]
323
-
324
- Arguments:
325
- <agent-name> Name of the agent to nudge
326
- [message] Text to send (default: "${DEFAULT_MESSAGE}")
327
-
328
- Options:
329
- --from <name> Sender name for the nudge prefix (default: orchestrator)
330
- --force Skip debounce check
331
- --json Output result as JSON
332
- --help, -h Show this help`;
333
-
334
283
  export async function nudgeCommand(args: string[]): Promise<void> {
335
- if (args.includes("--help") || args.includes("-h")) {
336
- process.stdout.write(`${NUDGE_HELP}\n`);
337
- return;
338
- }
339
-
340
- const positional = getPositionalArgs(args);
341
- const agentName = positional[0];
342
- if (!agentName || agentName.trim().length === 0) {
343
- throw new ValidationError("Agent name is required: overstory nudge <agent-name> [message]", {
344
- field: "agentName",
345
- });
346
- }
347
-
348
- const from = getFlag(args, "--from") ?? "orchestrator";
349
- const force = args.includes("--force");
350
- const json = args.includes("--json");
351
-
352
- // Build the nudge message: prefix with sender, use custom or default text
353
- const customMessage = positional.slice(1).join(" ");
354
- const rawMessage = customMessage.length > 0 ? customMessage : DEFAULT_MESSAGE;
355
- const message = `[NUDGE from ${from}] ${rawMessage}`;
356
-
357
- // Resolve project root
358
- const { resolveProjectRoot } = await import("../config.ts");
359
- const projectRoot = await resolveProjectRoot(process.cwd());
360
-
361
- const result = await nudgeAgent(projectRoot, agentName, message, force);
362
-
363
- if (json) {
364
- process.stdout.write(
365
- `${JSON.stringify({ agentName, delivered: result.delivered, reason: result.reason })}\n`,
284
+ const program = new Command();
285
+ program
286
+ .name("overstory nudge")
287
+ .description("Send a text nudge to an agent")
288
+ .argument("<agent-name>", "Name of the agent to nudge")
289
+ .argument("[message...]", "Text to send (default: check mail prompt)")
290
+ .option("--from <name>", "Sender name", "orchestrator")
291
+ .option("--force", "Skip debounce check")
292
+ .option("--json", "Output result as JSON")
293
+ .exitOverride()
294
+ .action(
295
+ async (
296
+ agentName: string,
297
+ messageParts: string[],
298
+ opts: { from: string; force?: boolean; json?: boolean },
299
+ ) => {
300
+ // Build the nudge message: prefix with sender, use custom or default text
301
+ const customMessage = messageParts.join(" ");
302
+ const rawMessage = customMessage.length > 0 ? customMessage : DEFAULT_MESSAGE;
303
+ const message = `[NUDGE from ${opts.from}] ${rawMessage}`;
304
+
305
+ // Resolve project root
306
+ const { resolveProjectRoot } = await import("../config.ts");
307
+ const projectRoot = await resolveProjectRoot(process.cwd());
308
+
309
+ const result = await nudgeAgent(projectRoot, agentName, message, opts.force ?? false);
310
+
311
+ if (opts.json) {
312
+ process.stdout.write(
313
+ `${JSON.stringify({ agentName, delivered: result.delivered, reason: result.reason })}\n`,
314
+ );
315
+ } else if (result.delivered) {
316
+ process.stdout.write(`📢 Nudged "${agentName}"\n`);
317
+ } else {
318
+ throw new AgentError(`Nudge failed: ${result.reason}`, { agentName });
319
+ }
320
+ },
366
321
  );
367
- } else if (result.delivered) {
368
- process.stdout.write(`📢 Nudged "${agentName}"\n`);
369
- } else {
370
- throw new AgentError(`Nudge failed: ${result.reason}`, { agentName });
371
- }
322
+
323
+ await program.parseAsync(["node", "overstory-nudge", ...args]);
372
324
  }
@@ -66,41 +66,9 @@ describe("primeCommand", () => {
66
66
  return stderrChunks.join("");
67
67
  }
68
68
 
69
- describe("Help", () => {
70
- test("--help shows help text", async () => {
71
- await primeCommand(["--help"]);
72
- const out = output();
73
-
74
- expect(out).toContain("overstory prime");
75
- expect(out).toContain("--agent");
76
- expect(out).toContain("--compact");
77
- });
78
-
79
- test("-h shows help text", async () => {
80
- await primeCommand(["-h"]);
81
- const out = output();
82
-
83
- expect(out).toContain("overstory prime");
84
- expect(out).toContain("--agent");
85
- expect(out).toContain("--compact");
86
- });
87
- });
88
-
89
- describe("parseArgs validation", () => {
90
- test("--agent without a name throws AgentError", async () => {
91
- await expect(primeCommand(["--agent"])).rejects.toThrow("--agent requires a name argument");
92
- });
93
-
94
- test("--agent followed by another flag throws AgentError", async () => {
95
- await expect(primeCommand(["--agent", "--compact"])).rejects.toThrow(
96
- "--agent requires a name argument",
97
- );
98
- });
99
- });
100
-
101
69
  describe("Orchestrator priming (no --agent flag)", () => {
102
70
  test("default prime outputs project context", async () => {
103
- await primeCommand([]);
71
+ await primeCommand({});
104
72
  const out = output();
105
73
 
106
74
  expect(out).toContain("# Overstory Context");
@@ -111,7 +79,7 @@ describe("primeCommand", () => {
111
79
  });
112
80
 
113
81
  test("includes agent manifest section", async () => {
114
- await primeCommand([]);
82
+ await primeCommand({});
115
83
  const out = output();
116
84
 
117
85
  expect(out).toContain("## Agent Manifest");
@@ -120,7 +88,7 @@ describe("primeCommand", () => {
120
88
  });
121
89
 
122
90
  test("without metrics.db shows no recent sessions message", async () => {
123
- await primeCommand([]);
91
+ await primeCommand({});
124
92
  const out = output();
125
93
 
126
94
  expect(out).toContain("## Recent Activity");
@@ -128,7 +96,7 @@ describe("primeCommand", () => {
128
96
  });
129
97
 
130
98
  test("--compact skips Recent Activity and Expertise sections", async () => {
131
- await primeCommand(["--compact"]);
99
+ await primeCommand({ compact: true });
132
100
  const out = output();
133
101
 
134
102
  // Should still have project basics
@@ -143,7 +111,7 @@ describe("primeCommand", () => {
143
111
 
144
112
  describe("Agent priming (--agent <name>)", () => {
145
113
  test("unknown agent outputs basic context and warns", async () => {
146
- await primeCommand(["--agent", "unknown-agent"]);
114
+ await primeCommand({ agent: "unknown-agent" });
147
115
  const out = output();
148
116
  const err = stderr();
149
117
 
@@ -166,13 +134,13 @@ expertiseDomains:
166
134
  - typescript
167
135
  - testing
168
136
  recentTasks:
169
- - beadId: task-001
137
+ - taskId: task-001
170
138
  summary: "Implemented feature X"
171
139
  completedAt: "2026-01-10T12:00:00Z"
172
140
  `,
173
141
  );
174
142
 
175
- await primeCommand(["--agent", "my-builder"]);
143
+ await primeCommand({ agent: "my-builder" });
176
144
  const out = output();
177
145
 
178
146
  expect(out).toContain("# Agent Context: my-builder");
@@ -193,7 +161,7 @@ recentTasks:
193
161
  capability: "builder",
194
162
  worktreePath: join(tempDir, ".overstory", "worktrees", "active-builder"),
195
163
  branchName: "overstory/active-builder/task-001",
196
- beadId: "task-001",
164
+ taskId: "task-001",
197
165
  tmuxSession: "overstory-active-builder",
198
166
  state: "working",
199
167
  pid: 12345,
@@ -212,7 +180,7 @@ recentTasks:
212
180
  `${JSON.stringify(sessions, null, 2)}\n`,
213
181
  );
214
182
 
215
- await primeCommand(["--agent", "active-builder"]);
183
+ await primeCommand({ agent: "active-builder" });
216
184
  const out = output();
217
185
 
218
186
  expect(out).toContain("# Agent Context: active-builder");
@@ -230,7 +198,7 @@ recentTasks:
230
198
  capability: "builder",
231
199
  worktreePath: join(tempDir, ".overstory", "worktrees", "completed-builder"),
232
200
  branchName: "overstory/completed-builder/task-002",
233
- beadId: "task-002",
201
+ taskId: "task-002",
234
202
  tmuxSession: "overstory-completed-builder",
235
203
  state: "completed",
236
204
  pid: null,
@@ -249,7 +217,7 @@ recentTasks:
249
217
  `${JSON.stringify(sessions, null, 2)}\n`,
250
218
  );
251
219
 
252
- await primeCommand(["--agent", "completed-builder"]);
220
+ await primeCommand({ agent: "completed-builder" });
253
221
  const out = output();
254
222
 
255
223
  expect(out).toContain("# Agent Context: completed-builder");
@@ -265,7 +233,7 @@ recentTasks:
265
233
  `${JSON.stringify(
266
234
  {
267
235
  agentName: "recovery-agent",
268
- beadId: "task-003",
236
+ taskId: "task-003",
269
237
  sessionId: "session-003",
270
238
  timestamp: new Date().toISOString(),
271
239
  progressSummary: "Implemented initial tests for prime command",
@@ -291,7 +259,7 @@ recentTasks: []
291
259
  `,
292
260
  );
293
261
 
294
- await primeCommand(["--agent", "recovery-agent", "--compact"]);
262
+ await primeCommand({ agent: "recovery-agent", compact: true });
295
263
  const out = output();
296
264
 
297
265
  expect(out).toContain("# Agent Context: recovery-agent");
@@ -317,7 +285,7 @@ recentTasks: []
317
285
  `,
318
286
  );
319
287
 
320
- await primeCommand(["--agent", "compact-agent", "--compact"]);
288
+ await primeCommand({ agent: "compact-agent", compact: true });
321
289
  const out = output();
322
290
 
323
291
  expect(out).toContain("# Agent Context: compact-agent");
@@ -340,7 +308,7 @@ recentTasks: []
340
308
  // Save and change cwd to the git repo
341
309
  process.chdir(gitRepoDir);
342
310
 
343
- await primeCommand([]);
311
+ await primeCommand({});
344
312
  const out = output();
345
313
 
346
314
  expect(out).toContain("# Overstory Context");
@@ -375,7 +343,7 @@ recentTasks: []
375
343
 
376
344
  process.chdir(gitRepoDir);
377
345
 
378
- await primeCommand([]);
346
+ await primeCommand({});
379
347
  const out = output();
380
348
 
381
349
  expect(out).toContain("Session branch: feature/my-work (merge target)");
@@ -412,7 +380,7 @@ recentTasks: []
412
380
  expect(existsBefore).toBe(false);
413
381
 
414
382
  // Run primeCommand
415
- await primeCommand([]);
383
+ await primeCommand({});
416
384
 
417
385
  // Verify .gitignore was created with correct content
418
386
  const content = await Bun.file(gitignorePath).text();
@@ -435,7 +403,7 @@ sessions.db
435
403
  expect(contentBefore).toBe(staleContent);
436
404
 
437
405
  // Run primeCommand
438
- await primeCommand([]);
406
+ await primeCommand({});
439
407
 
440
408
  // Verify .gitignore now has the wildcard+whitelist content
441
409
  const contentAfter = await Bun.file(gitignorePath).text();
@@ -455,7 +423,7 @@ sessions.db
455
423
  await new Promise((resolve) => setTimeout(resolve, 10));
456
424
 
457
425
  // Run primeCommand
458
- await primeCommand([]);
426
+ await primeCommand({});
459
427
 
460
428
  // Verify content is still correct
461
429
  const contentAfter = await Bun.file(gitignorePath).text();
@@ -12,7 +12,6 @@ import { loadCheckpoint } from "../agents/checkpoint.ts";
12
12
  import { loadIdentity } from "../agents/identity.ts";
13
13
  import { createManifestLoader } from "../agents/manifest.ts";
14
14
  import { loadConfig } from "../config.ts";
15
- import { AgentError } from "../errors.ts";
16
15
  import { createMetricsStore } from "../metrics/store.ts";
17
16
  import { createMulchClient } from "../mulch/client.ts";
18
17
  import { openSessionStore } from "../sessions/compat.ts";
@@ -35,32 +34,9 @@ const OVERSTORY_GITIGNORE = `# Wildcard+whitelist: ignore everything, whitelist
35
34
  !agent-defs/
36
35
  `;
37
36
 
38
- /**
39
- * Parse CLI flags from the args array.
40
- *
41
- * Supports:
42
- * - `--agent <name>` — Prime for a specific agent
43
- * - `--compact` — Output reduced context
44
- */
45
- function parseArgs(args: string[]): { agentName: string | null; compact: boolean } {
46
- let agentName: string | null = null;
47
- let compact = false;
48
-
49
- for (let i = 0; i < args.length; i++) {
50
- const arg = args[i];
51
- if (arg === "--agent") {
52
- const next = args[i + 1];
53
- if (next === undefined || next.startsWith("--")) {
54
- throw new AgentError("--agent requires a name argument");
55
- }
56
- agentName = next;
57
- i++; // Skip the value
58
- } else if (arg === "--compact") {
59
- compact = true;
60
- }
61
- }
62
-
63
- return { agentName, compact };
37
+ export interface PrimeOptions {
38
+ agent?: string;
39
+ compact?: boolean;
64
40
  }
65
41
 
66
42
  /**
@@ -89,7 +65,7 @@ function formatMetrics(sessions: SessionMetrics[]): string {
89
65
  const status = s.completedAt !== null ? "completed" : "in-progress";
90
66
  const duration = s.durationMs > 0 ? ` (${Math.round(s.durationMs / 1000)}s)` : "";
91
67
  const merge = s.mergeResult !== null ? ` [${s.mergeResult}]` : "";
92
- lines.push(`- ${s.agentName} (${s.capability}): ${s.beadId} — ${status}${duration}${merge}`);
68
+ lines.push(`- ${s.agentName} (${s.capability}): ${s.taskId} — ${status}${duration}${merge}`);
93
69
  }
94
70
  return lines.join("\n");
95
71
  }
@@ -110,7 +86,7 @@ function formatIdentity(identity: AgentIdentity): string {
110
86
  if (identity.recentTasks.length > 0) {
111
87
  lines.push("Recent tasks:");
112
88
  for (const task of identity.recentTasks) {
113
- lines.push(` - ${task.beadId}: ${task.summary} (${task.completedAt})`);
89
+ lines.push(` - ${task.taskId}: ${task.summary} (${task.completedAt})`);
114
90
  }
115
91
  }
116
92
 
@@ -156,24 +132,11 @@ async function healGitignore(overstoryDir: string): Promise<void> {
156
132
  * Gathers project state and outputs context to stdout for injection
157
133
  * into Claude Code's context.
158
134
  *
159
- * @param args - CLI arguments after "prime" subcommand
135
+ * @param opts - Command options
160
136
  */
161
- const PRIME_HELP = `overstory prime Load context for orchestrator/agent
162
-
163
- Usage: overstory prime [--agent <name>] [--compact]
164
-
165
- Options:
166
- --agent <name> Prime for a specific agent (default: orchestrator)
167
- --compact Output reduced context (for PreCompact hook)
168
- --help, -h Show this help`;
169
-
170
- export async function primeCommand(args: string[]): Promise<void> {
171
- if (args.includes("--help") || args.includes("-h")) {
172
- process.stdout.write(`${PRIME_HELP}\n`);
173
- return;
174
- }
175
-
176
- const { agentName, compact } = parseArgs(args);
137
+ export async function primeCommand(opts: PrimeOptions): Promise<void> {
138
+ const agentName = opts.agent ?? null;
139
+ const compact = opts.compact ?? false;
177
140
 
178
141
  // 1. Load config
179
142
  const config = await loadConfig(process.cwd());
@@ -221,7 +184,7 @@ async function outputAgentContext(
221
184
  const overstoryDir = join(config.project.root, ".overstory");
222
185
  const { store } = openSessionStore(overstoryDir);
223
186
  let sessionExists = false;
224
- let boundSession: { beadId: string } | null = null;
187
+ let boundSession: { taskId: string } | null = null;
225
188
  try {
226
189
  const agentSession = store.getByName(agentName);
227
190
  sessionExists = agentSession !== null;
@@ -229,9 +192,9 @@ async function outputAgentContext(
229
192
  agentSession &&
230
193
  agentSession.state !== "completed" &&
231
194
  agentSession.state !== "zombie" &&
232
- agentSession.beadId
195
+ agentSession.taskId
233
196
  ) {
234
- boundSession = { beadId: agentSession.beadId };
197
+ boundSession = { taskId: agentSession.taskId };
235
198
  }
236
199
  } finally {
237
200
  store.close();
@@ -263,7 +226,7 @@ async function outputAgentContext(
263
226
  // Activation context: if agent has a bound task, inject it
264
227
  if (boundSession) {
265
228
  sections.push("\n## Activation");
266
- sections.push(`You have a bound task: **${boundSession.beadId}**`);
229
+ sections.push(`You have a bound task: **${boundSession.taskId}**`);
267
230
  sections.push("Read your overlay at `.claude/CLAUDE.md` and begin working immediately.");
268
231
  sections.push("Do not wait for dispatch mail. Your assignment was bound at spawn time.");
269
232
  }
@@ -78,7 +78,7 @@ describe("replayCommand", () => {
78
78
  await replayCommand(["--help"]);
79
79
  const out = output();
80
80
 
81
- expect(out).toContain("overstory replay");
81
+ expect(out).toContain("replay");
82
82
  expect(out).toContain("--run");
83
83
  expect(out).toContain("--agent");
84
84
  expect(out).toContain("--json");
@@ -91,7 +91,7 @@ describe("replayCommand", () => {
91
91
  await replayCommand(["-h"]);
92
92
  const out = output();
93
93
 
94
- expect(out).toContain("overstory replay");
94
+ expect(out).toContain("replay");
95
95
  });
96
96
  });
97
97