@basein/runner 0.3.3 → 0.3.5

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.
@@ -823,6 +823,18 @@ export function setEditing(sidecar, cwd, on) {
823
823
  return undefined;
824
824
  return setProjectRecord(sidecar, cwd, { port: record.port, editing: on });
825
825
  }
826
+ /**
827
+ * `bir setup`: scenario editing on for `cwd`, unless it was ever set — an
828
+ * `off` a person stored is theirs, and no setup turns it back on. Returns true
829
+ * when it was switched on now.
830
+ */
831
+ export function settleEditing(sidecar, cwd) {
832
+ const record = projectRecord(sidecar, cwd);
833
+ if (!record || record.editing !== undefined)
834
+ return false;
835
+ setProjectRecord(sidecar, cwd, { port: record.port, editing: true });
836
+ return true;
837
+ }
826
838
  /**
827
839
  * Keep this project's stored replay switch ({@link ReplayPolicy.enabled}) in
828
840
  * line with what the person asked for, so the recorder never steers — or runs
@@ -225,6 +225,12 @@ function isHookRoute(route) {
225
225
  function isPlanMode(payload) {
226
226
  return payload.permission_mode === "plan";
227
227
  }
228
+ /** The `bir` tools whose `force` saves (or undoes) what the scenario check refused. */
229
+ const FORCEABLE_BIR_TOOLS = new Set(["scenario_edit", "scenario_undo"].map((tool) => `mcp__${SCENARIO_SERVER_KEY}__${tool}`));
230
+ /** A `bir` call that forces a change past the check (see `onToolPre`). */
231
+ function forcedBirChange(toolName, input) {
232
+ return FORCEABLE_BIR_TOOLS.has(toolName) && input?.force === true;
233
+ }
228
234
  /**
229
235
  * Tool arguments as an older proxy reports them — redacted, long strings
230
236
  * clipped — for joining a report that carries no `argsFingerprint` of its own.
@@ -2266,6 +2272,20 @@ export class ControlServer {
2266
2272
  if (toolUseId)
2267
2273
  (run.housekeepingUses ??= new Set()).add(toolUseId);
2268
2274
  logDetail("tool.pre.skipped", { run: run.runId, tool: toolName, why: "host housekeeping" });
2275
+ // `bir setup` lets Claude Code run every `bir` tool without asking — but a
2276
+ // change saved or taken back with `force`, past the check that refused
2277
+ // it, is the person's decision (editSteps.md D3), so Claude Code asks
2278
+ // whatever the allow rule says. Not where the person chose to be asked
2279
+ // nothing at all.
2280
+ if (forcedBirChange(toolName, modelArgs) && payload.permission_mode !== "bypassPermissions") {
2281
+ return {
2282
+ hookSpecificOutput: {
2283
+ hookEventName: "PreToolUse",
2284
+ permissionDecision: "ask",
2285
+ permissionDecisionReason: "force saves what the scenario check refused — only for a recording that was itself wrong; you decide, not the model",
2286
+ },
2287
+ };
2288
+ }
2269
2289
  return {};
2270
2290
  }
2271
2291
  // What a cancelled direct run left this session to tell (see
@@ -1456,15 +1456,17 @@ are where `bir` changes a scenario by hand, so the rules are strict:
1456
1456
  - Exit codes: `0` checked OK, saved or undone; `1` refused, not found, or a service error; `2`
1457
1457
  usage. `--json` prints the service's body unchanged.
1458
1458
 
1459
- The same commands are tools on the `bir` MCP server, which by default lists only `run_scenario`:
1460
- every tool definition rides along with every request of every session. `scenario_show` (`target`,
1461
- `step`), `scenario_edits` (`target`) and `investigate` (`id`) only read; they are listed in a project
1462
- where `bir scenario editing on` was run, or with `BIR_SCENARIO_TOOLS=read` in the `bir` server's
1463
- environment, and answer a host that calls them unlisted all the same. `scenario_check` (`target`,
1464
- `step`, `inputLogic`, `outputLogic`, `unfreeze`), `scenario_edit` (the same, plus `freeze`, `force`,
1465
- `note`, `revision`) and `scenario_undo` (`target`, `edit` or `step`, `force`, `note`) are offered
1466
- only in a project where `bir scenario editing on` was run, because that server runs in every session
1467
- of every installed project. Each tool runs this package's own `bir … --json`, with logic bodies
1459
+ The same commands are tools on the `bir` MCP server. `scenario_show` (`target`, `step`),
1460
+ `scenario_edits` (`target`) and `investigate` (`id`) only read; `scenario_check` (`target`, `step`,
1461
+ `inputLogic`, `outputLogic`, `unfreeze`), `scenario_edit` (the same, plus `freeze`, `force`, `note`,
1462
+ `revision`) and `scenario_undo` (`target`, `edit` or `step`, `force`, `note`) change a scenario. All
1463
+ six are listed where scenario editing is on — `bir setup` turns it on, and adds `mcp__bir` to
1464
+ `permissions.allow` in `.claude/settings.local.json`, so Claude Code runs every `bir` tool without
1465
+ asking. Elsewhere — `bir scenario editing off`, which a later setup keeps, or a project wired by a
1466
+ bare `bir install` — the server lists `run_scenario` alone: it runs in every session of every
1467
+ installed project, and every listed tool's definition rides along with every request.
1468
+ `BIR_SCENARIO_TOOLS=read` in its environment lists the reading three there, and they answer a host
1469
+ that calls them unlisted all the same. Each tool runs this package's own `bir … --json`, with logic bodies
1468
1470
  passed through temporary files; a refusal comes back as an MCP error result carrying the report. A
1469
1471
  reading tool's answer is capped at 24 000 characters (`BIR_SCENARIO_MAX_OUTPUT_CHARS`) and gives up
1470
1472
  after `BIR_READ_TIMEOUT_MS` (15 s) plus 10 s; a changing tool gets 120 s. A call the host cancels, or
@@ -271,12 +271,14 @@ undoes both, leaving everything else as it is:
271
271
  - registers a first-party MCP server under the key **`bir`** in the local scope — `~/.claude.json`,
272
272
  under Claude Code's key for this project, never the `.mcp.json` a team commits (`--mcp-json` puts
273
273
  it there instead, pre-approved in `.claude/settings.local.json`, the older shape). It exposes
274
- `mcp__bir__run_scenario` — the channel a fully-wrapped scenario's results come back through — and
275
- by default nothing else. Three tools that only read a scenario (`scenario_show`,
276
- `scenario_edits`, `investigate`) are listed after `bir scenario editing on`, or with
277
- `BIR_SCENARIO_TOOLS=read` in the server's environment, and three for changing one
278
- (`scenario_check` tries a change, `scenario_edit` saves it, `scenario_undo` takes it back) only
279
- after `bir scenario editing on`. §9.2 lists them with their arguments; the editing it describes
274
+ `mcp__bir__run_scenario` — the channel a fully-wrapped scenario's results come back through. Three
275
+ tools that only read a scenario (`scenario_show`, `scenario_edits`, `investigate`) and three for
276
+ changing one (`scenario_check` tries a change, `scenario_edit` saves it, `scenario_undo` takes it
277
+ back) come with scenario editing: `bir setup` turns it on, and adds `mcp__bir` to
278
+ `permissions.allow` in `.claude/settings.local.json` so Claude Code runs every `bir` tool without
279
+ asking. A bare `bir install --replay` does neither: its server lists `run_scenario` alone until
280
+ `bir scenario editing on` (or `BIR_SCENARIO_TOOLS=read` in the server's environment, for the
281
+ reading three). §9.2 lists them with their arguments; the editing it describes
280
282
  is built but not yet released. From the next version, a call to any of them except
281
283
  `run_scenario` is never recorded. In a subdirectory or linked worktree of a git repository the
282
284
  server is not added — in the local scope it would apply to the whole repository — and replay
@@ -630,8 +632,9 @@ bir scenario show <runId|scnId> [--step <n>]
630
632
  bir scenario check <runId|scnId> --step <n> [--input-logic <file|->] [--output-logic <file|->] [--unfreeze]
631
633
  bir scenario edit <runId|scnId> --step <n> [--input-logic <file|->] [--output-logic <file|->]
632
634
  [--freeze | --unfreeze] [--note "<why>"] [--force --note "<why>"] [--revision <n>]
635
+ bir scenario edit <runId|scnId> --param <name> --kind target|setting [--note "<why>"] [--revision <n>]
633
636
  bir scenario edits <runId|scnId>
634
- bir scenario undo <runId|scnId> [--edit <sedit_id> | --step <n>] [--force --note "<why>"]
637
+ bir scenario undo <runId|scnId> [--edit <sedit_id|pedit_id> | --step <n> | --param <name>] [--force --note "<why>"]
635
638
  bir scenario calc <runId|scnId> [--force [--discard-edits]]
636
639
  bir scenario editing on|off|status
637
640
  ```
@@ -666,8 +669,9 @@ never take, is never reached in the check. A `fetch` inside a `try` fails in the
666
669
  code in its own process, with the global scope and only a time limit, where `fetch` and `process`
667
670
  do exist. So read every change before it is saved — yours and Claude's.
668
671
 
669
- **Only a step's code and its mark can be changed.** Not the parameters, not their sample values, not
670
- the logic that builds the final answer. Only tool steps: a sub-task call row belongs to the service.
672
+ **Only a step's code and its mark can be changed — and a parameter's kind (below, *A value no prompt names*).**
673
+ Not the parameters' sample values, not the logic that builds the final answer. Only tool steps: a
674
+ sub-task call row belongs to the service.
671
675
 
672
676
  #### The fix, step by step
673
677
 
@@ -1024,13 +1028,17 @@ check.
1024
1028
  1. **In its terminal.** Claude runs `bir scenario …` like any other command. You see each command,
1025
1029
  and Claude Code asks you before it runs one, unless you allowed it. This works in every project.
1026
1030
  2. **As tools on the `bir` MCP server** — the server `bir setup` or `bir install --replay` adds
1027
- (§5.2). This is smoother for the model. **By default the server lists only `run_scenario`:
1028
- every tool definition rides along with every request of every session. The tools that read and
1029
- change a scenario come when you turn editing on, per project:**
1031
+ (§5.2). This is smoother for the model. **`bir setup` turns scenario editing on, so the server
1032
+ lists every tool below, and Claude Code runs them without asking (`mcp__bir` in
1033
+ `permissions.allow`, `.claude/settings.local.json`) — except `scenario_edit` or `scenario_undo`
1034
+ with `force`: the recorder's `PreToolUse` answers `ask` for those, so the person decides whether
1035
+ a change goes past the check that refused it.** Every listed tool's definition rides along
1036
+ with every request of every session, so the switch is per project, and an `off` is kept by
1037
+ every later setup. A bare `bir install --replay` leaves it off: `run_scenario` alone.
1030
1038
 
1031
1039
  ```bash
1032
1040
  bir scenario editing on # this project's `bir` server also offers the tools that read and change a scenario
1033
- bir scenario editing off # back to run_scenario alone
1041
+ bir scenario editing off # back to run_scenario alone; a later `bir setup` keeps it off
1034
1042
  bir scenario editing status # what is stored for this project
1035
1043
  ```
1036
1044
 
@@ -1043,12 +1051,12 @@ The tools, as the `bir` server defines them. **Bold** arguments are required.
1043
1051
  | Tool (`mcp__bir__…`) | Offered | Arguments | Runs |
1044
1052
  |---|---|---|---|
1045
1053
  | `run_scenario` | always, unless the runner is off | none | the plan armed for this turn (§6.1) |
1046
- | `scenario_show` | after `bir scenario editing on`, or with `BIR_SCENARIO_TOOLS=read` | **`target`**, `step` | `bir scenario show` |
1047
- | `scenario_edits` | after `bir scenario editing on`, or with `BIR_SCENARIO_TOOLS=read` | **`target`** | `bir scenario edits` |
1048
- | `investigate` | after `bir scenario editing on`, or with `BIR_SCENARIO_TOOLS=read` | `id` — a `run_`, `scn_` or `sexec_` id; without it, the newest turn here | `bir investigate` |
1049
- | `scenario_check` | after `bir scenario editing on` | **`target`**, **`step`**, `inputLogic`, `outputLogic`, `unfreeze` | `bir scenario check` |
1050
- | `scenario_edit` | after `bir scenario editing on` | **`target`**, **`step`**, `inputLogic`, `outputLogic`, `freeze`, `unfreeze`, `force`, `note`, `revision` | `bir scenario edit` |
1051
- | `scenario_undo` | after `bir scenario editing on` | **`target`**, `edit` or `step` (not both), `force`, `note` | `bir scenario undo` |
1054
+ | `scenario_show` | with scenario editing on (`bir setup` turns it on), or with `BIR_SCENARIO_TOOLS=read` | **`target`**, `step` | `bir scenario show` |
1055
+ | `scenario_edits` | with scenario editing on, or with `BIR_SCENARIO_TOOLS=read` | **`target`** | `bir scenario edits` |
1056
+ | `investigate` | with scenario editing on, or with `BIR_SCENARIO_TOOLS=read` | `id` — a `run_`, `scn_` or `sexec_` id; without it, the newest turn here | `bir investigate` |
1057
+ | `scenario_check` | with scenario editing on | **`target`**, **`step`**, `inputLogic`, `outputLogic`, `unfreeze` | `bir scenario check` |
1058
+ | `scenario_edit` | with scenario editing on | **`target`**, and **`step`** with `inputLogic`, `outputLogic`, `freeze`, `unfreeze`, `force` — or **`param`** with **`kind`**; `note`, `revision` | `bir scenario edit` |
1059
+ | `scenario_undo` | with scenario editing on | **`target`**, one of `edit`, `step` or `param`, `force`, `note` | `bir scenario undo` |
1052
1060
 
1053
1061
  - `target` is a `scn_` id, or the `run_` id of a whole-run scenario. `step` is the `stepIndex`.
1054
1062
  - `inputLogic` and `outputLogic` are the code itself, as text. The server writes them to temporary
@@ -1095,6 +1103,59 @@ For the hiring-year case, Claude's report would be: *step 4's code is a copy of
1095
1103
  so it was marked; the new code builds the query from `summary_table`; the check says it reproduces
1096
1104
  the recording, and the step will run by itself.*
1097
1105
 
1106
+ #### A value no prompt names — `--param <name> --kind setting`
1107
+
1108
+ > Built 2026-09-28, **not yet released**: it needs the next service deploy, then the next
1109
+ > `@basein/runner` version. The design is `findoffer.md` and `editSteps.md` ("Parameter kinds") in
1110
+ > the BaseIn repository.
1111
+
1112
+ Every parameter of a plan is one of two kinds:
1113
+
1114
+ | Kind | Means | When the prompt does not name it |
1115
+ |---|---|---|
1116
+ | **target** | what the task acts on — a file, a table, a region | the plan is declined: `missing_target`. A target is never guessed |
1117
+ | **setting** | a value nobody states, the same every time — a database, a host, a working folder | the recorded value is used |
1118
+
1119
+ A prompt that names a value always wins, whatever its kind. The calculation decides the kinds, and
1120
+ it can get one wrong. The hiring-year plan `scn_09dbd4e6` never ran: its `database` was a target,
1121
+ and the MCPMark prompt never names the database — it is simply the one the agent is connected to.
1122
+ `bir investigate` names such a target: `declined … missing_target (database not named in the
1123
+ prompt)`.
1124
+
1125
+ **Do this.** Make it a setting, and say why:
1126
+
1127
+ ```bash
1128
+ bir scenario edit scn_09dbd4e6-… --param database --kind setting --note "The database is the connection; the prompt never names it."
1129
+ ```
1130
+
1131
+ **You should see:**
1132
+
1133
+ ```
1134
+ Parameter database: target → setting (revision 4). Undo: bir scenario undo scn_09dbd4e6-… --edit pedit_…
1135
+ When a prompt names no database, the runner now uses its recorded value ("hys_trial"); a prompt that names one still wins.
1136
+ ```
1137
+
1138
+ - `--kind setting` needs `--note`: it is the one change that lets a replay use a recorded value.
1139
+ `--kind target` does not.
1140
+ - No code runs, so nothing is checked. The revision goes up by one, as for a step edit.
1141
+ - **A recalculation keeps the kind** while the parameter keeps its name, so unlike a step edit it
1142
+ does not hold a recalculation back. When a recalculation drops the parameter, the change is
1143
+ history.
1144
+ - `bir scenario edits` lists it as `param database`, and `bir investigate` reports it on every run
1145
+ (`param_kind_edited`).
1146
+ - `bir scenario undo … --param database` takes it back. A plain `bir scenario undo` takes back the
1147
+ newest change, a step's or a parameter's.
1148
+ - The `scenario_edit` tool takes `param` and `kind` instead of `step`; `scenario_undo` takes `param`.
1149
+
1150
+ **If it goes wrong:**
1151
+
1152
+ | Symptom | Fix |
1153
+ |---|---|
1154
+ | `--kind setting needs --note "why" (note_required)` | Add `--note "why"` |
1155
+ | `Not saved (not_found): … has no parameter …` | Use a name that `bir scenario show <id>` lists under `parameters` |
1156
+ | `Nothing to change: database is already a setting.` | Nothing to do |
1157
+ | `A parameter's kind is not checked` | `check` runs code, and a kind has none. Use `bir scenario edit` |
1158
+
1098
1159
  #### When it does not work
1099
1160
 
1100
1161
  | Symptom | Cause | Fix |
@@ -1119,8 +1180,9 @@ the recording, and the step will run by itself.*
1119
1180
  | `payload_too_large` | The whole request is larger than the service accepts (HTTP 413, over 256 kB) | A logic body may be at most 20 000 characters, and a note 500 |
1120
1181
  | `rate_limited` | More checks, edits and undos in a minute than the service allows (`SCENARIO_EDITS_PER_MINUTE`, 30 by default) | Wait a minute |
1121
1182
  | `not found` for a scenario you can see | It is not yours. **Only the owner can change a scenario** — an admin gets `not found` too | Ask the owner |
1122
- | The `scenario_check`, `scenario_edit` and `scenario_undo` tools are missing | `bir scenario editing on` was not run in this project, or the session started before it | Run it here, then restart the session |
1123
- | Only `run_scenario` is listed; `scenario_show`, `scenario_edits` and `investigate` are missing | That is the default: the reading tools come with `bir scenario editing on`, or with `BIR_SCENARIO_TOOLS=read` in the server's environment | Either one, then restart the session. Or run the `bir scenario …` commands in the terminal |
1183
+ | The `scenario_check`, `scenario_edit` and `scenario_undo` tools are missing | Scenario editing is off here: `bir scenario editing off` was run (a later setup keeps it off), the project was wired by `bir install` rather than `bir setup`, or the session started before the switch | `bir scenario editing on` here (or `bir setup`), then restart the session |
1184
+ | Only `run_scenario` is listed; `scenario_show`, `scenario_edits` and `investigate` are missing | The same: the reading tools come with scenario editing, or with `BIR_SCENARIO_TOOLS=read` in the server's environment | Either one, then restart the session. Or run the `bir scenario …` commands in the terminal |
1185
+ | Claude Code asks before each `bir` tool | No `mcp__bir` in `permissions.allow`: the project was wired by `bir install`, or the rule was taken out | `bir setup` here adds it (`bir doctor` says when it is missing) |
1124
1186
  | The `bir` server lists no tools at all | The runner is off here (`bir off`, `bir off --here`, or `BIR_OFF=1` where Claude Code started) | `bir on` (or `bir on --here`), and the server tells the open session its list changed. For `BIR_OFF=1`, start Claude Code without it |
1125
1187
 
1126
1188
  ---
@@ -75,7 +75,9 @@ if it is, it stops and asks you to `cd` to the project and paste again. Then:
75
75
  ==> Wiring the project
76
76
  + chrome-devtools → bir-proxy (local scope, over the .mcp.json entry; upstream: npx)
77
77
  + bir → bir-scenario (calculated replay; local scope)
78
+ + scenario editing on: the bir server offers investigate and the scenario tools too (`bir scenario editing off` takes them away)
78
79
  + hooks → C:\work\repo\.claude\settings.local.json (control server on http://127.0.0.1:53411; the recorder starts itself with each session)
80
+ + mcp__bir → permissions.allow in the same file (Claude Code runs the bir tools without asking)
79
81
  + .claude/settings.local.json is listed in C:\work\repo\.git\info\exclude
80
82
 
81
83
  Wrapped 1 server.
@@ -86,6 +88,7 @@ Done. Recording and replay are on for C:\work\repo
86
88
  account you@example.com (https://api.bi2202.com)
87
89
  wrapped chrome-devtools
88
90
  replay on — direct execution allowed for: all wrapped (narrow it with `bir replay allow chrome-devtools`)
91
+ tools run_scenario, scenario_show, scenario_edits, investigate, scenario_check, scenario_edit, scenario_undo — Claude Code runs them without asking, except a forced change
89
92
  recorder started in the background (pid 1234) — it starts itself with every Claude Code session
90
93
  log C:\Users\you\.baseinstrunner\logs\3f9c1a2b7d4e5f60.log
91
94
 
@@ -104,8 +107,11 @@ is not changed;
104
107
  *replay* says which of them a calculated scenario may call unattended — narrow
105
108
  it with `bir replay allow <names>`, turn it off with `bir replay off`, and read
106
109
  [calculatedReplayGuide.md §5.1](calculatedReplayGuide.md) before leaving it wide
107
- anywhere that matters; *recorder* is the background process, and *log* is where
108
- its audit lines go.
110
+ anywhere that matters; *tools* is what the `bir` MCP server gives Claude here —
111
+ every tool, and Claude Code runs them without asking, except a change forced
112
+ past the scenario check (`bir scenario editing off` leaves `run_scenario` alone,
113
+ and a later setup keeps it that way); *recorder* is
114
+ the background process, and *log* is where its audit lines go.
109
115
 
110
116
  A project with no MCP servers in any scope — none in `.mcp.json`, and none for
111
117
  this project or your user in `~/.claude.json` — shows `wrapped (no MCP servers
@@ -190,12 +196,12 @@ its prompt, its tool calls and its final answer.
190
196
  |---|---|
191
197
  | `~/.baseinstrunner/config.json` | the service address; `BIR_AUTH_URL` in the environment overrides it, and `bir setup` warns when the two differ |
192
198
  | `~/.baseinstrunner/credentials.json` | the cached session, bound to the service that issued it |
193
- | `~/.baseinstrunner/installed.json` | what `bir uninstall` needs to undo each change — the original text of the project files it rewrote, with their credential values left out — and each project's port, token and replay switches, and whether Claude's `bir` tools may change scenarios there (`bir scenario editing on`) |
199
+ | `~/.baseinstrunner/installed.json` | what `bir uninstall` needs to undo each change — the original text of the project files it rewrote, with their credential values left out — and each project's port, token and replay switches, whether Claude's `bir` tools may change scenarios there (`bir setup` turns it on, `bir scenario editing off` turns it off), and the permission rule setup added |
194
200
  | `~/.baseinstrunner/logs/<key>.log` | the recorder's audit log, one file per project |
195
201
  | `~/.baseinstrunner/node/` | a private Node, only if the machine had no usable one; not on PATH |
196
202
  | `~/.baseinstrunner/npm/` | the runner package |
197
203
  | `~/.baseinstrunner/bin/` | the `bir` and `bir-hooks` launchers, first on your user PATH |
198
- | `<project>/.claude/settings.local.json` | Claude Code's hooks for this project. Yours, not the team's: it carries this project's token and an absolute Node path |
204
+ | `<project>/.claude/settings.local.json` | Claude Code's hooks for this project, and `mcp__bir` in `permissions.allow` so the `bir` server's tools run without asking. Yours, not the team's: it carries this project's token and an absolute Node path |
199
205
  | `~/.claude.json` (`$CLAUDE_CONFIG_DIR/.claude.json` when that is set), this project's local scope | a copy of each MCP server it wraps, under the same name, running through `bir-proxy`; plus the `bir` scenario server. The copy takes precedence in this project only; `.mcp.json` and your user-scope servers are not changed |
200
206
  | `<project>/.git/info/exclude` | one line, `.claude/settings.local.json`, so it never shows in `git status` |
201
207
 
@@ -363,12 +369,16 @@ The saved code runs on your machine without asking you, like the code the
363
369
  calculation wrote. The check only tests what it sends for the recording's
364
370
  values. So read the code before it is saved, yours or Claude's.
365
371
 
366
- Claude can do this for you. Ask it in the session; it runs the same commands,
367
- and Claude Code asks you before each one, unless you allowed it. Or run
368
- `bir scenario editing on` in the project folder and restart Claude Code: the
369
- `bir` server then also offers the tools that read and change a scenario (by
370
- default it offers only `run_scenario`). These `bir` calls
371
- are never recorded as part of your task.
372
+ Claude can do this for you. Ask it in the session: `bir setup` gave the `bir`
373
+ server the tools that read and change a scenario, and Claude Code runs them
374
+ without asking you. The service still refuses a change that breaks the
375
+ recording, and a change Claude wants to force past that check (`force`) is
376
+ still yours to approve: Claude Code asks you first. `bir scenario edits` shows
377
+ what Claude changed; `bir scenario undo` takes it back. `bir scenario editing off` in the project
378
+ folder takes those tools away (restart Claude Code after), and a later
379
+ `bir setup` leaves them off; Claude can still run the same commands in its
380
+ terminal, and Claude Code then asks you before each one. These `bir` calls are
381
+ never recorded as part of your task.
372
382
 
373
383
  ---
374
384
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@basein/runner",
3
- "version": "0.3.3",
3
+ "version": "0.3.5",
4
4
  "description": "A recording MCP proxy: sits between any MCP client and its MCP servers, executes each call on the client's behalf, and records the run as a reusable BaseIn scenario.",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/production.md CHANGED
@@ -635,7 +635,7 @@ Truncation is always marked with the original size.
635
635
 
636
636
  ### 6.8 The `bir` MCP server (`src/bin/bir-scenario.ts`, `scenario-liveness.ts`, `service-read.ts`)
637
637
 
638
- **Tools listed.** `tools/list` returns only `run_scenario` by default. The read tools come with `bir scenario editing on` or `BIR_SCENARIO_TOOLS=read`, because every listed tool's definition rides along with every request of every session.
638
+ **Tools listed.** `tools/list` returns every tool where scenario editing is on, which `bir setup` turns on (it also adds `mcp__bir` to `permissions.allow` in `.claude/settings.local.json`, so Claude Code runs them without asking — except `scenario_edit` or `scenario_undo` with `force`, which the recorder's `PreToolUse` answers with `ask` unless the session is in `bypassPermissions` mode). Where it is off — `bir scenario editing off`, which a later setup keeps, or a project wired by a bare `bir install` — it returns only `run_scenario`, and the read tools come with `BIR_SCENARIO_TOOLS=read`, because every listed tool's definition rides along with every request of every session.
639
639
 
640
640
  **`run_scenario`.**
641
641
 
@@ -678,7 +678,7 @@ Truncation is always marked with the original size.
678
678
  | The direct plan budget is 100 s (was 120 s), and direct runs are clamped to 270 s. | Keeps a direct run under Claude Code's 2-minute auto-background of an MCP call, and inside `run_scenario`'s client timeout. | `BIR_REPLAY_PLAN_BUDGET_MS=120000` (or `BIR_REPLAY_BUDGET_MS`). |
679
679
  | The background recorder ignores an inherited `ANTHROPIC_API_KEY` for derivation. | That key is Claude Code's, so derivation billed the user's own account. | `BIR_DERIVE_API_KEY=<key>`, or `BIR_USE_ANTHROPIC_API_KEY=1`. A `bir-hooks` run by hand still uses the terminal's key. |
680
680
  | `run_scenario` never returns `isError`. | An error result makes the model retry or report a failure the user cannot act on. The reason is in `scenario.answered`. | `BIR_SCENARIO_DEBUG=1`. |
681
- | The `bir` server lists only `run_scenario`. | Tool definitions ride along with every request. | `BIR_SCENARIO_TOOLS=read`, or `bir scenario editing on`. |
681
+ | A bare `bir install` leaves the `bir` server listing only `run_scenario`, and adds no permission rule. | Tool definitions ride along with every request, and a fleet wired by hand must not have its plans changed by an agent. `bir setup` turns both on. | `bir scenario editing on` (or `BIR_SCENARIO_TOOLS=read` for the read tools), and `mcp__bir` in `permissions.allow`. |
682
682
  | The `run_scenario` client timeout is 290 s (was 180 s). | It stays under Claude Code's 5-minute MCP idle timeout, above the direct-run worst case. | `BIR_SCENARIO_RUN_TIMEOUT_MS=180000`. |
683
683
  | `bir-proxy` exits when its upstream dies. | Claude Code then shows the server as failed and offers a reconnect, as unwrapped. Staying up left tools listed that only answered errors. | `BIR_PROXY_STAY_UP=1`. |
684
684
  | Proxy stderr is quiet: routine lines only with verbose logging. | Claude Code files every stderr line as a "Server stderr" error. | `BIR_VERBOSE=1`. |