pi-rtk-optimizer 0.3.3 → 0.5.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.
Files changed (38) hide show
  1. package/CHANGELOG.md +102 -67
  2. package/README.md +292 -290
  3. package/config/config.example.json +36 -35
  4. package/package.json +4 -4
  5. package/src/additional-coverage-test.ts +278 -0
  6. package/src/boolean-format.ts +3 -0
  7. package/src/command-rewriter-test.ts +160 -120
  8. package/src/command-rewriter.ts +594 -585
  9. package/src/config-modal-test.ts +168 -0
  10. package/src/config-modal.ts +613 -600
  11. package/src/config-store.ts +224 -217
  12. package/src/index-test.ts +54 -0
  13. package/src/index.ts +410 -289
  14. package/src/output-compactor-test.ts +500 -158
  15. package/src/output-compactor.ts +432 -349
  16. package/src/record-utils.ts +6 -0
  17. package/src/rewrite-bypass.ts +332 -173
  18. package/src/rewrite-pipeline-safety.ts +154 -0
  19. package/src/rewrite-rules.ts +255 -255
  20. package/src/rtk-command-environment.ts +64 -0
  21. package/src/runtime-guard-test.ts +42 -50
  22. package/src/runtime-guard.ts +14 -14
  23. package/src/techniques/build.ts +155 -155
  24. package/src/techniques/emoji.ts +91 -0
  25. package/src/techniques/git.ts +231 -229
  26. package/src/techniques/index.ts +10 -16
  27. package/src/techniques/linter.ts +151 -161
  28. package/src/techniques/path-utils.ts +67 -0
  29. package/src/techniques/rtk.ts +136 -0
  30. package/src/techniques/search.ts +67 -76
  31. package/src/techniques/source.ts +253 -253
  32. package/src/techniques/test-output.ts +172 -172
  33. package/src/test-helpers.ts +10 -0
  34. package/src/tool-execution-sanitizer.ts +69 -0
  35. package/src/types-shims.d.ts +192 -183
  36. package/src/types.ts +103 -114
  37. package/src/zellij-modal.ts +1001 -1001
  38. package/src/compat-commands.ts +0 -207
@@ -1,255 +1,255 @@
1
- export type RtkRewriteCategory =
2
- | "gitGithub"
3
- | "filesystem"
4
- | "rust"
5
- | "javascript"
6
- | "python"
7
- | "go"
8
- | "containers"
9
- | "network"
10
- | "packageManagers";
11
-
12
- export interface RtkRewriteRule {
13
- id: string;
14
- category: RtkRewriteCategory;
15
- matcher: RegExp;
16
- replacement: string;
17
- description: string;
18
- }
19
-
20
- export const RTK_REWRITE_RULES: RtkRewriteRule[] = [
21
- // Git / GitHub
22
- {
23
- id: "git-leading-flags-proxy",
24
- category: "gitGithub",
25
- matcher: /^git\s+-(.+)$/,
26
- replacement: "rtk proxy git -$1",
27
- description: "git with leading flags (e.g. -C, --no-pager) -> proxy",
28
- },
29
- {
30
- id: "git-any",
31
- category: "gitGithub",
32
- matcher: /^git\s+(.+)$/,
33
- replacement: "rtk git $1",
34
- description: "git <args> -> rtk git",
35
- },
36
- {
37
- id: "gh-leading-flags-proxy",
38
- category: "gitGithub",
39
- matcher: /^gh\s+-(.+)$/,
40
- replacement: "rtk proxy gh -$1",
41
- description: "gh with leading flags -> proxy",
42
- },
43
- {
44
- id: "gh-any",
45
- category: "gitGithub",
46
- matcher: /^gh\s+(.+)$/,
47
- replacement: "rtk gh $1",
48
- description: "gh <args> -> rtk gh",
49
- },
50
-
51
- // Filesystem / shell helpers
52
- { id: "cat", category: "filesystem", matcher: /^cat\s+/, replacement: "rtk read ", description: "cat" },
53
- {
54
- id: "head-short-lines",
55
- category: "filesystem",
56
- matcher: /^head\s+-([0-9]+)\s+(.+)$/,
57
- replacement: "rtk read $2 --max-lines $1",
58
- description: "head -N <file>",
59
- },
60
- {
61
- id: "head-long-lines",
62
- category: "filesystem",
63
- matcher: /^head\s+--lines=([0-9]+)\s+(.+)$/,
64
- replacement: "rtk read $2 --max-lines $1",
65
- description: "head --lines=N <file>",
66
- },
67
- {
68
- id: "tail-short-lines",
69
- category: "filesystem",
70
- matcher: /^tail\s+-n\s*([0-9]+)\s+(.+)$/,
71
- replacement: "rtk read $2 --max-lines $1",
72
- description: "tail -n N <file>",
73
- },
74
- {
75
- id: "tail-long-lines",
76
- category: "filesystem",
77
- matcher: /^tail\s+--lines=([0-9]+)\s+(.+)$/,
78
- replacement: "rtk read $2 --max-lines $1",
79
- description: "tail --lines=N <file>",
80
- },
81
- { id: "grep", category: "filesystem", matcher: /^(rg|grep)\s+/, replacement: "rtk grep ", description: "rg/grep" },
82
- { id: "ls", category: "filesystem", matcher: /^ls\b/, replacement: "rtk ls", description: "ls" },
83
- { id: "tree", category: "filesystem", matcher: /^tree\b/, replacement: "rtk tree", description: "tree" },
84
- { id: "find", category: "filesystem", matcher: /^find\s+/, replacement: "rtk find ", description: "find" },
85
- { id: "diff", category: "filesystem", matcher: /^diff\s+/, replacement: "rtk diff ", description: "diff" },
86
- { id: "wc", category: "filesystem", matcher: /^wc\b/, replacement: "rtk wc", description: "wc" },
87
- {
88
- id: "powershell-proxy",
89
- category: "filesystem",
90
- matcher: /^(powershell(?:\.exe)?)\s+(.+)$/i,
91
- replacement: "rtk proxy $1 $2",
92
- description: "powershell -> proxy",
93
- },
94
- {
95
- id: "cmd-proxy",
96
- category: "filesystem",
97
- matcher: /^(cmd(?:\.exe)?)\s+(.+)$/i,
98
- replacement: "rtk proxy $1 $2",
99
- description: "cmd -> proxy",
100
- },
101
- { id: "bash-proxy", category: "filesystem", matcher: /^bash\s+(.+)$/i, replacement: "rtk proxy bash $1", description: "bash -> proxy" },
102
-
103
- // Rust
104
- {
105
- id: "cargo-any",
106
- category: "rust",
107
- matcher: /^cargo\s+(.+)$/,
108
- replacement: "rtk cargo $1",
109
- description: "cargo <args> -> rtk cargo",
110
- },
111
-
112
- // JavaScript / TypeScript ecosystem
113
- { id: "vitest", category: "javascript", matcher: /^vitest(?:\s+run)?\b/, replacement: "rtk vitest run", description: "vitest" },
114
- { id: "npx-vitest", category: "javascript", matcher: /^npx\s+vitest(?:\s+run)?\b/, replacement: "rtk vitest run", description: "npx vitest" },
115
- { id: "bunx-vitest", category: "javascript", matcher: /^bunx\s+vitest(?:\s+run)?\b/, replacement: "rtk vitest run", description: "bunx vitest" },
116
- { id: "pnpm-vitest", category: "javascript", matcher: /^pnpm\s+(?:exec\s+)?vitest(?:\s+run)?\b/, replacement: "rtk vitest run", description: "pnpm vitest" },
117
- {
118
- id: "npm-run",
119
- category: "javascript",
120
- matcher: /^npm\s+run\s+(.+)$/,
121
- replacement: "rtk proxy npm run $1",
122
- description: "npm run <script> -> proxy",
123
- },
124
- {
125
- id: "npm-script-shorthand",
126
- category: "javascript",
127
- matcher: /^npm\s+(test|start|build|lint)\b(.*)$/,
128
- replacement: "rtk proxy npm $1$2",
129
- description: "npm test/start/build/lint -> proxy",
130
- },
131
- { id: "tsc", category: "javascript", matcher: /^tsc\b/, replacement: "rtk tsc", description: "tsc" },
132
- { id: "npx-tsc", category: "javascript", matcher: /^npx\s+tsc\b/, replacement: "rtk tsc", description: "npx tsc" },
133
- { id: "bunx-tsc", category: "javascript", matcher: /^bunx\s+tsc\b/, replacement: "rtk tsc", description: "bunx tsc" },
134
- { id: "pnpm-tsc", category: "javascript", matcher: /^pnpm\s+(?:exec\s+)?tsc\b/, replacement: "rtk tsc", description: "pnpm tsc" },
135
- { id: "pnpm-typecheck", category: "javascript", matcher: /^pnpm\s+typecheck\b/, replacement: "rtk tsc", description: "pnpm typecheck" },
136
- { id: "eslint", category: "javascript", matcher: /^eslint\b/, replacement: "rtk lint", description: "eslint" },
137
- { id: "npx-eslint", category: "javascript", matcher: /^npx\s+eslint\b/, replacement: "rtk lint", description: "npx eslint" },
138
- { id: "bunx-eslint", category: "javascript", matcher: /^bunx\s+eslint\b/, replacement: "rtk lint", description: "bunx eslint" },
139
- { id: "pnpm-lint", category: "javascript", matcher: /^pnpm\s+lint\b/, replacement: "rtk lint", description: "pnpm lint" },
140
- { id: "next", category: "javascript", matcher: /^next\b/, replacement: "rtk next", description: "next" },
141
- { id: "npx-next", category: "javascript", matcher: /^npx\s+next\b/, replacement: "rtk next", description: "npx next" },
142
- { id: "bunx-next", category: "javascript", matcher: /^bunx\s+next\b/, replacement: "rtk next", description: "bunx next" },
143
- { id: "prettier", category: "javascript", matcher: /^prettier\b/, replacement: "rtk prettier", description: "prettier" },
144
- { id: "npx-prettier", category: "javascript", matcher: /^npx\s+prettier\b/, replacement: "rtk prettier", description: "npx prettier" },
145
- { id: "bunx-prettier", category: "javascript", matcher: /^bunx\s+prettier\b/, replacement: "rtk prettier", description: "bunx prettier" },
146
- { id: "playwright", category: "javascript", matcher: /^playwright\b/, replacement: "rtk playwright", description: "playwright" },
147
- { id: "npx-playwright", category: "javascript", matcher: /^npx\s+playwright\b/, replacement: "rtk playwright", description: "npx playwright" },
148
- { id: "bunx-playwright", category: "javascript", matcher: /^bunx\s+playwright\b/, replacement: "rtk playwright", description: "bunx playwright" },
149
- { id: "pnpm-playwright", category: "javascript", matcher: /^pnpm\s+playwright\b/, replacement: "rtk playwright", description: "pnpm playwright" },
150
- { id: "prisma", category: "javascript", matcher: /^prisma\b/, replacement: "rtk prisma", description: "prisma" },
151
- { id: "npx-prisma", category: "javascript", matcher: /^npx\s+prisma\b/, replacement: "rtk prisma", description: "npx prisma" },
152
- { id: "bunx-prisma", category: "javascript", matcher: /^bunx\s+prisma\b/, replacement: "rtk prisma", description: "bunx prisma" },
153
- { id: "pnpm-prisma", category: "javascript", matcher: /^pnpm\s+prisma\b/, replacement: "rtk prisma", description: "pnpm prisma" },
154
- { id: "bun-proxy", category: "javascript", matcher: /^bun\s+(.+)$/, replacement: "rtk proxy bun $1", description: "bun -> proxy" },
155
- { id: "node-proxy", category: "javascript", matcher: /^node\s+(.+)$/, replacement: "rtk proxy node $1", description: "node -> proxy" },
156
- { id: "tsx-proxy", category: "javascript", matcher: /^tsx\s+(.+)$/, replacement: "rtk proxy tsx $1", description: "tsx -> proxy" },
157
- { id: "npx-proxy", category: "javascript", matcher: /^npx\s+(.+)$/, replacement: "rtk proxy npx $1", description: "npx fallback -> proxy" },
158
- { id: "bunx-proxy", category: "javascript", matcher: /^bunx\s+(.+)$/, replacement: "rtk proxy bunx $1", description: "bunx fallback -> proxy" },
159
-
160
- // Python
161
- { id: "pytest", category: "python", matcher: /^pytest\b/, replacement: "rtk pytest", description: "pytest" },
162
- { id: "python-pytest", category: "python", matcher: /^python(?:3(?:\.\d+)?)?\s+-m\s+pytest\b/, replacement: "rtk pytest", description: "python -m pytest" },
163
- { id: "ruff", category: "python", matcher: /^ruff\b/, replacement: "rtk ruff", description: "ruff" },
164
- { id: "python-ruff", category: "python", matcher: /^python(?:3(?:\.\d+)?)?\s+-m\s+ruff\b/, replacement: "rtk ruff", description: "python -m ruff" },
165
- {
166
- id: "pip",
167
- category: "python",
168
- matcher: /^pip\s+(list|outdated|install|uninstall|show)\b/,
169
- replacement: "rtk pip $1",
170
- description: "pip supported commands",
171
- },
172
- {
173
- id: "uv-pip",
174
- category: "python",
175
- matcher: /^uv\s+pip\s+(list|outdated|install|uninstall|show)\b/,
176
- replacement: "rtk pip $1",
177
- description: "uv pip supported commands",
178
- },
179
- {
180
- id: "python-pip",
181
- category: "python",
182
- matcher: /^python(?:3(?:\.\d+)?)?\s+-m\s+pip\s+(list|outdated|install|uninstall|show)\b/,
183
- replacement: "rtk pip $1",
184
- description: "python -m pip supported commands",
185
- },
186
- {
187
- id: "python-proxy",
188
- category: "python",
189
- matcher: /^python(?:3(?:\.\d+)?)?\s+(.+)$/,
190
- replacement: "rtk proxy python $1",
191
- description: "python fallback -> proxy",
192
- },
193
- { id: "poetry-proxy", category: "python", matcher: /^poetry\s+(.+)$/, replacement: "rtk proxy poetry $1", description: "poetry -> proxy" },
194
-
195
- // Go
196
- { id: "go-any", category: "go", matcher: /^go\s+(.+)$/, replacement: "rtk go $1", description: "go <args> -> rtk go" },
197
- { id: "golangci", category: "go", matcher: /^golangci-lint\b/, replacement: "rtk golangci-lint", description: "golangci-lint" },
198
-
199
- // Containers
200
- {
201
- id: "docker-compose",
202
- category: "containers",
203
- matcher: /^docker\s+compose\s+(.+)$/,
204
- replacement: "rtk docker compose $1",
205
- description: "docker compose",
206
- },
207
- {
208
- id: "docker",
209
- category: "containers",
210
- matcher: /^docker\s+(.+)$/,
211
- replacement: "rtk docker $1",
212
- description: "docker",
213
- },
214
- {
215
- id: "kubectl",
216
- category: "containers",
217
- matcher: /^kubectl\s+(.+)$/,
218
- replacement: "rtk kubectl $1",
219
- description: "kubectl",
220
- },
221
-
222
- // Network
223
- { id: "curl", category: "network", matcher: /^curl\s+/, replacement: "rtk curl ", description: "curl" },
224
- { id: "wget", category: "network", matcher: /^wget\s+/, replacement: "rtk wget ", description: "wget" },
225
-
226
- // Package managers
227
- {
228
- id: "npm-proxy",
229
- category: "packageManagers",
230
- matcher: /^npm\s+(.+)$/,
231
- replacement: "rtk proxy npm $1",
232
- description: "npm fallback -> proxy",
233
- },
234
- {
235
- id: "pnpm-leading-flags-proxy",
236
- category: "packageManagers",
237
- matcher: /^pnpm\s+-(.+)$/,
238
- replacement: "rtk proxy pnpm -$1",
239
- description: "pnpm with leading flags -> proxy",
240
- },
241
- {
242
- id: "pnpm-dlx-proxy",
243
- category: "packageManagers",
244
- matcher: /^pnpm\s+dlx\b(.*)$/,
245
- replacement: "rtk proxy pnpm dlx$1",
246
- description: "pnpm dlx -> proxy",
247
- },
248
- {
249
- id: "pnpm-any",
250
- category: "packageManagers",
251
- matcher: /^pnpm\s+(.+)$/,
252
- replacement: "rtk pnpm $1",
253
- description: "pnpm <args> -> rtk pnpm",
254
- },
255
- ];
1
+ export type RtkRewriteCategory =
2
+ | "gitGithub"
3
+ | "filesystem"
4
+ | "rust"
5
+ | "javascript"
6
+ | "python"
7
+ | "go"
8
+ | "containers"
9
+ | "network"
10
+ | "packageManagers";
11
+
12
+ export interface RtkRewriteRule {
13
+ id: string;
14
+ category: RtkRewriteCategory;
15
+ matcher: RegExp;
16
+ replacement: string;
17
+ description: string;
18
+ }
19
+
20
+ export const RTK_REWRITE_RULES: RtkRewriteRule[] = [
21
+ // Git / GitHub
22
+ {
23
+ id: "git-leading-flags-proxy",
24
+ category: "gitGithub",
25
+ matcher: /^git\s+-(.+)$/,
26
+ replacement: "rtk proxy git -$1",
27
+ description: "git with leading flags (e.g. -C, --no-pager) -> proxy",
28
+ },
29
+ {
30
+ id: "git-any",
31
+ category: "gitGithub",
32
+ matcher: /^git\s+(.+)$/,
33
+ replacement: "rtk git $1",
34
+ description: "git <args> -> rtk git",
35
+ },
36
+ {
37
+ id: "gh-leading-flags-proxy",
38
+ category: "gitGithub",
39
+ matcher: /^gh\s+-(.+)$/,
40
+ replacement: "rtk proxy gh -$1",
41
+ description: "gh with leading flags -> proxy",
42
+ },
43
+ {
44
+ id: "gh-any",
45
+ category: "gitGithub",
46
+ matcher: /^gh\s+(.+)$/,
47
+ replacement: "rtk gh $1",
48
+ description: "gh <args> -> rtk gh",
49
+ },
50
+
51
+ // Filesystem / shell helpers
52
+ { id: "cat", category: "filesystem", matcher: /^cat\s+/, replacement: "rtk read ", description: "cat" },
53
+ {
54
+ id: "head-short-lines",
55
+ category: "filesystem",
56
+ matcher: /^head\s+-([0-9]+)\s+(.+)$/,
57
+ replacement: "rtk read $2 --max-lines $1",
58
+ description: "head -N <file>",
59
+ },
60
+ {
61
+ id: "head-long-lines",
62
+ category: "filesystem",
63
+ matcher: /^head\s+--lines=([0-9]+)\s+(.+)$/,
64
+ replacement: "rtk read $2 --max-lines $1",
65
+ description: "head --lines=N <file>",
66
+ },
67
+ {
68
+ id: "tail-short-lines",
69
+ category: "filesystem",
70
+ matcher: /^tail\s+-n\s*([0-9]+)\s+(.+)$/,
71
+ replacement: "rtk read $2 --max-lines $1",
72
+ description: "tail -n N <file>",
73
+ },
74
+ {
75
+ id: "tail-long-lines",
76
+ category: "filesystem",
77
+ matcher: /^tail\s+--lines=([0-9]+)\s+(.+)$/,
78
+ replacement: "rtk read $2 --max-lines $1",
79
+ description: "tail --lines=N <file>",
80
+ },
81
+ { id: "grep", category: "filesystem", matcher: /^(rg|grep)\s+/, replacement: "rtk grep ", description: "rg/grep" },
82
+ { id: "ls", category: "filesystem", matcher: /^ls\b/, replacement: "rtk ls", description: "ls" },
83
+ { id: "tree", category: "filesystem", matcher: /^tree\b/, replacement: "rtk tree", description: "tree" },
84
+ { id: "find", category: "filesystem", matcher: /^find\s+/, replacement: "rtk find ", description: "find" },
85
+ { id: "diff", category: "filesystem", matcher: /^diff\s+/, replacement: "rtk diff ", description: "diff" },
86
+ { id: "wc", category: "filesystem", matcher: /^wc\b/, replacement: "rtk wc", description: "wc" },
87
+ {
88
+ id: "powershell-proxy",
89
+ category: "filesystem",
90
+ matcher: /^(powershell(?:\.exe)?)\s+(.+)$/i,
91
+ replacement: "rtk proxy $1 $2",
92
+ description: "powershell -> proxy",
93
+ },
94
+ {
95
+ id: "cmd-proxy",
96
+ category: "filesystem",
97
+ matcher: /^(cmd(?:\.exe)?)\s+(.+)$/i,
98
+ replacement: "rtk proxy $1 $2",
99
+ description: "cmd -> proxy",
100
+ },
101
+ { id: "bash-proxy", category: "filesystem", matcher: /^bash\s+(.+)$/i, replacement: "rtk proxy bash $1", description: "bash -> proxy" },
102
+
103
+ // Rust
104
+ {
105
+ id: "cargo-any",
106
+ category: "rust",
107
+ matcher: /^cargo\s+(.+)$/,
108
+ replacement: "rtk cargo $1",
109
+ description: "cargo <args> -> rtk cargo",
110
+ },
111
+
112
+ // JavaScript / TypeScript ecosystem
113
+ { id: "vitest", category: "javascript", matcher: /^vitest(?:\s+run)?\b/, replacement: "rtk vitest run", description: "vitest" },
114
+ { id: "npx-vitest", category: "javascript", matcher: /^npx\s+vitest(?:\s+run)?\b/, replacement: "rtk vitest run", description: "npx vitest" },
115
+ { id: "bunx-vitest", category: "javascript", matcher: /^bunx\s+vitest(?:\s+run)?\b/, replacement: "rtk vitest run", description: "bunx vitest" },
116
+ { id: "pnpm-vitest", category: "javascript", matcher: /^pnpm\s+(?:exec\s+)?vitest(?:\s+run)?\b/, replacement: "rtk vitest run", description: "pnpm vitest" },
117
+ {
118
+ id: "npm-run",
119
+ category: "javascript",
120
+ matcher: /^npm\s+run\s+(.+)$/,
121
+ replacement: "rtk proxy npm run $1",
122
+ description: "npm run <script> -> proxy",
123
+ },
124
+ {
125
+ id: "npm-script-shorthand",
126
+ category: "javascript",
127
+ matcher: /^npm\s+(test|start|build|lint)\b(.*)$/,
128
+ replacement: "rtk proxy npm $1$2",
129
+ description: "npm test/start/build/lint -> proxy",
130
+ },
131
+ { id: "tsc", category: "javascript", matcher: /^tsc\b/, replacement: "rtk tsc", description: "tsc" },
132
+ { id: "npx-tsc", category: "javascript", matcher: /^npx\s+tsc\b/, replacement: "rtk tsc", description: "npx tsc" },
133
+ { id: "bunx-tsc", category: "javascript", matcher: /^bunx\s+tsc\b/, replacement: "rtk tsc", description: "bunx tsc" },
134
+ { id: "pnpm-tsc", category: "javascript", matcher: /^pnpm\s+(?:exec\s+)?tsc\b/, replacement: "rtk tsc", description: "pnpm tsc" },
135
+ { id: "pnpm-typecheck", category: "javascript", matcher: /^pnpm\s+typecheck\b/, replacement: "rtk tsc", description: "pnpm typecheck" },
136
+ { id: "eslint", category: "javascript", matcher: /^eslint\b/, replacement: "rtk lint", description: "eslint" },
137
+ { id: "npx-eslint", category: "javascript", matcher: /^npx\s+eslint\b/, replacement: "rtk lint", description: "npx eslint" },
138
+ { id: "bunx-eslint", category: "javascript", matcher: /^bunx\s+eslint\b/, replacement: "rtk lint", description: "bunx eslint" },
139
+ { id: "pnpm-lint", category: "javascript", matcher: /^pnpm\s+lint\b/, replacement: "rtk lint", description: "pnpm lint" },
140
+ { id: "next", category: "javascript", matcher: /^next\b/, replacement: "rtk next", description: "next" },
141
+ { id: "npx-next", category: "javascript", matcher: /^npx\s+next\b/, replacement: "rtk next", description: "npx next" },
142
+ { id: "bunx-next", category: "javascript", matcher: /^bunx\s+next\b/, replacement: "rtk next", description: "bunx next" },
143
+ { id: "prettier", category: "javascript", matcher: /^prettier\b/, replacement: "rtk prettier", description: "prettier" },
144
+ { id: "npx-prettier", category: "javascript", matcher: /^npx\s+prettier\b/, replacement: "rtk prettier", description: "npx prettier" },
145
+ { id: "bunx-prettier", category: "javascript", matcher: /^bunx\s+prettier\b/, replacement: "rtk prettier", description: "bunx prettier" },
146
+ { id: "playwright", category: "javascript", matcher: /^playwright\b/, replacement: "rtk playwright", description: "playwright" },
147
+ { id: "npx-playwright", category: "javascript", matcher: /^npx\s+playwright\b/, replacement: "rtk playwright", description: "npx playwright" },
148
+ { id: "bunx-playwright", category: "javascript", matcher: /^bunx\s+playwright\b/, replacement: "rtk playwright", description: "bunx playwright" },
149
+ { id: "pnpm-playwright", category: "javascript", matcher: /^pnpm\s+playwright\b/, replacement: "rtk playwright", description: "pnpm playwright" },
150
+ { id: "prisma", category: "javascript", matcher: /^prisma\b/, replacement: "rtk prisma", description: "prisma" },
151
+ { id: "npx-prisma", category: "javascript", matcher: /^npx\s+prisma\b/, replacement: "rtk prisma", description: "npx prisma" },
152
+ { id: "bunx-prisma", category: "javascript", matcher: /^bunx\s+prisma\b/, replacement: "rtk prisma", description: "bunx prisma" },
153
+ { id: "pnpm-prisma", category: "javascript", matcher: /^pnpm\s+prisma\b/, replacement: "rtk prisma", description: "pnpm prisma" },
154
+ { id: "bun-proxy", category: "javascript", matcher: /^bun\s+(.+)$/, replacement: "rtk proxy bun $1", description: "bun -> proxy" },
155
+ { id: "node-proxy", category: "javascript", matcher: /^node\s+(.+)$/, replacement: "rtk proxy node $1", description: "node -> proxy" },
156
+ { id: "tsx-proxy", category: "javascript", matcher: /^tsx\s+(.+)$/, replacement: "rtk proxy tsx $1", description: "tsx -> proxy" },
157
+ { id: "npx-proxy", category: "javascript", matcher: /^npx\s+(.+)$/, replacement: "rtk proxy npx $1", description: "npx fallback -> proxy" },
158
+ { id: "bunx-proxy", category: "javascript", matcher: /^bunx\s+(.+)$/, replacement: "rtk proxy bunx $1", description: "bunx fallback -> proxy" },
159
+
160
+ // Python
161
+ { id: "pytest", category: "python", matcher: /^pytest\b/, replacement: "rtk pytest", description: "pytest" },
162
+ { id: "python-pytest", category: "python", matcher: /^python(?:3(?:\.\d+)?)?\s+-m\s+pytest\b/, replacement: "rtk pytest", description: "python -m pytest" },
163
+ { id: "ruff", category: "python", matcher: /^ruff\b/, replacement: "rtk ruff", description: "ruff" },
164
+ { id: "python-ruff", category: "python", matcher: /^python(?:3(?:\.\d+)?)?\s+-m\s+ruff\b/, replacement: "rtk ruff", description: "python -m ruff" },
165
+ {
166
+ id: "pip",
167
+ category: "python",
168
+ matcher: /^pip\s+(list|outdated|install|uninstall|show)\b/,
169
+ replacement: "rtk pip $1",
170
+ description: "pip supported commands",
171
+ },
172
+ {
173
+ id: "uv-pip",
174
+ category: "python",
175
+ matcher: /^uv\s+pip\s+(list|outdated|install|uninstall|show)\b/,
176
+ replacement: "rtk pip $1",
177
+ description: "uv pip supported commands",
178
+ },
179
+ {
180
+ id: "python-pip",
181
+ category: "python",
182
+ matcher: /^python(?:3(?:\.\d+)?)?\s+-m\s+pip\s+(list|outdated|install|uninstall|show)\b/,
183
+ replacement: "rtk pip $1",
184
+ description: "python -m pip supported commands",
185
+ },
186
+ {
187
+ id: "python-proxy",
188
+ category: "python",
189
+ matcher: /^(python(?:3(?:\.\d+)?)?)\s+(.+)$/,
190
+ replacement: "rtk proxy $1 $2",
191
+ description: "python fallback -> proxy while preserving executable token",
192
+ },
193
+ { id: "poetry-proxy", category: "python", matcher: /^poetry\s+(.+)$/, replacement: "rtk proxy poetry $1", description: "poetry -> proxy" },
194
+
195
+ // Go
196
+ { id: "go-any", category: "go", matcher: /^go\s+(.+)$/, replacement: "rtk go $1", description: "go <args> -> rtk go" },
197
+ { id: "golangci", category: "go", matcher: /^golangci-lint\b/, replacement: "rtk golangci-lint", description: "golangci-lint" },
198
+
199
+ // Containers
200
+ {
201
+ id: "docker-compose",
202
+ category: "containers",
203
+ matcher: /^docker\s+compose\s+(.+)$/,
204
+ replacement: "rtk docker compose $1",
205
+ description: "docker compose",
206
+ },
207
+ {
208
+ id: "docker",
209
+ category: "containers",
210
+ matcher: /^docker\s+(.+)$/,
211
+ replacement: "rtk docker $1",
212
+ description: "docker",
213
+ },
214
+ {
215
+ id: "kubectl",
216
+ category: "containers",
217
+ matcher: /^kubectl\s+(.+)$/,
218
+ replacement: "rtk kubectl $1",
219
+ description: "kubectl",
220
+ },
221
+
222
+ // Network
223
+ { id: "curl", category: "network", matcher: /^curl\s+/, replacement: "rtk curl ", description: "curl" },
224
+ { id: "wget", category: "network", matcher: /^wget\s+/, replacement: "rtk wget ", description: "wget" },
225
+
226
+ // Package managers
227
+ {
228
+ id: "npm-proxy",
229
+ category: "packageManagers",
230
+ matcher: /^npm\s+(.+)$/,
231
+ replacement: "rtk proxy npm $1",
232
+ description: "npm fallback -> proxy",
233
+ },
234
+ {
235
+ id: "pnpm-leading-flags-proxy",
236
+ category: "packageManagers",
237
+ matcher: /^pnpm\s+-(.+)$/,
238
+ replacement: "rtk proxy pnpm -$1",
239
+ description: "pnpm with leading flags -> proxy",
240
+ },
241
+ {
242
+ id: "pnpm-dlx-proxy",
243
+ category: "packageManagers",
244
+ matcher: /^pnpm\s+dlx\b(.*)$/,
245
+ replacement: "rtk proxy pnpm dlx$1",
246
+ description: "pnpm dlx -> proxy",
247
+ },
248
+ {
249
+ id: "pnpm-any",
250
+ category: "packageManagers",
251
+ matcher: /^pnpm\s+(.+)$/,
252
+ replacement: "rtk pnpm $1",
253
+ description: "pnpm <args> -> rtk pnpm",
254
+ },
255
+ ];
@@ -0,0 +1,64 @@
1
+ import { join } from "node:path";
2
+
3
+ const RTK_DB_PATH_ENV_NAME = "RTK_DB_PATH";
4
+ const LEADING_ENV_ASSIGNMENT_PATTERN = /^((?:[A-Za-z_][A-Za-z0-9_]*=(?:"[^"]*"|'[^']*'|[^\s]+)\s+)*)/;
5
+ const RTK_DB_PATH_ASSIGNMENT_PATTERN = /(?:^|\s)RTK_DB_PATH=(?:"[^"]*"|'[^']*'|[^\s]+)(?=\s|$)/;
6
+
7
+ function resolveTemporaryDirectory(): string {
8
+ if (process.platform === "win32") {
9
+ const windowsTempDir = process.env.TEMP ?? process.env.TMP;
10
+ if (windowsTempDir && windowsTempDir.trim()) {
11
+ return windowsTempDir;
12
+ }
13
+
14
+ const localAppData = process.env.LOCALAPPDATA;
15
+ if (localAppData && localAppData.trim()) {
16
+ return join(localAppData, "Temp");
17
+ }
18
+
19
+ const userProfile = process.env.USERPROFILE;
20
+ if (userProfile && userProfile.trim()) {
21
+ return join(userProfile, "AppData", "Local", "Temp");
22
+ }
23
+
24
+ const systemRoot = process.env.SystemRoot ?? process.env.WINDIR;
25
+ if (systemRoot && systemRoot.trim()) {
26
+ return join(systemRoot, "Temp");
27
+ }
28
+
29
+ return "C:/Windows/Temp";
30
+ }
31
+
32
+ const posixTempDir = process.env.TMPDIR ?? process.env.TMP;
33
+ if (posixTempDir && posixTempDir.trim()) {
34
+ return posixTempDir;
35
+ }
36
+
37
+ return "/tmp";
38
+ }
39
+
40
+ function getTemporaryRtkHistoryDbPath(): string {
41
+ return join(resolveTemporaryDirectory(), "pi-rtk-optimizer", "history.db");
42
+ }
43
+
44
+ function quoteForShellEnv(value: string): string {
45
+ const normalizedValue = process.platform === "win32" ? value.replace(/\\/g, "/") : value;
46
+ return `"${normalizedValue.replace(/"/g, '\\"')}"`;
47
+ }
48
+
49
+ function hasLeadingRtkDbPathAssignment(command: string): boolean {
50
+ const leadingAssignments = command.match(LEADING_ENV_ASSIGNMENT_PATTERN)?.[1] ?? "";
51
+ return RTK_DB_PATH_ASSIGNMENT_PATTERN.test(leadingAssignments);
52
+ }
53
+
54
+ export function applyRtkCommandEnvironment(command: string): string {
55
+ if (!command.trim()) {
56
+ return command;
57
+ }
58
+
59
+ if (hasLeadingRtkDbPathAssignment(command)) {
60
+ return command;
61
+ }
62
+
63
+ return `${RTK_DB_PATH_ENV_NAME}=${quoteForShellEnv(getTemporaryRtkHistoryDbPath())} ${command}`;
64
+ }