2.6 KiB
issue, issue_title
| issue | issue_title |
|---|---|
| 128 | refactor: extract ForwardingManager class to encapsulate polling lifecycle |
Retro: #128 — extract ForwardingManager class
Final Retrospective (2026-05-08T02:00:00Z)
Session summary
Extracted the forwarding poll lifecycle — 3 mutable fields on ExtensionRuntime and 2 free functions in runtime.ts — into a ForwardingManager class in src/forwarding-manager.ts.
Introduced a ForwardingController interface so HandlerDeps references a narrow type instead of the concrete class.
Shipped as v5.9.0 with zero behavioral change. 11 new unit tests, 3 removed; total suite 1260 tests across 57 files.
Observations
What went well
- Plan-to-code was nearly 1:1 again. The two-commit structure (new class + tests, then wiring) from the revised plan strategy worked cleanly. Both deviations were small and self-contained.
- Mechanical handler test updates were trivially correct.
Replacing
startForwardedPermissionPolling: vi.fn()/stopForwardedPermissionPolling: vi.fn()withforwarding: { start: vi.fn(), stop: vi.fn() }across 7 test files was a predictable find-and-replace. - CI stayed green throughout. No regressions in the 1260-test suite after either commit.
What caused friction (agent side)
-
missing-context— Usedvi.runAllTimersAsync()in tests forForwardingManager, which usessetInterval. This caused an infinite loop ("Aborting after running 10000 timers"). Self-identified on the first test run; fixed by switching tovi.advanceTimersByTimeAsync(250). Impact: one test edit cycle (~1 minute), no incorrect commit landed. -
missing-context— Plan specifiedreadonly forwarding: ForwardingManagerinHandlerDeps, using the concrete class type. TypeScript's structural checker requires private fields (timer,context,processing, etc.) when the target is a class, so{ start: vi.fn(), stop: vi.fn() }in test mocks failspnpm run build. Self-identified when runningpnpm run buildafter the wiring step. Fixed by extracting aForwardingControllerinterface thatForwardingManagersatisfies andHandlerDepsreferences. Impact: one additional interface + two extra edits totypes.ts, ~2 minutes of rework, no incorrect commit landed.
What caused friction (user side)
- None observed.
Changes made
- Created
docs/retro/0128-extract-forwarding-manager.md(this file). - Added fake-timer rule to
.pi/skills/testing/SKILL.md— warns againstvi.runAllTimersAsync()withsetInterval. - Added interface-over-class rule to
.pi/skills/code-style/SKILL.md— use narrow interfaces in shared dep types, not concrete classes.