@gotgenes/pi-autoformat 0.1.0
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 +35 -0
- package/.github/workflows/release-please.yml +22 -0
- package/.markdownlint-cli2.yaml +3 -0
- package/.pi/extensions/pi-autoformat/config.json +28 -0
- package/.release-please-manifest.json +3 -0
- package/AGENTS.md +71 -0
- package/LICENSE +21 -0
- package/README.md +178 -0
- package/biome.json +17 -0
- package/docs/configuration.md +177 -0
- package/docs/plans/0001-initial-implementation-plan.md +402 -0
- package/package.json +32 -0
- package/prek.toml +24 -0
- package/release-please-config.json +22 -0
- package/schemas/pi-autoformat.schema.json +87 -0
- package/src/config-loader.ts +520 -0
- package/src/extension.ts +374 -0
- package/src/formatter-config.ts +80 -0
- package/src/formatter-executor.ts +68 -0
- package/src/formatter-registry.ts +61 -0
- package/src/index.ts +42 -0
- package/src/prompt-autoformatter.ts +58 -0
- package/src/touched-files-queue.ts +46 -0
- package/test/config-loader.test.ts +199 -0
- package/test/extension.test.ts +364 -0
- package/test/formatter-config.test.ts +64 -0
- package/test/formatter-executor.test.ts +82 -0
- package/test/formatter-registry.test.ts +75 -0
- package/test/prompt-autoformatter.test.ts +93 -0
- package/test/smoke.test.ts +9 -0
- package/test/touched-files-queue.test.ts +46 -0
- package/tsconfig.json +13 -0
- package/vitest.config.ts +10 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
env:
|
|
9
|
+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
check:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v6
|
|
16
|
+
|
|
17
|
+
- uses: pnpm/action-setup@v4
|
|
18
|
+
with:
|
|
19
|
+
version: latest
|
|
20
|
+
|
|
21
|
+
- uses: actions/setup-node@v6
|
|
22
|
+
with:
|
|
23
|
+
node-version: 24
|
|
24
|
+
cache: "pnpm"
|
|
25
|
+
|
|
26
|
+
- run: pnpm install --frozen-lockfile
|
|
27
|
+
|
|
28
|
+
- name: Type check
|
|
29
|
+
run: pnpm exec tsc --noEmit
|
|
30
|
+
|
|
31
|
+
- name: Lint
|
|
32
|
+
run: pnpm run lint
|
|
33
|
+
|
|
34
|
+
- name: Test
|
|
35
|
+
run: pnpm run test
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
name: release-please
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
|
|
8
|
+
env:
|
|
9
|
+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: write
|
|
13
|
+
pull-requests: write
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
release-please:
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
steps:
|
|
19
|
+
- uses: googleapis/release-please-action@v4.4.1
|
|
20
|
+
with:
|
|
21
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
22
|
+
config-file: release-please-config.json
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/gotgenes/pi-autoformat/main/schemas/pi-autoformat.schema.json",
|
|
3
|
+
"formatMode": "prompt",
|
|
4
|
+
"hideSummariesInTui": false,
|
|
5
|
+
"formatters": {
|
|
6
|
+
"biome": {
|
|
7
|
+
"command": [
|
|
8
|
+
"pnpm",
|
|
9
|
+
"exec",
|
|
10
|
+
"biome",
|
|
11
|
+
"check",
|
|
12
|
+
"--write",
|
|
13
|
+
"--files-ignore-unknown=true",
|
|
14
|
+
"$FILE"
|
|
15
|
+
],
|
|
16
|
+
"extensions": [".ts", ".json"]
|
|
17
|
+
},
|
|
18
|
+
"markdownlint-cli2": {
|
|
19
|
+
"command": ["pnpm", "exec", "markdownlint-cli2", "--fix", "$FILE"],
|
|
20
|
+
"extensions": [".md"]
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"chains": {
|
|
24
|
+
".ts": ["biome"],
|
|
25
|
+
".json": ["biome"],
|
|
26
|
+
".md": ["markdownlint-cli2"]
|
|
27
|
+
}
|
|
28
|
+
}
|
package/AGENTS.md
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
## Project Purpose
|
|
4
|
+
|
|
5
|
+
This repository is for a Pi extension that auto-formats files after agent edits so formatting does not fail late at commit time.
|
|
6
|
+
|
|
7
|
+
Read `docs/plans/` before making architectural changes.
|
|
8
|
+
|
|
9
|
+
## Workflow
|
|
10
|
+
|
|
11
|
+
- Keep scope tight.
|
|
12
|
+
- Prefer small, reversible changes.
|
|
13
|
+
- Preserve intentional behavior unless there is a clear reason to change it.
|
|
14
|
+
- Ask before removing functionality or changing defaults.
|
|
15
|
+
|
|
16
|
+
## Implementation Priorities
|
|
17
|
+
|
|
18
|
+
- Prefer prompt-end formatting over immediate per-tool formatting unless the task explicitly requires otherwise.
|
|
19
|
+
- Favor repository-configured formatter commands over hardcoded formatter behavior.
|
|
20
|
+
- Prefer extension-owned config files over Pi `settings.json` keys for package-specific behavior.
|
|
21
|
+
- Format only files touched by the agent, not the whole repository.
|
|
22
|
+
- Make formatter failures visible, but do not block the original file edit by default.
|
|
23
|
+
|
|
24
|
+
## Code Style
|
|
25
|
+
|
|
26
|
+
- Use TypeScript.
|
|
27
|
+
- Avoid `any` unless absolutely necessary.
|
|
28
|
+
- Use standard top-level imports only.
|
|
29
|
+
- Keep modules focused and composable.
|
|
30
|
+
- Prefer explicit configuration over hidden behavior.
|
|
31
|
+
|
|
32
|
+
## Configuration
|
|
33
|
+
|
|
34
|
+
- Use extension-owned config files:
|
|
35
|
+
- global: `~/.pi/agent/extensions/pi-autoformat/config.json`
|
|
36
|
+
- project: `.pi/extensions/pi-autoformat/config.json`
|
|
37
|
+
- Project config overrides global config.
|
|
38
|
+
- Do not move package configuration into Pi `settings.json` without explicit discussion.
|
|
39
|
+
- Keep `schemas/pi-autoformat.schema.json`, `docs/configuration.md`, `README.md`, and the TypeScript config loader aligned.
|
|
40
|
+
|
|
41
|
+
## Testing
|
|
42
|
+
|
|
43
|
+
- Add focused tests for formatter resolution, execution order, and failure handling.
|
|
44
|
+
- Test prompt-end batching behavior.
|
|
45
|
+
- Test custom formatter command configuration.
|
|
46
|
+
- Test multiple formatter chains for the same file type.
|
|
47
|
+
- Add focused tests for config loading, merge precedence, and validation issues.
|
|
48
|
+
- Add extension lifecycle tests once the runtime entrypoint exists.
|
|
49
|
+
|
|
50
|
+
## Commits
|
|
51
|
+
|
|
52
|
+
- Use Conventional Commits.
|
|
53
|
+
- Commit at meaningful checkpoints without waiting for an explicit reminder.
|
|
54
|
+
- Prefer small, reviewable commits that leave the repository in a valid state.
|
|
55
|
+
- Examples:
|
|
56
|
+
- `feat: add prompt-end formatter queue`
|
|
57
|
+
- `fix: preserve formatter order for markdown chains`
|
|
58
|
+
- `test: cover custom formatter override`
|
|
59
|
+
- `docs: refine initial implementation plan`
|
|
60
|
+
|
|
61
|
+
## Notes for Agents
|
|
62
|
+
|
|
63
|
+
Before implementing, understand:
|
|
64
|
+
|
|
65
|
+
1. the problem being solved
|
|
66
|
+
2. the timing tradeoffs between tool-mode and prompt-mode formatting
|
|
67
|
+
3. the need to support repository-specific formatter chains
|
|
68
|
+
4. the chosen config layout and merge precedence
|
|
69
|
+
5. the need to keep schema, config loader, and docs aligned
|
|
70
|
+
|
|
71
|
+
Do not assume commit-time hooks are an acceptable primary formatting mechanism.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Christopher D. Lasher
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# pi-autoformat
|
|
2
|
+
|
|
3
|
+
`pi-autoformat` is a Pi extension package that automatically formats files after the agent edits them.
|
|
4
|
+
|
|
5
|
+
## The problem this package solves
|
|
6
|
+
|
|
7
|
+
Pi agents often make correct code changes that still fail at commit time because formatting was never run.
|
|
8
|
+
|
|
9
|
+
That creates a frustrating workflow:
|
|
10
|
+
|
|
11
|
+
1. the agent edits files
|
|
12
|
+
2. the agent appears done
|
|
13
|
+
3. pre-commit hooks or CI run formatters later
|
|
14
|
+
4. files mutate after the fact
|
|
15
|
+
5. commits fail or the agent has to recover from surprise formatting changes
|
|
16
|
+
|
|
17
|
+
This package moves formatting earlier in the workflow so the agent is less likely to leave behind unformatted files.
|
|
18
|
+
|
|
19
|
+
## How it works
|
|
20
|
+
|
|
21
|
+
`pi-autoformat` watches files touched by Pi mutation tools and runs configured formatter commands for just those files.
|
|
22
|
+
|
|
23
|
+
Design goals:
|
|
24
|
+
|
|
25
|
+
- format only files the agent touched
|
|
26
|
+
- prefer prompt-end batching over per-edit formatting by default
|
|
27
|
+
- support repository-specific formatter commands
|
|
28
|
+
- support ordered formatter chains for the same extension
|
|
29
|
+
- surface formatter failures without blocking the original edit by default
|
|
30
|
+
- keep reporting concise by default, with interactive summaries and non-interactive logs
|
|
31
|
+
|
|
32
|
+
Default behavior is **prompt mode**:
|
|
33
|
+
|
|
34
|
+
- collect files touched during the agent's work
|
|
35
|
+
- run formatters once after the prompt finishes
|
|
36
|
+
|
|
37
|
+
This is safer than formatting immediately after every edit because prompt-end batching avoids mutating a file in between sibling exact-text edits.
|
|
38
|
+
|
|
39
|
+
## Installation
|
|
40
|
+
|
|
41
|
+
### From npm
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
pi install npm:@gotgenes/pi-autoformat
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Local development checkout
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pi install /absolute/path/to/pi-autoformat
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Configuration
|
|
54
|
+
|
|
55
|
+
`pi-autoformat` uses extension-owned config files.
|
|
56
|
+
|
|
57
|
+
Configuration is loaded in this order:
|
|
58
|
+
|
|
59
|
+
1. global: `~/.pi/agent/extensions/pi-autoformat/config.json`
|
|
60
|
+
2. project: `.pi/extensions/pi-autoformat/config.json`
|
|
61
|
+
|
|
62
|
+
Project config overrides global config.
|
|
63
|
+
|
|
64
|
+
Example:
|
|
65
|
+
|
|
66
|
+
```json
|
|
67
|
+
{
|
|
68
|
+
"$schema": "https://raw.githubusercontent.com/gotgenes/pi-autoformat/main/schemas/pi-autoformat.schema.json",
|
|
69
|
+
"formatMode": "prompt",
|
|
70
|
+
"commandTimeoutMs": 10000,
|
|
71
|
+
"hideSummariesInTui": false,
|
|
72
|
+
"formatters": {
|
|
73
|
+
"prettier": {
|
|
74
|
+
"command": ["prettier", "--write", "$FILE"],
|
|
75
|
+
"extensions": [".js", ".ts", ".tsx", ".json", ".md"]
|
|
76
|
+
},
|
|
77
|
+
"markdownlint-cli2": {
|
|
78
|
+
"command": ["markdownlint-cli2", "--fix", "$FILE"],
|
|
79
|
+
"extensions": [".md"]
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
"chains": {
|
|
83
|
+
".md": ["prettier", "markdownlint-cli2"],
|
|
84
|
+
".ts": ["prettier"],
|
|
85
|
+
".tsx": ["prettier"]
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
See [docs/configuration.md](docs/configuration.md) for the full configuration reference.
|
|
91
|
+
|
|
92
|
+
Formatter command resolution in v1 stays intentionally simple:
|
|
93
|
+
|
|
94
|
+
- built-in formatter commands run from the project `cwd`
|
|
95
|
+
- the extension uses the inherited environment and `PATH`
|
|
96
|
+
- if your environment manager already resolves the right tool for that directory, plain commands like `prettier` can work as-is
|
|
97
|
+
- if your repo needs wrappers such as `pnpm exec`, `npx`, `mise x`, or similar, configure those commands explicitly in `formatters`
|
|
98
|
+
|
|
99
|
+
## Reporting behavior
|
|
100
|
+
|
|
101
|
+
By default, `pi-autoformat` reports:
|
|
102
|
+
|
|
103
|
+
- concise success summaries after formatting runs
|
|
104
|
+
- per-file failure summaries when one or more formatter commands fail
|
|
105
|
+
- config validation issues detected while loading global or project config
|
|
106
|
+
|
|
107
|
+
In the interactive TUI, these appear as notifications.
|
|
108
|
+
|
|
109
|
+
Outside the TUI, they are written as prefixed log lines.
|
|
110
|
+
|
|
111
|
+
Set `hideSummariesInTui` to `true` if you want to suppress interactive success summaries while still surfacing failures.
|
|
112
|
+
|
|
113
|
+
## Formatter model
|
|
114
|
+
|
|
115
|
+
Each formatter entry can define:
|
|
116
|
+
|
|
117
|
+
- `command: string[]`
|
|
118
|
+
- `extensions: string[]`
|
|
119
|
+
- `environment?: Record<string, string>`
|
|
120
|
+
- `disabled?: boolean`
|
|
121
|
+
|
|
122
|
+
`$FILE` is replaced with the absolute path of the touched file.
|
|
123
|
+
|
|
124
|
+
Chains are configured separately so formatter order is explicit.
|
|
125
|
+
|
|
126
|
+
For v1, `pi-autoformat` runs formatters only when a `chains` entry exists for the file extension.
|
|
127
|
+
|
|
128
|
+
Example Markdown chain:
|
|
129
|
+
|
|
130
|
+
1. `prettier --write`
|
|
131
|
+
2. `markdownlint-cli2 --fix`
|
|
132
|
+
|
|
133
|
+
## Validation and autocomplete
|
|
134
|
+
|
|
135
|
+
The config file supports JSON Schema-based validation and editor autocomplete.
|
|
136
|
+
|
|
137
|
+
You can use either:
|
|
138
|
+
|
|
139
|
+
- the default-branch URL for the latest schema
|
|
140
|
+
- a pinned release-tag URL for reproducible validation
|
|
141
|
+
|
|
142
|
+
Examples:
|
|
143
|
+
|
|
144
|
+
```json
|
|
145
|
+
{
|
|
146
|
+
"$schema": "https://raw.githubusercontent.com/gotgenes/pi-autoformat/main/schemas/pi-autoformat.schema.json"
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
```json
|
|
151
|
+
{
|
|
152
|
+
"$schema": "https://raw.githubusercontent.com/gotgenes/pi-autoformat/v1.0.0/schemas/pi-autoformat.schema.json"
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Status
|
|
157
|
+
|
|
158
|
+
This project is under active development.
|
|
159
|
+
|
|
160
|
+
The current repository includes the formatter registry, execution pipeline, touched-file queue, config loading and validation, and the Pi extension runtime wiring for prompt-, tool-, and session-mode flushing.
|
|
161
|
+
|
|
162
|
+
Known v1 limitations:
|
|
163
|
+
|
|
164
|
+
- only Pi `write` and `edit` mutations are tracked automatically
|
|
165
|
+
- arbitrary shell-driven file mutations are not detected yet
|
|
166
|
+
- reporting is intentionally concise and does not yet expose full formatter stdout/stderr by default
|
|
167
|
+
|
|
168
|
+
## Development
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
pnpm install
|
|
172
|
+
pnpm test
|
|
173
|
+
pnpm run lint
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## License
|
|
177
|
+
|
|
178
|
+
MIT
|
package/biome.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://biomejs.dev/schemas/2.4.13/schema.json",
|
|
3
|
+
"formatter": {
|
|
4
|
+
"enabled": true,
|
|
5
|
+
"indentStyle": "space",
|
|
6
|
+
"indentWidth": 2
|
|
7
|
+
},
|
|
8
|
+
"linter": {
|
|
9
|
+
"enabled": true
|
|
10
|
+
},
|
|
11
|
+
"javascript": {
|
|
12
|
+
"formatter": {
|
|
13
|
+
"quoteStyle": "double",
|
|
14
|
+
"semicolons": "always"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# Configuration
|
|
2
|
+
|
|
3
|
+
`pi-autoformat` uses extension-owned config files.
|
|
4
|
+
|
|
5
|
+
## Config locations
|
|
6
|
+
|
|
7
|
+
Configuration is loaded from these files, in order:
|
|
8
|
+
|
|
9
|
+
1. global: `~/.pi/agent/extensions/pi-autoformat/config.json`
|
|
10
|
+
2. project: `.pi/extensions/pi-autoformat/config.json`
|
|
11
|
+
|
|
12
|
+
Project config overrides global config.
|
|
13
|
+
|
|
14
|
+
## Schema validation
|
|
15
|
+
|
|
16
|
+
The config file is designed to support JSON Schema validation and autocomplete.
|
|
17
|
+
|
|
18
|
+
You can point `$schema` at either:
|
|
19
|
+
|
|
20
|
+
- the default-branch URL for the latest published schema
|
|
21
|
+
- a pinned release-tag URL for reproducible validation
|
|
22
|
+
|
|
23
|
+
Examples:
|
|
24
|
+
|
|
25
|
+
Latest:
|
|
26
|
+
|
|
27
|
+
```json
|
|
28
|
+
{
|
|
29
|
+
"$schema": "https://raw.githubusercontent.com/gotgenes/pi-autoformat/main/schemas/pi-autoformat.schema.json",
|
|
30
|
+
"formatMode": "prompt",
|
|
31
|
+
"commandTimeoutMs": 10000,
|
|
32
|
+
"hideSummariesInTui": false,
|
|
33
|
+
"formatters": {
|
|
34
|
+
"prettier": {
|
|
35
|
+
"command": ["prettier", "--write", "$FILE"],
|
|
36
|
+
"extensions": [".js", ".ts", ".tsx", ".json", ".md"]
|
|
37
|
+
},
|
|
38
|
+
"markdownlint-cli2": {
|
|
39
|
+
"command": ["markdownlint-cli2", "--fix", "$FILE"],
|
|
40
|
+
"extensions": [".md"]
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"chains": {
|
|
44
|
+
".md": ["prettier", "markdownlint-cli2"],
|
|
45
|
+
".ts": ["prettier"],
|
|
46
|
+
".tsx": ["prettier"]
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Pinned tag:
|
|
52
|
+
|
|
53
|
+
```json
|
|
54
|
+
{
|
|
55
|
+
"$schema": "https://raw.githubusercontent.com/gotgenes/pi-autoformat/v1.0.0/schemas/pi-autoformat.schema.json"
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Settings reference
|
|
60
|
+
|
|
61
|
+
### `formatMode`
|
|
62
|
+
|
|
63
|
+
When formatting should run.
|
|
64
|
+
|
|
65
|
+
Allowed values:
|
|
66
|
+
|
|
67
|
+
- `"prompt"` — format once after the agent finishes the prompt. Recommended default.
|
|
68
|
+
- `"tool"` — format immediately after each successful mutation tool call.
|
|
69
|
+
- `"session"` — accumulate touched files and format on session shutdown.
|
|
70
|
+
|
|
71
|
+
### `commandTimeoutMs`
|
|
72
|
+
|
|
73
|
+
Timeout in milliseconds for each formatter command.
|
|
74
|
+
|
|
75
|
+
Example:
|
|
76
|
+
|
|
77
|
+
```json
|
|
78
|
+
{
|
|
79
|
+
"commandTimeoutMs": 10000
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### `hideSummariesInTui`
|
|
84
|
+
|
|
85
|
+
Whether formatter summaries should be hidden in the interactive TUI.
|
|
86
|
+
|
|
87
|
+
Example:
|
|
88
|
+
|
|
89
|
+
```json
|
|
90
|
+
{
|
|
91
|
+
"hideSummariesInTui": false
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### `formatters`
|
|
96
|
+
|
|
97
|
+
Formatter registry keyed by formatter name.
|
|
98
|
+
|
|
99
|
+
Each formatter can define:
|
|
100
|
+
|
|
101
|
+
- `command: string[]`
|
|
102
|
+
- `extensions: string[]`
|
|
103
|
+
- `environment?: Record<string, string>`
|
|
104
|
+
- `disabled?: boolean`
|
|
105
|
+
|
|
106
|
+
`$FILE` is replaced with the absolute path to the touched file.
|
|
107
|
+
|
|
108
|
+
For v1, formatter command resolution stays intentionally simple:
|
|
109
|
+
|
|
110
|
+
- commands run from the project `cwd`
|
|
111
|
+
- commands inherit the extension process environment and `PATH`
|
|
112
|
+
- the extension does not try to auto-detect and invoke project-local binaries on its own
|
|
113
|
+
- if your repo needs wrappers such as `pnpm exec`, `npx`, or `mise x`, configure them explicitly in `command`
|
|
114
|
+
|
|
115
|
+
Example:
|
|
116
|
+
|
|
117
|
+
```json
|
|
118
|
+
{
|
|
119
|
+
"formatters": {
|
|
120
|
+
"prettier": {
|
|
121
|
+
"command": ["pnpm", "exec", "prettier", "--write", "$FILE"],
|
|
122
|
+
"extensions": [".js", ".ts", ".tsx", ".json", ".md"]
|
|
123
|
+
},
|
|
124
|
+
"markdownlint-cli2": {
|
|
125
|
+
"command": ["pnpm", "exec", "markdownlint-cli2", "--fix", "$FILE"],
|
|
126
|
+
"extensions": [".md"],
|
|
127
|
+
"environment": {
|
|
128
|
+
"CI": "1"
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### `chains`
|
|
136
|
+
|
|
137
|
+
Ordered formatter chains keyed by file extension.
|
|
138
|
+
|
|
139
|
+
For v1, formatter execution is driven by explicit `chains` only.
|
|
140
|
+
If an extension has no `chains` entry, `pi-autoformat` does not run any formatter for that extension.
|
|
141
|
+
|
|
142
|
+
The chain order is explicit and should be preserved.
|
|
143
|
+
|
|
144
|
+
Example:
|
|
145
|
+
|
|
146
|
+
```json
|
|
147
|
+
{
|
|
148
|
+
"chains": {
|
|
149
|
+
".md": ["prettier", "markdownlint-cli2"],
|
|
150
|
+
".ts": ["prettier"],
|
|
151
|
+
".tsx": ["prettier"]
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Merge behavior
|
|
157
|
+
|
|
158
|
+
Merge order:
|
|
159
|
+
|
|
160
|
+
1. built-in defaults
|
|
161
|
+
2. global config
|
|
162
|
+
3. project config
|
|
163
|
+
|
|
164
|
+
Recommended merge semantics:
|
|
165
|
+
|
|
166
|
+
- top-level scalar values override by precedence
|
|
167
|
+
- `formatters` merge by formatter name
|
|
168
|
+
- `chains` merge by extension key
|
|
169
|
+
- when a project config defines a formatter or chain key, that key replaces the lower-precedence value for that entry
|
|
170
|
+
|
|
171
|
+
This keeps repo-local formatter behavior explicit while still allowing users to set global defaults such as `formatMode`.
|
|
172
|
+
|
|
173
|
+
## Notes
|
|
174
|
+
|
|
175
|
+
- Config is intentionally separate from Pi's shared `settings.json`.
|
|
176
|
+
- A dedicated config file avoids collisions with Pi core settings and makes strict schema validation practical.
|
|
177
|
+
- Schema URLs can point at either the default branch or pinned release tags depending on whether you want latest or reproducible validation behavior.
|