@gotgenes/pi-subagents 17.5.0 → 18.0.1
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 +20 -0
- package/README.md +22 -31
- package/docs/architecture/architecture.md +24 -19
- package/docs/decisions/0004-reconsider-ui-direction.md +17 -0
- package/docs/plans/0441-remove-agent-definition-management-subtree.md +180 -0
- package/docs/plans/0442-dissolve-agents-conversation-viewer.md +195 -0
- package/docs/plans/0443-consolidate-remaining-test-clone-families.md +268 -0
- package/docs/plans/0470-refresh-readme-command-surface.md +159 -0
- package/docs/retro/0441-remove-agent-definition-management-subtree.md +97 -0
- package/docs/retro/0442-dissolve-agents-conversation-viewer.md +108 -0
- package/docs/retro/0443-consolidate-remaining-test-clone-families.md +28 -0
- package/docs/retro/0463-file-snapshot-source-evicted-agents.md +54 -0
- package/docs/retro/0470-refresh-readme-command-surface.md +40 -0
- package/package.json +1 -1
- package/src/index.ts +4 -31
- package/src/ui/session-navigation.ts +1 -1
- package/src/ui/session-navigator.ts +3 -3
- package/src/ui/subagents-settings.ts +2 -2
- package/src/ui/agent-config-editor.ts +0 -199
- package/src/ui/agent-creation-wizard.ts +0 -233
- package/src/ui/agent-file-ops.ts +0 -59
- package/src/ui/agent-file-writer.ts +0 -55
- package/src/ui/agent-menu.ts +0 -331
- package/src/ui/conversation-viewer.ts +0 -241
- package/src/ui/message-formatters.ts +0 -195
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
---
|
|
2
|
+
issue: 441
|
|
3
|
+
issue_title: "pi-subagents: remove the orphaned agent-definition management subtree"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Retro: #441 — pi-subagents: remove the orphaned agent-definition management subtree
|
|
7
|
+
|
|
8
|
+
## Stage: Planning (2026-06-23T00:00:00Z)
|
|
9
|
+
|
|
10
|
+
### Session summary
|
|
11
|
+
|
|
12
|
+
Produced a deletion-only plan for Phase 19 Step 6: `git rm` the orphaned creation wizard, config editor, and their two file-ops helpers (plus tests), prune `test/helpers/ui-stubs.ts` to just `makeMenuUI`, and update the two current-state docs.
|
|
13
|
+
Verified against `main` that the five modules are pure orphans (no `src/` importer, `index.ts` clean) and that this is the unreleased tail of release batch "dissolve-agents".
|
|
14
|
+
The plan routes to `/build-plan` (no test cycles) with two commits.
|
|
15
|
+
|
|
16
|
+
### Observations
|
|
17
|
+
|
|
18
|
+
- Two deviations from the issue body, both forced by the codebase + the authoritative architecture doc rather than by preference, so no `ask_user` gate was used:
|
|
19
|
+
1. `menu-ui.ts` (the `MenuUI` interface) must also be deleted — it is orphaned by the same cut, and `architecture.md` lines 346/1076 explicitly schedule its removal under #441.
|
|
20
|
+
The issue body omits it.
|
|
21
|
+
2. `makeMenuManager` is removed whole, not just its `spawnAndWait` field — after the four test files go, its only consumer is its own self-test, so it is residual clutter.
|
|
22
|
+
The architecture doc's "if no surviving consumer remains" phrasing licenses this.
|
|
23
|
+
- `ui-stubs.ts` survives because `makeMenuUI` still has a real consumer (`subagents-settings.test.ts`); only the three other helpers (and the private `DEFAULT_TEST_AGENT_CONFIG` + the `AgentConfig` import) are pruned.
|
|
24
|
+
- Commit type is `refactor(pi-subagents):`, not `feat!:` — deleting already-unreachable code changes no observable behavior at this step.
|
|
25
|
+
The release is driven by Step 5's unreleased breaking `feat!:` (`cb813f2c`, after tag `pi-subagents-v17.5.0`); landing this tail lets release-please cut the major bump.
|
|
26
|
+
- Production duplication goes to zero when `agent-config-editor.ts` is deleted (the 11-line `disableAgent`/`ejectAgent` clone); pin with `pnpm fallow dupes`.
|
|
27
|
+
- Historical docs under `docs/plans/`, `docs/retro/`, and `docs/architecture/history/` mention the deleted modules only as records of completed phases — left untouched per convention; only `architecture.md` current-state and `SKILL.md` are updated.
|
|
28
|
+
|
|
29
|
+
## Stage: Implementation — Build (2026-06-23T17:00:00Z)
|
|
30
|
+
|
|
31
|
+
### Session summary
|
|
32
|
+
|
|
33
|
+
Executed the two-commit plan: `git rm` the five orphaned `src/ui/` modules and four test files in one atomic commit; pruned `test/helpers/ui-stubs.ts` and `ui-stubs.test.ts` to `makeMenuUI` only in the same commit.
|
|
34
|
+
Second commit updated `architecture.md` (directory tree, Step 6 ✅ and Landed note, Mermaid node) and `SKILL.md` (UI domain row 11→6).
|
|
35
|
+
Three additional doc-fixup commits addressed stale `architecture.md` prose (domain flowchart, cross-extension diagram, "What the core owns," "Composition model") deferred from #442.
|
|
36
|
+
All checks green: 62 test files / 950 tests, `fallow dead-code` clean, `fallow dupes` shows 0 production clone groups.
|
|
37
|
+
|
|
38
|
+
### Observations
|
|
39
|
+
|
|
40
|
+
- The pre-completion reviewer surfaced five stale `architecture.md` sections not covered by the plan's declared doc scope — all carried over from #442's retro note "Deferred the holistic architecture-doc refresh … to the batch tail [#441]."
|
|
41
|
+
Required three extra doc-fixup commits (`e440d0d1`, `04b13812`, and the SKILL.md file-count fix) beyond the plan's two.
|
|
42
|
+
**Lesson:** when a retro note explicitly defers a doc refresh to the batch tail, include it in the batch-tail plan's "Module-Level Changes" doc section so it isn't discovered only by the reviewer.
|
|
43
|
+
- `makeMenuManager` was removed whole (not just its `spawnAndWait` relay) because its only post-cut consumer was its own self-test — exactly the right call, consistent with the planning decision.
|
|
44
|
+
- Final file count in `src/`: 57 (was 58 in SKILL.md header; now corrected).
|
|
45
|
+
- Pre-completion reviewer: **PASS** (third dispatch, after two WARN rounds on the stale doc sections).
|
|
46
|
+
|
|
47
|
+
## Stage: Final Retrospective (2026-06-23T18:30:00Z)
|
|
48
|
+
|
|
49
|
+
### Session summary
|
|
50
|
+
|
|
51
|
+
Shipped #441 as the tail of release batch "dissolve-agents": pushed, CI green, closed both #441 and the stacked #442, merged release-please PR #469, and cut `pi-subagents-v18.0.0`.
|
|
52
|
+
The whole arc (plan → build → ship) executed in one session with no rework to the deletion itself — the only friction was doc staleness inherited from #442, caught by the pre-completion reviewer across two WARN rounds.
|
|
53
|
+
|
|
54
|
+
### Observations
|
|
55
|
+
|
|
56
|
+
#### What went well
|
|
57
|
+
|
|
58
|
+
- The fresh-context `pre-completion-reviewer` earned its keep on a deletion task: it caught five stale `architecture.md` sections (a domain Mermaid diagram, a cross-extension diagram label, and three prose passages) that referenced modules deleted in #442, none of which the plan or the implementation agent flagged.
|
|
59
|
+
Doc staleness is exactly the category a focused deletion misses, and the reviewer is the safety net that held.
|
|
60
|
+
- Batch-tail release mechanics worked exactly as planned: a `refactor(pi-subagents):` tail commit carried no version weight itself, the unreleased `feat(pi-subagents)!:` from #442 (`cb813f2c`) drove the major bump, and `release-please` cut `v18.0.0` cleanly while both issues closed with curated comments.
|
|
61
|
+
|
|
62
|
+
#### What caused friction (agent side)
|
|
63
|
+
|
|
64
|
+
1. `missing-context` (cross-session) — `#442`'s retro explicitly deferred a "holistic architecture-doc refresh" to the batch tail (#441), but #441's planning stage never pulled that deferred work into the plan's `Module-Level Changes` doc scope.
|
|
65
|
+
The `/plan-issue` "Check for prior session context" step reads only the **current** issue's retro (`NNNN` matching the issue number), so a predecessor batch member's deferred work is invisible to it.
|
|
66
|
+
Impact: three extra doc-fixup commits (`e440d0d1`, `04b13812`, and the `SKILL.md` file-count fix) and three pre-completion reviewer dispatches (two WARN, then PASS) during the build stage.
|
|
67
|
+
2. `wrong-abstraction` (fix scope) — after the first reviewer WARN named three stale sections, the fix addressed exactly those three rather than grepping `architecture.md` exhaustively for every reference to the deleted modules (`conversation-viewer`, `agent-menu`, `/agents`).
|
|
68
|
+
Impact: the second review round found two more stale sections, forcing another fix → commit → re-review cycle that one exhaustive grep would have collapsed into the first round.
|
|
69
|
+
|
|
70
|
+
#### What caused friction (user side)
|
|
71
|
+
|
|
72
|
+
- None substantive.
|
|
73
|
+
The user's two `Continue.` prompts during the build stage were mechanical resumptions (after an autoformat tool message and a context boundary), not redirections — the work was well-specified by the plan throughout.
|
|
74
|
+
|
|
75
|
+
### Diagnostic details
|
|
76
|
+
|
|
77
|
+
- **Model-performance correlation** — the `pre-completion-reviewer` ran on `anthropic/claude-sonnet-4-6` (per its agent frontmatter), an appropriate match for judgment-heavy doc-staleness and design review; no high-cost-model-on-mechanical-work or weak-model-on-judgment mismatch.
|
|
78
|
+
No other subagents were dispatched.
|
|
79
|
+
- **Unused-tool detection** — friction point 2 was a `grep`/`colgrep` gap: an exhaustive search for the deleted-module names across `architecture.md` after the first WARN would have surfaced all five stale references in one pass instead of two.
|
|
80
|
+
- **Feedback-loop gap analysis** — no gap; verification ran incrementally (baseline `check`/`lint` before edits, then `check`/`test`/`lint`/`fallow dead-code`/`fallow dupes` after each step, then the reviewer), not bunched at the end.
|
|
81
|
+
|
|
82
|
+
### Changes made
|
|
83
|
+
|
|
84
|
+
1. `.pi/prompts/plan-issue.md` — added step 5 to "Check for prior session context": a release-batch tail plan must read earlier batch members' retros for deferred work and fold it into `Module-Level Changes`.
|
|
85
|
+
2. `.pi/skills/pre-completion/SKILL.md` — added a line under "Overall: WARN": when a WARN names stale references to a deleted symbol, grep the file exhaustively for every instance before fixing, to avoid a second WARN round.
|
|
86
|
+
|
|
87
|
+
### Post-commit follow-up — stale `README.md`
|
|
88
|
+
|
|
89
|
+
After the retro commit, the user caught that `packages/pi-subagents/README.md` still documents the removed `/agents` command and conversation viewer and omits `/subagents:settings` and `/subagents:sessions` — a published, user-facing miss that shipped in `pi-subagents-v18.0.0`.
|
|
90
|
+
|
|
91
|
+
- `missing-context` (cross-session, user-caught) — the README was stale from #442's deletions (it documents `/agents`, not the module `agent-menu.ts`) and was never folded into #442's or #441's plan.
|
|
92
|
+
The pre-completion reviewer's README check keyed on module names, not the command names a README actually documents, so a module-name match missed it.
|
|
93
|
+
Impact: a user-facing doc defect shipped to npm; tracked as a follow-up in #470 (recommend `/plan-issue`).
|
|
94
|
+
|
|
95
|
+
3. Filed #470 to rewrite the stale `README.md` (removed `/agents` surface, missing `/subagents:` commands, eject UI gone).
|
|
96
|
+
4. `.pi/prompts/plan-issue.md` — `Module-Level Changes`: when a change adds, removes, or renames a slash command or user-facing feature, grep `packages/<PKG>/README.md` for the command/feature name (the `src/`-symbol grep misses command names).
|
|
97
|
+
5. `.pi/agents/pre-completion-reviewer.md` — broadened the forward-doc README check: when a change removes or renames a slash command or user-facing feature, grep the package `README.md` for the command/feature name, not just module names.
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
---
|
|
2
|
+
issue: 442
|
|
3
|
+
issue_title: "pi-subagents: dissolve /agents and remove the conversation-viewer subtree"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Retro: #442 — pi-subagents: dissolve /agents and remove the conversation-viewer subtree
|
|
7
|
+
|
|
8
|
+
## Stage: Planning (2026-06-23T18:06:31Z)
|
|
9
|
+
|
|
10
|
+
### Session summary
|
|
11
|
+
|
|
12
|
+
Planned Phase 19 Step 5: dissolve the `/agents` command and delete the conversation-viewer subtree (`agent-menu.ts`, `conversation-viewer.ts`, `message-formatters.ts`, plus their three tests), dewire `index.ts`.
|
|
13
|
+
Investigation surfaced a blocker the issue overlooked — a bidirectional type cycle between the hub and its leaves — and the operator chose a tidy-first resolution.
|
|
14
|
+
Plan committed at `packages/pi-subagents/docs/plans/0442-dissolve-agents-conversation-viewer.md`; this is a `/build-plan` (no red→green cycles), batched for release with the tail [#441].
|
|
15
|
+
|
|
16
|
+
### Observations
|
|
17
|
+
|
|
18
|
+
- Key finding: `agent-creation-wizard.ts` and `agent-config-editor.ts` (which survive until [#441]) both `import type { MenuUI } from "#src/ui/agent-menu"` and use it throughout, while the hub value-imports the wizard/editor classes — a bidirectional cycle.
|
|
19
|
+
Deleting either subtree first breaks `tsc --noEmit` (type-checks `src` + `test`).
|
|
20
|
+
The issue's "pure orphans" premise holds for runtime reachability but not at the type level.
|
|
21
|
+
- Flipping the [#442]/[#441] order does **not** fix it (cycle is bidirectional) — surfaced this directly when the operator asked about step ordering.
|
|
22
|
+
- Operator decision via `ask_user`: keep two commits, relocate `MenuUI` to a surviving `src/ui/menu-ui.ts` first (tidy-first).
|
|
23
|
+
Rejected alternatives: merge [#441] into [#442] (one deletion commit), or inline a throwaway `MenuUI` into the doomed leaves.
|
|
24
|
+
- Operator confirmed release timing: do not release until both [#442] and [#441] land — marker is `mid-batch — defer (batch "dissolve-agents")`, tail is [#441].
|
|
25
|
+
- `menu-ui.ts` is intentionally transient (one issue's lifespan); it keeps two live consumers (wizard/editor) immediately, so no fallow dead-code flag; [#441] deletes it with its consumers.
|
|
26
|
+
- Verified no collateral: `FsAgentFileOps` stays off the dead-code list because its own test still imports it; `subagents-settings.ts` defines its own `SubagentsSettingsUI` (no `MenuUI` coupling); `ui-stubs.ts`'s `makeMenuUI` is structurally typed; `join`/`buildParentSnapshot` become dead `index.ts` imports and are removed; deleting the consumers orphans no `display.ts` export.
|
|
27
|
+
- Change is breaking (the `/agents` command disappears) → deletion commit is `feat(pi-subagents)!:` with a `BREAKING CHANGE:` footer naming `/subagents:settings`, `/subagents:sessions`, and the background widget (verified the real registered command names, not the architecture's proposed `/subagents-settings`).
|
|
28
|
+
- Deferred the holistic architecture-doc refresh (Mermaid domain diagram, complexity/health tables, Phase-19-to-history migration) to the batch tail [#441] to avoid double-editing tables that [#441] also touches; [#442] keeps only the current-state file tree, the Step 5 `Outcome:` annotation, and the SKILL.md UI count accurate.
|
|
29
|
+
|
|
30
|
+
[#441]: https://github.com/gotgenes/pi-packages/issues/441
|
|
31
|
+
[#442]: https://github.com/gotgenes/pi-packages/issues/442
|
|
32
|
+
|
|
33
|
+
## Stage: Implementation — Build (2026-06-23T19:30:00Z)
|
|
34
|
+
|
|
35
|
+
### Session summary
|
|
36
|
+
|
|
37
|
+
Executed both plan commits (Step 1: extract `MenuUI`; Step 2: delete hub+viewer+formatters and dewire `index.ts`).
|
|
38
|
+
A mid-session diversion investigated the commitlint `#N`-in-body false positive (issue [#4099]), determined it is still present in v21.0.2 despite the issue being closed, and removed the `--strict` flag from `prek.toml` so the warning no longer blocks commits.
|
|
39
|
+
Pre-completion reviewer returned PASS.
|
|
40
|
+
|
|
41
|
+
### Observations
|
|
42
|
+
|
|
43
|
+
- **Unplanned fallow finding:** after deleting `agent-menu.ts`, `showAgentDetail` (`agent-config-editor.ts`) and `showCreateWizard` (`agent-creation-wizard.ts`) lost their only external callers and became unused class members.
|
|
44
|
+
The plan's risk analysis covered unused *files* (`FsAgentFileOps`) but not unused class *methods*.
|
|
45
|
+
Added `// fallow-ignore-next-line unused-class-member` suppressions with a comment pointing to [#441] as the removal commit.
|
|
46
|
+
Future plans for hub-deletion steps should explicitly check whether public methods on surviving leaf classes lose their only caller.
|
|
47
|
+
- **Unplanned commitlint diversion:** bodies with `#N` mid-sentence in multi-paragraph messages are still misidentified as footer tokens by commitlint v21.0.2 despite issue [#4099] being closed COMPLETED on 2026-06-02 with no linked PR.
|
|
48
|
+
Removed `--strict` from the `commit-msg` hook in `prek.toml` so the false-positive is a non-blocking warning; updated `AGENTS.md` accordingly.
|
|
49
|
+
This also required untangling a bad commit (the `git rm`'d pi-subagents files were swept into the commitlint fix commit) via `git reset HEAD~1` + selective re-staging.
|
|
50
|
+
- **Commit message refinement:** learned empirically that `#N` appearing in a wrapped body line (near end of line) triggers the false positive even in a single-paragraph body; a two-paragraph body with `#N` in the second paragraph was the original failure mode.
|
|
51
|
+
Workaround before the `--strict` removal: keep `#N` out of body prose; use `Refs #N` as a true footer with a blank-line separator.
|
|
52
|
+
- Pre-completion reviewer: PASS — all deterministic checks green; doc-staleness WARNs (Mermaid domain diagram, structural tables, Phase 19 history) are intentional mid-batch deferred work per the plan's Non-Goals, to be resolved at the batch tail [#441].
|
|
53
|
+
|
|
54
|
+
[#4099]: https://github.com/conventional-changelog/commitlint/issues/4099
|
|
55
|
+
|
|
56
|
+
## Stage: Final Retrospective (2026-06-23T20:05:13Z)
|
|
57
|
+
|
|
58
|
+
### Session summary
|
|
59
|
+
|
|
60
|
+
Shipped Phase 19 Step 5 across plan → build → ship: extracted `MenuUI` to break a bidirectional type cycle, deleted the `/agents` hub plus the conversation-viewer subtree, and dewired `index.ts`.
|
|
61
|
+
The release was correctly deferred at ship time per the `mid-batch — defer` marker (batch tail is [#441]).
|
|
62
|
+
The session's dominant friction was an unplanned commitlint diversion that produced a blunt fix, then a superseding surgical fix, a bad-commit untangle, and a new tracking issue ([#468]).
|
|
63
|
+
|
|
64
|
+
### Observations
|
|
65
|
+
|
|
66
|
+
#### What went well
|
|
67
|
+
|
|
68
|
+
1. The Planning `ask_user` gate caught the hub↔leaf bidirectional type cycle before any code was written and produced a clean tidy-first plan (relocate `MenuUI` first), so the two implementation commits were each green — no broken-commit sequence.
|
|
69
|
+
2. The commitlint claim was verified empirically by running `commitlint` against crafted test messages, not by trusting the closed-issue status — this confirmed [#4099] was closed `COMPLETED` without a shipped fix and that the false positive still fired in `v21.0.2`.
|
|
70
|
+
3. Incremental verification: `pnpm run check`/`lint`/`test`/`fallow dead-code` ran after each implementation step, so the unused-class-member finding surfaced at the right step rather than at the end.
|
|
71
|
+
|
|
72
|
+
#### What caused friction (agent side)
|
|
73
|
+
|
|
74
|
+
1. `premature-convergence` — the first commitlint fix (`9b60c943`, remove `--strict`) was blunt: dropping `--strict` silences every warning-level rule, including the load-bearing malformed-`!`-header rejection (Refs #457).
|
|
75
|
+
The surgical fix (`40189cc4`, disable only `footer-leading-blank`, keep `--strict`) only emerged from a separate branch reconsideration.
|
|
76
|
+
Impact: one superseded `fix(commitlint):` commit now permanent in pushed history; a #457 regression was avoided only because the blunt fix was reconsidered before the batch released.
|
|
77
|
+
2. `other` (git workflow) — `git rm` pre-stages its deletions, so a later `git add prek.toml AGENTS.md && git commit` for the commitlint fix swept the already-staged `/agents` deletions into the wrong commit.
|
|
78
|
+
Required `git reset HEAD~1` plus selective re-staging to untangle.
|
|
79
|
+
Impact: ~4 extra tool calls; caught immediately, no lasting damage.
|
|
80
|
+
3. `missing-context` / unused-tool — determining the upstream commitlint issue state took several rounds of `web_search` + `fetch_content` until the user said "Remember you have access to the `gh` CLI, too"; `gh issue view 4099 --repo conventional-changelog/commitlint` then returned the authoritative state (`CLOSED`/`COMPLETED`, no linked PR) in one call.
|
|
81
|
+
Impact: several wasted research rounds; user-caught.
|
|
82
|
+
4. `missing-context` (minor) — the plan's risk analysis covered unused *files* (`FsAgentFileOps`, kept live by its test import) but not unused class *methods*; deleting the hub orphaned `showAgentDetail` and `showCreateWizard`, tripping `fallow dead-code`.
|
|
83
|
+
Impact: low — caught by the gate, resolved with two `fallow-ignore-next-line unused-class-member` suppressions pointing at [#441].
|
|
84
|
+
|
|
85
|
+
#### What caused friction (user side)
|
|
86
|
+
|
|
87
|
+
1. The agent reached for `web_search`/`fetch_content` to check a GitHub issue's state instead of `gh`; the user had to point at an available tool.
|
|
88
|
+
Opportunity: reach for `gh issue view`/`gh pr view` first for GitHub issue/PR state, including upstream repos.
|
|
89
|
+
2. The user supplied the steer toward a surgical fix ("prefer surgical fixes over blunt ones").
|
|
90
|
+
Opportunity: a standing rule about disabling the single offending rule rather than the enforcement mode could have produced the surgical fix on the first pass.
|
|
91
|
+
|
|
92
|
+
### Diagnostic details
|
|
93
|
+
|
|
94
|
+
- **Model-performance correlation** — the `pre-completion-reviewer` subagent ran on `anthropic/claude-sonnet-4-6` (per its agent frontmatter), appropriate for judgment-heavy review; the implementation ran on `claude-opus-4-8`.
|
|
95
|
+
No quality mismatch.
|
|
96
|
+
The many `model_change` entries are transient UI cycling (no assistant turn under most), not real reassignments.
|
|
97
|
+
- **Escalation-delay tracking** — the upstream-issue-state investigation ran ~6 consecutive `web_search`/`fetch_content` calls before the `gh` reminder; one `gh issue view` would have resolved it immediately.
|
|
98
|
+
- **Unused-tool detection** — `gh` was available throughout but not used for upstream issue state until prompted.
|
|
99
|
+
- **Feedback-loop gap analysis** — no gap; verification ran incrementally after each step.
|
|
100
|
+
|
|
101
|
+
[#468]: https://github.com/gotgenes/pi-packages/issues/468
|
|
102
|
+
|
|
103
|
+
### Changes made
|
|
104
|
+
|
|
105
|
+
1. `AGENTS.md` (`## Commits`) — tightened the `footer-leading-blank` note from ~62 words to rule + `Refs #468`, dropping the parser-variant list and the two upstream issue numbers (now here and in [#468]).
|
|
106
|
+
2. `AGENTS.md` (`## Commits`) — added a single-rule-vs-mode principle: disable the single offending lint rule (`[0]`), not the `--strict` enforcement mode that gates the others.
|
|
107
|
+
3. `AGENTS.md` (`## Workflow`) — added a bullet to use `gh issue view N --repo owner/repo` for GitHub issue/PR state instead of web search.
|
|
108
|
+
4. `AGENTS.md` (`## Commits`, git mechanics) — added a note that staged `git rm` deletions ride along with the next `git commit` even when only unrelated paths are `git add`ed; commit with an explicit pathspec or check `git status` first.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
issue: 443
|
|
3
|
+
issue_title: "pi-subagents: consolidate remaining test clone families"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Retro: #443 — pi-subagents: consolidate remaining test clone families
|
|
7
|
+
|
|
8
|
+
## Stage: Planning (2026-06-23T00:00:00Z)
|
|
9
|
+
|
|
10
|
+
### Session summary
|
|
11
|
+
|
|
12
|
+
Planned Phase 19 Step 7 (test-clone consolidation) for `pi-subagents`.
|
|
13
|
+
Re-ran `fallow dupes` against current `main` and found the live state diverged from the issue's Phase-18-era snapshot: line numbers shifted after the terminal cut ([#441]/[#442]) and new Phase-19 UI test files added clones the issue never named.
|
|
14
|
+
Wrote `packages/pi-subagents/docs/plans/0443-consolidate-remaining-test-clone-families.md` and committed it.
|
|
15
|
+
|
|
16
|
+
### Observations
|
|
17
|
+
|
|
18
|
+
- The issue is the operator's own, but the proposed "extract a shared fixture" list was substantially invalidated by live evidence: several named targets (`resolveSpawnConfig`, `assembleSessionConfig`, `schedule`) are the repeated *system-under-test act*, which the `testing` skill says not to wrap to clear a clone metric.
|
|
19
|
+
- `ask_user` gate settled two decisions: **guardrail-first** (leave act-clones, extract only genuine fixtures) and **full live set** (include the new Phase-19 UI clones, notably the byte-identical `makeNavigable` factory duplicated across `session-navigation.test.ts` and `session-navigator.test.ts`).
|
|
20
|
+
- Eight genuine extraction targets identified; clearing them drops the count from 16 to 8 — below the issue's `≤ 10` target — without wrapping any act.
|
|
21
|
+
The four primary UI/lifecycle extractions alone reach 10.
|
|
22
|
+
- Six residual families are documented as intentional act-clones in Non-Goals so a future fallow pass reads them as deliberate, not oversight.
|
|
23
|
+
- Convention confirmed: cross-file helpers go in `test/helpers/<name>.ts` (imported via `#test/helpers/<name>`) with a companion `<name>.test.ts`; single-file helpers stay local.
|
|
24
|
+
- Invariants at risk flagged: the `#423` reactive-consumer assertion in `session-navigator.test.ts` must stay in the test body (not absorbed by the `renderCapturedOverlay` helper), and the resume-events emitter must preserve exact usage/compaction payloads.
|
|
25
|
+
- `Release: independent` — ships on its own; no batch coupling.
|
|
26
|
+
|
|
27
|
+
[#441]: https://github.com/gotgenes/pi-packages/issues/441
|
|
28
|
+
[#442]: https://github.com/gotgenes/pi-packages/issues/442
|
|
@@ -47,3 +47,57 @@ Test count went from 1088 to 1099 (+11); full suite, `check`, root `lint`, and `
|
|
|
47
47
|
Both fixed and re-committed; `check` + tests confirmed green after.
|
|
48
48
|
- **Transient dead code** between steps 1–2 and 3 (predicted in the plan) cleared at the step-3 tip; final `fallow dead-code` is clean.
|
|
49
49
|
- **Pre-completion reviewer: PASS** — deterministic checks, code design, test artifacts, Mermaid render, and all three cross-step invariants (no inbound core call, read-only overlay, renderer parity) verified; no follow-ups deferred.
|
|
50
|
+
|
|
51
|
+
## Stage: Final Retrospective (2026-06-23T17:43:05Z)
|
|
52
|
+
|
|
53
|
+
### Session summary
|
|
54
|
+
|
|
55
|
+
Single continuous session carried #463 from planning through ship: a 4-step plan, TDD implementation (+11 tests, 1088→1099), pre-completion PASS, and release of `pi-subagents` v17.5.0.
|
|
56
|
+
The defining moment was planning: an `ask_user` design gate plus operator Socratic pushback diverged the candidate-set design from the issue's literal "directory scan" wording to manager-retained descriptors.
|
|
57
|
+
Execution was notably clean — no rework, no plan deviations, two auto-fixed lint nits.
|
|
58
|
+
|
|
59
|
+
### Observations
|
|
60
|
+
|
|
61
|
+
#### What went well
|
|
62
|
+
|
|
63
|
+
- **The `ask_user` gate caught a real design fork the issue body got wrong.**
|
|
64
|
+
The issue's "Proposed change" said "enumerate persisted child-session JSONL files" (a directory scan).
|
|
65
|
+
Exploration revealed the persisted session carries no subagent `type`/`description`, so a scan yields degraded labels.
|
|
66
|
+
The gate surfaced descriptors-vs-scan-vs-hybrid; the operator's "why are we evicting at all?"
|
|
67
|
+
and "tell me more about how the labels degrade" drove a better-grounded decision (descriptors).
|
|
68
|
+
This is the `/plan-issue` "treat Proposed change as a hypothesis" contract working as intended — novel because the divergence was the *enumeration mechanism*, not a surface ambiguity.
|
|
69
|
+
- **Exploratory probe before the first TDD test.**
|
|
70
|
+
A disposable script (`explore-session.mjs`, deleted after) confirmed `buildSessionContext` auto-detects the leaf with no `leafId` and the `type !== "session"` filter drops the header — validating the `fileSnapshotSource` shape before any test was written (the `testing` skill's "inspect the actual runtime shape first" rule).
|
|
71
|
+
- **The plan predicted transient dead code and sequenced to clear it.**
|
|
72
|
+
`fileSnapshotSource` and `listEvicted()` had no caller until step 3; the plan flagged this and ordered the integration step to close it, so the final `fallow dead-code` gate passed with no surprise suppressions.
|
|
73
|
+
- **Pre-completion reviewer ran on `claude-sonnet-4-6`** — model appropriate for the judgment-heavy invariant/design checklist; returned PASS.
|
|
74
|
+
|
|
75
|
+
#### What caused friction (agent side)
|
|
76
|
+
|
|
77
|
+
- `other` — the first `ask_user` led with the enumeration mechanism (descriptors/scan/hybrid) before establishing *why eviction creates the problem*.
|
|
78
|
+
The operator's first reply was "Why are we 'evicting' subagents in the first place?", i.e. asking for the framing I already held but had not front-loaded.
|
|
79
|
+
Impact: two extra `ask_user` round-trips before the decision — but they produced a better-understood outcome, so net-positive; no rework.
|
|
80
|
+
- `other` (lint nit) — four `entry?.kind` optional chains on a destructured array element tripped `@typescript-eslint/no-unnecessary-condition`, and a stray `!` tripped `no-unnecessary-type-assertion`; both surfaced via the pre-commit hook.
|
|
81
|
+
Impact: two re-commits during steps 2–3, auto-fixed, zero rework.
|
|
82
|
+
|
|
83
|
+
#### What caused friction (user side)
|
|
84
|
+
|
|
85
|
+
- None.
|
|
86
|
+
The operator's Socratic questions mid-`ask_user` were the session's highest-value input — they converted a plausible-but-degraded design (scan) into the right one (descriptors).
|
|
87
|
+
If anything, this is a model for how the gate should be used.
|
|
88
|
+
|
|
89
|
+
### Diagnostic details
|
|
90
|
+
|
|
91
|
+
- **Model-performance correlation** — the `pre-completion-reviewer` subagent ran on `anthropic/claude-sonnet-4-6` (judgment-heavy review): appropriate, no mismatch.
|
|
92
|
+
Main-thread `model_change` events included a `deepseek-v4-flash` variant; no quality degradation was observed in any artifact (plan, code, tests all clean), so no actionable correlation.
|
|
93
|
+
- **Escalation-delay tracking** — no `rabbit-hole` points; longest same-error streak was the two lint auto-fixes, each resolved in one re-commit.
|
|
94
|
+
- **Unused-tool detection** — exploration used `colgrep`, `grep`, and a disposable runtime probe; no missed-tool opportunities.
|
|
95
|
+
- **Feedback-loop gap analysis** — verification ran incrementally: `pnpm run check` after the shared-interface steps (2 and 3), per-file `vitest` on each red/green cycle, and the full suite + lint + `fallow` before the docs commit.
|
|
96
|
+
No end-only verification.
|
|
97
|
+
|
|
98
|
+
### Changes made
|
|
99
|
+
|
|
100
|
+
1. Appended this Final Retrospective stage entry to `packages/pi-subagents/docs/retro/0463-file-snapshot-source-evicted-agents.md`.
|
|
101
|
+
|
|
102
|
+
No `AGENTS.md` or prompt changes — the session's friction was net-positive (the `ask_user` round-trips) or auto-fixed with zero rework (the lint nits).
|
|
103
|
+
Two candidate changes were considered and rejected as noise (a `code-design` note on `entry?.kind` optional chaining; an `ask-user` "why-before-mechanism" guidance already covered by the skill).
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
issue: 470
|
|
3
|
+
issue_title: "pi-subagents: README still documents the removed /agents command and omits /subagents:settings and /subagents:sessions"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Retro: #470 — pi-subagents README still documents the removed /agents command
|
|
7
|
+
|
|
8
|
+
## Stage: Planning (2026-06-23T00:00:00Z)
|
|
9
|
+
|
|
10
|
+
### Session summary
|
|
11
|
+
|
|
12
|
+
Planned a docs-only refresh of `packages/pi-subagents/README.md` to replace the removed `/agents` interactive-menu surface with the live `/subagents:settings` and `/subagents:sessions` commands, drop the deleted Conversation viewer feature bullet, and remove the eject customization story (ADR-0004 Decision C).
|
|
13
|
+
Verified the current command surface against `src/index.ts` `registerCommand` calls and enumerated every stale reference by grep (lines 21, 119, 228–252, 277–303, 318).
|
|
14
|
+
Classified as **ship independently** — not a member of any roadmap step or release batch; the `dissolve-agents` batch already shipped as `pi-subagents-v18.0.0`.
|
|
15
|
+
|
|
16
|
+
### Observations
|
|
17
|
+
|
|
18
|
+
- Author is the operator (`gotgenes`), and the issue spells out the stale lines and expected behavior precisely, so the `ask_user` gate was skipped — no design ambiguity.
|
|
19
|
+
- This is a `/build-plan` (docs-only) change: one reviewable commit, no red→green cycles, verified by `pnpm run lint` (rumdl) plus a re-grep for stale terms.
|
|
20
|
+
- Root cause (from the issue itself): the Phase 19 doc-staleness check keyed on module names (`agent-menu.ts`), not the command names a README documents (`/agents`) — the plan-issue README grep checklist now catches this class.
|
|
21
|
+
- Scope deliberately excludes `src/`, tests, `architecture.md`, and the ADRs — all already accurate post-Phase-19.
|
|
22
|
+
Only the README lagged.
|
|
23
|
+
- `.pi/skills/package-pi-subagents/SKILL.md` needs no update: it is an implementation-architecture reference that does not document slash commands, and its sole `/agents` mention is past-tense Phase 18 historical context (not a live-command reference).
|
|
24
|
+
|
|
25
|
+
## Stage: Implementation — Build (2026-06-23T00:00:00Z)
|
|
26
|
+
|
|
27
|
+
### Session summary
|
|
28
|
+
|
|
29
|
+
Executed the single-step docs plan in one commit: refreshed `packages/pi-subagents/README.md` to the post-Phase-19 command surface.
|
|
30
|
+
Replaced the removed `/agents` interactive-menu surface with `/subagents:settings` and `/subagents:sessions`, dropped the Conversation viewer feature bullet (now a Session transcripts bullet), removed the eject customization story (override + `enabled: false` only), and corrected the `subagents:settings_changed` events-table description.
|
|
31
|
+
No `src/`/`test/`/`.ts` files touched; `pnpm run lint` and `pnpm run check` stayed green throughout.
|
|
32
|
+
|
|
33
|
+
### Observations
|
|
34
|
+
|
|
35
|
+
- Command table descriptions were copied verbatim from the `registerCommand` calls in `src/index.ts` so the README matches `/help` output.
|
|
36
|
+
- The post-edit grep for `/agents` still matches lines 22/119/131/132/137 — all legitimate `.pi/agents/<name>.md` file-path references, not the removed command; `eject`/`wizard`/`conversation viewer` return zero matches.
|
|
37
|
+
- Pre-completion reviewer: WARN (non-blocking).
|
|
38
|
+
- Reviewer warnings: one finding — the planning-stage retro observation incorrectly claimed `SKILL.md` "already references the new commands."
|
|
39
|
+
The conclusion (no skill update needed) was correct, but the justification was wrong.
|
|
40
|
+
Corrected the planning observation in this same retro commit; `SKILL.md` is an architecture reference that does not document slash commands, so it genuinely needs no update.
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -8,11 +8,9 @@
|
|
|
8
8
|
* steer_subagent — LLM-callable: send a steering message to a running agent
|
|
9
9
|
*
|
|
10
10
|
* Commands:
|
|
11
|
-
* /agents — Interactive agent management menu
|
|
12
11
|
*/
|
|
13
12
|
|
|
14
13
|
import { readFileSync } from "node:fs";
|
|
15
|
-
import { join } from "node:path";
|
|
16
14
|
import {
|
|
17
15
|
createAgentSession,
|
|
18
16
|
DefaultResourceLoader,
|
|
@@ -27,7 +25,6 @@ import { InterruptHandler, SessionLifecycleHandler, ToolStartHandler } from "#sr
|
|
|
27
25
|
import { createChildLifecyclePublisher } from "#src/lifecycle/child-lifecycle";
|
|
28
26
|
import { ConcurrencyLimiter } from "#src/lifecycle/concurrency-limiter";
|
|
29
27
|
import { createSubagentSession, type SubagentSessionDeps } from "#src/lifecycle/create-subagent-session";
|
|
30
|
-
import { buildParentSnapshot } from "#src/lifecycle/parent-snapshot";
|
|
31
28
|
import { SubagentManager } from "#src/lifecycle/subagent-manager";
|
|
32
29
|
import { CompositeSubagentObserver } from "#src/observation/composite-subagent-observer";
|
|
33
30
|
import { type NotificationDetails, NotificationManager } from "#src/observation/notification";
|
|
@@ -45,8 +42,6 @@ import { SettingsManager } from "#src/settings";
|
|
|
45
42
|
import { AgentTool } from "#src/tools/agent-tool";
|
|
46
43
|
import { GetResultTool } from "#src/tools/get-result-tool";
|
|
47
44
|
import { SteerTool } from "#src/tools/steer-tool";
|
|
48
|
-
import { FsAgentFileOps } from "#src/ui/agent-file-ops";
|
|
49
|
-
import { AgentsMenuHandler } from "#src/ui/agent-menu";
|
|
50
45
|
import { AgentWidget } from "#src/ui/agent-widget";
|
|
51
46
|
import { SessionNavigatorHandler } from "#src/ui/session-navigator";
|
|
52
47
|
import { SubagentsSettingsHandler } from "#src/ui/subagents-settings";
|
|
@@ -162,44 +157,22 @@ export default function (pi: ExtensionAPI) {
|
|
|
162
157
|
|
|
163
158
|
pi.registerTool(new SteerTool(manager, pi.events).toToolDefinition());
|
|
164
159
|
|
|
165
|
-
// ---- /
|
|
166
|
-
|
|
167
|
-
const agentsMenu = new AgentsMenuHandler(
|
|
168
|
-
manager,
|
|
169
|
-
registry,
|
|
170
|
-
settings,
|
|
171
|
-
new FsAgentFileOps(),
|
|
172
|
-
join(getAgentDir(), "agents"),
|
|
173
|
-
join(process.cwd(), ".pi", "agents"),
|
|
174
|
-
);
|
|
175
|
-
|
|
176
|
-
pi.registerCommand("agents", {
|
|
177
|
-
description: "Manage agents",
|
|
178
|
-
handler: async (_args, ctx) => {
|
|
179
|
-
await agentsMenu.handle({
|
|
180
|
-
ui: ctx.ui,
|
|
181
|
-
modelRegistry: ctx.modelRegistry,
|
|
182
|
-
parentSnapshot: buildParentSnapshot(ctx),
|
|
183
|
-
});
|
|
184
|
-
},
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
// ---- /subagents-settings command ----
|
|
160
|
+
// ---- /subagents:settings command ----
|
|
188
161
|
|
|
189
162
|
const subagentsSettings = new SubagentsSettingsHandler(settings);
|
|
190
163
|
|
|
191
|
-
pi.registerCommand("subagents
|
|
164
|
+
pi.registerCommand("subagents:settings", {
|
|
192
165
|
description: "Configure subagent settings (concurrency, turn limits)",
|
|
193
166
|
handler: async (_args, ctx) => {
|
|
194
167
|
await subagentsSettings.handle({ ui: ctx.ui });
|
|
195
168
|
},
|
|
196
169
|
});
|
|
197
170
|
|
|
198
|
-
// ---- /
|
|
171
|
+
// ---- /subagents:sessions command ----
|
|
199
172
|
|
|
200
173
|
const sessionNavigator = new SessionNavigatorHandler();
|
|
201
174
|
|
|
202
|
-
pi.registerCommand("
|
|
175
|
+
pi.registerCommand("subagents:sessions", {
|
|
203
176
|
description: "View a subagent's session transcript (read-only)",
|
|
204
177
|
handler: async (_args, ctx) => {
|
|
205
178
|
await sessionNavigator.handle({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* session-navigation.ts — Pure selection and transcript-sourcing for native session navigation.
|
|
3
3
|
*
|
|
4
|
-
* Splits the unit-testable core of the `/
|
|
4
|
+
* Splits the unit-testable core of the `/subagents:sessions` command from its TUI
|
|
5
5
|
* wiring (`session-navigator.ts`): which subagents are navigable and how a picked
|
|
6
6
|
* agent's transcript is sourced (live, in this slice).
|
|
7
7
|
*
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* session-navigator.ts — The `/
|
|
2
|
+
* session-navigator.ts — The `/subagents:sessions` command: pick a subagent and
|
|
3
3
|
* read its transcript through Pi's own per-entry session components.
|
|
4
4
|
*
|
|
5
5
|
* SDK/TUI consumer half of native session navigation. The unit-testable core
|
|
@@ -65,7 +65,7 @@ export interface SessionNavigatorUI {
|
|
|
65
65
|
custom<R>(component: OverlayComponentFactory<R>, options?: unknown): Promise<R>;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
/** Parameters for one `/
|
|
68
|
+
/** Parameters for one `/subagents:sessions` invocation. */
|
|
69
69
|
export interface SessionNavigatorParams {
|
|
70
70
|
ui: SessionNavigatorUI;
|
|
71
71
|
agents: readonly NavigableSubagent[];
|
|
@@ -89,7 +89,7 @@ export interface TranscriptOverlayOptions {
|
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
/**
|
|
92
|
-
* Handler for the `/
|
|
92
|
+
* Handler for the `/subagents:sessions` slash command.
|
|
93
93
|
*
|
|
94
94
|
* Lists navigable subagents, lets the operator pick one, and opens its transcript
|
|
95
95
|
* read-only. Receives the agent snapshot (`manager.listAgents()`) rather than the
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// ---- Narrow interfaces ----
|
|
2
2
|
|
|
3
|
-
/** Narrow settings interface required by the subagents
|
|
3
|
+
/** Narrow settings interface required by the subagents:settings command. */
|
|
4
4
|
export interface SubagentsSettingsManager {
|
|
5
5
|
readonly maxConcurrent: number;
|
|
6
6
|
readonly defaultMaxTurns: number | undefined;
|
|
@@ -20,7 +20,7 @@ export interface SubagentsSettingsUI {
|
|
|
20
20
|
// ---- Class ----
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
-
* Handler for the `/subagents
|
|
23
|
+
* Handler for the `/subagents:settings` slash command.
|
|
24
24
|
*
|
|
25
25
|
* Call `handle({ ui })` from the Pi command registration to open the interactive
|
|
26
26
|
* settings list. Lifted from `AgentsMenuHandler.showSettings`.
|