@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,66 @@
|
|
|
1
|
+
import { accessSync, constants, statSync } from "node:fs";
|
|
2
|
+
import { delimiter, isAbsolute, join } from "node:path";
|
|
3
|
+
|
|
4
|
+
export type CommandProbe = (command: string) => boolean;
|
|
5
|
+
|
|
6
|
+
function isExecutableFile(filePath: string): boolean {
|
|
7
|
+
try {
|
|
8
|
+
const stat = statSync(filePath);
|
|
9
|
+
if (!stat.isFile()) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
accessSync(filePath, constants.X_OK);
|
|
13
|
+
return true;
|
|
14
|
+
} catch {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Synchronous PATH probe.
|
|
21
|
+
*
|
|
22
|
+
* - An absolute path returns true iff it points at an executable file.
|
|
23
|
+
* - A bare command name is searched along $PATH; the first executable match wins.
|
|
24
|
+
*
|
|
25
|
+
* Windows is intentionally out of scope; this extension assumes POSIX-style
|
|
26
|
+
* invocation.
|
|
27
|
+
*/
|
|
28
|
+
export function defaultCommandProbe(command: string): boolean {
|
|
29
|
+
if (command.length === 0) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
if (isAbsolute(command)) {
|
|
33
|
+
return isExecutableFile(command);
|
|
34
|
+
}
|
|
35
|
+
const pathEnv = process.env.PATH ?? "";
|
|
36
|
+
if (pathEnv.length === 0) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
for (const segment of pathEnv.split(delimiter)) {
|
|
40
|
+
if (segment.length === 0) {
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
if (isExecutableFile(join(segment, command))) {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Wraps a probe in a per-instance memoization cache. Intended to be created
|
|
52
|
+
* once per flush and shared across chain groups so the same command is probed
|
|
53
|
+
* at most once per flush.
|
|
54
|
+
*/
|
|
55
|
+
export function createCachedCommandProbe(probe: CommandProbe): CommandProbe {
|
|
56
|
+
const cache = new Map<string, boolean>();
|
|
57
|
+
return (command) => {
|
|
58
|
+
const cached = cache.get(command);
|
|
59
|
+
if (cached !== undefined) {
|
|
60
|
+
return cached;
|
|
61
|
+
}
|
|
62
|
+
const result = probe(command);
|
|
63
|
+
cache.set(command, result);
|
|
64
|
+
return result;
|
|
65
|
+
};
|
|
66
|
+
}
|