@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,195 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 442
|
|
3
|
-
issue_title: "pi-subagents: dissolve /agents and remove the conversation-viewer subtree"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Dissolve `/agents` and remove the conversation-viewer subtree
|
|
7
|
-
|
|
8
|
-
## Release Recommendation
|
|
9
|
-
|
|
10
|
-
**Release:** mid-batch — defer (batch "dissolve-agents"); confirm at ship time
|
|
11
|
-
|
|
12
|
-
This is Phase 19 Step 5, the first of the two deletion commits in release batch "dissolve-agents" (Steps 5–6).
|
|
13
|
-
The batch tail is Step 6 ([#441]); per the architecture roadmap's `Release batches` subsection the two ship together, and the operator has confirmed: do not release until both [#442] and [#441] have landed on `main`.
|
|
14
|
-
Hold the release-please PR open after this issue merges; the release is cut when [#441] (the tail) lands.
|
|
15
|
-
|
|
16
|
-
## Problem Statement
|
|
17
|
-
|
|
18
|
-
Phase 19 Steps 2–4 re-homed all four `/agents` menu responsibilities: settings moved to the `/subagents:settings` command, running-agent visibility moved to the background widget, and session viewing moved to native session navigation (`/subagents:sessions`).
|
|
19
|
-
With those replacements live, the `/agents` command and everything reachable only from `agent-menu.ts` is an orphaned subtree.
|
|
20
|
-
This issue performs the first of two terminal-cut deletions: dissolve the `/agents` command and delete the conversation-viewer subtree (`agent-menu.ts`, `conversation-viewer.ts`, `message-formatters.ts`, and their tests).
|
|
21
|
-
Deleting the hub `agent-menu.ts` wholesale — rather than surgically narrowing it once per option — is what orphans the definition-management leaves, so the hub must go first (it statically imports the wizard, editor, and file-ops, and dynamically imports the viewer).
|
|
22
|
-
|
|
23
|
-
## Goals
|
|
24
|
-
|
|
25
|
-
- Remove the `/agents` slash command and its menu hub (`agent-menu.ts`).
|
|
26
|
-
- Delete the conversation-viewer subtree: `conversation-viewer.ts` (the bespoke session overlay) and `message-formatters.ts` (its only consumer), plus all three tests.
|
|
27
|
-
- Dewire `index.ts`: drop the `registerCommand("agents", …)` block, the `AgentsMenuHandler` and `FsAgentFileOps` imports/construction, and the now-dead `join` and `buildParentSnapshot` imports.
|
|
28
|
-
- Keep `pnpm run check`, `pnpm run lint`, `pnpm run test`, and `pnpm fallow dead-code` green at every commit by breaking the hub↔leaf type cycle first (see Design Overview).
|
|
29
|
-
- Leave the agent-definition-management leaves (`agent-creation-wizard.ts`, `agent-config-editor.ts`, `agent-file-ops.ts`, `agent-file-writer.ts`) orphaned but compiling, for [#441] to `git rm`.
|
|
30
|
-
|
|
31
|
-
This change is **breaking**: removing the `/agents` command alters observable behavior on upgrade with no user edit.
|
|
32
|
-
The deletion commit uses `feat(pi-subagents)!:` with a `BREAKING CHANGE:` footer naming the replacements (`/subagents:settings`, `/subagents:sessions`, the background widget).
|
|
33
|
-
|
|
34
|
-
## Non-Goals
|
|
35
|
-
|
|
36
|
-
- Deleting the agent-definition-management subtree (`agent-creation-wizard.ts`, `agent-config-editor.ts`, `agent-file-ops.ts`, `agent-file-writer.ts`) and the transient `menu-ui.ts` — that is [#441] (Step 6), the batch tail.
|
|
37
|
-
- Consolidating residual test clone families — that is [#443] (Step 7), which runs after the cut.
|
|
38
|
-
- Cleaning up `test/helpers/ui-stubs.ts` (`makeFileOps`, `makeMenuManager`, `createTestSubagentConfig`) — its helpers still have surviving consumers (the wizard/editor tests) until [#441].
|
|
39
|
-
- The holistic architecture-doc refresh (health-metrics final numbers, the domain Mermaid diagram, the complexity tables, migrating Phase 19 to `docs/architecture/history/`) — deferred to the batch tail [#441] to avoid editing the same analytical tables twice, since they also reference files [#441] deletes.
|
|
40
|
-
|
|
41
|
-
## Background
|
|
42
|
-
|
|
43
|
-
Relevant modules and their current coupling:
|
|
44
|
-
|
|
45
|
-
- `src/ui/agent-menu.ts` (331 LOC) — the `AgentsMenuHandler` god-command; statically imports `AgentConfigEditor` and `AgentCreationWizard` (constructs them), and dynamically imports `ConversationViewer` in `viewAgentConversation`.
|
|
46
|
-
Defines three exported interfaces: `AgentMenuManager`, `AgentMenuSettings`, and `MenuUI`.
|
|
47
|
-
- `src/ui/conversation-viewer.ts` (241 LOC) — the bespoke scrollable session overlay; its only consumer is `agent-menu.ts`'s dynamic `import("./conversation-viewer")`.
|
|
48
|
-
- `src/ui/message-formatters.ts` (195 LOC) — pure per-message-type formatters; its only consumer is `ConversationViewer`.
|
|
49
|
-
- `src/index.ts` — registers the `/agents` command, constructs `AgentsMenuHandler` (wiring in `FsAgentFileOps` and the two agents dirs), and uses `join` + `buildParentSnapshot` only inside that block.
|
|
50
|
-
|
|
51
|
-
The hub↔leaf type cycle (the key constraint):
|
|
52
|
-
|
|
53
|
-
- `agent-menu.ts` value-imports the wizard and editor classes.
|
|
54
|
-
- `agent-creation-wizard.ts` and `agent-config-editor.ts` each `import type { MenuUI } from "#src/ui/agent-menu"` and use `MenuUI` as a parameter type throughout.
|
|
55
|
-
|
|
56
|
-
This is a bidirectional cycle: the hub imports the leaf classes; the leaves import the hub's `MenuUI` type.
|
|
57
|
-
Deleting either subtree first leaves the other half referencing a deleted module, so `tsc --noEmit` (which type-checks all of `src` + `test`) fails.
|
|
58
|
-
The issue's premise that the leaves become "pure orphans" once the hub is gone holds for *runtime* reachability but not at the *type* level — the `MenuUI` back-import keeps them coupled.
|
|
59
|
-
|
|
60
|
-
Constraints from AGENTS.md / package skill:
|
|
61
|
-
|
|
62
|
-
- Each commit must leave the repo in a valid state (`pnpm run check` green).
|
|
63
|
-
- This package builds public `.d.ts` bundles; none of the deleted modules are part of the public surface (`service.ts`, `layered-settings.ts`), so no `verify:public-types` impact.
|
|
64
|
-
- `MenuUI`, `AgentMenuManager`, `AgentMenuSettings` are internal — not exported from any package subpath.
|
|
65
|
-
|
|
66
|
-
## Design Overview
|
|
67
|
-
|
|
68
|
-
Resolve the cycle with a **tidy-first** preparatory move (per the operator's decision and the `code-design` skill's "preparatory refactoring"): relocate the `MenuUI` interface to its own surviving module before deleting the hub.
|
|
69
|
-
|
|
70
|
-
Only `MenuUI` needs to survive the cut — `AgentMenuManager` and `AgentMenuSettings` have no consumers outside the hub (verified) and die with it.
|
|
71
|
-
`MenuUI` is self-contained (its members reference only SDK-shaped primitives), so the extracted module carries no upstream-dependency baggage and introduces no Tell-Don't-Ask or output-argument smell.
|
|
72
|
-
|
|
73
|
-
New module `src/ui/menu-ui.ts`:
|
|
74
|
-
|
|
75
|
-
```typescript
|
|
76
|
-
/** Narrow UI interface — only the ctx.ui methods menu handlers actually call. */
|
|
77
|
-
export interface MenuUI {
|
|
78
|
-
select(title: string, options: string[]): Promise<string | undefined>;
|
|
79
|
-
confirm(title: string, message: string): Promise<boolean>;
|
|
80
|
-
input(title: string, defaultValue?: string): Promise<string | undefined>;
|
|
81
|
-
notify(message: string, level: "info" | "warning" | "error"): void;
|
|
82
|
-
editor(title: string, content: string): Promise<string | undefined>;
|
|
83
|
-
custom<R>(component: any, options?: any): Promise<R>;
|
|
84
|
-
}
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
Consumer call sites after the move (the leaves import the relocated type unchanged):
|
|
88
|
-
|
|
89
|
-
```typescript
|
|
90
|
-
// agent-creation-wizard.ts / agent-config-editor.ts
|
|
91
|
-
import type { MenuUI } from "#src/ui/menu-ui";
|
|
92
|
-
async showCreateWizard(ui: MenuUI, parentSnapshot: ParentSnapshot): Promise<void> { … }
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
`menu-ui.ts` is **transient**: after this issue it is imported only by the wizard and editor (both alive until [#441]), so it has live consumers and stays off the fallow dead-code list.
|
|
96
|
-
[#441] deletes the wizard, editor, and `menu-ui.ts` together, so the transient module never outlives its consumers.
|
|
97
|
-
|
|
98
|
-
Two-commit sequence within this issue:
|
|
99
|
-
|
|
100
|
-
1. `refactor(pi-subagents): extract MenuUI to its own module` — pure move; repoints the hub, wizard, and editor imports.
|
|
101
|
-
Green.
|
|
102
|
-
2. `feat(pi-subagents)!: dissolve /agents and remove the conversation-viewer subtree` — delete the three source files + three tests, dewire `index.ts`, update docs.
|
|
103
|
-
Green (wizard/editor now import `MenuUI` from the surviving `menu-ui.ts`; the hub is gone).
|
|
104
|
-
|
|
105
|
-
Edge cases / verifications already confirmed:
|
|
106
|
-
|
|
107
|
-
- `subagents-settings.ts` defines its own `SubagentsSettingsUI` interface — it does **not** import `MenuUI`, so the relocation does not touch the surviving settings command.
|
|
108
|
-
- `test/helpers/ui-stubs.ts`'s `makeMenuUI` is structurally typed and does **not** import the `MenuUI` type, so no test-helper repointing is needed.
|
|
109
|
-
- After dewiring, `join` (node:path) and `buildParentSnapshot` are used nowhere else in `index.ts` (verified) and their imports are removed; `getAgentDir`, `process.cwd`, `registry`, `settings`, and `manager` retain other live uses and stay.
|
|
110
|
-
- `FsAgentFileOps` becomes production-unused after the `index.ts` construction is removed, but `test/ui/agent-file-ops.test.ts` still imports it, so fallow (syntactic import analysis) keeps it off the dead-code list until [#441].
|
|
111
|
-
- Deleting the consumers does not orphan any local export: `formatDuration`/`getDisplayName`/`getModelLabelFromConfig` retain other consumers, and `wrapTextWithAnsi` is an external `@earendil-works/pi-tui` import.
|
|
112
|
-
|
|
113
|
-
## Module-Level Changes
|
|
114
|
-
|
|
115
|
-
Commit 1 — extract `MenuUI` (refactor):
|
|
116
|
-
|
|
117
|
-
- Add `src/ui/menu-ui.ts` — the `MenuUI` interface (moved verbatim from `agent-menu.ts`).
|
|
118
|
-
- `src/ui/agent-menu.ts` — remove the `MenuUI` interface definition; import `MenuUI` from `#src/ui/menu-ui`.
|
|
119
|
-
- `src/ui/agent-creation-wizard.ts` — change `import type { MenuUI } from "#src/ui/agent-menu"` to `from "#src/ui/menu-ui"`.
|
|
120
|
-
- `src/ui/agent-config-editor.ts` — same import repoint.
|
|
121
|
-
|
|
122
|
-
Commit 2 — dissolve `/agents` and delete the viewer subtree (feat!):
|
|
123
|
-
|
|
124
|
-
- Delete `src/ui/agent-menu.ts`, `src/ui/conversation-viewer.ts`, `src/ui/message-formatters.ts`.
|
|
125
|
-
- Delete `test/ui/agent-menu.test.ts`, `test/conversation-viewer.test.ts`, `test/message-formatters.test.ts`.
|
|
126
|
-
- `src/index.ts`:
|
|
127
|
-
- Remove the `import { FsAgentFileOps } from "#src/ui/agent-file-ops"` and `import { AgentsMenuHandler } from "#src/ui/agent-menu"` lines.
|
|
128
|
-
- Remove the now-dead `import { join } from "node:path"` and `import { buildParentSnapshot } from "#src/lifecycle/parent-snapshot"` lines.
|
|
129
|
-
- Remove the `// ---- /agents interactive menu ----` comment, the `agentsMenu` construction, and the `registerCommand("agents", …)` block.
|
|
130
|
-
- Remove the `/agents — Interactive agent management menu` line from the top-of-file `Commands:` doc comment.
|
|
131
|
-
- `packages/pi-subagents/docs/architecture/architecture.md` — update the current-state `ui/` file tree (remove the `agent-menu.ts`, `conversation-viewer.ts`, `message-formatters.ts` entries; add a `menu-ui.ts` entry), and annotate the Step 5 roadmap entry's `Outcome:` to record the actual approach (the `MenuUI` relocation prep; `index.ts` import-removal also drops `join`/`buildParentSnapshot`).
|
|
132
|
-
The structural-analysis tables, domain Mermaid diagram, and health-metrics numbers are deferred to the batch tail [#441] (see Non-Goals).
|
|
133
|
-
- `.pi/skills/package-pi-subagents/SKILL.md` — update the UI domain row: count `13` → `11`, and drop "conversation viewer, /agents menu" from the responsibility description (keep "creation wizard, config editor" — those survive until [#441]).
|
|
134
|
-
|
|
135
|
-
The Step 5 `Outcome:` line in `architecture.md` currently asserts "no edit to doomed files" and "`index.ts` edited once."
|
|
136
|
-
Both are now slightly inaccurate: the tidy-first prep repoints the doomed wizard/editor `MenuUI` import (one line each), and `index.ts` also sheds two now-dead imports.
|
|
137
|
-
The annotation should reflect this, not leave the stale claim.
|
|
138
|
-
|
|
139
|
-
## Test Impact Analysis
|
|
140
|
-
|
|
141
|
-
This is a deletion, not an extraction-for-testability, so no new unit tests are enabled.
|
|
142
|
-
|
|
143
|
-
1. New tests enabled: none.
|
|
144
|
-
2. Tests that become redundant / removed: `test/ui/agent-menu.test.ts`, `test/conversation-viewer.test.ts`, `test/message-formatters.test.ts` (the largest test function by LOC) — they exercise deleted production code and are deleted with it.
|
|
145
|
-
3. Tests that must stay as-is: the wizard/editor tests (`test/ui/agent-creation-wizard.test.ts`, `test/ui/agent-config-editor.test.ts`) keep compiling against the relocated `MenuUI` and survive until [#441]; `test/ui/subagents-settings.test.ts`, the session-navigation tests, and `test/ui/agent-widget.test.ts` pin the replacement surfaces and must stay green (see Invariants at risk).
|
|
146
|
-
|
|
147
|
-
## Invariants at risk
|
|
148
|
-
|
|
149
|
-
The cut removes surfaces whose responsibilities Steps 2–4 already re-homed.
|
|
150
|
-
Each replacement's invariant must remain green after this deletion:
|
|
151
|
-
|
|
152
|
-
- Settings management (Step 2, [#447]) → pinned by `test/ui/subagents-settings.test.ts`.
|
|
153
|
-
The `/subagents:settings` command and `SubagentsSettingsHandler` are untouched here.
|
|
154
|
-
- Running-agent visibility (Step 3, [#444]) → pinned by `test/ui/agent-widget.test.ts`.
|
|
155
|
-
The background widget is untouched.
|
|
156
|
-
- Session viewing (Step 4 / 4a, [#445]) → pinned by the session-navigation / session-navigator tests.
|
|
157
|
-
The `/subagents:sessions` command is untouched.
|
|
158
|
-
|
|
159
|
-
The deletion touches none of those files, so the full suite (minus the three deleted tests) staying green is the verification that no replacement regressed.
|
|
160
|
-
|
|
161
|
-
## Implementation Order
|
|
162
|
-
|
|
163
|
-
This issue has no red→green test cycles (a pure interface move plus deletions verified by the existing suite), so it is a build-style change — the next step is `/build-plan`, not `/tdd-plan`.
|
|
164
|
-
|
|
165
|
-
1. `refactor(pi-subagents): extract MenuUI to its own module`
|
|
166
|
-
- Add `src/ui/menu-ui.ts`; remove the interface from `agent-menu.ts` and import it; repoint the wizard and editor imports.
|
|
167
|
-
- Verify: `pnpm run check`, `pnpm run lint`, `pnpm run test`, `pnpm fallow dead-code` all green.
|
|
168
|
-
2. `feat(pi-subagents)!: dissolve /agents and remove the conversation-viewer subtree`
|
|
169
|
-
- Delete the three source files and three tests; dewire `index.ts`; update `architecture.md` file tree + Step 5 `Outcome:`; update `SKILL.md` UI row.
|
|
170
|
-
- `BREAKING CHANGE:` footer: the `/agents` command is removed; its responsibilities are served by `/subagents:settings` (configure concurrency/turn limits), `/subagents:sessions` (read-only transcript viewing), and the always-on background widget (running-agent visibility).
|
|
171
|
-
- Verify: `pnpm run check`, `pnpm run lint`, `pnpm run test`, `pnpm fallow dead-code` green; confirm `/agents` no longer registers and `menu-ui.ts` retains its wizard/editor consumers.
|
|
172
|
-
|
|
173
|
-
## Risks and Mitigations
|
|
174
|
-
|
|
175
|
-
- Risk: deleting the hub before the leaves breaks `tsc` via the `MenuUI` back-import.
|
|
176
|
-
Mitigation: the tidy-first Commit 1 relocates `MenuUI` to a surviving module so Commit 2 compiles; verified that only the wizard and editor consume `MenuUI` and that `subagents-settings.ts` and `ui-stubs.ts` do not.
|
|
177
|
-
- Risk: `FsAgentFileOps` becomes production-unused and trips `fallow dead-code`.
|
|
178
|
-
Mitigation: verified `test/ui/agent-file-ops.test.ts` still imports it; fallow's syntactic import analysis keeps it live until [#441].
|
|
179
|
-
Run `pnpm fallow dead-code` after Commit 2 to confirm.
|
|
180
|
-
- Risk: the transient `menu-ui.ts` looks like speculative indirection.
|
|
181
|
-
Mitigation: it is short-lived by design (one issue), has two live consumers immediately, and is deleted by the batch tail [#441]; the alternative (inlining a throwaway type into doomed files, or merging [#441] into [#442]) was considered and rejected via the operator decision.
|
|
182
|
-
- Risk: stale architecture docs mid-batch (the domain diagram and tables still show the deleted modules between [#442] and [#441]).
|
|
183
|
-
Mitigation: accepted deliberately — the analytical-table refresh is batched into the tail [#441] to avoid double-editing tables that [#441] also touches; the current-state file tree and SKILL.md count are kept accurate at each commit.
|
|
184
|
-
|
|
185
|
-
## Open Questions
|
|
186
|
-
|
|
187
|
-
None.
|
|
188
|
-
The hub↔leaf type-cycle resolution (relocate `MenuUI`, keep two commits) and the release-timing (defer until [#441] lands) were settled with the operator during planning.
|
|
189
|
-
|
|
190
|
-
[#441]: https://github.com/gotgenes/pi-packages/issues/441
|
|
191
|
-
[#442]: https://github.com/gotgenes/pi-packages/issues/442
|
|
192
|
-
[#443]: https://github.com/gotgenes/pi-packages/issues/443
|
|
193
|
-
[#444]: https://github.com/gotgenes/pi-packages/issues/444
|
|
194
|
-
[#445]: https://github.com/gotgenes/pi-packages/issues/445
|
|
195
|
-
[#447]: https://github.com/gotgenes/pi-packages/issues/447
|
|
@@ -1,268 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 443
|
|
3
|
-
issue_title: "pi-subagents: consolidate remaining test clone families"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Consolidate remaining test clone families
|
|
7
|
-
|
|
8
|
-
## Release Recommendation
|
|
9
|
-
|
|
10
|
-
**Release:** ship independently
|
|
11
|
-
|
|
12
|
-
This is Phase 19 Step 7 (Track C — test health), tagged `Release: independent` in the architecture roadmap.
|
|
13
|
-
It depends only on the terminal cut (Steps 5–6, [#441] / [#442], both closed) having landed, which it has.
|
|
14
|
-
No other roadmap step is gated on it, so it ships on its own.
|
|
15
|
-
|
|
16
|
-
## Problem Statement
|
|
17
|
-
|
|
18
|
-
`fallow dupes` reports test clone families in `pi-subagents`.
|
|
19
|
-
The issue (written at the Phase 18 end) named five files and a "≤ 10 clone groups (from 16)" target, on the premise that each clone is an extractable shared fixture.
|
|
20
|
-
|
|
21
|
-
Re-running fallow against current `main` (after the terminal cut shifted line numbers and the Phase-19 UI surfaces added new test files) shows the live picture differs from the issue's snapshot.
|
|
22
|
-
There are **16** `pi-subagents` test clone families today, but they split into two kinds:
|
|
23
|
-
|
|
24
|
-
1. Genuine *arrange / fixture / helper* duplication — safe to extract.
|
|
25
|
-
2. The repeated *system-under-test call* (`resolveSpawnConfig`, `assembleSessionConfig`, `schedule`) — which the `testing` skill explicitly says **not** to wrap in a helper just to clear a duplication metric, because the repeated act *is* the test subject.
|
|
26
|
-
|
|
27
|
-
Several of the issue's five named targets fall into category 2.
|
|
28
|
-
The operator confirmed (planning `ask_user`) a **guardrail-first** approach over the **full live set** of clones: extract only genuine fixtures, leave act-clones in place and documented, and address the new Phase-19 UI clones the issue never anticipated.
|
|
29
|
-
|
|
30
|
-
## Goals
|
|
31
|
-
|
|
32
|
-
- Extract genuine (non-act) test duplication into shared or hoisted helpers, following the package's `test/helpers/*.ts` convention.
|
|
33
|
-
- Clear the clone families that are legitimately arrange/fixture/result-extraction boilerplate.
|
|
34
|
-
- Keep the full suite green at every step — the existing tests are the safety net for their own refactor.
|
|
35
|
-
- Reach the issue's `≤ 10` clone-group target *honestly*, without wrapping any system-under-test call.
|
|
36
|
-
- Document the residual act-clones as intentional in the plan, so a future fallow pass does not re-flag them as oversight.
|
|
37
|
-
|
|
38
|
-
## Non-Goals
|
|
39
|
-
|
|
40
|
-
- Do **not** wrap or extract the repeated system-under-test call to clear a clone metric (the `testing`-skill guardrail).
|
|
41
|
-
These act-clones are left in place by design:
|
|
42
|
-
- `test/tools/spawn-config.test.ts` — repeated `resolveSpawnConfig(...)` calls (`dup:9b42a569`, `dup:ef875c08`).
|
|
43
|
-
- `test/session/session-config.test.ts` — repeated `assembleSessionConfig(...)` calls (`dup:539a8ca2`).
|
|
44
|
-
- `test/lifecycle/concurrency-limiter.test.ts` — repeated `schedule(...)` sequences (`dup:ff841f05`).
|
|
45
|
-
- `test/lifecycle/subagent-manager.test.ts` — `spawnBg` + `await promise` act blocks (`dup:29158516`, `dup:082c007e`).
|
|
46
|
-
- `test/lifecycle/subagent.test.ts` — `agent.run()` act block (`dup:a3814745`).
|
|
47
|
-
- `test/tools/get-result-tool.test.ts` — `execute(...)` act block (`dup:230828a8`, 5 lines, marginal).
|
|
48
|
-
- No production-source changes — this is test-only.
|
|
49
|
-
- No change to test *assertions* or behavior coverage; only the arrange/setup ceremony is consolidated.
|
|
50
|
-
- No new fallow rule or config change.
|
|
51
|
-
|
|
52
|
-
## Background
|
|
53
|
-
|
|
54
|
-
- Phase 19 Step 7 in `packages/pi-subagents/docs/architecture/architecture.md` ([#443]) — the roadmap entry, `Release: independent`.
|
|
55
|
-
- The terminal cut ([#441], [#442]) removed `agent-menu.ts`, the conversation viewer, and the definition-management subtree, deleting ~4 of the Phase-18 clone groups automatically and shifting the line numbers in the issue's target list.
|
|
56
|
-
- The Phase-19 replacement surfaces added new test files the issue could not have named: `test/ui/session-navigation.test.ts` and `test/ui/session-navigator.test.ts` ([#445], [#462], [#463]), which carry the largest genuine clone (an identical `makeNavigable` factory duplicated across both files).
|
|
57
|
-
- Shared-fixture convention: `test/helpers/<name>.ts` exporting named helpers, imported via the `#test/helpers/<name>` path alias, each with a companion `<name>.test.ts` (e.g. `make-subagent.ts` + `make-subagent.test.ts`).
|
|
58
|
-
- The `testing` skill rule that drives the guardrail: "Do not wrap the system-under-test call in a helper to eliminate a duplication-metric clone — the repeated act is the test subject, not duplication to remove."
|
|
59
|
-
|
|
60
|
-
## Design Overview
|
|
61
|
-
|
|
62
|
-
### Clone classification (live fallow output vs. issue)
|
|
63
|
-
|
|
64
|
-
| Fingerprint | Location | Kind | Disposition |
|
|
65
|
-
| -------------- | ----------------------------------------------------------------------------- | ---------------------------------------------- | --------------------------- |
|
|
66
|
-
| `dup:1d5dc276` | `ui/agent-widget.test.ts` :229 / :292 | duplicated `makeWidget` helper | **Extract** (hoist) |
|
|
67
|
-
| `dup:e29e4749` | `ui/session-navigation.test.ts` :23 / `ui/session-navigator.test.ts` :47 | duplicated `makeNavigable` factory (identical) | **Extract** (shared helper) |
|
|
68
|
-
| `dup:6268a42f` | `ui/session-navigator.test.ts` :201 / :229 | captured-overlay invocation boilerplate | **Extract** (local helper) |
|
|
69
|
-
| `dup:ea0a1bce` | `ui/session-navigator.test.ts` :220 / :243 | captured-overlay invocation boilerplate | **Extract** (local helper) |
|
|
70
|
-
| `dup:b0d55079` | `lifecycle/subagent-manager.test.ts` :92 / :109 | `resultConsumed`-observer arrange | **Extract** (local helper) |
|
|
71
|
-
| `dup:080c5017` | `lifecycle/subagent.test.ts` :257 / :273 | "ready subagent" arrange | **Extract** (local helper) |
|
|
72
|
-
| `dup:5d8dbd48` | `lifecycle/subagent-manager.test.ts` :376 / `lifecycle/subagent.test.ts` :717 | resume-events mock body (cross-file) | **Extract** (shared helper) |
|
|
73
|
-
| `dup:f4c08c00` | `lifecycle/workspace-bracket.test.ts` :90 / :97 | prepared-bracket arrange | **Extract** (local helper) |
|
|
74
|
-
| `dup:9b42a569` | `tools/spawn-config.test.ts` :43 / :56 | `resolveSpawnConfig` act | Leave (Non-Goal) |
|
|
75
|
-
| `dup:ef875c08` | `tools/spawn-config.test.ts` :81 / :95 | `resolveSpawnConfig` act | Leave (Non-Goal) |
|
|
76
|
-
| `dup:539a8ca2` | `session/session-config.test.ts` :131 / :151 | `assembleSessionConfig` act | Leave (Non-Goal) |
|
|
77
|
-
| `dup:ff841f05` | `lifecycle/concurrency-limiter.test.ts` :21 / :148 | `schedule` act | Leave (Non-Goal) |
|
|
78
|
-
| `dup:29158516` | `lifecycle/subagent-manager.test.ts` :335 / :383 | `spawnBg` + await act | Leave (Non-Goal) |
|
|
79
|
-
| `dup:082c007e` | `lifecycle/subagent-manager.test.ts` :410 / :422 | `spawnBg` + await act | Leave (Non-Goal) |
|
|
80
|
-
| `dup:a3814745` | `lifecycle/subagent.test.ts` :504 / :533 | `agent.run()` act | Leave (Non-Goal) |
|
|
81
|
-
| `dup:230828a8` | `tools/get-result-tool.test.ts` :81 / :89 | `execute` act (5 lines) | Leave (Non-Goal) |
|
|
82
|
-
|
|
83
|
-
Extracting the eight **Extract** families clears those fingerprints and drops the count from 16 to **8** — below the issue's `≤ 10` target — with no act-clone wrapped. (The four primary UI/lifecycle extractions alone reach 10; the cross-file and workspace-bracket arrange extractions take it to 8.)
|
|
84
|
-
|
|
85
|
-
### Shared-helper extractions (cross-file → `test/helpers/`)
|
|
86
|
-
|
|
87
|
-
Two clones span two files each, so their helpers must live in `test/helpers/` (the package convention for shared fixtures, with a companion test):
|
|
88
|
-
|
|
89
|
-
`test/helpers/make-navigable.ts`:
|
|
90
|
-
|
|
91
|
-
```typescript
|
|
92
|
-
import type { NavigableSubagent } from "#src/ui/session-navigation";
|
|
93
|
-
|
|
94
|
-
export function makeNavigable(overrides: Partial<NavigableSubagent> = {}): NavigableSubagent {
|
|
95
|
-
return {
|
|
96
|
-
id: "agent-1",
|
|
97
|
-
type: "general-purpose",
|
|
98
|
-
description: "Test task",
|
|
99
|
-
status: "completed",
|
|
100
|
-
startedAt: 1000,
|
|
101
|
-
completedAt: 4000,
|
|
102
|
-
toolUses: 2,
|
|
103
|
-
activeTools: new Map(),
|
|
104
|
-
responseText: "",
|
|
105
|
-
agentMessages: [],
|
|
106
|
-
isSessionReady: () => true,
|
|
107
|
-
subscribeToUpdates: vi.fn(() => () => {}),
|
|
108
|
-
getToolDefinition: vi.fn(() => undefined),
|
|
109
|
-
...overrides,
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
The two source copies are byte-identical (verified with `diff`), so this is a pure lift with no reconciliation.
|
|
115
|
-
Both call sites import it: `import { makeNavigable } from "#test/helpers/make-navigable";`.
|
|
116
|
-
|
|
117
|
-
`test/helpers/mock-session.ts` (extend the existing helper) — add a resume-events emitter for `dup:5d8dbd48`:
|
|
118
|
-
|
|
119
|
-
```typescript
|
|
120
|
-
export function emitResumeUsageAndCompaction(session: MockSession): void {
|
|
121
|
-
session.emit({ type: "message_end", message: { role: "assistant", usage: { input: 70, output: 30, cacheWrite: 5 } } });
|
|
122
|
-
session.emit({ type: "compaction_end", aborted: false, result: { tokensBefore: 999 }, reason: "overflow" });
|
|
123
|
-
}
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
Both `subagent-manager.test.ts` and `subagent.test.ts` set this inside a `mockImplementation(async () => { …; return "second"; })`, so the helper emits the events and each call site keeps its own `mockImplementation` wrapper and `return`. (Adding to the already-shared `mock-session.ts` avoids a one-function new module; its companion `mock-session.test.ts` gains a case.)
|
|
127
|
-
|
|
128
|
-
### Local-helper extractions (single-file)
|
|
129
|
-
|
|
130
|
-
These stay file-local (the convention reserves `test/helpers/` for cross-file sharing); each is a `function` declared once at the top of its `describe`/module and called from each test, with the **act left explicit** in every test:
|
|
131
|
-
|
|
132
|
-
- `ui/agent-widget.test.ts` — the `makeWidget(agents)` helper is currently declared *twice* (one per `describe`).
|
|
133
|
-
Hoist a single copy to module scope (above the first `describe`) and delete the second.
|
|
134
|
-
The second `describe` uses `vi.useFakeTimers()` in `beforeEach`, but `makeWidget` does not touch timers, so a module-scope definition serves both.
|
|
135
|
-
- `ui/session-navigator.test.ts` — extract a `renderCapturedOverlay(ui): string[]` helper that performs the repeated `const factory = ui.custom.mock.calls[0][0] as (…) => Component; return factory(mockTui(), ansiTheme(), undefined, vi.fn()).render(80);`.
|
|
136
|
-
This is *result extraction* (reading what the SUT produced), not the act (`new SessionNavigatorHandler().handle(…)` stays explicit in each test).
|
|
137
|
-
The `#423` reactive-consumer invariant assertion (`expect(record.getToolDefinition).not.toHaveBeenCalled()`) lives in the test body, untouched by the helper.
|
|
138
|
-
- `lifecycle/subagent-manager.test.ts` — extract a local `seedResultConsumedObserver()` returning `{ manager, record, seenConsumed: () => boolean | undefined }` for the two Bug-1 tests; the act (`markConsumed()` before/after `await record.promise`) stays in each test.
|
|
139
|
-
- `lifecycle/subagent.test.ts` — extract a local `makeReadySubagent()` returning `{ agent }` (build `makeSubagent()`, push a message onto a `createMockSession()`, wire `createSubagentSessionStub`/`toSubagentSession`); the act (reading `agent.messages` vs `agent.agentMessages`) stays in each test.
|
|
140
|
-
- `lifecycle/workspace-bracket.test.ts` — extract a local `preparedBracket(addendum?)` async helper that builds the workspace, constructs the `WorkspaceBracket`, and awaits `prepare(ctx)`, returning the bracket; the act (`bracket.dispose(outcome)`) stays in each test.
|
|
141
|
-
|
|
142
|
-
### Guardrail rationale (why the act-clones stay)
|
|
143
|
-
|
|
144
|
-
`spawn-config.test.ts` already extracts its arrange (`makeModelInfo`, `testRegistry`, `defaultSettings`); the only remaining duplication is the four-argument `resolveSpawnConfig(...)` call — the SUT.
|
|
145
|
-
`session-config.test.ts`'s clone is the six-argument `assembleSessionConfig(...)` SUT call.
|
|
146
|
-
`concurrency-limiter.test.ts`'s clone is the `schedule(...)` act sequence.
|
|
147
|
-
Wrapping any of these would hide the test subject behind a helper, exactly the anti-pattern the `testing` skill names.
|
|
148
|
-
They are recorded in Non-Goals so a later fallow pass reads them as deliberate.
|
|
149
|
-
|
|
150
|
-
### Design-review check
|
|
151
|
-
|
|
152
|
-
The `design-review` checklist (dependency width, Law of Demeter, output arguments, shared-interface changes) targets production wiring.
|
|
153
|
-
This change touches only test arrange code and introduces no production collaborator or shared-interface change, so the checklist finds nothing applicable.
|
|
154
|
-
The new `makeNavigable` helper follows ISP — it returns a full `NavigableSubagent` because both consumers (`listNavigableAgents` fixtures and `SessionNavigatorHandler` records) need the whole shape; there is no unused-field smell.
|
|
155
|
-
|
|
156
|
-
## Module-Level Changes
|
|
157
|
-
|
|
158
|
-
New files:
|
|
159
|
-
|
|
160
|
-
- `packages/pi-subagents/test/helpers/make-navigable.ts` — shared `makeNavigable` factory.
|
|
161
|
-
- `packages/pi-subagents/test/helpers/make-navigable.test.ts` — companion test (per convention).
|
|
162
|
-
|
|
163
|
-
Changed files:
|
|
164
|
-
|
|
165
|
-
- `packages/pi-subagents/test/helpers/mock-session.ts` — add `emitResumeUsageAndCompaction(session)`.
|
|
166
|
-
- `packages/pi-subagents/test/helpers/mock-session.test.ts` — add a case for the new emitter.
|
|
167
|
-
- `packages/pi-subagents/test/ui/session-navigation.test.ts` — delete local `makeNavigable`, import the shared one.
|
|
168
|
-
- `packages/pi-subagents/test/ui/session-navigator.test.ts` — delete local `makeNavigable`, import the shared one; add `renderCapturedOverlay` local helper and migrate its two clone sites.
|
|
169
|
-
- `packages/pi-subagents/test/ui/agent-widget.test.ts` — hoist `makeWidget` to a single module-scope definition; delete the duplicate.
|
|
170
|
-
- `packages/pi-subagents/test/lifecycle/subagent-manager.test.ts` — add `seedResultConsumedObserver` local helper (migrate `:92`/`:109`); migrate the `dup:5d8dbd48` resume-mock site to `emitResumeUsageAndCompaction`.
|
|
171
|
-
- `packages/pi-subagents/test/lifecycle/subagent.test.ts` — add `makeReadySubagent` local helper (migrate `:257`/`:273`); migrate the `dup:5d8dbd48` resume-mock site to `emitResumeUsageAndCompaction`.
|
|
172
|
-
- `packages/pi-subagents/test/lifecycle/workspace-bracket.test.ts` — add `preparedBracket` local helper; migrate the four construct-and-prepare sites.
|
|
173
|
-
|
|
174
|
-
Documentation:
|
|
175
|
-
|
|
176
|
-
- `packages/pi-subagents/docs/architecture/architecture.md` — Phase 19 Step 7 currently states "Outcome: test clone groups ≤ 10 (from 16); `subagent-manager.test.ts` uses shared factory helpers."
|
|
177
|
-
Update the Outcome to record the achieved count (8) and that the residual six families are intentional act-clones (left per the `testing` guardrail), so the roadmap and fallow stay reconciled.
|
|
178
|
-
No layout/complexity table references these test files, so no other architecture edit is needed.
|
|
179
|
-
- No `package-pi-subagents` SKILL.md reference to these helpers or counts — grep confirms no doc symbol to update beyond the architecture Outcome line.
|
|
180
|
-
|
|
181
|
-
## Test Impact Analysis
|
|
182
|
-
|
|
183
|
-
1. **New lower-level tests enabled.**
|
|
184
|
-
`make-navigable.test.ts` and the new `mock-session.test.ts` case pin the shared helpers' default shapes directly — previously each consumer test re-encoded the defaults inline.
|
|
185
|
-
These are the only genuinely new tests; the rest is arrange consolidation.
|
|
186
|
-
2. **Tests made redundant.**
|
|
187
|
-
None are removed.
|
|
188
|
-
The behavior assertions in every migrated test stay exactly as-is; only their arrange/setup lines collapse into a helper call.
|
|
189
|
-
The local copies of `makeNavigable`/`makeWidget` are deleted (duplication removed), not their tests.
|
|
190
|
-
3. **Tests that must stay as-is.**
|
|
191
|
-
All act-clone tests (Non-Goals list) keep their explicit SUT call.
|
|
192
|
-
The `session-navigator.test.ts` `#423` reactive-consumer assertions stay in the test body; `renderCapturedOverlay` only factors out the overlay-rendering boilerplate, not the assertions.
|
|
193
|
-
|
|
194
|
-
## Invariants at risk
|
|
195
|
-
|
|
196
|
-
- **`#423` reactive-consumer invariant** (`SessionNavigatorHandler` sources the transcript and never reads tool definitions off the record): pinned by `expect(record.getToolDefinition).not.toHaveBeenCalled()` in `session-navigator.test.ts`.
|
|
197
|
-
The `renderCapturedOverlay` extraction must leave that assertion in the test body, not absorb it.
|
|
198
|
-
- **Resume usage/compaction accumulation** (`#420`/`#421`/Phase 17 observer lifecycle): pinned by the resume tests in both `subagent-manager.test.ts` and `subagent.test.ts`.
|
|
199
|
-
`emitResumeUsageAndCompaction` must emit the identical event payloads (`input:70 output:30 cacheWrite:5`, `tokensBefore:999`, `reason:"overflow"`); the migrated tests assert on these exact numbers, so a value drift would surface as a red test in the same step.
|
|
200
|
-
- **Widget background-only filter** (`#444`/`#423`): the hoisted `makeWidget` must keep the `runInBackground: true` default merge (`{ invocation: { runInBackground: true }, ...a }`) — both `describe` copies already share it, so the hoist preserves it verbatim.
|
|
201
|
-
|
|
202
|
-
Each invariant is already covered by an existing assertion; no new pinning test is required beyond the helper companion tests.
|
|
203
|
-
|
|
204
|
-
## TDD Order
|
|
205
|
-
|
|
206
|
-
This is a test-only refactor: there is no new product behavior, so the "green" gate at each step is the **existing suite staying green** after the arrange is consolidated.
|
|
207
|
-
Each step is independently committable and leaves the suite green.
|
|
208
|
-
Run the affected file(s) with `pnpm --filter @gotgenes/pi-subagents exec vitest run <path>` and the full suite before the final commit (shared `test/helpers` changes touch multiple files).
|
|
209
|
-
|
|
210
|
-
1. **Shared `makeNavigable` fixture.**
|
|
211
|
-
Add `test/helpers/make-navigable.ts` and `make-navigable.test.ts` (companion: assert default shape + an override).
|
|
212
|
-
Delete the two local copies in `session-navigation.test.ts` / `session-navigator.test.ts` and import from `#test/helpers/make-navigable`.
|
|
213
|
-
Run both UI files green.
|
|
214
|
-
Commit: `test(pi-subagents): extract shared makeNavigable test fixture`.
|
|
215
|
-
2. **`agent-widget` makeWidget hoist.**
|
|
216
|
-
Hoist one `makeWidget` to module scope; delete the duplicate in the second `describe`.
|
|
217
|
-
Run `agent-widget.test.ts` green.
|
|
218
|
-
Commit: `test(pi-subagents): hoist duplicated makeWidget helper`.
|
|
219
|
-
3. **`session-navigator` captured-overlay helper.**
|
|
220
|
-
Add `renderCapturedOverlay(ui)` and migrate the two clone sites (`dup:6268a42f`, `dup:ea0a1bce`), keeping the `#423` assertions inline.
|
|
221
|
-
Run `session-navigator.test.ts` green.
|
|
222
|
-
Commit: `test(pi-subagents): extract captured-overlay render helper`.
|
|
223
|
-
4. **`subagent-manager` resultConsumed arrange + resume-events emitter.**
|
|
224
|
-
Add `emitResumeUsageAndCompaction` to `mock-session.ts` (+ companion case).
|
|
225
|
-
Add local `seedResultConsumedObserver` and migrate `:92`/`:109`.
|
|
226
|
-
Migrate the resume-mock site (`dup:5d8dbd48` manager half) to the emitter.
|
|
227
|
-
Run `subagent-manager.test.ts` + `mock-session.test.ts` green.
|
|
228
|
-
Commit: `test(pi-subagents): consolidate subagent-manager arrange helpers`.
|
|
229
|
-
5. **`subagent` ready-subagent arrange + resume-events emitter.**
|
|
230
|
-
Add local `makeReadySubagent` and migrate `:257`/`:273`.
|
|
231
|
-
Migrate the resume-mock site (`dup:5d8dbd48` subagent half) to `emitResumeUsageAndCompaction`.
|
|
232
|
-
Run `subagent.test.ts` green (this clears the cross-file `dup:5d8dbd48` once both halves use the emitter).
|
|
233
|
-
Commit: `test(pi-subagents): consolidate subagent ready-state arrange`.
|
|
234
|
-
6. **`workspace-bracket` prepared-bracket arrange.**
|
|
235
|
-
Add local `preparedBracket(addendum?)` and migrate the four construct-and-prepare sites.
|
|
236
|
-
Run `workspace-bracket.test.ts` green.
|
|
237
|
-
Commit: `test(pi-subagents): extract preparedBracket setup helper`.
|
|
238
|
-
7. **Verify + document.**
|
|
239
|
-
Run the full suite, `pnpm run check`, `pnpm run lint`, and `pnpm fallow dupes --workspace @gotgenes/pi-subagents` to confirm the eight target fingerprints are gone and the count is ≤ 10.
|
|
240
|
-
Update the Phase 19 Step 7 Outcome line in `architecture.md` to the achieved count and the intentional-residual note.
|
|
241
|
-
Commit: `docs(pi-subagents): reconcile Phase 19 Step 7 outcome with achieved clone count`.
|
|
242
|
-
|
|
243
|
-
## Risks and Mitigations
|
|
244
|
-
|
|
245
|
-
- **Risk: hoisting `makeWidget` past the fake-timers `beforeEach` changes timing.**
|
|
246
|
-
Mitigation: `makeWidget` constructs objects only (no timer calls); the `vi.useFakeTimers()` lives in the second `describe`'s `beforeEach`, unaffected by where the helper is declared.
|
|
247
|
-
Step 2 runs the file green to confirm.
|
|
248
|
-
- **Risk: the resume-events emitter drifts from one of the two call sites' expected numbers.**
|
|
249
|
-
Mitigation: both sites currently use identical payloads (verified); the migrated tests assert the exact numbers, so any drift fails red in steps 4–5.
|
|
250
|
-
- **Risk: a `test/helpers` change silently breaks an unrelated importer.**
|
|
251
|
-
Mitigation: `mock-session.ts` is widely imported; the change is purely additive (new export), and step 4 runs the full suite.
|
|
252
|
-
- **Risk: orphaned imports after deleting local helpers (Biome `noUnusedImports` is warning-level).**
|
|
253
|
-
Mitigation: after each deletion, re-check the file's imports (e.g. `vi` may still be used elsewhere; `NavigableSubagent` import in the UI files is type-only and still referenced).
|
|
254
|
-
The step 7 `pnpm run lint` is the backstop.
|
|
255
|
-
- **Risk: fallow re-flags the intentional act-clones in a future audit.**
|
|
256
|
-
Mitigation: the Non-Goals list and the architecture Outcome note record them as deliberate.
|
|
257
|
-
|
|
258
|
-
## Open Questions
|
|
259
|
-
|
|
260
|
-
- None.
|
|
261
|
-
The guardrail-first / full-live-set scope was settled via the planning `ask_user`; no follow-up issue is warranted because the residual act-clones are intentional, not deferred work.
|
|
262
|
-
|
|
263
|
-
[#441]: https://github.com/gotgenes/pi-packages/issues/441
|
|
264
|
-
[#442]: https://github.com/gotgenes/pi-packages/issues/442
|
|
265
|
-
[#443]: https://github.com/gotgenes/pi-packages/issues/443
|
|
266
|
-
[#445]: https://github.com/gotgenes/pi-packages/issues/445
|
|
267
|
-
[#462]: https://github.com/gotgenes/pi-packages/issues/462
|
|
268
|
-
[#463]: https://github.com/gotgenes/pi-packages/issues/463
|
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 444
|
|
3
|
-
issue_title: "pi-subagents: shrink the agent widget to background runs only"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Shrink the agent widget to background runs only
|
|
7
|
-
|
|
8
|
-
## Release Recommendation
|
|
9
|
-
|
|
10
|
-
**Release:** ship independently
|
|
11
|
-
|
|
12
|
-
Phase 19 Step 3 ([architecture roadmap][arch]) is tagged `Release: independent` — it is not a member of any release batch.
|
|
13
|
-
The change is self-contained to `agent-widget.ts` and its tests, touches no public surface, and ADR-0004 explicitly notes it is "independent of the spike."
|
|
14
|
-
|
|
15
|
-
## Problem Statement
|
|
16
|
-
|
|
17
|
-
The above-editor agent widget currently renders every agent — foreground and background alike.
|
|
18
|
-
For foreground runs the `subagent` tool's inline `onUpdate` stream already renders live progress, so the widget duplicates that display (ADR-0004 Decision A).
|
|
19
|
-
The widget should survive only as the **background-agent status surface**: the one place with no inline tool-call display, which must represent N parallel background agents at once.
|
|
20
|
-
|
|
21
|
-
There is also a latent inconsistency to fix.
|
|
22
|
-
`AgentWidget` calls `manager.listAgents()` at two sites — `update()` (which feeds `seedFinishedAgents`, `assembleWidgetState`, and `clearWidget`) and `renderWidget()` (the tree map).
|
|
23
|
-
Filtering at only one site would leave the other rendering foreground agents.
|
|
24
|
-
|
|
25
|
-
## Goals
|
|
26
|
-
|
|
27
|
-
- The widget shows only background agents (`record.invocation?.runInBackground === true`); foreground agents never appear.
|
|
28
|
-
- Both `listAgents()` call sites are funneled through a single private accessor that applies the background predicate once at the source.
|
|
29
|
-
- The foreground/widget duplication called out by ADR-0004 Decision A is eliminated.
|
|
30
|
-
- This is a UI behavior refinement, not a public-API or config change — it is **non-breaking** (no exported surface, default, or config shape changes on upgrade).
|
|
31
|
-
|
|
32
|
-
## Non-Goals
|
|
33
|
-
|
|
34
|
-
- Relabeling the widget heading from `Agents` to `Background agents` (see Open Questions) — not requested; keep scope tight.
|
|
35
|
-
- Any change to `widget-renderer.ts` rendering logic — it has no foreground-specific path; the fix lives entirely at the data source in `agent-widget.ts`.
|
|
36
|
-
- Other `listAgents()` consumers (`agent-menu.ts`) — those are removed wholesale by Phase 19 Step 5 ([#442]), out of scope here.
|
|
37
|
-
- Native session navigation ([#445], Step 4) and the `/subagents-settings` extraction ([#447], Step 2).
|
|
38
|
-
|
|
39
|
-
## Background
|
|
40
|
-
|
|
41
|
-
Relevant modules:
|
|
42
|
-
|
|
43
|
-
- `src/ui/agent-widget.ts` — `AgentWidget implements SubagentManagerObserver`; self-drives an 80 ms render loop from lifecycle events (Step 4 self-drive, [#423]).
|
|
44
|
-
`update()` reads `manager.listAgents()` into a local `allAgents`, then passes it to `seedFinishedAgents()`, `assembleWidgetState()`, and (on the idle path) `clearWidget()`.
|
|
45
|
-
`renderWidget(tui, theme)` independently calls `manager.listAgents().map(r => this.toWidgetAgent(r))` to build the tree.
|
|
46
|
-
- `src/ui/widget-renderer.ts` — pure rendering; `renderWidgetLines()` categorizes agents into running/queued/finished and emits tree lines.
|
|
47
|
-
It has no knowledge of foreground vs. background — it renders whatever list it receives.
|
|
48
|
-
- `Subagent.invocation` (`src/lifecycle/subagent.ts`) — a readonly `AgentInvocation | undefined` set once at construction.
|
|
49
|
-
`AgentInvocation.runInBackground` (`src/types.ts`) is the reliable signal: set by `spawn-config.ts` → `AgentInvocation.runInBackground` → stored on `Subagent.invocation`.
|
|
50
|
-
- `AgentSummary` (in `agent-widget.ts`) — the minimal `{ id, status, completedAt }` shape consumed by `assembleWidgetState`/`clearWidget`.
|
|
51
|
-
`Subagent` is structurally assignable to it, so the accessor can return `Subagent[]` without an interface change.
|
|
52
|
-
|
|
53
|
-
Constraint from AGENTS.md / package skill: pi-subagents is a minimal core; this is a consumer-side UI behavior change with no policy or core impact.
|
|
54
|
-
|
|
55
|
-
## Design Overview
|
|
56
|
-
|
|
57
|
-
Introduce one private accessor on `AgentWidget` and route both existing call sites through it:
|
|
58
|
-
|
|
59
|
-
```typescript
|
|
60
|
-
/** Background agents only — the widget's sole audience (ADR-0004 Decision A). */
|
|
61
|
-
private listBackgroundAgents(): Subagent[] {
|
|
62
|
-
return this.manager
|
|
63
|
-
.listAgents()
|
|
64
|
-
.filter(record => record.invocation?.runInBackground === true);
|
|
65
|
-
}
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
Call-site changes:
|
|
69
|
-
|
|
70
|
-
- `update()` — replace `const allAgents = this.manager.listAgents();` with `const backgroundAgents = this.listBackgroundAgents();` and rename the downstream references (`seedFinishedAgents`, `assembleWidgetState`, `clearWidget`).
|
|
71
|
-
- `renderWidget()` — replace `this.manager.listAgents().map(...)` with `this.listBackgroundAgents().map(...)`.
|
|
72
|
-
|
|
73
|
-
The predicate `record.invocation?.runInBackground === true` is applied exactly once, at the funnel.
|
|
74
|
-
`undefined` invocation (or `runInBackground` absent/false) is treated as foreground and excluded.
|
|
75
|
-
|
|
76
|
-
Edge cases verified:
|
|
77
|
-
|
|
78
|
-
- **`clearWidget` stale-purge:** it deletes `finishedTurnAge` entries for IDs "no longer in the list."
|
|
79
|
-
Because `seedFinishedAgents` only ever seeds from the background-filtered list, no foreground agent is ever tracked, so purging against the background-only list cannot drop a still-relevant entry — no behavior regression.
|
|
80
|
-
- **Queued agents:** the concurrency limiter queues only background agents (foreground bypasses the queue), so they carry `runInBackground === true` and remain visible; the queued-count display stays accurate.
|
|
81
|
-
- **All-foreground case:** `update()` sees an empty background list → `assembleWidgetState` reports no active/finished → `clearWidget` → widget never registers. `renderWidget()` is consequently never invoked.
|
|
82
|
-
- **Mixed case (the latent bug):** one background running + one foreground running → `update()` registers the widget (1 background active); `renderWidget()` must also filter, or it renders both.
|
|
83
|
-
Routing both sites through the accessor closes this.
|
|
84
|
-
|
|
85
|
-
## Module-Level Changes
|
|
86
|
-
|
|
87
|
-
- `src/ui/agent-widget.ts` — add private `listBackgroundAgents()`; route `update()` and `renderWidget()` through it; rename the `update()` local `allAgents` → `backgroundAgents`.
|
|
88
|
-
- `src/ui/widget-renderer.ts` — **no change.**
|
|
89
|
-
Verified there is no foreground-specific rendering path; filtering at the data source is sufficient.
|
|
90
|
-
Listed only to record the verification.
|
|
91
|
-
- `test/ui/agent-widget.test.ts` — migrate existing widget fixtures to set `invocation: { runInBackground: true }` (otherwise the new filter excludes them); add background-only filtering tests.
|
|
92
|
-
- `packages/pi-subagents/README.md` — line ~64, change "showing all active agents" → "showing active background agents" (stale prose once foreground is excluded).
|
|
93
|
-
- `packages/pi-subagents/docs/architecture/architecture.md` — mark Step 3 ✅ with a `Landed`/`Outcome` note; the `src/ui/agent-widget.ts` tree caption at line ~342 stays accurate (generic "live status widget").
|
|
94
|
-
|
|
95
|
-
Grep sweep performed for stale references to "all agents" / "showing all active agents" across `src/`, `test/`, `.pi/skills/package-pi-subagents/SKILL.md`, and `docs/`:
|
|
96
|
-
|
|
97
|
-
- `README.md:64` — stale, updated above.
|
|
98
|
-
- `.pi/skills/package-pi-subagents/SKILL.md:57` ("widget ─polls─→ Subagent records (listAgents)") — still accurate (it does poll `listAgents`, now filtered); no edit.
|
|
99
|
-
- `docs/comparison-with-upstream.md:29`, `architecture.md:342` — generic "live above-editor widget"; remain accurate.
|
|
100
|
-
|
|
101
|
-
## Test Impact Analysis
|
|
102
|
-
|
|
103
|
-
1. **New tests enabled by the change:**
|
|
104
|
-
- `update()` excludes foreground agents — an all-foreground agent list leaves the widget unregistered (`lastContent()` undefined).
|
|
105
|
-
- `renderWidget()` excludes foreground agents — a mixed background+foreground list renders only the background agent's description in the tree (the foreground description is absent).
|
|
106
|
-
This pins the previously-latent two-site inconsistency.
|
|
107
|
-
2. **Tests that become redundant:** none are removed.
|
|
108
|
-
The existing widget-behavior fixtures (`makeWidget` in the two `describe` blocks, plus the projection test's `createTestSubagent`) are migrated to set `invocation: { runInBackground: true }` so they continue to exercise the same lifecycle/seeding/self-drive behavior under the new filter.
|
|
109
|
-
3. **Tests that must stay as-is:** the `assembleWidgetState` pure-function suite — it calls the pure function directly with `AgentSummary[]`, not through the accessor, so it is unaffected by the filter and continues to pin the counting logic.
|
|
110
|
-
|
|
111
|
-
## Invariants at risk
|
|
112
|
-
|
|
113
|
-
This step touches `agent-widget.ts`, which prior phases already refactored.
|
|
114
|
-
The fixture migration must keep these invariants pinned (the tests stay, only their `invocation` field is added):
|
|
115
|
-
|
|
116
|
-
- **Self-drive from lifecycle ([#423]):** `onSubagentStarted`/`onSubagentCreated` start the 80 ms timer and render; `onSubagentCompleted`/`onSubagentCompacted` render.
|
|
117
|
-
Pinned by the "self-drives from lifecycle notifications" describe block — fixtures migrated to background invocation so the manager stub's agents survive the filter.
|
|
118
|
-
- **`seedFinishedAgents` idempotency / linger aging ([#374]):** finished agents seed once, age out after 1 turn (errors after 2), and `update()` never advances the age without a turn.
|
|
119
|
-
Pinned by the "update self-seeds finished agents" describe block — fixtures migrated to background invocation.
|
|
120
|
-
|
|
121
|
-
A later step must not regress these with a green suite; the migration preserves the assertions verbatim apart from the `invocation` field.
|
|
122
|
-
|
|
123
|
-
## TDD Order
|
|
124
|
-
|
|
125
|
-
1. **`test:` migrate widget fixtures to background invocation (preparatory / tidy-first).**
|
|
126
|
-
Surface: `test/ui/agent-widget.test.ts`.
|
|
127
|
-
Add `invocation: { runInBackground: true }` to the `makeWidget` agent stubs (both `describe` blocks) and to the projection test's `createTestSubagent` call.
|
|
128
|
-
No production change — the filter does not exist yet, so the field is inert and the suite stays green.
|
|
129
|
-
This makes the next step a clean addition rather than a mass fixture rewrite.
|
|
130
|
-
Commit: `test: set background invocation on agent-widget fixtures (#444)`.
|
|
131
|
-
2. **`feat:` filter the widget to background agents only.**
|
|
132
|
-
Red: add (a) an all-foreground list leaves the widget unregistered, and (b) a mixed background+foreground list renders only the background agent in `renderWidget()`.
|
|
133
|
-
Green: add the private `listBackgroundAgents()` accessor; route both `update()` and `renderWidget()` through it; rename the `update()` local to `backgroundAgents`.
|
|
134
|
-
Commit: `feat: shrink agent widget to background runs only (#444)`.
|
|
135
|
-
3. **`docs:` update widget docs for background-only behavior.**
|
|
136
|
-
Update `README.md` ("all active agents" → "active background agents") and mark Phase 19 Step 3 ✅ with a `Landed`/`Outcome` note in `docs/architecture/architecture.md`.
|
|
137
|
-
Commit: `docs: note background-only widget in README and roadmap (#444)`.
|
|
138
|
-
|
|
139
|
-
## Risks and Mitigations
|
|
140
|
-
|
|
141
|
-
- **Mass test breakage when the filter lands** — every `update()`-driven fixture would be filtered out and assertions would fail.
|
|
142
|
-
Mitigation: TDD step 1 migrates all fixtures first (inert until the filter exists), so step 2 only adds new tests.
|
|
143
|
-
- **A foreground agent the operator expected to see disappears** — intended per ADR-0004 Decision A; the inline `onUpdate` stream is authoritative for foreground runs.
|
|
144
|
-
- **`clearWidget` stale-purge dropping a relevant entry** — analyzed in Design Overview; foreground agents are never seeded, so purging against the background-only list is correct.
|
|
145
|
-
|
|
146
|
-
## Open Questions
|
|
147
|
-
|
|
148
|
-
- Should the widget heading read `Background agents` instead of `Agents`?
|
|
149
|
-
Deferred — not in the issue scope; revisit if the bare label reads as ambiguous in practice.
|
|
150
|
-
|
|
151
|
-
[arch]: ../architecture/architecture.md
|
|
152
|
-
[#442]: https://github.com/gotgenes/pi-packages/issues/442
|
|
153
|
-
[#445]: https://github.com/gotgenes/pi-packages/issues/445
|
|
154
|
-
[#447]: https://github.com/gotgenes/pi-packages/issues/447
|
|
155
|
-
[#423]: https://github.com/gotgenes/pi-packages/issues/423
|
|
156
|
-
[#374]: https://github.com/gotgenes/pi-packages/issues/374
|