@basein/runner 0.2.10 → 0.2.11
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 +22 -1
- package/dist/bin/bir-scenario.d.ts +18 -2
- package/dist/bin/bir-scenario.js +374 -4
- package/dist/bin/bir.d.ts +10 -0
- package/dist/bin/bir.js +140 -43
- package/dist/bin/investigate.js +1 -1
- package/dist/bin/scenario-edit.d.ts +173 -0
- package/dist/bin/scenario-edit.js +771 -0
- package/dist/config/generate.d.ts +21 -0
- package/dist/config/generate.js +16 -0
- package/docs/calculatedReplay.md +51 -0
- package/docs/calculatedReplayGuide.md +318 -8
- package/docs/quickstart.md +3 -1
- package/package.json +1 -1
package/dist/bin/bir.js
CHANGED
|
@@ -12,6 +12,16 @@
|
|
|
12
12
|
* bir login | logout
|
|
13
13
|
* bir --version
|
|
14
14
|
*
|
|
15
|
+
* bir scenario list | show <runId|scnId> [--step <n>] | calc <runId> [--force [--discard-edits]]
|
|
16
|
+
* bir scenario check|edit <runId|scnId> --step <n> --input-logic <file|-> … ← fix one step
|
|
17
|
+
* bir scenario edits | undo <runId|scnId> [--edit <sedit_id>]
|
|
18
|
+
* bir scenario editing on|off|status ← may this project's `bir` MCP server change a scenario?
|
|
19
|
+
* bir scenario replay <scnId> --prompt "…" [--dry] | bir replay status|on|off|allow …
|
|
20
|
+
* bir investigate [<id>] | list | executions
|
|
21
|
+
*
|
|
22
|
+
* The `scenario` words that read or change one step live in scenario-edit.ts
|
|
23
|
+
* (editSteps.md in the BaseIn repository); `investigate` in investigate.ts.
|
|
24
|
+
*
|
|
15
25
|
* `bir install` is reversible by construction: every file it edits is stashed
|
|
16
26
|
* verbatim first, so `bir uninstall` restores it byte-for-byte unless somebody
|
|
17
27
|
* else edited it in the meantime (in which case it repairs the entries and says
|
|
@@ -20,7 +30,7 @@
|
|
|
20
30
|
* from `serverInfo`, which must stay the upstream's (Phase 3).
|
|
21
31
|
*/
|
|
22
32
|
import { randomBytes } from "node:crypto";
|
|
23
|
-
import { existsSync, realpathSync, writeFileSync } from "node:fs";
|
|
33
|
+
import { existsSync, readFileSync, realpathSync, writeFileSync } from "node:fs";
|
|
24
34
|
import { dirname, join, resolve as resolvePath } from "node:path";
|
|
25
35
|
import { fileURLToPath } from "node:url";
|
|
26
36
|
import { ControlClient } from "../control/client.js";
|
|
@@ -37,6 +47,7 @@ import { DEFAULT_CONTROL_PORT } from "../control/server.js";
|
|
|
37
47
|
import { errText } from "../util/log.js";
|
|
38
48
|
import { journalPath, readJournal } from "../util/journal.js";
|
|
39
49
|
import { investigateCommand } from "./investigate.js";
|
|
50
|
+
import { SCENARIO_EDIT_SUBCOMMANDS, scenarioEditCommand } from "./scenario-edit.js";
|
|
40
51
|
import { loadCredentials } from "../auth/client.js";
|
|
41
52
|
import { packageVersion } from "../util/version.js";
|
|
42
53
|
const VERSION = packageVersion();
|
|
@@ -59,8 +70,20 @@ Commands:
|
|
|
59
70
|
logout revoke this machine's session and forget it
|
|
60
71
|
|
|
61
72
|
scenario list recorded runs and their calculated scenarios
|
|
62
|
-
scenario show <runId>
|
|
63
|
-
|
|
73
|
+
scenario show <runId|scnId> [--step <n>]
|
|
74
|
+
a scenario: intent, params, steps (--step: just that one)
|
|
75
|
+
scenario calc <runId> [--force [--discard-edits]]
|
|
76
|
+
calculate (or re-derive) a run's scenario
|
|
77
|
+
scenario check <runId|scnId> --step <n> [--input-logic <file|->] [--output-logic <file|->] [--unfreeze]
|
|
78
|
+
try a change to one step against the recording; saves nothing
|
|
79
|
+
scenario edit <runId|scnId> --step <n> [--input-logic <file|->] [--output-logic <file|->]
|
|
80
|
+
[--freeze | --unfreeze] [--note "why"] [--force --note "why"] [--revision <n>]
|
|
81
|
+
the same check, and save the change if it passes
|
|
82
|
+
scenario edits <runId|scnId> a scenario's hand edits, newest first
|
|
83
|
+
scenario undo <runId|scnId> [--edit <sedit_id>]
|
|
84
|
+
put a step back as it was before its newest edit
|
|
85
|
+
scenario editing on|off|status whether this project's bir MCP server offers the tools
|
|
86
|
+
that change a scenario (restart Claude Code after)
|
|
64
87
|
scenario replay <scnId> --prompt "…" [--dry]
|
|
65
88
|
replay --scenario <scnId> --prompt "…" [--dry]
|
|
66
89
|
replay status | on | off | allow <a,b> | allow all
|
|
@@ -83,8 +106,20 @@ Options:
|
|
|
83
106
|
--replay install/remove the scenario server, enabling calculated replay
|
|
84
107
|
--port <n> install/setup: control-server port to write into the hook URLs
|
|
85
108
|
(default: this project's, else the lowest free one from ${DEFAULT_CONTROL_PORT})
|
|
86
|
-
--json machine-readable output for status / doctor
|
|
109
|
+
--json machine-readable output for status / doctor / scenario / investigate
|
|
110
|
+
(scenario check|edit|edits|undo: the service's answer, unchanged)
|
|
87
111
|
--dry replay against recorded outputs only; run no real tools
|
|
112
|
+
--force scenario calc: recalculate in place · scenario edit: save although
|
|
113
|
+
the check refused it (needs --note; only for a recording that was wrong)
|
|
114
|
+
--step <n> scenario show|check|edit: the step, by the stepIndex \`show\` prints
|
|
115
|
+
--input-logic <file|-> scenario check|edit: the new input logic, from a file or stdin (-)
|
|
116
|
+
--output-logic <file|-> scenario check|edit: the new output logic, from a file or stdin (-)
|
|
117
|
+
--freeze scenario edit: mark the step "needs a judgement" (runs hand over before it)
|
|
118
|
+
--unfreeze scenario check|edit: ask to remove that mark; the check decides
|
|
119
|
+
--note <text> scenario edit|undo: why, kept in the history (required with --force)
|
|
120
|
+
--revision <n> scenario edit|undo: only if the plan is still at this chainRevision
|
|
121
|
+
--edit <id> scenario undo: the sedit_ id to undo (default: the newest that can be)
|
|
122
|
+
--discard-edits scenario calc --force: recalculate a plan with hand edits, replacing them
|
|
88
123
|
--no-browser login: print the link and code, open nothing (SSH, headless)
|
|
89
124
|
--token <value> login: redeem a one-time setup token from the console (no browser)
|
|
90
125
|
--password login: use the old email/password prompt (deprecated)
|
|
@@ -118,6 +153,9 @@ function parseArgs(argv) {
|
|
|
118
153
|
noDaemon: false,
|
|
119
154
|
restart: false,
|
|
120
155
|
portExplicit: false,
|
|
156
|
+
freeze: false,
|
|
157
|
+
unfreeze: false,
|
|
158
|
+
discardEdits: false,
|
|
121
159
|
};
|
|
122
160
|
for (let i = 1; i < argv.length; i += 1) {
|
|
123
161
|
const arg = argv[i];
|
|
@@ -214,6 +252,53 @@ function parseArgs(argv) {
|
|
|
214
252
|
args.limit = n;
|
|
215
253
|
break;
|
|
216
254
|
}
|
|
255
|
+
case "--step": {
|
|
256
|
+
// Digits only: `Number("")` is 0 and `Number("0x4")` is 4, and a step
|
|
257
|
+
// index nobody typed is a step nobody meant to change.
|
|
258
|
+
const raw = argv[++i] ?? "";
|
|
259
|
+
if (!/^\d+$/.test(raw))
|
|
260
|
+
usage(2);
|
|
261
|
+
args.step = Number(raw);
|
|
262
|
+
break;
|
|
263
|
+
}
|
|
264
|
+
case "--input-logic":
|
|
265
|
+
// A value flag, so a bare `-` (stdin) is taken here and never reaches
|
|
266
|
+
// the default branch, which refuses anything that starts with a dash.
|
|
267
|
+
args.inputLogic = argv[++i];
|
|
268
|
+
if (!args.inputLogic)
|
|
269
|
+
usage(2);
|
|
270
|
+
break;
|
|
271
|
+
case "--output-logic":
|
|
272
|
+
args.outputLogic = argv[++i];
|
|
273
|
+
if (!args.outputLogic)
|
|
274
|
+
usage(2);
|
|
275
|
+
break;
|
|
276
|
+
case "--freeze":
|
|
277
|
+
args.freeze = true;
|
|
278
|
+
break;
|
|
279
|
+
case "--unfreeze":
|
|
280
|
+
args.unfreeze = true;
|
|
281
|
+
break;
|
|
282
|
+
case "--note":
|
|
283
|
+
args.note = argv[++i];
|
|
284
|
+
if (args.note === undefined)
|
|
285
|
+
usage(2);
|
|
286
|
+
break;
|
|
287
|
+
case "--edit":
|
|
288
|
+
args.edit = argv[++i];
|
|
289
|
+
if (!args.edit)
|
|
290
|
+
usage(2);
|
|
291
|
+
break;
|
|
292
|
+
case "--revision": {
|
|
293
|
+
const raw = argv[++i] ?? "";
|
|
294
|
+
if (!/^\d+$/.test(raw) || Number(raw) <= 0)
|
|
295
|
+
usage(2);
|
|
296
|
+
args.revision = Number(raw);
|
|
297
|
+
break;
|
|
298
|
+
}
|
|
299
|
+
case "--discard-edits":
|
|
300
|
+
args.discardEdits = true;
|
|
301
|
+
break;
|
|
217
302
|
default:
|
|
218
303
|
if (arg.startsWith("-"))
|
|
219
304
|
usage(2);
|
|
@@ -221,6 +306,10 @@ function parseArgs(argv) {
|
|
|
221
306
|
args.positionals.push(arg);
|
|
222
307
|
}
|
|
223
308
|
}
|
|
309
|
+
if (args.freeze && args.unfreeze) {
|
|
310
|
+
process.stderr.write("[bir] --freeze and --unfreeze are mutually exclusive\n");
|
|
311
|
+
process.exit(2);
|
|
312
|
+
}
|
|
224
313
|
return args;
|
|
225
314
|
}
|
|
226
315
|
/** Absolute path to this package's built `bir-proxy.js`, for `--local`. */
|
|
@@ -960,51 +1049,59 @@ async function scenarioCommand(args) {
|
|
|
960
1049
|
}
|
|
961
1050
|
return 0;
|
|
962
1051
|
}
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
out("That run already has a scenario. Re-derive it in place with --force.");
|
|
993
|
-
return 1;
|
|
994
|
-
}
|
|
995
|
-
if (status === 503) {
|
|
996
|
-
out("The service has no Anthropic configuration, so it cannot calculate scenarios.");
|
|
997
|
-
return 1;
|
|
998
|
-
}
|
|
999
|
-
out(`Could not start calculation (HTTP ${status}): ${JSON.stringify(body)}`);
|
|
1000
|
-
return 1;
|
|
1052
|
+
// show, calc, and everything that reads or changes one step (editSteps.md).
|
|
1053
|
+
if (SCENARIO_EDIT_SUBCOMMANDS.has(sub)) {
|
|
1054
|
+
return scenarioEditCommand({
|
|
1055
|
+
positionals: args.positionals,
|
|
1056
|
+
json: args.json,
|
|
1057
|
+
force: args.force,
|
|
1058
|
+
step: args.step,
|
|
1059
|
+
inputLogic: args.inputLogic,
|
|
1060
|
+
outputLogic: args.outputLogic,
|
|
1061
|
+
freeze: args.freeze,
|
|
1062
|
+
unfreeze: args.unfreeze,
|
|
1063
|
+
note: args.note,
|
|
1064
|
+
edit: args.edit,
|
|
1065
|
+
revision: args.revision,
|
|
1066
|
+
discardEdits: args.discardEdits,
|
|
1067
|
+
}, {
|
|
1068
|
+
cwd: process.cwd(),
|
|
1069
|
+
out,
|
|
1070
|
+
service: async (method, path, body) => {
|
|
1071
|
+
try {
|
|
1072
|
+
return await service(method, path, body);
|
|
1073
|
+
}
|
|
1074
|
+
catch (err) {
|
|
1075
|
+
return { error: errText(err) };
|
|
1076
|
+
}
|
|
1077
|
+
},
|
|
1078
|
+
readFile: (path) => readFileSync(resolvePath(process.cwd(), path)),
|
|
1079
|
+
readStdin,
|
|
1080
|
+
});
|
|
1001
1081
|
}
|
|
1002
1082
|
if (sub === "replay") {
|
|
1003
1083
|
return replayCommand({ ...args, scenarioId: args.scenarioId ?? target });
|
|
1004
1084
|
}
|
|
1005
|
-
out("usage: bir scenario <list|show|calc|replay> …");
|
|
1085
|
+
out("usage: bir scenario <list|show|calc|check|edit|edits|undo|editing|replay> …");
|
|
1006
1086
|
return 2;
|
|
1007
1087
|
}
|
|
1088
|
+
/**
|
|
1089
|
+
* All of stdin, for `--input-logic -`. A person at a terminal gets told how to
|
|
1090
|
+
* end it; a pipe never sees the line (it goes to stderr, and only on a TTY).
|
|
1091
|
+
*/
|
|
1092
|
+
function readStdin() {
|
|
1093
|
+
if (process.stdin.isTTY) {
|
|
1094
|
+
process.stderr.write("[bir] reading the logic from stdin — end it with Ctrl-D (Ctrl-Z, Enter on Windows)\n");
|
|
1095
|
+
}
|
|
1096
|
+
return new Promise((resolve, reject) => {
|
|
1097
|
+
const chunks = [];
|
|
1098
|
+
process.stdin.on("data", (chunk) => {
|
|
1099
|
+
chunks.push(typeof chunk === "string" ? Buffer.from(chunk, "utf8") : chunk);
|
|
1100
|
+
});
|
|
1101
|
+
process.stdin.on("end", () => resolve(Buffer.concat(chunks)));
|
|
1102
|
+
process.stdin.on("error", reject);
|
|
1103
|
+
});
|
|
1104
|
+
}
|
|
1008
1105
|
/**
|
|
1009
1106
|
* `--dry` evaluates the scenario's stored logic against the **source run's
|
|
1010
1107
|
* recorded outputs**, server-side: no real tools, no side effects, one Haiku
|
package/dist/bin/investigate.js
CHANGED
|
@@ -183,7 +183,7 @@ export const DECLINES = {
|
|
|
183
183
|
},
|
|
184
184
|
nondeterministic_first_step: {
|
|
185
185
|
cause: "the chain's first step needs a judgement the calculation could not write code for, so the plan cannot start.",
|
|
186
|
-
fix: "the
|
|
186
|
+
fix: "if its code only has a slip, fix the step yourself: read it with `bir scenario show <scnId> --step 0`, write the input logic to a file, and run `bir scenario edit <scnId> --step 0 --input-logic <file>`; the service checks it against the recording before it saves it. A real judgement — a choice with no fixed rule — stays with the agent until a model step exists (plan-services.md W3.1).",
|
|
187
187
|
},
|
|
188
188
|
unusable_first_step: {
|
|
189
189
|
cause: "the first step calls a sub-task that is gone, switched off or stale.",
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* scenario-edit — read, check, change and undo one step of a calculated
|
|
3
|
+
* scenario (editSteps.md in the BaseIn repository; docs/calculatedReplayGuide.md §9.2).
|
|
4
|
+
*
|
|
5
|
+
* bir scenario show <runId|scnId> [--step <n>]
|
|
6
|
+
* bir scenario check <runId|scnId> --step <n> [--input-logic <file|->] [--output-logic <file|->] [--unfreeze]
|
|
7
|
+
* bir scenario edit <runId|scnId> --step <n> [--input-logic <file|->] [--output-logic <file|->]
|
|
8
|
+
* [--freeze | --unfreeze] [--note "why"] [--force --note "why"] [--revision <n>]
|
|
9
|
+
* bir scenario edits <runId|scnId>
|
|
10
|
+
* bir scenario undo <runId|scnId> [--edit <sedit_id>]
|
|
11
|
+
* bir scenario calc <runId> [--force [--discard-edits]]
|
|
12
|
+
* bir scenario editing on|off|status
|
|
13
|
+
*
|
|
14
|
+
* WHY THIS IS A CLIENT AND NOTHING MORE. Whether a change may be saved is
|
|
15
|
+
* decided on the service, against the recording, by the calculation's own
|
|
16
|
+
* check (D3) — and `check` and `edit` are the same function there (D11). A
|
|
17
|
+
* runner-side pre-check would be a second opinion that can disagree with the
|
|
18
|
+
* one that counts, so this module reads logic from files, sends it, and says
|
|
19
|
+
* in words what the service answered. `--json` prints the answer unchanged,
|
|
20
|
+
* which is what the `bir` MCP server hands the model.
|
|
21
|
+
*
|
|
22
|
+
* Logic never comes from the command line itself. A JavaScript body is full
|
|
23
|
+
* of quotes, braces and `$`, and every shell mangles a different subset of
|
|
24
|
+
* them; a file, or stdin with `-`, arrives byte for byte.
|
|
25
|
+
*
|
|
26
|
+
* Everything the commands touch is injected ({@link ScenarioEditDeps}), as in
|
|
27
|
+
* `investigate.ts`, so all of it is tested in-process against a fake service.
|
|
28
|
+
* The exception is `editing`, which writes the install sidecar — tests point
|
|
29
|
+
* `BIR_HOME` at a temporary directory for that.
|
|
30
|
+
*/
|
|
31
|
+
export type InputStatus = "reproduces" | "differs" | "throws" | "copy" | "not_checked";
|
|
32
|
+
export interface EditReport {
|
|
33
|
+
ok: boolean;
|
|
34
|
+
stepIndex: number;
|
|
35
|
+
toolName: string | null;
|
|
36
|
+
/** The recording the change was checked against. */
|
|
37
|
+
sourceRunId: string;
|
|
38
|
+
verifiable: boolean;
|
|
39
|
+
input: {
|
|
40
|
+
changed: boolean;
|
|
41
|
+
before: InputStatus;
|
|
42
|
+
after: InputStatus;
|
|
43
|
+
computed?: unknown;
|
|
44
|
+
recorded?: unknown;
|
|
45
|
+
firstDifference?: {
|
|
46
|
+
at: number;
|
|
47
|
+
computed: string;
|
|
48
|
+
recorded: string;
|
|
49
|
+
};
|
|
50
|
+
error?: string;
|
|
51
|
+
};
|
|
52
|
+
output: {
|
|
53
|
+
changed: boolean;
|
|
54
|
+
status: "runs" | "throws" | "not_object" | "unchanged";
|
|
55
|
+
emittedKeys?: string[];
|
|
56
|
+
error?: string;
|
|
57
|
+
};
|
|
58
|
+
later: Array<{
|
|
59
|
+
stepIndex: number;
|
|
60
|
+
toolName: string | null;
|
|
61
|
+
before: InputStatus;
|
|
62
|
+
after: InputStatus;
|
|
63
|
+
regressed: boolean;
|
|
64
|
+
}>;
|
|
65
|
+
answer: {
|
|
66
|
+
informativeBefore: boolean;
|
|
67
|
+
informativeAfter: boolean;
|
|
68
|
+
} | null;
|
|
69
|
+
mark: {
|
|
70
|
+
before: MarkState;
|
|
71
|
+
after: MarkState;
|
|
72
|
+
};
|
|
73
|
+
problems: string[];
|
|
74
|
+
}
|
|
75
|
+
interface MarkState {
|
|
76
|
+
marked: boolean;
|
|
77
|
+
why: string | null;
|
|
78
|
+
}
|
|
79
|
+
export interface StepState {
|
|
80
|
+
toolInputLogic: string | null;
|
|
81
|
+
toolOutputLogic: string | null;
|
|
82
|
+
nondeterministic: boolean;
|
|
83
|
+
nondeterministicWhy: string | null;
|
|
84
|
+
editedAt: string | null;
|
|
85
|
+
editForced: boolean;
|
|
86
|
+
}
|
|
87
|
+
export interface EditEntry {
|
|
88
|
+
id: string;
|
|
89
|
+
scenarioId: string;
|
|
90
|
+
stepIndex: number;
|
|
91
|
+
kind: "edit" | "freeze" | "revert";
|
|
92
|
+
revertsEditId: string | null;
|
|
93
|
+
note: string | null;
|
|
94
|
+
forced: boolean;
|
|
95
|
+
chainRevisionBefore: number;
|
|
96
|
+
chainRevisionAfter: number;
|
|
97
|
+
before: StepState;
|
|
98
|
+
after: StepState;
|
|
99
|
+
report: EditReport | null;
|
|
100
|
+
createdAt: string;
|
|
101
|
+
/** A later undo put this one back. */
|
|
102
|
+
revertedAt: string | null;
|
|
103
|
+
/** A recalculation replaced the chain; the entry is history now. */
|
|
104
|
+
replacedAt: string | null;
|
|
105
|
+
}
|
|
106
|
+
export type ServiceReply = {
|
|
107
|
+
status: number;
|
|
108
|
+
body: unknown;
|
|
109
|
+
} | {
|
|
110
|
+
error: string;
|
|
111
|
+
};
|
|
112
|
+
export interface ScenarioEditDeps {
|
|
113
|
+
cwd: string;
|
|
114
|
+
out: (line?: string) => void;
|
|
115
|
+
/** An authenticated call to the service; a failure to reach it is `{ error }`, never a throw. */
|
|
116
|
+
service: (method: string, path: string, body?: unknown) => Promise<ServiceReply>;
|
|
117
|
+
/** A logic file's bytes. Relative paths are the caller's to resolve. */
|
|
118
|
+
readFile: (path: string) => Buffer;
|
|
119
|
+
/** All of stdin, for `--input-logic -` / `--output-logic -`. */
|
|
120
|
+
readStdin: () => Promise<Buffer>;
|
|
121
|
+
}
|
|
122
|
+
export interface ScenarioEditArgs {
|
|
123
|
+
/** The words after `bir scenario`: `[sub, target | on|off|status, …]`. */
|
|
124
|
+
positionals: string[];
|
|
125
|
+
json: boolean;
|
|
126
|
+
force: boolean;
|
|
127
|
+
step?: number;
|
|
128
|
+
/** A path, or `-` for stdin. */
|
|
129
|
+
inputLogic?: string;
|
|
130
|
+
outputLogic?: string;
|
|
131
|
+
freeze: boolean;
|
|
132
|
+
unfreeze: boolean;
|
|
133
|
+
note?: string;
|
|
134
|
+
/** `undo --edit`: the `sedit_` id to put back. */
|
|
135
|
+
edit?: string;
|
|
136
|
+
/** `--revision`: save only if the plan is still at this `chainRevision`. */
|
|
137
|
+
revision?: number;
|
|
138
|
+
discardEdits: boolean;
|
|
139
|
+
}
|
|
140
|
+
/** The `bir scenario` words this module answers; `list` and `replay` stay in bir.ts. */
|
|
141
|
+
export declare const SCENARIO_EDIT_SUBCOMMANDS: ReadonlySet<string>;
|
|
142
|
+
/** The `bir` MCP server's tools that only read: always offered (D2). */
|
|
143
|
+
export declare const READ_TOOLS: readonly ["scenario_show", "scenario_edits", "investigate"];
|
|
144
|
+
/** The ones that change a scenario: offered only after `bir scenario editing on` (D2). */
|
|
145
|
+
export declare const EDIT_TOOLS: readonly ["scenario_check", "scenario_edit", "scenario_undo"];
|
|
146
|
+
export declare function scenarioEditCommand(args: ScenarioEditArgs, deps: ScenarioEditDeps): Promise<number>;
|
|
147
|
+
/**
|
|
148
|
+
* A logic file's text. UTF-8, with a byte-order mark dropped — and UTF-16 with
|
|
149
|
+
* its mark decoded, because that is what `"…" > step.js` writes in Windows
|
|
150
|
+
* PowerShell 5.1, and a service answering "SyntaxError" to a file that looks
|
|
151
|
+
* fine in every editor is a riddle nobody should have to solve.
|
|
152
|
+
*/
|
|
153
|
+
export declare function decodeLogic(bytes: Buffer): string;
|
|
154
|
+
/**
|
|
155
|
+
* The report in the lines editSteps.md "What a person sees" shows:
|
|
156
|
+
* `input`, `output` (when the output logic changed), `later`, `answer` (when
|
|
157
|
+
* the final answer read anything before) and `mark`.
|
|
158
|
+
*/
|
|
159
|
+
export declare function renderReport(out: (line?: string) => void, r: EditReport): void;
|
|
160
|
+
/**
|
|
161
|
+
* About {@link CONTEXT} characters either side of `at`. A text already that
|
|
162
|
+
* short — a window the service cut itself, or a small call — is printed whole.
|
|
163
|
+
*/
|
|
164
|
+
export declare function around(text: string, at: number): string;
|
|
165
|
+
/**
|
|
166
|
+
* Undo puts one step back as it was before its newest edit (D9). Without
|
|
167
|
+
* `--edit`, that is the newest entry nothing has put back and no
|
|
168
|
+
* recalculation replaced — which is by construction the newest of its step.
|
|
169
|
+
* An undo is itself such an entry, so a second `undo` redoes.
|
|
170
|
+
*/
|
|
171
|
+
export declare function newestUndoable(edits: EditEntry[]): EditEntry | undefined;
|
|
172
|
+
export {};
|
|
173
|
+
//# sourceMappingURL=scenario-edit.d.ts.map
|