@os-eco/overstory-cli 0.6.4 → 0.6.6
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.
- package/README.md +61 -61
- package/agents/builder.md +16 -16
- package/agents/coordinator.md +57 -57
- package/agents/issue-reviews.md +71 -0
- package/agents/lead.md +43 -42
- package/agents/merger.md +15 -15
- package/agents/monitor.md +37 -37
- package/agents/pr-reviews.md +60 -0
- package/agents/prioritize.md +110 -0
- package/agents/release.md +56 -0
- package/agents/reviewer.md +15 -15
- package/agents/scout.md +18 -18
- package/agents/supervisor.md +78 -78
- package/package.json +1 -1
- package/src/agents/checkpoint.test.ts +2 -2
- package/src/agents/hooks-deployer.test.ts +59 -25
- package/src/agents/hooks-deployer.ts +24 -6
- package/src/agents/identity.test.ts +27 -27
- package/src/agents/identity.ts +10 -10
- package/src/agents/lifecycle.test.ts +6 -6
- package/src/agents/lifecycle.ts +2 -2
- package/src/agents/overlay.test.ts +14 -14
- package/src/agents/overlay.ts +14 -14
- package/src/commands/agents.test.ts +5 -5
- package/src/commands/agents.ts +10 -9
- package/src/commands/clean.test.ts +5 -5
- package/src/commands/clean.ts +5 -5
- package/src/commands/completions.test.ts +10 -10
- package/src/commands/completions.ts +26 -28
- package/src/commands/coordinator.test.ts +4 -4
- package/src/commands/coordinator.ts +13 -13
- package/src/commands/costs.test.ts +45 -45
- package/src/commands/costs.ts +1 -1
- package/src/commands/dashboard.ts +11 -11
- package/src/commands/doctor.ts +4 -4
- package/src/commands/errors.ts +1 -1
- package/src/commands/feed.ts +1 -1
- package/src/commands/group.ts +3 -3
- package/src/commands/hooks.test.ts +7 -7
- package/src/commands/hooks.ts +7 -7
- package/src/commands/init.test.ts +6 -2
- package/src/commands/init.ts +19 -19
- package/src/commands/inspect.test.ts +16 -16
- package/src/commands/inspect.ts +19 -19
- package/src/commands/log.test.ts +21 -21
- package/src/commands/log.ts +10 -10
- package/src/commands/logs.ts +1 -1
- package/src/commands/mail.test.ts +7 -7
- package/src/commands/mail.ts +28 -11
- package/src/commands/merge.test.ts +8 -8
- package/src/commands/merge.ts +15 -15
- package/src/commands/metrics.test.ts +7 -7
- package/src/commands/metrics.ts +3 -3
- package/src/commands/monitor.test.ts +5 -5
- package/src/commands/monitor.ts +5 -5
- package/src/commands/nudge.test.ts +1 -1
- package/src/commands/nudge.ts +1 -1
- package/src/commands/prime.test.ts +5 -5
- package/src/commands/prime.ts +8 -8
- package/src/commands/replay.ts +1 -1
- package/src/commands/run.test.ts +1 -1
- package/src/commands/run.ts +2 -2
- package/src/commands/sling.test.ts +89 -7
- package/src/commands/sling.ts +109 -18
- package/src/commands/spec.test.ts +2 -2
- package/src/commands/spec.ts +13 -14
- package/src/commands/status.test.ts +99 -3
- package/src/commands/status.ts +19 -20
- package/src/commands/stop.test.ts +1 -1
- package/src/commands/stop.ts +2 -2
- package/src/commands/supervisor.test.ts +10 -10
- package/src/commands/supervisor.ts +14 -14
- package/src/commands/trace.test.ts +7 -7
- package/src/commands/trace.ts +10 -10
- package/src/commands/watch.ts +5 -5
- package/src/commands/worktree.test.ts +208 -32
- package/src/commands/worktree.ts +56 -18
- package/src/doctor/consistency.test.ts +14 -14
- package/src/doctor/dependencies.test.ts +5 -5
- package/src/doctor/dependencies.ts +2 -2
- package/src/doctor/logs.ts +1 -1
- package/src/doctor/merge-queue.test.ts +4 -4
- package/src/doctor/structure.test.ts +1 -1
- package/src/doctor/structure.ts +1 -1
- package/src/doctor/version.test.ts +3 -3
- package/src/doctor/version.ts +1 -1
- package/src/e2e/init-sling-lifecycle.test.ts +8 -4
- package/src/errors.ts +1 -1
- package/src/index.ts +13 -11
- package/src/mail/broadcast.test.ts +1 -1
- package/src/mail/client.test.ts +7 -7
- package/src/mail/client.ts +2 -2
- package/src/mail/store.test.ts +3 -3
- package/src/merge/queue.test.ts +12 -12
- package/src/merge/queue.ts +2 -2
- package/src/merge/resolver.test.ts +159 -7
- package/src/merge/resolver.ts +46 -2
- package/src/metrics/store.test.ts +44 -44
- package/src/metrics/store.ts +2 -2
- package/src/metrics/summary.test.ts +35 -35
- package/src/mulch/client.test.ts +1 -1
- package/src/mulch/client.ts +1 -1
- package/src/sessions/compat.test.ts +3 -3
- package/src/sessions/compat.ts +1 -1
- package/src/sessions/store.test.ts +4 -4
- package/src/sessions/store.ts +2 -2
- package/src/types.ts +14 -14
- package/src/watchdog/daemon.test.ts +10 -10
- package/src/watchdog/daemon.ts +1 -1
- package/src/watchdog/health.test.ts +1 -1
- package/src/worktree/manager.test.ts +20 -20
- package/src/worktree/manager.ts +120 -4
- package/src/worktree/tmux.test.ts +8 -3
- package/src/worktree/tmux.ts +19 -18
- package/templates/CLAUDE.md.tmpl +27 -27
- package/templates/hooks.json.tmpl +15 -11
- package/templates/overlay.md.tmpl +7 -7
package/src/commands/init.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* CLI command:
|
|
2
|
+
* CLI command: ov init [--force]
|
|
3
3
|
*
|
|
4
4
|
* Scaffolds the `.overstory/` directory in the current project with:
|
|
5
5
|
* - config.yaml (serialized from DEFAULT_CONFIG)
|
|
@@ -296,7 +296,7 @@ function buildHooksJson(): string {
|
|
|
296
296
|
hooks: [
|
|
297
297
|
{
|
|
298
298
|
type: "command",
|
|
299
|
-
command: "
|
|
299
|
+
command: "ov prime --agent orchestrator",
|
|
300
300
|
},
|
|
301
301
|
],
|
|
302
302
|
},
|
|
@@ -307,7 +307,7 @@ function buildHooksJson(): string {
|
|
|
307
307
|
hooks: [
|
|
308
308
|
{
|
|
309
309
|
type: "command",
|
|
310
|
-
command: "
|
|
310
|
+
command: "ov mail check --inject --agent orchestrator",
|
|
311
311
|
},
|
|
312
312
|
],
|
|
313
313
|
},
|
|
@@ -328,7 +328,7 @@ function buildHooksJson(): string {
|
|
|
328
328
|
hooks: [
|
|
329
329
|
{
|
|
330
330
|
type: "command",
|
|
331
|
-
command: `${toolNameExtract}
|
|
331
|
+
command: `${toolNameExtract} ov log tool-start --agent orchestrator --tool-name "$TOOL_NAME"`,
|
|
332
332
|
},
|
|
333
333
|
],
|
|
334
334
|
},
|
|
@@ -339,7 +339,7 @@ function buildHooksJson(): string {
|
|
|
339
339
|
hooks: [
|
|
340
340
|
{
|
|
341
341
|
type: "command",
|
|
342
|
-
command: `${toolNameExtract}
|
|
342
|
+
command: `${toolNameExtract} ov log tool-end --agent orchestrator --tool-name "$TOOL_NAME"`,
|
|
343
343
|
},
|
|
344
344
|
],
|
|
345
345
|
},
|
|
@@ -360,7 +360,7 @@ function buildHooksJson(): string {
|
|
|
360
360
|
hooks: [
|
|
361
361
|
{
|
|
362
362
|
type: "command",
|
|
363
|
-
command: "
|
|
363
|
+
command: "ov log session-end --agent orchestrator",
|
|
364
364
|
},
|
|
365
365
|
{
|
|
366
366
|
type: "command",
|
|
@@ -375,7 +375,7 @@ function buildHooksJson(): string {
|
|
|
375
375
|
hooks: [
|
|
376
376
|
{
|
|
377
377
|
type: "command",
|
|
378
|
-
command: "
|
|
378
|
+
command: "ov prime --agent orchestrator --compact",
|
|
379
379
|
},
|
|
380
380
|
],
|
|
381
381
|
},
|
|
@@ -450,11 +450,11 @@ CREATE TABLE IF NOT EXISTS sessions (
|
|
|
450
450
|
/**
|
|
451
451
|
* Content for .overstory/.gitignore — runtime state that should not be tracked.
|
|
452
452
|
* Uses wildcard+whitelist pattern: ignore everything, whitelist tracked files.
|
|
453
|
-
* Auto-healed by
|
|
453
|
+
* Auto-healed by ov prime on each session start.
|
|
454
454
|
* Config files (config.yaml, agent-manifest.json, hooks.json) remain tracked.
|
|
455
455
|
*/
|
|
456
456
|
export const OVERSTORY_GITIGNORE = `# Wildcard+whitelist: ignore everything, whitelist tracked files
|
|
457
|
-
# Auto-healed by
|
|
457
|
+
# Auto-healed by ov prime on each session start
|
|
458
458
|
*
|
|
459
459
|
!.gitignore
|
|
460
460
|
!config.yaml
|
|
@@ -476,13 +476,13 @@ Overstory turns a single Claude Code session into a multi-agent team by spawning
|
|
|
476
476
|
|
|
477
477
|
## Key Commands
|
|
478
478
|
|
|
479
|
-
- \`
|
|
480
|
-
- \`
|
|
481
|
-
- \`
|
|
482
|
-
- \`
|
|
483
|
-
- \`
|
|
484
|
-
- \`
|
|
485
|
-
- \`
|
|
479
|
+
- \`ov init\` — Initialize this directory
|
|
480
|
+
- \`ov status\` — Show active agents and state
|
|
481
|
+
- \`ov sling <id>\` — Spawn a worker agent
|
|
482
|
+
- \`ov mail check\` — Check agent messages
|
|
483
|
+
- \`ov merge\` — Merge agent work back
|
|
484
|
+
- \`ov dashboard\` — Live TUI monitoring
|
|
485
|
+
- \`ov doctor\` — Run health checks
|
|
486
486
|
|
|
487
487
|
## Structure
|
|
488
488
|
|
|
@@ -526,7 +526,7 @@ function printCreated(relativePath: string): void {
|
|
|
526
526
|
}
|
|
527
527
|
|
|
528
528
|
/**
|
|
529
|
-
* Entry point for `
|
|
529
|
+
* Entry point for `ov init [--force]`.
|
|
530
530
|
*
|
|
531
531
|
* Scaffolds the .overstory/ directory structure in the current working directory.
|
|
532
532
|
*
|
|
@@ -636,6 +636,6 @@ export async function initCommand(opts: InitOptions): Promise<void> {
|
|
|
636
636
|
}
|
|
637
637
|
|
|
638
638
|
process.stdout.write("\nDone.\n");
|
|
639
|
-
process.stdout.write(" Next: run `
|
|
640
|
-
process.stdout.write(" Then: run `
|
|
639
|
+
process.stdout.write(" Next: run `ov hooks install` to enable Claude Code hooks.\n");
|
|
640
|
+
process.stdout.write(" Then: run `ov status` to see the current state.\n");
|
|
641
641
|
}
|
|
@@ -39,7 +39,7 @@ function makeEvent(overrides: Partial<InsertEvent> = {}): InsertEvent {
|
|
|
39
39
|
function makeMetrics(overrides: Partial<SessionMetrics> = {}): SessionMetrics {
|
|
40
40
|
return {
|
|
41
41
|
agentName: "builder-1",
|
|
42
|
-
|
|
42
|
+
taskId: "overstory-001",
|
|
43
43
|
capability: "builder",
|
|
44
44
|
startedAt: new Date().toISOString(),
|
|
45
45
|
completedAt: null,
|
|
@@ -142,7 +142,7 @@ describe("inspectCommand", () => {
|
|
|
142
142
|
capability: "builder",
|
|
143
143
|
worktreePath: "/tmp/wt",
|
|
144
144
|
branchName: "overstory/builder-1/test",
|
|
145
|
-
|
|
145
|
+
taskId: "overstory-001",
|
|
146
146
|
tmuxSession: "overstory-test-builder-1",
|
|
147
147
|
state: "working",
|
|
148
148
|
pid: 12345,
|
|
@@ -174,7 +174,7 @@ describe("inspectCommand", () => {
|
|
|
174
174
|
capability: "builder",
|
|
175
175
|
worktreePath: "/tmp/wt",
|
|
176
176
|
branchName: "overstory/builder-1/test",
|
|
177
|
-
|
|
177
|
+
taskId: "overstory-001",
|
|
178
178
|
tmuxSession: "overstory-test-builder-1",
|
|
179
179
|
state: "working",
|
|
180
180
|
pid: 12345,
|
|
@@ -210,7 +210,7 @@ describe("inspectCommand", () => {
|
|
|
210
210
|
capability: "builder",
|
|
211
211
|
worktreePath: "/tmp/wt",
|
|
212
212
|
branchName: "overstory/builder-1/test",
|
|
213
|
-
|
|
213
|
+
taskId: "overstory-001",
|
|
214
214
|
tmuxSession: "overstory-test-builder-1",
|
|
215
215
|
state: "working",
|
|
216
216
|
pid: 12345,
|
|
@@ -229,7 +229,7 @@ describe("inspectCommand", () => {
|
|
|
229
229
|
expect(data.session.agentName).toBe("builder-1");
|
|
230
230
|
expect(data.session.capability).toBe("builder");
|
|
231
231
|
expect(data.session.state).toBe("working");
|
|
232
|
-
expect(data.session.
|
|
232
|
+
expect(data.session.taskId).toBe("overstory-001");
|
|
233
233
|
expect(data.timeSinceLastActivity).toBeGreaterThan(4000);
|
|
234
234
|
expect(data.timeSinceLastActivity).toBeLessThan(10000);
|
|
235
235
|
});
|
|
@@ -246,7 +246,7 @@ describe("inspectCommand", () => {
|
|
|
246
246
|
capability: "builder",
|
|
247
247
|
worktreePath: "/tmp/wt",
|
|
248
248
|
branchName: "overstory/builder-1/test",
|
|
249
|
-
|
|
249
|
+
taskId: "overstory-001",
|
|
250
250
|
tmuxSession: "overstory-test-builder-1",
|
|
251
251
|
state: "working",
|
|
252
252
|
pid: 12345,
|
|
@@ -285,7 +285,7 @@ describe("inspectCommand", () => {
|
|
|
285
285
|
capability: "builder",
|
|
286
286
|
worktreePath: "/tmp/wt",
|
|
287
287
|
branchName: "overstory/builder-1/test",
|
|
288
|
-
|
|
288
|
+
taskId: "overstory-001",
|
|
289
289
|
tmuxSession: "overstory-test-builder-1",
|
|
290
290
|
state: "working",
|
|
291
291
|
pid: 12345,
|
|
@@ -320,7 +320,7 @@ describe("inspectCommand", () => {
|
|
|
320
320
|
capability: "builder",
|
|
321
321
|
worktreePath: "/tmp/wt",
|
|
322
322
|
branchName: "overstory/builder-1/test",
|
|
323
|
-
|
|
323
|
+
taskId: "overstory-001",
|
|
324
324
|
tmuxSession: "overstory-test-builder-1",
|
|
325
325
|
state: "working",
|
|
326
326
|
pid: 12345,
|
|
@@ -355,7 +355,7 @@ describe("inspectCommand", () => {
|
|
|
355
355
|
capability: "builder",
|
|
356
356
|
worktreePath: "/tmp/wt",
|
|
357
357
|
branchName: "overstory/builder-1/test",
|
|
358
|
-
|
|
358
|
+
taskId: "overstory-001",
|
|
359
359
|
tmuxSession: "overstory-test-builder-1",
|
|
360
360
|
state: "working",
|
|
361
361
|
pid: 12345,
|
|
@@ -399,7 +399,7 @@ describe("inspectCommand", () => {
|
|
|
399
399
|
capability: "builder",
|
|
400
400
|
worktreePath: "/tmp/wt",
|
|
401
401
|
branchName: "overstory/builder-1/test",
|
|
402
|
-
|
|
402
|
+
taskId: "overstory-001",
|
|
403
403
|
tmuxSession: "overstory-test-builder-1",
|
|
404
404
|
state: "working",
|
|
405
405
|
pid: 12345,
|
|
@@ -442,7 +442,7 @@ describe("inspectCommand", () => {
|
|
|
442
442
|
capability: "builder",
|
|
443
443
|
worktreePath: "/tmp/wt",
|
|
444
444
|
branchName: "overstory/builder-1/test",
|
|
445
|
-
|
|
445
|
+
taskId: "overstory-001",
|
|
446
446
|
tmuxSession: "overstory-test-builder-1",
|
|
447
447
|
state: "working",
|
|
448
448
|
pid: 12345,
|
|
@@ -491,7 +491,7 @@ describe("inspectCommand", () => {
|
|
|
491
491
|
capability: "builder",
|
|
492
492
|
worktreePath: "/tmp/wt",
|
|
493
493
|
branchName: "overstory/builder-1/test",
|
|
494
|
-
|
|
494
|
+
taskId: "overstory-001",
|
|
495
495
|
tmuxSession: "overstory-test-builder-1",
|
|
496
496
|
state: "working",
|
|
497
497
|
pid: 12345,
|
|
@@ -528,7 +528,7 @@ describe("inspectCommand", () => {
|
|
|
528
528
|
capability: "builder",
|
|
529
529
|
worktreePath: "/tmp/wt",
|
|
530
530
|
branchName: "overstory/builder-1/test",
|
|
531
|
-
|
|
531
|
+
taskId: "overstory-001",
|
|
532
532
|
tmuxSession: "overstory-test-builder-1",
|
|
533
533
|
state: "working",
|
|
534
534
|
pid: 12345,
|
|
@@ -564,7 +564,7 @@ describe("inspectCommand", () => {
|
|
|
564
564
|
capability: "builder",
|
|
565
565
|
worktreePath: "/tmp/wt",
|
|
566
566
|
branchName: "overstory/builder-1/test",
|
|
567
|
-
|
|
567
|
+
taskId: "overstory-001",
|
|
568
568
|
tmuxSession: "overstory-test-builder-1",
|
|
569
569
|
state: "working",
|
|
570
570
|
pid: 12345,
|
|
@@ -601,7 +601,7 @@ describe("inspectCommand", () => {
|
|
|
601
601
|
capability: "builder",
|
|
602
602
|
worktreePath: "/tmp/wt",
|
|
603
603
|
branchName: "overstory/builder-1/test",
|
|
604
|
-
|
|
604
|
+
taskId: "overstory-001",
|
|
605
605
|
tmuxSession: "overstory-test-builder-1",
|
|
606
606
|
state: "working",
|
|
607
607
|
pid: 12345,
|
|
@@ -639,7 +639,7 @@ describe("inspectCommand", () => {
|
|
|
639
639
|
capability: "builder",
|
|
640
640
|
worktreePath: "/tmp/wt",
|
|
641
641
|
branchName: "overstory/builder-1/test",
|
|
642
|
-
|
|
642
|
+
taskId: "overstory-001",
|
|
643
643
|
tmuxSession: "overstory-test-builder-1",
|
|
644
644
|
state: "working",
|
|
645
645
|
pid: 12345,
|
package/src/commands/inspect.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* CLI command:
|
|
2
|
+
* CLI command: ov inspect <agent-name>
|
|
3
3
|
*
|
|
4
4
|
* Deep per-agent inspection aggregating data from EventStore, SessionStore,
|
|
5
5
|
* MetricsStore, and tmux capture-pane.
|
|
@@ -35,15 +35,15 @@ function formatDuration(ms: number): string {
|
|
|
35
35
|
function getStateIcon(state: AgentSession["state"]): string {
|
|
36
36
|
switch (state) {
|
|
37
37
|
case "booting":
|
|
38
|
-
return
|
|
38
|
+
return color.green("-");
|
|
39
39
|
case "working":
|
|
40
|
-
return
|
|
40
|
+
return color.cyan(">");
|
|
41
41
|
case "stalled":
|
|
42
|
-
return
|
|
42
|
+
return color.yellow("!");
|
|
43
43
|
case "completed":
|
|
44
|
-
return
|
|
44
|
+
return color.dim("x");
|
|
45
45
|
case "zombie":
|
|
46
|
-
return
|
|
46
|
+
return color.dim("x");
|
|
47
47
|
default:
|
|
48
48
|
return "?";
|
|
49
49
|
}
|
|
@@ -252,31 +252,31 @@ export function printInspectData(data: InspectData): void {
|
|
|
252
252
|
const w = process.stdout.write.bind(process.stdout);
|
|
253
253
|
const { session } = data;
|
|
254
254
|
|
|
255
|
-
w(`\
|
|
255
|
+
w(`\nAgent Inspection: ${session.agentName}\n`);
|
|
256
256
|
w(`${"═".repeat(80)}\n\n`);
|
|
257
257
|
|
|
258
258
|
// Agent state and metadata
|
|
259
259
|
const stateIcon = getStateIcon(session.state);
|
|
260
260
|
w(`${stateIcon} State: ${session.state}\n`);
|
|
261
|
-
w(
|
|
262
|
-
w(
|
|
263
|
-
w(
|
|
264
|
-
w(
|
|
261
|
+
w(`Last activity: ${formatDuration(data.timeSinceLastActivity)} ago\n`);
|
|
262
|
+
w(`Task: ${session.taskId}\n`);
|
|
263
|
+
w(`Capability: ${session.capability}\n`);
|
|
264
|
+
w(`Branch: ${session.branchName}\n`);
|
|
265
265
|
if (session.parentAgent) {
|
|
266
|
-
w(
|
|
266
|
+
w(`Parent: ${session.parentAgent} (depth: ${session.depth})\n`);
|
|
267
267
|
}
|
|
268
|
-
w(
|
|
269
|
-
w(
|
|
268
|
+
w(`Started: ${session.startedAt}\n`);
|
|
269
|
+
w(`Tmux: ${session.tmuxSession}\n`);
|
|
270
270
|
w("\n");
|
|
271
271
|
|
|
272
272
|
// Current file
|
|
273
273
|
if (data.currentFile) {
|
|
274
|
-
w(
|
|
274
|
+
w(`Current file: ${data.currentFile}\n\n`);
|
|
275
275
|
}
|
|
276
276
|
|
|
277
277
|
// Token usage
|
|
278
278
|
if (data.tokenUsage) {
|
|
279
|
-
w("
|
|
279
|
+
w("Token Usage\n");
|
|
280
280
|
w(`${"─".repeat(80)}\n`);
|
|
281
281
|
w(` Input: ${data.tokenUsage.inputTokens.toLocaleString()}\n`);
|
|
282
282
|
w(` Output: ${data.tokenUsage.outputTokens.toLocaleString()}\n`);
|
|
@@ -293,7 +293,7 @@ export function printInspectData(data: InspectData): void {
|
|
|
293
293
|
|
|
294
294
|
// Tool usage statistics (top 10)
|
|
295
295
|
if (data.toolStats.length > 0) {
|
|
296
|
-
w("
|
|
296
|
+
w("Tool Usage (Top 10)\n");
|
|
297
297
|
w(`${"─".repeat(80)}\n`);
|
|
298
298
|
const top10 = data.toolStats.slice(0, 10);
|
|
299
299
|
for (const stat of top10) {
|
|
@@ -306,7 +306,7 @@ export function printInspectData(data: InspectData): void {
|
|
|
306
306
|
|
|
307
307
|
// Recent tool calls
|
|
308
308
|
if (data.recentToolCalls.length > 0) {
|
|
309
|
-
w(
|
|
309
|
+
w(`Recent Tool Calls (last ${data.recentToolCalls.length})\n`);
|
|
310
310
|
w(`${"─".repeat(80)}\n`);
|
|
311
311
|
for (const call of data.recentToolCalls) {
|
|
312
312
|
const time = new Date(call.timestamp).toLocaleTimeString();
|
|
@@ -322,7 +322,7 @@ export function printInspectData(data: InspectData): void {
|
|
|
322
322
|
|
|
323
323
|
// tmux output
|
|
324
324
|
if (data.tmuxOutput) {
|
|
325
|
-
w("
|
|
325
|
+
w("Live Tmux Output\n");
|
|
326
326
|
w(`${"─".repeat(80)}\n`);
|
|
327
327
|
w(`${data.tmuxOutput}\n`);
|
|
328
328
|
w(`${"─".repeat(80)}\n`);
|
package/src/commands/log.test.ts
CHANGED
|
@@ -218,7 +218,7 @@ describe("logCommand", () => {
|
|
|
218
218
|
capability: "builder",
|
|
219
219
|
worktreePath: "/tmp/test",
|
|
220
220
|
branchName: "test-branch",
|
|
221
|
-
|
|
221
|
+
taskId: "bead-001",
|
|
222
222
|
tmuxSession: "test-tmux",
|
|
223
223
|
state: "working",
|
|
224
224
|
pid: 12345,
|
|
@@ -273,7 +273,7 @@ describe("logCommand", () => {
|
|
|
273
273
|
capability: "scout",
|
|
274
274
|
worktreePath: "/tmp/metrics",
|
|
275
275
|
branchName: "metrics-branch",
|
|
276
|
-
|
|
276
|
+
taskId: "bead-002",
|
|
277
277
|
tmuxSession: "metrics-tmux",
|
|
278
278
|
state: "working",
|
|
279
279
|
pid: 54321,
|
|
@@ -299,7 +299,7 @@ describe("logCommand", () => {
|
|
|
299
299
|
|
|
300
300
|
expect(metrics).toHaveLength(1);
|
|
301
301
|
expect(metrics[0]?.agentName).toBe("metrics-agent");
|
|
302
|
-
expect(metrics[0]?.
|
|
302
|
+
expect(metrics[0]?.taskId).toBe("bead-002");
|
|
303
303
|
expect(metrics[0]?.capability).toBe("scout");
|
|
304
304
|
expect(metrics[0]?.parentAgent).toBe("parent-agent");
|
|
305
305
|
});
|
|
@@ -313,7 +313,7 @@ describe("logCommand", () => {
|
|
|
313
313
|
capability: "coordinator",
|
|
314
314
|
worktreePath: tempDir,
|
|
315
315
|
branchName: "main",
|
|
316
|
-
|
|
316
|
+
taskId: "",
|
|
317
317
|
tmuxSession: "overstory-coordinator",
|
|
318
318
|
state: "working",
|
|
319
319
|
pid: 11111,
|
|
@@ -352,7 +352,7 @@ describe("logCommand", () => {
|
|
|
352
352
|
capability: "monitor",
|
|
353
353
|
worktreePath: tempDir,
|
|
354
354
|
branchName: "main",
|
|
355
|
-
|
|
355
|
+
taskId: "",
|
|
356
356
|
tmuxSession: "overstory-monitor",
|
|
357
357
|
state: "working",
|
|
358
358
|
pid: 22222,
|
|
@@ -389,7 +389,7 @@ describe("logCommand", () => {
|
|
|
389
389
|
capability: "coordinator",
|
|
390
390
|
worktreePath: tempDir,
|
|
391
391
|
branchName: "main",
|
|
392
|
-
|
|
392
|
+
taskId: "",
|
|
393
393
|
tmuxSession: "overstory-coordinator",
|
|
394
394
|
state: "working",
|
|
395
395
|
pid: 11111,
|
|
@@ -446,7 +446,7 @@ describe("logCommand", () => {
|
|
|
446
446
|
capability: "coordinator",
|
|
447
447
|
worktreePath: tempDir,
|
|
448
448
|
branchName: "main",
|
|
449
|
-
|
|
449
|
+
taskId: "",
|
|
450
450
|
tmuxSession: "overstory-coordinator-no-run",
|
|
451
451
|
state: "working",
|
|
452
452
|
pid: 11112,
|
|
@@ -476,7 +476,7 @@ describe("logCommand", () => {
|
|
|
476
476
|
capability: "builder",
|
|
477
477
|
worktreePath: tempDir,
|
|
478
478
|
branchName: "builder-branch",
|
|
479
|
-
|
|
479
|
+
taskId: "bead-builder-001",
|
|
480
480
|
tmuxSession: "overstory-builder",
|
|
481
481
|
state: "working",
|
|
482
482
|
pid: 11113,
|
|
@@ -530,7 +530,7 @@ describe("logCommand", () => {
|
|
|
530
530
|
capability: "coordinator",
|
|
531
531
|
worktreePath: tempDir,
|
|
532
532
|
branchName: "main",
|
|
533
|
-
|
|
533
|
+
taskId: "",
|
|
534
534
|
tmuxSession: "overstory-coordinator-completed",
|
|
535
535
|
state: "working",
|
|
536
536
|
pid: 11114,
|
|
@@ -583,7 +583,7 @@ describe("logCommand", () => {
|
|
|
583
583
|
capability: "lead",
|
|
584
584
|
worktreePath: tempDir,
|
|
585
585
|
branchName: "lead-alpha-branch",
|
|
586
|
-
|
|
586
|
+
taskId: "bead-lead-001",
|
|
587
587
|
tmuxSession: "overstory-lead-alpha",
|
|
588
588
|
state: "working",
|
|
589
589
|
pid: 33333,
|
|
@@ -623,7 +623,7 @@ describe("logCommand", () => {
|
|
|
623
623
|
capability: "builder",
|
|
624
624
|
worktreePath: tempDir,
|
|
625
625
|
branchName: "builder-beta-branch",
|
|
626
|
-
|
|
626
|
+
taskId: "bead-builder-001",
|
|
627
627
|
tmuxSession: "overstory-builder-beta",
|
|
628
628
|
state: "working",
|
|
629
629
|
pid: 44444,
|
|
@@ -665,7 +665,7 @@ describe("logCommand", () => {
|
|
|
665
665
|
capability: "builder",
|
|
666
666
|
worktreePath: "/tmp/activity",
|
|
667
667
|
branchName: "activity-branch",
|
|
668
|
-
|
|
668
|
+
taskId: "bead-003",
|
|
669
669
|
tmuxSession: "activity-tmux",
|
|
670
670
|
state: "working",
|
|
671
671
|
pid: 99999,
|
|
@@ -704,7 +704,7 @@ describe("logCommand", () => {
|
|
|
704
704
|
capability: "builder",
|
|
705
705
|
worktreePath: "/tmp/booting",
|
|
706
706
|
branchName: "booting-branch",
|
|
707
|
-
|
|
707
|
+
taskId: "bead-004",
|
|
708
708
|
tmuxSession: "booting-tmux",
|
|
709
709
|
state: "booting",
|
|
710
710
|
pid: 11111,
|
|
@@ -789,7 +789,7 @@ describe("logCommand", () => {
|
|
|
789
789
|
capability: "builder",
|
|
790
790
|
worktreePath: tempDir,
|
|
791
791
|
branchName: "mulch-fail-branch",
|
|
792
|
-
|
|
792
|
+
taskId: "bead-mulch-001",
|
|
793
793
|
tmuxSession: "overstory-mulch-fail",
|
|
794
794
|
state: "working",
|
|
795
795
|
pid: 55555,
|
|
@@ -828,7 +828,7 @@ describe("logCommand", () => {
|
|
|
828
828
|
capability: "coordinator",
|
|
829
829
|
worktreePath: tempDir,
|
|
830
830
|
branchName: "main",
|
|
831
|
-
|
|
831
|
+
taskId: "",
|
|
832
832
|
tmuxSession: "overstory-coordinator-mulch",
|
|
833
833
|
state: "working",
|
|
834
834
|
pid: 66666,
|
|
@@ -875,7 +875,7 @@ describe("logCommand", () => {
|
|
|
875
875
|
mulchClient: client,
|
|
876
876
|
agentName: "test-builder",
|
|
877
877
|
capability: "builder",
|
|
878
|
-
|
|
878
|
+
taskId: "bead-123",
|
|
879
879
|
mailDbPath,
|
|
880
880
|
parentAgent: "parent-lead",
|
|
881
881
|
projectRoot: tempDir,
|
|
@@ -908,7 +908,7 @@ describe("logCommand", () => {
|
|
|
908
908
|
mulchClient: client,
|
|
909
909
|
agentName: "test-builder",
|
|
910
910
|
capability: "builder",
|
|
911
|
-
|
|
911
|
+
taskId: "bead-456",
|
|
912
912
|
mailDbPath,
|
|
913
913
|
parentAgent: "parent-lead",
|
|
914
914
|
projectRoot: tempDir,
|
|
@@ -940,7 +940,7 @@ describe("logCommand", () => {
|
|
|
940
940
|
mulchClient: client,
|
|
941
941
|
agentName: "test-builder",
|
|
942
942
|
capability: "builder",
|
|
943
|
-
|
|
943
|
+
taskId: null,
|
|
944
944
|
mailDbPath,
|
|
945
945
|
parentAgent: null,
|
|
946
946
|
projectRoot: tempDir,
|
|
@@ -968,7 +968,7 @@ describe("logCommand", () => {
|
|
|
968
968
|
mulchClient: client,
|
|
969
969
|
agentName: "test-builder",
|
|
970
970
|
capability: "builder",
|
|
971
|
-
|
|
971
|
+
taskId: null,
|
|
972
972
|
mailDbPath,
|
|
973
973
|
parentAgent: null,
|
|
974
974
|
projectRoot: tempDir,
|
|
@@ -1047,7 +1047,7 @@ describe("logCommand", () => {
|
|
|
1047
1047
|
mulchClient: client,
|
|
1048
1048
|
agentName: "insight-agent",
|
|
1049
1049
|
capability: "builder",
|
|
1050
|
-
|
|
1050
|
+
taskId: "bead-insight",
|
|
1051
1051
|
mailDbPath,
|
|
1052
1052
|
parentAgent: "parent-agent",
|
|
1053
1053
|
projectRoot: tempDir,
|
|
@@ -1127,7 +1127,7 @@ describe("logCommand", () => {
|
|
|
1127
1127
|
mulchClient: client,
|
|
1128
1128
|
agentName: "mail-insight-agent",
|
|
1129
1129
|
capability: "scout",
|
|
1130
|
-
|
|
1130
|
+
taskId: "bead-mail",
|
|
1131
1131
|
mailDbPath,
|
|
1132
1132
|
parentAgent: "parent-agent",
|
|
1133
1133
|
projectRoot: tempDir,
|
package/src/commands/log.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* CLI command:
|
|
2
|
+
* CLI command: ov log <event> --agent <name> [--stdin]
|
|
3
3
|
*
|
|
4
4
|
* Called by Pre/PostToolUse and Stop hooks.
|
|
5
5
|
* Events: tool-start, tool-end, session-end.
|
|
@@ -227,7 +227,7 @@ export async function autoRecordExpertise(params: {
|
|
|
227
227
|
mulchClient: MulchClient;
|
|
228
228
|
agentName: string;
|
|
229
229
|
capability: string;
|
|
230
|
-
|
|
230
|
+
taskId: string | null;
|
|
231
231
|
mailDbPath: string;
|
|
232
232
|
parentAgent: string | null;
|
|
233
233
|
projectRoot: string;
|
|
@@ -247,7 +247,7 @@ export async function autoRecordExpertise(params: {
|
|
|
247
247
|
type: "reference",
|
|
248
248
|
description: `${params.capability} agent ${params.agentName} completed work in this domain. Files: ${filesList}`,
|
|
249
249
|
tags: ["auto-session-end", params.capability],
|
|
250
|
-
evidenceBead: params.
|
|
250
|
+
evidenceBead: params.taskId ?? undefined,
|
|
251
251
|
});
|
|
252
252
|
recordedDomains.push(domain);
|
|
253
253
|
} catch {
|
|
@@ -286,7 +286,7 @@ export async function autoRecordExpertise(params: {
|
|
|
286
286
|
type: insight.type,
|
|
287
287
|
description: insight.description,
|
|
288
288
|
tags: insight.tags,
|
|
289
|
-
evidenceBead: params.
|
|
289
|
+
evidenceBead: params.taskId ?? undefined,
|
|
290
290
|
});
|
|
291
291
|
if (!recordedDomains.includes(insight.domain)) {
|
|
292
292
|
recordedDomains.push(insight.domain);
|
|
@@ -503,14 +503,14 @@ async function runLog(opts: {
|
|
|
503
503
|
// Look up agent session for identity update and metrics recording
|
|
504
504
|
{
|
|
505
505
|
const agentSession = getAgentSession(config.project.root, opts.agent);
|
|
506
|
-
const
|
|
506
|
+
const taskId = agentSession?.taskId ?? null;
|
|
507
507
|
|
|
508
508
|
// Update agent identity with completed session
|
|
509
509
|
const identityBaseDir = join(config.project.root, ".overstory", "agents");
|
|
510
510
|
try {
|
|
511
511
|
await updateIdentity(identityBaseDir, opts.agent, {
|
|
512
512
|
sessionsCompleted: 1,
|
|
513
|
-
completedTask:
|
|
513
|
+
completedTask: taskId ? { taskId, summary: `Completed task ${taskId}` } : undefined,
|
|
514
514
|
});
|
|
515
515
|
} catch {
|
|
516
516
|
// Non-fatal: identity may not exist for this agent
|
|
@@ -542,7 +542,7 @@ async function runLog(opts: {
|
|
|
542
542
|
if (agentSession) {
|
|
543
543
|
// Auto-complete the current run when the coordinator exits.
|
|
544
544
|
// This handles the case where the user closes the tmux window
|
|
545
|
-
// without running `
|
|
545
|
+
// without running `ov coordinator stop`.
|
|
546
546
|
if (agentSession.capability === "coordinator") {
|
|
547
547
|
try {
|
|
548
548
|
const currentRunPath = join(config.project.root, ".overstory", "current-run.txt");
|
|
@@ -601,7 +601,7 @@ async function runLog(opts: {
|
|
|
601
601
|
|
|
602
602
|
metricsStore.recordSession({
|
|
603
603
|
agentName: opts.agent,
|
|
604
|
-
|
|
604
|
+
taskId: agentSession.taskId,
|
|
605
605
|
capability: agentSession.capability,
|
|
606
606
|
startedAt: agentSession.startedAt,
|
|
607
607
|
completedAt: now,
|
|
@@ -632,7 +632,7 @@ async function runLog(opts: {
|
|
|
632
632
|
mulchClient,
|
|
633
633
|
agentName: opts.agent,
|
|
634
634
|
capability: agentSession.capability,
|
|
635
|
-
|
|
635
|
+
taskId,
|
|
636
636
|
mailDbPath,
|
|
637
637
|
parentAgent: agentSession.parentAgent,
|
|
638
638
|
projectRoot: config.project.root,
|
|
@@ -710,7 +710,7 @@ export function createLogCommand(): Command {
|
|
|
710
710
|
}
|
|
711
711
|
|
|
712
712
|
/**
|
|
713
|
-
* Entry point for `
|
|
713
|
+
* Entry point for `ov log <event> --agent <name>`.
|
|
714
714
|
*/
|
|
715
715
|
export async function logCommand(args: string[]): Promise<void> {
|
|
716
716
|
const cmd = createLogCommand();
|
package/src/commands/logs.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* CLI command:
|
|
2
|
+
* CLI command: ov logs [--agent <name>] [--level <level>] [--since <time>] [--until <time>] [--limit <n>] [--follow] [--json]
|
|
3
3
|
*
|
|
4
4
|
* Queries NDJSON log files from .overstory/logs/{agent-name}/{session-timestamp}/events.ndjson
|
|
5
5
|
* and presents a unified timeline view.
|