@os-eco/overstory-cli 0.6.5 → 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.
Files changed (79) hide show
  1. package/README.md +60 -60
  2. package/agents/builder.md +16 -16
  3. package/agents/coordinator.md +57 -57
  4. package/agents/issue-reviews.md +71 -0
  5. package/agents/lead.md +43 -42
  6. package/agents/merger.md +15 -15
  7. package/agents/monitor.md +37 -37
  8. package/agents/pr-reviews.md +60 -0
  9. package/agents/prioritize.md +110 -0
  10. package/agents/release.md +56 -0
  11. package/agents/reviewer.md +15 -15
  12. package/agents/scout.md +18 -18
  13. package/agents/supervisor.md +78 -78
  14. package/package.json +1 -1
  15. package/src/agents/hooks-deployer.test.ts +23 -26
  16. package/src/agents/hooks-deployer.ts +9 -5
  17. package/src/agents/overlay.test.ts +5 -5
  18. package/src/agents/overlay.ts +11 -11
  19. package/src/commands/agents.ts +7 -6
  20. package/src/commands/clean.ts +5 -5
  21. package/src/commands/completions.test.ts +10 -10
  22. package/src/commands/completions.ts +26 -28
  23. package/src/commands/coordinator.test.ts +2 -2
  24. package/src/commands/coordinator.ts +12 -12
  25. package/src/commands/costs.ts +1 -1
  26. package/src/commands/dashboard.ts +8 -8
  27. package/src/commands/doctor.ts +4 -4
  28. package/src/commands/errors.ts +1 -1
  29. package/src/commands/feed.ts +1 -1
  30. package/src/commands/group.ts +3 -3
  31. package/src/commands/hooks.test.ts +7 -7
  32. package/src/commands/hooks.ts +7 -7
  33. package/src/commands/init.test.ts +6 -2
  34. package/src/commands/init.ts +19 -19
  35. package/src/commands/inspect.ts +19 -19
  36. package/src/commands/log.ts +3 -3
  37. package/src/commands/logs.ts +1 -1
  38. package/src/commands/mail.test.ts +2 -2
  39. package/src/commands/mail.ts +28 -11
  40. package/src/commands/merge.ts +7 -7
  41. package/src/commands/metrics.test.ts +1 -1
  42. package/src/commands/metrics.ts +2 -2
  43. package/src/commands/monitor.test.ts +5 -5
  44. package/src/commands/monitor.ts +4 -4
  45. package/src/commands/nudge.ts +1 -1
  46. package/src/commands/prime.test.ts +1 -1
  47. package/src/commands/prime.ts +2 -2
  48. package/src/commands/replay.ts +1 -1
  49. package/src/commands/run.ts +2 -2
  50. package/src/commands/sling.test.ts +84 -2
  51. package/src/commands/sling.ts +97 -9
  52. package/src/commands/spec.ts +8 -9
  53. package/src/commands/status.test.ts +2 -2
  54. package/src/commands/status.ts +2 -4
  55. package/src/commands/stop.ts +2 -2
  56. package/src/commands/supervisor.test.ts +1 -1
  57. package/src/commands/supervisor.ts +4 -4
  58. package/src/commands/trace.test.ts +2 -2
  59. package/src/commands/trace.ts +4 -4
  60. package/src/commands/watch.ts +5 -5
  61. package/src/commands/worktree.test.ts +3 -3
  62. package/src/commands/worktree.ts +11 -11
  63. package/src/doctor/dependencies.test.ts +5 -5
  64. package/src/doctor/dependencies.ts +2 -2
  65. package/src/doctor/logs.ts +1 -1
  66. package/src/doctor/structure.test.ts +1 -1
  67. package/src/doctor/structure.ts +1 -1
  68. package/src/doctor/version.test.ts +3 -3
  69. package/src/doctor/version.ts +1 -1
  70. package/src/e2e/init-sling-lifecycle.test.ts +6 -2
  71. package/src/index.ts +11 -9
  72. package/src/mail/client.test.ts +1 -1
  73. package/src/mail/client.ts +2 -2
  74. package/src/mulch/client.ts +1 -1
  75. package/src/worktree/tmux.test.ts +8 -3
  76. package/src/worktree/tmux.ts +19 -18
  77. package/templates/CLAUDE.md.tmpl +27 -27
  78. package/templates/hooks.json.tmpl +15 -11
  79. package/templates/overlay.md.tmpl +7 -7
@@ -66,7 +66,7 @@ describe("checkDependencies", () => {
66
66
  expect(toolNames).toContain("tmux availability");
67
67
  expect(toolNames).toContain("sd availability");
68
68
  expect(toolNames).toContain("mulch availability");
69
- expect(toolNames).toContain("overstory availability");
69
+ expect(toolNames).toContain("ov availability");
70
70
  expect(toolNames).toContain("cn availability");
71
71
  });
72
72
 
@@ -201,9 +201,9 @@ describe("checkDependencies", () => {
201
201
  expect(mlAlias?.category).toBe("dependencies");
202
202
  expect(["pass", "warn"]).toContain(mlAlias?.status ?? "");
203
203
  }
204
- const ovCheck = checks.find((c) => c.name === "overstory availability");
204
+ const ovCheck = checks.find((c) => c.name === "ov availability");
205
205
  if (ovCheck?.status === "pass") {
206
- const ovAlias = checks.find((c) => c.name === "ov alias");
206
+ const ovAlias = checks.find((c) => c.name === "overstory alias");
207
207
  expect(ovAlias).toBeDefined();
208
208
  expect(["pass", "warn"]).toContain(ovAlias?.status ?? "");
209
209
  }
@@ -229,9 +229,9 @@ describe("checkDependencies", () => {
229
229
  }
230
230
  });
231
231
 
232
- test("includes overstory availability check", async () => {
232
+ test("includes ov availability check", async () => {
233
233
  const checks = await checkDependencies(mockConfig, "/tmp/.overstory");
234
- const ovCheck = checks.find((c) => c.name === "overstory availability");
234
+ const ovCheck = checks.find((c) => c.name === "ov availability");
235
235
  expect(ovCheck).toBeDefined();
236
236
  expect(ovCheck?.category).toBe("dependencies");
237
237
  });
@@ -42,10 +42,10 @@ export const checkDependencies: DoctorCheckFn = async (
42
42
  installHint: "@os-eco/mulch-cli",
43
43
  },
44
44
  {
45
- name: "overstory",
45
+ name: "ov",
46
46
  versionFlag: "--version",
47
47
  required: true,
48
- alias: "ov",
48
+ alias: "overstory",
49
49
  installHint: "@os-eco/overstory-cli",
50
50
  },
51
51
  {
@@ -177,7 +177,7 @@ export const checkLogs: DoctorCheckFn = async (_config, overstoryDir): Promise<D
177
177
  totalBytes > DISK_USAGE_WARN_THRESHOLD
178
178
  ? [
179
179
  `Exceeds ${formatBytes(DISK_USAGE_WARN_THRESHOLD)} threshold`,
180
- "Consider running 'overstory worktree clean --completed' to remove old logs",
180
+ "Consider running 'ov worktree clean --completed' to remove old logs",
181
181
  ]
182
182
  : undefined,
183
183
  fixable: totalBytes > DISK_USAGE_WARN_THRESHOLD,
@@ -104,7 +104,7 @@ describe("checkStructure", () => {
104
104
  await Bun.write(
105
105
  join(overstoryDir, ".gitignore"),
106
106
  `# Wildcard+whitelist: ignore everything, whitelist tracked files
107
- # Auto-healed by overstory prime on each session start
107
+ # Auto-healed by ov prime on each session start
108
108
  *
109
109
  !.gitignore
110
110
  !config.yaml
@@ -32,7 +32,7 @@ export const checkStructure: DoctorCheckFn = async (
32
32
  category: "structure",
33
33
  status: overstoryDirExists ? "pass" : "fail",
34
34
  message: overstoryDirExists ? "Directory exists" : "Directory missing",
35
- details: overstoryDirExists ? undefined : ["Run 'overstory init' to create it"],
35
+ details: overstoryDirExists ? undefined : ["Run 'ov init' to create it"],
36
36
  fixable: !overstoryDirExists,
37
37
  });
38
38
 
@@ -70,7 +70,7 @@ describe("checkVersion", () => {
70
70
  const versionCheck = checks.find((c) => c.name === "version-current");
71
71
  expect(versionCheck).toBeDefined();
72
72
  expect(versionCheck?.status).toBeOneOf(["pass", "warn", "fail"]);
73
- expect(versionCheck?.message).toContain("overstory");
73
+ expect(versionCheck?.message).toContain("ov");
74
74
  });
75
75
 
76
76
  test("includes package-json-sync check", async () => {
@@ -88,8 +88,8 @@ describe("checkVersion", () => {
88
88
  expect(versionCheck).toBeDefined();
89
89
 
90
90
  if (versionCheck?.status === "pass") {
91
- // Message should contain version in format "overstory vX.Y.Z"
92
- expect(versionCheck.message).toMatch(/overstory v\d+\.\d+\.\d+/);
91
+ // Message should contain version in format "ov vX.Y.Z"
92
+ expect(versionCheck.message).toMatch(/ov v\d+\.\d+\.\d+/);
93
93
  }
94
94
  });
95
95
 
@@ -47,7 +47,7 @@ async function checkCurrentVersion(toolRoot: string): Promise<DoctorCheck> {
47
47
  name: "version-current",
48
48
  category: "version",
49
49
  status: "pass",
50
- message: `overstory v${packageJson.version}`,
50
+ message: `ov v${packageJson.version}`,
51
51
  };
52
52
  } catch (error) {
53
53
  return {
@@ -22,9 +22,13 @@ import type { OverlayConfig } from "../types.ts";
22
22
  const EXPECTED_AGENT_DEFS = [
23
23
  "builder.md",
24
24
  "coordinator.md",
25
+ "issue-reviews.md",
25
26
  "lead.md",
26
27
  "merger.md",
27
28
  "monitor.md",
29
+ "pr-reviews.md",
30
+ "prioritize.md",
31
+ "release.md",
28
32
  "reviewer.md",
29
33
  "scout.md",
30
34
  "supervisor.md",
@@ -109,7 +113,7 @@ describe("E2E: init→sling lifecycle on external project", () => {
109
113
  expect(config.project.name).toBeTruthy();
110
114
  });
111
115
 
112
- test("manifest loads successfully with all 8 agents", async () => {
116
+ test("manifest loads successfully with all 12 agents", async () => {
113
117
  await initCommand({});
114
118
 
115
119
  const manifestPath = join(tempDir, ".overstory", "agent-manifest.json");
@@ -269,7 +273,7 @@ describe("E2E: init→sling lifecycle on external project", () => {
269
273
  expect(overlayContent).toContain("orchestrator");
270
274
  expect(overlayContent).toContain("`src/main.ts`");
271
275
  expect(overlayContent).toContain("`src/utils.ts`");
272
- expect(overlayContent).toContain("mulch prime typescript");
276
+ expect(overlayContent).toContain("ml prime typescript");
273
277
 
274
278
  // No unresolved placeholders
275
279
  expect(overlayContent).not.toMatch(/\{\{[A-Z_]+\}\}/);
package/src/index.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  * Overstory CLI — main entry point and command router.
5
5
  *
6
6
  * Routes subcommands to their respective handlers in src/commands/.
7
- * Usage: overstory <command> [args...]
7
+ * Usage: ov <command> [args...]
8
8
  */
9
9
 
10
10
  import { Command } from "commander";
@@ -42,7 +42,7 @@ import { createWorktreeCommand } from "./commands/worktree.ts";
42
42
  import { OverstoryError, WorktreeError } from "./errors.ts";
43
43
  import { setQuiet } from "./logging/color.ts";
44
44
 
45
- const VERSION = "0.6.5";
45
+ const VERSION = "0.6.6";
46
46
 
47
47
  const COMMANDS = [
48
48
  "agents",
@@ -113,9 +113,9 @@ function suggestCommand(input: string): string | undefined {
113
113
  const program = new Command();
114
114
 
115
115
  program
116
- .name("overstory")
116
+ .name("ov")
117
117
  .description("Multi-agent orchestration for Claude Code")
118
- .version(`overstory v${VERSION}`, "-v, --version")
118
+ .version(`ov v${VERSION}`, "-v, --version")
119
119
  .option("-q, --quiet", "Suppress non-error output")
120
120
  .option("--json", "JSON output")
121
121
  .option("--verbose", "Verbose output");
@@ -295,7 +295,7 @@ program.on("command:*", (operands) => {
295
295
  if (suggestion) {
296
296
  process.stderr.write(`Did you mean '${suggestion}'?\n`);
297
297
  }
298
- process.stderr.write("Run 'overstory --help' for usage.\n");
298
+ process.stderr.write("Run 'ov --help' for usage.\n");
299
299
  process.exit(1);
300
300
  });
301
301
 
@@ -307,20 +307,22 @@ if (import.meta.main)
307
307
  main().catch((err: unknown) => {
308
308
  // Friendly message when running outside a git repository
309
309
  if (err instanceof WorktreeError && err.message.includes("not a git repository")) {
310
- process.stderr.write("Not in an overstory project. Run 'overstory init' first.\n");
310
+ process.stderr.write("Not in an overstory project. Run 'ov init' first.\n");
311
311
  process.exit(1);
312
312
  }
313
313
  if (err instanceof OverstoryError) {
314
314
  process.stderr.write(`Error [${err.code}]: ${err.message}\n`);
315
- process.exit(1);
315
+ process.exitCode = 1;
316
+ return;
316
317
  }
317
318
  if (err instanceof Error) {
318
319
  process.stderr.write(`Error: ${err.message}\n`);
319
320
  if (process.argv.includes("--verbose")) {
320
321
  process.stderr.write(`${err.stack}\n`);
321
322
  }
322
- process.exit(1);
323
+ process.exitCode = 1;
324
+ return;
323
325
  }
324
326
  process.stderr.write(`Unknown error: ${String(err)}\n`);
325
- process.exit(1);
327
+ process.exitCode = 1;
326
328
  });
@@ -225,7 +225,7 @@ describe("createMailClient", () => {
225
225
  });
226
226
 
227
227
  const result = client.checkInject("orchestrator");
228
- expect(result).toContain(`overstory mail reply ${id}`);
228
+ expect(result).toContain(`ov mail reply ${id}`);
229
229
  });
230
230
 
231
231
  test("formats multiple messages with correct count", () => {
@@ -96,7 +96,7 @@ function formatForInjection(messages: MailMessage[]): string {
96
96
  }
97
97
 
98
98
  const lines: string[] = [
99
- `📬 You have ${messages.length} new message${messages.length === 1 ? "" : "s"}:`,
99
+ `You have ${messages.length} new message${messages.length === 1 ? "" : "s"}:`,
100
100
  "",
101
101
  ];
102
102
 
@@ -108,7 +108,7 @@ function formatForInjection(messages: MailMessage[]): string {
108
108
  if (msg.payload !== null && PROTOCOL_TYPES.has(msg.type)) {
109
109
  lines.push(`Payload: ${msg.payload}`);
110
110
  }
111
- lines.push(`[Reply with: overstory mail reply ${msg.id} --body "..."]`);
111
+ lines.push(`[Reply with: ov mail reply ${msg.id} --body "..."]`);
112
112
  lines.push("");
113
113
  }
114
114
 
@@ -116,7 +116,7 @@ export function createMulchClient(cwd: string): MulchClient {
116
116
  args: string[],
117
117
  context: string,
118
118
  ): Promise<{ stdout: string; stderr: string }> {
119
- const { stdout, stderr, exitCode } = await runCommand(["mulch", ...args], cwd);
119
+ const { stdout, stderr, exitCode } = await runCommand(["ml", ...args], cwd);
120
120
  if (exitCode !== 0) {
121
121
  throw new AgentError(`mulch ${context} failed (exit ${exitCode}): ${stderr.trim()}`);
122
122
  }
@@ -210,15 +210,19 @@ describe("createSession", () => {
210
210
  }
211
211
  });
212
212
 
213
- test("still creates session when which overstory fails (uses fallback)", async () => {
213
+ test("still creates session when which ov and which overstory both fail (uses fallback)", async () => {
214
214
  let callCount = 0;
215
215
  spawnSpy.mockImplementation(() => {
216
216
  callCount++;
217
217
  if (callCount === 1) {
218
+ // which ov fails
219
+ return mockSpawnResult("", "ov not found", 1);
220
+ }
221
+ if (callCount === 2) {
218
222
  // which overstory fails
219
223
  return mockSpawnResult("", "overstory not found", 1);
220
224
  }
221
- if (callCount === 2) {
225
+ if (callCount === 3) {
222
226
  // tmux new-session
223
227
  return mockSpawnResult("", "", 0);
224
228
  }
@@ -230,7 +234,8 @@ describe("createSession", () => {
230
234
  expect(pid).toBe(5555);
231
235
 
232
236
  // The tmux command should contain the original command
233
- const tmuxCallArgs = spawnSpy.mock.calls[1] as unknown[];
237
+ // Call 0: which ov, Call 1: which overstory, Call 2: tmux new-session
238
+ const tmuxCallArgs = spawnSpy.mock.calls[2] as unknown[];
234
239
  const cmd = tmuxCallArgs[0] as string[];
235
240
  const tmuxCmd = cmd[7] as string;
236
241
  expect(tmuxCmd).toContain("echo test");
@@ -13,30 +13,31 @@ import { AgentError } from "../errors.ts";
13
13
  /**
14
14
  * Detect the directory containing the overstory binary.
15
15
  *
16
- * Checks process.argv[0] first (the bun/node executable path won't help,
17
- * but process.argv[1] is the script path for `bun run`), then falls back
18
- * to `which overstory` to find it on the current PATH.
16
+ * Tries `which ov` first (the short alias), then falls back to
17
+ * `which overstory` (the original name). Both are registered in
18
+ * package.json bin, but depending on how the tool was installed
19
+ * (bun link, npm link, global install), only one may be on PATH.
19
20
  *
20
21
  * Returns null if detection fails.
21
22
  */
22
23
  async function detectOverstoryBinDir(): Promise<string | null> {
23
- // process.argv[1] is the script entry point (e.g., /path/to/overstory/src/index.ts)
24
- // The overstory binary (bun link) resolves to a bin dir
25
- // Try `which overstory` for the most reliable result
26
- try {
27
- const proc = Bun.spawn(["which", "overstory"], {
28
- stdout: "pipe",
29
- stderr: "pipe",
30
- });
31
- const exitCode = await proc.exited;
32
- if (exitCode === 0) {
33
- const binPath = (await new Response(proc.stdout).text()).trim();
34
- if (binPath.length > 0) {
35
- return dirname(resolve(binPath));
24
+ // Try both command names — the alias migration may leave only one resolvable
25
+ for (const cmdName of ["ov", "overstory"]) {
26
+ try {
27
+ const proc = Bun.spawn(["which", cmdName], {
28
+ stdout: "pipe",
29
+ stderr: "pipe",
30
+ });
31
+ const exitCode = await proc.exited;
32
+ if (exitCode === 0) {
33
+ const binPath = (await new Response(proc.stdout).text()).trim();
34
+ if (binPath.length > 0) {
35
+ return dirname(resolve(binPath));
36
+ }
36
37
  }
38
+ } catch {
39
+ // which not available or command not on PATH — try next
37
40
  }
38
- } catch {
39
- // which not available or overstory not on PATH
40
41
  }
41
42
 
42
43
  // Fallback: if process.argv[1] points to overstory's own entry point (src/index.ts),
@@ -1,6 +1,6 @@
1
1
  # {{PROJECT_NAME}} — Overstory Orchestration
2
2
 
3
- > Auto-generated by `overstory init`. You may edit this file.
3
+ > Auto-generated by `ov init`. You may edit this file.
4
4
 
5
5
  This project uses **overstory** for Claude Code agent orchestration. Your session
6
6
  acts as the orchestrator: you decide what work to delegate, spawn worker agents,
@@ -10,34 +10,34 @@ monitor progress, and merge results.
10
10
 
11
11
  ```bash
12
12
  # Spawn a worker agent
13
- overstory sling <bead-id> --capability <type> --name <agent-name> \
13
+ ov sling <bead-id> --capability <type> --name <agent-name> \
14
14
  [--spec <path>] [--files file1,file2] [--parent <agent>] [--depth <n>]
15
15
 
16
16
  # Check system status
17
- overstory status # Overview of all agents, worktrees, {{TRACKER_NAME}}
18
- overstory status --json # Machine-readable output
19
- overstory status --watch # Live updating
17
+ ov status # Overview of all agents, worktrees, {{TRACKER_NAME}}
18
+ ov status --json # Machine-readable output
19
+ ov status --watch # Live updating
20
20
 
21
21
  # Messaging (SQLite-backed, ~1-5ms per query)
22
- overstory mail send --to <agent> --subject "..." --body "..."
23
- overstory mail check # Your inbox
24
- overstory mail list --unread # All unread messages
25
- overstory mail reply <id> --body "..."
22
+ ov mail send --to <agent> --subject "..." --body "..."
23
+ ov mail check # Your inbox
24
+ ov mail list --unread # All unread messages
25
+ ov mail reply <id> --body "..."
26
26
 
27
27
  # Merge completed work
28
- overstory merge --branch <name> # Merge a specific branch
29
- overstory merge --all # Merge all completed branches
30
- overstory merge --dry-run --branch <name> # Preview conflicts
28
+ ov merge --branch <name> # Merge a specific branch
29
+ ov merge --all # Merge all completed branches
30
+ ov merge --dry-run --branch <name> # Preview conflicts
31
31
 
32
32
  # Worktree management
33
- overstory worktree list # Show all worktrees with status
34
- overstory worktree clean --completed # Remove finished worktrees
33
+ ov worktree list # Show all worktrees with status
34
+ ov worktree clean --completed # Remove finished worktrees
35
35
 
36
36
  # Context and monitoring
37
- overstory prime # Reload context (config, mulch, recent activity)
38
- overstory watch --background # Start watchdog daemon
39
- overstory metrics # Performance summary
40
- overstory log <event> --agent <name> # Hook-driven event logging
37
+ ov prime # Reload context (config, mulch, recent activity)
38
+ ov watch --background # Start watchdog daemon
39
+ ov metrics # Performance summary
40
+ ov log <event> --agent <name> # Hook-driven event logging
41
41
  ```
42
42
 
43
43
  ## How to Spawn Agents
@@ -46,10 +46,10 @@ overstory log <event> --agent <name> # Hook-driven event logging
46
46
  2. Choose a capability based on the task:
47
47
  {{AGENT_DEFINITIONS}}
48
48
  3. Assign exclusive file scope so agents do not conflict
49
- 4. Spawn: `overstory sling <bead-id> --capability <type> --name <unique-name> --files src/foo.ts,src/bar.ts`
49
+ 4. Spawn: `ov sling <bead-id> --capability <type> --name <unique-name> --files src/foo.ts,src/bar.ts`
50
50
 
51
51
  Each spawned agent gets its own git worktree, branch, CLAUDE.md overlay, and
52
- tmux session. Agents communicate via `overstory mail` and report completion
52
+ tmux session. Agents communicate via `ov mail` and report completion
53
53
  by closing their {{TRACKER_NAME}} issue (`{{TRACKER_CLI}} close <id> --reason "summary"`).
54
54
 
55
55
  ## Hierarchical Delegation
@@ -58,10 +58,10 @@ You can spawn **team leads** that themselves spawn sub-workers:
58
58
 
59
59
  ```
60
60
  Orchestrator (this session)
61
- └── overstory sling bd-xyz --capability lead --name build-lead
62
- ├── overstory sling bd-abc --capability builder --name auth-login
63
- ├── overstory sling bd-def --capability builder --name auth-signup
64
- └── overstory sling bd-ghi --capability builder --name auth-reset
61
+ └── ov sling bd-xyz --capability lead --name build-lead
62
+ ├── ov sling bd-abc --capability builder --name auth-login
63
+ ├── ov sling bd-def --capability builder --name auth-signup
64
+ └── ov sling bd-ghi --capability builder --name auth-reset
65
65
  ```
66
66
 
67
67
  Depth limit is configurable (default: 2). Leads use `--parent` and `--depth`
@@ -69,7 +69,7 @@ to track hierarchy.
69
69
 
70
70
  ## Checking Status
71
71
 
72
- Run `overstory status` to see:
72
+ Run `ov status` to see:
73
73
  - Active agents and their states (booting, working, stalled, zombie)
74
74
  - Worktree locations and branches
75
75
  - Beads issue progress
@@ -83,7 +83,7 @@ All merges target **{{CANONICAL_BRANCH}}**. Agents work on branches named
83
83
  ## Conventions
84
84
 
85
85
  - Agents own files exclusively — no two agents modify the same file
86
- - Use `overstory mail` for all inter-agent communication (not {{TRACKER_NAME}})
86
+ - Use `ov mail` for all inter-agent communication (not {{TRACKER_NAME}})
87
87
  - Use `{{TRACKER_CLI}} close` to report task completion (not mail)
88
- - Merge via `overstory merge`, not raw `git merge`
88
+ - Merge via `ov merge`, not raw `git merge`
89
89
  - Logs live in `.overstory/logs/` — never delete them manually
@@ -6,7 +6,11 @@
6
6
  "hooks": [
7
7
  {
8
8
  "type": "command",
9
- "command": "[ -z \"$OVERSTORY_AGENT_NAME\" ] && exit 0; overstory prime --agent {{AGENT_NAME}}"
9
+ "command": "[ -z \"$OVERSTORY_AGENT_NAME\" ] && exit 0; ov prime --agent {{AGENT_NAME}}"
10
+ },
11
+ {
12
+ "type": "command",
13
+ "command": "[ -z \"$OVERSTORY_AGENT_NAME\" ] && exit 0; ov mail check --inject --agent {{AGENT_NAME}}"
10
14
  }
11
15
  ]
12
16
  }
@@ -17,7 +21,7 @@
17
21
  "hooks": [
18
22
  {
19
23
  "type": "command",
20
- "command": "[ -z \"$OVERSTORY_AGENT_NAME\" ] && exit 0; overstory mail check --inject --agent {{AGENT_NAME}}"
24
+ "command": "[ -z \"$OVERSTORY_AGENT_NAME\" ] && exit 0; ov mail check --inject --agent {{AGENT_NAME}}"
21
25
  }
22
26
  ]
23
27
  }
@@ -28,7 +32,7 @@
28
32
  "hooks": [
29
33
  {
30
34
  "type": "command",
31
- "command": "[ -z \"$OVERSTORY_AGENT_NAME\" ] && exit 0; overstory log tool-start --agent {{AGENT_NAME}} --stdin"
35
+ "command": "[ -z \"$OVERSTORY_AGENT_NAME\" ] && exit 0; ov log tool-start --agent {{AGENT_NAME}} --stdin"
32
36
  }
33
37
  ]
34
38
  },
@@ -37,7 +41,7 @@
37
41
  "hooks": [
38
42
  {
39
43
  "type": "command",
40
- "command": "read -r INPUT; CMD=$(echo \"$INPUT\" | sed 's/.*\"command\": *\"\\([^\"]*\\)\".*/\\1/'); if echo \"$CMD\" | grep -qE '\\bgit\\s+push\\b'; then echo '{\"decision\":\"block\",\"reason\":\"git push is blocked — use overstory merge to integrate changes, push manually when ready\"}'; exit 0; fi;"
44
+ "command": "read -r INPUT; CMD=$(echo \"$INPUT\" | sed 's/.*\"command\": *\"\\([^\"]*\\)\".*/\\1/'); if echo \"$CMD\" | grep -qE '\\bgit\\s+push\\b'; then echo '{\"decision\":\"block\",\"reason\":\"git push is blocked — use ov merge to integrate changes, push manually when ready\"}'; exit 0; fi;"
41
45
  }
42
46
  ]
43
47
  }
@@ -48,11 +52,11 @@
48
52
  "hooks": [
49
53
  {
50
54
  "type": "command",
51
- "command": "[ -z \"$OVERSTORY_AGENT_NAME\" ] && exit 0; overstory log tool-end --agent {{AGENT_NAME}} --stdin"
55
+ "command": "[ -z \"$OVERSTORY_AGENT_NAME\" ] && exit 0; ov log tool-end --agent {{AGENT_NAME}} --stdin"
52
56
  },
53
57
  {
54
58
  "type": "command",
55
- "command": "[ -z \"$OVERSTORY_AGENT_NAME\" ] && exit 0; overstory mail check --inject --agent {{AGENT_NAME}} --debounce 500"
59
+ "command": "[ -z \"$OVERSTORY_AGENT_NAME\" ] && exit 0; ov mail check --inject --agent {{AGENT_NAME}} --debounce 500"
56
60
  }
57
61
  ]
58
62
  },
@@ -61,7 +65,7 @@
61
65
  "hooks": [
62
66
  {
63
67
  "type": "command",
64
- "command": "[ -z \"$OVERSTORY_AGENT_NAME\" ] && exit 0; overstory mail check --inject --agent {{AGENT_NAME}} --debounce 30000"
68
+ "command": "[ -z \"$OVERSTORY_AGENT_NAME\" ] && exit 0; ov mail check --inject --agent {{AGENT_NAME}} --debounce 30000"
65
69
  }
66
70
  ]
67
71
  },
@@ -70,7 +74,7 @@
70
74
  "hooks": [
71
75
  {
72
76
  "type": "command",
73
- "command": "[ -z \"$OVERSTORY_AGENT_NAME\" ] && exit 0; read -r INPUT; if echo \"$INPUT\" | grep -qE '\\bgit\\s+commit\\b'; then mulch diff HEAD~1 >/dev/null 2>&1 || true; fi; exit 0;"
77
+ "command": "[ -z \"$OVERSTORY_AGENT_NAME\" ] && exit 0; read -r INPUT; if echo \"$INPUT\" | grep -qE '\\bgit\\s+commit\\b'; then ml diff HEAD~1 >/dev/null 2>&1 || true; fi; exit 0;"
74
78
  }
75
79
  ]
76
80
  }
@@ -81,11 +85,11 @@
81
85
  "hooks": [
82
86
  {
83
87
  "type": "command",
84
- "command": "[ -z \"$OVERSTORY_AGENT_NAME\" ] && exit 0; overstory log session-end --agent {{AGENT_NAME}} --stdin"
88
+ "command": "[ -z \"$OVERSTORY_AGENT_NAME\" ] && exit 0; ov log session-end --agent {{AGENT_NAME}} --stdin"
85
89
  },
86
90
  {
87
91
  "type": "command",
88
- "command": "[ -z \"$OVERSTORY_AGENT_NAME\" ] && exit 0; mulch learn"
92
+ "command": "[ -z \"$OVERSTORY_AGENT_NAME\" ] && exit 0; ml learn"
89
93
  }
90
94
  ]
91
95
  }
@@ -96,7 +100,7 @@
96
100
  "hooks": [
97
101
  {
98
102
  "type": "command",
99
- "command": "[ -z \"$OVERSTORY_AGENT_NAME\" ] && exit 0; overstory prime --agent {{AGENT_NAME}} --compact"
103
+ "command": "[ -z \"$OVERSTORY_AGENT_NAME\" ] && exit 0; ov prime --agent {{AGENT_NAME}} --compact"
100
104
  }
101
105
  ]
102
106
  }
@@ -1,5 +1,5 @@
1
1
  # DO NOT EDIT — Auto-generated by overstory
2
- # This overlay was written by `overstory sling`. Manual edits will be
2
+ # This overlay was written by `ov sling`. Manual edits will be
3
3
  # overwritten on the next spawn. Modify the template at
4
4
  # templates/overlay.md.tmpl in the overstory repo instead.
5
5
 
@@ -50,26 +50,26 @@ Prime relevant domain knowledge before starting work:
50
50
 
51
51
  ## Communication
52
52
 
53
- Use `overstory mail` for all communication. Your address is **{{AGENT_NAME}}**.
53
+ Use `ov mail` for all communication. Your address is **{{AGENT_NAME}}**.
54
54
 
55
55
  ```bash
56
56
  # Check your inbox (do this regularly)
57
- overstory mail check --agent {{AGENT_NAME}}
57
+ ov mail check --agent {{AGENT_NAME}}
58
58
 
59
59
  # Send a status update to your parent
60
- overstory mail send --to {{PARENT_AGENT}} --subject "status" \
60
+ ov mail send --to {{PARENT_AGENT}} --subject "status" \
61
61
  --body "Progress update here" --type status --agent {{AGENT_NAME}}
62
62
 
63
63
  # Ask a question
64
- overstory mail send --to {{PARENT_AGENT}} --subject "question" \
64
+ ov mail send --to {{PARENT_AGENT}} --subject "question" \
65
65
  --body "Your question here" --type question --priority high --agent {{AGENT_NAME}}
66
66
 
67
67
  # Report completion
68
- overstory mail send --to {{PARENT_AGENT}} --subject "done" \
68
+ ov mail send --to {{PARENT_AGENT}} --subject "done" \
69
69
  --body "Summary of what was done" --type result --agent {{AGENT_NAME}}
70
70
 
71
71
  # Reply to a message
72
- overstory mail reply <message-id> --body "Your reply" --agent {{AGENT_NAME}}
72
+ ov mail reply <message-id> --body "Your reply" --agent {{AGENT_NAME}}
73
73
  ```
74
74
 
75
75
  ## Spawning Sub-Workers