@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
|
@@ -3,6 +3,13 @@ import { dirname, join } from "node:path";
|
|
|
3
3
|
import { DEFAULT_QUALITY_GATES } from "../config.ts";
|
|
4
4
|
import { AgentError } from "../errors.ts";
|
|
5
5
|
import type { QualityGate } from "../types.ts";
|
|
6
|
+
import {
|
|
7
|
+
DANGEROUS_BASH_PATTERNS,
|
|
8
|
+
INTERACTIVE_TOOLS,
|
|
9
|
+
NATIVE_TEAM_TOOLS,
|
|
10
|
+
SAFE_BASH_PREFIXES,
|
|
11
|
+
WRITE_TOOLS,
|
|
12
|
+
} from "./guard-rules.ts";
|
|
6
13
|
|
|
7
14
|
/**
|
|
8
15
|
* Capabilities that must never modify project files.
|
|
@@ -31,96 +38,6 @@ const COORDINATION_CAPABILITIES = new Set(["coordinator", "supervisor", "monitor
|
|
|
31
38
|
*/
|
|
32
39
|
const COORDINATION_SAFE_PREFIXES = ["git add", "git commit"];
|
|
33
40
|
|
|
34
|
-
/**
|
|
35
|
-
* Claude Code native team/task tools that bypass overstory orchestration.
|
|
36
|
-
* All overstory agents must use `overstory sling` for delegation, not these.
|
|
37
|
-
*/
|
|
38
|
-
const NATIVE_TEAM_TOOLS = [
|
|
39
|
-
"Task",
|
|
40
|
-
"TeamCreate",
|
|
41
|
-
"TeamDelete",
|
|
42
|
-
"SendMessage",
|
|
43
|
-
"TaskCreate",
|
|
44
|
-
"TaskUpdate",
|
|
45
|
-
"TaskList",
|
|
46
|
-
"TaskGet",
|
|
47
|
-
"TaskOutput",
|
|
48
|
-
"TaskStop",
|
|
49
|
-
];
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Tools that require human interaction and block indefinitely in non-interactive
|
|
53
|
-
* tmux sessions. Agents run non-interactively and must never call these tools.
|
|
54
|
-
* Use overstory mail (--type question) to escalate to the orchestrator instead.
|
|
55
|
-
*/
|
|
56
|
-
const INTERACTIVE_TOOLS = ["AskUserQuestion", "EnterPlanMode", "EnterWorktree"];
|
|
57
|
-
|
|
58
|
-
/** Tools that non-implementation agents must not use. */
|
|
59
|
-
const WRITE_TOOLS = ["Write", "Edit", "NotebookEdit"];
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Bash commands that modify files and must be blocked for non-implementation agents.
|
|
63
|
-
* Each pattern is a regex fragment used inside a grep -qE check.
|
|
64
|
-
*/
|
|
65
|
-
const DANGEROUS_BASH_PATTERNS = [
|
|
66
|
-
"sed\\s+-i",
|
|
67
|
-
"sed\\s+--in-place",
|
|
68
|
-
"echo\\s+.*>",
|
|
69
|
-
"printf\\s+.*>",
|
|
70
|
-
"cat\\s+.*>",
|
|
71
|
-
"tee\\s",
|
|
72
|
-
"\\bvim\\b",
|
|
73
|
-
"\\bnano\\b",
|
|
74
|
-
"\\bvi\\b",
|
|
75
|
-
"\\bmv\\s",
|
|
76
|
-
"\\bcp\\s",
|
|
77
|
-
"\\brm\\s",
|
|
78
|
-
"\\bmkdir\\s",
|
|
79
|
-
"\\btouch\\s",
|
|
80
|
-
"\\bchmod\\s",
|
|
81
|
-
"\\bchown\\s",
|
|
82
|
-
">>",
|
|
83
|
-
"\\bgit\\s+add\\b",
|
|
84
|
-
"\\bgit\\s+commit\\b",
|
|
85
|
-
"\\bgit\\s+merge\\b",
|
|
86
|
-
"\\bgit\\s+push\\b",
|
|
87
|
-
"\\bgit\\s+reset\\b",
|
|
88
|
-
"\\bgit\\s+checkout\\b",
|
|
89
|
-
"\\bgit\\s+rebase\\b",
|
|
90
|
-
"\\bgit\\s+stash\\b",
|
|
91
|
-
"\\bnpm\\s+install\\b",
|
|
92
|
-
"\\bbun\\s+install\\b",
|
|
93
|
-
"\\bbun\\s+add\\b",
|
|
94
|
-
// Runtime eval flags — bypass shell pattern guards by executing JS/Python directly
|
|
95
|
-
"\\bbun\\s+-e\\b",
|
|
96
|
-
"\\bbun\\s+--eval\\b",
|
|
97
|
-
"\\bnode\\s+-e\\b",
|
|
98
|
-
"\\bnode\\s+--eval\\b",
|
|
99
|
-
"\\bdeno\\s+eval\\b",
|
|
100
|
-
"\\bpython3?\\s+-c\\b",
|
|
101
|
-
"\\bperl\\s+-e\\b",
|
|
102
|
-
"\\bruby\\s+-e\\b",
|
|
103
|
-
];
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Bash commands that are always safe for non-implementation agents.
|
|
107
|
-
* If a command starts with any of these prefixes, it bypasses the dangerous command check.
|
|
108
|
-
* This whitelist is checked BEFORE the blocklist.
|
|
109
|
-
*/
|
|
110
|
-
const SAFE_BASH_PREFIXES = [
|
|
111
|
-
"ov ",
|
|
112
|
-
"overstory ",
|
|
113
|
-
"bd ",
|
|
114
|
-
"sd ",
|
|
115
|
-
"git status",
|
|
116
|
-
"git log",
|
|
117
|
-
"git diff",
|
|
118
|
-
"git show",
|
|
119
|
-
"git blame",
|
|
120
|
-
"git branch",
|
|
121
|
-
"mulch ",
|
|
122
|
-
];
|
|
123
|
-
|
|
124
41
|
/**
|
|
125
42
|
* Extract command prefixes from quality gate configurations.
|
|
126
43
|
*
|
|
@@ -265,7 +265,7 @@ describe("generateOverlay", () => {
|
|
|
265
265
|
expect(output).not.toContain("bun run lint");
|
|
266
266
|
});
|
|
267
267
|
|
|
268
|
-
test("scout completion section includes
|
|
268
|
+
test("scout completion section includes sd close and mail send", async () => {
|
|
269
269
|
const config = makeConfig({
|
|
270
270
|
capability: "scout",
|
|
271
271
|
agentName: "recon-1",
|
|
@@ -274,7 +274,7 @@ describe("generateOverlay", () => {
|
|
|
274
274
|
});
|
|
275
275
|
const output = await generateOverlay(config);
|
|
276
276
|
|
|
277
|
-
expect(output).toContain("
|
|
277
|
+
expect(output).toContain("sd close overstory-task1");
|
|
278
278
|
expect(output).toContain("ov mail send --to lead-alpha");
|
|
279
279
|
});
|
|
280
280
|
|
|
@@ -426,14 +426,14 @@ describe("generateOverlay", () => {
|
|
|
426
426
|
expect(output).not.toContain("Quality Gates");
|
|
427
427
|
});
|
|
428
428
|
|
|
429
|
-
test("default trackerCli renders as
|
|
429
|
+
test("default trackerCli renders as sd in quality gates", async () => {
|
|
430
430
|
const config = makeConfig({ capability: "builder", taskId: "overstory-task1" });
|
|
431
431
|
const output = await generateOverlay(config);
|
|
432
432
|
|
|
433
|
-
expect(output).toContain("
|
|
433
|
+
expect(output).toContain("sd close overstory-task1");
|
|
434
434
|
});
|
|
435
435
|
|
|
436
|
-
test("custom trackerCli replaces
|
|
436
|
+
test("custom trackerCli replaces sd in quality gates", async () => {
|
|
437
437
|
const config = makeConfig({
|
|
438
438
|
capability: "builder",
|
|
439
439
|
trackerCli: "sd",
|
|
@@ -489,11 +489,11 @@ describe("generateOverlay", () => {
|
|
|
489
489
|
expect(output).not.toContain("{{TRACKER_NAME}}");
|
|
490
490
|
});
|
|
491
491
|
|
|
492
|
-
test("defaults
|
|
492
|
+
test("defaults: no trackerCli/trackerName produces sd/seeds", async () => {
|
|
493
493
|
const config = makeConfig({ capability: "builder", taskId: "overstory-back" });
|
|
494
494
|
const output = await generateOverlay(config);
|
|
495
495
|
|
|
496
|
-
expect(output).toContain("
|
|
496
|
+
expect(output).toContain("sd close overstory-back");
|
|
497
497
|
});
|
|
498
498
|
|
|
499
499
|
test("dispatch overrides: skipReview injects SKIP REVIEW directive for leads", async () => {
|
package/src/agents/overlay.ts
CHANGED
|
@@ -182,7 +182,7 @@ function formatQualityGates(config: OverlayConfig): string {
|
|
|
182
182
|
"Before reporting completion:",
|
|
183
183
|
"",
|
|
184
184
|
`1. **Record mulch learnings:** \`ml record <domain> --type <convention|pattern|reference> --description "..."\` — capture reusable knowledge from your work`,
|
|
185
|
-
`2. **Close issue:** \`${config.trackerCli ?? "
|
|
185
|
+
`2. **Close issue:** \`${config.trackerCli ?? "sd"} close ${config.taskId} --reason "summary of findings"\``,
|
|
186
186
|
`3. **Send results:** \`ov mail send --to ${config.parentAgent ?? "coordinator"} --subject "done" --body "Summary" --type result --agent ${config.agentName}\``,
|
|
187
187
|
"",
|
|
188
188
|
"You are a read-only agent. Do NOT commit, modify files, or run quality gates.",
|
|
@@ -207,7 +207,7 @@ function formatQualityGates(config: OverlayConfig): string {
|
|
|
207
207
|
`${gateLines.length + 1}. **Commit:** all changes committed to your branch (${config.branchName})`,
|
|
208
208
|
`${gateLines.length + 2}. **Record mulch learnings:** \`ml record <domain> --type <convention|pattern|failure|decision> --description "..." --outcome-status success --outcome-agent ${config.agentName}\` — capture insights from your work`,
|
|
209
209
|
`${gateLines.length + 3}. **Signal completion:** send \`worker_done\` mail to ${config.parentAgent ?? "coordinator"}: \`ov mail send --to ${config.parentAgent ?? "coordinator"} --subject "Worker done: ${config.taskId}" --body "Quality gates passed." --type worker_done --agent ${config.agentName}\``,
|
|
210
|
-
`${gateLines.length + 4}. **Close issue:** \`${config.trackerCli ?? "
|
|
210
|
+
`${gateLines.length + 4}. **Close issue:** \`${config.trackerCli ?? "sd"} close ${config.taskId} --reason "summary of changes"\``,
|
|
211
211
|
"",
|
|
212
212
|
"Do NOT push to the canonical branch. Your work will be merged by the",
|
|
213
213
|
"coordinator via `ov merge`.",
|
|
@@ -225,7 +225,7 @@ function formatConstraints(config: OverlayConfig): string {
|
|
|
225
225
|
"",
|
|
226
226
|
"- You are **read-only**: do NOT modify, create, or delete any files",
|
|
227
227
|
"- Do NOT commit, push, or make any git state changes",
|
|
228
|
-
`- Report completion via \`${config.trackerCli ?? "
|
|
228
|
+
`- Report completion via \`${config.trackerCli ?? "sd"} close\` AND \`ov mail send --type result\``,
|
|
229
229
|
"- If you encounter a blocking issue, send mail with `--priority urgent --type error`",
|
|
230
230
|
].join("\n");
|
|
231
231
|
}
|
|
@@ -238,7 +238,7 @@ function formatConstraints(config: OverlayConfig): string {
|
|
|
238
238
|
"- Only modify files in your File Scope",
|
|
239
239
|
`- Commit only to your branch: ${config.branchName}`,
|
|
240
240
|
"- Never push to the canonical branch",
|
|
241
|
-
`- Report completion via \`${config.trackerCli ?? "
|
|
241
|
+
`- Report completion via \`${config.trackerCli ?? "sd"} close\` AND \`ov mail send --type result\``,
|
|
242
242
|
"- If you encounter a blocking issue, send mail with `--priority urgent --type error`",
|
|
243
243
|
].join("\n");
|
|
244
244
|
}
|
|
@@ -318,7 +318,7 @@ export async function generateOverlay(config: OverlayConfig): Promise<string> {
|
|
|
318
318
|
"{{QUALITY_GATE_STEPS}}": formatQualityGatesSteps(config.qualityGates),
|
|
319
319
|
"{{QUALITY_GATE_BASH}}": formatQualityGatesBash(config.qualityGates),
|
|
320
320
|
"{{QUALITY_GATE_CAPABILITIES}}": formatQualityGatesCapabilities(config.qualityGates),
|
|
321
|
-
"{{TRACKER_CLI}}": config.trackerCli ?? "
|
|
321
|
+
"{{TRACKER_CLI}}": config.trackerCli ?? "sd",
|
|
322
322
|
"{{TRACKER_NAME}}": config.trackerName ?? "seeds",
|
|
323
323
|
};
|
|
324
324
|
|
|
@@ -108,6 +108,7 @@ describe("discoverAgents", () => {
|
|
|
108
108
|
lastActivity: "2024-01-01T00:01:00Z",
|
|
109
109
|
escalationLevel: 0,
|
|
110
110
|
stalledSince: null,
|
|
111
|
+
transcriptPath: null,
|
|
111
112
|
};
|
|
112
113
|
|
|
113
114
|
store.upsert(session);
|
|
@@ -140,6 +141,7 @@ describe("discoverAgents", () => {
|
|
|
140
141
|
lastActivity: "2024-01-01T00:01:00Z",
|
|
141
142
|
escalationLevel: 0,
|
|
142
143
|
stalledSince: null,
|
|
144
|
+
transcriptPath: null,
|
|
143
145
|
};
|
|
144
146
|
|
|
145
147
|
const scout: AgentSession = {
|
|
@@ -159,6 +161,7 @@ describe("discoverAgents", () => {
|
|
|
159
161
|
lastActivity: "2024-01-01T00:01:00Z",
|
|
160
162
|
escalationLevel: 0,
|
|
161
163
|
stalledSince: null,
|
|
164
|
+
transcriptPath: null,
|
|
162
165
|
};
|
|
163
166
|
|
|
164
167
|
store.upsert(builder);
|
|
@@ -191,6 +194,7 @@ describe("discoverAgents", () => {
|
|
|
191
194
|
lastActivity: "2024-01-01T00:01:00Z",
|
|
192
195
|
escalationLevel: 0,
|
|
193
196
|
stalledSince: null,
|
|
197
|
+
transcriptPath: null,
|
|
194
198
|
};
|
|
195
199
|
|
|
196
200
|
const completed: AgentSession = {
|
|
@@ -210,6 +214,7 @@ describe("discoverAgents", () => {
|
|
|
210
214
|
lastActivity: "2024-01-01T00:02:00Z",
|
|
211
215
|
escalationLevel: 0,
|
|
212
216
|
stalledSince: null,
|
|
217
|
+
transcriptPath: null,
|
|
213
218
|
};
|
|
214
219
|
|
|
215
220
|
store.upsert(working);
|
|
@@ -159,6 +159,7 @@ describe("--all", () => {
|
|
|
159
159
|
lastActivity: new Date().toISOString(),
|
|
160
160
|
escalationLevel: 0,
|
|
161
161
|
stalledSince: null,
|
|
162
|
+
transcriptPath: null,
|
|
162
163
|
});
|
|
163
164
|
store.close();
|
|
164
165
|
|
|
@@ -303,6 +304,7 @@ describe("individual flags", () => {
|
|
|
303
304
|
lastActivity: new Date().toISOString(),
|
|
304
305
|
escalationLevel: 0,
|
|
305
306
|
stalledSince: null,
|
|
307
|
+
transcriptPath: null,
|
|
306
308
|
});
|
|
307
309
|
store.close();
|
|
308
310
|
|
|
@@ -424,6 +426,7 @@ describe("synthetic session-end events", () => {
|
|
|
424
426
|
lastActivity: new Date().toISOString(),
|
|
425
427
|
escalationLevel: 0,
|
|
426
428
|
stalledSince: null,
|
|
429
|
+
transcriptPath: null,
|
|
427
430
|
...overrides,
|
|
428
431
|
};
|
|
429
432
|
}
|
|
@@ -356,7 +356,7 @@ export const COMMANDS: readonly CommandDef[] = [
|
|
|
356
356
|
},
|
|
357
357
|
{
|
|
358
358
|
name: "supervisor",
|
|
359
|
-
desc: "Per-project supervisor agent",
|
|
359
|
+
desc: "[DEPRECATED] Per-project supervisor agent",
|
|
360
360
|
flags: [
|
|
361
361
|
{ name: "--json", desc: "JSON output" },
|
|
362
362
|
{ name: "--help", desc: "Show help" },
|
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
import { mkdir, unlink } from "node:fs/promises";
|
|
16
16
|
import { join } from "node:path";
|
|
17
17
|
import { Command } from "commander";
|
|
18
|
-
import { deployHooks } from "../agents/hooks-deployer.ts";
|
|
19
18
|
import { createIdentity, loadIdentity } from "../agents/identity.ts";
|
|
20
19
|
import { createManifestLoader, resolveModel } from "../agents/manifest.ts";
|
|
21
20
|
import { loadConfig } from "../config.ts";
|
|
@@ -320,13 +319,26 @@ async function startCoordinator(
|
|
|
320
319
|
store.updateState(COORDINATOR_NAME, "completed");
|
|
321
320
|
}
|
|
322
321
|
|
|
322
|
+
// Resolve model and runtime early (needed for deployConfig and spawn)
|
|
323
|
+
const manifestLoader = createManifestLoader(
|
|
324
|
+
join(projectRoot, config.agents.manifestPath),
|
|
325
|
+
join(projectRoot, config.agents.baseDir),
|
|
326
|
+
);
|
|
327
|
+
const manifest = await manifestLoader.load();
|
|
328
|
+
const resolvedModel = resolveModel(config, manifest, "coordinator", "opus");
|
|
329
|
+
const runtime = getRuntime(undefined, config);
|
|
330
|
+
|
|
323
331
|
// Deploy hooks to the project root so the coordinator gets event logging,
|
|
324
332
|
// mail check --inject, and activity tracking via the standard hook pipeline.
|
|
325
333
|
// The ENV_GUARD prefix on all hooks (both template and generated guards)
|
|
326
334
|
// ensures they only activate when OVERSTORY_AGENT_NAME is set (i.e. for
|
|
327
335
|
// the coordinator's tmux session), so the user's own Claude Code session
|
|
328
336
|
// at the project root is unaffected.
|
|
329
|
-
await
|
|
337
|
+
await runtime.deployConfig(projectRoot, undefined, {
|
|
338
|
+
agentName: COORDINATOR_NAME,
|
|
339
|
+
capability: "coordinator",
|
|
340
|
+
worktreePath: projectRoot,
|
|
341
|
+
});
|
|
330
342
|
|
|
331
343
|
// Create coordinator identity if first run
|
|
332
344
|
const identityBaseDir = join(projectRoot, ".overstory", "agents");
|
|
@@ -343,15 +355,6 @@ async function startCoordinator(
|
|
|
343
355
|
});
|
|
344
356
|
}
|
|
345
357
|
|
|
346
|
-
// Resolve model from config > manifest > fallback
|
|
347
|
-
const manifestLoader = createManifestLoader(
|
|
348
|
-
join(projectRoot, config.agents.manifestPath),
|
|
349
|
-
join(projectRoot, config.agents.baseDir),
|
|
350
|
-
);
|
|
351
|
-
const manifest = await manifestLoader.load();
|
|
352
|
-
const resolvedModel = resolveModel(config, manifest, "coordinator", "opus");
|
|
353
|
-
const runtime = getRuntime(undefined, config);
|
|
354
|
-
|
|
355
358
|
// Preflight: verify tmux is installed before attempting to spawn.
|
|
356
359
|
// Without this check, a missing tmux leads to cryptic errors later.
|
|
357
360
|
await tmux.ensureTmuxAvailable();
|
|
@@ -402,6 +405,7 @@ async function startCoordinator(
|
|
|
402
405
|
lastActivity: new Date().toISOString(),
|
|
403
406
|
escalationLevel: 0,
|
|
404
407
|
stalledSince: null,
|
|
408
|
+
transcriptPath: null,
|
|
405
409
|
};
|
|
406
410
|
|
|
407
411
|
store.upsert(session);
|
|
@@ -780,6 +780,7 @@ describe("costsCommand", () => {
|
|
|
780
780
|
lastActivity: new Date().toISOString(),
|
|
781
781
|
escalationLevel: 0,
|
|
782
782
|
stalledSince: null,
|
|
783
|
+
transcriptPath: null,
|
|
783
784
|
});
|
|
784
785
|
sessionStore.close();
|
|
785
786
|
|
|
@@ -836,6 +837,7 @@ describe("costsCommand", () => {
|
|
|
836
837
|
lastActivity: new Date().toISOString(),
|
|
837
838
|
escalationLevel: 0,
|
|
838
839
|
stalledSince: null,
|
|
840
|
+
transcriptPath: null,
|
|
839
841
|
});
|
|
840
842
|
sessionStore.close();
|
|
841
843
|
|
|
@@ -900,6 +902,7 @@ describe("costsCommand", () => {
|
|
|
900
902
|
lastActivity: new Date().toISOString(),
|
|
901
903
|
escalationLevel: 0,
|
|
902
904
|
stalledSince: null,
|
|
905
|
+
transcriptPath: null,
|
|
903
906
|
});
|
|
904
907
|
sessionStore.upsert({
|
|
905
908
|
id: "sess-002",
|
|
@@ -918,6 +921,7 @@ describe("costsCommand", () => {
|
|
|
918
921
|
lastActivity: new Date().toISOString(),
|
|
919
922
|
escalationLevel: 0,
|
|
920
923
|
stalledSince: null,
|
|
924
|
+
transcriptPath: null,
|
|
921
925
|
});
|
|
922
926
|
sessionStore.close();
|
|
923
927
|
|
|
@@ -977,6 +981,7 @@ describe("costsCommand", () => {
|
|
|
977
981
|
lastActivity: new Date().toISOString(),
|
|
978
982
|
escalationLevel: 0,
|
|
979
983
|
stalledSince: null,
|
|
984
|
+
transcriptPath: null,
|
|
980
985
|
});
|
|
981
986
|
sessionStore.close();
|
|
982
987
|
|
|
@@ -17,7 +17,6 @@ const AGENT_DEF_FILES = [
|
|
|
17
17
|
"reviewer.md",
|
|
18
18
|
"lead.md",
|
|
19
19
|
"merger.md",
|
|
20
|
-
"supervisor.md",
|
|
21
20
|
"coordinator.md",
|
|
22
21
|
"monitor.md",
|
|
23
22
|
];
|
|
@@ -46,7 +45,7 @@ describe("initCommand: agent-defs deployment", () => {
|
|
|
46
45
|
await cleanupTempDir(tempDir);
|
|
47
46
|
});
|
|
48
47
|
|
|
49
|
-
test("creates .overstory/agent-defs/ with all
|
|
48
|
+
test("creates .overstory/agent-defs/ with all 7 agent definition files (supervisor deprecated)", async () => {
|
|
50
49
|
await initCommand({});
|
|
51
50
|
|
|
52
51
|
const agentDefsDir = join(tempDir, ".overstory", "agent-defs");
|
package/src/commands/init.ts
CHANGED
|
@@ -241,14 +241,6 @@ function buildAgentManifest(): AgentManifest {
|
|
|
241
241
|
canSpawn: true,
|
|
242
242
|
constraints: ["read-only", "no-worktree"],
|
|
243
243
|
},
|
|
244
|
-
supervisor: {
|
|
245
|
-
file: "supervisor.md",
|
|
246
|
-
model: "opus",
|
|
247
|
-
tools: ["Read", "Write", "Edit", "Glob", "Grep", "Bash", "Task"],
|
|
248
|
-
capabilities: ["coordinate", "supervise"],
|
|
249
|
-
canSpawn: true,
|
|
250
|
-
constraints: [],
|
|
251
|
-
},
|
|
252
244
|
monitor: {
|
|
253
245
|
file: "monitor.md",
|
|
254
246
|
model: "sonnet",
|
|
@@ -595,6 +587,7 @@ export async function initCommand(opts: InitOptions): Promise<void> {
|
|
|
595
587
|
const agentDefFiles = await readdir(overstoryAgentsDir);
|
|
596
588
|
for (const fileName of agentDefFiles) {
|
|
597
589
|
if (!fileName.endsWith(".md")) continue;
|
|
590
|
+
if (fileName === "supervisor.md") continue; // Deprecated: not deployed to new projects
|
|
598
591
|
const source = Bun.file(join(overstoryAgentsDir, fileName));
|
|
599
592
|
const content = await source.text();
|
|
600
593
|
await Bun.write(join(agentDefsTarget, fileName), content);
|
|
@@ -153,6 +153,7 @@ describe("inspectCommand", () => {
|
|
|
153
153
|
lastActivity: new Date().toISOString(),
|
|
154
154
|
escalationLevel: 0,
|
|
155
155
|
stalledSince: null,
|
|
156
|
+
transcriptPath: null,
|
|
156
157
|
});
|
|
157
158
|
store.close();
|
|
158
159
|
|
|
@@ -185,6 +186,7 @@ describe("inspectCommand", () => {
|
|
|
185
186
|
lastActivity: new Date().toISOString(),
|
|
186
187
|
escalationLevel: 0,
|
|
187
188
|
stalledSince: null,
|
|
189
|
+
transcriptPath: null,
|
|
188
190
|
});
|
|
189
191
|
store.close();
|
|
190
192
|
|
|
@@ -221,6 +223,7 @@ describe("inspectCommand", () => {
|
|
|
221
223
|
lastActivity: new Date(Date.now() - 5_000).toISOString(),
|
|
222
224
|
escalationLevel: 0,
|
|
223
225
|
stalledSince: null,
|
|
226
|
+
transcriptPath: null,
|
|
224
227
|
});
|
|
225
228
|
store.close();
|
|
226
229
|
|
|
@@ -257,6 +260,7 @@ describe("inspectCommand", () => {
|
|
|
257
260
|
lastActivity: new Date().toISOString(),
|
|
258
261
|
escalationLevel: 0,
|
|
259
262
|
stalledSince: null,
|
|
263
|
+
transcriptPath: null,
|
|
260
264
|
});
|
|
261
265
|
store.close();
|
|
262
266
|
|
|
@@ -296,6 +300,7 @@ describe("inspectCommand", () => {
|
|
|
296
300
|
lastActivity: new Date().toISOString(),
|
|
297
301
|
escalationLevel: 0,
|
|
298
302
|
stalledSince: null,
|
|
303
|
+
transcriptPath: null,
|
|
299
304
|
});
|
|
300
305
|
store.close();
|
|
301
306
|
|
|
@@ -331,6 +336,7 @@ describe("inspectCommand", () => {
|
|
|
331
336
|
lastActivity: new Date().toISOString(),
|
|
332
337
|
escalationLevel: 0,
|
|
333
338
|
stalledSince: null,
|
|
339
|
+
transcriptPath: null,
|
|
334
340
|
});
|
|
335
341
|
store.close();
|
|
336
342
|
|
|
@@ -366,6 +372,7 @@ describe("inspectCommand", () => {
|
|
|
366
372
|
lastActivity: new Date().toISOString(),
|
|
367
373
|
escalationLevel: 0,
|
|
368
374
|
stalledSince: null,
|
|
375
|
+
transcriptPath: null,
|
|
369
376
|
});
|
|
370
377
|
store.close();
|
|
371
378
|
|
|
@@ -410,6 +417,7 @@ describe("inspectCommand", () => {
|
|
|
410
417
|
lastActivity: new Date().toISOString(),
|
|
411
418
|
escalationLevel: 0,
|
|
412
419
|
stalledSince: null,
|
|
420
|
+
transcriptPath: null,
|
|
413
421
|
});
|
|
414
422
|
store.close();
|
|
415
423
|
|
|
@@ -453,6 +461,7 @@ describe("inspectCommand", () => {
|
|
|
453
461
|
lastActivity: new Date().toISOString(),
|
|
454
462
|
escalationLevel: 0,
|
|
455
463
|
stalledSince: null,
|
|
464
|
+
transcriptPath: null,
|
|
456
465
|
});
|
|
457
466
|
store.close();
|
|
458
467
|
|
|
@@ -502,6 +511,7 @@ describe("inspectCommand", () => {
|
|
|
502
511
|
lastActivity: new Date().toISOString(),
|
|
503
512
|
escalationLevel: 0,
|
|
504
513
|
stalledSince: null,
|
|
514
|
+
transcriptPath: null,
|
|
505
515
|
});
|
|
506
516
|
store.close();
|
|
507
517
|
|
|
@@ -539,6 +549,7 @@ describe("inspectCommand", () => {
|
|
|
539
549
|
lastActivity: new Date().toISOString(),
|
|
540
550
|
escalationLevel: 0,
|
|
541
551
|
stalledSince: null,
|
|
552
|
+
transcriptPath: null,
|
|
542
553
|
});
|
|
543
554
|
store.close();
|
|
544
555
|
|
|
@@ -577,6 +588,7 @@ describe("inspectCommand", () => {
|
|
|
577
588
|
lastActivity: new Date().toISOString(),
|
|
578
589
|
escalationLevel: 0,
|
|
579
590
|
stalledSince: null,
|
|
591
|
+
transcriptPath: null,
|
|
580
592
|
});
|
|
581
593
|
store.close();
|
|
582
594
|
|
|
@@ -614,6 +626,7 @@ describe("inspectCommand", () => {
|
|
|
614
626
|
lastActivity: new Date().toISOString(),
|
|
615
627
|
escalationLevel: 0,
|
|
616
628
|
stalledSince: null,
|
|
629
|
+
transcriptPath: null,
|
|
617
630
|
});
|
|
618
631
|
store.close();
|
|
619
632
|
|
|
@@ -652,6 +665,7 @@ describe("inspectCommand", () => {
|
|
|
652
665
|
lastActivity: new Date().toISOString(),
|
|
653
666
|
escalationLevel: 0,
|
|
654
667
|
stalledSince: null,
|
|
668
|
+
transcriptPath: null,
|
|
655
669
|
});
|
|
656
670
|
store.close();
|
|
657
671
|
|
package/src/commands/log.test.ts
CHANGED
|
@@ -229,6 +229,7 @@ describe("logCommand", () => {
|
|
|
229
229
|
lastActivity: new Date().toISOString(),
|
|
230
230
|
escalationLevel: 0,
|
|
231
231
|
stalledSince: null,
|
|
232
|
+
transcriptPath: null,
|
|
232
233
|
};
|
|
233
234
|
const store = createSessionStore(dbPath);
|
|
234
235
|
store.upsert(session);
|
|
@@ -284,6 +285,7 @@ describe("logCommand", () => {
|
|
|
284
285
|
lastActivity: new Date().toISOString(),
|
|
285
286
|
escalationLevel: 0,
|
|
286
287
|
stalledSince: null,
|
|
288
|
+
transcriptPath: null,
|
|
287
289
|
};
|
|
288
290
|
const sessStore = createSessionStore(sessionsDbPath);
|
|
289
291
|
sessStore.upsert(session);
|
|
@@ -324,6 +326,7 @@ describe("logCommand", () => {
|
|
|
324
326
|
lastActivity: new Date(Date.now() - 60_000).toISOString(),
|
|
325
327
|
escalationLevel: 0,
|
|
326
328
|
stalledSince: null,
|
|
329
|
+
transcriptPath: null,
|
|
327
330
|
};
|
|
328
331
|
const store = createSessionStore(dbPath);
|
|
329
332
|
store.upsert(session);
|
|
@@ -363,6 +366,7 @@ describe("logCommand", () => {
|
|
|
363
366
|
lastActivity: new Date(Date.now() - 60_000).toISOString(),
|
|
364
367
|
escalationLevel: 0,
|
|
365
368
|
stalledSince: null,
|
|
369
|
+
transcriptPath: null,
|
|
366
370
|
};
|
|
367
371
|
const store = createSessionStore(dbPath);
|
|
368
372
|
store.upsert(session);
|
|
@@ -400,6 +404,7 @@ describe("logCommand", () => {
|
|
|
400
404
|
lastActivity: new Date().toISOString(),
|
|
401
405
|
escalationLevel: 0,
|
|
402
406
|
stalledSince: null,
|
|
407
|
+
transcriptPath: null,
|
|
403
408
|
});
|
|
404
409
|
sessionStoreLocal.close();
|
|
405
410
|
|
|
@@ -457,6 +462,7 @@ describe("logCommand", () => {
|
|
|
457
462
|
lastActivity: new Date().toISOString(),
|
|
458
463
|
escalationLevel: 0,
|
|
459
464
|
stalledSince: null,
|
|
465
|
+
transcriptPath: null,
|
|
460
466
|
});
|
|
461
467
|
sessionStoreLocal.close();
|
|
462
468
|
|
|
@@ -487,6 +493,7 @@ describe("logCommand", () => {
|
|
|
487
493
|
lastActivity: new Date().toISOString(),
|
|
488
494
|
escalationLevel: 0,
|
|
489
495
|
stalledSince: null,
|
|
496
|
+
transcriptPath: null,
|
|
490
497
|
});
|
|
491
498
|
sessionStoreLocal.close();
|
|
492
499
|
|
|
@@ -541,6 +548,7 @@ describe("logCommand", () => {
|
|
|
541
548
|
lastActivity: new Date().toISOString(),
|
|
542
549
|
escalationLevel: 0,
|
|
543
550
|
stalledSince: null,
|
|
551
|
+
transcriptPath: null,
|
|
544
552
|
});
|
|
545
553
|
sessionStoreLocal.close();
|
|
546
554
|
|
|
@@ -594,6 +602,7 @@ describe("logCommand", () => {
|
|
|
594
602
|
lastActivity: new Date().toISOString(),
|
|
595
603
|
escalationLevel: 0,
|
|
596
604
|
stalledSince: null,
|
|
605
|
+
transcriptPath: null,
|
|
597
606
|
};
|
|
598
607
|
const store = createSessionStore(dbPath);
|
|
599
608
|
store.upsert(session);
|
|
@@ -634,6 +643,7 @@ describe("logCommand", () => {
|
|
|
634
643
|
lastActivity: new Date().toISOString(),
|
|
635
644
|
escalationLevel: 0,
|
|
636
645
|
stalledSince: null,
|
|
646
|
+
transcriptPath: null,
|
|
637
647
|
};
|
|
638
648
|
const store = createSessionStore(dbPath);
|
|
639
649
|
store.upsert(session);
|
|
@@ -676,6 +686,7 @@ describe("logCommand", () => {
|
|
|
676
686
|
lastActivity: oldTimestamp,
|
|
677
687
|
escalationLevel: 0,
|
|
678
688
|
stalledSince: null,
|
|
689
|
+
transcriptPath: null,
|
|
679
690
|
};
|
|
680
691
|
const store = createSessionStore(dbPath);
|
|
681
692
|
store.upsert(session);
|
|
@@ -715,6 +726,7 @@ describe("logCommand", () => {
|
|
|
715
726
|
lastActivity: new Date().toISOString(),
|
|
716
727
|
escalationLevel: 0,
|
|
717
728
|
stalledSince: null,
|
|
729
|
+
transcriptPath: null,
|
|
718
730
|
};
|
|
719
731
|
const store = createSessionStore(dbPath);
|
|
720
732
|
store.upsert(session);
|
|
@@ -800,6 +812,7 @@ describe("logCommand", () => {
|
|
|
800
812
|
lastActivity: new Date().toISOString(),
|
|
801
813
|
escalationLevel: 0,
|
|
802
814
|
stalledSince: null,
|
|
815
|
+
transcriptPath: null,
|
|
803
816
|
};
|
|
804
817
|
const store = createSessionStore(dbPath);
|
|
805
818
|
store.upsert(session);
|
|
@@ -839,6 +852,7 @@ describe("logCommand", () => {
|
|
|
839
852
|
lastActivity: new Date().toISOString(),
|
|
840
853
|
escalationLevel: 0,
|
|
841
854
|
stalledSince: null,
|
|
855
|
+
transcriptPath: null,
|
|
842
856
|
};
|
|
843
857
|
const store = createSessionStore(dbPath);
|
|
844
858
|
store.upsert(session);
|