@gotgenes/pi-subagents 6.18.5 → 6.18.6

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
@@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [6.18.6](https://github.com/gotgenes/pi-packages/compare/pi-subagents-v6.18.5...pi-subagents-v6.18.6) (2026-05-24)
9
+
10
+
11
+ ### Documentation
12
+
13
+ * plan extract RunContext from RunOptions ([#169](https://github.com/gotgenes/pi-packages/issues/169)) ([ca12b2e](https://github.com/gotgenes/pi-packages/commit/ca12b2ebd116cb50c6e12d2d3fe3a87ff997d6d6))
14
+ * **retro:** add planning stage notes for issue [#169](https://github.com/gotgenes/pi-packages/issues/169) ([05b0176](https://github.com/gotgenes/pi-packages/commit/05b01764a4aaa885efca9d061abf6bacb384057c))
15
+ * **retro:** add retro notes for issue [#168](https://github.com/gotgenes/pi-packages/issues/168) ([dfe46ed](https://github.com/gotgenes/pi-packages/commit/dfe46ed5b5ee62371912dbbc6227443adee8e67b))
16
+ * **retro:** add TDD stage notes for issue [#169](https://github.com/gotgenes/pi-packages/issues/169) ([84c0d8d](https://github.com/gotgenes/pi-packages/commit/84c0d8d5ef0a94750c470e3f10b3ab589caac794))
17
+ * update architecture doc for RunContext extraction ([#169](https://github.com/gotgenes/pi-packages/issues/169)) ([ea49fe1](https://github.com/gotgenes/pi-packages/commit/ea49fe1b9c316e6541814de821738d6d121c4d13))
18
+ * update RunOptions field references in comments ([#169](https://github.com/gotgenes/pi-packages/issues/169)) ([fd9c3ed](https://github.com/gotgenes/pi-packages/commit/fd9c3ed0e0b01c45136c8f34d8f31a89564e8061))
19
+
8
20
  ## [6.18.5](https://github.com/gotgenes/pi-packages/compare/pi-subagents-v6.18.4...pi-subagents-v6.18.5) (2026-05-24)
9
21
 
10
22
 
@@ -446,7 +446,7 @@ Bags with 10+ fields are the highest priority for decomposition.
446
446
  | --------------------------- | ------------------------------------------------------ | ------------------------------------------------- | -------- |
447
447
  | `ResolvedSpawnConfig` | 3 nested | foreground-runner, background-spawner, agent-tool | ✓ done |
448
448
  | `AgentSpawnConfig` | 13 → 13 (ParentSessionInfo nested) | agent-manager (internal) | ✓ done |
449
- | `RunOptions` | 12 | agent-runner | High |
449
+ | `RunOptions` | 9 (`RunContext` nested) | agent-runner | ✓ done |
450
450
  | `SessionConfig` | 8 (ToolFilterConfig nested) | agent-runner (output of assembler) | ✓ done |
451
451
  | `NotificationDetails` | 10 | notification | Medium |
452
452
  | `ResourceLoaderOptions` | 10 | agent-runner (SDK bridge) | Medium |
@@ -543,22 +543,23 @@ export interface ParentSessionInfo {
543
543
 
544
544
  `AgentSpawnConfig` now carries `parentSession?: ParentSessionInfo` instead of three flat optional fields.
545
545
 
546
- #### RunOptions (12 fields → extract RunContext)
546
+ #### RunOptions (12 fields → extract RunContext) — done ([#169][169])
547
547
 
548
- The `RunOptions` bag mixes execution parameters with context information:
548
+ The `RunOptions` bag mixes execution parameters with context information.
549
+ `RunContext` was extracted and nested as `RunOptions.context`:
549
550
 
550
551
  ```typescript
551
- /** Parent context needed to configure the child session. */
552
- interface RunContext {
553
- cwd?: string;
554
- parentSessionFile?: string;
555
- parentSessionId?: string;
552
+ /** Parent execution context where/who is running. */
553
+ export interface RunContext {
556
554
  exec: ShellExec;
557
555
  registry: AgentConfigLookup;
556
+ cwd?: string;
557
+ parentSession?: ParentSessionInfo;
558
558
  }
559
559
  ```
560
560
 
561
561
  The remaining `RunOptions` fields (`model`, `maxTurns`, `signal`, `isolated`, `thinkingLevel`, `defaultMaxTurns`, `graceTurns`, `onSessionCreated`) are genuine execution parameters.
562
+ `RunOptions` now has 9 fields: 1 nested `context: RunContext` plus 8 flat execution fields.
562
563
 
563
564
  #### SessionConfig (11 fields → extract ToolFilterConfig) — done ([#168][168])
564
565
 
@@ -630,10 +631,10 @@ All existing consumers satisfy both sub-interfaces via structural typing with no
630
631
  `filterActiveTools` now accepts a single `ToolFilterConfig` argument.
631
632
  `SessionConfig` reduced from 10 to 8 top-level fields.
632
633
 
633
- ### Step 6: Extract RunContext from RunOptions ([#169][169])
634
+ ### Step 6: Extract RunContext from RunOptions ([#169][169]) ✓ Done
634
635
 
635
- Extract context fields into `RunContext`.
636
- Reduces RunOptions from 12 to 7 fields.
636
+ Extracted `exec`, `registry`, `cwd`, and `parentSession` into `RunContext`, nested as `RunOptions.context`.
637
+ `RunOptions` reduced from 12 to 9 fields (1 nested `context` + 8 flat execution fields).
637
638
 
638
639
  ### Step 7: Reduce buildContentLines complexity ([#170][170])
639
640
 
@@ -0,0 +1,194 @@
1
+ ---
2
+ issue: 169
3
+ issue_title: "refactor(pi-subagents): extract RunContext from RunOptions (12 fields)"
4
+ ---
5
+
6
+ # Extract RunContext from RunOptions
7
+
8
+ ## Problem Statement
9
+
10
+ `RunOptions` in `agent-runner.ts` has 12 fields mixing two distinct concerns: parent execution context ("where/who is running") and per-call execution parameters ("how to run").
11
+ Extracting the context cluster into a named `RunContext` interface makes the separation explicit and reduces the flat field count from 12 to 9 (8 execution fields + 1 nested context).
12
+
13
+ ## Goals
14
+
15
+ - Define a `RunContext` interface grouping the 4 parent-context fields: `exec`, `registry`, `cwd`, and `parentSession`.
16
+ - Nest `RunContext` inside `RunOptions` as `context: RunContext`, replacing the 4 flat fields.
17
+ - Update `runAgent()` to read context fields from `options.context.*`.
18
+ - Update `AgentManager.startAgent()` to construct the nested `context` object when building `RunOptions`.
19
+ - Update all test files that construct or assert on `RunOptions` fields.
20
+ - Non-breaking refactor — `RunOptions` is not part of the public API (`service.ts` export boundary).
21
+
22
+ ## Non-Goals
23
+
24
+ - Changing the `AgentRunner` interface signature — `run()` keeps its 4 positional parameters; `RunContext` is nested inside `RunOptions`, not a separate parameter.
25
+ - Extracting `RunContext` into its own file — the interface is small (4 fields) and co-located with its consumer (`runAgent`).
26
+ - Further splitting the remaining 8 execution fields — they form a coherent "how to run" cluster.
27
+ - Hoisting `RunContext` construction to `AgentManager` instance level — two of the four fields (`cwd`, `parentSession`) vary per spawn, so a per-spawn construction is appropriate.
28
+
29
+ ## Background
30
+
31
+ Issue #164 (closed) reorganized source into domain directories; the runner now lives at `src/lifecycle/agent-runner.ts`.
32
+ Issue #166 (closed) extracted `ParentSessionInfo` and nested it inside `RunOptions.parentSession`.
33
+ Issue #167 (closed) split `RunnerIO` into `EnvironmentIO` and `SessionFactoryIO`.
34
+ Issue #168 (closed) extracted `ToolFilterConfig` from `SessionConfig`.
35
+
36
+ This issue continues the structural improvement by separating the two concerns mixed in `RunOptions`.
37
+
38
+ ### Field analysis
39
+
40
+ | Field | Concern | Usage in `runAgent()` |
41
+ | ------------------ | --------- | ------------------------------------------ |
42
+ | `exec` | Context | `io.detectEnv(options.exec, effectiveCwd)` |
43
+ | `registry` | Context | Passed to `assembleSessionConfig` |
44
+ | `cwd` | Context | Override working directory (worktree) |
45
+ | `parentSession` | Context | Session dir derivation + session linking |
46
+ | `model` | Execution | Per-call model override |
47
+ | `maxTurns` | Execution | Turn limit |
48
+ | `signal` | Execution | Abort forwarding |
49
+ | `isolated` | Execution | Extension isolation flag |
50
+ | `thinkingLevel` | Execution | Thinking level override |
51
+ | `onSessionCreated` | Execution | Session delivery callback |
52
+ | `defaultMaxTurns` | Execution | Fallback turn limit from runtime config |
53
+ | `graceTurns` | Execution | Grace window after soft limit |
54
+
55
+ ### Consumer analysis
56
+
57
+ `AgentManager.startAgent()` is the sole constructor of `RunOptions`.
58
+ The context fields come from two sources:
59
+
60
+ - Manager instance fields: `this.exec`, `this.registry`
61
+ - Per-spawn values: `worktreeCwd` (computed locally), `options.parentSession` (from `AgentSpawnConfig`)
62
+
63
+ ## Design Overview
64
+
65
+ ### `RunContext` interface
66
+
67
+ ```typescript
68
+ export interface RunContext {
69
+ /** Shell-exec callback for detectEnv — injected from pi.exec(). */
70
+ exec: ShellExec;
71
+ /** Agent config lookup — provides resolveAgentConfig and getToolNamesForType. */
72
+ registry: AgentConfigLookup;
73
+ /** Override working directory (e.g. for worktree isolation). */
74
+ cwd?: string;
75
+ /** Parent session identity (file path + session ID). */
76
+ parentSession?: ParentSessionInfo;
77
+ }
78
+ ```
79
+
80
+ ### Updated `RunOptions`
81
+
82
+ ```typescript
83
+ export interface RunOptions {
84
+ /** Parent execution context — where/who is running. */
85
+ context: RunContext;
86
+ model?: Model<any>;
87
+ maxTurns?: number;
88
+ signal?: AbortSignal;
89
+ isolated?: boolean;
90
+ thinkingLevel?: ThinkingLevel;
91
+ onSessionCreated?: (session: AgentSession) => void;
92
+ defaultMaxTurns?: number;
93
+ graceTurns?: number;
94
+ }
95
+ ```
96
+
97
+ ### Call-site sketch — `AgentManager.startAgent`
98
+
99
+ ```typescript
100
+ const promise = this.runner.run(snapshot, type, prompt, {
101
+ context: {
102
+ exec: this.exec,
103
+ registry: this.registry,
104
+ cwd: worktreeCwd,
105
+ parentSession: options.parentSession,
106
+ },
107
+ model: options.model,
108
+ maxTurns: options.maxTurns,
109
+ // ... remaining execution fields
110
+ });
111
+ ```
112
+
113
+ ### Access pattern in `runAgent`
114
+
115
+ ```typescript
116
+ const effectiveCwd = options.context.cwd ?? snapshot.cwd;
117
+ const env = await io.detectEnv(options.context.exec, effectiveCwd);
118
+ // ...
119
+ const sessionDir = io.deriveSessionDir(
120
+ options.context.parentSession?.parentSessionFile,
121
+ cfg.effectiveCwd,
122
+ );
123
+ ```
124
+
125
+ ## Module-Level Changes
126
+
127
+ ### `src/lifecycle/agent-runner.ts`
128
+
129
+ 1. Add `RunContext` interface (4 fields, exported) before `RunOptions`.
130
+ 2. Replace the 4 flat context fields on `RunOptions` with `context: RunContext`.
131
+ 3. Update all `options.*` reads in `runAgent()`:
132
+ - `options.exec` → `options.context.exec`
133
+ - `options.cwd` → `options.context.cwd`
134
+ - `options.parentSession` → `options.context.parentSession`
135
+ - `options.registry` → `options.context.registry`
136
+ 4. Move JSDoc from the removed flat fields to `RunContext` interface members.
137
+ 5. Export `RunContext`.
138
+
139
+ ### `src/lifecycle/agent-manager.ts`
140
+
141
+ 1. Update the `RunOptions` object literal in `startAgent()` to nest the four context fields under `context: { ... }`.
142
+ 2. No import changes needed — `RunOptions` is consumed via the `AgentRunner` interface, not imported directly.
143
+
144
+ ### No changes needed
145
+
146
+ - `src/lifecycle/agent-runner.ts` — `AgentRunner` interface signature unchanged (`options: RunOptions`).
147
+ - `src/lifecycle/agent-runner.ts` — `createAgentRunner()` unchanged.
148
+ - `src/index.ts` — no changes (doesn't import `RunOptions`).
149
+ - `src/runtime.ts` — comment-only reference to `RunOptions`; update comment if desired.
150
+ - `src/session/session-config.ts` — comment-only reference; update comment if desired.
151
+
152
+ ## Test Impact Analysis
153
+
154
+ ### New unit tests enabled
155
+
156
+ The extraction does not enable new test surfaces — `RunContext` is a plain data carrier with no behavior.
157
+ A type-check verification (`pnpm run check`) confirms the structural compatibility.
158
+
159
+ ### Existing tests that need updates
160
+
161
+ 1. `test/lifecycle/agent-runner.test.ts` — 9 `runAgent()` call sites: wrap `exec`, `registry`, `cwd`, and `parentSession` fields in `context: { ... }`.
162
+ 2. `test/lifecycle/agent-runner-extension-tools.test.ts` — 7 `runAgent()` call sites: same wrapping.
163
+ 3. `test/lifecycle/agent-manager.test.ts` — 3 assertion sites: update `runOpts.parentSession` → `runOpts.context.parentSession`, `runOpts.defaultMaxTurns` stays flat (execution field).
164
+
165
+ ### Tests that stay as-is
166
+
167
+ - `test/lifecycle/agent-runner-settings.test.ts` — tests `normalizeMaxTurns` (pure function, no `RunOptions` involvement).
168
+ - All other test files — no `RunOptions` construction or assertion.
169
+
170
+ ## TDD Order
171
+
172
+ 1. **Define `RunContext` and update `RunOptions`** — add `RunContext` interface, replace 4 flat fields with `context: RunContext` on `RunOptions`.
173
+ Update all `options.*` reads in `runAgent()` to `options.context.*`.
174
+ Update `agent-manager.ts` `startAgent()` to construct nested context.
175
+ Update `agent-runner.test.ts` (9 call sites) and `agent-runner-extension-tools.test.ts` (7 call sites) to nest context fields.
176
+ Update `agent-manager.test.ts` assertions (3 sites) to read from `runOpts.context.*`.
177
+ Run `pnpm run check` and `pnpm vitest run` to verify.
178
+ Commit: `refactor: extract RunContext from RunOptions (#169)`
179
+
180
+ 2. **Update comments** — update comment references in `runtime.ts` and `session-config.ts` that mention `RunOptions` field names.
181
+ Commit: `docs: update RunOptions field references in comments (#169)`
182
+
183
+ ## Risks and Mitigations
184
+
185
+ | Risk | Mitigation |
186
+ | ----------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
187
+ | Test factories using spread patterns lose context fields silently | No test factory returns `Partial<RunOptions>` — all call sites construct the options inline, so TypeScript will reject missing `context` |
188
+ | `agent-manager.test.ts` assertions on execution fields break | Only context-field assertions change; execution-field assertions (`defaultMaxTurns`, `graceTurns`) remain on `runOpts.*` |
189
+ | Nested access adds verbosity to `runAgent()` | Only 6 access sites gain the `.context` prefix; readability trade-off is minimal for the structural clarity gained |
190
+
191
+ ## Open Questions
192
+
193
+ None — the extraction follows the natural "where/who vs. how" seam identified in the issue body.
194
+ The issue's proposed flat `parentSessionFile`/`parentSessionId` fields have been superseded by the already-implemented `parentSession?: ParentSessionInfo` grouping from #166.
@@ -37,3 +37,40 @@ All 805 tests continue to pass; no new tests were added (pure structural refacto
37
37
  - All 9 flat-field assertions in `session-config.test.ts` (`result.toolNames`, `result.extensions`, `result.disallowedSet`) were correctly migrated to `result.toolFilter.*` — grep confirmed no stragglers.
38
38
  - `agent-runner-extension-tools.test.ts` required zero changes, confirming its role as a regression canary.
39
39
  - Architecture doc updated: `SessionConfig` row in the wide-interface table marked `✓ done`; Step 5 narrative updated to reflect actual field count (10 → 8, not 11 → 8 as the issue stated).
40
+
41
+ ## Stage: Final Retrospective (2026-05-24T20:00:00Z)
42
+
43
+ ### Session summary
44
+
45
+ Issue #168 completed across three sessions (Planning → TDD → Ship) with zero friction, rework, or plan deviations.
46
+ Total diff: 3 files changed, 37 insertions, 41 deletions (net reduction).
47
+ Released as `pi-subagents-v6.18.5`.
48
+
49
+ ### Observations
50
+
51
+ #### What went well
52
+
53
+ - **Grep-before-commit safety net.**
54
+ The planning session identified 9 flat-field assertions in `session-config.test.ts` that would silently pass as `undefined` if missed during migration.
55
+ The TDD session grepped for all three field names before committing step 1, catching all 9 in one pass.
56
+ This is the testing skill’s "grep for all test files" rule applied to assertion migration.
57
+ - **Regression canary identification during planning.**
58
+ The planning session called out `agent-runner-extension-tools.test.ts` as a zero-change regression canary.
59
+ The TDD session confirmed this prediction — no changes needed, all existing tests green.
60
+ Identifying canary tests during planning gave confidence that the two refactoring steps were correctly scoped.
61
+ - **2-step granularity was right.**
62
+ Step 1 (interface + assembler + tests) left intentional type errors in the consumer.
63
+ Step 2 (consumer update) resolved them.
64
+ This kept each commit reviewable and type-check-green at the session-config boundary.
65
+
66
+ #### What caused friction (agent side)
67
+
68
+ None.
69
+
70
+ #### What caused friction (user side)
71
+
72
+ None.
73
+
74
+ ### Changes made
75
+
76
+ No process changes — clean execution with no proposals warranted.
@@ -0,0 +1,37 @@
1
+ ---
2
+ issue: 169
3
+ issue_title: "refactor(pi-subagents): extract RunContext from RunOptions (12 fields)"
4
+ ---
5
+
6
+ # Retro: #169 — extract RunContext from RunOptions
7
+
8
+ ## Stage: Planning (2026-05-24T17:07:10Z)
9
+
10
+ ### Session summary
11
+
12
+ Produced a plan to extract 4 parent-context fields (`exec`, `registry`, `cwd`, `parentSession`) from `RunOptions` into a nested `RunContext` interface.
13
+ The plan is a single-step refactor (all changes in one commit) plus a comment-update commit, affecting 3 source files and 3 test files.
14
+
15
+ ### Observations
16
+
17
+ - The issue body proposed flat `parentSessionFile`/`parentSessionId` fields on `RunContext`, but #166 already grouped these into `ParentSessionInfo`.
18
+ The plan uses `parentSession?: ParentSessionInfo` instead, preserving the existing grouping.
19
+ - `RunOptions` is purely internal — not exported via `service.ts` — so the refactor is non-breaking.
20
+ - All test call sites construct `RunOptions` inline (no `Partial<RunOptions>` spread patterns), so TypeScript will catch any missing `context` field at compile time.
21
+ - The change is small enough to land in a single TDD step — no lift-and-shift needed.
22
+ - Prerequisite #164 (directory reorganization) is already implemented.
23
+
24
+ ## Stage: Implementation — TDD (2026-05-24T17:14:32Z)
25
+
26
+ ### Session summary
27
+
28
+ Completed both TDD steps in one session.
29
+ Step 1 defined `RunContext`, updated `RunOptions`, migrated `runAgent()` reads to `options.context.*`, restructured `AgentManager.startAgent()`, and updated all 16 test call sites across 3 test files.
30
+ Step 2 updated comment references in `runtime.ts` and `session-config.ts`.
31
+ Test count unchanged (50 files, 805 tests — pure refactor with no behavior change).
32
+
33
+ ### Observations
34
+
35
+ - The `agent-manager.test.ts` update also added two new assertions (`context.exec` and `context.registry` are defined) to each existing `getRunConfig` threading test, confirming the context object is wired correctly; these were not in the plan but add useful coverage.
36
+ - All 16 `runAgent()` call sites in tests used inline option literals (no spread patterns), so TypeScript caught any missed site at compile time — the plan's risk mitigation held.
37
+ - No deviations from the plan otherwise; the comment-only step was trivial.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gotgenes/pi-subagents",
3
- "version": "6.18.5",
3
+ "version": "6.18.6",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./src/service.ts"
@@ -225,17 +225,19 @@ export class AgentManager {
225
225
 
226
226
  const runConfig = this.getRunConfig?.();
227
227
  const promise = this.runner.run(snapshot, type, prompt, {
228
- exec: this.exec,
228
+ context: {
229
+ exec: this.exec,
230
+ registry: this.registry,
231
+ cwd: worktreeCwd,
232
+ parentSession: options.parentSession,
233
+ },
229
234
  model: options.model,
230
235
  maxTurns: options.maxTurns,
231
236
  defaultMaxTurns: runConfig?.defaultMaxTurns,
232
237
  graceTurns: runConfig?.graceTurns,
233
238
  isolated: options.isolated,
234
239
  thinkingLevel: options.thinkingLevel,
235
- cwd: worktreeCwd,
236
- parentSession: options.parentSession,
237
240
  signal: record.abortController!.signal,
238
- registry: this.registry,
239
241
  onSessionCreated: (session) => {
240
242
  // Capture the session file path early so it's available for display
241
243
  // before the run completes (e.g. in background agent status messages).
@@ -152,18 +152,31 @@ export type RunnerIO = EnvironmentIO & SessionFactoryIO;
152
152
 
153
153
  // ── Public interfaces ─────────────────────────────────────────────────────────
154
154
 
155
- export interface RunOptions {
155
+ /**
156
+ * Parent execution context — where/who is running.
157
+ *
158
+ * Groups the four fields that describe the parent environment and identity,
159
+ * separating them from the per-call execution parameters in RunOptions.
160
+ */
161
+ export interface RunContext {
156
162
  /** Shell-exec callback for detectEnv — injected from pi.exec(). */
157
163
  exec: ShellExec;
164
+ /** Agent config lookup — provides resolveAgentConfig and getToolNamesForType. */
165
+ registry: AgentConfigLookup;
166
+ /** Override working directory (e.g. for worktree isolation). */
167
+ cwd?: string;
168
+ /** Parent session identity (file path + session ID). */
169
+ parentSession?: ParentSessionInfo;
170
+ }
171
+
172
+ export interface RunOptions {
173
+ /** Parent execution context — where/who is running. */
174
+ context: RunContext;
158
175
  model?: Model<any>;
159
176
  maxTurns?: number;
160
177
  signal?: AbortSignal;
161
178
  isolated?: boolean;
162
179
  thinkingLevel?: ThinkingLevel;
163
- /** Override working directory (e.g. for worktree isolation). */
164
- cwd?: string;
165
- /** Parent session identity (file path + session ID). */
166
- parentSession?: ParentSessionInfo;
167
180
  /** Called once after session creation — session delivery mechanism. */
168
181
  onSessionCreated?: (session: AgentSession) => void;
169
182
  /**
@@ -177,8 +190,6 @@ export interface RunOptions {
177
190
  * module-scope `graceTurns` during migration.
178
191
  */
179
192
  graceTurns?: number;
180
- /** Agent config lookup — provides resolveAgentConfig and getToolNamesForType. */
181
- registry: AgentConfigLookup;
182
193
  }
183
194
 
184
195
  export interface RunResult {
@@ -275,8 +286,8 @@ export async function runAgent(
275
286
  io: RunnerIO,
276
287
  ): Promise<RunResult> {
277
288
  // Resolve working directory upfront — needed for detectEnv before assembly.
278
- const effectiveCwd = options.cwd ?? snapshot.cwd;
279
- const env = await io.detectEnv(options.exec, effectiveCwd);
289
+ const effectiveCwd = options.context.cwd ?? snapshot.cwd;
290
+ const env = await io.detectEnv(options.context.exec, effectiveCwd);
280
291
 
281
292
  // Assemble session configuration (synchronous, no SDK objects).
282
293
  const cfg = assembleSessionConfig(
@@ -288,13 +299,13 @@ export async function runAgent(
288
299
  modelRegistry: snapshot.modelRegistry,
289
300
  },
290
301
  {
291
- cwd: options.cwd,
302
+ cwd: options.context.cwd,
292
303
  isolated: options.isolated,
293
304
  model: options.model,
294
305
  thinkingLevel: options.thinkingLevel,
295
306
  },
296
307
  env,
297
- options.registry,
308
+ options.context.registry,
298
309
  io.assemblerIO,
299
310
  );
300
311
 
@@ -322,9 +333,9 @@ export async function runAgent(
322
333
  // Create a persisted SessionManager so transcripts are written in Pi's
323
334
  // official JSONL format. Falls back to a temp directory when the parent
324
335
  // session is not persisted (e.g. headless/API mode).
325
- const sessionDir = io.deriveSessionDir(options.parentSession?.parentSessionFile, cfg.effectiveCwd);
336
+ const sessionDir = io.deriveSessionDir(options.context.parentSession?.parentSessionFile, cfg.effectiveCwd);
326
337
  const sessionManager = io.createSessionManager(cfg.effectiveCwd, sessionDir);
327
- sessionManager.newSession({ parentSession: options.parentSession?.parentSessionId });
338
+ sessionManager.newSession({ parentSession: options.context.parentSession?.parentSessionId });
328
339
 
329
340
  const { session } = await io.createSession({
330
341
  cwd: cfg.effectiveCwd,
package/src/runtime.ts CHANGED
@@ -22,7 +22,7 @@ export interface WidgetLike {
22
22
  }
23
23
 
24
24
  /**
25
- * Narrow config subset read by AgentManager when constructing RunOptions.
25
+ * Narrow config subset read by AgentManager when constructing RunOptions execution fields.
26
26
  * Kept separate so callers can satisfy it without depending on the full runtime.
27
27
  */
28
28
  export interface RunConfig {
@@ -91,7 +91,7 @@ export interface AssemblerContext {
91
91
  }
92
92
 
93
93
  /**
94
- * Narrow slice of RunOptions consumed by the assembler.
94
+ * Narrow slice of RunOptions execution fields consumed by the assembler.
95
95
  * All fields are optional — callers pass only what they have.
96
96
  */
97
97
  export interface AssemblerOptions {