@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.
package/dist/index.js CHANGED
@@ -667,6 +667,62 @@ function resolveCheckMap(settings) {
667
667
  for (const c of CHECKS) out[c.id] = checkValue(settings, c.id);
668
668
  return out;
669
669
  }
670
+ function isGoNode(v) {
671
+ return v !== null && typeof v === "object" && typeof v.Pos === "function";
672
+ }
673
+ function toPlainTree(goNode) {
674
+ const kind = syntax.NodeType(goNode);
675
+ const out = { kind, pos: goNode.Pos().Offset(), end: goNode.End().Offset() };
676
+ const spec = KINDS[kind];
677
+ if (!spec) {
678
+ unknownKinds.add(kind);
679
+ return out;
680
+ }
681
+ convertFields(goNode, spec, out, kind);
682
+ return out;
683
+ }
684
+ function convertFields(goNode, spec, out, kind) {
685
+ for (const f of spec.scalars ?? []) out[f] = goNode[f];
686
+ for (const f of spec.nodes ?? []) {
687
+ const v = goNode[f];
688
+ if (v === void 0 || v === null) {
689
+ out[f] = null;
690
+ } else if (Array.isArray(v)) {
691
+ out[f] = v.map((c) => isGoNode(c) ? toPlainTree(c) : c);
692
+ } else if (isGoNode(v)) {
693
+ out[f] = toPlainTree(v);
694
+ } else if (typeof v === "object" && STRUCTS[`${kind}.${f}`]) {
695
+ const sub = { struct: `${kind}.${f}` };
696
+ convertFields(v, STRUCTS[`${kind}.${f}`], sub, `${kind}.${f}`);
697
+ out[f] = sub;
698
+ } else {
699
+ out[f] = v;
700
+ }
701
+ }
702
+ }
703
+ function childrenOf(n) {
704
+ const spec = n.kind ? KINDS[n.kind] : STRUCTS[n.struct];
705
+ if (!spec?.nodes) return [];
706
+ const out = [];
707
+ for (const f of spec.nodes) {
708
+ if (spec.notWalked?.includes(f)) continue;
709
+ const v = n[f];
710
+ if (!v) continue;
711
+ if (Array.isArray(v)) {
712
+ for (const c of v) if (c) out.push(c);
713
+ } else if (v.kind) {
714
+ out.push(v);
715
+ } else if (v.struct) {
716
+ out.push(...childrenOf(v));
717
+ }
718
+ }
719
+ return out;
720
+ }
721
+ function walk(root, fn) {
722
+ if (!root) return;
723
+ if (!fn(root)) return;
724
+ for (const c of childrenOf(root)) walk(c, fn);
725
+ }
670
726
  function isInvisibleChar(char) {
671
727
  return INVISIBLE_ONE.test(char);
672
728
  }
@@ -822,7 +878,7 @@ function judgeInlineCode(language, code, isProtected) {
822
878
  }
823
879
  function isCatHeredocOrLit(part) {
824
880
  if (!part) return false;
825
- const t = syntax.NodeType(part);
881
+ const t = part.kind;
826
882
  if (t === "Lit") return true;
827
883
  if (t !== "CmdSubst") return false;
828
884
  const stmts = part.Stmts || [];
@@ -832,9 +888,9 @@ function isCatHeredocOrLit(part) {
832
888
  const hasHeredoc = redirs.some((r) => r && r.Hdoc);
833
889
  if (!hasHeredoc) return false;
834
890
  const cmd = stmt.Cmd;
835
- if (!cmd || syntax.NodeType(cmd) !== "CallExpr") return false;
891
+ if (!cmd || cmd.kind !== "CallExpr") return false;
836
892
  const firstArg = cmd.Args?.[0]?.Parts || [];
837
- if (firstArg.length !== 1 || syntax.NodeType(firstArg[0]) !== "Lit") return false;
893
+ if (firstArg.length !== 1 || firstArg[0].kind !== "Lit") return false;
838
894
  return (firstArg[0].Value || "").toLowerCase() === "cat";
839
895
  }
840
896
  function parseShared(command) {
@@ -846,7 +902,7 @@ function parseShared(command) {
846
902
  }
847
903
  let parsed;
848
904
  try {
849
- parsed = sharedParser.Parse(command, "cmd");
905
+ parsed = toPlainTree(sharedParser.Parse(command, "cmd"));
850
906
  } catch {
851
907
  parsed = PARSE_FAIL;
852
908
  }
@@ -907,10 +963,10 @@ function fileAccessViewImpl(command) {
907
963
  const at = (byteOffset) => toCharIndex === null ? byteOffset : toCharIndex(byteOffset);
908
964
  const edits = [];
909
965
  try {
910
- syntax.Walk(f, (node) => {
966
+ walk(f, (node) => {
911
967
  if (!node) return false;
912
968
  const n = node;
913
- if (syntax.NodeType(n) !== "CallExpr") return true;
969
+ if (n.kind !== "CallExpr") return true;
914
970
  const args = n.Args || [];
915
971
  const words = args.map((a) => resolveWordLiteral(a));
916
972
  const head = unwrapCommandHead(words);
@@ -922,8 +978,8 @@ function fileAccessViewImpl(command) {
922
978
  if (!PROGRAM_DIR.test(word)) continue;
923
979
  const name = word.split(/[\\/]/).pop() ?? "";
924
980
  if (!name) continue;
925
- const s = at(args[i].Pos().Offset());
926
- const e = at(args[i].End().Offset());
981
+ const s = at(args[i].pos);
982
+ const e = at(args[i].end);
927
983
  if (s < 0 || e < 0) continue;
928
984
  edits.push([s, e, name]);
929
985
  }
@@ -951,10 +1007,10 @@ function literalPayloadsOf(command, depth) {
951
1007
  if (f === PARSE_FAIL) return [];
952
1008
  const out = [];
953
1009
  try {
954
- syntax.Walk(f, (node) => {
1010
+ walk(f, (node) => {
955
1011
  if (!node || out.length >= MAX_READING_PAYLOADS) return false;
956
1012
  const n = node;
957
- if (syntax.NodeType(n) !== "CallExpr") return true;
1013
+ if (n.kind !== "CallExpr") return true;
958
1014
  const words = (n.Args || []).map((a) => resolveWordLiteral(a));
959
1015
  if (words.length === 0) return true;
960
1016
  const payload = literalShellPayload(words, baseWord(words[0]));
@@ -974,23 +1030,23 @@ function foldCommandWords(reading) {
974
1030
  const at = (byteOffset) => toCharIndex === null ? byteOffset : toCharIndex(byteOffset);
975
1031
  const edits = [];
976
1032
  try {
977
- syntax.Walk(f, (node) => {
1033
+ walk(f, (node) => {
978
1034
  if (!node) return false;
979
1035
  const n = node;
980
- if (syntax.NodeType(n) !== "CallExpr") return true;
1036
+ if (n.kind !== "CallExpr") return true;
981
1037
  const args = n.Args || [];
982
1038
  const words = args.map((a) => resolveWordLiteral(a));
983
1039
  const folded = words.map((w) => w === null ? null : foldHomoglyphs(w));
984
1040
  const head = unwrapCommandHead(folded);
985
1041
  for (let i = 0; i <= head && i < args.length; i++) {
986
1042
  const parts = args[i].Parts || [];
987
- if (parts.length !== 1 || syntax.NodeType(parts[0]) !== "Lit") continue;
1043
+ if (parts.length !== 1 || parts[0].kind !== "Lit") continue;
988
1044
  const value = parts[0].Value ?? "";
989
1045
  const word = folded[i];
990
1046
  if (word === null || word === value || !/[^\x00-\x7f]/.test(value)) continue;
991
1047
  if (!/^[A-Za-z0-9._/-]+$/.test(word)) continue;
992
- const s = at(args[i].Pos().Offset());
993
- const e = at(args[i].End().Offset());
1048
+ const s = at(args[i].pos);
1049
+ const e = at(args[i].end);
994
1050
  if (s < 0 || e < 0) continue;
995
1051
  edits.push([s, e, word]);
996
1052
  }
@@ -1027,10 +1083,10 @@ function interpreterHeredocSpans(f, at) {
1027
1083
  const stmts = f?.Stmts || [];
1028
1084
  const candidates = [];
1029
1085
  let unsafe = false;
1030
- syntax.Walk(f, (node) => {
1086
+ walk(f, (node) => {
1031
1087
  if (!node || unsafe) return false;
1032
1088
  const n = node;
1033
- const t = syntax.NodeType(n);
1089
+ const t = n.kind;
1034
1090
  if (t === "FuncDecl") {
1035
1091
  unsafe = true;
1036
1092
  return false;
@@ -1050,7 +1106,7 @@ function interpreterHeredocSpans(f, at) {
1050
1106
  });
1051
1107
  if (unsafe) return [];
1052
1108
  for (const st of stmts) {
1053
- if (!st?.Cmd || syntax.NodeType(st.Cmd) !== "CallExpr") continue;
1109
+ if (!st?.Cmd || st.Cmd.kind !== "CallExpr") continue;
1054
1110
  const words = (st.Cmd.Args || []).map((a) => resolveWordLiteral(a));
1055
1111
  const name = (words[0] ?? "").toLowerCase();
1056
1112
  if (!STDIN_CODE_INTERPRETERS.test(name)) continue;
@@ -1065,8 +1121,8 @@ function interpreterHeredocSpans(f, at) {
1065
1121
  if (stdin.length !== 1 || others > 0) continue;
1066
1122
  const r = stdin[0];
1067
1123
  if (heredocText(r.Hdoc) === null) continue;
1068
- const hs = at(r.Hdoc.Pos().Offset());
1069
- const he = at(r.Hdoc.End().Offset());
1124
+ const hs = at(r.Hdoc.pos);
1125
+ const he = at(r.Hdoc.end);
1070
1126
  if (hs < 0 || he < 0 || he <= hs) continue;
1071
1127
  spans.push([hs, he]);
1072
1128
  }
@@ -1086,24 +1142,24 @@ function normalizeCommandForPolicyImpl(command, codeBodies) {
1086
1142
  strips.push([hs, he]);
1087
1143
  msgSpans.add(`${hs}:${he}`);
1088
1144
  }
1089
- syntax.Walk(f, (node) => {
1145
+ walk(f, (node) => {
1090
1146
  if (!node) return false;
1091
1147
  const n = node;
1092
- if (syntax.NodeType(n) !== "CallExpr") return true;
1148
+ if (n.kind !== "CallExpr") return true;
1093
1149
  const args = n.Args || [];
1094
1150
  for (let i = 0; i < args.length - 1; i++) {
1095
1151
  const argParts = args[i].Parts || [];
1096
- if (argParts.length !== 1 || syntax.NodeType(argParts[0]) !== "Lit") continue;
1152
+ if (argParts.length !== 1 || argParts[0].kind !== "Lit") continue;
1097
1153
  const flagVal = argParts[0].Value || "";
1098
1154
  if (!MESSAGE_FLAGS.has(flagVal.toLowerCase())) continue;
1099
1155
  const next = args[i + 1];
1100
1156
  const nextParts = next.Parts || [];
1101
1157
  if (nextParts.length !== 1) continue;
1102
1158
  const quotedNode = nextParts[0];
1103
- const nt = syntax.NodeType(quotedNode);
1159
+ const nt = quotedNode.kind;
1104
1160
  const markStrip = () => {
1105
- const s = at(next.Pos().Offset());
1106
- const e = at(next.End().Offset());
1161
+ const s = at(next.pos);
1162
+ const e = at(next.end);
1107
1163
  if (s < 0 || e < 0) return;
1108
1164
  strips.push([s, e]);
1109
1165
  msgSpans.add(`${s}:${e}`);
@@ -1112,7 +1168,7 @@ function normalizeCommandForPolicyImpl(command, codeBodies) {
1112
1168
  markStrip();
1113
1169
  } else if (nt === "DblQuoted") {
1114
1170
  const innerParts = quotedNode.Parts || [];
1115
- const allLit = innerParts.length === 0 || innerParts.every((p) => syntax.NodeType(p) === "Lit");
1171
+ const allLit = innerParts.length === 0 || innerParts.every((p) => p.kind === "Lit");
1116
1172
  if (allLit) {
1117
1173
  markStrip();
1118
1174
  } else if (innerParts.every((p) => isCatHeredocOrLit(p))) {
@@ -1121,8 +1177,8 @@ function normalizeCommandForPolicyImpl(command, codeBodies) {
1121
1177
  }
1122
1178
  }
1123
1179
  for (const arg of args) {
1124
- const s = at(arg.Pos().Offset());
1125
- const e = at(arg.End().Offset());
1180
+ const s = at(arg.pos);
1181
+ const e = at(arg.end);
1126
1182
  if (s < 0 || e < 0) continue;
1127
1183
  if (msgSpans.has(`${s}:${e}`)) continue;
1128
1184
  const resolved = resolveWordLiteral(arg);
@@ -1162,10 +1218,10 @@ function scanArgsForDynamicExec(args, startIdx) {
1162
1218
  let hasParamExp = false;
1163
1219
  let hasCurl = false;
1164
1220
  for (let i = startIdx; i < args.length; i++) {
1165
- syntax.Walk(args[i], (inner) => {
1221
+ walk(args[i], (inner) => {
1166
1222
  if (!inner) return false;
1167
1223
  const inn = inner;
1168
- const it = syntax.NodeType(inn);
1224
+ const it = inn.kind;
1169
1225
  if (it === "CmdSubst") hasCmdSubst = true;
1170
1226
  if (it === "ParamExp") hasParamExp = true;
1171
1227
  if (it === "Lit" && DOWNLOAD_CMDS.has(inn.Value?.toLowerCase())) hasCurl = true;
@@ -1178,15 +1234,16 @@ function scanArgsForDynamicExec(args, startIdx) {
1178
1234
  }
1179
1235
  function detectDangerousShellExec(command) {
1180
1236
  try {
1181
- const f = sharedParser.Parse(command, "cmd");
1237
+ const f = parseShared(command);
1238
+ if (f === PARSE_FAIL) return null;
1182
1239
  let result = null;
1183
1240
  const assigned = assignedNames(f);
1184
- syntax.Walk(f, (node) => {
1241
+ walk(f, (node) => {
1185
1242
  if (!node || result === "block") return false;
1186
1243
  const n = node;
1187
- if (syntax.NodeType(n) === "BinaryCmd" && n.Y && !listOps().has(n.Op)) {
1244
+ if (n.kind === "BinaryCmd" && n.Y && !listOps().has(n.Op)) {
1188
1245
  const call = n.Y.Cmd;
1189
- if (call && syntax.NodeType(call) === "CallExpr") {
1246
+ if (call && call.kind === "CallExpr") {
1190
1247
  const words = (call.Args || []).map((a) => resolveWordLiteral(a));
1191
1248
  const head2 = unwrapCommandHead(words);
1192
1249
  const name = (words[head2] ?? "").split("/").pop() ?? "";
@@ -1199,7 +1256,7 @@ function detectDangerousShellExec(command) {
1199
1256
  result = "review";
1200
1257
  }
1201
1258
  }
1202
- if (syntax.NodeType(n) !== "CallExpr") return true;
1259
+ if (n.kind !== "CallExpr") return true;
1203
1260
  const args = n.Args || [];
1204
1261
  if (args.length === 0) return true;
1205
1262
  const headWords = args.map(
@@ -1210,7 +1267,7 @@ function detectDangerousShellExec(command) {
1210
1267
  if (!lookup && (opaqueExecutable(args[0], assigned) || opaqueExecutable(args[head], assigned)))
1211
1268
  result = "review";
1212
1269
  const firstParts = args[0].Parts || [];
1213
- if (firstParts.length !== 1 || syntax.NodeType(firstParts[0]) !== "Lit") return true;
1270
+ if (firstParts.length !== 1 || firstParts[0].kind !== "Lit") return true;
1214
1271
  const cmdName = firstParts[0].Value?.toLowerCase() ?? "";
1215
1272
  if (cmdName === "eval") {
1216
1273
  const v = scanArgsForDynamicExec(args, 1);
@@ -1218,7 +1275,7 @@ function detectDangerousShellExec(command) {
1218
1275
  } else if (SHELL_INTERPRETERS.has(cmdName)) {
1219
1276
  for (let i = 1; i < args.length - 1; i++) {
1220
1277
  const flagParts = args[i].Parts || [];
1221
- if (flagParts.length !== 1 || syntax.NodeType(flagParts[0]) !== "Lit" || flagParts[0].Value !== "-c")
1278
+ if (flagParts.length !== 1 || flagParts[0].kind !== "Lit" || flagParts[0].Value !== "-c")
1222
1279
  continue;
1223
1280
  const v = scanArgsForDynamicExec(args, i + 1);
1224
1281
  if (v === "block" || v === "review" && result === null) result = v;
@@ -1242,8 +1299,7 @@ function isDefaultExpansion(part) {
1242
1299
  }
1243
1300
  function lookupSubstitution(part) {
1244
1301
  const stmts = part.Stmts ?? [];
1245
- if (stmts.length !== 1 || !stmts[0].Cmd || syntax.NodeType(stmts[0].Cmd) !== "CallExpr")
1246
- return null;
1302
+ if (stmts.length !== 1 || !stmts[0].Cmd || stmts[0].Cmd.kind !== "CallExpr") return null;
1247
1303
  const words = (stmts[0].Cmd.Args ?? []).map((a) => resolveWordLiteral(a));
1248
1304
  if (words.some((w) => w === null)) return null;
1249
1305
  if (words.length === 2 && words[0] === "which") return words[1];
@@ -1253,9 +1309,9 @@ function lookupSubstitution(part) {
1253
1309
  }
1254
1310
  function assignedNames(f) {
1255
1311
  const names = /* @__PURE__ */ new Set();
1256
- syntax.Walk(f, (node) => {
1312
+ walk(f, (node) => {
1257
1313
  if (!node) return false;
1258
- const kind = syntax.NodeType(node);
1314
+ const kind = node.kind;
1259
1315
  if (kind === "Assign" && node.Name?.Value) names.add(node.Name.Value);
1260
1316
  if (kind === "ForClause" && node.Loop?.Name?.Value) names.add(node.Loop.Name.Value);
1261
1317
  if (kind === "CallExpr") {
@@ -1270,7 +1326,7 @@ function assignedNames(f) {
1270
1326
  }
1271
1327
  function executableParts(word, assigned, quoted = false) {
1272
1328
  return (word?.Parts ?? []).flatMap((part) => {
1273
- const kind = syntax.NodeType(part);
1329
+ const kind = part.kind;
1274
1330
  if (kind === "DblQuoted") return executableParts(part, assigned, true);
1275
1331
  if (kind === "Lit") return [{ kind: "Lit", value: part.Value ?? "", quoted }];
1276
1332
  if (kind === "SglQuoted")
@@ -1338,10 +1394,10 @@ function chmodHasOpenPermMode(command) {
1338
1394
  if (f === PARSE_FAIL) return false;
1339
1395
  let found = false;
1340
1396
  try {
1341
- syntax.Walk(f, (node) => {
1397
+ walk(f, (node) => {
1342
1398
  if (!node || found) return false;
1343
1399
  const n = node;
1344
- if (syntax.NodeType(n) !== "CallExpr") return true;
1400
+ if (n.kind !== "CallExpr") return true;
1345
1401
  const words = (n.Args || []).map((a) => resolveWordLiteral(a));
1346
1402
  if (words.length === 0) return true;
1347
1403
  const name = (words[0] ?? "").toLowerCase();
@@ -1394,11 +1450,11 @@ function redirStdinOps() {
1394
1450
  }
1395
1451
  function deriveBinaryOp(sample) {
1396
1452
  try {
1397
- const f = sharedParser.Parse(sample, "cmd");
1453
+ const f = toPlainTree(sharedParser.Parse(sample, "cmd"));
1398
1454
  let op = -1;
1399
- syntax.Walk(f, (node) => {
1455
+ walk(f, (node) => {
1400
1456
  const n = node;
1401
- if (n && syntax.NodeType(n) === "BinaryCmd" && op < 0) op = n.Op;
1457
+ if (n && n.kind === "BinaryCmd" && op < 0) op = n.Op;
1402
1458
  return true;
1403
1459
  });
1404
1460
  return op;
@@ -1472,7 +1528,7 @@ function heredocText(word) {
1472
1528
  const parts = word?.Parts ?? [];
1473
1529
  let out = "";
1474
1530
  for (const p of parts) {
1475
- if (syntax.NodeType(p) !== "Lit") return null;
1531
+ if (p.kind !== "Lit") return null;
1476
1532
  out += p.Value ?? "";
1477
1533
  }
1478
1534
  return out;
@@ -1508,7 +1564,7 @@ function attachedCode(interp, flag) {
1508
1564
  }
1509
1565
  function inlineExecCall(stmt, pipeFed) {
1510
1566
  const cmd = stmt?.Cmd;
1511
- if (!cmd || syntax.NodeType(cmd) !== "CallExpr") return null;
1567
+ if (!cmd || cmd.kind !== "CallExpr") return null;
1512
1568
  const words = (cmd.Args || []).map((a) => resolveWordLiteral(a));
1513
1569
  if (words.length === 0) return null;
1514
1570
  const headIdx = unwrapCommandHead(words);
@@ -1589,10 +1645,10 @@ function shellPayloadNeedsReview(payload) {
1589
1645
  let review = false;
1590
1646
  payloadNesting++;
1591
1647
  try {
1592
- syntax.Walk(f, (node) => {
1648
+ walk(f, (node) => {
1593
1649
  if (!node || review) return false;
1594
1650
  const n = node;
1595
- if (syntax.NodeType(n) !== "CallExpr") return true;
1651
+ if (n.kind !== "CallExpr") return true;
1596
1652
  const words = (n.Args || []).map((a) => resolveWordLiteral(a));
1597
1653
  if (words.length === 0) return true;
1598
1654
  const h = unwrapCommandHead(words);
@@ -1626,10 +1682,10 @@ function inlineExecCalls(command) {
1626
1682
  if (f === PARSE_FAIL) return PARSE_FAIL;
1627
1683
  const calls = [];
1628
1684
  try {
1629
- syntax.Walk(f, (node) => {
1685
+ walk(f, (node) => {
1630
1686
  if (!node || calls.length >= MAX_INLINE_CALLS) return false;
1631
1687
  const n = node;
1632
- const t = syntax.NodeType(n);
1688
+ const t = n.kind;
1633
1689
  if (t === "BinaryCmd" && n.Y && !listOps().has(n.Op)) {
1634
1690
  const call = inlineExecCall(n.Y, true);
1635
1691
  if (call) calls.push(call);
@@ -1764,7 +1820,7 @@ function shellScriptOperands(command) {
1764
1820
  walkWithCalls(f, (node) => {
1765
1821
  if (!node) return false;
1766
1822
  const n = node;
1767
- if (syntax.NodeType(n) !== "CallExpr") return true;
1823
+ if (n.kind !== "CallExpr") return true;
1768
1824
  const callArgs = n.Args || [];
1769
1825
  if (callArgs.length === 0) return true;
1770
1826
  const words = callArgs.map((a) => resolveWordLiteral(a));
@@ -1800,7 +1856,7 @@ function shellScriptOperands(command) {
1800
1856
  }
1801
1857
  function windowsDrivePathSpelling(word) {
1802
1858
  const parts = word?.Parts || [];
1803
- if (parts.length === 0 || !parts.every((p) => syntax.NodeType(p) === "Lit")) return null;
1859
+ if (parts.length === 0 || !parts.every((p) => p.kind === "Lit")) return null;
1804
1860
  const raw = parts.map((p) => p.Value ?? "").join("");
1805
1861
  return /^[A-Za-z]:\\[^\s'"$`]*$/.test(raw) ? raw : null;
1806
1862
  }
@@ -1838,15 +1894,15 @@ function recordTopLevelAssignments(f) {
1838
1894
  }
1839
1895
  function probeBinOp(src) {
1840
1896
  try {
1841
- const cmd = syntax.NewParser().Parse(src, "probe")?.Stmts?.[0]?.Cmd;
1842
- if (cmd && syntax.NodeType(cmd) === "BinaryCmd") return cmd.Op;
1897
+ const cmd = toPlainTree(syntax2.NewParser().Parse(src, "probe"))?.Stmts?.[0]?.Cmd;
1898
+ if (cmd && cmd.kind === "BinaryCmd") return cmd.Op;
1843
1899
  } catch {
1844
1900
  }
1845
1901
  return null;
1846
1902
  }
1847
1903
  function recordTopLevelStmt(stmt) {
1848
1904
  if (!stmt || !stmt.Cmd) return false;
1849
- const t = syntax.NodeType(stmt.Cmd);
1905
+ const t = stmt.Cmd.kind;
1850
1906
  if (t === "BinaryCmd") {
1851
1907
  if (!AND_OR_OPS.has(stmt.Cmd.Op)) return false;
1852
1908
  if (!recordTopLevelStmt(stmt.Cmd.X)) return false;
@@ -1856,7 +1912,7 @@ function recordTopLevelStmt(stmt) {
1856
1912
  if (t !== "CallExpr" && t !== "DeclClause") return false;
1857
1913
  let at = 0;
1858
1914
  try {
1859
- at = stmt.Pos().Offset();
1915
+ at = stmt.pos;
1860
1916
  } catch {
1861
1917
  at = 0;
1862
1918
  }
@@ -1867,14 +1923,14 @@ function recordTopLevelStmt(stmt) {
1867
1923
  }
1868
1924
  function recordAssignments(n, at) {
1869
1925
  if (!assignmentTable) return;
1870
- const t = syntax.NodeType(n);
1926
+ const t = n.kind;
1871
1927
  let assigns = [];
1872
1928
  if (t === "CallExpr") {
1873
1929
  if ((n.Args || []).length > 0) return;
1874
1930
  assigns = n.Assigns || [];
1875
1931
  } else if (t === "DeclClause") {
1876
1932
  if (!ASSIGNMENT_HEADS.has(n.Variant?.Value ?? "")) return;
1877
- assigns = (n.Args || []).filter((a) => syntax.NodeType(a) === "Assign");
1933
+ assigns = (n.Args || []).filter((a) => a.kind === "Assign");
1878
1934
  } else return;
1879
1935
  for (const a of assigns) {
1880
1936
  const name = a?.Name?.Value;
@@ -1883,13 +1939,13 @@ function recordAssignments(n, at) {
1883
1939
  }
1884
1940
  }
1885
1941
  function resolveTrivialSubst(part) {
1886
- if (syntax.NodeType(part) !== "CmdSubst") return void 0;
1942
+ if (part.kind !== "CmdSubst") return void 0;
1887
1943
  const stmts = part.Stmts || [];
1888
1944
  if (stmts.length !== 1) return void 0;
1889
1945
  const st = stmts[0];
1890
1946
  if ((st.Redirs || []).length > 0 || st.Negated || st.Background) return void 0;
1891
1947
  const cmd = st.Cmd;
1892
- if (!cmd || syntax.NodeType(cmd) !== "CallExpr") return void 0;
1948
+ if (!cmd || cmd.kind !== "CallExpr") return void 0;
1893
1949
  if ((cmd.Assigns || []).length > 0) return void 0;
1894
1950
  const words = (cmd.Args || []).map((a) => resolveWordLiteral(a));
1895
1951
  if (words.length === 0 || words.some((w) => w === null)) return void 0;
@@ -1914,7 +1970,7 @@ function recordedExpansion(name) {
1914
1970
  return rec.value;
1915
1971
  }
1916
1972
  function isPlainParam(p) {
1917
- if (syntax.NodeType(p) !== "ParamExp") return false;
1973
+ if (p.kind !== "ParamExp") return false;
1918
1974
  return !(p.Excl || p.Length || p.Width || p.Index || p.Slice || p.Repl || p.Exp);
1919
1975
  }
1920
1976
  function expandPlainParam(p) {
@@ -1926,9 +1982,9 @@ function expandPlainParam(p) {
1926
1982
  }
1927
1983
  function functionBodies(f) {
1928
1984
  const out = /* @__PURE__ */ new Map();
1929
- syntax.Walk(f, (node) => {
1985
+ walk(f, (node) => {
1930
1986
  const n = node;
1931
- if (n && syntax.NodeType(n) === "FuncDecl" && n.Name?.Value && n.Body) {
1987
+ if (n && n.kind === "FuncDecl" && n.Name?.Value && n.Body) {
1932
1988
  const list = out.get(n.Name.Value) ?? [];
1933
1989
  list.push(n.Body);
1934
1990
  out.set(n.Name.Value, list);
@@ -1939,10 +1995,10 @@ function functionBodies(f) {
1939
1995
  }
1940
1996
  function rebindsPositionals(body) {
1941
1997
  let found = false;
1942
- syntax.Walk(body, (node) => {
1998
+ walk(body, (node) => {
1943
1999
  const n = node;
1944
2000
  if (found || !n) return false;
1945
- if (syntax.NodeType(n) === "CallExpr") {
2001
+ if (n.kind === "CallExpr") {
1946
2002
  const words = (n.Args || []).map((a) => resolveWordLiteral(a));
1947
2003
  if (words[0] === "shift") found = true;
1948
2004
  else if (words[0] === "set" && words.slice(1).some((w) => w === null || w === "--" || !/^[-+]/.test(w)))
@@ -1962,7 +2018,7 @@ function tableBindings() {
1962
2018
  function walkWithCalls(f, visit) {
1963
2019
  const bodies = functionBodies(f);
1964
2020
  if (bodies.size === 0) {
1965
- syntax.Walk(f, visit);
2021
+ walk(f, visit);
1966
2022
  return;
1967
2023
  }
1968
2024
  const seenCalls = /* @__PURE__ */ new Set();
@@ -1996,8 +2052,8 @@ function walkWithCalls(f, visit) {
1996
2052
  currentStmtOffset = Number.MAX_SAFE_INTEGER;
1997
2053
  callDepth++;
1998
2054
  try {
1999
- if (body.Cmd && syntax.NodeType(body.Cmd) === "Block") recordTopLevelAssignments(body.Cmd);
2000
- syntax.Walk(body, step);
2055
+ if (body.Cmd && body.Cmd.kind === "Block") recordTopLevelAssignments(body.Cmd);
2056
+ walk(body, step);
2001
2057
  } finally {
2002
2058
  callDepth--;
2003
2059
  assignmentTable = outerTable;
@@ -2008,10 +2064,10 @@ function walkWithCalls(f, visit) {
2008
2064
  const step = (node) => {
2009
2065
  if (!node) return false;
2010
2066
  const go = visit(node);
2011
- if (go !== false && syntax.NodeType(node) === "CallExpr") inline(node);
2067
+ if (go !== false && node.kind === "CallExpr") inline(node);
2012
2068
  return go;
2013
2069
  };
2014
- syntax.Walk(f, step);
2070
+ walk(f, step);
2015
2071
  }
2016
2072
  function withAssignments(f, body) {
2017
2073
  const outerTable = assignmentTable;
@@ -2036,7 +2092,7 @@ function walkCommandScope(command, visit) {
2036
2092
  if (f === PARSE_FAIL) return "parse-fail";
2037
2093
  withAssignments(f, () => {
2038
2094
  walkWithCalls(f, (node) => {
2039
- if (node && syntax.NodeType(node) === "Stmt") trackStatement(node);
2095
+ if (node && node.kind === "Stmt") trackStatement(node);
2040
2096
  return visit(node);
2041
2097
  });
2042
2098
  });
@@ -2044,7 +2100,7 @@ function walkCommandScope(command, visit) {
2044
2100
  }
2045
2101
  function trackStatement(n) {
2046
2102
  try {
2047
- currentStmtOffset = n.Pos().Offset();
2103
+ currentStmtOffset = n.pos;
2048
2104
  } catch {
2049
2105
  currentStmtOffset = Number.MAX_SAFE_INTEGER;
2050
2106
  }
@@ -2060,11 +2116,11 @@ function resolveWordLiteral(w) {
2060
2116
  return s;
2061
2117
  }
2062
2118
  function resolveWordPrefix(w) {
2063
- const walk2 = (parts) => {
2119
+ const walk3 = (parts) => {
2064
2120
  let s = "";
2065
2121
  for (const p of parts) {
2066
2122
  if (p && typeof p === "object" && Array.isArray(p.Parts) && p.Dollar !== void 0) {
2067
- const inner = walk2(p.Parts);
2123
+ const inner = walk3(p.Parts);
2068
2124
  s += inner.prefix;
2069
2125
  if (inner.dynamic) return { prefix: s, dynamic: true };
2070
2126
  continue;
@@ -2075,10 +2131,10 @@ function resolveWordPrefix(w) {
2075
2131
  }
2076
2132
  return { prefix: s, dynamic: false };
2077
2133
  };
2078
- return walk2(w?.Parts || []);
2134
+ return walk3(w?.Parts || []);
2079
2135
  }
2080
2136
  function resolvePart(p, inQuotes) {
2081
- const t = syntax.NodeType(p);
2137
+ const t = p.kind;
2082
2138
  if (t === "Lit") {
2083
2139
  const raw = p.Value ?? "";
2084
2140
  if (!inQuotes) return raw.replace(/\\(.)/g, "$1");
@@ -2174,7 +2230,7 @@ function extractShellDestinations(command) {
2174
2230
  () => walkWithCalls(f, (node) => {
2175
2231
  if (!node) return false;
2176
2232
  const n = node;
2177
- if (syntax.NodeType(n) === "Stmt") {
2233
+ if (n.kind === "Stmt") {
2178
2234
  trackStatement(n);
2179
2235
  for (const raw of redirectWords(n)) {
2180
2236
  const host2 = devNetRedirectHost(raw);
@@ -2186,7 +2242,7 @@ function extractShellDestinations(command) {
2186
2242
  out.push({ host: host2, binary, raw });
2187
2243
  }
2188
2244
  }
2189
- if (syntax.NodeType(n) !== "CallExpr") return true;
2245
+ if (n.kind !== "CallExpr") return true;
2190
2246
  const callArgs = n.Args || [];
2191
2247
  if (callArgs.length === 0) return true;
2192
2248
  const words = callArgs.map((a) => resolveWordLiteral(a));
@@ -2221,7 +2277,7 @@ function extractShellDestTokens(command) {
2221
2277
  () => walkWithCalls(f, (node) => {
2222
2278
  if (!node) return false;
2223
2279
  const n = node;
2224
- if (syntax.NodeType(n) === "Stmt") {
2280
+ if (n.kind === "Stmt") {
2225
2281
  trackStatement(n);
2226
2282
  for (const raw of redirectWords(n)) {
2227
2283
  const host2 = devNetRedirectHost(raw);
@@ -2233,7 +2289,7 @@ function extractShellDestTokens(command) {
2233
2289
  out.push({ token: host2, binary });
2234
2290
  }
2235
2291
  }
2236
- if (syntax.NodeType(n) !== "CallExpr") return true;
2292
+ if (n.kind !== "CallExpr") return true;
2237
2293
  const callArgs = n.Args || [];
2238
2294
  if (callArgs.length === 0) return true;
2239
2295
  const words = callArgs.map((a) => resolveWordLiteral(a));
@@ -2301,11 +2357,11 @@ function isWaivableCleanupTarget(p) {
2301
2357
  }
2302
2358
  function deriveRedirOp(sample) {
2303
2359
  try {
2304
- const f = sharedParser.Parse(sample, "cmd");
2360
+ const f = toPlainTree(sharedParser.Parse(sample, "cmd"));
2305
2361
  let op = -1;
2306
- syntax.Walk(f, (node) => {
2362
+ walk(f, (node) => {
2307
2363
  const n = node;
2308
- if (n && syntax.NodeType(n) === "Redirect" && op < 0) op = n.Op;
2364
+ if (n && n.kind === "Redirect" && op < 0) op = n.Op;
2309
2365
  return true;
2310
2366
  });
2311
2367
  return op;
@@ -2318,7 +2374,7 @@ function collectSameCommandCreations(f) {
2318
2374
  try {
2319
2375
  const stmts = Array.isArray(f?.Stmts) ? f.Stmts : [];
2320
2376
  for (const stmt of stmts) {
2321
- if (!stmt || !stmt.Cmd || syntax.NodeType(stmt.Cmd) !== "CallExpr") continue;
2377
+ if (!stmt || !stmt.Cmd || stmt.Cmd.kind !== "CallExpr") continue;
2322
2378
  const redirs = stmt.Redirs || [];
2323
2379
  if (!redirs.some((r) => r && REDIR_HEREDOC_OPS.has(r.Op))) continue;
2324
2380
  for (const r of redirs) {
@@ -2342,10 +2398,10 @@ function isRmCreatedInCommandCleanup(command) {
2342
2398
  let sawRm = false;
2343
2399
  let ok = true;
2344
2400
  try {
2345
- syntax.Walk(f, (node) => {
2401
+ walk(f, (node) => {
2346
2402
  if (!node || !ok) return false;
2347
2403
  const n = node;
2348
- if (syntax.NodeType(n) !== "CallExpr") return true;
2404
+ if (n.kind !== "CallExpr") return true;
2349
2405
  const args = n.Args || [];
2350
2406
  const name = (resolveWordLiteral(args[0]) ?? "").toLowerCase();
2351
2407
  if (name !== "rm") return true;
@@ -2395,10 +2451,10 @@ function analyzeFsOperationImpl(command, depth = 0) {
2395
2451
  walkWithCalls(f, (node) => {
2396
2452
  if (!node || result?.verdict === "block") return false;
2397
2453
  const n = node;
2398
- const nodeType = syntax.NodeType(n);
2454
+ const nodeType = n.kind;
2399
2455
  if (nodeType === "Stmt") {
2400
2456
  try {
2401
- currentStmtOffset = n.Pos().Offset();
2457
+ currentStmtOffset = n.pos;
2402
2458
  } catch {
2403
2459
  currentStmtOffset = Number.MAX_SAFE_INTEGER;
2404
2460
  }
@@ -2911,11 +2967,12 @@ function analyzeShellCommand(command) {
2911
2967
  if (lower2.startsWith("-")) allTokens.push(lower2.replace(/^-+/, ""));
2912
2968
  };
2913
2969
  try {
2914
- const f = sharedParser.Parse(command, "cmd");
2915
- syntax.Walk(f, (node) => {
2970
+ const f = parseShared(command);
2971
+ if (f === PARSE_FAIL) throw new Error("parse failed");
2972
+ walk(f, (node) => {
2916
2973
  if (!node) return false;
2917
2974
  const n = node;
2918
- if (syntax.NodeType(n) !== "CallExpr") return true;
2975
+ if (n.kind !== "CallExpr") return true;
2919
2976
  const wordValues2 = (n.Args || []).map((arg) => {
2920
2977
  return (arg.Parts || []).map((p) => (p.Value ?? "").replace(/\\(.)/g, "$1")).join("");
2921
2978
  }).filter((s) => s.length > 0);
@@ -3187,7 +3244,7 @@ function runnablePrefix(command) {
3187
3244
  let text = command;
3188
3245
  for (let attempt = 0; attempt < 32; attempt++) {
3189
3246
  try {
3190
- return syntax2.NewParser().Parse(text, "");
3247
+ return toPlainTree(syntax3.NewParser().Parse(text, ""));
3191
3248
  } catch (error) {
3192
3249
  const message = String(typeof error?.Error === "function" ? error.Error() : error?.message);
3193
3250
  const line = Number(/^(\d+):/.exec(message)?.[1]);
@@ -3255,7 +3312,7 @@ function wordValues(word, state) {
3255
3312
  out2 = next.slice(0, MAX_ALTERNATIVES);
3256
3313
  };
3257
3314
  for (const node of nodes) {
3258
- const kind = syntax2.NodeType(node);
3315
+ const kind = node.kind;
3259
3316
  let pieces;
3260
3317
  if (kind === "ParamExp") pieces = paramValues(node, quoted);
3261
3318
  else if (kind === "DblQuoted") {
@@ -3323,9 +3380,9 @@ function collectShellFileAccesses(command, context = {}) {
3323
3380
  }
3324
3381
  function substitutions(word, state, depth) {
3325
3382
  if (!word) return;
3326
- syntax2.Walk(word, (node) => {
3383
+ walk(word, (node) => {
3327
3384
  if (!node) return false;
3328
- if (["CmdSubst", "ProcSubst"].includes(syntax2.NodeType(node))) {
3385
+ if (["CmdSubst", "ProcSubst"].includes(node.kind)) {
3329
3386
  statements(node.Stmts ?? [], clone(state), depth + 1);
3330
3387
  return false;
3331
3388
  }
@@ -3749,7 +3806,7 @@ function collectShellFileAccesses(command, context = {}) {
3749
3806
  }
3750
3807
  function readsScriptFromStdin(stmt) {
3751
3808
  const cmd = stmt?.Cmd;
3752
- if (!cmd || syntax2.NodeType(cmd) !== "CallExpr") return false;
3809
+ if (!cmd || cmd.kind !== "CallExpr") return false;
3753
3810
  const words = (cmd.Args ?? []).map((a) => resolveWordLiteral(a));
3754
3811
  const head = unwrapCommandHead(words);
3755
3812
  return SHELL_INTERPRETERS.has(base(words[head])) && shellConsumesPipe(words.slice(head + 1));
@@ -3763,7 +3820,7 @@ function collectShellFileAccesses(command, context = {}) {
3763
3820
  }
3764
3821
  function producedText(stmt) {
3765
3822
  const cmd = stmt?.Cmd;
3766
- if (!cmd || syntax2.NodeType(cmd) !== "CallExpr") return null;
3823
+ if (!cmd || cmd.kind !== "CallExpr") return null;
3767
3824
  const words = (cmd.Args ?? []).map((a) => resolveWordLiteral(a));
3768
3825
  if (words.some((w) => w === null)) return null;
3769
3826
  const head = unwrapCommandHead(words);
@@ -3782,7 +3839,7 @@ function collectShellFileAccesses(command, context = {}) {
3782
3839
  if (!stmt || depth > MAX_DEPTH) return;
3783
3840
  state.onSuccess = void 0;
3784
3841
  if (stmt.Background) state = clone(state);
3785
- const headWord = stmt.Cmd && syntax2.NodeType(stmt.Cmd) === "CallExpr" ? base(resolveWordLiteral(stmt.Cmd.Args?.[0])) : "";
3842
+ const headWord = stmt.Cmd && stmt.Cmd.kind === "CallExpr" ? base(resolveWordLiteral(stmt.Cmd.Args?.[0])) : "";
3786
3843
  const sends = SENDING_STDIN.has(headWord);
3787
3844
  for (const redir of stmt.Redirs ?? []) {
3788
3845
  substitutions(redir.Word, state, depth);
@@ -3798,7 +3855,7 @@ function collectShellFileAccesses(command, context = {}) {
3798
3855
  const cmd = stmt.Cmd;
3799
3856
  if (!cmd) return;
3800
3857
  stdinScript(stmt, state, depth);
3801
- switch (syntax2.NodeType(cmd)) {
3858
+ switch (cmd.kind) {
3802
3859
  case "CallExpr":
3803
3860
  call(cmd, state, depth);
3804
3861
  break;
@@ -3812,7 +3869,7 @@ function collectShellFileAccesses(command, context = {}) {
3812
3869
  for (; ; ) {
3813
3870
  segments2.unshift({ op: node.Op, part: node.Y });
3814
3871
  const left = node.X;
3815
- if (left?.Cmd && syntax2.NodeType(left.Cmd) === "BinaryCmd" && !left.Redirs?.length && !left.Negated && !left.Background)
3872
+ if (left?.Cmd && left.Cmd.kind === "BinaryCmd" && !left.Redirs?.length && !left.Negated && !left.Background)
3816
3873
  node = left.Cmd;
3817
3874
  else {
3818
3875
  segments2.unshift({ op: node.Op, part: left });
@@ -5150,11 +5207,10 @@ function shellWriteUnseen(command, target) {
5150
5207
  let unseen = false;
5151
5208
  let seen = false;
5152
5209
  try {
5153
- syntax4.Walk(f, (node) => {
5210
+ walk(f, (node) => {
5154
5211
  if (!node || unseen) return false;
5155
5212
  const n = node;
5156
- if (syntax4.NodeType(n) !== "Stmt" || !n.Cmd || syntax4.NodeType(n.Cmd) !== "CallExpr")
5157
- return true;
5213
+ if (n.kind !== "Stmt" || !n.Cmd || n.Cmd.kind !== "CallExpr") return true;
5158
5214
  const words = (n.Cmd.Args || []).map(
5159
5215
  (a) => resolveWordLiteral(a)
5160
5216
  );
@@ -5209,14 +5265,14 @@ function analyzeGitImpl(command) {
5209
5265
  seen.add(key);
5210
5266
  findings.push(f);
5211
5267
  };
5212
- const walk2 = new GitWalk((inv) => classify(inv).forEach(found), found);
5213
- const parsed = walk2.run(command, 0);
5268
+ const walk3 = new GitWalk((inv) => classify(inv).forEach(found), found);
5269
+ const parsed = walk3.run(command, 0);
5214
5270
  return { parsed, findings };
5215
5271
  }
5216
5272
  function isPositionalParam(word) {
5217
5273
  let parts = word?.Parts || [];
5218
- if (parts.length === 1 && syntax5.NodeType(parts[0]) === "DblQuoted") parts = parts[0].Parts || [];
5219
- if (parts.length !== 1 || syntax5.NodeType(parts[0]) !== "ParamExp") return false;
5274
+ if (parts.length === 1 && parts[0].kind === "DblQuoted") parts = parts[0].Parts || [];
5275
+ if (parts.length !== 1 || parts[0].kind !== "ParamExp") return false;
5220
5276
  return /^(\d+|@|\*)$/.test(parts[0].Param?.Value ?? "");
5221
5277
  }
5222
5278
  function boundPositionals() {
@@ -5230,11 +5286,11 @@ function boundPositionals() {
5230
5286
  function plainParamName(word) {
5231
5287
  let parts = word?.Parts || [];
5232
5288
  let quoted = false;
5233
- if (parts.length === 1 && syntax5.NodeType(parts[0]) === "DblQuoted") {
5289
+ if (parts.length === 1 && parts[0].kind === "DblQuoted") {
5234
5290
  parts = parts[0].Parts || [];
5235
5291
  quoted = true;
5236
5292
  }
5237
- if (parts.length !== 1 || syntax5.NodeType(parts[0]) !== "ParamExp") return null;
5293
+ if (parts.length !== 1 || parts[0].kind !== "ParamExp") return null;
5238
5294
  const p = parts[0];
5239
5295
  if (p.Excl || p.Length || p.Width || p.Index || p.Slice || p.Repl || p.Exp) return null;
5240
5296
  const name = p.Param?.Value;
@@ -5259,7 +5315,7 @@ function resolveGitWords(word) {
5259
5315
  }
5260
5316
  const parts = word?.Parts || [];
5261
5317
  const expansion = parts.some((p) => {
5262
- const t = syntax5.NodeType(p);
5318
+ const t = p.kind;
5263
5319
  return t === "ParamExp" || t === "CmdSubst";
5264
5320
  });
5265
5321
  return expansion ? splitFields(value) : [value];
@@ -5660,14 +5716,14 @@ function hookCommands(text) {
5660
5716
  const root = parsed?.hooks;
5661
5717
  if (!root || typeof root !== "object") return null;
5662
5718
  const out = [];
5663
- const walk2 = (v, depth) => {
5719
+ const walk3 = (v, depth) => {
5664
5720
  if (depth > 8 || !v || typeof v !== "object") return;
5665
5721
  for (const [k, x] of Object.entries(v)) {
5666
5722
  if (k === "command" && typeof x === "string") out.push(x);
5667
- else walk2(x, depth + 1);
5723
+ else walk3(x, depth + 1);
5668
5724
  }
5669
5725
  };
5670
- walk2(root, 0);
5726
+ walk3(root, 0);
5671
5727
  return out;
5672
5728
  }
5673
5729
  function hooksDisarmed(text) {
@@ -5834,9 +5890,9 @@ function isDupInOp(op) {
5834
5890
  if (dupInOp === null) {
5835
5891
  let found = -1;
5836
5892
  try {
5837
- syntax6.Walk(parseShared("cat <&3"), (node) => {
5893
+ walk(parseShared("cat <&3"), (node) => {
5838
5894
  const n = node;
5839
- if (found === -1 && n && syntax6.NodeType(n) === "Stmt" && n.Redirs?.[0]) {
5895
+ if (found === -1 && n && n.kind === "Stmt" && n.Redirs?.[0]) {
5840
5896
  found = n.Redirs[0].Op;
5841
5897
  }
5842
5898
  return true;
@@ -5857,10 +5913,10 @@ function analyzeOutbound(command) {
5857
5913
  return hit;
5858
5914
  }
5859
5915
  const findings = [];
5860
- const walk2 = new OutboundWalk(findings);
5861
- const parsed = walk2.run(command, 0);
5916
+ const walk3 = new OutboundWalk(findings);
5917
+ const parsed = walk3.run(command, 0);
5862
5918
  const envOut = findings.find((f) => f.checkId === "data.env-exfil");
5863
- if (envOut) envOut.destinations = walk2.envDestinations();
5919
+ if (envOut) envOut.destinations = walk3.envDestinations();
5864
5920
  const computed = { parsed, findings };
5865
5921
  if (cache2.size >= CACHE_MAX2) {
5866
5922
  const oldest = cache2.keys().next().value;
@@ -5876,7 +5932,7 @@ function wordShape(word) {
5876
5932
  const parts = word?.Parts || [];
5877
5933
  let out = "";
5878
5934
  for (const p of parts) {
5879
- const t = syntax6.NodeType(p);
5935
+ const t = p.kind;
5880
5936
  if (t === "Lit" || t === "SglQuoted") out += p.Value ?? "";
5881
5937
  else if (t === "DblQuoted") out += wordShape(p);
5882
5938
  else out += "X";
@@ -6011,16 +6067,16 @@ function declDumpsEnv(decl) {
6011
6067
  }
6012
6068
  function paramName(word) {
6013
6069
  let parts = word?.Parts || [];
6014
- if (parts.length === 1 && syntax6.NodeType(parts[0]) === "DblQuoted") parts = parts[0].Parts || [];
6015
- if (parts.length !== 1 || syntax6.NodeType(parts[0]) !== "ParamExp") return null;
6070
+ if (parts.length === 1 && parts[0].kind === "DblQuoted") parts = parts[0].Parts || [];
6071
+ if (parts.length !== 1 || parts[0].kind !== "ParamExp") return null;
6016
6072
  return parts[0].Param?.Value ?? null;
6017
6073
  }
6018
6074
  function refersTo(word, names) {
6019
6075
  let hit = false;
6020
- syntax6.Walk(word, (node) => {
6076
+ walk(word, (node) => {
6021
6077
  if (hit || !node) return false;
6022
6078
  const n = node;
6023
- if (syntax6.NodeType(n) === "ParamExp" && names.has(n.Param?.Value)) hit = true;
6079
+ if (n.kind === "ParamExp" && names.has(n.Param?.Value)) hit = true;
6024
6080
  return !hit;
6025
6081
  });
6026
6082
  return hit;
@@ -6028,10 +6084,10 @@ function refersTo(word, names) {
6028
6084
  function runsCommandsIn(stmt) {
6029
6085
  const readVars = /* @__PURE__ */ new Set();
6030
6086
  let hit = false;
6031
- syntax6.Walk(stmt, (node) => {
6087
+ walk(stmt, (node) => {
6032
6088
  if (hit || !node) return false;
6033
6089
  const n = node;
6034
- if (syntax6.NodeType(n) !== "CallExpr") return true;
6090
+ if (n.kind !== "CallExpr") return true;
6035
6091
  const words = wordsOf(n);
6036
6092
  if (words.length === 0) return true;
6037
6093
  const { head, at } = headOf(words);
@@ -6608,7 +6664,7 @@ function localContexts(file2) {
6608
6664
  if (depth > 64) return null;
6609
6665
  if (!stmt || stmt.Background || stmt.Negated || stmt.Redirs?.length) return null;
6610
6666
  const cmd = stmt.Cmd;
6611
- const kind = syntax7.NodeType(cmd);
6667
+ const kind = cmd.kind;
6612
6668
  if (kind === "BinaryCmd" && cmd.Op === andOp) {
6613
6669
  const next = visit(cmd.X, steps, depth + 1);
6614
6670
  return next === null ? null : visit(cmd.Y, next, depth + 1);
@@ -6624,7 +6680,7 @@ function localContexts(file2) {
6624
6680
  )
6625
6681
  ))
6626
6682
  return null;
6627
- contexts.set(cmd.Pos().Offset(), steps);
6683
+ contexts.set(cmd.pos, steps);
6628
6684
  return null;
6629
6685
  }
6630
6686
  if (file2.Stmts?.length === 1) visit(file2.Stmts[0], []);
@@ -6635,12 +6691,12 @@ function collect(command, out, depth) {
6635
6691
  const f = parseShared(command);
6636
6692
  if (typeof f === "symbol") return;
6637
6693
  const contexts = depth === 0 ? localContexts(f) : /* @__PURE__ */ new Map();
6638
- syntax7.Walk(f, (node) => {
6639
- if (node && syntax7.NodeType(node) === "CallExpr") {
6694
+ walk(f, (node) => {
6695
+ if (node && node.kind === "CallExpr") {
6640
6696
  const words = (node.Args || []).map((a) => resolveWordLiteral(a));
6641
6697
  const start = out.length;
6642
6698
  if (words.length > 0) fromCall(words, out, depth);
6643
- const steps = contexts.get(node.Pos().Offset());
6699
+ const steps = contexts.get(node.pos);
6644
6700
  for (let i = start; i < out.length; i++) {
6645
6701
  if (["npx", "bunx", "npm exec"].includes(out[i].manager)) {
6646
6702
  if (!steps) out[i].localCwd = null;
@@ -6687,7 +6743,7 @@ function collect2(command, out, depth) {
6687
6743
  try {
6688
6744
  walkCommandScope(command, (node) => {
6689
6745
  const n = node;
6690
- if (!n || syntax8.NodeType(n) !== "CallExpr") return true;
6746
+ if (!n || n.kind !== "CallExpr") return true;
6691
6747
  const words = (n.Args || []).map((a) => resolveWordLiteral(a));
6692
6748
  if (words.length === 0) return true;
6693
6749
  const prefix = (n.Assigns || []).filter((a) => a?.Name?.Value).map(
@@ -8072,12 +8128,12 @@ function extractContentDestinations(text) {
8072
8128
  function extractArgDestinations(args) {
8073
8129
  const out = /* @__PURE__ */ new Set();
8074
8130
  try {
8075
- walk(args, void 0, out, 0);
8131
+ walk2(args, void 0, out, 0);
8076
8132
  } catch {
8077
8133
  }
8078
8134
  return [...out];
8079
8135
  }
8080
- function walk(value, key, out, depth) {
8136
+ function walk2(value, key, out, depth) {
8081
8137
  if (out.size >= MAX_DESTINATIONS || depth > 12) return;
8082
8138
  if (typeof value === "string") {
8083
8139
  const s = value.length > MAX_SCAN_CHARS ? value.slice(0, MAX_SCAN_CHARS) : value;
@@ -8096,12 +8152,12 @@ function walk(value, key, out, depth) {
8096
8152
  return;
8097
8153
  }
8098
8154
  if (Array.isArray(value)) {
8099
- for (const v of value) walk(v, key, out, depth + 1);
8155
+ for (const v of value) walk2(v, key, out, depth + 1);
8100
8156
  return;
8101
8157
  }
8102
8158
  if (value && typeof value === "object") {
8103
8159
  for (const [k, v] of Object.entries(value))
8104
- walk(v, k, out, depth + 1);
8160
+ walk2(v, k, out, depth + 1);
8105
8161
  }
8106
8162
  }
8107
8163
  function destinationDomain(dest) {
@@ -8753,9 +8809,9 @@ function classifyCall(head, args, prefixes, env, state, out) {
8753
8809
  function walkCalls(command, out, depth, state) {
8754
8810
  const f = parseShared(command);
8755
8811
  if (typeof f === "symbol" || !f) return;
8756
- syntax9.Walk(f, (node) => {
8812
+ walk(f, (node) => {
8757
8813
  if (!node) return false;
8758
- const type = syntax9.NodeType(node);
8814
+ const type = node.kind;
8759
8815
  if (type === "DeclClause") {
8760
8816
  for (const a of node.Args || []) if (a?.Name?.Value) state.env.add(a.Name.Value);
8761
8817
  return true;
@@ -8896,7 +8952,7 @@ function matchCanaryArgs(args, values) {
8896
8952
  if (values.length === 0) return null;
8897
8953
  const needles = prepare(values);
8898
8954
  if (needles.length === 0) return null;
8899
- const walk2 = (v, depth, fieldPath) => {
8955
+ const walk3 = (v, depth, fieldPath) => {
8900
8956
  if (depth > MAX_DEPTH4) return null;
8901
8957
  if (typeof v === "string") {
8902
8958
  const hit = matchPrepared(v, needles);
@@ -8905,31 +8961,31 @@ function matchCanaryArgs(args, values) {
8905
8961
  const trimmed = v.trim();
8906
8962
  if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
8907
8963
  try {
8908
- return walk2(JSON.parse(v), depth + 1, fieldPath);
8964
+ return walk3(JSON.parse(v), depth + 1, fieldPath);
8909
8965
  } catch {
8910
8966
  }
8911
8967
  }
8912
8968
  }
8913
8969
  return null;
8914
8970
  }
8915
- if (typeof v === "number" && Number.isFinite(v)) return walk2(String(v), depth, fieldPath);
8971
+ if (typeof v === "number" && Number.isFinite(v)) return walk3(String(v), depth, fieldPath);
8916
8972
  if (Array.isArray(v)) {
8917
8973
  for (let i = 0; i < v.length; i++) {
8918
- const h = walk2(v[i], depth + 1, `${fieldPath}[${i}]`);
8974
+ const h = walk3(v[i], depth + 1, `${fieldPath}[${i}]`);
8919
8975
  if (h) return h;
8920
8976
  }
8921
8977
  return null;
8922
8978
  }
8923
8979
  if (v && typeof v === "object") {
8924
8980
  for (const [k, child] of Object.entries(v)) {
8925
- const h = walk2(child, depth + 1, fieldPath ? `${fieldPath}.${k}` : k);
8981
+ const h = walk3(child, depth + 1, fieldPath ? `${fieldPath}.${k}` : k);
8926
8982
  if (h) return h;
8927
8983
  }
8928
8984
  }
8929
8985
  return null;
8930
8986
  };
8931
8987
  try {
8932
- return walk2(args, 0, "");
8988
+ return walk3(args, 0, "");
8933
8989
  } catch (e) {
8934
8990
  console.error(
8935
8991
  "[node9 engine] canary args walk failed:",
@@ -8938,26 +8994,20 @@ function matchCanaryArgs(args, values) {
8938
8994
  return null;
8939
8995
  }
8940
8996
  }
8941
- var import_mvdan_sh, import_picomatch, import_safe_regex2, import_picomatch2, import_mvdan_sh2, import_mvdan_sh3, import_safe_regex22, import_crypto2, import_crypto3, import_mvdan_sh4, import_mvdan_sh5, import_mvdan_sh6, import_mvdan_sh7, import_mvdan_sh8, import_crypto4, import_mvdan_sh9, import_crypto5, 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, 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;
8997
+ var import_picomatch, import_safe_regex2, import_picomatch2, import_mvdan_sh, import_mvdan_sh2, import_mvdan_sh3, import_safe_regex22, import_crypto2, import_crypto3, import_crypto4, import_crypto5, 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, 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;
8942
8998
  var init_dist = __esm({
8943
8999
  "packages/policy-engine/dist/index.mjs"() {
8944
9000
  "use strict";
8945
- import_mvdan_sh = __toESM(require("mvdan-sh"), 1);
8946
9001
  import_picomatch = __toESM(require("picomatch"), 1);
8947
9002
  import_safe_regex2 = __toESM(require("safe-regex2"), 1);
8948
9003
  import_picomatch2 = __toESM(require("picomatch"), 1);
9004
+ import_mvdan_sh = __toESM(require("mvdan-sh"), 1);
8949
9005
  import_mvdan_sh2 = __toESM(require("mvdan-sh"), 1);
8950
9006
  import_mvdan_sh3 = __toESM(require("mvdan-sh"), 1);
8951
9007
  import_safe_regex22 = __toESM(require("safe-regex2"), 1);
8952
9008
  import_crypto2 = require("crypto");
8953
9009
  import_crypto3 = require("crypto");
8954
- import_mvdan_sh4 = __toESM(require("mvdan-sh"), 1);
8955
- import_mvdan_sh5 = __toESM(require("mvdan-sh"), 1);
8956
- import_mvdan_sh6 = __toESM(require("mvdan-sh"), 1);
8957
- import_mvdan_sh7 = __toESM(require("mvdan-sh"), 1);
8958
- import_mvdan_sh8 = __toESM(require("mvdan-sh"), 1);
8959
9010
  import_crypto4 = require("crypto");
8960
- import_mvdan_sh9 = __toESM(require("mvdan-sh"), 1);
8961
9011
  import_crypto5 = __toESM(require("crypto"), 1);
8962
9012
  MAX_REGEX_LENGTH = 256;
8963
9013
  REGEX_CACHE_MAX = 500;
@@ -11603,6 +11653,61 @@ var init_dist = __esm({
11603
11653
  return s.untrustedContent.afterExposure === "log-only" ? "log" : "review";
11604
11654
  }
11605
11655
  };
11656
+ ({ syntax } = import_mvdan_sh2.default);
11657
+ KINDS = {
11658
+ File: { nodes: ["Stmts"] },
11659
+ Stmt: { nodes: ["Cmd", "Redirs"], scalars: ["Negated", "Background", "Coprocess"] },
11660
+ CallExpr: { nodes: ["Assigns", "Args"] },
11661
+ Assign: { nodes: ["Name", "Value", "Index", "Array"], scalars: ["Append", "Naked"] },
11662
+ Word: { nodes: ["Parts"] },
11663
+ Lit: { scalars: ["Value"] },
11664
+ SglQuoted: { scalars: ["Value", "Dollar"] },
11665
+ DblQuoted: { nodes: ["Parts"], scalars: ["Dollar"] },
11666
+ ParamExp: {
11667
+ nodes: ["Param", "Index", "Slice", "Repl", "Exp"],
11668
+ scalars: ["Short", "Excl", "Length", "Width"]
11669
+ },
11670
+ CmdSubst: { nodes: ["Stmts"], scalars: ["Backquotes", "TempFile", "ReplyVar"] },
11671
+ ArithmExp: { nodes: ["X"], scalars: ["Bracket", "Unsigned"] },
11672
+ ArithmCmd: { nodes: ["X"], scalars: ["Unsigned"] },
11673
+ ProcSubst: { nodes: ["Stmts"], scalars: ["Op"] },
11674
+ ExtGlob: { nodes: ["Pattern"], scalars: ["Op"] },
11675
+ BraceExp: { nodes: ["Elems"], scalars: ["Sequence"] },
11676
+ // only with SplitBraces, unused here
11677
+ BinaryCmd: { nodes: ["X", "Y"], scalars: ["Op"] },
11678
+ BinaryArithm: { nodes: ["X", "Y"], scalars: ["Op"] },
11679
+ UnaryArithm: { nodes: ["X"], scalars: ["Op", "Post"] },
11680
+ ParenArithm: { nodes: ["X"] },
11681
+ BinaryTest: { nodes: ["X", "Y"], scalars: ["Op"] },
11682
+ UnaryTest: { nodes: ["X"], scalars: ["Op"] },
11683
+ ParenTest: { nodes: ["X"] },
11684
+ Redirect: { nodes: ["N", "Word", "Hdoc"], scalars: ["Op"] },
11685
+ Block: { nodes: ["Stmts"] },
11686
+ Subshell: { nodes: ["Stmts"] },
11687
+ IfClause: { nodes: ["Cond", "Then", "Else"] },
11688
+ WhileClause: { nodes: ["Cond", "Do"], scalars: ["Until"] },
11689
+ ForClause: { nodes: ["Loop", "Do"], scalars: ["Select"] },
11690
+ WordIter: { nodes: ["Name", "Items"] },
11691
+ CStyleLoop: { nodes: ["Init", "Cond", "Post"] },
11692
+ CaseClause: { nodes: ["Word", "Items"] },
11693
+ CaseItem: { nodes: ["Patterns", "Stmts"], scalars: ["Op"] },
11694
+ FuncDecl: { nodes: ["Name", "Body"], scalars: ["RsrvWord"] },
11695
+ DeclClause: { nodes: ["Variant", "Args"], notWalked: ["Variant"] },
11696
+ LetClause: { nodes: ["Exprs"] },
11697
+ TimeClause: { nodes: ["Stmt"], scalars: ["PosixFormat"] },
11698
+ CoprocClause: { nodes: ["Name", "Stmt"] },
11699
+ TestClause: { nodes: ["X"] },
11700
+ TestDecl: { nodes: ["Description", "Body"] },
11701
+ ArrayExpr: { nodes: ["Elems"] },
11702
+ ArrayElem: { nodes: ["Index", "Value"] },
11703
+ Comment: { scalars: ["Text"] }
11704
+ };
11705
+ STRUCTS = {
11706
+ "ParamExp.Slice": { nodes: ["Offset", "Length"], notWalked: ["Offset", "Length"] },
11707
+ "ParamExp.Repl": { nodes: ["Orig", "With"], scalars: ["All"] },
11708
+ "ParamExp.Exp": { nodes: ["Word"], scalars: ["Op"] }
11709
+ };
11710
+ unknownKinds = /* @__PURE__ */ new Set();
11606
11711
  INVISIBLE_RE = /[­͏؜᠎​-‏‪-‮⁠-⁤-︀-️]|[\u{E0000}-\u{E007F}]/gu;
11607
11712
  INVISIBLE_ONE = new RegExp(`^(?:${INVISIBLE_RE.source.split("|")[0]})$`, "u");
11608
11713
  HOMOGLYPHS = {
@@ -11888,8 +11993,8 @@ var init_dist = __esm({
11888
11993
  php: PHP
11889
11994
  };
11890
11995
  STRING_LITERAL = /(['"`])((?:\\.|(?!\1)[^\\\n]){1,4096})\1/g;
11891
- ({ syntax } = import_mvdan_sh2.default);
11892
- sharedParser = syntax.NewParser();
11996
+ ({ syntax: syntax2 } = import_mvdan_sh.default);
11997
+ sharedParser = syntax2.NewParser();
11893
11998
  MESSAGE_FLAGS = /* @__PURE__ */ new Set([
11894
11999
  "-m",
11895
12000
  "--message",
@@ -11923,7 +12028,7 @@ var init_dist = __esm({
11923
12028
  NORMALIZE_CACHE_MAX = 5e3;
11924
12029
  normalizeCache = /* @__PURE__ */ new Map();
11925
12030
  codeBodiesCache = /* @__PURE__ */ new Map();
11926
- AST_CACHE_MAX = 5e3;
12031
+ AST_CACHE_MAX = 256;
11927
12032
  astCache = /* @__PURE__ */ new Map();
11928
12033
  PARSE_FAIL = /* @__PURE__ */ Symbol("parse-fail");
11929
12034
  INTERPRETER_LINE = /^#![ \t]*[\w./+-]+(?:[ \t]+[\w./+=:-]+)*[ \t]*\r?(?=\n|$)/;
@@ -12908,7 +13013,7 @@ var init_dist = __esm({
12908
13013
  ARGV_FIELDS = ["args", "argv"];
12909
13014
  BARE_WORD = /^[A-Za-z0-9_./+:@%,-]+$/;
12910
13015
  MAX_ARGV_CHARACTERS = 262144;
12911
- ({ syntax: syntax2 } = import_mvdan_sh3.default);
13016
+ ({ syntax: syntax3 } = import_mvdan_sh3.default);
12912
13017
  MAX_ALTERNATIVES = 64;
12913
13018
  MAX_CALL_DEPTH2 = 4;
12914
13019
  MAX_CALL_WALKS2 = 256;
@@ -13000,7 +13105,6 @@ var init_dist = __esm({
13000
13105
  );
13001
13106
  exempt = (p) => SYSTEM_DIRS_EXEMPT.some((d) => within(p, d));
13002
13107
  RANK = { allow: 0, review: 1, block: 2 };
13003
- ({ syntax: syntax3 } = import_mvdan_sh.default);
13004
13108
  SEQUENCE_OPS = (() => {
13005
13109
  const ops = /* @__PURE__ */ new Set();
13006
13110
  for (const text of ["x && y", "x || y"]) {
@@ -16161,7 +16265,6 @@ zoo`.split("\n");
16161
16265
  );
16162
16266
  NEVER_NEGATED = /* @__PURE__ */ new Set([SIGNALS[1].any[0]]);
16163
16267
  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;
16164
- ({ syntax: syntax4 } = import_mvdan_sh4.default);
16165
16268
  RDR_IN = (() => {
16166
16269
  try {
16167
16270
  return parseShared("x <y").Stmts[0].Redirs[0].Op;
@@ -16190,7 +16293,6 @@ zoo`.split("\n");
16190
16293
  "tar"
16191
16294
  ]);
16192
16295
  LITERAL_VERBS = /* @__PURE__ */ new Set(["echo", "printf", ":", "true", "touch", "sed"]);
16193
- ({ syntax: syntax5 } = import_mvdan_sh5.default);
16194
16296
  GIT_PRESCREEN_RE = /git|husky/i;
16195
16297
  MAX_PAYLOAD_DEPTH2 = 8;
16196
16298
  MAX_ALIAS_DEPTH = 5;
@@ -16259,7 +16361,7 @@ zoo`.split("\n");
16259
16361
  visit(node, depth) {
16260
16362
  if (!node) return false;
16261
16363
  const n = node;
16262
- const type = syntax5.NodeType(n);
16364
+ const type = n.kind;
16263
16365
  if (type === "Stmt") {
16264
16366
  this.visitHeredocShell(n, depth);
16265
16367
  return true;
@@ -16267,7 +16369,7 @@ zoo`.split("\n");
16267
16369
  if (type === "ForClause") {
16268
16370
  const loop = n.Loop;
16269
16371
  const name = loop?.Name?.Value;
16270
- if (name && syntax5.NodeType(loop) === "WordIter") {
16372
+ if (name && loop.kind === "WordIter") {
16271
16373
  const items = (loop.Items || []).map((w) => resolveWordLiteral(w));
16272
16374
  const literal = items.length > 0 && items.every((v) => v !== null);
16273
16375
  this.loopVars.set(name, literal ? items.slice(0, MAX_LOOP_ITEMS) : null);
@@ -16334,7 +16436,7 @@ zoo`.split("\n");
16334
16436
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
16335
16437
  visitHeredocShell(stmt, depth) {
16336
16438
  const cmd = stmt.Cmd;
16337
- if (!cmd || syntax5.NodeType(cmd) !== "CallExpr" || depth >= MAX_PAYLOAD_DEPTH2) return;
16439
+ if (!cmd || cmd.kind !== "CallExpr" || depth >= MAX_PAYLOAD_DEPTH2) return;
16338
16440
  const redirs = stmt.Redirs || [];
16339
16441
  const hdoc = redirs.find((r) => r?.Hdoc && (r.N == null || r.N.Value === "0"));
16340
16442
  if (!hdoc) return;
@@ -16588,7 +16690,6 @@ zoo`.split("\n");
16588
16690
  ]);
16589
16691
  SETTINGS_RE = /\/(?:\.claude\/settings(?:\.local)?\.json|\.gemini\/settings\.json|\.codex\/hooks\.json|\.cursor\/hooks\.json)$/i;
16590
16692
  HOOK_WORDS_RE = /"hooks"|\b(PreToolUse|PostToolUse|UserPromptSubmit|Notification|Stop|SubagentStop|SessionStart|SessionEnd|PreCompact|BeforeTool|AfterTool)\b|"command"\s*:/;
16591
- ({ syntax: syntax6 } = import_mvdan_sh6.default);
16592
16693
  SHELLS = /* @__PURE__ */ new Set([...SHELL_INTERPRETERS, "mksh", "ash", "csh", "tcsh"]);
16593
16694
  NETCATS = /* @__PURE__ */ new Set(["nc", "ncat", "netcat", "nc.traditional", "nc.openbsd"]);
16594
16695
  NET_CLIENTS = /* @__PURE__ */ new Set([...NETCATS, "telnet", "socat"]);
@@ -16646,7 +16747,7 @@ zoo`.split("\n");
16646
16747
  const f = parseShared(command);
16647
16748
  if (!f || typeof f !== "object" || !f.Stmts) return false;
16648
16749
  try {
16649
- syntax6.Walk(f, (node) => this.visit(node, depth));
16750
+ walk(f, (node) => this.visit(node, depth));
16650
16751
  } catch {
16651
16752
  return false;
16652
16753
  }
@@ -16685,7 +16786,7 @@ zoo`.split("\n");
16685
16786
  }
16686
16787
  visit(n, depth) {
16687
16788
  if (!n) return false;
16688
- const type = syntax6.NodeType(n);
16789
+ const type = n.kind;
16689
16790
  if (type === "Stmt") {
16690
16791
  this.visitStmt(n, depth);
16691
16792
  return true;
@@ -16705,7 +16806,7 @@ zoo`.split("\n");
16705
16806
  const redirs = redirectWords(stmt);
16706
16807
  const toSocket = redirs.some((w) => w !== null && DEV_NET_RE.test(w));
16707
16808
  if (!cmd) return;
16708
- const type = syntax6.NodeType(cmd);
16809
+ const type = cmd.kind;
16709
16810
  if (type !== "CallExpr" || wordsOf(cmd).length > 0) {
16710
16811
  if (this.readsNetFd(stmt) && runsCommandsIn(stmt)) {
16711
16812
  this.reverseShell("commands are read from a network socket opened with exec");
@@ -16791,7 +16892,7 @@ zoo`.split("\n");
16791
16892
  const stages = [];
16792
16893
  const flatten = (s) => {
16793
16894
  const c = s?.Cmd;
16794
- if (c && syntax6.NodeType(c) === "BinaryCmd" && isPipeOp(c.Op)) {
16895
+ if (c && c.kind === "BinaryCmd" && isPipeOp(c.Op)) {
16795
16896
  flatten(c.X);
16796
16897
  flatten(c.Y);
16797
16898
  } else stages.push(s);
@@ -16813,8 +16914,8 @@ zoo`.split("\n");
16813
16914
  sinks.set(i, socketHosts(st));
16814
16915
  }
16815
16916
  if (!c) return;
16816
- if (syntax6.NodeType(c) === "DeclClause" && declDumpsEnv(c) && dump < 0) dump = i;
16817
- if (syntax6.NodeType(c) !== "CallExpr") {
16917
+ if (c.kind === "DeclClause" && declDumpsEnv(c) && dump < 0) dump = i;
16918
+ if (c.kind !== "CallExpr") {
16818
16919
  if (runsCommandsIn(st)) shell = i;
16819
16920
  return;
16820
16921
  }
@@ -16855,10 +16956,10 @@ zoo`.split("\n");
16855
16956
  /** A word (or assignment value) whose text includes an env dump's output. */
16856
16957
  carriesEnv(word) {
16857
16958
  let hit = false;
16858
- syntax6.Walk(word, (node) => {
16959
+ walk(word, (node) => {
16859
16960
  if (hit || !node) return false;
16860
16961
  const n = node;
16861
- const t = syntax6.NodeType(n);
16962
+ const t = n.kind;
16862
16963
  if (t === "ParamExp" && n.Param?.Value && this.envVars.has(n.Param.Value)) {
16863
16964
  hit = true;
16864
16965
  return false;
@@ -16875,11 +16976,11 @@ zoo`.split("\n");
16875
16976
  stmtsDumpEnv(stmts) {
16876
16977
  let hit = false;
16877
16978
  for (const s of stmts) {
16878
- syntax6.Walk(s, (node) => {
16979
+ walk(s, (node) => {
16879
16980
  if (hit || !node) return false;
16880
16981
  const n = node;
16881
- const t = syntax6.NodeType(n);
16882
- if (t === "Stmt" && n.Cmd && syntax6.NodeType(n.Cmd) === "CallExpr") {
16982
+ const t = n.kind;
16983
+ if (t === "Stmt" && n.Cmd && n.Cmd.kind === "CallExpr") {
16883
16984
  const words = wordsOf(n.Cmd);
16884
16985
  if (words.length > 0 && dumpsEnv(words, n)) hit = true;
16885
16986
  }
@@ -16896,7 +16997,6 @@ zoo`.split("\n");
16896
16997
  this.run(payload, depth + 1);
16897
16998
  }
16898
16999
  };
16899
- ({ syntax: syntax7 } = import_mvdan_sh8.default);
16900
17000
  NPM_INSTALL_VERBS = /* @__PURE__ */ new Set([
16901
17001
  "install",
16902
17002
  "i",
@@ -17278,7 +17378,6 @@ zoo`.split("\n");
17278
17378
  SHELLS2 = /* @__PURE__ */ new Set(["sh", "bash", "zsh", "dash", "ksh", "ash"]);
17279
17379
  MAX_NESTING = 3;
17280
17380
  SHELL_VALUE_FLAGS = /* @__PURE__ */ new Set(["--rcfile", "--init-file", "-O", "+O", "-o", "+o"]);
17281
- ({ syntax: syntax8 } = import_mvdan_sh7.default);
17282
17381
  NPM_FAMILY = /* @__PURE__ */ new Set(["npm", "pnpm", "yarn", "bun", "npx", "pnpx", "bunx"]);
17283
17382
  PIP_FAMILY = /* @__PURE__ */ new Set(["pip", "pip3", "uv", "uvx", "pipx", "pipenv"]);
17284
17383
  NPM_FETCH_VERBS = /* @__PURE__ */ new Set([
@@ -17810,7 +17909,6 @@ zoo`.split("\n");
17810
17909
  ACCOUNT_KEY_RE = /("(?:iban|account|account_number|accountNumber)"\s*:\s*")([A-Za-z0-9 .-]{6,40})(")/g;
17811
17910
  ACCOUNT_VALUE_RE = /"([A-Z]{2}\d{2}[A-Z0-9]{11,30})"/g;
17812
17911
  MAX_MASK_DEPTH = 64;
17813
- ({ syntax: syntax9 } = import_mvdan_sh9.default);
17814
17912
  EMPTY = {
17815
17913
  fetches: false,
17816
17914
  sends: false,