@os-eco/overstory-cli 0.7.0 → 0.7.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.
- package/README.md +6 -5
- package/agents/builder.md +1 -1
- package/agents/coordinator.md +12 -11
- package/agents/lead.md +6 -6
- package/agents/monitor.md +4 -4
- package/agents/reviewer.md +1 -1
- package/agents/scout.md +5 -5
- package/agents/supervisor.md +36 -32
- package/package.json +1 -1
- package/src/agents/guard-rules.ts +97 -0
- package/src/agents/hooks-deployer.ts +7 -90
- package/src/agents/overlay.test.ts +7 -7
- package/src/agents/overlay.ts +5 -5
- package/src/commands/agents.test.ts +5 -0
- package/src/commands/clean.test.ts +3 -0
- package/src/commands/completions.ts +1 -1
- package/src/commands/coordinator.test.ts +1 -0
- package/src/commands/coordinator.ts +15 -11
- package/src/commands/costs.test.ts +5 -0
- package/src/commands/init.test.ts +1 -2
- package/src/commands/init.ts +1 -8
- package/src/commands/inspect.test.ts +14 -0
- package/src/commands/log.test.ts +14 -0
- package/src/commands/log.ts +39 -0
- package/src/commands/mail.test.ts +5 -0
- package/src/commands/monitor.ts +15 -11
- package/src/commands/nudge.test.ts +1 -0
- package/src/commands/prime.test.ts +2 -0
- package/src/commands/prime.ts +6 -2
- package/src/commands/run.test.ts +1 -0
- package/src/commands/sling.test.ts +15 -1
- package/src/commands/sling.ts +44 -21
- package/src/commands/status.test.ts +1 -0
- package/src/commands/stop.test.ts +1 -0
- package/src/commands/supervisor.ts +19 -12
- package/src/commands/trace.test.ts +1 -0
- package/src/commands/worktree.test.ts +9 -0
- package/src/config.ts +29 -0
- package/src/doctor/consistency.test.ts +14 -0
- package/src/e2e/init-sling-lifecycle.test.ts +3 -5
- package/src/index.ts +1 -1
- package/src/mail/broadcast.test.ts +1 -0
- package/src/merge/resolver.ts +23 -4
- package/src/runtimes/claude.test.ts +1 -1
- package/src/runtimes/pi-guards.test.ts +433 -0
- package/src/runtimes/pi-guards.ts +349 -0
- package/src/runtimes/pi.test.ts +620 -0
- package/src/runtimes/pi.ts +244 -0
- package/src/runtimes/registry.test.ts +33 -0
- package/src/runtimes/registry.ts +15 -2
- package/src/runtimes/types.ts +63 -0
- package/src/schema-consistency.test.ts +1 -0
- package/src/sessions/compat.ts +1 -0
- package/src/sessions/store.test.ts +31 -0
- package/src/sessions/store.ts +37 -4
- package/src/types.ts +17 -0
- package/src/watchdog/daemon.test.ts +7 -4
- package/src/watchdog/daemon.ts +1 -1
- package/src/watchdog/health.test.ts +1 -0
- package/src/watchdog/triage.ts +14 -4
|
@@ -207,6 +207,7 @@ describe("checkConsistency", () => {
|
|
|
207
207
|
lastActivity: new Date().toISOString(),
|
|
208
208
|
escalationLevel: 0,
|
|
209
209
|
stalledSince: null,
|
|
210
|
+
transcriptPath: null,
|
|
210
211
|
});
|
|
211
212
|
store.close();
|
|
212
213
|
|
|
@@ -243,6 +244,7 @@ describe("checkConsistency", () => {
|
|
|
243
244
|
lastActivity: new Date().toISOString(),
|
|
244
245
|
escalationLevel: 0,
|
|
245
246
|
stalledSince: null,
|
|
247
|
+
transcriptPath: null,
|
|
246
248
|
});
|
|
247
249
|
store.close();
|
|
248
250
|
|
|
@@ -278,6 +280,7 @@ describe("checkConsistency", () => {
|
|
|
278
280
|
lastActivity: new Date().toISOString(),
|
|
279
281
|
escalationLevel: 0,
|
|
280
282
|
stalledSince: null,
|
|
283
|
+
transcriptPath: null,
|
|
281
284
|
});
|
|
282
285
|
store.close();
|
|
283
286
|
|
|
@@ -314,6 +317,7 @@ describe("checkConsistency", () => {
|
|
|
314
317
|
lastActivity: new Date().toISOString(),
|
|
315
318
|
escalationLevel: 0,
|
|
316
319
|
stalledSince: null,
|
|
320
|
+
transcriptPath: null,
|
|
317
321
|
});
|
|
318
322
|
store.close();
|
|
319
323
|
|
|
@@ -353,6 +357,7 @@ describe("checkConsistency", () => {
|
|
|
353
357
|
lastActivity: new Date().toISOString(),
|
|
354
358
|
escalationLevel: 0,
|
|
355
359
|
stalledSince: null,
|
|
360
|
+
transcriptPath: null,
|
|
356
361
|
});
|
|
357
362
|
store.close();
|
|
358
363
|
|
|
@@ -426,6 +431,7 @@ describe("checkConsistency", () => {
|
|
|
426
431
|
lastActivity: new Date().toISOString(),
|
|
427
432
|
escalationLevel: 0,
|
|
428
433
|
stalledSince: null,
|
|
434
|
+
transcriptPath: null,
|
|
429
435
|
});
|
|
430
436
|
|
|
431
437
|
store.upsert({
|
|
@@ -445,6 +451,7 @@ describe("checkConsistency", () => {
|
|
|
445
451
|
lastActivity: new Date().toISOString(),
|
|
446
452
|
escalationLevel: 0,
|
|
447
453
|
stalledSince: null,
|
|
454
|
+
transcriptPath: null,
|
|
448
455
|
});
|
|
449
456
|
store.close();
|
|
450
457
|
|
|
@@ -481,6 +488,7 @@ describe("checkConsistency", () => {
|
|
|
481
488
|
lastActivity: new Date().toISOString(),
|
|
482
489
|
escalationLevel: 0,
|
|
483
490
|
stalledSince: null,
|
|
491
|
+
transcriptPath: null,
|
|
484
492
|
});
|
|
485
493
|
}
|
|
486
494
|
|
|
@@ -501,6 +509,7 @@ describe("checkConsistency", () => {
|
|
|
501
509
|
lastActivity: new Date().toISOString(),
|
|
502
510
|
escalationLevel: 0,
|
|
503
511
|
stalledSince: null,
|
|
512
|
+
transcriptPath: null,
|
|
504
513
|
});
|
|
505
514
|
store.close();
|
|
506
515
|
|
|
@@ -535,6 +544,7 @@ describe("checkConsistency", () => {
|
|
|
535
544
|
lastActivity: new Date().toISOString(),
|
|
536
545
|
escalationLevel: 0,
|
|
537
546
|
stalledSince: null,
|
|
547
|
+
transcriptPath: null,
|
|
538
548
|
});
|
|
539
549
|
|
|
540
550
|
store.upsert({
|
|
@@ -554,6 +564,7 @@ describe("checkConsistency", () => {
|
|
|
554
564
|
lastActivity: new Date().toISOString(),
|
|
555
565
|
escalationLevel: 0,
|
|
556
566
|
stalledSince: null,
|
|
567
|
+
transcriptPath: null,
|
|
557
568
|
});
|
|
558
569
|
}
|
|
559
570
|
store.close();
|
|
@@ -597,6 +608,7 @@ describe("checkConsistency", () => {
|
|
|
597
608
|
lastActivity: new Date().toISOString(),
|
|
598
609
|
escalationLevel: 0,
|
|
599
610
|
stalledSince: null,
|
|
611
|
+
transcriptPath: null,
|
|
600
612
|
});
|
|
601
613
|
|
|
602
614
|
store.upsert({
|
|
@@ -616,6 +628,7 @@ describe("checkConsistency", () => {
|
|
|
616
628
|
lastActivity: new Date().toISOString(),
|
|
617
629
|
escalationLevel: 0,
|
|
618
630
|
stalledSince: null,
|
|
631
|
+
transcriptPath: null,
|
|
619
632
|
});
|
|
620
633
|
|
|
621
634
|
// Lead-2 has builders only (bad)
|
|
@@ -636,6 +649,7 @@ describe("checkConsistency", () => {
|
|
|
636
649
|
lastActivity: new Date().toISOString(),
|
|
637
650
|
escalationLevel: 0,
|
|
638
651
|
stalledSince: null,
|
|
652
|
+
transcriptPath: null,
|
|
639
653
|
});
|
|
640
654
|
store.close();
|
|
641
655
|
|
|
@@ -27,7 +27,6 @@ const EXPECTED_AGENT_DEFS = [
|
|
|
27
27
|
"monitor.md",
|
|
28
28
|
"reviewer.md",
|
|
29
29
|
"scout.md",
|
|
30
|
-
"supervisor.md",
|
|
31
30
|
];
|
|
32
31
|
|
|
33
32
|
describe("E2E: init→sling lifecycle on external project", () => {
|
|
@@ -77,7 +76,7 @@ describe("E2E: init→sling lifecycle on external project", () => {
|
|
|
77
76
|
const gitignoreFile = Bun.file(join(overstoryDir, ".gitignore"));
|
|
78
77
|
expect(await gitignoreFile.exists()).toBe(true);
|
|
79
78
|
|
|
80
|
-
// agent-defs/ contains all
|
|
79
|
+
// agent-defs/ contains all 7 agent definition files (supervisor deprecated)
|
|
81
80
|
const agentDefsDir = join(overstoryDir, "agent-defs");
|
|
82
81
|
const agentDefFiles = (await readdir(agentDefsDir)).filter((f) => f.endsWith(".md")).sort();
|
|
83
82
|
expect(agentDefFiles).toEqual(EXPECTED_AGENT_DEFS);
|
|
@@ -109,7 +108,7 @@ describe("E2E: init→sling lifecycle on external project", () => {
|
|
|
109
108
|
expect(config.project.name).toBeTruthy();
|
|
110
109
|
});
|
|
111
110
|
|
|
112
|
-
test("manifest loads successfully with all
|
|
111
|
+
test("manifest loads successfully with all 7 agents (supervisor deprecated)", async () => {
|
|
113
112
|
await initCommand({});
|
|
114
113
|
|
|
115
114
|
const manifestPath = join(tempDir, ".overstory", "agent-manifest.json");
|
|
@@ -118,7 +117,7 @@ describe("E2E: init→sling lifecycle on external project", () => {
|
|
|
118
117
|
|
|
119
118
|
const manifest = await loader.load();
|
|
120
119
|
|
|
121
|
-
// All
|
|
120
|
+
// All 7 agents present (supervisor removed: deprecated, use lead instead)
|
|
122
121
|
const agentNames = Object.keys(manifest.agents).sort();
|
|
123
122
|
expect(agentNames).toEqual([
|
|
124
123
|
"builder",
|
|
@@ -128,7 +127,6 @@ describe("E2E: init→sling lifecycle on external project", () => {
|
|
|
128
127
|
"monitor",
|
|
129
128
|
"reviewer",
|
|
130
129
|
"scout",
|
|
131
|
-
"supervisor",
|
|
132
130
|
]);
|
|
133
131
|
|
|
134
132
|
// Each agent has a valid file reference
|
package/src/index.ts
CHANGED
|
@@ -45,7 +45,7 @@ import { OverstoryError, WorktreeError } from "./errors.ts";
|
|
|
45
45
|
import { jsonError } from "./json.ts";
|
|
46
46
|
import { brand, chalk, muted, setQuiet } from "./logging/color.ts";
|
|
47
47
|
|
|
48
|
-
export const VERSION = "0.7.
|
|
48
|
+
export const VERSION = "0.7.2";
|
|
49
49
|
|
|
50
50
|
const rawArgs = process.argv.slice(2);
|
|
51
51
|
|
package/src/merge/resolver.ts
CHANGED
|
@@ -13,10 +13,12 @@
|
|
|
13
13
|
|
|
14
14
|
import { MergeError } from "../errors.ts";
|
|
15
15
|
import type { MulchClient } from "../mulch/client.ts";
|
|
16
|
+
import { getRuntime } from "../runtimes/registry.ts";
|
|
16
17
|
import type {
|
|
17
18
|
ConflictHistory,
|
|
18
19
|
MergeEntry,
|
|
19
20
|
MergeResult,
|
|
21
|
+
OverstoryConfig,
|
|
20
22
|
ParsedConflictPattern,
|
|
21
23
|
ResolutionTier,
|
|
22
24
|
} from "../types.ts";
|
|
@@ -243,6 +245,7 @@ async function tryAiResolve(
|
|
|
243
245
|
conflictFiles: string[],
|
|
244
246
|
repoRoot: string,
|
|
245
247
|
pastResolutions?: string[],
|
|
248
|
+
config?: OverstoryConfig,
|
|
246
249
|
): Promise<{ success: boolean; remainingConflicts: string[] }> {
|
|
247
250
|
const remainingConflicts: string[] = [];
|
|
248
251
|
|
|
@@ -265,7 +268,9 @@ async function tryAiResolve(
|
|
|
265
268
|
content,
|
|
266
269
|
].join(" ");
|
|
267
270
|
|
|
268
|
-
const
|
|
271
|
+
const runtime = getRuntime(config?.runtime?.printCommand ?? config?.runtime?.default, config);
|
|
272
|
+
const argv = runtime.buildPrintCommand(prompt);
|
|
273
|
+
const proc = Bun.spawn(argv, {
|
|
269
274
|
cwd: repoRoot,
|
|
270
275
|
stdout: "pipe",
|
|
271
276
|
stderr: "pipe",
|
|
@@ -315,6 +320,7 @@ async function tryReimagine(
|
|
|
315
320
|
entry: MergeEntry,
|
|
316
321
|
canonicalBranch: string,
|
|
317
322
|
repoRoot: string,
|
|
323
|
+
config?: OverstoryConfig,
|
|
318
324
|
): Promise<{ success: boolean }> {
|
|
319
325
|
// Abort the current merge
|
|
320
326
|
await runGit(repoRoot, ["merge", "--abort"]);
|
|
@@ -348,7 +354,9 @@ async function tryReimagine(
|
|
|
348
354
|
branchContent,
|
|
349
355
|
].join("");
|
|
350
356
|
|
|
351
|
-
const
|
|
357
|
+
const runtime = getRuntime(config?.runtime?.printCommand ?? config?.runtime?.default, config);
|
|
358
|
+
const argv = runtime.buildPrintCommand(prompt);
|
|
359
|
+
const proc = Bun.spawn(argv, {
|
|
352
360
|
cwd: repoRoot,
|
|
353
361
|
stdout: "pipe",
|
|
354
362
|
stderr: "pipe",
|
|
@@ -556,6 +564,7 @@ export function createMergeResolver(options: {
|
|
|
556
564
|
aiResolveEnabled: boolean;
|
|
557
565
|
reimagineEnabled: boolean;
|
|
558
566
|
mulchClient?: MulchClient;
|
|
567
|
+
config?: OverstoryConfig;
|
|
559
568
|
}): MergeResolver {
|
|
560
569
|
return {
|
|
561
570
|
async resolve(
|
|
@@ -632,7 +641,12 @@ export function createMergeResolver(options: {
|
|
|
632
641
|
// Tier 3: AI-resolve
|
|
633
642
|
if (options.aiResolveEnabled && !history.skipTiers.includes("ai-resolve")) {
|
|
634
643
|
lastTier = "ai-resolve";
|
|
635
|
-
const aiResult = await tryAiResolve(
|
|
644
|
+
const aiResult = await tryAiResolve(
|
|
645
|
+
conflictFiles,
|
|
646
|
+
repoRoot,
|
|
647
|
+
history.pastResolutions,
|
|
648
|
+
options.config,
|
|
649
|
+
);
|
|
636
650
|
if (aiResult.success) {
|
|
637
651
|
if (options.mulchClient) {
|
|
638
652
|
recordConflictPattern(options.mulchClient, entry, "ai-resolve", conflictFiles, true);
|
|
@@ -651,7 +665,12 @@ export function createMergeResolver(options: {
|
|
|
651
665
|
// Tier 4: Re-imagine
|
|
652
666
|
if (options.reimagineEnabled && !history.skipTiers.includes("reimagine")) {
|
|
653
667
|
lastTier = "reimagine";
|
|
654
|
-
const reimagineResult = await tryReimagine(
|
|
668
|
+
const reimagineResult = await tryReimagine(
|
|
669
|
+
entry,
|
|
670
|
+
canonicalBranch,
|
|
671
|
+
repoRoot,
|
|
672
|
+
options.config,
|
|
673
|
+
);
|
|
655
674
|
if (reimagineResult.success) {
|
|
656
675
|
if (options.mulchClient) {
|
|
657
676
|
recordConflictPattern(options.mulchClient, entry, "reimagine", conflictFiles, true);
|
|
@@ -611,6 +611,6 @@ describe("ClaudeRuntime integration: registry resolves 'claude' as default", ()
|
|
|
611
611
|
test("getRuntime rejects unknown runtimes", async () => {
|
|
612
612
|
const { getRuntime } = await import("./registry.ts");
|
|
613
613
|
expect(() => getRuntime("codex")).toThrow('Unknown runtime: "codex"');
|
|
614
|
-
expect(() => getRuntime("
|
|
614
|
+
expect(() => getRuntime("opencode")).toThrow('Unknown runtime: "opencode"');
|
|
615
615
|
});
|
|
616
616
|
});
|