@os-eco/overstory-cli 0.7.0 → 0.7.3

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 (91) hide show
  1. package/README.md +7 -6
  2. package/agents/builder.md +1 -1
  3. package/agents/coordinator.md +12 -11
  4. package/agents/lead.md +6 -6
  5. package/agents/monitor.md +4 -4
  6. package/agents/reviewer.md +1 -1
  7. package/agents/scout.md +5 -5
  8. package/agents/supervisor.md +36 -32
  9. package/package.json +1 -1
  10. package/src/agents/guard-rules.ts +97 -0
  11. package/src/agents/hooks-deployer.test.ts +6 -5
  12. package/src/agents/hooks-deployer.ts +7 -90
  13. package/src/agents/identity.test.ts +3 -2
  14. package/src/agents/manifest.test.ts +4 -3
  15. package/src/agents/overlay.test.ts +10 -9
  16. package/src/agents/overlay.ts +5 -5
  17. package/src/commands/agents.test.ts +10 -4
  18. package/src/commands/clean.test.ts +3 -0
  19. package/src/commands/completions.test.ts +8 -5
  20. package/src/commands/completions.ts +38 -2
  21. package/src/commands/coordinator.test.ts +1 -0
  22. package/src/commands/coordinator.ts +15 -11
  23. package/src/commands/costs.test.ts +9 -3
  24. package/src/commands/dashboard.test.ts +265 -6
  25. package/src/commands/dashboard.ts +367 -64
  26. package/src/commands/doctor.test.ts +3 -2
  27. package/src/commands/errors.test.ts +3 -2
  28. package/src/commands/feed.test.ts +3 -2
  29. package/src/commands/feed.ts +2 -29
  30. package/src/commands/init.test.ts +1 -2
  31. package/src/commands/init.ts +1 -8
  32. package/src/commands/inspect.test.ts +17 -2
  33. package/src/commands/log.test.ts +262 -8
  34. package/src/commands/log.ts +232 -110
  35. package/src/commands/logs.test.ts +3 -2
  36. package/src/commands/mail.test.ts +8 -2
  37. package/src/commands/metrics.test.ts +4 -3
  38. package/src/commands/monitor.ts +15 -11
  39. package/src/commands/nudge.test.ts +4 -2
  40. package/src/commands/prime.test.ts +4 -2
  41. package/src/commands/prime.ts +6 -2
  42. package/src/commands/replay.test.ts +3 -2
  43. package/src/commands/run.test.ts +3 -1
  44. package/src/commands/sling.test.ts +142 -1
  45. package/src/commands/sling.ts +145 -24
  46. package/src/commands/status.test.ts +9 -8
  47. package/src/commands/stop.test.ts +1 -0
  48. package/src/commands/supervisor.ts +19 -12
  49. package/src/commands/trace.test.ts +4 -2
  50. package/src/commands/watch.test.ts +3 -2
  51. package/src/commands/worktree.test.ts +9 -0
  52. package/src/config.test.ts +3 -3
  53. package/src/config.ts +29 -0
  54. package/src/doctor/agents.test.ts +3 -2
  55. package/src/doctor/consistency.test.ts +14 -0
  56. package/src/doctor/logs.test.ts +3 -2
  57. package/src/doctor/structure.test.ts +3 -2
  58. package/src/e2e/init-sling-lifecycle.test.ts +3 -5
  59. package/src/index.ts +3 -1
  60. package/src/logging/color.ts +1 -1
  61. package/src/logging/format.test.ts +110 -0
  62. package/src/logging/format.ts +42 -1
  63. package/src/logging/logger.test.ts +3 -2
  64. package/src/mail/broadcast.test.ts +1 -0
  65. package/src/mail/client.test.ts +3 -2
  66. package/src/mail/store.test.ts +3 -2
  67. package/src/merge/queue.test.ts +3 -2
  68. package/src/merge/resolver.test.ts +39 -0
  69. package/src/merge/resolver.ts +24 -5
  70. package/src/mulch/client.test.ts +63 -2
  71. package/src/mulch/client.ts +62 -1
  72. package/src/runtimes/claude.test.ts +5 -4
  73. package/src/runtimes/pi-guards.test.ts +457 -0
  74. package/src/runtimes/pi-guards.ts +349 -0
  75. package/src/runtimes/pi.test.ts +620 -0
  76. package/src/runtimes/pi.ts +244 -0
  77. package/src/runtimes/registry.test.ts +33 -0
  78. package/src/runtimes/registry.ts +15 -2
  79. package/src/runtimes/types.ts +63 -0
  80. package/src/schema-consistency.test.ts +5 -2
  81. package/src/sessions/compat.test.ts +3 -2
  82. package/src/sessions/compat.ts +1 -0
  83. package/src/sessions/store.test.ts +34 -2
  84. package/src/sessions/store.ts +37 -4
  85. package/src/test-helpers.ts +20 -1
  86. package/src/types.ts +17 -0
  87. package/src/watchdog/daemon.test.ts +11 -7
  88. package/src/watchdog/daemon.ts +1 -1
  89. package/src/watchdog/health.test.ts +1 -0
  90. package/src/watchdog/triage.test.ts +3 -2
  91. package/src/watchdog/triage.ts +14 -4
@@ -10,10 +10,11 @@
10
10
  */
11
11
 
12
12
  import { afterEach, beforeEach, describe, expect, test } from "bun:test";
13
- import { mkdtemp, rm } from "node:fs/promises";
13
+ import { mkdtemp } from "node:fs/promises";
14
14
  import { tmpdir } from "node:os";
15
15
  import { join } from "node:path";
16
16
  import { ValidationError } from "../errors.ts";
17
+ import { cleanupTempDir } from "../test-helpers.ts";
17
18
  import { doctorCommand } from "./doctor.ts";
18
19
 
19
20
  describe("doctorCommand", () => {
@@ -47,7 +48,7 @@ describe("doctorCommand", () => {
47
48
  afterEach(async () => {
48
49
  process.stdout.write = originalWrite;
49
50
  process.chdir(originalCwd);
50
- await rm(tempDir, { recursive: true, force: true });
51
+ await cleanupTempDir(tempDir);
51
52
  });
52
53
 
53
54
  function output(): string {
@@ -9,11 +9,12 @@
9
9
  */
10
10
 
11
11
  import { afterEach, beforeEach, describe, expect, test } from "bun:test";
12
- import { mkdtemp, rm } from "node:fs/promises";
12
+ import { mkdtemp } from "node:fs/promises";
13
13
  import { tmpdir } from "node:os";
14
14
  import { join } from "node:path";
15
15
  import { ValidationError } from "../errors.ts";
16
16
  import { createEventStore } from "../events/store.ts";
17
+ import { cleanupTempDir } from "../test-helpers.ts";
17
18
  import type { InsertEvent } from "../types.ts";
18
19
  import { errorsCommand } from "./errors.ts";
19
20
 
@@ -64,7 +65,7 @@ describe("errorsCommand", () => {
64
65
  afterEach(async () => {
65
66
  process.stdout.write = originalWrite;
66
67
  process.chdir(originalCwd);
67
- await rm(tempDir, { recursive: true, force: true });
68
+ await cleanupTempDir(tempDir);
68
69
  });
69
70
 
70
71
  function output(): string {
@@ -9,11 +9,12 @@
9
9
  */
10
10
 
11
11
  import { afterEach, beforeEach, describe, expect, test } from "bun:test";
12
- import { mkdtemp, rm } from "node:fs/promises";
12
+ import { mkdtemp } from "node:fs/promises";
13
13
  import { tmpdir } from "node:os";
14
14
  import { join } from "node:path";
15
15
  import { ValidationError } from "../errors.ts";
16
16
  import { createEventStore } from "../events/store.ts";
17
+ import { cleanupTempDir } from "../test-helpers.ts";
17
18
  import type { InsertEvent } from "../types.ts";
18
19
  import { feedCommand } from "./feed.ts";
19
20
 
@@ -64,7 +65,7 @@ describe("feedCommand", () => {
64
65
  afterEach(async () => {
65
66
  process.stdout.write = originalWrite;
66
67
  process.chdir(originalCwd);
67
- await rm(tempDir, { recursive: true, force: true });
68
+ await cleanupTempDir(tempDir);
68
69
  });
69
70
 
70
71
  function output(): string {
@@ -13,14 +13,7 @@ import { ValidationError } from "../errors.ts";
13
13
  import { createEventStore } from "../events/store.ts";
14
14
  import { jsonOutput } from "../json.ts";
15
15
  import type { ColorFn } from "../logging/color.ts";
16
- import { color } from "../logging/color.ts";
17
- import {
18
- buildAgentColorMap,
19
- buildEventDetail,
20
- extendAgentColorMap,
21
- formatAbsoluteTime,
22
- } from "../logging/format.ts";
23
- import { eventLabel } from "../logging/theme.ts";
16
+ import { buildAgentColorMap, extendAgentColorMap, formatEventLine } from "../logging/format.ts";
24
17
  import type { StoredEvent } from "../types.ts";
25
18
 
26
19
  /**
@@ -28,27 +21,7 @@ import type { StoredEvent } from "../types.ts";
28
21
  * HH:MM:SS LABEL agentname detail
29
22
  */
30
23
  function printEvent(event: StoredEvent, colorMap: Map<string, ColorFn>): void {
31
- const w = process.stdout.write.bind(process.stdout);
32
-
33
- const timeStr = formatAbsoluteTime(event.createdAt);
34
-
35
- const label = eventLabel(event.eventType);
36
-
37
- const levelColorFn =
38
- event.level === "error" ? color.red : event.level === "warn" ? color.yellow : null;
39
- const applyLevel = (text: string) => (levelColorFn ? levelColorFn(text) : text);
40
-
41
- const detail = buildEventDetail(event, 60);
42
- const detailSuffix = detail ? ` ${color.dim(detail)}` : "";
43
-
44
- const agentColorFn = colorMap.get(event.agentName) ?? color.gray;
45
- const agentLabel = ` ${agentColorFn(event.agentName.padEnd(15))}`;
46
-
47
- w(
48
- `${color.dim(timeStr)} ` +
49
- `${applyLevel(label.color(color.bold(label.compact)))}` +
50
- `${agentLabel}${detailSuffix}\n`,
51
- );
24
+ process.stdout.write(`${formatEventLine(event, colorMap)}\n`);
52
25
  }
53
26
 
54
27
  interface FeedOpts {
@@ -17,7 +17,6 @@ const AGENT_DEF_FILES = [
17
17
  "reviewer.md",
18
18
  "lead.md",
19
19
  "merger.md",
20
- "supervisor.md",
21
20
  "coordinator.md",
22
21
  "monitor.md",
23
22
  ];
@@ -46,7 +45,7 @@ describe("initCommand: agent-defs deployment", () => {
46
45
  await cleanupTempDir(tempDir);
47
46
  });
48
47
 
49
- test("creates .overstory/agent-defs/ with all 8 agent definition files", async () => {
48
+ test("creates .overstory/agent-defs/ with all 7 agent definition files (supervisor deprecated)", async () => {
50
49
  await initCommand({});
51
50
 
52
51
  const agentDefsDir = join(tempDir, ".overstory", "agent-defs");
@@ -241,14 +241,6 @@ function buildAgentManifest(): AgentManifest {
241
241
  canSpawn: true,
242
242
  constraints: ["read-only", "no-worktree"],
243
243
  },
244
- supervisor: {
245
- file: "supervisor.md",
246
- model: "opus",
247
- tools: ["Read", "Write", "Edit", "Glob", "Grep", "Bash", "Task"],
248
- capabilities: ["coordinate", "supervise"],
249
- canSpawn: true,
250
- constraints: [],
251
- },
252
244
  monitor: {
253
245
  file: "monitor.md",
254
246
  model: "sonnet",
@@ -595,6 +587,7 @@ export async function initCommand(opts: InitOptions): Promise<void> {
595
587
  const agentDefFiles = await readdir(overstoryAgentsDir);
596
588
  for (const fileName of agentDefFiles) {
597
589
  if (!fileName.endsWith(".md")) continue;
590
+ if (fileName === "supervisor.md") continue; // Deprecated: not deployed to new projects
598
591
  const source = Bun.file(join(overstoryAgentsDir, fileName));
599
592
  const content = await source.text();
600
593
  await Bun.write(join(agentDefsTarget, fileName), content);
@@ -9,13 +9,14 @@
9
9
  */
10
10
 
11
11
  import { afterEach, beforeEach, describe, expect, test } from "bun:test";
12
- import { mkdtemp, rm } from "node:fs/promises";
12
+ import { mkdtemp } from "node:fs/promises";
13
13
  import { tmpdir } from "node:os";
14
14
  import { join } from "node:path";
15
15
  import { ValidationError } from "../errors.ts";
16
16
  import { createEventStore } from "../events/store.ts";
17
17
  import { createMetricsStore } from "../metrics/store.ts";
18
18
  import { createSessionStore } from "../sessions/store.ts";
19
+ import { cleanupTempDir } from "../test-helpers.ts";
19
20
  import type { InsertEvent, SessionMetrics } from "../types.ts";
20
21
  import { gatherInspectData, inspectCommand } from "./inspect.ts";
21
22
 
@@ -89,7 +90,7 @@ describe("inspectCommand", () => {
89
90
  afterEach(async () => {
90
91
  process.stdout.write = originalWrite;
91
92
  process.chdir(originalCwd);
92
- await rm(tempDir, { recursive: true, force: true });
93
+ await cleanupTempDir(tempDir);
93
94
  });
94
95
 
95
96
  function output(): string {
@@ -153,6 +154,7 @@ describe("inspectCommand", () => {
153
154
  lastActivity: new Date().toISOString(),
154
155
  escalationLevel: 0,
155
156
  stalledSince: null,
157
+ transcriptPath: null,
156
158
  });
157
159
  store.close();
158
160
 
@@ -185,6 +187,7 @@ describe("inspectCommand", () => {
185
187
  lastActivity: new Date().toISOString(),
186
188
  escalationLevel: 0,
187
189
  stalledSince: null,
190
+ transcriptPath: null,
188
191
  });
189
192
  store.close();
190
193
 
@@ -221,6 +224,7 @@ describe("inspectCommand", () => {
221
224
  lastActivity: new Date(Date.now() - 5_000).toISOString(),
222
225
  escalationLevel: 0,
223
226
  stalledSince: null,
227
+ transcriptPath: null,
224
228
  });
225
229
  store.close();
226
230
 
@@ -257,6 +261,7 @@ describe("inspectCommand", () => {
257
261
  lastActivity: new Date().toISOString(),
258
262
  escalationLevel: 0,
259
263
  stalledSince: null,
264
+ transcriptPath: null,
260
265
  });
261
266
  store.close();
262
267
 
@@ -296,6 +301,7 @@ describe("inspectCommand", () => {
296
301
  lastActivity: new Date().toISOString(),
297
302
  escalationLevel: 0,
298
303
  stalledSince: null,
304
+ transcriptPath: null,
299
305
  });
300
306
  store.close();
301
307
 
@@ -331,6 +337,7 @@ describe("inspectCommand", () => {
331
337
  lastActivity: new Date().toISOString(),
332
338
  escalationLevel: 0,
333
339
  stalledSince: null,
340
+ transcriptPath: null,
334
341
  });
335
342
  store.close();
336
343
 
@@ -366,6 +373,7 @@ describe("inspectCommand", () => {
366
373
  lastActivity: new Date().toISOString(),
367
374
  escalationLevel: 0,
368
375
  stalledSince: null,
376
+ transcriptPath: null,
369
377
  });
370
378
  store.close();
371
379
 
@@ -410,6 +418,7 @@ describe("inspectCommand", () => {
410
418
  lastActivity: new Date().toISOString(),
411
419
  escalationLevel: 0,
412
420
  stalledSince: null,
421
+ transcriptPath: null,
413
422
  });
414
423
  store.close();
415
424
 
@@ -453,6 +462,7 @@ describe("inspectCommand", () => {
453
462
  lastActivity: new Date().toISOString(),
454
463
  escalationLevel: 0,
455
464
  stalledSince: null,
465
+ transcriptPath: null,
456
466
  });
457
467
  store.close();
458
468
 
@@ -502,6 +512,7 @@ describe("inspectCommand", () => {
502
512
  lastActivity: new Date().toISOString(),
503
513
  escalationLevel: 0,
504
514
  stalledSince: null,
515
+ transcriptPath: null,
505
516
  });
506
517
  store.close();
507
518
 
@@ -539,6 +550,7 @@ describe("inspectCommand", () => {
539
550
  lastActivity: new Date().toISOString(),
540
551
  escalationLevel: 0,
541
552
  stalledSince: null,
553
+ transcriptPath: null,
542
554
  });
543
555
  store.close();
544
556
 
@@ -577,6 +589,7 @@ describe("inspectCommand", () => {
577
589
  lastActivity: new Date().toISOString(),
578
590
  escalationLevel: 0,
579
591
  stalledSince: null,
592
+ transcriptPath: null,
580
593
  });
581
594
  store.close();
582
595
 
@@ -614,6 +627,7 @@ describe("inspectCommand", () => {
614
627
  lastActivity: new Date().toISOString(),
615
628
  escalationLevel: 0,
616
629
  stalledSince: null,
630
+ transcriptPath: null,
617
631
  });
618
632
  store.close();
619
633
 
@@ -652,6 +666,7 @@ describe("inspectCommand", () => {
652
666
  lastActivity: new Date().toISOString(),
653
667
  escalationLevel: 0,
654
668
  stalledSince: null,
669
+ transcriptPath: null,
655
670
  });
656
671
  store.close();
657
672