@robota-sdk/agent-subagent-runner 3.0.0-beta.99 → 3.0.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.
Files changed (2) hide show
  1. package/CHANGELOG.md +621 -1
  2. package/package.json +6 -6
package/CHANGELOG.md CHANGED
@@ -1,5 +1,625 @@
1
1
  # @robota-sdk/agent-subagent-runner
2
2
 
3
+ ## 3.0.1
4
+ ### Patch Changes
5
+
6
+ - @robota-sdk/agent-core@3.0.1
7
+ - @robota-sdk/agent-executor@3.0.1
8
+ - @robota-sdk/agent-framework@3.0.1
9
+ - @robota-sdk/agent-interface-execution@3.0.1
10
+ - @robota-sdk/agent-process@3.0.1
11
+
12
+ ## 3.0.0
13
+ ### Major Changes
14
+
15
+ - 807d161: **BREAKING — ARCH-010: the execution root is a required contract field, and the containment guard now fails closed.**
16
+
17
+ The file-tool containment guard was fail-open: with no root configured it answered "allowed". A tool
18
+ built with no `cwd` therefore had no boundary — measured, a `Read` constructed that way returned the
19
+ contents of `/etc/hostname` — and the child-process subagent worker called `createDefaultTools()` with
20
+ no argument at all, so subagents got exactly that. Three independent auditors found three different
21
+ symptoms of this one missing field.
22
+
23
+ **Removed — seven context-free tool singletons.** `readTool`, `writeTool`, `editTool`, `globTool`,
24
+ `grepTool`, `shellTool`, `bashTool` are gone from `@robota-sdk/agent-tools`. A module-level instance is
25
+ bound at import time and can carry no containment root, so after the guard was inverted they could only
26
+ refuse everything.
27
+
28
+ Migrate to the factory of the same name, passing the directory the tool is allowed to work in:
29
+
30
+ ```ts
31
+ // before
32
+ import { readTool, globTool } from '@robota-sdk/agent-tools';
33
+ const tools = [readTool, globTool];
34
+
35
+ // after
36
+ import { createReadTool, createGlobTool } from '@robota-sdk/agent-tools';
37
+ const cwd = process.cwd(); // or the workspace this agent is scoped to
38
+ const tools = [createReadTool({ cwd }), createGlobTool({ cwd })];
39
+ ```
40
+
41
+ `webFetchTool`, `webSearchTool` and `askUserQuestionTool` are unchanged — they touch no filesystem, so
42
+ there is no root to contain them by.
43
+
44
+ **`cwd` is now REQUIRED** on `ISandboxToolOptions`, `IContainedBuiltinToolOptions` (and everything
45
+ extending them), `ICreateDefaultToolsOptions`, `ISessionOptions` and `ISubagentOptions`. The `= {}`
46
+ default parameter was removed from every builtin factory — that default was the mechanism by which
47
+ "forgot the root" was legal. `new Session({...})` without `cwd` no longer compiles, and also throws at
48
+ construction, because a required field is only required to a TypeScript caller.
49
+
50
+ **`Session` no longer reads `process.cwd()`.** It uses the root it was given, and `getCwd()` exposes it
51
+ so a fork or subagent asks the session instead of re-deriving a root that can disagree with it.
52
+
53
+ **Behavioural change even for callers that already passed a root**: a tool that somehow reaches the
54
+ guard with no root now REFUSES with an explicit error ("no containment root is configured … this is an
55
+ assembly bug, not a path problem") instead of allowing the access.
56
+ - 0c07176: **BREAKING — ARCH-021: child-process subagents compose the PRODUCT's surface, not imported defaults.**
57
+
58
+ The child-process worker built its surface from `createDefaultProviderDefinitions()` and `createDefaultTools()` — a fixed six-vendor registry and the framework's default tool tier — while the composition root had already handed the runner the fully composed surface and the runner dropped it. So a product's custom providers and pack-contributed tools reached an **in-process** subagent and not a **child-process** one, and ARCH-006's landed invariant "every tool the configured CLI runs comes from a pack" was **false in the child**: dropping a pack did not drop its tools.
59
+
60
+ This is the second finding at that line. ARCH-010 — judged BLOCKER, a subagent `Read` returning `/etc/hostname` — patched one argument there and left the reconstruction standing.
61
+
62
+ ```ts
63
+ // the port: what the product composes, stated by the composition root
64
+ export interface ISubagentWorkerComposition {
65
+ createTools(context: { readonly cwd: string }): IToolWithEventService[];
66
+ readonly providerDefinitions: readonly IProviderDefinition[];
67
+ }
68
+
69
+ export function runSubagentWorkerMain(composition: ISubagentWorkerComposition): void;
70
+ ```
71
+
72
+ **Why a recipe and not a broker.** A composition cannot be projected across a process boundary because it is _code_: `createProvider` is a function and a tool carries `execute`. The two sound answers are to proxy the instances or to stop expressing the contract as instances. Proxying loses on containment — a proxied tool executes in the **parent**, bound to the parent's checkout, while a worktree-isolated child's execution root is a different directory — and a prior-art sweep found **no specification that defines a per-call working root for a proxied tool invocation** (MCP roots are session-scoped and pull-based). So the recipe crosses and the child builds an equivalent surface at its own root, which is what every comparable product does.
73
+
74
+ **Per package, classified against each barrel:**
75
+
76
+ - **`agent-subagent-runner` (major)** — `runSubagentWorkerMain` gains a **required** parameter; `ISubagentWorkerComposition` is added to the barrel; `ISubagentWorkerReadyMessage` gains `composedToolNames?`; and the `@robota-sdk/agent-provider-defaults` **dependency edge is removed**.
77
+ - **`agent-cli` (patch)** — composition-root wiring plus one new internal `product/` module; no barrel change.
78
+
79
+ **The structural guarantee reaches one axis, and the document says so.** Deleting the manifest edge makes the **provider** axis a compile error, because that package solely owns `createDefaultProviderDefinitions`. The **tool** axis cannot be cut the same way: `createDefaultTools` is barrel-exported by `agent-framework`, which this package must keep for `createSubagentSession`. That axis is held by a new `harness:scan` check instead — and it is the axis with the failure history, so claiming compile-time enforcement across both would have been an overclaim exactly where it matters. The cause (no defaults-aggregator leaf for the tool surface) is tracked as ARCH-035.
80
+
81
+ **Fail closed on what a recipe cannot reproduce.** A recipe carries anything that is a pure function of (execution root, serialized payload, ambient durable state) — not a live, unrepeatable handle. Today that is `sandboxClient`, and it is reachable with public code (`E2BSandboxClient` and `InMemorySandboxClient` are both on `agent-tools`' barrel). The composition root now **refuses** to select the child-process runner in that case, naming the capability, rather than yielding a sandboxed parent with a host-tool child. Projection is tracked as ARCH-033.
82
+
83
+ **Verified per run, not by construction.** The child declares its composed tool names in `ready`, so the built binary can be asked what it actually composed. Measured on the real artifact: `["Shell","Bash","Read","Write","Edit","Glob","Grep","WebFetch","WebSearch","AskUserQuestion"]` — `pack-coding`'s surface, from the product's own packs.
84
+
85
+ **Also filed rather than folded in:** ARCH-034 (in-process and child-process subagents get different tool surfaces), ARCH-036 (`deps.builtInAgents` is dropped by the child-process path), SEC-009 (`apiKey` rides in the IPC start payload; comparable products use the child's environment).
86
+ - 4772067: **BREAKING — ARCH-031: the subagent seam is derived from its transport SSOT instead of copied.**
87
+
88
+ One field family — what a subagent job IS — was declared three times as independent shapes and carried
89
+ between them by six hand-written object literals that nothing checked for totality. A field added to
90
+ either side had to be hand-copied at every hop, and a miss compiled clean as a silent no-op. TYPE-003
91
+ named this cause and derived one hop; the next two changes each dropped a field at a hop it had skipped
92
+ (CORE-025's permission policy, and ANALYTICS-001's `usage`, dropped in the very commit that added it).
93
+
94
+ ```ts
95
+ // now, in @robota-sdk/agent-interface-transport
96
+ export type ISubagentSpawnRequest = Omit<IAgentBackgroundTaskRequest, 'kind'>;
97
+ export type ISubagentJobResult = Omit<IBackgroundTaskResult, 'kind' | 'exitCode' | 'signalCode'>;
98
+ ```
99
+
100
+ All four projections collapse to spreads. `parentTaskId` and `providerProfile` now reach the runner
101
+ because they exist on the source, not because someone remembered them.
102
+
103
+ **Per package, classified against each barrel:**
104
+
105
+ - **`agent-executor` (major)** — the barrel loses `ISubagentSpawnRequest` and `ISubagentJobResult` (they
106
+ moved to their owner; re-publishing them here would be a pass-through re-export). `ISubagentJobStart`
107
+ and `ISubagentJobHandle` rename `jobId` → `taskId`, `ISubagentJobStart` gains `worktree?`, and
108
+ `ISubagentWorktreePrepareRequest` renames `jobId` → `taskId`.
109
+ - **`agent-framework` (major)** — the barrel loses eleven type-only re-exports of `agent-executor`-owned
110
+ types. They carried zero runtime values, so they bought none of the assembly convenience a runtime
111
+ facade exists for, while making one field family look like it had three owners. Separately,
112
+ `ISpawnAgentTaskRequest.permissionPolicy` goes optional → **required**.
113
+ - **`agent-subagent-runner` (major)** — `ISubagentWorkerStartPayload` renames `jobId` → `taskId` and gains
114
+ `worktree?`. This package is not in the item's declared `area:`; the audit that caught it is the reason
115
+ it is here.
116
+ - **`agent-interface-transport` (minor)** — two new barrel exports; nothing removed or renamed.
117
+ - **`agent-core` (minor)** — **two** new barrel exports. `DEFAULT_BACKGROUND_PERMISSION_POLICY` is the
118
+ intended one; collapsing the hand-listed permissions block to `export *` also surfaced
119
+ `clearRegisteredToolArgumentKeys`, which the old list had omitted. It is documented as public rather
120
+ than re-narrowed — a barrel that cannot fall out of step with its owner is the point of the collapse.
121
+ Nothing was removed: all nine previously-listed permission types remain on the barrel.
122
+ - **`agent-cli` (patch)** — migrated as the only in-repo implementer of `ISubagentWorktreeAdapter`; no
123
+ barrel change.
124
+
125
+ **`permissionPolicy` is now required at the spawn boundary**, and its default is one exported constant
126
+ owned by the permission SSOT. It was previously applied as `?? 'inherit-allowlist'` in the middle of a
127
+ projection, in **two** packages independently, with nothing keeping them equal — a security-relevant value
128
+ whose default was declared twice. Every spawn site now states its own policy.
129
+
130
+ **The worktree identity moved to the runner envelope.** It is runner-produced — the worktree does not
131
+ exist when a caller builds a request — so it rides on `ISubagentJobStart.worktree` and crosses the IPC
132
+ boundary there. The runner no longer also rewrites `request.cwd`, which had given ARCH-010's execution-root
133
+ rule two carriers that could disagree. `branchName` **relocated rather than being deleted**: it has no
134
+ reader in this repository today, and for a library that is not a reason to drop a legitimate contract.
135
+
136
+ **Renames are consistent across the SPI** (`type` → `agentType`, `jobId` → `taskId`) rather than applied to
137
+ one shape, which would have left two names for one identifier in a single file. The IPC validator's
138
+ string-literal keys are now typed against the contract, so the next rename is a compile error instead of a
139
+ runtime rejection of every start payload.
140
+ - 6fab98f: **BREAKING — DIST-006: the built `configured CLI` binary could not spawn a subagent at all.**
141
+
142
+ `/agent run` failed on every distributed build with `Subagent worker exited before result: exit code 1`. The child's real stderr was `Cannot find module '…/agent-cli/dist/node/child-process-subagent-worker.js'`. `getDefaultSubagentWorkerPath()` resolved the worker relative to its own `import.meta.url`; INFRA-028 bundles every workspace package into `agent-cli/dist/node/bin.js`, so at runtime that directory is **agent-cli's** dist, where the worker was never emitted. It worked from source, which is why nothing caught it.
143
+
144
+ **Second occurrence of one cause.** `agent-subagent-runner/tsdown.config.ts` already carried a comment naming this exact failure: _"Without this entry the file never existed, so the child-process subagent silently failed from any dist build."_ That fix put the worker next to its OWN package's bundle; bundling then moved the resolver's notion of "next to me" one package along.
145
+
146
+ **The defect was the function, not the missing file.** `getDefaultSubagentWorkerPath()` answered _"where is my worker file on disk?"_ from a library that cannot know — the answer is a property of the packaging step. Emitting the file where the resolver looks would have fixed **one of three shipped artifacts**: the npm bundle, but not the Bun single-file binaries published on every tag, nor the Electron desktop sidecar that embeds them. A compiled single-file executable has no sibling directory to emit into.
147
+
148
+ ```ts
149
+ // removed — a question no library can answer
150
+ export function getDefaultSubagentWorkerPath(): string;
151
+
152
+ // now: the composition root states how to start a copy of ITSELF
153
+ export interface ISubagentWorkerEntry {
154
+ readonly execPath: string;
155
+ readonly args: readonly string[];
156
+ readonly execArgv?: readonly string[];
157
+ }
158
+ ```
159
+
160
+ `IChildProcessSubagentRunnerOptions.workerPath` → **`workerEntry`**, and the runner `spawn`s `execPath args… --__agent-subagent-worker` instead of forking a module path. `configured CLI`'s own entry enters worker mode through the new `runSubagentWorkerMain()`, so **there is no second artifact and no path to get wrong**. The one seam satisfies all three shapes: a bundled Node build names the file it is executing, a `tsx` source run names the same and adds `--import tsx`, and a compiled binary names _nothing_ — `process.execPath` is the binary, and re-executing it re-enters its embedded entry.
161
+
162
+ **Per package, classified against each barrel:**
163
+
164
+ - **`agent-subagent-runner` (major)** — the barrel loses `getDefaultSubagentWorkerPath` (deleted, not renamed) and gains `SUBAGENT_WORKER_MODE_FLAG`, `isSubagentWorkerModeArgv`, `runSubagentWorkerMain`, `ISubagentWorkerEntry`. `IChildProcessSubagentRunnerOptions` renames `workerPath` → `workerEntry` and drops `execArgv` — it now has exactly one owner, on the entry descriptor. The separate `child-process-subagent-worker` bundle entry is gone.
165
+ - **`agent-cli` (patch)** — composition-root wiring only; no barrel change.
166
+
167
+ **Two things this also repairs, both found in review:**
168
+
169
+ - **The child's stderr was discarded** (`stdio: [..., 'ignore', 'ipc']`), so a worker that died before its first IPC message reported only an exit code. That is why occurrence #2 had to be diagnosed by hand. It is now captured, bounded, and appended to the error, making the next occurrence self-reporting.
170
+ - **A source run executed the BUILT worker, not the source worker**, because package `exports` resolve to `dist`. `resolveExecArgv`'s `--import tsx` branch was therefore dead code. Self-fork names the entry actually running, so source runs finally run source.
171
+
172
+ **Verified against the artifacts, not from source:** the built `dist/node/bin.js` and a real `bun --compile` single-file binary each complete the worker IPC handshake (`{type:'ready'}`), each refuse a hand-typed flag with no IPC channel (exit 2, "Silence is not success" — measured on both), and the shipped bundle no longer contains the string `child-process-subagent-worker.js` — there is nothing left to look for.
173
+
174
+ ### Minor Changes
175
+
176
+ - 9c19c50: `/fork [name] [--same-dir]` copies the live conversation into a background session.
177
+
178
+ The session writes a copy of its own record under a fresh id — messages, system prompt, tool schemas
179
+ and full history, and deliberately not the sandbox snapshot, goal, plan or branch — then spawns a
180
+ background job carrying only `resumeSessionId`. The child restores that record itself, so no
181
+ conversation crosses the child-process boundary and the worker start payload's key set is unchanged.
182
+ The background panel gains an `attach` control that switches the terminal onto the forked session; it
183
+ is a view switch, never a merge, and a missing record or a terminal task is refused with the task's
184
+ own status.
185
+
186
+ **`@robota-sdk/agent-framework` is `major` for one reason: `ICommandHostSessionAccess` gains a
187
+ required member.** `forkSession({ name? })` is not optional, so an external implementation of that
188
+ role port stops compiling until it adds the method. Every other change in this set is additive:
189
+
190
+ - `agent-interface-execution` — `TExecutionControl` gains `'attach'`.
191
+ - `agent-interface-command` — `TCommandUiIntent` gains `{ type: 'switch-session'; sessionId }`.
192
+ - `agent-subagent-runner` — `ISubagentWorkerComposition` gains the optional `openSessionStore`, and
193
+ the worker resumes a record when the job names one. A composition that registers no store and
194
+ receives no `resumeSessionId` behaves exactly as before.
195
+ - `agent-framework` also gains the fork-record builder, `SessionTurnMemory`, and
196
+ `IAgentBackgroundTaskRequest.resumeSessionId?`; `loadSessionRecord` now returns
197
+ `restoredSystemPrompt`, which makes a record field that was written and never read take effect on
198
+ restore.
199
+ - `agent-executor`, `agent-command`, `agent-transport-tui`, `agent-cli` — the spawn input, the
200
+ `/fork` module and the attach control that carry it to the surface.
201
+ - 1698be4: A child-process subagent can no longer send the parent's provider credential to a different
202
+ endpoint.
203
+
204
+ - **Before spawning a child**, the parent compares every environment variable that decides where
205
+ the provider connects or which credential it sends. If the child's environment differs, the job
206
+ is refused before the credential leaves the parent. The error names the variable, never its
207
+ value. The variables compared are:
208
+ - the proxy and TLS variables;
209
+ - the variables the provider's SDK reads, such as `OPENAI_BASE_URL`, `ANTHROPIC_AUTH_TOKEN` and
210
+ the Vertex settings;
211
+ - the credential's own variable.
212
+ - **The child** repeats the check before it builds its provider. It builds that provider from the
213
+ parent's effective connection exactly: it no longer fills in a base URL, options or a default
214
+ credential from its own registry, and a credential reference that resolves to nothing is refused.
215
+ - **Where the effective connection comes from:** the parent applies its own definition defaults
216
+ (base URL, options). `profileName` is sent only when it names the connection actually sent.
217
+ - **New contracts:**
218
+ - `IProviderDefinition.destinationEnvironment`, declared by every built-in provider.
219
+ - `createProviderFromExactProfile`, `connectionEnvironmentNames`,
220
+ `findConnectionEnvironmentDivergence`, `sealConnectionEnvironment`,
221
+ `verifyConnectionEnvironment` and `TRANSPORT_ENVIRONMENT`.
222
+ - The start payload's `connectionCheck`.
223
+ - The child-process runner's `providerDefinitions` option, now required: a provider with no
224
+ definition there is refused, because its connection cannot be checked.
225
+ - e8779c9: A subagent consults the sandbox its shell tools run under, as its parent does. With
226
+ `autoAllowBashIfSandboxed` on, a confined command the subagent's gate leaves to the mode now runs
227
+ without a prompt. Before, a `context: fork` skill asked for approval, and a print run refused it.
228
+ An Agent-tool subagent in `auto` mode sent a command allowed by a broad rule like `Bash(npm *)` to
229
+ its classifier instead. A background policy's ceiling is still checked first: nothing outside it
230
+ runs.
231
+
232
+ - `agent-framework` (minor): `createSubagentSession` takes a `commandSandbox` option. The fork and the
233
+ in-process runner derive it from the parent's sandbox, the instance their inherited tools run
234
+ under. `sandboxApprovalFor` is exported.
235
+ - `agent-subagent-runner` (minor): `ISubagentWorkerComposition` takes an optional `createSandbox`. The
236
+ worker builds that sandbox once and hands the same instance to `createTools` and to the session.
237
+ - `agent-cli` (patch): the configured product's worker composition builds the OS sandbox through `createSandbox`, so
238
+ a child-process subagent approves what its parent approves.
239
+ - 122e82b: A child-process subagent confines and approves commands with its parent's sandbox settings as they
240
+ stand when it starts. Before, it read its root's settings files, so a `/sandbox` change made in the
241
+ session did not reach it. `/sandbox` changes the live sandbox and only the user settings file, which
242
+ project settings outrank. A worktree child also missed the parent's untracked local settings.
243
+
244
+ - `agent-subagent-runner` (minor): the runner factory takes `parentSandboxSettings`, read at each
245
+ spawn. The start payload carries it, the IPC guard checks it is a record, and the worker hands it to
246
+ `createSandbox` as `parentSettings`.
247
+ - `agent-cli` (patch): the configured CLI sends its live sandbox's settings, and a child builds its sandbox from
248
+ them. It refuses settings it cannot read rather than falling back to the files.
249
+ - 0368058: A running child-process subagent follows a `/sandbox` change made in its parent session. Before, it
250
+ kept the settings it started with until it ended, so a long-running `auto`-mode subagent went on
251
+ auto-approving confined commands after the user turned auto-allow off.
252
+
253
+ - `agent-tools` (minor): `OsSandboxClient.watchSettings(watcher)` reports each `configure`, until
254
+ its returned function is called.
255
+ - `agent-subagent-runner` (minor): the runner factory takes `watchParentSandboxSettings`, and
256
+ forwards each change to every running child as a `sandbox_settings` message. It watches before
257
+ reading the start payload, so no change is lost while a child starts, and stops when the child
258
+ exits or fails to start. A composed sandbox may define `applyParentSettings`. The worker applies
259
+ each change through it. On settings it cannot take, it aborts the run, lets a running command
260
+ finish, and ends the run with that error.
261
+ - `agent-cli` (patch): the configured CLI watches its live sandbox, and a child applies each change to the
262
+ instance its tools and approval read.
263
+ - 7937c19: Split the `@robota-sdk/agent-provider` monolith into SDK-aligned leaf packages (ARCH-PROVIDER-002 Stage A). The single package that hard-bundled all three vendor SDKs (`@anthropic-ai/sdk`, `openai`, `@google/genai`) is **removed** and replaced by per-vendor leaves, each depending only on `@robota-sdk/agent-core` + its one SDK: `@robota-sdk/agent-provider-anthropic`, `@robota-sdk/agent-provider-openai`, `@robota-sdk/agent-provider-openai-compatible` (DeepSeek/Qwen/Gemma over the shared OpenAI-compatible base), `@robota-sdk/agent-provider-gemini` (+ a `./google` entry), and `@robota-sdk/agent-provider-bytedance` (media/video `IVideoGenerationProvider`). The aggregated `createDefaultProviderDefinitions()` now lives in the new `@robota-sdk/agent-builtin-providers` leaf.
264
+
265
+ Migration: replace `@robota-sdk/agent-provider/<vendor>` imports with the corresponding `@robota-sdk/agent-provider-<vendor>` package (`/deepseek`, `/qwen`, `/gemma` → `@robota-sdk/agent-provider-openai-compatible`; `/google` → `@robota-sdk/agent-provider-gemini/google`), and import `createDefaultProviderDefinitions` from `@robota-sdk/agent-builtin-providers`. Consumers now pull only the vendor SDK(s) they actually use.
266
+ - c6c56a6: Move the concrete `GitWorktreeIsolationAdapter` (git CLI + filesystem I/O) out of the reusable
267
+ `@robota-sdk/agent-executor` runtime-primitives package into the `@robota-sdk/agent-cli` composition
268
+ root, restoring the executor's "creates no Git worktrees" boundary (ARL-02 / ARCH-FIX-024, INFRA-031).
269
+
270
+ **Breaking (`@robota-sdk/agent-subagent-runner`):** `worktreeAdapter` is now a **required** option on
271
+ `createChildProcessSubagentRunnerFactory` / `IChildProcessSubagentRunnerOptions`. The concrete git
272
+ default (`createGitWorktreeIsolationAdapter()`) has been removed — inject the adapter at the composition
273
+ root. `@robota-sdk/agent-executor` no longer exports `GitWorktreeIsolationAdapter`,
274
+ `createGitWorktreeIsolationAdapter`, or `IGitWorktreeIsolationAdapterOptions` (the
275
+ `ISubagentWorktreeAdapter` port and `WorktreeSubagentRunner` remain). CLI runtime behavior is unchanged.
276
+
277
+ ### Patch Changes
278
+
279
+ - f336838: One permission evaluation order for every caller. The interactive session, background tasks and
280
+ subagents used to run two different resolvers, so the same call could be decided differently
281
+ depending on who made it. They now share `evaluatePermission`, and a background policy only adds a
282
+ ceiling, an ask-everything flag and the task's own lists to it:
283
+
284
+ deny → caller ceiling → unevaluable deny (ask) → never-auto-approve set (ask) → ask-everything →
285
+ bypassPermissions → allow → mode.
286
+
287
+ - **`ask` rules.** `permissions.ask` patterns always ask, in every mode including
288
+ `bypassPermissions`. They are matched per command like a deny rule, and are validated at
289
+ construction alongside `allow` and `deny`.
290
+ - **Never auto-approved, bypass included:** removing a critical path with `rm`/`rmdir` (the root, a
291
+ top-level directory, home, the working directory or a parent), and a modify-class write into
292
+ `.git`, the configured project-state directory, `.claude`, `.agents`, `.mcp.json`, `.gitconfig`, `.npmrc` or a shell rc file.
293
+ Files inside an isolated worktree (`the configured project-state directory/worktrees/<name>/…`) are ordinary files. With no
294
+ approver attached, an ask is a denial.
295
+ - **A ceiling is checked before bypass and before any ask.** A subagent's `inherit-allowlist` ceiling
296
+ is now the parent's *effective* rules, read live at spawn: settings, preset lists and command
297
+ auto-allows. It used to be the raw settings file. An unevaluable deny under a policy now asks,
298
+ like everywhere else, where it used to deny outright; with no approver it is still a denial.
299
+ - **Settings layers union `permissions.allow`**, as they already did `deny`. A checked-in project
300
+ file no longer silently discards the user's allow list.
301
+ - **Print mode, `createQuery()` and headless sessions default to `default` mode**, not
302
+ `bypassPermissions`. They have no approver, so a call that would ask is denied. Pass
303
+ `--permission-mode` / `permissionMode: 'bypassPermissions'` explicitly for unattended runs.
304
+
305
+ **Breaking:**
306
+ - `@robota-sdk/agent-core` removes `resolvePermissionByPolicy` and `TPermissionPolicyDecision` in
307
+ favour of `projectPermissionPolicy` plus `evaluatePermission`'s new `context` argument.
308
+ - `@robota-sdk/agent-framework` changes the settings merge rule for `permissions.allow`, and the
309
+ default permission mode of `createQuery()` and headless sessions.
310
+ - 57280bf: Every published package now declares `"engines": { "node": ">=22.12.0" }`. Before, 27 of the 38
311
+ packages declared no floor (`agent-core`, `agent-tools` and every provider among them),
312
+ `agent-session` and `agent-file-authority` declared `>=20.19.0`, and the other nine declared
313
+ `>=22.0.0`, so a consumer on Node 20 saw at most a warning from a transitive dependency.
314
+
315
+ Why 22.12: `agent-cli` and `agent-ui-terminal` need Node 22 through `ink` 7, and the CommonJS entries
316
+ of `agent-tools` and its dependents, `agent-transport`/`node` and its dependents, and
317
+ `agent-ui-terminal` `require()` ESM-only dependencies (`p-limit`, `jose`, `chalk`), which Node 22
318
+ supports unflagged only from 22.12. `engines` is advisory unless the consumer enables `engine-strict`.
319
+
320
+ No code changes: `tsdown` now reads `node22.12.0` as its build target from the field.
321
+ - 18c0d5c: Every published package now exports `./package.json`, so `require('<package>/package.json')` and
322
+ `import('<package>/package.json', { with: { type: 'json' } })` work instead of failing with
323
+ `ERR_PACKAGE_PATH_NOT_EXPORTED`, and each tarball now ships the package's `CHANGELOG.md`.
324
+ - 2e07cad: A subagent and a fork-context skill now start in the permission mode their parent is in at that
325
+ moment. The runtime used to hand them the mode it was built with, so after a switch to `plan` a
326
+ subagent the model started, or a skill it ran in a fork, still ran in the earlier mode and could
327
+ edit. `IInProcessSubagentRunnerDeps` gains the optional `getParentPermissionMode`, which the session
328
+ wires to its live mode; the in-process and child-process runners read it at spawn and fall back to
329
+ `permissionMode` when it is absent.
330
+
331
+ In plan mode the model can no longer run `/workflows create` or `/workflows build`: both save to
332
+ the project, and `create` also runs the workflow. The user can still run them by hand.
333
+ - 2c612ba: Release the migrated Robota product with its public SDK namespace, robota command, compatible SDK exports, internal product configuration, and verified CLI startup and delivery corrections.
334
+ - 7116367: Credentials the runtime holds for itself no longer reach the commands it runs.
335
+
336
+ - `agent-cli` — once a workspace's settings are admitted, every variable a provider profile or
337
+ definition names as its credential (`$ENV:` references, and defaults such as `OPENAI_API_KEY`)
338
+ leaves the process environment, so tools, hooks, background shells, a skill's `!` commands and
339
+ the environment an MCP header helper inherits no longer carry it, a hosted worker's broker token
340
+ included (a variable an MCP definition references explicitly still resolves); the provider keeps
341
+ authenticating from the startup snapshot. A user or managed settings layer can let
342
+ commands see one with `"commandEnvAllow": ["NAME"]`; project settings cannot. With the OS sandbox
343
+ on, confined commands can no longer read `settings.json`, `credentials/`, `mcp-credentials/` or
344
+ `remote-host-identity.json` under the user state directory. **Behavior change:** a command that
345
+ relied on inheriting a provider key now needs the opt-in, and a host embedding `startCli` finds
346
+ those variables gone from its own `process.env` afterwards — a later in-process call must pass them
347
+ in its `environment`.
348
+ - `agent-framework` — the settings schema gains `commandEnvAllow`; `checkSettingsDocument` and
349
+ `buildProviderProfilesSnapshot` take an optional environment map to resolve `$ENV:` references
350
+ against instead of the live process environment.
351
+ - `agent-command` — provider startup checks credentials against the host's environment snapshot.
352
+ - `agent-tools` — `OsSandboxClient` takes `hiddenPaths`, always hidden from confined commands and
353
+ not changeable by sandbox settings.
354
+ - `agent-subagent-runner` — a child-process subagent removes its provider credential variable from
355
+ its own environment once its provider is built, unless the start payload says the owner opted it in
356
+ (`keepProviderCredential`).
357
+ - `dag-node-instant-node` — prompt nodes accept an env resolver (`createPromptBackedNodeDefinition`'s
358
+ third argument, `rehydrateInstantNode`'s `resolveEnv`) for their `$ENV:` credential default.
359
+ - `agent-command-workflows` — `/workflows create` and `/workflows run` resolve prompt-node credentials
360
+ from the host's environment snapshot.
361
+ - 4f3c075: Assemble complete, verified package generations before switching build output; preserve the previous generation on build failure and pack only verified regular-file images. Include copied CLI web assets in affected-build ordering and artifact transfer. Preserve the CLI version in managed build paths. Public runtime contracts remain compatible (patch).
362
+ - 7d9cc66: Pass the child execution root and restored sandbox to hook composition. The stock CLI explicitly refuses command and HTTP hooks for separate task workers whose hook capabilities are unavailable, instead of executing those hooks on the host.
363
+ - dfb9b15: Release the integrated provider credential isolation and consumer runtime and interaction composition updates.
364
+ - 9c6a8db: A background agent's tool call that needs approval now reaches a person instead of being refused
365
+ automatically. The child process asks the parent session's own approver, identified as a background
366
+ agent naming its task, and parks the call until an answer arrives; cancelling the task dismisses any
367
+ still-parked ask immediately rather than leaving it outstanding. A parent with no approver attached
368
+ (print mode, a truly headless run) still fails every such call closed, the same default as before.
369
+
370
+ An agent task's result and its background-task-workspace entry now report how many of its tool calls
371
+ were refused and why (denied by a person, no approver attached, the approver itself failed, or the
372
+ task ended before an attached approver answered) — present only when at least one call was refused, so
373
+ a task that finished as it always did carries no new field.
374
+
375
+ A workspace entry for a `/loop`-managed iteration now carries a stable `loopId`, so a surface can stop
376
+ the loop itself rather than only cancelling its disposable wake timer, and a snapshot can include a
377
+ self-paced loop summary for an iteration that has no background-task entry of its own yet.
378
+ - Updated dependencies [9c19c50]
379
+ - Updated dependencies [7b6234c]
380
+ - Updated dependencies [5307f8a]
381
+ - Updated dependencies [b462ee7]
382
+ - Updated dependencies [08a9bd6]
383
+ - Updated dependencies [818f0c8]
384
+ - Updated dependencies [4eea54b]
385
+ - Updated dependencies [30e5e50]
386
+ - Updated dependencies [bb4696a]
387
+ - Updated dependencies [3c81769]
388
+ - Updated dependencies [724fabb]
389
+ - Updated dependencies [997f2fb]
390
+ - Updated dependencies [bfe8ed5]
391
+ - Updated dependencies [1698be4]
392
+ - Updated dependencies [9368d00]
393
+ - Updated dependencies [d4189b9]
394
+ - Updated dependencies [9edae52]
395
+ - Updated dependencies [4078a72]
396
+ - Updated dependencies [4c73a0b]
397
+ - Updated dependencies [af2f2ad]
398
+ - Updated dependencies [267af5f]
399
+ - Updated dependencies [196a900]
400
+ - Updated dependencies [f336838]
401
+ - Updated dependencies [34e50f0]
402
+ - Updated dependencies [722e88a]
403
+ - Updated dependencies [a5cc36e]
404
+ - Updated dependencies [d23c848]
405
+ - Updated dependencies [b70fa3d]
406
+ - Updated dependencies [2711ec6]
407
+ - Updated dependencies [3038eb7]
408
+ - Updated dependencies [02b7452]
409
+ - Updated dependencies [4dd45cc]
410
+ - Updated dependencies [e689c8e]
411
+ - Updated dependencies [4241fc5]
412
+ - Updated dependencies [ec5e477]
413
+ - Updated dependencies [4f49d14]
414
+ - Updated dependencies [007fd90]
415
+ - Updated dependencies [c7f9203]
416
+ - Updated dependencies [18b52cc]
417
+ - Updated dependencies [9843fe6]
418
+ - Updated dependencies [7b72344]
419
+ - Updated dependencies [6ae3f28]
420
+ - Updated dependencies [9721162]
421
+ - Updated dependencies [be0e53c]
422
+ - Updated dependencies [57f57f5]
423
+ - Updated dependencies [ba822c1]
424
+ - Updated dependencies [9721162]
425
+ - Updated dependencies [6e6b06b]
426
+ - Updated dependencies [7d77ce4]
427
+ - Updated dependencies [8bd5fac]
428
+ - Updated dependencies [57280bf]
429
+ - Updated dependencies [5033dd9]
430
+ - Updated dependencies [18c0d5c]
431
+ - Updated dependencies [dbd888d]
432
+ - Updated dependencies [1887e54]
433
+ - Updated dependencies [caaab20]
434
+ - Updated dependencies [f01868f]
435
+ - Updated dependencies [e8779c9]
436
+ - Updated dependencies [5a0ee96]
437
+ - Updated dependencies [9f46375]
438
+ - Updated dependencies [4e11579]
439
+ - Updated dependencies [41cca13]
440
+ - Updated dependencies [193a0bc]
441
+ - Updated dependencies [54e2848]
442
+ - Updated dependencies [3c1967f]
443
+ - Updated dependencies [ada3841]
444
+ - Updated dependencies [5093a30]
445
+ - Updated dependencies [5684612]
446
+ - Updated dependencies [6ee8725]
447
+ - Updated dependencies [6072e9a]
448
+ - Updated dependencies [94b2c87]
449
+ - Updated dependencies [3ab2eca]
450
+ - Updated dependencies [2e07cad]
451
+ - Updated dependencies [e8d70ac]
452
+ - Updated dependencies [2c612ba]
453
+ - Updated dependencies [66af868]
454
+ - Updated dependencies [e079992]
455
+ - Updated dependencies [7116367]
456
+ - Updated dependencies [5bb675a]
457
+ - Updated dependencies [e706b43]
458
+ - Updated dependencies [60f3965]
459
+ - Updated dependencies [115e104]
460
+ - Updated dependencies [04719a9]
461
+ - Updated dependencies [04a6de4]
462
+ - Updated dependencies [0ba247b]
463
+ - Updated dependencies [6f41c53]
464
+ - Updated dependencies [7d9cc66]
465
+ - Updated dependencies [4c5148e]
466
+ - Updated dependencies [37af5dc]
467
+ - Updated dependencies [807d161]
468
+ - Updated dependencies [fec722f]
469
+ - Updated dependencies [e82215f]
470
+ - Updated dependencies [52b7346]
471
+ - Updated dependencies [2ebff01]
472
+ - Updated dependencies [2ebff01]
473
+ - Updated dependencies [2d3b2c0]
474
+ - Updated dependencies [b078afa]
475
+ - Updated dependencies [2d3b2c0]
476
+ - Updated dependencies [baa6863]
477
+ - Updated dependencies [2d3b2c0]
478
+ - Updated dependencies [3a8876b]
479
+ - Updated dependencies [4772067]
480
+ - Updated dependencies [7b85767]
481
+ - Updated dependencies [0f98419]
482
+ - Updated dependencies [64ba748]
483
+ - Updated dependencies [9fbab1b]
484
+ - Updated dependencies [d312755]
485
+ - Updated dependencies [a009f5b]
486
+ - Updated dependencies [c207a31]
487
+ - Updated dependencies [9b4f63b]
488
+ - Updated dependencies [1e3f91a]
489
+ - Updated dependencies [4f3c075]
490
+ - Updated dependencies [7d9cc66]
491
+ - Updated dependencies [475e085]
492
+ - Updated dependencies [e477440]
493
+ - Updated dependencies [9dcb5da]
494
+ - Updated dependencies [a95ca85]
495
+ - Updated dependencies [b6d14ce]
496
+ - Updated dependencies [0382a51]
497
+ - Updated dependencies [93d061d]
498
+ - Updated dependencies [39554a1]
499
+ - Updated dependencies [d28430a]
500
+ - Updated dependencies [bed26ea]
501
+ - Updated dependencies [7d9cc66]
502
+ - Updated dependencies [fe48835]
503
+ - Updated dependencies [7d9cc66]
504
+ - Updated dependencies [1e40b5b]
505
+ - Updated dependencies [c6c56a6]
506
+ - Updated dependencies [bad976f]
507
+ - Updated dependencies [7d9cc66]
508
+ - Updated dependencies [7d9cc66]
509
+ - Updated dependencies [7d9cc66]
510
+ - Updated dependencies [7d9cc66]
511
+ - Updated dependencies [7d9cc66]
512
+ - Updated dependencies [7d9cc66]
513
+ - Updated dependencies [df02568]
514
+ - Updated dependencies [7d9cc66]
515
+ - Updated dependencies [7d9cc66]
516
+ - Updated dependencies [4b76cfa]
517
+ - Updated dependencies [d9bd9ec]
518
+ - Updated dependencies [8865acf]
519
+ - Updated dependencies [90e7a10]
520
+ - Updated dependencies [fcb0da3]
521
+ - Updated dependencies [07b627f]
522
+ - Updated dependencies [d0de5b2]
523
+ - Updated dependencies [9c6a8db]
524
+ - Updated dependencies [dfb9b15]
525
+ - Updated dependencies [9665c6e]
526
+ - Updated dependencies [44393be]
527
+ - Updated dependencies [c7fa299]
528
+ - Updated dependencies [7d9cc66]
529
+ - Updated dependencies [7d9cc66]
530
+ - Updated dependencies [7d9cc66]
531
+ - Updated dependencies [5134b3b]
532
+ - Updated dependencies [dd444c1]
533
+ - Updated dependencies [1f57e7f]
534
+ - Updated dependencies [7911a7d]
535
+ - Updated dependencies [833afe1]
536
+ - Updated dependencies [d6b9404]
537
+ - Updated dependencies [7863b16]
538
+ - Updated dependencies [fde558e]
539
+ - Updated dependencies [db5c439]
540
+ - Updated dependencies [7d9cc66]
541
+ - Updated dependencies [62663ae]
542
+ - Updated dependencies [4a01a87]
543
+ - Updated dependencies [9c6a8db]
544
+ - Updated dependencies [cbee54e]
545
+ - Updated dependencies [23a30cd]
546
+ - Updated dependencies [7d9cc66]
547
+ - Updated dependencies [7d9cc66]
548
+ - Updated dependencies [9814afc]
549
+ - Updated dependencies [7d9cc66]
550
+ - Updated dependencies [02053ec]
551
+ - Updated dependencies [242a644]
552
+ - @robota-sdk/agent-interface-execution@3.0.0
553
+ - @robota-sdk/agent-framework@3.0.0
554
+ - @robota-sdk/agent-executor@3.0.0
555
+ - @robota-sdk/agent-core@3.0.0
556
+ - @robota-sdk/agent-process@3.0.0
557
+
558
+ ## 3.0.0-beta.106
559
+ ### Patch Changes
560
+
561
+ - @robota-sdk/agent-core@3.0.0-beta.106
562
+ - @robota-sdk/agent-executor@3.0.0-beta.106
563
+ - @robota-sdk/agent-framework@3.0.0-beta.106
564
+ - @robota-sdk/agent-interface-execution@3.0.0-beta.106
565
+ - @robota-sdk/agent-process@3.0.0-beta.106
566
+
567
+ ## 3.0.0-beta.105
568
+ ### Patch Changes
569
+
570
+ - @robota-sdk/agent-core@3.0.0-beta.105
571
+ - @robota-sdk/agent-executor@3.0.0-beta.105
572
+ - @robota-sdk/agent-framework@3.0.0-beta.105
573
+ - @robota-sdk/agent-interface-execution@3.0.0-beta.105
574
+ - @robota-sdk/agent-process@3.0.0-beta.105
575
+
576
+ ## 3.0.0-beta.104
577
+ ### Patch Changes
578
+
579
+ - @robota-sdk/agent-core@3.0.0-beta.104
580
+ - @robota-sdk/agent-executor@3.0.0-beta.104
581
+ - @robota-sdk/agent-framework@3.0.0-beta.104
582
+ - @robota-sdk/agent-interface-execution@3.0.0-beta.104
583
+ - @robota-sdk/agent-process@3.0.0-beta.104
584
+
585
+ ## 3.0.0-beta.103
586
+ ### Patch Changes
587
+
588
+ - Updated dependencies [6f41c53]
589
+ - @robota-sdk/agent-core@3.0.0-beta.103
590
+ - @robota-sdk/agent-executor@3.0.0-beta.103
591
+ - @robota-sdk/agent-framework@3.0.0-beta.103
592
+ - @robota-sdk/agent-interface-execution@3.0.0-beta.103
593
+ - @robota-sdk/agent-process@3.0.0-beta.103
594
+
595
+ ## 3.0.0-beta.102
596
+ ### Patch Changes
597
+
598
+ - @robota-sdk/agent-core@3.0.0-beta.102
599
+ - @robota-sdk/agent-executor@3.0.0-beta.102
600
+ - @robota-sdk/agent-framework@3.0.0-beta.102
601
+ - @robota-sdk/agent-interface-execution@3.0.0-beta.102
602
+ - @robota-sdk/agent-process@3.0.0-beta.102
603
+
604
+ ## 3.0.0-beta.101
605
+ ### Patch Changes
606
+
607
+ - Updated dependencies [62663ae]
608
+ - @robota-sdk/agent-core@3.0.0-beta.101
609
+ - @robota-sdk/agent-framework@3.0.0-beta.101
610
+ - @robota-sdk/agent-executor@3.0.0-beta.101
611
+ - @robota-sdk/agent-interface-execution@3.0.0-beta.101
612
+ - @robota-sdk/agent-process@3.0.0-beta.101
613
+
614
+ ## 3.0.0-beta.100
615
+ ### Patch Changes
616
+
617
+ - @robota-sdk/agent-core@3.0.0-beta.100
618
+ - @robota-sdk/agent-executor@3.0.0-beta.100
619
+ - @robota-sdk/agent-framework@3.0.0-beta.100
620
+ - @robota-sdk/agent-interface-execution@3.0.0-beta.100
621
+ - @robota-sdk/agent-process@3.0.0-beta.100
622
+
3
623
  ## 3.0.0-beta.99
4
624
  ### Patch Changes
5
625
 
@@ -101,7 +721,7 @@
101
721
  ### Patch Changes
102
722
 
103
723
  - 7116367: Credentials the runtime holds for itself no longer reach the commands it runs.
104
-
724
+
105
725
  - `agent-cli` — once a workspace's settings are admitted, every variable a provider profile or
106
726
  definition names as its credential (`$ENV:` references, and defaults such as `OPENAI_API_KEY`)
107
727
  leaves the process environment, so tools, hooks, background shells, a skill's `!` commands and
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@robota-sdk/agent-subagent-runner",
3
- "version": "3.0.0-beta.99",
3
+ "version": "3.0.1",
4
4
  "description": "Child-process subagent runner for Robota SDK — optional package for running subagents in isolated child processes",
5
5
  "type": "module",
6
6
  "main": "dist/node/index.js",
@@ -39,11 +39,11 @@
39
39
  "CHANGELOG.md"
40
40
  ],
41
41
  "dependencies": {
42
- "@robota-sdk/agent-core": "3.0.0-beta.99",
43
- "@robota-sdk/agent-executor": "3.0.0-beta.99",
44
- "@robota-sdk/agent-framework": "3.0.0-beta.99",
45
- "@robota-sdk/agent-interface-execution": "3.0.0-beta.99",
46
- "@robota-sdk/agent-process": "3.0.0-beta.99"
42
+ "@robota-sdk/agent-core": "3.0.1",
43
+ "@robota-sdk/agent-executor": "3.0.1",
44
+ "@robota-sdk/agent-framework": "3.0.1",
45
+ "@robota-sdk/agent-interface-execution": "3.0.1",
46
+ "@robota-sdk/agent-process": "3.0.1"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@types/node": "^22.19.21",