@katyella/legio 0.1.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/CHANGELOG.md +422 -0
- package/LICENSE +21 -0
- package/README.md +555 -0
- package/agents/builder.md +141 -0
- package/agents/coordinator.md +351 -0
- package/agents/cto.md +196 -0
- package/agents/gateway.md +276 -0
- package/agents/lead.md +281 -0
- package/agents/merger.md +156 -0
- package/agents/monitor.md +212 -0
- package/agents/reviewer.md +142 -0
- package/agents/scout.md +131 -0
- package/agents/supervisor.md +416 -0
- package/bin/legio.mjs +38 -0
- package/package.json +77 -0
- package/src/agents/checkpoint.test.ts +88 -0
- package/src/agents/checkpoint.ts +102 -0
- package/src/agents/hooks-deployer.test.ts +1820 -0
- package/src/agents/hooks-deployer.ts +574 -0
- package/src/agents/identity.test.ts +614 -0
- package/src/agents/identity.ts +385 -0
- package/src/agents/lifecycle.test.ts +202 -0
- package/src/agents/lifecycle.ts +184 -0
- package/src/agents/manifest.test.ts +558 -0
- package/src/agents/manifest.ts +297 -0
- package/src/agents/overlay.test.ts +592 -0
- package/src/agents/overlay.ts +316 -0
- package/src/beads/client.test.ts +210 -0
- package/src/beads/client.ts +227 -0
- package/src/beads/molecules.test.ts +320 -0
- package/src/beads/molecules.ts +209 -0
- package/src/commands/agents.test.ts +325 -0
- package/src/commands/agents.ts +286 -0
- package/src/commands/clean.test.ts +730 -0
- package/src/commands/clean.ts +653 -0
- package/src/commands/completions.test.ts +346 -0
- package/src/commands/completions.ts +950 -0
- package/src/commands/coordinator.test.ts +1524 -0
- package/src/commands/coordinator.ts +880 -0
- package/src/commands/costs.test.ts +1015 -0
- package/src/commands/costs.ts +473 -0
- package/src/commands/dashboard.test.ts +94 -0
- package/src/commands/dashboard.ts +607 -0
- package/src/commands/doctor.test.ts +295 -0
- package/src/commands/doctor.ts +213 -0
- package/src/commands/down.test.ts +308 -0
- package/src/commands/down.ts +124 -0
- package/src/commands/errors.test.ts +648 -0
- package/src/commands/errors.ts +255 -0
- package/src/commands/feed.test.ts +579 -0
- package/src/commands/feed.ts +368 -0
- package/src/commands/gateway.test.ts +698 -0
- package/src/commands/gateway.ts +419 -0
- package/src/commands/group.test.ts +262 -0
- package/src/commands/group.ts +539 -0
- package/src/commands/hooks.test.ts +292 -0
- package/src/commands/hooks.ts +210 -0
- package/src/commands/init.test.ts +211 -0
- package/src/commands/init.ts +622 -0
- package/src/commands/inspect.test.ts +670 -0
- package/src/commands/inspect.ts +455 -0
- package/src/commands/log.test.ts +1556 -0
- package/src/commands/log.ts +752 -0
- package/src/commands/logs.test.ts +379 -0
- package/src/commands/logs.ts +544 -0
- package/src/commands/mail.test.ts +1726 -0
- package/src/commands/mail.ts +926 -0
- package/src/commands/merge.test.ts +676 -0
- package/src/commands/merge.ts +374 -0
- package/src/commands/metrics.test.ts +444 -0
- package/src/commands/metrics.ts +150 -0
- package/src/commands/monitor.test.ts +151 -0
- package/src/commands/monitor.ts +394 -0
- package/src/commands/nudge.test.ts +230 -0
- package/src/commands/nudge.ts +373 -0
- package/src/commands/prime.test.ts +467 -0
- package/src/commands/prime.ts +386 -0
- package/src/commands/replay.test.ts +742 -0
- package/src/commands/replay.ts +367 -0
- package/src/commands/run.test.ts +443 -0
- package/src/commands/run.ts +365 -0
- package/src/commands/server.test.ts +626 -0
- package/src/commands/server.ts +298 -0
- package/src/commands/sling.test.ts +810 -0
- package/src/commands/sling.ts +700 -0
- package/src/commands/spec.test.ts +206 -0
- package/src/commands/spec.ts +171 -0
- package/src/commands/status.test.ts +276 -0
- package/src/commands/status.ts +339 -0
- package/src/commands/stop.test.ts +357 -0
- package/src/commands/stop.ts +119 -0
- package/src/commands/supervisor.test.ts +186 -0
- package/src/commands/supervisor.ts +544 -0
- package/src/commands/trace.test.ts +746 -0
- package/src/commands/trace.ts +332 -0
- package/src/commands/up.test.ts +597 -0
- package/src/commands/up.ts +275 -0
- package/src/commands/watch.test.ts +152 -0
- package/src/commands/watch.ts +238 -0
- package/src/commands/worktree.test.ts +648 -0
- package/src/commands/worktree.ts +266 -0
- package/src/config.test.ts +496 -0
- package/src/config.ts +616 -0
- package/src/doctor/agents.test.ts +448 -0
- package/src/doctor/agents.ts +396 -0
- package/src/doctor/config-check.test.ts +184 -0
- package/src/doctor/config-check.ts +185 -0
- package/src/doctor/consistency.test.ts +645 -0
- package/src/doctor/consistency.ts +294 -0
- package/src/doctor/databases.test.ts +284 -0
- package/src/doctor/databases.ts +211 -0
- package/src/doctor/dependencies.test.ts +150 -0
- package/src/doctor/dependencies.ts +179 -0
- package/src/doctor/logs.test.ts +244 -0
- package/src/doctor/logs.ts +295 -0
- package/src/doctor/merge-queue.test.ts +210 -0
- package/src/doctor/merge-queue.ts +144 -0
- package/src/doctor/structure.test.ts +285 -0
- package/src/doctor/structure.ts +195 -0
- package/src/doctor/types.ts +37 -0
- package/src/doctor/version.test.ts +130 -0
- package/src/doctor/version.ts +131 -0
- package/src/e2e/chat-flow.test.ts +346 -0
- package/src/e2e/init-sling-lifecycle.test.ts +288 -0
- package/src/errors.test.ts +21 -0
- package/src/errors.ts +246 -0
- package/src/events/store.test.ts +660 -0
- package/src/events/store.ts +344 -0
- package/src/events/tool-filter.test.ts +330 -0
- package/src/events/tool-filter.ts +126 -0
- package/src/global-setup.ts +14 -0
- package/src/index.ts +339 -0
- package/src/insights/analyzer.test.ts +466 -0
- package/src/insights/analyzer.ts +203 -0
- package/src/logging/color.test.ts +118 -0
- package/src/logging/color.ts +71 -0
- package/src/logging/logger.test.ts +812 -0
- package/src/logging/logger.ts +266 -0
- package/src/logging/reporter.test.ts +258 -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 +873 -0
- package/src/mail/client.ts +236 -0
- package/src/mail/store.test.ts +815 -0
- package/src/mail/store.ts +402 -0
- package/src/merge/queue.test.ts +449 -0
- package/src/merge/queue.ts +262 -0
- package/src/merge/resolver.test.ts +1453 -0
- package/src/merge/resolver.ts +759 -0
- package/src/metrics/store.test.ts +1167 -0
- package/src/metrics/store.ts +511 -0
- package/src/metrics/summary.test.ts +397 -0
- package/src/metrics/summary.ts +178 -0
- package/src/metrics/transcript.test.ts +643 -0
- package/src/metrics/transcript.ts +351 -0
- package/src/mulch/client.test.ts +547 -0
- package/src/mulch/client.ts +416 -0
- package/src/server/audit-store.test.ts +384 -0
- package/src/server/audit-store.ts +257 -0
- package/src/server/headless.test.ts +180 -0
- package/src/server/headless.ts +151 -0
- package/src/server/index.test.ts +241 -0
- package/src/server/index.ts +317 -0
- package/src/server/public/app.js +187 -0
- package/src/server/public/apple-touch-icon.png +0 -0
- package/src/server/public/components/agent-badge.js +37 -0
- package/src/server/public/components/data-table.js +114 -0
- package/src/server/public/components/gateway-chat.js +256 -0
- package/src/server/public/components/issue-card.js +96 -0
- package/src/server/public/components/layout.js +88 -0
- package/src/server/public/components/message-bubble.js +120 -0
- package/src/server/public/components/stat-card.js +26 -0
- package/src/server/public/components/terminal-panel.js +140 -0
- package/src/server/public/favicon-16.png +0 -0
- package/src/server/public/favicon-32.png +0 -0
- package/src/server/public/favicon.ico +0 -0
- package/src/server/public/favicon.png +0 -0
- package/src/server/public/index.html +64 -0
- package/src/server/public/lib/api.js +35 -0
- package/src/server/public/lib/markdown.js +8 -0
- package/src/server/public/lib/preact-setup.js +8 -0
- package/src/server/public/lib/state.js +99 -0
- package/src/server/public/lib/utils.js +309 -0
- package/src/server/public/lib/ws.js +79 -0
- package/src/server/public/views/chat.js +983 -0
- package/src/server/public/views/costs.js +692 -0
- package/src/server/public/views/dashboard.js +781 -0
- package/src/server/public/views/gateway-chat.js +622 -0
- package/src/server/public/views/inspect.js +399 -0
- package/src/server/public/views/issues.js +470 -0
- package/src/server/public/views/setup.js +94 -0
- package/src/server/public/views/task-detail.js +422 -0
- package/src/server/routes.test.ts +3816 -0
- package/src/server/routes.ts +1964 -0
- package/src/server/websocket.test.ts +288 -0
- package/src/server/websocket.ts +196 -0
- package/src/sessions/compat.test.ts +109 -0
- package/src/sessions/compat.ts +17 -0
- package/src/sessions/store.test.ts +969 -0
- package/src/sessions/store.ts +480 -0
- package/src/test-helpers.test.ts +97 -0
- package/src/test-helpers.ts +143 -0
- package/src/types.ts +708 -0
- package/src/watchdog/daemon.test.ts +1233 -0
- package/src/watchdog/daemon.ts +533 -0
- package/src/watchdog/health.test.ts +371 -0
- package/src/watchdog/health.ts +248 -0
- package/src/watchdog/triage.test.ts +162 -0
- package/src/watchdog/triage.ts +193 -0
- package/src/worktree/manager.test.ts +444 -0
- package/src/worktree/manager.ts +224 -0
- package/src/worktree/tmux.test.ts +1238 -0
- package/src/worktree/tmux.ts +644 -0
- package/templates/CLAUDE.md.tmpl +89 -0
- package/templates/hooks.json.tmpl +132 -0
- package/templates/overlay.md.tmpl +79 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { describe, expect, test } from "vitest";
|
|
4
|
+
|
|
5
|
+
// Resolve the project root from this file's location (src/logging/ -> project root)
|
|
6
|
+
const projectRoot = join(dirname(import.meta.dirname), "..");
|
|
7
|
+
|
|
8
|
+
function makeEnv(overrides: Record<string, string | undefined>): Record<string, string> {
|
|
9
|
+
const merged = { ...process.env, ...overrides };
|
|
10
|
+
return Object.fromEntries(Object.entries(merged).filter(([, v]) => v !== undefined)) as Record<
|
|
11
|
+
string,
|
|
12
|
+
string
|
|
13
|
+
>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async function runBun(
|
|
17
|
+
code: string,
|
|
18
|
+
envOverrides: Record<string, string | undefined>,
|
|
19
|
+
): Promise<string> {
|
|
20
|
+
return new Promise((resolve, reject) => {
|
|
21
|
+
const proc = spawn("node", ["-e", code], {
|
|
22
|
+
cwd: projectRoot,
|
|
23
|
+
env: makeEnv(envOverrides),
|
|
24
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
25
|
+
});
|
|
26
|
+
let stdout = "";
|
|
27
|
+
proc.stdout?.on("data", (chunk: Buffer) => {
|
|
28
|
+
stdout += chunk.toString();
|
|
29
|
+
});
|
|
30
|
+
proc.on("close", () => resolve(stdout));
|
|
31
|
+
proc.on("error", reject);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
describe("color module", () => {
|
|
36
|
+
// Test via subprocess to control env vars at import time
|
|
37
|
+
|
|
38
|
+
test("colors enabled by default (no env vars)", async () => {
|
|
39
|
+
const code =
|
|
40
|
+
'import { color, colorsEnabled } from "./src/logging/color.ts"; console.log(JSON.stringify({ colorsEnabled, reset: color.reset }))';
|
|
41
|
+
const output = await runBun(code, {
|
|
42
|
+
NO_COLOR: undefined,
|
|
43
|
+
FORCE_COLOR: undefined,
|
|
44
|
+
TERM: undefined,
|
|
45
|
+
});
|
|
46
|
+
const result = JSON.parse(output.trim());
|
|
47
|
+
expect(result.colorsEnabled).toBe(true);
|
|
48
|
+
expect(result.reset).toBe("\x1b[0m");
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test("NO_COLOR disables colors", async () => {
|
|
52
|
+
const code =
|
|
53
|
+
'import { color, colorsEnabled } from "./src/logging/color.ts"; console.log(JSON.stringify({ colorsEnabled, reset: color.reset }))';
|
|
54
|
+
const output = await runBun(code, { NO_COLOR: "1", FORCE_COLOR: undefined });
|
|
55
|
+
const result = JSON.parse(output.trim());
|
|
56
|
+
expect(result.colorsEnabled).toBe(false);
|
|
57
|
+
expect(result.reset).toBe("");
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test("TERM=dumb disables colors", async () => {
|
|
61
|
+
const code =
|
|
62
|
+
'import { color, colorsEnabled } from "./src/logging/color.ts"; console.log(JSON.stringify({ colorsEnabled, reset: color.reset }))';
|
|
63
|
+
const output = await runBun(code, {
|
|
64
|
+
TERM: "dumb",
|
|
65
|
+
NO_COLOR: undefined,
|
|
66
|
+
FORCE_COLOR: undefined,
|
|
67
|
+
});
|
|
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 code =
|
|
75
|
+
'import { color, colorsEnabled } from "./src/logging/color.ts"; console.log(JSON.stringify({ colorsEnabled, reset: color.reset }))';
|
|
76
|
+
const output = await runBun(code, { NO_COLOR: "1", FORCE_COLOR: "1" });
|
|
77
|
+
const result = JSON.parse(output.trim());
|
|
78
|
+
expect(result.colorsEnabled).toBe(true);
|
|
79
|
+
expect(result.reset).toBe("\x1b[0m");
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test("FORCE_COLOR=0 disables colors", async () => {
|
|
83
|
+
const code =
|
|
84
|
+
'import { color, colorsEnabled } from "./src/logging/color.ts"; console.log(JSON.stringify({ colorsEnabled, reset: color.reset }))';
|
|
85
|
+
const output = await runBun(code, { FORCE_COLOR: "0", NO_COLOR: undefined });
|
|
86
|
+
const result = JSON.parse(output.trim());
|
|
87
|
+
expect(result.colorsEnabled).toBe(false);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
test("setQuiet/isQuiet controls quiet mode", async () => {
|
|
91
|
+
const { isQuiet, setQuiet } = await import("./color.ts");
|
|
92
|
+
expect(isQuiet()).toBe(false);
|
|
93
|
+
setQuiet(true);
|
|
94
|
+
expect(isQuiet()).toBe(true);
|
|
95
|
+
setQuiet(false);
|
|
96
|
+
expect(isQuiet()).toBe(false);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
test("all color keys present", async () => {
|
|
100
|
+
const { color } = await import("./color.ts");
|
|
101
|
+
const expectedKeys = [
|
|
102
|
+
"reset",
|
|
103
|
+
"bold",
|
|
104
|
+
"dim",
|
|
105
|
+
"red",
|
|
106
|
+
"green",
|
|
107
|
+
"yellow",
|
|
108
|
+
"blue",
|
|
109
|
+
"magenta",
|
|
110
|
+
"cyan",
|
|
111
|
+
"white",
|
|
112
|
+
"gray",
|
|
113
|
+
];
|
|
114
|
+
for (const key of expectedKeys) {
|
|
115
|
+
expect(key in color).toBe(true);
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
});
|
|
@@ -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
|
+
}
|