pi-rtk-optimizer 0.5.4 → 0.6.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/CHANGELOG.md +17 -6
- package/README.md +34 -49
- package/config/config.example.json +0 -9
- package/package.json +64 -64
- package/src/additional-coverage-test.ts +13 -14
- package/src/command-rewriter-test.ts +118 -160
- package/src/command-rewriter.ts +43 -594
- package/src/config-modal-test.ts +3 -0
- package/src/config-modal.ts +1 -105
- package/src/config-store.ts +0 -24
- package/src/index-test.ts +80 -1
- package/src/index.ts +21 -6
- package/src/output-compactor-test.ts +4 -4
- package/src/rtk-rewrite-provider.ts +90 -0
- package/src/runtime-guard-test.ts +4 -3
- package/src/runtime-guard.ts +1 -1
- package/src/types.ts +0 -18
- package/src/rewrite-bypass.ts +0 -332
- package/src/rewrite-rules.ts +0 -255
|
@@ -1,160 +1,118 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
|
|
3
|
-
import { computeRewriteDecision } from "./command-rewriter.ts";
|
|
4
|
-
import { cloneDefaultConfig, runTest } from "./test-helpers.ts";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
return
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
runTest("
|
|
12
|
-
const config = cloneDefaultConfig();
|
|
13
|
-
const decision = computeRewriteDecision("
|
|
14
|
-
|
|
15
|
-
assert.equal(decision.
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
);
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
assert.equal(decision.
|
|
29
|
-
assert.equal(decision.reason, "no_match");
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
runTest("
|
|
33
|
-
const config = cloneDefaultConfig();
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
assert.equal(
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
assert.equal(
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
assert.equal(
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
assert.equal(decision.changed,
|
|
80
|
-
assert.equal(decision.
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const
|
|
86
|
-
const
|
|
87
|
-
assert.equal(
|
|
88
|
-
assert.equal(
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
];
|
|
120
|
-
|
|
121
|
-
for (const command of auditedCommands) {
|
|
122
|
-
const decision = computeRewriteDecision(command, config);
|
|
123
|
-
assert.equal(decision.changed, false, command);
|
|
124
|
-
assert.equal(decision.rewrittenCommand, command, command);
|
|
125
|
-
assert.equal(decision.reason, "no_match", command);
|
|
126
|
-
}
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
runTest("formatting-sensitive ls flows bypass rewrites", () => {
|
|
130
|
-
const config = cloneDefaultConfig();
|
|
131
|
-
const auditedCommands = ["ls -la", "ls -l src | grep command-rewriter"];
|
|
132
|
-
|
|
133
|
-
for (const command of auditedCommands) {
|
|
134
|
-
const decision = computeRewriteDecision(command, config);
|
|
135
|
-
assert.equal(decision.changed, false, command);
|
|
136
|
-
assert.equal(decision.rewrittenCommand, command, command);
|
|
137
|
-
assert.equal(decision.reason, "no_match", command);
|
|
138
|
-
}
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
runTest("native bash shell proxy flows bypass rewrites when RTK parity is unsafe", () => {
|
|
142
|
-
const config = cloneDefaultConfig();
|
|
143
|
-
const command = 'bash -lc "find src -type f | xargs grep todo"';
|
|
144
|
-
const decision = computeRewriteDecision(command, config);
|
|
145
|
-
|
|
146
|
-
assert.equal(decision.changed, false);
|
|
147
|
-
assert.equal(decision.rewrittenCommand, command);
|
|
148
|
-
assert.equal(decision.reason, "no_match");
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
runTest("python proxy rewrites preserve the original executable token", () => {
|
|
152
|
-
const config = cloneDefaultConfig();
|
|
153
|
-
const decision = computeRewriteDecision('python3.11 -c "print(1)"', config);
|
|
154
|
-
|
|
155
|
-
assert.equal(decision.changed, true);
|
|
156
|
-
assert.equal(decision.rule?.id, "python-proxy");
|
|
157
|
-
assert.equal(decision.rewrittenCommand, `rtk proxy ${expectedProxyExecutable("python3.11")} -c "print(1)"`);
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
console.log("All command-rewriter tests passed.");
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
|
|
3
|
+
import { computeRewriteDecision } from "./command-rewriter.ts";
|
|
4
|
+
import { cloneDefaultConfig, runTest } from "./test-helpers.ts";
|
|
5
|
+
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
6
|
+
|
|
7
|
+
function createMockPi(execResult: { code: number; stdout?: string; stderr?: string }): ExtensionAPI {
|
|
8
|
+
return { exec: async () => execResult } as unknown as ExtensionAPI;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
runTest("empty command unchanged", async () => {
|
|
12
|
+
const config = cloneDefaultConfig();
|
|
13
|
+
const decision = await computeRewriteDecision("", config, createMockPi({ code: 1 }));
|
|
14
|
+
assert.equal(decision.changed, false);
|
|
15
|
+
assert.equal(decision.reason, "empty");
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
runTest("already rtk unchanged", async () => {
|
|
19
|
+
const config = cloneDefaultConfig();
|
|
20
|
+
const decision = await computeRewriteDecision("rtk status", config, createMockPi({ code: 1 }));
|
|
21
|
+
assert.equal(decision.changed, false);
|
|
22
|
+
assert.equal(decision.reason, "already_rtk");
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
runTest("rtk unsupported heredoc result leaves command unchanged", async () => {
|
|
26
|
+
const config = cloneDefaultConfig();
|
|
27
|
+
const decision = await computeRewriteDecision("cat <<EOF", config, createMockPi({ code: 1 }));
|
|
28
|
+
assert.equal(decision.changed, false);
|
|
29
|
+
assert.equal(decision.reason, "no_match");
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
runTest("quoted heredoc marker is delegated to RTK rewrite", async () => {
|
|
33
|
+
const config = cloneDefaultConfig();
|
|
34
|
+
const command = 'echo "<<not heredoc" && git status';
|
|
35
|
+
const decision = await computeRewriteDecision(
|
|
36
|
+
command,
|
|
37
|
+
config,
|
|
38
|
+
createMockPi({ code: 3, stdout: 'echo "<<not heredoc" && rtk git status' }),
|
|
39
|
+
);
|
|
40
|
+
assert.equal(decision.changed, true);
|
|
41
|
+
assert.equal(decision.rewrittenCommand, 'echo "<<not heredoc" && rtk git status');
|
|
42
|
+
assert.equal(decision.reason, "ok");
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
runTest("legacy category toggles do not pre-filter RTK rewrite source of truth", async () => {
|
|
46
|
+
const config = { ...cloneDefaultConfig(), rewriteGitGithub: false };
|
|
47
|
+
const decision = await computeRewriteDecision("git status", config, createMockPi({ code: 3, stdout: "rtk git status" }));
|
|
48
|
+
assert.equal(decision.changed, true);
|
|
49
|
+
assert.equal(decision.rewrittenCommand, "rtk git status");
|
|
50
|
+
assert.equal(decision.reason, "ok");
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
runTest("rtk exit 0 rewrites", async () => {
|
|
54
|
+
const config = cloneDefaultConfig();
|
|
55
|
+
const decision = await computeRewriteDecision("git status", config, createMockPi({ code: 0, stdout: "rtk git status" }));
|
|
56
|
+
assert.equal(decision.changed, true);
|
|
57
|
+
assert.equal(decision.rewrittenCommand, "rtk git status");
|
|
58
|
+
assert.equal(decision.reason, "ok");
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
runTest("rtk exit 3 rewrites", async () => {
|
|
62
|
+
const config = cloneDefaultConfig();
|
|
63
|
+
const decision = await computeRewriteDecision("git status", config, createMockPi({ code: 3, stdout: "rtk git status" }));
|
|
64
|
+
assert.equal(decision.changed, true);
|
|
65
|
+
assert.equal(decision.rewrittenCommand, "rtk git status");
|
|
66
|
+
assert.equal(decision.reason, "ok");
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
runTest("exit 1 leaves unchanged", async () => {
|
|
70
|
+
const config = cloneDefaultConfig();
|
|
71
|
+
const decision = await computeRewriteDecision("git status", config, createMockPi({ code: 1 }));
|
|
72
|
+
assert.equal(decision.changed, false);
|
|
73
|
+
assert.equal(decision.reason, "no_match");
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
runTest("exit 2 leaves unchanged", async () => {
|
|
77
|
+
const config = cloneDefaultConfig();
|
|
78
|
+
const decision = await computeRewriteDecision("git status", config, createMockPi({ code: 2, stderr: "denied" }));
|
|
79
|
+
assert.equal(decision.changed, false);
|
|
80
|
+
assert.equal(decision.reason, "no_match");
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
runTest("unknown category passes through to RTK", async () => {
|
|
84
|
+
const config = cloneDefaultConfig();
|
|
85
|
+
const pi = createMockPi({ code: 0, stdout: "rtk custom" });
|
|
86
|
+
const decision = await computeRewriteDecision("custom-cmd", config, pi);
|
|
87
|
+
assert.equal(decision.changed, true);
|
|
88
|
+
assert.equal(decision.rewrittenCommand, "rtk custom");
|
|
89
|
+
assert.equal(decision.reason, "ok");
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
runTest("exec error/timeout leaves unchanged", async () => {
|
|
93
|
+
const config = cloneDefaultConfig();
|
|
94
|
+
const pi = {
|
|
95
|
+
exec: async () => {
|
|
96
|
+
throw new Error("timeout");
|
|
97
|
+
},
|
|
98
|
+
} as unknown as ExtensionAPI;
|
|
99
|
+
const decision = await computeRewriteDecision("git status", config, pi);
|
|
100
|
+
assert.equal(decision.changed, false);
|
|
101
|
+
assert.equal(decision.reason, "no_match");
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
runTest("compound commands forwarded to RTK", async () => {
|
|
105
|
+
const config = cloneDefaultConfig();
|
|
106
|
+
let capturedArgs: string[] = [];
|
|
107
|
+
const pi = {
|
|
108
|
+
exec: async (_cmd: string, args: string[]) => {
|
|
109
|
+
capturedArgs = args;
|
|
110
|
+
return { code: 0, stdout: "rtk result" };
|
|
111
|
+
},
|
|
112
|
+
} as unknown as ExtensionAPI;
|
|
113
|
+
const decision = await computeRewriteDecision("git status && cargo test", config, pi);
|
|
114
|
+
assert.equal(decision.changed, true);
|
|
115
|
+
assert.deepEqual(capturedArgs, ["rewrite", "git status && cargo test"]);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
console.log("All command-rewriter tests passed.");
|