pi-formatter 1.0.0 → 1.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/README.md +17 -19
- package/extensions/formatter/config.ts +3 -3
- package/extensions/index.ts +10 -18
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
A [pi](https://pi.dev) extension that auto-formats files after `write` and
|
|
4
4
|
`edit` tool calls.
|
|
5
5
|
|
|
6
|
-
By default, formatting runs once per
|
|
7
|
-
|
|
6
|
+
By default, formatting runs once per prompt — after the agent finishes all its
|
|
7
|
+
work and yields control back to you. You can also format after each individual
|
|
8
|
+
tool call or defer formatting until the session shuts down.
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
the old default, set `"formatMode": "tool"`.
|
|
10
|
+
To format after every individual edit instead, set `"formatMode": "tool"`.
|
|
11
11
|
|
|
12
12
|
## 📦 Install
|
|
13
13
|
|
|
@@ -22,19 +22,17 @@ best-effort post-processing. Formatter failures never block tool results.
|
|
|
22
22
|
|
|
23
23
|
Formatting modes:
|
|
24
24
|
|
|
25
|
-
- `tool`: format immediately after each successful `write` or `edit` tool
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
keeping files formatted throughout the run.
|
|
25
|
+
- `tool`: format immediately after each successful `write` or `edit` tool call.
|
|
26
|
+
Use this mode when you want files on disk to stay formatted after every edit,
|
|
27
|
+
even while the agent is still working.
|
|
28
|
+
- `prompt`: collect all files touched during the agent run and format them once
|
|
29
|
+
when the agent finishes and yields control back to you. This is the default.
|
|
30
|
+
Use this mode to avoid mid-run formatter interruptions while still getting
|
|
31
|
+
clean files after each response.
|
|
33
32
|
- `session`: collect files touched during the current session and format them
|
|
34
|
-
once at
|
|
35
|
-
Use this mode when you want the fewest
|
|
36
|
-
|
|
37
|
-
runs stay pending until the session ends or changes.
|
|
33
|
+
once at session shutdown, reload, or switch.
|
|
34
|
+
Use this mode when you want the fewest interruptions and are okay with
|
|
35
|
+
formatting only when the session ends.
|
|
38
36
|
|
|
39
37
|
Supported file types:
|
|
40
38
|
|
|
@@ -61,14 +59,14 @@ folder (default: `~/.pi/agent`, overridable via `PI_CODING_AGENT_DIR`):
|
|
|
61
59
|
|
|
62
60
|
```json
|
|
63
61
|
{
|
|
64
|
-
"formatMode": "
|
|
62
|
+
"formatMode": "prompt",
|
|
65
63
|
"commandTimeoutMs": 10000,
|
|
66
64
|
"hideCallSummariesInTui": false
|
|
67
65
|
}
|
|
68
66
|
```
|
|
69
67
|
|
|
70
|
-
- `formatMode`: formatting strategy (`"tool"` | `"
|
|
71
|
-
default: `"
|
|
68
|
+
- `formatMode`: formatting strategy (`"tool"` | `"prompt"` | `"session"`,
|
|
69
|
+
default: `"prompt"`). Use `"tool"` to format after every individual edit.
|
|
72
70
|
- `commandTimeoutMs`: timeout (ms) per formatter command (default: `10000`)
|
|
73
71
|
- `hideCallSummariesInTui`: hide formatter pass/fail summaries in the TUI
|
|
74
72
|
(default: `false`)
|
|
@@ -2,11 +2,11 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { getAgentDir } from "@mariozechner/pi-coding-agent";
|
|
4
4
|
|
|
5
|
-
export type FormatMode = "tool" | "
|
|
5
|
+
export type FormatMode = "tool" | "prompt" | "session";
|
|
6
6
|
|
|
7
7
|
const DEFAULT_COMMAND_TIMEOUT_MS = 10_000;
|
|
8
8
|
const DEFAULT_HIDE_CALL_SUMMARIES_IN_TUI = false;
|
|
9
|
-
const DEFAULT_FORMAT_MODE: FormatMode = "
|
|
9
|
+
export const DEFAULT_FORMAT_MODE: FormatMode = "prompt";
|
|
10
10
|
const FORMATTER_CONFIG_FILE = "formatter.json";
|
|
11
11
|
|
|
12
12
|
export type FormatterConfigSnapshot = {
|
|
@@ -65,7 +65,7 @@ function parseBooleanValue(value: unknown, defaultValue: boolean): boolean {
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
function parseFormatMode(value: unknown, defaultValue: FormatMode): FormatMode {
|
|
68
|
-
if (value === "tool" || value === "
|
|
68
|
+
if (value === "tool" || value === "prompt" || value === "session") {
|
|
69
69
|
return value;
|
|
70
70
|
}
|
|
71
71
|
|
package/extensions/index.ts
CHANGED
|
@@ -79,9 +79,9 @@ function getFormatterSettingItems(
|
|
|
79
79
|
id: "formatMode",
|
|
80
80
|
label: "Format mode",
|
|
81
81
|
description:
|
|
82
|
-
"Choose whether formatting runs after each successful write/edit tool call, once after each
|
|
82
|
+
"Choose whether formatting runs after each successful write/edit tool call, once after each prompt completes, or once when the session shuts down.",
|
|
83
83
|
currentValue: config.formatMode,
|
|
84
|
-
values: ["tool", "
|
|
84
|
+
values: ["tool", "prompt", "session"],
|
|
85
85
|
},
|
|
86
86
|
{
|
|
87
87
|
id: "commandTimeoutMs",
|
|
@@ -112,7 +112,7 @@ type FormatterContext = {
|
|
|
112
112
|
export default function (pi: ExtensionAPI) {
|
|
113
113
|
let formatterConfig = loadFormatterConfig();
|
|
114
114
|
const formatQueueByPath = new Map<string, Promise<void>>();
|
|
115
|
-
const
|
|
115
|
+
const pendingPromptPaths = new Set<string>();
|
|
116
116
|
const pendingSessionPaths = new Set<string>();
|
|
117
117
|
|
|
118
118
|
const enqueueFormat = async (
|
|
@@ -208,7 +208,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
208
208
|
};
|
|
209
209
|
|
|
210
210
|
const flushPendingPaths = async (ctx: FormatterContext): Promise<void> => {
|
|
211
|
-
await flushPaths(
|
|
211
|
+
await flushPaths(pendingPromptPaths, ctx);
|
|
212
212
|
await flushPaths(pendingSessionPaths, ctx);
|
|
213
213
|
};
|
|
214
214
|
|
|
@@ -235,32 +235,24 @@ export default function (pi: ExtensionAPI) {
|
|
|
235
235
|
return;
|
|
236
236
|
}
|
|
237
237
|
|
|
238
|
-
if (formatterConfig.formatMode === "
|
|
239
|
-
|
|
238
|
+
if (formatterConfig.formatMode === "prompt") {
|
|
239
|
+
pendingPromptPaths.add(filePath);
|
|
240
240
|
return;
|
|
241
241
|
}
|
|
242
242
|
|
|
243
243
|
pendingSessionPaths.add(filePath);
|
|
244
244
|
});
|
|
245
245
|
|
|
246
|
-
pi.on("turn_end", async (_event, ctx) => {
|
|
247
|
-
if (pendingTurnPaths.size === 0) {
|
|
248
|
-
return;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
await flushPaths(pendingTurnPaths, ctx);
|
|
252
|
-
});
|
|
253
|
-
|
|
254
246
|
pi.on("agent_end", async (_event, ctx) => {
|
|
255
|
-
if (
|
|
247
|
+
if (pendingPromptPaths.size === 0) {
|
|
256
248
|
return;
|
|
257
249
|
}
|
|
258
250
|
|
|
259
|
-
await flushPaths(
|
|
251
|
+
await flushPaths(pendingPromptPaths, ctx);
|
|
260
252
|
});
|
|
261
253
|
|
|
262
254
|
pi.on("session_switch", async (_event, ctx) => {
|
|
263
|
-
if (
|
|
255
|
+
if (pendingPromptPaths.size === 0 && pendingSessionPaths.size === 0) {
|
|
264
256
|
return;
|
|
265
257
|
}
|
|
266
258
|
|
|
@@ -268,7 +260,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
268
260
|
});
|
|
269
261
|
|
|
270
262
|
pi.on("session_shutdown", async (_event, ctx) => {
|
|
271
|
-
if (
|
|
263
|
+
if (pendingPromptPaths.size === 0 && pendingSessionPaths.size === 0) {
|
|
272
264
|
return;
|
|
273
265
|
}
|
|
274
266
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-formatter",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Pi extension that auto-formats files
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Pi extension that auto-formats files.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"extensions",
|