mirror of
https://bitbucket.org/siakitem/my-pi.git
synced 2026-08-28 08:35:57 +00:00
51 lines
3.0 KiB
Markdown
51 lines
3.0 KiB
Markdown
---
|
|
issue: 43
|
|
issue_title: "Eliminate module-scope mutable state and cached getAgentDir() in src/index.ts"
|
|
---
|
|
|
|
# Retro: #43 — Eliminate module-scope mutable state
|
|
|
|
## Final Retrospective (2026-05-03T19:04:00Z)
|
|
|
|
### Session summary
|
|
|
|
Replaced all module-scope mutable state in `src/index.ts` (cached `getAgentDir()` paths, mutable config, logger singletons, setter-injection functions) with an `ExtensionRuntime` context object created at factory invocation time.
|
|
`src/index.ts` went from 466 → 99 lines; `src/runtime.ts` (318 lines) now holds the runtime interface, factory, and all relocated helpers.
|
|
The forwarded-permissions IO module was also refactored to accept an explicit logger parameter instead of using a module-scope singleton.
|
|
|
|
### Observations
|
|
|
|
#### What went well
|
|
|
|
- The 7-step TDD sequence from the plan executed cleanly — each commit was independently valid and the full test suite stayed green throughout.
|
|
The plan's decision to add `runtime` to `HandlerDeps` alongside the old stubs (step 3) before removing the stubs (step 4) allowed both phases to compile and test independently.
|
|
- The `createExtensionRuntime({ agentDir: tmpDir })` pattern immediately proved its value: 29 tests in `tests/runtime.test.ts` exercise the runtime in isolation without any `PI_CODING_AGENT_DIR` timing hacks.
|
|
- Forwarded-permissions logger threading touched 30+ call sites but landed in a single clean commit with no rework — the mechanical nature of "prepend logger parameter" made it safe to do in bulk.
|
|
|
|
#### What caused friction (agent side)
|
|
|
|
1. `missing-context` — Used `vi.fn(() => ({}))` to mock `PermissionManager` constructor in `tests/runtime.test.ts`.
|
|
Arrow functions are not constructable, so `new PermissionManager()` threw `"() => ({}) is not a constructor"`.
|
|
The same pattern caused friction in #42.
|
|
Impact: 1 failed test run + 1 edit to fix; added friction but no rework beyond the immediate fix.
|
|
Self-identified.
|
|
|
|
2. `missing-context` — Wrote `await import("../src/permission-manager")` inside non-async `it()` callbacks in step 2 tests for `createPermissionManagerForCwd`.
|
|
Biome flagged `await` outside async function.
|
|
Impact: 1 failed lint + 1 edit to switch to a static top-level import of the already-mocked `PermissionManager`.
|
|
Self-identified.
|
|
|
|
3. `wrong-abstraction` — The plan's step 3 ("update test mocks") and step 4 ("update handlers + type") were described as sequential, but TypeScript rejects extra properties on typed object literals, so `runtime` couldn't be added to test mocks until `HandlerDeps` declared the field.
|
|
The solution was to add `runtime` to `HandlerDeps` (with old stubs still present) in step 3, making the type change part of the same commit.
|
|
Impact: minor plan deviation but no rework — the commit sequence remained valid.
|
|
Self-identified.
|
|
|
|
#### What caused friction (user side)
|
|
|
|
- Nothing notable.
|
|
The user provided a clear plan, and the session ran without corrections or redirections.
|
|
|
|
### Changes made
|
|
|
|
1. Added class-constructor mocking rule to `AGENTS.md` § Testing.
|