@basein/runner 0.2.12 → 0.3.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/README.md +540 -369
- package/dist/auth/client.d.ts +65 -3
- package/dist/auth/client.js +305 -53
- package/dist/bin/bir-hooks.d.ts +72 -31
- package/dist/bin/bir-hooks.js +176 -284
- package/dist/bin/bir-proxy.d.ts +17 -2
- package/dist/bin/bir-proxy.js +222 -28
- package/dist/bin/bir-scenario.d.ts +61 -21
- package/dist/bin/bir-scenario.js +593 -122
- package/dist/bin/bir.d.ts +12 -6
- package/dist/bin/bir.js +2935 -489
- package/dist/bin/investigate.js +40 -15
- package/dist/bin/scenario-edit.d.ts +7 -1
- package/dist/bin/scenario-edit.js +43 -21
- package/dist/bin/scenario-liveness.d.ts +194 -0
- package/dist/bin/scenario-liveness.js +459 -0
- package/dist/bin/scenario-stderr.d.ts +43 -0
- package/dist/bin/scenario-stderr.js +76 -0
- package/dist/bin/service-read.d.ts +88 -0
- package/dist/bin/service-read.js +128 -0
- package/dist/bin/setup.d.ts +19 -0
- package/dist/bin/setup.js +146 -20
- package/dist/config/adapters/claude-code.d.ts +92 -14
- package/dist/config/adapters/claude-code.js +291 -101
- package/dist/config/adapters/generic.d.ts +4 -1
- package/dist/config/adapters/generic.js +13 -14
- package/dist/config/generate.d.ts +392 -14
- package/dist/config/generate.js +666 -19
- package/dist/config/mcp-approval.d.ts +76 -0
- package/dist/config/mcp-approval.js +210 -0
- package/dist/config/node-path.d.ts +42 -0
- package/dist/config/node-path.js +102 -0
- package/dist/config/overrides.d.ts +62 -0
- package/dist/config/overrides.js +136 -0
- package/dist/config/resolve.d.ts +70 -8
- package/dist/config/resolve.js +186 -15
- package/dist/control/client.d.ts +22 -0
- package/dist/control/client.js +26 -7
- package/dist/control/correlation.d.ts +23 -5
- package/dist/control/correlation.js +0 -0
- package/dist/control/daemon.d.ts +400 -18
- package/dist/control/daemon.js +1105 -102
- package/dist/control/discovery.d.ts +77 -5
- package/dist/control/discovery.js +186 -11
- package/dist/control/ensure-hook.d.ts +61 -0
- package/dist/control/ensure-hook.js +160 -8
- package/dist/control/paths.d.ts +26 -0
- package/dist/control/paths.js +34 -0
- package/dist/control/pin-guard.d.ts +83 -0
- package/dist/control/pin-guard.js +534 -0
- package/dist/control/recorder-keeper.d.ts +229 -0
- package/dist/control/recorder-keeper.js +721 -0
- package/dist/control/recorder-main.d.ts +73 -0
- package/dist/control/recorder-main.js +778 -0
- package/dist/control/server.d.ts +707 -31
- package/dist/control/server.js +2786 -302
- package/dist/control/transcript.d.ts +21 -1
- package/dist/control/transcript.js +378 -112
- package/dist/index.d.ts +5 -1
- package/dist/index.js +5 -1
- package/dist/jsonrpc/framing.d.ts +76 -12
- package/dist/jsonrpc/framing.js +216 -59
- package/dist/proxy/intercept.d.ts +49 -5
- package/dist/proxy/intercept.js +188 -59
- package/dist/proxy/relay.d.ts +16 -0
- package/dist/proxy/relay.js +77 -5
- package/dist/proxy/revive.d.ts +122 -0
- package/dist/proxy/revive.js +251 -0
- package/dist/proxy/session.d.ts +222 -14
- package/dist/proxy/session.js +708 -99
- package/dist/record/recorder.d.ts +51 -3
- package/dist/record/recorder.js +3 -0
- package/dist/record/redact.d.ts +103 -9
- package/dist/record/redact.js +659 -30
- package/dist/record/remote-recorder.d.ts +327 -32
- package/dist/record/remote-recorder.js +1517 -187
- package/dist/record/switchable-recorder.d.ts +126 -0
- package/dist/record/switchable-recorder.js +351 -0
- package/dist/record/truncate.d.ts +40 -1
- package/dist/record/truncate.js +111 -4
- package/dist/replay/bash-channel.d.ts +35 -0
- package/dist/replay/bash-channel.js +133 -0
- package/dist/replay/bundle.d.ts +10 -0
- package/dist/replay/bundle.js +10 -0
- package/dist/replay/controller.d.ts +369 -20
- package/dist/replay/controller.js +1176 -107
- package/dist/replay/derive.d.ts +1 -0
- package/dist/replay/derive.js +81 -24
- package/dist/replay/executor.d.ts +51 -16
- package/dist/replay/executor.js +114 -41
- package/dist/replay/handover.d.ts +54 -1
- package/dist/replay/handover.js +55 -5
- package/dist/replay/logic.d.ts +62 -10
- package/dist/replay/logic.js +140 -22
- package/dist/replay/plan.d.ts +201 -27
- package/dist/replay/plan.js +581 -141
- package/dist/replay/safety.d.ts +72 -0
- package/dist/replay/safety.js +303 -0
- package/dist/replay/source-run.d.ts +10 -0
- package/dist/replay/source-run.js +80 -35
- package/dist/replay/targets.d.ts +15 -1
- package/dist/replay/targets.js +62 -4
- package/dist/replay/tool-error.d.ts +15 -1
- package/dist/replay/tool-error.js +33 -1
- package/dist/replay/types.d.ts +7 -4
- package/dist/upstream/client.d.ts +56 -3
- package/dist/upstream/client.js +61 -4
- package/dist/upstream/headers.d.ts +43 -0
- package/dist/upstream/headers.js +90 -0
- package/dist/upstream/http-client.d.ts +213 -22
- package/dist/upstream/http-client.js +1034 -168
- package/dist/upstream/http-transport.d.ts +143 -0
- package/dist/upstream/http-transport.js +391 -0
- package/dist/upstream/lazy-client.d.ts +8 -0
- package/dist/upstream/lazy-client.js +29 -1
- package/dist/upstream/sse.d.ts +78 -0
- package/dist/upstream/sse.js +189 -0
- package/dist/upstream/stdio-client.d.ts +61 -1
- package/dist/upstream/stdio-client.js +356 -33
- package/dist/util/atomic-write.d.ts +29 -0
- package/dist/util/atomic-write.js +96 -0
- package/dist/util/journal.d.ts +15 -0
- package/dist/util/journal.js +48 -3
- package/dist/util/log.d.ts +10 -0
- package/dist/util/log.js +28 -1
- package/dist/util/off-switch.d.ts +46 -0
- package/dist/util/off-switch.js +91 -0
- package/dist/util/service-health.d.ts +133 -0
- package/dist/util/service-health.js +217 -0
- package/docs/BaseInstRunner.md +694 -621
- package/docs/calculatedReplay.md +1625 -1304
- package/docs/calculatedReplayGuide.md +1212 -1087
- package/docs/installRun.md +1013 -772
- package/docs/loginWeb.md +627 -607
- package/docs/mcpmark.md +49 -16
- package/docs/my-first-sample.md +569 -545
- package/docs/quickstart.md +384 -311
- package/docs/t-bench.md +406 -394
- package/package.json +58 -57
- package/production.md +1371 -0
- package/scripts/install.ps1 +97 -6
- package/scripts/install.sh +104 -7
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bash-channel — delivering text to the model as a `Bash` command's genuine
|
|
3
|
+
* output (docs/calculatedReplay.md §8).
|
|
4
|
+
*
|
|
5
|
+
* The model reaches for `Bash` when it cannot call a scripted tool, and a real
|
|
6
|
+
* command output is trusted where a `deny` reason reads as interception, so a
|
|
7
|
+
* divergence bundle or a hand-over note is delivered by rewriting that call
|
|
8
|
+
* into a `cat`.
|
|
9
|
+
*
|
|
10
|
+
* THE COMMAND MUST STAY SHORT. It used to carry the whole text as a heredoc —
|
|
11
|
+
* up to 60 000 characters inside the command string. Measured through Git Bash
|
|
12
|
+
* on Windows: 8 000 characters print intact; 9 000 to 30 000 print only the
|
|
13
|
+
* first 8 171, with "here-document delimited by end-of-file"; 40 000 fail to
|
|
14
|
+
* spawn at all (ENAMETOOLONG). A bundle cut there loses its later steps and its
|
|
15
|
+
* footer, and the model redoes work that already ran. So a short text still
|
|
16
|
+
* rides inline, and anything longer is written to a private file the command
|
|
17
|
+
* reads. The caller caps the text itself ({@link ./bundle.ts}'s
|
|
18
|
+
* `BASH_CHANNEL_MAX`), because the host truncates long command output too.
|
|
19
|
+
*/
|
|
20
|
+
/** Up to this many characters the text rides inside the command, as a heredoc. */
|
|
21
|
+
export declare const HEREDOC_MAX = 6000;
|
|
22
|
+
/** Where delivered texts wait to be read. Under `BIR_HOME`, mode 0700. */
|
|
23
|
+
export declare function deliveryDir(): string;
|
|
24
|
+
/**
|
|
25
|
+
* The command that prints `text`, or undefined when it could not be prepared —
|
|
26
|
+
* the caller then delivers through another channel.
|
|
27
|
+
*/
|
|
28
|
+
export declare function bashCommandFor(text: string): string | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* Remove delivered texts older than an hour. For the recorder to call when it
|
|
31
|
+
* starts and on its housekeeping tick: a process that exits within the hour
|
|
32
|
+
* cannot sweep what it wrote. Never throws; returns how many it removed.
|
|
33
|
+
*/
|
|
34
|
+
export declare function sweepDeliveries(dir?: string): number;
|
|
35
|
+
//# sourceMappingURL=bash-channel.d.ts.map
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bash-channel — delivering text to the model as a `Bash` command's genuine
|
|
3
|
+
* output (docs/calculatedReplay.md §8).
|
|
4
|
+
*
|
|
5
|
+
* The model reaches for `Bash` when it cannot call a scripted tool, and a real
|
|
6
|
+
* command output is trusted where a `deny` reason reads as interception, so a
|
|
7
|
+
* divergence bundle or a hand-over note is delivered by rewriting that call
|
|
8
|
+
* into a `cat`.
|
|
9
|
+
*
|
|
10
|
+
* THE COMMAND MUST STAY SHORT. It used to carry the whole text as a heredoc —
|
|
11
|
+
* up to 60 000 characters inside the command string. Measured through Git Bash
|
|
12
|
+
* on Windows: 8 000 characters print intact; 9 000 to 30 000 print only the
|
|
13
|
+
* first 8 171, with "here-document delimited by end-of-file"; 40 000 fail to
|
|
14
|
+
* spawn at all (ENAMETOOLONG). A bundle cut there loses its later steps and its
|
|
15
|
+
* footer, and the model redoes work that already ran. So a short text still
|
|
16
|
+
* rides inline, and anything longer is written to a private file the command
|
|
17
|
+
* reads. The caller caps the text itself ({@link ./bundle.ts}'s
|
|
18
|
+
* `BASH_CHANNEL_MAX`), because the host truncates long command output too.
|
|
19
|
+
*/
|
|
20
|
+
import { randomUUID } from "node:crypto";
|
|
21
|
+
import { readdirSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
22
|
+
import { join } from "node:path";
|
|
23
|
+
import { configDir, ensureDir } from "../control/paths.js";
|
|
24
|
+
/** Up to this many characters the text rides inside the command, as a heredoc. */
|
|
25
|
+
export const HEREDOC_MAX = 6_000;
|
|
26
|
+
/** A delivered file is read once, at once; an hour is a generous margin. */
|
|
27
|
+
const MAX_AGE_MS = 60 * 60_000;
|
|
28
|
+
/** Where delivered texts wait to be read. Under `BIR_HOME`, mode 0700. */
|
|
29
|
+
export function deliveryDir() {
|
|
30
|
+
return join(configDir(), "tmp");
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The command that prints `text`, or undefined when it could not be prepared —
|
|
34
|
+
* the caller then delivers through another channel.
|
|
35
|
+
*/
|
|
36
|
+
export function bashCommandFor(text) {
|
|
37
|
+
if (text.length <= HEREDOC_MAX) {
|
|
38
|
+
// Neutralise the delimiter, so no text can end the heredoc early.
|
|
39
|
+
const delimiter = "BIR_EOF";
|
|
40
|
+
const safe = text.split(delimiter).join("BIR_EOF_");
|
|
41
|
+
return `cat <<'${delimiter}'\n${safe}\n${delimiter}`;
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
const dir = deliveryDir();
|
|
45
|
+
ensureDir(dir);
|
|
46
|
+
sweep(dir);
|
|
47
|
+
const path = join(dir, `replay-${randomUUID()}.txt`);
|
|
48
|
+
writeFileSync(path, text, { encoding: "utf8", mode: 0o600 });
|
|
49
|
+
// The file holds live tool outputs. It is kept an hour — a Bash call can
|
|
50
|
+
// wait that long on a permission prompt before it reads it — and then
|
|
51
|
+
// removed by this process, not only by a later delivery that may never
|
|
52
|
+
// come ("swept after 1 h").
|
|
53
|
+
scheduleSweep(dir);
|
|
54
|
+
return `cat ${shellQuote(shellPath(path))}`;
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Remove delivered texts older than an hour. For the recorder to call when it
|
|
62
|
+
* starts and on its housekeeping tick: a process that exits within the hour
|
|
63
|
+
* cannot sweep what it wrote. Never throws; returns how many it removed.
|
|
64
|
+
*/
|
|
65
|
+
export function sweepDeliveries(dir = deliveryDir()) {
|
|
66
|
+
return sweep(dir).removed;
|
|
67
|
+
}
|
|
68
|
+
/** Past {@link MAX_AGE_MS}, how long a scheduled sweep waits more. */
|
|
69
|
+
const SWEEP_SLACK_MS = 60_000;
|
|
70
|
+
/** The sweep waiting for this process's newest delivered file to age out, by directory. */
|
|
71
|
+
const scheduledSweeps = new Map();
|
|
72
|
+
/**
|
|
73
|
+
* Sweep `dir` once the file just written is old enough to go, and again while
|
|
74
|
+
* younger ones are left. Unref'd: it never keeps the process alive.
|
|
75
|
+
*/
|
|
76
|
+
function scheduleSweep(dir) {
|
|
77
|
+
const earlier = scheduledSweeps.get(dir);
|
|
78
|
+
if (earlier)
|
|
79
|
+
clearTimeout(earlier);
|
|
80
|
+
const timer = setTimeout(() => {
|
|
81
|
+
scheduledSweeps.delete(dir);
|
|
82
|
+
if (sweep(dir).left > 0)
|
|
83
|
+
scheduleSweep(dir);
|
|
84
|
+
}, MAX_AGE_MS + SWEEP_SLACK_MS);
|
|
85
|
+
timer.unref?.();
|
|
86
|
+
scheduledSweeps.set(dir, timer);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* A path every shell the host may run can open. Forward slashes on Windows:
|
|
90
|
+
* Git Bash reads `C:/Users/…` as it is, and so does PowerShell's `cat`.
|
|
91
|
+
*/
|
|
92
|
+
function shellPath(path) {
|
|
93
|
+
return process.platform === "win32" ? path.replace(/\\/g, "/") : path;
|
|
94
|
+
}
|
|
95
|
+
/** Single-quoted for a POSIX shell (and harmless in PowerShell). */
|
|
96
|
+
function shellQuote(s) {
|
|
97
|
+
return `'${s.replace(/'/g, `'\\''`)}'`;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Remove delivered texts older than {@link MAX_AGE_MS}. Never throws. Says how
|
|
101
|
+
* many it removed, and how many younger ones are left.
|
|
102
|
+
*/
|
|
103
|
+
function sweep(dir) {
|
|
104
|
+
let names;
|
|
105
|
+
try {
|
|
106
|
+
names = readdirSync(dir);
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
return { removed: 0, left: 0 };
|
|
110
|
+
}
|
|
111
|
+
const cutoff = Date.now() - MAX_AGE_MS;
|
|
112
|
+
let removed = 0;
|
|
113
|
+
let left = 0;
|
|
114
|
+
for (const name of names) {
|
|
115
|
+
if (!name.startsWith("replay-") || !name.endsWith(".txt"))
|
|
116
|
+
continue;
|
|
117
|
+
const path = join(dir, name);
|
|
118
|
+
try {
|
|
119
|
+
if (statSync(path).mtimeMs < cutoff) {
|
|
120
|
+
unlinkSync(path);
|
|
121
|
+
removed += 1;
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
left += 1;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
// Gone already, or not ours to remove.
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return { removed, left };
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=bash-channel.js.map
|
package/dist/replay/bundle.d.ts
CHANGED
|
@@ -16,6 +16,16 @@
|
|
|
16
16
|
*/
|
|
17
17
|
/** `permissionDecisionReason` is fed to the model as text; keep denials bounded. */
|
|
18
18
|
export declare const MAX_REPLAY_REASON = 60000;
|
|
19
|
+
/**
|
|
20
|
+
* Ceiling on text delivered as a `Bash` command's output.
|
|
21
|
+
*
|
|
22
|
+
* Claude Code middle-truncates Bash output above `BASH_MAX_OUTPUT_LENGTH`
|
|
23
|
+
* (30 000 by default), and a bundle cut in the middle loses exactly the steps
|
|
24
|
+
* the model needs to see were already done — so it does them again. Laid out
|
|
25
|
+
* at this size with the fair-share rule, every step stays represented and the
|
|
26
|
+
* cut never happens. A hand-over note in front of it is counted inside this.
|
|
27
|
+
*/
|
|
28
|
+
export declare const BASH_CHANNEL_MAX = 25000;
|
|
19
29
|
/** One executed step, pre-stringified and ready to lay out. */
|
|
20
30
|
export interface BundleEntry {
|
|
21
31
|
toolName: string;
|
package/dist/replay/bundle.js
CHANGED
|
@@ -16,6 +16,16 @@
|
|
|
16
16
|
*/
|
|
17
17
|
/** `permissionDecisionReason` is fed to the model as text; keep denials bounded. */
|
|
18
18
|
export const MAX_REPLAY_REASON = 60_000;
|
|
19
|
+
/**
|
|
20
|
+
* Ceiling on text delivered as a `Bash` command's output.
|
|
21
|
+
*
|
|
22
|
+
* Claude Code middle-truncates Bash output above `BASH_MAX_OUTPUT_LENGTH`
|
|
23
|
+
* (30 000 by default), and a bundle cut in the middle loses exactly the steps
|
|
24
|
+
* the model needs to see were already done — so it does them again. Laid out
|
|
25
|
+
* at this size with the fair-share rule, every step stays represented and the
|
|
26
|
+
* cut never happens. A hand-over note in front of it is counted inside this.
|
|
27
|
+
*/
|
|
28
|
+
export const BASH_CHANNEL_MAX = 25_000;
|
|
19
29
|
/** Cap each computed input so one huge argument object cannot starve responses. */
|
|
20
30
|
const MAX_INPUT_CHARS = 2_000;
|
|
21
31
|
/** Fixed structural overhead reserved per step (labels, separators). */
|