@gotgenes/pi-subagents 7.8.0 → 7.8.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
CHANGED
|
@@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [7.8.1](https://github.com/gotgenes/pi-packages/compare/pi-subagents-v7.8.0...pi-subagents-v7.8.1) (2026-05-26)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Documentation
|
|
12
|
+
|
|
13
|
+
* plan reduce test duplication — top 3 clone families ([#219](https://github.com/gotgenes/pi-packages/issues/219)) ([c941b1b](https://github.com/gotgenes/pi-packages/commit/c941b1b3c047f6895eb57da3291b75082a2b99a3))
|
|
14
|
+
* **retro:** add planning stage notes for issue [#219](https://github.com/gotgenes/pi-packages/issues/219) ([5122f7c](https://github.com/gotgenes/pi-packages/commit/5122f7cd666873abbbb6b6880fffb1e751beb9b5))
|
|
15
|
+
* **retro:** add retro notes for issue [#218](https://github.com/gotgenes/pi-packages/issues/218) ([ef9187b](https://github.com/gotgenes/pi-packages/commit/ef9187ba8521d10212bd992cbfcf3d853886938b))
|
|
16
|
+
* **retro:** add TDD stage notes for issue [#219](https://github.com/gotgenes/pi-packages/issues/219) ([975f94e](https://github.com/gotgenes/pi-packages/commit/975f94e5e868310765029050490098b335a67e1e))
|
|
17
|
+
|
|
8
18
|
## [7.8.0](https://github.com/gotgenes/pi-packages/compare/pi-subagents-v7.7.0...pi-subagents-v7.8.0) (2026-05-26)
|
|
9
19
|
|
|
10
20
|
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
---
|
|
2
|
+
issue: 219
|
|
3
|
+
issue_title: "Reduce test duplication — top 3 clone families (Phase 13, Step 6)"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Reduce test duplication — top 3 clone families
|
|
7
|
+
|
|
8
|
+
## Problem statement
|
|
9
|
+
|
|
10
|
+
After Phase 12, three test files carry the heaviest remaining clone families in pi-subagents:
|
|
11
|
+
|
|
12
|
+
1. `test/lifecycle/agent-manager.test.ts` (929 lines) — 16 clone groups, ~160 duplicated lines.
|
|
13
|
+
Repeated inline runner stubs, worktree stubs, and manager-lifecycle boilerplate.
|
|
14
|
+
2. `test/conversation-viewer.test.ts` (307 lines) — 8 clone groups, ~91 duplicated lines.
|
|
15
|
+
Near-identical `ConversationViewer` construction in every test, plus repeated width-loop assertion patterns.
|
|
16
|
+
3. `test/ui/agent-config-editor.test.ts` (471 lines) — 5 clone groups, ~42 duplicated lines.
|
|
17
|
+
Repeated `makeEditor()` + `makeMenuUI()` + `fileOps.findAgentFile.mockReturnValue(...)` setup.
|
|
18
|
+
|
|
19
|
+
Total target: reduce test duplication by ~200 lines (from ~1,046 combined test-setup lines to < 850).
|
|
20
|
+
|
|
21
|
+
## Goals
|
|
22
|
+
|
|
23
|
+
- Extract shared setup and assertion helpers for the three target test files.
|
|
24
|
+
- Reduce test duplication by ~200 lines without changing test semantics.
|
|
25
|
+
- Follow the existing `test/helpers/` convention (factory + matching `.test.ts` file).
|
|
26
|
+
|
|
27
|
+
## Non-goals
|
|
28
|
+
|
|
29
|
+
- No production code changes.
|
|
30
|
+
- No new test coverage — this is purely a refactoring of existing test infrastructure.
|
|
31
|
+
- Not consolidating clone families in other test files beyond the top 3.
|
|
32
|
+
- Not changing any assertion logic or test structure beyond replacing inline stubs with factory calls.
|
|
33
|
+
|
|
34
|
+
## Background
|
|
35
|
+
|
|
36
|
+
The project already has several shared test helpers in `test/helpers/`: `make-record.ts`, `mock-session.ts`, `ui-stubs.ts`, `runner-io.ts`, `stub-ctx.ts`, `make-deps.ts`.
|
|
37
|
+
Each helper has a companion `.test.ts` file — this convention must be followed.
|
|
38
|
+
|
|
39
|
+
Dependencies #214 (closure-to-class conversions) and #216 (startAgent decomposition) are both closed, so the production code these tests cover is stable.
|
|
40
|
+
|
|
41
|
+
## Design overview
|
|
42
|
+
|
|
43
|
+
### File 1: `agent-manager.test.ts` — extract to `test/helpers/manager-stubs.ts`
|
|
44
|
+
|
|
45
|
+
Five clone families to extract:
|
|
46
|
+
|
|
47
|
+
1. **Never-resolving runner** — `{ run: vi.fn().mockImplementation(() => new Promise(() => {})), resume: vi.fn() }` appears 5 times.
|
|
48
|
+
Extract as `createBlockingRunner(): AgentRunner`.
|
|
49
|
+
|
|
50
|
+
2. **Session-creating runner** — runner that calls `opts.onSessionCreated?.(session)` and resolves.
|
|
51
|
+
Appears 5+ times with minor variations (some emit events through the session, some don't).
|
|
52
|
+
Extract as `createSessionRunner(session?: MockSession): AgentRunner` that calls `onSessionCreated` and returns a standard result.
|
|
53
|
+
|
|
54
|
+
3. **Worktree stubs with path+branch** — `{ create: vi.fn().mockReturnValue({ path, branch }), cleanup: vi.fn(() => ({ hasChanges: false })), prune: vi.fn() }` appears 4 times identically, plus 1 variant with `create` returning `undefined`.
|
|
55
|
+
Extract as `createMockWorktrees(overrides?)`.
|
|
56
|
+
|
|
57
|
+
4. **Standard run result shape** — `{ responseText: "done", session, aborted: false, steered: false }` is repeated in many runner factories.
|
|
58
|
+
Extract as `createRunResult(overrides?)`.
|
|
59
|
+
|
|
60
|
+
5. **Gated runner** — uses `Promise.withResolvers` to control when the runner completes.
|
|
61
|
+
Appears 2 times.
|
|
62
|
+
Keep inline — too tightly coupled to individual test flow-control to generalize cleanly.
|
|
63
|
+
|
|
64
|
+
Tests that construct custom runners with unique behavior (event-emitting runners in the `lifetimeUsage` and `compactionCount` tests) keep their inline stubs — those encode test-specific emission sequences that a shared factory would obscure.
|
|
65
|
+
|
|
66
|
+
### File 2: `conversation-viewer.test.ts` — inline factory + assertion helper
|
|
67
|
+
|
|
68
|
+
Two clone families to extract:
|
|
69
|
+
|
|
70
|
+
1. **`ConversationViewer` construction** — 15 near-identical constructor calls with the same 8 fields.
|
|
71
|
+
Extract as an inline `createTestViewer(overrides?)` factory at the top of the test file.
|
|
72
|
+
The factory provides defaults for `tui`, `session`, `record`, `activity`, `theme`, `done`, `registry`, and `wrapText`, and accepts overrides including a convenience `width` and `messages` parameter.
|
|
73
|
+
|
|
74
|
+
2. **Width-loop assertion** — the `for (const w of widths) { create viewer; assertAllLinesFit(viewer.render(w), w) }` pattern repeats in 10 "render width safety" tests.
|
|
75
|
+
Extract as an inline `assertRenderFitsWidths(messages, widths?, viewerOverrides?)` helper.
|
|
76
|
+
|
|
77
|
+
These helpers stay inline (not in `test/helpers/`) because they depend on file-local helpers (`mockTui`, `mockSession`, `ansiTheme`) and are only used by this one test file.
|
|
78
|
+
|
|
79
|
+
### File 3: `agent-config-editor.test.ts` — inline setup helper
|
|
80
|
+
|
|
81
|
+
One clone family to extract:
|
|
82
|
+
|
|
83
|
+
1. **Detail-test setup** — `makeEditor()` + `makeMenuUI([...])` + `fileOps.findAgentFile.mockReturnValue(...)` + optional `fileOps.read.mockReturnValue(...)` appears in ~18 tests.
|
|
84
|
+
Extract as an inline `setupDetail(selectResults, options?)` factory that returns `{ fileOps, editor, ui }` with pre-configured mocks.
|
|
85
|
+
Options: `filePath`, `fileContent`, `config` (merged into default via `createTestAgentConfig`).
|
|
86
|
+
|
|
87
|
+
This stays inline because it's specific to the `showAgentDetail` test suite and depends on file-local `testRegistry` setup.
|
|
88
|
+
|
|
89
|
+
## Module-level changes
|
|
90
|
+
|
|
91
|
+
### New files
|
|
92
|
+
|
|
93
|
+
| File | Purpose |
|
|
94
|
+
| ------------------------------------ | --------------------------------------------------------------------------------------- |
|
|
95
|
+
| `test/helpers/manager-stubs.ts` | `createBlockingRunner`, `createSessionRunner`, `createMockWorktrees`, `createRunResult` |
|
|
96
|
+
| `test/helpers/manager-stubs.test.ts` | Smoke tests for the factories |
|
|
97
|
+
|
|
98
|
+
### Modified files
|
|
99
|
+
|
|
100
|
+
| File | Change |
|
|
101
|
+
| -------------------------------------- | --------------------------------------------------------------------------- |
|
|
102
|
+
| `test/lifecycle/agent-manager.test.ts` | Replace inline runner/worktree stubs with `manager-stubs` factories |
|
|
103
|
+
| `test/conversation-viewer.test.ts` | Add `createTestViewer` + `assertRenderFitsWidths` inline, migrate all tests |
|
|
104
|
+
| `test/ui/agent-config-editor.test.ts` | Add `setupDetail` inline, migrate `showAgentDetail` tests |
|
|
105
|
+
|
|
106
|
+
### Unchanged files
|
|
107
|
+
|
|
108
|
+
No production source files are modified.
|
|
109
|
+
No other test files are modified.
|
|
110
|
+
|
|
111
|
+
## Test impact analysis
|
|
112
|
+
|
|
113
|
+
1. **New unit tests**: `manager-stubs.test.ts` adds smoke tests verifying factory return shapes (blocking runner never resolves, session runner calls `onSessionCreated`, worktree factory returns the expected interface, run result contains the correct fields).
|
|
114
|
+
2. **Simplified tests**: ~30 tests across the three files replace 3–6 lines of inline stub construction with 1-line factory calls.
|
|
115
|
+
3. **Unchanged tests**: All existing test assertions remain identical — only the setup code changes.
|
|
116
|
+
Tests with custom runner behavior (event-emitting, gated, error-throwing) keep their inline stubs.
|
|
117
|
+
|
|
118
|
+
## TDD order
|
|
119
|
+
|
|
120
|
+
1. **Create `test/helpers/manager-stubs.ts` + `manager-stubs.test.ts`** Add `createBlockingRunner`, `createSessionRunner`, `createMockWorktrees`, `createRunResult`.
|
|
121
|
+
Add smoke tests verifying each factory's return shape and basic behavior.
|
|
122
|
+
Commit: `test: add manager-stubs helper factories (#219)`
|
|
123
|
+
|
|
124
|
+
2. **Migrate `agent-manager.test.ts` to use manager-stubs** Replace 5 inline never-resolving runners with `createBlockingRunner()`.
|
|
125
|
+
Replace 4 identical worktree stubs with `createMockWorktrees()` / `createMockWorktrees({ create: ... })`.
|
|
126
|
+
Replace inline session-creating runners with `createSessionRunner(session)` where the test only needs `onSessionCreated` wiring.
|
|
127
|
+
Replace inline run-result objects with `createRunResult()` where the default shape suffices.
|
|
128
|
+
Run `pnpm vitest run test/lifecycle/agent-manager.test.ts` to verify green.
|
|
129
|
+
Commit: `test: migrate agent-manager tests to manager-stubs (#219)`
|
|
130
|
+
|
|
131
|
+
3. **Add inline factories to `conversation-viewer.test.ts` and migrate** Add `createTestViewer(overrides?)` inline factory with defaults for all 8 constructor fields.
|
|
132
|
+
Add `assertRenderFitsWidths(messages, widths?, overrides?)` inline helper.
|
|
133
|
+
Migrate all 10 "render width safety" tests to use `assertRenderFitsWidths`.
|
|
134
|
+
Migrate all 5 "safety net" tests to use `createTestViewer`.
|
|
135
|
+
Run `pnpm vitest run test/conversation-viewer.test.ts` to verify green.
|
|
136
|
+
Commit: `test: reduce conversation-viewer test duplication (#219)`
|
|
137
|
+
|
|
138
|
+
4. **Add inline `setupDetail` to `agent-config-editor.test.ts` and migrate** Add `setupDetail(selectResults, options?)` returning `{ fileOps, editor, ui }`.
|
|
139
|
+
Migrate `showAgentDetail` tests to use `setupDetail`.
|
|
140
|
+
Run `pnpm vitest run test/ui/agent-config-editor.test.ts` to verify green.
|
|
141
|
+
Commit: `test: reduce agent-config-editor test duplication (#219)`
|
|
142
|
+
|
|
143
|
+
5. **Final verification** Run `pnpm vitest run` (full suite) to confirm no regressions.
|
|
144
|
+
Run `pnpm run check` to confirm no type errors.
|
|
145
|
+
Commit is not needed — this is a verification-only step.
|
|
146
|
+
|
|
147
|
+
## Risks and mitigations
|
|
148
|
+
|
|
149
|
+
1. **Factory defaults diverge from test intent** — If a shared factory's defaults don't match what an individual test expects, assertions silently pass or fail for the wrong reason.
|
|
150
|
+
Mitigation: diff all inline stubs against the proposed factory defaults before writing the factory.
|
|
151
|
+
Keep tests with unique mock behavior inline rather than force-fitting them into a factory.
|
|
152
|
+
|
|
153
|
+
2. **Over-abstraction obscures test intent** — Extracting too many details into helpers makes tests harder to read.
|
|
154
|
+
Mitigation: only extract truly duplicated boilerplate (stub construction); keep test-specific setup and assertions inline.
|
|
155
|
+
The gated runner pattern stays inline for this reason.
|
|
156
|
+
|
|
157
|
+
3. **Intermediate broken state** — Partially migrated test files may have import conflicts.
|
|
158
|
+
Mitigation: each TDD step fully migrates one file before committing.
|
|
159
|
+
|
|
160
|
+
## Open questions
|
|
161
|
+
|
|
162
|
+
None — the issue scope is well-defined and the dependencies are resolved.
|
|
@@ -33,3 +33,40 @@ All 970 tests pass; `settings.ts` now has 0 Pi SDK imports and all `PI_CODING_AG
|
|
|
33
33
|
- **Test simplification was significant:** Removed `originalAgentDirEnv` save/restore scaffolding from 5 `describe` blocks; the test code shrank by 32 lines net.
|
|
34
34
|
- **`/nonexistent` sentinel:** Tests that construct `SettingsManager` but never call `load()` pass `agentDir: "/nonexistent"` — a clear signal the field is unused in that scope.
|
|
35
35
|
- Architecture doc Step 5 heading marked `✓` and folded into the last `feat:` commit by `pi-autoformat`.
|
|
36
|
+
|
|
37
|
+
## Stage: Final Retrospective (2026-05-26T17:22:11Z)
|
|
38
|
+
|
|
39
|
+
### Session summary
|
|
40
|
+
|
|
41
|
+
Issue #218 went from plan to shipped release (`pi-subagents-v7.8.0`) in a single continuous session.
|
|
42
|
+
Planning, TDD (2 feat commits + 1 doc commit), shipping, CI verification, issue close, and release-please merge all completed without user intervention beyond stage transitions.
|
|
43
|
+
|
|
44
|
+
### Observations
|
|
45
|
+
|
|
46
|
+
#### What went well
|
|
47
|
+
|
|
48
|
+
- **Clean mechanical execution:** The entire change was 2 production files (`settings.ts`, `index.ts`) and 1 test file, with zero unexpected test breakage and zero rework commits.
|
|
49
|
+
- **Test simplification payoff:** Removing `PI_CODING_AGENT_DIR` env var scaffolding from 5 `describe` blocks shrank the test file by 32 lines net — a tangible improvement in test readability.
|
|
50
|
+
- **Ship stage model efficiency:** The `/ship-issue` stage ran on `deepseek-v4-flash`, which was appropriate for the purely mechanical push/CI/close/merge workflow.
|
|
51
|
+
|
|
52
|
+
#### What caused friction (agent side)
|
|
53
|
+
|
|
54
|
+
1. `wrong-abstraction` — The plan split steps 1 and 2 into separate commits, but changing `loadSettings(cwd)` to `loadSettings(agentDir, cwd)` immediately broke `SettingsManager.load()` which calls it.
|
|
55
|
+
The agent recognized this during the red phase and combined them into one commit.
|
|
56
|
+
The existing testing skill rule ("When a TDD plan lists separate steps that share a type definition… fold them into one step") already covers this — the plan just didn't apply it.
|
|
57
|
+
Impact: added friction but no rework; recognized on first test run.
|
|
58
|
+
2. `missing-context` — Attempted to add `| ✓ #218 |` as an extra column to one row of the architecture doc's findings table, creating a column-count mismatch.
|
|
59
|
+
The autoformatter reverted the broken table.
|
|
60
|
+
The agent then spent ~5 tool calls (`git show --stat`, `git status`, `grep` ×2, `read`) investigating what happened before switching to the Step 5 heading approach.
|
|
61
|
+
Impact: ~2 minutes of investigation; no rework beyond the heading edit.
|
|
62
|
+
|
|
63
|
+
#### What caused friction (user side)
|
|
64
|
+
|
|
65
|
+
- The user asked "Are we ready for shipping?"
|
|
66
|
+
which surfaced that the TDD retro stage notes were still uncommitted.
|
|
67
|
+
This was a useful checkpoint — the ship stage committed them before pushing.
|
|
68
|
+
Opportunity: the `/tdd-plan` prompt could commit retro notes as part of its final step, but the current flow (write notes, then commit in ship) is lightweight enough that enforcing it would add complexity for marginal gain.
|
|
69
|
+
|
|
70
|
+
### Changes made
|
|
71
|
+
|
|
72
|
+
1. Retro file updated at `packages/pi-subagents/docs/retro/0218-push-sdk-boundary-in-settings.md` — no other files changed.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
issue: 219
|
|
3
|
+
issue_title: "Reduce test duplication — top 3 clone families (Phase 13, Step 6)"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Retro: #219 — Reduce test duplication — top 3 clone families
|
|
7
|
+
|
|
8
|
+
## Stage: Planning (2026-05-26T20:00:00Z)
|
|
9
|
+
|
|
10
|
+
### Session summary
|
|
11
|
+
|
|
12
|
+
Analyzed duplication patterns in the three target test files (`agent-manager.test.ts`, `conversation-viewer.test.ts`, `agent-config-editor.test.ts`).
|
|
13
|
+
Produced a 5-step TDD plan with shared `manager-stubs.ts` helper for runner/worktree factories, plus inline factories for the two UI test files.
|
|
14
|
+
|
|
15
|
+
### Observations
|
|
16
|
+
|
|
17
|
+
- The agent-manager test has the most diverse clone families (runner stubs, worktree stubs, run-result shapes) — these benefit from a shared helper file since the patterns are reused across 15+ describe blocks.
|
|
18
|
+
- The conversation-viewer and config-editor duplication is more localized — inline factories within each test file are the right granularity to avoid over-extraction.
|
|
19
|
+
- Gated runners (using `Promise.withResolvers`) were deliberately kept inline since they encode test-specific flow control that a factory would obscure.
|
|
20
|
+
- Both dependencies (#214, #216) are closed, so the production code is stable and the tests won't shift under us during implementation.
|
|
21
|
+
|
|
22
|
+
## Stage: Implementation — TDD (2026-05-26T17:42:41Z)
|
|
23
|
+
|
|
24
|
+
### Session summary
|
|
25
|
+
|
|
26
|
+
Completed all 4 TDD cycles: created `test/helpers/manager-stubs.ts` + `manager-stubs.test.ts` (13 smoke tests), migrated `agent-manager.test.ts`, `conversation-viewer.test.ts`, and `agent-config-editor.test.ts`.
|
|
27
|
+
Test count delta: 970 → 983 (+13 from smoke tests).
|
|
28
|
+
All 4 commits landed cleanly; full suite green at every step.
|
|
29
|
+
|
|
30
|
+
### Observations
|
|
31
|
+
|
|
32
|
+
- Target file line savings: `agent-manager.test.ts` −63, `conversation-viewer.test.ts` −58, `agent-config-editor.test.ts` −16; offset by +211 for the new helper files.
|
|
33
|
+
Net LOC is positive, but the _clone_ lines fallow detects are eliminated — the metric the issue targets.
|
|
34
|
+
- The `createSessionRunner` + `createRunResult` chain required careful identity-check verification: `createRunResult(sess)` calls `toAgentSession(sess)` which casts without creating a new object, so `toBe(session)` assertions in the execution-state tests still pass. ✓
|
|
35
|
+
- ESLint auto-fixed two cosmetic issues on commit (`activity = undefined` → `activity` destructuring, `session as unknown` cast removal) — caught by pre-commit hooks, not a problem in practice.
|
|
36
|
+
- The `assertRenderFitsWidths` helper in `conversation-viewer.test.ts` reduced the 10 render-safety tests from ~8 lines each to 1–4 lines each; the `setupDetail` helper in `agent-config-editor.test.ts` eliminated 3 repeated setup lines per test across 18 `showAgentDetail` tests.
|