@gotgenes/pi-autoformat 0.1.0 → 4.0.3
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/.github/workflows/ci.yml +1 -3
- package/.github/workflows/release-please.yml +29 -0
- package/.markdownlint-cli2.yaml +14 -2
- package/.pi/extensions/pi-autoformat/config.json +3 -6
- package/.pi/prompts/README.md +59 -0
- package/.pi/prompts/plan-issue.md +64 -0
- package/.pi/prompts/retro.md +144 -0
- package/.pi/prompts/ship-issue.md +77 -0
- package/.pi/prompts/tdd-plan.md +67 -0
- package/.pi/skills/pi-extension-lifecycle/SKILL.md +256 -0
- package/.release-please-manifest.json +1 -1
- package/AGENTS.md +39 -0
- package/CHANGELOG.md +365 -0
- package/README.md +42 -109
- package/biome.json +1 -1
- package/docs/assets/logo.png +0 -0
- package/docs/assets/logo.svg +533 -0
- package/docs/configuration.md +358 -38
- package/docs/plans/0001-initial-implementation-plan.md +17 -9
- package/docs/plans/0002-richer-tui-formatter-summaries.md +220 -0
- package/docs/plans/0003-additional-pi-mutation-tools.md +273 -0
- package/docs/plans/0004-shell-driven-mutation-coverage.md +296 -0
- package/docs/plans/0010-acceptance-test-coverage.md +240 -0
- package/docs/plans/0012-remove-unused-formatter-extensions-field.md +152 -0
- package/docs/plans/0013-fallback-chain-step-type.md +280 -0
- package/docs/plans/0014-batch-by-default-formatter-dispatch.md +195 -0
- package/docs/plans/0015-builtin-treefmt-and-treefmt-nix-support.md +290 -0
- package/docs/plans/0016-detailed-formatter-output-on-failure.md +245 -0
- package/docs/plans/0022-pi-coding-agent-types.md +201 -0
- package/docs/plans/0027-format-before-agent-exit-follow-up-turn.md +355 -0
- package/docs/plans/0031-turn-end-flush-with-change-detection.md +365 -0
- package/docs/retro/0002-richer-tui-formatter-summaries.md +47 -0
- package/docs/retro/0013-fallback-chain-step-type.md +67 -0
- package/docs/retro/0015-builtin-treefmt-and-treefmt-nix-support.md +56 -0
- package/docs/retro/0016-detailed-formatter-output-on-failure.md +60 -0
- package/docs/retro/0022-pi-coding-agent-types.md +62 -0
- package/docs/testing.md +95 -0
- package/package.json +30 -11
- package/prek.toml +2 -2
- package/schemas/pi-autoformat.schema.json +145 -21
- package/src/builtin-formatters.ts +205 -0
- package/src/command-probe.ts +66 -0
- package/src/config-loader.ts +829 -90
- package/src/custom-mutation-tools.ts +125 -0
- package/src/extension.ts +469 -82
- package/src/format-scope.ts +118 -0
- package/src/formatter-config.ts +73 -36
- package/src/formatter-executor.ts +230 -34
- package/src/formatter-output-report.ts +149 -0
- package/src/formatter-registry.ts +139 -30
- package/src/index.ts +26 -5
- package/src/prompt-autoformatter.ts +148 -23
- package/src/shell-mutation-detector.ts +572 -0
- package/src/touched-files-queue.ts +72 -11
- package/test/acceptance-event-bus.test.ts +138 -0
- package/test/acceptance.test.ts +69 -0
- package/test/builtin-formatters.test.ts +382 -0
- package/test/command-probe.test.ts +79 -0
- package/test/config-loader.test.ts +640 -21
- package/test/custom-mutation-tools.test.ts +190 -0
- package/test/extension.test.ts +1535 -158
- package/test/fallback-acceptance.test.ts +98 -0
- package/test/fixtures/event-bus-emitter.ts +26 -0
- package/test/fixtures/formatter-recorder.mjs +25 -0
- package/test/format-scope.test.ts +139 -0
- package/test/formatter-config.test.ts +56 -5
- package/test/formatter-executor.test.ts +555 -35
- package/test/formatter-output-report.test.ts +178 -0
- package/test/formatter-registry.test.ts +330 -37
- package/test/helpers/rpc.ts +146 -0
- package/test/prompt-autoformatter.test.ts +315 -22
- package/test/schema.test.ts +149 -0
- package/test/shell-mutation-detector.test.ts +221 -0
- package/test/touched-files-queue.test.ts +40 -1
- package/test/types/theme-stub.test-d.ts +42 -0
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
---
|
|
2
|
+
issue: 31
|
|
3
|
+
issue_title: "Pre-commit flush: format touched files before agent-initiated git commits"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Turn-end flush with change detection
|
|
7
|
+
|
|
8
|
+
## Problem Statement
|
|
9
|
+
|
|
10
|
+
pi-autoformat runs its formatter flush at `agent_end`, which fires after the agent's full turn loop completes.
|
|
11
|
+
In TDD and commit-heavy workflows, the agent writes files in one turn and commits them in a later turn.
|
|
12
|
+
Because formatting has not yet run, pre-commit hooks (e.g. Biome via prek) reject the commit.
|
|
13
|
+
The agent then has to run the formatter manually, re-stage, and retry — wasting tokens and time.
|
|
14
|
+
|
|
15
|
+
Observed in `pi-permission-system`: 3 of ~10 commits required retry after Biome rejection.
|
|
16
|
+
|
|
17
|
+
The typical pattern across 4,925 analysed turns:
|
|
18
|
+
|
|
19
|
+
```text
|
|
20
|
+
Turn N: edit src/foo.ts (single tool call)
|
|
21
|
+
Turn N+1: edit src/bar.ts (single tool call)
|
|
22
|
+
Turn N+2: bash("git add ... \n git commit -m '...'")
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
93.4% of turns contain exactly one tool call.
|
|
26
|
+
Writes and commits always occur in separate turns.
|
|
27
|
+
Zero instances of same-file edits within a single turn were found across all session data.
|
|
28
|
+
|
|
29
|
+
## Goals
|
|
30
|
+
|
|
31
|
+
1. Move the primary formatter flush from `agent_end` to `turn_end` so files are formatted between turns — before any subsequent commit.
|
|
32
|
+
2. Detect whether formatting actually changed file content (content hashing before/after) and only notify the agent when changes occurred or the formatter failed.
|
|
33
|
+
3. Notify the agent inline via a steering message (`pi.sendMessage` during streaming) so it sees the notification before its next LLM call.
|
|
34
|
+
4. Remove the `notifyAgent` config field; turn-end steering replaces the `agent_end` follow-up turn mechanism.
|
|
35
|
+
5. Keep `agent_end` as a safety-net flush for any files not yet formatted (e.g. files added via EventBus without a turn loop).
|
|
36
|
+
|
|
37
|
+
## Non-Goals
|
|
38
|
+
|
|
39
|
+
1. Re-staging formatted files in the git index — session data shows `git add` and `git commit` always share the same bash command, run in a turn after formatting has already occurred.
|
|
40
|
+
2. Command detection for `git commit` at `tool_call` — the turn-end flush makes this unnecessary; the intra-turn write+commit pattern has never occurred in session data.
|
|
41
|
+
3. Exposing an explicit flush tool or slash command for agents.
|
|
42
|
+
4. Byte-level diffs or line-change summaries in the notification — file names and failure details are sufficient.
|
|
43
|
+
|
|
44
|
+
## Background
|
|
45
|
+
|
|
46
|
+
### Session data analysis
|
|
47
|
+
|
|
48
|
+
| Metric | Count | % |
|
|
49
|
+
| --- | --- | --- |
|
|
50
|
+
| Total turns with tools | 4,925 | 100% |
|
|
51
|
+
| Single-tool turns | 4,515 | 91.7% |
|
|
52
|
+
| Multi-tool turns | 410 | 8.3% |
|
|
53
|
+
| Same-file edits in same turn | 0 | 0% |
|
|
54
|
+
| Read-after-write to same file in same turn | 0 | 0% |
|
|
55
|
+
| Write + git commit in same turn | 0 | 0% |
|
|
56
|
+
|
|
57
|
+
The original argument against per-turn formatting was that it could corrupt `Edit` tool `oldText` matching or `Read` tool `offset`/`limit` when a formatter changes a file between two tool calls targeting the same file within a turn.
|
|
58
|
+
The session data shows this scenario has never occurred.
|
|
59
|
+
|
|
60
|
+
### Pi agent loop lifecycle (from source)
|
|
61
|
+
|
|
62
|
+
```text
|
|
63
|
+
OUTER LOOP:
|
|
64
|
+
INNER LOOP (while hasMoreToolCalls || pendingMessages):
|
|
65
|
+
turn_start
|
|
66
|
+
process pendingMessages (steering messages from previous turn)
|
|
67
|
+
LLM generates response
|
|
68
|
+
execute tool calls sequentially:
|
|
69
|
+
beforeToolCall → tool runs → afterToolCall (tool_result)
|
|
70
|
+
turn_end ← FLUSH HERE, send steering message if changes
|
|
71
|
+
shouldStopAfterTurn? (not used by coding-agent)
|
|
72
|
+
pendingMessages = getSteeringMessages() ← PICKS UP OUR MESSAGE
|
|
73
|
+
END INNER LOOP
|
|
74
|
+
|
|
75
|
+
followUpMessages = getFollowUpMessages()
|
|
76
|
+
if followUp → continue outer loop
|
|
77
|
+
else → break
|
|
78
|
+
agent_end ← SAFETY-NET FLUSH
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Key properties:
|
|
82
|
+
|
|
83
|
+
- `turn_end` is fully `await`ed before the next `turn_start`.
|
|
84
|
+
- During the turn loop, `isStreaming` is `true`; `pi.sendMessage()` defaults to `agent.steer()`.
|
|
85
|
+
- Steering messages are consumed as `pendingMessages` at the start of the next turn, injected before the LLM call.
|
|
86
|
+
- When the agent's final turn has no tool calls (text-only), the queue is empty, so the turn-end flush is a no-op and no steering message is sent.
|
|
87
|
+
|
|
88
|
+
### Relevant modules
|
|
89
|
+
|
|
90
|
+
| Module | Role |
|
|
91
|
+
| --- | --- |
|
|
92
|
+
| `src/extension.ts` | Extension entrypoint. Lifecycle handlers for `session_start`, `tool_call`, `tool_result`, `agent_end`, `session_shutdown`. Owns `queueFlush()` and reporting. |
|
|
93
|
+
| `src/prompt-autoformatter.ts` | `PromptAutoformatter` class. `flushPrompt()` drains the touched-file queue and runs formatter chains. |
|
|
94
|
+
| `src/formatter-executor.ts` | `BatchRun` type with `stdout`, `stderr`, `exitCode`. Runs formatter commands. |
|
|
95
|
+
| `src/formatter-config.ts` | `AutoformatConfig` with `notifyAgent` boolean (to be removed). `UserFormatterConfig`. |
|
|
96
|
+
| `src/config-loader.ts` | Loads/merges config, validates fields. |
|
|
97
|
+
| `schemas/pi-autoformat.schema.json` | JSON Schema for config validation. |
|
|
98
|
+
| `docs/configuration.md` | User-facing config documentation. |
|
|
99
|
+
| `test/extension.test.ts` | Extension lifecycle tests with `TestPi` harness. |
|
|
100
|
+
|
|
101
|
+
### Relationship to plan 0027
|
|
102
|
+
|
|
103
|
+
Plan 0027 introduced `notifyAgent` (default `false`), which sends a follow-up turn at `agent_end` via `pi.sendMessage({ triggerTurn: true })`.
|
|
104
|
+
This plan replaces that mechanism: formatting moves to `turn_end` with inline steering, making the `agent_end` follow-up unnecessary.
|
|
105
|
+
The `notifyAgent` field is removed per the deprecation policy in AGENTS.md.
|
|
106
|
+
|
|
107
|
+
## Design Overview
|
|
108
|
+
|
|
109
|
+
### Flush at `turn_end`
|
|
110
|
+
|
|
111
|
+
Register a new `turn_end` handler in `src/extension.ts`.
|
|
112
|
+
On each `turn_end` event, call `queueFlush(ctx)`.
|
|
113
|
+
The queue contains files recorded during the turn's `tool_result` events.
|
|
114
|
+
After the flush, the queue is empty; the next turn starts with clean files on disk.
|
|
115
|
+
|
|
116
|
+
### Content-change detection
|
|
117
|
+
|
|
118
|
+
Wrap the formatter execution with before/after content hashing to determine which files were actually changed.
|
|
119
|
+
|
|
120
|
+
Add a `changedFiles` field to `ChainGroupResult`:
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
export type ChainGroupResult = {
|
|
124
|
+
chain: ChainStep[];
|
|
125
|
+
files: string[];
|
|
126
|
+
runs: BatchRun[];
|
|
127
|
+
changedFiles: string[]; // files whose content changed after formatting
|
|
128
|
+
};
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
In `flushPrompt()`, before running each chain group's formatter:
|
|
132
|
+
|
|
133
|
+
1. Read and hash (SHA-256) each input file.
|
|
134
|
+
2. Run the formatter.
|
|
135
|
+
3. Re-read and hash each file.
|
|
136
|
+
4. Populate `changedFiles` with files whose hash differs.
|
|
137
|
+
|
|
138
|
+
Files that no longer exist after formatting (deleted by the formatter — unusual but possible) are excluded from `changedFiles`.
|
|
139
|
+
|
|
140
|
+
The hashing cost is 2× reads per formatted file.
|
|
141
|
+
These files are small source files already in the OS page cache (just written by the agent moments ago), so the overhead is negligible.
|
|
142
|
+
|
|
143
|
+
### Steering notification
|
|
144
|
+
|
|
145
|
+
After the flush, if any files changed or any run failed, compose a steering message and call `pi.sendMessage()`.
|
|
146
|
+
During the turn loop, `isStreaming` is `true`, so `sendMessage` defaults to `agent.steer()`.
|
|
147
|
+
The message is consumed as `pendingMessages` at the start of the next turn.
|
|
148
|
+
|
|
149
|
+
Message format:
|
|
150
|
+
|
|
151
|
+
```text
|
|
152
|
+
[autoformat] Formatted 2 file(s): src/foo.ts, src/bar.ts
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
When there are failures:
|
|
156
|
+
|
|
157
|
+
```text
|
|
158
|
+
[autoformat] Formatted 1 file(s): src/foo.ts
|
|
159
|
+
|
|
160
|
+
Failures:
|
|
161
|
+
biome (exit 1) on src/broken.ts:
|
|
162
|
+
SyntaxError: Unexpected token at line 42
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
When only failures (no successful changes):
|
|
166
|
+
|
|
167
|
+
```text
|
|
168
|
+
[autoformat] Failures:
|
|
169
|
+
biome (exit 1) on src/broken.ts:
|
|
170
|
+
SyntaxError: Unexpected token at line 42
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
File list truncated at 10 with "… and N more" suffix.
|
|
174
|
+
Failure details use the existing `formatterOutput` config limits.
|
|
175
|
+
|
|
176
|
+
No message is sent when:
|
|
177
|
+
|
|
178
|
+
- The flush processed no files (empty queue).
|
|
179
|
+
- The formatter ran but no files changed and no runs failed.
|
|
180
|
+
|
|
181
|
+
### Removing `notifyAgent`
|
|
182
|
+
|
|
183
|
+
Per AGENTS.md deprecation policy:
|
|
184
|
+
|
|
185
|
+
- Remove `notifyAgent` from `AutoformatConfig`, `UserFormatterConfig`, `createFormatterConfig()`.
|
|
186
|
+
- Remove from `schemas/pi-autoformat.schema.json` and `docs/configuration.md`.
|
|
187
|
+
- In `src/config-loader.ts`: when `notifyAgent` key is present, emit a config issue (`notifyAgent has been removed; the extension now notifies via steering messages at turn end.`) and discard.
|
|
188
|
+
- Remove the `agent_end` follow-up turn logic (`followUpPending`, `buildNotifyMessageContent`, `pi.sendMessage({ triggerTurn: true })`).
|
|
189
|
+
- Remove `followUpPending` from `SessionState`.
|
|
190
|
+
|
|
191
|
+
### `agent_end` safety net
|
|
192
|
+
|
|
193
|
+
The `agent_end` handler still calls `queueFlush(ctx)` as a safety net for files added via EventBus or other non-turn paths.
|
|
194
|
+
It no longer sends follow-up turns.
|
|
195
|
+
In the normal case, `turn_end` has already drained the queue, so the `agent_end` flush is a no-op.
|
|
196
|
+
|
|
197
|
+
### `TestPi` harness changes
|
|
198
|
+
|
|
199
|
+
Add `turn_end` to the `EventName` type.
|
|
200
|
+
Keep `sendMessage` capture for steering-message assertions.
|
|
201
|
+
|
|
202
|
+
## Module-Level Changes
|
|
203
|
+
|
|
204
|
+
### `src/prompt-autoformatter.ts`
|
|
205
|
+
|
|
206
|
+
1. Add `changedFiles: string[]` to `ChainGroupResult`.
|
|
207
|
+
2. In `flushPrompt()`, hash file contents before and after each chain group execution.
|
|
208
|
+
3. Populate `changedFiles` by comparing hashes.
|
|
209
|
+
|
|
210
|
+
### `src/formatter-config.ts`
|
|
211
|
+
|
|
212
|
+
1. Remove `notifyAgent` from `UserFormatterConfig` and `AutoformatConfig`.
|
|
213
|
+
2. Remove from `DEFAULT_FORMATTER_CONFIG`.
|
|
214
|
+
3. Remove from `createFormatterConfig()`.
|
|
215
|
+
|
|
216
|
+
### `src/config-loader.ts`
|
|
217
|
+
|
|
218
|
+
1. When `notifyAgent` key is present in user config, emit a config issue and discard.
|
|
219
|
+
2. Remove `notifyAgent` validation logic.
|
|
220
|
+
|
|
221
|
+
### `schemas/pi-autoformat.schema.json`
|
|
222
|
+
|
|
223
|
+
1. Remove `notifyAgent` property.
|
|
224
|
+
|
|
225
|
+
### `src/extension.ts`
|
|
226
|
+
|
|
227
|
+
1. Add a `turn_end` handler that calls `queueFlush(ctx)` and, if the result has changes or failures, sends a steering message via `pi.sendMessage()`.
|
|
228
|
+
2. Extract `buildSteeringMessageContent(result): string | undefined` helper (replaces `buildNotifyMessageContent`).
|
|
229
|
+
3. Simplify `agent_end` handler: remove `followUpPending` logic, keep safety-net flush only.
|
|
230
|
+
4. Remove `followUpPending` from `SessionState`.
|
|
231
|
+
5. Remove `buildNotifyMessageContent` (replaced by `buildSteeringMessageContent`).
|
|
232
|
+
6. Update `queueFlush` return type if needed to propagate the result for steering decisions.
|
|
233
|
+
|
|
234
|
+
### `docs/configuration.md`
|
|
235
|
+
|
|
236
|
+
1. Remove `notifyAgent` section.
|
|
237
|
+
2. Add a section explaining turn-end formatting and steering notifications.
|
|
238
|
+
|
|
239
|
+
### `README.md`
|
|
240
|
+
|
|
241
|
+
1. Remove `notifyAgent` references.
|
|
242
|
+
2. Update description of formatting timing.
|
|
243
|
+
|
|
244
|
+
### `test/extension.test.ts`
|
|
245
|
+
|
|
246
|
+
1. Add `turn_end` to `EventName` type in `TestPi`.
|
|
247
|
+
2. Add tests for turn-end flush behavior.
|
|
248
|
+
3. Add tests for steering message on file changes.
|
|
249
|
+
4. Add tests for no steering message when no changes.
|
|
250
|
+
5. Add tests for steering message on formatter failure.
|
|
251
|
+
6. Remove `notifyAgent`-specific tests (follow-up turn, loop guard, etc.).
|
|
252
|
+
7. Update `createLoadResult` helper to drop `notifyAgent`.
|
|
253
|
+
|
|
254
|
+
### `test/prompt-autoformatter.test.ts`
|
|
255
|
+
|
|
256
|
+
1. Add tests for `changedFiles` population in `ChainGroupResult`.
|
|
257
|
+
2. Test that unchanged files are not in `changedFiles`.
|
|
258
|
+
3. Test that failed runs do not populate `changedFiles` (or populate correctly depending on behavior).
|
|
259
|
+
|
|
260
|
+
### `test/config-loader.test.ts`
|
|
261
|
+
|
|
262
|
+
1. Add test for legacy `notifyAgent` key producing a config issue.
|
|
263
|
+
2. Remove `notifyAgent` validation tests.
|
|
264
|
+
|
|
265
|
+
## TDD Order
|
|
266
|
+
|
|
267
|
+
### 1. Content-change detection in `flushPrompt`
|
|
268
|
+
|
|
269
|
+
- **Test surface:** `test/prompt-autoformatter.test.ts`.
|
|
270
|
+
- **Covers:** `changedFiles` populated when formatter changes file content. Empty when formatter is a no-op. Files that don't exist after formatting are excluded.
|
|
271
|
+
- **Commit:** `feat: detect content changes in flushPrompt (#31)`
|
|
272
|
+
|
|
273
|
+
### 2. Remove `notifyAgent` from config types and defaults
|
|
274
|
+
|
|
275
|
+
- **Test surface:** `test/formatter-config.test.ts`, `test/config-loader.test.ts`.
|
|
276
|
+
- **Covers:** `notifyAgent` removed from types; `createFormatterConfig()` no longer accepts it. Legacy key in config emits a config issue and is discarded.
|
|
277
|
+
- **Commit:** `feat!: remove notifyAgent config field (#31)`
|
|
278
|
+
|
|
279
|
+
### 3. Remove `notifyAgent` from JSON schema and docs
|
|
280
|
+
|
|
281
|
+
- **Test surface:** `test/schema.test.ts`, manual review.
|
|
282
|
+
- **Covers:** Schema no longer includes `notifyAgent`. Docs updated.
|
|
283
|
+
- **Commit:** `feat!: remove notifyAgent from schema and docs (#31)`
|
|
284
|
+
|
|
285
|
+
### 4. Steering message builder
|
|
286
|
+
|
|
287
|
+
- **Test surface:** `test/extension.test.ts`.
|
|
288
|
+
- **Covers:** Message with 1 changed file, 3 changed files, 11 files (truncation). Message with failures. Message with mixed changes + failures. Returns `undefined` when no changes and no failures.
|
|
289
|
+
- **Commit:** `feat: add buildSteeringMessageContent helper (#31)`
|
|
290
|
+
|
|
291
|
+
### 5. Turn-end flush handler
|
|
292
|
+
|
|
293
|
+
- **Test surface:** `test/extension.test.ts`.
|
|
294
|
+
- **Covers:** `turn_end` event triggers flush. Files recorded in `tool_result` are formatted at `turn_end`. Queue is empty after flush.
|
|
295
|
+
- **Commit:** `feat: flush formatters at turn_end (#31)`
|
|
296
|
+
|
|
297
|
+
### 6. Steering notification on change
|
|
298
|
+
|
|
299
|
+
- **Test surface:** `test/extension.test.ts`.
|
|
300
|
+
- **Covers:** When flush changes files, `pi.sendMessage` is called with steering content. When flush is a no-op (no changes, no failures), no message is sent.
|
|
301
|
+
- **Commit:** `feat: send steering notification after turn-end formatting (#31)`
|
|
302
|
+
|
|
303
|
+
### 7. Steering notification on failure
|
|
304
|
+
|
|
305
|
+
- **Test surface:** `test/extension.test.ts`.
|
|
306
|
+
- **Covers:** When a formatter run fails, steering message includes failure details (stderr, exit code).
|
|
307
|
+
- **Commit:** `feat: include failure details in steering notification (#31)`
|
|
308
|
+
|
|
309
|
+
### 8. Remove `agent_end` follow-up turn logic
|
|
310
|
+
|
|
311
|
+
- **Test surface:** `test/extension.test.ts`.
|
|
312
|
+
- **Covers:** `agent_end` handler no longer calls `pi.sendMessage`. `followUpPending` removed from `SessionState`. `agent_end` still calls safety-net `queueFlush`.
|
|
313
|
+
- **Commit:** `feat!: replace agent_end follow-up with turn-end steering (#31)`
|
|
314
|
+
|
|
315
|
+
### 9. Agent-end safety-net flush
|
|
316
|
+
|
|
317
|
+
- **Test surface:** `test/extension.test.ts`.
|
|
318
|
+
- **Covers:** Files added via EventBus (no turn loop) are formatted at `agent_end`. Files already flushed at `turn_end` are not re-formatted at `agent_end`.
|
|
319
|
+
- **Commit:** `test: agent_end safety-net flush (#31)`
|
|
320
|
+
|
|
321
|
+
### 10. Documentation
|
|
322
|
+
|
|
323
|
+
- **Test surface:** Manual review.
|
|
324
|
+
- **Covers:** `docs/configuration.md` updated. `README.md` updated.
|
|
325
|
+
- **Commit:** `docs: document turn-end formatting and steering notifications (#31)`
|
|
326
|
+
|
|
327
|
+
## Risks and Mitigations
|
|
328
|
+
|
|
329
|
+
### Formatter latency between turns
|
|
330
|
+
|
|
331
|
+
Formatting at `turn_end` adds latency between turns — the agent waits for the formatter before its next LLM call.
|
|
332
|
+
Mitigation: most turns have 1-3 touched files; formatter runs are typically sub-second.
|
|
333
|
+
The existing `commandTimeoutMs` config prevents hangs.
|
|
334
|
+
|
|
335
|
+
### Steering message noise
|
|
336
|
+
|
|
337
|
+
Even with change detection, active editing sessions may produce frequent "Formatted X" messages.
|
|
338
|
+
Mitigation: messages are only sent when content actually changed or a formatter failed.
|
|
339
|
+
During long edit streaks where the agent writes already-formatted code, no messages are sent.
|
|
340
|
+
|
|
341
|
+
### File I/O from content hashing
|
|
342
|
+
|
|
343
|
+
Reading files before and after formatting doubles the I/O per formatted file.
|
|
344
|
+
Mitigation: files are small source files already in the OS page cache.
|
|
345
|
+
The hash computation (SHA-256) is negligible for typical file sizes.
|
|
346
|
+
|
|
347
|
+
### Breaking change: `notifyAgent` removal
|
|
348
|
+
|
|
349
|
+
Users who set `notifyAgent: true` will see a config issue.
|
|
350
|
+
Mitigation: the replacement (turn-end steering) provides strictly better behavior — inline notification during the turn rather than a follow-up turn after the agent finishes.
|
|
351
|
+
The deprecation policy (accept, warn, discard) ensures no hard failure.
|
|
352
|
+
|
|
353
|
+
### `turn_end` not firing for non-turn paths
|
|
354
|
+
|
|
355
|
+
Files added via EventBus or `session_shutdown` never pass through `turn_end`.
|
|
356
|
+
Mitigation: `agent_end` and `session_shutdown` safety-net flushes handle these paths.
|
|
357
|
+
|
|
358
|
+
## Open Questions
|
|
359
|
+
|
|
360
|
+
1. Should the steering message include which formatter ran (e.g. "biome formatted src/foo.ts") or just the file list?
|
|
361
|
+
Start with the file list; add formatter names if users find it useful.
|
|
362
|
+
|
|
363
|
+
2. Should there be a config to disable turn-end formatting entirely (revert to agent-end-only)?
|
|
364
|
+
Defer until someone needs it.
|
|
365
|
+
If needed, the implementation can gate the `turn_end` flush behind a boolean.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
issue: 1
|
|
3
|
+
issue_title: "Add richer TUI formatter summaries"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Retro: #1 — Add richer TUI formatter summaries
|
|
7
|
+
|
|
8
|
+
## Final Retrospective (2026-05-02T01:09:19Z)
|
|
9
|
+
|
|
10
|
+
### Session summary
|
|
11
|
+
|
|
12
|
+
Planned, implemented, shipped, and released `2.2.0` for issue #1.
|
|
13
|
+
Replaced transient success toasts with a persistent themed `setStatus("autoformat", ...)` footer line; failures keep the warning toast and additionally leave an error-styled status that survives until the next flush.
|
|
14
|
+
Seven TDD commits plus a docs commit landed cleanly; CI green; release-please PR `#19` merged.
|
|
15
|
+
|
|
16
|
+
### Observations
|
|
17
|
+
|
|
18
|
+
#### What went well
|
|
19
|
+
|
|
20
|
+
- TDD execution was unusually clean — seven cycles (`4d4fb8c` → `9a10d59`), every commit green, the one minor deviation (folding step 1's minimal impl into its own test commit so `main` never carried a failing test) was noted and within the slash-command's deviation guidance.
|
|
21
|
+
- The lint-fixup split worked correctly: `pnpm run lint:fix` touched both source and docs files; `src/extension.ts` + `test/extension.test.ts` fixups were amended into the most recent `test:` commit and the `docs:` commit stayed docs-only, per the slash-command rule.
|
|
22
|
+
- `/plan-issue`'s "Decide" step did its job — first `ask_user` surfaced that the issue was exploratory, second `ask_user` (after researching the actual Pi UI surface) converged on a concrete, shippable direction in one round.
|
|
23
|
+
|
|
24
|
+
#### What caused friction (agent side)
|
|
25
|
+
|
|
26
|
+
- `instruction-violation` (user-caught) — Wrote prose paragraphs in `README.md` and `docs/configuration.md` with hard wraps inside multi-sentence paragraphs.
|
|
27
|
+
`AGENTS.md` § Markdown already says "Use one sentence per line (unbroken) for better diffs."
|
|
28
|
+
Required an `--amend` of the docs commit (`1df2550`) after the user pointed it out.
|
|
29
|
+
Impact: one rework cycle, no commit churn beyond the amend, but the rule was visible in `AGENTS.md` and I had read it that session.
|
|
30
|
+
- `premature-convergence` / `missing-context` — In the first `/plan-issue` `ask_user`, I assumed `ctx.ui.notify` was the only Pi UI primitive available and offered four options all routed through notifications.
|
|
31
|
+
The user redirected with "let's explore our options before we converge.
|
|
32
|
+
The Pi codebase is at `~/development/pi/pi-mono`."
|
|
33
|
+
Reading `pi-mono/packages/coding-agent/src/core/extensions/types.ts` revealed `setStatus`, `setWidget`, `custom`, and `theme.fg` — substantively richer surface area.
|
|
34
|
+
The second `ask_user` led to the actually-shipped design.
|
|
35
|
+
Impact: one extra `ask_user` round; would have produced a weaker plan if the user had not redirected.
|
|
36
|
+
|
|
37
|
+
#### What caused friction (user side)
|
|
38
|
+
|
|
39
|
+
- The pi-extension project depends on the Pi runtime API surface, but nothing in `AGENTS.md` or the project context points an agent at `pi-mono` for that surface.
|
|
40
|
+
The user supplied the path mid-session as a redirection.
|
|
41
|
+
Earlier mention (or a hint in `AGENTS.md`) would have eliminated the first round of shallow options.
|
|
42
|
+
Framed as opportunity, not criticism: this is the kind of context that lives in one head and can be cheaply written down once.
|
|
43
|
+
|
|
44
|
+
### Changes made
|
|
45
|
+
|
|
46
|
+
1. Added this retro file at `docs/retro/0002-richer-tui-formatter-summaries.md`.
|
|
47
|
+
No `AGENTS.md` or prompt changes were landed; both candidate proposals (Pi-runtime API pointer in `AGENTS.md` § Notes for Agents, and a sentence-per-line scan note in `/tdd-plan` step 3) were declined this round.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
issue: 13
|
|
3
|
+
issue_title: "Add `fallback` step type to formatter chains"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Retro: #13 — Add `fallback` step type to formatter chains
|
|
7
|
+
|
|
8
|
+
## Final Retrospective (2026-05-02T00:22:50Z)
|
|
9
|
+
|
|
10
|
+
### Session summary
|
|
11
|
+
|
|
12
|
+
Took issue #13 from `/plan-issue` through `/tdd-plan` and `/ship-issue` end-to-end.
|
|
13
|
+
Added a `fallback` chain step type with `PATH`-only fallthrough, per-flush probe caching, and reporting that names which alternative actually ran.
|
|
14
|
+
Eleven TDD commits landed cleanly into release `v2.1.0` via release-please.
|
|
15
|
+
Mid-session the user introduced a new "sync with remote first" rule for all flow prompts; that work was committed independently and the TDD flow resumed without rework.
|
|
16
|
+
|
|
17
|
+
### Observations
|
|
18
|
+
|
|
19
|
+
#### What went well
|
|
20
|
+
|
|
21
|
+
- The plan/TDD/ship flow worked end-to-end against a non-trivial change with no human-in-the-loop debugging. Eleven feat commits + acceptance test + docs landed in a single sitting and release-please picked them all up into `v2.1.0` automatically.
|
|
22
|
+
- TDD discipline caught a real bug at step 10 of the plan: the acceptance test surfaced that `flushPrompt` was emitting groups with empty `runs[]` when all fallback alternatives were missing, contradicting the plan's "group is a no-op" wording.
|
|
23
|
+
Fixed in the same commit.
|
|
24
|
+
- Running `pnpm exec tsc --noEmit` mid-flow caught a vacuous test in step 8 — `commandProbe` was passed via the constructor's options but TS flagged it as an unknown property. Without the typecheck the test would have passed for the wrong reason.
|
|
25
|
+
|
|
26
|
+
#### What caused friction (agent side)
|
|
27
|
+
|
|
28
|
+
- `instruction-violation` (self-identified, end-of-flow) — `pnpm run lint:fix` reformatted some test files; that cleanup landed inside the `docs:` commit instead of being amended onto the most recent feat commit.
|
|
29
|
+
The existing rule in `.pi/prompts/tdd-plan.md` says to amend onto the prior feat commit when not yet pushed; I had not pushed.
|
|
30
|
+
Impact: noisier final commit (`docs: document fallback chain steps...` touches 9 files instead of 2), but no rework.
|
|
31
|
+
- `rabbit-hole` — markdown table column alignment with em-dashes (`—`) failed `MD060` repeatedly because em-dash width-vs-byte math was off.
|
|
32
|
+
Took three table-edit attempts to land a passing layout.
|
|
33
|
+
Should have switched to ASCII hyphen on the first failure.
|
|
34
|
+
Impact: ~1 minute, no rework.
|
|
35
|
+
- `missing-context` (self-identified, step 8) — wrote a `commandProbe` test against `PromptAutoformatter` constructor options before extending `PromptAutoformatterOptions` to declare the field.
|
|
36
|
+
Test passed vacuously (unknown property silently ignored at runtime).
|
|
37
|
+
Caught by `pnpm exec tsc --noEmit`, fixed in same commit.
|
|
38
|
+
Impact: ~5 minutes to wire the option through, same commit.
|
|
39
|
+
- `missing-context` (self-identified, plan-author side) — plan TDD step 10 said put the e2e test in `test/acceptance.test.ts`, but that file is gated on the real `pi` CLI.
|
|
40
|
+
Created `test/fallback-acceptance.test.ts` instead and noted the deviation in the commit body.
|
|
41
|
+
Impact: marginal — correct outcome, ~30 seconds of judgment to deviate.
|
|
42
|
+
- `wrong-abstraction` — when changing `executeChainGroup`'s input shape in step 7, I rewrote `test/formatter-executor.test.ts` wholesale via `Write` instead of surgical edits.
|
|
43
|
+
All tests still covered the same surface but the diff is harder to review.
|
|
44
|
+
Impact: cosmetic.
|
|
45
|
+
|
|
46
|
+
#### What caused friction (user side)
|
|
47
|
+
|
|
48
|
+
- The "sync with remote first" rule (`git pull --ff-only` at the top of every flow prompt) was retrofitted mid-TDD.
|
|
49
|
+
Catching it then was good — the user noticed before I'd made anything irreversible — but had the rule existed before this session it would have eliminated one full conversational interruption.
|
|
50
|
+
Treat as a "rule earned through observation, not friction" rather than user-side friction.
|
|
51
|
+
|
|
52
|
+
### Novel wins
|
|
53
|
+
|
|
54
|
+
- The `/plan-issue` → `/tdd-plan` → `/ship-issue` chain produced a clean `v2.1.0` release with no manual intervention beyond the TDD execution itself.
|
|
55
|
+
This is the first session where release-please's commit grouping handled a 9-feat-commit feature cleanly into one minor bump.
|
|
56
|
+
- Mid-flow prompt evolution worked: the user paused execution to update flow templates, I committed those updates as their own change, and TDD resumed without state corruption.
|
|
57
|
+
|
|
58
|
+
### Insight from retro discussion
|
|
59
|
+
|
|
60
|
+
Proposal B (a human-readable "use ASCII `-` in markdown tables" rule for `AGENTS.md`) was rejected with the observation: markdownlint already caught the violation — that's *why* the build failed three times — so the right behavioral lesson is "linter says column width is wrong → stop iterating on whitespace, switch to ASCII," not "add a project rule papering over a tool that already works."
|
|
61
|
+
Adding rules for things the existing toolchain already detects is redundant when the project's premise is auto-formatting.
|
|
62
|
+
Kept the retro file's record of the rabbit-hole as the lesson; no `AGENTS.md` change.
|
|
63
|
+
|
|
64
|
+
### Changes made
|
|
65
|
+
|
|
66
|
+
1. `.pi/prompts/tdd-plan.md` — appended one clause to the lint-fixup rule: "The fixup must NOT land in a `docs:` commit." Closes the gap that produced this session's noisy `3bbc846` docs commit.
|
|
67
|
+
2. `docs/retro/0013-fallback-chain-step-type.md` — this file.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
issue: 15
|
|
3
|
+
issue_title: "Built-in `treefmt` and `treefmt-nix` project formatter support"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Retro: #15 — Built-in `treefmt` and `treefmt-nix` project formatter support
|
|
7
|
+
|
|
8
|
+
## Final Retrospective (2026-05-02T03:50:00Z)
|
|
9
|
+
|
|
10
|
+
### Session summary
|
|
11
|
+
|
|
12
|
+
Took issue #15 from `/plan-issue` through `/tdd-plan` and `/ship-issue` end-to-end.
|
|
13
|
+
Added two opt-in built-in formatters (`treefmt`, `treefmt-nix`), a wildcard `"*"` chain key, per-session config-root discovery cache, skip-pattern parsing, and a `treefmt-nix`-over-`treefmt` precedence rule inside `fallback` groups.
|
|
14
|
+
Eleven `feat:` commits plus a `docs:` commit landed cleanly; release-please rolled them into `v2.4.0` with no human-in-the-loop debugging.
|
|
15
|
+
|
|
16
|
+
### Observations
|
|
17
|
+
|
|
18
|
+
#### What went well
|
|
19
|
+
|
|
20
|
+
- The plan/TDD/ship flow ran end-to-end with zero rework or user intervention.
|
|
21
|
+
271 tests passed; type-check clean; release-please picked everything up.
|
|
22
|
+
- Refactoring `executeChainGroup` into `executeChainGroupWithPartition` and delegating preserved the existing `BatchRun[]` API, so all 16 prior executor tests stayed green while new partition-aware behavior was added.
|
|
23
|
+
Existing tests stayed unchanged.
|
|
24
|
+
- The async `discoverRoot` precedence check inside the `fallback` resolver — `treefmt-nix` wins over `treefmt` only when both PATH-probe true **and** resolve to the same root — landed first try with two focused tests (same-root override; different-root preserves user order).
|
|
25
|
+
- `walkUp` + `DiscoveryCache` design (per-session memoization, sentinel for "no match") landed first try and the cache reuse test exercises it cleanly.
|
|
26
|
+
|
|
27
|
+
#### What caused friction (agent side)
|
|
28
|
+
|
|
29
|
+
- `other` (self-identified, post-hoc) — Two `void 0;` lines were inserted into tests (`test/builtin-formatters.test.ts:74`, `test/formatter-executor.test.ts:299`) as an `Edit`-tool workaround: when inserting tests near visually similar text, I padded `oldText` with a fake marker line instead of widening `oldText` with more surrounding context.
|
|
30
|
+
Impact: 2 lines of dead code shipped to `main`; cleanup deferred to this retro commit.
|
|
31
|
+
- `other` (lint-caught at end of TDD) — `wildcardConfig` const left over in `test/prompt-autoformatter.test.ts` after I switched the wildcard test from a fake-formatter-shadow approach to monkey-patching the real built-in registry mid-edit.
|
|
32
|
+
Biome flagged the unused-binding warning during `pnpm run lint`; removed during the lint-fixup amend.
|
|
33
|
+
Impact: one extra edit cycle, amended into the most recent feat commit per the prompt's rule.
|
|
34
|
+
- `missing-context` (step 5) — `treefmtConfigPath` initially used `existsSync` to choose between `treefmt.toml` and `.treefmt.toml`, which broke a unit test that passed `/repo` as the root without creating any files on disk.
|
|
35
|
+
Adjusted to default to the canonical `treefmt.toml` when neither file exists.
|
|
36
|
+
Impact: one extra red→green cycle within step 5, no rework.
|
|
37
|
+
- `instruction-violation` (self-identified, mild) — Plan suggested separate `test:` then `feat:` commits per TDD step.
|
|
38
|
+
I bundled each step's test + implementation into one `feat:` commit, citing AGENTS.md's "small reviewable commits" preference.
|
|
39
|
+
Noted as a deviation in the summary; not flagged by the user.
|
|
40
|
+
Impact: none; arguably the right call given AGENTS.md, but the prompt itself already says "`test:` for test-only commits (rare; usually folded into the feat)" — so this matches the prompt's own hint.
|
|
41
|
+
|
|
42
|
+
#### What caused friction (user side)
|
|
43
|
+
|
|
44
|
+
- None worth flagging — the user ran the three slash-command prompts and let them complete.
|
|
45
|
+
This is a sign the prompts are doing the right thing, not a friction point.
|
|
46
|
+
|
|
47
|
+
### Changes made
|
|
48
|
+
|
|
49
|
+
1. Removed leftover `void 0;` cruft from `test/builtin-formatters.test.ts` (line 74) and `test/formatter-executor.test.ts` (line 299).
|
|
50
|
+
2. Added a one-line rule to the `## Testing` section of `AGENTS.md`: "Do not insert no-op statements (`void 0;`, unused locals) in tests just to make an `Edit` tool's `oldText` unique — widen `oldText` with surrounding context instead."
|
|
51
|
+
3. Wrote this retro file at `docs/retro/0015-builtin-treefmt-and-treefmt-nix-support.md`.
|
|
52
|
+
|
|
53
|
+
### Cross-session pattern
|
|
54
|
+
|
|
55
|
+
The pattern from #13 holds: when the plan is detailed enough to enumerate types, edge cases, and TDD ordering, the TDD execution is essentially mechanical and lands without rework.
|
|
56
|
+
The friction sources are now small enough to be agent-tooling artifacts (`Edit` no-op markers, in-flight refactor cruft) rather than design or strategy gaps.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
issue: 2
|
|
3
|
+
issue_title: "Support optional detailed formatter output in reports"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Retro: #2 — Support optional detailed formatter output in reports
|
|
7
|
+
|
|
8
|
+
## Final Retrospective (2026-05-02T02:15:00Z)
|
|
9
|
+
|
|
10
|
+
### Session summary
|
|
11
|
+
|
|
12
|
+
Triaged the open backlog, picked issue #2, planned (`docs/plans/0016-detailed-formatter-output-on-failure.md`), implemented across ten TDD cycles, and shipped `2.3.0`.
|
|
13
|
+
Added an opt-in `formatterOutput` config object that surfaces a failed formatter run's `stderr` (or `stdout + stderr`) with tail-preserving byte/line truncation; defaults preserve prior concise reporting.
|
|
14
|
+
While testing, the user reported an "Unexpected runtime error: ... `fgColors`" warning above the editor that traced to a latent `this`-binding bug in `themed()` from the plan-0002 work; landed a regression test plus fix (`6ba7576`, `6a6ec16`) in the same release.
|
|
15
|
+
|
|
16
|
+
### Observations
|
|
17
|
+
|
|
18
|
+
#### What went well
|
|
19
|
+
|
|
20
|
+
- Backlog triage at the start was useful as a standalone workflow — `gh issue list` → ranked recommendation → user pick.
|
|
21
|
+
The format ("top picks / defer / recommendation") gave the user a real choice without forcing a single answer.
|
|
22
|
+
- Plan-number selection caught a small alignment hazard preemptively: `0002` was taken (mismatched with issue #2), `0005` was the next free slot, but I picked `0016` to keep `0015` reserved for issue #15.
|
|
23
|
+
Tiny detail; the kind of thing only worth noting because it would have been irritating to fix later.
|
|
24
|
+
- TDD execution was clean — ten cycles, every commit landed green.
|
|
25
|
+
Step 9's truncation e2e test was already green when written, which surfaced as evidence the helper-module boundary (`src/formatter-output-report.ts`) was at the right level: unit tests had already covered the corners.
|
|
26
|
+
- The mid-session `fgColors` bug investigation was textbook: read the user's symptom, traced through our `themed()` helper, opened `pi-mono`'s `Theme` class, identified the destructured-method `this`-loss pattern, then took the user's correction ("Other way around, I want to put the test in that should fail") and ran proper red→green TDD on the fix.
|
|
27
|
+
- The "outstanding changes" moment after committing the plan was a nice meta-confirmation: the autoformat extension itself reformatted the plan file we'd just written, exactly as advertised.
|
|
28
|
+
Folded as a single `docs: apply autoformat to plan 0016` follow-up.
|
|
29
|
+
|
|
30
|
+
#### What caused friction (agent side)
|
|
31
|
+
|
|
32
|
+
- `missing-context` (user-caught, latent) — The test stubs throughout `test/extension.test.ts` use `theme: { fg: (_name, text) => text }`, a plain function that doesn't depend on `this`.
|
|
33
|
+
Pi's real `Theme.fg` is an instance method that reads `this.fgColors`.
|
|
34
|
+
The shape mismatch hid a `this`-binding bug from plan-0002's `themed()` helper for a full release cycle until the user surfaced it from running against their custom catppuccin theme.
|
|
35
|
+
Impact: one user-reported warning in production, one regression test (`6ba7576`), one fix commit (`6a6ec16`).
|
|
36
|
+
Diagnosis required reading `pi-mono/packages/coding-agent/src/modes/interactive/theme/theme.ts` — the same external repo flagged in the #1 retro as missing from the agent's onboarding context.
|
|
37
|
+
- `premature-convergence` (self-identified, low-impact) — On the `formatterOutput` config shape (single boolean vs object with knobs), I judged the issue's "Follow-up ideas" unambiguous and skipped the `ask_user` gate.
|
|
38
|
+
The shape landed fine, but a 30-second sanity check would have been cheap insurance for a permanent config surface.
|
|
39
|
+
No rework, no change of direction.
|
|
40
|
+
Impact: added confidence cost; no commit churn.
|
|
41
|
+
- `scope-drift` (sanctioned, worth noting) — The `themed()` `this`-binding fix is unrelated to issue #2.
|
|
42
|
+
The user explicitly directed the fix during the session, and the close comment flagged it as out-of-scope-but-found-while-testing.
|
|
43
|
+
Combining the fix into release `2.3.0` was kinder to the user (one push, one release) but slightly conflates the release notes.
|
|
44
|
+
No rework; flagged here so the pattern is visible.
|
|
45
|
+
|
|
46
|
+
#### What caused friction (user side)
|
|
47
|
+
|
|
48
|
+
- The `pi-mono` repo at `~/development/pi/pi-mono` is the canonical reference for Pi's runtime API surface (`ExtensionApi`, `Theme`, etc.).
|
|
49
|
+
This is the second consecutive retro where reading `pi-mono` was decisive — first to discover `setStatus`/`theme.fg` (#1 retro), now to diagnose a `this`-binding bug rooted in that same surface.
|
|
50
|
+
The path lives in one head; surfacing it once in `AGENTS.md` would have eliminated a redirection in #1 and accelerated diagnosis in #2.
|
|
51
|
+
Framed as opportunity, not criticism: low-cost, high-payoff context to write down.
|
|
52
|
+
|
|
53
|
+
### Changes made
|
|
54
|
+
|
|
55
|
+
1. Added this retro file at `docs/retro/0016-detailed-formatter-output-on-failure.md`.
|
|
56
|
+
2. Added a one-line `pi-mono` pointer at the end of `AGENTS.md` § Notes for Agents — then **reverted it** in the same retro commit after a follow-up question surfaced that Pi publishes `@mariozechner/pi-coding-agent` to npm.
|
|
57
|
+
The right fix is to depend on the published types package, not to point agents at a sibling git checkout.
|
|
58
|
+
3. Opened issue #22 ("Depend on `@mariozechner/pi-coding-agent` for runtime types instead of duck-typing") to track the typing refactor.
|
|
59
|
+
The duck-typed `*Like` aliases in `src/extension.ts` are what let the `theme.fg` `this`-binding bug ship; switching to real types from the published Pi package would have caught it at compile time.
|
|
60
|
+
Tracked as a follow-up rather than implemented inline because the change touches `package.json`, `src/extension.ts`, and several test files — over the retro's scope budget.
|