@os-eco/overstory-cli 0.6.1
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/LICENSE +21 -0
- package/README.md +381 -0
- package/agents/builder.md +137 -0
- package/agents/coordinator.md +263 -0
- package/agents/lead.md +301 -0
- package/agents/merger.md +160 -0
- package/agents/monitor.md +214 -0
- package/agents/reviewer.md +140 -0
- package/agents/scout.md +119 -0
- package/agents/supervisor.md +423 -0
- package/package.json +47 -0
- package/src/agents/checkpoint.test.ts +88 -0
- package/src/agents/checkpoint.ts +101 -0
- package/src/agents/hooks-deployer.test.ts +2040 -0
- package/src/agents/hooks-deployer.ts +607 -0
- package/src/agents/identity.test.ts +603 -0
- package/src/agents/identity.ts +384 -0
- package/src/agents/lifecycle.test.ts +196 -0
- package/src/agents/lifecycle.ts +183 -0
- package/src/agents/manifest.test.ts +746 -0
- package/src/agents/manifest.ts +354 -0
- package/src/agents/overlay.test.ts +676 -0
- package/src/agents/overlay.ts +308 -0
- package/src/beads/client.test.ts +217 -0
- package/src/beads/client.ts +202 -0
- package/src/beads/molecules.test.ts +338 -0
- package/src/beads/molecules.ts +198 -0
- package/src/commands/agents.test.ts +322 -0
- package/src/commands/agents.ts +287 -0
- package/src/commands/clean.test.ts +670 -0
- package/src/commands/clean.ts +618 -0
- package/src/commands/completions.test.ts +342 -0
- package/src/commands/completions.ts +887 -0
- package/src/commands/coordinator.test.ts +1530 -0
- package/src/commands/coordinator.ts +733 -0
- package/src/commands/costs.test.ts +1119 -0
- package/src/commands/costs.ts +564 -0
- package/src/commands/dashboard.test.ts +308 -0
- package/src/commands/dashboard.ts +838 -0
- package/src/commands/doctor.test.ts +294 -0
- package/src/commands/doctor.ts +213 -0
- package/src/commands/errors.test.ts +647 -0
- package/src/commands/errors.ts +248 -0
- package/src/commands/feed.test.ts +578 -0
- package/src/commands/feed.ts +361 -0
- package/src/commands/group.test.ts +262 -0
- package/src/commands/group.ts +511 -0
- package/src/commands/hooks.test.ts +458 -0
- package/src/commands/hooks.ts +253 -0
- package/src/commands/init.test.ts +347 -0
- package/src/commands/init.ts +650 -0
- package/src/commands/inspect.test.ts +670 -0
- package/src/commands/inspect.ts +431 -0
- package/src/commands/log.test.ts +1454 -0
- package/src/commands/log.ts +724 -0
- package/src/commands/logs.test.ts +379 -0
- package/src/commands/logs.ts +546 -0
- package/src/commands/mail.test.ts +1270 -0
- package/src/commands/mail.ts +771 -0
- package/src/commands/merge.test.ts +670 -0
- package/src/commands/merge.ts +355 -0
- package/src/commands/metrics.test.ts +444 -0
- package/src/commands/metrics.ts +143 -0
- package/src/commands/monitor.test.ts +191 -0
- package/src/commands/monitor.ts +390 -0
- package/src/commands/nudge.test.ts +230 -0
- package/src/commands/nudge.ts +372 -0
- package/src/commands/prime.test.ts +470 -0
- package/src/commands/prime.ts +381 -0
- package/src/commands/replay.test.ts +741 -0
- package/src/commands/replay.ts +360 -0
- package/src/commands/run.test.ts +431 -0
- package/src/commands/run.ts +351 -0
- package/src/commands/sling.test.ts +657 -0
- package/src/commands/sling.ts +661 -0
- package/src/commands/spec.test.ts +203 -0
- package/src/commands/spec.ts +168 -0
- package/src/commands/status.test.ts +430 -0
- package/src/commands/status.ts +398 -0
- package/src/commands/stop.test.ts +420 -0
- package/src/commands/stop.ts +151 -0
- package/src/commands/supervisor.test.ts +187 -0
- package/src/commands/supervisor.ts +535 -0
- package/src/commands/trace.test.ts +745 -0
- package/src/commands/trace.ts +325 -0
- package/src/commands/watch.test.ts +145 -0
- package/src/commands/watch.ts +247 -0
- package/src/commands/worktree.test.ts +786 -0
- package/src/commands/worktree.ts +311 -0
- package/src/config.test.ts +822 -0
- package/src/config.ts +829 -0
- package/src/doctor/agents.test.ts +454 -0
- package/src/doctor/agents.ts +396 -0
- package/src/doctor/config-check.test.ts +190 -0
- package/src/doctor/config-check.ts +183 -0
- package/src/doctor/consistency.test.ts +651 -0
- package/src/doctor/consistency.ts +294 -0
- package/src/doctor/databases.test.ts +290 -0
- package/src/doctor/databases.ts +218 -0
- package/src/doctor/dependencies.test.ts +184 -0
- package/src/doctor/dependencies.ts +175 -0
- package/src/doctor/logs.test.ts +251 -0
- package/src/doctor/logs.ts +295 -0
- package/src/doctor/merge-queue.test.ts +216 -0
- package/src/doctor/merge-queue.ts +144 -0
- package/src/doctor/structure.test.ts +291 -0
- package/src/doctor/structure.ts +198 -0
- package/src/doctor/types.ts +37 -0
- package/src/doctor/version.test.ts +136 -0
- package/src/doctor/version.ts +129 -0
- package/src/e2e/init-sling-lifecycle.test.ts +277 -0
- package/src/errors.ts +217 -0
- package/src/events/store.test.ts +660 -0
- package/src/events/store.ts +369 -0
- package/src/events/tool-filter.test.ts +330 -0
- package/src/events/tool-filter.ts +126 -0
- package/src/index.ts +316 -0
- package/src/insights/analyzer.test.ts +466 -0
- package/src/insights/analyzer.ts +203 -0
- package/src/logging/color.test.ts +142 -0
- package/src/logging/color.ts +71 -0
- package/src/logging/logger.test.ts +813 -0
- package/src/logging/logger.ts +266 -0
- package/src/logging/reporter.test.ts +259 -0
- package/src/logging/reporter.ts +109 -0
- package/src/logging/sanitizer.test.ts +190 -0
- package/src/logging/sanitizer.ts +57 -0
- package/src/mail/broadcast.test.ts +203 -0
- package/src/mail/broadcast.ts +92 -0
- package/src/mail/client.test.ts +773 -0
- package/src/mail/client.ts +223 -0
- package/src/mail/store.test.ts +705 -0
- package/src/mail/store.ts +387 -0
- package/src/merge/queue.test.ts +359 -0
- package/src/merge/queue.ts +231 -0
- package/src/merge/resolver.test.ts +1345 -0
- package/src/merge/resolver.ts +645 -0
- package/src/metrics/store.test.ts +667 -0
- package/src/metrics/store.ts +445 -0
- package/src/metrics/summary.test.ts +398 -0
- package/src/metrics/summary.ts +178 -0
- package/src/metrics/transcript.test.ts +356 -0
- package/src/metrics/transcript.ts +175 -0
- package/src/mulch/client.test.ts +671 -0
- package/src/mulch/client.ts +332 -0
- package/src/sessions/compat.test.ts +280 -0
- package/src/sessions/compat.ts +104 -0
- package/src/sessions/store.test.ts +873 -0
- package/src/sessions/store.ts +494 -0
- package/src/test-helpers.test.ts +124 -0
- package/src/test-helpers.ts +126 -0
- package/src/tracker/beads.ts +56 -0
- package/src/tracker/factory.test.ts +80 -0
- package/src/tracker/factory.ts +64 -0
- package/src/tracker/seeds.ts +182 -0
- package/src/tracker/types.ts +52 -0
- package/src/types.ts +724 -0
- package/src/watchdog/daemon.test.ts +1975 -0
- package/src/watchdog/daemon.ts +671 -0
- package/src/watchdog/health.test.ts +431 -0
- package/src/watchdog/health.ts +264 -0
- package/src/watchdog/triage.test.ts +164 -0
- package/src/watchdog/triage.ts +179 -0
- package/src/worktree/manager.test.ts +439 -0
- package/src/worktree/manager.ts +198 -0
- package/src/worktree/tmux.test.ts +1009 -0
- package/src/worktree/tmux.ts +509 -0
- package/templates/CLAUDE.md.tmpl +89 -0
- package/templates/hooks.json.tmpl +105 -0
- package/templates/overlay.md.tmpl +81 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
|
|
4
|
+
// Resolve the project root from this file's location (src/logging/ -> project root)
|
|
5
|
+
const projectRoot = join(dirname(import.meta.dir), "..");
|
|
6
|
+
|
|
7
|
+
describe("color module", () => {
|
|
8
|
+
// Test via subprocess to control env vars at import time
|
|
9
|
+
|
|
10
|
+
test("colors enabled by default (no env vars)", async () => {
|
|
11
|
+
const proc = Bun.spawn(
|
|
12
|
+
[
|
|
13
|
+
"bun",
|
|
14
|
+
"-e",
|
|
15
|
+
'import { color, colorsEnabled } from "./src/logging/color.ts"; console.log(JSON.stringify({ colorsEnabled, reset: color.reset }))',
|
|
16
|
+
],
|
|
17
|
+
{
|
|
18
|
+
cwd: projectRoot,
|
|
19
|
+
stdout: "pipe",
|
|
20
|
+
stderr: "pipe",
|
|
21
|
+
env: { ...process.env, NO_COLOR: undefined, FORCE_COLOR: undefined, TERM: undefined },
|
|
22
|
+
},
|
|
23
|
+
);
|
|
24
|
+
await proc.exited;
|
|
25
|
+
const output = await new Response(proc.stdout).text();
|
|
26
|
+
const result = JSON.parse(output.trim());
|
|
27
|
+
expect(result.colorsEnabled).toBe(true);
|
|
28
|
+
expect(result.reset).toBe("\x1b[0m");
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test("NO_COLOR disables colors", async () => {
|
|
32
|
+
const proc = Bun.spawn(
|
|
33
|
+
[
|
|
34
|
+
"bun",
|
|
35
|
+
"-e",
|
|
36
|
+
'import { color, colorsEnabled } from "./src/logging/color.ts"; console.log(JSON.stringify({ colorsEnabled, reset: color.reset }))',
|
|
37
|
+
],
|
|
38
|
+
{
|
|
39
|
+
cwd: projectRoot,
|
|
40
|
+
stdout: "pipe",
|
|
41
|
+
stderr: "pipe",
|
|
42
|
+
env: { ...process.env, NO_COLOR: "1", FORCE_COLOR: undefined },
|
|
43
|
+
},
|
|
44
|
+
);
|
|
45
|
+
await proc.exited;
|
|
46
|
+
const output = await new Response(proc.stdout).text();
|
|
47
|
+
const result = JSON.parse(output.trim());
|
|
48
|
+
expect(result.colorsEnabled).toBe(false);
|
|
49
|
+
expect(result.reset).toBe("");
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test("TERM=dumb disables colors", async () => {
|
|
53
|
+
const proc = Bun.spawn(
|
|
54
|
+
[
|
|
55
|
+
"bun",
|
|
56
|
+
"-e",
|
|
57
|
+
'import { color, colorsEnabled } from "./src/logging/color.ts"; console.log(JSON.stringify({ colorsEnabled, reset: color.reset }))',
|
|
58
|
+
],
|
|
59
|
+
{
|
|
60
|
+
cwd: projectRoot,
|
|
61
|
+
stdout: "pipe",
|
|
62
|
+
stderr: "pipe",
|
|
63
|
+
env: { ...process.env, TERM: "dumb", NO_COLOR: undefined, FORCE_COLOR: undefined },
|
|
64
|
+
},
|
|
65
|
+
);
|
|
66
|
+
await proc.exited;
|
|
67
|
+
const output = await new Response(proc.stdout).text();
|
|
68
|
+
const result = JSON.parse(output.trim());
|
|
69
|
+
expect(result.colorsEnabled).toBe(false);
|
|
70
|
+
expect(result.reset).toBe("");
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test("FORCE_COLOR overrides NO_COLOR", async () => {
|
|
74
|
+
const proc = Bun.spawn(
|
|
75
|
+
[
|
|
76
|
+
"bun",
|
|
77
|
+
"-e",
|
|
78
|
+
'import { color, colorsEnabled } from "./src/logging/color.ts"; console.log(JSON.stringify({ colorsEnabled, reset: color.reset }))',
|
|
79
|
+
],
|
|
80
|
+
{
|
|
81
|
+
cwd: projectRoot,
|
|
82
|
+
stdout: "pipe",
|
|
83
|
+
stderr: "pipe",
|
|
84
|
+
env: { ...process.env, NO_COLOR: "1", FORCE_COLOR: "1" },
|
|
85
|
+
},
|
|
86
|
+
);
|
|
87
|
+
await proc.exited;
|
|
88
|
+
const output = await new Response(proc.stdout).text();
|
|
89
|
+
const result = JSON.parse(output.trim());
|
|
90
|
+
expect(result.colorsEnabled).toBe(true);
|
|
91
|
+
expect(result.reset).toBe("\x1b[0m");
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
test("FORCE_COLOR=0 disables colors", async () => {
|
|
95
|
+
const proc = Bun.spawn(
|
|
96
|
+
[
|
|
97
|
+
"bun",
|
|
98
|
+
"-e",
|
|
99
|
+
'import { color, colorsEnabled } from "./src/logging/color.ts"; console.log(JSON.stringify({ colorsEnabled, reset: color.reset }))',
|
|
100
|
+
],
|
|
101
|
+
{
|
|
102
|
+
cwd: projectRoot,
|
|
103
|
+
stdout: "pipe",
|
|
104
|
+
stderr: "pipe",
|
|
105
|
+
env: { ...process.env, FORCE_COLOR: "0", NO_COLOR: undefined },
|
|
106
|
+
},
|
|
107
|
+
);
|
|
108
|
+
await proc.exited;
|
|
109
|
+
const output = await new Response(proc.stdout).text();
|
|
110
|
+
const result = JSON.parse(output.trim());
|
|
111
|
+
expect(result.colorsEnabled).toBe(false);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test("setQuiet/isQuiet controls quiet mode", async () => {
|
|
115
|
+
const { isQuiet, setQuiet } = await import("./color.ts");
|
|
116
|
+
expect(isQuiet()).toBe(false);
|
|
117
|
+
setQuiet(true);
|
|
118
|
+
expect(isQuiet()).toBe(true);
|
|
119
|
+
setQuiet(false);
|
|
120
|
+
expect(isQuiet()).toBe(false);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
test("all color keys present", async () => {
|
|
124
|
+
const { color } = await import("./color.ts");
|
|
125
|
+
const expectedKeys = [
|
|
126
|
+
"reset",
|
|
127
|
+
"bold",
|
|
128
|
+
"dim",
|
|
129
|
+
"red",
|
|
130
|
+
"green",
|
|
131
|
+
"yellow",
|
|
132
|
+
"blue",
|
|
133
|
+
"magenta",
|
|
134
|
+
"cyan",
|
|
135
|
+
"white",
|
|
136
|
+
"gray",
|
|
137
|
+
];
|
|
138
|
+
for (const key of expectedKeys) {
|
|
139
|
+
expect(key in color).toBe(true);
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
});
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Central ANSI color and output control.
|
|
3
|
+
*
|
|
4
|
+
* Respects the NO_COLOR convention (https://no-color.org/):
|
|
5
|
+
* - When NO_COLOR env var is set (any value), all color codes become empty strings
|
|
6
|
+
* - When TERM=dumb, colors are disabled
|
|
7
|
+
* - When FORCE_COLOR is set to a truthy value, colors are forced on
|
|
8
|
+
*
|
|
9
|
+
* Also provides --quiet support: when quiet mode is enabled, non-error
|
|
10
|
+
* output is suppressed. Commands check isQuiet() before writing to stdout.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Priority order for color detection:
|
|
15
|
+
* 1. FORCE_COLOR (highest) — set to non-"0" to force colors on
|
|
16
|
+
* 2. NO_COLOR — any value disables colors
|
|
17
|
+
* 3. TERM=dumb — disables colors
|
|
18
|
+
* 4. Default: colors enabled
|
|
19
|
+
*/
|
|
20
|
+
function shouldUseColor(): boolean {
|
|
21
|
+
if (process.env.FORCE_COLOR !== undefined) {
|
|
22
|
+
return process.env.FORCE_COLOR !== "0";
|
|
23
|
+
}
|
|
24
|
+
if (process.env.NO_COLOR !== undefined) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
if (process.env.TERM === "dumb") {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const useColor = shouldUseColor();
|
|
34
|
+
|
|
35
|
+
function code(ansiCode: string): string {
|
|
36
|
+
return useColor ? ansiCode : "";
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* ANSI color codes that respect NO_COLOR.
|
|
41
|
+
* When colors are disabled, all values are empty strings.
|
|
42
|
+
*/
|
|
43
|
+
export const color = {
|
|
44
|
+
reset: code("\x1b[0m"),
|
|
45
|
+
bold: code("\x1b[1m"),
|
|
46
|
+
dim: code("\x1b[2m"),
|
|
47
|
+
red: code("\x1b[31m"),
|
|
48
|
+
green: code("\x1b[32m"),
|
|
49
|
+
yellow: code("\x1b[33m"),
|
|
50
|
+
blue: code("\x1b[34m"),
|
|
51
|
+
magenta: code("\x1b[35m"),
|
|
52
|
+
cyan: code("\x1b[36m"),
|
|
53
|
+
white: code("\x1b[37m"),
|
|
54
|
+
gray: code("\x1b[90m"),
|
|
55
|
+
} as const;
|
|
56
|
+
|
|
57
|
+
/** Whether ANSI colors are currently enabled. */
|
|
58
|
+
export const colorsEnabled = useColor;
|
|
59
|
+
|
|
60
|
+
// --- Quiet mode ---
|
|
61
|
+
let quietMode = false;
|
|
62
|
+
|
|
63
|
+
/** Enable quiet mode (suppress non-error output). */
|
|
64
|
+
export function setQuiet(enabled: boolean): void {
|
|
65
|
+
quietMode = enabled;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Check if quiet mode is active. */
|
|
69
|
+
export function isQuiet(): boolean {
|
|
70
|
+
return quietMode;
|
|
71
|
+
}
|