@node9/proxy 2.43.0 → 2.43.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +103 -26
- package/dist/cli.mjs +103 -26
- package/dist/dashboard.mjs +213 -135
- package/dist/index.js +185 -105
- package/dist/index.mjs +185 -105
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -799,12 +799,12 @@ function judgeInlineCode(language, code, isProtected) {
|
|
|
799
799
|
category
|
|
800
800
|
};
|
|
801
801
|
}
|
|
802
|
-
const
|
|
803
|
-
if (
|
|
802
|
+
const path31 = protectedLiteral(text, isProtected);
|
|
803
|
+
if (path31) {
|
|
804
804
|
return {
|
|
805
805
|
outcome: "dangerous",
|
|
806
806
|
what: WHAT["reads-protected"],
|
|
807
|
-
evidence:
|
|
807
|
+
evidence: path31.slice(0, 60),
|
|
808
808
|
category: "reads-protected"
|
|
809
809
|
};
|
|
810
810
|
}
|
|
@@ -2967,9 +2967,9 @@ function ruleServerMatches(rule, serverLabel) {
|
|
|
2967
2967
|
if (rule.notServer && label2 && matchesPattern(label2, rule.notServer)) return false;
|
|
2968
2968
|
return true;
|
|
2969
2969
|
}
|
|
2970
|
-
function getNestedValue(obj,
|
|
2970
|
+
function getNestedValue(obj, path31) {
|
|
2971
2971
|
if (!obj || typeof obj !== "object") return null;
|
|
2972
|
-
const segments2 =
|
|
2972
|
+
const segments2 = path31.split(".");
|
|
2973
2973
|
for (const seg of segments2) {
|
|
2974
2974
|
if (FORBIDDEN_PATH_SEGMENTS.has(seg)) return null;
|
|
2975
2975
|
}
|
|
@@ -3949,8 +3949,8 @@ function collectFileAccesses(tool, args, context = {}, inspection = {}) {
|
|
|
3949
3949
|
}
|
|
3950
3950
|
return out;
|
|
3951
3951
|
}
|
|
3952
|
-
function within(
|
|
3953
|
-
return
|
|
3952
|
+
function within(path31, root) {
|
|
3953
|
+
return path31 === root || path31.startsWith(root === "/" ? "/" : root + "/");
|
|
3954
3954
|
}
|
|
3955
3955
|
function hits(access, paths, directories, context) {
|
|
3956
3956
|
const home = context.homeDirs?.[0] ?? "~";
|
|
@@ -5338,7 +5338,10 @@ function classify(inv) {
|
|
|
5338
5338
|
out.push({ ...f, shown: inv.shown, reason: `${f.reason}: ${inv.shown}` });
|
|
5339
5339
|
};
|
|
5340
5340
|
if (hooksBypass(inv)) found(HOOKS_BYPASS);
|
|
5341
|
-
|
|
5341
|
+
const staged = stagesEverything(inv);
|
|
5342
|
+
if (staged) {
|
|
5343
|
+
found(staged.ifWorkTreeTop === void 0 ? STAGE_ALL : { ...STAGE_ALL, ...staged });
|
|
5344
|
+
}
|
|
5342
5345
|
if (inv.sub === null) {
|
|
5343
5346
|
found(UNREADABLE);
|
|
5344
5347
|
return out;
|
|
@@ -5399,12 +5402,35 @@ function appliedValue(env, name) {
|
|
|
5399
5402
|
const word = f?.Stmts?.[0]?.Cmd?.Args?.[1];
|
|
5400
5403
|
return word ? resolveWordLiteral(word) : null;
|
|
5401
5404
|
}
|
|
5405
|
+
function lexicalPath(p) {
|
|
5406
|
+
if (/^[\\/~$]/.test(p) || /^[A-Za-z]:/.test(p)) return null;
|
|
5407
|
+
const parts = [];
|
|
5408
|
+
let climbed = false;
|
|
5409
|
+
for (const part of p.split(/[\\/]+/)) {
|
|
5410
|
+
if (part === "" || part === ".") continue;
|
|
5411
|
+
if (part === "..") {
|
|
5412
|
+
if (parts.length === 0) climbed = true;
|
|
5413
|
+
else parts.pop();
|
|
5414
|
+
} else parts.push(part);
|
|
5415
|
+
}
|
|
5416
|
+
return { parts, climbed };
|
|
5417
|
+
}
|
|
5418
|
+
function hooksPathBypasses(value) {
|
|
5419
|
+
if (value === null || value === void 0) return true;
|
|
5420
|
+
const v = value.trim();
|
|
5421
|
+
if (v === "" || v === "true") return true;
|
|
5422
|
+
const lp = lexicalPath(v);
|
|
5423
|
+
if (lp === null || lp.climbed || lp.parts.length === 0) return true;
|
|
5424
|
+
return lp.parts[0] === ".git" && lp.parts[1] !== "hooks";
|
|
5425
|
+
}
|
|
5402
5426
|
function hooksBypass(inv) {
|
|
5403
|
-
if (inv.config.has("core.hookspath")
|
|
5427
|
+
if (inv.config.has("core.hookspath") && hooksPathBypasses(inv.config.get("core.hookspath")))
|
|
5428
|
+
return true;
|
|
5404
5429
|
for (const [name, value] of inv.env) {
|
|
5405
5430
|
if (name === "GIT_CONFIG_PARAMETERS" && value !== null && /core\.hookspath/i.test(value))
|
|
5406
5431
|
return true;
|
|
5407
|
-
|
|
5432
|
+
const key = /^GIT_CONFIG_KEY_(\d+)$/.exec(name);
|
|
5433
|
+
if (key && value !== null && value.toLowerCase() === "core.hookspath" && hooksPathBypasses(inv.env.get(`GIT_CONFIG_VALUE_${key[1]}`)))
|
|
5408
5434
|
return true;
|
|
5409
5435
|
}
|
|
5410
5436
|
for (const name of HOOK_KILL_SWITCHES) {
|
|
@@ -5446,7 +5472,10 @@ function configWritesHooksPath(args) {
|
|
|
5446
5472
|
}
|
|
5447
5473
|
const key = args[i];
|
|
5448
5474
|
if (key === null || key === void 0 || key.toLowerCase() !== "core.hookspath") return false;
|
|
5449
|
-
|
|
5475
|
+
const unset = args.slice(0, i).some((w) => w === "--unset" || w === "--unset-all") || args[0] === "unset";
|
|
5476
|
+
if (unset) return true;
|
|
5477
|
+
if (i + 1 < args.length) return hooksPathBypasses(args[i + 1]);
|
|
5478
|
+
return write;
|
|
5450
5479
|
}
|
|
5451
5480
|
function isHookPath(word) {
|
|
5452
5481
|
return /(^|[\\/])(\.git[\\/]hooks|\.husky)([\\/]|$)/.test(word);
|
|
@@ -5481,31 +5510,49 @@ function chmodDisarmsHook(args, shown) {
|
|
|
5481
5510
|
function wholeTree(operand) {
|
|
5482
5511
|
if (/^:\(top\)\.?$/.test(operand) || operand === ":/" || operand === "*") return true;
|
|
5483
5512
|
if (operand.startsWith(":")) return false;
|
|
5513
|
+
const lp = lexicalPath(operand);
|
|
5514
|
+
return lp !== null && lp.parts.length === 0;
|
|
5515
|
+
}
|
|
5516
|
+
function chdirPrefix(inv) {
|
|
5517
|
+
const dirs = inv.chdir ?? [];
|
|
5518
|
+
if (dirs.length === 0) return null;
|
|
5484
5519
|
const parts = [];
|
|
5485
|
-
for (const
|
|
5486
|
-
if (
|
|
5487
|
-
|
|
5488
|
-
|
|
5520
|
+
for (const d of dirs) {
|
|
5521
|
+
if (d === null || d === "") return null;
|
|
5522
|
+
const lp = lexicalPath(d);
|
|
5523
|
+
if (lp === null || lp.climbed) return null;
|
|
5524
|
+
parts.push(...lp.parts);
|
|
5489
5525
|
}
|
|
5490
|
-
return parts.length === 0
|
|
5526
|
+
return parts.length === 0 ? null : parts.join("/");
|
|
5491
5527
|
}
|
|
5492
5528
|
function stagesEverything(inv) {
|
|
5493
5529
|
const sub = inv.sub?.toLowerCase();
|
|
5530
|
+
const prefix = chdirPrefix(inv);
|
|
5531
|
+
const judge = (operands2) => {
|
|
5532
|
+
let conditional = false;
|
|
5533
|
+
for (const operand of operands2) {
|
|
5534
|
+
if (!wholeTree(operand)) continue;
|
|
5535
|
+
if (prefix === null || operand.startsWith(":") || operand.startsWith("/")) return {};
|
|
5536
|
+
if (wholeTree(`${prefix}/${operand === "*" ? "." : operand}`)) return {};
|
|
5537
|
+
conditional = true;
|
|
5538
|
+
}
|
|
5539
|
+
return conditional && prefix !== null ? { ifWorkTreeTop: prefix } : null;
|
|
5540
|
+
};
|
|
5494
5541
|
if (sub === "add") {
|
|
5495
5542
|
const o = parseOptions(inv.args, "", ADD_LONG_VALUE);
|
|
5496
5543
|
if (o.flags.has("-n") || o.flags.has("--dry-run") || o.flags.has("-i") || o.flags.has("--interactive") || o.flags.has("-p") || o.flags.has("--patch") || o.flags.has("-e") || o.flags.has("--edit"))
|
|
5497
|
-
return
|
|
5544
|
+
return null;
|
|
5498
5545
|
const all = o.flags.has("-A") || o.flags.has("--all") || o.flags.has("--no-ignore-removal") || o.flags.has("-u") || o.flags.has("--update");
|
|
5499
|
-
if (all && o.operands.length === 0) return
|
|
5500
|
-
return o.operands
|
|
5546
|
+
if (all && o.operands.length === 0) return {};
|
|
5547
|
+
return judge(o.operands);
|
|
5501
5548
|
}
|
|
5502
5549
|
if (sub === "commit") {
|
|
5503
5550
|
const o = parseOptions(inv.args, "mFCcut", COMMIT_LONG_VALUE);
|
|
5504
|
-
if (o.flags.has("--dry-run")) return
|
|
5505
|
-
if (o.flags.has("-a") || o.flags.has("--all")) return
|
|
5506
|
-
return o.operands
|
|
5551
|
+
if (o.flags.has("--dry-run")) return null;
|
|
5552
|
+
if (o.flags.has("-a") || o.flags.has("--all")) return {};
|
|
5553
|
+
return judge(o.operands);
|
|
5507
5554
|
}
|
|
5508
|
-
return
|
|
5555
|
+
return null;
|
|
5509
5556
|
}
|
|
5510
5557
|
function hookTextRunsNothing(text) {
|
|
5511
5558
|
return text.split(/\r?\n/).every((line) => INERT_LINE_RE.test(line.trim()));
|
|
@@ -7161,9 +7208,9 @@ function bareToolName(toolName) {
|
|
|
7161
7208
|
const parts = toolName.split("__");
|
|
7162
7209
|
return (parts.length >= 3 ? parts.slice(2).join("__") : toolName).toLowerCase();
|
|
7163
7210
|
}
|
|
7164
|
-
function valuesAt(args,
|
|
7211
|
+
function valuesAt(args, path31) {
|
|
7165
7212
|
let cursors = [args];
|
|
7166
|
-
for (const rawSegment of
|
|
7213
|
+
for (const rawSegment of path31.split(".")) {
|
|
7167
7214
|
const isArray = rawSegment.endsWith("[]");
|
|
7168
7215
|
const key = isArray ? rawSegment.slice(0, -2) : rawSegment;
|
|
7169
7216
|
const next = [];
|
|
@@ -7194,8 +7241,8 @@ function extractToolDestinations(toolName, args) {
|
|
|
7194
7241
|
try {
|
|
7195
7242
|
const out = [];
|
|
7196
7243
|
const paths = DESTINATION_ARGS.get(bareToolName(toolName)) ?? [];
|
|
7197
|
-
for (const
|
|
7198
|
-
for (const value of valuesAt(args,
|
|
7244
|
+
for (const path31 of paths) {
|
|
7245
|
+
for (const value of valuesAt(args, path31)) {
|
|
7199
7246
|
const host2 = hostOf(value);
|
|
7200
7247
|
if (host2) out.push({ host: host2, binary: toolName, raw: value });
|
|
7201
7248
|
}
|
|
@@ -7221,8 +7268,8 @@ function ssrfDestinationFloor(toolName, args, opts = {}) {
|
|
|
7221
7268
|
try {
|
|
7222
7269
|
const paths = DESTINATION_ARGS.get(bareToolName(toolName));
|
|
7223
7270
|
if (!paths) return null;
|
|
7224
|
-
for (const
|
|
7225
|
-
for (const value of valuesAt(args,
|
|
7271
|
+
for (const path31 of paths) {
|
|
7272
|
+
for (const value of valuesAt(args, path31)) {
|
|
7226
7273
|
const host2 = hostOf(value);
|
|
7227
7274
|
if (!host2) continue;
|
|
7228
7275
|
const m = classifySsrf(host2);
|
|
@@ -7231,7 +7278,7 @@ function ssrfDestinationFloor(toolName, args, opts = {}) {
|
|
|
7231
7278
|
const decision = ssrfFloorDecision(m, written, opts);
|
|
7232
7279
|
if (decision === null) continue;
|
|
7233
7280
|
const reason = decision === "review" ? ssrfDisguisedReason(m, written) : ssrfReason(m, host2);
|
|
7234
|
-
return { ...m, argPath:
|
|
7281
|
+
return { ...m, argPath: path31, host: host2, reason, decision };
|
|
7235
7282
|
}
|
|
7236
7283
|
}
|
|
7237
7284
|
return null;
|
|
@@ -7513,7 +7560,7 @@ async function evaluatePolicy(config, toolName, args, context = {}, hostHooks =
|
|
|
7513
7560
|
}
|
|
7514
7561
|
async function evaluatePolicyCore(config, toolName, args, context = {}, hooks = {}) {
|
|
7515
7562
|
const { agent, cwd, activeEnvironment } = context;
|
|
7516
|
-
const { checkProvenance: checkProvenance2, isTrustedHost: isTrustedHost2, isConfiguredRegistry } = hooks;
|
|
7563
|
+
const { checkProvenance: checkProvenance2, isTrustedHost: isTrustedHost2, isConfiguredRegistry, isGitWorkTreeTop: isGitWorkTreeTop2 } = hooks;
|
|
7517
7564
|
const settingsView = catalogSettings(config);
|
|
7518
7565
|
const layers = inspectionLayers(config.policy);
|
|
7519
7566
|
const cv = (id) => checkValue(settingsView, id);
|
|
@@ -7667,6 +7714,8 @@ async function evaluatePolicyCore(config, toolName, args, context = {}, hooks =
|
|
|
7667
7714
|
const action = cv(id);
|
|
7668
7715
|
const finding = action === "off" ? void 0 : git.findings.find((f) => f.checkId === id);
|
|
7669
7716
|
if (!finding) continue;
|
|
7717
|
+
if (finding.ifWorkTreeTop !== void 0 && isGitWorkTreeTop2 && cwd && !isGitWorkTreeTop2(finding.ifWorkTreeTop, cwd))
|
|
7718
|
+
continue;
|
|
7670
7719
|
const v = applyCheckValue(action, {
|
|
7671
7720
|
decision: "review",
|
|
7672
7721
|
blockedByLabel: `Node9 (AST): ${finding.ruleName}`,
|
|
@@ -16278,6 +16327,7 @@ zoo`.split("\n");
|
|
|
16278
16327
|
/** The words after `git`: global options, then the subcommand. */
|
|
16279
16328
|
visitGit(rest, env, depth, viaXargs, fromAlias, shown) {
|
|
16280
16329
|
const config = /* @__PURE__ */ new Map();
|
|
16330
|
+
const chdir = [];
|
|
16281
16331
|
let i = 0;
|
|
16282
16332
|
while (i < rest.length) {
|
|
16283
16333
|
const w = rest[i];
|
|
@@ -16292,6 +16342,7 @@ zoo`.split("\n");
|
|
|
16292
16342
|
i++;
|
|
16293
16343
|
value = i < rest.length ? rest[i] : null;
|
|
16294
16344
|
}
|
|
16345
|
+
if (name === "-C") chdir.push(viaXargs || (value ?? "").includes("{}") ? null : value);
|
|
16295
16346
|
if (name === "-c" && value !== null) {
|
|
16296
16347
|
const ceq = value.indexOf("=");
|
|
16297
16348
|
const key = (ceq > 0 ? value.slice(0, ceq) : value).toLowerCase();
|
|
@@ -16308,7 +16359,7 @@ zoo`.split("\n");
|
|
|
16308
16359
|
}
|
|
16309
16360
|
const subWord = i < rest.length ? rest[i] : void 0;
|
|
16310
16361
|
const args = rest.slice(i + 1);
|
|
16311
|
-
const inv = { sub: null, args, config, env, shown };
|
|
16362
|
+
const inv = { sub: null, args, config, env, shown, chdir };
|
|
16312
16363
|
if (subWord === void 0) {
|
|
16313
16364
|
if (!viaXargs) return;
|
|
16314
16365
|
this.emit(inv);
|
|
@@ -16322,16 +16373,23 @@ zoo`.split("\n");
|
|
|
16322
16373
|
const fromConfig = config.get(`alias.${subWord.toLowerCase()}`);
|
|
16323
16374
|
const alias = fromConfig !== void 0 ? fromConfig : this.aliases.get(subWord);
|
|
16324
16375
|
if (alias !== void 0 && !fromAlias) {
|
|
16325
|
-
this.expandAlias(subWord, alias, args, env, depth, 0, shown);
|
|
16376
|
+
this.expandAlias(subWord, alias, args, env, depth, 0, shown, chdir);
|
|
16326
16377
|
return;
|
|
16327
16378
|
}
|
|
16328
16379
|
inv.sub = subWord;
|
|
16329
16380
|
this.emit(inv);
|
|
16330
16381
|
this.recordAliasDefinition(inv, env, depth);
|
|
16331
16382
|
}
|
|
16332
|
-
expandAlias(name, value, args, env, depth, level, shown) {
|
|
16383
|
+
expandAlias(name, value, args, env, depth, level, shown, chdir) {
|
|
16333
16384
|
if (value === null) {
|
|
16334
|
-
this.emit({
|
|
16385
|
+
this.emit({
|
|
16386
|
+
sub: null,
|
|
16387
|
+
args,
|
|
16388
|
+
config: /* @__PURE__ */ new Map(),
|
|
16389
|
+
env,
|
|
16390
|
+
shown: `${shown} (alias ${name})`,
|
|
16391
|
+
chdir
|
|
16392
|
+
});
|
|
16335
16393
|
return;
|
|
16336
16394
|
}
|
|
16337
16395
|
if (value.startsWith("!")) {
|
|
@@ -16345,7 +16403,16 @@ zoo`.split("\n");
|
|
|
16345
16403
|
const nested = this.aliases.get(sub);
|
|
16346
16404
|
const expandedShown = `${shown} (alias ${name} = ${value})`;
|
|
16347
16405
|
if (nested !== void 0 && level < MAX_ALIAS_DEPTH) {
|
|
16348
|
-
this.expandAlias(
|
|
16406
|
+
this.expandAlias(
|
|
16407
|
+
sub,
|
|
16408
|
+
nested,
|
|
16409
|
+
[...words.slice(1), ...args],
|
|
16410
|
+
env,
|
|
16411
|
+
depth,
|
|
16412
|
+
level + 1,
|
|
16413
|
+
shown,
|
|
16414
|
+
chdir
|
|
16415
|
+
);
|
|
16349
16416
|
return;
|
|
16350
16417
|
}
|
|
16351
16418
|
this.emit({
|
|
@@ -16353,7 +16420,8 @@ zoo`.split("\n");
|
|
|
16353
16420
|
args: [...words.slice(1), ...args],
|
|
16354
16421
|
config: /* @__PURE__ */ new Map(),
|
|
16355
16422
|
env,
|
|
16356
|
-
shown: expandedShown
|
|
16423
|
+
shown: expandedShown,
|
|
16424
|
+
chdir
|
|
16357
16425
|
});
|
|
16358
16426
|
}
|
|
16359
16427
|
/**
|
|
@@ -16387,7 +16455,7 @@ zoo`.split("\n");
|
|
|
16387
16455
|
if (i + 1 >= args.length) return;
|
|
16388
16456
|
const value = args[i + 1];
|
|
16389
16457
|
this.aliases.set(m[1], value);
|
|
16390
|
-
this.expandAlias(m[1], value, [], env, depth, 0, `${inv.shown}
|
|
16458
|
+
this.expandAlias(m[1], value, [], env, depth, 0, `${inv.shown}`, []);
|
|
16391
16459
|
}
|
|
16392
16460
|
};
|
|
16393
16461
|
POSITIONAL2 = "\0positional";
|
|
@@ -18303,8 +18371,8 @@ var ConfigFileSchema = z.object({
|
|
|
18303
18371
|
}).strict();
|
|
18304
18372
|
function formatIssues(issues) {
|
|
18305
18373
|
const lines = issues.map((issue) => {
|
|
18306
|
-
const
|
|
18307
|
-
return ` \u2022 ${
|
|
18374
|
+
const path31 = issue.path.length > 0 ? issue.path.map(String).join(".") : "root";
|
|
18375
|
+
return ` \u2022 ${path31}: ${issue.message}`;
|
|
18308
18376
|
});
|
|
18309
18377
|
return `Invalid config:
|
|
18310
18378
|
${lines.join("\n")}`;
|
|
@@ -18317,9 +18385,9 @@ function prunePaths(root, paths) {
|
|
|
18317
18385
|
const yi = y[y.length - 1];
|
|
18318
18386
|
return typeof xi === "number" && typeof yi === "number" ? yi - xi : 0;
|
|
18319
18387
|
});
|
|
18320
|
-
for (const
|
|
18388
|
+
for (const path31 of ordered) {
|
|
18321
18389
|
let cur = root;
|
|
18322
|
-
for (const key of
|
|
18390
|
+
for (const key of path31.slice(0, -1)) {
|
|
18323
18391
|
if (cur === null || typeof cur !== "object") {
|
|
18324
18392
|
cur = void 0;
|
|
18325
18393
|
break;
|
|
@@ -18327,7 +18395,7 @@ function prunePaths(root, paths) {
|
|
|
18327
18395
|
cur = cur[key];
|
|
18328
18396
|
}
|
|
18329
18397
|
if (cur === null || typeof cur !== "object") continue;
|
|
18330
|
-
const last =
|
|
18398
|
+
const last = path31[path31.length - 1];
|
|
18331
18399
|
if (Array.isArray(cur)) {
|
|
18332
18400
|
const i = Number(last);
|
|
18333
18401
|
if (Number.isInteger(i) && i >= 0 && i < cur.length) {
|
|
@@ -18363,7 +18431,7 @@ function sanitizeConfig(raw) {
|
|
|
18363
18431
|
return issue.keys.map((k) => [...at, k]);
|
|
18364
18432
|
}
|
|
18365
18433
|
return [at.slice(0, -level || void 0)];
|
|
18366
|
-
}).filter((
|
|
18434
|
+
}).filter((path31) => path31.length > 0);
|
|
18367
18435
|
if (paths.length === 0 || !prunePaths(working, paths)) break;
|
|
18368
18436
|
}
|
|
18369
18437
|
if (ConfigFileSchema.safeParse(working).success) break;
|
|
@@ -19801,13 +19869,13 @@ function getConfig(cwd) {
|
|
|
19801
19869
|
}
|
|
19802
19870
|
if (Array.isArray(mc.jailPaths)) {
|
|
19803
19871
|
for (const jp of mc.jailPaths) {
|
|
19804
|
-
const
|
|
19805
|
-
if (!
|
|
19872
|
+
const path31 = typeof jp?.path === "string" ? jp.path.trim() : "";
|
|
19873
|
+
if (!path31) continue;
|
|
19806
19874
|
const verdict = jp?.verdict === "review" ? "review" : "block";
|
|
19807
|
-
for (const r of pathRules(
|
|
19875
|
+
for (const r of pathRules(path31, verdict, "org-managed jail")) {
|
|
19808
19876
|
mergedPolicy.smartRules.push({ ...r, name: `org:${r.name}` });
|
|
19809
19877
|
}
|
|
19810
|
-
mergedPolicy.managedJailPaths.push({ path:
|
|
19878
|
+
mergedPolicy.managedJailPaths.push({ path: path31, verdict });
|
|
19811
19879
|
}
|
|
19812
19880
|
}
|
|
19813
19881
|
if (Array.isArray(mc.trustedHosts)) {
|
|
@@ -20188,6 +20256,9 @@ function readCappedText(file2, maxBytes, openFlags = "r") {
|
|
|
20188
20256
|
return r ? { text: r.bytes.toString("utf8"), truncated: r.truncated } : null;
|
|
20189
20257
|
}
|
|
20190
20258
|
|
|
20259
|
+
// src/policy/index.ts
|
|
20260
|
+
import path13 from "path";
|
|
20261
|
+
|
|
20191
20262
|
// src/dlp.ts
|
|
20192
20263
|
init_dist();
|
|
20193
20264
|
init_dist();
|
|
@@ -21508,10 +21579,19 @@ async function evaluatePolicy2(toolName, args, agent, cwd, opts) {
|
|
|
21508
21579
|
// reaches a long-lived in-process authorizer (the gateway) within seconds.
|
|
21509
21580
|
isTrustedHost: config.policy.trustedHostsManaged ? (host2) => matchesTrustedHost(host2, config.policy.trustedHosts) : isTrustedHost,
|
|
21510
21581
|
readAgentSettings,
|
|
21511
|
-
isConfiguredRegistry: (host2, at) => configuredRegistryHosts(at).has(host2)
|
|
21582
|
+
isConfiguredRegistry: (host2, at) => configuredRegistryHosts(at).has(host2),
|
|
21583
|
+
isGitWorkTreeTop
|
|
21512
21584
|
}
|
|
21513
21585
|
);
|
|
21514
21586
|
}
|
|
21587
|
+
function isGitWorkTreeTop(dir2, cwd) {
|
|
21588
|
+
if (!path13.isAbsolute(cwd)) return true;
|
|
21589
|
+
try {
|
|
21590
|
+
return fs13.existsSync(path13.join(path13.resolve(cwd, dir2), ".git"));
|
|
21591
|
+
} catch {
|
|
21592
|
+
return true;
|
|
21593
|
+
}
|
|
21594
|
+
}
|
|
21515
21595
|
var MAX_AGENT_SETTINGS_BYTES = 256 * 1024;
|
|
21516
21596
|
function readAgentSettings(absPath) {
|
|
21517
21597
|
const r = readCappedText(
|
|
@@ -21527,11 +21607,11 @@ function isIgnoredTool2(toolName) {
|
|
|
21527
21607
|
|
|
21528
21608
|
// src/auth/state.ts
|
|
21529
21609
|
import fs14 from "fs";
|
|
21530
|
-
import
|
|
21610
|
+
import path14 from "path";
|
|
21531
21611
|
import os9 from "os";
|
|
21532
21612
|
init_forecast_context();
|
|
21533
|
-
var PAUSED_FILE =
|
|
21534
|
-
var TRUST_FILE =
|
|
21613
|
+
var PAUSED_FILE = path14.join(os9.homedir(), ".node9", "PAUSED");
|
|
21614
|
+
var TRUST_FILE = path14.join(os9.homedir(), ".node9", "trust.json");
|
|
21535
21615
|
function extractCommandPattern(toolName, args) {
|
|
21536
21616
|
const lower2 = toolName.toLowerCase();
|
|
21537
21617
|
if (lower2 !== "bash" && lower2 !== "execute_bash" && lower2 !== "shell") return void 0;
|
|
@@ -21608,7 +21688,7 @@ function writeTrustSession(toolName, durationMs, args) {
|
|
|
21608
21688
|
}
|
|
21609
21689
|
function getPersistentDecision(toolName) {
|
|
21610
21690
|
try {
|
|
21611
|
-
const file2 =
|
|
21691
|
+
const file2 = path14.join(os9.homedir(), ".node9", "decisions.json");
|
|
21612
21692
|
if (!fs14.existsSync(file2)) return null;
|
|
21613
21693
|
const decisions = JSON.parse(fs14.readFileSync(file2, "utf-8"));
|
|
21614
21694
|
const d = decisions[toolName];
|
|
@@ -21623,7 +21703,7 @@ init_forecast_context();
|
|
|
21623
21703
|
import fs15 from "fs";
|
|
21624
21704
|
import http from "http";
|
|
21625
21705
|
import net from "net";
|
|
21626
|
-
import
|
|
21706
|
+
import path15 from "path";
|
|
21627
21707
|
import os10 from "os";
|
|
21628
21708
|
|
|
21629
21709
|
// src/auth/decision-record.ts
|
|
@@ -21774,7 +21854,7 @@ function recordFromLegacyWait(body, now = Date.now()) {
|
|
|
21774
21854
|
}
|
|
21775
21855
|
|
|
21776
21856
|
// src/auth/daemon.ts
|
|
21777
|
-
var ACTIVITY_SOCKET_PATH = process.platform === "win32" ? "\\\\.\\pipe\\node9-activity" :
|
|
21857
|
+
var ACTIVITY_SOCKET_PATH = process.platform === "win32" ? "\\\\.\\pipe\\node9-activity" : path15.join(os10.tmpdir(), "node9-activity.sock");
|
|
21778
21858
|
function notifyActivitySocket(data) {
|
|
21779
21859
|
if (forecastRun()) return Promise.resolve(false);
|
|
21780
21860
|
return new Promise((resolve) => {
|
|
@@ -21819,7 +21899,7 @@ var DAEMON_HOST = "127.0.0.1";
|
|
|
21819
21899
|
function getInternalToken() {
|
|
21820
21900
|
if (forecastRun()) return null;
|
|
21821
21901
|
try {
|
|
21822
|
-
const pidFile =
|
|
21902
|
+
const pidFile = path15.join(os10.homedir(), ".node9", "daemon.pid");
|
|
21823
21903
|
if (!fs15.existsSync(pidFile)) return null;
|
|
21824
21904
|
const data = JSON.parse(fs15.readFileSync(pidFile, "utf-8"));
|
|
21825
21905
|
process.kill(data.pid, 0);
|
|
@@ -21830,7 +21910,7 @@ function getInternalToken() {
|
|
|
21830
21910
|
}
|
|
21831
21911
|
function isDaemonRunning() {
|
|
21832
21912
|
if (forecastRun()) return false;
|
|
21833
|
-
const pidFile =
|
|
21913
|
+
const pidFile = path15.join(os10.homedir(), ".node9", "daemon.pid");
|
|
21834
21914
|
if (fs15.existsSync(pidFile)) {
|
|
21835
21915
|
let pid;
|
|
21836
21916
|
let port;
|
|
@@ -22193,7 +22273,7 @@ import { randomUUID as randomUUID2 } from "crypto";
|
|
|
22193
22273
|
// src/apps/state.ts
|
|
22194
22274
|
import fs17 from "fs";
|
|
22195
22275
|
import os12 from "os";
|
|
22196
|
-
import
|
|
22276
|
+
import path17 from "path";
|
|
22197
22277
|
|
|
22198
22278
|
// src/apps/catalog.ts
|
|
22199
22279
|
var APP_CATALOG = [
|
|
@@ -22326,10 +22406,10 @@ init_audit();
|
|
|
22326
22406
|
|
|
22327
22407
|
// src/daemon/mcp-tools.ts
|
|
22328
22408
|
import fs16 from "fs";
|
|
22329
|
-
import
|
|
22409
|
+
import path16 from "path";
|
|
22330
22410
|
import os11 from "os";
|
|
22331
22411
|
function getMcpToolsFile() {
|
|
22332
|
-
return
|
|
22412
|
+
return path16.join(os11.homedir(), ".node9", "mcp-tools.json");
|
|
22333
22413
|
}
|
|
22334
22414
|
function readMcpToolsConfig() {
|
|
22335
22415
|
try {
|
|
@@ -22344,7 +22424,7 @@ function readMcpToolsConfig() {
|
|
|
22344
22424
|
|
|
22345
22425
|
// src/apps/state.ts
|
|
22346
22426
|
function appsFilePath(home = os12.homedir()) {
|
|
22347
|
-
return
|
|
22427
|
+
return path17.join(home, ".node9", "apps.json");
|
|
22348
22428
|
}
|
|
22349
22429
|
var SIGNAL_KINDS = /* @__PURE__ */ new Set(["mcp-server", "command", "package", "env-name"]);
|
|
22350
22430
|
function emptyFile() {
|
|
@@ -22448,14 +22528,14 @@ function resolveLinkedServer(label2, opts = {}) {
|
|
|
22448
22528
|
|
|
22449
22529
|
// src/auth/orchestrator.ts
|
|
22450
22530
|
import os21 from "os";
|
|
22451
|
-
import
|
|
22531
|
+
import path30 from "path";
|
|
22452
22532
|
|
|
22453
22533
|
// src/ui/native.ts
|
|
22454
22534
|
import { spawn } from "child_process";
|
|
22455
|
-
import
|
|
22535
|
+
import path19 from "path";
|
|
22456
22536
|
|
|
22457
22537
|
// src/context-sniper.ts
|
|
22458
|
-
import
|
|
22538
|
+
import path18 from "path";
|
|
22459
22539
|
function smartTruncate(str, maxLen = 500) {
|
|
22460
22540
|
if (str.length <= maxLen) return str;
|
|
22461
22541
|
const edge = Math.floor(maxLen / 2) - 3;
|
|
@@ -22523,7 +22603,7 @@ function computeRiskMetadata(args, tier, blockedByLabel, matchedField, matchedWo
|
|
|
22523
22603
|
intent = "EDIT";
|
|
22524
22604
|
if (obj.file_path) {
|
|
22525
22605
|
editFilePath = String(obj.file_path);
|
|
22526
|
-
editFileName =
|
|
22606
|
+
editFileName = path18.basename(editFilePath);
|
|
22527
22607
|
}
|
|
22528
22608
|
const result = extractContext(String(obj.new_string), matchedWord);
|
|
22529
22609
|
contextSnippet = result.snippet;
|
|
@@ -22591,7 +22671,7 @@ function formatArgs(args, matchedField, matchedWord) {
|
|
|
22591
22671
|
if (typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
22592
22672
|
const obj = parsed;
|
|
22593
22673
|
if (obj.old_string !== void 0 && obj.new_string !== void 0) {
|
|
22594
|
-
const file2 = obj.file_path ?
|
|
22674
|
+
const file2 = obj.file_path ? path19.basename(String(obj.file_path)) : "file";
|
|
22595
22675
|
const oldPreview = smartTruncate(String(obj.old_string), 120);
|
|
22596
22676
|
const newPreview = extractContext(String(obj.new_string), matchedWord).snippet;
|
|
22597
22677
|
return {
|
|
@@ -22796,17 +22876,17 @@ end run`;
|
|
|
22796
22876
|
// src/canary/registry.ts
|
|
22797
22877
|
import fs19 from "fs";
|
|
22798
22878
|
import os14 from "os";
|
|
22799
|
-
import
|
|
22879
|
+
import path21 from "path";
|
|
22800
22880
|
init_dist();
|
|
22801
22881
|
|
|
22802
22882
|
// src/shields/jail.ts
|
|
22803
22883
|
import fs18 from "fs";
|
|
22804
22884
|
import os13 from "os";
|
|
22805
|
-
import
|
|
22885
|
+
import path20 from "path";
|
|
22806
22886
|
init_dist();
|
|
22807
22887
|
var USER_JAIL_SHIELD = "user-jail";
|
|
22808
22888
|
function jailStorePath() {
|
|
22809
|
-
return
|
|
22889
|
+
return path20.join(os13.homedir(), ".node9", "jail-paths.json");
|
|
22810
22890
|
}
|
|
22811
22891
|
function readJailPaths() {
|
|
22812
22892
|
let text;
|
|
@@ -22840,7 +22920,7 @@ function findJailedPathIn(candidate, paths) {
|
|
|
22840
22920
|
|
|
22841
22921
|
// src/canary/registry.ts
|
|
22842
22922
|
function canaryStorePath() {
|
|
22843
|
-
return
|
|
22923
|
+
return path21.join(os14.homedir(), ".node9", "canaries.json");
|
|
22844
22924
|
}
|
|
22845
22925
|
function isRecord(x) {
|
|
22846
22926
|
if (!x || typeof x !== "object") return false;
|
|
@@ -22880,7 +22960,7 @@ init_dist();
|
|
|
22880
22960
|
init_dist();
|
|
22881
22961
|
import fs20 from "fs";
|
|
22882
22962
|
import os15 from "os";
|
|
22883
|
-
import
|
|
22963
|
+
import path22 from "path";
|
|
22884
22964
|
var MAX_SCRIPT_BYTES = 64 * 1024;
|
|
22885
22965
|
var MAX_RECORDED_WRITES = 32;
|
|
22886
22966
|
function readScriptFile(resolved) {
|
|
@@ -22911,7 +22991,7 @@ function readScriptFile(resolved) {
|
|
|
22911
22991
|
}
|
|
22912
22992
|
function absolute(p, cwd, home) {
|
|
22913
22993
|
const spelled = p === "~" || p.startsWith("~/") ? home + p.slice(1) : p;
|
|
22914
|
-
return
|
|
22994
|
+
return path22.resolve(cwd, spelled);
|
|
22915
22995
|
}
|
|
22916
22996
|
async function resolveSessionScript(toolName, args, cwd, layers, deps, home = os15.homedir()) {
|
|
22917
22997
|
try {
|
|
@@ -22973,12 +23053,12 @@ init_dist();
|
|
|
22973
23053
|
|
|
22974
23054
|
// src/exposure/known-hosts.ts
|
|
22975
23055
|
import fs22 from "fs";
|
|
22976
|
-
import
|
|
23056
|
+
import path24 from "path";
|
|
22977
23057
|
|
|
22978
23058
|
// src/utils/git-remotes.ts
|
|
22979
23059
|
init_dist();
|
|
22980
23060
|
import fs21 from "fs";
|
|
22981
|
-
import
|
|
23061
|
+
import path23 from "path";
|
|
22982
23062
|
function readSmallFile(p, max) {
|
|
22983
23063
|
let fd;
|
|
22984
23064
|
try {
|
|
@@ -23010,20 +23090,20 @@ function gitRemoteHost(url) {
|
|
|
23010
23090
|
return null;
|
|
23011
23091
|
}
|
|
23012
23092
|
function findGitConfig(dir2, walkUp = true) {
|
|
23013
|
-
let cur =
|
|
23093
|
+
let cur = path23.resolve(dir2);
|
|
23014
23094
|
for (let i = 0; i < (walkUp ? 64 : 1); i++) {
|
|
23015
|
-
const dotGit =
|
|
23016
|
-
const direct = readSmallFile(
|
|
23095
|
+
const dotGit = path23.join(cur, ".git");
|
|
23096
|
+
const direct = readSmallFile(path23.join(dotGit, "config"), 1e6);
|
|
23017
23097
|
if (direct !== null) return direct;
|
|
23018
23098
|
const pointer = readSmallFile(dotGit, 4096);
|
|
23019
23099
|
const m = pointer && /^gitdir:\s*(.+?)\s*$/m.exec(pointer);
|
|
23020
23100
|
if (m) {
|
|
23021
|
-
let gitDir =
|
|
23022
|
-
const common = readSmallFile(
|
|
23023
|
-
if (common !== null) gitDir =
|
|
23024
|
-
return readSmallFile(
|
|
23101
|
+
let gitDir = path23.resolve(cur, m[1]);
|
|
23102
|
+
const common = readSmallFile(path23.join(gitDir, "commondir"), 4096);
|
|
23103
|
+
if (common !== null) gitDir = path23.resolve(gitDir, common.trim());
|
|
23104
|
+
return readSmallFile(path23.join(gitDir, "config"), 1e6);
|
|
23025
23105
|
}
|
|
23026
|
-
const parent =
|
|
23106
|
+
const parent = path23.dirname(cur);
|
|
23027
23107
|
if (parent === cur) return null;
|
|
23028
23108
|
cur = parent;
|
|
23029
23109
|
}
|
|
@@ -23033,12 +23113,12 @@ var cache4 = /* @__PURE__ */ new Map();
|
|
|
23033
23113
|
function readGitRemotes(dir2, opts = {}) {
|
|
23034
23114
|
if (!dir2) return [];
|
|
23035
23115
|
const walkUp = opts.walkUp !== false;
|
|
23036
|
-
const key = `${walkUp ? "up" : "at"}:${
|
|
23116
|
+
const key = `${walkUp ? "up" : "at"}:${path23.resolve(dir2)}`;
|
|
23037
23117
|
const hit = cache4.get(key);
|
|
23038
23118
|
if (hit) return hit;
|
|
23039
23119
|
const out = [];
|
|
23040
23120
|
try {
|
|
23041
|
-
const cfg = findGitConfig(
|
|
23121
|
+
const cfg = findGitConfig(path23.resolve(dir2), walkUp);
|
|
23042
23122
|
if (cfg !== null) {
|
|
23043
23123
|
let current = null;
|
|
23044
23124
|
for (const line of cfg.split(/\r?\n/)) {
|
|
@@ -23074,15 +23154,15 @@ var ECOSYSTEMS = [
|
|
|
23074
23154
|
];
|
|
23075
23155
|
var cache5 = /* @__PURE__ */ new Map();
|
|
23076
23156
|
function manifestRoot(dir2) {
|
|
23077
|
-
let cur =
|
|
23157
|
+
let cur = path24.resolve(dir2);
|
|
23078
23158
|
for (let i = 0; i < 64; i++) {
|
|
23079
23159
|
for (const [m] of ECOSYSTEMS) {
|
|
23080
23160
|
try {
|
|
23081
|
-
if (fs22.existsSync(
|
|
23161
|
+
if (fs22.existsSync(path24.join(cur, m))) return cur;
|
|
23082
23162
|
} catch {
|
|
23083
23163
|
}
|
|
23084
23164
|
}
|
|
23085
|
-
const parent =
|
|
23165
|
+
const parent = path24.dirname(cur);
|
|
23086
23166
|
if (parent === cur) return null;
|
|
23087
23167
|
cur = parent;
|
|
23088
23168
|
}
|
|
@@ -23091,7 +23171,7 @@ function manifestRoot(dir2) {
|
|
|
23091
23171
|
function knownProjectHosts(dir2) {
|
|
23092
23172
|
const empty = { hosts: /* @__PURE__ */ new Set(), repos: /* @__PURE__ */ new Set(), remotes: /* @__PURE__ */ new Map() };
|
|
23093
23173
|
if (!dir2) return empty;
|
|
23094
|
-
const key =
|
|
23174
|
+
const key = path24.resolve(dir2);
|
|
23095
23175
|
const hit = cache5.get(key);
|
|
23096
23176
|
if (hit) return hit;
|
|
23097
23177
|
const out = { hosts: /* @__PURE__ */ new Set(), repos: /* @__PURE__ */ new Set(), remotes: /* @__PURE__ */ new Map() };
|
|
@@ -23104,7 +23184,7 @@ function knownProjectHosts(dir2) {
|
|
|
23104
23184
|
const root = manifestRoot(key);
|
|
23105
23185
|
if (root !== null) {
|
|
23106
23186
|
for (const [m, registry] of ECOSYSTEMS) {
|
|
23107
|
-
if (fs22.existsSync(
|
|
23187
|
+
if (fs22.existsSync(path24.join(root, m))) out.hosts.add(registry);
|
|
23108
23188
|
}
|
|
23109
23189
|
try {
|
|
23110
23190
|
if (fs22.readdirSync(root).some((f) => f.endsWith(".gemspec")))
|
|
@@ -23122,7 +23202,7 @@ function knownProjectHosts(dir2) {
|
|
|
23122
23202
|
init_dist();
|
|
23123
23203
|
import fs23 from "fs";
|
|
23124
23204
|
import os16 from "os";
|
|
23125
|
-
import
|
|
23205
|
+
import path25 from "path";
|
|
23126
23206
|
var WRITE_OPS = /* @__PURE__ */ new Set(["write", "create", "remove"]);
|
|
23127
23207
|
var LIFECYCLE_RE = /"(scripts|preinstall|install|postinstall|prepare|prepublish|prepublishOnly|prepack|postpack|publish|postpublish)"\s*:/;
|
|
23128
23208
|
function writtenContent(args) {
|
|
@@ -23172,7 +23252,7 @@ function judgeWritesAfterExposure(opts) {
|
|
|
23172
23252
|
seen.add(p);
|
|
23173
23253
|
if (p === "/dev" || p.startsWith("/dev/")) continue;
|
|
23174
23254
|
if (root !== null && isInside(root, p)) {
|
|
23175
|
-
if (isAgentInstructionPath(p, root) && (
|
|
23255
|
+
if (isAgentInstructionPath(p, root) && (path25.basename(p) !== "package.json" || packageScriptsTouched(opts.args, p, opts.shellCommand)))
|
|
23176
23256
|
holds.push({ path: p, why: "agent-instruction" });
|
|
23177
23257
|
continue;
|
|
23178
23258
|
}
|
|
@@ -23196,7 +23276,7 @@ function judgeWritesAfterExposure(opts) {
|
|
|
23196
23276
|
import crypto3 from "crypto";
|
|
23197
23277
|
import fs24 from "fs";
|
|
23198
23278
|
import os17 from "os";
|
|
23199
|
-
import
|
|
23279
|
+
import path26 from "path";
|
|
23200
23280
|
|
|
23201
23281
|
// src/daemon/exposure-store.ts
|
|
23202
23282
|
var SESSION_EXPOSURE_TTL_MS = 4 * 60 * 60 * 1e3;
|
|
@@ -23204,11 +23284,11 @@ var SESSION_EXPOSURE_TTL_MS = 4 * 60 * 60 * 1e3;
|
|
|
23204
23284
|
// src/exposure/marker.ts
|
|
23205
23285
|
init_forecast_context();
|
|
23206
23286
|
function dir() {
|
|
23207
|
-
return
|
|
23287
|
+
return path26.join(os17.homedir(), ".node9", "exposure-sessions");
|
|
23208
23288
|
}
|
|
23209
23289
|
function file(sessionId) {
|
|
23210
23290
|
const id = crypto3.createHash("sha256").update(sessionId).digest("hex").slice(0, 32);
|
|
23211
|
-
return
|
|
23291
|
+
return path26.join(dir(), id);
|
|
23212
23292
|
}
|
|
23213
23293
|
function maybeSessionExposed(sessionId) {
|
|
23214
23294
|
if (!sessionId) return false;
|
|
@@ -23319,10 +23399,10 @@ function sourceWord(toolName) {
|
|
|
23319
23399
|
// src/auth/trusted-recipients.ts
|
|
23320
23400
|
init_dist();
|
|
23321
23401
|
import fs26 from "fs";
|
|
23322
|
-
import
|
|
23402
|
+
import path27 from "path";
|
|
23323
23403
|
import os18 from "os";
|
|
23324
23404
|
function getTrustedRecipientsPath() {
|
|
23325
|
-
return
|
|
23405
|
+
return path27.join(os18.homedir(), ".node9", "trusted-recipients.json");
|
|
23326
23406
|
}
|
|
23327
23407
|
function readTrustedRecipients() {
|
|
23328
23408
|
try {
|
|
@@ -23335,7 +23415,7 @@ function readTrustedRecipients() {
|
|
|
23335
23415
|
}
|
|
23336
23416
|
function writeTrustedRecipients(entries) {
|
|
23337
23417
|
const filePath = getTrustedRecipientsPath();
|
|
23338
|
-
fs26.mkdirSync(
|
|
23418
|
+
fs26.mkdirSync(path27.dirname(filePath), { recursive: true });
|
|
23339
23419
|
const tmp = filePath + ".node9-tmp";
|
|
23340
23420
|
fs26.writeFileSync(tmp, JSON.stringify({ entries }, null, 2), { mode: 384 });
|
|
23341
23421
|
fs26.renameSync(tmp, filePath);
|
|
@@ -23373,7 +23453,7 @@ init_forecast_context();
|
|
|
23373
23453
|
init_audit();
|
|
23374
23454
|
import fs27 from "fs";
|
|
23375
23455
|
import os19 from "os";
|
|
23376
|
-
import
|
|
23456
|
+
import path28 from "path";
|
|
23377
23457
|
init_dist();
|
|
23378
23458
|
var CLOUD_ARRAY_KEYS = /* @__PURE__ */ new Set(["exposureDestinations", "exposureDestinationHashes"]);
|
|
23379
23459
|
function maskArgsForCloud(args) {
|
|
@@ -23408,7 +23488,7 @@ async function initNode9SaaS(toolName, args, creds, meta, riskMetadata, agentPol
|
|
|
23408
23488
|
let ciContext;
|
|
23409
23489
|
if (process.env.CI) {
|
|
23410
23490
|
try {
|
|
23411
|
-
const ciContextPath =
|
|
23491
|
+
const ciContextPath = path28.join(os19.homedir(), ".node9", "ci-context.json");
|
|
23412
23492
|
const ci = readCappedText(ciContextPath, 1e4);
|
|
23413
23493
|
if (!ci) throw new Error("ci-context.json unreadable");
|
|
23414
23494
|
if (ci.truncated) throw new Error("ci-context.json exceeds 10 KB");
|
|
@@ -23546,10 +23626,10 @@ init_dist();
|
|
|
23546
23626
|
init_forecast_context();
|
|
23547
23627
|
init_dist();
|
|
23548
23628
|
import fs28 from "fs";
|
|
23549
|
-
import
|
|
23629
|
+
import path29 from "path";
|
|
23550
23630
|
import os20 from "os";
|
|
23551
23631
|
function loopStateFile() {
|
|
23552
|
-
return
|
|
23632
|
+
return path29.join(os20.homedir(), ".node9", "loop-state.json");
|
|
23553
23633
|
}
|
|
23554
23634
|
function readState() {
|
|
23555
23635
|
try {
|
|
@@ -23563,7 +23643,7 @@ function readState() {
|
|
|
23563
23643
|
}
|
|
23564
23644
|
}
|
|
23565
23645
|
function writeState(records) {
|
|
23566
|
-
const dir2 =
|
|
23646
|
+
const dir2 = path29.dirname(loopStateFile());
|
|
23567
23647
|
if (!fs28.existsSync(dir2)) fs28.mkdirSync(dir2, { recursive: true });
|
|
23568
23648
|
const tmpPath = `${loopStateFile()}.${os20.hostname()}.${process.pid}.tmp`;
|
|
23569
23649
|
fs28.writeFileSync(tmpPath, JSON.stringify(records));
|
|
@@ -23763,9 +23843,9 @@ function isMcpToolName(toolName) {
|
|
|
23763
23843
|
return /^mcp__[^_](?:[^_]|_(?!_))*?__/i.test(toolName);
|
|
23764
23844
|
}
|
|
23765
23845
|
function absoluteUploadPath(spelled, cwd) {
|
|
23766
|
-
const expanded = spelled === "~" || spelled.startsWith("~/") ?
|
|
23767
|
-
if (
|
|
23768
|
-
return cwd &&
|
|
23846
|
+
const expanded = spelled === "~" || spelled.startsWith("~/") ? path30.join(os21.homedir(), spelled.slice(1)) : spelled;
|
|
23847
|
+
if (path30.isAbsolute(expanded)) return expanded;
|
|
23848
|
+
return cwd && path30.isAbsolute(cwd) ? path30.resolve(cwd, expanded) : expanded;
|
|
23769
23849
|
}
|
|
23770
23850
|
function extractFilePaths(toolName, args, shellCommand) {
|
|
23771
23851
|
const paths = [];
|