@os-eco/overstory-cli 0.6.10 → 0.7.0
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 +156 -274
- package/agents/lead.md +29 -19
- package/package.json +5 -3
- package/src/agents/hooks-deployer.test.ts +53 -0
- package/src/agents/hooks-deployer.ts +4 -4
- package/src/agents/manifest.test.ts +1 -0
- package/src/agents/overlay.test.ts +102 -0
- package/src/agents/overlay.ts +45 -6
- package/src/commands/completions.ts +3 -3
- package/src/commands/coordinator.ts +25 -13
- package/src/commands/costs.test.ts +1 -1
- package/src/commands/costs.ts +13 -20
- package/src/commands/dashboard.ts +38 -138
- package/src/commands/doctor.test.ts +1 -1
- package/src/commands/doctor.ts +2 -2
- package/src/commands/ecosystem.ts +2 -1
- package/src/commands/errors.test.ts +4 -5
- package/src/commands/errors.ts +4 -62
- package/src/commands/feed.test.ts +2 -2
- package/src/commands/feed.ts +12 -106
- package/src/commands/group.ts +4 -4
- package/src/commands/inspect.ts +10 -44
- package/src/commands/logs.ts +7 -63
- package/src/commands/mail.test.ts +63 -1
- package/src/commands/mail.ts +18 -1
- package/src/commands/merge.ts +2 -2
- package/src/commands/metrics.test.ts +2 -2
- package/src/commands/metrics.ts +3 -17
- package/src/commands/monitor.ts +19 -9
- package/src/commands/replay.test.ts +2 -2
- package/src/commands/replay.ts +12 -135
- package/src/commands/run.ts +7 -23
- package/src/commands/sling.test.ts +227 -27
- package/src/commands/sling.ts +120 -21
- package/src/commands/status.ts +5 -18
- package/src/commands/supervisor.ts +22 -12
- package/src/commands/trace.test.ts +5 -6
- package/src/commands/trace.ts +13 -111
- package/src/config.test.ts +22 -0
- package/src/config.ts +22 -0
- package/src/doctor/agents.test.ts +1 -0
- package/src/doctor/config-check.test.ts +1 -0
- package/src/doctor/consistency.test.ts +1 -0
- package/src/doctor/databases.test.ts +1 -0
- package/src/doctor/dependencies.test.ts +1 -0
- package/src/doctor/ecosystem.test.ts +1 -0
- package/src/doctor/logs.test.ts +1 -0
- package/src/doctor/merge-queue.test.ts +1 -0
- package/src/doctor/structure.test.ts +1 -0
- package/src/doctor/version.test.ts +1 -0
- package/src/index.ts +8 -4
- package/src/logging/format.ts +214 -0
- package/src/logging/theme.ts +132 -0
- package/src/metrics/store.test.ts +46 -0
- package/src/metrics/store.ts +11 -0
- package/src/mulch/client.test.ts +20 -0
- package/src/mulch/client.ts +312 -45
- package/src/runtimes/claude.test.ts +616 -0
- package/src/runtimes/claude.ts +218 -0
- package/src/runtimes/registry.test.ts +53 -0
- package/src/runtimes/registry.ts +33 -0
- package/src/runtimes/types.ts +125 -0
- package/src/types.ts +15 -0
- package/src/worktree/tmux.test.ts +28 -13
- package/src/worktree/tmux.ts +14 -28
- package/templates/overlay.md.tmpl +3 -1
package/src/worktree/tmux.ts
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
import { dirname, resolve } from "node:path";
|
|
11
11
|
import { AgentError } from "../errors.ts";
|
|
12
|
+
import type { ReadyState } from "../runtimes/types.ts";
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Detect the directory containing the overstory binary.
|
|
@@ -435,58 +436,43 @@ export async function capturePaneContent(name: string, lines = 50): Promise<stri
|
|
|
435
436
|
/**
|
|
436
437
|
* Wait for a tmux session's TUI to become ready for input.
|
|
437
438
|
*
|
|
438
|
-
*
|
|
439
|
-
*
|
|
440
|
-
*
|
|
441
|
-
*
|
|
442
|
-
*
|
|
443
|
-
* Additionally handles the workspace trust dialog: if 'trust this folder' is detected,
|
|
444
|
-
* sends Enter to auto-confirm before continuing to wait for the real TUI. The trust
|
|
445
|
-
* dialog check must precede phase checks since it replaces the normal TUI temporarily.
|
|
439
|
+
* Delegates all readiness detection to the provided `detectReady` callback,
|
|
440
|
+
* making this function runtime-agnostic. The callback inspects pane content
|
|
441
|
+
* and returns a ReadyState phase: "loading" (keep waiting), "dialog" (send
|
|
442
|
+
* Enter to dismiss, then continue), or "ready" (return true).
|
|
446
443
|
*
|
|
447
444
|
* @param name - Tmux session name to poll
|
|
445
|
+
* @param detectReady - Callback that inspects pane content and returns ReadyState
|
|
448
446
|
* @param timeoutMs - Maximum time to wait before giving up (default 30s)
|
|
449
447
|
* @param pollIntervalMs - Time between polls (default 500ms)
|
|
450
|
-
* @returns true once
|
|
448
|
+
* @returns true once detectReady returns { phase: "ready" }, false on timeout or dead session
|
|
451
449
|
*/
|
|
452
450
|
export async function waitForTuiReady(
|
|
453
451
|
name: string,
|
|
452
|
+
detectReady: (paneContent: string) => ReadyState,
|
|
454
453
|
timeoutMs = 30_000,
|
|
455
454
|
pollIntervalMs = 500,
|
|
456
455
|
): Promise<boolean> {
|
|
457
456
|
const maxAttempts = Math.ceil(timeoutMs / pollIntervalMs);
|
|
458
|
-
let
|
|
459
|
-
let statusBarSeen = false;
|
|
460
|
-
let trustHandled = false;
|
|
457
|
+
let dialogHandled = false;
|
|
461
458
|
|
|
462
459
|
for (let i = 0; i < maxAttempts; i++) {
|
|
463
460
|
const content = await capturePaneContent(name);
|
|
464
461
|
if (content !== null) {
|
|
465
|
-
|
|
466
|
-
|
|
462
|
+
const state = detectReady(content);
|
|
463
|
+
|
|
464
|
+
if (state.phase === "dialog" && !dialogHandled) {
|
|
467
465
|
await sendKeys(name, "");
|
|
468
|
-
|
|
466
|
+
dialogHandled = true;
|
|
469
467
|
await Bun.sleep(pollIntervalMs);
|
|
470
468
|
continue;
|
|
471
469
|
}
|
|
472
470
|
|
|
473
|
-
|
|
474
|
-
if (content.includes("\u276f") || content.includes('Try "')) {
|
|
475
|
-
promptSeen = true;
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
// Phase 2: status bar text confirms full TUI render
|
|
479
|
-
if (content.includes("bypass permissions") || content.includes("shift+tab")) {
|
|
480
|
-
statusBarSeen = true;
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
// Return true only when both phases complete
|
|
484
|
-
if (promptSeen && statusBarSeen) {
|
|
471
|
+
if (state.phase === "ready") {
|
|
485
472
|
return true;
|
|
486
473
|
}
|
|
487
474
|
}
|
|
488
475
|
|
|
489
|
-
// Check if session died — no point waiting if it's gone
|
|
490
476
|
const alive = await isSessionAlive(name);
|
|
491
477
|
if (!alive) {
|
|
492
478
|
return false;
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
## Your Assignment
|
|
11
11
|
|
|
12
12
|
- **Agent Name:** {{AGENT_NAME}}
|
|
13
|
-
- **Task ID:** {{
|
|
13
|
+
- **Task ID:** {{TASK_ID}}
|
|
14
14
|
- **Spec:** {{SPEC_PATH}}
|
|
15
15
|
- **Branch:** {{BRANCH_NAME}}
|
|
16
16
|
- **Worktree:** {{WORKTREE_PATH}}
|
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
|
|
22
22
|
{{SKIP_SCOUT}}
|
|
23
23
|
|
|
24
|
+
{{DISPATCH_OVERRIDES}}
|
|
25
|
+
|
|
24
26
|
## Working Directory
|
|
25
27
|
|
|
26
28
|
Your worktree root is: `{{WORKTREE_PATH}}`
|