@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
|
@@ -137,7 +137,7 @@ function makeAgentSession(overrides: Partial<AgentSession> = {}): AgentSession {
|
|
|
137
137
|
capability: "builder",
|
|
138
138
|
worktreePath: join(tempDir, ".overstory", "worktrees", "my-builder"),
|
|
139
139
|
branchName: "overstory/my-builder/bead-123",
|
|
140
|
-
|
|
140
|
+
taskId: "bead-123",
|
|
141
141
|
tmuxSession: "overstory-test-project-my-builder",
|
|
142
142
|
state: "working",
|
|
143
143
|
pid: 99999,
|
package/src/commands/stop.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* CLI command:
|
|
2
|
+
* CLI command: ov stop <agent-name>
|
|
3
3
|
*
|
|
4
4
|
* Explicitly terminates a running agent by:
|
|
5
5
|
* 1. Looking up the agent session by name
|
|
@@ -37,7 +37,7 @@ export interface StopDeps {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
|
-
* Entry point for `
|
|
40
|
+
* Entry point for `ov stop <agent-name>`.
|
|
41
41
|
*
|
|
42
42
|
* @param agentName - Name of the agent to stop
|
|
43
43
|
* @param opts - Command options
|
|
@@ -11,10 +11,10 @@ import { buildSupervisorBeacon, supervisorCommand } from "./supervisor.ts";
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
describe("buildSupervisorBeacon", () => {
|
|
14
|
-
test("contains agent name and
|
|
14
|
+
test("contains agent name and taskId from opts", () => {
|
|
15
15
|
const beacon = buildSupervisorBeacon({
|
|
16
16
|
name: "supervisor-1",
|
|
17
|
-
|
|
17
|
+
taskId: "task-abc123",
|
|
18
18
|
depth: 1,
|
|
19
19
|
parent: "coordinator",
|
|
20
20
|
});
|
|
@@ -26,7 +26,7 @@ describe("buildSupervisorBeacon", () => {
|
|
|
26
26
|
test("contains [OVERSTORY] prefix", () => {
|
|
27
27
|
const beacon = buildSupervisorBeacon({
|
|
28
28
|
name: "supervisor-1",
|
|
29
|
-
|
|
29
|
+
taskId: "task-1",
|
|
30
30
|
depth: 1,
|
|
31
31
|
parent: "coordinator",
|
|
32
32
|
});
|
|
@@ -37,7 +37,7 @@ describe("buildSupervisorBeacon", () => {
|
|
|
37
37
|
test("contains (supervisor) designation", () => {
|
|
38
38
|
const beacon = buildSupervisorBeacon({
|
|
39
39
|
name: "supervisor-1",
|
|
40
|
-
|
|
40
|
+
taskId: "task-1",
|
|
41
41
|
depth: 1,
|
|
42
42
|
parent: "coordinator",
|
|
43
43
|
});
|
|
@@ -48,7 +48,7 @@ describe("buildSupervisorBeacon", () => {
|
|
|
48
48
|
test("contains depth and parent info from opts", () => {
|
|
49
49
|
const beacon = buildSupervisorBeacon({
|
|
50
50
|
name: "supervisor-1",
|
|
51
|
-
|
|
51
|
+
taskId: "task-1",
|
|
52
52
|
depth: 2,
|
|
53
53
|
parent: "lead-cli",
|
|
54
54
|
});
|
|
@@ -60,7 +60,7 @@ describe("buildSupervisorBeacon", () => {
|
|
|
60
60
|
test("contains startup instructions", () => {
|
|
61
61
|
const beacon = buildSupervisorBeacon({
|
|
62
62
|
name: "supervisor-1",
|
|
63
|
-
|
|
63
|
+
taskId: "task-1",
|
|
64
64
|
depth: 1,
|
|
65
65
|
parent: "coordinator",
|
|
66
66
|
});
|
|
@@ -69,9 +69,9 @@ describe("buildSupervisorBeacon", () => {
|
|
|
69
69
|
expect(beacon).toContain("mulch prime");
|
|
70
70
|
|
|
71
71
|
// Should include mail check with agent name
|
|
72
|
-
expect(beacon).toContain("
|
|
72
|
+
expect(beacon).toContain("ov mail check --agent supervisor-1");
|
|
73
73
|
|
|
74
|
-
// Should include bd show with
|
|
74
|
+
// Should include bd show with taskId
|
|
75
75
|
expect(beacon).toContain("bd show task-1");
|
|
76
76
|
});
|
|
77
77
|
|
|
@@ -79,13 +79,13 @@ describe("buildSupervisorBeacon", () => {
|
|
|
79
79
|
const before = new Date();
|
|
80
80
|
const beacon = buildSupervisorBeacon({
|
|
81
81
|
name: "supervisor-1",
|
|
82
|
-
|
|
82
|
+
taskId: "task-1",
|
|
83
83
|
depth: 1,
|
|
84
84
|
parent: "coordinator",
|
|
85
85
|
});
|
|
86
86
|
const after = new Date();
|
|
87
87
|
|
|
88
|
-
// Extract timestamp from beacon (format: [OVERSTORY] {name} (supervisor) {timestamp} task:{
|
|
88
|
+
// Extract timestamp from beacon (format: [OVERSTORY] {name} (supervisor) {timestamp} task:{taskId})
|
|
89
89
|
const timestampMatch = beacon.match(/\(supervisor\)\s+(\S+)\s+task:/);
|
|
90
90
|
expect(timestampMatch).toBeTruthy();
|
|
91
91
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* CLI command:
|
|
2
|
+
* CLI command: ov supervisor start|stop|status
|
|
3
3
|
*
|
|
4
4
|
* Manages per-project supervisor agent lifecycle. The supervisor is a persistent
|
|
5
5
|
* agent that runs at the project root (NOT in a worktree), assigned to a specific
|
|
@@ -36,13 +36,13 @@ import { isRunningAsRoot } from "./sling.ts";
|
|
|
36
36
|
* Build the supervisor startup beacon.
|
|
37
37
|
*
|
|
38
38
|
* @param opts.name - Supervisor agent name
|
|
39
|
-
* @param opts.
|
|
39
|
+
* @param opts.taskId - Bead task ID
|
|
40
40
|
* @param opts.depth - Hierarchy depth (default 1)
|
|
41
41
|
* @param opts.parent - Parent agent name (default "coordinator")
|
|
42
42
|
*/
|
|
43
43
|
export function buildSupervisorBeacon(opts: {
|
|
44
44
|
name: string;
|
|
45
|
-
|
|
45
|
+
taskId: string;
|
|
46
46
|
depth: number;
|
|
47
47
|
parent: string;
|
|
48
48
|
trackerCli?: string;
|
|
@@ -50,9 +50,9 @@ export function buildSupervisorBeacon(opts: {
|
|
|
50
50
|
const cli = opts.trackerCli ?? "bd";
|
|
51
51
|
const timestamp = new Date().toISOString();
|
|
52
52
|
const parts = [
|
|
53
|
-
`[OVERSTORY] ${opts.name} (supervisor) ${timestamp} task:${opts.
|
|
53
|
+
`[OVERSTORY] ${opts.name} (supervisor) ${timestamp} task:${opts.taskId}`,
|
|
54
54
|
`Depth: ${opts.depth} | Parent: ${opts.parent} | Role: per-project supervisor`,
|
|
55
|
-
`Startup: run mulch prime, check mail (
|
|
55
|
+
`Startup: run mulch prime, check mail (ov mail check --agent ${opts.name}), read task (${cli} show ${opts.taskId}), then begin supervising`,
|
|
56
56
|
];
|
|
57
57
|
return parts.join(" — ");
|
|
58
58
|
}
|
|
@@ -182,7 +182,7 @@ async function startSupervisor(opts: {
|
|
|
182
182
|
|
|
183
183
|
const beacon = buildSupervisorBeacon({
|
|
184
184
|
name: opts.name,
|
|
185
|
-
|
|
185
|
+
taskId: opts.task,
|
|
186
186
|
depth: opts.depth,
|
|
187
187
|
parent: opts.parent,
|
|
188
188
|
trackerCli: trackerCliName(resolvedBackend),
|
|
@@ -202,7 +202,7 @@ async function startSupervisor(opts: {
|
|
|
202
202
|
capability: "supervisor",
|
|
203
203
|
worktreePath: projectRoot, // Supervisor uses project root, not a worktree
|
|
204
204
|
branchName: config.project.canonicalBranch, // Operates on canonical branch
|
|
205
|
-
|
|
205
|
+
taskId: opts.task,
|
|
206
206
|
tmuxSession,
|
|
207
207
|
state: "booting",
|
|
208
208
|
pid,
|
|
@@ -222,7 +222,7 @@ async function startSupervisor(opts: {
|
|
|
222
222
|
capability: "supervisor",
|
|
223
223
|
tmuxSession,
|
|
224
224
|
projectRoot,
|
|
225
|
-
|
|
225
|
+
taskId: opts.task,
|
|
226
226
|
parent: opts.parent,
|
|
227
227
|
depth: opts.depth,
|
|
228
228
|
pid,
|
|
@@ -347,7 +347,7 @@ async function statusSupervisor(opts: { name?: string; json: boolean }): Promise
|
|
|
347
347
|
agentName: session.agentName,
|
|
348
348
|
state: session.state,
|
|
349
349
|
tmuxSession: session.tmuxSession,
|
|
350
|
-
|
|
350
|
+
taskId: session.taskId,
|
|
351
351
|
parentAgent: session.parentAgent,
|
|
352
352
|
depth: session.depth,
|
|
353
353
|
pid: session.pid,
|
|
@@ -362,7 +362,7 @@ async function statusSupervisor(opts: { name?: string; json: boolean }): Promise
|
|
|
362
362
|
process.stdout.write(`Supervisor '${opts.name}': ${stateLabel}\n`);
|
|
363
363
|
process.stdout.write(` Session: ${session.id}\n`);
|
|
364
364
|
process.stdout.write(` Tmux: ${session.tmuxSession}\n`);
|
|
365
|
-
process.stdout.write(` Task: ${session.
|
|
365
|
+
process.stdout.write(` Task: ${session.taskId}\n`);
|
|
366
366
|
process.stdout.write(` Parent: ${session.parentAgent}\n`);
|
|
367
367
|
process.stdout.write(` Depth: ${session.depth}\n`);
|
|
368
368
|
process.stdout.write(` PID: ${session.pid}\n`);
|
|
@@ -401,7 +401,7 @@ async function statusSupervisor(opts: { name?: string; json: boolean }): Promise
|
|
|
401
401
|
? ("zombie" as const)
|
|
402
402
|
: session.state,
|
|
403
403
|
tmuxSession: session.tmuxSession,
|
|
404
|
-
|
|
404
|
+
taskId: session.taskId,
|
|
405
405
|
parentAgent: session.parentAgent,
|
|
406
406
|
depth: session.depth,
|
|
407
407
|
startedAt: session.startedAt,
|
|
@@ -416,7 +416,7 @@ async function statusSupervisor(opts: { name?: string; json: boolean }): Promise
|
|
|
416
416
|
for (const status of statuses) {
|
|
417
417
|
const stateLabel = status.running ? "running" : status.state;
|
|
418
418
|
process.stdout.write(
|
|
419
|
-
` ${status.agentName}: ${stateLabel} (task: ${status.
|
|
419
|
+
` ${status.agentName}: ${stateLabel} (task: ${status.taskId}, parent: ${status.parentAgent})\n`,
|
|
420
420
|
);
|
|
421
421
|
}
|
|
422
422
|
}
|
|
@@ -427,7 +427,7 @@ async function statusSupervisor(opts: { name?: string; json: boolean }): Promise
|
|
|
427
427
|
}
|
|
428
428
|
|
|
429
429
|
/**
|
|
430
|
-
* Create the Commander command for `
|
|
430
|
+
* Create the Commander command for `ov supervisor`.
|
|
431
431
|
*/
|
|
432
432
|
export function createSupervisorCommand(): Command {
|
|
433
433
|
const cmd = new Command("supervisor").description("Manage per-project supervisor agents");
|
|
@@ -480,7 +480,7 @@ export function createSupervisorCommand(): Command {
|
|
|
480
480
|
}
|
|
481
481
|
|
|
482
482
|
/**
|
|
483
|
-
* Entry point for `
|
|
483
|
+
* Entry point for `ov supervisor <subcommand>`.
|
|
484
484
|
*/
|
|
485
485
|
export async function supervisorCommand(args: string[]): Promise<void> {
|
|
486
486
|
const cmd = createSupervisorCommand();
|
|
@@ -509,7 +509,7 @@ describe("traceCommand", () => {
|
|
|
509
509
|
// === Target resolution ===
|
|
510
510
|
|
|
511
511
|
describe("target resolution", () => {
|
|
512
|
-
test("agent name is used as-is when not a
|
|
512
|
+
test("agent name is used as-is when not a task ID pattern", async () => {
|
|
513
513
|
const dbPath = join(tempDir, ".overstory", "events.db");
|
|
514
514
|
const store = createEventStore(dbPath);
|
|
515
515
|
store.insert(makeEvent({ agentName: "my-custom-agent" }));
|
|
@@ -523,8 +523,8 @@ describe("traceCommand", () => {
|
|
|
523
523
|
expect(parsed[0]?.agentName).toBe("my-custom-agent");
|
|
524
524
|
});
|
|
525
525
|
|
|
526
|
-
test("
|
|
527
|
-
// Create a session that maps
|
|
526
|
+
test("task ID pattern is detected and resolved to agent name via SessionStore", async () => {
|
|
527
|
+
// Create a session that maps task ID to agent name
|
|
528
528
|
const sessDbPath = join(tempDir, ".overstory", "sessions.db");
|
|
529
529
|
const sessionStore = createSessionStore(sessDbPath);
|
|
530
530
|
sessionStore.upsert({
|
|
@@ -533,7 +533,7 @@ describe("traceCommand", () => {
|
|
|
533
533
|
capability: "builder",
|
|
534
534
|
worktreePath: "/tmp/wt",
|
|
535
535
|
branchName: "feat/task",
|
|
536
|
-
|
|
536
|
+
taskId: "overstory-rj1k",
|
|
537
537
|
tmuxSession: "tmux-001",
|
|
538
538
|
state: "completed",
|
|
539
539
|
pid: null,
|
|
@@ -561,7 +561,7 @@ describe("traceCommand", () => {
|
|
|
561
561
|
expect(parsed[0]?.agentName).toBe("builder-for-task");
|
|
562
562
|
});
|
|
563
563
|
|
|
564
|
-
test("unresolved
|
|
564
|
+
test("unresolved task ID falls back to using task ID as agent name", async () => {
|
|
565
565
|
// Create sessions.db but with no matching bead
|
|
566
566
|
const sessDbPath = join(tempDir, ".overstory", "sessions.db");
|
|
567
567
|
const sessionStore = createSessionStore(sessDbPath);
|
|
@@ -579,13 +579,13 @@ describe("traceCommand", () => {
|
|
|
579
579
|
expect(parsed).toEqual([]);
|
|
580
580
|
});
|
|
581
581
|
|
|
582
|
-
test("short agent names without
|
|
582
|
+
test("short agent names without task pattern are not resolved as task IDs", async () => {
|
|
583
583
|
const dbPath = join(tempDir, ".overstory", "events.db");
|
|
584
584
|
const store = createEventStore(dbPath);
|
|
585
585
|
store.insert(makeEvent({ agentName: "scout" }));
|
|
586
586
|
store.close();
|
|
587
587
|
|
|
588
|
-
// "scout" does not match
|
|
588
|
+
// "scout" does not match task pattern word-alphanumeric
|
|
589
589
|
await traceCommand(["scout", "--json"]);
|
|
590
590
|
const out = output();
|
|
591
591
|
|
package/src/commands/trace.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* CLI command:
|
|
2
|
+
* CLI command: ov trace <target> [--json] [--since <ts>] [--until <ts>] [--limit <n>]
|
|
3
3
|
*
|
|
4
4
|
* Shows a chronological timeline of events for an agent or bead task.
|
|
5
|
-
* Target can be an agent name or a
|
|
5
|
+
* Target can be an agent name or a task ID (resolved to agent name via SessionStore).
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { join } from "node:path";
|
|
@@ -29,10 +29,10 @@ const EVENT_LABELS: Record<EventType, { label: string; color: ColorFn }> = {
|
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
|
-
* Detect whether a target string looks like a
|
|
33
|
-
*
|
|
32
|
+
* Detect whether a target string looks like a task ID.
|
|
33
|
+
* Task IDs follow the pattern: word-alphanumeric (e.g., "overstory-rj1k", "myproject-abc1").
|
|
34
34
|
*/
|
|
35
|
-
function
|
|
35
|
+
function looksLikeTaskId(target: string): boolean {
|
|
36
36
|
return /^[a-z][a-z0-9]*-[a-z0-9]{3,}$/i.test(target);
|
|
37
37
|
}
|
|
38
38
|
|
|
@@ -220,16 +220,16 @@ async function executeTrace(target: string, opts: TraceOpts): Promise<void> {
|
|
|
220
220
|
// Resolve target to agent name
|
|
221
221
|
let agentName = target;
|
|
222
222
|
|
|
223
|
-
if (
|
|
224
|
-
// Try to resolve
|
|
223
|
+
if (looksLikeTaskId(target)) {
|
|
224
|
+
// Try to resolve task ID to agent name via SessionStore
|
|
225
225
|
const { store: sessionStore } = openSessionStore(overstoryDir);
|
|
226
226
|
try {
|
|
227
227
|
const allSessions = sessionStore.getAll();
|
|
228
|
-
const matchingSession = allSessions.find((s) => s.
|
|
228
|
+
const matchingSession = allSessions.find((s) => s.taskId === target);
|
|
229
229
|
if (matchingSession) {
|
|
230
230
|
agentName = matchingSession.agentName;
|
|
231
231
|
} else {
|
|
232
|
-
// No session found for this
|
|
232
|
+
// No session found for this task ID; treat it as an agent name anyway
|
|
233
233
|
// (the event query will return empty results if no events match)
|
|
234
234
|
agentName = target;
|
|
235
235
|
}
|
|
@@ -275,7 +275,7 @@ async function executeTrace(target: string, opts: TraceOpts): Promise<void> {
|
|
|
275
275
|
export function createTraceCommand(): Command {
|
|
276
276
|
return new Command("trace")
|
|
277
277
|
.description("Chronological event timeline for agent/bead")
|
|
278
|
-
.argument("<target>", "Agent name or
|
|
278
|
+
.argument("<target>", "Agent name or task ID")
|
|
279
279
|
.option("--json", "Output as JSON array of StoredEvent objects")
|
|
280
280
|
.option("--since <timestamp>", "Start time filter (ISO 8601)")
|
|
281
281
|
.option("--until <timestamp>", "End time filter (ISO 8601)")
|
package/src/commands/watch.ts
CHANGED
|
@@ -20,12 +20,12 @@ import { isProcessRunning } from "../watchdog/health.ts";
|
|
|
20
20
|
function formatCheck(check: HealthCheck): string {
|
|
21
21
|
const actionIcon =
|
|
22
22
|
check.action === "terminate"
|
|
23
|
-
? "
|
|
23
|
+
? "x"
|
|
24
24
|
: check.action === "escalate"
|
|
25
|
-
? "
|
|
25
|
+
? "!"
|
|
26
26
|
: check.action === "investigate"
|
|
27
|
-
? "
|
|
28
|
-
: "
|
|
27
|
+
? ">"
|
|
28
|
+
: "x";
|
|
29
29
|
const pidLabel = check.pidAlive === null ? "n/a" : check.pidAlive ? "up" : "down";
|
|
30
30
|
let line = `${actionIcon} ${check.agentName}: ${check.state} (tmux=${check.tmuxAlive ? "up" : "down"}, pid=${pidLabel})`;
|
|
31
31
|
if (check.reconciliationNote) {
|
|
@@ -84,7 +84,7 @@ async function removePidFile(pidFilePath: string): Promise<void> {
|
|
|
84
84
|
*/
|
|
85
85
|
async function resolveOverstoryBin(): Promise<string> {
|
|
86
86
|
try {
|
|
87
|
-
const proc = Bun.spawn(["which", "
|
|
87
|
+
const proc = Bun.spawn(["which", "ov"], {
|
|
88
88
|
stdout: "pipe",
|
|
89
89
|
stderr: "pipe",
|
|
90
90
|
});
|