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
package/src/rewrite-bypass.ts
DELETED
|
@@ -1,332 +0,0 @@
|
|
|
1
|
-
import type { RtkRewriteRule } from "./rewrite-rules.js";
|
|
2
|
-
|
|
3
|
-
const COMMAND_WORD_PATTERN = /"(?:\\.|[^"])*"|'(?:\\.|[^'])*'|`(?:\\.|[^`])*`|[^\s]+/g;
|
|
4
|
-
const BYPASSED_CARGO_SUBCOMMANDS = new Set(["help", "install", "publish"]);
|
|
5
|
-
const GH_STRUCTURED_OUTPUT_FLAGS = ["--json", "--jq", "--template"] as const;
|
|
6
|
-
const UNSAFE_COMPOUND_REWRITE_COMMANDS = new Set(["find", "grep", "rg", "ls"]);
|
|
7
|
-
const BYPASSED_FIND_ACTIONS = new Set([
|
|
8
|
-
"-delete",
|
|
9
|
-
"-exec",
|
|
10
|
-
"-execdir",
|
|
11
|
-
"-fprint",
|
|
12
|
-
"-fprint0",
|
|
13
|
-
"-fprintf",
|
|
14
|
-
"-fls",
|
|
15
|
-
"-ls",
|
|
16
|
-
"-ok",
|
|
17
|
-
"-okdir",
|
|
18
|
-
"-print0",
|
|
19
|
-
"-printf",
|
|
20
|
-
"-prune",
|
|
21
|
-
"-quit",
|
|
22
|
-
]);
|
|
23
|
-
const BASH_INLINE_COMMAND_FLAGS = new Set(["-c", "-cl", "-lc", "--command"]);
|
|
24
|
-
const POWERSHELL_INLINE_COMMAND_FLAGS = new Set(["-c", "-command", "-encodedcommand"]);
|
|
25
|
-
const CMD_INLINE_COMMAND_FLAGS = new Set(["/c", "/k"]);
|
|
26
|
-
const INTERACTIVE_CONTAINER_SHELLS = new Set([
|
|
27
|
-
"ash",
|
|
28
|
-
"bash",
|
|
29
|
-
"cmd",
|
|
30
|
-
"cmd.exe",
|
|
31
|
-
"fish",
|
|
32
|
-
"powershell",
|
|
33
|
-
"powershell.exe",
|
|
34
|
-
"pwsh",
|
|
35
|
-
"pwsh.exe",
|
|
36
|
-
"sh",
|
|
37
|
-
"zsh",
|
|
38
|
-
]);
|
|
39
|
-
|
|
40
|
-
function splitCommandWords(commandBody: string): string[] {
|
|
41
|
-
return commandBody.match(COMMAND_WORD_PATTERN) ?? [];
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function splitTopLevelCompoundSegments(command: string): string[] {
|
|
45
|
-
const segments: string[] = [];
|
|
46
|
-
let segmentStart = 0;
|
|
47
|
-
let quote: "'" | '"' | "`" | null = null;
|
|
48
|
-
let escaped = false;
|
|
49
|
-
|
|
50
|
-
const pushSegment = (endIndex: number): void => {
|
|
51
|
-
const segment = command.slice(segmentStart, endIndex).trim();
|
|
52
|
-
if (segment) {
|
|
53
|
-
segments.push(segment);
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
for (let index = 0; index < command.length; index += 1) {
|
|
58
|
-
const char = command[index] ?? "";
|
|
59
|
-
const nextChar = command[index + 1] ?? "";
|
|
60
|
-
const prevChar = index > 0 ? command[index - 1] ?? "" : "";
|
|
61
|
-
|
|
62
|
-
if (escaped) {
|
|
63
|
-
escaped = false;
|
|
64
|
-
continue;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (quote !== null) {
|
|
68
|
-
if (char === "\\" && quote !== "'") {
|
|
69
|
-
escaped = true;
|
|
70
|
-
continue;
|
|
71
|
-
}
|
|
72
|
-
if (char === quote) {
|
|
73
|
-
quote = null;
|
|
74
|
-
}
|
|
75
|
-
continue;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
if (char === "\\") {
|
|
79
|
-
escaped = true;
|
|
80
|
-
continue;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (char === "'" || char === '"' || char === "`") {
|
|
84
|
-
quote = char;
|
|
85
|
-
continue;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
let separatorLength = 0;
|
|
89
|
-
if ((char === "&" && nextChar === "&") || (char === "|" && nextChar === "|") || (char === "|" && nextChar === "&")) {
|
|
90
|
-
separatorLength = 2;
|
|
91
|
-
} else if (char === "|" && prevChar !== ">") {
|
|
92
|
-
separatorLength = 1;
|
|
93
|
-
} else if (char === "&" && nextChar !== ">" && prevChar !== ">" && prevChar !== "<") {
|
|
94
|
-
separatorLength = 1;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// Intentionally ignore semicolons here so unquoted sed scripts remain eligible for
|
|
98
|
-
// segment-level rewriting instead of being treated as unsafe compound shells.
|
|
99
|
-
if (separatorLength === 0) {
|
|
100
|
-
continue;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
pushSegment(index);
|
|
104
|
-
segmentStart = index + separatorLength;
|
|
105
|
-
if (separatorLength === 2) {
|
|
106
|
-
index += 1;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
pushSegment(command.length);
|
|
111
|
-
return segments;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
function shouldBypassCargoRewrite(tokens: string[]): boolean {
|
|
115
|
-
let index = 1;
|
|
116
|
-
|
|
117
|
-
while (index < tokens.length && tokens[index].startsWith("+")) {
|
|
118
|
-
index += 1;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
while (index < tokens.length && tokens[index].startsWith("-")) {
|
|
122
|
-
index += 1;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const subcommand = tokens[index]?.toLowerCase();
|
|
126
|
-
if (!subcommand) {
|
|
127
|
-
return true;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
return BYPASSED_CARGO_SUBCOMMANDS.has(subcommand);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
function normalizeCommandWord(token: string): string {
|
|
134
|
-
const unwrapped = token.replace(/^(?:["'`])|(?:["'`])$/g, "");
|
|
135
|
-
const lastPathSeparator = Math.max(unwrapped.lastIndexOf("/"), unwrapped.lastIndexOf("\\"));
|
|
136
|
-
const basename = lastPathSeparator >= 0 ? unwrapped.slice(lastPathSeparator + 1) : unwrapped;
|
|
137
|
-
return basename.toLowerCase();
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
function findInteractiveShellIndex(tokens: string[], startIndex: number, endIndex: number): number {
|
|
141
|
-
for (let index = startIndex; index < endIndex; index += 1) {
|
|
142
|
-
if (INTERACTIVE_CONTAINER_SHELLS.has(normalizeCommandWord(tokens[index] ?? ""))) {
|
|
143
|
-
return index;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
return -1;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
function hasTrailingArguments(tokens: string[], startIndex: number, endIndex: number): boolean {
|
|
151
|
-
return startIndex >= 0 && startIndex < endIndex - 1;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
function hasStructuredGhOutputFlag(tokens: string[]): boolean {
|
|
155
|
-
return tokens.some((token) => {
|
|
156
|
-
const normalized = token.toLowerCase();
|
|
157
|
-
return GH_STRUCTURED_OUTPUT_FLAGS.some((flag) => normalized === flag || normalized.startsWith(`${flag}=`));
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
function hasShortInteractiveFlag(token: string, flag: "i" | "t"): boolean {
|
|
162
|
-
if (!token.startsWith("-") || token.startsWith("--")) {
|
|
163
|
-
return false;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
return token.slice(1).includes(flag);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
function hasInteractiveFlagPair(tokens: string[], startIndex: number, endIndex: number): boolean {
|
|
170
|
-
let interactive = false;
|
|
171
|
-
let tty = false;
|
|
172
|
-
|
|
173
|
-
for (let index = startIndex; index < endIndex; index += 1) {
|
|
174
|
-
const token = tokens[index] ?? "";
|
|
175
|
-
if (token === "--interactive") {
|
|
176
|
-
interactive = true;
|
|
177
|
-
continue;
|
|
178
|
-
}
|
|
179
|
-
if (token === "--tty") {
|
|
180
|
-
tty = true;
|
|
181
|
-
continue;
|
|
182
|
-
}
|
|
183
|
-
if (hasShortInteractiveFlag(token, "i")) {
|
|
184
|
-
interactive = true;
|
|
185
|
-
}
|
|
186
|
-
if (hasShortInteractiveFlag(token, "t")) {
|
|
187
|
-
tty = true;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
return interactive && tty;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
function shouldBypassInteractiveContainerRewrite(tokens: string[]): boolean {
|
|
195
|
-
const command = tokens[0]?.toLowerCase();
|
|
196
|
-
if (!command) {
|
|
197
|
-
return false;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
if (command === "docker" || command === "podman") {
|
|
201
|
-
const subcommand = tokens[1]?.toLowerCase();
|
|
202
|
-
if (subcommand === "run" || subcommand === "exec") {
|
|
203
|
-
const interactiveShellIndex = findInteractiveShellIndex(tokens, 2, tokens.length);
|
|
204
|
-
return (
|
|
205
|
-
interactiveShellIndex >= 0 &&
|
|
206
|
-
!hasTrailingArguments(tokens, interactiveShellIndex, tokens.length) &&
|
|
207
|
-
!hasInteractiveFlagPair(tokens, 2, interactiveShellIndex)
|
|
208
|
-
);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
if (subcommand === "compose") {
|
|
212
|
-
const composeSubcommand = tokens[2]?.toLowerCase();
|
|
213
|
-
if (composeSubcommand === "run" || composeSubcommand === "exec") {
|
|
214
|
-
const interactiveShellIndex = findInteractiveShellIndex(tokens, 3, tokens.length);
|
|
215
|
-
return (
|
|
216
|
-
interactiveShellIndex >= 0 &&
|
|
217
|
-
!hasTrailingArguments(tokens, interactiveShellIndex, tokens.length) &&
|
|
218
|
-
!hasInteractiveFlagPair(tokens, 3, interactiveShellIndex)
|
|
219
|
-
);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
if (command === "kubectl" && tokens[1]?.toLowerCase() === "exec") {
|
|
225
|
-
const separatorIndex = tokens.indexOf("--");
|
|
226
|
-
if (separatorIndex === -1 || separatorIndex >= tokens.length - 1) {
|
|
227
|
-
return false;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
const interactiveShellIndex = findInteractiveShellIndex(tokens, separatorIndex + 1, tokens.length);
|
|
231
|
-
if (interactiveShellIndex === -1) {
|
|
232
|
-
return false;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
return !hasTrailingArguments(tokens, interactiveShellIndex, tokens.length) && !hasInteractiveFlagPair(tokens, 2, separatorIndex);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
return false;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
function shouldBypassFindRewrite(tokens: string[]): boolean {
|
|
242
|
-
return tokens.slice(1).some((token) => {
|
|
243
|
-
const normalized = token.toLowerCase();
|
|
244
|
-
return (
|
|
245
|
-
BYPASSED_FIND_ACTIONS.has(normalized) ||
|
|
246
|
-
normalized.startsWith("-exec") ||
|
|
247
|
-
normalized.startsWith("-ok") ||
|
|
248
|
-
normalized.startsWith("-printf") ||
|
|
249
|
-
normalized.startsWith("-fprint") ||
|
|
250
|
-
normalized.startsWith("-fls")
|
|
251
|
-
);
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
function shouldBypassLsRewrite(tokens: string[]): boolean {
|
|
256
|
-
return tokens.slice(1).some((token) => token.startsWith("-"));
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
function shouldBypassNativeShellProxyRewrite(tokens: string[]): boolean {
|
|
260
|
-
const command = normalizeCommandWord(tokens[0] ?? "");
|
|
261
|
-
const firstArgument = tokens[1]?.toLowerCase();
|
|
262
|
-
if (!command || !firstArgument) {
|
|
263
|
-
return false;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
if (command === "bash") {
|
|
267
|
-
return BASH_INLINE_COMMAND_FLAGS.has(firstArgument);
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
if (command === "powershell" || command === "powershell.exe") {
|
|
271
|
-
return POWERSHELL_INLINE_COMMAND_FLAGS.has(firstArgument);
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
if (command === "cmd" || command === "cmd.exe") {
|
|
275
|
-
return CMD_INLINE_COMMAND_FLAGS.has(firstArgument);
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
return false;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
/**
|
|
282
|
-
* Skips entire compound commands when any segment depends on native shell piping or
|
|
283
|
-
* formatting-sensitive search/list output that RTK wrappers may not preserve exactly.
|
|
284
|
-
*/
|
|
285
|
-
export function shouldBypassWholeCommandRewrite(command: string): boolean {
|
|
286
|
-
const segments = splitTopLevelCompoundSegments(command.trim());
|
|
287
|
-
if (segments.length <= 1) {
|
|
288
|
-
return false;
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
return segments.some((segment) => {
|
|
292
|
-
const tokens = splitCommandWords(segment);
|
|
293
|
-
const commandName = normalizeCommandWord(tokens[0] ?? "");
|
|
294
|
-
return UNSAFE_COMPOUND_REWRITE_COMMANDS.has(commandName) || shouldBypassNativeShellProxyRewrite(tokens);
|
|
295
|
-
});
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
/**
|
|
299
|
-
* Skips RTK rewrites for command shapes that do not map cleanly to RTK wrappers.
|
|
300
|
-
*/
|
|
301
|
-
export function shouldBypassRewriteForCommand(commandBody: string, rule: RtkRewriteRule): boolean {
|
|
302
|
-
const tokens = splitCommandWords(commandBody.trim());
|
|
303
|
-
if (tokens.length === 0) {
|
|
304
|
-
return false;
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
if (tokens[0]?.toLowerCase() === "gh" && hasStructuredGhOutputFlag(tokens)) {
|
|
308
|
-
return true;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
if (rule.category === "rust" && tokens[0]?.toLowerCase() === "cargo") {
|
|
312
|
-
return shouldBypassCargoRewrite(tokens);
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
if (rule.category === "containers") {
|
|
316
|
-
return shouldBypassInteractiveContainerRewrite(tokens);
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
if (rule.id === "find") {
|
|
320
|
-
return shouldBypassFindRewrite(tokens);
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
if (rule.id === "ls") {
|
|
324
|
-
return shouldBypassLsRewrite(tokens);
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
if (rule.id === "bash-proxy" || rule.id === "cmd-proxy" || rule.id === "powershell-proxy") {
|
|
328
|
-
return shouldBypassNativeShellProxyRewrite(tokens);
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
return false;
|
|
332
|
-
}
|
package/src/rewrite-rules.ts
DELETED
|
@@ -1,255 +0,0 @@
|
|
|
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
|
-
];
|