@os-eco/overstory-cli 0.6.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 (170) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +381 -0
  3. package/agents/builder.md +137 -0
  4. package/agents/coordinator.md +263 -0
  5. package/agents/lead.md +301 -0
  6. package/agents/merger.md +160 -0
  7. package/agents/monitor.md +214 -0
  8. package/agents/reviewer.md +140 -0
  9. package/agents/scout.md +119 -0
  10. package/agents/supervisor.md +423 -0
  11. package/package.json +47 -0
  12. package/src/agents/checkpoint.test.ts +88 -0
  13. package/src/agents/checkpoint.ts +101 -0
  14. package/src/agents/hooks-deployer.test.ts +2040 -0
  15. package/src/agents/hooks-deployer.ts +607 -0
  16. package/src/agents/identity.test.ts +603 -0
  17. package/src/agents/identity.ts +384 -0
  18. package/src/agents/lifecycle.test.ts +196 -0
  19. package/src/agents/lifecycle.ts +183 -0
  20. package/src/agents/manifest.test.ts +746 -0
  21. package/src/agents/manifest.ts +354 -0
  22. package/src/agents/overlay.test.ts +676 -0
  23. package/src/agents/overlay.ts +308 -0
  24. package/src/beads/client.test.ts +217 -0
  25. package/src/beads/client.ts +202 -0
  26. package/src/beads/molecules.test.ts +338 -0
  27. package/src/beads/molecules.ts +198 -0
  28. package/src/commands/agents.test.ts +322 -0
  29. package/src/commands/agents.ts +287 -0
  30. package/src/commands/clean.test.ts +670 -0
  31. package/src/commands/clean.ts +618 -0
  32. package/src/commands/completions.test.ts +342 -0
  33. package/src/commands/completions.ts +887 -0
  34. package/src/commands/coordinator.test.ts +1530 -0
  35. package/src/commands/coordinator.ts +733 -0
  36. package/src/commands/costs.test.ts +1119 -0
  37. package/src/commands/costs.ts +564 -0
  38. package/src/commands/dashboard.test.ts +308 -0
  39. package/src/commands/dashboard.ts +838 -0
  40. package/src/commands/doctor.test.ts +294 -0
  41. package/src/commands/doctor.ts +213 -0
  42. package/src/commands/errors.test.ts +647 -0
  43. package/src/commands/errors.ts +248 -0
  44. package/src/commands/feed.test.ts +578 -0
  45. package/src/commands/feed.ts +361 -0
  46. package/src/commands/group.test.ts +262 -0
  47. package/src/commands/group.ts +511 -0
  48. package/src/commands/hooks.test.ts +458 -0
  49. package/src/commands/hooks.ts +253 -0
  50. package/src/commands/init.test.ts +347 -0
  51. package/src/commands/init.ts +650 -0
  52. package/src/commands/inspect.test.ts +670 -0
  53. package/src/commands/inspect.ts +431 -0
  54. package/src/commands/log.test.ts +1454 -0
  55. package/src/commands/log.ts +724 -0
  56. package/src/commands/logs.test.ts +379 -0
  57. package/src/commands/logs.ts +546 -0
  58. package/src/commands/mail.test.ts +1270 -0
  59. package/src/commands/mail.ts +771 -0
  60. package/src/commands/merge.test.ts +670 -0
  61. package/src/commands/merge.ts +355 -0
  62. package/src/commands/metrics.test.ts +444 -0
  63. package/src/commands/metrics.ts +143 -0
  64. package/src/commands/monitor.test.ts +191 -0
  65. package/src/commands/monitor.ts +390 -0
  66. package/src/commands/nudge.test.ts +230 -0
  67. package/src/commands/nudge.ts +372 -0
  68. package/src/commands/prime.test.ts +470 -0
  69. package/src/commands/prime.ts +381 -0
  70. package/src/commands/replay.test.ts +741 -0
  71. package/src/commands/replay.ts +360 -0
  72. package/src/commands/run.test.ts +431 -0
  73. package/src/commands/run.ts +351 -0
  74. package/src/commands/sling.test.ts +657 -0
  75. package/src/commands/sling.ts +661 -0
  76. package/src/commands/spec.test.ts +203 -0
  77. package/src/commands/spec.ts +168 -0
  78. package/src/commands/status.test.ts +430 -0
  79. package/src/commands/status.ts +398 -0
  80. package/src/commands/stop.test.ts +420 -0
  81. package/src/commands/stop.ts +151 -0
  82. package/src/commands/supervisor.test.ts +187 -0
  83. package/src/commands/supervisor.ts +535 -0
  84. package/src/commands/trace.test.ts +745 -0
  85. package/src/commands/trace.ts +325 -0
  86. package/src/commands/watch.test.ts +145 -0
  87. package/src/commands/watch.ts +247 -0
  88. package/src/commands/worktree.test.ts +786 -0
  89. package/src/commands/worktree.ts +311 -0
  90. package/src/config.test.ts +822 -0
  91. package/src/config.ts +829 -0
  92. package/src/doctor/agents.test.ts +454 -0
  93. package/src/doctor/agents.ts +396 -0
  94. package/src/doctor/config-check.test.ts +190 -0
  95. package/src/doctor/config-check.ts +183 -0
  96. package/src/doctor/consistency.test.ts +651 -0
  97. package/src/doctor/consistency.ts +294 -0
  98. package/src/doctor/databases.test.ts +290 -0
  99. package/src/doctor/databases.ts +218 -0
  100. package/src/doctor/dependencies.test.ts +184 -0
  101. package/src/doctor/dependencies.ts +175 -0
  102. package/src/doctor/logs.test.ts +251 -0
  103. package/src/doctor/logs.ts +295 -0
  104. package/src/doctor/merge-queue.test.ts +216 -0
  105. package/src/doctor/merge-queue.ts +144 -0
  106. package/src/doctor/structure.test.ts +291 -0
  107. package/src/doctor/structure.ts +198 -0
  108. package/src/doctor/types.ts +37 -0
  109. package/src/doctor/version.test.ts +136 -0
  110. package/src/doctor/version.ts +129 -0
  111. package/src/e2e/init-sling-lifecycle.test.ts +277 -0
  112. package/src/errors.ts +217 -0
  113. package/src/events/store.test.ts +660 -0
  114. package/src/events/store.ts +369 -0
  115. package/src/events/tool-filter.test.ts +330 -0
  116. package/src/events/tool-filter.ts +126 -0
  117. package/src/index.ts +316 -0
  118. package/src/insights/analyzer.test.ts +466 -0
  119. package/src/insights/analyzer.ts +203 -0
  120. package/src/logging/color.test.ts +142 -0
  121. package/src/logging/color.ts +71 -0
  122. package/src/logging/logger.test.ts +813 -0
  123. package/src/logging/logger.ts +266 -0
  124. package/src/logging/reporter.test.ts +259 -0
  125. package/src/logging/reporter.ts +109 -0
  126. package/src/logging/sanitizer.test.ts +190 -0
  127. package/src/logging/sanitizer.ts +57 -0
  128. package/src/mail/broadcast.test.ts +203 -0
  129. package/src/mail/broadcast.ts +92 -0
  130. package/src/mail/client.test.ts +773 -0
  131. package/src/mail/client.ts +223 -0
  132. package/src/mail/store.test.ts +705 -0
  133. package/src/mail/store.ts +387 -0
  134. package/src/merge/queue.test.ts +359 -0
  135. package/src/merge/queue.ts +231 -0
  136. package/src/merge/resolver.test.ts +1345 -0
  137. package/src/merge/resolver.ts +645 -0
  138. package/src/metrics/store.test.ts +667 -0
  139. package/src/metrics/store.ts +445 -0
  140. package/src/metrics/summary.test.ts +398 -0
  141. package/src/metrics/summary.ts +178 -0
  142. package/src/metrics/transcript.test.ts +356 -0
  143. package/src/metrics/transcript.ts +175 -0
  144. package/src/mulch/client.test.ts +671 -0
  145. package/src/mulch/client.ts +332 -0
  146. package/src/sessions/compat.test.ts +280 -0
  147. package/src/sessions/compat.ts +104 -0
  148. package/src/sessions/store.test.ts +873 -0
  149. package/src/sessions/store.ts +494 -0
  150. package/src/test-helpers.test.ts +124 -0
  151. package/src/test-helpers.ts +126 -0
  152. package/src/tracker/beads.ts +56 -0
  153. package/src/tracker/factory.test.ts +80 -0
  154. package/src/tracker/factory.ts +64 -0
  155. package/src/tracker/seeds.ts +182 -0
  156. package/src/tracker/types.ts +52 -0
  157. package/src/types.ts +724 -0
  158. package/src/watchdog/daemon.test.ts +1975 -0
  159. package/src/watchdog/daemon.ts +671 -0
  160. package/src/watchdog/health.test.ts +431 -0
  161. package/src/watchdog/health.ts +264 -0
  162. package/src/watchdog/triage.test.ts +164 -0
  163. package/src/watchdog/triage.ts +179 -0
  164. package/src/worktree/manager.test.ts +439 -0
  165. package/src/worktree/manager.ts +198 -0
  166. package/src/worktree/tmux.test.ts +1009 -0
  167. package/src/worktree/tmux.ts +509 -0
  168. package/templates/CLAUDE.md.tmpl +89 -0
  169. package/templates/hooks.json.tmpl +105 -0
  170. package/templates/overlay.md.tmpl +81 -0
@@ -0,0 +1,187 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import { isRunningAsRoot } from "./sling.ts";
3
+ import { buildSupervisorBeacon, supervisorCommand } from "./supervisor.ts";
4
+
5
+ /**
6
+ * Tests for supervisor command functions.
7
+ *
8
+ * Session persistence is now handled by SessionStore (SQLite).
9
+ * Those tests live in src/sessions/store.test.ts and src/sessions/compat.test.ts.
10
+ * Here we test beacon generation.
11
+ */
12
+
13
+ describe("buildSupervisorBeacon", () => {
14
+ test("contains agent name and beadId from opts", () => {
15
+ const beacon = buildSupervisorBeacon({
16
+ name: "supervisor-1",
17
+ beadId: "task-abc123",
18
+ depth: 1,
19
+ parent: "coordinator",
20
+ });
21
+
22
+ expect(beacon).toContain("supervisor-1");
23
+ expect(beacon).toContain("task-abc123");
24
+ });
25
+
26
+ test("contains [OVERSTORY] prefix", () => {
27
+ const beacon = buildSupervisorBeacon({
28
+ name: "supervisor-1",
29
+ beadId: "task-1",
30
+ depth: 1,
31
+ parent: "coordinator",
32
+ });
33
+
34
+ expect(beacon).toContain("[OVERSTORY]");
35
+ });
36
+
37
+ test("contains (supervisor) designation", () => {
38
+ const beacon = buildSupervisorBeacon({
39
+ name: "supervisor-1",
40
+ beadId: "task-1",
41
+ depth: 1,
42
+ parent: "coordinator",
43
+ });
44
+
45
+ expect(beacon).toContain("(supervisor)");
46
+ });
47
+
48
+ test("contains depth and parent info from opts", () => {
49
+ const beacon = buildSupervisorBeacon({
50
+ name: "supervisor-1",
51
+ beadId: "task-1",
52
+ depth: 2,
53
+ parent: "lead-cli",
54
+ });
55
+
56
+ expect(beacon).toContain("Depth: 2");
57
+ expect(beacon).toContain("Parent: lead-cli");
58
+ });
59
+
60
+ test("contains startup instructions", () => {
61
+ const beacon = buildSupervisorBeacon({
62
+ name: "supervisor-1",
63
+ beadId: "task-1",
64
+ depth: 1,
65
+ parent: "coordinator",
66
+ });
67
+
68
+ // Should include mulch prime
69
+ expect(beacon).toContain("mulch prime");
70
+
71
+ // Should include mail check with agent name
72
+ expect(beacon).toContain("overstory mail check --agent supervisor-1");
73
+
74
+ // Should include bd show with beadId
75
+ expect(beacon).toContain("bd show task-1");
76
+ });
77
+
78
+ test("contains ISO timestamp", () => {
79
+ const before = new Date();
80
+ const beacon = buildSupervisorBeacon({
81
+ name: "supervisor-1",
82
+ beadId: "task-1",
83
+ depth: 1,
84
+ parent: "coordinator",
85
+ });
86
+ const after = new Date();
87
+
88
+ // Extract timestamp from beacon (format: [OVERSTORY] {name} (supervisor) {timestamp} task:{beadId})
89
+ const timestampMatch = beacon.match(/\(supervisor\)\s+(\S+)\s+task:/);
90
+ expect(timestampMatch).toBeTruthy();
91
+
92
+ if (timestampMatch?.[1]) {
93
+ const timestamp = new Date(timestampMatch[1]);
94
+ expect(timestamp.getTime()).toBeGreaterThanOrEqual(before.getTime());
95
+ expect(timestamp.getTime()).toBeLessThanOrEqual(after.getTime());
96
+
97
+ // Verify ISO format (should parse correctly)
98
+ expect(timestamp.toISOString()).toBeTruthy();
99
+ }
100
+ });
101
+ });
102
+
103
+ describe("supervisorCommand", () => {
104
+ test("--help prints help containing required keywords", async () => {
105
+ const originalWrite = process.stdout.write;
106
+ let output = "";
107
+ process.stdout.write = ((chunk: string) => {
108
+ output += chunk;
109
+ return true;
110
+ }) as typeof process.stdout.write;
111
+
112
+ try {
113
+ await supervisorCommand(["--help"]);
114
+ expect(output).toContain("overstory supervisor");
115
+ expect(output).toContain("start");
116
+ expect(output).toContain("stop");
117
+ expect(output).toContain("status");
118
+ expect(output).toContain("--task");
119
+ expect(output).toContain("--name");
120
+ } finally {
121
+ process.stdout.write = originalWrite;
122
+ }
123
+ });
124
+
125
+ test("-h prints help", async () => {
126
+ const originalWrite = process.stdout.write;
127
+ let output = "";
128
+ process.stdout.write = ((chunk: string) => {
129
+ output += chunk;
130
+ return true;
131
+ }) as typeof process.stdout.write;
132
+
133
+ try {
134
+ await supervisorCommand(["-h"]);
135
+ expect(output).toContain("overstory supervisor");
136
+ } finally {
137
+ process.stdout.write = originalWrite;
138
+ }
139
+ });
140
+
141
+ test("empty args [] shows help", async () => {
142
+ const originalWrite = process.stdout.write;
143
+ let output = "";
144
+ process.stdout.write = ((chunk: string) => {
145
+ output += chunk;
146
+ return true;
147
+ }) as typeof process.stdout.write;
148
+
149
+ try {
150
+ await supervisorCommand([]);
151
+ expect(output).toContain("overstory supervisor");
152
+ } finally {
153
+ process.stdout.write = originalWrite;
154
+ }
155
+ });
156
+
157
+ test("unknown subcommand throws ValidationError with bad value in message", async () => {
158
+ expect(async () => {
159
+ await supervisorCommand(["invalid-subcommand"]);
160
+ }).toThrow(/invalid-subcommand/);
161
+ });
162
+
163
+ test("start without --task throws ValidationError", async () => {
164
+ expect(async () => {
165
+ await supervisorCommand(["start", "--name", "supervisor-1"]);
166
+ }).toThrow(/--task/);
167
+ });
168
+
169
+ test("start without --name throws ValidationError", async () => {
170
+ expect(async () => {
171
+ await supervisorCommand(["start", "--task", "task-1"]);
172
+ }).toThrow(/--name/);
173
+ });
174
+
175
+ test("stop without --name throws ValidationError", async () => {
176
+ expect(async () => {
177
+ await supervisorCommand(["stop"]);
178
+ }).toThrow(/--name/);
179
+ });
180
+ });
181
+
182
+ describe("isRunningAsRoot (imported from sling)", () => {
183
+ test("is accessible from supervisor test file", () => {
184
+ expect(isRunningAsRoot(() => 0)).toBe(true);
185
+ expect(isRunningAsRoot(() => 1000)).toBe(false);
186
+ });
187
+ });