@gotgenes/pi-subagents 18.0.1 → 18.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/docs/architecture/architecture.md +157 -204
- package/docs/architecture/history/phase-19-implement-ui-decisions.md +282 -0
- package/package.json +5 -6
- package/src/lifecycle/subagent.ts +5 -9
- package/src/observation/notification.ts +23 -10
- package/src/observation/subagent-events-observer.ts +1 -3
- package/src/tools/get-result-report.ts +60 -0
- package/src/tools/get-result-tool.ts +25 -40
- package/src/types.ts +1 -1
- package/src/ui/session-navigator.ts +0 -2
- package/.prettierignore +0 -5
- package/AGENTS.md +0 -7
- package/docs/plans/0048-implement-subagents-api.md +0 -304
- package/docs/plans/0049-remove-group-join-output-file-rpc.md +0 -180
- package/docs/plans/0051-update-adr-0001-hard-fork.md +0 -77
- package/docs/plans/0052-remove-scheduled-subagents.md +0 -133
- package/docs/plans/0053-extract-model-resolution-from-execute.md +0 -181
- package/docs/plans/0054-decompose-index-into-modules.md +0 -302
- package/docs/plans/0057-structured-debug-logging.md +0 -154
- package/docs/plans/0061-session-format-transcript.md +0 -284
- package/docs/plans/0066-replace-as-any-with-sdk-types.md +0 -215
- package/docs/plans/0069-create-subagent-runtime.md +0 -345
- package/docs/plans/0070-extract-event-handlers.md +0 -306
- package/docs/plans/0071-extract-session-config-assembler.md +0 -362
- package/docs/plans/0072-inject-agent-manager-collaborators.md +0 -329
- package/docs/plans/0076-inject-cwd-into-agent-manager.md +0 -102
- package/docs/plans/0077-inject-project-agents-dir.md +0 -115
- package/docs/plans/0080-consolidate-agent-config-lookup.md +0 -247
- package/docs/plans/0084-extract-git-worktree-manager.md +0 -142
- package/docs/plans/0087-evolve-subagent-runtime-methods.md +0 -240
- package/docs/plans/0098-extract-agent-record-state-machine.md +0 -435
- package/docs/plans/0099-replace-ctx-with-parent-snapshot.md +0 -488
- package/docs/plans/0100-replace-callback-threading-with-session-subscription.md +0 -454
- package/docs/plans/0102-consolidate-test-record-factory.md +0 -176
- package/docs/plans/0108-extract-agent-type-registry.md +0 -322
- package/docs/plans/0109-extract-settings-manager.md +0 -276
- package/docs/plans/0110-agent-activity-tracker.md +0 -297
- package/docs/plans/0111-split-agent-record-lifecycle.md +0 -582
- package/docs/plans/0112-replace-agent-manager-callbacks.md +0 -241
- package/docs/plans/0113-disambiguate-spawn-options.md +0 -155
- package/docs/plans/0114-narrow-agent-tool-menu-deps.md +0 -279
- package/docs/plans/0115-decompose-agent-tool.md +0 -337
- package/docs/plans/0116-type-housekeeping.md +0 -351
- package/docs/plans/0118-settings-manager-apply-methods.md +0 -271
- package/docs/plans/0123-remove-vi-fn-cast-smell.md +0 -179
- package/docs/plans/0131-consolidate-shared-test-fixtures.md +0 -207
- package/docs/plans/0132-inject-io-into-session-config.md +0 -219
- package/docs/plans/0133-inject-sdk-boundary-into-agent-runner.md +0 -373
- package/docs/plans/0134-reduce-as-any-casts.md +0 -366
- package/docs/plans/0135-extract-display-helpers.md +0 -182
- package/docs/plans/0136-decompose-agent-menu.md +0 -300
- package/docs/plans/0144-consolidate-observation-model.md +0 -263
- package/docs/plans/0145-decompose-execute-push-ctx-to-boundary.md +0 -290
- package/docs/plans/0146-narrow-ui-context.md +0 -319
- package/docs/plans/0147-inject-wrap-text-into-conversation-viewer.md +0 -166
- package/docs/plans/0148-split-agent-widget-rendering.md +0 -255
- package/docs/plans/0152-add-prompt-snippet.md +0 -91
- package/docs/plans/0164-reorganize-into-domain-directories.md +0 -409
- package/docs/plans/0165-decompose-resolved-spawn-config.md +0 -157
- package/docs/plans/0166-extract-parent-session-info.md +0 -231
- package/docs/plans/0167-narrow-runner-io.md +0 -150
- package/docs/plans/0168-extract-tool-filter-config.md +0 -173
- package/docs/plans/0169-extract-run-context-from-run-options.md +0 -194
- package/docs/plans/0170-reduce-build-content-lines-complexity.md +0 -225
- package/docs/plans/0171-reduce-render-result-complexity.md +0 -200
- package/docs/plans/0172-extract-turn-formatting.md +0 -206
- package/docs/plans/0180-reorder-append-prompt-for-kv-cache.md +0 -100
- package/docs/plans/0185-remove-persistent-agent-memory.md +0 -161
- package/docs/plans/0188-replace-any-casts-with-sdk-types.md +0 -162
- package/docs/plans/0192-define-session-context-interface.md +0 -107
- package/docs/plans/0193-runtime-owns-context-queries.md +0 -245
- package/docs/plans/0194-align-tool-interfaces-for-structural-typing.md +0 -139
- package/docs/plans/0195-convert-tool-factories-to-classes.md +0 -264
- package/docs/plans/0196-convert-runner-menu-to-classes.md +0 -268
- package/docs/plans/0205-decompose-render-widget-lines.md +0 -140
- package/docs/plans/0206-decompose-show-agent-detail.md +0 -211
- package/docs/plans/0207-decompose-agent-widget-update.md +0 -242
- package/docs/plans/0208-extract-shared-test-fixtures.md +0 -298
- package/docs/plans/0214-convert-remaining-closure-factories-to-classes.md +0 -261
- package/docs/plans/0215-decompose-build-parent-context.md +0 -166
- package/docs/plans/0216-decompose-start-agent.md +0 -255
- package/docs/plans/0217-extract-overwrite-guard.md +0 -176
- package/docs/plans/0218-push-sdk-boundary-in-settings.md +0 -172
- package/docs/plans/0219-reduce-test-duplication-top-3-clone-families.md +0 -162
- package/docs/plans/0227-evolve-agent-record-into-agent.md +0 -322
- package/docs/plans/0228-async-start-agent-dissolve-run-handle.md +0 -288
- package/docs/plans/0229-agent-born-complete.md +0 -564
- package/docs/plans/0230-extract-concurrency-queue.md +0 -265
- package/docs/plans/0231-push-exec-registry-to-runner.md +0 -245
- package/docs/plans/0232-agent-resume-internal-observer-lifecycle.md +0 -180
- package/docs/plans/0237-remove-disallowed-tools.md +0 -180
- package/docs/plans/0238-remove-extensions-filtering.md +0 -191
- package/docs/plans/0239-collapse-filter-active-tools.md +0 -217
- package/docs/plans/0242-rename-agent-tool-to-subagent.md +0 -165
- package/docs/plans/0256-extract-worktree-isolation.md +0 -256
- package/docs/plans/0257-extract-child-session-factory.md +0 -285
- package/docs/plans/0262-add-workspace-provider-seam.md +0 -264
- package/docs/plans/0264-remove-extension-lifecycle-control.md +0 -277
- package/docs/plans/0265-born-complete-subagent-session.md +0 -333
- package/docs/plans/0270-type-consumable-public-surface.md +0 -204
- package/docs/plans/0272-export-workspace-collaborator-types.md +0 -147
- package/docs/plans/0277-encapsulate-agent-session.md +0 -304
- package/docs/plans/0280-rename-agent-to-subagent.md +0 -197
- package/docs/plans/0360-custom-agents-default-append.md +0 -132
- package/docs/plans/0373-extract-subagent-state.md +0 -250
- package/docs/plans/0374-encapsulate-subagent-start-notification.md +0 -268
- package/docs/plans/0375-extract-run-listener-workspace-bracket.md +0 -300
- package/docs/plans/0376-extract-manager-observer.md +0 -232
- package/docs/plans/0377-split-widget-delegation-from-runtime.md +0 -254
- package/docs/plans/0378-consolidate-lifecycle-test-fixtures.md +0 -243
- package/docs/plans/0379-consolidate-ui-tools-test-fixtures.md +0 -335
- package/docs/plans/0380-extract-layered-settings-loader.md +0 -223
- package/docs/plans/0381-replace-concurrency-queue-with-limiter.md +0 -267
- package/docs/plans/0400-include-parent-prompt-in-replace-mode.md +0 -199
- package/docs/plans/0403-abort-subagents-on-interrupt.md +0 -180
- package/docs/plans/0412-unify-session-mock-builders.md +0 -146
- package/docs/plans/0420-fold-run-metrics-live-activity-onto-record.md +0 -228
- package/docs/plans/0421-migrate-activity-readers-to-record-getters.md +0 -309
- package/docs/plans/0422-delete-activity-tracker-ui-observer.md +0 -204
- package/docs/plans/0423-widget-self-drive-from-lifecycle.md +0 -264
- package/docs/plans/0424-drop-widget-dep-from-subagent-tool.md +0 -166
- package/docs/plans/0425-reconcile-subagent-events-contract.md +0 -144
- package/docs/plans/0426-consolidate-residual-test-clone-families.md +0 -235
- package/docs/plans/0427-reconsider-ui-direction.md +0 -212
- package/docs/plans/0441-remove-agent-definition-management-subtree.md +0 -180
- package/docs/plans/0442-dissolve-agents-conversation-viewer.md +0 -195
- package/docs/plans/0443-consolidate-remaining-test-clone-families.md +0 -268
- package/docs/plans/0444-shrink-widget-to-background-agents.md +0 -156
- package/docs/plans/0445-native-session-navigation.md +0 -365
- package/docs/plans/0446-spike-session-navigation-entry-criteria.md +0 -171
- package/docs/plans/0447-extract-subagents-settings-command.md +0 -220
- package/docs/plans/0448-block-disabled-agent-spawn.md +0 -207
- package/docs/plans/0462-navigation-renderer-tui-components.md +0 -338
- package/docs/plans/0463-file-snapshot-source-evicted-agents.md +0 -306
- package/docs/plans/0470-refresh-readme-command-surface.md +0 -159
- package/docs/retro/0048-implement-subagents-api.md +0 -44
- package/docs/retro/0049-remove-group-join-output-file-rpc.md +0 -49
- package/docs/retro/0051-update-adr-0001-hard-fork.md +0 -39
- package/docs/retro/0053-extract-model-resolution-from-execute.md +0 -40
- package/docs/retro/0054-decompose-index-into-modules.md +0 -53
- package/docs/retro/0057-structured-debug-logging.md +0 -77
- package/docs/retro/0061-session-format-transcript.md +0 -41
- package/docs/retro/0066-replace-as-any-with-sdk-types.md +0 -44
- package/docs/retro/0069-create-subagent-runtime.md +0 -43
- package/docs/retro/0070-extract-event-handlers.md +0 -49
- package/docs/retro/0071-extract-session-config-assembler.md +0 -60
- package/docs/retro/0072-inject-agent-manager-collaborators.md +0 -46
- package/docs/retro/0076-inject-cwd-into-agent-manager.md +0 -35
- package/docs/retro/0077-inject-project-agents-dir.md +0 -33
- package/docs/retro/0080-consolidate-agent-config-lookup.md +0 -35
- package/docs/retro/0084-extract-git-worktree-manager.md +0 -37
- package/docs/retro/0087-evolve-subagent-runtime-methods.md +0 -42
- package/docs/retro/0098-extract-agent-record-state-machine.md +0 -46
- package/docs/retro/0099-replace-ctx-with-parent-snapshot.md +0 -37
- package/docs/retro/0100-replace-callback-threading-with-session-subscription.md +0 -36
- package/docs/retro/0102-consolidate-test-record-factory.md +0 -30
- package/docs/retro/0108-extract-agent-type-registry.md +0 -41
- package/docs/retro/0109-extract-settings-manager.md +0 -55
- package/docs/retro/0110-agent-activity-tracker.md +0 -44
- package/docs/retro/0111-split-agent-record-lifecycle.md +0 -61
- package/docs/retro/0112-replace-agent-manager-callbacks.md +0 -35
- package/docs/retro/0113-disambiguate-spawn-options.md +0 -29
- package/docs/retro/0114-narrow-agent-tool-menu-deps.md +0 -38
- package/docs/retro/0115-decompose-agent-tool.md +0 -51
- package/docs/retro/0116-type-housekeeping.md +0 -42
- package/docs/retro/0118-settings-manager-apply-methods.md +0 -40
- package/docs/retro/0123-remove-vi-fn-cast-smell.md +0 -49
- package/docs/retro/0131-consolidate-shared-test-fixtures.md +0 -46
- package/docs/retro/0132-inject-io-into-session-config.md +0 -33
- package/docs/retro/0133-inject-sdk-boundary-into-agent-runner.md +0 -45
- package/docs/retro/0134-reduce-as-any-casts.md +0 -56
- package/docs/retro/0135-extract-display-helpers.md +0 -38
- package/docs/retro/0136-decompose-agent-menu.md +0 -43
- package/docs/retro/0144-consolidate-observation-model.md +0 -39
- package/docs/retro/0145-decompose-execute-push-ctx-to-boundary.md +0 -56
- package/docs/retro/0146-narrow-ui-context.md +0 -70
- package/docs/retro/0147-inject-wrap-text-into-conversation-viewer.md +0 -90
- package/docs/retro/0148-split-agent-widget-rendering.md +0 -39
- package/docs/retro/0152-add-prompt-snippet.md +0 -34
- package/docs/retro/0164-reorganize-into-domain-directories.md +0 -82
- package/docs/retro/0165-decompose-resolved-spawn-config.md +0 -78
- package/docs/retro/0166-extract-parent-session-info.md +0 -66
- package/docs/retro/0167-narrow-runner-io.md +0 -63
- package/docs/retro/0168-extract-tool-filter-config.md +0 -76
- package/docs/retro/0169-extract-run-context-from-run-options.md +0 -68
- package/docs/retro/0170-reduce-build-content-lines-complexity.md +0 -72
- package/docs/retro/0171-reduce-render-result-complexity.md +0 -77
- package/docs/retro/0172-extract-turn-formatting.md +0 -80
- package/docs/retro/0180-reorder-append-prompt-for-kv-cache.md +0 -62
- package/docs/retro/0185-remove-persistent-agent-memory.md +0 -73
- package/docs/retro/0188-replace-any-casts-with-sdk-types.md +0 -69
- package/docs/retro/0192-define-session-context-interface.md +0 -59
- package/docs/retro/0193-runtime-owns-context-queries.md +0 -75
- package/docs/retro/0194-align-tool-interfaces-for-structural-typing.md +0 -62
- package/docs/retro/0195-convert-tool-factories-to-classes.md +0 -84
- package/docs/retro/0196-convert-runner-menu-to-classes.md +0 -73
- package/docs/retro/0205-decompose-render-widget-lines.md +0 -64
- package/docs/retro/0206-decompose-show-agent-detail.md +0 -67
- package/docs/retro/0207-decompose-agent-widget-update.md +0 -92
- package/docs/retro/0208-extract-shared-test-fixtures.md +0 -102
- package/docs/retro/0214-convert-remaining-closure-factories-to-classes.md +0 -66
- package/docs/retro/0215-decompose-build-parent-context.md +0 -61
- package/docs/retro/0216-decompose-start-agent.md +0 -80
- package/docs/retro/0217-extract-overwrite-guard.md +0 -63
- package/docs/retro/0218-push-sdk-boundary-in-settings.md +0 -72
- package/docs/retro/0219-reduce-test-duplication-top-3-clone-families.md +0 -64
- package/docs/retro/0227-evolve-agent-record-into-agent.md +0 -80
- package/docs/retro/0228-async-start-agent-dissolve-run-handle.md +0 -80
- package/docs/retro/0229-agent-born-complete.md +0 -89
- package/docs/retro/0230-extract-concurrency-queue.md +0 -38
- package/docs/retro/0231-push-exec-registry-to-runner.md +0 -71
- package/docs/retro/0232-agent-resume-internal-observer-lifecycle.md +0 -109
- package/docs/retro/0237-remove-disallowed-tools.md +0 -78
- package/docs/retro/0238-remove-extensions-filtering.md +0 -72
- package/docs/retro/0239-collapse-filter-active-tools.md +0 -70
- package/docs/retro/0242-rename-agent-tool-to-subagent.md +0 -82
- package/docs/retro/0256-extract-worktree-isolation.md +0 -89
- package/docs/retro/0257-extract-child-session-factory.md +0 -33
- package/docs/retro/0262-add-workspace-provider-seam.md +0 -89
- package/docs/retro/0264-remove-extension-lifecycle-control.md +0 -91
- package/docs/retro/0265-born-complete-subagent-session.md +0 -97
- package/docs/retro/0270-type-consumable-public-surface.md +0 -108
- package/docs/retro/0272-export-workspace-collaborator-types.md +0 -38
- package/docs/retro/0277-encapsulate-agent-session.md +0 -80
- package/docs/retro/0280-rename-agent-to-subagent.md +0 -96
- package/docs/retro/0360-custom-agents-default-append.md +0 -81
- package/docs/retro/0373-extract-subagent-state.md +0 -94
- package/docs/retro/0374-encapsulate-subagent-start-notification.md +0 -171
- package/docs/retro/0375-extract-run-listener-workspace-bracket.md +0 -104
- package/docs/retro/0376-extract-manager-observer.md +0 -81
- package/docs/retro/0377-split-widget-delegation-from-runtime.md +0 -105
- package/docs/retro/0378-consolidate-lifecycle-test-fixtures.md +0 -100
- package/docs/retro/0379-consolidate-ui-tools-test-fixtures.md +0 -52
- package/docs/retro/0380-extract-layered-settings-loader.md +0 -97
- package/docs/retro/0381-replace-concurrency-queue-with-limiter.md +0 -95
- package/docs/retro/0400-include-parent-prompt-in-replace-mode.md +0 -84
- package/docs/retro/0403-abort-subagents-on-interrupt.md +0 -90
- package/docs/retro/0412-unify-session-mock-builders.md +0 -80
- package/docs/retro/0420-fold-run-metrics-live-activity-onto-record.md +0 -90
- package/docs/retro/0421-migrate-activity-readers-to-record-getters.md +0 -105
- package/docs/retro/0422-delete-activity-tracker-ui-observer.md +0 -97
- package/docs/retro/0423-widget-self-drive-from-lifecycle.md +0 -112
- package/docs/retro/0424-drop-widget-dep-from-subagent-tool.md +0 -89
- package/docs/retro/0425-reconcile-subagent-events-contract.md +0 -101
- package/docs/retro/0426-consolidate-residual-test-clone-families.md +0 -100
- package/docs/retro/0427-reconsider-ui-direction.md +0 -102
- package/docs/retro/0441-remove-agent-definition-management-subtree.md +0 -97
- package/docs/retro/0442-dissolve-agents-conversation-viewer.md +0 -108
- package/docs/retro/0443-consolidate-remaining-test-clone-families.md +0 -28
- package/docs/retro/0444-shrink-widget-to-background-agents.md +0 -81
- package/docs/retro/0445-native-session-navigation.md +0 -122
- package/docs/retro/0446-spike-session-navigation-entry-criteria.md +0 -99
- package/docs/retro/0447-extract-subagents-settings-command.md +0 -91
- package/docs/retro/0448-block-disabled-agent-spawn.md +0 -75
- package/docs/retro/0462-navigation-renderer-tui-components.md +0 -105
- package/docs/retro/0463-file-snapshot-source-evicted-agents.md +0 -103
- package/docs/retro/0470-refresh-readme-command-surface.md +0 -40
- package/src/observation/notification-state.ts +0 -27
- package/vitest.config.ts +0 -14
|
@@ -1,290 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 145
|
|
3
|
-
issue_title: "Decompose execute and push ExtensionContext to the boundary (Phase 9, Step M)"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Decompose execute and push ctx to the boundary
|
|
7
|
-
|
|
8
|
-
## Problem Statement
|
|
9
|
-
|
|
10
|
-
`agent-tool.ts` `execute` is ~140 lines mixing three concerns: boundary extraction (~5 lines reading `ctx`), config resolution (~60 lines unpacking `resolvedConfig` field by field), and dispatch (~80 lines building 14–16 field parameter bags for `spawnBackground` and `runForeground`).
|
|
11
|
-
The large parameter bags exist because config resolution happens inline instead of in a dedicated function.
|
|
12
|
-
Meanwhile, `ExtensionContext` is threaded from `execute` through `ForegroundParams.ctx` / `BackgroundParams.ctx` into `foreground-runner` and `background-spawner`, where the only thing consumed is `sessionManager.getSessionFile()` and `sessionManager.getSessionId()`.
|
|
13
|
-
`AgentManager.spawn()` and `spawnAndWait()` accept `ExtensionContext` directly and call `buildParentSnapshot(ctx)` internally — but this is already a pure boundary concern that belongs at the call site.
|
|
14
|
-
Additionally, `execute` reaches into `ctx` for model info and session identity — these are session-scoped values that `index.ts` already captures and could inject as collaborators, removing `execute`'s need to read `ctx` beyond the UI context it already delegates to `widget.setUICtx()`.
|
|
15
|
-
|
|
16
|
-
## Goals
|
|
17
|
-
|
|
18
|
-
- Extract config resolution into a pure function (`resolveSpawnConfig`) so `execute` becomes: resolve config → dispatch.
|
|
19
|
-
- Inject three missing collaborators into `createAgentTool` so `execute` no longer extracts values from `ctx`:
|
|
20
|
-
- `buildSnapshot: (inheritContext: boolean) => ParentSnapshot` — closure over `ctx`, wired in `index.ts`.
|
|
21
|
-
- `getModelInfo: () => ModelInfo` — provides `parentModel` and `modelRegistry` for `resolveSpawnConfig`.
|
|
22
|
-
- `getSessionInfo: () => { parentSessionFile: string; parentSessionId: string }` — parent session identity.
|
|
23
|
-
- Replace `ForegroundParams.ctx` and `BackgroundParams.ctx` with plain domain values (`parentSessionFile`, `parentSessionId`, `snapshot`).
|
|
24
|
-
- Change `AgentManager.spawn()` and `spawnAndWait()` to accept `ParentSnapshot` instead of `ExtensionContext`.
|
|
25
|
-
- Move `buildParentSnapshot(ctx)` calls to the two boundaries: `index.ts` (via closure) and `service-adapter.ts`.
|
|
26
|
-
- Eliminate the `vi.mock("../src/parent-snapshot.js")` in `agent-manager.test.ts`.
|
|
27
|
-
- Apply the dependency bag convention: dissolve `ForegroundDeps`, `BackgroundDeps`, `AdapterDeps` (each ≤3 fields) into plain parameters.
|
|
28
|
-
- This is a breaking internal refactor — no public API changes.
|
|
29
|
-
|
|
30
|
-
## Non-Goals
|
|
31
|
-
|
|
32
|
-
- Narrowing menu handler ctx (Step N, #146) — deferred.
|
|
33
|
-
- Injecting text wrapping into ConversationViewer (Step O, #147) — unrelated track.
|
|
34
|
-
- Observation model consolidation (Step L, #144) — independent track.
|
|
35
|
-
- Changing the `SubagentsService` public API in `service.ts`.
|
|
36
|
-
|
|
37
|
-
## Background
|
|
38
|
-
|
|
39
|
-
### Relevant modules
|
|
40
|
-
|
|
41
|
-
| Module | Current role |
|
|
42
|
-
| ----------------------------- | ------------------------------------------------------------------------------------------------ |
|
|
43
|
-
| `tools/agent-tool.ts` | `execute` callback — 140 lines, mixes boundary extraction, config resolution, dispatch |
|
|
44
|
-
| `tools/foreground-runner.ts` | `runForeground()` — receives 14-field `ForegroundParams` including `ctx` with `sessionManager` |
|
|
45
|
-
| `tools/background-spawner.ts` | `spawnBackground()` — receives 14-field `BackgroundParams` including `ctx` with `sessionManager` |
|
|
46
|
-
| `agent-manager.ts` | `spawn()` / `spawnAndWait()` accept `ExtensionContext`, call `buildParentSnapshot()` internally |
|
|
47
|
-
| `parent-snapshot.ts` | `buildParentSnapshot(ctx)` — pure function capturing `ParentSnapshot` from ctx |
|
|
48
|
-
| `service-adapter.ts` | Cross-extension boundary — calls `manager.spawn(session.ctx, ...)` |
|
|
49
|
-
| `invocation-config.ts` | `resolveAgentInvocationConfig()` — merges agent config with tool params |
|
|
50
|
-
| `model-resolver.ts` | `resolveInvocationModel()` — resolves model strings to model instances |
|
|
51
|
-
| `index.ts` | Extension entry point — wires `createAgentTool` deps, captures `runtime.currentCtx` |
|
|
52
|
-
| `runtime.ts` | `SubagentRuntime` — holds session-scoped mutable state including `currentCtx` |
|
|
53
|
-
|
|
54
|
-
### Constraints from AGENTS.md
|
|
55
|
-
|
|
56
|
-
- Keep modules focused and composable (one concern per file).
|
|
57
|
-
- Prefer explicit configuration over hidden behavior.
|
|
58
|
-
- Keep Pi SDK imports out of business-logic modules.
|
|
59
|
-
- Business logic should be pure functions — keep IO at the edges.
|
|
60
|
-
|
|
61
|
-
### Phase 9 context
|
|
62
|
-
|
|
63
|
-
This is Step M of Phase 9.
|
|
64
|
-
It has no blockers and blocks Step N (#146), which narrows menu handler ctx.
|
|
65
|
-
After this step, `ExtensionContext` appears only at true SDK/extension boundaries: `index.ts` closures, `service-adapter.ts`, and menu handlers.
|
|
66
|
-
|
|
67
|
-
## Design Overview
|
|
68
|
-
|
|
69
|
-
### Part 1: Extract config resolution (done)
|
|
70
|
-
|
|
71
|
-
A new pure function `resolveSpawnConfig` in `spawn-config.ts` encapsulates all config resolution logic previously inline in `execute`.
|
|
72
|
-
`execute` calls `resolveSpawnConfig(params, registry, modelInfo, settings)` and dispatches on the result.
|
|
73
|
-
This is already committed.
|
|
74
|
-
|
|
75
|
-
### Part 2: Inject collaborators and push ctx out of execute
|
|
76
|
-
|
|
77
|
-
`execute` currently reads `ctx.model`, `ctx.modelRegistry`, `ctx.sessionManager`, and passes `ctx` to `buildParentSnapshot`.
|
|
78
|
-
These are all session-scoped values that `index.ts` captures at session start.
|
|
79
|
-
Three collaborators replace the `ctx` reads:
|
|
80
|
-
|
|
81
|
-
```typescript
|
|
82
|
-
// Injected as plain parameters into createAgentTool:
|
|
83
|
-
buildSnapshot: (inheritContext: boolean) => ParentSnapshot,
|
|
84
|
-
getModelInfo: () => ModelInfo,
|
|
85
|
-
getSessionInfo: () => { parentSessionFile: string; parentSessionId: string },
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
`index.ts` wires them as closures over `runtime.currentCtx`:
|
|
89
|
-
|
|
90
|
-
```typescript
|
|
91
|
-
createAgentTool({
|
|
92
|
-
// ... existing params ...
|
|
93
|
-
buildSnapshot: (inheritContext) => buildParentSnapshot(ctx, inheritContext),
|
|
94
|
-
getModelInfo: () => ({
|
|
95
|
-
parentModel: ctx.model,
|
|
96
|
-
modelRegistry: ctx.modelRegistry,
|
|
97
|
-
}),
|
|
98
|
-
getSessionInfo: () => ({
|
|
99
|
-
parentSessionFile: ctx.sessionManager.getSessionFile(),
|
|
100
|
-
parentSessionId: ctx.sessionManager.getSessionId(),
|
|
101
|
-
}),
|
|
102
|
-
})
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
After this, `execute` touches `ctx` only for `ctx.ui` — which is already delegated via `widget.setUICtx()`.
|
|
106
|
-
The `ExtensionContext` import in `agent-tool.ts` is removed entirely.
|
|
107
|
-
|
|
108
|
-
### Part 3: Push ctx out of AgentManager
|
|
109
|
-
|
|
110
|
-
`AgentManager.spawn()` and `spawnAndWait()` accept `ParentSnapshot` instead of `ExtensionContext`.
|
|
111
|
-
The internal `buildParentSnapshot(ctx, ...)` call is removed — `snapshot` arrives pre-built from the call sites.
|
|
112
|
-
`service-adapter.ts` calls `buildParentSnapshot(session.ctx, ...)` at its boundary before delegating.
|
|
113
|
-
|
|
114
|
-
### Part 4: Push ctx out of foreground-runner and background-spawner
|
|
115
|
-
|
|
116
|
-
`ForegroundParams.ctx` and `BackgroundParams.ctx` are replaced by `snapshot: ParentSnapshot`, `parentSessionFile: string`, `parentSessionId: string`.
|
|
117
|
-
The narrow manager interfaces change from `ctx: any` to `snapshot: ParentSnapshot`.
|
|
118
|
-
|
|
119
|
-
### Part 5: Shrink params bags with ResolvedSpawnConfig
|
|
120
|
-
|
|
121
|
-
`ForegroundParams` and `BackgroundParams` carry `ResolvedSpawnConfig` instead of 10+ individual fields that were computed during config resolution.
|
|
122
|
-
Only dispatch-specific fields (`rawType`, `fellBack`, `toolCallId`, `displayName`) remain as separate params fields.
|
|
123
|
-
|
|
124
|
-
### Part 6: Dissolve small dependency bags
|
|
125
|
-
|
|
126
|
-
Per the dependency bag convention:
|
|
127
|
-
|
|
128
|
-
- `ForegroundDeps` (3 fields) → plain parameters on `runForeground`.
|
|
129
|
-
- `BackgroundDeps` (3 fields) → plain parameters on `spawnBackground`.
|
|
130
|
-
- `AdapterDeps` (4 fields) → plain parameters on `createSubagentsService`.
|
|
131
|
-
- `AgentToolDeps` → destructured in the `createAgentTool` signature; the interface stays as a named type for the test factory.
|
|
132
|
-
|
|
133
|
-
The narrow `*ManagerDeps` and `*WidgetDeps` interfaces stay — they define the contract each function needs from its collaborators.
|
|
134
|
-
|
|
135
|
-
## Module-Level Changes
|
|
136
|
-
|
|
137
|
-
### New file: `src/tools/spawn-config.ts` (done)
|
|
138
|
-
|
|
139
|
-
- `ResolvedSpawnConfig` interface.
|
|
140
|
-
- `ModelInfo` interface.
|
|
141
|
-
- `resolveSpawnConfig()` pure function.
|
|
142
|
-
|
|
143
|
-
### Modified: `src/tools/agent-tool.ts`
|
|
144
|
-
|
|
145
|
-
- `execute` shrinks from ~140 to ~20 lines.
|
|
146
|
-
- `ExtensionContext` import removed — `execute` no longer reads `ctx` directly (beyond `ctx.ui` via widget).
|
|
147
|
-
- Three new collaborator parameters: `buildSnapshot`, `getModelInfo`, `getSessionInfo`.
|
|
148
|
-
- Calls `resolveSpawnConfig(params, registry, getModelInfo(), settings)`.
|
|
149
|
-
- Calls `buildSnapshot(config.inheritContext)` for the snapshot.
|
|
150
|
-
- Calls `getSessionInfo()` for parent session identity.
|
|
151
|
-
- Passes domain values (not `ctx`) to `runForeground` / `spawnBackground`.
|
|
152
|
-
- `AgentToolManager.spawn` and `spawnAndWait` signatures change to accept `ParentSnapshot`.
|
|
153
|
-
- `AgentToolDeps` stays as a named type (used by test factory) but its fields are destructured in `createAgentTool`.
|
|
154
|
-
|
|
155
|
-
### Modified: `src/tools/foreground-runner.ts`
|
|
156
|
-
|
|
157
|
-
- `ForegroundDeps` interface removed — `runForeground` accepts `manager`, `widget`, `agentActivity` as plain parameters.
|
|
158
|
-
- `ForegroundParams.ctx` removed — replaced by `snapshot`, `parentSessionFile`, `parentSessionId`.
|
|
159
|
-
- `ForegroundManagerDeps.spawnAndWait` signature changes from `ctx: any` to `snapshot: ParentSnapshot`.
|
|
160
|
-
- Individual config fields move into `ResolvedSpawnConfig`.
|
|
161
|
-
|
|
162
|
-
### Modified: `src/tools/background-spawner.ts`
|
|
163
|
-
|
|
164
|
-
- `BackgroundDeps` interface removed — `spawnBackground` accepts `manager`, `widget`, `agentActivity` as plain parameters.
|
|
165
|
-
- `BackgroundParams.ctx` removed — replaced by `snapshot`, `parentSessionFile`, `parentSessionId`.
|
|
166
|
-
- `BackgroundManagerDeps.spawn` signature changes from `ctx: any` to `snapshot: ParentSnapshot`.
|
|
167
|
-
- Individual config fields move into `ResolvedSpawnConfig`.
|
|
168
|
-
|
|
169
|
-
### Modified: `src/agent-manager.ts`
|
|
170
|
-
|
|
171
|
-
- `spawn()` signature changes from `ctx: ExtensionContext` to `snapshot: ParentSnapshot`.
|
|
172
|
-
- `spawnAndWait()` signature changes from `ctx: ExtensionContext` to `snapshot: ParentSnapshot`.
|
|
173
|
-
- Internal `buildParentSnapshot(ctx, ...)` call removed.
|
|
174
|
-
- Imports of `ExtensionContext` and `buildParentSnapshot` removed.
|
|
175
|
-
|
|
176
|
-
### Modified: `src/service-adapter.ts`
|
|
177
|
-
|
|
178
|
-
- `AdapterDeps` interface removed — `createSubagentsService` accepts plain parameters.
|
|
179
|
-
- `AgentManagerLike.spawn` signature changes from `ctx: unknown` to `snapshot: ParentSnapshot`.
|
|
180
|
-
- `spawn()` method calls `buildParentSnapshot(session.ctx, options?.inheritContext)` before delegating.
|
|
181
|
-
- Adds imports of `buildParentSnapshot` and `ParentSnapshot`.
|
|
182
|
-
|
|
183
|
-
### Modified: `src/index.ts`
|
|
184
|
-
|
|
185
|
-
- Wiring for `createAgentTool` adds three collaborator closures: `buildSnapshot`, `getModelInfo`, `getSessionInfo`.
|
|
186
|
-
- `manager.spawn` / `spawnAndWait` wiring adapters removed (closures no longer need to relay `ctx`).
|
|
187
|
-
- Wiring for `createSubagentsService` changes from bag to plain arguments.
|
|
188
|
-
|
|
189
|
-
## Test Impact Analysis
|
|
190
|
-
|
|
191
|
-
### New unit tests enabled
|
|
192
|
-
|
|
193
|
-
- `spawn-config.test.ts` (done) — pure-function tests for `resolveSpawnConfig`.
|
|
194
|
-
|
|
195
|
-
### Existing tests that simplify
|
|
196
|
-
|
|
197
|
-
- `agent-manager.test.ts` — the `vi.mock("../src/parent-snapshot.js")` block is removed.
|
|
198
|
-
All tests pass a plain `ParentSnapshot` object directly instead of `mockCtx`.
|
|
199
|
-
- `foreground-runner.test.ts` — `makeCtx()` helper removed; plain strings for session identity.
|
|
200
|
-
- `background-spawner.test.ts` — same as foreground.
|
|
201
|
-
- `agent-tool.test.ts` — `makeCtx()` simplified; collaborator stubs replace `ctx.model` / `ctx.modelRegistry` reads.
|
|
202
|
-
- `service-adapter.test.ts` — adapter test setup changes from bag to plain parameters.
|
|
203
|
-
|
|
204
|
-
### Existing tests that stay
|
|
205
|
-
|
|
206
|
-
- `parent-snapshot.test.ts` — unchanged; `buildParentSnapshot` is still a standalone pure function.
|
|
207
|
-
|
|
208
|
-
## TDD Order
|
|
209
|
-
|
|
210
|
-
### Step 1: Extract resolveSpawnConfig (done)
|
|
211
|
-
|
|
212
|
-
1. ~~Write `spawn-config.test.ts`, implement `spawn-config.ts`.~~
|
|
213
|
-
Commit: `feat: extract resolveSpawnConfig pure function (#145)` ✓
|
|
214
|
-
|
|
215
|
-
2. ~~Rewire `execute` to call `resolveSpawnConfig`.~~
|
|
216
|
-
Commit: `refactor: use resolveSpawnConfig in execute (#145)` ✓
|
|
217
|
-
|
|
218
|
-
### Step 2: Push ctx out of AgentManager
|
|
219
|
-
|
|
220
|
-
3. Red: update `agent-manager.test.ts` — replace `mockCtx` with a plain `ParentSnapshot` object, remove `vi.mock("../src/parent-snapshot.js")`.
|
|
221
|
-
Green: change `AgentManager.spawn()` and `spawnAndWait()` to accept `ParentSnapshot`.
|
|
222
|
-
Update `agent-tool.ts` manager interface, `service-adapter.ts` to call `buildParentSnapshot` at its boundary, and `index.ts` wiring.
|
|
223
|
-
Commit: `refactor: AgentManager accepts ParentSnapshot instead of ExtensionContext (#145)`
|
|
224
|
-
|
|
225
|
-
### Step 3: Inject collaborators into createAgentTool
|
|
226
|
-
|
|
227
|
-
4. Red: update `agent-tool.test.ts` — add `buildSnapshot`, `getModelInfo`, `getSessionInfo` stubs to `createToolDeps`; simplify `makeCtx()`.
|
|
228
|
-
Green: add three collaborator parameters to `createAgentTool`; rewrite `execute` to use them instead of `ctx.model` / `ctx.modelRegistry` / `ctx.sessionManager`.
|
|
229
|
-
Remove `ExtensionContext` import from `agent-tool.ts`.
|
|
230
|
-
Update `index.ts` wiring to provide closures.
|
|
231
|
-
Commit: `refactor: inject collaborators into createAgentTool, eliminate ctx reads (#145)`
|
|
232
|
-
|
|
233
|
-
### Step 4: Push ctx out of foreground-runner and background-spawner
|
|
234
|
-
|
|
235
|
-
5. Red: update `foreground-runner.test.ts` — remove `makeCtx()`, replace `ForegroundParams.ctx` with `snapshot` / `parentSessionFile` / `parentSessionId`.
|
|
236
|
-
Green: change `ForegroundParams` to use plain domain values, update `runForeground` accordingly.
|
|
237
|
-
Commit: `refactor: foreground-runner receives domain values instead of ctx (#145)`
|
|
238
|
-
|
|
239
|
-
6. Red: update `background-spawner.test.ts` — remove `makeCtx()`, replace `BackgroundParams.ctx` with `snapshot` / `parentSessionFile` / `parentSessionId`.
|
|
240
|
-
Green: change `BackgroundParams` to use plain domain values, update `spawnBackground` accordingly.
|
|
241
|
-
Commit: `refactor: background-spawner receives domain values instead of ctx (#145)`
|
|
242
|
-
|
|
243
|
-
### Step 5: Shrink params bags with ResolvedSpawnConfig
|
|
244
|
-
|
|
245
|
-
7. Red: update `foreground-runner.test.ts` `makeParams()` to use `ResolvedSpawnConfig` fields.
|
|
246
|
-
Green: change `ForegroundParams` to carry `ResolvedSpawnConfig`.
|
|
247
|
-
Update `agent-tool.ts` dispatch to pass the config through.
|
|
248
|
-
Commit: `refactor: ForegroundParams carries ResolvedSpawnConfig (#145)`
|
|
249
|
-
|
|
250
|
-
8. Red: update `background-spawner.test.ts` `makeParams()` to use `ResolvedSpawnConfig` fields.
|
|
251
|
-
Green: change `BackgroundParams` to carry `ResolvedSpawnConfig`.
|
|
252
|
-
Update `agent-tool.ts` dispatch to pass the config through.
|
|
253
|
-
Commit: `refactor: BackgroundParams carries ResolvedSpawnConfig (#145)`
|
|
254
|
-
|
|
255
|
-
### Step 6: Dissolve small dependency bags
|
|
256
|
-
|
|
257
|
-
9. Red: update `foreground-runner.test.ts` calls to pass `manager`, `widget`, `agentActivity` as plain args.
|
|
258
|
-
Green: remove `ForegroundDeps` interface, change `runForeground` signature.
|
|
259
|
-
Commit: `refactor: dissolve ForegroundDeps into plain parameters (#145)`
|
|
260
|
-
|
|
261
|
-
10. Red: update `background-spawner.test.ts` calls to pass plain args.
|
|
262
|
-
Green: remove `BackgroundDeps` interface, change `spawnBackground` signature.
|
|
263
|
-
Commit: `refactor: dissolve BackgroundDeps into plain parameters (#145)`
|
|
264
|
-
|
|
265
|
-
11. Red: update `service-adapter.test.ts` to pass plain parameters instead of `AdapterDeps` bag.
|
|
266
|
-
Green: remove `AdapterDeps` interface, change `createSubagentsService` signature.
|
|
267
|
-
Update `index.ts` wiring call site.
|
|
268
|
-
Commit: `refactor: dissolve AdapterDeps into plain parameters (#145)`
|
|
269
|
-
|
|
270
|
-
12. Refactor: destructure `AgentToolDeps` in `createAgentTool` signature (keep the named type for test factory).
|
|
271
|
-
Commit: `refactor: destructure AgentToolDeps in createAgentTool (#145)`
|
|
272
|
-
|
|
273
|
-
### Step 7: Final verification
|
|
274
|
-
|
|
275
|
-
13. Run full test suite and type check.
|
|
276
|
-
|
|
277
|
-
## Risks and Mitigations
|
|
278
|
-
|
|
279
|
-
| Risk | Mitigation |
|
|
280
|
-
| --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
281
|
-
| Wide blast radius — touches 7+ source files and 5+ test files | Incremental TDD steps; each commit leaves the repo green |
|
|
282
|
-
| `service-adapter.ts` now imports `buildParentSnapshot` — new coupling | Acceptable: the adapter is already a boundary module that bridges `ExtensionContext` to domain types |
|
|
283
|
-
| `ResolvedSpawnConfig` could become a new "god object" | It is a pure data return from a single function; consumers destructure what they need |
|
|
284
|
-
| Three new collaborators grow `AgentToolDeps` from 6 to 9 fields | The deps bag is destructured at the signature; the named type exists only for the test factory. The real dependency count stays the same — previously hidden behind `ctx` reads |
|
|
285
|
-
| `index.ts` closures capture `ctx` — stale reference risk | Same pattern `service-adapter.ts` already uses via `runtime.currentCtx`; session lifecycle clears on shutdown |
|
|
286
|
-
|
|
287
|
-
## Open Questions
|
|
288
|
-
|
|
289
|
-
- The exact boundary between fields that stay in `ForegroundParams` / `BackgroundParams` vs. fields that move into `ResolvedSpawnConfig` may shift during implementation.
|
|
290
|
-
The guiding principle: if the field is computed during config resolution, it belongs in `ResolvedSpawnConfig`; if it is dispatch-specific (e.g., `toolCallId`, `signal`, `onUpdate`), it stays in the params type.
|
|
@@ -1,319 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 146
|
|
3
|
-
issue_title: "Narrow UI context for menu handlers (Phase 9, Step N)"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Narrow UI context for menu handlers
|
|
7
|
-
|
|
8
|
-
## Problem Statement
|
|
9
|
-
|
|
10
|
-
Menu handler functions (`showAgentsMenu`, `showAgentDetail`, `showCreateWizard`, etc.) declare `ctx: ExtensionContext` but only call `ctx.ui.select/confirm/input/notify/editor/custom` and `ctx.modelRegistry`.
|
|
11
|
-
This forces 42 `ctx as any` casts across 3 test files (`agent-menu.test.ts`: 8, `agent-config-editor.test.ts`: 20, `agent-creation-wizard.test.ts`: 14) because tests cannot construct a full `ExtensionContext`.
|
|
12
|
-
|
|
13
|
-
## Goals
|
|
14
|
-
|
|
15
|
-
- Define a `MenuUI` interface with the subset of `ctx.ui` methods that menu handlers actually use (`select`, `confirm`, `input`, `notify`, `editor`, `custom`).
|
|
16
|
-
- Menu handler functions accept `MenuUI` (plus `modelRegistry` passed separately) instead of `ExtensionContext`.
|
|
17
|
-
- `index.ts` handler registration extracts `ctx.ui` and `ctx.modelRegistry` from the SDK `ExtensionContext`.
|
|
18
|
-
- Change `WizardManager.spawnAndWait` to accept `ParentSnapshot` (introduced by #145) instead of `ExtensionContext`.
|
|
19
|
-
- Apply dependency bag convention: dissolve ≤4-field deps into plain parameters; keep ≥5-field interfaces but destructure in signature.
|
|
20
|
-
- Eliminate all 42 `ctx as any` casts from menu, editor, and wizard test files.
|
|
21
|
-
|
|
22
|
-
## Non-Goals
|
|
23
|
-
|
|
24
|
-
- Changing the behavior of `ctx.ui.custom` — pass-through only.
|
|
25
|
-
- Narrowing `ExtensionContext` usage in `index.ts` closures (the `as any` casts for `runtime.currentCtx?.ctx` are addressed separately).
|
|
26
|
-
- Injecting `modelRegistry` further (already a narrow interface from `model-resolver.ts`).
|
|
27
|
-
|
|
28
|
-
## Background
|
|
29
|
-
|
|
30
|
-
### Dependency: #145 (Step M) — Decompose execute
|
|
31
|
-
|
|
32
|
-
Issue #145 is **closed/implemented**.
|
|
33
|
-
`buildParentSnapshot(ctx)` converts `ExtensionContext` → `ParentSnapshot` at the call site.
|
|
34
|
-
This enables `WizardManager.spawnAndWait` to accept `ParentSnapshot` instead of `ExtensionContext`.
|
|
35
|
-
|
|
36
|
-
### Existing modules
|
|
37
|
-
|
|
38
|
-
- `agent-menu.ts` (296 lines) — menu handler factory, 8-field `AgentMenuDeps`, all inner functions take `ctx: ExtensionContext`
|
|
39
|
-
- `agent-config-editor.ts` (202 lines) — `AgentConfigEditorDeps` (4 fields), `showAgentDetail` takes `ctx: ExtensionContext`
|
|
40
|
-
- `agent-creation-wizard.ts` (246 lines) — `AgentCreationWizardDeps` (5 fields), `WizardManager.spawnAndWait` takes `ctx: ExtensionContext`
|
|
41
|
-
- `tools/get-result-tool.ts` — `GetResultDeps` (4 fields)
|
|
42
|
-
- `tools/steer-tool.ts` — `SteerToolDeps` (4 fields)
|
|
43
|
-
- `index.ts` — wires everything, handler registration extracts `ctx.ui` and passes `ExtensionContext`
|
|
44
|
-
|
|
45
|
-
### ExtensionContext usage in menu handlers
|
|
46
|
-
|
|
47
|
-
Every `ctx` reference in the three menu UI modules maps to exactly one of:
|
|
48
|
-
|
|
49
|
-
- `ctx.ui.select(...)` — 9 call sites
|
|
50
|
-
- `ctx.ui.confirm(...)` — 5 call sites
|
|
51
|
-
- `ctx.ui.input(...)` — 7 call sites
|
|
52
|
-
- `ctx.ui.notify(...)` — 15 call sites
|
|
53
|
-
- `ctx.ui.editor(...)` — 2 call sites
|
|
54
|
-
- `ctx.ui.custom(...)` — 1 call site (conversation viewer overlay)
|
|
55
|
-
- `ctx.modelRegistry` — 1 call site (model label resolution in `showAllAgentsList`)
|
|
56
|
-
|
|
57
|
-
No other `ExtensionContext` properties (session, tools, hooks, etc.) are accessed.
|
|
58
|
-
|
|
59
|
-
## Design Overview
|
|
60
|
-
|
|
61
|
-
### MenuUI interface
|
|
62
|
-
|
|
63
|
-
A narrow interface capturing only the `ctx.ui` methods used by menu handlers:
|
|
64
|
-
|
|
65
|
-
```typescript
|
|
66
|
-
export interface MenuUI {
|
|
67
|
-
select(title: string, options: string[]): Promise<string | undefined>;
|
|
68
|
-
confirm(title: string, message: string): Promise<boolean>;
|
|
69
|
-
input(title: string, defaultValue?: string): Promise<string | undefined>;
|
|
70
|
-
notify(message: string, level: "info" | "warning" | "error"): void;
|
|
71
|
-
editor(title: string, content: string): Promise<string | undefined>;
|
|
72
|
-
custom<R>(component: any, options?: any): Promise<R>;
|
|
73
|
-
}
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
`select` uses a plain `string` return (not a generic `<T extends string>`) to match the SDK's structural signature.
|
|
77
|
-
|
|
78
|
-
`modelRegistry` is not included in `MenuUI` — it is not a UI concern.
|
|
79
|
-
Instead, the handler registration in `index.ts` passes it separately.
|
|
80
|
-
|
|
81
|
-
### Handler signature change
|
|
82
|
-
|
|
83
|
-
The menu handler currently receives `ExtensionContext` directly:
|
|
84
|
-
|
|
85
|
-
```typescript
|
|
86
|
-
// index.ts — before
|
|
87
|
-
handler: async (_args, ctx) => { await agentsMenuHandler(ctx); },
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
After this change, `index.ts` destructures what each handler needs:
|
|
91
|
-
|
|
92
|
-
```typescript
|
|
93
|
-
// index.ts — after
|
|
94
|
-
handler: async (_args, ctx) => {
|
|
95
|
-
await agentsMenuHandler({
|
|
96
|
-
ui: ctx.ui,
|
|
97
|
-
modelRegistry: ctx.modelRegistry,
|
|
98
|
-
parentSnapshot: buildParentSnapshot(ctx),
|
|
99
|
-
});
|
|
100
|
-
},
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
In `agent-menu.ts`, the return type changes from `(ctx: ExtensionContext) => Promise<void>` to a function that accepts `{ ui: MenuUI; modelRegistry: ModelRegistry; parentSnapshot: ParentSnapshot }`.
|
|
104
|
-
The `ExtensionContext` import is removed from `agent-menu.ts`, `agent-config-editor.ts`, and `agent-creation-wizard.ts`.
|
|
105
|
-
|
|
106
|
-
`modelRegistry` is threaded from the handler through `showAgentsMenu` → `showAllAgentsList` (the only consumer).
|
|
107
|
-
`parentSnapshot` is threaded from the handler through `showAgentsMenu` → `wizard.showCreateWizard` → `showGenerateWizard` (the only consumer).
|
|
108
|
-
|
|
109
|
-
### Wizard spawnAndWait — drop ctx parameter
|
|
110
|
-
|
|
111
|
-
`WizardManager.spawnAndWait` currently takes `ctx: ExtensionContext` as its first parameter and passes it to `deps.manager.spawnAndWait(ctx, ...)`.
|
|
112
|
-
Once the menu handler no longer receives `ExtensionContext`, the wizard has no `ctx` to pass.
|
|
113
|
-
|
|
114
|
-
Thread `parentSnapshot` as a parameter from the handler through the wizard, keeping `AgentMenuManager.spawnAndWait` accepting `ParentSnapshot` as its first parameter (consistent with `AgentManager.spawnAndWait`).
|
|
115
|
-
The wizard's `showGenerateWizard` receives `parentSnapshot` and passes it to `deps.manager.spawnAndWait(parentSnapshot, ...)`.
|
|
116
|
-
|
|
117
|
-
```typescript
|
|
118
|
-
// agent-creation-wizard.ts — after
|
|
119
|
-
async function showGenerateWizard(
|
|
120
|
-
ui: MenuUI,
|
|
121
|
-
parentSnapshot: ParentSnapshot,
|
|
122
|
-
targetDir: string,
|
|
123
|
-
) {
|
|
124
|
-
// ...
|
|
125
|
-
const record = await deps.manager.spawnAndWait(
|
|
126
|
-
parentSnapshot, "general-purpose", generatePrompt, { ... },
|
|
127
|
-
);
|
|
128
|
-
}
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
The creation wizard no longer imports `ExtensionContext`.
|
|
132
|
-
|
|
133
|
-
### Dependency bag convention
|
|
134
|
-
|
|
135
|
-
Per `docs/architecture/architecture.md` § Dependency bag convention:
|
|
136
|
-
|
|
137
|
-
- **≤4 fields** → dissolve the interface, accept as plain parameters.
|
|
138
|
-
- **≥5 fields** → keep the interface but destructure in the function signature.
|
|
139
|
-
|
|
140
|
-
#### Dissolve (≤4 fields)
|
|
141
|
-
|
|
142
|
-
`AgentConfigEditorDeps` (4 fields: `fileOps`, `registry`, `personalAgentsDir`, `projectAgentsDir`) → plain parameters on `createAgentConfigEditor`.
|
|
143
|
-
|
|
144
|
-
`GetResultDeps` (4 fields: `getRecord`, `cancelNudge`, `getConversation`, `registry`) → plain parameters on `createGetResultTool`.
|
|
145
|
-
|
|
146
|
-
`SteerToolDeps` (4 fields: `getRecord`, `emitEvent`, `steerAgent`, `queueSteer`) → plain parameters on `createSteerTool`.
|
|
147
|
-
|
|
148
|
-
#### Keep + destructure (≥5 fields)
|
|
149
|
-
|
|
150
|
-
`AgentMenuDeps` (8 fields) — keep the interface, destructure in `createAgentsMenuHandler({ manager, registry, ... })`.
|
|
151
|
-
|
|
152
|
-
`AgentCreationWizardDeps` (5 fields) — keep the interface, destructure in `createAgentCreationWizard({ fileOps, manager, ... })`.
|
|
153
|
-
|
|
154
|
-
### Consumer call-site sketch (menu handler registration)
|
|
155
|
-
|
|
156
|
-
```typescript
|
|
157
|
-
// index.ts
|
|
158
|
-
pi.registerCommand('agents', {
|
|
159
|
-
description: 'Manage agents',
|
|
160
|
-
handler: async (_args, ctx) => {
|
|
161
|
-
await agentsMenuHandler({
|
|
162
|
-
ui: ctx.ui,
|
|
163
|
-
modelRegistry: ctx.modelRegistry,
|
|
164
|
-
parentSnapshot: buildParentSnapshot(ctx),
|
|
165
|
-
});
|
|
166
|
-
},
|
|
167
|
-
});
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
### Extracted module interaction sketch (agent-config-editor)
|
|
171
|
-
|
|
172
|
-
```typescript
|
|
173
|
-
// agent-config-editor.ts — after dissolving deps
|
|
174
|
-
export function createAgentConfigEditor(
|
|
175
|
-
fileOps: AgentFileOps,
|
|
176
|
-
registry: AgentTypeRegistry,
|
|
177
|
-
personalAgentsDir: string,
|
|
178
|
-
projectAgentsDir: string,
|
|
179
|
-
) {
|
|
180
|
-
// ... closures capture these directly; no deps.foo indirection
|
|
181
|
-
}
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
No Tell-Don't-Ask violations — each parameter is a primitive or injectable collaborator.
|
|
185
|
-
No output-argument mutations — pure closure capture.
|
|
186
|
-
|
|
187
|
-
## Module-Level Changes
|
|
188
|
-
|
|
189
|
-
### New file: none
|
|
190
|
-
|
|
191
|
-
All changes are modifications to existing files.
|
|
192
|
-
|
|
193
|
-
### Modified: `src/ui/agent-menu.ts`
|
|
194
|
-
|
|
195
|
-
- Add `MenuUI` interface export (the new narrow type).
|
|
196
|
-
- Import `ModelRegistry` from `model-resolver.js`.
|
|
197
|
-
- Remove `ExtensionContext` import.
|
|
198
|
-
- Change all inner function signatures from `(ctx: ExtensionContext)` to `(ui: MenuUI)`.
|
|
199
|
-
- Replace `ctx.ui.xxx(...)` → `ui.xxx(...)`.
|
|
200
|
-
- Replace `ctx.modelRegistry` → parameter `modelRegistry` threaded to `showAllAgentsList`.
|
|
201
|
-
- Change `AgentMenuDeps` usage: destructure in `createAgentsMenuHandler` signature.
|
|
202
|
-
- Change return type from `(ctx: ExtensionContext) => Promise<void>` to `(params: { ui: MenuUI; modelRegistry: ModelRegistry; parentSnapshot: ParentSnapshot }) => Promise<void>`.
|
|
203
|
-
- Thread `modelRegistry` from handler through `showAgentsMenu` → `showAllAgentsList`.
|
|
204
|
-
- Thread `parentSnapshot` from handler through `showAgentsMenu` → `wizard.showCreateWizard` → `showGenerateWizard`.
|
|
205
|
-
- Update `AgentMenuManager.spawnAndWait` to accept `ParentSnapshot` instead of `ExtensionContext`.
|
|
206
|
-
- Remove `Omit<AgentSpawnConfig, "isBackground">` in favor of plain inline type.
|
|
207
|
-
|
|
208
|
-
### Modified: `src/ui/agent-config-editor.ts`
|
|
209
|
-
|
|
210
|
-
- Remove `ExtensionContext` import.
|
|
211
|
-
- Add `MenuUI` import from `agent-menu.js`.
|
|
212
|
-
- Change all inner function signatures from `(ctx: ExtensionContext)` to `(ui: MenuUI)`.
|
|
213
|
-
- Replace `ctx.ui.xxx(...)` → `ui.xxx(...)`.
|
|
214
|
-
- Dissolve `AgentConfigEditorDeps`: replace single deps parameter with 4 plain parameters.
|
|
215
|
-
|
|
216
|
-
### Modified: `src/ui/agent-creation-wizard.ts`
|
|
217
|
-
|
|
218
|
-
- Remove `ExtensionContext` import.
|
|
219
|
-
- Add `MenuUI` import from `agent-menu.js`.
|
|
220
|
-
- Add `ParentSnapshot` import from `parent-snapshot.js`.
|
|
221
|
-
- Change all inner function signatures from `(ctx: ExtensionContext)` to `(ui: MenuUI)`.
|
|
222
|
-
- Replace `ctx.ui.xxx(...)` → `ui.xxx(...)`.
|
|
223
|
-
- Change `WizardManager.spawnAndWait` to accept `ParentSnapshot` instead of `ExtensionContext`.
|
|
224
|
-
- Thread `parentSnapshot` as a parameter from `showCreateWizard(ui, parentSnapshot)` → `showGenerateWizard(ui, parentSnapshot, targetDir)`.
|
|
225
|
-
- Destructure `AgentCreationWizardDeps` in signature.
|
|
226
|
-
|
|
227
|
-
### Modified: `src/tools/get-result-tool.ts`
|
|
228
|
-
|
|
229
|
-
- Dissolve `GetResultDeps`: replace single deps parameter with 4 plain parameters.
|
|
230
|
-
|
|
231
|
-
### Modified: `src/tools/steer-tool.ts`
|
|
232
|
-
|
|
233
|
-
- Dissolve `SteerToolDeps`: replace single deps parameter with 4 plain parameters.
|
|
234
|
-
|
|
235
|
-
### Modified: `src/index.ts`
|
|
236
|
-
|
|
237
|
-
- Update `createAgentConfigEditor` call: pass 4 plain args instead of `AgentConfigEditorDeps`.
|
|
238
|
-
- Update `createAgentCreationWizard` call: pass 4 plain args instead of `AgentCreationWizardDeps` (registry is the `WizardRegistry`, not the full `AgentTypeRegistry` — pass `{ reload: () => registry.reload() }`).
|
|
239
|
-
- Update `createGetResultTool` call: pass 4 plain args instead of `GetResultDeps`.
|
|
240
|
-
- Update `createSteerTool` call: pass 4 plain args instead of `SteerToolDeps`.
|
|
241
|
-
- Update `spawnAndWait` in menu handler deps: keep `ParentSnapshot` as first parameter.
|
|
242
|
-
- Update `/agents` command handler to destructure `ctx.ui`, `ctx.modelRegistry`, and `buildParentSnapshot(ctx)`.
|
|
243
|
-
|
|
244
|
-
### Modified: test files
|
|
245
|
-
|
|
246
|
-
- `test/ui/agent-menu.test.ts` — remove `ctx as any` casts; pass `{ ui: { ... }, modelRegistry: {}, parentSnapshot: {} }`.
|
|
247
|
-
- `test/ui/agent-config-editor.test.ts` — remove `ctx as any` casts; pass `MenuUI` objects directly.
|
|
248
|
-
- `test/ui/agent-creation-wizard.test.ts` — remove `ctx as any` casts; pass `MenuUI` and stub `ParentSnapshot`.
|
|
249
|
-
- `test/tools/get-result-tool.test.ts` — update `makeDeps` and `execute` helpers for dissolved parameters.
|
|
250
|
-
- `test/tools/steer-tool.test.ts` — update `makeDeps` and `execute` helpers for dissolved parameters.
|
|
251
|
-
|
|
252
|
-
### Unchanged
|
|
253
|
-
|
|
254
|
-
- `src/ui/conversation-viewer.ts` — unrelated; uses its own deps.
|
|
255
|
-
- `src/ui/agent-widget.ts` — already narrow (no `ExtensionContext`).
|
|
256
|
-
- `src/agent-manager.ts` — already accepts `ParentSnapshot` from #145.
|
|
257
|
-
- `src/parent-snapshot.ts` — unchanged.
|
|
258
|
-
|
|
259
|
-
## Test Impact Analysis
|
|
260
|
-
|
|
261
|
-
1. **New unit tests enabled:** None — this is a signature change, not an extraction.
|
|
262
|
-
The existing test coverage already exercises menu navigation, editing, creation, and tool operations.
|
|
263
|
-
|
|
264
|
-
2. **Existing tests that simplify:** All 42 `ctx as any` casts are removed from the three test files.
|
|
265
|
-
`makeCtx()` returns a plain `MenuUI`-shaped object (already structurally compatible).
|
|
266
|
-
The `makeCtx` helper in `agent-menu.test.ts` already returns the right shape — it just needs the cast removed and the handler-call interface updated.
|
|
267
|
-
|
|
268
|
-
3. **Tests that must stay:** All existing test assertions stay — only the method of constructing the handler input changes.
|
|
269
|
-
`get-result-tool.test.ts` and `steer-tool.test.ts` may need minor updates if the deps dissolve changes the factory call signature, but no assertion changes.
|
|
270
|
-
|
|
271
|
-
## TDD Order
|
|
272
|
-
|
|
273
|
-
Each step must leave `pnpm run check` green.
|
|
274
|
-
When a step changes a factory signature, it must also update the corresponding `index.ts` call site in the same commit.
|
|
275
|
-
|
|
276
|
-
1. **Refactor:** Define and export `MenuUI` interface in `agent-menu.ts`.
|
|
277
|
-
No other changes — just add the interface alongside the existing code.
|
|
278
|
-
Commit: `refactor: add MenuUI interface (#146)`
|
|
279
|
-
|
|
280
|
-
2. **Refactor:** Update `agent-config-editor.ts` — dissolve `AgentConfigEditorDeps` into 4 plain parameters; change `showAgentDetail(ctx)` to `showAgentDetail(ui: MenuUI)`; replace `ctx.ui.xxx` → `ui.xxx`.
|
|
281
|
-
Update `agent-config-editor.test.ts` — remove `ctx as any` casts, pass `MenuUI` objects directly.
|
|
282
|
-
Update `index.ts` — update `createAgentConfigEditor` call to pass 4 plain args.
|
|
283
|
-
Commit: `refactor: dissolve AgentConfigEditorDeps and narrow to MenuUI (#146)`
|
|
284
|
-
|
|
285
|
-
3. **Refactor:** Update `agent-creation-wizard.ts` — destructure `AgentCreationWizardDeps`; change `showCreateWizard(ctx)` to `showCreateWizard(ui: MenuUI, parentSnapshot: ParentSnapshot)`; thread `parentSnapshot` to `showGenerateWizard`; change `WizardManager.spawnAndWait` to accept `ParentSnapshot`; replace `ctx.ui.xxx` → `ui.xxx`.
|
|
286
|
-
Update `agent-creation-wizard.test.ts` — remove `ctx as any` casts, pass `MenuUI` and stub `ParentSnapshot`.
|
|
287
|
-
Update `index.ts` — update `createAgentCreationWizard` call for destructured params.
|
|
288
|
-
Commit: `refactor: narrow creation wizard to MenuUI and ParentSnapshot (#146)`
|
|
289
|
-
|
|
290
|
-
4. **Refactor:** Update `agent-menu.ts` — destructure `AgentMenuDeps`; change handler return type to accept `{ ui: MenuUI; modelRegistry: ModelRegistry; parentSnapshot: ParentSnapshot }`; thread `modelRegistry` to `showAllAgentsList`; thread `parentSnapshot` to `wizard.showCreateWizard`; update `AgentMenuManager.spawnAndWait` to accept `ParentSnapshot`; replace `ctx.ui.xxx` → `ui.xxx`.
|
|
291
|
-
Update `agent-menu.test.ts` — remove `ctx as any` casts, pass `{ ui, modelRegistry, parentSnapshot }`.
|
|
292
|
-
Update `index.ts` — update `/agents` handler to destructure `ctx.ui`, `ctx.modelRegistry`, and `buildParentSnapshot(ctx)`.
|
|
293
|
-
Commit: `refactor: narrow agent menu to MenuUI interface (#146)`
|
|
294
|
-
|
|
295
|
-
5. **Refactor:** Update `get-result-tool.ts` — dissolve `GetResultDeps` into 4 plain parameters.
|
|
296
|
-
Update `test/tools/get-result-tool.test.ts` — update `makeDeps` and `execute` helpers.
|
|
297
|
-
Update `index.ts` — update `createGetResultTool` call to pass 4 plain args.
|
|
298
|
-
Commit: `refactor: dissolve GetResultDeps into plain parameters (#146)`
|
|
299
|
-
|
|
300
|
-
6. **Refactor:** Update `steer-tool.ts` — dissolve `SteerToolDeps` into 4 plain parameters.
|
|
301
|
-
Update `test/tools/steer-tool.test.ts` — update `makeDeps` and `execute` helpers.
|
|
302
|
-
Update `index.ts` — update `createSteerTool` call to pass 4 plain args.
|
|
303
|
-
Commit: `refactor: dissolve SteerToolDeps into plain parameters (#146)`
|
|
304
|
-
|
|
305
|
-
7. **Verify:** Run full test suite (`pnpm vitest run`) and type check (`pnpm run check`).
|
|
306
|
-
Confirm zero `ctx as any` in the three menu test files.
|
|
307
|
-
Commit: none (verification only).
|
|
308
|
-
|
|
309
|
-
## Risks and Mitigations
|
|
310
|
-
|
|
311
|
-
| Risk | Mitigation |
|
|
312
|
-
| ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
313
|
-
| `ctx.ui.custom` signature mismatch between `MenuUI` and real `ExtensionContext.ui` | `MenuUI.custom` uses `any` for the component and options parameters since these are opaque TUI types internal to the SDK. This matches the existing usage where `ctx.ui.custom<undefined>(...)` passes a TUI component constructor. |
|
|
314
|
-
| `ParentSnapshot` threading through menu → wizard call chain | The handler receives `parentSnapshot` from `index.ts` and threads it through `showAgentsMenu` → `showCreateWizard` → `showGenerateWizard`. Only `showGenerateWizard` uses it; the other functions relay it. This is acceptable since the parameter follows the existing `targetDir` threading pattern already in the wizard. |
|
|
315
|
-
| Deps dissolution breaks `index.ts` type check mid-sequence | Each TDD step updates the factory, its test file, AND the `index.ts` call site together, keeping `pnpm run check` green after every commit. |
|
|
316
|
-
|
|
317
|
-
## Open Questions
|
|
318
|
-
|
|
319
|
-
- None — the design follows the architecture doc's Step N specification and the dependency (#145) is already implemented.
|