@robota-sdk/agent-subagent-runner 3.0.0-beta.86 → 3.0.0-beta.88

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,48 @@
1
1
  # @robota-sdk/agent-subagent-runner
2
2
 
3
+ ## 3.0.0-beta.88
4
+
5
+ ### Patch Changes
6
+
7
+ - @robota-sdk/agent-framework@3.0.0-beta.88
8
+ - @robota-sdk/agent-core@3.0.0-beta.88
9
+ - @robota-sdk/agent-executor@3.0.0-beta.88
10
+ - @robota-sdk/agent-interface-execution@3.0.0-beta.88
11
+ - @robota-sdk/agent-process@3.0.0-beta.88
12
+
13
+ ## 3.0.0-beta.87
14
+
15
+ ### Patch Changes
16
+
17
+ - 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.
18
+ - 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.
19
+ - Updated dependencies
20
+ - Updated dependencies [66af868]
21
+ - Updated dependencies [7d9cc66]
22
+ - Updated dependencies [7d9cc66]
23
+ - Updated dependencies [7d9cc66]
24
+ - Updated dependencies [7d9cc66]
25
+ - Updated dependencies [7d9cc66]
26
+ - Updated dependencies [7d9cc66]
27
+ - Updated dependencies [7d9cc66]
28
+ - Updated dependencies [7d9cc66]
29
+ - Updated dependencies [7d9cc66]
30
+ - Updated dependencies [7d9cc66]
31
+ - Updated dependencies [7d9cc66]
32
+ - Updated dependencies [7d9cc66]
33
+ - Updated dependencies [7d9cc66]
34
+ - Updated dependencies [7d9cc66]
35
+ - Updated dependencies [7d9cc66]
36
+ - Updated dependencies [7d9cc66]
37
+ - Updated dependencies [7d9cc66]
38
+ - Updated dependencies [7d9cc66]
39
+ - Updated dependencies [7d9cc66]
40
+ - @robota-sdk/agent-core@3.0.0-beta.87
41
+ - @robota-sdk/agent-executor@3.0.0-beta.87
42
+ - @robota-sdk/agent-framework@3.0.0-beta.87
43
+ - @robota-sdk/agent-interface-execution@3.0.0-beta.87
44
+ - @robota-sdk/agent-process@3.0.0-beta.87
45
+
3
46
  ## 3.0.0-beta.86
4
47
 
5
48
  ### Patch Changes
@@ -88,7 +131,7 @@
88
131
  under. `sandboxApprovalFor` is exported.
89
132
  - `agent-subagent-runner` (minor): `ISubagentWorkerComposition` takes an optional `createSandbox`. The
90
133
  worker builds that sandbox once and hands the same instance to `createTools` and to the session.
91
- - `agent-cli` (patch): robota's worker composition builds the OS sandbox through `createSandbox`, so
134
+ - `agent-cli` (patch): Robota's worker composition builds the OS sandbox through `createSandbox`, so
92
135
  a child-process subagent approves what its parent approves.
93
136
 
94
137
  - 122e82b: A child-process subagent confines and approves commands with its parent's sandbox settings as they
@@ -99,7 +142,7 @@
99
142
  - `agent-subagent-runner` (minor): the runner factory takes `parentSandboxSettings`, read at each
100
143
  spawn. The start payload carries it, the IPC guard checks it is a record, and the worker hands it to
101
144
  `createSandbox` as `parentSettings`.
102
- - `agent-cli` (patch): robota sends its live sandbox's settings, and a child builds its sandbox from
145
+ - `agent-cli` (patch): Robota sends its live sandbox's settings, and a child builds its sandbox from
103
146
  them. It refuses settings it cannot read rather than falling back to the files.
104
147
 
105
148
  - 0368058: A running child-process subagent follows a `/sandbox` change made in its parent session. Before, it
@@ -114,7 +157,7 @@
114
157
  exits or fails to start. A composed sandbox may define `applyParentSettings`. The worker applies
115
158
  each change through it. On settings it cannot take, it aborts the run, lets a running command
116
159
  finish, and ends the run with that error.
117
- - `agent-cli` (patch): robota watches its live sandbox, and a child applies each change to the
160
+ - `agent-cli` (patch): Robota watches its live sandbox, and a child applies each change to the
118
161
  instance its tools and approval read.
119
162
 
120
163
  ### Patch Changes
@@ -241,7 +284,7 @@
241
284
 
242
285
  - 0c07176: **BREAKING — ARCH-021: child-process subagents compose the PRODUCT's surface, not imported defaults.**
243
286
 
244
- 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 robota runs comes from a pack" was **false in the child**: dropping a pack did not drop its tools.
287
+ 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 Robota runs comes from a pack" was **false in the child**: dropping a pack did not drop its tools.
245
288
 
246
289
  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.
247
290
 
@@ -345,7 +388,7 @@
345
388
  }
346
389
  ```
347
390
 
348
- `IChildProcessSubagentRunnerOptions.workerPath` → **`workerEntry`**, and the runner `spawn`s `execPath args… --__robota-subagent-worker` instead of forking a module path. `robota`'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.
391
+ `IChildProcessSubagentRunnerOptions.workerPath` → **`workerEntry`**, and the runner `spawn`s `execPath args… --__agent-subagent-worker` instead of forking a module path. `robota`'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.
349
392
 
350
393
  **Per package, classified against each barrel:**
351
394
 
@@ -442,8 +485,8 @@
442
485
  construction alongside `allow` and `deny`.
443
486
  - **Never auto-approved, bypass included:** removing a critical path with `rm`/`rmdir` (the root, a
444
487
  top-level directory, home, the working directory or a parent), and a modify-class write into
445
- `.git`, `.robota`, `.claude`, `.agents`, `.mcp.json`, `.gitconfig`, `.npmrc` or a shell rc file.
446
- Files inside an isolated worktree (`.robota/worktrees/<name>/…`) are ordinary files. With no
488
+ `.git`, `.Robota`, `.claude`, `.agents`, `.mcp.json`, `.gitconfig`, `.npmrc` or a shell rc file.
489
+ Files inside an isolated worktree (`$PRODUCT_PROJECT_STATE_DIR/worktrees/<name>/…`) are ordinary files. With no
447
490
  approver attached, an ask is a denial.
448
491
  - **A ceiling is checked before bypass and before any ask.** A subagent's `inherit-allowlist` ceiling
449
492
  is now the parent's _effective_ rules, read live at spawn: settings, preset lists and command
package/README.md CHANGED
@@ -22,7 +22,7 @@ composition root (e.g. agent-cli)
22
22
  └── ChildProcessSubagentRunner ← this package
23
23
  ├── spawn() ← a copy of the running artifact in worker mode
24
24
  ├── IPC messages ← TSubagentWorkerParentMessage / TSubagentWorkerChildMessage
25
- └── worktree isolation ← via agent-executor, with an injected worktree adapter
25
+ └── worktree isolation ← vian agent-executor, with an injected worktree adapter
26
26
  ```
27
27
 
28
28
  The runner composes nothing itself. The composition root supplies how to start a copy of itself
@@ -68,7 +68,7 @@ const factory = createChildProcessSubagentRunnerFactory({
68
68
  workerEntry: { execPath: process.execPath, args: [process.argv[1] ?? ''] },
69
69
  providerConfig,
70
70
  providerDefinitions: myProviderDefinitions, // required: a job whose provider is not here is refused
71
- logsDir: '.robota/logs',
71
+ logsDir: hostSelectedLogDirectory,
72
72
  worktreeAdapter, // required: no concrete git default — inject the port at the composition root
73
73
  });
74
74
  ```
@@ -134,4 +134,4 @@ how the provider connection is checked across the process boundary.
134
134
 
135
135
  ## License
136
136
 
137
- Robota is dual-licensed under the [GNU AGPL-3.0](../../LICENSE) or a [commercial license](../../COMMERCIAL.md). See [LICENSING.md](../../LICENSING.md).
137
+ This package is dual-licensed under the [GNU AGPL-3.0](../../LICENSE) or a [commercial license](../../COMMERCIAL.md). See [LICENSING.md](../../LICENSING.md).
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("node:child_process"),t=require("node:fs"),n=require("node:path"),r=require("@robota-sdk/agent-executor"),i=require("@robota-sdk/agent-process"),a=require("@robota-sdk/agent-core"),o=require("@robota-sdk/agent-framework");function s(e){return{provider:{model:e.provider.model},permissions:e.permissions,defaultTrustLevel:e.defaultTrustLevel,...e.hooks===void 0?{}:{hooks:e.hooks}}}function c(e){return{agentsMd:e.agentsMd,projectNotesMd:e.projectNotesMd}}const l={name:{kind:`string`,required:!0},description:{kind:`string`,required:!0},systemPrompt:{kind:`string`,required:!0},model:{kind:`string`,required:!1},effort:{kind:`effort`,required:!1},role:{kind:`string`,required:!1},maxTurns:{kind:`number`,required:!1},tools:{kind:`string[]`,required:!1},disallowedTools:{kind:`string[]`,required:!1}},u={agentsMd:{kind:`string`,required:!0},projectNotesMd:{kind:`string`,required:!0},memoryMd:{kind:`string`,required:!1},taskContext:{kind:`string`,required:!1},compactInstructions:{kind:`string`,required:!1},agentsFileEntries:{kind:`file-entry[]`,required:!1},projectNotesFileEntries:{kind:`file-entry[]`,required:!1}};function d(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function f(e){return Array.isArray(e)&&e.every(e=>typeof e==`string`)}function p(e){return d(e)&&typeof e.filePath==`string`&&typeof e.content==`string`&&typeof e.contentHash==`string`}function m(e,t){switch(e){case`string`:return typeof t==`string`;case`number`:return typeof t==`number`&&Number.isFinite(t);case`effort`:return typeof t==`string`&&(0,a.isModelEffort)(t);case`string[]`:return f(t);case`file-entry[]`:return Array.isArray(t)&&t.every(p)}}function h(e,t){let n={};for(let r of Object.keys(t)){let t=e[r];t!==void 0&&(n[r]=t)}return n}function g(e,t,n){if(!d(t))return{ok:!1,reason:`${e}: expected an object`};for(let[r,i]of Object.entries(n)){let n=t[r];if(n===void 0){if(i.required)return{ok:!1,reason:`${e}.${r}: required`};continue}if(!m(i.kind,n))return{ok:!1,reason:`${e}.${r}: expected ${i.kind}`}}return{ok:!0,value:h(t,n)}}function _(e){return h(e,l)}function v(e){return g(`agentDefinition`,e,l)}function y(e){let t={name:e.name,description:e.description,systemPrompt:e.systemPrompt};return e.model!==void 0&&(t.model=e.model),e.effort!==void 0&&(t.effort=e.effort),e.role!==void 0&&(t.role=e.role),e.maxTurns!==void 0&&(t.maxTurns=e.maxTurns),e.tools!==void 0&&(t.tools=[...e.tools]),e.disallowedTools!==void 0&&(t.disallowedTools=[...e.disallowedTools]),t}function b(e){return h(e,u)}function x(e){return g(`parentContext`,e,u)}function S(e){let t={agentsMd:e.agentsMd,projectNotesMd:e.projectNotesMd};return e.memoryMd!==void 0&&(t.memoryMd=e.memoryMd),e.taskContext!==void 0&&(t.taskContext=e.taskContext),e.compactInstructions!==void 0&&(t.compactInstructions=e.compactInstructions),e.agentsFileEntries!==void 0&&(t.agentsFileEntries=e.agentsFileEntries.map(e=>({...e}))),e.projectNotesFileEntries!==void 0&&(t.projectNotesFileEntries=e.projectNotesFileEntries.map(e=>({...e}))),t}function ee(e){return e.sessionTiers===void 0?{}:{sessionTiers:e.sessionTiers}}async function C(e){let{sandboxClient:t,sandboxType:n}=e;return t?.snapshot===void 0||n===void 0?{}:{sandboxProjection:{type:n,snapshotId:await t.snapshot()}}}function w(e,t,n,i,o){let s=n.providerDefinitions,c=(n.providerConfig??t.config.provider).name;if((0,a.findProviderDefinition)(s,c)===void 0)throw new r.BackgroundTaskError(`validation`,`No provider definition for "${c}" was given to the subagent runner, so the connection a child would make cannot be checked; the subagent was not started.`);let l=E(n.providerConfig,t,e,s),u=(0,r.connectionEnvironmentNames)(l,s),d=(0,r.findConnectionEnvironmentDivergence)(u,i,o);if(d!==void 0)throw new r.BackgroundTaskError(`validation`,`The subagent's environment sets ${d} differently from this session, which would change where its provider connects or which credential it sends; the subagent was not started.`);return{providerProfile:l,connectionCheck:(0,r.sealConnectionEnvironment)(u,o)}}function te(e,t,n){let r=ne(e.request.agentType,t.customAgentRegistry,t.builtInAgents,t.agentDefinitions),i={taskId:e.taskId,request:e.request,...e.worktree?{worktree:e.worktree}:{},agentDefinition:_(re(r,e)),parentConfig:s(t.getParentPermissionRules===void 0?t.config:{...t.config,permissions:t.getParentPermissionRules()}),parentContext:b(c(t.context)),...n.connection??w(e,t,n,process.env,process.env),permissionMode:t.getParentPermissionMode?.()??t.permissionMode,...ee(t),...n.parentSandboxSettings===void 0?{}:{parentSandboxSettings:n.parentSandboxSettings},...n.logsDir?{logsDir:n.logsDir}:{}};return C(t).then(e=>({...i,...e}))}function ne(e,t,n,i){let a=t?.(e)??n?.find(t=>t.name===e)??i?.find(t=>t.name===e);if(!a)throw new r.BackgroundTaskError(`validation`,`Unknown agent type: ${e}`);return a}function re(e,t){return{...e,...t.request.model?{model:t.request.model}:{},...t.request.effort===void 0?{}:{effort:t.request.effort},...t.request.allowedTools?{tools:t.request.allowedTools}:{},...t.request.disallowedTools?{disallowedTools:t.request.disallowedTools}:{}}}function T(e,t){return e.apiKeyEnv===void 0?e.apiKey===void 0?t===void 0?{}:t.startsWith(`$ENV:`)?{apiKeyEnv:t.slice(5)}:{apiKey:t}:{apiKey:e.apiKey}:{apiKeyEnv:e.apiKeyEnv}}function E(e,t,n,r){let i=e??t.config.provider,o=(0,a.findProviderDefinition)(r,i.name)?.defaults??{},s=i.baseURL??o.baseURL,c=i.options??o.options,l=T(i,o.apiKey);return{...e===void 0&&t.config.currentProvider!==void 0?{profileName:t.config.currentProvider}:{},type:i.name,model:n.request.model??i.model,...l,...s===void 0?{}:{baseURL:s},...i.timeout===void 0?{}:{timeout:i.timeout},...c===void 0?{}:{options:c}}}function D(e){return typeof e==`object`&&!!e}function ie(e){if(!D(e)||!O(e,`nonce`)||!O(e,`digest`))return!1;let t=e.names;return Array.isArray(t)&&t.every(e=>typeof e==`string`)}function O(e,t){return typeof e[t]==`string`}function k(e,t){return O(e,t)}function ae(e,t){return O(e,t)}function oe(e,t){return e[t]===void 0||typeof e[t]==`string`}function se(e){if(e.usage===void 0)return!0;let t=e.usage;return D(t)?typeof t.promptTokens==`number`&&typeof t.completionTokens==`number`&&typeof t.totalTokens==`number`:!1}function ce(e){if(e.composedToolNames===void 0)return!0;let t=e.composedToolNames;return Array.isArray(t)?t.every(e=>typeof e==`string`):!1}function le(e){return!D(e)||!ae(e,`taskId`)||!D(e.request)||!k(e.request,`agentType`)||!k(e.request,`prompt`)||!k(e.request,`permissionPolicy`)||!k(e.request,`cwd`)||!oe(e.request,`resumeSessionId`)||e.worktree!==void 0&&(!D(e.worktree)||!O(e.worktree,`path`))||!v(e.agentDefinition).ok||!D(e.parentConfig)||!x(e.parentContext).ok||!D(e.providerProfile)||!O(e.providerProfile,`type`)||!O(e.providerProfile,`model`)||e.parentSandboxSettings!==void 0&&!D(e.parentSandboxSettings)?!1:ie(e.connectionCheck)}function A(e){if(!D(e)||!O(e,`type`))return!1;switch(e.type){case`start`:return le(e.payload);case`send`:return O(e,`prompt`);case`cancel`:return e.reason===void 0||typeof e.reason==`string`;case`sandbox_settings`:return D(e.settings);case`permission_response`:return O(e,`requestId`)&&ue(e.result);default:return!1}}function ue(e){return typeof e==`boolean`||e===`allow-session`||e===`allow-project`}function j(e){if(!D(e)||!O(e,`type`))return!1;switch(e.type){case`ready`:return ce(e);case`text_delta`:return O(e,`delta`);case`tool_start`:return O(e,`toolName`);case`tool_end`:return O(e,`toolName`)&&typeof e.success==`boolean`;case`permission_request`:return O(e,`requestId`)&&O(e,`toolName`);case`result`:return O(e,`output`)&&se(e);case`error`:return O(e,`message`);case`cancelled`:return e.reason===void 0||typeof e.reason==`string`;default:return!1}}const de=process.platform!==`win32`;function fe(e,t){return new Promise(n=>{if(e.exitCode!==null||e.signalCode!==null){n();return}let r=setTimeout(()=>{e.removeListener(`exit`,i),n()},t);r.unref?.();let i=()=>{clearTimeout(r),n()};e.once(`exit`,i)})}const M=new WeakMap;function N(e){let t=e.stderr;if(!t)return;let n=(0,a.createBoundedOutput)({maxBytes:4096,retain:`tail`,truncationMarker:()=>``});M.set(e,n),t.on(`error`,()=>{}),t.on(`data`,e=>n.append(e))}function P(e){return(M.get(e)?.toString()??``).trim()}function F(e,t,n,i,a,o){switch(e.type){case`ready`:t();break;case`result`:n(e);break;case`error`:i(new r.BackgroundTaskError(`runner`,e.message));break;case`cancelled`:i(new r.BackgroundTaskError(`runner`,e.reason??`Subagent worker cancelled`));break;case`text_delta`:a?.({type:`background_task_text_delta`,delta:e.delta});break;case`tool_start`:a?.({type:`background_task_tool_start`,toolName:e.toolName,firstArg:I(e.toolArgs)});break;case`tool_end`:a?.({type:`background_task_tool_end`,toolName:e.toolName,success:e.success});break;case`permission_request`:o?.(e);break;default:i(new r.BackgroundTaskError(`runner`,`Unhandled subagent worker message`))}}function I(e){if(!e)return;let t=Object.values(e)[0];if(t!==void 0)return typeof t==`object`?JSON.stringify(t):String(t)}function L(e,t){return new Promise((n,i)=>{if(!e.connected){i(new r.BackgroundTaskError(`crash`,`Subagent worker IPC channel is closed`));return}e.send(t,e=>{if(e){i(e);return}n()})})}async function R(e,t){await(0,i.killProcessTree)(e.child,{graceMs:e.killGraceMs,processGroup:de,preKill:async()=>{e.child.connected&&(await L(e.child,{type:`cancel`,reason:t}).catch(()=>void 0),await fe(e.child,e.killGraceMs))}})}function z(e){return new Promise((t,n)=>{new B(e,t,n).start()})}var B=class{options;resolve;reject;settled=!1;started=!1;ready=!1;timeoutTimer;handshakeTimer;handshakeBudgetMs;payload;deniedToolCallCounts={"no-approver":0,"denied-by-person":0,"approver-error":0,cancelled:0};pendingPermissionRequests=new Map;constructor(e,t,n){this.options=e,this.resolve=t,this.reject=n;let i=e.handshakeBudgetMs;this.handshakeBudgetMs=i!==void 0&&i>0?i:3e4,this.payload=e.payload.catch(e=>{this.rejectOnce(e instanceof Error?e:Error(String(e)))}),this.timeoutTimer=pe(this.options.runtime,e=>this.rejectOnce(e)),this.handshakeTimer=setTimeout(()=>{this.ready||this.settled||(R(this.options.runtime,`Subagent worker never signalled ready`),this.rejectOnce(new r.BackgroundTaskError(`runner`,`Subagent worker never signalled ready within ${this.handshakeBudgetMs}ms. Its entry must dispatch worker mode before starting the host application.`)))},this.handshakeBudgetMs),this.handshakeTimer.unref?.()}start(){let{child:e}=this.options.runtime;e.on(`message`,this.onMessage),e.on(`error`,this.onError),e.on(`exit`,this.onExit),e.once(`spawn`,()=>{setImmediate(this.startWorker)})}startWorker=()=>{if(this.started)return;this.started=!0;let{child:e}=this.options.runtime;this.payload.then(t=>t===void 0?void 0:L(e,{type:`start`,payload:t})).catch(e=>{this.rejectOnce(e instanceof Error?e:Error(String(e)))})};onMessage=e=>{if(!j(e)){this.rejectOnce(new r.BackgroundTaskError(`runner`,`Received malformed subagent worker message`));return}this.ready=!0,clearTimeout(this.handshakeTimer);let{job:t}=this.options.runtime;F(e,this.startWorker,this.resolveOnce,this.rejectOnce,t.emit,this.onPermissionRequest)};onPermissionRequest=e=>{let t=this.answerPermissionRequest(e).finally(()=>{this.pendingPermissionRequests.delete(e.requestId)});this.pendingPermissionRequests.set(e.requestId,t)};async answerPermissionRequest(e){let{reason:t,result:n}=await this.askApprover(e);t!==void 0&&(this.deniedToolCallCounts[t]+=1);let{child:r}=this.options.runtime;r.connected&&await L(r,{type:`permission_response`,requestId:e.requestId,result:n}).catch(()=>void 0)}async askApprover(e){let t=this.options.permissionApprover;if(t===void 0)return{reason:`no-approver`,result:!1};try{let n=await t(e.toolName,e.toolArgs??{},this.options.permissionAbort.signal);return n===!1?this.options.permissionAbort.signal.aborted?{reason:`cancelled`,result:!1}:{reason:`denied-by-person`,result:!1}:{result:n}}catch{return{reason:`approver-error`,result:!1}}}onError=e=>{this.rejectOnce(new r.BackgroundTaskError(`crash`,e.message))};onExit=(e,t)=>{this.settled||this.rejectOnce(new r.BackgroundTaskError(`crash`,ge(e,t,P(this.options.runtime.child))))};resolveOnce=e=>{this.settled||(this.settled=!0,this.settleAfterPendingPermissionRequests(()=>{let{runtime:t,resolveTranscriptPath:n}=this.options;this.resolve(me(t.job,e,n,this.deniedToolCallCounts))}))};rejectOnce=e=>{this.settled||(this.settled=!0,this.settleAfterPendingPermissionRequests(()=>this.reject(e)))};async settleAfterPendingPermissionRequests(e){this.options.permissionAbort.abort(),this.clearTimers(),this.cleanup(),await Promise.all(this.pendingPermissionRequests.values()),e()}clearTimers(){this.timeoutTimer&&clearTimeout(this.timeoutTimer),clearTimeout(this.handshakeTimer)}cleanup(){let{child:e}=this.options.runtime;e.off(`message`,this.onMessage),e.off(`error`,this.onError),e.off(`exit`,this.onExit)}};function V(e){let t=!1,n=()=>{};return{promise:new Promise((e,t)=>{n=t}),reject(i){t||(t=!0,n(new r.BackgroundTaskError(`runner`,i??`Subagent job cancelled: ${e}`)))}}}function pe(e,t){if(e.job.request.timeoutMs)return setTimeout(()=>{R(e,`Subagent worker timed out`),t(new r.BackgroundTaskError(`timeout`,`Subagent worker timed out`))},e.job.request.timeoutMs)}function me(e,t,n,r){let i=n(e),a=he(r);return{taskId:e.taskId,output:t.output,...i?{metadata:{transcriptPath:i,logPath:i}}:{},...t.usage?{usage:t.usage}:{},...a?{deniedToolCalls:a}:{}}}function he(e){let t=Object.values(e).reduce((e,t)=>e+t,0);return t===0?void 0:{total:t,byReason:{...e}}}function ge(e,t,n){return`Subagent worker exited before result: ${t===null?`exit code ${e===null?`unknown`:e}`:`signal ${t}`}${n.length>0?`: ${n}`:``}`}const H=`--__robota-subagent-worker`;function _e(e){return e.includes(H)}const ve=process.platform!==`win32`;function ye(e){return t=>{let n=new U(t,e);return e.worktreeIsolation===!1?n:(0,r.createWorktreeSubagentRunner)({runner:n,worktreeAdapter:e.worktreeAdapter,hooks:t.config.hooks,hookTypeExecutors:t.hookTypeExecutors})}}var U=class{deps;workerEntry;killGraceMs;handshakeBudgetMs;providerConfig;providerDefinitions;env;logsDir;parentSandboxSettings;watchParentSandboxSettings;constructor(e,t){this.deps=e,this.workerEntry=t.workerEntry,this.killGraceMs=t.killGraceMs??i.DEFAULT_KILL_GRACE_MS,this.handshakeBudgetMs=t.handshakeBudgetMs,this.providerConfig=t.providerConfig,this.providerDefinitions=t.providerDefinitions,this.env=t.env,this.logsDir=t.logsDir,this.parentSandboxSettings=t.parentSandboxSettings,this.watchParentSandboxSettings=t.watchParentSandboxSettings}start(t){let n=this.workerEntry,i={...process.env,...this.env??{}},a=w(t,this.deps,{...this.providerConfig===void 0?{}:{providerConfig:this.providerConfig},providerDefinitions:this.providerDefinitions},process.env,i),o=(0,e.spawn)(n.execPath,[...n.execArgv??[],...n.args,H],{cwd:(0,r.subagentExecutionRoot)(t),env:i,stdio:[`ignore`,`ignore`,`pipe`,`ipc`],detached:ve});N(o),this.forwardSandboxSettingChanges(o);let s={job:t,child:o,killGraceMs:this.killGraceMs},c=this.createStartPayload(t,a),l=new AbortController,u=this.permissionApprover(t),d=z({runtime:s,payload:c,...this.handshakeBudgetMs===void 0?{}:{handshakeBudgetMs:this.handshakeBudgetMs},resolveTranscriptPath:e=>this.resolveTranscriptPath(e),permissionAbort:l,...u===void 0?{}:{permissionApprover:u}}),f=V(t.taskId);d.catch(()=>void 0);let p=Promise.race([d,f.promise]);p.catch(()=>void 0);let m=this.resolveTranscriptPath(t);return{taskId:t.taskId,...o.pid!==void 0&&{pid:o.pid},...m!==void 0&&{transcriptPath:m,logPath:m},result:p,cancel:async e=>{l.abort(e),f.reject(e),await R(s,e)},send:async e=>{await L(o,{type:`send`,prompt:e})},...m!==void 0&&{readLog:async e=>be(t.taskId,m,e)}}}createStartPayload(e,t){let n=this.parentSandboxSettings?.();return te(e,this.deps,{connection:t,providerDefinitions:this.providerDefinitions,...this.logsDir===void 0?{}:{logsDir:this.logsDir},...n===void 0?{}:{parentSandboxSettings:n}})}forwardSandboxSettingChanges(e){let t=this.watchParentSandboxSettings?.(t=>{e.connected&&L(e,{type:`sandbox_settings`,settings:t}).catch(()=>void 0)});t!==void 0&&(e.once(`exit`,t),e.once(`error`,t))}resolveTranscriptPath(e){if(this.logsDir)return(0,n.join)(this.logsDir,e.request.parentSessionId,`subagents`,`${e.taskId}.jsonl`)}permissionApprover(e){let t=this.deps.permissionHandler;if(t===void 0)return;let n={kind:`background-agent`,label:e.request.agentType,taskId:e.taskId};return(e,r,i)=>t(e,r,{requester:n,signal:i})}};function be(e,n,i){return(0,t.existsSync)(n)?(0,r.createBackgroundTaskLogPage)(e,(0,t.readFileSync)(n,`utf8`).split(/\r?\n/).filter(Boolean),i):{taskId:e,cursor:i,lines:[]}}function xe(e,t,n){let r=e.request.resumeSessionId;if(r!==void 0){if(n===void 0)throw Error(`subagent worker: job ${e.taskId} asks to resume session ${r}, but this composition opens no session store. Register ISubagentWorkerComposition.openSessionStore at the composition root — the same place providerDefinitions is registered.`);(0,o.restoreSessionRecordIntoSession)(n,r,t)}}function Se(e,t){let n=e.request.resumeSessionId;if(n!==void 0){if(t.openSessionStore===void 0)throw Error(`subagent worker: job ${e.taskId} asks to resume session ${n}, but this composition opens no session store. Register ISubagentWorkerComposition.openSessionStore at the composition root — the same place providerDefinitions is registered.`);return t.openSessionStore({cwd:e.request.cwd})}}async function Ce(e,t){if(e===void 0)return;let n=t?.[e.type];if(n===void 0)throw Error(`subagent worker: sandbox type "${e.type}" is not registered in the worker composition. The parent is sandboxed and passed a snapshot reference, but this child cannot construct that client type. Register it in ISubagentWorkerComposition.sandboxFactories at the composition root — the same place providerDefinitions is registered, and for the same reason.`);return n(e.snapshotId)}const we={write:()=>{},writeLine:()=>{},writeMarkdown:()=>{},writeError:()=>{},prompt:()=>Promise.resolve(``),select:()=>Promise.resolve(0),spinner:()=>({stop:()=>{},update:()=>{}})};let W=null,G=!1;const K=new Map;let Te=0,q,J,Y,X=Promise.resolve();function Z(e){process.send&&process.send(e)}function Q(e,t){let n=!1,r=()=>{n||(n=!0,process.exit(t))};if(process.send){let t=setTimeout(r,2e3);t.unref?.(),process.send(e,void 0,void 0,()=>{clearTimeout(t),r()})}else r()}function Ee(e){try{return(0,a.sumHistoryUsage)(e.getFullHistory())}catch{return}}async function De(e,t){try{if(!(0,r.verifyConnectionEnvironment)(e.connectionCheck,process.env))throw Error(`The provider connection environment changed after the parent checked it; the subagent was not started.`);let n=await Ce(e.sandboxProjection,t.sandboxFactories),i=(0,r.createProviderFromExactProfile)(e.providerProfile,e.request.model,t.providerDefinitions),a=e.logsDir?(0,o.createSubagentLogger)(e.request.parentSessionId,e.taskId,e.logsDir):void 0,s=Se(e,t),c=q??e.parentSandboxSettings;J=n===void 0?t.createSandbox?.({cwd:(0,r.subagentExecutionRoot)(e),...c===void 0?{}:{parentSettings:c}}):void 0;let l=n??J?.client;W=(0,o.createSubagentSession)({agentDefinition:y(e.agentDefinition),parentConfig:e.parentConfig,parentContext:S(e.parentContext),parentTools:t.createTools({cwd:(0,r.subagentExecutionRoot)(e),...l===void 0?{}:{sandboxClient:l},...e.sessionTiers===void 0?{}:{sessionTiers:e.sessionTiers}}),cwd:(0,r.subagentExecutionRoot)(e),provider:i,terminal:we,sessionId:e.request.resumeSessionId??e.taskId,...s===void 0?{}:{sessionStore:s},...a?{sessionLogger:a}:{},permissionMode:e.permissionMode,...J?.commandSandbox===void 0?{}:{commandSandbox:J.commandSandbox},...e.request.permissionPolicy===void 0?{}:{permissionPolicy:e.request.permissionPolicy},...e.request.allowedTools===void 0?{}:{taskAllowedTools:e.request.allowedTools},...e.request.disallowedTools===void 0?{}:{taskDisallowedTools:e.request.disallowedTools},hooks:e.parentConfig.hooks,...t.createHookTypeExecutors===void 0?{}:{hookTypeExecutors:t.createHookTypeExecutors()},onTextDelta:e=>Z({type:`text_delta`,delta:e}),onToolExecution:Ae,permissionHandler:Oe}),xe(e,W,s);let u=await W.run(e.request.prompt);if(Y!==void 0){Q({type:`error`,message:Y},0);return}if(G){Q({type:`cancelled`,reason:`Subagent worker cancelled`},130);return}let d=Ee(W);Q({type:`result`,output:u,...d?{usage:d}:{}},0)}catch(e){if(Y!==void 0){Q({type:`error`,message:Y},0);return}if(G){Q({type:`cancelled`,reason:`Subagent worker cancelled`},130);return}Q({type:`error`,message:e instanceof Error?e.message:String(e)},0)}}function Oe(e,t){let n=`perm_${++Te}`;return new Promise(r=>{K.set(n,r),Z({type:`permission_request`,requestId:n,toolName:e,toolArgs:t})})}function ke(e,t){let n=K.get(e);n!==void 0&&(K.delete(e),n(t))}function Ae(e){if(e.type===`start`){Z({type:`tool_start`,toolName:e.toolName,toolArgs:e.toolArgs});return}Z({type:`tool_end`,toolName:e.toolName,success:e.success??!0})}function $(e){if(W===null){Z({type:`error`,message:`Subagent worker has not started`});return}X=X.then(async()=>{try{await W?.run(e)}catch(e){Z({type:`error`,message:e instanceof Error?e.message:String(e)})}})}async function je(e){G=!0,W?.abort(),Z({type:`cancelled`,reason:e}),await W?.shutdown({reason:`other`}).catch(()=>void 0),setTimeout(()=>process.exit(130),0)}function Me(e){try{return e.createTools({cwd:process.cwd()}).map(e=>e.getName())}catch(e){process.stderr.write(`robota: could not enumerate the composed tool surface: ${e instanceof Error?e.message:String(e)}\n`);return}}function Ne(e){q=e;try{J?.applyParentSettings?.(e)}catch(e){Y??=e instanceof Error?e.message:String(e),W?.abort()}}function Pe(e){process.send===void 0&&(process.stderr.write(`robota: subagent worker mode requires an IPC channel; it is started by the agent runtime, not by hand.
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("node:child_process"),t=require("node:fs"),n=require("node:path"),r=require("@robota-sdk/agent-executor"),i=require("@robota-sdk/agent-process"),a=require("@robota-sdk/agent-core"),o=require("@robota-sdk/agent-framework");function s(e){return{provider:{model:e.provider.model},permissions:e.permissions,defaultTrustLevel:e.defaultTrustLevel,...e.hooks===void 0?{}:{hooks:e.hooks}}}function c(e){return{agentsMd:e.agentsMd,projectNotesMd:e.projectNotesMd}}const l={name:{kind:`string`,required:!0},description:{kind:`string`,required:!0},systemPrompt:{kind:`string`,required:!0},model:{kind:`string`,required:!1},effort:{kind:`effort`,required:!1},role:{kind:`string`,required:!1},maxTurns:{kind:`number`,required:!1},tools:{kind:`string[]`,required:!1},disallowedTools:{kind:`string[]`,required:!1}},u={agentsMd:{kind:`string`,required:!0},projectNotesMd:{kind:`string`,required:!0},memoryMd:{kind:`string`,required:!1},taskContext:{kind:`string`,required:!1},compactInstructions:{kind:`string`,required:!1},agentsFileEntries:{kind:`file-entry[]`,required:!1},projectNotesFileEntries:{kind:`file-entry[]`,required:!1}};function d(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function f(e){return Array.isArray(e)&&e.every(e=>typeof e==`string`)}function p(e){return d(e)&&typeof e.filePath==`string`&&typeof e.content==`string`&&typeof e.contentHash==`string`}function m(e,t){switch(e){case`string`:return typeof t==`string`;case`number`:return typeof t==`number`&&Number.isFinite(t);case`effort`:return typeof t==`string`&&(0,a.isModelEffort)(t);case`string[]`:return f(t);case`file-entry[]`:return Array.isArray(t)&&t.every(p)}}function h(e,t){let n={};for(let r of Object.keys(t)){let t=e[r];t!==void 0&&(n[r]=t)}return n}function g(e,t,n){if(!d(t))return{ok:!1,reason:`${e}: expected an object`};for(let[r,i]of Object.entries(n)){let n=t[r];if(n===void 0){if(i.required)return{ok:!1,reason:`${e}.${r}: required`};continue}if(!m(i.kind,n))return{ok:!1,reason:`${e}.${r}: expected ${i.kind}`}}return{ok:!0,value:h(t,n)}}function _(e){return h(e,l)}function v(e){return g(`agentDefinition`,e,l)}function y(e){let t={name:e.name,description:e.description,systemPrompt:e.systemPrompt};return e.model!==void 0&&(t.model=e.model),e.effort!==void 0&&(t.effort=e.effort),e.role!==void 0&&(t.role=e.role),e.maxTurns!==void 0&&(t.maxTurns=e.maxTurns),e.tools!==void 0&&(t.tools=[...e.tools]),e.disallowedTools!==void 0&&(t.disallowedTools=[...e.disallowedTools]),t}function b(e){return h(e,u)}function x(e){return g(`parentContext`,e,u)}function S(e){let t={agentsMd:e.agentsMd,projectNotesMd:e.projectNotesMd};return e.memoryMd!==void 0&&(t.memoryMd=e.memoryMd),e.taskContext!==void 0&&(t.taskContext=e.taskContext),e.compactInstructions!==void 0&&(t.compactInstructions=e.compactInstructions),e.agentsFileEntries!==void 0&&(t.agentsFileEntries=e.agentsFileEntries.map(e=>({...e}))),e.projectNotesFileEntries!==void 0&&(t.projectNotesFileEntries=e.projectNotesFileEntries.map(e=>({...e}))),t}function ee(e){return e.sessionTiers===void 0?{}:{sessionTiers:e.sessionTiers}}async function C(e){let{sandboxClient:t,sandboxType:n}=e;return t?.snapshot===void 0||n===void 0?{}:{sandboxProjection:{type:n,snapshotId:await t.snapshot()}}}function w(e,t,n,i,o){let s=n.providerDefinitions,c=(n.providerConfig??t.config.provider).name;if((0,a.findProviderDefinition)(s,c)===void 0)throw new r.BackgroundTaskError(`validation`,`No provider definition for "${c}" was given to the subagent runner, so the connection a child would make cannot be checked; the subagent was not started.`);let l=E(n.providerConfig,t,e,s),u=(0,r.connectionEnvironmentNames)(l,s),d=(0,r.findConnectionEnvironmentDivergence)(u,i,o);if(d!==void 0)throw new r.BackgroundTaskError(`validation`,`The subagent's environment sets ${d} differently from this session, which would change where its provider connects or which credential it sends; the subagent was not started.`);return{providerProfile:l,connectionCheck:(0,r.sealConnectionEnvironment)(u,o)}}function te(e,t,n){let r=ne(e.request.agentType,t.customAgentRegistry,t.builtInAgents,t.agentDefinitions),i={taskId:e.taskId,request:e.request,...e.worktree?{worktree:e.worktree}:{},agentDefinition:_(re(r,e)),parentConfig:s(t.getParentPermissionRules===void 0?t.config:{...t.config,permissions:t.getParentPermissionRules()}),parentContext:b(c(t.context)),...n.connection??w(e,t,n,process.env,process.env),permissionMode:t.getParentPermissionMode?.()??t.permissionMode,...ee(t),...n.parentSandboxSettings===void 0?{}:{parentSandboxSettings:n.parentSandboxSettings},...n.logsDir?{logsDir:n.logsDir}:{}};return C(t).then(e=>({...i,...e}))}function ne(e,t,n,i){let a=t?.(e)??n?.find(t=>t.name===e)??i?.find(t=>t.name===e);if(!a)throw new r.BackgroundTaskError(`validation`,`Unknown agent type: ${e}`);return a}function re(e,t){return{...e,...t.request.model?{model:t.request.model}:{},...t.request.effort===void 0?{}:{effort:t.request.effort},...t.request.allowedTools?{tools:t.request.allowedTools}:{},...t.request.disallowedTools?{disallowedTools:t.request.disallowedTools}:{}}}function T(e,t){return e.apiKeyEnv===void 0?e.apiKey===void 0?t===void 0?{}:t.startsWith(`$ENV:`)?{apiKeyEnv:t.slice(5)}:{apiKey:t}:{apiKey:e.apiKey}:{apiKeyEnv:e.apiKeyEnv}}function E(e,t,n,r){let i=e??t.config.provider,o=(0,a.findProviderDefinition)(r,i.name)?.defaults??{},s=i.baseURL??o.baseURL,c=i.options??o.options,l=T(i,o.apiKey);return{...e===void 0&&t.config.currentProvider!==void 0?{profileName:t.config.currentProvider}:{},type:i.name,model:n.request.model??i.model,...l,...s===void 0?{}:{baseURL:s},...i.timeout===void 0?{}:{timeout:i.timeout},...c===void 0?{}:{options:c}}}function D(e){return typeof e==`object`&&!!e}function ie(e){if(!D(e)||!O(e,`nonce`)||!O(e,`digest`))return!1;let t=e.names;return Array.isArray(t)&&t.every(e=>typeof e==`string`)}function O(e,t){return typeof e[t]==`string`}function k(e,t){return O(e,t)}function ae(e,t){return O(e,t)}function oe(e,t){return e[t]===void 0||typeof e[t]==`string`}function se(e){if(e.usage===void 0)return!0;let t=e.usage;return D(t)?typeof t.promptTokens==`number`&&typeof t.completionTokens==`number`&&typeof t.totalTokens==`number`:!1}function ce(e){if(e.composedToolNames===void 0)return!0;let t=e.composedToolNames;return Array.isArray(t)?t.every(e=>typeof e==`string`):!1}function le(e){return!D(e)||!ae(e,`taskId`)||!D(e.request)||!k(e.request,`agentType`)||!k(e.request,`prompt`)||!k(e.request,`permissionPolicy`)||!k(e.request,`cwd`)||!oe(e.request,`resumeSessionId`)||e.worktree!==void 0&&(!D(e.worktree)||!O(e.worktree,`path`))||!v(e.agentDefinition).ok||!D(e.parentConfig)||!x(e.parentContext).ok||!D(e.providerProfile)||!O(e.providerProfile,`type`)||!O(e.providerProfile,`model`)||e.parentSandboxSettings!==void 0&&!D(e.parentSandboxSettings)?!1:ie(e.connectionCheck)}function A(e){if(!D(e)||!O(e,`type`))return!1;switch(e.type){case`start`:return le(e.payload);case`send`:return O(e,`prompt`);case`cancel`:return e.reason===void 0||typeof e.reason==`string`;case`sandbox_settings`:return D(e.settings);case`permission_response`:return O(e,`requestId`)&&ue(e.result);default:return!1}}function ue(e){return typeof e==`boolean`||e===`allow-session`||e===`allow-project`}function j(e){if(!D(e)||!O(e,`type`))return!1;switch(e.type){case`ready`:return ce(e);case`text_delta`:return O(e,`delta`);case`tool_start`:return O(e,`toolName`);case`tool_end`:return O(e,`toolName`)&&typeof e.success==`boolean`;case`permission_request`:return O(e,`requestId`)&&O(e,`toolName`);case`result`:return O(e,`output`)&&se(e);case`error`:return O(e,`message`);case`cancelled`:return e.reason===void 0||typeof e.reason==`string`;default:return!1}}const de=process.platform!==`win32`;function fe(e,t){return new Promise(n=>{if(e.exitCode!==null||e.signalCode!==null){n();return}let r=setTimeout(()=>{e.removeListener(`exit`,i),n()},t);r.unref?.();let i=()=>{clearTimeout(r),n()};e.once(`exit`,i)})}const M=new WeakMap;function N(e){let t=e.stderr;if(!t)return;let n=(0,a.createBoundedOutput)({maxBytes:4096,retain:`tail`,truncationMarker:()=>``});M.set(e,n),t.on(`error`,()=>{}),t.on(`data`,e=>n.append(e))}function P(e){return(M.get(e)?.toString()??``).trim()}function F(e,t,n,i,a,o){switch(e.type){case`ready`:t();break;case`result`:n(e);break;case`error`:i(new r.BackgroundTaskError(`runner`,e.message));break;case`cancelled`:i(new r.BackgroundTaskError(`runner`,e.reason??`Subagent worker cancelled`));break;case`text_delta`:a?.({type:`background_task_text_delta`,delta:e.delta});break;case`tool_start`:a?.({type:`background_task_tool_start`,toolName:e.toolName,firstArg:I(e.toolArgs)});break;case`tool_end`:a?.({type:`background_task_tool_end`,toolName:e.toolName,success:e.success});break;case`permission_request`:o?.(e);break;default:i(new r.BackgroundTaskError(`runner`,`Unhandled subagent worker message`))}}function I(e){if(!e)return;let t=Object.values(e)[0];if(t!==void 0)return typeof t==`object`?JSON.stringify(t):String(t)}function L(e,t){return new Promise((n,i)=>{if(!e.connected){i(new r.BackgroundTaskError(`crash`,`Subagent worker IPC channel is closed`));return}e.send(t,e=>{if(e){i(e);return}n()})})}async function R(e,t){await(0,i.killProcessTree)(e.child,{graceMs:e.killGraceMs,processGroup:de,preKill:async()=>{e.child.connected&&(await L(e.child,{type:`cancel`,reason:t}).catch(()=>void 0),await fe(e.child,e.killGraceMs))}})}function z(e){return new Promise((t,n)=>{new B(e,t,n).start()})}var B=class{options;resolve;reject;settled=!1;started=!1;ready=!1;timeoutTimer;handshakeTimer;handshakeBudgetMs;payload;deniedToolCallCounts={"no-approver":0,"denied-by-person":0,"approver-error":0,cancelled:0};pendingPermissionRequests=new Map;constructor(e,t,n){this.options=e,this.resolve=t,this.reject=n;let i=e.handshakeBudgetMs;this.handshakeBudgetMs=i!==void 0&&i>0?i:3e4,this.payload=e.payload.catch(e=>{this.rejectOnce(e instanceof Error?e:Error(String(e)))}),this.timeoutTimer=pe(this.options.runtime,e=>this.rejectOnce(e)),this.handshakeTimer=setTimeout(()=>{this.ready||this.settled||(R(this.options.runtime,`Subagent worker never signalled ready`),this.rejectOnce(new r.BackgroundTaskError(`runner`,`Subagent worker never signalled ready within ${this.handshakeBudgetMs}ms. Its entry must dispatch worker mode before starting the host application.`)))},this.handshakeBudgetMs),this.handshakeTimer.unref?.()}start(){let{child:e}=this.options.runtime;e.on(`message`,this.onMessage),e.on(`error`,this.onError),e.on(`exit`,this.onExit),e.once(`spawn`,()=>{setImmediate(this.startWorker)})}startWorker=()=>{if(this.started)return;this.started=!0;let{child:e}=this.options.runtime;this.payload.then(t=>t===void 0?void 0:L(e,{type:`start`,payload:t})).catch(e=>{this.rejectOnce(e instanceof Error?e:Error(String(e)))})};onMessage=e=>{if(!j(e)){this.rejectOnce(new r.BackgroundTaskError(`runner`,`Received malformed subagent worker message`));return}this.ready=!0,clearTimeout(this.handshakeTimer);let{job:t}=this.options.runtime;F(e,this.startWorker,this.resolveOnce,this.rejectOnce,t.emit,this.onPermissionRequest)};onPermissionRequest=e=>{let t=this.answerPermissionRequest(e).finally(()=>{this.pendingPermissionRequests.delete(e.requestId)});this.pendingPermissionRequests.set(e.requestId,t)};async answerPermissionRequest(e){let{reason:t,result:n}=await this.askApprover(e);t!==void 0&&(this.deniedToolCallCounts[t]+=1);let{child:r}=this.options.runtime;r.connected&&await L(r,{type:`permission_response`,requestId:e.requestId,result:n}).catch(()=>void 0)}async askApprover(e){let t=this.options.permissionApprover;if(t===void 0)return{reason:`no-approver`,result:!1};try{let n=await t(e.toolName,e.toolArgs??{},this.options.permissionAbort.signal);return n===!1?this.options.permissionAbort.signal.aborted?{reason:`cancelled`,result:!1}:{reason:`denied-by-person`,result:!1}:{result:n}}catch{return{reason:`approver-error`,result:!1}}}onError=e=>{this.rejectOnce(new r.BackgroundTaskError(`crash`,e.message))};onExit=(e,t)=>{this.settled||this.rejectOnce(new r.BackgroundTaskError(`crash`,ge(e,t,P(this.options.runtime.child))))};resolveOnce=e=>{this.settled||(this.settled=!0,this.settleAfterPendingPermissionRequests(()=>{let{runtime:t,resolveTranscriptPath:n}=this.options;this.resolve(me(t.job,e,n,this.deniedToolCallCounts))}))};rejectOnce=e=>{this.settled||(this.settled=!0,this.settleAfterPendingPermissionRequests(()=>this.reject(e)))};async settleAfterPendingPermissionRequests(e){this.options.permissionAbort.abort(),this.clearTimers(),this.cleanup(),await Promise.all(this.pendingPermissionRequests.values()),e()}clearTimers(){this.timeoutTimer&&clearTimeout(this.timeoutTimer),clearTimeout(this.handshakeTimer)}cleanup(){let{child:e}=this.options.runtime;e.off(`message`,this.onMessage),e.off(`error`,this.onError),e.off(`exit`,this.onExit)}};function V(e){let t=!1,n=()=>{};return{promise:new Promise((e,t)=>{n=t}),reject(i){t||(t=!0,n(new r.BackgroundTaskError(`runner`,i??`Subagent job cancelled: ${e}`)))}}}function pe(e,t){if(e.job.request.timeoutMs)return setTimeout(()=>{R(e,`Subagent worker timed out`),t(new r.BackgroundTaskError(`timeout`,`Subagent worker timed out`))},e.job.request.timeoutMs)}function me(e,t,n,r){let i=n(e),a=he(r);return{taskId:e.taskId,output:t.output,...i?{metadata:{transcriptPath:i,logPath:i}}:{},...t.usage?{usage:t.usage}:{},...a?{deniedToolCalls:a}:{}}}function he(e){let t=Object.values(e).reduce((e,t)=>e+t,0);return t===0?void 0:{total:t,byReason:{...e}}}function ge(e,t,n){return`Subagent worker exited before result: ${t===null?`exit code ${e===null?`unknown`:e}`:`signal ${t}`}${n.length>0?`: ${n}`:``}`}const H=`--__agent-subagent-worker`;function _e(e){return e.includes(H)}const ve=process.platform!==`win32`;function ye(e){return t=>{let n=new U(t,e);return e.worktreeIsolation===!1?n:(0,r.createWorktreeSubagentRunner)({runner:n,worktreeAdapter:e.worktreeAdapter,hooks:t.config.hooks,hookTypeExecutors:t.hookTypeExecutors})}}var U=class{deps;workerEntry;killGraceMs;handshakeBudgetMs;providerConfig;providerDefinitions;env;expectedEnvironment;inheritEnvironment;logsDir;parentSandboxSettings;watchParentSandboxSettings;constructor(e,t){if(this.deps=e,this.workerEntry=t.workerEntry,this.killGraceMs=t.killGraceMs??i.DEFAULT_KILL_GRACE_MS,this.handshakeBudgetMs=t.handshakeBudgetMs,this.providerConfig=t.providerConfig,this.providerDefinitions=t.providerDefinitions,this.env=t.env,this.expectedEnvironment=t.expectedEnvironment,this.inheritEnvironment=t.inheritEnvironment!==!1,!this.inheritEnvironment&&this.expectedEnvironment===void 0)throw Error(`An explicit expected environment is required when child inheritance is disabled.`);this.logsDir=t.logsDir,this.parentSandboxSettings=t.parentSandboxSettings,this.watchParentSandboxSettings=t.watchParentSandboxSettings}start(t){let n=this.workerEntry,i=this.inheritEnvironment?{...process.env,...this.env??{}}:{...this.env??{}},a=w(t,this.deps,{...this.providerConfig===void 0?{}:{providerConfig:this.providerConfig},providerDefinitions:this.providerDefinitions},this.expectedEnvironment??process.env,i),o=(0,e.spawn)(n.execPath,[...n.execArgv??[],...n.args,H],{cwd:(0,r.subagentExecutionRoot)(t),env:i,stdio:[`ignore`,`ignore`,`pipe`,`ipc`],detached:ve});N(o),this.forwardSandboxSettingChanges(o);let s={job:t,child:o,killGraceMs:this.killGraceMs},c=this.createStartPayload(t,a),l=new AbortController,u=this.permissionApprover(t),d=z({runtime:s,payload:c,...this.handshakeBudgetMs===void 0?{}:{handshakeBudgetMs:this.handshakeBudgetMs},resolveTranscriptPath:e=>this.resolveTranscriptPath(e),permissionAbort:l,...u===void 0?{}:{permissionApprover:u}}),f=V(t.taskId);d.catch(()=>void 0);let p=Promise.race([d,f.promise]);p.catch(()=>void 0);let m=this.resolveTranscriptPath(t);return{taskId:t.taskId,...o.pid!==void 0&&{pid:o.pid},...m!==void 0&&{transcriptPath:m,logPath:m},result:p,cancel:async e=>{l.abort(e),f.reject(e),await R(s,e)},send:async e=>{await L(o,{type:`send`,prompt:e})},...m!==void 0&&{readLog:async e=>be(t.taskId,m,e)}}}createStartPayload(e,t){let n=this.parentSandboxSettings?.();return te(e,this.deps,{connection:t,providerDefinitions:this.providerDefinitions,...this.logsDir===void 0?{}:{logsDir:this.logsDir},...n===void 0?{}:{parentSandboxSettings:n}})}forwardSandboxSettingChanges(e){let t=this.watchParentSandboxSettings?.(t=>{e.connected&&L(e,{type:`sandbox_settings`,settings:t}).catch(()=>void 0)});t!==void 0&&(e.once(`exit`,t),e.once(`error`,t))}resolveTranscriptPath(e){if(this.logsDir)return(0,n.join)(this.logsDir,e.request.parentSessionId,`subagents`,`${e.taskId}.jsonl`)}permissionApprover(e){let t=this.deps.permissionHandler;if(t===void 0)return;let n={kind:`background-agent`,label:e.request.agentType,taskId:e.taskId};return(e,r,i)=>t(e,r,{requester:n,signal:i})}};function be(e,n,i){return(0,t.existsSync)(n)?(0,r.createBackgroundTaskLogPage)(e,(0,t.readFileSync)(n,`utf8`).split(/\r?\n/).filter(Boolean),i):{taskId:e,cursor:i,lines:[]}}function xe(e,t,n){let r=e.request.resumeSessionId;if(r!==void 0){if(n===void 0)throw Error(`subagent worker: job ${e.taskId} asks to resume session ${r}, but this composition opens no session store. Register ISubagentWorkerComposition.openSessionStore at the composition root — the same place providerDefinitions is registered.`);(0,o.restoreSessionRecordIntoSession)(n,r,t)}}function Se(e,t){let n=e.request.resumeSessionId;if(n!==void 0){if(t.openSessionStore===void 0)throw Error(`subagent worker: job ${e.taskId} asks to resume session ${n}, but this composition opens no session store. Register ISubagentWorkerComposition.openSessionStore at the composition root — the same place providerDefinitions is registered.`);return t.openSessionStore({cwd:e.request.cwd})}}async function Ce(e,t){if(e===void 0)return;let n=t?.[e.type];if(n===void 0)throw Error(`subagent worker: sandbox type "${e.type}" is not registered in the worker composition. The parent is sandboxed and passed a snapshot reference, but this child cannot construct that client type. Register it in ISubagentWorkerComposition.sandboxFactories at the composition root — the same place providerDefinitions is registered, and for the same reason.`);return n(e.snapshotId)}const we={write:()=>{},writeLine:()=>{},writeMarkdown:()=>{},writeError:()=>{},prompt:()=>Promise.resolve(``),select:()=>Promise.resolve(0),spinner:()=>({stop:()=>{},update:()=>{}})};let W=null,G=!1;const K=new Map;let Te=0,q,J,Y,X=Promise.resolve();function Z(e){process.send&&process.send(e)}function Q(e,t){let n=!1,r=()=>{n||(n=!0,process.exit(t))};if(process.send){let t=setTimeout(r,2e3);t.unref?.(),process.send(e,void 0,void 0,()=>{clearTimeout(t),r()})}else r()}function Ee(e){try{return(0,a.sumHistoryUsage)(e.getFullHistory())}catch{return}}async function De(e,t){try{if(!(0,r.verifyConnectionEnvironment)(e.connectionCheck,process.env))throw Error(`The provider connection environment changed after the parent checked it; the subagent was not started.`);let n=await Ce(e.sandboxProjection,t.sandboxFactories),i=(0,r.createProviderFromExactProfile)(e.providerProfile,e.request.model,t.providerDefinitions),a=e.logsDir?(0,o.createSubagentLogger)(e.request.parentSessionId,e.taskId,e.logsDir):void 0,s=Se(e,t),c=q??e.parentSandboxSettings;J=n===void 0?t.createSandbox?.({cwd:(0,r.subagentExecutionRoot)(e),...c===void 0?{}:{parentSettings:c}}):void 0;let l=n??J?.client;W=(0,o.createSubagentSession)({agentDefinition:y(e.agentDefinition),parentConfig:e.parentConfig,parentContext:S(e.parentContext),parentTools:t.createTools({cwd:(0,r.subagentExecutionRoot)(e),...l===void 0?{}:{sandboxClient:l},...e.sessionTiers===void 0?{}:{sessionTiers:e.sessionTiers}}),cwd:(0,r.subagentExecutionRoot)(e),provider:i,terminal:we,sessionId:e.request.resumeSessionId??e.taskId,...s===void 0?{}:{sessionStore:s},...a?{sessionLogger:a}:{},permissionMode:e.permissionMode,...J?.commandSandbox===void 0?{}:{commandSandbox:J.commandSandbox},...e.request.permissionPolicy===void 0?{}:{permissionPolicy:e.request.permissionPolicy},...e.request.allowedTools===void 0?{}:{taskAllowedTools:e.request.allowedTools},...e.request.disallowedTools===void 0?{}:{taskDisallowedTools:e.request.disallowedTools},hooks:e.parentConfig.hooks,...t.createHookTypeExecutors===void 0?{}:{hookTypeExecutors:t.createHookTypeExecutors({cwd:(0,r.subagentExecutionRoot)(e),...l===void 0?{}:{sandboxClient:l}})},onTextDelta:e=>Z({type:`text_delta`,delta:e}),onToolExecution:Ae,permissionHandler:Oe}),xe(e,W,s);let u=await W.run(e.request.prompt);if(Y!==void 0){Q({type:`error`,message:Y},0);return}if(G){Q({type:`cancelled`,reason:`Subagent worker cancelled`},130);return}let d=Ee(W);Q({type:`result`,output:u,...d?{usage:d}:{}},0)}catch(e){if(Y!==void 0){Q({type:`error`,message:Y},0);return}if(G){Q({type:`cancelled`,reason:`Subagent worker cancelled`},130);return}Q({type:`error`,message:e instanceof Error?e.message:String(e)},0)}}function Oe(e,t){let n=`perm_${++Te}`;return new Promise(r=>{K.set(n,r),Z({type:`permission_request`,requestId:n,toolName:e,toolArgs:t})})}function ke(e,t){let n=K.get(e);n!==void 0&&(K.delete(e),n(t))}function Ae(e){if(e.type===`start`){Z({type:`tool_start`,toolName:e.toolName,toolArgs:e.toolArgs});return}Z({type:`tool_end`,toolName:e.toolName,success:e.success??!0})}function $(e){if(W===null){Z({type:`error`,message:`Subagent worker has not started`});return}X=X.then(async()=>{try{await W?.run(e)}catch(e){Z({type:`error`,message:e instanceof Error?e.message:String(e)})}})}async function je(e){G=!0,W?.abort(),Z({type:`cancelled`,reason:e}),await W?.shutdown({reason:`other`}).catch(()=>void 0),setTimeout(()=>process.exit(130),0)}function Me(e){try{return e.createTools({cwd:process.cwd()}).map(e=>e.getName())}catch(e){process.stderr.write(`agent: could not enumerate the composed tool surface: ${e instanceof Error?e.message:String(e)}\n`);return}}function Ne(e){q=e;try{J?.applyParentSettings?.(e)}catch(e){Y??=e instanceof Error?e.message:String(e),W?.abort()}}function Pe(e){process.send===void 0&&(process.stderr.write(`agent: subagent worker mode requires an IPC channel; it is started by the agent runtime, not by hand.
2
2
  `),process.exit(2)),process.on(`message`,t=>{if(!A(t)){Z({type:`error`,message:`Malformed subagent worker parent message`});return}switch(t.type){case`start`:X=X.then(()=>De(t.payload,e));break;case`send`:$(t.prompt);break;case`cancel`:je(t.reason);break;case`sandbox_settings`:Ne(t.settings);break;case`permission_response`:ke(t.requestId,t.result);break;default:Z({type:`error`,message:`Unhandled subagent worker parent message`})}}),process.on(`disconnect`,()=>{G=!0,W?.abort(),W?.shutdown({reason:`other`}).catch(()=>void 0)});let t=Me(e);Z({type:`ready`,...t?{composedToolNames:t}:{}})}exports.ChildProcessSubagentRunner=U,exports.SUBAGENT_WORKER_MODE_FLAG=H,exports.createChildProcessSubagentRunnerFactory=ye,exports.decodeAgentDefinitionDto=v,exports.decodeParentContextDto=x,exports.encodeAgentDefinition=_,exports.encodeParentContext=b,exports.isSubagentWorkerChildMessage=j,exports.isSubagentWorkerModeArgv=_e,exports.isSubagentWorkerParentMessage=A,exports.restoreAgentDefinition=y,exports.restoreParentContext=S,exports.runSubagentWorkerMain=Pe;
@@ -21,7 +21,7 @@ import { ISerializableProviderProfile, ISubagentSpawnRequest } from "@robota-sdk
21
21
  * Deliberately not a plausible user flag: it is part of an internal process contract, and a user
22
22
  * who types it gets a loud refusal rather than a half-started worker.
23
23
  */
24
- declare const SUBAGENT_WORKER_MODE_FLAG = "--__robota-subagent-worker";
24
+ declare const SUBAGENT_WORKER_MODE_FLAG = "--__agent-subagent-worker";
25
25
  /**
26
26
  * How to spawn a copy of the running artifact in subagent-worker mode.
27
27
  *
@@ -61,7 +61,7 @@ type TResumeSessionStore = Parameters<typeof restoreSessionRecordIntoSession>[0]
61
61
  * `createDefaultProviderDefinitions()` and building the child's surface from them, while the
62
62
  * composition root had already handed the runner the fully composed surface. So a product's custom
63
63
  * providers and pack-owned tools reached an in-process subagent and not a child-process one, and
64
- * ARCH-006's invariant — every tool robota runs comes from a pack — was false in the child.
64
+ * ARCH-006's invariant — every tool agent runs comes from a pack — was false in the child.
65
65
  *
66
66
  * **Why a recipe rather than the instances.** A composition cannot be projected across a process
67
67
  * boundary, because it is code: `createProvider` is a function and a tool carries `execute`. The two
@@ -72,8 +72,11 @@ type TResumeSessionStore = Parameters<typeof restoreSessionRecordIntoSession>[0]
72
72
  * comparable product does.
73
73
  */
74
74
  interface ISubagentWorkerComposition {
75
- /** Product-selected hook executors for the child session. */
76
- createHookTypeExecutors?: () => IHookTypeExecutor[];
75
+ /** Product-selected hooks receive the same execution boundary as the child tools. */
76
+ createHookTypeExecutors?: (context: {
77
+ readonly cwd: string;
78
+ readonly sandboxClient?: TProjectedSandboxClient;
79
+ }) => IHookTypeExecutor[];
77
80
  /**
78
81
  * The product's tool surface for THIS subagent's execution root.
79
82
  *
@@ -237,6 +240,10 @@ interface IChildProcessSubagentRunnerOptions {
237
240
  */
238
241
  handshakeBudgetMs?: number;
239
242
  env?: NodeJS.ProcessEnv;
243
+ /** Explicit host snapshot used to resolve this provider; defaults to the live process environment. */
244
+ expectedEnvironment?: NodeJS.ProcessEnv;
245
+ /** A host can supply a curated child environment without inheriting unrelated process secrets. */
246
+ inheritEnvironment?: boolean;
240
247
  worktreeIsolation?: boolean;
241
248
  worktreeAdapter: ISubagentWorktreeAdapter;
242
249
  logsDir?: string;
@@ -262,6 +269,8 @@ declare class ChildProcessSubagentRunner implements ISubagentRunner {
262
269
  private readonly providerConfig?;
263
270
  private readonly providerDefinitions;
264
271
  private readonly env?;
272
+ private readonly expectedEnvironment?;
273
+ private readonly inheritEnvironment;
265
274
  private readonly logsDir?;
266
275
  private readonly parentSandboxSettings?;
267
276
  private readonly watchParentSandboxSettings?;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/worker-entry.ts","../../src/worker-composition.ts","../../src/child-process-subagent-runner.ts","../../src/subagent-worker-start-dto.ts","../../src/child-process-subagent-ipc.ts","../../src/child-process-subagent-worker.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;cAmBa;;;;;;;;;;UAWI;;WAEN;;WAEA;;WAEA;;;iBAIK,yBAAyB;;;;;;;;;KC3B7B,sBAAsB,kBAAkB;;;;;;;;;;;;;;;;;;;;;;UAuBnC;;EAEf,gCAAgC;;;;;;;;;EAShC,YAAY;aACD;;;;;;;;;;;;;;aAcA;;eAEE;;;;;;;;;;aAUF,gBAAgB;MACvB;;;;;;WAOK,8BAA8B;;;;;;;;;;;;;;;;;;;;;WAsB9B,mBAAmB,SAAS,eAAe;;;;;;;;;;;;;;WAe3C,oBAAoB;aAAoB;QAAkB;;;;;;;;;;WAW1D,iBAAiB;aACf;;aAEA,iBAAiB;QACtB;;;KAII,yBAAyB,SAAS;;UAG7B;WACN,QAAQ;WACR,iBAAiB;;;;;;;WAOjB,uBAAuB,UAAU;;;;;;;;KAShC,yBAAyB,uBAAuB,QAAQ;;;;;;;;;;;;;KAcxD;;;;;;;UAQK;WACN;WACA;;;;UCzHM;;;;;;;EAOf,aAAa;EACb,iBAAiB;;;;;;EAMjB,8BAA8B;EAC9B;;;;;EAKA;EACA,MAAM,OAAO;EACb;EACA,iBAAiB;EACjB;;;;;;EAMA,8BAA8B;;;;;;EAM9B,8BAA8B,WAAW,UAAU;;iBAGrC,wCACd,SAAS,qCACR;cAaU,sCAAsC;mBAY9B;mBAXF;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;EAGE,YAAA,MAAM,8BACvB,SAAS;EAaX,MAAM,KAAK,oBAAoB;;;;;;;;;UAoGvB;UAaA;UAYA;;;;;;;;;UAaA;;;;;;;;KC3PL,sBAAsB;UAEV;WACN;WACA;WACA;WACA;WACA,SAAS;WACT;WACA;WACA;WACA;;UAGM;WACN;WACA;WACA;;UAGM;WACN;WACA;WACA;WACA;WACA;WACA,6BAA6B;WAC7B,mCAAmC;;KAmClC,iBAAiB;WAChB;WAAmB,OAAO;;WAAoB;WAAoB;;iBAmE/D,sBACd,YAAY,mBACX;iBAOa,yBACd,iBACC,iBAAiB;;iBASJ,uBAAuB,KAAK,oCAAoC;;iBAgBhE,oBACd,SAAS,yBACR;iBAOa,uBACd,iBACC,iBAAiB;iBAIJ,qBAAqB,KAAK,kCAAkC;;;KClMhE;;UAKK;WACN;aAAqB;;WACrB,aAAa;WACb,mBAAmB;WACnB,QAAQ;;UAGF;EACf;EACA,SAAS;;;;;;;;;;EAUT;aAAsB;aAAuB;;;EAE7C,iBAAiB;;;;;;;;;;;EAWjB,cAAc;;;;;;;EAOd,eAAe;EACf,iBAAiB;;;;;EAKjB,iBAAiB;;;;;;;;;;;;EAYjB,oBAAoB;;;;;;;EAOpB;aAA0B;;;;;;;EAM1B,wBAAwB;EACxB,iBAAiB;EACjB;;UAGe;EACf;EACA,SAAS;;UAGM;EACf;EACA;;UAGe;EACf;EACA;;;UAIe;EACf;EACA,UAAU;;;;;;;KAQA;;;;;;UAOK;EACf;EACA;EACA,QAAQ;;KAGE,+BACR,8BACA,6BACA,+BACA,wCACA;UAEa;EACf;;;;;;;;;EASA;;UAGe;EACf;EACA;;UAGe;EACf;EACA;EACA,WAAW;;UAGI;EACf;EACA;EACA;;;;;;;UAQe;EACf;EACA;EACA;EACA,WAAW;;UAGI;EACf;EACA;;EAEA,QAAQ;;UAGO;EACf;EACA;;UAGe;EACf;EACA;;KAGU,8BACR,8BACA,kCACA,kCACA,gCACA,0CACA,+BACA,8BACA;iBAkHY,8BACd,OAAO,2BACN,SAAS;iBAuBI,6BACd,OAAO,2BACN,SAAS;;;;;;;;;;;;;;iBCNI,sBAAsB,aAAa"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/worker-entry.ts","../../src/worker-composition.ts","../../src/child-process-subagent-runner.ts","../../src/subagent-worker-start-dto.ts","../../src/child-process-subagent-ipc.ts","../../src/child-process-subagent-worker.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;cAmBa;;;;;;;;;;UAWI;;WAEN;;WAEA;;WAEA;;;iBAIK,yBAAyB;;;;;;;;;KC3B7B,sBAAsB,kBAAkB;;;;;;;;;;;;;;;;;;;;;;UAuBnC;;EAEf,2BAA2B;aAChB;aACA,gBAAgB;QACrB;;;;;;;;;EASN,YAAY;aACD;;;;;;;;;;;;;;aAcA;;eAEE;;;;;;;;;;aAUF,gBAAgB;MACvB;;;;;;WAOK,8BAA8B;;;;;;;;;;;;;;;;;;;;;WAsB9B,mBAAmB,SAAS,eAAe;;;;;;;;;;;;;;WAe3C,oBAAoB;aAAoB;QAAkB;;;;;;;;;;WAW1D,iBAAiB;aACf;;aAEA,iBAAiB;QACtB;;;KAII,yBAAyB,SAAS;;UAG7B;WACN,QAAQ;WACR,iBAAiB;;;;;;;WAOjB,uBAAuB,UAAU;;;;;;;;KAShC,yBAAyB,uBAAuB,QAAQ;;;;;;;;;;;;;KAcxD;;;;;;;UAQK;WACN;WACA;;;;UC5HM;;;;;;;EAOf,aAAa;EACb,iBAAiB;;;;;;EAMjB,8BAA8B;EAC9B;;;;;EAKA;EACA,MAAM,OAAO;;EAEb,sBAAsB,OAAO;;EAE7B;EACA;EACA,iBAAiB;EACjB;;;;;;EAMA,8BAA8B;;;;;;EAM9B,8BAA8B,WAAW,UAAU;;iBAGrC,wCACd,SAAS,qCACR;cAaU,sCAAsC;mBAc9B;mBAbF;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;EAGE,YAAA,MAAM,8BACvB,SAAS;EAkBX,MAAM,KAAK,oBAAoB;;;;;;;;;UAoGvB;UAaA;UAYA;;;;;;;;;UAaA;;;;;;;;KCtQL,sBAAsB;UAEV;WACN;WACA;WACA;WACA;WACA,SAAS;WACT;WACA;WACA;WACA;;UAGM;WACN;WACA;WACA;;UAGM;WACN;WACA;WACA;WACA;WACA;WACA,6BAA6B;WAC7B,mCAAmC;;KAmClC,iBAAiB;WAChB;WAAmB,OAAO;;WAAoB;WAAoB;;iBAmE/D,sBACd,YAAY,mBACX;iBAOa,yBACd,iBACC,iBAAiB;;iBASJ,uBAAuB,KAAK,oCAAoC;;iBAgBhE,oBACd,SAAS,yBACR;iBAOa,uBACd,iBACC,iBAAiB;iBAIJ,qBAAqB,KAAK,kCAAkC;;;KClMhE;;UAKK;WACN;aAAqB;;WACrB,aAAa;WACb,mBAAmB;WACnB,QAAQ;;UAGF;EACf;EACA,SAAS;;;;;;;;;;EAUT;aAAsB;aAAuB;;;EAE7C,iBAAiB;;;;;;;;;;;EAWjB,cAAc;;;;;;;EAOd,eAAe;EACf,iBAAiB;;;;;EAKjB,iBAAiB;;;;;;;;;;;;EAYjB,oBAAoB;;;;;;;EAOpB;aAA0B;;;;;;;EAM1B,wBAAwB;EACxB,iBAAiB;EACjB;;UAGe;EACf;EACA,SAAS;;UAGM;EACf;EACA;;UAGe;EACf;EACA;;;UAIe;EACf;EACA,UAAU;;;;;;;KAQA;;;;;;UAOK;EACf;EACA;EACA,QAAQ;;KAGE,+BACR,8BACA,6BACA,+BACA,wCACA;UAEa;EACf;;;;;;;;;EASA;;UAGe;EACf;EACA;;UAGe;EACf;EACA;EACA,WAAW;;UAGI;EACf;EACA;EACA;;;;;;;UAQe;EACf;EACA;EACA;EACA,WAAW;;UAGI;EACf;EACA;;EAEA,QAAQ;;UAGO;EACf;EACA;;UAGe;EACf;EACA;;KAGU,8BACR,8BACA,kCACA,kCACA,gCACA,0CACA,+BACA,8BACA;iBAkHY,8BACd,OAAO,2BACN,SAAS;iBAuBI,6BACd,OAAO,2BACN,SAAS;;;;;;;;;;;;;;iBCDI,sBAAsB,aAAa"}
@@ -21,7 +21,7 @@ import { ISerializableProviderProfile, ISubagentSpawnRequest } from "@robota-sdk
21
21
  * Deliberately not a plausible user flag: it is part of an internal process contract, and a user
22
22
  * who types it gets a loud refusal rather than a half-started worker.
23
23
  */
24
- declare const SUBAGENT_WORKER_MODE_FLAG = "--__robota-subagent-worker";
24
+ declare const SUBAGENT_WORKER_MODE_FLAG = "--__agent-subagent-worker";
25
25
  /**
26
26
  * How to spawn a copy of the running artifact in subagent-worker mode.
27
27
  *
@@ -61,7 +61,7 @@ type TResumeSessionStore = Parameters<typeof restoreSessionRecordIntoSession>[0]
61
61
  * `createDefaultProviderDefinitions()` and building the child's surface from them, while the
62
62
  * composition root had already handed the runner the fully composed surface. So a product's custom
63
63
  * providers and pack-owned tools reached an in-process subagent and not a child-process one, and
64
- * ARCH-006's invariant — every tool robota runs comes from a pack — was false in the child.
64
+ * ARCH-006's invariant — every tool agent runs comes from a pack — was false in the child.
65
65
  *
66
66
  * **Why a recipe rather than the instances.** A composition cannot be projected across a process
67
67
  * boundary, because it is code: `createProvider` is a function and a tool carries `execute`. The two
@@ -72,8 +72,11 @@ type TResumeSessionStore = Parameters<typeof restoreSessionRecordIntoSession>[0]
72
72
  * comparable product does.
73
73
  */
74
74
  interface ISubagentWorkerComposition {
75
- /** Product-selected hook executors for the child session. */
76
- createHookTypeExecutors?: () => IHookTypeExecutor[];
75
+ /** Product-selected hooks receive the same execution boundary as the child tools. */
76
+ createHookTypeExecutors?: (context: {
77
+ readonly cwd: string;
78
+ readonly sandboxClient?: TProjectedSandboxClient;
79
+ }) => IHookTypeExecutor[];
77
80
  /**
78
81
  * The product's tool surface for THIS subagent's execution root.
79
82
  *
@@ -237,6 +240,10 @@ interface IChildProcessSubagentRunnerOptions {
237
240
  */
238
241
  handshakeBudgetMs?: number;
239
242
  env?: NodeJS.ProcessEnv;
243
+ /** Explicit host snapshot used to resolve this provider; defaults to the live process environment. */
244
+ expectedEnvironment?: NodeJS.ProcessEnv;
245
+ /** A host can supply a curated child environment without inheriting unrelated process secrets. */
246
+ inheritEnvironment?: boolean;
240
247
  worktreeIsolation?: boolean;
241
248
  worktreeAdapter: ISubagentWorktreeAdapter;
242
249
  logsDir?: string;
@@ -262,6 +269,8 @@ declare class ChildProcessSubagentRunner implements ISubagentRunner {
262
269
  private readonly providerConfig?;
263
270
  private readonly providerDefinitions;
264
271
  private readonly env?;
272
+ private readonly expectedEnvironment?;
273
+ private readonly inheritEnvironment;
265
274
  private readonly logsDir?;
266
275
  private readonly parentSandboxSettings?;
267
276
  private readonly watchParentSandboxSettings?;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/worker-entry.ts","../../src/worker-composition.ts","../../src/child-process-subagent-runner.ts","../../src/subagent-worker-start-dto.ts","../../src/child-process-subagent-ipc.ts","../../src/child-process-subagent-worker.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;cAmBa;;;;;;;;;;UAWI;;WAEN;;WAEA;;WAEA;;;iBAIK,yBAAyB;;;;;;;;;KC3B7B,sBAAsB,kBAAkB;;;;;;;;;;;;;;;;;;;;;;UAuBnC;;EAEf,gCAAgC;;;;;;;;;EAShC,YAAY;aACD;;;;;;;;;;;;;;aAcA;;eAEE;;;;;;;;;;aAUF,gBAAgB;MACvB;;;;;;WAOK,8BAA8B;;;;;;;;;;;;;;;;;;;;;WAsB9B,mBAAmB,SAAS,eAAe;;;;;;;;;;;;;;WAe3C,oBAAoB;aAAoB;QAAkB;;;;;;;;;;WAW1D,iBAAiB;aACf;;aAEA,iBAAiB;QACtB;;;KAII,yBAAyB,SAAS;;UAG7B;WACN,QAAQ;WACR,iBAAiB;;;;;;;WAOjB,uBAAuB,UAAU;;;;;;;;KAShC,yBAAyB,uBAAuB,QAAQ;;;;;;;;;;;;;KAcxD;;;;;;;UAQK;WACN;WACA;;;;UCzHM;;;;;;;EAOf,aAAa;EACb,iBAAiB;;;;;;EAMjB,8BAA8B;EAC9B;;;;;EAKA;EACA,MAAM,OAAO;EACb;EACA,iBAAiB;EACjB;;;;;;EAMA,8BAA8B;;;;;;EAM9B,8BAA8B,WAAW,UAAU;;iBAGrC,wCACd,SAAS,qCACR;cAaU,sCAAsC;mBAY9B;mBAXF;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;EAGE,YAAA,MAAM,8BACvB,SAAS;EAaX,MAAM,KAAK,oBAAoB;;;;;;;;;UAoGvB;UAaA;UAYA;;;;;;;;;UAaA;;;;;;;;KC3PL,sBAAsB;UAEV;WACN;WACA;WACA;WACA;WACA,SAAS;WACT;WACA;WACA;WACA;;UAGM;WACN;WACA;WACA;;UAGM;WACN;WACA;WACA;WACA;WACA;WACA,6BAA6B;WAC7B,mCAAmC;;KAmClC,iBAAiB;WAChB;WAAmB,OAAO;;WAAoB;WAAoB;;iBAmE/D,sBACd,YAAY,mBACX;iBAOa,yBACd,iBACC,iBAAiB;;iBASJ,uBAAuB,KAAK,oCAAoC;;iBAgBhE,oBACd,SAAS,yBACR;iBAOa,uBACd,iBACC,iBAAiB;iBAIJ,qBAAqB,KAAK,kCAAkC;;;KClMhE;;UAKK;WACN;aAAqB;;WACrB,aAAa;WACb,mBAAmB;WACnB,QAAQ;;UAGF;EACf;EACA,SAAS;;;;;;;;;;EAUT;aAAsB;aAAuB;;;EAE7C,iBAAiB;;;;;;;;;;;EAWjB,cAAc;;;;;;;EAOd,eAAe;EACf,iBAAiB;;;;;EAKjB,iBAAiB;;;;;;;;;;;;EAYjB,oBAAoB;;;;;;;EAOpB;aAA0B;;;;;;;EAM1B,wBAAwB;EACxB,iBAAiB;EACjB;;UAGe;EACf;EACA,SAAS;;UAGM;EACf;EACA;;UAGe;EACf;EACA;;;UAIe;EACf;EACA,UAAU;;;;;;;KAQA;;;;;;UAOK;EACf;EACA;EACA,QAAQ;;KAGE,+BACR,8BACA,6BACA,+BACA,wCACA;UAEa;EACf;;;;;;;;;EASA;;UAGe;EACf;EACA;;UAGe;EACf;EACA;EACA,WAAW;;UAGI;EACf;EACA;EACA;;;;;;;UAQe;EACf;EACA;EACA;EACA,WAAW;;UAGI;EACf;EACA;;EAEA,QAAQ;;UAGO;EACf;EACA;;UAGe;EACf;EACA;;KAGU,8BACR,8BACA,kCACA,kCACA,gCACA,0CACA,+BACA,8BACA;iBAkHY,8BACd,OAAO,2BACN,SAAS;iBAuBI,6BACd,OAAO,2BACN,SAAS;;;;;;;;;;;;;;iBCNI,sBAAsB,aAAa"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/worker-entry.ts","../../src/worker-composition.ts","../../src/child-process-subagent-runner.ts","../../src/subagent-worker-start-dto.ts","../../src/child-process-subagent-ipc.ts","../../src/child-process-subagent-worker.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;cAmBa;;;;;;;;;;UAWI;;WAEN;;WAEA;;WAEA;;;iBAIK,yBAAyB;;;;;;;;;KC3B7B,sBAAsB,kBAAkB;;;;;;;;;;;;;;;;;;;;;;UAuBnC;;EAEf,2BAA2B;aAChB;aACA,gBAAgB;QACrB;;;;;;;;;EASN,YAAY;aACD;;;;;;;;;;;;;;aAcA;;eAEE;;;;;;;;;;aAUF,gBAAgB;MACvB;;;;;;WAOK,8BAA8B;;;;;;;;;;;;;;;;;;;;;WAsB9B,mBAAmB,SAAS,eAAe;;;;;;;;;;;;;;WAe3C,oBAAoB;aAAoB;QAAkB;;;;;;;;;;WAW1D,iBAAiB;aACf;;aAEA,iBAAiB;QACtB;;;KAII,yBAAyB,SAAS;;UAG7B;WACN,QAAQ;WACR,iBAAiB;;;;;;;WAOjB,uBAAuB,UAAU;;;;;;;;KAShC,yBAAyB,uBAAuB,QAAQ;;;;;;;;;;;;;KAcxD;;;;;;;UAQK;WACN;WACA;;;;UC5HM;;;;;;;EAOf,aAAa;EACb,iBAAiB;;;;;;EAMjB,8BAA8B;EAC9B;;;;;EAKA;EACA,MAAM,OAAO;;EAEb,sBAAsB,OAAO;;EAE7B;EACA;EACA,iBAAiB;EACjB;;;;;;EAMA,8BAA8B;;;;;;EAM9B,8BAA8B,WAAW,UAAU;;iBAGrC,wCACd,SAAS,qCACR;cAaU,sCAAsC;mBAc9B;mBAbF;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;EAGE,YAAA,MAAM,8BACvB,SAAS;EAkBX,MAAM,KAAK,oBAAoB;;;;;;;;;UAoGvB;UAaA;UAYA;;;;;;;;;UAaA;;;;;;;;KCtQL,sBAAsB;UAEV;WACN;WACA;WACA;WACA;WACA,SAAS;WACT;WACA;WACA;WACA;;UAGM;WACN;WACA;WACA;;UAGM;WACN;WACA;WACA;WACA;WACA;WACA,6BAA6B;WAC7B,mCAAmC;;KAmClC,iBAAiB;WAChB;WAAmB,OAAO;;WAAoB;WAAoB;;iBAmE/D,sBACd,YAAY,mBACX;iBAOa,yBACd,iBACC,iBAAiB;;iBASJ,uBAAuB,KAAK,oCAAoC;;iBAgBhE,oBACd,SAAS,yBACR;iBAOa,uBACd,iBACC,iBAAiB;iBAIJ,qBAAqB,KAAK,kCAAkC;;;KClMhE;;UAKK;WACN;aAAqB;;WACrB,aAAa;WACb,mBAAmB;WACnB,QAAQ;;UAGF;EACf;EACA,SAAS;;;;;;;;;;EAUT;aAAsB;aAAuB;;;EAE7C,iBAAiB;;;;;;;;;;;EAWjB,cAAc;;;;;;;EAOd,eAAe;EACf,iBAAiB;;;;;EAKjB,iBAAiB;;;;;;;;;;;;EAYjB,oBAAoB;;;;;;;EAOpB;aAA0B;;;;;;;EAM1B,wBAAwB;EACxB,iBAAiB;EACjB;;UAGe;EACf;EACA,SAAS;;UAGM;EACf;EACA;;UAGe;EACf;EACA;;;UAIe;EACf;EACA,UAAU;;;;;;;KAQA;;;;;;UAOK;EACf;EACA;EACA,QAAQ;;KAGE,+BACR,8BACA,6BACA,+BACA,wCACA;UAEa;EACf;;;;;;;;;EASA;;UAGe;EACf;EACA;;UAGe;EACf;EACA;EACA,WAAW;;UAGI;EACf;EACA;EACA;;;;;;;UAQe;EACf;EACA;EACA;EACA,WAAW;;UAGI;EACf;EACA;;EAEA,QAAQ;;UAGO;EACf;EACA;;UAGe;EACf;EACA;;KAGU,8BACR,8BACA,kCACA,kCACA,gCACA,0CACA,+BACA,8BACA;iBAkHY,8BACd,OAAO,2BACN,SAAS;iBAuBI,6BACd,OAAO,2BACN,SAAS;;;;;;;;;;;;;;iBCDI,sBAAsB,aAAa"}
@@ -1,3 +1,3 @@
1
- import{spawn as e}from"node:child_process";import{existsSync as t,readFileSync as n}from"node:fs";import{join as r}from"node:path";import{BackgroundTaskError as i,connectionEnvironmentNames as a,createBackgroundTaskLogPage as o,createProviderFromExactProfile as s,createWorktreeSubagentRunner as c,findConnectionEnvironmentDivergence as l,sealConnectionEnvironment as u,subagentExecutionRoot as d,verifyConnectionEnvironment as f}from"@robota-sdk/agent-executor";import{DEFAULT_KILL_GRACE_MS as p,killProcessTree as m}from"@robota-sdk/agent-process";import{createBoundedOutput as ee,findProviderDefinition as h,isModelEffort as te,sumHistoryUsage as ne}from"@robota-sdk/agent-core";import{createSubagentLogger as g,createSubagentSession as re,restoreSessionRecordIntoSession as ie}from"@robota-sdk/agent-framework";function ae(e){return{provider:{model:e.provider.model},permissions:e.permissions,defaultTrustLevel:e.defaultTrustLevel,...e.hooks===void 0?{}:{hooks:e.hooks}}}function oe(e){return{agentsMd:e.agentsMd,projectNotesMd:e.projectNotesMd}}const _={name:{kind:`string`,required:!0},description:{kind:`string`,required:!0},systemPrompt:{kind:`string`,required:!0},model:{kind:`string`,required:!1},effort:{kind:`effort`,required:!1},role:{kind:`string`,required:!1},maxTurns:{kind:`number`,required:!1},tools:{kind:`string[]`,required:!1},disallowedTools:{kind:`string[]`,required:!1}},v={agentsMd:{kind:`string`,required:!0},projectNotesMd:{kind:`string`,required:!0},memoryMd:{kind:`string`,required:!1},taskContext:{kind:`string`,required:!1},compactInstructions:{kind:`string`,required:!1},agentsFileEntries:{kind:`file-entry[]`,required:!1},projectNotesFileEntries:{kind:`file-entry[]`,required:!1}};function y(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function se(e){return Array.isArray(e)&&e.every(e=>typeof e==`string`)}function ce(e){return y(e)&&typeof e.filePath==`string`&&typeof e.content==`string`&&typeof e.contentHash==`string`}function le(e,t){switch(e){case`string`:return typeof t==`string`;case`number`:return typeof t==`number`&&Number.isFinite(t);case`effort`:return typeof t==`string`&&te(t);case`string[]`:return se(t);case`file-entry[]`:return Array.isArray(t)&&t.every(ce)}}function b(e,t){let n={};for(let r of Object.keys(t)){let t=e[r];t!==void 0&&(n[r]=t)}return n}function x(e,t,n){if(!y(t))return{ok:!1,reason:`${e}: expected an object`};for(let[r,i]of Object.entries(n)){let n=t[r];if(n===void 0){if(i.required)return{ok:!1,reason:`${e}.${r}: required`};continue}if(!le(i.kind,n))return{ok:!1,reason:`${e}.${r}: expected ${i.kind}`}}return{ok:!0,value:b(t,n)}}function S(e){return b(e,_)}function C(e){return x(`agentDefinition`,e,_)}function w(e){let t={name:e.name,description:e.description,systemPrompt:e.systemPrompt};return e.model!==void 0&&(t.model=e.model),e.effort!==void 0&&(t.effort=e.effort),e.role!==void 0&&(t.role=e.role),e.maxTurns!==void 0&&(t.maxTurns=e.maxTurns),e.tools!==void 0&&(t.tools=[...e.tools]),e.disallowedTools!==void 0&&(t.disallowedTools=[...e.disallowedTools]),t}function T(e){return b(e,v)}function E(e){return x(`parentContext`,e,v)}function D(e){let t={agentsMd:e.agentsMd,projectNotesMd:e.projectNotesMd};return e.memoryMd!==void 0&&(t.memoryMd=e.memoryMd),e.taskContext!==void 0&&(t.taskContext=e.taskContext),e.compactInstructions!==void 0&&(t.compactInstructions=e.compactInstructions),e.agentsFileEntries!==void 0&&(t.agentsFileEntries=e.agentsFileEntries.map(e=>({...e}))),e.projectNotesFileEntries!==void 0&&(t.projectNotesFileEntries=e.projectNotesFileEntries.map(e=>({...e}))),t}function ue(e){return e.sessionTiers===void 0?{}:{sessionTiers:e.sessionTiers}}async function de(e){let{sandboxClient:t,sandboxType:n}=e;return t?.snapshot===void 0||n===void 0?{}:{sandboxProjection:{type:n,snapshotId:await t.snapshot()}}}function O(e,t,n,r,o){let s=n.providerDefinitions,c=(n.providerConfig??t.config.provider).name;if(h(s,c)===void 0)throw new i(`validation`,`No provider definition for "${c}" was given to the subagent runner, so the connection a child would make cannot be checked; the subagent was not started.`);let d=ge(n.providerConfig,t,e,s),f=a(d,s),p=l(f,r,o);if(p!==void 0)throw new i(`validation`,`The subagent's environment sets ${p} differently from this session, which would change where its provider connects or which credential it sends; the subagent was not started.`);return{providerProfile:d,connectionCheck:u(f,o)}}function fe(e,t,n){let r=pe(e.request.agentType,t.customAgentRegistry,t.builtInAgents,t.agentDefinitions),i={taskId:e.taskId,request:e.request,...e.worktree?{worktree:e.worktree}:{},agentDefinition:S(me(r,e)),parentConfig:ae(t.getParentPermissionRules===void 0?t.config:{...t.config,permissions:t.getParentPermissionRules()}),parentContext:T(oe(t.context)),...n.connection??O(e,t,n,process.env,process.env),permissionMode:t.getParentPermissionMode?.()??t.permissionMode,...ue(t),...n.parentSandboxSettings===void 0?{}:{parentSandboxSettings:n.parentSandboxSettings},...n.logsDir?{logsDir:n.logsDir}:{}};return de(t).then(e=>({...i,...e}))}function pe(e,t,n,r){let a=t?.(e)??n?.find(t=>t.name===e)??r?.find(t=>t.name===e);if(!a)throw new i(`validation`,`Unknown agent type: ${e}`);return a}function me(e,t){return{...e,...t.request.model?{model:t.request.model}:{},...t.request.effort===void 0?{}:{effort:t.request.effort},...t.request.allowedTools?{tools:t.request.allowedTools}:{},...t.request.disallowedTools?{disallowedTools:t.request.disallowedTools}:{}}}function he(e,t){return e.apiKeyEnv===void 0?e.apiKey===void 0?t===void 0?{}:t.startsWith(`$ENV:`)?{apiKeyEnv:t.slice(5)}:{apiKey:t}:{apiKey:e.apiKey}:{apiKeyEnv:e.apiKeyEnv}}function ge(e,t,n,r){let i=e??t.config.provider,a=h(r,i.name)?.defaults??{},o=i.baseURL??a.baseURL,s=i.options??a.options,c=he(i,a.apiKey);return{...e===void 0&&t.config.currentProvider!==void 0?{profileName:t.config.currentProvider}:{},type:i.name,model:n.request.model??i.model,...c,...o===void 0?{}:{baseURL:o},...i.timeout===void 0?{}:{timeout:i.timeout},...s===void 0?{}:{options:s}}}function k(e){return typeof e==`object`&&!!e}function _e(e){if(!k(e)||!A(e,`nonce`)||!A(e,`digest`))return!1;let t=e.names;return Array.isArray(t)&&t.every(e=>typeof e==`string`)}function A(e,t){return typeof e[t]==`string`}function j(e,t){return A(e,t)}function M(e,t){return A(e,t)}function N(e,t){return e[t]===void 0||typeof e[t]==`string`}function P(e){if(e.usage===void 0)return!0;let t=e.usage;return k(t)?typeof t.promptTokens==`number`&&typeof t.completionTokens==`number`&&typeof t.totalTokens==`number`:!1}function F(e){if(e.composedToolNames===void 0)return!0;let t=e.composedToolNames;return Array.isArray(t)?t.every(e=>typeof e==`string`):!1}function I(e){return!k(e)||!M(e,`taskId`)||!k(e.request)||!j(e.request,`agentType`)||!j(e.request,`prompt`)||!j(e.request,`permissionPolicy`)||!j(e.request,`cwd`)||!N(e.request,`resumeSessionId`)||e.worktree!==void 0&&(!k(e.worktree)||!A(e.worktree,`path`))||!C(e.agentDefinition).ok||!k(e.parentConfig)||!E(e.parentContext).ok||!k(e.providerProfile)||!A(e.providerProfile,`type`)||!A(e.providerProfile,`model`)||e.parentSandboxSettings!==void 0&&!k(e.parentSandboxSettings)?!1:_e(e.connectionCheck)}function L(e){if(!k(e)||!A(e,`type`))return!1;switch(e.type){case`start`:return I(e.payload);case`send`:return A(e,`prompt`);case`cancel`:return e.reason===void 0||typeof e.reason==`string`;case`sandbox_settings`:return k(e.settings);case`permission_response`:return A(e,`requestId`)&&ve(e.result);default:return!1}}function ve(e){return typeof e==`boolean`||e===`allow-session`||e===`allow-project`}function R(e){if(!k(e)||!A(e,`type`))return!1;switch(e.type){case`ready`:return F(e);case`text_delta`:return A(e,`delta`);case`tool_start`:return A(e,`toolName`);case`tool_end`:return A(e,`toolName`)&&typeof e.success==`boolean`;case`permission_request`:return A(e,`requestId`)&&A(e,`toolName`);case`result`:return A(e,`output`)&&P(e);case`error`:return A(e,`message`);case`cancelled`:return e.reason===void 0||typeof e.reason==`string`;default:return!1}}const ye=process.platform!==`win32`;function be(e,t){return new Promise(n=>{if(e.exitCode!==null||e.signalCode!==null){n();return}let r=setTimeout(()=>{e.removeListener(`exit`,i),n()},t);r.unref?.();let i=()=>{clearTimeout(r),n()};e.once(`exit`,i)})}const z=new WeakMap;function xe(e){let t=e.stderr;if(!t)return;let n=ee({maxBytes:4096,retain:`tail`,truncationMarker:()=>``});z.set(e,n),t.on(`error`,()=>{}),t.on(`data`,e=>n.append(e))}function Se(e){return(z.get(e)?.toString()??``).trim()}function Ce(e,t,n,r,a,o){switch(e.type){case`ready`:t();break;case`result`:n(e);break;case`error`:r(new i(`runner`,e.message));break;case`cancelled`:r(new i(`runner`,e.reason??`Subagent worker cancelled`));break;case`text_delta`:a?.({type:`background_task_text_delta`,delta:e.delta});break;case`tool_start`:a?.({type:`background_task_tool_start`,toolName:e.toolName,firstArg:we(e.toolArgs)});break;case`tool_end`:a?.({type:`background_task_tool_end`,toolName:e.toolName,success:e.success});break;case`permission_request`:o?.(e);break;default:r(new i(`runner`,`Unhandled subagent worker message`))}}function we(e){if(!e)return;let t=Object.values(e)[0];if(t!==void 0)return typeof t==`object`?JSON.stringify(t):String(t)}function B(e,t){return new Promise((n,r)=>{if(!e.connected){r(new i(`crash`,`Subagent worker IPC channel is closed`));return}e.send(t,e=>{if(e){r(e);return}n()})})}async function V(e,t){await m(e.child,{graceMs:e.killGraceMs,processGroup:ye,preKill:async()=>{e.child.connected&&(await B(e.child,{type:`cancel`,reason:t}).catch(()=>void 0),await be(e.child,e.killGraceMs))}})}function Te(e){return new Promise((t,n)=>{new Ee(e,t,n).start()})}var Ee=class{options;resolve;reject;settled=!1;started=!1;ready=!1;timeoutTimer;handshakeTimer;handshakeBudgetMs;payload;deniedToolCallCounts={"no-approver":0,"denied-by-person":0,"approver-error":0,cancelled:0};pendingPermissionRequests=new Map;constructor(e,t,n){this.options=e,this.resolve=t,this.reject=n;let r=e.handshakeBudgetMs;this.handshakeBudgetMs=r!==void 0&&r>0?r:3e4,this.payload=e.payload.catch(e=>{this.rejectOnce(e instanceof Error?e:Error(String(e)))}),this.timeoutTimer=Oe(this.options.runtime,e=>this.rejectOnce(e)),this.handshakeTimer=setTimeout(()=>{this.ready||this.settled||(V(this.options.runtime,`Subagent worker never signalled ready`),this.rejectOnce(new i(`runner`,`Subagent worker never signalled ready within ${this.handshakeBudgetMs}ms. Its entry must dispatch worker mode before starting the host application.`)))},this.handshakeBudgetMs),this.handshakeTimer.unref?.()}start(){let{child:e}=this.options.runtime;e.on(`message`,this.onMessage),e.on(`error`,this.onError),e.on(`exit`,this.onExit),e.once(`spawn`,()=>{setImmediate(this.startWorker)})}startWorker=()=>{if(this.started)return;this.started=!0;let{child:e}=this.options.runtime;this.payload.then(t=>t===void 0?void 0:B(e,{type:`start`,payload:t})).catch(e=>{this.rejectOnce(e instanceof Error?e:Error(String(e)))})};onMessage=e=>{if(!R(e)){this.rejectOnce(new i(`runner`,`Received malformed subagent worker message`));return}this.ready=!0,clearTimeout(this.handshakeTimer);let{job:t}=this.options.runtime;Ce(e,this.startWorker,this.resolveOnce,this.rejectOnce,t.emit,this.onPermissionRequest)};onPermissionRequest=e=>{let t=this.answerPermissionRequest(e).finally(()=>{this.pendingPermissionRequests.delete(e.requestId)});this.pendingPermissionRequests.set(e.requestId,t)};async answerPermissionRequest(e){let{reason:t,result:n}=await this.askApprover(e);t!==void 0&&(this.deniedToolCallCounts[t]+=1);let{child:r}=this.options.runtime;r.connected&&await B(r,{type:`permission_response`,requestId:e.requestId,result:n}).catch(()=>void 0)}async askApprover(e){let t=this.options.permissionApprover;if(t===void 0)return{reason:`no-approver`,result:!1};try{let n=await t(e.toolName,e.toolArgs??{},this.options.permissionAbort.signal);return n===!1?this.options.permissionAbort.signal.aborted?{reason:`cancelled`,result:!1}:{reason:`denied-by-person`,result:!1}:{result:n}}catch{return{reason:`approver-error`,result:!1}}}onError=e=>{this.rejectOnce(new i(`crash`,e.message))};onExit=(e,t)=>{this.settled||this.rejectOnce(new i(`crash`,je(e,t,Se(this.options.runtime.child))))};resolveOnce=e=>{this.settled||(this.settled=!0,this.settleAfterPendingPermissionRequests(()=>{let{runtime:t,resolveTranscriptPath:n}=this.options;this.resolve(ke(t.job,e,n,this.deniedToolCallCounts))}))};rejectOnce=e=>{this.settled||(this.settled=!0,this.settleAfterPendingPermissionRequests(()=>this.reject(e)))};async settleAfterPendingPermissionRequests(e){this.options.permissionAbort.abort(),this.clearTimers(),this.cleanup(),await Promise.all(this.pendingPermissionRequests.values()),e()}clearTimers(){this.timeoutTimer&&clearTimeout(this.timeoutTimer),clearTimeout(this.handshakeTimer)}cleanup(){let{child:e}=this.options.runtime;e.off(`message`,this.onMessage),e.off(`error`,this.onError),e.off(`exit`,this.onExit)}};function De(e){let t=!1,n=()=>{};return{promise:new Promise((e,t)=>{n=t}),reject(r){t||(t=!0,n(new i(`runner`,r??`Subagent job cancelled: ${e}`)))}}}function Oe(e,t){if(e.job.request.timeoutMs)return setTimeout(()=>{V(e,`Subagent worker timed out`),t(new i(`timeout`,`Subagent worker timed out`))},e.job.request.timeoutMs)}function ke(e,t,n,r){let i=n(e),a=Ae(r);return{taskId:e.taskId,output:t.output,...i?{metadata:{transcriptPath:i,logPath:i}}:{},...t.usage?{usage:t.usage}:{},...a?{deniedToolCalls:a}:{}}}function Ae(e){let t=Object.values(e).reduce((e,t)=>e+t,0);return t===0?void 0:{total:t,byReason:{...e}}}function je(e,t,n){return`Subagent worker exited before result: ${t===null?`exit code ${e===null?`unknown`:e}`:`signal ${t}`}${n.length>0?`: ${n}`:``}`}const H=`--__robota-subagent-worker`;function Me(e){return e.includes(H)}const Ne=process.platform!==`win32`;function Pe(e){return t=>{let n=new U(t,e);return e.worktreeIsolation===!1?n:c({runner:n,worktreeAdapter:e.worktreeAdapter,hooks:t.config.hooks,hookTypeExecutors:t.hookTypeExecutors})}}var U=class{deps;workerEntry;killGraceMs;handshakeBudgetMs;providerConfig;providerDefinitions;env;logsDir;parentSandboxSettings;watchParentSandboxSettings;constructor(e,t){this.deps=e,this.workerEntry=t.workerEntry,this.killGraceMs=t.killGraceMs??p,this.handshakeBudgetMs=t.handshakeBudgetMs,this.providerConfig=t.providerConfig,this.providerDefinitions=t.providerDefinitions,this.env=t.env,this.logsDir=t.logsDir,this.parentSandboxSettings=t.parentSandboxSettings,this.watchParentSandboxSettings=t.watchParentSandboxSettings}start(t){let n=this.workerEntry,r={...process.env,...this.env??{}},i=O(t,this.deps,{...this.providerConfig===void 0?{}:{providerConfig:this.providerConfig},providerDefinitions:this.providerDefinitions},process.env,r),a=e(n.execPath,[...n.execArgv??[],...n.args,H],{cwd:d(t),env:r,stdio:[`ignore`,`ignore`,`pipe`,`ipc`],detached:Ne});xe(a),this.forwardSandboxSettingChanges(a);let o={job:t,child:a,killGraceMs:this.killGraceMs},s=this.createStartPayload(t,i),c=new AbortController,l=this.permissionApprover(t),u=Te({runtime:o,payload:s,...this.handshakeBudgetMs===void 0?{}:{handshakeBudgetMs:this.handshakeBudgetMs},resolveTranscriptPath:e=>this.resolveTranscriptPath(e),permissionAbort:c,...l===void 0?{}:{permissionApprover:l}}),f=De(t.taskId);u.catch(()=>void 0);let p=Promise.race([u,f.promise]);p.catch(()=>void 0);let m=this.resolveTranscriptPath(t);return{taskId:t.taskId,...a.pid!==void 0&&{pid:a.pid},...m!==void 0&&{transcriptPath:m,logPath:m},result:p,cancel:async e=>{c.abort(e),f.reject(e),await V(o,e)},send:async e=>{await B(a,{type:`send`,prompt:e})},...m!==void 0&&{readLog:async e=>Fe(t.taskId,m,e)}}}createStartPayload(e,t){let n=this.parentSandboxSettings?.();return fe(e,this.deps,{connection:t,providerDefinitions:this.providerDefinitions,...this.logsDir===void 0?{}:{logsDir:this.logsDir},...n===void 0?{}:{parentSandboxSettings:n}})}forwardSandboxSettingChanges(e){let t=this.watchParentSandboxSettings?.(t=>{e.connected&&B(e,{type:`sandbox_settings`,settings:t}).catch(()=>void 0)});t!==void 0&&(e.once(`exit`,t),e.once(`error`,t))}resolveTranscriptPath(e){if(this.logsDir)return r(this.logsDir,e.request.parentSessionId,`subagents`,`${e.taskId}.jsonl`)}permissionApprover(e){let t=this.deps.permissionHandler;if(t===void 0)return;let n={kind:`background-agent`,label:e.request.agentType,taskId:e.taskId};return(e,r,i)=>t(e,r,{requester:n,signal:i})}};function Fe(e,r,i){return t(r)?o(e,n(r,`utf8`).split(/\r?\n/).filter(Boolean),i):{taskId:e,cursor:i,lines:[]}}function Ie(e,t,n){let r=e.request.resumeSessionId;if(r!==void 0){if(n===void 0)throw Error(`subagent worker: job ${e.taskId} asks to resume session ${r}, but this composition opens no session store. Register ISubagentWorkerComposition.openSessionStore at the composition root — the same place providerDefinitions is registered.`);ie(n,r,t)}}function Le(e,t){let n=e.request.resumeSessionId;if(n!==void 0){if(t.openSessionStore===void 0)throw Error(`subagent worker: job ${e.taskId} asks to resume session ${n}, but this composition opens no session store. Register ISubagentWorkerComposition.openSessionStore at the composition root — the same place providerDefinitions is registered.`);return t.openSessionStore({cwd:e.request.cwd})}}async function Re(e,t){if(e===void 0)return;let n=t?.[e.type];if(n===void 0)throw Error(`subagent worker: sandbox type "${e.type}" is not registered in the worker composition. The parent is sandboxed and passed a snapshot reference, but this child cannot construct that client type. Register it in ISubagentWorkerComposition.sandboxFactories at the composition root — the same place providerDefinitions is registered, and for the same reason.`);return n(e.snapshotId)}const ze={write:()=>{},writeLine:()=>{},writeMarkdown:()=>{},writeError:()=>{},prompt:()=>Promise.resolve(``),select:()=>Promise.resolve(0),spinner:()=>({stop:()=>{},update:()=>{}})};let W=null,G=!1;const K=new Map;let Be=0,q,J,Y,X=Promise.resolve();function Z(e){process.send&&process.send(e)}function Q(e,t){let n=!1,r=()=>{n||(n=!0,process.exit(t))};if(process.send){let t=setTimeout(r,2e3);t.unref?.(),process.send(e,void 0,void 0,()=>{clearTimeout(t),r()})}else r()}function Ve(e){try{return ne(e.getFullHistory())}catch{return}}async function He(e,t){try{if(!f(e.connectionCheck,process.env))throw Error(`The provider connection environment changed after the parent checked it; the subagent was not started.`);let n=await Re(e.sandboxProjection,t.sandboxFactories),r=s(e.providerProfile,e.request.model,t.providerDefinitions),i=e.logsDir?g(e.request.parentSessionId,e.taskId,e.logsDir):void 0,a=Le(e,t),o=q??e.parentSandboxSettings;J=n===void 0?t.createSandbox?.({cwd:d(e),...o===void 0?{}:{parentSettings:o}}):void 0;let c=n??J?.client;W=re({agentDefinition:w(e.agentDefinition),parentConfig:e.parentConfig,parentContext:D(e.parentContext),parentTools:t.createTools({cwd:d(e),...c===void 0?{}:{sandboxClient:c},...e.sessionTiers===void 0?{}:{sessionTiers:e.sessionTiers}}),cwd:d(e),provider:r,terminal:ze,sessionId:e.request.resumeSessionId??e.taskId,...a===void 0?{}:{sessionStore:a},...i?{sessionLogger:i}:{},permissionMode:e.permissionMode,...J?.commandSandbox===void 0?{}:{commandSandbox:J.commandSandbox},...e.request.permissionPolicy===void 0?{}:{permissionPolicy:e.request.permissionPolicy},...e.request.allowedTools===void 0?{}:{taskAllowedTools:e.request.allowedTools},...e.request.disallowedTools===void 0?{}:{taskDisallowedTools:e.request.disallowedTools},hooks:e.parentConfig.hooks,...t.createHookTypeExecutors===void 0?{}:{hookTypeExecutors:t.createHookTypeExecutors()},onTextDelta:e=>Z({type:`text_delta`,delta:e}),onToolExecution:$,permissionHandler:Ue}),Ie(e,W,a);let l=await W.run(e.request.prompt);if(Y!==void 0){Q({type:`error`,message:Y},0);return}if(G){Q({type:`cancelled`,reason:`Subagent worker cancelled`},130);return}let u=Ve(W);Q({type:`result`,output:l,...u?{usage:u}:{}},0)}catch(e){if(Y!==void 0){Q({type:`error`,message:Y},0);return}if(G){Q({type:`cancelled`,reason:`Subagent worker cancelled`},130);return}Q({type:`error`,message:e instanceof Error?e.message:String(e)},0)}}function Ue(e,t){let n=`perm_${++Be}`;return new Promise(r=>{K.set(n,r),Z({type:`permission_request`,requestId:n,toolName:e,toolArgs:t})})}function We(e,t){let n=K.get(e);n!==void 0&&(K.delete(e),n(t))}function $(e){if(e.type===`start`){Z({type:`tool_start`,toolName:e.toolName,toolArgs:e.toolArgs});return}Z({type:`tool_end`,toolName:e.toolName,success:e.success??!0})}function Ge(e){if(W===null){Z({type:`error`,message:`Subagent worker has not started`});return}X=X.then(async()=>{try{await W?.run(e)}catch(e){Z({type:`error`,message:e instanceof Error?e.message:String(e)})}})}async function Ke(e){G=!0,W?.abort(),Z({type:`cancelled`,reason:e}),await W?.shutdown({reason:`other`}).catch(()=>void 0),setTimeout(()=>process.exit(130),0)}function qe(e){try{return e.createTools({cwd:process.cwd()}).map(e=>e.getName())}catch(e){process.stderr.write(`robota: could not enumerate the composed tool surface: ${e instanceof Error?e.message:String(e)}\n`);return}}function Je(e){q=e;try{J?.applyParentSettings?.(e)}catch(e){Y??=e instanceof Error?e.message:String(e),W?.abort()}}function Ye(e){process.send===void 0&&(process.stderr.write(`robota: subagent worker mode requires an IPC channel; it is started by the agent runtime, not by hand.
1
+ import{spawn as e}from"node:child_process";import{existsSync as t,readFileSync as n}from"node:fs";import{join as r}from"node:path";import{BackgroundTaskError as i,connectionEnvironmentNames as a,createBackgroundTaskLogPage as o,createProviderFromExactProfile as s,createWorktreeSubagentRunner as c,findConnectionEnvironmentDivergence as l,sealConnectionEnvironment as u,subagentExecutionRoot as d,verifyConnectionEnvironment as f}from"@robota-sdk/agent-executor";import{DEFAULT_KILL_GRACE_MS as p,killProcessTree as m}from"@robota-sdk/agent-process";import{createBoundedOutput as ee,findProviderDefinition as h,isModelEffort as te,sumHistoryUsage as ne}from"@robota-sdk/agent-core";import{createSubagentLogger as g,createSubagentSession as re,restoreSessionRecordIntoSession as ie}from"@robota-sdk/agent-framework";function ae(e){return{provider:{model:e.provider.model},permissions:e.permissions,defaultTrustLevel:e.defaultTrustLevel,...e.hooks===void 0?{}:{hooks:e.hooks}}}function oe(e){return{agentsMd:e.agentsMd,projectNotesMd:e.projectNotesMd}}const _={name:{kind:`string`,required:!0},description:{kind:`string`,required:!0},systemPrompt:{kind:`string`,required:!0},model:{kind:`string`,required:!1},effort:{kind:`effort`,required:!1},role:{kind:`string`,required:!1},maxTurns:{kind:`number`,required:!1},tools:{kind:`string[]`,required:!1},disallowedTools:{kind:`string[]`,required:!1}},v={agentsMd:{kind:`string`,required:!0},projectNotesMd:{kind:`string`,required:!0},memoryMd:{kind:`string`,required:!1},taskContext:{kind:`string`,required:!1},compactInstructions:{kind:`string`,required:!1},agentsFileEntries:{kind:`file-entry[]`,required:!1},projectNotesFileEntries:{kind:`file-entry[]`,required:!1}};function y(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function se(e){return Array.isArray(e)&&e.every(e=>typeof e==`string`)}function ce(e){return y(e)&&typeof e.filePath==`string`&&typeof e.content==`string`&&typeof e.contentHash==`string`}function le(e,t){switch(e){case`string`:return typeof t==`string`;case`number`:return typeof t==`number`&&Number.isFinite(t);case`effort`:return typeof t==`string`&&te(t);case`string[]`:return se(t);case`file-entry[]`:return Array.isArray(t)&&t.every(ce)}}function b(e,t){let n={};for(let r of Object.keys(t)){let t=e[r];t!==void 0&&(n[r]=t)}return n}function x(e,t,n){if(!y(t))return{ok:!1,reason:`${e}: expected an object`};for(let[r,i]of Object.entries(n)){let n=t[r];if(n===void 0){if(i.required)return{ok:!1,reason:`${e}.${r}: required`};continue}if(!le(i.kind,n))return{ok:!1,reason:`${e}.${r}: expected ${i.kind}`}}return{ok:!0,value:b(t,n)}}function S(e){return b(e,_)}function C(e){return x(`agentDefinition`,e,_)}function w(e){let t={name:e.name,description:e.description,systemPrompt:e.systemPrompt};return e.model!==void 0&&(t.model=e.model),e.effort!==void 0&&(t.effort=e.effort),e.role!==void 0&&(t.role=e.role),e.maxTurns!==void 0&&(t.maxTurns=e.maxTurns),e.tools!==void 0&&(t.tools=[...e.tools]),e.disallowedTools!==void 0&&(t.disallowedTools=[...e.disallowedTools]),t}function T(e){return b(e,v)}function E(e){return x(`parentContext`,e,v)}function D(e){let t={agentsMd:e.agentsMd,projectNotesMd:e.projectNotesMd};return e.memoryMd!==void 0&&(t.memoryMd=e.memoryMd),e.taskContext!==void 0&&(t.taskContext=e.taskContext),e.compactInstructions!==void 0&&(t.compactInstructions=e.compactInstructions),e.agentsFileEntries!==void 0&&(t.agentsFileEntries=e.agentsFileEntries.map(e=>({...e}))),e.projectNotesFileEntries!==void 0&&(t.projectNotesFileEntries=e.projectNotesFileEntries.map(e=>({...e}))),t}function ue(e){return e.sessionTiers===void 0?{}:{sessionTiers:e.sessionTiers}}async function de(e){let{sandboxClient:t,sandboxType:n}=e;return t?.snapshot===void 0||n===void 0?{}:{sandboxProjection:{type:n,snapshotId:await t.snapshot()}}}function O(e,t,n,r,o){let s=n.providerDefinitions,c=(n.providerConfig??t.config.provider).name;if(h(s,c)===void 0)throw new i(`validation`,`No provider definition for "${c}" was given to the subagent runner, so the connection a child would make cannot be checked; the subagent was not started.`);let d=ge(n.providerConfig,t,e,s),f=a(d,s),p=l(f,r,o);if(p!==void 0)throw new i(`validation`,`The subagent's environment sets ${p} differently from this session, which would change where its provider connects or which credential it sends; the subagent was not started.`);return{providerProfile:d,connectionCheck:u(f,o)}}function fe(e,t,n){let r=pe(e.request.agentType,t.customAgentRegistry,t.builtInAgents,t.agentDefinitions),i={taskId:e.taskId,request:e.request,...e.worktree?{worktree:e.worktree}:{},agentDefinition:S(me(r,e)),parentConfig:ae(t.getParentPermissionRules===void 0?t.config:{...t.config,permissions:t.getParentPermissionRules()}),parentContext:T(oe(t.context)),...n.connection??O(e,t,n,process.env,process.env),permissionMode:t.getParentPermissionMode?.()??t.permissionMode,...ue(t),...n.parentSandboxSettings===void 0?{}:{parentSandboxSettings:n.parentSandboxSettings},...n.logsDir?{logsDir:n.logsDir}:{}};return de(t).then(e=>({...i,...e}))}function pe(e,t,n,r){let a=t?.(e)??n?.find(t=>t.name===e)??r?.find(t=>t.name===e);if(!a)throw new i(`validation`,`Unknown agent type: ${e}`);return a}function me(e,t){return{...e,...t.request.model?{model:t.request.model}:{},...t.request.effort===void 0?{}:{effort:t.request.effort},...t.request.allowedTools?{tools:t.request.allowedTools}:{},...t.request.disallowedTools?{disallowedTools:t.request.disallowedTools}:{}}}function he(e,t){return e.apiKeyEnv===void 0?e.apiKey===void 0?t===void 0?{}:t.startsWith(`$ENV:`)?{apiKeyEnv:t.slice(5)}:{apiKey:t}:{apiKey:e.apiKey}:{apiKeyEnv:e.apiKeyEnv}}function ge(e,t,n,r){let i=e??t.config.provider,a=h(r,i.name)?.defaults??{},o=i.baseURL??a.baseURL,s=i.options??a.options,c=he(i,a.apiKey);return{...e===void 0&&t.config.currentProvider!==void 0?{profileName:t.config.currentProvider}:{},type:i.name,model:n.request.model??i.model,...c,...o===void 0?{}:{baseURL:o},...i.timeout===void 0?{}:{timeout:i.timeout},...s===void 0?{}:{options:s}}}function k(e){return typeof e==`object`&&!!e}function _e(e){if(!k(e)||!A(e,`nonce`)||!A(e,`digest`))return!1;let t=e.names;return Array.isArray(t)&&t.every(e=>typeof e==`string`)}function A(e,t){return typeof e[t]==`string`}function j(e,t){return A(e,t)}function M(e,t){return A(e,t)}function N(e,t){return e[t]===void 0||typeof e[t]==`string`}function P(e){if(e.usage===void 0)return!0;let t=e.usage;return k(t)?typeof t.promptTokens==`number`&&typeof t.completionTokens==`number`&&typeof t.totalTokens==`number`:!1}function F(e){if(e.composedToolNames===void 0)return!0;let t=e.composedToolNames;return Array.isArray(t)?t.every(e=>typeof e==`string`):!1}function I(e){return!k(e)||!M(e,`taskId`)||!k(e.request)||!j(e.request,`agentType`)||!j(e.request,`prompt`)||!j(e.request,`permissionPolicy`)||!j(e.request,`cwd`)||!N(e.request,`resumeSessionId`)||e.worktree!==void 0&&(!k(e.worktree)||!A(e.worktree,`path`))||!C(e.agentDefinition).ok||!k(e.parentConfig)||!E(e.parentContext).ok||!k(e.providerProfile)||!A(e.providerProfile,`type`)||!A(e.providerProfile,`model`)||e.parentSandboxSettings!==void 0&&!k(e.parentSandboxSettings)?!1:_e(e.connectionCheck)}function L(e){if(!k(e)||!A(e,`type`))return!1;switch(e.type){case`start`:return I(e.payload);case`send`:return A(e,`prompt`);case`cancel`:return e.reason===void 0||typeof e.reason==`string`;case`sandbox_settings`:return k(e.settings);case`permission_response`:return A(e,`requestId`)&&ve(e.result);default:return!1}}function ve(e){return typeof e==`boolean`||e===`allow-session`||e===`allow-project`}function R(e){if(!k(e)||!A(e,`type`))return!1;switch(e.type){case`ready`:return F(e);case`text_delta`:return A(e,`delta`);case`tool_start`:return A(e,`toolName`);case`tool_end`:return A(e,`toolName`)&&typeof e.success==`boolean`;case`permission_request`:return A(e,`requestId`)&&A(e,`toolName`);case`result`:return A(e,`output`)&&P(e);case`error`:return A(e,`message`);case`cancelled`:return e.reason===void 0||typeof e.reason==`string`;default:return!1}}const ye=process.platform!==`win32`;function be(e,t){return new Promise(n=>{if(e.exitCode!==null||e.signalCode!==null){n();return}let r=setTimeout(()=>{e.removeListener(`exit`,i),n()},t);r.unref?.();let i=()=>{clearTimeout(r),n()};e.once(`exit`,i)})}const z=new WeakMap;function xe(e){let t=e.stderr;if(!t)return;let n=ee({maxBytes:4096,retain:`tail`,truncationMarker:()=>``});z.set(e,n),t.on(`error`,()=>{}),t.on(`data`,e=>n.append(e))}function Se(e){return(z.get(e)?.toString()??``).trim()}function Ce(e,t,n,r,a,o){switch(e.type){case`ready`:t();break;case`result`:n(e);break;case`error`:r(new i(`runner`,e.message));break;case`cancelled`:r(new i(`runner`,e.reason??`Subagent worker cancelled`));break;case`text_delta`:a?.({type:`background_task_text_delta`,delta:e.delta});break;case`tool_start`:a?.({type:`background_task_tool_start`,toolName:e.toolName,firstArg:we(e.toolArgs)});break;case`tool_end`:a?.({type:`background_task_tool_end`,toolName:e.toolName,success:e.success});break;case`permission_request`:o?.(e);break;default:r(new i(`runner`,`Unhandled subagent worker message`))}}function we(e){if(!e)return;let t=Object.values(e)[0];if(t!==void 0)return typeof t==`object`?JSON.stringify(t):String(t)}function B(e,t){return new Promise((n,r)=>{if(!e.connected){r(new i(`crash`,`Subagent worker IPC channel is closed`));return}e.send(t,e=>{if(e){r(e);return}n()})})}async function V(e,t){await m(e.child,{graceMs:e.killGraceMs,processGroup:ye,preKill:async()=>{e.child.connected&&(await B(e.child,{type:`cancel`,reason:t}).catch(()=>void 0),await be(e.child,e.killGraceMs))}})}function Te(e){return new Promise((t,n)=>{new Ee(e,t,n).start()})}var Ee=class{options;resolve;reject;settled=!1;started=!1;ready=!1;timeoutTimer;handshakeTimer;handshakeBudgetMs;payload;deniedToolCallCounts={"no-approver":0,"denied-by-person":0,"approver-error":0,cancelled:0};pendingPermissionRequests=new Map;constructor(e,t,n){this.options=e,this.resolve=t,this.reject=n;let r=e.handshakeBudgetMs;this.handshakeBudgetMs=r!==void 0&&r>0?r:3e4,this.payload=e.payload.catch(e=>{this.rejectOnce(e instanceof Error?e:Error(String(e)))}),this.timeoutTimer=Oe(this.options.runtime,e=>this.rejectOnce(e)),this.handshakeTimer=setTimeout(()=>{this.ready||this.settled||(V(this.options.runtime,`Subagent worker never signalled ready`),this.rejectOnce(new i(`runner`,`Subagent worker never signalled ready within ${this.handshakeBudgetMs}ms. Its entry must dispatch worker mode before starting the host application.`)))},this.handshakeBudgetMs),this.handshakeTimer.unref?.()}start(){let{child:e}=this.options.runtime;e.on(`message`,this.onMessage),e.on(`error`,this.onError),e.on(`exit`,this.onExit),e.once(`spawn`,()=>{setImmediate(this.startWorker)})}startWorker=()=>{if(this.started)return;this.started=!0;let{child:e}=this.options.runtime;this.payload.then(t=>t===void 0?void 0:B(e,{type:`start`,payload:t})).catch(e=>{this.rejectOnce(e instanceof Error?e:Error(String(e)))})};onMessage=e=>{if(!R(e)){this.rejectOnce(new i(`runner`,`Received malformed subagent worker message`));return}this.ready=!0,clearTimeout(this.handshakeTimer);let{job:t}=this.options.runtime;Ce(e,this.startWorker,this.resolveOnce,this.rejectOnce,t.emit,this.onPermissionRequest)};onPermissionRequest=e=>{let t=this.answerPermissionRequest(e).finally(()=>{this.pendingPermissionRequests.delete(e.requestId)});this.pendingPermissionRequests.set(e.requestId,t)};async answerPermissionRequest(e){let{reason:t,result:n}=await this.askApprover(e);t!==void 0&&(this.deniedToolCallCounts[t]+=1);let{child:r}=this.options.runtime;r.connected&&await B(r,{type:`permission_response`,requestId:e.requestId,result:n}).catch(()=>void 0)}async askApprover(e){let t=this.options.permissionApprover;if(t===void 0)return{reason:`no-approver`,result:!1};try{let n=await t(e.toolName,e.toolArgs??{},this.options.permissionAbort.signal);return n===!1?this.options.permissionAbort.signal.aborted?{reason:`cancelled`,result:!1}:{reason:`denied-by-person`,result:!1}:{result:n}}catch{return{reason:`approver-error`,result:!1}}}onError=e=>{this.rejectOnce(new i(`crash`,e.message))};onExit=(e,t)=>{this.settled||this.rejectOnce(new i(`crash`,je(e,t,Se(this.options.runtime.child))))};resolveOnce=e=>{this.settled||(this.settled=!0,this.settleAfterPendingPermissionRequests(()=>{let{runtime:t,resolveTranscriptPath:n}=this.options;this.resolve(ke(t.job,e,n,this.deniedToolCallCounts))}))};rejectOnce=e=>{this.settled||(this.settled=!0,this.settleAfterPendingPermissionRequests(()=>this.reject(e)))};async settleAfterPendingPermissionRequests(e){this.options.permissionAbort.abort(),this.clearTimers(),this.cleanup(),await Promise.all(this.pendingPermissionRequests.values()),e()}clearTimers(){this.timeoutTimer&&clearTimeout(this.timeoutTimer),clearTimeout(this.handshakeTimer)}cleanup(){let{child:e}=this.options.runtime;e.off(`message`,this.onMessage),e.off(`error`,this.onError),e.off(`exit`,this.onExit)}};function De(e){let t=!1,n=()=>{};return{promise:new Promise((e,t)=>{n=t}),reject(r){t||(t=!0,n(new i(`runner`,r??`Subagent job cancelled: ${e}`)))}}}function Oe(e,t){if(e.job.request.timeoutMs)return setTimeout(()=>{V(e,`Subagent worker timed out`),t(new i(`timeout`,`Subagent worker timed out`))},e.job.request.timeoutMs)}function ke(e,t,n,r){let i=n(e),a=Ae(r);return{taskId:e.taskId,output:t.output,...i?{metadata:{transcriptPath:i,logPath:i}}:{},...t.usage?{usage:t.usage}:{},...a?{deniedToolCalls:a}:{}}}function Ae(e){let t=Object.values(e).reduce((e,t)=>e+t,0);return t===0?void 0:{total:t,byReason:{...e}}}function je(e,t,n){return`Subagent worker exited before result: ${t===null?`exit code ${e===null?`unknown`:e}`:`signal ${t}`}${n.length>0?`: ${n}`:``}`}const H=`--__agent-subagent-worker`;function Me(e){return e.includes(H)}const Ne=process.platform!==`win32`;function Pe(e){return t=>{let n=new U(t,e);return e.worktreeIsolation===!1?n:c({runner:n,worktreeAdapter:e.worktreeAdapter,hooks:t.config.hooks,hookTypeExecutors:t.hookTypeExecutors})}}var U=class{deps;workerEntry;killGraceMs;handshakeBudgetMs;providerConfig;providerDefinitions;env;expectedEnvironment;inheritEnvironment;logsDir;parentSandboxSettings;watchParentSandboxSettings;constructor(e,t){if(this.deps=e,this.workerEntry=t.workerEntry,this.killGraceMs=t.killGraceMs??p,this.handshakeBudgetMs=t.handshakeBudgetMs,this.providerConfig=t.providerConfig,this.providerDefinitions=t.providerDefinitions,this.env=t.env,this.expectedEnvironment=t.expectedEnvironment,this.inheritEnvironment=t.inheritEnvironment!==!1,!this.inheritEnvironment&&this.expectedEnvironment===void 0)throw Error(`An explicit expected environment is required when child inheritance is disabled.`);this.logsDir=t.logsDir,this.parentSandboxSettings=t.parentSandboxSettings,this.watchParentSandboxSettings=t.watchParentSandboxSettings}start(t){let n=this.workerEntry,r=this.inheritEnvironment?{...process.env,...this.env??{}}:{...this.env??{}},i=O(t,this.deps,{...this.providerConfig===void 0?{}:{providerConfig:this.providerConfig},providerDefinitions:this.providerDefinitions},this.expectedEnvironment??process.env,r),a=e(n.execPath,[...n.execArgv??[],...n.args,H],{cwd:d(t),env:r,stdio:[`ignore`,`ignore`,`pipe`,`ipc`],detached:Ne});xe(a),this.forwardSandboxSettingChanges(a);let o={job:t,child:a,killGraceMs:this.killGraceMs},s=this.createStartPayload(t,i),c=new AbortController,l=this.permissionApprover(t),u=Te({runtime:o,payload:s,...this.handshakeBudgetMs===void 0?{}:{handshakeBudgetMs:this.handshakeBudgetMs},resolveTranscriptPath:e=>this.resolveTranscriptPath(e),permissionAbort:c,...l===void 0?{}:{permissionApprover:l}}),f=De(t.taskId);u.catch(()=>void 0);let p=Promise.race([u,f.promise]);p.catch(()=>void 0);let m=this.resolveTranscriptPath(t);return{taskId:t.taskId,...a.pid!==void 0&&{pid:a.pid},...m!==void 0&&{transcriptPath:m,logPath:m},result:p,cancel:async e=>{c.abort(e),f.reject(e),await V(o,e)},send:async e=>{await B(a,{type:`send`,prompt:e})},...m!==void 0&&{readLog:async e=>Fe(t.taskId,m,e)}}}createStartPayload(e,t){let n=this.parentSandboxSettings?.();return fe(e,this.deps,{connection:t,providerDefinitions:this.providerDefinitions,...this.logsDir===void 0?{}:{logsDir:this.logsDir},...n===void 0?{}:{parentSandboxSettings:n}})}forwardSandboxSettingChanges(e){let t=this.watchParentSandboxSettings?.(t=>{e.connected&&B(e,{type:`sandbox_settings`,settings:t}).catch(()=>void 0)});t!==void 0&&(e.once(`exit`,t),e.once(`error`,t))}resolveTranscriptPath(e){if(this.logsDir)return r(this.logsDir,e.request.parentSessionId,`subagents`,`${e.taskId}.jsonl`)}permissionApprover(e){let t=this.deps.permissionHandler;if(t===void 0)return;let n={kind:`background-agent`,label:e.request.agentType,taskId:e.taskId};return(e,r,i)=>t(e,r,{requester:n,signal:i})}};function Fe(e,r,i){return t(r)?o(e,n(r,`utf8`).split(/\r?\n/).filter(Boolean),i):{taskId:e,cursor:i,lines:[]}}function Ie(e,t,n){let r=e.request.resumeSessionId;if(r!==void 0){if(n===void 0)throw Error(`subagent worker: job ${e.taskId} asks to resume session ${r}, but this composition opens no session store. Register ISubagentWorkerComposition.openSessionStore at the composition root — the same place providerDefinitions is registered.`);ie(n,r,t)}}function Le(e,t){let n=e.request.resumeSessionId;if(n!==void 0){if(t.openSessionStore===void 0)throw Error(`subagent worker: job ${e.taskId} asks to resume session ${n}, but this composition opens no session store. Register ISubagentWorkerComposition.openSessionStore at the composition root — the same place providerDefinitions is registered.`);return t.openSessionStore({cwd:e.request.cwd})}}async function Re(e,t){if(e===void 0)return;let n=t?.[e.type];if(n===void 0)throw Error(`subagent worker: sandbox type "${e.type}" is not registered in the worker composition. The parent is sandboxed and passed a snapshot reference, but this child cannot construct that client type. Register it in ISubagentWorkerComposition.sandboxFactories at the composition root — the same place providerDefinitions is registered, and for the same reason.`);return n(e.snapshotId)}const ze={write:()=>{},writeLine:()=>{},writeMarkdown:()=>{},writeError:()=>{},prompt:()=>Promise.resolve(``),select:()=>Promise.resolve(0),spinner:()=>({stop:()=>{},update:()=>{}})};let W=null,G=!1;const K=new Map;let Be=0,q,J,Y,X=Promise.resolve();function Z(e){process.send&&process.send(e)}function Q(e,t){let n=!1,r=()=>{n||(n=!0,process.exit(t))};if(process.send){let t=setTimeout(r,2e3);t.unref?.(),process.send(e,void 0,void 0,()=>{clearTimeout(t),r()})}else r()}function Ve(e){try{return ne(e.getFullHistory())}catch{return}}async function He(e,t){try{if(!f(e.connectionCheck,process.env))throw Error(`The provider connection environment changed after the parent checked it; the subagent was not started.`);let n=await Re(e.sandboxProjection,t.sandboxFactories),r=s(e.providerProfile,e.request.model,t.providerDefinitions),i=e.logsDir?g(e.request.parentSessionId,e.taskId,e.logsDir):void 0,a=Le(e,t),o=q??e.parentSandboxSettings;J=n===void 0?t.createSandbox?.({cwd:d(e),...o===void 0?{}:{parentSettings:o}}):void 0;let c=n??J?.client;W=re({agentDefinition:w(e.agentDefinition),parentConfig:e.parentConfig,parentContext:D(e.parentContext),parentTools:t.createTools({cwd:d(e),...c===void 0?{}:{sandboxClient:c},...e.sessionTiers===void 0?{}:{sessionTiers:e.sessionTiers}}),cwd:d(e),provider:r,terminal:ze,sessionId:e.request.resumeSessionId??e.taskId,...a===void 0?{}:{sessionStore:a},...i?{sessionLogger:i}:{},permissionMode:e.permissionMode,...J?.commandSandbox===void 0?{}:{commandSandbox:J.commandSandbox},...e.request.permissionPolicy===void 0?{}:{permissionPolicy:e.request.permissionPolicy},...e.request.allowedTools===void 0?{}:{taskAllowedTools:e.request.allowedTools},...e.request.disallowedTools===void 0?{}:{taskDisallowedTools:e.request.disallowedTools},hooks:e.parentConfig.hooks,...t.createHookTypeExecutors===void 0?{}:{hookTypeExecutors:t.createHookTypeExecutors({cwd:d(e),...c===void 0?{}:{sandboxClient:c}})},onTextDelta:e=>Z({type:`text_delta`,delta:e}),onToolExecution:$,permissionHandler:Ue}),Ie(e,W,a);let l=await W.run(e.request.prompt);if(Y!==void 0){Q({type:`error`,message:Y},0);return}if(G){Q({type:`cancelled`,reason:`Subagent worker cancelled`},130);return}let u=Ve(W);Q({type:`result`,output:l,...u?{usage:u}:{}},0)}catch(e){if(Y!==void 0){Q({type:`error`,message:Y},0);return}if(G){Q({type:`cancelled`,reason:`Subagent worker cancelled`},130);return}Q({type:`error`,message:e instanceof Error?e.message:String(e)},0)}}function Ue(e,t){let n=`perm_${++Be}`;return new Promise(r=>{K.set(n,r),Z({type:`permission_request`,requestId:n,toolName:e,toolArgs:t})})}function We(e,t){let n=K.get(e);n!==void 0&&(K.delete(e),n(t))}function $(e){if(e.type===`start`){Z({type:`tool_start`,toolName:e.toolName,toolArgs:e.toolArgs});return}Z({type:`tool_end`,toolName:e.toolName,success:e.success??!0})}function Ge(e){if(W===null){Z({type:`error`,message:`Subagent worker has not started`});return}X=X.then(async()=>{try{await W?.run(e)}catch(e){Z({type:`error`,message:e instanceof Error?e.message:String(e)})}})}async function Ke(e){G=!0,W?.abort(),Z({type:`cancelled`,reason:e}),await W?.shutdown({reason:`other`}).catch(()=>void 0),setTimeout(()=>process.exit(130),0)}function qe(e){try{return e.createTools({cwd:process.cwd()}).map(e=>e.getName())}catch(e){process.stderr.write(`agent: could not enumerate the composed tool surface: ${e instanceof Error?e.message:String(e)}\n`);return}}function Je(e){q=e;try{J?.applyParentSettings?.(e)}catch(e){Y??=e instanceof Error?e.message:String(e),W?.abort()}}function Ye(e){process.send===void 0&&(process.stderr.write(`agent: subagent worker mode requires an IPC channel; it is started by the agent runtime, not by hand.
2
2
  `),process.exit(2)),process.on(`message`,t=>{if(!L(t)){Z({type:`error`,message:`Malformed subagent worker parent message`});return}switch(t.type){case`start`:X=X.then(()=>He(t.payload,e));break;case`send`:Ge(t.prompt);break;case`cancel`:Ke(t.reason);break;case`sandbox_settings`:Je(t.settings);break;case`permission_response`:We(t.requestId,t.result);break;default:Z({type:`error`,message:`Unhandled subagent worker parent message`})}}),process.on(`disconnect`,()=>{G=!0,W?.abort(),W?.shutdown({reason:`other`}).catch(()=>void 0)});let t=qe(e);Z({type:`ready`,...t?{composedToolNames:t}:{}})}export{U as ChildProcessSubagentRunner,H as SUBAGENT_WORKER_MODE_FLAG,Pe as createChildProcessSubagentRunnerFactory,C as decodeAgentDefinitionDto,E as decodeParentContextDto,S as encodeAgentDefinition,T as encodeParentContext,R as isSubagentWorkerChildMessage,Me as isSubagentWorkerModeArgv,L as isSubagentWorkerParentMessage,w as restoreAgentDefinition,D as restoreParentContext,Ye as runSubagentWorkerMain};
3
3
  //# sourceMappingURL=index.js.map