@robota-sdk/agent-subagent-runner 3.0.0-beta.99 → 3.0.2

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