@node9/proxy 2.50.1 → 2.51.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/cli-main.js +969 -366
- package/dist/dashboard.mjs +577 -29
- package/dist/hook.js +575 -28
- package/dist/index.js +776 -231
- package/dist/index.mjs +776 -231
- package/dist/scan-ink.mjs +2 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -2091,9 +2091,15 @@ function detectDangerousShellExec(command) {
|
|
|
2091
2091
|
if (f === PARSE_FAIL) return null;
|
|
2092
2092
|
let result = null;
|
|
2093
2093
|
const assigned = assignedNames(f);
|
|
2094
|
-
|
|
2094
|
+
const known = plainlyNamedPrograms(f);
|
|
2095
|
+
const calledByName = literallyCalledFunctions(f);
|
|
2096
|
+
const bodies = [];
|
|
2097
|
+
const inBody = (pos) => bodies.some(([a, b]) => pos >= a && pos < b);
|
|
2098
|
+
walkWithCalls(f, (node) => {
|
|
2095
2099
|
if (!node || result === "block") return false;
|
|
2096
2100
|
const n = node;
|
|
2101
|
+
if (n.kind === "FuncDecl" && n.Body && callDepth === 0 && calledByName.has(n.Name?.Value))
|
|
2102
|
+
bodies.push([n.Body.pos, n.Body.end]);
|
|
2097
2103
|
if (n.kind === "BinaryCmd" && n.Y && !listOps().has(n.Op)) {
|
|
2098
2104
|
const call = n.Y.Cmd;
|
|
2099
2105
|
if (call && call.kind === "CallExpr") {
|
|
@@ -2117,7 +2123,8 @@ function detectDangerousShellExec(command) {
|
|
|
2117
2123
|
);
|
|
2118
2124
|
const head = unwrapCommandHead(headWords, false, true);
|
|
2119
2125
|
const lookup = headWords[0]?.toLowerCase() === "command" && headWords.slice(1).some((w) => w === "-v" || w === "-V");
|
|
2120
|
-
|
|
2126
|
+
const unboundBody = callDepth === 0 && inBody(n.pos ?? -1);
|
|
2127
|
+
if (!lookup && !unboundBody && (opaqueExecutable(args[0], assigned, known) || opaqueExecutable(args[head], assigned, known)))
|
|
2121
2128
|
result = "review";
|
|
2122
2129
|
const firstParts = args[0].Parts || [];
|
|
2123
2130
|
if (firstParts.length !== 1 || firstParts[0].kind !== "Lit") return true;
|
|
@@ -2177,11 +2184,105 @@ function assignedNames(f) {
|
|
|
2177
2184
|
});
|
|
2178
2185
|
return names;
|
|
2179
2186
|
}
|
|
2180
|
-
function
|
|
2187
|
+
function literallyCalledFunctions(f) {
|
|
2188
|
+
const declared = /* @__PURE__ */ new Set();
|
|
2189
|
+
const called = /* @__PURE__ */ new Set();
|
|
2190
|
+
walk(f, (node) => {
|
|
2191
|
+
if (!node) return false;
|
|
2192
|
+
if (node.kind === "FuncDecl" && node.Name?.Value) declared.add(node.Name.Value);
|
|
2193
|
+
if (node.kind === "CallExpr") {
|
|
2194
|
+
const head = resolveWordLiteral(node.Args?.[0]);
|
|
2195
|
+
if (head) called.add(head);
|
|
2196
|
+
}
|
|
2197
|
+
return true;
|
|
2198
|
+
});
|
|
2199
|
+
return new Set([...declared].filter((name) => called.has(name)));
|
|
2200
|
+
}
|
|
2201
|
+
function plainlyNamedPrograms(f) {
|
|
2202
|
+
const values = /* @__PURE__ */ new Map();
|
|
2203
|
+
const arrays = /* @__PURE__ */ new Set();
|
|
2204
|
+
const give = (name, value) => {
|
|
2205
|
+
if (value === null || !PLAIN_PROGRAM_NAME.test(value)) {
|
|
2206
|
+
values.set(name, null);
|
|
2207
|
+
return;
|
|
2208
|
+
}
|
|
2209
|
+
const cur = values.get(name);
|
|
2210
|
+
if (cur === null) return;
|
|
2211
|
+
if (cur === void 0) values.set(name, /* @__PURE__ */ new Set([value]));
|
|
2212
|
+
else cur.add(value);
|
|
2213
|
+
};
|
|
2214
|
+
const literalOnly = (w) => {
|
|
2215
|
+
const parts = w?.Parts ?? [];
|
|
2216
|
+
if (parts.length !== 1) return null;
|
|
2217
|
+
const p = parts[0];
|
|
2218
|
+
if (p.kind === "Lit") return p.Value ?? null;
|
|
2219
|
+
if (p.kind === "ParamExp" && expansionName(p) === "FUNCNAME") return "FUNCNAME";
|
|
2220
|
+
if (p.kind === "SglQuoted" && !p.Dollar) return p.Value ?? null;
|
|
2221
|
+
if (p.kind === "DblQuoted") {
|
|
2222
|
+
const inner = p.Parts ?? [];
|
|
2223
|
+
return inner.length === 1 && inner[0].kind === "Lit" ? inner[0].Value ?? null : null;
|
|
2224
|
+
}
|
|
2225
|
+
return null;
|
|
2226
|
+
};
|
|
2227
|
+
let ifsTouched = false;
|
|
2228
|
+
walk(f, (node) => {
|
|
2229
|
+
if (!node) return false;
|
|
2230
|
+
const kind = node.kind;
|
|
2231
|
+
if (kind === "FuncDecl" && node.Name?.Value) give(node.Name.Value, node.Name.Value);
|
|
2232
|
+
if (kind === "Assign" && node.Name?.Value) {
|
|
2233
|
+
const name = node.Name.Value;
|
|
2234
|
+
if (name === "IFS") ifsTouched = true;
|
|
2235
|
+
if (node.Append) values.set(name, null);
|
|
2236
|
+
else if (node.Array) {
|
|
2237
|
+
arrays.add(name);
|
|
2238
|
+
for (const el of node.Array.Elems ?? []) give(name, literalOnly(el.Value));
|
|
2239
|
+
} else if (node.Index) {
|
|
2240
|
+
arrays.add(name);
|
|
2241
|
+
give(name, node.Value ? literalOnly(node.Value) : null);
|
|
2242
|
+
} else give(name, node.Value ? literalOnly(node.Value) : null);
|
|
2243
|
+
}
|
|
2244
|
+
if (kind === "ForClause" && node.Loop?.Name?.Value) values.set(node.Loop.Name.Value, null);
|
|
2245
|
+
if (kind === "CallExpr") {
|
|
2246
|
+
const words = (node.Args ?? []).map((a) => resolveWordLiteral(a));
|
|
2247
|
+
if (VARIABLE_READERS.has(words[0] ?? "")) {
|
|
2248
|
+
for (const w of words.slice(1)) if (w && /^[A-Za-z_]\w*$/.test(w)) values.set(w, null);
|
|
2249
|
+
}
|
|
2250
|
+
}
|
|
2251
|
+
return true;
|
|
2252
|
+
});
|
|
2253
|
+
if (ifsTouched) return /* @__PURE__ */ new Set();
|
|
2254
|
+
const functions = /* @__PURE__ */ new Set();
|
|
2255
|
+
walk(f, (node) => {
|
|
2256
|
+
if (node && node.kind === "FuncDecl" && node.Name?.Value) functions.add(node.Name.Value);
|
|
2257
|
+
return true;
|
|
2258
|
+
});
|
|
2259
|
+
const callable = (v) => functions.has(v) || v === "FUNCNAME" || v === "true" || v === "false" || v === ":";
|
|
2260
|
+
for (const [name, vals] of values) {
|
|
2261
|
+
if (vals && ![...vals].every(callable)) values.set(name, null);
|
|
2262
|
+
}
|
|
2263
|
+
const known = /* @__PURE__ */ new Set();
|
|
2264
|
+
for (const [name, vals] of values)
|
|
2265
|
+
if (vals && (vals.size === 1 || arrays.has(name) && vals.size > 0)) known.add(name);
|
|
2266
|
+
return known;
|
|
2267
|
+
}
|
|
2268
|
+
function expansionName(part) {
|
|
2269
|
+
if (part.kind !== "ParamExp") return null;
|
|
2270
|
+
if (part.Excl || part.Length || part.Width || part.Slice || part.Repl || part.Exp) return null;
|
|
2271
|
+
return part.Param?.Value ?? null;
|
|
2272
|
+
}
|
|
2273
|
+
function executableParts(word, assigned, quoted = false, known = EMPTY_NAMES) {
|
|
2181
2274
|
return (word?.Parts ?? []).flatMap((part) => {
|
|
2182
2275
|
const kind = part.kind;
|
|
2183
|
-
if (kind === "DblQuoted") return executableParts(part, assigned, true);
|
|
2276
|
+
if (kind === "DblQuoted") return executableParts(part, assigned, true, known);
|
|
2184
2277
|
if (kind === "Lit") return [{ kind: "Lit", value: part.Value ?? "", quoted }];
|
|
2278
|
+
const name = expansionName(part);
|
|
2279
|
+
if (name !== null && (known.has(name) || name === "FUNCNAME"))
|
|
2280
|
+
return [{ kind: "Lit", value: name, quoted }];
|
|
2281
|
+
if (name !== null) {
|
|
2282
|
+
const bound = recordedExpansion(name === "@" || name === "*" ? "1" : name);
|
|
2283
|
+
if (typeof bound === "string" && PLAIN_PROGRAM_NAME.test(bound))
|
|
2284
|
+
return [{ kind: "Lit", value: bound, quoted }];
|
|
2285
|
+
}
|
|
2185
2286
|
if (kind === "SglQuoted")
|
|
2186
2287
|
return [{ kind: part.Dollar ? "Dynamic" : "Lit", value: part.Value ?? "", quoted: true }];
|
|
2187
2288
|
if (kind === "ParamExp" && isDefaultExpansion(part) && !assigned.has(part.Param?.Value)) {
|
|
@@ -2189,14 +2290,14 @@ function executableParts(word, assigned, quoted = false) {
|
|
|
2189
2290
|
if (fallback !== null) return [{ kind: "Lit", value: fallback, quoted }];
|
|
2190
2291
|
}
|
|
2191
2292
|
if (kind === "CmdSubst") {
|
|
2192
|
-
const
|
|
2193
|
-
if (
|
|
2293
|
+
const name2 = lookupSubstitution(part);
|
|
2294
|
+
if (name2 !== null) return [{ kind: "Lit", value: name2, quoted }];
|
|
2194
2295
|
}
|
|
2195
2296
|
return [{ kind: "Dynamic", value: "", quoted }];
|
|
2196
2297
|
});
|
|
2197
2298
|
}
|
|
2198
|
-
function opaqueExecutable(word, assigned) {
|
|
2199
|
-
const parts = executableParts(word, assigned);
|
|
2299
|
+
function opaqueExecutable(word, assigned, known = EMPTY_NAMES) {
|
|
2300
|
+
const parts = executableParts(word, assigned, false, known);
|
|
2200
2301
|
let lastSlash = -1;
|
|
2201
2302
|
parts.forEach((p, i) => {
|
|
2202
2303
|
if (p.kind === "Lit" && p.value.includes("/")) lastSlash = i;
|
|
@@ -2318,6 +2419,9 @@ function deriveBinaryOp(sample) {
|
|
|
2318
2419
|
function isListOp(op) {
|
|
2319
2420
|
return listOps().has(op);
|
|
2320
2421
|
}
|
|
2422
|
+
function isPipeOp(op) {
|
|
2423
|
+
return pipeOps().has(op);
|
|
2424
|
+
}
|
|
2321
2425
|
function listOps() {
|
|
2322
2426
|
if (_listOps) return _listOps;
|
|
2323
2427
|
_listOps = new Set(
|
|
@@ -2562,6 +2666,33 @@ function isProtectedCodePath(p) {
|
|
|
2562
2666
|
if (matchSensitivePath(p) !== null) return true;
|
|
2563
2667
|
return SYSTEM_AUTH_FILES.includes(p) || SYSTEM_AUTH_DIRS.some((d) => p === d || p.startsWith(d + "/"));
|
|
2564
2668
|
}
|
|
2669
|
+
function isJailedCodePath(literal, jailPaths) {
|
|
2670
|
+
const value = trimTrailingSlashes(literal.replace(/\\/g, "/"));
|
|
2671
|
+
if (!value) return false;
|
|
2672
|
+
for (const raw of jailPaths) {
|
|
2673
|
+
const jail = trimTrailingSlashes(raw.trim().replace(/\\/g, "/"));
|
|
2674
|
+
if (!jail) continue;
|
|
2675
|
+
const home = homeTail(jail);
|
|
2676
|
+
if (home === null) {
|
|
2677
|
+
if (value === jail || value.startsWith(jail + "/")) return true;
|
|
2678
|
+
continue;
|
|
2679
|
+
}
|
|
2680
|
+
if (!home) continue;
|
|
2681
|
+
const tail = homeTail(value);
|
|
2682
|
+
if (tail !== null && (tail === home || tail.startsWith(home + "/"))) return true;
|
|
2683
|
+
}
|
|
2684
|
+
return false;
|
|
2685
|
+
}
|
|
2686
|
+
function trimTrailingSlashes(s) {
|
|
2687
|
+
let end = s.length;
|
|
2688
|
+
while (end > 0 && s.charCodeAt(end - 1) === 47) end--;
|
|
2689
|
+
return s.slice(0, end);
|
|
2690
|
+
}
|
|
2691
|
+
function homeTail(p) {
|
|
2692
|
+
const m = /^(?:~|\$\{?HOME\}?|\/home\/[^/]+|\/Users\/[^/]+|\/root)(?:\/(.*))?$/.exec(p);
|
|
2693
|
+
if (!m) return null;
|
|
2694
|
+
return m[1] ?? "";
|
|
2695
|
+
}
|
|
2565
2696
|
function inlineExecDescription(r) {
|
|
2566
2697
|
const lead = r ? `The AI is running code directly from the command line: ${inlineExecReason(r).replace(/^This/, "this")}.` : "The AI is running code directly from the command line.";
|
|
2567
2698
|
return `${lead} Review the full script below before allowing it to execute.`;
|
|
@@ -2570,7 +2701,8 @@ function inlineExecReason(r) {
|
|
|
2570
2701
|
const who = r.interp ? `This inline ${r.interp} code` : "This inline code";
|
|
2571
2702
|
return r.evidence ? `${who} ${r.what} (${r.evidence})` : `${who} ${r.what}`;
|
|
2572
2703
|
}
|
|
2573
|
-
function inlineExecReview(command) {
|
|
2704
|
+
function inlineExecReview(command, jailPaths = []) {
|
|
2705
|
+
const isProtected = jailPaths.length === 0 ? isProtectedCodePath : (p) => isProtectedCodePath(p) || isJailedCodePath(p, jailPaths);
|
|
2574
2706
|
const calls = inlineExecCalls(command);
|
|
2575
2707
|
if (calls === PARSE_FAIL) {
|
|
2576
2708
|
return INLINE_EXEC_FALLBACK.test(command) ? { outcome: "unreadable", interp: "", what: "could not be parsed" } : null;
|
|
@@ -2593,7 +2725,7 @@ function inlineExecReview(command) {
|
|
|
2593
2725
|
what: `is ${call.interp} code, which node9 does not read`
|
|
2594
2726
|
};
|
|
2595
2727
|
} else {
|
|
2596
|
-
const judged = judgeInlineCode(language, code,
|
|
2728
|
+
const judged = judgeInlineCode(language, code, isProtected);
|
|
2597
2729
|
if (judged) finding = { ...judged, interp: call.interp };
|
|
2598
2730
|
}
|
|
2599
2731
|
if (finding?.outcome === "dangerous") return finding;
|
|
@@ -2774,6 +2906,11 @@ function recordTopLevelStmt(stmt) {
|
|
|
2774
2906
|
if (t === "DeclClause") return ASSIGNMENT_HEADS.has(stmt.Cmd.Variant?.Value ?? "");
|
|
2775
2907
|
return (stmt.Cmd.Args || []).length === 0 && (stmt.Cmd.Assigns || []).length > 0;
|
|
2776
2908
|
}
|
|
2909
|
+
function arrayElements(value) {
|
|
2910
|
+
if (typeof value !== "string" || !value.startsWith(ARRAY_MARK)) return null;
|
|
2911
|
+
const body = value.slice(ARRAY_MARK.length);
|
|
2912
|
+
return body === "" ? [] : body.split(ARRAY_SEP);
|
|
2913
|
+
}
|
|
2777
2914
|
function recordAssignments(n, at) {
|
|
2778
2915
|
if (!assignmentTable) return;
|
|
2779
2916
|
const t = n.kind;
|
|
@@ -2787,7 +2924,19 @@ function recordAssignments(n, at) {
|
|
|
2787
2924
|
} else return;
|
|
2788
2925
|
for (const a of assigns) {
|
|
2789
2926
|
const name = a?.Name?.Value;
|
|
2790
|
-
if (!name
|
|
2927
|
+
if (!name) continue;
|
|
2928
|
+
if (a.Array) {
|
|
2929
|
+
const elems = (a.Array.Elems || []).map(
|
|
2930
|
+
(e) => e?.Index ? null : resolveWordLiteral(e?.Value)
|
|
2931
|
+
);
|
|
2932
|
+
const literal = elems.every((v) => v !== null);
|
|
2933
|
+
assignmentTable.set(name, {
|
|
2934
|
+
value: literal && !a.Append ? ARRAY_MARK + elems.join(ARRAY_SEP) : null,
|
|
2935
|
+
at
|
|
2936
|
+
});
|
|
2937
|
+
continue;
|
|
2938
|
+
}
|
|
2939
|
+
if (!a.Value || a.Append) continue;
|
|
2791
2940
|
assignmentTable.set(name, { value: resolveWordLiteral(a.Value), at });
|
|
2792
2941
|
}
|
|
2793
2942
|
}
|
|
@@ -2798,7 +2947,33 @@ function resolveTrivialSubst(part) {
|
|
|
2798
2947
|
const st = stmts[0];
|
|
2799
2948
|
if ((st.Redirs || []).length > 0 || st.Negated || st.Background) return void 0;
|
|
2800
2949
|
const cmd = st.Cmd;
|
|
2801
|
-
if (!cmd
|
|
2950
|
+
if (!cmd) return void 0;
|
|
2951
|
+
if (cmd.kind === "BinaryCmd" && pipeOps().has(cmd.Op)) {
|
|
2952
|
+
const left = cmd.X?.Cmd;
|
|
2953
|
+
const right = cmd.Y?.Cmd;
|
|
2954
|
+
if (!left || !right || left.kind !== "CallExpr" || right.kind !== "CallExpr") return void 0;
|
|
2955
|
+
if ((cmd.X.Redirs || []).length > 0 || (cmd.Y.Redirs || []).length > 0) return void 0;
|
|
2956
|
+
const input = trivialCallOutput(left);
|
|
2957
|
+
if (input === void 0) return void 0;
|
|
2958
|
+
const filter = (right.Args || []).map((a) => resolveWordLiteral(a));
|
|
2959
|
+
if (filter.some((w) => w === null)) return void 0;
|
|
2960
|
+
const f = baseWord(filter[0]);
|
|
2961
|
+
const flags = filter.slice(1);
|
|
2962
|
+
if (f === "base64" && flags.length === 1 && /^(-d|-D|--decode)$/.test(flags[0])) {
|
|
2963
|
+
try {
|
|
2964
|
+
const out = Buffer.from(input, "base64").toString("utf8");
|
|
2965
|
+
return /^[\x20-\x7e]*$/.test(out) ? out : void 0;
|
|
2966
|
+
} catch {
|
|
2967
|
+
return void 0;
|
|
2968
|
+
}
|
|
2969
|
+
}
|
|
2970
|
+
if (f === "rev" && flags.length === 0) return [...input].reverse().join("");
|
|
2971
|
+
return void 0;
|
|
2972
|
+
}
|
|
2973
|
+
if (cmd.kind !== "CallExpr") return void 0;
|
|
2974
|
+
return trivialCallOutput(cmd);
|
|
2975
|
+
}
|
|
2976
|
+
function trivialCallOutput(cmd) {
|
|
2802
2977
|
if ((cmd.Assigns || []).length > 0) return void 0;
|
|
2803
2978
|
const words = (cmd.Args || []).map((a) => resolveWordLiteral(a));
|
|
2804
2979
|
if (words.length === 0 || words.some((w) => w === null)) return void 0;
|
|
@@ -2810,9 +2985,16 @@ function resolveTrivialSubst(part) {
|
|
|
2810
2985
|
return rest.slice(i).join(" ");
|
|
2811
2986
|
}
|
|
2812
2987
|
if (head === "printf") {
|
|
2988
|
+
if (rest.length === 1 && /^(?:\\(?:[0-7]{1,3}|x[0-9A-Fa-f]{1,2}))+$/.test(rest[0])) {
|
|
2989
|
+
return rest[0].replace(
|
|
2990
|
+
/\\(?:x([0-9A-Fa-f]{1,2})|([0-7]{1,3}))/g,
|
|
2991
|
+
(_, hex, oct) => String.fromCharCode(hex ? parseInt(hex, 16) : parseInt(oct, 8))
|
|
2992
|
+
);
|
|
2993
|
+
}
|
|
2813
2994
|
if (rest.length !== 2) return void 0;
|
|
2814
|
-
|
|
2815
|
-
return
|
|
2995
|
+
const m = /^([^%]*)%s([^%]*?)(\\n)?$/.exec(rest[0]);
|
|
2996
|
+
if (!m) return void 0;
|
|
2997
|
+
return m[1] + rest[1] + m[2];
|
|
2816
2998
|
}
|
|
2817
2999
|
return void 0;
|
|
2818
3000
|
}
|
|
@@ -2826,11 +3008,28 @@ function isPlainParam(p) {
|
|
|
2826
3008
|
if (p.kind !== "ParamExp") return false;
|
|
2827
3009
|
return !(p.Excl || p.Length || p.Width || p.Index || p.Slice || p.Repl || p.Exp);
|
|
2828
3010
|
}
|
|
3011
|
+
function indexedParam(p) {
|
|
3012
|
+
if (p.kind !== "ParamExp" || !p.Index) return null;
|
|
3013
|
+
if (p.Excl || p.Length || p.Width || p.Slice || p.Repl || p.Exp) return null;
|
|
3014
|
+
const index = resolveWordLiteral(p.Index);
|
|
3015
|
+
const name = p.Param?.Value;
|
|
3016
|
+
return name && index !== null ? { name, index } : null;
|
|
3017
|
+
}
|
|
2829
3018
|
function expandPlainParam(p) {
|
|
2830
3019
|
if (!assignmentTable) return void 0;
|
|
3020
|
+
const indexed = indexedParam(p);
|
|
3021
|
+
if (indexed) {
|
|
3022
|
+
const elems = arrayElements(recordedExpansion(indexed.name));
|
|
3023
|
+
if (elems === null) return void 0;
|
|
3024
|
+
if (indexed.index === "@" || indexed.index === "*") return elems.join(" ");
|
|
3025
|
+
return /^\d+$/.test(indexed.index) ? elems[Number(indexed.index)] ?? null : null;
|
|
3026
|
+
}
|
|
2831
3027
|
if (!isPlainParam(p)) return void 0;
|
|
2832
3028
|
const recorded = recordedExpansion(p.Param?.Value);
|
|
2833
|
-
if (recorded !== void 0)
|
|
3029
|
+
if (recorded !== void 0) {
|
|
3030
|
+
const elems = arrayElements(recorded);
|
|
3031
|
+
return elems === null ? recorded : elems[0] ?? "";
|
|
3032
|
+
}
|
|
2834
3033
|
return HOME_VARIABLES.has(p.Param?.Value) ? "~" : void 0;
|
|
2835
3034
|
}
|
|
2836
3035
|
function functionBodies(f) {
|
|
@@ -5777,7 +5976,59 @@ function dynamicOptionWord(word) {
|
|
|
5777
5976
|
if (/^--[a-z-]+=/.test(prefix) || /^-[cC]/.test(prefix)) return `${prefix}$\u2026`;
|
|
5778
5977
|
return null;
|
|
5779
5978
|
}
|
|
5780
|
-
function
|
|
5979
|
+
function arrayExpansionWords(word) {
|
|
5980
|
+
let parts = word?.Parts || [];
|
|
5981
|
+
if (parts.length === 1 && parts[0].kind === "DblQuoted") parts = parts[0].Parts || [];
|
|
5982
|
+
if (parts.length !== 1 || parts[0].kind !== "ParamExp" || !parts[0].Index) return null;
|
|
5983
|
+
const index = resolveWordLiteral(parts[0].Index);
|
|
5984
|
+
if (index !== "@" && index !== "*") return null;
|
|
5985
|
+
const elems = arrayElements(recordedExpansion(parts[0].Param?.Value));
|
|
5986
|
+
return elems;
|
|
5987
|
+
}
|
|
5988
|
+
function producedLiteral(call) {
|
|
5989
|
+
if ((call.Assigns || []).length > 0) return null;
|
|
5990
|
+
const words = (call.Args || []).map((a) => resolveWordLiteral(a));
|
|
5991
|
+
if (words.length === 0 || words.some((w) => w === null)) return null;
|
|
5992
|
+
const head = baseWord(words[0]);
|
|
5993
|
+
const rest = words.slice(1);
|
|
5994
|
+
if (head === "git" && rest[0] === "rev-parse" && rest[1] === "--show-toplevel" && rest.length === 2)
|
|
5995
|
+
return ":/";
|
|
5996
|
+
if (head === "echo") {
|
|
5997
|
+
let i = 0;
|
|
5998
|
+
while (i < rest.length && /^-[neE]+$/.test(rest[i])) i++;
|
|
5999
|
+
return rest.length - i === 1 ? rest[i] : null;
|
|
6000
|
+
}
|
|
6001
|
+
if (head === "printf" && rest.length === 2 && /^%s(\\[0n])?$/.test(rest[0])) return rest[1];
|
|
6002
|
+
return null;
|
|
6003
|
+
}
|
|
6004
|
+
function treeTopWord(word, treeTopVars = NO_VARS) {
|
|
6005
|
+
let parts = word?.Parts || [];
|
|
6006
|
+
if (parts.length === 1 && parts[0].kind === "DblQuoted") parts = parts[0].Parts || [];
|
|
6007
|
+
if (parts.length !== 1) return false;
|
|
6008
|
+
const p = parts[0];
|
|
6009
|
+
if (p.kind === "ParamExp") {
|
|
6010
|
+
const name = plainParamName(word)?.name;
|
|
6011
|
+
return name === "PWD" || name !== void 0 && treeTopVars.has(name);
|
|
6012
|
+
}
|
|
6013
|
+
if (p.kind !== "CmdSubst") return false;
|
|
6014
|
+
const stmts = p.Stmts || [];
|
|
6015
|
+
if (stmts.length !== 1 || !stmts[0].Cmd || stmts[0].Cmd.kind !== "CallExpr") return false;
|
|
6016
|
+
const words = (stmts[0].Cmd.Args || []).map((a) => resolveWordLiteral(a));
|
|
6017
|
+
if (words.some((w) => w === null)) return false;
|
|
6018
|
+
const head = baseWord(words[0]);
|
|
6019
|
+
if (head === "pwd") return words.length === 1 || words[1] === "-P" || words[1] === "-L";
|
|
6020
|
+
return head === "git" && words[1] === "rev-parse" && words[2] === "--show-toplevel";
|
|
6021
|
+
}
|
|
6022
|
+
function resolveGitWords(word, treeTopVars = NO_VARS, appended = NO_APPENDS) {
|
|
6023
|
+
if (treeTopWord(word, treeTopVars)) return [":/"];
|
|
6024
|
+
const plain = plainParamName(word);
|
|
6025
|
+
if (plain && appended.has(plain.name)) {
|
|
6026
|
+
const v = appended.get(plain.name);
|
|
6027
|
+
if (v === null || v === void 0) return [null];
|
|
6028
|
+
return plain.quoted ? [v] : splitFields(v);
|
|
6029
|
+
}
|
|
6030
|
+
const elems = arrayExpansionWords(word);
|
|
6031
|
+
if (elems !== null) return elems;
|
|
5781
6032
|
const value = resolveWordLiteral(word);
|
|
5782
6033
|
if (value === null) {
|
|
5783
6034
|
if (isPositionalParam(word)) return boundPositionals() ?? [POSITIONAL2];
|
|
@@ -5885,6 +6136,8 @@ function classify(inv) {
|
|
|
5885
6136
|
if (o.flags.has("-n") || o.flags.has("--dry-run")) break;
|
|
5886
6137
|
const forced = o.flags.has("-f") || o.flags.has("--force") || o.flags.has("--force-with-lease") || o.flags.has("--force-if-includes") || o.flags.has("--mirror") || o.operands.some((r) => r.startsWith("+"));
|
|
5887
6138
|
if (forced) found(FORCE_PUSH);
|
|
6139
|
+
const deletes = o.flags.has("-d") || o.flags.has("--delete") || o.operands.some((r) => /^:[^:]/.test(r));
|
|
6140
|
+
if (deletes) found(DESTRUCTIVE);
|
|
5888
6141
|
break;
|
|
5889
6142
|
}
|
|
5890
6143
|
case "reset": {
|
|
@@ -5912,11 +6165,72 @@ function classify(inv) {
|
|
|
5912
6165
|
if (o.flags.has("-d") || o.flags.has("--delete")) found(DESTRUCTIVE);
|
|
5913
6166
|
break;
|
|
5914
6167
|
}
|
|
6168
|
+
// node9Firewall#385: history and work discarded through plumbing. A ref
|
|
6169
|
+
// deleted by hand, a stash dropped, the reflog expired or pruned: the
|
|
6170
|
+
// commits behind them are gone the way `branch -D` loses them.
|
|
6171
|
+
case "update-ref": {
|
|
6172
|
+
const o = parseOptions(inv.args, "m", /* @__PURE__ */ new Set());
|
|
6173
|
+
if (o.flags.has("-d") && (o.dynamic || o.operands.some(isHistoryRef))) found(DESTRUCTIVE);
|
|
6174
|
+
break;
|
|
6175
|
+
}
|
|
6176
|
+
case "reflog": {
|
|
6177
|
+
const o = parseOptions(inv.args, "", /* @__PURE__ */ new Set());
|
|
6178
|
+
if (o.operands[0] === "expire" || o.operands[0] === "delete") found(DESTRUCTIVE);
|
|
6179
|
+
break;
|
|
6180
|
+
}
|
|
6181
|
+
case "gc": {
|
|
6182
|
+
if (inv.config.get("gc.reflogexpire") === "now") found(DESTRUCTIVE);
|
|
6183
|
+
break;
|
|
6184
|
+
}
|
|
6185
|
+
case "stash": {
|
|
6186
|
+
const o = parseOptions(inv.args, "", /* @__PURE__ */ new Set());
|
|
6187
|
+
if (o.operands[0] === "clear" || o.operands[0] === "drop") found(DESTRUCTIVE);
|
|
6188
|
+
break;
|
|
6189
|
+
}
|
|
6190
|
+
case "worktree": {
|
|
6191
|
+
const o = parseOptions(inv.args, "", /* @__PURE__ */ new Set());
|
|
6192
|
+
if (o.operands[0] === "remove" && (o.flags.has("-f") || o.flags.has("--force")))
|
|
6193
|
+
found(DESTRUCTIVE);
|
|
6194
|
+
break;
|
|
6195
|
+
}
|
|
6196
|
+
// The working tree overwritten: `restore` from another ref, a forced
|
|
6197
|
+
// checkout, or `checkout -- .` (every local change dropped). A bare
|
|
6198
|
+
// `restore .` or `checkout .` stays an ordinary undo, as pinned.
|
|
6199
|
+
case "restore": {
|
|
6200
|
+
const o = parseOptions(inv.args, "s", RESTORE_LONG_VALUE);
|
|
6201
|
+
const src = restoreSource(inv.args);
|
|
6202
|
+
const whole = o.dynamic || o.operands.some(wholeTree);
|
|
6203
|
+
if (src !== null && src !== "HEAD" && whole) found(DESTRUCTIVE);
|
|
6204
|
+
break;
|
|
6205
|
+
}
|
|
6206
|
+
case "checkout": {
|
|
6207
|
+
const o = parseOptions(inv.args, "bB", CHECKOUT_LONG_VALUE);
|
|
6208
|
+
const forced = o.flags.has("-f") || o.flags.has("--force");
|
|
6209
|
+
const dropAll = inv.args.includes("--") && o.operands.some(wholeTree);
|
|
6210
|
+
if (forced || dropAll) found(DESTRUCTIVE);
|
|
6211
|
+
break;
|
|
6212
|
+
}
|
|
5915
6213
|
default:
|
|
5916
6214
|
break;
|
|
5917
6215
|
}
|
|
5918
6216
|
return out;
|
|
5919
6217
|
}
|
|
6218
|
+
function isExcludePathspec(operand) {
|
|
6219
|
+
return /^:[!^]/.test(operand) || /^:\([^)]*\bexclude\b[^)]*\)/.test(operand);
|
|
6220
|
+
}
|
|
6221
|
+
function restoreSource(args) {
|
|
6222
|
+
for (let i = 0; i < args.length; i++) {
|
|
6223
|
+
const w = args[i];
|
|
6224
|
+
if (w === null) continue;
|
|
6225
|
+
if (w.startsWith("--source=")) return w.slice("--source=".length);
|
|
6226
|
+
if (w === "--source" || w === "-s") return args[i + 1] ?? null;
|
|
6227
|
+
if (/^-s./.test(w)) return w.slice(2);
|
|
6228
|
+
}
|
|
6229
|
+
return null;
|
|
6230
|
+
}
|
|
6231
|
+
function isHistoryRef(ref) {
|
|
6232
|
+
return /^refs\/(heads|stash)(\/|$)/.test(ref);
|
|
6233
|
+
}
|
|
5920
6234
|
function killSwitchSet(name, value) {
|
|
5921
6235
|
if (value === null) return false;
|
|
5922
6236
|
switch (name) {
|
|
@@ -5974,6 +6288,7 @@ function hooksBypass(inv) {
|
|
|
5974
6288
|
const o = parseOptions(inv.args, "mFCcut", COMMIT_LONG_VALUE);
|
|
5975
6289
|
return o.flags.has("-n") || o.flags.has("--no-verify");
|
|
5976
6290
|
}
|
|
6291
|
+
if (sub === "commit-tree") return true;
|
|
5977
6292
|
if (sub !== void 0 && NO_VERIFY_SUBS.has(sub)) {
|
|
5978
6293
|
return inv.args.some((a) => a === "--no-verify");
|
|
5979
6294
|
}
|
|
@@ -6011,7 +6326,20 @@ function configWritesHooksPath(args) {
|
|
|
6011
6326
|
return write;
|
|
6012
6327
|
}
|
|
6013
6328
|
function isHookPath(word) {
|
|
6014
|
-
return /(^|[\\/])(\.git[\\/]hooks|\.husky)([\\/]|$)/.test(word);
|
|
6329
|
+
return /(^|[\\/])(\.git[\\/]hooks|\.husky|\.githooks)([\\/]|$)/.test(word);
|
|
6330
|
+
}
|
|
6331
|
+
function isLiveHookFile(word) {
|
|
6332
|
+
if (!isHookPath(word)) return false;
|
|
6333
|
+
const m = /(^|[\\/])(\.git[\\/]hooks|\.husky|\.githooks)(?:[\\/](.*))?$/.exec(word);
|
|
6334
|
+
if (!m) return false;
|
|
6335
|
+
const rest = m[3] ?? "";
|
|
6336
|
+
if (rest === "" || rest === "_") return true;
|
|
6337
|
+
const leaf = rest.replace(/^_[\\/]/, "");
|
|
6338
|
+
return /^[a-z-]+$/.test(leaf);
|
|
6339
|
+
}
|
|
6340
|
+
function hookBodyIsEmpty(text) {
|
|
6341
|
+
const lines = text.split(/\r?\n/).map((l) => l.trim()).filter((l) => l !== "" && !l.startsWith("#"));
|
|
6342
|
+
return lines.every((l) => /^(exit(\s+0)?|true|:|set\s+-[a-zA-Z]+|set\s+-o\s+\w+)$/.test(l));
|
|
6015
6343
|
}
|
|
6016
6344
|
function modeRemovesExecute(mode) {
|
|
6017
6345
|
if (/^[0-7]{3,4}$/.test(mode)) {
|
|
@@ -6020,6 +6348,22 @@ function modeRemovesExecute(mode) {
|
|
|
6020
6348
|
}
|
|
6021
6349
|
return mode.split(",").some((part) => /^[ugoa]*-[rwst]*x/.test(part));
|
|
6022
6350
|
}
|
|
6351
|
+
function redirOpIsAppend(redir) {
|
|
6352
|
+
return redir?.Op === appendOp();
|
|
6353
|
+
}
|
|
6354
|
+
function appendOp() {
|
|
6355
|
+
if (_appendOp !== null) return _appendOp;
|
|
6356
|
+
try {
|
|
6357
|
+
const f = parseShared("echo x >> y");
|
|
6358
|
+
_appendOp = typeof f === "symbol" ? -1 : f.Stmts[0].Redirs[0].Op;
|
|
6359
|
+
} catch {
|
|
6360
|
+
_appendOp = -1;
|
|
6361
|
+
}
|
|
6362
|
+
return _appendOp;
|
|
6363
|
+
}
|
|
6364
|
+
function hooksBypassed(shown) {
|
|
6365
|
+
return { ...HOOKS_BYPASS, shown, reason: `${HOOKS_BYPASS.reason}: ${shown}` };
|
|
6366
|
+
}
|
|
6023
6367
|
function chmodDisarmsHook(args, shown) {
|
|
6024
6368
|
let i = 0;
|
|
6025
6369
|
while (i < args.length) {
|
|
@@ -6062,6 +6406,7 @@ function stagesEverything(inv) {
|
|
|
6062
6406
|
const sub = inv.sub?.toLowerCase();
|
|
6063
6407
|
const prefix = chdirPrefix(inv);
|
|
6064
6408
|
const judge = (operands2) => {
|
|
6409
|
+
if (operands2.length > 0 && operands2.every(isExcludePathspec)) return {};
|
|
6065
6410
|
let conditional = false;
|
|
6066
6411
|
for (const operand of operands2) {
|
|
6067
6412
|
if (!wholeTree(operand)) continue;
|
|
@@ -6354,7 +6699,7 @@ function evaluateAgentFileWrite(args, accesses, context, settings, shell, hooks
|
|
|
6354
6699
|
}
|
|
6355
6700
|
return null;
|
|
6356
6701
|
}
|
|
6357
|
-
function
|
|
6702
|
+
function isPipeOp2(op) {
|
|
6358
6703
|
return !isListOp(op);
|
|
6359
6704
|
}
|
|
6360
6705
|
function isDupInOp(op) {
|
|
@@ -8387,7 +8732,7 @@ async function evaluatePolicyCore(config, toolName, args, context = {}, hooks =
|
|
|
8387
8732
|
if (v?.logged) noteLogged(v);
|
|
8388
8733
|
else if (v) candidates.push(v);
|
|
8389
8734
|
};
|
|
8390
|
-
const inline = reviewsEveryInline(config.settings.mode) ? detectInlineExec(shellCommand) ? void 0 : null : inlineExecReview(shellCommand);
|
|
8735
|
+
const inline = reviewsEveryInline(config.settings.mode) ? detectInlineExec(shellCommand) ? void 0 : null : inlineExecReview(shellCommand, config.policy.jailPaths);
|
|
8391
8736
|
if (inline !== null) {
|
|
8392
8737
|
consider("commands.inline-exec", {
|
|
8393
8738
|
decision: "review",
|
|
@@ -8730,7 +9075,7 @@ function* validCardRuns(text, base2, exemptFractions = true) {
|
|
|
8730
9075
|
let m;
|
|
8731
9076
|
while ((m = re.exec(text)) !== null) {
|
|
8732
9077
|
const digits = m[0].replace(/\D/g, "");
|
|
8733
|
-
const fraction = exemptFractions && isDecimalFraction(text, m.index, digits.length === m[0].length);
|
|
9078
|
+
const fraction = exemptFractions && (isDecimalFraction(text, m.index, digits.length === m[0].length) || isInteriorDotNumber(m[0]));
|
|
8734
9079
|
if (!fraction && validateLuhn(digits)) {
|
|
8735
9080
|
yield { index: m.index, length: m[0].length, digits };
|
|
8736
9081
|
} else {
|
|
@@ -8757,6 +9102,12 @@ function replaceValidCards(text, replace, { exemptFractions = true } = {}) {
|
|
|
8757
9102
|
}
|
|
8758
9103
|
return out;
|
|
8759
9104
|
}
|
|
9105
|
+
function isInteriorDotNumber(run) {
|
|
9106
|
+
const first = run.indexOf(".");
|
|
9107
|
+
if (first <= 0 || first === run.length - 1) return false;
|
|
9108
|
+
if (run.indexOf(".", first + 1) !== -1) return false;
|
|
9109
|
+
return !/[-\s]/.test(run);
|
|
9110
|
+
}
|
|
8760
9111
|
function isDecimalFraction(text, index, unseparated) {
|
|
8761
9112
|
if (!unseparated) return false;
|
|
8762
9113
|
const sep = text[index - 1];
|
|
@@ -9480,7 +9831,7 @@ function matchCanaryArgs(args, values) {
|
|
|
9480
9831
|
return null;
|
|
9481
9832
|
}
|
|
9482
9833
|
}
|
|
9483
|
-
var getFilename, __filename2, 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, ASI, ASI_IDS, PACK_SHIELD_OWASP, PACK_RULE_OWASP, 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_ALTERNATIVES, MAX_CALL_DEPTH, MAX_CALL_WALKS, MAX_XARGS_PAYLOAD, 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, ops, MAX_INLINE_CODE, WHAT, OUTSIDE, pyImport, either, PYTHON, NODE, PERL, RUBY, PHP, TABLES, STRING_LITERAL, 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, andOrOps, MAX_CALL_DEPTH2, MAX_CALL_WALKS2, callDepth, callWalks, FS_OP_CACHE_MAX, fsOpCache, stripDotSlash, REDIR_TRUNCATE_OPS, REDIR_FILE_IN_OPS, REDIR_HEREDOC_OPS, FIND_OPTIONS, COPY_RULE_OF, INDIRECT_SHAPE_RE, SOURCES_FILE_RE, SHELL_SET_VARS, pipeOps, callWords, JAILED_GLOB_NAMES, JAILED_DIR_NAMES, shellGlob, GLOB_META, isReaderWord, positionalAfter, NONE, UNKNOWN, FORBIDDEN_PATH_SEGMENTS, BASH_TOOL_NAMES, MCP_EXECUTORS, BUILTIN_FIELDS, ARGV_FIELDS, BARE_WORD, MAX_ARGV_CHARACTERS, 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;
|
|
9834
|
+
var getFilename, __filename2, 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, ASI, ASI_IDS, PACK_SHIELD_OWASP, PACK_RULE_OWASP, 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_ALTERNATIVES, MAX_CALL_DEPTH, MAX_CALL_WALKS, MAX_XARGS_PAYLOAD, 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, ops, MAX_INLINE_CODE, WHAT, OUTSIDE, pyImport, either, PYTHON, NODE, PERL, RUBY, PHP, TABLES, STRING_LITERAL, 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, EMPTY_NAMES, VARIABLE_READERS, PLAIN_PROGRAM_NAME, 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, andOrOps, ARRAY_MARK, ARRAY_SEP, MAX_CALL_DEPTH2, MAX_CALL_WALKS2, callDepth, callWalks, FS_OP_CACHE_MAX, fsOpCache, stripDotSlash, REDIR_TRUNCATE_OPS, REDIR_FILE_IN_OPS, REDIR_HEREDOC_OPS, FIND_OPTIONS, COPY_RULE_OF, INDIRECT_SHAPE_RE, SOURCES_FILE_RE, SHELL_SET_VARS, pipeOps, callWords, JAILED_GLOB_NAMES, JAILED_DIR_NAMES, shellGlob, GLOB_META, isReaderWord, positionalAfter, NONE, UNKNOWN, FORBIDDEN_PATH_SEGMENTS, BASH_TOOL_NAMES, MCP_EXECUTORS, BUILTIN_FIELDS, ARGV_FIELDS, BARE_WORD, MAX_ARGV_CHARACTERS, 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, NO_VARS, NO_APPENDS, FORCE_PUSH, DESTRUCTIVE, UNREADABLE, PUSH_LONG_VALUE, BRANCH_LONG_VALUE, TAG_LONG_VALUE, CLEAN_LONG_VALUE, RESTORE_LONG_VALUE, CHECKOUT_LONG_VALUE, HOOKS_BYPASS, NO_VERIFY_SUBS, HOOK_KILL_SWITCHES, COMMIT_LONG_VALUE, CHMOD_OPTION_RE, _appendOp, 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;
|
|
9484
9835
|
var init_dist = __esm({
|
|
9485
9836
|
"packages/policy-engine/dist/index.mjs"() {
|
|
9486
9837
|
"use strict";
|
|
@@ -12747,6 +13098,7 @@ var init_dist = __esm({
|
|
|
12747
13098
|
"sqlite3"
|
|
12748
13099
|
]);
|
|
12749
13100
|
defaultExpansionOps = null;
|
|
13101
|
+
EMPTY_NAMES = /* @__PURE__ */ new Set();
|
|
12750
13102
|
VARIABLE_READERS = /* @__PURE__ */ new Set([
|
|
12751
13103
|
"read",
|
|
12752
13104
|
"mapfile",
|
|
@@ -12759,6 +13111,7 @@ var init_dist = __esm({
|
|
|
12759
13111
|
"readonly",
|
|
12760
13112
|
"printf"
|
|
12761
13113
|
]);
|
|
13114
|
+
PLAIN_PROGRAM_NAME = /^[A-Za-z_][\w.+-]*$/;
|
|
12762
13115
|
FS_READ_TOOLS = /* @__PURE__ */ new Set([
|
|
12763
13116
|
"cat",
|
|
12764
13117
|
"less",
|
|
@@ -13653,6 +14006,8 @@ var init_dist = __esm({
|
|
|
13653
14006
|
AND_OR_OPS: new Set([and, or].filter((o) => o !== null))
|
|
13654
14007
|
};
|
|
13655
14008
|
});
|
|
14009
|
+
ARRAY_MARK = "array";
|
|
14010
|
+
ARRAY_SEP = "";
|
|
13656
14011
|
MAX_CALL_DEPTH2 = 4;
|
|
13657
14012
|
MAX_CALL_WALKS2 = 256;
|
|
13658
14013
|
callDepth = 0;
|
|
@@ -16982,7 +17337,22 @@ zoo`.split("\n");
|
|
|
16982
17337
|
found;
|
|
16983
17338
|
/** Aliases defined earlier in this command: name -> value (null = dynamic). */
|
|
16984
17339
|
aliases = /* @__PURE__ */ new Map();
|
|
17340
|
+
/** node9Firewall#385: variables assigned a tree-top word (`scope="$PWD"`,
|
|
17341
|
+
* `root=$(git rev-parse --show-toplevel)`, `DIR=$(pwd)`), so the
|
|
17342
|
+
* variable reads as the top where it is used. */
|
|
17343
|
+
treeTopVars = /* @__PURE__ */ new Set();
|
|
17344
|
+
/** node9Firewall#385 (c): a string a script builds with `+=` from
|
|
17345
|
+
* literals (`mode=--ha; mode+=rd`). The jail's table does not follow an
|
|
17346
|
+
* append (JAIL-14a); the git rules read the built word, since a flag
|
|
17347
|
+
* spelled in two halves is still that flag. name -> value, null once a
|
|
17348
|
+
* half is unknown. */
|
|
17349
|
+
appended = /* @__PURE__ */ new Map();
|
|
16985
17350
|
payloads = /* @__PURE__ */ new Set();
|
|
17351
|
+
/** node9Firewall#385 (a): the text this command writes to each path
|
|
17352
|
+
* (`cat > /tmp/x.sh <<'SH' ... SH`, `echo '...' > f`, `>>` appends), so
|
|
17353
|
+
* a later statement that runs the path (`bash f`, `sh f`, `./f`) is
|
|
17354
|
+
* judged on what it runs. null once a write to the path is unknown. */
|
|
17355
|
+
written = /* @__PURE__ */ new Map();
|
|
16986
17356
|
/** `for NAME in a b c`: the literal items, or null when one is dynamic. */
|
|
16987
17357
|
loopVars = /* @__PURE__ */ new Map();
|
|
16988
17358
|
/** Walk one command string. Returns false when it did not parse. */
|
|
@@ -17001,6 +17371,25 @@ zoo`.split("\n");
|
|
|
17001
17371
|
const type = n.kind;
|
|
17002
17372
|
if (type === "Stmt") {
|
|
17003
17373
|
this.visitHeredocShell(n, depth);
|
|
17374
|
+
this.visitPipeline(n, depth);
|
|
17375
|
+
this.visitHookWrite(n);
|
|
17376
|
+
this.recordScriptWrite(n);
|
|
17377
|
+
this.visitWrittenScript(n, depth);
|
|
17378
|
+
return true;
|
|
17379
|
+
}
|
|
17380
|
+
if (type === "Assign" && n.Name?.Value && n.Value) {
|
|
17381
|
+
const name = n.Name.Value;
|
|
17382
|
+
if (n.Append) {
|
|
17383
|
+
const prev = this.appended.has(name) ? this.appended.get(name) : resolveWordLiteral(n.Value) === null ? null : void 0;
|
|
17384
|
+
const base2 = prev === void 0 ? recordedExpansion(name) : prev;
|
|
17385
|
+
const piece = resolveWordLiteral(n.Value);
|
|
17386
|
+
this.appended.set(name, typeof base2 === "string" && piece !== null ? base2 + piece : null);
|
|
17387
|
+
this.treeTopVars.delete(name);
|
|
17388
|
+
return true;
|
|
17389
|
+
}
|
|
17390
|
+
this.appended.delete(name);
|
|
17391
|
+
if (treeTopWord(n.Value, this.treeTopVars)) this.treeTopVars.add(name);
|
|
17392
|
+
else this.treeTopVars.delete(name);
|
|
17004
17393
|
return true;
|
|
17005
17394
|
}
|
|
17006
17395
|
if (type === "ForClause") {
|
|
@@ -17029,13 +17418,13 @@ zoo`.split("\n");
|
|
|
17029
17418
|
const param = plainParamName(rawArgs[loopArg]);
|
|
17030
17419
|
for (const item of this.loopVars.get(param.name)) {
|
|
17031
17420
|
const words2 = rawArgs.flatMap(
|
|
17032
|
-
(a, i) => i === loopArg ? param.quoted ? [item] : splitFields(item) : resolveGitWords(a)
|
|
17421
|
+
(a, i) => i === loopArg ? param.quoted ? [item] : splitFields(item) : resolveGitWords(a, this.treeTopVars, this.appended)
|
|
17033
17422
|
);
|
|
17034
17423
|
this.visitWords(words2, new Map(prefixEnv), depth, false);
|
|
17035
17424
|
}
|
|
17036
17425
|
return true;
|
|
17037
17426
|
}
|
|
17038
|
-
const words = rawArgs.flatMap((a) => resolveGitWords(a));
|
|
17427
|
+
const words = rawArgs.flatMap((a) => resolveGitWords(a, this.treeTopVars, this.appended));
|
|
17039
17428
|
this.visitWords(words, prefixEnv, depth, false);
|
|
17040
17429
|
return true;
|
|
17041
17430
|
}
|
|
@@ -17060,6 +17449,23 @@ zoo`.split("\n");
|
|
|
17060
17449
|
if (f) this.found(f);
|
|
17061
17450
|
return;
|
|
17062
17451
|
}
|
|
17452
|
+
if (headWord === "rm" || headWord === "unlink") {
|
|
17453
|
+
if (words.slice(head + 1).some((w) => w !== null && isLiveHookFile(w)))
|
|
17454
|
+
this.found(hooksBypassed(shownOf(words)));
|
|
17455
|
+
return;
|
|
17456
|
+
}
|
|
17457
|
+
if (headWord === "mv") {
|
|
17458
|
+
const operands2 = words.slice(head + 1).filter((w) => w === null || !w.startsWith("-"));
|
|
17459
|
+
const src = operands2[0];
|
|
17460
|
+
if (typeof src === "string" && isLiveHookFile(src)) this.found(hooksBypassed(shownOf(words)));
|
|
17461
|
+
return;
|
|
17462
|
+
}
|
|
17463
|
+
if (headWord === "perl") {
|
|
17464
|
+
const code = words.slice(head + 1).find((w) => w !== null && /\brename\b/.test(w));
|
|
17465
|
+
const m = code ? /rename\s*\(?\s*q[qw]?\s*[(\[{<'"]([^)\]}>'"]+)/.exec(code) : null;
|
|
17466
|
+
if (m && isLiveHookFile(m[1])) this.found(hooksBypassed(shownOf(words)));
|
|
17467
|
+
return;
|
|
17468
|
+
}
|
|
17063
17469
|
if (depth < MAX_PAYLOAD_DEPTH2) {
|
|
17064
17470
|
const payload = literalShellPayload(words, baseWord(words[0]));
|
|
17065
17471
|
if (payload !== null) this.runPayload(payload, depth);
|
|
@@ -17070,6 +17476,127 @@ zoo`.split("\n");
|
|
|
17070
17476
|
this.payloads.add(payload);
|
|
17071
17477
|
this.run(payload, depth + 1);
|
|
17072
17478
|
}
|
|
17479
|
+
/**
|
|
17480
|
+
* node9Firewall#385: a pipeline whose last stage reads its pathspec from
|
|
17481
|
+
* stdin (`git add --pathspec-from-file=-`) or runs git over the names it
|
|
17482
|
+
* is fed (`xargs -0 git add --`), with a producer that is one literal
|
|
17483
|
+
* (`git rev-parse --show-toplevel`, `printf '%s\0' .`): the literal is
|
|
17484
|
+
* the operand, and the call is judged with it.
|
|
17485
|
+
*/
|
|
17486
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
17487
|
+
visitPipeline(stmt, depth) {
|
|
17488
|
+
const cmd = stmt.Cmd;
|
|
17489
|
+
if (!cmd || cmd.kind !== "BinaryCmd" || !isPipeOp(cmd.Op)) return;
|
|
17490
|
+
const stages = [];
|
|
17491
|
+
let cur = cmd;
|
|
17492
|
+
while (cur?.kind === "BinaryCmd" && isPipeOp(cur.Op)) {
|
|
17493
|
+
stages.unshift(cur.Y);
|
|
17494
|
+
const left = cur.X;
|
|
17495
|
+
if (left?.Cmd?.kind === "BinaryCmd" && isPipeOp(left.Cmd.Op)) cur = left.Cmd;
|
|
17496
|
+
else {
|
|
17497
|
+
stages.unshift(left);
|
|
17498
|
+
break;
|
|
17499
|
+
}
|
|
17500
|
+
}
|
|
17501
|
+
if (stages.length < 2) return;
|
|
17502
|
+
const producer = stages[stages.length - 2]?.Cmd;
|
|
17503
|
+
const consumer = stages[stages.length - 1]?.Cmd;
|
|
17504
|
+
if (!producer || !consumer || producer.kind !== "CallExpr" || consumer.kind !== "CallExpr")
|
|
17505
|
+
return;
|
|
17506
|
+
const fed = producedLiteral(producer);
|
|
17507
|
+
if (fed === null) return;
|
|
17508
|
+
const words = (consumer.Args || []).flatMap(
|
|
17509
|
+
(a) => resolveGitWords(a, this.treeTopVars, this.appended)
|
|
17510
|
+
);
|
|
17511
|
+
const head = unwrapCommandHead(words);
|
|
17512
|
+
const viaXargs = words.slice(0, head).some((w) => baseWord(w) === "xargs");
|
|
17513
|
+
const fromFile = words.findIndex(
|
|
17514
|
+
(w) => w === "--pathspec-from-file=-" || w === "--pathspec-from-file"
|
|
17515
|
+
);
|
|
17516
|
+
if (!viaXargs && fromFile < 0) return;
|
|
17517
|
+
let fedWords;
|
|
17518
|
+
if (fromFile >= 0) {
|
|
17519
|
+
fedWords = words.filter(
|
|
17520
|
+
(w, k) => !(k === fromFile || w === "-" && words[k - 1] === "--pathspec-from-file")
|
|
17521
|
+
);
|
|
17522
|
+
fedWords.push(fed);
|
|
17523
|
+
} else fedWords = [...words, fed];
|
|
17524
|
+
this.visitWords(fedWords, /* @__PURE__ */ new Map(), depth, false);
|
|
17525
|
+
}
|
|
17526
|
+
/**
|
|
17527
|
+
* node9Firewall#385 (e): a hook file written with a body that checks
|
|
17528
|
+
* nothing (`cat > .githooks/pre-commit <<'SH' exit 0 SH`, `echo 'exit 0'
|
|
17529
|
+
* > .git/hooks/pre-push`, `: > .githooks/pre-commit`). A real body (a
|
|
17530
|
+
* test, a linter) is ordinary work on the hooks.
|
|
17531
|
+
*/
|
|
17532
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
17533
|
+
visitHookWrite(stmt) {
|
|
17534
|
+
const cmd = stmt.Cmd;
|
|
17535
|
+
if (!cmd || cmd.kind !== "CallExpr") return;
|
|
17536
|
+
const redirs = stmt.Redirs || [];
|
|
17537
|
+
const target = redirs.find((r) => r?.Word && !r.Hdoc && (r.N == null || r.N.Value === "1"));
|
|
17538
|
+
if (!target) return;
|
|
17539
|
+
const path210 = resolveWordLiteral(target.Word);
|
|
17540
|
+
if (path210 === null || !isLiveHookFile(path210)) return;
|
|
17541
|
+
const hdoc = redirs.find((r) => r?.Hdoc);
|
|
17542
|
+
const words = (cmd.Args || []).map((a) => resolveWordLiteral(a));
|
|
17543
|
+
const head = baseWord(words[0]);
|
|
17544
|
+
let body = null;
|
|
17545
|
+
if (hdoc) body = resolveWordLiteral(hdoc.Hdoc);
|
|
17546
|
+
else if (head === ":" || head === "true" || words.length === 0) body = "";
|
|
17547
|
+
else if (head === "echo" || head === "printf") {
|
|
17548
|
+
const rest = words.slice(1);
|
|
17549
|
+
body = rest.some((w) => w === null) ? null : rest.filter((w) => !/^-[neE]+$/.test(w)).join(" ");
|
|
17550
|
+
if (body !== null) body = body.replace(/\\n/g, "\n");
|
|
17551
|
+
}
|
|
17552
|
+
if (body !== null && hookBodyIsEmpty(body)) this.found(hooksBypassed(shownOf(words)));
|
|
17553
|
+
}
|
|
17554
|
+
/** A statement that writes a literal text to a path, by redirect. */
|
|
17555
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
17556
|
+
recordScriptWrite(stmt) {
|
|
17557
|
+
const cmd = stmt.Cmd;
|
|
17558
|
+
if (!cmd || cmd.kind !== "CallExpr") return;
|
|
17559
|
+
const redirs = stmt.Redirs || [];
|
|
17560
|
+
const target = redirs.find((r) => r?.Word && !r.Hdoc && (r.N == null || r.N.Value === "1"));
|
|
17561
|
+
if (!target) return;
|
|
17562
|
+
const path210 = resolveWordLiteral(target.Word);
|
|
17563
|
+
if (path210 === null) return;
|
|
17564
|
+
const append = /^>>/.test(target.Op?.toString() ?? "") || redirOpIsAppend(target);
|
|
17565
|
+
const hdoc = redirs.find((r) => r?.Hdoc);
|
|
17566
|
+
const words = (cmd.Args || []).map((a) => resolveWordLiteral(a));
|
|
17567
|
+
const head = baseWord(words[0]);
|
|
17568
|
+
let text = null;
|
|
17569
|
+
if (hdoc && (head === "cat" || head === "tee")) text = resolveWordLiteral(hdoc.Hdoc);
|
|
17570
|
+
else if (head === "echo" || head === "printf") {
|
|
17571
|
+
const rest = words.slice(1);
|
|
17572
|
+
text = rest.some((w) => w === null) ? null : rest.filter((w) => !/^-[neE]+$/.test(w)).join(" ");
|
|
17573
|
+
if (text !== null && head === "printf") text = text.replace(/\\n/g, "\n");
|
|
17574
|
+
} else return;
|
|
17575
|
+
const prev = this.written.get(path210);
|
|
17576
|
+
if (text === null || append && prev === null) this.written.set(path210, null);
|
|
17577
|
+
else this.written.set(path210, append && typeof prev === "string" ? `${prev}
|
|
17578
|
+
${text}` : text);
|
|
17579
|
+
}
|
|
17580
|
+
/** A statement that runs a path this command wrote: the text is the script. */
|
|
17581
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
17582
|
+
visitWrittenScript(stmt, depth) {
|
|
17583
|
+
const cmd = stmt.Cmd;
|
|
17584
|
+
if (!cmd || cmd.kind !== "CallExpr" || this.written.size === 0 || depth >= MAX_PAYLOAD_DEPTH2)
|
|
17585
|
+
return;
|
|
17586
|
+
const words = (cmd.Args || []).map((a) => resolveWordLiteral(a));
|
|
17587
|
+
const head = unwrapCommandHead(words);
|
|
17588
|
+
const name = baseWord(words[head]);
|
|
17589
|
+
let ran = null;
|
|
17590
|
+
if (PAYLOAD_SHELLS.has(name) && name !== "eval") {
|
|
17591
|
+
const operand = words.slice(head + 1).find((w) => w === null || !w.startsWith("-"));
|
|
17592
|
+
if (typeof operand === "string") ran = operand;
|
|
17593
|
+
} else if (typeof words[head] === "string" && this.written.has(words[head])) {
|
|
17594
|
+
ran = words[head];
|
|
17595
|
+
}
|
|
17596
|
+
if (ran === null) return;
|
|
17597
|
+
const text = this.written.get(ran);
|
|
17598
|
+
if (typeof text === "string") this.runPayload(text, depth);
|
|
17599
|
+
}
|
|
17073
17600
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
17074
17601
|
visitHeredocShell(stmt, depth) {
|
|
17075
17602
|
const cmd = stmt.Cmd;
|
|
@@ -17221,6 +17748,8 @@ zoo`.split("\n");
|
|
|
17221
17748
|
}
|
|
17222
17749
|
};
|
|
17223
17750
|
POSITIONAL2 = "\0positional";
|
|
17751
|
+
NO_VARS = /* @__PURE__ */ new Set();
|
|
17752
|
+
NO_APPENDS = /* @__PURE__ */ new Map();
|
|
17224
17753
|
FORCE_PUSH = {
|
|
17225
17754
|
checkId: "commands.git-destructive",
|
|
17226
17755
|
ruleName: "review-force-push",
|
|
@@ -17279,6 +17808,8 @@ zoo`.split("\n");
|
|
|
17279
17808
|
"--cleanup"
|
|
17280
17809
|
]);
|
|
17281
17810
|
CLEAN_LONG_VALUE = /* @__PURE__ */ new Set(["--exclude"]);
|
|
17811
|
+
RESTORE_LONG_VALUE = /* @__PURE__ */ new Set(["--source", "--pathspec-from-file"]);
|
|
17812
|
+
CHECKOUT_LONG_VALUE = /* @__PURE__ */ new Set(["--pathspec-from-file", "--orphan", "--conflict"]);
|
|
17282
17813
|
HOOKS_BYPASS = {
|
|
17283
17814
|
checkId: "commands.git-hooks-bypass",
|
|
17284
17815
|
ruleName: "review-git-hooks-bypass",
|
|
@@ -17304,6 +17835,7 @@ zoo`.split("\n");
|
|
|
17304
17835
|
"--gpg-sign"
|
|
17305
17836
|
]);
|
|
17306
17837
|
CHMOD_OPTION_RE = /^-[RvcfHLP]+$/;
|
|
17838
|
+
_appendOp = null;
|
|
17307
17839
|
STAGE_ALL = {
|
|
17308
17840
|
checkId: "commands.git-stage-all",
|
|
17309
17841
|
ruleName: "review-git-stage-all",
|
|
@@ -17428,7 +17960,7 @@ zoo`.split("\n");
|
|
|
17428
17960
|
this.visitStmt(n, depth);
|
|
17429
17961
|
return true;
|
|
17430
17962
|
}
|
|
17431
|
-
if (type === "BinaryCmd" &&
|
|
17963
|
+
if (type === "BinaryCmd" && isPipeOp2(n.Op)) {
|
|
17432
17964
|
this.visitPipeline(n);
|
|
17433
17965
|
return true;
|
|
17434
17966
|
}
|
|
@@ -17529,7 +18061,7 @@ zoo`.split("\n");
|
|
|
17529
18061
|
const stages = [];
|
|
17530
18062
|
const flatten = (s) => {
|
|
17531
18063
|
const c = s?.Cmd;
|
|
17532
|
-
if (c && c.kind === "BinaryCmd" &&
|
|
18064
|
+
if (c && c.kind === "BinaryCmd" && isPipeOp2(c.Op)) {
|
|
17533
18065
|
flatten(c.X);
|
|
17534
18066
|
flatten(c.Y);
|
|
17535
18067
|
} else stages.push(s);
|
|
@@ -18942,9 +19474,9 @@ init_audit();
|
|
|
18942
19474
|
|
|
18943
19475
|
// src/config/index.ts
|
|
18944
19476
|
init_esm_shims();
|
|
18945
|
-
import
|
|
18946
|
-
import
|
|
18947
|
-
import
|
|
19477
|
+
import fs5 from "fs";
|
|
19478
|
+
import path6 from "path";
|
|
19479
|
+
import os5 from "os";
|
|
18948
19480
|
|
|
18949
19481
|
// src/config-schema.ts
|
|
18950
19482
|
init_esm_shims();
|
|
@@ -19237,11 +19769,18 @@ function slug(s) {
|
|
|
19237
19769
|
var B = "[\\s/\\\\]";
|
|
19238
19770
|
var SEP = "[/\\\\]";
|
|
19239
19771
|
function pathToRegexFragment(rawPath) {
|
|
19240
|
-
const
|
|
19772
|
+
const trimmed = rawPath.trim();
|
|
19773
|
+
const tail = trimmed.replace(/^~[\\/]?/, "").replace(/^\$\{?HOME\}?[\\/]?/, "").replace(/^\/(?:home|Users)\/[^\\/]+[\\/]?/, "").replace(/^[A-Za-z]:[\\/]Users[\\/][^\\/]+[\\/]?/, "").replace(/^[\\/]+/, "").replace(/[\\/]+$/, "");
|
|
19241
19774
|
const segments2 = tail.split(/[\\/]+/).filter(Boolean).map(escapeRegex);
|
|
19242
19775
|
if (segments2.length === 0) return "";
|
|
19776
|
+
if (isAbsoluteOutsideHome(trimmed)) {
|
|
19777
|
+
return `(^|[^A-Za-z0-9_.~\\/-])/${segments2.join(SEP)}(${B}|$)`;
|
|
19778
|
+
}
|
|
19243
19779
|
return `(^|${B})${segments2.join(SEP)}(${B}|$)`;
|
|
19244
19780
|
}
|
|
19781
|
+
function isAbsoluteOutsideHome(p) {
|
|
19782
|
+
return p.startsWith("/") && !/^\/(?:home|Users|root)(?:\/|$)/.test(p);
|
|
19783
|
+
}
|
|
19245
19784
|
function pathMatchesFragment(candidate, rawPath) {
|
|
19246
19785
|
const value = pathToRegexFragment(rawPath);
|
|
19247
19786
|
if (!value || !candidate) return false;
|
|
@@ -19507,17 +20046,57 @@ function applyManagedApprovers(local, managed) {
|
|
|
19507
20046
|
};
|
|
19508
20047
|
}
|
|
19509
20048
|
|
|
19510
|
-
// src/
|
|
20049
|
+
// src/shields/jail.ts
|
|
19511
20050
|
init_esm_shims();
|
|
19512
20051
|
import fs3 from "fs";
|
|
19513
|
-
import path4 from "path";
|
|
19514
20052
|
import os3 from "os";
|
|
20053
|
+
import path4 from "path";
|
|
20054
|
+
init_dist();
|
|
20055
|
+
var USER_JAIL_SHIELD = "user-jail";
|
|
20056
|
+
function jailStorePath() {
|
|
20057
|
+
return path4.join(os3.homedir(), ".node9", "jail-paths.json");
|
|
20058
|
+
}
|
|
20059
|
+
function readJailPaths() {
|
|
20060
|
+
let text;
|
|
20061
|
+
try {
|
|
20062
|
+
text = fs3.readFileSync(jailStorePath(), "utf8");
|
|
20063
|
+
} catch (err) {
|
|
20064
|
+
if (err.code === "ENOENT") return [];
|
|
20065
|
+
throw err;
|
|
20066
|
+
}
|
|
20067
|
+
let parsed;
|
|
20068
|
+
try {
|
|
20069
|
+
parsed = JSON.parse(text);
|
|
20070
|
+
} catch {
|
|
20071
|
+
throw new Error(`${jailStorePath()} is not valid JSON \u2014 fix it before changing the jail.`);
|
|
20072
|
+
}
|
|
20073
|
+
if (!Array.isArray(parsed.paths)) return [];
|
|
20074
|
+
return parsed.paths.filter(
|
|
20075
|
+
(p) => !!p && typeof p.path === "string" && (p.verdict === "block" || p.verdict === "review")
|
|
20076
|
+
);
|
|
20077
|
+
}
|
|
20078
|
+
function findJailedPath(candidate) {
|
|
20079
|
+
return findJailedPathIn(candidate, readJailPaths());
|
|
20080
|
+
}
|
|
20081
|
+
function findJailedPathIn(candidate, paths) {
|
|
20082
|
+
if (!candidate) return null;
|
|
20083
|
+
for (const entry of paths) {
|
|
20084
|
+
if (pathMatchesFragment(candidate, entry.path)) return entry;
|
|
20085
|
+
}
|
|
20086
|
+
return null;
|
|
20087
|
+
}
|
|
20088
|
+
|
|
20089
|
+
// src/auth/trusted-hosts.ts
|
|
20090
|
+
init_esm_shims();
|
|
20091
|
+
import fs4 from "fs";
|
|
20092
|
+
import path5 from "path";
|
|
20093
|
+
import os4 from "os";
|
|
19515
20094
|
function getTrustedHostsPath() {
|
|
19516
|
-
return
|
|
20095
|
+
return path5.join(os4.homedir(), ".node9", "trusted-hosts.json");
|
|
19517
20096
|
}
|
|
19518
20097
|
function readTrustedHosts() {
|
|
19519
20098
|
try {
|
|
19520
|
-
const raw =
|
|
20099
|
+
const raw = fs4.readFileSync(getTrustedHostsPath(), "utf8");
|
|
19521
20100
|
const parsed = JSON.parse(raw);
|
|
19522
20101
|
return Array.isArray(parsed.hosts) ? parsed.hosts : [];
|
|
19523
20102
|
} catch {
|
|
@@ -19528,7 +20107,7 @@ var _cache = null;
|
|
|
19528
20107
|
var CACHE_TTL_MS = 5e3;
|
|
19529
20108
|
function getFileMtime() {
|
|
19530
20109
|
try {
|
|
19531
|
-
return
|
|
20110
|
+
return fs4.statSync(getTrustedHostsPath()).mtimeMs;
|
|
19532
20111
|
} catch {
|
|
19533
20112
|
return 0;
|
|
19534
20113
|
}
|
|
@@ -20013,7 +20592,8 @@ var DEFAULT_CONFIG = {
|
|
|
20013
20592
|
trustedHostsManaged: false,
|
|
20014
20593
|
appPermissions: {},
|
|
20015
20594
|
appLinks: {},
|
|
20016
|
-
managedJailPaths: []
|
|
20595
|
+
managedJailPaths: [],
|
|
20596
|
+
jailPaths: []
|
|
20017
20597
|
},
|
|
20018
20598
|
environments: {}
|
|
20019
20599
|
};
|
|
@@ -20082,8 +20662,8 @@ function noteRejectedApiUrl(raw) {
|
|
|
20082
20662
|
if (rejectedApiUrlsSeen.has(key)) return;
|
|
20083
20663
|
rejectedApiUrlsSeen.add(key);
|
|
20084
20664
|
try {
|
|
20085
|
-
|
|
20086
|
-
|
|
20665
|
+
fs5.appendFileSync(
|
|
20666
|
+
path6.join(os5.homedir(), ".node9", "hook-debug.log"),
|
|
20087
20667
|
`[${(/* @__PURE__ */ new Date()).toISOString()}] REFUSED apiUrl, using the default instead: ${String(raw).slice(0, 200).replace(/[\r\n]+/g, " ")}
|
|
20088
20668
|
`
|
|
20089
20669
|
);
|
|
@@ -20100,9 +20680,9 @@ function getCredentials() {
|
|
|
20100
20680
|
};
|
|
20101
20681
|
}
|
|
20102
20682
|
try {
|
|
20103
|
-
const credPath =
|
|
20104
|
-
if (
|
|
20105
|
-
const creds = JSON.parse(
|
|
20683
|
+
const credPath = path6.join(os5.homedir(), ".node9", "credentials.json");
|
|
20684
|
+
if (fs5.existsSync(credPath)) {
|
|
20685
|
+
const creds = JSON.parse(fs5.readFileSync(credPath, "utf-8"));
|
|
20106
20686
|
const profileName = process.env.NODE9_PROFILE || "default";
|
|
20107
20687
|
const profile = creds[profileName];
|
|
20108
20688
|
if (typeof profile?.apiKey === "string" && profile.apiKey.length > 0) {
|
|
@@ -20134,7 +20714,7 @@ function readRulesCacheResilient(cacheFile) {
|
|
|
20134
20714
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
20135
20715
|
let content;
|
|
20136
20716
|
try {
|
|
20137
|
-
content =
|
|
20717
|
+
content = fs5.readFileSync(cacheFile, "utf-8");
|
|
20138
20718
|
existed = true;
|
|
20139
20719
|
} catch (err) {
|
|
20140
20720
|
if (err.code === "ENOENT") return {};
|
|
@@ -20149,10 +20729,10 @@ function readRulesCacheResilient(cacheFile) {
|
|
|
20149
20729
|
}
|
|
20150
20730
|
}
|
|
20151
20731
|
if (existed || sawReadError) {
|
|
20152
|
-
const backup =
|
|
20732
|
+
const backup = path6.join(path6.dirname(cacheFile), "rules-cache.last-good.json");
|
|
20153
20733
|
if (backup !== cacheFile) {
|
|
20154
20734
|
try {
|
|
20155
|
-
const raw = JSON.parse(
|
|
20735
|
+
const raw = JSON.parse(fs5.readFileSync(backup, "utf-8"));
|
|
20156
20736
|
logCacheReadIssue(cacheFile, "RULES_CACHE_CORRUPT_USED_BACKUP");
|
|
20157
20737
|
lastParsedRulesCache = raw;
|
|
20158
20738
|
return raw;
|
|
@@ -20175,8 +20755,8 @@ function logCacheReadIssue(cacheFile, kind) {
|
|
|
20175
20755
|
if (now - cacheReadLastLoggedAt < CACHE_LOG_REARM_MS) return;
|
|
20176
20756
|
cacheReadLastLoggedAt = now;
|
|
20177
20757
|
try {
|
|
20178
|
-
|
|
20179
|
-
|
|
20758
|
+
fs5.appendFileSync(
|
|
20759
|
+
path6.join(os5.homedir(), ".node9", "hook-debug.log"),
|
|
20180
20760
|
`[${(/* @__PURE__ */ new Date()).toISOString()}] ${kind} ${cacheFile}
|
|
20181
20761
|
`
|
|
20182
20762
|
);
|
|
@@ -20202,8 +20782,8 @@ function catalogSettingsFrom(settings, policy) {
|
|
|
20202
20782
|
}
|
|
20203
20783
|
function getConfig(cwd) {
|
|
20204
20784
|
if (!cwd && cachedConfig) return cachedConfig;
|
|
20205
|
-
const globalPath =
|
|
20206
|
-
const projectPath =
|
|
20785
|
+
const globalPath = path6.join(os5.homedir(), ".node9", "config.json");
|
|
20786
|
+
const projectPath = path6.join(cwd ?? process.cwd(), "node9.config.json");
|
|
20207
20787
|
const globalConfig = tryLoadConfig(globalPath);
|
|
20208
20788
|
const projectConfig = tryLoadConfig(projectPath, { project: true });
|
|
20209
20789
|
const mergedSettings = {
|
|
@@ -20253,7 +20833,8 @@ function getConfig(cwd) {
|
|
|
20253
20833
|
trustedHostsManaged: false,
|
|
20254
20834
|
appPermissions: {},
|
|
20255
20835
|
appLinks: {},
|
|
20256
|
-
managedJailPaths: []
|
|
20836
|
+
managedJailPaths: [],
|
|
20837
|
+
jailPaths: []
|
|
20257
20838
|
};
|
|
20258
20839
|
const mergedEnvironments = { ...DEFAULT_CONFIG.environments };
|
|
20259
20840
|
const rank = (v) => {
|
|
@@ -20448,7 +21029,7 @@ function getConfig(cwd) {
|
|
|
20448
21029
|
let cloudMandatesEnforcement = false;
|
|
20449
21030
|
let cloudMandatesAppPerm = false;
|
|
20450
21031
|
{
|
|
20451
|
-
const cacheFile =
|
|
21032
|
+
const cacheFile = path6.join(os5.homedir(), ".node9", "rules-cache.json");
|
|
20452
21033
|
try {
|
|
20453
21034
|
const raw = readRulesCacheResilient(cacheFile);
|
|
20454
21035
|
if (Array.isArray(raw.rules) && raw.rules.length > 0) {
|
|
@@ -20648,6 +21229,7 @@ function getConfig(cwd) {
|
|
|
20648
21229
|
mergedPolicy.smartRules.push({ ...r, name: `org:${r.name}` });
|
|
20649
21230
|
}
|
|
20650
21231
|
mergedPolicy.managedJailPaths.push({ path: path33, verdict });
|
|
21232
|
+
mergedPolicy.jailPaths.push(path33);
|
|
20651
21233
|
}
|
|
20652
21234
|
}
|
|
20653
21235
|
if (Array.isArray(mc.trustedHosts)) {
|
|
@@ -20723,6 +21305,11 @@ function getConfig(cwd) {
|
|
|
20723
21305
|
}
|
|
20724
21306
|
}
|
|
20725
21307
|
mergedPolicy.appliedShields = appliedShields.sort();
|
|
21308
|
+
if (appliedShields.includes(USER_JAIL_SHIELD)) {
|
|
21309
|
+
for (const { path: path33 } of readJailPaths()) {
|
|
21310
|
+
if (!mergedPolicy.jailPaths.includes(path33)) mergedPolicy.jailPaths.push(path33);
|
|
21311
|
+
}
|
|
21312
|
+
}
|
|
20726
21313
|
const existingAdvisoryNames = new Set(mergedPolicy.smartRules.map((r) => r.name));
|
|
20727
21314
|
const cc = mergedPolicy.commandChecks ?? {};
|
|
20728
21315
|
const advisoryKnobKey = (name) => {
|
|
@@ -20880,10 +21467,10 @@ function getConfig(cwd) {
|
|
|
20880
21467
|
}
|
|
20881
21468
|
function tryLoadConfig(filePath, options = {}) {
|
|
20882
21469
|
v2ChecksByPath.delete(filePath);
|
|
20883
|
-
if (!
|
|
21470
|
+
if (!fs5.existsSync(filePath)) return null;
|
|
20884
21471
|
let raw;
|
|
20885
21472
|
try {
|
|
20886
|
-
raw = JSON.parse(
|
|
21473
|
+
raw = JSON.parse(fs5.readFileSync(filePath, "utf-8"));
|
|
20887
21474
|
} catch (err) {
|
|
20888
21475
|
const msg = err instanceof Error ? err.message : String(err);
|
|
20889
21476
|
process.stderr.write(
|
|
@@ -20989,27 +21576,27 @@ init_dist();
|
|
|
20989
21576
|
// src/policy/index.ts
|
|
20990
21577
|
init_esm_shims();
|
|
20991
21578
|
init_dist();
|
|
20992
|
-
import
|
|
21579
|
+
import fs14 from "fs";
|
|
20993
21580
|
|
|
20994
21581
|
// src/utils/read-capped.ts
|
|
20995
21582
|
init_esm_shims();
|
|
20996
|
-
import
|
|
21583
|
+
import fs6 from "fs";
|
|
20997
21584
|
function readCapped(file2, maxBytes, openFlags = "r") {
|
|
20998
21585
|
if (maxBytes < 0) return null;
|
|
20999
21586
|
let fd;
|
|
21000
21587
|
try {
|
|
21001
|
-
fd =
|
|
21588
|
+
fd = fs6.openSync(file2, openFlags);
|
|
21002
21589
|
} catch {
|
|
21003
21590
|
return null;
|
|
21004
21591
|
}
|
|
21005
21592
|
try {
|
|
21006
|
-
const st =
|
|
21593
|
+
const st = fs6.fstatSync(fd);
|
|
21007
21594
|
if (!st.isFile()) return null;
|
|
21008
21595
|
const want = Math.min(st.size, maxBytes + 1);
|
|
21009
21596
|
const buf = Buffer.alloc(want);
|
|
21010
21597
|
let read2 = 0;
|
|
21011
21598
|
while (read2 < want) {
|
|
21012
|
-
const n =
|
|
21599
|
+
const n = fs6.readSync(fd, buf, read2, want - read2, read2);
|
|
21013
21600
|
if (n <= 0) break;
|
|
21014
21601
|
read2 += n;
|
|
21015
21602
|
}
|
|
@@ -21021,7 +21608,7 @@ function readCapped(file2, maxBytes, openFlags = "r") {
|
|
|
21021
21608
|
return null;
|
|
21022
21609
|
} finally {
|
|
21023
21610
|
try {
|
|
21024
|
-
|
|
21611
|
+
fs6.closeSync(fd);
|
|
21025
21612
|
} catch {
|
|
21026
21613
|
}
|
|
21027
21614
|
}
|
|
@@ -21032,24 +21619,24 @@ function readCappedText(file2, maxBytes, openFlags = "r") {
|
|
|
21032
21619
|
}
|
|
21033
21620
|
|
|
21034
21621
|
// src/policy/index.ts
|
|
21035
|
-
import
|
|
21622
|
+
import path15 from "path";
|
|
21036
21623
|
|
|
21037
21624
|
// src/dlp.ts
|
|
21038
21625
|
init_esm_shims();
|
|
21039
21626
|
init_dist();
|
|
21040
21627
|
init_dist();
|
|
21041
|
-
import
|
|
21042
|
-
import
|
|
21628
|
+
import fs7 from "fs";
|
|
21629
|
+
import path7 from "path";
|
|
21043
21630
|
function scanFilePath(filePath, cwd = process.cwd(), options = {}) {
|
|
21044
21631
|
if (!filePath) return null;
|
|
21045
21632
|
let resolved;
|
|
21046
21633
|
try {
|
|
21047
|
-
const absolute2 =
|
|
21048
|
-
resolved =
|
|
21634
|
+
const absolute2 = path7.resolve(cwd, filePath);
|
|
21635
|
+
resolved = fs7.realpathSync.native(absolute2);
|
|
21049
21636
|
} catch (err) {
|
|
21050
21637
|
const code = err.code;
|
|
21051
21638
|
if (code === "ENOENT" || code === "ENOTDIR") {
|
|
21052
|
-
resolved =
|
|
21639
|
+
resolved = path7.resolve(cwd, filePath);
|
|
21053
21640
|
} else {
|
|
21054
21641
|
return sensitivePathMatch(filePath);
|
|
21055
21642
|
}
|
|
@@ -21272,29 +21859,29 @@ function combineWithEngine(gates, engine, opts = { panicMode: false }) {
|
|
|
21272
21859
|
// src/policy/file-access.ts
|
|
21273
21860
|
init_esm_shims();
|
|
21274
21861
|
init_dist();
|
|
21275
|
-
import
|
|
21276
|
-
import
|
|
21277
|
-
import
|
|
21862
|
+
import fs8 from "fs";
|
|
21863
|
+
import os6 from "os";
|
|
21864
|
+
import path8 from "path";
|
|
21278
21865
|
function absoluteSpelling(p, cwd, home) {
|
|
21279
21866
|
if (p === "~" || p.startsWith("~/")) p = home + p.slice(1);
|
|
21280
|
-
return
|
|
21867
|
+
return path8.isAbsolute(p) ? p : `${cwd}/${p}`;
|
|
21281
21868
|
}
|
|
21282
21869
|
function physical(p, followFinal, links = 0) {
|
|
21283
21870
|
if (links > 40) throw new Error("Too many symbolic links");
|
|
21284
21871
|
if (!followFinal) {
|
|
21285
|
-
const parent = physical(
|
|
21286
|
-
return { path: `${parent.path}/${
|
|
21872
|
+
const parent = physical(path8.dirname(p), true, links);
|
|
21873
|
+
return { path: `${parent.path}/${path8.basename(p)}`, missing: parent.missing };
|
|
21287
21874
|
}
|
|
21288
21875
|
try {
|
|
21289
|
-
return { path:
|
|
21876
|
+
return { path: fs8.realpathSync.native(p), missing: false };
|
|
21290
21877
|
} catch (error) {
|
|
21291
21878
|
const code = error.code;
|
|
21292
21879
|
if (!["ENOENT", "ENOTDIR"].includes(code ?? "")) throw error;
|
|
21293
21880
|
try {
|
|
21294
|
-
if (
|
|
21295
|
-
const target =
|
|
21881
|
+
if (fs8.lstatSync(p).isSymbolicLink()) {
|
|
21882
|
+
const target = fs8.readlinkSync(p);
|
|
21296
21883
|
return physical(
|
|
21297
|
-
|
|
21884
|
+
path8.isAbsolute(target) ? target : `${path8.dirname(p)}/${target}`,
|
|
21298
21885
|
true,
|
|
21299
21886
|
links + 1
|
|
21300
21887
|
);
|
|
@@ -21303,13 +21890,13 @@ function physical(p, followFinal, links = 0) {
|
|
|
21303
21890
|
if (!["ENOENT", "ENOTDIR"].includes(linkError.code ?? ""))
|
|
21304
21891
|
throw linkError;
|
|
21305
21892
|
}
|
|
21306
|
-
const parent =
|
|
21893
|
+
const parent = path8.dirname(p);
|
|
21307
21894
|
if (parent === p) return { path: p, missing: true };
|
|
21308
21895
|
const resolved = physical(parent, true, links);
|
|
21309
|
-
return { path: `${resolved.path}/${
|
|
21896
|
+
return { path: `${resolved.path}/${path8.basename(p)}`, missing: true };
|
|
21310
21897
|
}
|
|
21311
21898
|
}
|
|
21312
|
-
function prepareFileAccesses(tool, args, cwd = process.cwd(), inspection = {}, home =
|
|
21899
|
+
function prepareFileAccesses(tool, args, cwd = process.cwd(), inspection = {}, home = os6.homedir()) {
|
|
21313
21900
|
const context = { cwd, homeDirs: [home, "/root"] };
|
|
21314
21901
|
const accesses = collectFileAccesses(tool, args, context, inspection);
|
|
21315
21902
|
const handledPaths = /* @__PURE__ */ new Set();
|
|
@@ -21332,14 +21919,14 @@ function prepareFileAccesses(tool, args, cwd = process.cwd(), inspection = {}, h
|
|
|
21332
21919
|
const raw = absoluteSpelling(access.path, access.cwd ?? cwd, home);
|
|
21333
21920
|
if (access.directoryTarget) {
|
|
21334
21921
|
try {
|
|
21335
|
-
if (!
|
|
21922
|
+
if (!fs8.statSync(absoluteSpelling(access.directoryTarget, access.cwd ?? cwd, home)).isDirectory())
|
|
21336
21923
|
continue;
|
|
21337
21924
|
} catch {
|
|
21338
21925
|
}
|
|
21339
21926
|
}
|
|
21340
21927
|
if (access.operation === "create") {
|
|
21341
21928
|
try {
|
|
21342
|
-
|
|
21929
|
+
fs8.statSync(raw);
|
|
21343
21930
|
continue;
|
|
21344
21931
|
} catch {
|
|
21345
21932
|
}
|
|
@@ -21391,39 +21978,39 @@ function prepareFileAccesses(tool, args, cwd = process.cwd(), inspection = {}, h
|
|
|
21391
21978
|
init_esm_shims();
|
|
21392
21979
|
init_dist();
|
|
21393
21980
|
import picomatch3 from "picomatch";
|
|
21394
|
-
import
|
|
21981
|
+
import path12 from "path";
|
|
21395
21982
|
|
|
21396
21983
|
// src/supply-chain/osv-index.ts
|
|
21397
21984
|
init_esm_shims();
|
|
21398
21985
|
init_dist();
|
|
21399
|
-
import
|
|
21400
|
-
import
|
|
21401
|
-
import
|
|
21986
|
+
import fs10 from "fs";
|
|
21987
|
+
import os7 from "os";
|
|
21988
|
+
import path10 from "path";
|
|
21402
21989
|
import { createHash as createHash4 } from "crypto";
|
|
21403
21990
|
|
|
21404
21991
|
// src/utils/atomic-write.ts
|
|
21405
21992
|
init_esm_shims();
|
|
21406
|
-
import
|
|
21407
|
-
import
|
|
21993
|
+
import fs9 from "fs";
|
|
21994
|
+
import path9 from "path";
|
|
21408
21995
|
import { randomUUID } from "crypto";
|
|
21409
21996
|
function atomicWriteSync(filePath, data, options) {
|
|
21410
|
-
const dir2 =
|
|
21411
|
-
if (!
|
|
21997
|
+
const dir2 = path9.dirname(filePath);
|
|
21998
|
+
if (!fs9.existsSync(dir2)) fs9.mkdirSync(dir2, { recursive: true });
|
|
21412
21999
|
const tmpPath = `${filePath}.${randomUUID()}.tmp`;
|
|
21413
22000
|
try {
|
|
21414
|
-
|
|
22001
|
+
fs9.writeFileSync(tmpPath, data, options);
|
|
21415
22002
|
} catch (err) {
|
|
21416
22003
|
try {
|
|
21417
|
-
|
|
22004
|
+
fs9.unlinkSync(tmpPath);
|
|
21418
22005
|
} catch {
|
|
21419
22006
|
}
|
|
21420
22007
|
throw err;
|
|
21421
22008
|
}
|
|
21422
22009
|
try {
|
|
21423
|
-
|
|
22010
|
+
fs9.renameSync(tmpPath, filePath);
|
|
21424
22011
|
} catch (err) {
|
|
21425
22012
|
try {
|
|
21426
|
-
|
|
22013
|
+
fs9.unlinkSync(tmpPath);
|
|
21427
22014
|
} catch {
|
|
21428
22015
|
}
|
|
21429
22016
|
throw err;
|
|
@@ -21433,10 +22020,10 @@ function atomicWriteSync(filePath, data, options) {
|
|
|
21433
22020
|
// src/supply-chain/osv-index.ts
|
|
21434
22021
|
var INDEX_FRESH_MS = 72 * 60 * 60 * 1e3;
|
|
21435
22022
|
function osvRoot() {
|
|
21436
|
-
return
|
|
22023
|
+
return path10.join(os7.homedir(), ".node9", "osv");
|
|
21437
22024
|
}
|
|
21438
22025
|
function ecoDir(eco) {
|
|
21439
|
-
return
|
|
22026
|
+
return path10.join(osvRoot(), eco);
|
|
21440
22027
|
}
|
|
21441
22028
|
function indexKey(eco, name) {
|
|
21442
22029
|
switch (eco) {
|
|
@@ -21455,11 +22042,11 @@ function shardOf(key) {
|
|
|
21455
22042
|
return createHash4("sha1").update(key).digest("hex").slice(0, 2);
|
|
21456
22043
|
}
|
|
21457
22044
|
function shardPath(eco, shard) {
|
|
21458
|
-
return
|
|
22045
|
+
return path10.join(ecoDir(eco), "shards", `${shard}.json`);
|
|
21459
22046
|
}
|
|
21460
22047
|
function readMeta(eco) {
|
|
21461
22048
|
try {
|
|
21462
|
-
const m = JSON.parse(
|
|
22049
|
+
const m = JSON.parse(fs10.readFileSync(path10.join(ecoDir(eco), "meta.json"), "utf8"));
|
|
21463
22050
|
if (typeof m?.syncedAt !== "string" || typeof m?.lastModifiedMs !== "number") return null;
|
|
21464
22051
|
return m;
|
|
21465
22052
|
} catch {
|
|
@@ -21468,7 +22055,7 @@ function readMeta(eco) {
|
|
|
21468
22055
|
}
|
|
21469
22056
|
function readShard(eco, shard) {
|
|
21470
22057
|
try {
|
|
21471
|
-
const s = JSON.parse(
|
|
22058
|
+
const s = JSON.parse(fs10.readFileSync(shardPath(eco, shard), "utf8"));
|
|
21472
22059
|
return s && typeof s === "object" && !Array.isArray(s) ? s : {};
|
|
21473
22060
|
} catch {
|
|
21474
22061
|
return {};
|
|
@@ -21822,19 +22409,19 @@ async function registryInfo(eco, name, version, freshWindowMs, raw) {
|
|
|
21822
22409
|
|
|
21823
22410
|
// src/supply-chain/local-resolve.ts
|
|
21824
22411
|
init_esm_shims();
|
|
21825
|
-
import
|
|
21826
|
-
import
|
|
22412
|
+
import fs11 from "fs";
|
|
22413
|
+
import path11 from "path";
|
|
21827
22414
|
var MAX_LEVELS = 32;
|
|
21828
22415
|
var LOCAL_FIRST_MANAGERS = /* @__PURE__ */ new Set(["npx", "bunx", "npm exec"]);
|
|
21829
22416
|
function resolveInstalled(name, cwd) {
|
|
21830
|
-
if (!cwd || !
|
|
22417
|
+
if (!cwd || !path11.isAbsolute(cwd)) return null;
|
|
21831
22418
|
if (!/^(?:@[^/\\]+\/)?[^/\\]+$/.test(name)) return null;
|
|
21832
|
-
let dir2 =
|
|
22419
|
+
let dir2 = path11.resolve(cwd);
|
|
21833
22420
|
for (let i = 0; i < MAX_LEVELS; i++) {
|
|
21834
|
-
const pkgDir =
|
|
21835
|
-
const manifest =
|
|
22421
|
+
const pkgDir = path11.join(dir2, "node_modules", ...name.split("/"));
|
|
22422
|
+
const manifest = path11.join(pkgDir, "package.json");
|
|
21836
22423
|
try {
|
|
21837
|
-
const raw =
|
|
22424
|
+
const raw = fs11.readFileSync(manifest, "utf8");
|
|
21838
22425
|
const parsed = JSON.parse(raw);
|
|
21839
22426
|
if (typeof parsed.version === "string" && parsed.version.length > 0) {
|
|
21840
22427
|
return { version: parsed.version, dir: pkgDir };
|
|
@@ -21842,7 +22429,7 @@ function resolveInstalled(name, cwd) {
|
|
|
21842
22429
|
return null;
|
|
21843
22430
|
} catch {
|
|
21844
22431
|
}
|
|
21845
|
-
const parent =
|
|
22432
|
+
const parent = path11.dirname(dir2);
|
|
21846
22433
|
if (parent === dir2) break;
|
|
21847
22434
|
dir2 = parent;
|
|
21848
22435
|
}
|
|
@@ -21964,7 +22551,7 @@ function checkInstalled(p, version, misses) {
|
|
|
21964
22551
|
}
|
|
21965
22552
|
async function checkOne(p, cfg, misses, networkCapped, cwd) {
|
|
21966
22553
|
if (p.ecosystem === "npm" && LOCAL_FIRST_MANAGERS.has(p.manager) && p.localCwd !== null && (p.raw === p.name || p.version)) {
|
|
21967
|
-
const localCwd = cwd &&
|
|
22554
|
+
const localCwd = cwd && path12.isAbsolute(cwd) ? (p.localCwd ?? []).reduce((dir2, step) => path12.resolve(dir2, step), cwd) : void 0;
|
|
21968
22555
|
const installed = resolveInstalled(p.name, localCwd);
|
|
21969
22556
|
if (installed && (!p.version || p.version === installed.version))
|
|
21970
22557
|
return checkInstalled(p, installed.version, misses);
|
|
@@ -22110,9 +22697,9 @@ async function runPackageCheck(toolName, args, cfg, cwd, opts = {}) {
|
|
|
22110
22697
|
// src/supply-chain/registries.ts
|
|
22111
22698
|
init_esm_shims();
|
|
22112
22699
|
init_dist();
|
|
22113
|
-
import
|
|
22114
|
-
import
|
|
22115
|
-
import
|
|
22700
|
+
import os8 from "os";
|
|
22701
|
+
import path13 from "path";
|
|
22702
|
+
import fs12 from "fs";
|
|
22116
22703
|
var MAX_CONFIG_BYTES = 256 * 1024;
|
|
22117
22704
|
var MAX_PARENT_DIRS = 12;
|
|
22118
22705
|
var TTL_MS = 5e3;
|
|
@@ -22153,29 +22740,29 @@ var REGISTRY_KEY_RE = /registry|index|find-links|mirror/i;
|
|
|
22153
22740
|
var REGISTRY_SECTION_RE = /index|source|registr|scopes|mirror/i;
|
|
22154
22741
|
var URL_RE2 = /https?:\/\/[^\s"'<>,;]+/gi;
|
|
22155
22742
|
function userFiles(home, env) {
|
|
22156
|
-
const xdg = env.XDG_CONFIG_HOME ||
|
|
22743
|
+
const xdg = env.XDG_CONFIG_HOME || path13.join(home, ".config");
|
|
22157
22744
|
return [
|
|
22158
|
-
env.NPM_CONFIG_USERCONFIG || env.npm_config_userconfig ||
|
|
22159
|
-
|
|
22160
|
-
|
|
22161
|
-
|
|
22745
|
+
env.NPM_CONFIG_USERCONFIG || env.npm_config_userconfig || path13.join(home, ".npmrc"),
|
|
22746
|
+
path13.join(home, ".yarnrc"),
|
|
22747
|
+
path13.join(home, ".yarnrc.yml"),
|
|
22748
|
+
path13.join(home, ".bunfig.toml"),
|
|
22162
22749
|
env.PIP_CONFIG_FILE || "",
|
|
22163
|
-
|
|
22164
|
-
|
|
22750
|
+
path13.join(xdg, "pip", "pip.conf"),
|
|
22751
|
+
path13.join(home, ".pip", "pip.conf"),
|
|
22165
22752
|
"/etc/pip.conf",
|
|
22166
|
-
env.VIRTUAL_ENV ?
|
|
22753
|
+
env.VIRTUAL_ENV ? path13.join(env.VIRTUAL_ENV, "pip.conf") : "",
|
|
22167
22754
|
env.UV_CONFIG_FILE || "",
|
|
22168
|
-
|
|
22755
|
+
path13.join(xdg, "uv", "uv.toml"),
|
|
22169
22756
|
"/etc/uv/uv.toml"
|
|
22170
22757
|
].filter(Boolean);
|
|
22171
22758
|
}
|
|
22172
22759
|
function projectFiles(cwd) {
|
|
22173
|
-
if (!cwd || !
|
|
22760
|
+
if (!cwd || !path13.isAbsolute(cwd)) return [];
|
|
22174
22761
|
const out = [];
|
|
22175
22762
|
let dir2 = cwd;
|
|
22176
22763
|
for (let i = 0; i < MAX_PARENT_DIRS; i++) {
|
|
22177
|
-
for (const f of PROJECT_FILES) out.push(
|
|
22178
|
-
const parent =
|
|
22764
|
+
for (const f of PROJECT_FILES) out.push(path13.join(dir2, f));
|
|
22765
|
+
const parent = path13.dirname(dir2);
|
|
22179
22766
|
if (parent === dir2) break;
|
|
22180
22767
|
dir2 = parent;
|
|
22181
22768
|
}
|
|
@@ -22215,7 +22802,7 @@ function hostsInText(text, out) {
|
|
|
22215
22802
|
}
|
|
22216
22803
|
}
|
|
22217
22804
|
var cache3 = /* @__PURE__ */ new Map();
|
|
22218
|
-
function configuredRegistryHosts(cwd, env = process.env, home =
|
|
22805
|
+
function configuredRegistryHosts(cwd, env = process.env, home = os8.homedir()) {
|
|
22219
22806
|
const key = [
|
|
22220
22807
|
cwd ?? "",
|
|
22221
22808
|
home,
|
|
@@ -22237,7 +22824,7 @@ function configuredRegistryHosts(cwd, env = process.env, home = os7.homedir()) {
|
|
|
22237
22824
|
const r = readCappedText(
|
|
22238
22825
|
file2,
|
|
22239
22826
|
MAX_CONFIG_BYTES,
|
|
22240
|
-
|
|
22827
|
+
fs12.constants.O_RDONLY | (fs12.constants.O_NONBLOCK ?? 0)
|
|
22241
22828
|
);
|
|
22242
22829
|
if (r) hostsInText(r.text, hosts);
|
|
22243
22830
|
}
|
|
@@ -22247,27 +22834,27 @@ function configuredRegistryHosts(cwd, env = process.env, home = os7.homedir()) {
|
|
|
22247
22834
|
|
|
22248
22835
|
// src/utils/provenance.ts
|
|
22249
22836
|
init_esm_shims();
|
|
22250
|
-
import
|
|
22251
|
-
import
|
|
22252
|
-
import
|
|
22837
|
+
import fs13 from "fs";
|
|
22838
|
+
import path14 from "path";
|
|
22839
|
+
import os9 from "os";
|
|
22253
22840
|
var SYSTEM_PREFIXES = ["/usr/bin", "/usr/sbin", "/bin", "/sbin"];
|
|
22254
22841
|
var MANAGED_PREFIXES = ["/usr/local/bin", "/opt/homebrew", "/home/linuxbrew", "/nix/store"];
|
|
22255
22842
|
var USER_PREFIXES = [
|
|
22256
|
-
|
|
22257
|
-
|
|
22258
|
-
|
|
22259
|
-
|
|
22260
|
-
|
|
22843
|
+
path14.join(os9.homedir(), "bin"),
|
|
22844
|
+
path14.join(os9.homedir(), ".local", "bin"),
|
|
22845
|
+
path14.join(os9.homedir(), ".cargo", "bin"),
|
|
22846
|
+
path14.join(os9.homedir(), ".npm-global", "bin"),
|
|
22847
|
+
path14.join(os9.homedir(), ".volta", "bin")
|
|
22261
22848
|
];
|
|
22262
22849
|
var SUSPECT_PREFIXES = ["/tmp", "/var/tmp", "/dev/shm"];
|
|
22263
22850
|
function findInPath(cmd) {
|
|
22264
|
-
if (
|
|
22851
|
+
if (path14.posix.isAbsolute(cmd)) return cmd;
|
|
22265
22852
|
const pathEnv = process.env.PATH ?? "";
|
|
22266
|
-
for (const dir2 of pathEnv.split(
|
|
22853
|
+
for (const dir2 of pathEnv.split(path14.delimiter)) {
|
|
22267
22854
|
if (!dir2) continue;
|
|
22268
|
-
const full =
|
|
22855
|
+
const full = path14.join(dir2, cmd);
|
|
22269
22856
|
try {
|
|
22270
|
-
|
|
22857
|
+
fs13.accessSync(full, fs13.constants.X_OK);
|
|
22271
22858
|
return full;
|
|
22272
22859
|
} catch {
|
|
22273
22860
|
}
|
|
@@ -22278,7 +22865,7 @@ function _classifyPath(resolved, cwd) {
|
|
|
22278
22865
|
if (cwd && resolved.startsWith(cwd + "/")) {
|
|
22279
22866
|
return { trustLevel: "user", reason: "binary in project directory" };
|
|
22280
22867
|
}
|
|
22281
|
-
const osTmp =
|
|
22868
|
+
const osTmp = os9.tmpdir();
|
|
22282
22869
|
const allSuspect = osTmp ? [...SUSPECT_PREFIXES, osTmp] : SUSPECT_PREFIXES;
|
|
22283
22870
|
if (allSuspect.some((p) => resolved === p || resolved.startsWith(p + "/"))) {
|
|
22284
22871
|
return { trustLevel: "suspect", reason: `binary in temp directory: ${resolved}` };
|
|
@@ -22296,7 +22883,7 @@ function _classifyPath(resolved, cwd) {
|
|
|
22296
22883
|
}
|
|
22297
22884
|
function checkProvenance(cmd, cwd) {
|
|
22298
22885
|
const bare = cmd.startsWith("./") ? cmd.slice(2) : cmd;
|
|
22299
|
-
if (
|
|
22886
|
+
if (path14.posix.isAbsolute(bare)) {
|
|
22300
22887
|
const early = _classifyPath(bare, cwd);
|
|
22301
22888
|
if (early.trustLevel === "suspect") {
|
|
22302
22889
|
return { resolvedPath: bare, ...early };
|
|
@@ -22312,7 +22899,7 @@ function checkProvenance(cmd, cwd) {
|
|
|
22312
22899
|
reason: "binary not found in PATH"
|
|
22313
22900
|
};
|
|
22314
22901
|
}
|
|
22315
|
-
resolved =
|
|
22902
|
+
resolved = fs13.realpathSync(found);
|
|
22316
22903
|
} catch {
|
|
22317
22904
|
return {
|
|
22318
22905
|
resolvedPath: cmd,
|
|
@@ -22321,7 +22908,7 @@ function checkProvenance(cmd, cwd) {
|
|
|
22321
22908
|
};
|
|
22322
22909
|
}
|
|
22323
22910
|
try {
|
|
22324
|
-
const stat =
|
|
22911
|
+
const stat = fs13.statSync(resolved);
|
|
22325
22912
|
if (stat.mode & 2) {
|
|
22326
22913
|
return {
|
|
22327
22914
|
resolvedPath: resolved,
|
|
@@ -22375,9 +22962,9 @@ async function evaluatePolicy2(toolName, args, agent, cwd, opts) {
|
|
|
22375
22962
|
);
|
|
22376
22963
|
}
|
|
22377
22964
|
function isGitWorkTreeTop(dir2, cwd) {
|
|
22378
|
-
if (!
|
|
22965
|
+
if (!path15.isAbsolute(cwd)) return true;
|
|
22379
22966
|
try {
|
|
22380
|
-
return
|
|
22967
|
+
return fs14.existsSync(path15.join(path15.resolve(cwd, dir2), ".git"));
|
|
22381
22968
|
} catch {
|
|
22382
22969
|
return true;
|
|
22383
22970
|
}
|
|
@@ -22387,7 +22974,7 @@ function readAgentSettings(absPath) {
|
|
|
22387
22974
|
const r = readCappedText(
|
|
22388
22975
|
absPath,
|
|
22389
22976
|
MAX_AGENT_SETTINGS_BYTES,
|
|
22390
|
-
|
|
22977
|
+
fs14.constants.O_RDONLY | (fs14.constants.O_NONBLOCK ?? 0)
|
|
22391
22978
|
);
|
|
22392
22979
|
return r && !r.truncated ? r.text : null;
|
|
22393
22980
|
}
|
|
@@ -22397,12 +22984,12 @@ function isIgnoredTool2(toolName) {
|
|
|
22397
22984
|
|
|
22398
22985
|
// src/auth/state.ts
|
|
22399
22986
|
init_esm_shims();
|
|
22400
|
-
import
|
|
22401
|
-
import
|
|
22402
|
-
import
|
|
22987
|
+
import fs15 from "fs";
|
|
22988
|
+
import path16 from "path";
|
|
22989
|
+
import os10 from "os";
|
|
22403
22990
|
init_forecast_context();
|
|
22404
|
-
var PAUSED_FILE =
|
|
22405
|
-
var TRUST_FILE =
|
|
22991
|
+
var PAUSED_FILE = path16.join(os10.homedir(), ".node9", "PAUSED");
|
|
22992
|
+
var TRUST_FILE = path16.join(os10.homedir(), ".node9", "trust.json");
|
|
22406
22993
|
function extractCommandPattern(toolName, args) {
|
|
22407
22994
|
const lower2 = toolName.toLowerCase();
|
|
22408
22995
|
if (lower2 !== "bash" && lower2 !== "execute_bash" && lower2 !== "shell") return void 0;
|
|
@@ -22415,11 +23002,11 @@ function extractCommandPattern(toolName, args) {
|
|
|
22415
23002
|
function checkPause() {
|
|
22416
23003
|
if (forecastRun()) return { paused: false };
|
|
22417
23004
|
try {
|
|
22418
|
-
if (!
|
|
22419
|
-
const state = JSON.parse(
|
|
23005
|
+
if (!fs15.existsSync(PAUSED_FILE)) return { paused: false };
|
|
23006
|
+
const state = JSON.parse(fs15.readFileSync(PAUSED_FILE, "utf-8"));
|
|
22420
23007
|
if (state.expiry > 0 && Date.now() >= state.expiry) {
|
|
22421
23008
|
try {
|
|
22422
|
-
|
|
23009
|
+
fs15.unlinkSync(PAUSED_FILE);
|
|
22423
23010
|
} catch {
|
|
22424
23011
|
}
|
|
22425
23012
|
return { paused: false };
|
|
@@ -22432,8 +23019,8 @@ function checkPause() {
|
|
|
22432
23019
|
function getActiveTrustSession(toolName, args) {
|
|
22433
23020
|
if (forecastRun()) return false;
|
|
22434
23021
|
try {
|
|
22435
|
-
if (!
|
|
22436
|
-
const trust = JSON.parse(
|
|
23022
|
+
if (!fs15.existsSync(TRUST_FILE)) return false;
|
|
23023
|
+
const trust = JSON.parse(fs15.readFileSync(TRUST_FILE, "utf-8"));
|
|
22437
23024
|
const now = Date.now();
|
|
22438
23025
|
const active = trust.entries.filter((e) => e.expiry > now);
|
|
22439
23026
|
if (active.length !== trust.entries.length) {
|
|
@@ -22456,8 +23043,8 @@ function writeTrustSession(toolName, durationMs, args) {
|
|
|
22456
23043
|
try {
|
|
22457
23044
|
let trust = { entries: [] };
|
|
22458
23045
|
try {
|
|
22459
|
-
if (
|
|
22460
|
-
trust = JSON.parse(
|
|
23046
|
+
if (fs15.existsSync(TRUST_FILE)) {
|
|
23047
|
+
trust = JSON.parse(fs15.readFileSync(TRUST_FILE, "utf-8"));
|
|
22461
23048
|
}
|
|
22462
23049
|
} catch {
|
|
22463
23050
|
}
|
|
@@ -22479,9 +23066,9 @@ function writeTrustSession(toolName, durationMs, args) {
|
|
|
22479
23066
|
}
|
|
22480
23067
|
function getPersistentDecision(toolName) {
|
|
22481
23068
|
try {
|
|
22482
|
-
const file2 =
|
|
22483
|
-
if (!
|
|
22484
|
-
const decisions = JSON.parse(
|
|
23069
|
+
const file2 = path16.join(os10.homedir(), ".node9", "decisions.json");
|
|
23070
|
+
if (!fs15.existsSync(file2)) return null;
|
|
23071
|
+
const decisions = JSON.parse(fs15.readFileSync(file2, "utf-8"));
|
|
22485
23072
|
const d = decisions[toolName];
|
|
22486
23073
|
if (d === "allow" || d === "deny") return d;
|
|
22487
23074
|
} catch {
|
|
@@ -22492,16 +23079,16 @@ function getPersistentDecision(toolName) {
|
|
|
22492
23079
|
// src/auth/daemon.ts
|
|
22493
23080
|
init_esm_shims();
|
|
22494
23081
|
init_forecast_context();
|
|
22495
|
-
import
|
|
23082
|
+
import fs17 from "fs";
|
|
22496
23083
|
import http from "http";
|
|
22497
23084
|
import net from "net";
|
|
22498
|
-
import
|
|
22499
|
-
import
|
|
23085
|
+
import path18 from "path";
|
|
23086
|
+
import os11 from "os";
|
|
22500
23087
|
|
|
22501
23088
|
// src/utils/activity-socket.ts
|
|
22502
23089
|
init_esm_shims();
|
|
22503
|
-
import
|
|
22504
|
-
import
|
|
23090
|
+
import fs16 from "fs";
|
|
23091
|
+
import path17 from "path";
|
|
22505
23092
|
|
|
22506
23093
|
// src/utils/own-dir.ts
|
|
22507
23094
|
init_esm_shims();
|
|
@@ -22510,7 +23097,7 @@ init_esm_shims();
|
|
|
22510
23097
|
var currentUid = () => typeof process.getuid === "function" ? process.getuid() : void 0;
|
|
22511
23098
|
function isPrivateDir(dir2, uid = currentUid()) {
|
|
22512
23099
|
try {
|
|
22513
|
-
const st =
|
|
23100
|
+
const st = fs16.lstatSync(dir2);
|
|
22514
23101
|
if (st.isSymbolicLink() || !st.isDirectory()) return false;
|
|
22515
23102
|
if (uid !== void 0 && st.uid !== uid) return false;
|
|
22516
23103
|
return (st.mode & 18) === 0;
|
|
@@ -22522,13 +23109,13 @@ var WINDOWS_PIPE = /^\\\\\.\\pipe\\node9-activity-[0-9a-f]{32}$/;
|
|
|
22522
23109
|
function isTrustedActivitySocket(socketPath, uid = currentUid()) {
|
|
22523
23110
|
if (process.platform === "win32") return WINDOWS_PIPE.test(socketPath);
|
|
22524
23111
|
try {
|
|
22525
|
-
const st =
|
|
23112
|
+
const st = fs16.lstatSync(socketPath);
|
|
22526
23113
|
if (!st.isSocket()) return false;
|
|
22527
23114
|
if (uid !== void 0 && st.uid !== uid) return false;
|
|
22528
23115
|
} catch {
|
|
22529
23116
|
return false;
|
|
22530
23117
|
}
|
|
22531
|
-
return isPrivateDir(
|
|
23118
|
+
return isPrivateDir(path17.dirname(socketPath), uid);
|
|
22532
23119
|
}
|
|
22533
23120
|
|
|
22534
23121
|
// src/auth/decision-record.ts
|
|
@@ -22680,9 +23267,9 @@ function recordFromLegacyWait(body, now = Date.now()) {
|
|
|
22680
23267
|
}
|
|
22681
23268
|
|
|
22682
23269
|
// src/auth/daemon.ts
|
|
22683
|
-
function daemonActivitySocket(home =
|
|
23270
|
+
function daemonActivitySocket(home = os11.homedir()) {
|
|
22684
23271
|
try {
|
|
22685
|
-
const raw =
|
|
23272
|
+
const raw = fs17.readFileSync(path18.join(home, ".node9", "daemon.pid"), "utf-8");
|
|
22686
23273
|
const p = JSON.parse(raw).activitySocket;
|
|
22687
23274
|
return typeof p === "string" && isTrustedActivitySocket(p) ? p : null;
|
|
22688
23275
|
} catch {
|
|
@@ -22746,9 +23333,9 @@ var DAEMON_HOST = "127.0.0.1";
|
|
|
22746
23333
|
function getInternalToken() {
|
|
22747
23334
|
if (forecastRun()) return null;
|
|
22748
23335
|
try {
|
|
22749
|
-
const pidFile =
|
|
22750
|
-
if (!
|
|
22751
|
-
const data = JSON.parse(
|
|
23336
|
+
const pidFile = path18.join(os11.homedir(), ".node9", "daemon.pid");
|
|
23337
|
+
if (!fs17.existsSync(pidFile)) return null;
|
|
23338
|
+
const data = JSON.parse(fs17.readFileSync(pidFile, "utf-8"));
|
|
22752
23339
|
process.kill(data.pid, 0);
|
|
22753
23340
|
return data.internalToken ?? null;
|
|
22754
23341
|
} catch {
|
|
@@ -22757,12 +23344,12 @@ function getInternalToken() {
|
|
|
22757
23344
|
}
|
|
22758
23345
|
function isDaemonRunning() {
|
|
22759
23346
|
if (forecastRun()) return false;
|
|
22760
|
-
const pidFile =
|
|
22761
|
-
if (
|
|
23347
|
+
const pidFile = path18.join(os11.homedir(), ".node9", "daemon.pid");
|
|
23348
|
+
if (fs17.existsSync(pidFile)) {
|
|
22762
23349
|
let pid;
|
|
22763
23350
|
let port;
|
|
22764
23351
|
try {
|
|
22765
|
-
const data = JSON.parse(
|
|
23352
|
+
const data = JSON.parse(fs17.readFileSync(pidFile, "utf-8"));
|
|
22766
23353
|
pid = data.pid;
|
|
22767
23354
|
port = data.port;
|
|
22768
23355
|
} catch {
|
|
@@ -22780,7 +23367,7 @@ function isDaemonRunning() {
|
|
|
22780
23367
|
} catch (err) {
|
|
22781
23368
|
if (err instanceof Error && "code" in err && err.code === "ESRCH") {
|
|
22782
23369
|
try {
|
|
22783
|
-
|
|
23370
|
+
fs17.unlinkSync(pidFile);
|
|
22784
23371
|
} catch {
|
|
22785
23372
|
}
|
|
22786
23373
|
}
|
|
@@ -23120,9 +23707,9 @@ import { randomUUID as randomUUID2 } from "crypto";
|
|
|
23120
23707
|
|
|
23121
23708
|
// src/apps/state.ts
|
|
23122
23709
|
init_esm_shims();
|
|
23123
|
-
import
|
|
23124
|
-
import
|
|
23125
|
-
import
|
|
23710
|
+
import fs19 from "fs";
|
|
23711
|
+
import os13 from "os";
|
|
23712
|
+
import path20 from "path";
|
|
23126
23713
|
|
|
23127
23714
|
// src/apps/catalog.ts
|
|
23128
23715
|
init_esm_shims();
|
|
@@ -23256,22 +23843,22 @@ init_audit();
|
|
|
23256
23843
|
|
|
23257
23844
|
// src/daemon/mcp-tools.ts
|
|
23258
23845
|
init_esm_shims();
|
|
23259
|
-
import
|
|
23260
|
-
import
|
|
23261
|
-
import
|
|
23846
|
+
import fs18 from "fs";
|
|
23847
|
+
import path19 from "path";
|
|
23848
|
+
import os12 from "os";
|
|
23262
23849
|
|
|
23263
23850
|
// src/mcp-cmd.ts
|
|
23264
23851
|
init_esm_shims();
|
|
23265
23852
|
|
|
23266
23853
|
// src/daemon/mcp-tools.ts
|
|
23267
23854
|
function getMcpToolsFile() {
|
|
23268
|
-
return
|
|
23855
|
+
return path19.join(os12.homedir(), ".node9", "mcp-tools.json");
|
|
23269
23856
|
}
|
|
23270
23857
|
function readMcpToolsConfig() {
|
|
23271
23858
|
try {
|
|
23272
23859
|
const file2 = getMcpToolsFile();
|
|
23273
|
-
if (!
|
|
23274
|
-
const raw =
|
|
23860
|
+
if (!fs18.existsSync(file2)) return {};
|
|
23861
|
+
const raw = fs18.readFileSync(file2, "utf-8");
|
|
23275
23862
|
return JSON.parse(raw);
|
|
23276
23863
|
} catch {
|
|
23277
23864
|
return {};
|
|
@@ -23279,8 +23866,8 @@ function readMcpToolsConfig() {
|
|
|
23279
23866
|
}
|
|
23280
23867
|
|
|
23281
23868
|
// src/apps/state.ts
|
|
23282
|
-
function appsFilePath(home =
|
|
23283
|
-
return
|
|
23869
|
+
function appsFilePath(home = os13.homedir()) {
|
|
23870
|
+
return path20.join(home, ".node9", "apps.json");
|
|
23284
23871
|
}
|
|
23285
23872
|
var SIGNAL_KINDS = /* @__PURE__ */ new Set(["mcp-server", "command", "package", "env-name"]);
|
|
23286
23873
|
function emptyFile() {
|
|
@@ -23328,7 +23915,7 @@ function readAppsFile(home) {
|
|
|
23328
23915
|
function readAppsFileStrict(home) {
|
|
23329
23916
|
let text;
|
|
23330
23917
|
try {
|
|
23331
|
-
text =
|
|
23918
|
+
text = fs19.readFileSync(appsFilePath(home), "utf8");
|
|
23332
23919
|
} catch (e) {
|
|
23333
23920
|
return e.code === "ENOENT" ? emptyFile() : null;
|
|
23334
23921
|
}
|
|
@@ -23343,7 +23930,7 @@ var NO_LINKS = /* @__PURE__ */ Object.create(null);
|
|
|
23343
23930
|
function localLinks() {
|
|
23344
23931
|
const file2 = appsFilePath();
|
|
23345
23932
|
try {
|
|
23346
|
-
const mtimeMs =
|
|
23933
|
+
const mtimeMs = fs19.statSync(file2).mtimeMs;
|
|
23347
23934
|
if (!linkCache || linkCache.file !== file2 || linkCache.mtimeMs !== mtimeMs) {
|
|
23348
23935
|
linkCache = { mtimeMs, file: file2, links: readAppsFile().links };
|
|
23349
23936
|
}
|
|
@@ -23389,11 +23976,11 @@ import path32 from "path";
|
|
|
23389
23976
|
// src/ui/native.ts
|
|
23390
23977
|
init_esm_shims();
|
|
23391
23978
|
import { spawn } from "child_process";
|
|
23392
|
-
import
|
|
23979
|
+
import path22 from "path";
|
|
23393
23980
|
|
|
23394
23981
|
// src/context-sniper.ts
|
|
23395
23982
|
init_esm_shims();
|
|
23396
|
-
import
|
|
23983
|
+
import path21 from "path";
|
|
23397
23984
|
function smartTruncate(str, maxLen = 500) {
|
|
23398
23985
|
if (str.length <= maxLen) return str;
|
|
23399
23986
|
const edge = Math.floor(maxLen / 2) - 3;
|
|
@@ -23461,7 +24048,7 @@ function computeRiskMetadata(args, tier, blockedByLabel, matchedField, matchedWo
|
|
|
23461
24048
|
intent = "EDIT";
|
|
23462
24049
|
if (obj.file_path) {
|
|
23463
24050
|
editFilePath = String(obj.file_path);
|
|
23464
|
-
editFileName =
|
|
24051
|
+
editFileName = path21.basename(editFilePath);
|
|
23465
24052
|
}
|
|
23466
24053
|
const result = extractContext(String(obj.new_string), matchedWord);
|
|
23467
24054
|
contextSnippet = result.snippet;
|
|
@@ -23530,7 +24117,7 @@ function formatArgs(args, matchedField, matchedWord) {
|
|
|
23530
24117
|
if (typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
23531
24118
|
const obj = parsed;
|
|
23532
24119
|
if (obj.old_string !== void 0 && obj.new_string !== void 0) {
|
|
23533
|
-
const file2 = obj.file_path ?
|
|
24120
|
+
const file2 = obj.file_path ? path22.basename(String(obj.file_path)) : "file";
|
|
23534
24121
|
const oldPreview = smartTruncate(String(obj.old_string), 120);
|
|
23535
24122
|
const newPreview = extractContext(String(obj.new_string), matchedWord).snippet;
|
|
23536
24123
|
return {
|
|
@@ -23738,48 +24325,6 @@ import fs20 from "fs";
|
|
|
23738
24325
|
import os14 from "os";
|
|
23739
24326
|
import path23 from "path";
|
|
23740
24327
|
init_dist();
|
|
23741
|
-
|
|
23742
|
-
// src/shields/jail.ts
|
|
23743
|
-
init_esm_shims();
|
|
23744
|
-
import fs19 from "fs";
|
|
23745
|
-
import os13 from "os";
|
|
23746
|
-
import path22 from "path";
|
|
23747
|
-
init_dist();
|
|
23748
|
-
var USER_JAIL_SHIELD = "user-jail";
|
|
23749
|
-
function jailStorePath() {
|
|
23750
|
-
return path22.join(os13.homedir(), ".node9", "jail-paths.json");
|
|
23751
|
-
}
|
|
23752
|
-
function readJailPaths() {
|
|
23753
|
-
let text;
|
|
23754
|
-
try {
|
|
23755
|
-
text = fs19.readFileSync(jailStorePath(), "utf8");
|
|
23756
|
-
} catch (err) {
|
|
23757
|
-
if (err.code === "ENOENT") return [];
|
|
23758
|
-
throw err;
|
|
23759
|
-
}
|
|
23760
|
-
let parsed;
|
|
23761
|
-
try {
|
|
23762
|
-
parsed = JSON.parse(text);
|
|
23763
|
-
} catch {
|
|
23764
|
-
throw new Error(`${jailStorePath()} is not valid JSON \u2014 fix it before changing the jail.`);
|
|
23765
|
-
}
|
|
23766
|
-
if (!Array.isArray(parsed.paths)) return [];
|
|
23767
|
-
return parsed.paths.filter(
|
|
23768
|
-
(p) => !!p && typeof p.path === "string" && (p.verdict === "block" || p.verdict === "review")
|
|
23769
|
-
);
|
|
23770
|
-
}
|
|
23771
|
-
function findJailedPath(candidate) {
|
|
23772
|
-
return findJailedPathIn(candidate, readJailPaths());
|
|
23773
|
-
}
|
|
23774
|
-
function findJailedPathIn(candidate, paths) {
|
|
23775
|
-
if (!candidate) return null;
|
|
23776
|
-
for (const entry of paths) {
|
|
23777
|
-
if (pathMatchesFragment(candidate, entry.path)) return entry;
|
|
23778
|
-
}
|
|
23779
|
-
return null;
|
|
23780
|
-
}
|
|
23781
|
-
|
|
23782
|
-
// src/canary/registry.ts
|
|
23783
24328
|
function canaryStorePath() {
|
|
23784
24329
|
return path23.join(os14.homedir(), ".node9", "canaries.json");
|
|
23785
24330
|
}
|