@alisio/plugin-swarm 0.0.0-stage → 0.1.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/.agents/agents/swarm-architect.md +20 -0
- package/.agents/agents/swarm-cleaner.md +20 -0
- package/.agents/agents/swarm-coder.md +20 -0
- package/.agents/agents/swarm-hardener.md +20 -0
- package/.agents/agents/swarm-lieutenant.md +20 -0
- package/.agents/agents/swarm-qa.md +20 -0
- package/.agents/agents/swarm-refactorer.md +20 -0
- package/.agents/agents/swarm-specifier.md +20 -0
- package/.agents/skills/swarm-architecture-rules/SKILL.md +43 -0
- package/.agents/skills/swarm-clarification/SKILL.md +42 -0
- package/.agents/skills/swarm-cleaner-metrics/SKILL.md +44 -0
- package/.agents/skills/swarm-engineering-constitution/SKILL.md +44 -0
- package/.agents/skills/swarm-gherkin-spec/SKILL.md +43 -0
- package/.agents/skills/swarm-handoff-protocol/SKILL.md +45 -0
- package/.agents/skills/swarm-lieutenant/SKILL.md +41 -0
- package/.agents/skills/swarm-mutation-hardening/SKILL.md +43 -0
- package/.agents/skills/swarm-qa-acceptance/SKILL.md +42 -0
- package/.agents/skills/swarm-tdd-slice/SKILL.md +44 -0
- package/.agents/skills/swarm-toolchain-profile/SKILL.md +41 -0
- package/LICENSE +21 -0
- package/README.es.md +337 -0
- package/README.md +322 -2
- package/assets/approval-flow.svg +1 -0
- package/assets/architecture.svg +1 -0
- package/assets/audit-states.svg +1 -0
- package/assets/dashboard.css +964 -0
- package/assets/dashboard.html +123 -0
- package/assets/dashboard.js +965 -0
- package/assets/dashboard.svg +1 -0
- package/assets/handoff-sequence.svg +1 -0
- package/assets/pack-pipelines.svg +1 -0
- package/assets/packs/four-pack/pack.json +18 -0
- package/assets/packs/six-pack/pack.json +22 -0
- package/assets/packs/two-pack/pack.json +14 -0
- package/assets/screenshots/dashboard-board-dark.png +0 -0
- package/assets/screenshots/dashboard-board-light.png +0 -0
- package/assets/screenshots/dashboard-documents-diff.png +0 -0
- package/assets/screenshots/dashboard-empty-state.png +0 -0
- package/assets/screenshots/dashboard-phone.png +0 -0
- package/assets/screenshots/dashboard-reject-dialog.png +0 -0
- package/assets/screenshots/dashboard-transcript-tail.png +0 -0
- package/assets/screenshots/dashboard-work-queue.png +0 -0
- package/assets/task-states.svg +1 -0
- package/assets/toolchains/node-ts.json +61 -0
- package/cover.svg +46 -0
- package/dist/adapters/child-session-runner.d.ts +36 -0
- package/dist/adapters/child-session-runner.d.ts.map +1 -0
- package/dist/adapters/child-session-runner.js +156 -0
- package/dist/adapters/child-session-runner.js.map +1 -0
- package/dist/adapters/fs-board-store.d.ts +11 -0
- package/dist/adapters/fs-board-store.d.ts.map +1 -0
- package/dist/adapters/fs-board-store.js +27 -0
- package/dist/adapters/fs-board-store.js.map +1 -0
- package/dist/adapters/fs-handoff-store.d.ts +36 -0
- package/dist/adapters/fs-handoff-store.d.ts.map +1 -0
- package/dist/adapters/fs-handoff-store.js +254 -0
- package/dist/adapters/fs-handoff-store.js.map +1 -0
- package/dist/adapters/fs-task-state-store.d.ts +16 -0
- package/dist/adapters/fs-task-state-store.d.ts.map +1 -0
- package/dist/adapters/fs-task-state-store.js +66 -0
- package/dist/adapters/fs-task-state-store.js.map +1 -0
- package/dist/adapters/git-worktree.d.ts +31 -0
- package/dist/adapters/git-worktree.d.ts.map +1 -0
- package/dist/adapters/git-worktree.js +209 -0
- package/dist/adapters/git-worktree.js.map +1 -0
- package/dist/adapters/process-exec.d.ts +36 -0
- package/dist/adapters/process-exec.d.ts.map +1 -0
- package/dist/adapters/process-exec.js +138 -0
- package/dist/adapters/process-exec.js.map +1 -0
- package/dist/adapters/process-gate-runner.d.ts +39 -0
- package/dist/adapters/process-gate-runner.d.ts.map +1 -0
- package/dist/adapters/process-gate-runner.js +242 -0
- package/dist/adapters/process-gate-runner.js.map +1 -0
- package/dist/adapters/unavailable-runner.d.ts +4 -0
- package/dist/adapters/unavailable-runner.d.ts.map +1 -0
- package/dist/adapters/unavailable-runner.js +12 -0
- package/dist/adapters/unavailable-runner.js.map +1 -0
- package/dist/app/audit.d.ts +23 -0
- package/dist/app/audit.d.ts.map +1 -0
- package/dist/app/audit.js +9 -0
- package/dist/app/audit.js.map +1 -0
- package/dist/app/budget.d.ts +29 -0
- package/dist/app/budget.d.ts.map +1 -0
- package/dist/app/budget.js +78 -0
- package/dist/app/budget.js.map +1 -0
- package/dist/app/chat-store.d.ts +18 -0
- package/dist/app/chat-store.d.ts.map +1 -0
- package/dist/app/chat-store.js +48 -0
- package/dist/app/chat-store.js.map +1 -0
- package/dist/app/documents.d.ts +33 -0
- package/dist/app/documents.d.ts.map +1 -0
- package/dist/app/documents.js +63 -0
- package/dist/app/documents.js.map +1 -0
- package/dist/app/forge.d.ts +106 -0
- package/dist/app/forge.d.ts.map +1 -0
- package/dist/app/forge.js +420 -0
- package/dist/app/forge.js.map +1 -0
- package/dist/app/operator.d.ts +46 -0
- package/dist/app/operator.d.ts.map +1 -0
- package/dist/app/operator.js +168 -0
- package/dist/app/operator.js.map +1 -0
- package/dist/app/pidfile.d.ts +18 -0
- package/dist/app/pidfile.d.ts.map +1 -0
- package/dist/app/pidfile.js +56 -0
- package/dist/app/pidfile.js.map +1 -0
- package/dist/app/project.d.ts +93 -0
- package/dist/app/project.d.ts.map +1 -0
- package/dist/app/project.js +291 -0
- package/dist/app/project.js.map +1 -0
- package/dist/app/prompts.d.ts +48 -0
- package/dist/app/prompts.d.ts.map +1 -0
- package/dist/app/prompts.js +88 -0
- package/dist/app/prompts.js.map +1 -0
- package/dist/app/pump.d.ts +144 -0
- package/dist/app/pump.d.ts.map +1 -0
- package/dist/app/pump.js +707 -0
- package/dist/app/pump.js.map +1 -0
- package/dist/app/services.d.ts +112 -0
- package/dist/app/services.d.ts.map +1 -0
- package/dist/app/services.js +323 -0
- package/dist/app/services.js.map +1 -0
- package/dist/app/state.d.ts +70 -0
- package/dist/app/state.d.ts.map +1 -0
- package/dist/app/state.js +96 -0
- package/dist/app/state.js.map +1 -0
- package/dist/args.d.ts +10 -0
- package/dist/args.d.ts.map +1 -0
- package/dist/args.js +33 -0
- package/dist/args.js.map +1 -0
- package/dist/coordinator.d.ts +80 -0
- package/dist/coordinator.d.ts.map +1 -0
- package/dist/coordinator.js +481 -0
- package/dist/coordinator.js.map +1 -0
- package/dist/dashboard/api.d.ts +28 -0
- package/dist/dashboard/api.d.ts.map +1 -0
- package/dist/dashboard/api.js +178 -0
- package/dist/dashboard/api.js.map +1 -0
- package/dist/dashboard/auth.d.ts +13 -0
- package/dist/dashboard/auth.d.ts.map +1 -0
- package/dist/dashboard/auth.js +36 -0
- package/dist/dashboard/auth.js.map +1 -0
- package/dist/dashboard/open.d.ts +7 -0
- package/dist/dashboard/open.d.ts.map +1 -0
- package/dist/dashboard/open.js +17 -0
- package/dist/dashboard/open.js.map +1 -0
- package/dist/dashboard/server.d.ts +28 -0
- package/dist/dashboard/server.d.ts.map +1 -0
- package/dist/dashboard/server.js +176 -0
- package/dist/dashboard/server.js.map +1 -0
- package/dist/doctor.d.ts +28 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +108 -0
- package/dist/doctor.js.map +1 -0
- package/dist/domain/attention.d.ts +20 -0
- package/dist/domain/attention.d.ts.map +1 -0
- package/dist/domain/attention.js +41 -0
- package/dist/domain/attention.js.map +1 -0
- package/dist/domain/envelope.d.ts +37 -0
- package/dist/domain/envelope.d.ts.map +1 -0
- package/dist/domain/envelope.js +106 -0
- package/dist/domain/envelope.js.map +1 -0
- package/dist/domain/handoff.d.ts +57 -0
- package/dist/domain/handoff.d.ts.map +1 -0
- package/dist/domain/handoff.js +191 -0
- package/dist/domain/handoff.js.map +1 -0
- package/dist/domain/identifiers.d.ts +18 -0
- package/dist/domain/identifiers.d.ts.map +1 -0
- package/dist/domain/identifiers.js +70 -0
- package/dist/domain/identifiers.js.map +1 -0
- package/dist/domain/pack.d.ts +45 -0
- package/dist/domain/pack.d.ts.map +1 -0
- package/dist/domain/pack.js +207 -0
- package/dist/domain/pack.js.map +1 -0
- package/dist/domain/pipeline.d.ts +33 -0
- package/dist/domain/pipeline.d.ts.map +1 -0
- package/dist/domain/pipeline.js +50 -0
- package/dist/domain/pipeline.js.map +1 -0
- package/dist/domain/task.d.ts +26 -0
- package/dist/domain/task.d.ts.map +1 -0
- package/dist/domain/task.js +154 -0
- package/dist/domain/task.js.map +1 -0
- package/dist/domain/taskstate.d.ts +37 -0
- package/dist/domain/taskstate.d.ts.map +1 -0
- package/dist/domain/taskstate.js +98 -0
- package/dist/domain/taskstate.js.map +1 -0
- package/dist/gates/dry.d.ts +14 -0
- package/dist/gates/dry.d.ts.map +1 -0
- package/dist/gates/dry.js +71 -0
- package/dist/gates/dry.js.map +1 -0
- package/dist/gates/parsers.d.ts +34 -0
- package/dist/gates/parsers.d.ts.map +1 -0
- package/dist/gates/parsers.js +120 -0
- package/dist/gates/parsers.js.map +1 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +207 -0
- package/dist/index.js.map +1 -0
- package/dist/options.d.ts +13 -0
- package/dist/options.d.ts.map +1 -0
- package/dist/options.js +27 -0
- package/dist/options.js.map +1 -0
- package/dist/panel.d.ts +5 -0
- package/dist/panel.d.ts.map +1 -0
- package/dist/panel.js +52 -0
- package/dist/panel.js.map +1 -0
- package/dist/ports/agent-runner.d.ts +51 -0
- package/dist/ports/agent-runner.d.ts.map +1 -0
- package/dist/ports/agent-runner.js +2 -0
- package/dist/ports/agent-runner.js.map +1 -0
- package/dist/ports/board-store.d.ts +7 -0
- package/dist/ports/board-store.d.ts.map +1 -0
- package/dist/ports/board-store.js +2 -0
- package/dist/ports/board-store.js.map +1 -0
- package/dist/ports/clock.d.ts +5 -0
- package/dist/ports/clock.d.ts.map +1 -0
- package/dist/ports/clock.js +2 -0
- package/dist/ports/clock.js.map +1 -0
- package/dist/ports/gate-runner.d.ts +34 -0
- package/dist/ports/gate-runner.d.ts.map +1 -0
- package/dist/ports/gate-runner.js +2 -0
- package/dist/ports/gate-runner.js.map +1 -0
- package/dist/ports/handoff-store.d.ts +39 -0
- package/dist/ports/handoff-store.d.ts.map +1 -0
- package/dist/ports/handoff-store.js +2 -0
- package/dist/ports/handoff-store.js.map +1 -0
- package/dist/ports/isolation.d.ts +43 -0
- package/dist/ports/isolation.d.ts.map +1 -0
- package/dist/ports/isolation.js +2 -0
- package/dist/ports/isolation.js.map +1 -0
- package/dist/ports/notifier.d.ts +28 -0
- package/dist/ports/notifier.d.ts.map +1 -0
- package/dist/ports/notifier.js +2 -0
- package/dist/ports/notifier.js.map +1 -0
- package/dist/ports/task-state-store.d.ts +10 -0
- package/dist/ports/task-state-store.d.ts.map +1 -0
- package/dist/ports/task-state-store.js +2 -0
- package/dist/ports/task-state-store.js.map +1 -0
- package/dist/refs.d.ts +10 -0
- package/dist/refs.d.ts.map +1 -0
- package/dist/refs.js +19 -0
- package/dist/refs.js.map +1 -0
- package/dist/resources.d.ts +55 -0
- package/dist/resources.d.ts.map +1 -0
- package/dist/resources.js +255 -0
- package/dist/resources.js.map +1 -0
- package/dist/status.d.ts +18 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +60 -0
- package/dist/status.js.map +1 -0
- package/dist/storage.d.ts +18 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +79 -0
- package/dist/storage.js.map +1 -0
- package/dist/toolchains/profile.d.ts +21 -0
- package/dist/toolchains/profile.d.ts.map +1 -0
- package/dist/toolchains/profile.js +60 -0
- package/dist/toolchains/profile.js.map +1 -0
- package/dist/toolchains/thresholds.d.ts +29 -0
- package/dist/toolchains/thresholds.d.ts.map +1 -0
- package/dist/toolchains/thresholds.js +45 -0
- package/dist/toolchains/thresholds.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/package.json +51 -3
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type ChildProcess } from "node:child_process";
|
|
2
|
+
/** Bounded process execution for gates: argv arrays, timeouts, output caps, scrubbed environment. */
|
|
3
|
+
export interface ExecOptions {
|
|
4
|
+
cwd: string;
|
|
5
|
+
timeoutMs: number;
|
|
6
|
+
/** Maximum bytes kept per stream; a process that exceeds it is killed. */
|
|
7
|
+
maxOutput: number;
|
|
8
|
+
env?: NodeJS.ProcessEnv;
|
|
9
|
+
}
|
|
10
|
+
export interface ExecResult {
|
|
11
|
+
/** `null` when the process never started or was killed by a signal. */
|
|
12
|
+
code: number | null;
|
|
13
|
+
stdout: string;
|
|
14
|
+
stderr: string;
|
|
15
|
+
timedOut: boolean;
|
|
16
|
+
truncated: boolean;
|
|
17
|
+
cancelled?: boolean;
|
|
18
|
+
spawnError?: string;
|
|
19
|
+
}
|
|
20
|
+
export type Exec = (argv: string[], options: ExecOptions) => Promise<ExecResult>;
|
|
21
|
+
/** Only these variables reach gate commands: no tokens, no shell state, no tool configuration. */
|
|
22
|
+
export declare function scrubbedGateEnv(): NodeJS.ProcessEnv;
|
|
23
|
+
/** Tracks running gate processes so close, teardown and dispose can stop them. */
|
|
24
|
+
export declare class ProcessTracker {
|
|
25
|
+
private readonly active;
|
|
26
|
+
get size(): number;
|
|
27
|
+
add(child: ChildProcess, cwd: string): {
|
|
28
|
+
cancelled: boolean;
|
|
29
|
+
cwd: string;
|
|
30
|
+
};
|
|
31
|
+
remove(child: ChildProcess): void;
|
|
32
|
+
/** Kill every tracked process, or only those running under a directory. */
|
|
33
|
+
killAll(under?: string): void;
|
|
34
|
+
}
|
|
35
|
+
export declare function createExec(tracker?: ProcessTracker): Exec;
|
|
36
|
+
//# sourceMappingURL=process-exec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-exec.d.ts","sourceRoot":"","sources":["../../src/adapters/process-exec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAS,MAAM,oBAAoB,CAAC;AAE9D,qGAAqG;AAErG,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,uEAAuE;IACvE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,IAAI,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;AAEjF,kGAAkG;AAClG,wBAAgB,eAAe,IAAI,MAAM,CAAC,UAAU,CAOnD;AAED,kFAAkF;AAClF,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgE;IAEvF,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,GAAG,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,GAAG;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAIzE;IAED,MAAM,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAEhC;IAED,2EAA2E;IAC3E,OAAO,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAM5B;CACF;AAiBD,wBAAgB,UAAU,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,IAAI,CAiFzD"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
/** Only these variables reach gate commands: no tokens, no shell state, no tool configuration. */
|
|
3
|
+
export function scrubbedGateEnv() {
|
|
4
|
+
const env = { CI: "1", NO_COLOR: "1", LANG: "C", LC_ALL: "C" };
|
|
5
|
+
for (const key of ["PATH", "HOME", "TMPDIR", "TEMP", "TMP", "SYSTEMROOT", "COMSPEC"]) {
|
|
6
|
+
const value = process.env[key];
|
|
7
|
+
if (value !== undefined)
|
|
8
|
+
env[key] = value;
|
|
9
|
+
}
|
|
10
|
+
return env;
|
|
11
|
+
}
|
|
12
|
+
/** Tracks running gate processes so close, teardown and dispose can stop them. */
|
|
13
|
+
export class ProcessTracker {
|
|
14
|
+
active = new Map();
|
|
15
|
+
get size() {
|
|
16
|
+
return this.active.size;
|
|
17
|
+
}
|
|
18
|
+
add(child, cwd) {
|
|
19
|
+
const flag = { cancelled: false, cwd };
|
|
20
|
+
this.active.set(child, flag);
|
|
21
|
+
return flag;
|
|
22
|
+
}
|
|
23
|
+
remove(child) {
|
|
24
|
+
this.active.delete(child);
|
|
25
|
+
}
|
|
26
|
+
/** Kill every tracked process, or only those running under a directory. */
|
|
27
|
+
killAll(under) {
|
|
28
|
+
for (const [child, flag] of this.active) {
|
|
29
|
+
if (under !== undefined && flag.cwd !== under && !flag.cwd.startsWith(`${under}/`))
|
|
30
|
+
continue;
|
|
31
|
+
flag.cancelled = true;
|
|
32
|
+
killTree(child);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function killTree(child) {
|
|
37
|
+
if (child.pid === undefined)
|
|
38
|
+
return;
|
|
39
|
+
try {
|
|
40
|
+
// Detached children lead their own process group, so the whole tree (npx, node) goes at once.
|
|
41
|
+
if (process.platform === "win32")
|
|
42
|
+
child.kill("SIGKILL");
|
|
43
|
+
else
|
|
44
|
+
process.kill(-child.pid, "SIGKILL");
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
try {
|
|
48
|
+
child.kill("SIGKILL");
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
// Already gone.
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export function createExec(tracker) {
|
|
56
|
+
return (argv, options) => new Promise((resolvePromise) => {
|
|
57
|
+
const [command, ...args] = argv;
|
|
58
|
+
if (!command) {
|
|
59
|
+
resolvePromise({
|
|
60
|
+
code: null,
|
|
61
|
+
stdout: "",
|
|
62
|
+
stderr: "",
|
|
63
|
+
timedOut: false,
|
|
64
|
+
truncated: false,
|
|
65
|
+
spawnError: "Empty command",
|
|
66
|
+
});
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
let child;
|
|
70
|
+
try {
|
|
71
|
+
child = spawn(command, args, {
|
|
72
|
+
cwd: options.cwd,
|
|
73
|
+
env: options.env ?? scrubbedGateEnv(),
|
|
74
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
75
|
+
detached: process.platform !== "win32",
|
|
76
|
+
windowsHide: true,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
resolvePromise({
|
|
81
|
+
code: null,
|
|
82
|
+
stdout: "",
|
|
83
|
+
stderr: "",
|
|
84
|
+
timedOut: false,
|
|
85
|
+
truncated: false,
|
|
86
|
+
spawnError: error instanceof Error ? error.message : String(error),
|
|
87
|
+
});
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const flag = tracker?.add(child, options.cwd);
|
|
91
|
+
let stdout = "";
|
|
92
|
+
let stderr = "";
|
|
93
|
+
let timedOut = false;
|
|
94
|
+
let truncated = false;
|
|
95
|
+
let spawnError;
|
|
96
|
+
let finished = false;
|
|
97
|
+
const keep = (current, chunk) => {
|
|
98
|
+
const room = options.maxOutput - current.length;
|
|
99
|
+
if (chunk.length > room) {
|
|
100
|
+
truncated = true;
|
|
101
|
+
killTree(child);
|
|
102
|
+
}
|
|
103
|
+
return room > 0 ? current + chunk.toString("utf8", 0, room) : current;
|
|
104
|
+
};
|
|
105
|
+
child.stdout?.on("data", (chunk) => {
|
|
106
|
+
stdout = keep(stdout, chunk);
|
|
107
|
+
});
|
|
108
|
+
child.stderr?.on("data", (chunk) => {
|
|
109
|
+
stderr = keep(stderr, chunk);
|
|
110
|
+
});
|
|
111
|
+
const timer = setTimeout(() => {
|
|
112
|
+
timedOut = true;
|
|
113
|
+
killTree(child);
|
|
114
|
+
}, options.timeoutMs);
|
|
115
|
+
const done = (code) => {
|
|
116
|
+
if (finished)
|
|
117
|
+
return;
|
|
118
|
+
finished = true;
|
|
119
|
+
clearTimeout(timer);
|
|
120
|
+
tracker?.remove(child);
|
|
121
|
+
resolvePromise({
|
|
122
|
+
code,
|
|
123
|
+
stdout,
|
|
124
|
+
stderr,
|
|
125
|
+
timedOut,
|
|
126
|
+
truncated,
|
|
127
|
+
...(flag?.cancelled ? { cancelled: true } : {}),
|
|
128
|
+
...(spawnError ? { spawnError } : {}),
|
|
129
|
+
});
|
|
130
|
+
};
|
|
131
|
+
child.on("error", (error) => {
|
|
132
|
+
spawnError = error.code ?? error.message;
|
|
133
|
+
done(null);
|
|
134
|
+
});
|
|
135
|
+
child.on("close", (code) => done(code));
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=process-exec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-exec.js","sourceRoot":"","sources":["../../src/adapters/process-exec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { GateReport, GateRequest, GateRunner } from "../ports/gate-runner.js";
|
|
2
|
+
import type { CommandName, Toolchain } from "../toolchains/profile.js";
|
|
3
|
+
import { type Exec, ProcessTracker } from "./process-exec.js";
|
|
4
|
+
export interface ProcessGateDeps {
|
|
5
|
+
loadToolchain: (id: string) => Promise<Toolchain>;
|
|
6
|
+
/** Test seam; production uses a bounded `spawn` that never goes through a shell. */
|
|
7
|
+
exec?: Exec;
|
|
8
|
+
tracker?: ProcessTracker;
|
|
9
|
+
/** Read a report file relative to the working directory (contained, never following symlinks out). */
|
|
10
|
+
readFile?: (workdir: string, relative: string) => Promise<string | undefined>;
|
|
11
|
+
/** Per-command timeouts in milliseconds. */
|
|
12
|
+
timeouts?: Partial<Record<CommandName | "git", number>>;
|
|
13
|
+
maxOutput?: number;
|
|
14
|
+
}
|
|
15
|
+
/** Gate runner over the node-ts toolchain profile: argv arrays, timeouts, caps, scrubbed env. */
|
|
16
|
+
export declare class ProcessGateRunner implements GateRunner {
|
|
17
|
+
private readonly deps;
|
|
18
|
+
private readonly tracker;
|
|
19
|
+
private readonly exec;
|
|
20
|
+
private readonly timeouts;
|
|
21
|
+
constructor(deps: ProcessGateDeps);
|
|
22
|
+
cancelAll(under?: string): void;
|
|
23
|
+
run(request: GateRequest): Promise<GateReport>;
|
|
24
|
+
private dispatch;
|
|
25
|
+
private command;
|
|
26
|
+
private run1;
|
|
27
|
+
/** Spawn failures, timeouts, cancellation and runaway output are never a "pass". */
|
|
28
|
+
private abnormal;
|
|
29
|
+
private changedFiles;
|
|
30
|
+
private read;
|
|
31
|
+
private report;
|
|
32
|
+
private testsGreen;
|
|
33
|
+
private testFirst;
|
|
34
|
+
private coverage;
|
|
35
|
+
private crap;
|
|
36
|
+
private dry;
|
|
37
|
+
private mutation;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=process-gate-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-gate-runner.d.ts","sourceRoot":"","sources":["../../src/adapters/process-gate-runner.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAEnF,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAoB,MAAM,0BAA0B,CAAC;AAEzF,OAAO,EAAc,KAAK,IAAI,EAAmB,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAE3F,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;IAClD,oFAAoF;IACpF,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,sGAAsG;IACtG,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAC9E,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,GAAG,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA8BD,iGAAiG;AACjG,qBAAa,iBAAkB,YAAW,UAAU;IAKtC,OAAO,CAAC,QAAQ,CAAC,IAAI;IAJjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAO;IAC5B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsC;IAE/D,YAA6B,IAAI,EAAE,eAAe,EAIjD;IAED,SAAS,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAE9B;IAEK,GAAG,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAanD;IAED,OAAO,CAAC,QAAQ;IA0BhB,OAAO,CAAC,OAAO;IAMf,OAAO,CAAC,IAAI;IAaZ,oFAAoF;IACpF,OAAO,CAAC,QAAQ;YAYF,YAAY;YAoBZ,IAAI;YAKJ,MAAM;YAgBN,UAAU;YAaV,SAAS;YAYT,QAAQ;YAeR,IAAI;YA2BJ,GAAG;YA2BH,QAAQ;CAoBvB"}
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import { detectDuplicates } from "../gates/dry.js";
|
|
2
|
+
import { isSourceFile, isTestFile, parseEslintComplexity, parseIstanbulSummary, parseStrykerReport, toFunctionMetrics, } from "../gates/parsers.js";
|
|
3
|
+
import { readText, resolveContained } from "../storage.js";
|
|
4
|
+
import { evaluateThresholds } from "../toolchains/thresholds.js";
|
|
5
|
+
import { createExec, ProcessTracker } from "./process-exec.js";
|
|
6
|
+
const DEFAULT_TIMEOUTS = {
|
|
7
|
+
test: 300_000,
|
|
8
|
+
coverage: 600_000,
|
|
9
|
+
complexity: 300_000,
|
|
10
|
+
mutation: 1_800_000,
|
|
11
|
+
acceptance: 600_000,
|
|
12
|
+
git: 60_000,
|
|
13
|
+
};
|
|
14
|
+
const MAX_OUTPUT = 4 * 1024 * 1024;
|
|
15
|
+
const MAX_SOURCE_FILES = 500;
|
|
16
|
+
const MAX_SOURCE_BYTES = 200_000;
|
|
17
|
+
const DRY_WINDOW = 6;
|
|
18
|
+
const pass = (extra = {}) => ({ passed: true, findings: [], ...extra });
|
|
19
|
+
const fail = (findings, extra = {}) => ({
|
|
20
|
+
passed: false,
|
|
21
|
+
findings,
|
|
22
|
+
...extra,
|
|
23
|
+
});
|
|
24
|
+
const broken = (error) => ({ passed: false, findings: [error], error });
|
|
25
|
+
function tail(result) {
|
|
26
|
+
const text = `${result.stdout}\n${result.stderr}`.trim().split("\n").slice(-40).join("\n");
|
|
27
|
+
return text.length > 3000 ? text.slice(-3000) : text;
|
|
28
|
+
}
|
|
29
|
+
/** Gate runner over the node-ts toolchain profile: argv arrays, timeouts, caps, scrubbed env. */
|
|
30
|
+
export class ProcessGateRunner {
|
|
31
|
+
deps;
|
|
32
|
+
tracker;
|
|
33
|
+
exec;
|
|
34
|
+
timeouts;
|
|
35
|
+
constructor(deps) {
|
|
36
|
+
this.deps = deps;
|
|
37
|
+
this.tracker = deps.tracker ?? new ProcessTracker();
|
|
38
|
+
this.exec = deps.exec ?? createExec(this.tracker);
|
|
39
|
+
this.timeouts = { ...DEFAULT_TIMEOUTS, ...deps.timeouts };
|
|
40
|
+
}
|
|
41
|
+
cancelAll(under) {
|
|
42
|
+
this.tracker.killAll(under);
|
|
43
|
+
}
|
|
44
|
+
async run(request) {
|
|
45
|
+
const started = Date.now();
|
|
46
|
+
try {
|
|
47
|
+
const toolchain = await this.deps.loadToolchain(request.toolchain);
|
|
48
|
+
const outcome = await this.dispatch(request, toolchain);
|
|
49
|
+
return { gate: request.gate, ...outcome, durationMs: Date.now() - started };
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
return {
|
|
53
|
+
gate: request.gate,
|
|
54
|
+
...broken(error instanceof Error ? error.message : String(error)),
|
|
55
|
+
durationMs: Date.now() - started,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
dispatch(request, toolchain) {
|
|
60
|
+
const gates = {
|
|
61
|
+
"tests-green": () => this.testsGreen(request, toolchain, "test", "Tests"),
|
|
62
|
+
acceptance: () => this.testsGreen(request, toolchain, toolchain.commands.acceptance ? "acceptance" : "test", "Acceptance checks"),
|
|
63
|
+
"test-first": () => this.testFirst(request),
|
|
64
|
+
coverage: () => this.coverage(request, toolchain),
|
|
65
|
+
crap: () => this.crap(request, toolchain),
|
|
66
|
+
dry: () => this.dry(request),
|
|
67
|
+
mutation: () => this.mutation(request, toolchain),
|
|
68
|
+
structure: async () => pass({
|
|
69
|
+
skipped: "There is no deterministic structure checker in this build; the architect role verifies it",
|
|
70
|
+
}),
|
|
71
|
+
};
|
|
72
|
+
return gates[request.gate]();
|
|
73
|
+
}
|
|
74
|
+
// ---- helpers ----
|
|
75
|
+
command(toolchain, name) {
|
|
76
|
+
const command = toolchain.commands[name];
|
|
77
|
+
if (!command)
|
|
78
|
+
throw new Error(`The ${toolchain.id} toolchain has no ${name} command`);
|
|
79
|
+
return command;
|
|
80
|
+
}
|
|
81
|
+
run1(request, name, command, extra = []) {
|
|
82
|
+
return this.exec([...command.argv, ...extra], {
|
|
83
|
+
cwd: request.workdir,
|
|
84
|
+
timeoutMs: this.timeouts[name],
|
|
85
|
+
maxOutput: this.deps.maxOutput ?? MAX_OUTPUT,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
/** Spawn failures, timeouts, cancellation and runaway output are never a "pass". */
|
|
89
|
+
abnormal(result, label, timeoutMs) {
|
|
90
|
+
if (result.cancelled)
|
|
91
|
+
return broken("Gate cancelled");
|
|
92
|
+
if (result.spawnError)
|
|
93
|
+
return broken(`${label} could not start: ${result.spawnError}`);
|
|
94
|
+
if (result.timedOut) {
|
|
95
|
+
return fail([`${label} timed out after ${Math.round(timeoutMs / 1000)} seconds`], {
|
|
96
|
+
timedOut: true,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
if (result.truncated)
|
|
100
|
+
return fail([`${label} produced too much output and was stopped`]);
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
async changedFiles(request) {
|
|
104
|
+
if (!request.since || !/^[0-9a-f]{7,40}$/.test(request.since)) {
|
|
105
|
+
throw new Error("The gate needs the base commit of the role's work");
|
|
106
|
+
}
|
|
107
|
+
const result = await this.exec(["git", "diff", "--name-only", "--diff-filter=ACMR", `${request.since}..HEAD`], {
|
|
108
|
+
cwd: request.workdir,
|
|
109
|
+
timeoutMs: this.timeouts.git,
|
|
110
|
+
maxOutput: this.deps.maxOutput ?? MAX_OUTPUT,
|
|
111
|
+
});
|
|
112
|
+
if (result.code !== 0)
|
|
113
|
+
throw new Error(`git diff failed: ${tail(result) || `exit ${result.code}`}`);
|
|
114
|
+
return result.stdout
|
|
115
|
+
.split("\n")
|
|
116
|
+
.map((line) => line.trim())
|
|
117
|
+
.filter(Boolean);
|
|
118
|
+
}
|
|
119
|
+
async read(request, relative) {
|
|
120
|
+
if (this.deps.readFile)
|
|
121
|
+
return this.deps.readFile(request.workdir, relative);
|
|
122
|
+
return readText(await resolveContained(request.workdir, relative));
|
|
123
|
+
}
|
|
124
|
+
async report(request, command, result, label) {
|
|
125
|
+
if (!command.report)
|
|
126
|
+
return result.stdout;
|
|
127
|
+
const text = await this.read(request, command.report);
|
|
128
|
+
if (text === undefined) {
|
|
129
|
+
throw new Error(`${label} did not produce its report at ${command.report}\n${tail(result)}`);
|
|
130
|
+
}
|
|
131
|
+
return text;
|
|
132
|
+
}
|
|
133
|
+
// ---- gates ----
|
|
134
|
+
async testsGreen(request, toolchain, name, label) {
|
|
135
|
+
const result = await this.run1(request, name, this.command(toolchain, name));
|
|
136
|
+
const abnormal = this.abnormal(result, label, this.timeouts[name]);
|
|
137
|
+
if (abnormal)
|
|
138
|
+
return abnormal;
|
|
139
|
+
if (result.code !== 0)
|
|
140
|
+
return fail([`${label} failed (exit ${result.code})`, tail(result)]);
|
|
141
|
+
return pass();
|
|
142
|
+
}
|
|
143
|
+
async testFirst(request) {
|
|
144
|
+
const changed = await this.changedFiles(request);
|
|
145
|
+
if (changed.length === 0)
|
|
146
|
+
return fail(["The role made no changes since the base commit"]);
|
|
147
|
+
const tests = changed.filter(isTestFile);
|
|
148
|
+
if (tests.length === 0) {
|
|
149
|
+
return fail([
|
|
150
|
+
"No test file is part of the diff: write the failing test first and commit it with the change",
|
|
151
|
+
]);
|
|
152
|
+
}
|
|
153
|
+
return pass();
|
|
154
|
+
}
|
|
155
|
+
async coverage(request, toolchain) {
|
|
156
|
+
const command = this.command(toolchain, "coverage");
|
|
157
|
+
const result = await this.run1(request, "coverage", command);
|
|
158
|
+
const abnormal = this.abnormal(result, "The coverage run", this.timeouts.coverage);
|
|
159
|
+
if (abnormal)
|
|
160
|
+
return abnormal;
|
|
161
|
+
if (result.code !== 0)
|
|
162
|
+
return fail([`The coverage run failed (exit ${result.code})`, tail(result)]);
|
|
163
|
+
const summary = parseIstanbulSummary(await this.report(request, command, result, "The coverage run"), request.workdir);
|
|
164
|
+
const evaluation = evaluateThresholds(request.thresholds, { coverage: summary.coverage });
|
|
165
|
+
return evaluation.passed ? pass() : fail(evaluation.failures.map((f) => f.message));
|
|
166
|
+
}
|
|
167
|
+
async crap(request, toolchain) {
|
|
168
|
+
const changed = (await this.changedFiles(request)).filter(isSourceFile);
|
|
169
|
+
if (changed.length === 0)
|
|
170
|
+
return pass({ skipped: "No changed source files" });
|
|
171
|
+
const coverageCommand = this.command(toolchain, "coverage");
|
|
172
|
+
const coverageRun = await this.run1(request, "coverage", coverageCommand);
|
|
173
|
+
const abnormal = this.abnormal(coverageRun, "The coverage run", this.timeouts.coverage);
|
|
174
|
+
if (abnormal)
|
|
175
|
+
return abnormal;
|
|
176
|
+
if (coverageRun.code !== 0) {
|
|
177
|
+
return fail([`The coverage run failed (exit ${coverageRun.code})`, tail(coverageRun)]);
|
|
178
|
+
}
|
|
179
|
+
const coverage = parseIstanbulSummary(await this.report(request, coverageCommand, coverageRun, "The coverage run"), request.workdir);
|
|
180
|
+
const lint = await this.run1(request, "complexity", this.command(toolchain, "complexity"));
|
|
181
|
+
const lintAbnormal = this.abnormal(lint, "The complexity run", this.timeouts.complexity);
|
|
182
|
+
if (lintAbnormal)
|
|
183
|
+
return lintAbnormal;
|
|
184
|
+
// ESLint exits non-zero whenever it reports a finding: the JSON is what matters.
|
|
185
|
+
const entries = parseEslintComplexity(lint.stdout, request.workdir).filter((entry) => changed.includes(entry.file));
|
|
186
|
+
const evaluation = evaluateThresholds(request.thresholds, {
|
|
187
|
+
functions: toFunctionMetrics(entries, coverage.files),
|
|
188
|
+
});
|
|
189
|
+
return evaluation.passed ? pass() : fail(evaluation.failures.map((f) => f.message));
|
|
190
|
+
}
|
|
191
|
+
async dry(request) {
|
|
192
|
+
const changed = (await this.changedFiles(request)).filter(isSourceFile);
|
|
193
|
+
if (changed.length === 0)
|
|
194
|
+
return pass({ skipped: "No changed source files" });
|
|
195
|
+
const listing = await this.exec(["git", "ls-files"], {
|
|
196
|
+
cwd: request.workdir,
|
|
197
|
+
timeoutMs: this.timeouts.git,
|
|
198
|
+
maxOutput: this.deps.maxOutput ?? MAX_OUTPUT,
|
|
199
|
+
});
|
|
200
|
+
if (listing.code !== 0)
|
|
201
|
+
return broken(`git ls-files failed: ${tail(listing)}`);
|
|
202
|
+
const names = [
|
|
203
|
+
...new Set([
|
|
204
|
+
...listing.stdout
|
|
205
|
+
.split("\n")
|
|
206
|
+
.map((l) => l.trim())
|
|
207
|
+
.filter(isSourceFile),
|
|
208
|
+
...changed,
|
|
209
|
+
]),
|
|
210
|
+
].slice(0, MAX_SOURCE_FILES);
|
|
211
|
+
const sources = [];
|
|
212
|
+
for (const path of names) {
|
|
213
|
+
const text = await this.read(request, path);
|
|
214
|
+
if (text !== undefined && text.length <= MAX_SOURCE_BYTES)
|
|
215
|
+
sources.push({ path, text });
|
|
216
|
+
}
|
|
217
|
+
const findings = detectDuplicates(sources, { window: DRY_WINDOW, only: changed });
|
|
218
|
+
return findings.length === 0 ? pass() : fail(findings);
|
|
219
|
+
}
|
|
220
|
+
async mutation(request, toolchain) {
|
|
221
|
+
const changed = (await this.changedFiles(request)).filter(isSourceFile);
|
|
222
|
+
if (changed.length === 0)
|
|
223
|
+
return pass({ skipped: "No changed source files to mutate" });
|
|
224
|
+
const command = this.command(toolchain, "mutation");
|
|
225
|
+
const result = await this.run1(request, "mutation", command, ["--mutate", changed.join(",")]);
|
|
226
|
+
const abnormal = this.abnormal(result, "The mutation run", this.timeouts.mutation);
|
|
227
|
+
if (abnormal)
|
|
228
|
+
return abnormal;
|
|
229
|
+
// Stryker also exits non-zero below its own threshold; the pack threshold is judged here.
|
|
230
|
+
const summary = parseStrykerReport(await this.report(request, command, result, "The mutation run"), changed);
|
|
231
|
+
if (summary.score === undefined)
|
|
232
|
+
return pass({ skipped: "No mutants in the changed files" });
|
|
233
|
+
const evaluation = evaluateThresholds(request.thresholds, { mutation: summary.score });
|
|
234
|
+
if (evaluation.passed)
|
|
235
|
+
return pass();
|
|
236
|
+
return fail([
|
|
237
|
+
...evaluation.failures.map((f) => f.message),
|
|
238
|
+
...summary.survivors.map((line) => `Surviving mutant: ${line}`),
|
|
239
|
+
]);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
//# sourceMappingURL=process-gate-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-gate-runner.js","sourceRoot":"","sources":["../../src/adapters/process-gate-runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unavailable-runner.d.ts","sourceRoot":"","sources":["../../src/adapters/unavailable-runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAa,MAAM,0BAA0B,CAAC;AAEvE,4FAA4F;AAC5F,eAAO,MAAM,iBAAiB,EAAE,WAU/B,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Placeholder until the child-session adapter lands (Phase 3): every run fails visibly. */
|
|
2
|
+
export const unavailableRunner = {
|
|
3
|
+
async run() {
|
|
4
|
+
return {
|
|
5
|
+
status: "failed",
|
|
6
|
+
text: "",
|
|
7
|
+
error: "No agent runner is configured: the child-session runner is not available in this build",
|
|
8
|
+
};
|
|
9
|
+
},
|
|
10
|
+
cancelProject() { },
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=unavailable-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unavailable-runner.js","sourceRoot":"","sources":["../../src/adapters/unavailable-runner.ts"],"names":[],"mappings":"AAEA,4FAA4F;AAC5F,MAAM,CAAC,MAAM,iBAAiB,GAAgB;IAC5C,KAAK,CAAC,GAAG;QACP,OAAO;YACL,MAAM,EAAE,QAAQ;YAChB,IAAI,EAAE,EAAE;YACR,KAAK,EACH,wFAAwF;SAC3F,CAAC;IACJ,CAAC;IACD,aAAa,KAAU,CAAC;CACzB,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Two-pass audit handshake (AD-5). The first handoff envelope is parked and the same session is
|
|
3
|
+
* challenged to re-verify. A second envelope with the same commit releases it; a changed commit
|
|
4
|
+
* restarts the challenge, bounded by `maxAuditRounds`.
|
|
5
|
+
*/
|
|
6
|
+
export interface AuditState {
|
|
7
|
+
commit: string;
|
|
8
|
+
/** Challenges issued so far for this task and role. */
|
|
9
|
+
challenges: number;
|
|
10
|
+
}
|
|
11
|
+
export type AuditStep = {
|
|
12
|
+
action: "release";
|
|
13
|
+
commit: string;
|
|
14
|
+
} | {
|
|
15
|
+
action: "challenge";
|
|
16
|
+
state: AuditState;
|
|
17
|
+
} | {
|
|
18
|
+
action: "exhausted";
|
|
19
|
+
challenges: number;
|
|
20
|
+
};
|
|
21
|
+
export declare const startAudit: (commit: string) => AuditState;
|
|
22
|
+
export declare function nextAudit(state: AuditState, commit: string, maxRounds: number): AuditStep;
|
|
23
|
+
//# sourceMappingURL=audit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/app/audit.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,SAAS,GACjB;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAAE,GAC1C;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhD,eAAO,MAAM,UAAU,WAAY,MAAM,KAAG,UAAyC,CAAC;AAEtF,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,CAIzF"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const startAudit = (commit) => ({ commit, challenges: 1 });
|
|
2
|
+
export function nextAudit(state, commit, maxRounds) {
|
|
3
|
+
if (commit === state.commit)
|
|
4
|
+
return { action: "release", commit };
|
|
5
|
+
if (state.challenges >= maxRounds)
|
|
6
|
+
return { action: "exhausted", challenges: state.challenges };
|
|
7
|
+
return { action: "challenge", state: { commit, challenges: state.challenges + 1 } };
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/app/audit.ts"],"names":[],"mappings":"AAgBA,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,MAAc,EAAc,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;AAEtF,MAAM,UAAU,SAAS,CAAC,KAAiB,EAAE,MAAc,EAAE,SAAiB;IAC5E,IAAI,MAAM,KAAK,KAAK,CAAC,MAAM;QAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IAClE,IAAI,KAAK,CAAC,UAAU,IAAI,SAAS;QAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC;IAChG,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,GAAG,CAAC,EAAE,EAAE,CAAC;AACtF,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { AttentionItem } from "../domain/attention.js";
|
|
2
|
+
export interface UsageMeterOptions {
|
|
3
|
+
file: string;
|
|
4
|
+
/** `options.tokenBudget`: a soft cap on total tokens; absent means unlimited. */
|
|
5
|
+
limit?: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Swarm-wide token meter (spec 8.4). The budget is a soft cap: crossing it pauses the pumps from
|
|
9
|
+
* starting new runs and raises a decision; runs already in flight finish. Persisted so a restart
|
|
10
|
+
* does not reset the spend.
|
|
11
|
+
*/
|
|
12
|
+
export declare class UsageMeter {
|
|
13
|
+
private readonly file;
|
|
14
|
+
private readonly base;
|
|
15
|
+
private data;
|
|
16
|
+
private constructor();
|
|
17
|
+
static open(options: UsageMeterOptions): Promise<UsageMeter>;
|
|
18
|
+
get total(): number;
|
|
19
|
+
/** Effective limit including raises, or `undefined` when unlimited. */
|
|
20
|
+
get limit(): number | undefined;
|
|
21
|
+
get exceeded(): boolean;
|
|
22
|
+
private save;
|
|
23
|
+
/** Add spent tokens. Returns true exactly when this call crossed the limit. */
|
|
24
|
+
record(tokens: number): Promise<boolean>;
|
|
25
|
+
raise(extra: number): Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
/** The decision item raised while the soft cap is exceeded. */
|
|
28
|
+
export declare function budgetAttention(project: string, meter: UsageMeter | undefined, createdAt: string): AttentionItem | undefined;
|
|
29
|
+
//# sourceMappingURL=budget.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"budget.d.ts","sourceRoot":"","sources":["../../src/app/budget.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAU5D,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,qBAAa,UAAU;IAEnB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,IAAI;IAHd,OAAO,eAIH;IAEJ,OAAa,IAAI,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC,CAkBjE;IAED,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,uEAAuE;IACvE,IAAI,KAAK,IAAI,MAAM,GAAG,SAAS,CAE9B;IAED,IAAI,QAAQ,IAAI,OAAO,CAGtB;IAED,OAAO,CAAC,IAAI;IAIZ,+EAA+E;IACzE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAM7C;IAEK,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKxC;CACF;AAED,+DAA+D;AAC/D,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,UAAU,GAAG,SAAS,EAC7B,SAAS,EAAE,MAAM,GAChB,aAAa,GAAG,SAAS,CAW3B"}
|