@os-eco/overstory-cli 0.9.1 → 0.9.2

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 (87) hide show
  1. package/README.md +20 -6
  2. package/agents/coordinator.md +30 -6
  3. package/agents/lead.md +11 -1
  4. package/package.json +1 -1
  5. package/src/agents/hooks-deployer.test.ts +9 -1
  6. package/src/agents/hooks-deployer.ts +2 -1
  7. package/src/agents/overlay.test.ts +26 -0
  8. package/src/agents/overlay.ts +18 -4
  9. package/src/commands/agents.ts +1 -1
  10. package/src/commands/clean.test.ts +3 -0
  11. package/src/commands/clean.ts +1 -58
  12. package/src/commands/completions.test.ts +18 -6
  13. package/src/commands/completions.ts +40 -1
  14. package/src/commands/coordinator.test.ts +77 -4
  15. package/src/commands/coordinator.ts +226 -124
  16. package/src/commands/dashboard.ts +46 -9
  17. package/src/commands/doctor.ts +3 -1
  18. package/src/commands/ecosystem.test.ts +126 -1
  19. package/src/commands/ecosystem.ts +7 -53
  20. package/src/commands/feed.test.ts +117 -2
  21. package/src/commands/feed.ts +46 -30
  22. package/src/commands/group.test.ts +274 -155
  23. package/src/commands/group.ts +11 -5
  24. package/src/commands/init.ts +8 -0
  25. package/src/commands/log.test.ts +35 -0
  26. package/src/commands/log.ts +10 -6
  27. package/src/commands/logs.test.ts +423 -1
  28. package/src/commands/logs.ts +99 -104
  29. package/src/commands/orchestrator.ts +42 -0
  30. package/src/commands/prime.test.ts +177 -2
  31. package/src/commands/prime.ts +4 -2
  32. package/src/commands/sling.ts +3 -3
  33. package/src/commands/upgrade.test.ts +2 -0
  34. package/src/commands/upgrade.ts +1 -17
  35. package/src/commands/watch.test.ts +67 -1
  36. package/src/commands/watch.ts +4 -79
  37. package/src/config.test.ts +250 -0
  38. package/src/config.ts +43 -0
  39. package/src/doctor/agents.test.ts +72 -5
  40. package/src/doctor/agents.ts +10 -10
  41. package/src/doctor/consistency.test.ts +35 -0
  42. package/src/doctor/consistency.ts +7 -3
  43. package/src/doctor/dependencies.test.ts +58 -1
  44. package/src/doctor/dependencies.ts +4 -2
  45. package/src/doctor/providers.test.ts +41 -5
  46. package/src/doctor/types.ts +2 -1
  47. package/src/doctor/version.test.ts +106 -2
  48. package/src/doctor/version.ts +4 -2
  49. package/src/doctor/watchdog.test.ts +167 -0
  50. package/src/doctor/watchdog.ts +158 -0
  51. package/src/e2e/init-sling-lifecycle.test.ts +2 -1
  52. package/src/errors.test.ts +350 -0
  53. package/src/events/tailer.test.ts +25 -0
  54. package/src/events/tailer.ts +8 -1
  55. package/src/index.ts +4 -1
  56. package/src/mail/store.test.ts +110 -0
  57. package/src/runtimes/aider.test.ts +124 -0
  58. package/src/runtimes/aider.ts +147 -0
  59. package/src/runtimes/amp.test.ts +164 -0
  60. package/src/runtimes/amp.ts +154 -0
  61. package/src/runtimes/claude.test.ts +4 -2
  62. package/src/runtimes/goose.test.ts +133 -0
  63. package/src/runtimes/goose.ts +157 -0
  64. package/src/runtimes/pi-guards.ts +2 -1
  65. package/src/runtimes/pi.test.ts +9 -9
  66. package/src/runtimes/pi.ts +6 -7
  67. package/src/runtimes/registry.test.ts +1 -1
  68. package/src/runtimes/registry.ts +13 -4
  69. package/src/runtimes/sapling.ts +2 -1
  70. package/src/runtimes/types.ts +2 -2
  71. package/src/types.ts +4 -0
  72. package/src/utils/bin.test.ts +10 -0
  73. package/src/utils/bin.ts +37 -0
  74. package/src/utils/fs.test.ts +119 -0
  75. package/src/utils/fs.ts +62 -0
  76. package/src/utils/pid.test.ts +68 -0
  77. package/src/utils/pid.ts +45 -0
  78. package/src/utils/time.test.ts +43 -0
  79. package/src/utils/time.ts +37 -0
  80. package/src/utils/version.test.ts +33 -0
  81. package/src/utils/version.ts +70 -0
  82. package/src/watchdog/daemon.test.ts +255 -1
  83. package/src/watchdog/daemon.ts +46 -9
  84. package/src/watchdog/health.test.ts +15 -1
  85. package/src/watchdog/health.ts +1 -1
  86. package/src/watchdog/triage.test.ts +49 -9
  87. package/src/watchdog/triage.ts +21 -5
@@ -29,6 +29,11 @@ import {
29
29
  createCoordinatorCommand,
30
30
  resolveAttach,
31
31
  } from "./coordinator.ts";
32
+ import {
33
+ buildOrchestratorBeacon,
34
+ createOrchestratorCommand,
35
+ orchestratorCommand,
36
+ } from "./orchestrator.ts";
32
37
 
33
38
  // --- Fake Tmux ---
34
39
 
@@ -272,14 +277,26 @@ beforeEach(async () => {
272
277
  canSpawn: true,
273
278
  constraints: [],
274
279
  },
280
+ orchestrator: {
281
+ file: "orchestrator.md",
282
+ model: "opus",
283
+ tools: ["Read", "Bash"],
284
+ capabilities: ["orchestrate", "coordinate"],
285
+ canSpawn: true,
286
+ constraints: [],
287
+ },
288
+ },
289
+ capabilityIndex: {
290
+ coordinate: ["coordinator", "orchestrator"],
291
+ orchestrate: ["orchestrator"],
275
292
  },
276
- capabilityIndex: { coordinate: ["coordinator"] },
277
293
  };
278
294
  await Bun.write(
279
295
  join(overstoryDir, "agent-manifest.json"),
280
296
  `${JSON.stringify(manifest, null, "\t")}\n`,
281
297
  );
282
298
  await Bun.write(join(agentDefsDir, "coordinator.md"), "# Coordinator\n");
299
+ await Bun.write(join(agentDefsDir, "orchestrator.md"), "# Orchestrator\n");
283
300
 
284
301
  // Override cwd so coordinator commands find our temp project
285
302
  process.chdir(tempDir);
@@ -1255,14 +1272,16 @@ describe("buildCoordinatorBeacon", () => {
1255
1272
 
1256
1273
  test("includes hierarchy enforcement instruction", () => {
1257
1274
  const beacon = buildCoordinatorBeacon();
1258
- expect(beacon).toContain("ONLY spawn leads");
1259
- expect(beacon).toContain("NEVER spawn non-lead agents directly");
1275
+ expect(beacon).toContain("Default to leads");
1276
+ expect(beacon).toContain("spawn scout/builder directly");
1277
+ expect(beacon).toContain("NEVER spawn reviewer or merger directly");
1260
1278
  });
1261
1279
 
1262
1280
  test("includes delegation instruction", () => {
1263
1281
  const beacon = buildCoordinatorBeacon();
1264
1282
  expect(beacon).toContain("DELEGATION");
1265
- expect(beacon).toContain("spawn a lead who will spawn scouts");
1283
+ expect(beacon).toContain("spawn a lead who will handle scouts/builders/reviewers");
1284
+ expect(beacon).toContain("--dispatch-max-agents 1/2");
1266
1285
  });
1267
1286
 
1268
1287
  test("parts are joined with em-dash separator", () => {
@@ -1273,6 +1292,60 @@ describe("buildCoordinatorBeacon", () => {
1273
1292
  });
1274
1293
  });
1275
1294
 
1295
+ describe("orchestratorCommand", () => {
1296
+ test("help shows orchestrator command name", async () => {
1297
+ const output = await captureStdout(() => orchestratorCommand(["--help"]));
1298
+ expect(output).toContain("orchestrator");
1299
+ });
1300
+
1301
+ test("start creates orchestrator session with orchestrator capability", async () => {
1302
+ const { deps, calls } = makeDeps({ "overstory-test-project-orchestrator": true });
1303
+ const originalSleep = Bun.sleep;
1304
+ Bun.sleep = (() => Promise.resolve()) as typeof Bun.sleep;
1305
+
1306
+ try {
1307
+ const output = await captureStdout(() =>
1308
+ orchestratorCommand(["start", "--no-attach", "--json"], deps),
1309
+ );
1310
+ const parsed = JSON.parse(output) as Record<string, unknown>;
1311
+
1312
+ expect(parsed.agentName).toBe("orchestrator");
1313
+ expect(parsed.capability).toBe("orchestrator");
1314
+ expect(parsed.tmuxSession).toBe("overstory-test-project-orchestrator");
1315
+ expect(calls.createSession[0]?.name).toBe("overstory-test-project-orchestrator");
1316
+ expect(calls.createSession[0]?.command).toContain("orchestrator.md");
1317
+
1318
+ const session = loadSessionsFromDb().find((entry) => entry.agentName === "orchestrator");
1319
+ expect(session?.capability).toBe("orchestrator");
1320
+ } finally {
1321
+ Bun.sleep = originalSleep;
1322
+ }
1323
+ });
1324
+
1325
+ test("command registration includes orchestrator start/stop/status", () => {
1326
+ const cmd = createOrchestratorCommand({});
1327
+ const subcommandNames = cmd.commands.map((c) => c.name());
1328
+ expect(subcommandNames).toContain("start");
1329
+ expect(subcommandNames).toContain("stop");
1330
+ expect(subcommandNames).toContain("status");
1331
+ expect(subcommandNames).not.toContain("check-complete");
1332
+ });
1333
+ });
1334
+
1335
+ describe("buildOrchestratorBeacon", () => {
1336
+ test("includes orchestrator identity in header", () => {
1337
+ const beacon = buildOrchestratorBeacon();
1338
+ expect(beacon).toContain("[OVERSTORY] orchestrator (orchestrator)");
1339
+ });
1340
+
1341
+ test("includes ecosystem startup instructions", () => {
1342
+ const beacon = buildOrchestratorBeacon("sd");
1343
+ expect(beacon).toContain("ov mail check --agent orchestrator");
1344
+ expect(beacon).toContain("sd ready");
1345
+ expect(beacon).toContain("inspect ecosystem status");
1346
+ });
1347
+ });
1348
+
1276
1349
  describe("resolveAttach", () => {
1277
1350
  test("--attach flag forces attach regardless of TTY", () => {
1278
1351
  expect(resolveAttach(["--attach"], false)).toBe(true);