@basein/runner 0.2.11 → 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 -350
- 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 -10
- package/dist/bin/bir-scenario.js +704 -135
- package/dist/bin/bir.d.ts +14 -8
- package/dist/bin/bir.js +2937 -488
- package/dist/bin/investigate.js +41 -16
- package/dist/bin/scenario-edit.d.ts +43 -10
- package/dist/bin/scenario-edit.js +281 -80
- 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 +2803 -306
- 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/housekeeping.d.ts +71 -0
- package/dist/record/housekeeping.js +417 -0
- 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 +371 -20
- package/dist/replay/controller.js +1185 -111
- 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 -1244
- package/docs/calculatedReplayGuide.md +1212 -879
- 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 -271
- 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
package/dist/bin/investigate.js
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
* declined and what mode armed; the service knows the baseline, the ledger and
|
|
18
18
|
* whether a run ever became a recording. Both lists are printed, worst first.
|
|
19
19
|
*/
|
|
20
|
+
import { ReadClock, jsonText, readWithin, serviceProblem, underMcp, unreachable } from "./service-read.js";
|
|
20
21
|
const num = (v) => {
|
|
21
22
|
if (v === undefined || v === null || v === "")
|
|
22
23
|
return undefined;
|
|
@@ -170,8 +171,8 @@ export const DECLINES = {
|
|
|
170
171
|
fix: "wait for the calculation, or start one with `bir scenario calc <runId>`, then run the prompt again.",
|
|
171
172
|
},
|
|
172
173
|
similarity: {
|
|
173
|
-
cause: "the prompt was a hit on the recording but below the steering threshold (
|
|
174
|
-
fix: "phrase the prompt closer to the recorded one, or lower
|
|
174
|
+
cause: "the prompt was a hit on the recording but below the steering threshold (BIR_MIN_STEER_SIMILARITY, default 0.92).",
|
|
175
|
+
fix: "phrase the prompt closer to the recorded one, or lower BIR_MIN_STEER_SIMILARITY.",
|
|
175
176
|
},
|
|
176
177
|
coverage: {
|
|
177
178
|
cause: "no step of the scenario could run anywhere: its tools are neither wrapped MCP servers registered in this session nor built-ins.",
|
|
@@ -179,7 +180,7 @@ export const DECLINES = {
|
|
|
179
180
|
},
|
|
180
181
|
known_bad_first_step: {
|
|
181
182
|
cause: "the chain's first step is parked after repeated failures.",
|
|
182
|
-
fix: "wait: the service retries it once an hour for a day, then repairs the plan from the next run of the prompt. To repair now: `bir scenario calc <
|
|
183
|
+
fix: "wait: the service retries it once an hour for a day, then repairs the plan from the next run of the prompt — unless the plan has steps edited by hand, or is a sub-task, which it does not repair on its own. To repair now: `bir scenario calc <scnId> --force` (add --discard-edits to drop hand edits), or fix the step: `bir scenario edit <scnId> --step 0 --input-logic <file>`. `bir investigate <scnId>` names the scenario id.",
|
|
183
184
|
},
|
|
184
185
|
nondeterministic_first_step: {
|
|
185
186
|
cause: "the chain's first step needs a judgement the calculation could not write code for, so the plan cannot start.",
|
|
@@ -435,16 +436,22 @@ export function renderService(out, s, viewerIsOwner) {
|
|
|
435
436
|
renderFindings(out, s.findings ?? [], "Service findings");
|
|
436
437
|
}
|
|
437
438
|
// ── the command ───────────────────────────────────────────────────────────────
|
|
438
|
-
async function fetchInvestigation(deps, id, limit) {
|
|
439
|
-
const reply = await deps.service(`/investigate/${id}${limit ? `?limit=${limit}` : ""}`);
|
|
440
|
-
if ("error" in reply)
|
|
441
|
-
return { note: `service not consulted: ${reply.error}
|
|
439
|
+
async function fetchInvestigation(deps, id, limit, clock) {
|
|
440
|
+
const reply = await clock.within(deps.service(`/investigate/${id}${limit ? `?limit=${limit}` : ""}`));
|
|
441
|
+
if ("error" in reply) {
|
|
442
|
+
return { note: `service not consulted: ${serviceProblem(reply.error)}`, unreachable: unreachable(reply.error) };
|
|
443
|
+
}
|
|
442
444
|
if (reply.status === 404)
|
|
443
445
|
return { note: `the service has nothing for ${id} (not yours, or never reached it)` };
|
|
444
446
|
if (reply.status !== 200)
|
|
445
447
|
return { note: `service answered HTTP ${reply.status}` };
|
|
446
448
|
return { data: reply.body };
|
|
447
449
|
}
|
|
450
|
+
/** A turn without its raw journal lines, which only a person reading the whole record wants. */
|
|
451
|
+
function withoutEvents(turn) {
|
|
452
|
+
const { events, ...rest } = turn;
|
|
453
|
+
return { ...rest, eventCount: events.length };
|
|
454
|
+
}
|
|
448
455
|
/** Which id the service should be asked about for a turn. */
|
|
449
456
|
function serviceIdFor(turn) {
|
|
450
457
|
return (turn.reported?.ticket ??
|
|
@@ -463,9 +470,10 @@ export async function investigateCommand(args, deps) {
|
|
|
463
470
|
params.set("limit", String(args.limit));
|
|
464
471
|
if (args.user)
|
|
465
472
|
params.set("user", args.user);
|
|
466
|
-
const reply = await deps.service(`/investigate/executions${params.size ? `?${params}` : ""}`);
|
|
473
|
+
const reply = await readWithin(deps.service(`/investigate/executions${params.size ? `?${params}` : ""}`));
|
|
467
474
|
if ("error" in reply) {
|
|
468
|
-
|
|
475
|
+
const words = serviceProblem(reply.error);
|
|
476
|
+
out(`Could not reach the service: ${words}${words === reply.error ? "" : ` (${reply.error})`}`);
|
|
469
477
|
return 1;
|
|
470
478
|
}
|
|
471
479
|
if (reply.status === 403) {
|
|
@@ -482,7 +490,7 @@ export async function investigateCommand(args, deps) {
|
|
|
482
490
|
}
|
|
483
491
|
const body = reply.body;
|
|
484
492
|
if (args.json) {
|
|
485
|
-
out(
|
|
493
|
+
out(jsonText(body));
|
|
486
494
|
return 0;
|
|
487
495
|
}
|
|
488
496
|
const rows = body.executions ?? [];
|
|
@@ -503,7 +511,7 @@ export async function investigateCommand(args, deps) {
|
|
|
503
511
|
const limit = args.limit ?? 20;
|
|
504
512
|
const recent = turns.slice(-limit).reverse();
|
|
505
513
|
if (args.json) {
|
|
506
|
-
out(
|
|
514
|
+
out(jsonText(underMcp() ? recent.map(withoutEvents) : recent));
|
|
507
515
|
return 0;
|
|
508
516
|
}
|
|
509
517
|
if (recent.length === 0) {
|
|
@@ -550,14 +558,31 @@ export async function investigateCommand(args, deps) {
|
|
|
550
558
|
}
|
|
551
559
|
const findings = turn ? localFindings(turn) : [];
|
|
552
560
|
const serviceId = turn ? serviceIdFor(turn) : id;
|
|
553
|
-
|
|
561
|
+
// Both reads below share one bound, so a slow "no" followed by a held
|
|
562
|
+
// second try still ends inside the time the `bir` MCP server allows a
|
|
563
|
+
// reading tool — with the journal half, which needed no service at all.
|
|
564
|
+
const clock = new ReadClock();
|
|
565
|
+
const service = await fetchInvestigation(deps, serviceId, args.limit, clock);
|
|
554
566
|
// A matched turn's own run id is unknown to the service; when the scenario
|
|
555
|
-
// lookup fails, the matched run is still worth a try
|
|
556
|
-
|
|
557
|
-
|
|
567
|
+
// lookup fails, the matched run is still worth a try — unless the service
|
|
568
|
+
// could not be reached at all, when a second try only doubles the wait, or
|
|
569
|
+
// the bound is spent.
|
|
570
|
+
const fallbackId = turn &&
|
|
571
|
+
service.note &&
|
|
572
|
+
!service.unreachable &&
|
|
573
|
+
turn.matched?.runId &&
|
|
574
|
+
serviceId !== turn.matched.runId &&
|
|
575
|
+
clock.remaining() > 0
|
|
576
|
+
? turn.matched.runId
|
|
577
|
+
: undefined;
|
|
578
|
+
const second = fallbackId ? await fetchInvestigation(deps, fallbackId, args.limit, clock) : undefined;
|
|
558
579
|
const chosen = service.data ? service : second?.data ? second : service;
|
|
559
580
|
if (args.json) {
|
|
560
|
-
|
|
581
|
+
// For a model (the `bir` MCP server), the turn goes without its raw
|
|
582
|
+
// journal lines: every field they carry is already parsed into the turn,
|
|
583
|
+
// and a long turn's lines are most of the output.
|
|
584
|
+
const shown = turn ? (underMcp() ? withoutEvents(turn) : turn) : null;
|
|
585
|
+
out(jsonText({ turn: shown, findings, service: chosen.data ?? null, note: chosen.note ?? null }));
|
|
561
586
|
return 0;
|
|
562
587
|
}
|
|
563
588
|
if (turn) {
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
* bir scenario edit <runId|scnId> --step <n> [--input-logic <file|->] [--output-logic <file|->]
|
|
8
8
|
* [--freeze | --unfreeze] [--note "why"] [--force --note "why"] [--revision <n>]
|
|
9
9
|
* bir scenario edits <runId|scnId>
|
|
10
|
-
* bir scenario undo <runId|scnId> [--edit <sedit_id>]
|
|
11
|
-
* bir scenario calc <runId> [--force [--discard-edits]]
|
|
10
|
+
* bir scenario undo <runId|scnId> [--edit <sedit_id> | --step <n>] [--force --note "why"]
|
|
11
|
+
* bir scenario calc <runId|scnId> [--force [--discard-edits]]
|
|
12
12
|
* bir scenario editing on|off|status
|
|
13
13
|
*
|
|
14
14
|
* WHY THIS IS A CLIENT AND NOTHING MORE. Whether a change may be saved is
|
|
@@ -70,6 +70,10 @@ export interface EditReport {
|
|
|
70
70
|
before: MarkState;
|
|
71
71
|
after: MarkState;
|
|
72
72
|
};
|
|
73
|
+
/** The logic and mark asked for are what the step already has (rule 10). */
|
|
74
|
+
noChange?: boolean;
|
|
75
|
+
/** The check stopped at the service's sandbox-time budget: *too costly to check* (rule 11). */
|
|
76
|
+
budgetExceeded?: boolean;
|
|
73
77
|
problems: string[];
|
|
74
78
|
}
|
|
75
79
|
interface MarkState {
|
|
@@ -131,7 +135,7 @@ export interface ScenarioEditArgs {
|
|
|
131
135
|
freeze: boolean;
|
|
132
136
|
unfreeze: boolean;
|
|
133
137
|
note?: string;
|
|
134
|
-
/** `undo --edit`: the `sedit_` id to put back. */
|
|
138
|
+
/** `undo --edit`: the `sedit_` id to put back. `undo --step` is {@link step}. */
|
|
135
139
|
edit?: string;
|
|
136
140
|
/** `--revision`: save only if the plan is still at this `chainRevision`. */
|
|
137
141
|
revision?: number;
|
|
@@ -139,7 +143,13 @@ export interface ScenarioEditArgs {
|
|
|
139
143
|
}
|
|
140
144
|
/** The `bir scenario` words this module answers; `list` and `replay` stay in bir.ts. */
|
|
141
145
|
export declare const SCENARIO_EDIT_SUBCOMMANDS: ReadonlySet<string>;
|
|
142
|
-
/**
|
|
146
|
+
/**
|
|
147
|
+
* The `bir` MCP server's tools that only read. Offered with scenario editing
|
|
148
|
+
* on, or where the server's environment has `BIR_SCENARIO_TOOLS=read` — no
|
|
149
|
+
* longer in every session: their definitions ride along with every request a
|
|
150
|
+
* session makes, and only somebody working on a scenario ever calls them (the
|
|
151
|
+
* same answers are `bir scenario show` and `bir investigate` in a terminal).
|
|
152
|
+
*/
|
|
143
153
|
export declare const READ_TOOLS: readonly ["scenario_show", "scenario_edits", "investigate"];
|
|
144
154
|
/** The ones that change a scenario: offered only after `bir scenario editing on` (D2). */
|
|
145
155
|
export declare const EDIT_TOOLS: readonly ["scenario_check", "scenario_edit", "scenario_undo"];
|
|
@@ -155,19 +165,42 @@ export declare function decodeLogic(bytes: Buffer): string;
|
|
|
155
165
|
* The report in the lines editSteps.md "What a person sees" shows:
|
|
156
166
|
* `input`, `output` (when the output logic changed), `later`, `answer` (when
|
|
157
167
|
* the final answer read anything before) and `mark`.
|
|
168
|
+
*
|
|
169
|
+
* `check` prints every line: it is where a person explores a change, and "step
|
|
170
|
+
* 5 still reproduces" is an answer there. `edit` and `undo` are acts, and print
|
|
171
|
+
* `brief`ly — what changed and what went wrong: `input` always, `output` when
|
|
172
|
+
* it changed, `later` only for a step that broke, `answer` only when it lost its
|
|
173
|
+
* values, `mark` only when it moves. The report is the same one either way (D11);
|
|
174
|
+
* only the lines that say "nothing to see" are left out.
|
|
175
|
+
*
|
|
176
|
+
* An `undo` does not judge the step itself — its code and mark go back exactly
|
|
177
|
+
* as they were (editSteps.md, "Undo") — so its report's input status is
|
|
178
|
+
* `not_checked` by design, and printing the usual reason for that ("the
|
|
179
|
+
* recorded call is plain text") would be false. It says what happened instead.
|
|
158
180
|
*/
|
|
159
|
-
export declare function renderReport(out: (line?: string) => void, r: EditReport
|
|
181
|
+
export declare function renderReport(out: (line?: string) => void, r: EditReport, opts?: {
|
|
182
|
+
brief?: boolean;
|
|
183
|
+
undo?: boolean;
|
|
184
|
+
}): void;
|
|
160
185
|
/**
|
|
161
186
|
* About {@link CONTEXT} characters either side of `at`. A text already that
|
|
162
187
|
* short — a window the service cut itself, or a small call — is printed whole.
|
|
163
188
|
*/
|
|
164
189
|
export declare function around(text: string, at: number): string;
|
|
165
190
|
/**
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
191
|
+
* What `undo` without `--edit` takes back (D9): the newest **edit** — never an
|
|
192
|
+
* undo entry — that nothing has put back and no recalculation replaced; of
|
|
193
|
+
* step `step` when it is given.
|
|
194
|
+
*
|
|
195
|
+
* Undo entries are skipped on purpose. They used to be picked like any other,
|
|
196
|
+
* so a second `undo` redid the first one, and a step edited twice toggled
|
|
197
|
+
* between its two edits for ever and never got back to the calculation's code
|
|
198
|
+
* (C12). Now a second `undo` goes one further back; a redo is asked for by
|
|
199
|
+
* name, `--edit <the undo's id>`, which the undo prints.
|
|
200
|
+
*
|
|
201
|
+
* Whether the step is still exactly as that edit left it is the service's
|
|
202
|
+
* question, not this list's: it answers `not_latest_edit` when it is not.
|
|
170
203
|
*/
|
|
171
|
-
export declare function newestUndoable(edits: EditEntry[]): EditEntry | undefined;
|
|
204
|
+
export declare function newestUndoable(edits: EditEntry[], step?: number): EditEntry | undefined;
|
|
172
205
|
export {};
|
|
173
206
|
//# sourceMappingURL=scenario-edit.d.ts.map
|