@node9/proxy 2.46.1 → 2.47.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.
@@ -106,22 +106,16 @@ var init_forecast_context = __esm({
106
106
  });
107
107
 
108
108
  // packages/policy-engine/dist/index.mjs
109
- import mvdanSh3 from "mvdan-sh";
110
109
  import picomatch from "picomatch";
111
110
  import safeRegex from "safe-regex2";
112
111
  import pm from "picomatch";
113
- import mvdanSh from "mvdan-sh";
114
112
  import mvdanSh2 from "mvdan-sh";
113
+ import mvdanSh from "mvdan-sh";
114
+ import mvdanSh3 from "mvdan-sh";
115
115
  import safeRegex2 from "safe-regex2";
116
116
  import { createHash as createHash2 } from "crypto";
117
117
  import { createHash as createHash22 } from "crypto";
118
- import mvdanSh4 from "mvdan-sh";
119
- import mvdanSh5 from "mvdan-sh";
120
- import mvdanSh6 from "mvdan-sh";
121
- import mvdanSh8 from "mvdan-sh";
122
- import mvdanSh7 from "mvdan-sh";
123
118
  import { createHash as createHash3 } from "crypto";
124
- import mvdanSh9 from "mvdan-sh";
125
119
  import crypto from "crypto";
126
120
  function validateRegex(pattern) {
127
121
  if (!pattern) return "Pattern is required";
@@ -703,6 +697,62 @@ function resolveCheckMap(settings) {
703
697
  for (const c of CHECKS) out[c.id] = checkValue(settings, c.id);
704
698
  return out;
705
699
  }
700
+ function isGoNode(v) {
701
+ return v !== null && typeof v === "object" && typeof v.Pos === "function";
702
+ }
703
+ function toPlainTree(goNode) {
704
+ const kind = syntax.NodeType(goNode);
705
+ const out = { kind, pos: goNode.Pos().Offset(), end: goNode.End().Offset() };
706
+ const spec = KINDS[kind];
707
+ if (!spec) {
708
+ unknownKinds.add(kind);
709
+ return out;
710
+ }
711
+ convertFields(goNode, spec, out, kind);
712
+ return out;
713
+ }
714
+ function convertFields(goNode, spec, out, kind) {
715
+ for (const f of spec.scalars ?? []) out[f] = goNode[f];
716
+ for (const f of spec.nodes ?? []) {
717
+ const v = goNode[f];
718
+ if (v === void 0 || v === null) {
719
+ out[f] = null;
720
+ } else if (Array.isArray(v)) {
721
+ out[f] = v.map((c) => isGoNode(c) ? toPlainTree(c) : c);
722
+ } else if (isGoNode(v)) {
723
+ out[f] = toPlainTree(v);
724
+ } else if (typeof v === "object" && STRUCTS[`${kind}.${f}`]) {
725
+ const sub = { struct: `${kind}.${f}` };
726
+ convertFields(v, STRUCTS[`${kind}.${f}`], sub, `${kind}.${f}`);
727
+ out[f] = sub;
728
+ } else {
729
+ out[f] = v;
730
+ }
731
+ }
732
+ }
733
+ function childrenOf(n) {
734
+ const spec = n.kind ? KINDS[n.kind] : STRUCTS[n.struct];
735
+ if (!spec?.nodes) return [];
736
+ const out = [];
737
+ for (const f of spec.nodes) {
738
+ if (spec.notWalked?.includes(f)) continue;
739
+ const v = n[f];
740
+ if (!v) continue;
741
+ if (Array.isArray(v)) {
742
+ for (const c of v) if (c) out.push(c);
743
+ } else if (v.kind) {
744
+ out.push(v);
745
+ } else if (v.struct) {
746
+ out.push(...childrenOf(v));
747
+ }
748
+ }
749
+ return out;
750
+ }
751
+ function walk(root, fn) {
752
+ if (!root) return;
753
+ if (!fn(root)) return;
754
+ for (const c of childrenOf(root)) walk(c, fn);
755
+ }
706
756
  function isInvisibleChar(char) {
707
757
  return INVISIBLE_ONE.test(char);
708
758
  }
@@ -858,7 +908,7 @@ function judgeInlineCode(language, code, isProtected) {
858
908
  }
859
909
  function isCatHeredocOrLit(part) {
860
910
  if (!part) return false;
861
- const t = syntax.NodeType(part);
911
+ const t = part.kind;
862
912
  if (t === "Lit") return true;
863
913
  if (t !== "CmdSubst") return false;
864
914
  const stmts = part.Stmts || [];
@@ -868,9 +918,9 @@ function isCatHeredocOrLit(part) {
868
918
  const hasHeredoc = redirs.some((r) => r && r.Hdoc);
869
919
  if (!hasHeredoc) return false;
870
920
  const cmd = stmt.Cmd;
871
- if (!cmd || syntax.NodeType(cmd) !== "CallExpr") return false;
921
+ if (!cmd || cmd.kind !== "CallExpr") return false;
872
922
  const firstArg = cmd.Args?.[0]?.Parts || [];
873
- if (firstArg.length !== 1 || syntax.NodeType(firstArg[0]) !== "Lit") return false;
923
+ if (firstArg.length !== 1 || firstArg[0].kind !== "Lit") return false;
874
924
  return (firstArg[0].Value || "").toLowerCase() === "cat";
875
925
  }
876
926
  function parseShared(command) {
@@ -882,7 +932,7 @@ function parseShared(command) {
882
932
  }
883
933
  let parsed;
884
934
  try {
885
- parsed = sharedParser.Parse(command, "cmd");
935
+ parsed = toPlainTree(sharedParser.Parse(command, "cmd"));
886
936
  } catch {
887
937
  parsed = PARSE_FAIL;
888
938
  }
@@ -943,10 +993,10 @@ function fileAccessViewImpl(command) {
943
993
  const at = (byteOffset) => toCharIndex === null ? byteOffset : toCharIndex(byteOffset);
944
994
  const edits = [];
945
995
  try {
946
- syntax.Walk(f, (node) => {
996
+ walk(f, (node) => {
947
997
  if (!node) return false;
948
998
  const n = node;
949
- if (syntax.NodeType(n) !== "CallExpr") return true;
999
+ if (n.kind !== "CallExpr") return true;
950
1000
  const args = n.Args || [];
951
1001
  const words = args.map((a) => resolveWordLiteral(a));
952
1002
  const head = unwrapCommandHead(words);
@@ -958,8 +1008,8 @@ function fileAccessViewImpl(command) {
958
1008
  if (!PROGRAM_DIR.test(word)) continue;
959
1009
  const name = word.split(/[\\/]/).pop() ?? "";
960
1010
  if (!name) continue;
961
- const s = at(args[i].Pos().Offset());
962
- const e = at(args[i].End().Offset());
1011
+ const s = at(args[i].pos);
1012
+ const e = at(args[i].end);
963
1013
  if (s < 0 || e < 0) continue;
964
1014
  edits.push([s, e, name]);
965
1015
  }
@@ -987,10 +1037,10 @@ function literalPayloadsOf(command, depth) {
987
1037
  if (f === PARSE_FAIL) return [];
988
1038
  const out = [];
989
1039
  try {
990
- syntax.Walk(f, (node) => {
1040
+ walk(f, (node) => {
991
1041
  if (!node || out.length >= MAX_READING_PAYLOADS) return false;
992
1042
  const n = node;
993
- if (syntax.NodeType(n) !== "CallExpr") return true;
1043
+ if (n.kind !== "CallExpr") return true;
994
1044
  const words = (n.Args || []).map((a) => resolveWordLiteral(a));
995
1045
  if (words.length === 0) return true;
996
1046
  const payload = literalShellPayload(words, baseWord(words[0]));
@@ -1010,23 +1060,23 @@ function foldCommandWords(reading) {
1010
1060
  const at = (byteOffset) => toCharIndex === null ? byteOffset : toCharIndex(byteOffset);
1011
1061
  const edits = [];
1012
1062
  try {
1013
- syntax.Walk(f, (node) => {
1063
+ walk(f, (node) => {
1014
1064
  if (!node) return false;
1015
1065
  const n = node;
1016
- if (syntax.NodeType(n) !== "CallExpr") return true;
1066
+ if (n.kind !== "CallExpr") return true;
1017
1067
  const args = n.Args || [];
1018
1068
  const words = args.map((a) => resolveWordLiteral(a));
1019
1069
  const folded = words.map((w) => w === null ? null : foldHomoglyphs(w));
1020
1070
  const head = unwrapCommandHead(folded);
1021
1071
  for (let i = 0; i <= head && i < args.length; i++) {
1022
1072
  const parts = args[i].Parts || [];
1023
- if (parts.length !== 1 || syntax.NodeType(parts[0]) !== "Lit") continue;
1073
+ if (parts.length !== 1 || parts[0].kind !== "Lit") continue;
1024
1074
  const value = parts[0].Value ?? "";
1025
1075
  const word = folded[i];
1026
1076
  if (word === null || word === value || !/[^\x00-\x7f]/.test(value)) continue;
1027
1077
  if (!/^[A-Za-z0-9._/-]+$/.test(word)) continue;
1028
- const s = at(args[i].Pos().Offset());
1029
- const e = at(args[i].End().Offset());
1078
+ const s = at(args[i].pos);
1079
+ const e = at(args[i].end);
1030
1080
  if (s < 0 || e < 0) continue;
1031
1081
  edits.push([s, e, word]);
1032
1082
  }
@@ -1063,10 +1113,10 @@ function interpreterHeredocSpans(f, at) {
1063
1113
  const stmts = f?.Stmts || [];
1064
1114
  const candidates = [];
1065
1115
  let unsafe = false;
1066
- syntax.Walk(f, (node) => {
1116
+ walk(f, (node) => {
1067
1117
  if (!node || unsafe) return false;
1068
1118
  const n = node;
1069
- const t = syntax.NodeType(n);
1119
+ const t = n.kind;
1070
1120
  if (t === "FuncDecl") {
1071
1121
  unsafe = true;
1072
1122
  return false;
@@ -1086,7 +1136,7 @@ function interpreterHeredocSpans(f, at) {
1086
1136
  });
1087
1137
  if (unsafe) return [];
1088
1138
  for (const st of stmts) {
1089
- if (!st?.Cmd || syntax.NodeType(st.Cmd) !== "CallExpr") continue;
1139
+ if (!st?.Cmd || st.Cmd.kind !== "CallExpr") continue;
1090
1140
  const words = (st.Cmd.Args || []).map((a) => resolveWordLiteral(a));
1091
1141
  const name = (words[0] ?? "").toLowerCase();
1092
1142
  if (!STDIN_CODE_INTERPRETERS.test(name)) continue;
@@ -1101,8 +1151,8 @@ function interpreterHeredocSpans(f, at) {
1101
1151
  if (stdin.length !== 1 || others > 0) continue;
1102
1152
  const r = stdin[0];
1103
1153
  if (heredocText(r.Hdoc) === null) continue;
1104
- const hs = at(r.Hdoc.Pos().Offset());
1105
- const he = at(r.Hdoc.End().Offset());
1154
+ const hs = at(r.Hdoc.pos);
1155
+ const he = at(r.Hdoc.end);
1106
1156
  if (hs < 0 || he < 0 || he <= hs) continue;
1107
1157
  spans.push([hs, he]);
1108
1158
  }
@@ -1122,24 +1172,24 @@ function normalizeCommandForPolicyImpl(command, codeBodies) {
1122
1172
  strips.push([hs, he]);
1123
1173
  msgSpans.add(`${hs}:${he}`);
1124
1174
  }
1125
- syntax.Walk(f, (node) => {
1175
+ walk(f, (node) => {
1126
1176
  if (!node) return false;
1127
1177
  const n = node;
1128
- if (syntax.NodeType(n) !== "CallExpr") return true;
1178
+ if (n.kind !== "CallExpr") return true;
1129
1179
  const args = n.Args || [];
1130
1180
  for (let i = 0; i < args.length - 1; i++) {
1131
1181
  const argParts = args[i].Parts || [];
1132
- if (argParts.length !== 1 || syntax.NodeType(argParts[0]) !== "Lit") continue;
1182
+ if (argParts.length !== 1 || argParts[0].kind !== "Lit") continue;
1133
1183
  const flagVal = argParts[0].Value || "";
1134
1184
  if (!MESSAGE_FLAGS.has(flagVal.toLowerCase())) continue;
1135
1185
  const next = args[i + 1];
1136
1186
  const nextParts = next.Parts || [];
1137
1187
  if (nextParts.length !== 1) continue;
1138
1188
  const quotedNode = nextParts[0];
1139
- const nt = syntax.NodeType(quotedNode);
1189
+ const nt = quotedNode.kind;
1140
1190
  const markStrip = () => {
1141
- const s = at(next.Pos().Offset());
1142
- const e = at(next.End().Offset());
1191
+ const s = at(next.pos);
1192
+ const e = at(next.end);
1143
1193
  if (s < 0 || e < 0) return;
1144
1194
  strips.push([s, e]);
1145
1195
  msgSpans.add(`${s}:${e}`);
@@ -1148,7 +1198,7 @@ function normalizeCommandForPolicyImpl(command, codeBodies) {
1148
1198
  markStrip();
1149
1199
  } else if (nt === "DblQuoted") {
1150
1200
  const innerParts = quotedNode.Parts || [];
1151
- const allLit = innerParts.length === 0 || innerParts.every((p) => syntax.NodeType(p) === "Lit");
1201
+ const allLit = innerParts.length === 0 || innerParts.every((p) => p.kind === "Lit");
1152
1202
  if (allLit) {
1153
1203
  markStrip();
1154
1204
  } else if (innerParts.every((p) => isCatHeredocOrLit(p))) {
@@ -1157,8 +1207,8 @@ function normalizeCommandForPolicyImpl(command, codeBodies) {
1157
1207
  }
1158
1208
  }
1159
1209
  for (const arg of args) {
1160
- const s = at(arg.Pos().Offset());
1161
- const e = at(arg.End().Offset());
1210
+ const s = at(arg.pos);
1211
+ const e = at(arg.end);
1162
1212
  if (s < 0 || e < 0) continue;
1163
1213
  if (msgSpans.has(`${s}:${e}`)) continue;
1164
1214
  const resolved = resolveWordLiteral(arg);
@@ -1198,10 +1248,10 @@ function scanArgsForDynamicExec(args, startIdx) {
1198
1248
  let hasParamExp = false;
1199
1249
  let hasCurl = false;
1200
1250
  for (let i = startIdx; i < args.length; i++) {
1201
- syntax.Walk(args[i], (inner) => {
1251
+ walk(args[i], (inner) => {
1202
1252
  if (!inner) return false;
1203
1253
  const inn = inner;
1204
- const it = syntax.NodeType(inn);
1254
+ const it = inn.kind;
1205
1255
  if (it === "CmdSubst") hasCmdSubst = true;
1206
1256
  if (it === "ParamExp") hasParamExp = true;
1207
1257
  if (it === "Lit" && DOWNLOAD_CMDS.has(inn.Value?.toLowerCase())) hasCurl = true;
@@ -1214,15 +1264,16 @@ function scanArgsForDynamicExec(args, startIdx) {
1214
1264
  }
1215
1265
  function detectDangerousShellExec(command) {
1216
1266
  try {
1217
- const f = sharedParser.Parse(command, "cmd");
1267
+ const f = parseShared(command);
1268
+ if (f === PARSE_FAIL) return null;
1218
1269
  let result = null;
1219
1270
  const assigned = assignedNames(f);
1220
- syntax.Walk(f, (node) => {
1271
+ walk(f, (node) => {
1221
1272
  if (!node || result === "block") return false;
1222
1273
  const n = node;
1223
- if (syntax.NodeType(n) === "BinaryCmd" && n.Y && !listOps().has(n.Op)) {
1274
+ if (n.kind === "BinaryCmd" && n.Y && !listOps().has(n.Op)) {
1224
1275
  const call = n.Y.Cmd;
1225
- if (call && syntax.NodeType(call) === "CallExpr") {
1276
+ if (call && call.kind === "CallExpr") {
1226
1277
  const words = (call.Args || []).map((a) => resolveWordLiteral(a));
1227
1278
  const head2 = unwrapCommandHead(words);
1228
1279
  const name = (words[head2] ?? "").split("/").pop() ?? "";
@@ -1235,7 +1286,7 @@ function detectDangerousShellExec(command) {
1235
1286
  result = "review";
1236
1287
  }
1237
1288
  }
1238
- if (syntax.NodeType(n) !== "CallExpr") return true;
1289
+ if (n.kind !== "CallExpr") return true;
1239
1290
  const args = n.Args || [];
1240
1291
  if (args.length === 0) return true;
1241
1292
  const headWords = args.map(
@@ -1246,7 +1297,7 @@ function detectDangerousShellExec(command) {
1246
1297
  if (!lookup && (opaqueExecutable(args[0], assigned) || opaqueExecutable(args[head], assigned)))
1247
1298
  result = "review";
1248
1299
  const firstParts = args[0].Parts || [];
1249
- if (firstParts.length !== 1 || syntax.NodeType(firstParts[0]) !== "Lit") return true;
1300
+ if (firstParts.length !== 1 || firstParts[0].kind !== "Lit") return true;
1250
1301
  const cmdName = firstParts[0].Value?.toLowerCase() ?? "";
1251
1302
  if (cmdName === "eval") {
1252
1303
  const v = scanArgsForDynamicExec(args, 1);
@@ -1254,7 +1305,7 @@ function detectDangerousShellExec(command) {
1254
1305
  } else if (SHELL_INTERPRETERS.has(cmdName)) {
1255
1306
  for (let i = 1; i < args.length - 1; i++) {
1256
1307
  const flagParts = args[i].Parts || [];
1257
- if (flagParts.length !== 1 || syntax.NodeType(flagParts[0]) !== "Lit" || flagParts[0].Value !== "-c")
1308
+ if (flagParts.length !== 1 || flagParts[0].kind !== "Lit" || flagParts[0].Value !== "-c")
1258
1309
  continue;
1259
1310
  const v = scanArgsForDynamicExec(args, i + 1);
1260
1311
  if (v === "block" || v === "review" && result === null) result = v;
@@ -1278,8 +1329,7 @@ function isDefaultExpansion(part) {
1278
1329
  }
1279
1330
  function lookupSubstitution(part) {
1280
1331
  const stmts = part.Stmts ?? [];
1281
- if (stmts.length !== 1 || !stmts[0].Cmd || syntax.NodeType(stmts[0].Cmd) !== "CallExpr")
1282
- return null;
1332
+ if (stmts.length !== 1 || !stmts[0].Cmd || stmts[0].Cmd.kind !== "CallExpr") return null;
1283
1333
  const words = (stmts[0].Cmd.Args ?? []).map((a) => resolveWordLiteral(a));
1284
1334
  if (words.some((w) => w === null)) return null;
1285
1335
  if (words.length === 2 && words[0] === "which") return words[1];
@@ -1289,9 +1339,9 @@ function lookupSubstitution(part) {
1289
1339
  }
1290
1340
  function assignedNames(f) {
1291
1341
  const names = /* @__PURE__ */ new Set();
1292
- syntax.Walk(f, (node) => {
1342
+ walk(f, (node) => {
1293
1343
  if (!node) return false;
1294
- const kind = syntax.NodeType(node);
1344
+ const kind = node.kind;
1295
1345
  if (kind === "Assign" && node.Name?.Value) names.add(node.Name.Value);
1296
1346
  if (kind === "ForClause" && node.Loop?.Name?.Value) names.add(node.Loop.Name.Value);
1297
1347
  if (kind === "CallExpr") {
@@ -1306,7 +1356,7 @@ function assignedNames(f) {
1306
1356
  }
1307
1357
  function executableParts(word, assigned, quoted = false) {
1308
1358
  return (word?.Parts ?? []).flatMap((part) => {
1309
- const kind = syntax.NodeType(part);
1359
+ const kind = part.kind;
1310
1360
  if (kind === "DblQuoted") return executableParts(part, assigned, true);
1311
1361
  if (kind === "Lit") return [{ kind: "Lit", value: part.Value ?? "", quoted }];
1312
1362
  if (kind === "SglQuoted")
@@ -1374,10 +1424,10 @@ function chmodHasOpenPermMode(command) {
1374
1424
  if (f === PARSE_FAIL) return false;
1375
1425
  let found = false;
1376
1426
  try {
1377
- syntax.Walk(f, (node) => {
1427
+ walk(f, (node) => {
1378
1428
  if (!node || found) return false;
1379
1429
  const n = node;
1380
- if (syntax.NodeType(n) !== "CallExpr") return true;
1430
+ if (n.kind !== "CallExpr") return true;
1381
1431
  const words = (n.Args || []).map((a) => resolveWordLiteral(a));
1382
1432
  if (words.length === 0) return true;
1383
1433
  const name = (words[0] ?? "").toLowerCase();
@@ -1430,11 +1480,11 @@ function redirStdinOps() {
1430
1480
  }
1431
1481
  function deriveBinaryOp(sample) {
1432
1482
  try {
1433
- const f = sharedParser.Parse(sample, "cmd");
1483
+ const f = toPlainTree(sharedParser.Parse(sample, "cmd"));
1434
1484
  let op = -1;
1435
- syntax.Walk(f, (node) => {
1485
+ walk(f, (node) => {
1436
1486
  const n = node;
1437
- if (n && syntax.NodeType(n) === "BinaryCmd" && op < 0) op = n.Op;
1487
+ if (n && n.kind === "BinaryCmd" && op < 0) op = n.Op;
1438
1488
  return true;
1439
1489
  });
1440
1490
  return op;
@@ -1508,7 +1558,7 @@ function heredocText(word) {
1508
1558
  const parts = word?.Parts ?? [];
1509
1559
  let out = "";
1510
1560
  for (const p of parts) {
1511
- if (syntax.NodeType(p) !== "Lit") return null;
1561
+ if (p.kind !== "Lit") return null;
1512
1562
  out += p.Value ?? "";
1513
1563
  }
1514
1564
  return out;
@@ -1544,7 +1594,7 @@ function attachedCode(interp, flag) {
1544
1594
  }
1545
1595
  function inlineExecCall(stmt, pipeFed) {
1546
1596
  const cmd = stmt?.Cmd;
1547
- if (!cmd || syntax.NodeType(cmd) !== "CallExpr") return null;
1597
+ if (!cmd || cmd.kind !== "CallExpr") return null;
1548
1598
  const words = (cmd.Args || []).map((a) => resolveWordLiteral(a));
1549
1599
  if (words.length === 0) return null;
1550
1600
  const headIdx = unwrapCommandHead(words);
@@ -1625,10 +1675,10 @@ function shellPayloadNeedsReview(payload) {
1625
1675
  let review = false;
1626
1676
  payloadNesting++;
1627
1677
  try {
1628
- syntax.Walk(f, (node) => {
1678
+ walk(f, (node) => {
1629
1679
  if (!node || review) return false;
1630
1680
  const n = node;
1631
- if (syntax.NodeType(n) !== "CallExpr") return true;
1681
+ if (n.kind !== "CallExpr") return true;
1632
1682
  const words = (n.Args || []).map((a) => resolveWordLiteral(a));
1633
1683
  if (words.length === 0) return true;
1634
1684
  const h = unwrapCommandHead(words);
@@ -1662,10 +1712,10 @@ function inlineExecCalls(command) {
1662
1712
  if (f === PARSE_FAIL) return PARSE_FAIL;
1663
1713
  const calls = [];
1664
1714
  try {
1665
- syntax.Walk(f, (node) => {
1715
+ walk(f, (node) => {
1666
1716
  if (!node || calls.length >= MAX_INLINE_CALLS) return false;
1667
1717
  const n = node;
1668
- const t = syntax.NodeType(n);
1718
+ const t = n.kind;
1669
1719
  if (t === "BinaryCmd" && n.Y && !listOps().has(n.Op)) {
1670
1720
  const call = inlineExecCall(n.Y, true);
1671
1721
  if (call) calls.push(call);
@@ -1800,7 +1850,7 @@ function shellScriptOperands(command) {
1800
1850
  walkWithCalls(f, (node) => {
1801
1851
  if (!node) return false;
1802
1852
  const n = node;
1803
- if (syntax.NodeType(n) !== "CallExpr") return true;
1853
+ if (n.kind !== "CallExpr") return true;
1804
1854
  const callArgs = n.Args || [];
1805
1855
  if (callArgs.length === 0) return true;
1806
1856
  const words = callArgs.map((a) => resolveWordLiteral(a));
@@ -1836,7 +1886,7 @@ function shellScriptOperands(command) {
1836
1886
  }
1837
1887
  function windowsDrivePathSpelling(word) {
1838
1888
  const parts = word?.Parts || [];
1839
- if (parts.length === 0 || !parts.every((p) => syntax.NodeType(p) === "Lit")) return null;
1889
+ if (parts.length === 0 || !parts.every((p) => p.kind === "Lit")) return null;
1840
1890
  const raw = parts.map((p) => p.Value ?? "").join("");
1841
1891
  return /^[A-Za-z]:\\[^\s'"$`]*$/.test(raw) ? raw : null;
1842
1892
  }
@@ -1874,15 +1924,15 @@ function recordTopLevelAssignments(f) {
1874
1924
  }
1875
1925
  function probeBinOp(src) {
1876
1926
  try {
1877
- const cmd = syntax.NewParser().Parse(src, "probe")?.Stmts?.[0]?.Cmd;
1878
- if (cmd && syntax.NodeType(cmd) === "BinaryCmd") return cmd.Op;
1927
+ const cmd = toPlainTree(syntax2.NewParser().Parse(src, "probe"))?.Stmts?.[0]?.Cmd;
1928
+ if (cmd && cmd.kind === "BinaryCmd") return cmd.Op;
1879
1929
  } catch {
1880
1930
  }
1881
1931
  return null;
1882
1932
  }
1883
1933
  function recordTopLevelStmt(stmt) {
1884
1934
  if (!stmt || !stmt.Cmd) return false;
1885
- const t = syntax.NodeType(stmt.Cmd);
1935
+ const t = stmt.Cmd.kind;
1886
1936
  if (t === "BinaryCmd") {
1887
1937
  if (!AND_OR_OPS.has(stmt.Cmd.Op)) return false;
1888
1938
  if (!recordTopLevelStmt(stmt.Cmd.X)) return false;
@@ -1892,7 +1942,7 @@ function recordTopLevelStmt(stmt) {
1892
1942
  if (t !== "CallExpr" && t !== "DeclClause") return false;
1893
1943
  let at = 0;
1894
1944
  try {
1895
- at = stmt.Pos().Offset();
1945
+ at = stmt.pos;
1896
1946
  } catch {
1897
1947
  at = 0;
1898
1948
  }
@@ -1903,14 +1953,14 @@ function recordTopLevelStmt(stmt) {
1903
1953
  }
1904
1954
  function recordAssignments(n, at) {
1905
1955
  if (!assignmentTable) return;
1906
- const t = syntax.NodeType(n);
1956
+ const t = n.kind;
1907
1957
  let assigns = [];
1908
1958
  if (t === "CallExpr") {
1909
1959
  if ((n.Args || []).length > 0) return;
1910
1960
  assigns = n.Assigns || [];
1911
1961
  } else if (t === "DeclClause") {
1912
1962
  if (!ASSIGNMENT_HEADS.has(n.Variant?.Value ?? "")) return;
1913
- assigns = (n.Args || []).filter((a) => syntax.NodeType(a) === "Assign");
1963
+ assigns = (n.Args || []).filter((a) => a.kind === "Assign");
1914
1964
  } else return;
1915
1965
  for (const a of assigns) {
1916
1966
  const name = a?.Name?.Value;
@@ -1919,13 +1969,13 @@ function recordAssignments(n, at) {
1919
1969
  }
1920
1970
  }
1921
1971
  function resolveTrivialSubst(part) {
1922
- if (syntax.NodeType(part) !== "CmdSubst") return void 0;
1972
+ if (part.kind !== "CmdSubst") return void 0;
1923
1973
  const stmts = part.Stmts || [];
1924
1974
  if (stmts.length !== 1) return void 0;
1925
1975
  const st = stmts[0];
1926
1976
  if ((st.Redirs || []).length > 0 || st.Negated || st.Background) return void 0;
1927
1977
  const cmd = st.Cmd;
1928
- if (!cmd || syntax.NodeType(cmd) !== "CallExpr") return void 0;
1978
+ if (!cmd || cmd.kind !== "CallExpr") return void 0;
1929
1979
  if ((cmd.Assigns || []).length > 0) return void 0;
1930
1980
  const words = (cmd.Args || []).map((a) => resolveWordLiteral(a));
1931
1981
  if (words.length === 0 || words.some((w) => w === null)) return void 0;
@@ -1950,7 +2000,7 @@ function recordedExpansion(name) {
1950
2000
  return rec.value;
1951
2001
  }
1952
2002
  function isPlainParam(p) {
1953
- if (syntax.NodeType(p) !== "ParamExp") return false;
2003
+ if (p.kind !== "ParamExp") return false;
1954
2004
  return !(p.Excl || p.Length || p.Width || p.Index || p.Slice || p.Repl || p.Exp);
1955
2005
  }
1956
2006
  function expandPlainParam(p) {
@@ -1962,9 +2012,9 @@ function expandPlainParam(p) {
1962
2012
  }
1963
2013
  function functionBodies(f) {
1964
2014
  const out = /* @__PURE__ */ new Map();
1965
- syntax.Walk(f, (node) => {
2015
+ walk(f, (node) => {
1966
2016
  const n = node;
1967
- if (n && syntax.NodeType(n) === "FuncDecl" && n.Name?.Value && n.Body) {
2017
+ if (n && n.kind === "FuncDecl" && n.Name?.Value && n.Body) {
1968
2018
  const list = out.get(n.Name.Value) ?? [];
1969
2019
  list.push(n.Body);
1970
2020
  out.set(n.Name.Value, list);
@@ -1975,10 +2025,10 @@ function functionBodies(f) {
1975
2025
  }
1976
2026
  function rebindsPositionals(body) {
1977
2027
  let found = false;
1978
- syntax.Walk(body, (node) => {
2028
+ walk(body, (node) => {
1979
2029
  const n = node;
1980
2030
  if (found || !n) return false;
1981
- if (syntax.NodeType(n) === "CallExpr") {
2031
+ if (n.kind === "CallExpr") {
1982
2032
  const words = (n.Args || []).map((a) => resolveWordLiteral(a));
1983
2033
  if (words[0] === "shift") found = true;
1984
2034
  else if (words[0] === "set" && words.slice(1).some((w) => w === null || w === "--" || !/^[-+]/.test(w)))
@@ -1998,7 +2048,7 @@ function tableBindings() {
1998
2048
  function walkWithCalls(f, visit) {
1999
2049
  const bodies = functionBodies(f);
2000
2050
  if (bodies.size === 0) {
2001
- syntax.Walk(f, visit);
2051
+ walk(f, visit);
2002
2052
  return;
2003
2053
  }
2004
2054
  const seenCalls = /* @__PURE__ */ new Set();
@@ -2032,8 +2082,8 @@ function walkWithCalls(f, visit) {
2032
2082
  currentStmtOffset = Number.MAX_SAFE_INTEGER;
2033
2083
  callDepth++;
2034
2084
  try {
2035
- if (body.Cmd && syntax.NodeType(body.Cmd) === "Block") recordTopLevelAssignments(body.Cmd);
2036
- syntax.Walk(body, step);
2085
+ if (body.Cmd && body.Cmd.kind === "Block") recordTopLevelAssignments(body.Cmd);
2086
+ walk(body, step);
2037
2087
  } finally {
2038
2088
  callDepth--;
2039
2089
  assignmentTable = outerTable;
@@ -2044,10 +2094,10 @@ function walkWithCalls(f, visit) {
2044
2094
  const step = (node) => {
2045
2095
  if (!node) return false;
2046
2096
  const go = visit(node);
2047
- if (go !== false && syntax.NodeType(node) === "CallExpr") inline(node);
2097
+ if (go !== false && node.kind === "CallExpr") inline(node);
2048
2098
  return go;
2049
2099
  };
2050
- syntax.Walk(f, step);
2100
+ walk(f, step);
2051
2101
  }
2052
2102
  function withAssignments(f, body) {
2053
2103
  const outerTable = assignmentTable;
@@ -2072,7 +2122,7 @@ function walkCommandScope(command, visit) {
2072
2122
  if (f === PARSE_FAIL) return "parse-fail";
2073
2123
  withAssignments(f, () => {
2074
2124
  walkWithCalls(f, (node) => {
2075
- if (node && syntax.NodeType(node) === "Stmt") trackStatement(node);
2125
+ if (node && node.kind === "Stmt") trackStatement(node);
2076
2126
  return visit(node);
2077
2127
  });
2078
2128
  });
@@ -2080,7 +2130,7 @@ function walkCommandScope(command, visit) {
2080
2130
  }
2081
2131
  function trackStatement(n) {
2082
2132
  try {
2083
- currentStmtOffset = n.Pos().Offset();
2133
+ currentStmtOffset = n.pos;
2084
2134
  } catch {
2085
2135
  currentStmtOffset = Number.MAX_SAFE_INTEGER;
2086
2136
  }
@@ -2096,11 +2146,11 @@ function resolveWordLiteral(w) {
2096
2146
  return s;
2097
2147
  }
2098
2148
  function resolveWordPrefix(w) {
2099
- const walk2 = (parts) => {
2149
+ const walk3 = (parts) => {
2100
2150
  let s = "";
2101
2151
  for (const p of parts) {
2102
2152
  if (p && typeof p === "object" && Array.isArray(p.Parts) && p.Dollar !== void 0) {
2103
- const inner = walk2(p.Parts);
2153
+ const inner = walk3(p.Parts);
2104
2154
  s += inner.prefix;
2105
2155
  if (inner.dynamic) return { prefix: s, dynamic: true };
2106
2156
  continue;
@@ -2111,10 +2161,10 @@ function resolveWordPrefix(w) {
2111
2161
  }
2112
2162
  return { prefix: s, dynamic: false };
2113
2163
  };
2114
- return walk2(w?.Parts || []);
2164
+ return walk3(w?.Parts || []);
2115
2165
  }
2116
2166
  function resolvePart(p, inQuotes) {
2117
- const t = syntax.NodeType(p);
2167
+ const t = p.kind;
2118
2168
  if (t === "Lit") {
2119
2169
  const raw = p.Value ?? "";
2120
2170
  if (!inQuotes) return raw.replace(/\\(.)/g, "$1");
@@ -2210,7 +2260,7 @@ function extractShellDestinations(command) {
2210
2260
  () => walkWithCalls(f, (node) => {
2211
2261
  if (!node) return false;
2212
2262
  const n = node;
2213
- if (syntax.NodeType(n) === "Stmt") {
2263
+ if (n.kind === "Stmt") {
2214
2264
  trackStatement(n);
2215
2265
  for (const raw of redirectWords(n)) {
2216
2266
  const host2 = devNetRedirectHost(raw);
@@ -2222,7 +2272,7 @@ function extractShellDestinations(command) {
2222
2272
  out.push({ host: host2, binary, raw });
2223
2273
  }
2224
2274
  }
2225
- if (syntax.NodeType(n) !== "CallExpr") return true;
2275
+ if (n.kind !== "CallExpr") return true;
2226
2276
  const callArgs = n.Args || [];
2227
2277
  if (callArgs.length === 0) return true;
2228
2278
  const words = callArgs.map((a) => resolveWordLiteral(a));
@@ -2257,7 +2307,7 @@ function extractShellDestTokens(command) {
2257
2307
  () => walkWithCalls(f, (node) => {
2258
2308
  if (!node) return false;
2259
2309
  const n = node;
2260
- if (syntax.NodeType(n) === "Stmt") {
2310
+ if (n.kind === "Stmt") {
2261
2311
  trackStatement(n);
2262
2312
  for (const raw of redirectWords(n)) {
2263
2313
  const host2 = devNetRedirectHost(raw);
@@ -2269,7 +2319,7 @@ function extractShellDestTokens(command) {
2269
2319
  out.push({ token: host2, binary });
2270
2320
  }
2271
2321
  }
2272
- if (syntax.NodeType(n) !== "CallExpr") return true;
2322
+ if (n.kind !== "CallExpr") return true;
2273
2323
  const callArgs = n.Args || [];
2274
2324
  if (callArgs.length === 0) return true;
2275
2325
  const words = callArgs.map((a) => resolveWordLiteral(a));
@@ -2337,11 +2387,11 @@ function isWaivableCleanupTarget(p) {
2337
2387
  }
2338
2388
  function deriveRedirOp(sample) {
2339
2389
  try {
2340
- const f = sharedParser.Parse(sample, "cmd");
2390
+ const f = toPlainTree(sharedParser.Parse(sample, "cmd"));
2341
2391
  let op = -1;
2342
- syntax.Walk(f, (node) => {
2392
+ walk(f, (node) => {
2343
2393
  const n = node;
2344
- if (n && syntax.NodeType(n) === "Redirect" && op < 0) op = n.Op;
2394
+ if (n && n.kind === "Redirect" && op < 0) op = n.Op;
2345
2395
  return true;
2346
2396
  });
2347
2397
  return op;
@@ -2354,7 +2404,7 @@ function collectSameCommandCreations(f) {
2354
2404
  try {
2355
2405
  const stmts = Array.isArray(f?.Stmts) ? f.Stmts : [];
2356
2406
  for (const stmt of stmts) {
2357
- if (!stmt || !stmt.Cmd || syntax.NodeType(stmt.Cmd) !== "CallExpr") continue;
2407
+ if (!stmt || !stmt.Cmd || stmt.Cmd.kind !== "CallExpr") continue;
2358
2408
  const redirs = stmt.Redirs || [];
2359
2409
  if (!redirs.some((r) => r && REDIR_HEREDOC_OPS.has(r.Op))) continue;
2360
2410
  for (const r of redirs) {
@@ -2378,10 +2428,10 @@ function isRmCreatedInCommandCleanup(command) {
2378
2428
  let sawRm = false;
2379
2429
  let ok = true;
2380
2430
  try {
2381
- syntax.Walk(f, (node) => {
2431
+ walk(f, (node) => {
2382
2432
  if (!node || !ok) return false;
2383
2433
  const n = node;
2384
- if (syntax.NodeType(n) !== "CallExpr") return true;
2434
+ if (n.kind !== "CallExpr") return true;
2385
2435
  const args = n.Args || [];
2386
2436
  const name = (resolveWordLiteral(args[0]) ?? "").toLowerCase();
2387
2437
  if (name !== "rm") return true;
@@ -2431,10 +2481,10 @@ function analyzeFsOperationImpl(command, depth = 0) {
2431
2481
  walkWithCalls(f, (node) => {
2432
2482
  if (!node || result?.verdict === "block") return false;
2433
2483
  const n = node;
2434
- const nodeType = syntax.NodeType(n);
2484
+ const nodeType = n.kind;
2435
2485
  if (nodeType === "Stmt") {
2436
2486
  try {
2437
- currentStmtOffset = n.Pos().Offset();
2487
+ currentStmtOffset = n.pos;
2438
2488
  } catch {
2439
2489
  currentStmtOffset = Number.MAX_SAFE_INTEGER;
2440
2490
  }
@@ -2947,11 +2997,12 @@ function analyzeShellCommand(command) {
2947
2997
  if (lower2.startsWith("-")) allTokens.push(lower2.replace(/^-+/, ""));
2948
2998
  };
2949
2999
  try {
2950
- const f = sharedParser.Parse(command, "cmd");
2951
- syntax.Walk(f, (node) => {
3000
+ const f = parseShared(command);
3001
+ if (f === PARSE_FAIL) throw new Error("parse failed");
3002
+ walk(f, (node) => {
2952
3003
  if (!node) return false;
2953
3004
  const n = node;
2954
- if (syntax.NodeType(n) !== "CallExpr") return true;
3005
+ if (n.kind !== "CallExpr") return true;
2955
3006
  const wordValues2 = (n.Args || []).map((arg) => {
2956
3007
  return (arg.Parts || []).map((p) => (p.Value ?? "").replace(/\\(.)/g, "$1")).join("");
2957
3008
  }).filter((s) => s.length > 0);
@@ -3223,7 +3274,7 @@ function runnablePrefix(command) {
3223
3274
  let text = command;
3224
3275
  for (let attempt = 0; attempt < 32; attempt++) {
3225
3276
  try {
3226
- return syntax2.NewParser().Parse(text, "");
3277
+ return toPlainTree(syntax3.NewParser().Parse(text, ""));
3227
3278
  } catch (error) {
3228
3279
  const message = String(typeof error?.Error === "function" ? error.Error() : error?.message);
3229
3280
  const line = Number(/^(\d+):/.exec(message)?.[1]);
@@ -3291,7 +3342,7 @@ function wordValues(word, state) {
3291
3342
  out2 = next.slice(0, MAX_ALTERNATIVES);
3292
3343
  };
3293
3344
  for (const node of nodes) {
3294
- const kind = syntax2.NodeType(node);
3345
+ const kind = node.kind;
3295
3346
  let pieces;
3296
3347
  if (kind === "ParamExp") pieces = paramValues(node, quoted);
3297
3348
  else if (kind === "DblQuoted") {
@@ -3359,9 +3410,9 @@ function collectShellFileAccesses(command, context = {}) {
3359
3410
  }
3360
3411
  function substitutions(word, state, depth) {
3361
3412
  if (!word) return;
3362
- syntax2.Walk(word, (node) => {
3413
+ walk(word, (node) => {
3363
3414
  if (!node) return false;
3364
- if (["CmdSubst", "ProcSubst"].includes(syntax2.NodeType(node))) {
3415
+ if (["CmdSubst", "ProcSubst"].includes(node.kind)) {
3365
3416
  statements(node.Stmts ?? [], clone(state), depth + 1);
3366
3417
  return false;
3367
3418
  }
@@ -3785,7 +3836,7 @@ function collectShellFileAccesses(command, context = {}) {
3785
3836
  }
3786
3837
  function readsScriptFromStdin(stmt) {
3787
3838
  const cmd = stmt?.Cmd;
3788
- if (!cmd || syntax2.NodeType(cmd) !== "CallExpr") return false;
3839
+ if (!cmd || cmd.kind !== "CallExpr") return false;
3789
3840
  const words = (cmd.Args ?? []).map((a) => resolveWordLiteral(a));
3790
3841
  const head = unwrapCommandHead(words);
3791
3842
  return SHELL_INTERPRETERS.has(base(words[head])) && shellConsumesPipe(words.slice(head + 1));
@@ -3799,7 +3850,7 @@ function collectShellFileAccesses(command, context = {}) {
3799
3850
  }
3800
3851
  function producedText(stmt) {
3801
3852
  const cmd = stmt?.Cmd;
3802
- if (!cmd || syntax2.NodeType(cmd) !== "CallExpr") return null;
3853
+ if (!cmd || cmd.kind !== "CallExpr") return null;
3803
3854
  const words = (cmd.Args ?? []).map((a) => resolveWordLiteral(a));
3804
3855
  if (words.some((w) => w === null)) return null;
3805
3856
  const head = unwrapCommandHead(words);
@@ -3818,7 +3869,7 @@ function collectShellFileAccesses(command, context = {}) {
3818
3869
  if (!stmt || depth > MAX_DEPTH) return;
3819
3870
  state.onSuccess = void 0;
3820
3871
  if (stmt.Background) state = clone(state);
3821
- const headWord = stmt.Cmd && syntax2.NodeType(stmt.Cmd) === "CallExpr" ? base(resolveWordLiteral(stmt.Cmd.Args?.[0])) : "";
3872
+ const headWord = stmt.Cmd && stmt.Cmd.kind === "CallExpr" ? base(resolveWordLiteral(stmt.Cmd.Args?.[0])) : "";
3822
3873
  const sends = SENDING_STDIN.has(headWord);
3823
3874
  for (const redir of stmt.Redirs ?? []) {
3824
3875
  substitutions(redir.Word, state, depth);
@@ -3834,7 +3885,7 @@ function collectShellFileAccesses(command, context = {}) {
3834
3885
  const cmd = stmt.Cmd;
3835
3886
  if (!cmd) return;
3836
3887
  stdinScript(stmt, state, depth);
3837
- switch (syntax2.NodeType(cmd)) {
3888
+ switch (cmd.kind) {
3838
3889
  case "CallExpr":
3839
3890
  call(cmd, state, depth);
3840
3891
  break;
@@ -3848,7 +3899,7 @@ function collectShellFileAccesses(command, context = {}) {
3848
3899
  for (; ; ) {
3849
3900
  segments2.unshift({ op: node.Op, part: node.Y });
3850
3901
  const left = node.X;
3851
- if (left?.Cmd && syntax2.NodeType(left.Cmd) === "BinaryCmd" && !left.Redirs?.length && !left.Negated && !left.Background)
3902
+ if (left?.Cmd && left.Cmd.kind === "BinaryCmd" && !left.Redirs?.length && !left.Negated && !left.Background)
3852
3903
  node = left.Cmd;
3853
3904
  else {
3854
3905
  segments2.unshift({ op: node.Op, part: left });
@@ -5218,11 +5269,10 @@ function shellWriteUnseen(command, target) {
5218
5269
  let unseen = false;
5219
5270
  let seen = false;
5220
5271
  try {
5221
- syntax4.Walk(f, (node) => {
5272
+ walk(f, (node) => {
5222
5273
  if (!node || unseen) return false;
5223
5274
  const n = node;
5224
- if (syntax4.NodeType(n) !== "Stmt" || !n.Cmd || syntax4.NodeType(n.Cmd) !== "CallExpr")
5225
- return true;
5275
+ if (n.kind !== "Stmt" || !n.Cmd || n.Cmd.kind !== "CallExpr") return true;
5226
5276
  const words = (n.Cmd.Args || []).map(
5227
5277
  (a) => resolveWordLiteral(a)
5228
5278
  );
@@ -5277,14 +5327,14 @@ function analyzeGitImpl(command) {
5277
5327
  seen.add(key);
5278
5328
  findings.push(f);
5279
5329
  };
5280
- const walk2 = new GitWalk((inv) => classify(inv).forEach(found), found);
5281
- const parsed = walk2.run(command, 0);
5330
+ const walk3 = new GitWalk((inv) => classify(inv).forEach(found), found);
5331
+ const parsed = walk3.run(command, 0);
5282
5332
  return { parsed, findings };
5283
5333
  }
5284
5334
  function isPositionalParam(word) {
5285
5335
  let parts = word?.Parts || [];
5286
- if (parts.length === 1 && syntax5.NodeType(parts[0]) === "DblQuoted") parts = parts[0].Parts || [];
5287
- if (parts.length !== 1 || syntax5.NodeType(parts[0]) !== "ParamExp") return false;
5336
+ if (parts.length === 1 && parts[0].kind === "DblQuoted") parts = parts[0].Parts || [];
5337
+ if (parts.length !== 1 || parts[0].kind !== "ParamExp") return false;
5288
5338
  return /^(\d+|@|\*)$/.test(parts[0].Param?.Value ?? "");
5289
5339
  }
5290
5340
  function boundPositionals() {
@@ -5298,11 +5348,11 @@ function boundPositionals() {
5298
5348
  function plainParamName(word) {
5299
5349
  let parts = word?.Parts || [];
5300
5350
  let quoted = false;
5301
- if (parts.length === 1 && syntax5.NodeType(parts[0]) === "DblQuoted") {
5351
+ if (parts.length === 1 && parts[0].kind === "DblQuoted") {
5302
5352
  parts = parts[0].Parts || [];
5303
5353
  quoted = true;
5304
5354
  }
5305
- if (parts.length !== 1 || syntax5.NodeType(parts[0]) !== "ParamExp") return null;
5355
+ if (parts.length !== 1 || parts[0].kind !== "ParamExp") return null;
5306
5356
  const p = parts[0];
5307
5357
  if (p.Excl || p.Length || p.Width || p.Index || p.Slice || p.Repl || p.Exp) return null;
5308
5358
  const name = p.Param?.Value;
@@ -5327,7 +5377,7 @@ function resolveGitWords(word) {
5327
5377
  }
5328
5378
  const parts = word?.Parts || [];
5329
5379
  const expansion = parts.some((p) => {
5330
- const t = syntax5.NodeType(p);
5380
+ const t = p.kind;
5331
5381
  return t === "ParamExp" || t === "CmdSubst";
5332
5382
  });
5333
5383
  return expansion ? splitFields(value) : [value];
@@ -5728,14 +5778,14 @@ function hookCommands(text) {
5728
5778
  const root = parsed?.hooks;
5729
5779
  if (!root || typeof root !== "object") return null;
5730
5780
  const out = [];
5731
- const walk2 = (v, depth) => {
5781
+ const walk3 = (v, depth) => {
5732
5782
  if (depth > 8 || !v || typeof v !== "object") return;
5733
5783
  for (const [k, x] of Object.entries(v)) {
5734
5784
  if (k === "command" && typeof x === "string") out.push(x);
5735
- else walk2(x, depth + 1);
5785
+ else walk3(x, depth + 1);
5736
5786
  }
5737
5787
  };
5738
- walk2(root, 0);
5788
+ walk3(root, 0);
5739
5789
  return out;
5740
5790
  }
5741
5791
  function hooksDisarmed(text) {
@@ -5902,9 +5952,9 @@ function isDupInOp(op) {
5902
5952
  if (dupInOp === null) {
5903
5953
  let found = -1;
5904
5954
  try {
5905
- syntax6.Walk(parseShared("cat <&3"), (node) => {
5955
+ walk(parseShared("cat <&3"), (node) => {
5906
5956
  const n = node;
5907
- if (found === -1 && n && syntax6.NodeType(n) === "Stmt" && n.Redirs?.[0]) {
5957
+ if (found === -1 && n && n.kind === "Stmt" && n.Redirs?.[0]) {
5908
5958
  found = n.Redirs[0].Op;
5909
5959
  }
5910
5960
  return true;
@@ -5925,10 +5975,10 @@ function analyzeOutbound(command) {
5925
5975
  return hit;
5926
5976
  }
5927
5977
  const findings = [];
5928
- const walk2 = new OutboundWalk(findings);
5929
- const parsed = walk2.run(command, 0);
5978
+ const walk3 = new OutboundWalk(findings);
5979
+ const parsed = walk3.run(command, 0);
5930
5980
  const envOut = findings.find((f) => f.checkId === "data.env-exfil");
5931
- if (envOut) envOut.destinations = walk2.envDestinations();
5981
+ if (envOut) envOut.destinations = walk3.envDestinations();
5932
5982
  const computed = { parsed, findings };
5933
5983
  if (cache2.size >= CACHE_MAX2) {
5934
5984
  const oldest = cache2.keys().next().value;
@@ -5944,7 +5994,7 @@ function wordShape(word) {
5944
5994
  const parts = word?.Parts || [];
5945
5995
  let out = "";
5946
5996
  for (const p of parts) {
5947
- const t = syntax6.NodeType(p);
5997
+ const t = p.kind;
5948
5998
  if (t === "Lit" || t === "SglQuoted") out += p.Value ?? "";
5949
5999
  else if (t === "DblQuoted") out += wordShape(p);
5950
6000
  else out += "X";
@@ -6079,16 +6129,16 @@ function declDumpsEnv(decl) {
6079
6129
  }
6080
6130
  function paramName(word) {
6081
6131
  let parts = word?.Parts || [];
6082
- if (parts.length === 1 && syntax6.NodeType(parts[0]) === "DblQuoted") parts = parts[0].Parts || [];
6083
- if (parts.length !== 1 || syntax6.NodeType(parts[0]) !== "ParamExp") return null;
6132
+ if (parts.length === 1 && parts[0].kind === "DblQuoted") parts = parts[0].Parts || [];
6133
+ if (parts.length !== 1 || parts[0].kind !== "ParamExp") return null;
6084
6134
  return parts[0].Param?.Value ?? null;
6085
6135
  }
6086
6136
  function refersTo(word, names) {
6087
6137
  let hit = false;
6088
- syntax6.Walk(word, (node) => {
6138
+ walk(word, (node) => {
6089
6139
  if (hit || !node) return false;
6090
6140
  const n = node;
6091
- if (syntax6.NodeType(n) === "ParamExp" && names.has(n.Param?.Value)) hit = true;
6141
+ if (n.kind === "ParamExp" && names.has(n.Param?.Value)) hit = true;
6092
6142
  return !hit;
6093
6143
  });
6094
6144
  return hit;
@@ -6096,10 +6146,10 @@ function refersTo(word, names) {
6096
6146
  function runsCommandsIn(stmt) {
6097
6147
  const readVars = /* @__PURE__ */ new Set();
6098
6148
  let hit = false;
6099
- syntax6.Walk(stmt, (node) => {
6149
+ walk(stmt, (node) => {
6100
6150
  if (hit || !node) return false;
6101
6151
  const n = node;
6102
- if (syntax6.NodeType(n) !== "CallExpr") return true;
6152
+ if (n.kind !== "CallExpr") return true;
6103
6153
  const words = wordsOf(n);
6104
6154
  if (words.length === 0) return true;
6105
6155
  const { head, at } = headOf(words);
@@ -6676,7 +6726,7 @@ function localContexts(file2) {
6676
6726
  if (depth > 64) return null;
6677
6727
  if (!stmt || stmt.Background || stmt.Negated || stmt.Redirs?.length) return null;
6678
6728
  const cmd = stmt.Cmd;
6679
- const kind = syntax7.NodeType(cmd);
6729
+ const kind = cmd.kind;
6680
6730
  if (kind === "BinaryCmd" && cmd.Op === andOp) {
6681
6731
  const next = visit(cmd.X, steps, depth + 1);
6682
6732
  return next === null ? null : visit(cmd.Y, next, depth + 1);
@@ -6692,7 +6742,7 @@ function localContexts(file2) {
6692
6742
  )
6693
6743
  ))
6694
6744
  return null;
6695
- contexts.set(cmd.Pos().Offset(), steps);
6745
+ contexts.set(cmd.pos, steps);
6696
6746
  return null;
6697
6747
  }
6698
6748
  if (file2.Stmts?.length === 1) visit(file2.Stmts[0], []);
@@ -6703,12 +6753,12 @@ function collect(command, out, depth) {
6703
6753
  const f = parseShared(command);
6704
6754
  if (typeof f === "symbol") return;
6705
6755
  const contexts = depth === 0 ? localContexts(f) : /* @__PURE__ */ new Map();
6706
- syntax7.Walk(f, (node) => {
6707
- if (node && syntax7.NodeType(node) === "CallExpr") {
6756
+ walk(f, (node) => {
6757
+ if (node && node.kind === "CallExpr") {
6708
6758
  const words = (node.Args || []).map((a) => resolveWordLiteral(a));
6709
6759
  const start = out.length;
6710
6760
  if (words.length > 0) fromCall(words, out, depth);
6711
- const steps = contexts.get(node.Pos().Offset());
6761
+ const steps = contexts.get(node.pos);
6712
6762
  for (let i = start; i < out.length; i++) {
6713
6763
  if (["npx", "bunx", "npm exec"].includes(out[i].manager)) {
6714
6764
  if (!steps) out[i].localCwd = null;
@@ -6755,7 +6805,7 @@ function collect2(command, out, depth) {
6755
6805
  try {
6756
6806
  walkCommandScope(command, (node) => {
6757
6807
  const n = node;
6758
- if (!n || syntax8.NodeType(n) !== "CallExpr") return true;
6808
+ if (!n || n.kind !== "CallExpr") return true;
6759
6809
  const words = (n.Args || []).map((a) => resolveWordLiteral(a));
6760
6810
  if (words.length === 0) return true;
6761
6811
  const prefix = (n.Assigns || []).filter((a) => a?.Name?.Value).map(
@@ -8140,12 +8190,12 @@ function extractContentDestinations(text) {
8140
8190
  function extractArgDestinations(args) {
8141
8191
  const out = /* @__PURE__ */ new Set();
8142
8192
  try {
8143
- walk(args, void 0, out, 0);
8193
+ walk2(args, void 0, out, 0);
8144
8194
  } catch {
8145
8195
  }
8146
8196
  return [...out];
8147
8197
  }
8148
- function walk(value, key, out, depth) {
8198
+ function walk2(value, key, out, depth) {
8149
8199
  if (out.size >= MAX_DESTINATIONS || depth > 12) return;
8150
8200
  if (typeof value === "string") {
8151
8201
  const s = value.length > MAX_SCAN_CHARS ? value.slice(0, MAX_SCAN_CHARS) : value;
@@ -8164,12 +8214,12 @@ function walk(value, key, out, depth) {
8164
8214
  return;
8165
8215
  }
8166
8216
  if (Array.isArray(value)) {
8167
- for (const v of value) walk(v, key, out, depth + 1);
8217
+ for (const v of value) walk2(v, key, out, depth + 1);
8168
8218
  return;
8169
8219
  }
8170
8220
  if (value && typeof value === "object") {
8171
8221
  for (const [k, v] of Object.entries(value))
8172
- walk(v, k, out, depth + 1);
8222
+ walk2(v, k, out, depth + 1);
8173
8223
  }
8174
8224
  }
8175
8225
  function destinationDomain(dest) {
@@ -8821,9 +8871,9 @@ function classifyCall(head, args, prefixes, env, state, out) {
8821
8871
  function walkCalls(command, out, depth, state) {
8822
8872
  const f = parseShared(command);
8823
8873
  if (typeof f === "symbol" || !f) return;
8824
- syntax9.Walk(f, (node) => {
8874
+ walk(f, (node) => {
8825
8875
  if (!node) return false;
8826
- const type = syntax9.NodeType(node);
8876
+ const type = node.kind;
8827
8877
  if (type === "DeclClause") {
8828
8878
  for (const a of node.Args || []) if (a?.Name?.Value) state.env.add(a.Name.Value);
8829
8879
  return true;
@@ -8975,7 +9025,7 @@ function matchCanaryArgs(args, values) {
8975
9025
  if (values.length === 0) return null;
8976
9026
  const needles = prepare(values);
8977
9027
  if (needles.length === 0) return null;
8978
- const walk2 = (v, depth, fieldPath) => {
9028
+ const walk3 = (v, depth, fieldPath) => {
8979
9029
  if (depth > MAX_DEPTH4) return null;
8980
9030
  if (typeof v === "string") {
8981
9031
  const hit = matchPrepared(v, needles);
@@ -8984,31 +9034,31 @@ function matchCanaryArgs(args, values) {
8984
9034
  const trimmed = v.trim();
8985
9035
  if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
8986
9036
  try {
8987
- return walk2(JSON.parse(v), depth + 1, fieldPath);
9037
+ return walk3(JSON.parse(v), depth + 1, fieldPath);
8988
9038
  } catch {
8989
9039
  }
8990
9040
  }
8991
9041
  }
8992
9042
  return null;
8993
9043
  }
8994
- if (typeof v === "number" && Number.isFinite(v)) return walk2(String(v), depth, fieldPath);
9044
+ if (typeof v === "number" && Number.isFinite(v)) return walk3(String(v), depth, fieldPath);
8995
9045
  if (Array.isArray(v)) {
8996
9046
  for (let i = 0; i < v.length; i++) {
8997
- const h = walk2(v[i], depth + 1, `${fieldPath}[${i}]`);
9047
+ const h = walk3(v[i], depth + 1, `${fieldPath}[${i}]`);
8998
9048
  if (h) return h;
8999
9049
  }
9000
9050
  return null;
9001
9051
  }
9002
9052
  if (v && typeof v === "object") {
9003
9053
  for (const [k, child] of Object.entries(v)) {
9004
- const h = walk2(child, depth + 1, fieldPath ? `${fieldPath}.${k}` : k);
9054
+ const h = walk3(child, depth + 1, fieldPath ? `${fieldPath}.${k}` : k);
9005
9055
  if (h) return h;
9006
9056
  }
9007
9057
  }
9008
9058
  return null;
9009
9059
  };
9010
9060
  try {
9011
- return walk2(args, 0, "");
9061
+ return walk3(args, 0, "");
9012
9062
  } catch (e) {
9013
9063
  console.error(
9014
9064
  "[node9 engine] canary args walk failed:",
@@ -9017,7 +9067,7 @@ function matchCanaryArgs(args, values) {
9017
9067
  return null;
9018
9068
  }
9019
9069
  }
9020
- var MAX_REGEX_LENGTH, REGEX_CACHE_MAX, regexCache, aws_default, bash_safe_default, docker_default, filesystem_default, github_default, k8s_default, mongodb_default, postgres_default, project_jail_default, redis_default, finance_default, identity_default, publishing_default, settings_default, branches_default, ACTION_TEMPLATES, ACTION_CHECKS, GAP, prog, httpTo, httpWrite, HTTP_WRITE, HTTP_WRITE_ANY, NOT_STRIPE_TEST, postTo, STRIPE_OBJECTS, APP_SHIELD_SPECS, APP_SHIELDS, APP_SHIELD_NAMES, APP_SERVER_GLOB, GENERAL_ACTION_RULES, BUILTIN_SHIELDS, SSRF_MAX_HOST, METADATA_ADDRESSES, STRICT_TIERS, METADATA_HOSTNAMES, v4Octets, TIER_REASON, CHECK_TEXT, LEVELS, MODE_VALUES, SOFT, STRICT, BLOCK_ALL, LEVEL_CHECKS, VERDICTS, CHECK_VERDICT_RANK, ALL, BUILTIN_DANGEROUS_WORDS, PRODUCT_CHECKS, SHIELD_RULE_NAME, SHIELD_RULES_FOLDED_INTO_PRODUCT, CHECKS, CHECK_BY_ID, LEGACY_TO_ID, PROJECT_JAIL_BLOCK_READ, OVERRIDE_PREFIX, LABEL_WRAPPERS, LEGACY_READERS, INVISIBLE_RE, INVISIBLE_ONE, HOMOGLYPHS, HOMOGLYPH_RE, MAX_BLOBS, MIN_DECODED, BASE64_RUN_RE, HEX_RUN_RE, HEX_ESCAPE_RUN_RE, SYSTEM_AUTH_FILES, SYSTEM_AUTH_DIRS, PASSWORD_HASH_FILES, STARTUP_NAMES, SYSTEM_DIRS, SYSTEM_DIRS_EXEMPT, UPLOAD_SYSTEM_DIRS, AGENT_INSTRUCTION_FILES, AGENT_INSTRUCTION_DIRS, LEGACY_SYSTEM_PATH_RE, MAX_INLINE_CODE, WHAT, OUTSIDE, pyImport, either, PYTHON, NODE, PERL, RUBY, PHP, TABLES, STRING_LITERAL, syntax, sharedParser, MESSAGE_FLAGS, SHELL_INTERPRETERS, DOWNLOAD_CMDS, NORMALIZE_CACHE_MAX, normalizeCache, codeBodiesCache, AST_CACHE_MAX, astCache, PARSE_FAIL, INTERPRETER_LINE, PROGRAM_DIR, ACCESS_VIEW_CACHE_MAX, accessViewCache, MAX_READING_PAYLOADS, STDIN_CODE_INTERPRETERS, RUNS_TEXT_ELSEWHERE, defaultExpansionOps, VARIABLE_READERS, FS_READ_TOOLS, GREP_SHAPE, PATTERN_VERBS, PATTERN_VERB_NAMES, GREP_FILE_OPERANDS, READER_VALUE_LETTERS, FILE_OPERAND_FLAGS, SCP_VALUE_FLAGS, CURL_SOURCE_FLAGS, CURL_VALUE_LETTERS, WGET_VALUE_LETTERS, TAR_VALUE_LETTERS, ZIP_VALUE_LETTERS, RSYNC_VALUE_LETTERS, RSYNC_SKIP, CP_VALUE_LETTERS, INSTALL_VALUE_LETTERS, COPY_VERBS, TAR_MODE_WORD, COPY_VERB_HEADS, FS_OP_PRESCREEN_RE, HOME_CACHE_ALLOWLIST, SENSITIVE_PATH_RULES, AST_FS_REGEX_RULES, SQL_DB_CLIS, SQL_DDL_RE, CHMOD_OPEN_PERM_TOKENS, COMMAND_WRAPPERS, INLINE_INTERPRETER, RUNNER_WRAPPERS, _redirStdinOps, _listOps, WRAPPER_TAKES_TARGET, FIND_EXEC_FLAGS, FS_MUTATION_TOOLS, INTERP_LEADING_TARGET, MAX_PAYLOAD_NESTING, payloadNesting, MAX_INLINE_CALLS, INLINE_EXEC_FALLBACK, UNREADABLE_SOURCE, SCRIPT_RUNNERS, SCRIPT_RUNNER_VALUE_FLAGS, MAX_SCRIPT_OPERANDS, NET_BINARIES, VALUE_FLAGS, HOME_VARIABLES, assignmentTable, currentStmtOffset, PAYLOAD_BUDGET, payloadBudget, seenPayloads, UNANALYSABLE_NESTING, ASSIGNMENT_HEADS, AND_OP, OR_OP, AND_OR_OPS, MAX_CALL_DEPTH, MAX_CALL_WALKS, callDepth, callWalks, FS_OP_CACHE_MAX, fsOpCache, stripDotSlash, REDIR_TRUNCATE_OPS, REDIR_FILE_IN_OPS, REDIR_HEREDOC_OPS, FIND_OPTIONS, COPY_RULE_OF, isReaderWord, positionalAfter, NONE, UNKNOWN, FORBIDDEN_PATH_SEGMENTS, BASH_TOOL_NAMES, MCP_EXECUTORS, BUILTIN_FIELDS, ARGV_FIELDS, BARE_WORD, MAX_ARGV_CHARACTERS, syntax2, MAX_ALTERNATIVES, MAX_CALL_DEPTH2, MAX_CALL_WALKS2, POSITIONAL, MAX_DEPTH, MAX_PAYLOAD_DEPTH, unique, clone, SENDING_STDIN, DOWNLOAD_SHORT_VALUE, DOWNLOAD_LONG_VALUE, DOWNLOAD_OUTPUT_FLAGS, DOWNLOAD_DIR_FLAGS, base, quoteGlob, asWord, WRITES, APPENDS, READS, DUP_OUT, HERE_STRING, AND, OR, DEFAULT_OPS, exempt, RANK, syntax3, SEQUENCE_OPS, BIP39_ENGLISH, BIP39_PUBLIC_VECTORS, indices, lengths, hash, MAX_MNEMONIC_HASHES, SECRET_VIEW_LIMITS, IBAN_LENGTH, IBAN_BBAN_SHAPE, B58, B58_INDEX, XPRV_VERSIONS, B62, CRC32_TABLE, GITHUB_TOKEN_RE, B64URL, B64URL_INDEX, CASK_TWO_ZERO_SUFFIX, CASK_FOUR_ZERO_SUFFIX, CF_ODD, CF_EVEN, SPANISH_LETTERS, HETU_CHARS, VERHOEFF_D, VERHOEFF_P, MAX, UNTRUSTED_TOOLS, INJECTION_SIGNALS, MENTION_QUOTE_RE, MENTION_WORD_RE, ASSIGNMENT_CONTEXT_RE, DLP_STOPWORDS, REFERENCE_VALUE_RE, IDENTIFIER_VALUE_RE, PATH_VALUE_RE, DOTTED_REFERENCE_RE, CONCATENATION_RE, EMAIL_VALUE_RE, FIXTURE_NAME_RE, DERIVATIVE_NAME_RE, QUERY_CREDENTIAL_VALUE_RE, OTP_SECRET_RE, OTP_DOC_SECRETS, ASSIGNED_SECRET_VALUE_RE, ASSIGNED_SECRET_NAME_RE, NAME_KEYWORD_RE, ARN_CONTEXT_RE, CIPHER_KEY_NAME_RE, CIPHER_NAME_PARTS, CIPHER_KEY_VALUE_RE, LARAVEL_KEY_VALUE_RE, SQL_PASSWORD_VALUE_RE, GRAFANA_KEY_VALUE_RE, BASIC_VALUE_RE, BASIC_PAIR_RE, BASIC_HEADER_RE, BASIC_HEADER_PAIR_RE, BASIC_PLACEHOLDER_RE, BASIC_TEMPLATE_MARKERS, DROPBOX_SECRET_RE, OTP_CAPTURE_RE, DB_URL_PASSWORD_RE, DLP_PATTERNS, DLP_PATTERNS_GLOBAL, SENSITIVE_PATH_PATTERNS, SENSITIVE_PATH_REGEXES, MAX_DEPTH2, MAX_STRING_BYTES, MAX_JSON_PARSE_BYTES, BATCH_SEPARATOR, ENCODED_RUN_RE, IMPERATIVE, SECRET_TARGET, GUARD, SIGNALS, DESTINATION_RE, REUSED_SIGNALS, NEVER_NEGATED, NEGATION_BEFORE, syntax4, RDR_IN, COPY_VERBS2, LITERAL_VERBS, syntax5, GIT_PRESCREEN_RE, MAX_PAYLOAD_DEPTH2, MAX_ALIAS_DEPTH, CACHE_MAX, cache, PAYLOAD_SHELLS, CONFIG_SCOPE_FLAGS, CONFIG_VALUE_FLAGS, GLOBAL_VALUE_OPTIONS, GLOBAL_FLAG_OPTIONS, MAX_LOOP_ITEMS, GitWalk, POSITIONAL2, FORCE_PUSH, DESTRUCTIVE, UNREADABLE, PUSH_LONG_VALUE, BRANCH_LONG_VALUE, TAG_LONG_VALUE, CLEAN_LONG_VALUE, HOOKS_BYPASS, NO_VERIFY_SUBS, HOOK_KILL_SWITCHES, COMMIT_LONG_VALUE, CHMOD_OPTION_RE, STAGE_ALL, ADD_LONG_VALUE, CHECK_ID, RULE_NAME, INERT_LINE_RE, CHECK_ID2, INSTRUCTION_NAMES, SETTINGS_RE, HOOK_WORDS_RE, syntax6, SHELLS, NETCATS, NET_CLIENTS, SENDERS, NETCAT_EXEC_LONG, DECL_DUMPS, PROC_ENVIRON_RE, DEV_NET_RE, SOCAT_PROGRAM_RE, SOCAT_NET_RE, PRESCREEN_RE, MAX_PAYLOAD_DEPTH3, CACHE_MAX2, cache2, dupInOp, REVERSE_SHELL_DESCRIPTION, ENV_EXFIL_DESCRIPTION, DYNAMIC_WORD, MULTICALL, SHELL_VALUE_OPTIONS, INTERPRETERS, OutboundWalk, syntax7, NPM_INSTALL_VERBS, NPM_EXEC_VERBS, PNPM_INSTALL_VERBS, YARN_INSTALL_VERBS, BUN_INSTALL_VERBS, DLX_VERBS, NON_REGISTRY_RE, NPM_NAME_RE, EXACT_SEMVER_RE, NPM_VALUE_FLAGS, PNPM_VALUE_FLAGS, YARN_VALUE_FLAGS, BUN_VALUE_FLAGS, PIP_VALUE_FLAGS, UV_VALUE_FLAGS, POETRY_VALUE_FLAGS, PIPENV_VALUE_FLAGS, PIPX_VALUE_FLAGS, PY_SPEC_RE, PY_EXACT_RE, EXACT_VERSION_RE, GEM_NAME_RE, GEM_VALUE_FLAGS, BUNDLE_VALUE_FLAGS, CRATE_NAME_RE, CARGO_ADD_VALUE_FLAGS, CARGO_INSTALL_VALUE_FLAGS, GO_VALUE_FLAGS, GO_PATH_RE, NUGET_NAME_RE, DOTNET_ADD_VALUE_FLAGS, DOTNET_TOOL_VALUE_FLAGS, NUGET_VALUE_FLAGS, MAVEN_COORD_RE, COMPOSER_NAME_RE, COMPOSER_VALUE_FLAGS, EDITOR_HEADS, EXTENSION_ID_RE, MANAGER_HEADS, SHELLS2, MAX_NESTING, SHELL_VALUE_FLAGS, syntax8, NPM_FAMILY, PIP_FAMILY, NPM_FETCH_VERBS, PIP_FETCH_VERBS, NPM_FLAGS, PIP_FLAGS, NPM_VARS, PIP_VARS, PRESCREEN_RE2, PIP_ATTACHED_RE, MAX_PAYLOAD_DEPTH4, PUBLIC_REGISTRY_HOSTS, TUNING_FIELDS, MAP_GOVERNED, KNOB_GOVERNED, CONFIGURABLE_CHECK_IDS, DEFAULT_EGRESS_ALLOWLIST, PRIVATE_HOST_SUFFIXES, SOURCE_COMMANDS, SINK_COMMANDS, OBFUSCATORS, SENSITIVE_PATTERNS, FLAGS_WITH_VALUES, DESTINATION_ARGS, MCP_DESTINATION_KEYS, ARGUMENT_SCAN_LIMITS, RUN_CHAR, runChar, VERDICT_RANK, SQL_DML_KEYWORDS, MAX_DESTINATIONS, MAX_SCAN_CHARS, EMAIL_RE, URL_RE, IBAN_RE, RECIPIENT_KEYS, DESTRUCTIVE_VERB_RE, PII_EMAIL_RE, PII_SSN_RE, PII_PHONE_RE, PII_CC16_RE, PII_CC15_RE, PII_CC14_RE, PII_CC13_RE, PII_CC19_RE, CARD_PATTERNS, PII_ROUTING_RE, ROUTING_LABEL_RE, ROUTING_LABEL_WINDOW, NATIONAL_ID_SHAPES, NATIONAL_ID_LABEL_RE, NATIONAL_ID_LABEL_CS_RE, idLabelIn, NATIONAL_ID_LABEL_WINDOW, NATIONAL_ID_GUARD_RE, PII_IBAN_RE, REALTIME_PII_PATTERNS, MAX_PII_SCAN_BYTES, IBAN_DESTINATION_KEYS, WHOLE_IBAN_RE, JSON_ESCAPE_RE, JSON_ESCAPES, MASKED_KINDS, ENTRY_RE, IBAN_TEXT_RE, EMAIL_TEXT_RE, ACCOUNT_KEY_RE, ACCOUNT_VALUE_RE, MAX_MASK_DEPTH, syntax9, EMPTY, CURL_SEND_FLAGS, WGET_SEND_FLAGS, IWR_SEND_FLAGS, WRITE_METHODS, GH_READ, GH_WRITE, GH_HOSTNAME_FLAGS, GH_REPO_VALUE_FLAGS, GH_API_VALUE_FLAGS, GIT_FETCH, PUBLISH, SHELLS3, OWN_HEADS, MAX_DEPTH3, CWD_CHANGERS, TERMINAL_ESCAPE_RE, LOOP_MAX_RECORDS, CANARY_MIN_LENGTH, MAX_TEXT, MAX_DEPTH4, MAX_JSON_PARSE, URL_DEPTH, B64_DEPTH, MIN_SEGMENT, SEPARATORS, stripSeparators, looksText, CANARY_DECODERS, VIEWS, LONG_OUTPUT_THRESHOLD_BYTES, CANONICAL_EXTRACTOR_VERSION;
9070
+ var MAX_REGEX_LENGTH, REGEX_CACHE_MAX, regexCache, aws_default, bash_safe_default, docker_default, filesystem_default, github_default, k8s_default, mongodb_default, postgres_default, project_jail_default, redis_default, finance_default, identity_default, publishing_default, settings_default, branches_default, ACTION_TEMPLATES, ACTION_CHECKS, GAP, prog, httpTo, httpWrite, HTTP_WRITE, HTTP_WRITE_ANY, NOT_STRIPE_TEST, postTo, STRIPE_OBJECTS, APP_SHIELD_SPECS, APP_SHIELDS, APP_SHIELD_NAMES, APP_SERVER_GLOB, GENERAL_ACTION_RULES, BUILTIN_SHIELDS, SSRF_MAX_HOST, METADATA_ADDRESSES, STRICT_TIERS, METADATA_HOSTNAMES, v4Octets, TIER_REASON, CHECK_TEXT, LEVELS, MODE_VALUES, SOFT, STRICT, BLOCK_ALL, LEVEL_CHECKS, VERDICTS, CHECK_VERDICT_RANK, ALL, BUILTIN_DANGEROUS_WORDS, PRODUCT_CHECKS, SHIELD_RULE_NAME, SHIELD_RULES_FOLDED_INTO_PRODUCT, CHECKS, CHECK_BY_ID, LEGACY_TO_ID, PROJECT_JAIL_BLOCK_READ, OVERRIDE_PREFIX, LABEL_WRAPPERS, LEGACY_READERS, syntax, KINDS, STRUCTS, unknownKinds, INVISIBLE_RE, INVISIBLE_ONE, HOMOGLYPHS, HOMOGLYPH_RE, MAX_BLOBS, MIN_DECODED, BASE64_RUN_RE, HEX_RUN_RE, HEX_ESCAPE_RUN_RE, SYSTEM_AUTH_FILES, SYSTEM_AUTH_DIRS, PASSWORD_HASH_FILES, STARTUP_NAMES, SYSTEM_DIRS, SYSTEM_DIRS_EXEMPT, UPLOAD_SYSTEM_DIRS, AGENT_INSTRUCTION_FILES, AGENT_INSTRUCTION_DIRS, LEGACY_SYSTEM_PATH_RE, MAX_INLINE_CODE, WHAT, OUTSIDE, pyImport, either, PYTHON, NODE, PERL, RUBY, PHP, TABLES, STRING_LITERAL, syntax2, sharedParser, MESSAGE_FLAGS, SHELL_INTERPRETERS, DOWNLOAD_CMDS, NORMALIZE_CACHE_MAX, normalizeCache, codeBodiesCache, AST_CACHE_MAX, astCache, PARSE_FAIL, INTERPRETER_LINE, PROGRAM_DIR, ACCESS_VIEW_CACHE_MAX, accessViewCache, MAX_READING_PAYLOADS, STDIN_CODE_INTERPRETERS, RUNS_TEXT_ELSEWHERE, defaultExpansionOps, VARIABLE_READERS, FS_READ_TOOLS, GREP_SHAPE, PATTERN_VERBS, PATTERN_VERB_NAMES, GREP_FILE_OPERANDS, READER_VALUE_LETTERS, FILE_OPERAND_FLAGS, SCP_VALUE_FLAGS, CURL_SOURCE_FLAGS, CURL_VALUE_LETTERS, WGET_VALUE_LETTERS, TAR_VALUE_LETTERS, ZIP_VALUE_LETTERS, RSYNC_VALUE_LETTERS, RSYNC_SKIP, CP_VALUE_LETTERS, INSTALL_VALUE_LETTERS, COPY_VERBS, TAR_MODE_WORD, COPY_VERB_HEADS, FS_OP_PRESCREEN_RE, HOME_CACHE_ALLOWLIST, SENSITIVE_PATH_RULES, AST_FS_REGEX_RULES, SQL_DB_CLIS, SQL_DDL_RE, CHMOD_OPEN_PERM_TOKENS, COMMAND_WRAPPERS, INLINE_INTERPRETER, RUNNER_WRAPPERS, _redirStdinOps, _listOps, WRAPPER_TAKES_TARGET, FIND_EXEC_FLAGS, FS_MUTATION_TOOLS, INTERP_LEADING_TARGET, MAX_PAYLOAD_NESTING, payloadNesting, MAX_INLINE_CALLS, INLINE_EXEC_FALLBACK, UNREADABLE_SOURCE, SCRIPT_RUNNERS, SCRIPT_RUNNER_VALUE_FLAGS, MAX_SCRIPT_OPERANDS, NET_BINARIES, VALUE_FLAGS, HOME_VARIABLES, assignmentTable, currentStmtOffset, PAYLOAD_BUDGET, payloadBudget, seenPayloads, UNANALYSABLE_NESTING, ASSIGNMENT_HEADS, AND_OP, OR_OP, AND_OR_OPS, MAX_CALL_DEPTH, MAX_CALL_WALKS, callDepth, callWalks, FS_OP_CACHE_MAX, fsOpCache, stripDotSlash, REDIR_TRUNCATE_OPS, REDIR_FILE_IN_OPS, REDIR_HEREDOC_OPS, FIND_OPTIONS, COPY_RULE_OF, isReaderWord, positionalAfter, NONE, UNKNOWN, FORBIDDEN_PATH_SEGMENTS, BASH_TOOL_NAMES, MCP_EXECUTORS, BUILTIN_FIELDS, ARGV_FIELDS, BARE_WORD, MAX_ARGV_CHARACTERS, syntax3, MAX_ALTERNATIVES, MAX_CALL_DEPTH2, MAX_CALL_WALKS2, POSITIONAL, MAX_DEPTH, MAX_PAYLOAD_DEPTH, unique, clone, SENDING_STDIN, DOWNLOAD_SHORT_VALUE, DOWNLOAD_LONG_VALUE, DOWNLOAD_OUTPUT_FLAGS, DOWNLOAD_DIR_FLAGS, base, quoteGlob, asWord, WRITES, APPENDS, READS, DUP_OUT, HERE_STRING, AND, OR, DEFAULT_OPS, exempt, RANK, SEQUENCE_OPS, BIP39_ENGLISH, BIP39_PUBLIC_VECTORS, indices, lengths, hash, MAX_MNEMONIC_HASHES, SECRET_VIEW_LIMITS, IBAN_LENGTH, IBAN_BBAN_SHAPE, B58, B58_INDEX, XPRV_VERSIONS, B62, CRC32_TABLE, GITHUB_TOKEN_RE, B64URL, B64URL_INDEX, CASK_TWO_ZERO_SUFFIX, CASK_FOUR_ZERO_SUFFIX, CF_ODD, CF_EVEN, SPANISH_LETTERS, HETU_CHARS, VERHOEFF_D, VERHOEFF_P, MAX, UNTRUSTED_TOOLS, INJECTION_SIGNALS, MENTION_QUOTE_RE, MENTION_WORD_RE, ASSIGNMENT_CONTEXT_RE, DLP_STOPWORDS, REFERENCE_VALUE_RE, IDENTIFIER_VALUE_RE, PATH_VALUE_RE, DOTTED_REFERENCE_RE, CONCATENATION_RE, EMAIL_VALUE_RE, FIXTURE_NAME_RE, DERIVATIVE_NAME_RE, QUERY_CREDENTIAL_VALUE_RE, OTP_SECRET_RE, OTP_DOC_SECRETS, ASSIGNED_SECRET_VALUE_RE, ASSIGNED_SECRET_NAME_RE, NAME_KEYWORD_RE, ARN_CONTEXT_RE, CIPHER_KEY_NAME_RE, CIPHER_NAME_PARTS, CIPHER_KEY_VALUE_RE, LARAVEL_KEY_VALUE_RE, SQL_PASSWORD_VALUE_RE, GRAFANA_KEY_VALUE_RE, BASIC_VALUE_RE, BASIC_PAIR_RE, BASIC_HEADER_RE, BASIC_HEADER_PAIR_RE, BASIC_PLACEHOLDER_RE, BASIC_TEMPLATE_MARKERS, DROPBOX_SECRET_RE, OTP_CAPTURE_RE, DB_URL_PASSWORD_RE, DLP_PATTERNS, DLP_PATTERNS_GLOBAL, SENSITIVE_PATH_PATTERNS, SENSITIVE_PATH_REGEXES, MAX_DEPTH2, MAX_STRING_BYTES, MAX_JSON_PARSE_BYTES, BATCH_SEPARATOR, ENCODED_RUN_RE, IMPERATIVE, SECRET_TARGET, GUARD, SIGNALS, DESTINATION_RE, REUSED_SIGNALS, NEVER_NEGATED, NEGATION_BEFORE, RDR_IN, COPY_VERBS2, LITERAL_VERBS, GIT_PRESCREEN_RE, MAX_PAYLOAD_DEPTH2, MAX_ALIAS_DEPTH, CACHE_MAX, cache, PAYLOAD_SHELLS, CONFIG_SCOPE_FLAGS, CONFIG_VALUE_FLAGS, GLOBAL_VALUE_OPTIONS, GLOBAL_FLAG_OPTIONS, MAX_LOOP_ITEMS, GitWalk, POSITIONAL2, FORCE_PUSH, DESTRUCTIVE, UNREADABLE, PUSH_LONG_VALUE, BRANCH_LONG_VALUE, TAG_LONG_VALUE, CLEAN_LONG_VALUE, HOOKS_BYPASS, NO_VERIFY_SUBS, HOOK_KILL_SWITCHES, COMMIT_LONG_VALUE, CHMOD_OPTION_RE, STAGE_ALL, ADD_LONG_VALUE, CHECK_ID, RULE_NAME, INERT_LINE_RE, CHECK_ID2, INSTRUCTION_NAMES, SETTINGS_RE, HOOK_WORDS_RE, SHELLS, NETCATS, NET_CLIENTS, SENDERS, NETCAT_EXEC_LONG, DECL_DUMPS, PROC_ENVIRON_RE, DEV_NET_RE, SOCAT_PROGRAM_RE, SOCAT_NET_RE, PRESCREEN_RE, MAX_PAYLOAD_DEPTH3, CACHE_MAX2, cache2, dupInOp, REVERSE_SHELL_DESCRIPTION, ENV_EXFIL_DESCRIPTION, DYNAMIC_WORD, MULTICALL, SHELL_VALUE_OPTIONS, INTERPRETERS, OutboundWalk, NPM_INSTALL_VERBS, NPM_EXEC_VERBS, PNPM_INSTALL_VERBS, YARN_INSTALL_VERBS, BUN_INSTALL_VERBS, DLX_VERBS, NON_REGISTRY_RE, NPM_NAME_RE, EXACT_SEMVER_RE, NPM_VALUE_FLAGS, PNPM_VALUE_FLAGS, YARN_VALUE_FLAGS, BUN_VALUE_FLAGS, PIP_VALUE_FLAGS, UV_VALUE_FLAGS, POETRY_VALUE_FLAGS, PIPENV_VALUE_FLAGS, PIPX_VALUE_FLAGS, PY_SPEC_RE, PY_EXACT_RE, EXACT_VERSION_RE, GEM_NAME_RE, GEM_VALUE_FLAGS, BUNDLE_VALUE_FLAGS, CRATE_NAME_RE, CARGO_ADD_VALUE_FLAGS, CARGO_INSTALL_VALUE_FLAGS, GO_VALUE_FLAGS, GO_PATH_RE, NUGET_NAME_RE, DOTNET_ADD_VALUE_FLAGS, DOTNET_TOOL_VALUE_FLAGS, NUGET_VALUE_FLAGS, MAVEN_COORD_RE, COMPOSER_NAME_RE, COMPOSER_VALUE_FLAGS, EDITOR_HEADS, EXTENSION_ID_RE, MANAGER_HEADS, SHELLS2, MAX_NESTING, SHELL_VALUE_FLAGS, NPM_FAMILY, PIP_FAMILY, NPM_FETCH_VERBS, PIP_FETCH_VERBS, NPM_FLAGS, PIP_FLAGS, NPM_VARS, PIP_VARS, PRESCREEN_RE2, PIP_ATTACHED_RE, MAX_PAYLOAD_DEPTH4, PUBLIC_REGISTRY_HOSTS, TUNING_FIELDS, MAP_GOVERNED, KNOB_GOVERNED, CONFIGURABLE_CHECK_IDS, DEFAULT_EGRESS_ALLOWLIST, PRIVATE_HOST_SUFFIXES, SOURCE_COMMANDS, SINK_COMMANDS, OBFUSCATORS, SENSITIVE_PATTERNS, FLAGS_WITH_VALUES, DESTINATION_ARGS, MCP_DESTINATION_KEYS, ARGUMENT_SCAN_LIMITS, RUN_CHAR, runChar, VERDICT_RANK, SQL_DML_KEYWORDS, MAX_DESTINATIONS, MAX_SCAN_CHARS, EMAIL_RE, URL_RE, IBAN_RE, RECIPIENT_KEYS, DESTRUCTIVE_VERB_RE, PII_EMAIL_RE, PII_SSN_RE, PII_PHONE_RE, PII_CC16_RE, PII_CC15_RE, PII_CC14_RE, PII_CC13_RE, PII_CC19_RE, CARD_PATTERNS, PII_ROUTING_RE, ROUTING_LABEL_RE, ROUTING_LABEL_WINDOW, NATIONAL_ID_SHAPES, NATIONAL_ID_LABEL_RE, NATIONAL_ID_LABEL_CS_RE, idLabelIn, NATIONAL_ID_LABEL_WINDOW, NATIONAL_ID_GUARD_RE, PII_IBAN_RE, REALTIME_PII_PATTERNS, MAX_PII_SCAN_BYTES, IBAN_DESTINATION_KEYS, WHOLE_IBAN_RE, JSON_ESCAPE_RE, JSON_ESCAPES, MASKED_KINDS, ENTRY_RE, IBAN_TEXT_RE, EMAIL_TEXT_RE, ACCOUNT_KEY_RE, ACCOUNT_VALUE_RE, MAX_MASK_DEPTH, EMPTY, CURL_SEND_FLAGS, WGET_SEND_FLAGS, IWR_SEND_FLAGS, WRITE_METHODS, GH_READ, GH_WRITE, GH_HOSTNAME_FLAGS, GH_REPO_VALUE_FLAGS, GH_API_VALUE_FLAGS, GIT_FETCH, PUBLISH, SHELLS3, OWN_HEADS, MAX_DEPTH3, CWD_CHANGERS, TERMINAL_ESCAPE_RE, LOOP_MAX_RECORDS, CANARY_MIN_LENGTH, MAX_TEXT, MAX_DEPTH4, MAX_JSON_PARSE, URL_DEPTH, B64_DEPTH, MIN_SEGMENT, SEPARATORS, stripSeparators, looksText, CANARY_DECODERS, VIEWS, LONG_OUTPUT_THRESHOLD_BYTES, CANONICAL_EXTRACTOR_VERSION;
9021
9071
  var init_dist = __esm({
9022
9072
  "packages/policy-engine/dist/index.mjs"() {
9023
9073
  "use strict";
@@ -11665,6 +11715,61 @@ var init_dist = __esm({
11665
11715
  return s.untrustedContent.afterExposure === "log-only" ? "log" : "review";
11666
11716
  }
11667
11717
  };
11718
+ ({ syntax } = mvdanSh);
11719
+ KINDS = {
11720
+ File: { nodes: ["Stmts"] },
11721
+ Stmt: { nodes: ["Cmd", "Redirs"], scalars: ["Negated", "Background", "Coprocess"] },
11722
+ CallExpr: { nodes: ["Assigns", "Args"] },
11723
+ Assign: { nodes: ["Name", "Value", "Index", "Array"], scalars: ["Append", "Naked"] },
11724
+ Word: { nodes: ["Parts"] },
11725
+ Lit: { scalars: ["Value"] },
11726
+ SglQuoted: { scalars: ["Value", "Dollar"] },
11727
+ DblQuoted: { nodes: ["Parts"], scalars: ["Dollar"] },
11728
+ ParamExp: {
11729
+ nodes: ["Param", "Index", "Slice", "Repl", "Exp"],
11730
+ scalars: ["Short", "Excl", "Length", "Width"]
11731
+ },
11732
+ CmdSubst: { nodes: ["Stmts"], scalars: ["Backquotes", "TempFile", "ReplyVar"] },
11733
+ ArithmExp: { nodes: ["X"], scalars: ["Bracket", "Unsigned"] },
11734
+ ArithmCmd: { nodes: ["X"], scalars: ["Unsigned"] },
11735
+ ProcSubst: { nodes: ["Stmts"], scalars: ["Op"] },
11736
+ ExtGlob: { nodes: ["Pattern"], scalars: ["Op"] },
11737
+ BraceExp: { nodes: ["Elems"], scalars: ["Sequence"] },
11738
+ // only with SplitBraces, unused here
11739
+ BinaryCmd: { nodes: ["X", "Y"], scalars: ["Op"] },
11740
+ BinaryArithm: { nodes: ["X", "Y"], scalars: ["Op"] },
11741
+ UnaryArithm: { nodes: ["X"], scalars: ["Op", "Post"] },
11742
+ ParenArithm: { nodes: ["X"] },
11743
+ BinaryTest: { nodes: ["X", "Y"], scalars: ["Op"] },
11744
+ UnaryTest: { nodes: ["X"], scalars: ["Op"] },
11745
+ ParenTest: { nodes: ["X"] },
11746
+ Redirect: { nodes: ["N", "Word", "Hdoc"], scalars: ["Op"] },
11747
+ Block: { nodes: ["Stmts"] },
11748
+ Subshell: { nodes: ["Stmts"] },
11749
+ IfClause: { nodes: ["Cond", "Then", "Else"] },
11750
+ WhileClause: { nodes: ["Cond", "Do"], scalars: ["Until"] },
11751
+ ForClause: { nodes: ["Loop", "Do"], scalars: ["Select"] },
11752
+ WordIter: { nodes: ["Name", "Items"] },
11753
+ CStyleLoop: { nodes: ["Init", "Cond", "Post"] },
11754
+ CaseClause: { nodes: ["Word", "Items"] },
11755
+ CaseItem: { nodes: ["Patterns", "Stmts"], scalars: ["Op"] },
11756
+ FuncDecl: { nodes: ["Name", "Body"], scalars: ["RsrvWord"] },
11757
+ DeclClause: { nodes: ["Variant", "Args"], notWalked: ["Variant"] },
11758
+ LetClause: { nodes: ["Exprs"] },
11759
+ TimeClause: { nodes: ["Stmt"], scalars: ["PosixFormat"] },
11760
+ CoprocClause: { nodes: ["Name", "Stmt"] },
11761
+ TestClause: { nodes: ["X"] },
11762
+ TestDecl: { nodes: ["Description", "Body"] },
11763
+ ArrayExpr: { nodes: ["Elems"] },
11764
+ ArrayElem: { nodes: ["Index", "Value"] },
11765
+ Comment: { scalars: ["Text"] }
11766
+ };
11767
+ STRUCTS = {
11768
+ "ParamExp.Slice": { nodes: ["Offset", "Length"], notWalked: ["Offset", "Length"] },
11769
+ "ParamExp.Repl": { nodes: ["Orig", "With"], scalars: ["All"] },
11770
+ "ParamExp.Exp": { nodes: ["Word"], scalars: ["Op"] }
11771
+ };
11772
+ unknownKinds = /* @__PURE__ */ new Set();
11668
11773
  INVISIBLE_RE = /[­͏؜᠎​-‏‪-‮⁠-⁤-︀-️]|[\u{E0000}-\u{E007F}]/gu;
11669
11774
  INVISIBLE_ONE = new RegExp(`^(?:${INVISIBLE_RE.source.split("|")[0]})$`, "u");
11670
11775
  HOMOGLYPHS = {
@@ -11950,8 +12055,8 @@ var init_dist = __esm({
11950
12055
  php: PHP
11951
12056
  };
11952
12057
  STRING_LITERAL = /(['"`])((?:\\.|(?!\1)[^\\\n]){1,4096})\1/g;
11953
- ({ syntax } = mvdanSh);
11954
- sharedParser = syntax.NewParser();
12058
+ ({ syntax: syntax2 } = mvdanSh2);
12059
+ sharedParser = syntax2.NewParser();
11955
12060
  MESSAGE_FLAGS = /* @__PURE__ */ new Set([
11956
12061
  "-m",
11957
12062
  "--message",
@@ -11985,7 +12090,7 @@ var init_dist = __esm({
11985
12090
  NORMALIZE_CACHE_MAX = 5e3;
11986
12091
  normalizeCache = /* @__PURE__ */ new Map();
11987
12092
  codeBodiesCache = /* @__PURE__ */ new Map();
11988
- AST_CACHE_MAX = 5e3;
12093
+ AST_CACHE_MAX = 256;
11989
12094
  astCache = /* @__PURE__ */ new Map();
11990
12095
  PARSE_FAIL = /* @__PURE__ */ Symbol("parse-fail");
11991
12096
  INTERPRETER_LINE = /^#![ \t]*[\w./+-]+(?:[ \t]+[\w./+=:-]+)*[ \t]*\r?(?=\n|$)/;
@@ -12970,7 +13075,7 @@ var init_dist = __esm({
12970
13075
  ARGV_FIELDS = ["args", "argv"];
12971
13076
  BARE_WORD = /^[A-Za-z0-9_./+:@%,-]+$/;
12972
13077
  MAX_ARGV_CHARACTERS = 262144;
12973
- ({ syntax: syntax2 } = mvdanSh2);
13078
+ ({ syntax: syntax3 } = mvdanSh3);
12974
13079
  MAX_ALTERNATIVES = 64;
12975
13080
  MAX_CALL_DEPTH2 = 4;
12976
13081
  MAX_CALL_WALKS2 = 256;
@@ -13062,7 +13167,6 @@ var init_dist = __esm({
13062
13167
  );
13063
13168
  exempt = (p) => SYSTEM_DIRS_EXEMPT.some((d) => within(p, d));
13064
13169
  RANK = { allow: 0, review: 1, block: 2 };
13065
- ({ syntax: syntax3 } = mvdanSh3);
13066
13170
  SEQUENCE_OPS = (() => {
13067
13171
  const ops = /* @__PURE__ */ new Set();
13068
13172
  for (const text of ["x && y", "x || y"]) {
@@ -16224,7 +16328,6 @@ zoo`.split("\n");
16224
16328
  );
16225
16329
  NEVER_NEGATED = /* @__PURE__ */ new Set([SIGNALS[1].any[0]]);
16226
16330
  NEGATION_BEFORE = /\b(never|do not|don'?t|must not|mustn'?t|should not|shouldn'?t|not allowed to|forbidden to|avoid|without|no|not)\b[^.!?;:\n]{0,24}$/i;
16227
- ({ syntax: syntax4 } = mvdanSh4);
16228
16331
  RDR_IN = (() => {
16229
16332
  try {
16230
16333
  return parseShared("x <y").Stmts[0].Redirs[0].Op;
@@ -16253,7 +16356,6 @@ zoo`.split("\n");
16253
16356
  "tar"
16254
16357
  ]);
16255
16358
  LITERAL_VERBS = /* @__PURE__ */ new Set(["echo", "printf", ":", "true", "touch", "sed"]);
16256
- ({ syntax: syntax5 } = mvdanSh5);
16257
16359
  GIT_PRESCREEN_RE = /git|husky/i;
16258
16360
  MAX_PAYLOAD_DEPTH2 = 8;
16259
16361
  MAX_ALIAS_DEPTH = 5;
@@ -16322,7 +16424,7 @@ zoo`.split("\n");
16322
16424
  visit(node, depth) {
16323
16425
  if (!node) return false;
16324
16426
  const n = node;
16325
- const type = syntax5.NodeType(n);
16427
+ const type = n.kind;
16326
16428
  if (type === "Stmt") {
16327
16429
  this.visitHeredocShell(n, depth);
16328
16430
  return true;
@@ -16330,7 +16432,7 @@ zoo`.split("\n");
16330
16432
  if (type === "ForClause") {
16331
16433
  const loop = n.Loop;
16332
16434
  const name = loop?.Name?.Value;
16333
- if (name && syntax5.NodeType(loop) === "WordIter") {
16435
+ if (name && loop.kind === "WordIter") {
16334
16436
  const items = (loop.Items || []).map((w) => resolveWordLiteral(w));
16335
16437
  const literal = items.length > 0 && items.every((v) => v !== null);
16336
16438
  this.loopVars.set(name, literal ? items.slice(0, MAX_LOOP_ITEMS) : null);
@@ -16397,7 +16499,7 @@ zoo`.split("\n");
16397
16499
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
16398
16500
  visitHeredocShell(stmt, depth) {
16399
16501
  const cmd = stmt.Cmd;
16400
- if (!cmd || syntax5.NodeType(cmd) !== "CallExpr" || depth >= MAX_PAYLOAD_DEPTH2) return;
16502
+ if (!cmd || cmd.kind !== "CallExpr" || depth >= MAX_PAYLOAD_DEPTH2) return;
16401
16503
  const redirs = stmt.Redirs || [];
16402
16504
  const hdoc = redirs.find((r) => r?.Hdoc && (r.N == null || r.N.Value === "0"));
16403
16505
  if (!hdoc) return;
@@ -16651,7 +16753,6 @@ zoo`.split("\n");
16651
16753
  ]);
16652
16754
  SETTINGS_RE = /\/(?:\.claude\/settings(?:\.local)?\.json|\.gemini\/settings\.json|\.codex\/hooks\.json|\.cursor\/hooks\.json)$/i;
16653
16755
  HOOK_WORDS_RE = /"hooks"|\b(PreToolUse|PostToolUse|UserPromptSubmit|Notification|Stop|SubagentStop|SessionStart|SessionEnd|PreCompact|BeforeTool|AfterTool)\b|"command"\s*:/;
16654
- ({ syntax: syntax6 } = mvdanSh6);
16655
16756
  SHELLS = /* @__PURE__ */ new Set([...SHELL_INTERPRETERS, "mksh", "ash", "csh", "tcsh"]);
16656
16757
  NETCATS = /* @__PURE__ */ new Set(["nc", "ncat", "netcat", "nc.traditional", "nc.openbsd"]);
16657
16758
  NET_CLIENTS = /* @__PURE__ */ new Set([...NETCATS, "telnet", "socat"]);
@@ -16709,7 +16810,7 @@ zoo`.split("\n");
16709
16810
  const f = parseShared(command);
16710
16811
  if (!f || typeof f !== "object" || !f.Stmts) return false;
16711
16812
  try {
16712
- syntax6.Walk(f, (node) => this.visit(node, depth));
16813
+ walk(f, (node) => this.visit(node, depth));
16713
16814
  } catch {
16714
16815
  return false;
16715
16816
  }
@@ -16748,7 +16849,7 @@ zoo`.split("\n");
16748
16849
  }
16749
16850
  visit(n, depth) {
16750
16851
  if (!n) return false;
16751
- const type = syntax6.NodeType(n);
16852
+ const type = n.kind;
16752
16853
  if (type === "Stmt") {
16753
16854
  this.visitStmt(n, depth);
16754
16855
  return true;
@@ -16768,7 +16869,7 @@ zoo`.split("\n");
16768
16869
  const redirs = redirectWords(stmt);
16769
16870
  const toSocket = redirs.some((w) => w !== null && DEV_NET_RE.test(w));
16770
16871
  if (!cmd) return;
16771
- const type = syntax6.NodeType(cmd);
16872
+ const type = cmd.kind;
16772
16873
  if (type !== "CallExpr" || wordsOf(cmd).length > 0) {
16773
16874
  if (this.readsNetFd(stmt) && runsCommandsIn(stmt)) {
16774
16875
  this.reverseShell("commands are read from a network socket opened with exec");
@@ -16854,7 +16955,7 @@ zoo`.split("\n");
16854
16955
  const stages = [];
16855
16956
  const flatten = (s) => {
16856
16957
  const c = s?.Cmd;
16857
- if (c && syntax6.NodeType(c) === "BinaryCmd" && isPipeOp(c.Op)) {
16958
+ if (c && c.kind === "BinaryCmd" && isPipeOp(c.Op)) {
16858
16959
  flatten(c.X);
16859
16960
  flatten(c.Y);
16860
16961
  } else stages.push(s);
@@ -16876,8 +16977,8 @@ zoo`.split("\n");
16876
16977
  sinks.set(i, socketHosts(st));
16877
16978
  }
16878
16979
  if (!c) return;
16879
- if (syntax6.NodeType(c) === "DeclClause" && declDumpsEnv(c) && dump < 0) dump = i;
16880
- if (syntax6.NodeType(c) !== "CallExpr") {
16980
+ if (c.kind === "DeclClause" && declDumpsEnv(c) && dump < 0) dump = i;
16981
+ if (c.kind !== "CallExpr") {
16881
16982
  if (runsCommandsIn(st)) shell = i;
16882
16983
  return;
16883
16984
  }
@@ -16918,10 +17019,10 @@ zoo`.split("\n");
16918
17019
  /** A word (or assignment value) whose text includes an env dump's output. */
16919
17020
  carriesEnv(word) {
16920
17021
  let hit = false;
16921
- syntax6.Walk(word, (node) => {
17022
+ walk(word, (node) => {
16922
17023
  if (hit || !node) return false;
16923
17024
  const n = node;
16924
- const t = syntax6.NodeType(n);
17025
+ const t = n.kind;
16925
17026
  if (t === "ParamExp" && n.Param?.Value && this.envVars.has(n.Param.Value)) {
16926
17027
  hit = true;
16927
17028
  return false;
@@ -16938,11 +17039,11 @@ zoo`.split("\n");
16938
17039
  stmtsDumpEnv(stmts) {
16939
17040
  let hit = false;
16940
17041
  for (const s of stmts) {
16941
- syntax6.Walk(s, (node) => {
17042
+ walk(s, (node) => {
16942
17043
  if (hit || !node) return false;
16943
17044
  const n = node;
16944
- const t = syntax6.NodeType(n);
16945
- if (t === "Stmt" && n.Cmd && syntax6.NodeType(n.Cmd) === "CallExpr") {
17045
+ const t = n.kind;
17046
+ if (t === "Stmt" && n.Cmd && n.Cmd.kind === "CallExpr") {
16946
17047
  const words = wordsOf(n.Cmd);
16947
17048
  if (words.length > 0 && dumpsEnv(words, n)) hit = true;
16948
17049
  }
@@ -16959,7 +17060,6 @@ zoo`.split("\n");
16959
17060
  this.run(payload, depth + 1);
16960
17061
  }
16961
17062
  };
16962
- ({ syntax: syntax7 } = mvdanSh7);
16963
17063
  NPM_INSTALL_VERBS = /* @__PURE__ */ new Set([
16964
17064
  "install",
16965
17065
  "i",
@@ -17341,7 +17441,6 @@ zoo`.split("\n");
17341
17441
  SHELLS2 = /* @__PURE__ */ new Set(["sh", "bash", "zsh", "dash", "ksh", "ash"]);
17342
17442
  MAX_NESTING = 3;
17343
17443
  SHELL_VALUE_FLAGS = /* @__PURE__ */ new Set(["--rcfile", "--init-file", "-O", "+O", "-o", "+o"]);
17344
- ({ syntax: syntax8 } = mvdanSh8);
17345
17444
  NPM_FAMILY = /* @__PURE__ */ new Set(["npm", "pnpm", "yarn", "bun", "npx", "pnpx", "bunx"]);
17346
17445
  PIP_FAMILY = /* @__PURE__ */ new Set(["pip", "pip3", "uv", "uvx", "pipx", "pipenv"]);
17347
17446
  NPM_FETCH_VERBS = /* @__PURE__ */ new Set([
@@ -17873,7 +17972,6 @@ zoo`.split("\n");
17873
17972
  ACCOUNT_KEY_RE = /("(?:iban|account|account_number|accountNumber)"\s*:\s*")([A-Za-z0-9 .-]{6,40})(")/g;
17874
17973
  ACCOUNT_VALUE_RE = /"([A-Z]{2}\d{2}[A-Z0-9]{11,30})"/g;
17875
17974
  MAX_MASK_DEPTH = 64;
17876
- ({ syntax: syntax9 } = mvdanSh9);
17877
17975
  EMPTY = {
17878
17976
  fetches: false,
17879
17977
  sends: false,
@@ -18520,18 +18618,18 @@ function statAndFirstLine(file2) {
18520
18618
  }
18521
18619
  function listCodexSessionFiles(base2 = codexSessionsDir()) {
18522
18620
  const files = [];
18523
- const walk2 = (dir2) => {
18621
+ const walk3 = (dir2) => {
18524
18622
  try {
18525
18623
  for (const entry of fs3.readdirSync(dir2, { withFileTypes: true })) {
18526
18624
  const file2 = path3.join(dir2, entry.name);
18527
- if (entry.isDirectory()) walk2(file2);
18625
+ if (entry.isDirectory()) walk3(file2);
18528
18626
  else if (entry.isFile() && entry.name.endsWith(".jsonl")) files.push(file2);
18529
18627
  }
18530
18628
  } catch {
18531
18629
  }
18532
18630
  };
18533
- walk2(base2);
18534
- if (path3.basename(base2) === "sessions") walk2(path3.join(path3.dirname(base2), "archived_sessions"));
18631
+ walk3(base2);
18632
+ if (path3.basename(base2) === "sessions") walk3(path3.join(path3.dirname(base2), "archived_sessions"));
18535
18633
  const sessions = /* @__PURE__ */ new Map();
18536
18634
  for (const file2 of files.sort()) {
18537
18635
  try {
@@ -24796,7 +24894,7 @@ import * as fs26 from "fs";
24796
24894
  import * as path27 from "path";
24797
24895
  function listSessionFiles(dir2, maxDepth = 6) {
24798
24896
  const out = [];
24799
- const walk2 = (d, rel, depth) => {
24897
+ const walk3 = (d, rel, depth) => {
24800
24898
  if (depth > maxDepth) return;
24801
24899
  let entries;
24802
24900
  try {
@@ -24806,11 +24904,11 @@ function listSessionFiles(dir2, maxDepth = 6) {
24806
24904
  }
24807
24905
  for (const e of entries) {
24808
24906
  const childRel = rel ? path27.join(rel, e.name) : e.name;
24809
- if (e.isDirectory()) walk2(path27.join(d, e.name), childRel, depth + 1);
24907
+ if (e.isDirectory()) walk3(path27.join(d, e.name), childRel, depth + 1);
24810
24908
  else if (e.name.endsWith(".jsonl")) out.push(childRel);
24811
24909
  }
24812
24910
  };
24813
- walk2(dir2, "", 0);
24911
+ walk3(dir2, "", 0);
24814
24912
  return out;
24815
24913
  }
24816
24914
  function sessionIdOf(relPath) {
@@ -29603,19 +29701,19 @@ function scrubDecoys(subject, values) {
29603
29701
  for (const v of values) if (v) out = out.split(v).join("[node9-decoy]");
29604
29702
  return out;
29605
29703
  };
29606
- const walk2 = (v, depth) => {
29704
+ const walk3 = (v, depth) => {
29607
29705
  if (depth > 6) return v;
29608
29706
  if (typeof v === "string") return scrubText(v);
29609
- if (Array.isArray(v)) return v.map((x) => walk2(x, depth + 1));
29707
+ if (Array.isArray(v)) return v.map((x) => walk3(x, depth + 1));
29610
29708
  if (v && typeof v === "object") {
29611
29709
  const out = {};
29612
29710
  for (const [k, child] of Object.entries(v))
29613
- out[k] = walk2(child, depth + 1);
29711
+ out[k] = walk3(child, depth + 1);
29614
29712
  return out;
29615
29713
  }
29616
29714
  return v;
29617
29715
  };
29618
- return walk2(subject, 0);
29716
+ return walk3(subject, 0);
29619
29717
  }
29620
29718
  function detectLoops(calls, project, sessionId, agent) {
29621
29719
  const counts = /* @__PURE__ */ new Map();