@wrongstack/tools 1.0.9 → 1.0.10
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/dist/bash-kill-guard.d.ts +6 -4
- package/dist/bash.js +1 -1
- package/dist/builtin.js +2 -2
- package/dist/{chunk-OXO773CW.js → chunk-6I6RXQFG.js} +2 -2
- package/dist/{chunk-QA37PFYL.js → chunk-FCSUBTUJ.js} +85 -53
- package/dist/{chunk-WEUEU53R.js → chunk-FVSMTEO3.js} +2 -2
- package/dist/{chunk-HV7RWDCL.js → chunk-V25Q6TQ7.js} +3 -3
- package/dist/index.js +4 -4
- package/dist/pack.js +3 -3
- package/dist/tool-tier.js +4 -4
- package/package.json +5 -5
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
* dangerous kill commands targeting protected PIDs.
|
|
8
8
|
*
|
|
9
9
|
* Handles:
|
|
10
|
-
* - Direct kill commands: kill -9 12345
|
|
10
|
+
* - Direct kill commands: kill -9 12345, kill -- 12345, kill 111 12345 (every target)
|
|
11
|
+
* - Sequenced commands: `true; kill 12345`, `a && kill 12345`, `a || kill 12345`,
|
|
12
|
+
* `a & kill 12345`, newline-separated — each segment is checked on its own
|
|
11
13
|
* - Shell -c wrapped: bash -c "kill -9 12345" (any shell path — see P2 #10)
|
|
12
14
|
* - Full path kills: /bin/kill -9 12345
|
|
13
15
|
* - Name-based kills: pkill, killall, pgrep
|
|
@@ -41,7 +43,10 @@
|
|
|
41
43
|
* fast path for the common non-obfuscated forms.
|
|
42
44
|
*/
|
|
43
45
|
export interface KillCommand {
|
|
46
|
+
/** First PID target (kept for single-target callers). */
|
|
44
47
|
pid?: number;
|
|
48
|
+
/** Every PID target when the command names more than one (`kill 1 2 3`). */
|
|
49
|
+
pids?: number[];
|
|
45
50
|
name?: string;
|
|
46
51
|
signal?: string;
|
|
47
52
|
isGroupKill: boolean;
|
|
@@ -52,9 +57,6 @@ export interface KillCheckResult {
|
|
|
52
57
|
blocked: boolean;
|
|
53
58
|
reason?: string;
|
|
54
59
|
}
|
|
55
|
-
/**
|
|
56
|
-
* Parse a kill command string to extract PID and signal.
|
|
57
|
-
*/
|
|
58
60
|
export declare function parseKillCommand(command: string): KillCommand | null;
|
|
59
61
|
/**
|
|
60
62
|
* Main entry point: Check if a bash command contains a kill operation targeting protected PIDs.
|
package/dist/bash.js
CHANGED
package/dist/builtin.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
TIER2_TOOLS,
|
|
7
7
|
TIER3_TOOLS,
|
|
8
8
|
builtinTools
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-6I6RXQFG.js";
|
|
10
10
|
import "./chunk-BVHKBBGA.js";
|
|
11
11
|
import "./chunk-ENE22I5W.js";
|
|
12
12
|
import "./chunk-XRNN44QY.js";
|
|
@@ -36,7 +36,7 @@ import "./chunk-ON6ET5ER.js";
|
|
|
36
36
|
import "./chunk-DLZCOEVG.js";
|
|
37
37
|
import "./chunk-YJTXRH5Y.js";
|
|
38
38
|
import "./chunk-ZBMANLYH.js";
|
|
39
|
-
import "./chunk-
|
|
39
|
+
import "./chunk-FCSUBTUJ.js";
|
|
40
40
|
import "./chunk-QAWI3RSK.js";
|
|
41
41
|
import "./chunk-BTSFTGIL.js";
|
|
42
42
|
import "./chunk-PVCB7RUZ.js";
|
|
@@ -89,7 +89,7 @@ import {
|
|
|
89
89
|
checkAndBlockKillCommand,
|
|
90
90
|
diagnoseBashism,
|
|
91
91
|
shellArgs
|
|
92
|
-
} from "./chunk-
|
|
92
|
+
} from "./chunk-FCSUBTUJ.js";
|
|
93
93
|
import {
|
|
94
94
|
detectDanger,
|
|
95
95
|
execTool
|
|
@@ -1623,4 +1623,4 @@ export {
|
|
|
1623
1623
|
TIER3_TOOLS,
|
|
1624
1624
|
builtinTools
|
|
1625
1625
|
};
|
|
1626
|
-
//# sourceMappingURL=chunk-
|
|
1626
|
+
//# sourceMappingURL=chunk-6I6RXQFG.js.map
|
|
@@ -185,6 +185,34 @@ function isKillRelatedCommand(cmd) {
|
|
|
185
185
|
if (SCRIPT_KILL_RE_POSIX.test(normalized)) return true;
|
|
186
186
|
return false;
|
|
187
187
|
}
|
|
188
|
+
function parsePosixKillTargets(normalized, command) {
|
|
189
|
+
const tokens = normalized.split(" ");
|
|
190
|
+
if (tokens[0]?.toLowerCase() !== "kill") return null;
|
|
191
|
+
let i = 1;
|
|
192
|
+
let signal = "TERM";
|
|
193
|
+
const first = tokens[i];
|
|
194
|
+
if (first !== void 0 && /^-[sn]$/i.test(first)) {
|
|
195
|
+
const value = tokens[i + 1];
|
|
196
|
+
if (!value || !/^[a-zA-Z0-9]+$/.test(value)) return null;
|
|
197
|
+
signal = value.toUpperCase();
|
|
198
|
+
i += 2;
|
|
199
|
+
} else if (first !== void 0 && first !== "--" && /^-[a-zA-Z0-9]+$/.test(first) && tokens.length - i >= 2) {
|
|
200
|
+
signal = first.slice(1).toUpperCase();
|
|
201
|
+
i += 1;
|
|
202
|
+
}
|
|
203
|
+
if (tokens[i] === "--") i += 1;
|
|
204
|
+
const targets = tokens.slice(i);
|
|
205
|
+
if (targets.length === 0 || !targets.every((t) => /^-?\d+$/.test(t))) return null;
|
|
206
|
+
const pids = targets.map((t) => Number.parseInt(t.replace(/^-/, ""), 10));
|
|
207
|
+
return {
|
|
208
|
+
pid: pids[0],
|
|
209
|
+
...pids.length > 1 ? { pids } : {},
|
|
210
|
+
signal,
|
|
211
|
+
isGroupKill: targets.some((t) => t.startsWith("-")),
|
|
212
|
+
isAllKill: false,
|
|
213
|
+
originalCommand: command
|
|
214
|
+
};
|
|
215
|
+
}
|
|
188
216
|
function parseKillCommand(command) {
|
|
189
217
|
const normalized = command.replace(/\s+/g, " ").trim();
|
|
190
218
|
if (isWin) {
|
|
@@ -241,27 +269,8 @@ function parseKillCommand(command) {
|
|
|
241
269
|
originalCommand: command
|
|
242
270
|
};
|
|
243
271
|
}
|
|
244
|
-
const
|
|
245
|
-
if (
|
|
246
|
-
return {
|
|
247
|
-
pid: parseInt(killSignalOptionMatch[2], 10),
|
|
248
|
-
signal: killSignalOptionMatch[1].toUpperCase(),
|
|
249
|
-
isGroupKill: false,
|
|
250
|
-
isAllKill: false,
|
|
251
|
-
originalCommand: command
|
|
252
|
-
};
|
|
253
|
-
}
|
|
254
|
-
const killPosixMatch = normalized.match(/^kill\s+(?:(-[a-zA-Z0-9]+)\s+)?(\d+)$/);
|
|
255
|
-
if (killPosixMatch?.[2]) {
|
|
256
|
-
const sig = killPosixMatch[1] ? killPosixMatch[1].slice(1).toUpperCase() : "TERM";
|
|
257
|
-
return {
|
|
258
|
-
pid: parseInt(killPosixMatch[2], 10),
|
|
259
|
-
signal: sig,
|
|
260
|
-
isGroupKill: false,
|
|
261
|
-
isAllKill: false,
|
|
262
|
-
originalCommand: command
|
|
263
|
-
};
|
|
264
|
-
}
|
|
272
|
+
const gitBashKill = parsePosixKillTargets(normalized, command);
|
|
273
|
+
if (gitBashKill) return gitBashKill;
|
|
265
274
|
const stopProcNameMatch = normalized.match(
|
|
266
275
|
/^(?:stop-process|kill)\s+-(?:name|n)\s+(?:['"]([a-zA-Z0-9_.-]+)['"]|([a-zA-Z0-9_.-]+))(?:\s|$)/i
|
|
267
276
|
);
|
|
@@ -324,33 +333,8 @@ function parseKillCommand(command) {
|
|
|
324
333
|
}
|
|
325
334
|
return null;
|
|
326
335
|
}
|
|
327
|
-
const
|
|
328
|
-
if (
|
|
329
|
-
const pidOrGroup = signalOptionMatch[2];
|
|
330
|
-
const isGroupKill = pidOrGroup.startsWith("-");
|
|
331
|
-
return {
|
|
332
|
-
pid: parseInt(isGroupKill ? pidOrGroup.slice(1) : pidOrGroup, 10),
|
|
333
|
-
signal: signalOptionMatch[1].toUpperCase(),
|
|
334
|
-
isGroupKill,
|
|
335
|
-
isAllKill: false,
|
|
336
|
-
originalCommand: command
|
|
337
|
-
};
|
|
338
|
-
}
|
|
339
|
-
const simpleMatch = normalized.match(/^kill\s+(?:(-[a-zA-Z0-9]+)\s+)?(\d+|-?\d+)$/);
|
|
340
|
-
if (simpleMatch) {
|
|
341
|
-
const signal = simpleMatch[1] ?? "-TERM";
|
|
342
|
-
const pidOrGroup = simpleMatch[2];
|
|
343
|
-
if (!pidOrGroup) return null;
|
|
344
|
-
const isGroupKill = pidOrGroup.startsWith("-");
|
|
345
|
-
const pid = isGroupKill ? parseInt(pidOrGroup.slice(1), 10) : parseInt(pidOrGroup, 10);
|
|
346
|
-
return {
|
|
347
|
-
pid,
|
|
348
|
-
signal: signal.slice(1),
|
|
349
|
-
isGroupKill,
|
|
350
|
-
isAllKill: false,
|
|
351
|
-
originalCommand: command
|
|
352
|
-
};
|
|
353
|
-
}
|
|
336
|
+
const posixKill = parsePosixKillTargets(normalized, command);
|
|
337
|
+
if (posixKill) return posixKill;
|
|
354
338
|
const pkillMatch = normalized.match(/^pkill\s+(?:(-[a-zA-Z]+)\s+)?(.+)$/);
|
|
355
339
|
if (pkillMatch?.[2]) {
|
|
356
340
|
const name = pkillMatch[2];
|
|
@@ -429,14 +413,60 @@ async function isKillProtected(kill) {
|
|
|
429
413
|
const protectedPids = await registry.getAllProtectedPids();
|
|
430
414
|
return protectedPids.length > 0;
|
|
431
415
|
}
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
if (
|
|
435
|
-
return
|
|
416
|
+
const targets = kill.pids ?? (kill.pid !== void 0 ? [kill.pid] : []);
|
|
417
|
+
for (const pid of targets) {
|
|
418
|
+
if (await registry.shouldBlockKill(pid)) return true;
|
|
419
|
+
if (pid === process.pid || pid === process.ppid) return true;
|
|
436
420
|
}
|
|
437
421
|
return false;
|
|
438
422
|
}
|
|
439
423
|
async function checkAndBlockKillCommand(command) {
|
|
424
|
+
const whole = await checkSingleCommand(command);
|
|
425
|
+
if (whole.blocked) return whole;
|
|
426
|
+
const segments = splitShellSequence(command);
|
|
427
|
+
if (segments.length > 1) {
|
|
428
|
+
for (const segment of segments) {
|
|
429
|
+
const result = await checkSingleCommand(segment);
|
|
430
|
+
if (result.blocked) return result;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
return { blocked: false };
|
|
434
|
+
}
|
|
435
|
+
function splitShellSequence(command) {
|
|
436
|
+
const segments = [];
|
|
437
|
+
let current = "";
|
|
438
|
+
let quote = null;
|
|
439
|
+
for (let i = 0; i < command.length; i++) {
|
|
440
|
+
const ch = command[i];
|
|
441
|
+
const next = command[i + 1];
|
|
442
|
+
if (quote) {
|
|
443
|
+
if (ch === quote) quote = null;
|
|
444
|
+
current += ch;
|
|
445
|
+
continue;
|
|
446
|
+
}
|
|
447
|
+
if (ch === "\\" && next !== void 0) {
|
|
448
|
+
current += ch + next;
|
|
449
|
+
i++;
|
|
450
|
+
continue;
|
|
451
|
+
}
|
|
452
|
+
if (ch === '"' || ch === "'") {
|
|
453
|
+
quote = ch;
|
|
454
|
+
current += ch;
|
|
455
|
+
continue;
|
|
456
|
+
}
|
|
457
|
+
const isSeparator = ch === ";" || ch === "\n" || ch === "\r" || ch === "|" && next === "|" || ch === "&" && command[i - 1] !== ">" && next !== ">";
|
|
458
|
+
if (isSeparator) {
|
|
459
|
+
if ((ch === "|" || ch === "&") && next === ch) i++;
|
|
460
|
+
if (current.trim()) segments.push(current.trim());
|
|
461
|
+
current = "";
|
|
462
|
+
continue;
|
|
463
|
+
}
|
|
464
|
+
current += ch;
|
|
465
|
+
}
|
|
466
|
+
if (current.trim()) segments.push(current.trim());
|
|
467
|
+
return segments;
|
|
468
|
+
}
|
|
469
|
+
async function checkSingleCommand(command) {
|
|
440
470
|
const normalized = command.replace(/\s+/g, " ").trim();
|
|
441
471
|
const killCmd = extractKillCommand(normalized) || (isKillRelatedCommand(normalized) ? normalized : null);
|
|
442
472
|
if (!killCmd) {
|
|
@@ -462,6 +492,8 @@ async function checkAndBlockKillCommand(command) {
|
|
|
462
492
|
let target;
|
|
463
493
|
if (parsed.name) {
|
|
464
494
|
target = `process name "${parsed.name}"`;
|
|
495
|
+
} else if (parsed.pids && parsed.pids.length > 1) {
|
|
496
|
+
target = `PIDs ${parsed.pids.join(", ")}`;
|
|
465
497
|
} else if (parsed.pid !== void 0) {
|
|
466
498
|
target = `PID ${parsed.pid}`;
|
|
467
499
|
} else {
|
|
@@ -1054,4 +1086,4 @@ export {
|
|
|
1054
1086
|
checkAndBlockKillCommand,
|
|
1055
1087
|
bashTool
|
|
1056
1088
|
};
|
|
1057
|
-
//# sourceMappingURL=chunk-
|
|
1089
|
+
//# sourceMappingURL=chunk-FCSUBTUJ.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
builtinTools
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-6I6RXQFG.js";
|
|
4
4
|
|
|
5
5
|
// src/pack.ts
|
|
6
6
|
var builtinToolsPack = {
|
|
@@ -12,4 +12,4 @@ var builtinToolsPack = {
|
|
|
12
12
|
export {
|
|
13
13
|
builtinToolsPack
|
|
14
14
|
};
|
|
15
|
-
//# sourceMappingURL=chunk-
|
|
15
|
+
//# sourceMappingURL=chunk-FVSMTEO3.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
builtinToolsPack
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-FVSMTEO3.js";
|
|
4
4
|
import {
|
|
5
5
|
TIER1_TOOLS,
|
|
6
6
|
TIER2_TOOLS
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-6I6RXQFG.js";
|
|
8
8
|
|
|
9
9
|
// src/tool-tier.ts
|
|
10
10
|
function toolNameSet(tools) {
|
|
@@ -54,4 +54,4 @@ export {
|
|
|
54
54
|
selectBuiltinToolsForTier,
|
|
55
55
|
registerBuiltinToolTier
|
|
56
56
|
};
|
|
57
|
-
//# sourceMappingURL=chunk-
|
|
57
|
+
//# sourceMappingURL=chunk-V25Q6TQ7.js.map
|
package/dist/index.js
CHANGED
|
@@ -46,10 +46,10 @@ import "./chunk-Z6DAKQ3U.js";
|
|
|
46
46
|
import {
|
|
47
47
|
registerBuiltinToolTier,
|
|
48
48
|
selectBuiltinToolsForTier
|
|
49
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-V25Q6TQ7.js";
|
|
50
50
|
import {
|
|
51
51
|
builtinToolsPack
|
|
52
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-FVSMTEO3.js";
|
|
53
53
|
import {
|
|
54
54
|
OFF_ONLY_TOOLS,
|
|
55
55
|
OPTIONAL_TOOLS,
|
|
@@ -64,7 +64,7 @@ import {
|
|
|
64
64
|
pwshTool,
|
|
65
65
|
readUrlContentTool,
|
|
66
66
|
securityAstScanTool
|
|
67
|
-
} from "./chunk-
|
|
67
|
+
} from "./chunk-6I6RXQFG.js";
|
|
68
68
|
import {
|
|
69
69
|
discoverE2EProjects,
|
|
70
70
|
e2ePlanTool
|
|
@@ -192,7 +192,7 @@ import {
|
|
|
192
192
|
import {
|
|
193
193
|
bashTool,
|
|
194
194
|
checkAndBlockKillCommand
|
|
195
|
-
} from "./chunk-
|
|
195
|
+
} from "./chunk-FCSUBTUJ.js";
|
|
196
196
|
import {
|
|
197
197
|
checkExecKillCommand,
|
|
198
198
|
configureDangerBypass,
|
package/dist/pack.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
builtinToolsPack
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-FVSMTEO3.js";
|
|
4
|
+
import "./chunk-6I6RXQFG.js";
|
|
5
5
|
import "./chunk-BVHKBBGA.js";
|
|
6
6
|
import "./chunk-ENE22I5W.js";
|
|
7
7
|
import "./chunk-XRNN44QY.js";
|
|
@@ -31,7 +31,7 @@ import "./chunk-ON6ET5ER.js";
|
|
|
31
31
|
import "./chunk-DLZCOEVG.js";
|
|
32
32
|
import "./chunk-YJTXRH5Y.js";
|
|
33
33
|
import "./chunk-ZBMANLYH.js";
|
|
34
|
-
import "./chunk-
|
|
34
|
+
import "./chunk-FCSUBTUJ.js";
|
|
35
35
|
import "./chunk-QAWI3RSK.js";
|
|
36
36
|
import "./chunk-BTSFTGIL.js";
|
|
37
37
|
import "./chunk-PVCB7RUZ.js";
|
package/dist/tool-tier.js
CHANGED
|
@@ -2,9 +2,9 @@ import {
|
|
|
2
2
|
BUILTIN_TIER_COUNTS,
|
|
3
3
|
registerBuiltinToolTier,
|
|
4
4
|
selectBuiltinToolsForTier
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-V25Q6TQ7.js";
|
|
6
|
+
import "./chunk-FVSMTEO3.js";
|
|
7
|
+
import "./chunk-6I6RXQFG.js";
|
|
8
8
|
import "./chunk-BVHKBBGA.js";
|
|
9
9
|
import "./chunk-ENE22I5W.js";
|
|
10
10
|
import "./chunk-XRNN44QY.js";
|
|
@@ -34,7 +34,7 @@ import "./chunk-ON6ET5ER.js";
|
|
|
34
34
|
import "./chunk-DLZCOEVG.js";
|
|
35
35
|
import "./chunk-YJTXRH5Y.js";
|
|
36
36
|
import "./chunk-ZBMANLYH.js";
|
|
37
|
-
import "./chunk-
|
|
37
|
+
import "./chunk-FCSUBTUJ.js";
|
|
38
38
|
import "./chunk-QAWI3RSK.js";
|
|
39
39
|
import "./chunk-BTSFTGIL.js";
|
|
40
40
|
import "./chunk-PVCB7RUZ.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wrongstack/tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.10",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "WrongStack built-in tools: read/write/edit, bash/exec, grep/glob, git, fetch, test, lint, and more.",
|
|
6
6
|
"repository": {
|
|
@@ -237,10 +237,10 @@
|
|
|
237
237
|
"@msgpack/msgpack": "^3.1.3",
|
|
238
238
|
"@playwright/test": "^1.63.0",
|
|
239
239
|
"@typescript/typescript6": "^6.0.2",
|
|
240
|
-
"@wrongstack/core": "1.0.
|
|
241
|
-
"@wrongstack/kanban": "1.0.
|
|
242
|
-
"@wrongstack/persistence": "1.0.
|
|
243
|
-
"@wrongstack/primitives": "1.0.
|
|
240
|
+
"@wrongstack/core": "1.0.10",
|
|
241
|
+
"@wrongstack/kanban": "1.0.10",
|
|
242
|
+
"@wrongstack/persistence": "1.0.10",
|
|
243
|
+
"@wrongstack/primitives": "1.0.10",
|
|
244
244
|
"tree-sitter-wasm": "1.1.8",
|
|
245
245
|
"turndown": "^7.2.4",
|
|
246
246
|
"undici": "^8.10.2",
|