@wrongstack/tools 0.277.2 → 0.280.1
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.js +2 -2
- package/dist/bash.js.map +1 -1
- package/dist/builtin.js +314 -15
- package/dist/builtin.js.map +1 -1
- package/dist/codebase-index/index.js +12 -11
- package/dist/codebase-index/index.js.map +1 -1
- package/dist/codebase-index/worker.js +12 -11
- package/dist/codebase-index/worker.js.map +1 -1
- package/dist/exec-Ca3fnpUh.d.ts +121 -0
- package/dist/exec.d.ts +2 -39
- package/dist/exec.js +322 -11
- package/dist/exec.js.map +1 -1
- package/dist/index.d.ts +46 -3
- package/dist/index.js +629 -153
- package/dist/index.js.map +1 -1
- package/dist/install.js.map +1 -1
- package/dist/json.js +0 -1
- package/dist/json.js.map +1 -1
- package/dist/logs.js.map +1 -1
- package/dist/pack.js +314 -15
- package/dist/pack.js.map +1 -1
- package/dist/scaffold.js.map +1 -1
- package/dist/tool-icons.js +6 -6
- package/dist/tool-icons.js.map +1 -1
- package/package.json +2 -2
package/dist/pack.js
CHANGED
|
@@ -1753,7 +1753,7 @@ function looksLikePowerShell(command) {
|
|
|
1753
1753
|
if (/&\s+\$/.test(trimmed)) return true;
|
|
1754
1754
|
if (/(^|\s)@\s*\(/.test(trimmed)) return true;
|
|
1755
1755
|
if (/(^|\s)@\{/.test(trimmed)) return true;
|
|
1756
|
-
if (/(?:^|[\s
|
|
1756
|
+
if (/(?:^|[\s[({,;])(?:-eq|-ne|-lt|-gt|-le|-ge|-like|-notlike|-match|-notmatch|-contains|-notcontains|-in|-notin|-and|-or|-not|-band|-bor|-bxor|-replace|-isplit|-csplit|-osplit|-join|-is|-as|-f)(?:$|[\s\])},;])/i.test(trimmed)) {
|
|
1757
1757
|
return true;
|
|
1758
1758
|
}
|
|
1759
1759
|
if (PS_VERB_RE.test(trimmed)) return true;
|
|
@@ -1780,7 +1780,7 @@ function looksLikePowerShellExtended(command) {
|
|
|
1780
1780
|
return true;
|
|
1781
1781
|
}
|
|
1782
1782
|
if (/^\s*<#|#>\s*$/m.test(trimmed)) return true;
|
|
1783
|
-
if (/(?:^|\s)[
|
|
1783
|
+
if (/(?:^|\s)[-//](?:AsPlainText|PipelineVariable|pv|FilterHashtable|OutVariable|ov)(?:\s|=|$)/i.test(trimmed)) {
|
|
1784
1784
|
return true;
|
|
1785
1785
|
}
|
|
1786
1786
|
return false;
|
|
@@ -3713,9 +3713,8 @@ func formatType(t ast.Expr) string {
|
|
|
3713
3713
|
}
|
|
3714
3714
|
`;
|
|
3715
3715
|
async function syncGoParse(filePath, content, lang) {
|
|
3716
|
-
const tmpDir = path3.join(os2.tmpdir(), "ws-go-parse");
|
|
3716
|
+
const tmpDir = await fs2.mkdtemp(path3.join(os2.tmpdir(), "ws-go-parse-"));
|
|
3717
3717
|
try {
|
|
3718
|
-
await fs2.mkdir(tmpDir, { recursive: true });
|
|
3719
3718
|
const scriptPath = path3.join(tmpDir, "parse.go");
|
|
3720
3719
|
await fs2.writeFile(scriptPath, GO_PARSE_SCRIPT, "utf8");
|
|
3721
3720
|
const proc = spawn("go", ["run", scriptPath], {
|
|
@@ -3759,6 +3758,8 @@ async function syncGoParse(filePath, content, lang) {
|
|
|
3759
3758
|
return { file: filePath, lang, symbols, mtimeMs: Date.now() };
|
|
3760
3759
|
} catch {
|
|
3761
3760
|
return { file: filePath, lang, symbols: [], mtimeMs: Date.now() };
|
|
3761
|
+
} finally {
|
|
3762
|
+
await fs2.rm(tmpDir, { recursive: true, force: true });
|
|
3762
3763
|
}
|
|
3763
3764
|
}
|
|
3764
3765
|
async function parseSymbols3(opts) {
|
|
@@ -6091,6 +6092,294 @@ function findSimilarity(haystack, needle) {
|
|
|
6091
6092
|
}
|
|
6092
6093
|
return line;
|
|
6093
6094
|
}
|
|
6095
|
+
|
|
6096
|
+
// src/_danger-detect.ts
|
|
6097
|
+
var argHas = (args, value) => args.includes(value);
|
|
6098
|
+
var argMatches = (args, re) => args.some((a) => re.test(a));
|
|
6099
|
+
var hasShortFlags = (args, letters) => {
|
|
6100
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6101
|
+
for (const a of args) {
|
|
6102
|
+
if (!a.startsWith("-") || a.startsWith("--")) continue;
|
|
6103
|
+
for (const ch of a.replace(/^-+/, "")) seen.add(ch);
|
|
6104
|
+
}
|
|
6105
|
+
return letters.split("").every((l) => seen.has(l));
|
|
6106
|
+
};
|
|
6107
|
+
var RULES = [
|
|
6108
|
+
// ----- rm / rmdir: recursive force delete (any path) -----
|
|
6109
|
+
// Note: BLOCKED_ARG_PATTERNS already hard-denies root/home/glob paths,
|
|
6110
|
+
// but `rm -rf ./build` is a normal dev workflow that the user might
|
|
6111
|
+
// want to do intentionally. We downgrade it to 'destructive' so the
|
|
6112
|
+
// confirm prompt can approve.
|
|
6113
|
+
{
|
|
6114
|
+
id: "rm-recursive",
|
|
6115
|
+
level: "destructive",
|
|
6116
|
+
test: (cmd, args) => (cmd === "rm" || cmd === "rmdir") && hasShortFlags(args, "rf"),
|
|
6117
|
+
reason: "recursive force-delete"
|
|
6118
|
+
},
|
|
6119
|
+
// ----- Windows PowerShell Remove-Item: -Recurse -Force -----
|
|
6120
|
+
{
|
|
6121
|
+
id: "powershell-remove-item-recursive-force",
|
|
6122
|
+
level: "destructive",
|
|
6123
|
+
test: (cmd, args) => {
|
|
6124
|
+
if (cmd !== "powershell" && cmd !== "pwsh") return false;
|
|
6125
|
+
const hasRecurse = argMatches(args, /^-(?:R|Recurse|Recurse\s)/);
|
|
6126
|
+
const hasForce = argHas(args, "-Force") || argHas(args, "-F");
|
|
6127
|
+
if (argHas(args, "-WhatIf")) return false;
|
|
6128
|
+
return hasRecurse && hasForce;
|
|
6129
|
+
},
|
|
6130
|
+
reason: "Remove-Item with -Recurse -Force"
|
|
6131
|
+
},
|
|
6132
|
+
// ----- find -exec / -ok / -execdir -----
|
|
6133
|
+
{
|
|
6134
|
+
id: "find-exec",
|
|
6135
|
+
level: "destructive",
|
|
6136
|
+
test: (cmd, args) => {
|
|
6137
|
+
if (cmd !== "find") return false;
|
|
6138
|
+
return args.some(
|
|
6139
|
+
(a) => a === "-exec" || a === "-exec;" || a === "-ok" || a === "-ok;" || a === "-execdir" || a === "-execdir;" || a.startsWith("-exec=") || a.startsWith("-ok=") || a.startsWith("-execdir=")
|
|
6140
|
+
);
|
|
6141
|
+
},
|
|
6142
|
+
reason: "find with -exec/-ok (executes arbitrary command on matches)"
|
|
6143
|
+
},
|
|
6144
|
+
// ----- git --exec= / --upload-pack= / --receive-pack= -----
|
|
6145
|
+
// These run arbitrary commands via the git transport layer.
|
|
6146
|
+
{
|
|
6147
|
+
id: "git-exec",
|
|
6148
|
+
level: "destructive",
|
|
6149
|
+
test: (cmd, args) => cmd === "git" && args.some(
|
|
6150
|
+
(a) => a.startsWith("--exec=") || a.startsWith("--upload-pack=") || a.startsWith("--receive-pack=") || a === "--exec" || a === "--upload-pack" || a === "--receive-pack"
|
|
6151
|
+
),
|
|
6152
|
+
reason: "git with --exec/--upload-pack/--receive-pack (runs arbitrary code)"
|
|
6153
|
+
},
|
|
6154
|
+
// ----- Windows: format / diskpart / bcdedit -----
|
|
6155
|
+
{
|
|
6156
|
+
id: "win32-format",
|
|
6157
|
+
level: "destructive",
|
|
6158
|
+
test: (cmd) => cmd === "format" || cmd === "format.exe",
|
|
6159
|
+
reason: "format (Windows disk format)"
|
|
6160
|
+
},
|
|
6161
|
+
{
|
|
6162
|
+
id: "win32-diskpart",
|
|
6163
|
+
level: "destructive",
|
|
6164
|
+
test: (cmd) => cmd === "diskpart" || cmd === "diskpart.exe",
|
|
6165
|
+
reason: "diskpart (Windows partition editor)"
|
|
6166
|
+
},
|
|
6167
|
+
{
|
|
6168
|
+
id: "win32-bcdedit",
|
|
6169
|
+
level: "destructive",
|
|
6170
|
+
test: (cmd) => cmd === "bcdedit" || cmd === "bcdedit.exe",
|
|
6171
|
+
reason: "bcdedit (Windows boot config editor)"
|
|
6172
|
+
},
|
|
6173
|
+
// ----- mkfs family -----
|
|
6174
|
+
{
|
|
6175
|
+
id: "mkfs",
|
|
6176
|
+
level: "destructive",
|
|
6177
|
+
test: (cmd) => /^mkfs(\.[a-z0-9]+)?$/.test(cmd) || cmd === "mkswap",
|
|
6178
|
+
reason: "mkfs (filesystem creation \u2014 destroys existing data)"
|
|
6179
|
+
},
|
|
6180
|
+
// ----- dd writing to a block device -----
|
|
6181
|
+
{
|
|
6182
|
+
id: "dd-to-block-device",
|
|
6183
|
+
level: "destructive",
|
|
6184
|
+
test: (cmd, args) => {
|
|
6185
|
+
if (cmd !== "dd") return false;
|
|
6186
|
+
return args.some((a) => /of=\/dev\/(sd|hd|nvme|vd|mmcblk|xvd|loop|disk)/.test(a));
|
|
6187
|
+
},
|
|
6188
|
+
reason: "dd writing to a block device"
|
|
6189
|
+
},
|
|
6190
|
+
// ----- Secure-erase tools -----
|
|
6191
|
+
{
|
|
6192
|
+
id: "shred",
|
|
6193
|
+
level: "destructive",
|
|
6194
|
+
test: (cmd) => cmd === "shred" || cmd === "shred.exe",
|
|
6195
|
+
reason: "shred (secure file delete)"
|
|
6196
|
+
},
|
|
6197
|
+
{
|
|
6198
|
+
id: "wipefs",
|
|
6199
|
+
level: "destructive",
|
|
6200
|
+
test: (cmd) => cmd === "wipefs" || cmd === "wipefs.exe",
|
|
6201
|
+
reason: "wipefs (signature wipe \u2014 destroys filesystem headers)"
|
|
6202
|
+
},
|
|
6203
|
+
{
|
|
6204
|
+
id: "sdelete",
|
|
6205
|
+
level: "destructive",
|
|
6206
|
+
test: (cmd) => cmd === "sdelete" || cmd === "sdelete.exe",
|
|
6207
|
+
reason: "sdelete (Sysinternals secure delete)"
|
|
6208
|
+
},
|
|
6209
|
+
// ----- VCS history rewrite (destructive) -----
|
|
6210
|
+
// `git push --force` / `-f` rewrites remote history. `--force-with-lease`
|
|
6211
|
+
// is the safer variant (checks remote hasn't moved) but still rewrites.
|
|
6212
|
+
{
|
|
6213
|
+
id: "git-push-force",
|
|
6214
|
+
level: "destructive",
|
|
6215
|
+
test: (cmd, args) => {
|
|
6216
|
+
if (cmd !== "git") return false;
|
|
6217
|
+
const pushIdx = args.indexOf("push");
|
|
6218
|
+
if (pushIdx < 0) return false;
|
|
6219
|
+
for (let i = pushIdx + 1; i < args.length; i++) {
|
|
6220
|
+
const a = args[i];
|
|
6221
|
+
if (a === "--force" || a === "-f" || a === "--force-with-lease") return true;
|
|
6222
|
+
if (!a.startsWith("-") && !a.includes("=")) continue;
|
|
6223
|
+
if (a.startsWith("--force")) return true;
|
|
6224
|
+
}
|
|
6225
|
+
return false;
|
|
6226
|
+
},
|
|
6227
|
+
reason: "git push with --force / -f (rewrites remote history)"
|
|
6228
|
+
},
|
|
6229
|
+
// ----- git reset --hard (destructive) -----
|
|
6230
|
+
{
|
|
6231
|
+
id: "git-reset-hard",
|
|
6232
|
+
level: "destructive",
|
|
6233
|
+
test: (cmd, args) => cmd === "git" && args.some((a) => a === "--hard" || a.startsWith("--hard=")),
|
|
6234
|
+
reason: "git reset --hard (discards working tree + index)"
|
|
6235
|
+
},
|
|
6236
|
+
// ----- git clean -f / -fd (destructive) -----
|
|
6237
|
+
{
|
|
6238
|
+
id: "git-clean-force",
|
|
6239
|
+
level: "destructive",
|
|
6240
|
+
test: (cmd, args) => {
|
|
6241
|
+
if (cmd !== "git") return false;
|
|
6242
|
+
const cleanIdx = args.indexOf("clean");
|
|
6243
|
+
if (cleanIdx < 0) return false;
|
|
6244
|
+
return args.slice(cleanIdx + 1).some(
|
|
6245
|
+
(a) => a === "-f" || a === "--force" || a.startsWith("-f") || a.startsWith("--force=")
|
|
6246
|
+
);
|
|
6247
|
+
},
|
|
6248
|
+
reason: "git clean -f (deletes untracked files)"
|
|
6249
|
+
},
|
|
6250
|
+
// ----- package publish (destructive — public, irreversible) -----
|
|
6251
|
+
{
|
|
6252
|
+
id: "npm-publish",
|
|
6253
|
+
level: "destructive",
|
|
6254
|
+
test: (cmd, args) => {
|
|
6255
|
+
if (!["npm", "pnpm", "yarn", "bun", "cargo"].includes(cmd)) return false;
|
|
6256
|
+
return args.includes("publish") || cmd === "cargo" && args.includes("yank");
|
|
6257
|
+
},
|
|
6258
|
+
reason: "publishing to a public package registry (hard to reverse)"
|
|
6259
|
+
},
|
|
6260
|
+
// ----- k8s cluster-wide destructive ops (destructive) -----
|
|
6261
|
+
{
|
|
6262
|
+
id: "kubectl-delete-namespace",
|
|
6263
|
+
level: "destructive",
|
|
6264
|
+
test: (cmd, args) => {
|
|
6265
|
+
if (cmd !== "kubectl") return false;
|
|
6266
|
+
const delIdx = args.indexOf("delete");
|
|
6267
|
+
if (delIdx < 0) return false;
|
|
6268
|
+
const after = args.slice(delIdx + 1);
|
|
6269
|
+
return after[0] === "namespace" || after[0] === "ns";
|
|
6270
|
+
},
|
|
6271
|
+
reason: "kubectl delete namespace (deletes all resources in the namespace)"
|
|
6272
|
+
},
|
|
6273
|
+
{
|
|
6274
|
+
id: "kubectl-drain",
|
|
6275
|
+
level: "destructive",
|
|
6276
|
+
test: (cmd, args) => cmd === "kubectl" && args.includes("drain"),
|
|
6277
|
+
reason: "kubectl drain (evicts pods, marks node unschedulable)"
|
|
6278
|
+
},
|
|
6279
|
+
// ----- inline code evaluation (caution — high false-positive) -----
|
|
6280
|
+
// Common in scripts: `python -c "..."`, `node -e "..."`, `bash -c "..."`.
|
|
6281
|
+
// We tag 'caution' rather than 'destructive' because these are used in
|
|
6282
|
+
// many legitimate one-liners (e.g. `python -c "print(1)"`).
|
|
6283
|
+
{
|
|
6284
|
+
id: "inline-eval",
|
|
6285
|
+
level: "caution",
|
|
6286
|
+
test: (cmd, args) => {
|
|
6287
|
+
if (![
|
|
6288
|
+
"python",
|
|
6289
|
+
"python3",
|
|
6290
|
+
"python2",
|
|
6291
|
+
"node",
|
|
6292
|
+
"bash",
|
|
6293
|
+
"sh",
|
|
6294
|
+
"zsh",
|
|
6295
|
+
"ruby",
|
|
6296
|
+
"perl",
|
|
6297
|
+
"lua"
|
|
6298
|
+
].includes(cmd)) {
|
|
6299
|
+
return false;
|
|
6300
|
+
}
|
|
6301
|
+
return args.some(
|
|
6302
|
+
(a) => a === "-c" || a === "-e" || a === "--eval" || a === "-eval" || a === "-E"
|
|
6303
|
+
);
|
|
6304
|
+
},
|
|
6305
|
+
reason: "inline script evaluation (-c / -e / --eval)"
|
|
6306
|
+
},
|
|
6307
|
+
// ----- pipe-to-shell (caution — well-known exfil pattern) -----
|
|
6308
|
+
// The classic `curl https://... | sh` download-and-run vector. Detected by
|
|
6309
|
+
// looking for a known fetcher followed by a shell sink. We use a simple
|
|
6310
|
+
// substring scan; false positives are limited because both tokens must
|
|
6311
|
+
// appear in the same argv.
|
|
6312
|
+
{
|
|
6313
|
+
id: "pipe-to-shell",
|
|
6314
|
+
level: "caution",
|
|
6315
|
+
test: (_cmd, args) => {
|
|
6316
|
+
const hasFetcher = args.some(
|
|
6317
|
+
(a) => /^(curl|wget|fetch|httpie|http)$/i.test(a) || a.startsWith("curl") || a.startsWith("wget")
|
|
6318
|
+
);
|
|
6319
|
+
const hasShellSink = args.some(
|
|
6320
|
+
(a) => a === "sh" || a === "bash" || a === "zsh" || a === "fish" || a === "pwsh" || a === "powershell" || a.endsWith("/sh") || a.endsWith("/bash") || a.endsWith("/zsh") || a.endsWith("/pwsh")
|
|
6321
|
+
);
|
|
6322
|
+
return hasFetcher && hasShellSink;
|
|
6323
|
+
},
|
|
6324
|
+
reason: "network fetch piped to a shell (download-and-run pattern)"
|
|
6325
|
+
},
|
|
6326
|
+
// ----- privilege escalation (caution) -----
|
|
6327
|
+
{
|
|
6328
|
+
id: "sudo",
|
|
6329
|
+
level: "caution",
|
|
6330
|
+
test: (cmd) => cmd === "sudo" || cmd === "doas",
|
|
6331
|
+
reason: "privilege escalation (sudo / doas)"
|
|
6332
|
+
},
|
|
6333
|
+
{
|
|
6334
|
+
id: "runas",
|
|
6335
|
+
level: "caution",
|
|
6336
|
+
test: (cmd) => cmd === "runas" || cmd === "runas.exe",
|
|
6337
|
+
reason: "Windows runas (run as different user)"
|
|
6338
|
+
},
|
|
6339
|
+
// ----- world-writable permissions (caution) -----
|
|
6340
|
+
// `chmod 777` is rarely correct. `chmod -R 777` is almost always wrong.
|
|
6341
|
+
// We only flag octal modes; symbolic modes like `chmod o+w` are
|
|
6342
|
+
// left to the operator's discretion.
|
|
6343
|
+
{
|
|
6344
|
+
id: "chmod-world-writable",
|
|
6345
|
+
level: "caution",
|
|
6346
|
+
test: (cmd, args) => {
|
|
6347
|
+
if (cmd !== "chmod") return false;
|
|
6348
|
+
return args.some((a) => /^[0-7]{3,4}$/.test(a) && /7/.test(a));
|
|
6349
|
+
},
|
|
6350
|
+
reason: "chmod with world-writable octal mode (e.g. 777)"
|
|
6351
|
+
}
|
|
6352
|
+
];
|
|
6353
|
+
function detectDanger(cmd, args, bypass) {
|
|
6354
|
+
const reasons = [];
|
|
6355
|
+
let level = "safe";
|
|
6356
|
+
let matchedRule;
|
|
6357
|
+
for (const rule of RULES) {
|
|
6358
|
+
if (bypass?.has(rule.id)) continue;
|
|
6359
|
+
if (!rule.test(cmd, args)) continue;
|
|
6360
|
+
reasons.push(rule.reason);
|
|
6361
|
+
matchedRule = rule.id;
|
|
6362
|
+
if (levelRank(rule.level) > levelRank(level)) {
|
|
6363
|
+
level = rule.level;
|
|
6364
|
+
}
|
|
6365
|
+
}
|
|
6366
|
+
if (level === "safe") return { level: "safe", reasons: [] };
|
|
6367
|
+
const result = { level, reasons };
|
|
6368
|
+
if (matchedRule !== void 0) result.matchedRule = matchedRule;
|
|
6369
|
+
return result;
|
|
6370
|
+
}
|
|
6371
|
+
function levelRank(level) {
|
|
6372
|
+
switch (level) {
|
|
6373
|
+
case "safe":
|
|
6374
|
+
return 0;
|
|
6375
|
+
case "caution":
|
|
6376
|
+
return 1;
|
|
6377
|
+
case "destructive":
|
|
6378
|
+
return 2;
|
|
6379
|
+
}
|
|
6380
|
+
}
|
|
6381
|
+
|
|
6382
|
+
// src/exec.ts
|
|
6094
6383
|
var isWin3 = process.platform === "win32";
|
|
6095
6384
|
var DEFAULT_ALLOWED_COMMANDS = /* @__PURE__ */ new Set([
|
|
6096
6385
|
// JS / TS toolchain
|
|
@@ -6698,6 +6987,7 @@ var DEFAULT_ALLOWED_COMMANDS = /* @__PURE__ */ new Set([
|
|
|
6698
6987
|
]);
|
|
6699
6988
|
var allowedCommands = new Set(DEFAULT_ALLOWED_COMMANDS);
|
|
6700
6989
|
var normalizeCmd = (c) => c.trim();
|
|
6990
|
+
var dangerBypass = /* @__PURE__ */ new Set();
|
|
6701
6991
|
function isExecCommandAllowed(cmd) {
|
|
6702
6992
|
return allowedCommands.has(normalizeCmd(cmd));
|
|
6703
6993
|
}
|
|
@@ -6786,6 +7076,7 @@ function validateArgs(cmd, args) {
|
|
|
6786
7076
|
}
|
|
6787
7077
|
return null;
|
|
6788
7078
|
}
|
|
7079
|
+
var SAFE_DANGER = { level: "safe", reasons: [] };
|
|
6789
7080
|
var execTool = {
|
|
6790
7081
|
name: "exec",
|
|
6791
7082
|
category: "Shell",
|
|
@@ -6830,7 +7121,8 @@ var execTool = {
|
|
|
6830
7121
|
stderr: "Circuit breaker is open \u2014 too many consecutive failures. Use /kill reset to recover.",
|
|
6831
7122
|
exitCode: 1,
|
|
6832
7123
|
truncated: false,
|
|
6833
|
-
allowed: false
|
|
7124
|
+
allowed: false,
|
|
7125
|
+
danger: SAFE_DANGER
|
|
6834
7126
|
};
|
|
6835
7127
|
}
|
|
6836
7128
|
const cmd = input.command.trim();
|
|
@@ -6842,7 +7134,8 @@ var execTool = {
|
|
|
6842
7134
|
stderr: "Empty command",
|
|
6843
7135
|
exitCode: 1,
|
|
6844
7136
|
truncated: false,
|
|
6845
|
-
allowed: false
|
|
7137
|
+
allowed: false,
|
|
7138
|
+
danger: SAFE_DANGER
|
|
6846
7139
|
};
|
|
6847
7140
|
if (!isExecCommandAllowed(cmd)) {
|
|
6848
7141
|
return {
|
|
@@ -6852,11 +7145,13 @@ var execTool = {
|
|
|
6852
7145
|
stderr: `Command "${cmd}" not in allowlist. Add it to your ~/.wrongstack/config.json under "tools": { "exec": { "allow": ["${cmd}"] } }, or use the bash tool for one-off arbitrary commands.`,
|
|
6853
7146
|
exitCode: 1,
|
|
6854
7147
|
truncated: false,
|
|
6855
|
-
allowed: false
|
|
7148
|
+
allowed: false,
|
|
7149
|
+
danger: SAFE_DANGER
|
|
6856
7150
|
};
|
|
6857
7151
|
}
|
|
6858
7152
|
const args = (input.args ?? []).slice(0, MAX_ARGS);
|
|
6859
7153
|
const timeout = Math.max(1, Math.min(input.timeout ?? DEFAULT_TIMEOUT_MS2, DEFAULT_TIMEOUT_MS2));
|
|
7154
|
+
const danger = detectDanger(cmd, args, dangerBypass);
|
|
6860
7155
|
const argError = validateArgs(cmd, args);
|
|
6861
7156
|
if (argError) {
|
|
6862
7157
|
return {
|
|
@@ -6866,7 +7161,8 @@ var execTool = {
|
|
|
6866
7161
|
stderr: argError,
|
|
6867
7162
|
exitCode: 1,
|
|
6868
7163
|
truncated: false,
|
|
6869
|
-
allowed: false
|
|
7164
|
+
allowed: false,
|
|
7165
|
+
danger
|
|
6870
7166
|
};
|
|
6871
7167
|
}
|
|
6872
7168
|
let cwd;
|
|
@@ -6880,14 +7176,15 @@ var execTool = {
|
|
|
6880
7176
|
stderr: `cwd "${input.cwd ?? ctx.cwd}" resolves outside project root`,
|
|
6881
7177
|
exitCode: 1,
|
|
6882
7178
|
truncated: false,
|
|
6883
|
-
allowed: false
|
|
7179
|
+
allowed: false,
|
|
7180
|
+
danger
|
|
6884
7181
|
};
|
|
6885
7182
|
}
|
|
6886
7183
|
const signal = opts.signal;
|
|
6887
|
-
return runCommand(cmd, args, cwd, timeout, signal, ctx.session?.id);
|
|
7184
|
+
return runCommand(cmd, args, cwd, timeout, signal, ctx.session?.id, danger);
|
|
6888
7185
|
}
|
|
6889
7186
|
};
|
|
6890
|
-
function runCommand(cmd, args, cwd, timeout, signal, sessionId) {
|
|
7187
|
+
function runCommand(cmd, args, cwd, timeout, signal, sessionId, danger) {
|
|
6891
7188
|
return new Promise((resolve7) => {
|
|
6892
7189
|
let stdout = "";
|
|
6893
7190
|
let stderr = "";
|
|
@@ -6924,7 +7221,8 @@ function runCommand(cmd, args, cwd, timeout, signal, sessionId) {
|
|
|
6924
7221
|
stderr: `spawn failed: ${toErrorMessage$1(err)}`,
|
|
6925
7222
|
exitCode: 1,
|
|
6926
7223
|
truncated: false,
|
|
6927
|
-
allowed: true
|
|
7224
|
+
allowed: true,
|
|
7225
|
+
danger
|
|
6928
7226
|
});
|
|
6929
7227
|
return;
|
|
6930
7228
|
}
|
|
@@ -6943,7 +7241,8 @@ function runCommand(cmd, args, cwd, timeout, signal, sessionId) {
|
|
|
6943
7241
|
stderr: stderrText,
|
|
6944
7242
|
exitCode: isAbort ? 124 : 1,
|
|
6945
7243
|
truncated: Buffer.byteLength(stdout, "utf8") > COMMAND_OUTPUT_MAX_BYTES,
|
|
6946
|
-
allowed: true
|
|
7244
|
+
allowed: true,
|
|
7245
|
+
danger
|
|
6947
7246
|
});
|
|
6948
7247
|
});
|
|
6949
7248
|
const registry = getProcessRegistry();
|
|
@@ -6991,7 +7290,8 @@ function runCommand(cmd, args, cwd, timeout, signal, sessionId) {
|
|
|
6991
7290
|
stderr: normalizeCommandOutput(stderr),
|
|
6992
7291
|
exitCode,
|
|
6993
7292
|
truncated: Buffer.byteLength(stdout, "utf8") > COMMAND_OUTPUT_MAX_BYTES || Buffer.byteLength(stderr, "utf8") > COMMAND_OUTPUT_MAX_BYTES,
|
|
6994
|
-
allowed: true
|
|
7293
|
+
allowed: true,
|
|
7294
|
+
danger
|
|
6995
7295
|
});
|
|
6996
7296
|
});
|
|
6997
7297
|
});
|
|
@@ -8494,7 +8794,6 @@ var jsonTool = {
|
|
|
8494
8794
|
return executeTransform(input, ctx);
|
|
8495
8795
|
case "merge":
|
|
8496
8796
|
return executeMerge(input);
|
|
8497
|
-
case "parse":
|
|
8498
8797
|
default:
|
|
8499
8798
|
return executeParse(input, ctx);
|
|
8500
8799
|
}
|