@node9/proxy 1.67.5 → 2.0.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.js +575 -938
- package/dist/cli.mjs +568 -931
- package/dist/dashboard.mjs +0 -60
- package/dist/index.js +0 -50
- package/dist/index.mjs +0 -50
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -243,8 +243,8 @@ function sanitizeConfig(raw) {
|
|
|
243
243
|
}
|
|
244
244
|
}
|
|
245
245
|
const lines = result.error.issues.map((issue) => {
|
|
246
|
-
const
|
|
247
|
-
return ` \u2022 ${
|
|
246
|
+
const path71 = issue.path.length > 0 ? issue.path.join(".") : "root";
|
|
247
|
+
return ` \u2022 ${path71}: ${issue.message}`;
|
|
248
248
|
});
|
|
249
249
|
return {
|
|
250
250
|
sanitized,
|
|
@@ -624,9 +624,9 @@ function matchesPattern(text, patterns) {
|
|
|
624
624
|
const withoutDotSlash = text.replace(/^\.\//, "");
|
|
625
625
|
return isMatch(withoutDotSlash) || isMatch(`./${withoutDotSlash}`);
|
|
626
626
|
}
|
|
627
|
-
function getNestedValue(obj,
|
|
627
|
+
function getNestedValue(obj, path71) {
|
|
628
628
|
if (!obj || typeof obj !== "object") return null;
|
|
629
|
-
const segments =
|
|
629
|
+
const segments = path71.split(".");
|
|
630
630
|
for (const seg of segments) {
|
|
631
631
|
if (FORBIDDEN_PATH_SEGMENTS.has(seg)) return null;
|
|
632
632
|
}
|
|
@@ -5098,11 +5098,6 @@ function getConfig(cwd) {
|
|
|
5098
5098
|
ignoredTools: [...DEFAULT_CONFIG.policy.ignoredTools],
|
|
5099
5099
|
toolInspection: { ...DEFAULT_CONFIG.policy.toolInspection },
|
|
5100
5100
|
smartRules: [...DEFAULT_CONFIG.policy.smartRules],
|
|
5101
|
-
snapshot: {
|
|
5102
|
-
tools: [...DEFAULT_CONFIG.policy.snapshot.tools],
|
|
5103
|
-
onlyPaths: [...DEFAULT_CONFIG.policy.snapshot.onlyPaths],
|
|
5104
|
-
ignorePaths: [...DEFAULT_CONFIG.policy.snapshot.ignorePaths]
|
|
5105
|
-
},
|
|
5106
5101
|
dlp: { ...DEFAULT_CONFIG.policy.dlp },
|
|
5107
5102
|
egress: {
|
|
5108
5103
|
...DEFAULT_CONFIG.policy.egress,
|
|
@@ -5170,12 +5165,6 @@ function getConfig(cwd) {
|
|
|
5170
5165
|
);
|
|
5171
5166
|
mergedPolicy.smartRules = [...filteredBlocks, ...localRules, ...filteredNonBlocks];
|
|
5172
5167
|
}
|
|
5173
|
-
if (p.snapshot) {
|
|
5174
|
-
const s2 = p.snapshot;
|
|
5175
|
-
if (s2.tools) mergedPolicy.snapshot.tools.push(...s2.tools);
|
|
5176
|
-
if (s2.onlyPaths) mergedPolicy.snapshot.onlyPaths.push(...s2.onlyPaths);
|
|
5177
|
-
if (s2.ignorePaths) mergedPolicy.snapshot.ignorePaths.push(...s2.ignorePaths);
|
|
5178
|
-
}
|
|
5179
5168
|
if (p.dlp) {
|
|
5180
5169
|
const d = p.dlp;
|
|
5181
5170
|
if (d.enabled !== void 0) mergedPolicy.dlp.enabled = d.enabled;
|
|
@@ -5381,13 +5370,13 @@ function getConfig(cwd) {
|
|
|
5381
5370
|
}
|
|
5382
5371
|
if (Array.isArray(mc.jailPaths)) {
|
|
5383
5372
|
for (const jp of mc.jailPaths) {
|
|
5384
|
-
const
|
|
5385
|
-
if (!
|
|
5373
|
+
const path71 = typeof jp?.path === "string" ? jp.path.trim() : "";
|
|
5374
|
+
if (!path71) continue;
|
|
5386
5375
|
const verdict = jp?.verdict === "review" ? "review" : "block";
|
|
5387
|
-
for (const r of pathRules(
|
|
5376
|
+
for (const r of pathRules(path71, verdict, "org-managed jail")) {
|
|
5388
5377
|
mergedPolicy.smartRules.push({ ...r, name: `org:${r.name}` });
|
|
5389
5378
|
}
|
|
5390
|
-
mergedPolicy.managedJailPaths.push({ path:
|
|
5379
|
+
mergedPolicy.managedJailPaths.push({ path: path71, verdict });
|
|
5391
5380
|
}
|
|
5392
5381
|
}
|
|
5393
5382
|
if (Array.isArray(mc.trustedHosts)) {
|
|
@@ -5510,10 +5499,6 @@ function getConfig(cwd) {
|
|
|
5510
5499
|
mergedPolicy.dangerousWords = [...new Set(mergedPolicy.dangerousWords)];
|
|
5511
5500
|
mergedPolicy.ignoredTools = [...new Set(mergedPolicy.ignoredTools)];
|
|
5512
5501
|
mergedPolicy.skillPinning.roots = [...new Set(mergedPolicy.skillPinning.roots)];
|
|
5513
|
-
mergedPolicy.snapshot.tools = [...new Set(mergedPolicy.snapshot.tools)];
|
|
5514
|
-
mergedPolicy.snapshot.onlyPaths = [...new Set(mergedPolicy.snapshot.onlyPaths)];
|
|
5515
|
-
mergedPolicy.snapshot.ignorePaths = [...new Set(mergedPolicy.snapshot.ignorePaths)];
|
|
5516
|
-
mergedSettings.enableUndo = false;
|
|
5517
5502
|
const result = {
|
|
5518
5503
|
settings: mergedSettings,
|
|
5519
5504
|
policy: mergedPolicy,
|
|
@@ -5599,19 +5584,6 @@ var init_config = __esm({
|
|
|
5599
5584
|
settings: {
|
|
5600
5585
|
mode: "standard",
|
|
5601
5586
|
autoStartDaemon: true,
|
|
5602
|
-
// The undo feature was REMOVED. This default is one of two places that say
|
|
5603
|
-
// so; the other is the pin further down, which overwrites whatever a config
|
|
5604
|
-
// file, the dashboard or the cloud supplies. Setting `enableUndo` anywhere
|
|
5605
|
-
// has no effect — do not restore the advice that used to live here, because
|
|
5606
|
-
// a comment recommending a knob that is silently discarded is the same lie
|
|
5607
|
-
// on disk the pin exists to prevent.
|
|
5608
|
-
//
|
|
5609
|
-
// Why it went: the store was a per-project bare git repo with no size
|
|
5610
|
-
// ceiling, and eviction dropped the index row without deleting the objects.
|
|
5611
|
-
// On one machine it reached 378G (352G of it orphaned tmp_pack_* from an
|
|
5612
|
-
// interrupted `git gc`) and filled the disk. A security tool must not be
|
|
5613
|
-
// what fills a customer's disk. Leftovers: `node9 undo --purge`.
|
|
5614
|
-
enableUndo: false,
|
|
5615
5587
|
enableHookLogDebug: true,
|
|
5616
5588
|
approvalTimeoutMs: 12e4,
|
|
5617
5589
|
// 120-second auto-deny timeout
|
|
@@ -5652,25 +5624,6 @@ var init_config = __esm({
|
|
|
5652
5624
|
"terminal.execute": "command",
|
|
5653
5625
|
"postgres:query": "sql"
|
|
5654
5626
|
},
|
|
5655
|
-
snapshot: {
|
|
5656
|
-
tools: [
|
|
5657
|
-
"str_replace_based_edit_tool",
|
|
5658
|
-
"write_file",
|
|
5659
|
-
"edit_file",
|
|
5660
|
-
"create_file",
|
|
5661
|
-
"edit",
|
|
5662
|
-
"replace",
|
|
5663
|
-
// Claude / canonicalised Hermes — shouldSnapshot lowercases the
|
|
5664
|
-
// incoming name before set-membership, so we list the lowercase
|
|
5665
|
-
// forms of `Bash`/`Write`/`Edit`/`MultiEdit`. Without these,
|
|
5666
|
-
// post-canonicalisation Hermes `patch` / `write_file` (which now
|
|
5667
|
-
// arrive as `Edit` / `Write`) silently skipped snapshotting.
|
|
5668
|
-
"write",
|
|
5669
|
-
"multiedit"
|
|
5670
|
-
],
|
|
5671
|
-
onlyPaths: [],
|
|
5672
|
-
ignorePaths: ["**/node_modules/**", "dist/**", "build/**", ".next/**", "**/*.log"]
|
|
5673
|
-
},
|
|
5674
5627
|
smartRules: [
|
|
5675
5628
|
// ── rm safety (critical — always evaluated first) ──────────────────────
|
|
5676
5629
|
{
|
|
@@ -6017,18 +5970,6 @@ var init_provenance = __esm({
|
|
|
6017
5970
|
});
|
|
6018
5971
|
|
|
6019
5972
|
// src/policy/index.ts
|
|
6020
|
-
function shouldSnapshot(toolName, args, config) {
|
|
6021
|
-
if (!config.settings.enableUndo) return false;
|
|
6022
|
-
const snap = config.policy.snapshot;
|
|
6023
|
-
if (!snap.tools.includes(toolName.toLowerCase())) return false;
|
|
6024
|
-
const a = args && typeof args === "object" ? args : {};
|
|
6025
|
-
const filePath = String(a.file_path ?? a.path ?? a.filename ?? "");
|
|
6026
|
-
if (filePath) {
|
|
6027
|
-
if (snap.ignorePaths.length && (0, import_picomatch2.default)(snap.ignorePaths)(filePath)) return false;
|
|
6028
|
-
if (snap.onlyPaths.length && !(0, import_picomatch2.default)(snap.onlyPaths)(filePath)) return false;
|
|
6029
|
-
}
|
|
6030
|
-
return true;
|
|
6031
|
-
}
|
|
6032
5973
|
async function evaluatePolicy2(toolName, args, agent, cwd, opts) {
|
|
6033
5974
|
const config = getConfig();
|
|
6034
5975
|
const activeEnvironment = getActiveEnvironment(config) ?? void 0;
|
|
@@ -6377,14 +6318,13 @@ async function deriveExplainTrace(toolName, args) {
|
|
|
6377
6318
|
});
|
|
6378
6319
|
return { tool: toolName, args, waterfall, steps, decision: "allow" };
|
|
6379
6320
|
}
|
|
6380
|
-
var import_fs7, import_path7, import_os6,
|
|
6321
|
+
var import_fs7, import_path7, import_os6, SQL_DML_KEYWORDS2, EXPLAIN_AGENT;
|
|
6381
6322
|
var init_policy = __esm({
|
|
6382
6323
|
"src/policy/index.ts"() {
|
|
6383
6324
|
"use strict";
|
|
6384
6325
|
import_fs7 = __toESM(require("fs"));
|
|
6385
6326
|
import_path7 = __toESM(require("path"));
|
|
6386
6327
|
import_os6 = __toESM(require("os"));
|
|
6387
|
-
import_picomatch2 = __toESM(require("picomatch"));
|
|
6388
6328
|
init_dlp();
|
|
6389
6329
|
init_config();
|
|
6390
6330
|
init_provenance();
|
|
@@ -16903,16 +16843,6 @@ function bindActivitySocket() {
|
|
|
16903
16843
|
sessionHistory.recordTestFail(data.ts);
|
|
16904
16844
|
return;
|
|
16905
16845
|
}
|
|
16906
|
-
if (data.status === "snapshot") {
|
|
16907
|
-
broadcast("snapshot", {
|
|
16908
|
-
hash: data.hash,
|
|
16909
|
-
tool: data.tool,
|
|
16910
|
-
argsSummary: data.argsSummary,
|
|
16911
|
-
fileCount: data.fileCount,
|
|
16912
|
-
ts: data.ts
|
|
16913
|
-
});
|
|
16914
|
-
return;
|
|
16915
|
-
}
|
|
16916
16846
|
if (data.status === "execution-completed") {
|
|
16917
16847
|
broadcast("execution-result", {
|
|
16918
16848
|
id: data.id,
|
|
@@ -22825,7 +22755,7 @@ var require_util = __commonJS({
|
|
|
22825
22755
|
var { kDestroyed, kBodyUsed, kListeners, kBody } = require_symbols();
|
|
22826
22756
|
var { IncomingMessage } = require("http");
|
|
22827
22757
|
var stream = require("stream");
|
|
22828
|
-
var
|
|
22758
|
+
var net3 = require("net");
|
|
22829
22759
|
var { stringify } = require("querystring");
|
|
22830
22760
|
var { EventEmitter: EE } = require("events");
|
|
22831
22761
|
var timers = require_timers();
|
|
@@ -22937,14 +22867,14 @@ var require_util = __commonJS({
|
|
|
22937
22867
|
}
|
|
22938
22868
|
const port = url.port != null ? url.port : url.protocol === "https:" ? 443 : 80;
|
|
22939
22869
|
let origin = url.origin != null ? url.origin : `${url.protocol || ""}//${url.hostname || ""}:${port}`;
|
|
22940
|
-
let
|
|
22870
|
+
let path71 = url.path != null ? url.path : `${url.pathname || ""}${url.search || ""}`;
|
|
22941
22871
|
if (origin[origin.length - 1] === "/") {
|
|
22942
22872
|
origin = origin.slice(0, origin.length - 1);
|
|
22943
22873
|
}
|
|
22944
|
-
if (
|
|
22945
|
-
|
|
22874
|
+
if (path71 && path71[0] !== "/") {
|
|
22875
|
+
path71 = `/${path71}`;
|
|
22946
22876
|
}
|
|
22947
|
-
return new URL(`${origin}${
|
|
22877
|
+
return new URL(`${origin}${path71}`);
|
|
22948
22878
|
}
|
|
22949
22879
|
if (!isHttpOrHttpsPrefixed(url.origin || url.protocol)) {
|
|
22950
22880
|
throw new InvalidArgumentError("Invalid URL protocol: the URL must start with `http:` or `https:`.");
|
|
@@ -22974,7 +22904,7 @@ var require_util = __commonJS({
|
|
|
22974
22904
|
}
|
|
22975
22905
|
assert(typeof host === "string");
|
|
22976
22906
|
const servername = getHostname(host);
|
|
22977
|
-
if (
|
|
22907
|
+
if (net3.isIP(servername)) {
|
|
22978
22908
|
return "";
|
|
22979
22909
|
}
|
|
22980
22910
|
return servername;
|
|
@@ -23765,9 +23695,9 @@ var require_diagnostics = __commonJS({
|
|
|
23765
23695
|
"undici:client:sendHeaders",
|
|
23766
23696
|
(evt) => {
|
|
23767
23697
|
const {
|
|
23768
|
-
request: { method, path:
|
|
23698
|
+
request: { method, path: path71, origin }
|
|
23769
23699
|
} = evt;
|
|
23770
|
-
debugLog("sending request to %s %s%s", method, origin,
|
|
23700
|
+
debugLog("sending request to %s %s%s", method, origin, path71);
|
|
23771
23701
|
}
|
|
23772
23702
|
);
|
|
23773
23703
|
}
|
|
@@ -23785,14 +23715,14 @@ var require_diagnostics = __commonJS({
|
|
|
23785
23715
|
"undici:request:headers",
|
|
23786
23716
|
(evt) => {
|
|
23787
23717
|
const {
|
|
23788
|
-
request: { method, path:
|
|
23718
|
+
request: { method, path: path71, origin },
|
|
23789
23719
|
response: { statusCode }
|
|
23790
23720
|
} = evt;
|
|
23791
23721
|
debugLog(
|
|
23792
23722
|
"received response to %s %s%s - HTTP %d",
|
|
23793
23723
|
method,
|
|
23794
23724
|
origin,
|
|
23795
|
-
|
|
23725
|
+
path71,
|
|
23796
23726
|
statusCode
|
|
23797
23727
|
);
|
|
23798
23728
|
}
|
|
@@ -23801,23 +23731,23 @@ var require_diagnostics = __commonJS({
|
|
|
23801
23731
|
"undici:request:trailers",
|
|
23802
23732
|
(evt) => {
|
|
23803
23733
|
const {
|
|
23804
|
-
request: { method, path:
|
|
23734
|
+
request: { method, path: path71, origin }
|
|
23805
23735
|
} = evt;
|
|
23806
|
-
debugLog("trailers received from %s %s%s", method, origin,
|
|
23736
|
+
debugLog("trailers received from %s %s%s", method, origin, path71);
|
|
23807
23737
|
}
|
|
23808
23738
|
);
|
|
23809
23739
|
diagnosticsChannel.subscribe(
|
|
23810
23740
|
"undici:request:error",
|
|
23811
23741
|
(evt) => {
|
|
23812
23742
|
const {
|
|
23813
|
-
request: { method, path:
|
|
23743
|
+
request: { method, path: path71, origin },
|
|
23814
23744
|
error
|
|
23815
23745
|
} = evt;
|
|
23816
23746
|
debugLog(
|
|
23817
23747
|
"request to %s %s%s errored - %s",
|
|
23818
23748
|
method,
|
|
23819
23749
|
origin,
|
|
23820
|
-
|
|
23750
|
+
path71,
|
|
23821
23751
|
error.message
|
|
23822
23752
|
);
|
|
23823
23753
|
}
|
|
@@ -23920,7 +23850,7 @@ var require_request = __commonJS({
|
|
|
23920
23850
|
var kHandler = /* @__PURE__ */ Symbol("handler");
|
|
23921
23851
|
var Request = class {
|
|
23922
23852
|
constructor(origin, {
|
|
23923
|
-
path:
|
|
23853
|
+
path: path71,
|
|
23924
23854
|
method,
|
|
23925
23855
|
body,
|
|
23926
23856
|
headers,
|
|
@@ -23937,11 +23867,11 @@ var require_request = __commonJS({
|
|
|
23937
23867
|
maxRedirections,
|
|
23938
23868
|
typeOfService
|
|
23939
23869
|
}, handler) {
|
|
23940
|
-
if (typeof
|
|
23870
|
+
if (typeof path71 !== "string") {
|
|
23941
23871
|
throw new InvalidArgumentError("path must be a string");
|
|
23942
|
-
} else if (
|
|
23872
|
+
} else if (path71[0] !== "/" && !(path71.startsWith("http://") || path71.startsWith("https://")) && method !== "CONNECT") {
|
|
23943
23873
|
throw new InvalidArgumentError("path must be an absolute URL or start with a slash");
|
|
23944
|
-
} else if (invalidPathRegex.test(
|
|
23874
|
+
} else if (invalidPathRegex.test(path71)) {
|
|
23945
23875
|
throw new InvalidArgumentError("invalid request path");
|
|
23946
23876
|
}
|
|
23947
23877
|
if (typeof method !== "string") {
|
|
@@ -24016,7 +23946,7 @@ var require_request = __commonJS({
|
|
|
24016
23946
|
this.completed = false;
|
|
24017
23947
|
this.aborted = false;
|
|
24018
23948
|
this.upgrade = upgrade || null;
|
|
24019
|
-
this.path = query ? serializePathWithQuery(
|
|
23949
|
+
this.path = query ? serializePathWithQuery(path71, query) : path71;
|
|
24020
23950
|
this.origin = origin;
|
|
24021
23951
|
this.protocol = getProtocolFromUrlString(origin);
|
|
24022
23952
|
this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" : idempotent;
|
|
@@ -24595,7 +24525,7 @@ var require_dispatcher_base = __commonJS({
|
|
|
24595
24525
|
var require_connect = __commonJS({
|
|
24596
24526
|
"node_modules/undici/lib/core/connect.js"(exports2, module2) {
|
|
24597
24527
|
"use strict";
|
|
24598
|
-
var
|
|
24528
|
+
var net3 = require("net");
|
|
24599
24529
|
var assert = require("assert");
|
|
24600
24530
|
var util = require_util();
|
|
24601
24531
|
var { InvalidArgumentError } = require_errors();
|
|
@@ -24664,7 +24594,7 @@ var require_connect = __commonJS({
|
|
|
24664
24594
|
} else {
|
|
24665
24595
|
assert(!httpSocket, "httpSocket can only be sent on TLS update");
|
|
24666
24596
|
port = port || 80;
|
|
24667
|
-
socket =
|
|
24597
|
+
socket = net3.connect({
|
|
24668
24598
|
highWaterMark: 64 * 1024,
|
|
24669
24599
|
// Same as nodejs fs streams.
|
|
24670
24600
|
...options,
|
|
@@ -29055,7 +28985,7 @@ var require_client_h1 = __commonJS({
|
|
|
29055
28985
|
return method !== "GET" && method !== "HEAD" && method !== "OPTIONS" && method !== "TRACE" && method !== "CONNECT";
|
|
29056
28986
|
}
|
|
29057
28987
|
function writeH1(client, request2) {
|
|
29058
|
-
const { method, path:
|
|
28988
|
+
const { method, path: path71, host, upgrade, blocking, reset } = request2;
|
|
29059
28989
|
let { body, headers, contentLength } = request2;
|
|
29060
28990
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH" || method === "QUERY" || method === "PROPFIND" || method === "PROPPATCH";
|
|
29061
28991
|
if (util.isFormDataLike(body)) {
|
|
@@ -29124,7 +29054,7 @@ var require_client_h1 = __commonJS({
|
|
|
29124
29054
|
if (socket.setTypeOfService) {
|
|
29125
29055
|
socket.setTypeOfService(request2.typeOfService);
|
|
29126
29056
|
}
|
|
29127
|
-
let header = `${method} ${
|
|
29057
|
+
let header = `${method} ${path71} HTTP/1.1\r
|
|
29128
29058
|
`;
|
|
29129
29059
|
if (typeof host === "string") {
|
|
29130
29060
|
header += `host: ${host}\r
|
|
@@ -29777,7 +29707,7 @@ var require_client_h2 = __commonJS({
|
|
|
29777
29707
|
function writeH2(client, request2) {
|
|
29778
29708
|
const requestTimeout = request2.bodyTimeout ?? client[kBodyTimeout];
|
|
29779
29709
|
const session = client[kHTTP2Session];
|
|
29780
|
-
const { method, path:
|
|
29710
|
+
const { method, path: path71, host, upgrade, expectContinue, signal, protocol, headers: reqHeaders } = request2;
|
|
29781
29711
|
let { body } = request2;
|
|
29782
29712
|
if (upgrade != null && upgrade !== "websocket") {
|
|
29783
29713
|
util.errorRequest(client, request2, new InvalidArgumentError(`Custom upgrade "${upgrade}" not supported over HTTP/2`));
|
|
@@ -29845,7 +29775,7 @@ var require_client_h2 = __commonJS({
|
|
|
29845
29775
|
}
|
|
29846
29776
|
headers[HTTP2_HEADER_METHOD] = "CONNECT";
|
|
29847
29777
|
headers[HTTP2_HEADER_PROTOCOL] = "websocket";
|
|
29848
|
-
headers[HTTP2_HEADER_PATH] =
|
|
29778
|
+
headers[HTTP2_HEADER_PATH] = path71;
|
|
29849
29779
|
if (protocol === "ws:" || protocol === "wss:") {
|
|
29850
29780
|
headers[HTTP2_HEADER_SCHEME] = protocol === "ws:" ? "http" : "https";
|
|
29851
29781
|
} else {
|
|
@@ -29886,7 +29816,7 @@ var require_client_h2 = __commonJS({
|
|
|
29886
29816
|
stream.setTimeout(requestTimeout);
|
|
29887
29817
|
return true;
|
|
29888
29818
|
}
|
|
29889
|
-
headers[HTTP2_HEADER_PATH] =
|
|
29819
|
+
headers[HTTP2_HEADER_PATH] = path71;
|
|
29890
29820
|
headers[HTTP2_HEADER_SCHEME] = protocol === "http:" ? "http" : "https";
|
|
29891
29821
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
|
|
29892
29822
|
if (body && typeof body.read === "function") {
|
|
@@ -30202,7 +30132,7 @@ var require_client = __commonJS({
|
|
|
30202
30132
|
"node_modules/undici/lib/dispatcher/client.js"(exports2, module2) {
|
|
30203
30133
|
"use strict";
|
|
30204
30134
|
var assert = require("assert");
|
|
30205
|
-
var
|
|
30135
|
+
var net3 = require("net");
|
|
30206
30136
|
var http7 = require("http");
|
|
30207
30137
|
var util = require_util();
|
|
30208
30138
|
var { ClientStats } = require_stats();
|
|
@@ -30356,7 +30286,7 @@ var require_client = __commonJS({
|
|
|
30356
30286
|
if (maxRequestsPerClient != null && (!Number.isInteger(maxRequestsPerClient) || maxRequestsPerClient < 0)) {
|
|
30357
30287
|
throw new InvalidArgumentError("maxRequestsPerClient must be a positive number");
|
|
30358
30288
|
}
|
|
30359
|
-
if (localAddress != null && (typeof localAddress !== "string" ||
|
|
30289
|
+
if (localAddress != null && (typeof localAddress !== "string" || net3.isIP(localAddress) === 0)) {
|
|
30360
30290
|
throw new InvalidArgumentError("localAddress must be valid string IP address");
|
|
30361
30291
|
}
|
|
30362
30292
|
if (maxResponseSize != null && (!Number.isInteger(maxResponseSize) || maxResponseSize < -1)) {
|
|
@@ -30528,7 +30458,7 @@ var require_client = __commonJS({
|
|
|
30528
30458
|
const idx = hostname.indexOf("]");
|
|
30529
30459
|
assert(idx !== -1);
|
|
30530
30460
|
const ip = hostname.substring(1, idx);
|
|
30531
|
-
assert(
|
|
30461
|
+
assert(net3.isIPv6(ip));
|
|
30532
30462
|
hostname = ip;
|
|
30533
30463
|
}
|
|
30534
30464
|
client[kConnecting] = true;
|
|
@@ -31471,10 +31401,10 @@ var require_socks5_utils = __commonJS({
|
|
|
31471
31401
|
"node_modules/undici/lib/core/socks5-utils.js"(exports2, module2) {
|
|
31472
31402
|
"use strict";
|
|
31473
31403
|
var { Buffer: Buffer2 } = require("buffer");
|
|
31474
|
-
var
|
|
31404
|
+
var net3 = require("net");
|
|
31475
31405
|
var { InvalidArgumentError } = require_errors();
|
|
31476
31406
|
function parseAddress(address) {
|
|
31477
|
-
if (
|
|
31407
|
+
if (net3.isIPv4(address)) {
|
|
31478
31408
|
const parts = address.split(".").map(Number);
|
|
31479
31409
|
return {
|
|
31480
31410
|
type: 1,
|
|
@@ -31482,7 +31412,7 @@ var require_socks5_utils = __commonJS({
|
|
|
31482
31412
|
buffer: Buffer2.from(parts)
|
|
31483
31413
|
};
|
|
31484
31414
|
}
|
|
31485
|
-
if (
|
|
31415
|
+
if (net3.isIPv6(address)) {
|
|
31486
31416
|
return {
|
|
31487
31417
|
type: 4,
|
|
31488
31418
|
// IPv6
|
|
@@ -31942,7 +31872,7 @@ var require_socks5_client = __commonJS({
|
|
|
31942
31872
|
var require_socks5_proxy_agent = __commonJS({
|
|
31943
31873
|
"node_modules/undici/lib/dispatcher/socks5-proxy-agent.js"(exports2, module2) {
|
|
31944
31874
|
"use strict";
|
|
31945
|
-
var
|
|
31875
|
+
var net3 = require("net");
|
|
31946
31876
|
var { URL: URL5 } = require("url");
|
|
31947
31877
|
var tls;
|
|
31948
31878
|
var DispatcherBase = require_dispatcher_base();
|
|
@@ -32004,7 +31934,7 @@ var require_socks5_proxy_agent = __commonJS({
|
|
|
32004
31934
|
socket2.removeListener("connect", onConnect);
|
|
32005
31935
|
reject(err2);
|
|
32006
31936
|
};
|
|
32007
|
-
const socket2 =
|
|
31937
|
+
const socket2 = net3.connect({
|
|
32008
31938
|
host: proxyHost,
|
|
32009
31939
|
port: proxyPort
|
|
32010
31940
|
});
|
|
@@ -32188,10 +32118,10 @@ var require_proxy_agent = __commonJS({
|
|
|
32188
32118
|
};
|
|
32189
32119
|
const {
|
|
32190
32120
|
origin,
|
|
32191
|
-
path:
|
|
32121
|
+
path: path71 = "/",
|
|
32192
32122
|
headers = {}
|
|
32193
32123
|
} = opts;
|
|
32194
|
-
opts.path = origin +
|
|
32124
|
+
opts.path = origin + path71;
|
|
32195
32125
|
if (!("host" in headers) && !("Host" in headers)) {
|
|
32196
32126
|
const { host } = new URL(origin);
|
|
32197
32127
|
headers.host = host;
|
|
@@ -34254,20 +34184,20 @@ var require_mock_utils = __commonJS({
|
|
|
34254
34184
|
}
|
|
34255
34185
|
return normalizedQp;
|
|
34256
34186
|
}
|
|
34257
|
-
function safeUrl(
|
|
34258
|
-
if (typeof
|
|
34259
|
-
return
|
|
34187
|
+
function safeUrl(path71) {
|
|
34188
|
+
if (typeof path71 !== "string") {
|
|
34189
|
+
return path71;
|
|
34260
34190
|
}
|
|
34261
|
-
const pathSegments =
|
|
34191
|
+
const pathSegments = path71.split("?", 3);
|
|
34262
34192
|
if (pathSegments.length !== 2) {
|
|
34263
|
-
return
|
|
34193
|
+
return path71;
|
|
34264
34194
|
}
|
|
34265
34195
|
const qp = new URLSearchParams(pathSegments.pop());
|
|
34266
34196
|
qp.sort();
|
|
34267
34197
|
return [...pathSegments, qp.toString()].join("?");
|
|
34268
34198
|
}
|
|
34269
|
-
function matchKey(mockDispatch2, { path:
|
|
34270
|
-
const pathMatch = matchValue(mockDispatch2.path,
|
|
34199
|
+
function matchKey(mockDispatch2, { path: path71, method, body, headers }) {
|
|
34200
|
+
const pathMatch = matchValue(mockDispatch2.path, path71);
|
|
34271
34201
|
const methodMatch = matchValue(mockDispatch2.method, method);
|
|
34272
34202
|
const bodyMatch = typeof mockDispatch2.body !== "undefined" ? matchValue(mockDispatch2.body, body) : true;
|
|
34273
34203
|
const headersMatch = matchHeaders(mockDispatch2, headers);
|
|
@@ -34292,8 +34222,8 @@ var require_mock_utils = __commonJS({
|
|
|
34292
34222
|
const basePath = key.query ? serializePathWithQuery(key.path, key.query) : key.path;
|
|
34293
34223
|
const resolvedPath = typeof basePath === "string" ? safeUrl(basePath) : basePath;
|
|
34294
34224
|
const resolvedPathWithoutTrailingSlash = removeTrailingSlash(resolvedPath);
|
|
34295
|
-
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path:
|
|
34296
|
-
return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(
|
|
34225
|
+
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path71, ignoreTrailingSlash }) => {
|
|
34226
|
+
return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(path71)), resolvedPathWithoutTrailingSlash) : matchValue(safeUrl(path71), resolvedPath);
|
|
34297
34227
|
});
|
|
34298
34228
|
if (matchedMockDispatches.length === 0) {
|
|
34299
34229
|
throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`);
|
|
@@ -34332,19 +34262,19 @@ var require_mock_utils = __commonJS({
|
|
|
34332
34262
|
mockDispatches.splice(index, 1);
|
|
34333
34263
|
}
|
|
34334
34264
|
}
|
|
34335
|
-
function removeTrailingSlash(
|
|
34336
|
-
while (
|
|
34337
|
-
|
|
34265
|
+
function removeTrailingSlash(path71) {
|
|
34266
|
+
while (path71.endsWith("/")) {
|
|
34267
|
+
path71 = path71.slice(0, -1);
|
|
34338
34268
|
}
|
|
34339
|
-
if (
|
|
34340
|
-
|
|
34269
|
+
if (path71.length === 0) {
|
|
34270
|
+
path71 = "/";
|
|
34341
34271
|
}
|
|
34342
|
-
return
|
|
34272
|
+
return path71;
|
|
34343
34273
|
}
|
|
34344
34274
|
function buildKey(opts) {
|
|
34345
|
-
const { path:
|
|
34275
|
+
const { path: path71, method, body, headers, query } = opts;
|
|
34346
34276
|
return {
|
|
34347
|
-
path:
|
|
34277
|
+
path: path71,
|
|
34348
34278
|
method,
|
|
34349
34279
|
body,
|
|
34350
34280
|
headers,
|
|
@@ -35034,10 +34964,10 @@ var require_pending_interceptors_formatter = __commonJS({
|
|
|
35034
34964
|
}
|
|
35035
34965
|
format(pendingInterceptors) {
|
|
35036
34966
|
const withPrettyHeaders = pendingInterceptors.map(
|
|
35037
|
-
({ method, path:
|
|
34967
|
+
({ method, path: path71, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
|
|
35038
34968
|
Method: method,
|
|
35039
34969
|
Origin: origin,
|
|
35040
|
-
Path:
|
|
34970
|
+
Path: path71,
|
|
35041
34971
|
"Status code": statusCode,
|
|
35042
34972
|
Persistent: persist ? PERSISTENT : NOT_PERSISTENT,
|
|
35043
34973
|
Invocations: timesInvoked,
|
|
@@ -35119,9 +35049,9 @@ var require_mock_agent = __commonJS({
|
|
|
35119
35049
|
const acceptNonStandardSearchParameters = this[kMockAgentAcceptsNonStandardSearchParameters];
|
|
35120
35050
|
const dispatchOpts = { ...opts };
|
|
35121
35051
|
if (acceptNonStandardSearchParameters && dispatchOpts.path) {
|
|
35122
|
-
const [
|
|
35052
|
+
const [path71, searchParams] = dispatchOpts.path.split("?");
|
|
35123
35053
|
const normalizedSearchParams = normalizeSearchParams(searchParams, acceptNonStandardSearchParameters);
|
|
35124
|
-
dispatchOpts.path = `${
|
|
35054
|
+
dispatchOpts.path = `${path71}?${normalizedSearchParams}`;
|
|
35125
35055
|
}
|
|
35126
35056
|
return this[kAgent].dispatch(dispatchOpts, handler);
|
|
35127
35057
|
}
|
|
@@ -35249,8 +35179,8 @@ var require_snapshot_utils = __commonJS({
|
|
|
35249
35179
|
match: new Set(matchHeaders.map((header) => caseSensitive ? header : header.toLowerCase()))
|
|
35250
35180
|
};
|
|
35251
35181
|
}
|
|
35252
|
-
var
|
|
35253
|
-
var hashId =
|
|
35182
|
+
var crypto9 = runtimeFeatures.has("crypto") ? require("crypto") : null;
|
|
35183
|
+
var hashId = crypto9?.hash ? (value) => crypto9.hash("sha256", value, "base64url") : (value) => Buffer.from(value).toString("base64url");
|
|
35254
35184
|
function isUndiciHeaders(headers) {
|
|
35255
35185
|
return Array.isArray(headers) && (headers.length & 1) === 0;
|
|
35256
35186
|
}
|
|
@@ -35522,12 +35452,12 @@ var require_snapshot_recorder = __commonJS({
|
|
|
35522
35452
|
* @return {Promise<void>} - Resolves when snapshots are loaded
|
|
35523
35453
|
*/
|
|
35524
35454
|
async loadSnapshots(filePath) {
|
|
35525
|
-
const
|
|
35526
|
-
if (!
|
|
35455
|
+
const path71 = filePath || this.#snapshotPath;
|
|
35456
|
+
if (!path71) {
|
|
35527
35457
|
throw new InvalidArgumentError("Snapshot path is required");
|
|
35528
35458
|
}
|
|
35529
35459
|
try {
|
|
35530
|
-
const data = await readFile(resolve2(
|
|
35460
|
+
const data = await readFile(resolve2(path71), "utf8");
|
|
35531
35461
|
const parsed = JSON.parse(data);
|
|
35532
35462
|
if (Array.isArray(parsed)) {
|
|
35533
35463
|
this.#snapshots.clear();
|
|
@@ -35541,7 +35471,7 @@ var require_snapshot_recorder = __commonJS({
|
|
|
35541
35471
|
if (error.code === "ENOENT") {
|
|
35542
35472
|
this.#snapshots.clear();
|
|
35543
35473
|
} else {
|
|
35544
|
-
throw new UndiciError(`Failed to load snapshots from ${
|
|
35474
|
+
throw new UndiciError(`Failed to load snapshots from ${path71}`, { cause: error });
|
|
35545
35475
|
}
|
|
35546
35476
|
}
|
|
35547
35477
|
}
|
|
@@ -35552,11 +35482,11 @@ var require_snapshot_recorder = __commonJS({
|
|
|
35552
35482
|
* @returns {Promise<void>} - Resolves when snapshots are saved
|
|
35553
35483
|
*/
|
|
35554
35484
|
async saveSnapshots(filePath) {
|
|
35555
|
-
const
|
|
35556
|
-
if (!
|
|
35485
|
+
const path71 = filePath || this.#snapshotPath;
|
|
35486
|
+
if (!path71) {
|
|
35557
35487
|
throw new InvalidArgumentError("Snapshot path is required");
|
|
35558
35488
|
}
|
|
35559
|
-
const resolvedPath = resolve2(
|
|
35489
|
+
const resolvedPath = resolve2(path71);
|
|
35560
35490
|
await mkdir(dirname2(resolvedPath), { recursive: true });
|
|
35561
35491
|
const data = Array.from(this.#snapshots.entries()).map(([hash, snapshot]) => ({
|
|
35562
35492
|
hash,
|
|
@@ -36181,15 +36111,15 @@ var require_redirect_handler = __commonJS({
|
|
|
36181
36111
|
return;
|
|
36182
36112
|
}
|
|
36183
36113
|
const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)));
|
|
36184
|
-
const
|
|
36185
|
-
const redirectUrlString = `${origin}${
|
|
36114
|
+
const path71 = search ? `${pathname}${search}` : pathname;
|
|
36115
|
+
const redirectUrlString = `${origin}${path71}`;
|
|
36186
36116
|
for (const historyUrl of this.history) {
|
|
36187
36117
|
if (historyUrl.toString() === redirectUrlString) {
|
|
36188
36118
|
throw new InvalidArgumentError(`Redirect loop detected. Cannot redirect to ${origin}. This typically happens when using a Client or Pool with cross-origin redirects. Use an Agent for cross-origin redirects.`);
|
|
36189
36119
|
}
|
|
36190
36120
|
}
|
|
36191
36121
|
this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin);
|
|
36192
|
-
this.opts.path =
|
|
36122
|
+
this.opts.path = path71;
|
|
36193
36123
|
this.opts.origin = origin;
|
|
36194
36124
|
this.opts.query = null;
|
|
36195
36125
|
}
|
|
@@ -41308,10 +41238,10 @@ var require_subresource_integrity = __commonJS({
|
|
|
41308
41238
|
var assert = require("assert");
|
|
41309
41239
|
var { runtimeFeatures } = require_runtime_features();
|
|
41310
41240
|
var validSRIHashAlgorithmTokenSet = /* @__PURE__ */ new Map([["sha256", 0], ["sha384", 1], ["sha512", 2]]);
|
|
41311
|
-
var
|
|
41241
|
+
var crypto9;
|
|
41312
41242
|
if (runtimeFeatures.has("crypto")) {
|
|
41313
|
-
|
|
41314
|
-
const cryptoHashes =
|
|
41243
|
+
crypto9 = require("crypto");
|
|
41244
|
+
const cryptoHashes = crypto9.getHashes();
|
|
41315
41245
|
if (cryptoHashes.length === 0) {
|
|
41316
41246
|
validSRIHashAlgorithmTokenSet.clear();
|
|
41317
41247
|
}
|
|
@@ -41401,7 +41331,7 @@ var require_subresource_integrity = __commonJS({
|
|
|
41401
41331
|
return result;
|
|
41402
41332
|
}
|
|
41403
41333
|
var applyAlgorithmToBytes = (algorithm, bytes) => {
|
|
41404
|
-
return
|
|
41334
|
+
return crypto9.hash(algorithm, bytes, "base64");
|
|
41405
41335
|
};
|
|
41406
41336
|
function caseSensitiveMatch(actualValue, expectedValue) {
|
|
41407
41337
|
let actualValueLength = actualValue.length;
|
|
@@ -42396,11 +42326,11 @@ var require_fetch = __commonJS({
|
|
|
42396
42326
|
function dispatch({ body }) {
|
|
42397
42327
|
const url = requestCurrentURL(request2);
|
|
42398
42328
|
const agent = fetchParams.controller.dispatcher;
|
|
42399
|
-
const
|
|
42329
|
+
const path71 = url.pathname + url.search;
|
|
42400
42330
|
const hasTrailingQuestionMark = url.search.length === 0 && url.href[url.href.length - url.hash.length - 1] === "?";
|
|
42401
42331
|
return new Promise((resolve2, reject) => agent.dispatch(
|
|
42402
42332
|
{
|
|
42403
|
-
path: hasTrailingQuestionMark ? `${
|
|
42333
|
+
path: hasTrailingQuestionMark ? `${path71}?` : path71,
|
|
42404
42334
|
origin: url.origin,
|
|
42405
42335
|
method: request2.method,
|
|
42406
42336
|
body: agent.isMockActive ? request2.body && (request2.body.source || request2.body.stream) : body,
|
|
@@ -43331,9 +43261,9 @@ var require_util4 = __commonJS({
|
|
|
43331
43261
|
}
|
|
43332
43262
|
}
|
|
43333
43263
|
}
|
|
43334
|
-
function validateCookiePath(
|
|
43335
|
-
for (let i = 0; i <
|
|
43336
|
-
const code =
|
|
43264
|
+
function validateCookiePath(path71) {
|
|
43265
|
+
for (let i = 0; i < path71.length; ++i) {
|
|
43266
|
+
const code = path71.charCodeAt(i);
|
|
43337
43267
|
if (code < 32 || // exclude CTLs (0-31)
|
|
43338
43268
|
code === 127 || // DEL
|
|
43339
43269
|
code === 59) {
|
|
@@ -44335,7 +44265,7 @@ var require_connection = __commonJS({
|
|
|
44335
44265
|
var { WebsocketFrameSend } = require_frame();
|
|
44336
44266
|
var assert = require("assert");
|
|
44337
44267
|
var { runtimeFeatures } = require_runtime_features();
|
|
44338
|
-
var
|
|
44268
|
+
var crypto9 = runtimeFeatures.has("crypto") ? require("crypto") : null;
|
|
44339
44269
|
var warningEmitted = false;
|
|
44340
44270
|
function establishWebSocketConnection(url, protocols, client, handler, options) {
|
|
44341
44271
|
const requestURL = url;
|
|
@@ -44355,7 +44285,7 @@ var require_connection = __commonJS({
|
|
|
44355
44285
|
const headersList = getHeadersList(new Headers(options.headers));
|
|
44356
44286
|
request2.headersList = headersList;
|
|
44357
44287
|
}
|
|
44358
|
-
const keyValue =
|
|
44288
|
+
const keyValue = crypto9.randomBytes(16).toString("base64");
|
|
44359
44289
|
request2.headersList.append("sec-websocket-key", keyValue, true);
|
|
44360
44290
|
request2.headersList.append("sec-websocket-version", "13", true);
|
|
44361
44291
|
for (const protocol of protocols) {
|
|
@@ -44395,7 +44325,7 @@ var require_connection = __commonJS({
|
|
|
44395
44325
|
return;
|
|
44396
44326
|
}
|
|
44397
44327
|
const secWSAccept = response.headersList.get("Sec-WebSocket-Accept");
|
|
44398
|
-
const digest =
|
|
44328
|
+
const digest = crypto9.hash("sha1", keyValue + uid, "base64");
|
|
44399
44329
|
if (secWSAccept !== digest) {
|
|
44400
44330
|
failWebsocketConnection(handler, 1002, "Incorrect hash received in Sec-WebSocket-Accept header.");
|
|
44401
44331
|
return;
|
|
@@ -46503,11 +46433,11 @@ var require_undici = __commonJS({
|
|
|
46503
46433
|
if (typeof opts.path !== "string") {
|
|
46504
46434
|
throw new InvalidArgumentError("invalid opts.path");
|
|
46505
46435
|
}
|
|
46506
|
-
let
|
|
46436
|
+
let path71 = opts.path;
|
|
46507
46437
|
if (!opts.path.startsWith("/")) {
|
|
46508
|
-
|
|
46438
|
+
path71 = `/${path71}`;
|
|
46509
46439
|
}
|
|
46510
|
-
url = new URL(util.parseOrigin(url).origin +
|
|
46440
|
+
url = new URL(util.parseOrigin(url).origin + path71);
|
|
46511
46441
|
} else {
|
|
46512
46442
|
if (!opts) {
|
|
46513
46443
|
opts = typeof url === "object" ? url : {};
|
|
@@ -46649,20 +46579,20 @@ function getModelContextLimit(model) {
|
|
|
46649
46579
|
return 2e5;
|
|
46650
46580
|
}
|
|
46651
46581
|
function readSessionUsage() {
|
|
46652
|
-
const projectsDir =
|
|
46653
|
-
if (!
|
|
46582
|
+
const projectsDir = import_path67.default.join(import_os60.default.homedir(), ".claude", "projects");
|
|
46583
|
+
if (!import_fs72.default.existsSync(projectsDir)) return null;
|
|
46654
46584
|
let latestFile = null;
|
|
46655
46585
|
let latestMtime = 0;
|
|
46656
46586
|
try {
|
|
46657
|
-
for (const dir of
|
|
46658
|
-
const dirPath =
|
|
46587
|
+
for (const dir of import_fs72.default.readdirSync(projectsDir)) {
|
|
46588
|
+
const dirPath = import_path67.default.join(projectsDir, dir);
|
|
46659
46589
|
try {
|
|
46660
|
-
if (!
|
|
46661
|
-
for (const file of
|
|
46590
|
+
if (!import_fs72.default.statSync(dirPath).isDirectory()) continue;
|
|
46591
|
+
for (const file of import_fs72.default.readdirSync(dirPath)) {
|
|
46662
46592
|
if (!file.endsWith(".jsonl") || file.startsWith("agent-")) continue;
|
|
46663
|
-
const filePath =
|
|
46593
|
+
const filePath = import_path67.default.join(dirPath, file);
|
|
46664
46594
|
try {
|
|
46665
|
-
const mtime =
|
|
46595
|
+
const mtime = import_fs72.default.statSync(filePath).mtimeMs;
|
|
46666
46596
|
if (mtime > latestMtime) {
|
|
46667
46597
|
latestMtime = mtime;
|
|
46668
46598
|
latestFile = filePath;
|
|
@@ -46677,7 +46607,7 @@ function readSessionUsage() {
|
|
|
46677
46607
|
}
|
|
46678
46608
|
if (!latestFile) return null;
|
|
46679
46609
|
try {
|
|
46680
|
-
const lines =
|
|
46610
|
+
const lines = import_fs72.default.readFileSync(latestFile, "utf-8").split("\n");
|
|
46681
46611
|
let lastModel = "";
|
|
46682
46612
|
let lastInput = 0;
|
|
46683
46613
|
let lastOutput = 0;
|
|
@@ -46738,7 +46668,7 @@ function formatBase(activity) {
|
|
|
46738
46668
|
const time = new Date(activity.ts).toLocaleTimeString([], { hour12: false });
|
|
46739
46669
|
const icon = getIcon(activity.tool);
|
|
46740
46670
|
const toolName = activity.tool.slice(0, 16).padEnd(16);
|
|
46741
|
-
const argsStr = JSON.stringify(activity.args ?? {}).replace(/\s+/g, " ").replaceAll(
|
|
46671
|
+
const argsStr = JSON.stringify(activity.args ?? {}).replace(/\s+/g, " ").replaceAll(import_os60.default.homedir(), "~");
|
|
46742
46672
|
const argsPreview = argsStr.length > 70 ? argsStr.slice(0, 70) + "\u2026" : argsStr;
|
|
46743
46673
|
return `${import_chalk39.default.gray(time)} ${icon} ${agentLabel(activity.agent, activity.mcpServer, activity.sessionId)}${import_chalk39.default.white.bold(toolName)} ${import_chalk39.default.dim(argsPreview)}`;
|
|
46744
46674
|
}
|
|
@@ -46777,9 +46707,9 @@ function renderPending(activity) {
|
|
|
46777
46707
|
}
|
|
46778
46708
|
async function ensureDaemon() {
|
|
46779
46709
|
let pidPort = null;
|
|
46780
|
-
if (
|
|
46710
|
+
if (import_fs72.default.existsSync(PID_FILE)) {
|
|
46781
46711
|
try {
|
|
46782
|
-
const { port } = JSON.parse(
|
|
46712
|
+
const { port } = JSON.parse(import_fs72.default.readFileSync(PID_FILE, "utf-8"));
|
|
46783
46713
|
pidPort = port;
|
|
46784
46714
|
} catch {
|
|
46785
46715
|
console.error(import_chalk39.default.dim("\u26A0\uFE0F Could not read PID file; falling back to default port."));
|
|
@@ -46796,7 +46726,7 @@ async function ensureDaemon() {
|
|
|
46796
46726
|
console.log(import_chalk39.default.dim("\u{1F6E1}\uFE0F Starting Node9 daemon..."));
|
|
46797
46727
|
const startupFd = openStartupLogFd();
|
|
46798
46728
|
recordStartupState("starting");
|
|
46799
|
-
const child = (0,
|
|
46729
|
+
const child = (0, import_child_process13.spawn)(process.execPath, [process.argv[1], "daemon"], {
|
|
46800
46730
|
detached: true,
|
|
46801
46731
|
stdio: ["ignore", "ignore", startupFd ?? "ignore"],
|
|
46802
46732
|
env: { ...process.env, NODE9_AUTO_STARTED: "1" }
|
|
@@ -46805,7 +46735,7 @@ async function ensureDaemon() {
|
|
|
46805
46735
|
child.unref();
|
|
46806
46736
|
if (startupFd !== void 0) {
|
|
46807
46737
|
try {
|
|
46808
|
-
|
|
46738
|
+
import_fs72.default.closeSync(startupFd);
|
|
46809
46739
|
} catch {
|
|
46810
46740
|
}
|
|
46811
46741
|
}
|
|
@@ -46944,9 +46874,9 @@ function buildRecoveryCardLines(req) {
|
|
|
46944
46874
|
];
|
|
46945
46875
|
}
|
|
46946
46876
|
function readApproversFromDisk() {
|
|
46947
|
-
const configPath =
|
|
46877
|
+
const configPath = import_path67.default.join(import_os60.default.homedir(), ".node9", "config.json");
|
|
46948
46878
|
try {
|
|
46949
|
-
const raw = JSON.parse(
|
|
46879
|
+
const raw = JSON.parse(import_fs72.default.readFileSync(configPath, "utf-8"));
|
|
46950
46880
|
const settings = raw.settings ?? {};
|
|
46951
46881
|
return settings.approvers ?? {};
|
|
46952
46882
|
} catch {
|
|
@@ -46962,15 +46892,15 @@ function approverStatusLine() {
|
|
|
46962
46892
|
return `${fmt("native", "native")} ${fmt("cloud", "cloud")} ${fmt("terminal", "terminal")}`;
|
|
46963
46893
|
}
|
|
46964
46894
|
function toggleApprover(channel) {
|
|
46965
|
-
const configPath =
|
|
46895
|
+
const configPath = import_path67.default.join(import_os60.default.homedir(), ".node9", "config.json");
|
|
46966
46896
|
try {
|
|
46967
|
-
const raw = JSON.parse(
|
|
46897
|
+
const raw = JSON.parse(import_fs72.default.readFileSync(configPath, "utf-8"));
|
|
46968
46898
|
const settings = raw.settings ?? {};
|
|
46969
46899
|
const approvers = settings.approvers ?? {};
|
|
46970
46900
|
approvers[channel] = approvers[channel] === false;
|
|
46971
46901
|
settings.approvers = approvers;
|
|
46972
46902
|
raw.settings = settings;
|
|
46973
|
-
|
|
46903
|
+
import_fs72.default.writeFileSync(configPath, JSON.stringify(raw, null, 2) + "\n");
|
|
46974
46904
|
} catch (err2) {
|
|
46975
46905
|
process.stderr.write(`[node9] toggleApprover failed: ${String(err2)}
|
|
46976
46906
|
`);
|
|
@@ -47142,8 +47072,8 @@ async function startTail(options = {}) {
|
|
|
47142
47072
|
}
|
|
47143
47073
|
postDecisionHttp(req2.id, httpDecision, authToken, port, httpOpts).catch((err2) => {
|
|
47144
47074
|
try {
|
|
47145
|
-
|
|
47146
|
-
|
|
47075
|
+
import_fs72.default.appendFileSync(
|
|
47076
|
+
import_path67.default.join(import_os60.default.homedir(), ".node9", "hook-debug.log"),
|
|
47147
47077
|
`[tail] POST /decision failed: ${String(err2)}
|
|
47148
47078
|
`
|
|
47149
47079
|
);
|
|
@@ -47207,9 +47137,9 @@ async function startTail(options = {}) {
|
|
|
47207
47137
|
};
|
|
47208
47138
|
process.stdin.on("keypress", onKeypress);
|
|
47209
47139
|
}
|
|
47210
|
-
const auditLog =
|
|
47140
|
+
const auditLog = import_path67.default.join(import_os60.default.homedir(), ".node9", "audit.log");
|
|
47211
47141
|
try {
|
|
47212
|
-
const unackedDlp =
|
|
47142
|
+
const unackedDlp = import_fs72.default.readFileSync(auditLog, "utf-8").split("\n").filter((l) => l.includes('"response-dlp"')).length;
|
|
47213
47143
|
if (unackedDlp > 0) {
|
|
47214
47144
|
console.log("");
|
|
47215
47145
|
console.log(
|
|
@@ -47249,7 +47179,7 @@ async function startTail(options = {}) {
|
|
|
47249
47179
|
if (stallWarned) return;
|
|
47250
47180
|
if (Date.now() - lastActivityFromDaemon < STALL_THRESHOLD_MS) return;
|
|
47251
47181
|
try {
|
|
47252
|
-
const auditMtime =
|
|
47182
|
+
const auditMtime = import_fs72.default.statSync(auditLog).mtimeMs;
|
|
47253
47183
|
if (Date.now() - auditMtime >= STALL_THRESHOLD_MS) return;
|
|
47254
47184
|
console.log("");
|
|
47255
47185
|
console.log(
|
|
@@ -47393,19 +47323,6 @@ async function startTail(options = {}) {
|
|
|
47393
47323
|
activityPending.set(data.id, data);
|
|
47394
47324
|
renderPending(data);
|
|
47395
47325
|
}
|
|
47396
|
-
if (event === "snapshot") {
|
|
47397
|
-
const time = new Date(data.ts).toLocaleTimeString([], { hour12: false });
|
|
47398
|
-
const hash = data.hash ?? "";
|
|
47399
|
-
const rawSummary = data.argsSummary ?? data.tool;
|
|
47400
|
-
const summary = shortenPathSummary(rawSummary);
|
|
47401
|
-
const fileCount = data.fileCount ?? 0;
|
|
47402
|
-
const files = fileCount > 0 ? import_chalk39.default.dim(` \xB7 ${fileCount} file${fileCount === 1 ? "" : "s"}`) : "";
|
|
47403
|
-
process.stdout.write(
|
|
47404
|
-
`${import_chalk39.default.dim(time)} ${import_chalk39.default.cyan("\u{1F4F8} snapshot")} ${import_chalk39.default.dim(hash)} ${summary}${files}
|
|
47405
|
-
`
|
|
47406
|
-
);
|
|
47407
|
-
return;
|
|
47408
|
-
}
|
|
47409
47326
|
if (event === "activity-result") {
|
|
47410
47327
|
const original = activityPending.get(data.id);
|
|
47411
47328
|
if (original) {
|
|
@@ -47434,21 +47351,21 @@ async function startTail(options = {}) {
|
|
|
47434
47351
|
process.exit(1);
|
|
47435
47352
|
});
|
|
47436
47353
|
}
|
|
47437
|
-
var import_http5, import_chalk39,
|
|
47354
|
+
var import_http5, import_chalk39, import_fs72, import_os60, import_path67, import_readline5, import_child_process13, PID_FILE, ICONS, MODEL_CONTEXT_LIMITS, RESET, BOLD, RED, YELLOW, CYAN, GRAY, GREEN, HIDE_CURSOR, SHOW_CURSOR, ERASE_DOWN, pendingShownForId, pendingWrappedLines, DIVIDER;
|
|
47438
47355
|
var init_tail = __esm({
|
|
47439
47356
|
"src/tui/tail.ts"() {
|
|
47440
47357
|
"use strict";
|
|
47441
47358
|
import_http5 = __toESM(require("http"));
|
|
47442
47359
|
import_chalk39 = __toESM(require("chalk"));
|
|
47443
|
-
|
|
47444
|
-
|
|
47445
|
-
|
|
47360
|
+
import_fs72 = __toESM(require("fs"));
|
|
47361
|
+
import_os60 = __toESM(require("os"));
|
|
47362
|
+
import_path67 = __toESM(require("path"));
|
|
47446
47363
|
import_readline5 = __toESM(require("readline"));
|
|
47447
|
-
|
|
47364
|
+
import_child_process13 = require("child_process");
|
|
47448
47365
|
init_startup_log();
|
|
47449
47366
|
init_daemon2();
|
|
47450
47367
|
init_daemon();
|
|
47451
|
-
PID_FILE =
|
|
47368
|
+
PID_FILE = import_path67.default.join(import_os60.default.homedir(), ".node9", "daemon.pid");
|
|
47452
47369
|
ICONS = {
|
|
47453
47370
|
bash: "\u{1F4BB}",
|
|
47454
47371
|
shell: "\u{1F4BB}",
|
|
@@ -47570,9 +47487,9 @@ function formatTimeLeft(resetsAt) {
|
|
|
47570
47487
|
return ` (${m}m left)`;
|
|
47571
47488
|
}
|
|
47572
47489
|
function safeReadJson(filePath) {
|
|
47573
|
-
if (!
|
|
47490
|
+
if (!import_fs73.default.existsSync(filePath)) return null;
|
|
47574
47491
|
try {
|
|
47575
|
-
return JSON.parse(
|
|
47492
|
+
return JSON.parse(import_fs73.default.readFileSync(filePath, "utf-8"));
|
|
47576
47493
|
} catch {
|
|
47577
47494
|
return null;
|
|
47578
47495
|
}
|
|
@@ -47593,12 +47510,12 @@ function countHooksInFile(filePath) {
|
|
|
47593
47510
|
return Object.keys(cfg.hooks).length;
|
|
47594
47511
|
}
|
|
47595
47512
|
function countRulesInDir(rulesDir) {
|
|
47596
|
-
if (!
|
|
47513
|
+
if (!import_fs73.default.existsSync(rulesDir)) return 0;
|
|
47597
47514
|
let count = 0;
|
|
47598
47515
|
try {
|
|
47599
|
-
for (const entry of
|
|
47516
|
+
for (const entry of import_fs73.default.readdirSync(rulesDir, { withFileTypes: true })) {
|
|
47600
47517
|
if (entry.isDirectory()) {
|
|
47601
|
-
count += countRulesInDir(
|
|
47518
|
+
count += countRulesInDir(import_path68.default.join(rulesDir, entry.name));
|
|
47602
47519
|
} else if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
47603
47520
|
count++;
|
|
47604
47521
|
}
|
|
@@ -47609,46 +47526,46 @@ function countRulesInDir(rulesDir) {
|
|
|
47609
47526
|
}
|
|
47610
47527
|
function isSamePath(a, b) {
|
|
47611
47528
|
try {
|
|
47612
|
-
return
|
|
47529
|
+
return import_path68.default.resolve(a) === import_path68.default.resolve(b);
|
|
47613
47530
|
} catch {
|
|
47614
47531
|
return false;
|
|
47615
47532
|
}
|
|
47616
47533
|
}
|
|
47617
47534
|
function countConfigs(cwd) {
|
|
47618
|
-
const homeDir2 =
|
|
47619
|
-
const claudeDir =
|
|
47535
|
+
const homeDir2 = import_os61.default.homedir();
|
|
47536
|
+
const claudeDir = import_path68.default.join(homeDir2, ".claude");
|
|
47620
47537
|
let claudeMdCount = 0;
|
|
47621
47538
|
let rulesCount = 0;
|
|
47622
47539
|
let hooksCount = 0;
|
|
47623
47540
|
const userMcpServers = /* @__PURE__ */ new Set();
|
|
47624
47541
|
const projectMcpServers = /* @__PURE__ */ new Set();
|
|
47625
|
-
if (
|
|
47626
|
-
rulesCount += countRulesInDir(
|
|
47627
|
-
const userSettings =
|
|
47542
|
+
if (import_fs73.default.existsSync(import_path68.default.join(claudeDir, "CLAUDE.md"))) claudeMdCount++;
|
|
47543
|
+
rulesCount += countRulesInDir(import_path68.default.join(claudeDir, "rules"));
|
|
47544
|
+
const userSettings = import_path68.default.join(claudeDir, "settings.json");
|
|
47628
47545
|
for (const name of getMcpServerNames(userSettings)) userMcpServers.add(name);
|
|
47629
47546
|
hooksCount += countHooksInFile(userSettings);
|
|
47630
|
-
const userClaudeJson =
|
|
47547
|
+
const userClaudeJson = import_path68.default.join(homeDir2, ".claude.json");
|
|
47631
47548
|
for (const name of getMcpServerNames(userClaudeJson)) userMcpServers.add(name);
|
|
47632
47549
|
for (const name of getDisabledMcpServers(userClaudeJson, "disabledMcpServers")) {
|
|
47633
47550
|
userMcpServers.delete(name);
|
|
47634
47551
|
}
|
|
47635
47552
|
if (cwd) {
|
|
47636
|
-
if (
|
|
47637
|
-
if (
|
|
47638
|
-
const projectClaudeDir =
|
|
47553
|
+
if (import_fs73.default.existsSync(import_path68.default.join(cwd, "CLAUDE.md"))) claudeMdCount++;
|
|
47554
|
+
if (import_fs73.default.existsSync(import_path68.default.join(cwd, "CLAUDE.local.md"))) claudeMdCount++;
|
|
47555
|
+
const projectClaudeDir = import_path68.default.join(cwd, ".claude");
|
|
47639
47556
|
const overlapsUserScope = isSamePath(projectClaudeDir, claudeDir);
|
|
47640
47557
|
if (!overlapsUserScope) {
|
|
47641
|
-
if (
|
|
47642
|
-
rulesCount += countRulesInDir(
|
|
47643
|
-
const projSettings =
|
|
47558
|
+
if (import_fs73.default.existsSync(import_path68.default.join(projectClaudeDir, "CLAUDE.md"))) claudeMdCount++;
|
|
47559
|
+
rulesCount += countRulesInDir(import_path68.default.join(projectClaudeDir, "rules"));
|
|
47560
|
+
const projSettings = import_path68.default.join(projectClaudeDir, "settings.json");
|
|
47644
47561
|
for (const name of getMcpServerNames(projSettings)) projectMcpServers.add(name);
|
|
47645
47562
|
hooksCount += countHooksInFile(projSettings);
|
|
47646
47563
|
}
|
|
47647
|
-
if (
|
|
47648
|
-
const localSettings =
|
|
47564
|
+
if (import_fs73.default.existsSync(import_path68.default.join(projectClaudeDir, "CLAUDE.local.md"))) claudeMdCount++;
|
|
47565
|
+
const localSettings = import_path68.default.join(projectClaudeDir, "settings.local.json");
|
|
47649
47566
|
for (const name of getMcpServerNames(localSettings)) projectMcpServers.add(name);
|
|
47650
47567
|
hooksCount += countHooksInFile(localSettings);
|
|
47651
|
-
const mcpJsonServers = getMcpServerNames(
|
|
47568
|
+
const mcpJsonServers = getMcpServerNames(import_path68.default.join(cwd, ".mcp.json"));
|
|
47652
47569
|
const disabledMcpJson = getDisabledMcpServers(localSettings, "disabledMcpjsonServers");
|
|
47653
47570
|
for (const name of disabledMcpJson) mcpJsonServers.delete(name);
|
|
47654
47571
|
for (const name of mcpJsonServers) projectMcpServers.add(name);
|
|
@@ -47681,12 +47598,12 @@ function readActiveShieldsHud() {
|
|
|
47681
47598
|
return shieldsCache.value;
|
|
47682
47599
|
}
|
|
47683
47600
|
try {
|
|
47684
|
-
const shieldsPath =
|
|
47685
|
-
if (!
|
|
47601
|
+
const shieldsPath = import_path68.default.join(import_os61.default.homedir(), ".node9", "shields.json");
|
|
47602
|
+
if (!import_fs73.default.existsSync(shieldsPath)) {
|
|
47686
47603
|
shieldsCache = { value: [], ts: now };
|
|
47687
47604
|
return [];
|
|
47688
47605
|
}
|
|
47689
|
-
const parsed = JSON.parse(
|
|
47606
|
+
const parsed = JSON.parse(import_fs73.default.readFileSync(shieldsPath, "utf-8"));
|
|
47690
47607
|
if (!Array.isArray(parsed.active)) {
|
|
47691
47608
|
shieldsCache = { value: [], ts: now };
|
|
47692
47609
|
return [];
|
|
@@ -47788,17 +47705,17 @@ function renderContextLine(stdin) {
|
|
|
47788
47705
|
async function main() {
|
|
47789
47706
|
try {
|
|
47790
47707
|
const [stdin, daemonStatus2] = await Promise.all([readStdin(), queryDaemon()]);
|
|
47791
|
-
if (
|
|
47708
|
+
if (import_fs73.default.existsSync(import_path68.default.join(import_os61.default.homedir(), ".node9", "hud-debug"))) {
|
|
47792
47709
|
try {
|
|
47793
|
-
const logPath =
|
|
47710
|
+
const logPath = import_path68.default.join(import_os61.default.homedir(), ".node9", "hud-debug.log");
|
|
47794
47711
|
const MAX_LOG_SIZE = 10 * 1024 * 1024;
|
|
47795
47712
|
let size = 0;
|
|
47796
47713
|
try {
|
|
47797
|
-
size =
|
|
47714
|
+
size = import_fs73.default.statSync(logPath).size;
|
|
47798
47715
|
} catch {
|
|
47799
47716
|
}
|
|
47800
47717
|
if (size < MAX_LOG_SIZE) {
|
|
47801
|
-
|
|
47718
|
+
import_fs73.default.appendFileSync(
|
|
47802
47719
|
logPath,
|
|
47803
47720
|
JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), stdin }) + "\n"
|
|
47804
47721
|
);
|
|
@@ -47819,11 +47736,11 @@ async function main() {
|
|
|
47819
47736
|
try {
|
|
47820
47737
|
const cwd = stdin.cwd ?? process.cwd();
|
|
47821
47738
|
for (const configPath of [
|
|
47822
|
-
|
|
47823
|
-
|
|
47739
|
+
import_path68.default.join(cwd, "node9.config.json"),
|
|
47740
|
+
import_path68.default.join(import_os61.default.homedir(), ".node9", "config.json")
|
|
47824
47741
|
]) {
|
|
47825
|
-
if (!
|
|
47826
|
-
const cfg = JSON.parse(
|
|
47742
|
+
if (!import_fs73.default.existsSync(configPath)) continue;
|
|
47743
|
+
const cfg = JSON.parse(import_fs73.default.readFileSync(configPath, "utf-8"));
|
|
47827
47744
|
const hud = cfg.settings?.hud;
|
|
47828
47745
|
if (hud && "showEnvironmentCounts" in hud) return hud.showEnvironmentCounts !== false;
|
|
47829
47746
|
}
|
|
@@ -47841,13 +47758,13 @@ async function main() {
|
|
|
47841
47758
|
renderOffline();
|
|
47842
47759
|
}
|
|
47843
47760
|
}
|
|
47844
|
-
var
|
|
47761
|
+
var import_fs73, import_path68, import_os61, import_http6, RESET2, BOLD2, DIM, RED2, GREEN2, YELLOW2, BLUE, MAGENTA, CYAN2, WHITE, BAR_FILLED, BAR_EMPTY, BAR_WIDTH, shieldsCache, SHIELDS_CACHE_TTL_MS;
|
|
47845
47762
|
var init_hud = __esm({
|
|
47846
47763
|
"src/cli/hud.ts"() {
|
|
47847
47764
|
"use strict";
|
|
47848
|
-
|
|
47849
|
-
|
|
47850
|
-
|
|
47765
|
+
import_fs73 = __toESM(require("fs"));
|
|
47766
|
+
import_path68 = __toESM(require("path"));
|
|
47767
|
+
import_os61 = __toESM(require("os"));
|
|
47851
47768
|
import_http6 = __toESM(require("http"));
|
|
47852
47769
|
init_daemon();
|
|
47853
47770
|
RESET2 = "\x1B[0m";
|
|
@@ -47969,10 +47886,10 @@ function writeCredentialsAndConfig(apiKey, opts = {}) {
|
|
|
47969
47886
|
// src/cli.ts
|
|
47970
47887
|
init_daemon2();
|
|
47971
47888
|
var import_chalk40 = __toESM(require("chalk"));
|
|
47972
|
-
var
|
|
47973
|
-
var
|
|
47974
|
-
var
|
|
47975
|
-
var
|
|
47889
|
+
var import_fs74 = __toESM(require("fs"));
|
|
47890
|
+
var import_path69 = __toESM(require("path"));
|
|
47891
|
+
var import_os62 = __toESM(require("os"));
|
|
47892
|
+
var import_child_process14 = require("child_process");
|
|
47976
47893
|
var import_prompts3 = require("@inquirer/prompts");
|
|
47977
47894
|
|
|
47978
47895
|
// src/utils/duration.ts
|
|
@@ -48252,290 +48169,28 @@ init_service();
|
|
|
48252
48169
|
|
|
48253
48170
|
// src/cli/commands/check.ts
|
|
48254
48171
|
var import_chalk9 = __toESM(require("chalk"));
|
|
48255
|
-
var
|
|
48256
|
-
var
|
|
48257
|
-
var
|
|
48258
|
-
var
|
|
48172
|
+
var import_fs48 = __toESM(require("fs"));
|
|
48173
|
+
var import_child_process6 = require("child_process");
|
|
48174
|
+
var import_path46 = __toESM(require("path"));
|
|
48175
|
+
var import_os43 = __toESM(require("os"));
|
|
48259
48176
|
init_orchestrator();
|
|
48260
48177
|
init_state();
|
|
48261
48178
|
init_daemon();
|
|
48262
48179
|
init_startup_log();
|
|
48263
48180
|
init_config();
|
|
48264
|
-
init_policy();
|
|
48265
48181
|
|
|
48266
|
-
// src/
|
|
48267
|
-
var import_child_process6 = require("child_process");
|
|
48268
|
-
var import_crypto12 = __toESM(require("crypto"));
|
|
48182
|
+
// src/skill-pin.ts
|
|
48269
48183
|
var import_fs46 = __toESM(require("fs"));
|
|
48270
|
-
var import_net3 = __toESM(require("net"));
|
|
48271
48184
|
var import_path44 = __toESM(require("path"));
|
|
48272
48185
|
var import_os41 = __toESM(require("os"));
|
|
48273
|
-
var
|
|
48274
|
-
function notifySnapshotTaken(hash, tool, argsSummary, fileCount) {
|
|
48275
|
-
try {
|
|
48276
|
-
const payload = JSON.stringify({
|
|
48277
|
-
status: "snapshot",
|
|
48278
|
-
hash,
|
|
48279
|
-
tool,
|
|
48280
|
-
argsSummary,
|
|
48281
|
-
fileCount,
|
|
48282
|
-
ts: Date.now()
|
|
48283
|
-
});
|
|
48284
|
-
const sock = import_net3.default.createConnection(ACTIVITY_SOCKET_PATH3);
|
|
48285
|
-
sock.on("connect", () => {
|
|
48286
|
-
sock.end(payload);
|
|
48287
|
-
});
|
|
48288
|
-
sock.on("error", () => {
|
|
48289
|
-
});
|
|
48290
|
-
} catch {
|
|
48291
|
-
}
|
|
48292
|
-
}
|
|
48293
|
-
var SNAPSHOT_STACK_PATH = import_path44.default.join(import_os41.default.homedir(), ".node9", "snapshots.json");
|
|
48294
|
-
var UNDO_LATEST_PATH = import_path44.default.join(import_os41.default.homedir(), ".node9", "undo_latest.txt");
|
|
48295
|
-
var MAX_SNAPSHOTS = 10;
|
|
48296
|
-
var GIT_TIMEOUT = 15e3;
|
|
48297
|
-
function readStack() {
|
|
48298
|
-
try {
|
|
48299
|
-
if (import_fs46.default.existsSync(SNAPSHOT_STACK_PATH))
|
|
48300
|
-
return JSON.parse(import_fs46.default.readFileSync(SNAPSHOT_STACK_PATH, "utf-8"));
|
|
48301
|
-
} catch {
|
|
48302
|
-
}
|
|
48303
|
-
return [];
|
|
48304
|
-
}
|
|
48305
|
-
function writeStack(stack) {
|
|
48306
|
-
const dir = import_path44.default.dirname(SNAPSHOT_STACK_PATH);
|
|
48307
|
-
if (!import_fs46.default.existsSync(dir)) import_fs46.default.mkdirSync(dir, { recursive: true });
|
|
48308
|
-
import_fs46.default.writeFileSync(SNAPSHOT_STACK_PATH, JSON.stringify(stack, null, 2));
|
|
48309
|
-
}
|
|
48310
|
-
function extractFilePath(args) {
|
|
48311
|
-
if (!args || typeof args !== "object") return null;
|
|
48312
|
-
const a = args;
|
|
48313
|
-
const fp = a.file_path ?? a.path ?? a.filename;
|
|
48314
|
-
return typeof fp === "string" ? fp : null;
|
|
48315
|
-
}
|
|
48316
|
-
function buildArgsSummary(tool, args) {
|
|
48317
|
-
const filePath = extractFilePath(args);
|
|
48318
|
-
if (filePath) return filePath;
|
|
48319
|
-
if (!args || typeof args !== "object") return "";
|
|
48320
|
-
const a = args;
|
|
48321
|
-
const cmd = a.command ?? a.cmd;
|
|
48322
|
-
if (typeof cmd === "string") return cmd.slice(0, 80);
|
|
48323
|
-
const sql = a.sql ?? a.query;
|
|
48324
|
-
if (typeof sql === "string") return sql.slice(0, 80);
|
|
48325
|
-
return "";
|
|
48326
|
-
}
|
|
48327
|
-
function findProjectRoot(filePath) {
|
|
48328
|
-
let dir = import_path44.default.dirname(filePath);
|
|
48329
|
-
while (true) {
|
|
48330
|
-
if (import_fs46.default.existsSync(import_path44.default.join(dir, ".git")) || import_fs46.default.existsSync(import_path44.default.join(dir, "package.json"))) {
|
|
48331
|
-
return dir;
|
|
48332
|
-
}
|
|
48333
|
-
const parent = import_path44.default.dirname(dir);
|
|
48334
|
-
if (parent === dir) return process.cwd();
|
|
48335
|
-
dir = parent;
|
|
48336
|
-
}
|
|
48337
|
-
}
|
|
48338
|
-
function normalizeCwdForHash(cwd) {
|
|
48339
|
-
let normalized;
|
|
48340
|
-
try {
|
|
48341
|
-
normalized = import_fs46.default.realpathSync(cwd);
|
|
48342
|
-
} catch {
|
|
48343
|
-
normalized = cwd;
|
|
48344
|
-
}
|
|
48345
|
-
normalized = normalized.replace(/\\/g, "/");
|
|
48346
|
-
if (process.platform === "win32") normalized = normalized.toLowerCase();
|
|
48347
|
-
return normalized;
|
|
48348
|
-
}
|
|
48349
|
-
function getShadowRepoDir(cwd) {
|
|
48350
|
-
const hash = import_crypto12.default.createHash("sha256").update(normalizeCwdForHash(cwd)).digest("hex").slice(0, 16);
|
|
48351
|
-
return import_path44.default.join(import_os41.default.homedir(), ".node9", "snapshots", hash);
|
|
48352
|
-
}
|
|
48353
|
-
function cleanOrphanedIndexFiles(shadowDir) {
|
|
48354
|
-
try {
|
|
48355
|
-
const cutoff = Date.now() - 6e4;
|
|
48356
|
-
for (const f of import_fs46.default.readdirSync(shadowDir)) {
|
|
48357
|
-
if (f.startsWith("index_")) {
|
|
48358
|
-
const fp = import_path44.default.join(shadowDir, f);
|
|
48359
|
-
try {
|
|
48360
|
-
if (import_fs46.default.statSync(fp).mtimeMs < cutoff) import_fs46.default.unlinkSync(fp);
|
|
48361
|
-
} catch {
|
|
48362
|
-
}
|
|
48363
|
-
}
|
|
48364
|
-
}
|
|
48365
|
-
} catch {
|
|
48366
|
-
}
|
|
48367
|
-
}
|
|
48368
|
-
function writeShadowExcludes(shadowDir, ignorePaths) {
|
|
48369
|
-
const hardcoded = [".git", ".node9"];
|
|
48370
|
-
const lines = [...hardcoded, ...ignorePaths].join("\n");
|
|
48371
|
-
try {
|
|
48372
|
-
import_fs46.default.writeFileSync(import_path44.default.join(shadowDir, "info", "exclude"), lines + "\n", "utf8");
|
|
48373
|
-
} catch {
|
|
48374
|
-
}
|
|
48375
|
-
}
|
|
48376
|
-
function ensureShadowRepo(shadowDir, cwd) {
|
|
48377
|
-
cleanOrphanedIndexFiles(shadowDir);
|
|
48378
|
-
const normalizedCwd = normalizeCwdForHash(cwd);
|
|
48379
|
-
const shadowEnvBase = { ...process.env, GIT_DIR: shadowDir, GIT_WORK_TREE: cwd };
|
|
48380
|
-
const check = (0, import_child_process6.spawnSync)("git", ["rev-parse", "--git-dir"], {
|
|
48381
|
-
env: shadowEnvBase,
|
|
48382
|
-
timeout: 3e3
|
|
48383
|
-
});
|
|
48384
|
-
if (check.status === 0) {
|
|
48385
|
-
const ptPath = import_path44.default.join(shadowDir, "project-path.txt");
|
|
48386
|
-
try {
|
|
48387
|
-
const stored = import_fs46.default.readFileSync(ptPath, "utf8").trim();
|
|
48388
|
-
if (stored === normalizedCwd) return true;
|
|
48389
|
-
if (process.env.NODE9_DEBUG === "1")
|
|
48390
|
-
console.error(
|
|
48391
|
-
`[Node9] Shadow repo path mismatch: stored="${stored}" expected="${normalizedCwd}" \u2014 reinitializing`
|
|
48392
|
-
);
|
|
48393
|
-
import_fs46.default.rmSync(shadowDir, { recursive: true, force: true });
|
|
48394
|
-
} catch {
|
|
48395
|
-
try {
|
|
48396
|
-
import_fs46.default.writeFileSync(ptPath, normalizedCwd, "utf8");
|
|
48397
|
-
} catch {
|
|
48398
|
-
}
|
|
48399
|
-
return true;
|
|
48400
|
-
}
|
|
48401
|
-
}
|
|
48402
|
-
try {
|
|
48403
|
-
import_fs46.default.mkdirSync(shadowDir, { recursive: true });
|
|
48404
|
-
} catch {
|
|
48405
|
-
}
|
|
48406
|
-
const init = (0, import_child_process6.spawnSync)("git", ["init", "--bare", shadowDir], { timeout: 5e3 });
|
|
48407
|
-
if (init.status !== 0 || init.error) {
|
|
48408
|
-
const reason = init.error ? init.error.message : init.stderr?.toString();
|
|
48409
|
-
if (process.env.NODE9_DEBUG === "1") console.error("[Node9] git init --bare failed:", reason);
|
|
48410
|
-
return false;
|
|
48411
|
-
}
|
|
48412
|
-
const configFile = import_path44.default.join(shadowDir, "config");
|
|
48413
|
-
(0, import_child_process6.spawnSync)("git", ["config", "--file", configFile, "core.untrackedCache", "true"], {
|
|
48414
|
-
timeout: 3e3
|
|
48415
|
-
});
|
|
48416
|
-
(0, import_child_process6.spawnSync)("git", ["config", "--file", configFile, "core.fsmonitor", "true"], {
|
|
48417
|
-
timeout: 3e3
|
|
48418
|
-
});
|
|
48419
|
-
try {
|
|
48420
|
-
import_fs46.default.writeFileSync(import_path44.default.join(shadowDir, "project-path.txt"), normalizedCwd, "utf8");
|
|
48421
|
-
} catch {
|
|
48422
|
-
}
|
|
48423
|
-
return true;
|
|
48424
|
-
}
|
|
48425
|
-
async function createShadowSnapshot(tool = "unknown", args = {}, ignorePaths = []) {
|
|
48426
|
-
let indexFile = null;
|
|
48427
|
-
try {
|
|
48428
|
-
const rawFilePath = extractFilePath(args);
|
|
48429
|
-
const absFilePath = rawFilePath && import_path44.default.isAbsolute(rawFilePath) ? rawFilePath : null;
|
|
48430
|
-
const cwd = absFilePath ? findProjectRoot(absFilePath) : process.cwd();
|
|
48431
|
-
const shadowDir = getShadowRepoDir(cwd);
|
|
48432
|
-
if (!ensureShadowRepo(shadowDir, cwd)) return null;
|
|
48433
|
-
writeShadowExcludes(shadowDir, ignorePaths);
|
|
48434
|
-
indexFile = import_path44.default.join(shadowDir, `index_${process.pid}_${Date.now()}`);
|
|
48435
|
-
const shadowEnv = {
|
|
48436
|
-
...process.env,
|
|
48437
|
-
GIT_DIR: shadowDir,
|
|
48438
|
-
GIT_WORK_TREE: cwd,
|
|
48439
|
-
GIT_INDEX_FILE: indexFile
|
|
48440
|
-
};
|
|
48441
|
-
(0, import_child_process6.spawnSync)("git", ["add", "-A"], { env: shadowEnv, timeout: GIT_TIMEOUT });
|
|
48442
|
-
const treeRes = (0, import_child_process6.spawnSync)("git", ["write-tree"], { env: shadowEnv, timeout: GIT_TIMEOUT });
|
|
48443
|
-
const treeHash = treeRes.stdout?.toString().trim();
|
|
48444
|
-
if (!treeHash || treeRes.status !== 0) return null;
|
|
48445
|
-
const commitRes = (0, import_child_process6.spawnSync)(
|
|
48446
|
-
"git",
|
|
48447
|
-
["commit-tree", treeHash, "-m", `Node9 AI Snapshot: ${(/* @__PURE__ */ new Date()).toISOString()}`],
|
|
48448
|
-
{ env: shadowEnv, timeout: GIT_TIMEOUT }
|
|
48449
|
-
);
|
|
48450
|
-
const commitHash = commitRes.stdout?.toString().trim();
|
|
48451
|
-
if (!commitHash || commitRes.status !== 0) return null;
|
|
48452
|
-
const stack = readStack();
|
|
48453
|
-
const prevEntry = [...stack].reverse().find((e) => e.cwd === cwd);
|
|
48454
|
-
let capturedFiles = [];
|
|
48455
|
-
let capturedDiff = null;
|
|
48456
|
-
if (prevEntry) {
|
|
48457
|
-
const filesRes = (0, import_child_process6.spawnSync)("git", ["diff", "--name-only", prevEntry.hash, commitHash], {
|
|
48458
|
-
env: shadowEnv,
|
|
48459
|
-
timeout: GIT_TIMEOUT
|
|
48460
|
-
});
|
|
48461
|
-
if (filesRes.status === 0) {
|
|
48462
|
-
capturedFiles = filesRes.stdout?.toString().trim().split("\n").filter(Boolean) ?? [];
|
|
48463
|
-
}
|
|
48464
|
-
if (capturedFiles.length === 0) {
|
|
48465
|
-
return prevEntry.hash;
|
|
48466
|
-
}
|
|
48467
|
-
const diffRes = (0, import_child_process6.spawnSync)("git", ["diff", prevEntry.hash, commitHash], {
|
|
48468
|
-
env: shadowEnv,
|
|
48469
|
-
timeout: GIT_TIMEOUT
|
|
48470
|
-
});
|
|
48471
|
-
if (diffRes.status === 0) {
|
|
48472
|
-
capturedDiff = diffRes.stdout?.toString() || null;
|
|
48473
|
-
}
|
|
48474
|
-
} else {
|
|
48475
|
-
const filesRes = (0, import_child_process6.spawnSync)("git", ["ls-tree", "-r", "--name-only", commitHash], {
|
|
48476
|
-
env: shadowEnv,
|
|
48477
|
-
timeout: GIT_TIMEOUT
|
|
48478
|
-
});
|
|
48479
|
-
if (filesRes.status === 0) {
|
|
48480
|
-
capturedFiles = filesRes.stdout?.toString().trim().split("\n").filter(Boolean) ?? [];
|
|
48481
|
-
}
|
|
48482
|
-
capturedDiff = null;
|
|
48483
|
-
}
|
|
48484
|
-
stack.push({
|
|
48485
|
-
hash: commitHash,
|
|
48486
|
-
tool,
|
|
48487
|
-
argsSummary: buildArgsSummary(tool, args),
|
|
48488
|
-
files: capturedFiles,
|
|
48489
|
-
diff: capturedDiff,
|
|
48490
|
-
cwd,
|
|
48491
|
-
timestamp: Date.now()
|
|
48492
|
-
});
|
|
48493
|
-
const shouldGc = stack.length % 5 === 0;
|
|
48494
|
-
let cwdCount = 0;
|
|
48495
|
-
let oldestCwdIdx = -1;
|
|
48496
|
-
for (let i = 0; i < stack.length; i++) {
|
|
48497
|
-
if (stack[i].cwd === cwd) {
|
|
48498
|
-
if (oldestCwdIdx === -1) oldestCwdIdx = i;
|
|
48499
|
-
cwdCount++;
|
|
48500
|
-
}
|
|
48501
|
-
}
|
|
48502
|
-
if (cwdCount > MAX_SNAPSHOTS) stack.splice(oldestCwdIdx, 1);
|
|
48503
|
-
writeStack(stack);
|
|
48504
|
-
const entry = stack[stack.length - 1];
|
|
48505
|
-
notifySnapshotTaken(commitHash.slice(0, 7), tool, entry.argsSummary, capturedFiles.length);
|
|
48506
|
-
import_fs46.default.writeFileSync(UNDO_LATEST_PATH, commitHash);
|
|
48507
|
-
if (shouldGc) {
|
|
48508
|
-
(0, import_child_process6.spawn)("git", ["gc", "--auto"], { env: shadowEnv, detached: true, stdio: "ignore" }).unref();
|
|
48509
|
-
}
|
|
48510
|
-
return commitHash;
|
|
48511
|
-
} catch (err2) {
|
|
48512
|
-
if (process.env.NODE9_DEBUG === "1") console.error("[Node9 Undo Engine Error]:", err2);
|
|
48513
|
-
return null;
|
|
48514
|
-
} finally {
|
|
48515
|
-
if (indexFile) {
|
|
48516
|
-
try {
|
|
48517
|
-
import_fs46.default.unlinkSync(indexFile);
|
|
48518
|
-
} catch {
|
|
48519
|
-
}
|
|
48520
|
-
}
|
|
48521
|
-
}
|
|
48522
|
-
}
|
|
48523
|
-
function getSnapshotHistory() {
|
|
48524
|
-
return readStack();
|
|
48525
|
-
}
|
|
48526
|
-
|
|
48527
|
-
// src/skill-pin.ts
|
|
48528
|
-
var import_fs47 = __toESM(require("fs"));
|
|
48529
|
-
var import_path45 = __toESM(require("path"));
|
|
48530
|
-
var import_os42 = __toESM(require("os"));
|
|
48531
|
-
var import_crypto13 = __toESM(require("crypto"));
|
|
48186
|
+
var import_crypto12 = __toESM(require("crypto"));
|
|
48532
48187
|
function getPinsFilePath2() {
|
|
48533
|
-
return
|
|
48188
|
+
return import_path44.default.join(import_os41.default.homedir(), ".node9", "skill-pins.json");
|
|
48534
48189
|
}
|
|
48535
48190
|
var MAX_FILES = 5e3;
|
|
48536
48191
|
var MAX_TOTAL_BYTES = 50 * 1024 * 1024;
|
|
48537
48192
|
function sha256Bytes(buf) {
|
|
48538
|
-
return
|
|
48193
|
+
return import_crypto12.default.createHash("sha256").update(buf).digest("hex");
|
|
48539
48194
|
}
|
|
48540
48195
|
function walkDir(root) {
|
|
48541
48196
|
const out = [];
|
|
@@ -48544,18 +48199,18 @@ function walkDir(root) {
|
|
|
48544
48199
|
if (out.length >= MAX_FILES) return;
|
|
48545
48200
|
let entries;
|
|
48546
48201
|
try {
|
|
48547
|
-
entries =
|
|
48202
|
+
entries = import_fs46.default.readdirSync(dir, { withFileTypes: true });
|
|
48548
48203
|
} catch {
|
|
48549
48204
|
return;
|
|
48550
48205
|
}
|
|
48551
48206
|
entries.sort((a, b) => a.name.localeCompare(b.name));
|
|
48552
48207
|
for (const entry of entries) {
|
|
48553
48208
|
if (out.length >= MAX_FILES) return;
|
|
48554
|
-
const full =
|
|
48555
|
-
const rel = relDir ?
|
|
48209
|
+
const full = import_path44.default.join(dir, entry.name);
|
|
48210
|
+
const rel = relDir ? import_path44.default.posix.join(relDir, entry.name) : entry.name;
|
|
48556
48211
|
let lst;
|
|
48557
48212
|
try {
|
|
48558
|
-
lst =
|
|
48213
|
+
lst = import_fs46.default.lstatSync(full);
|
|
48559
48214
|
} catch {
|
|
48560
48215
|
continue;
|
|
48561
48216
|
}
|
|
@@ -48567,7 +48222,7 @@ function walkDir(root) {
|
|
|
48567
48222
|
if (!lst.isFile()) continue;
|
|
48568
48223
|
if (totalBytes + lst.size > MAX_TOTAL_BYTES) continue;
|
|
48569
48224
|
try {
|
|
48570
|
-
const buf =
|
|
48225
|
+
const buf = import_fs46.default.readFileSync(full);
|
|
48571
48226
|
totalBytes += buf.length;
|
|
48572
48227
|
out.push({ rel, hash: sha256Bytes(buf) });
|
|
48573
48228
|
} catch {
|
|
@@ -48581,32 +48236,32 @@ function walkDir(root) {
|
|
|
48581
48236
|
function hashSkillRoot(absPath) {
|
|
48582
48237
|
let lst;
|
|
48583
48238
|
try {
|
|
48584
|
-
lst =
|
|
48239
|
+
lst = import_fs46.default.lstatSync(absPath);
|
|
48585
48240
|
} catch {
|
|
48586
48241
|
return { exists: false, contentHash: "", fileCount: 0 };
|
|
48587
48242
|
}
|
|
48588
48243
|
if (lst.isSymbolicLink()) return { exists: false, contentHash: "", fileCount: 0 };
|
|
48589
48244
|
if (lst.isFile()) {
|
|
48590
48245
|
try {
|
|
48591
|
-
return { exists: true, contentHash: sha256Bytes(
|
|
48246
|
+
return { exists: true, contentHash: sha256Bytes(import_fs46.default.readFileSync(absPath)), fileCount: 1 };
|
|
48592
48247
|
} catch {
|
|
48593
48248
|
return { exists: false, contentHash: "", fileCount: 0 };
|
|
48594
48249
|
}
|
|
48595
48250
|
}
|
|
48596
48251
|
if (lst.isDirectory()) {
|
|
48597
48252
|
const entries = walkDir(absPath);
|
|
48598
|
-
const contentHash =
|
|
48253
|
+
const contentHash = import_crypto12.default.createHash("sha256").update(entries.join("\n")).digest("hex");
|
|
48599
48254
|
return { exists: true, contentHash, fileCount: entries.length };
|
|
48600
48255
|
}
|
|
48601
48256
|
return { exists: false, contentHash: "", fileCount: 0 };
|
|
48602
48257
|
}
|
|
48603
48258
|
function getRootKey(absPath) {
|
|
48604
|
-
return
|
|
48259
|
+
return import_crypto12.default.createHash("sha256").update(absPath).digest("hex").slice(0, 16);
|
|
48605
48260
|
}
|
|
48606
48261
|
function readSkillPinsSafe() {
|
|
48607
48262
|
const filePath = getPinsFilePath2();
|
|
48608
48263
|
try {
|
|
48609
|
-
const raw =
|
|
48264
|
+
const raw = import_fs46.default.readFileSync(filePath, "utf-8");
|
|
48610
48265
|
if (!raw.trim()) return { ok: false, reason: "corrupt", detail: "empty file" };
|
|
48611
48266
|
const parsed = JSON.parse(raw);
|
|
48612
48267
|
if (!parsed.roots || typeof parsed.roots !== "object" || Array.isArray(parsed.roots)) {
|
|
@@ -48626,10 +48281,10 @@ function readSkillPins() {
|
|
|
48626
48281
|
}
|
|
48627
48282
|
function writeSkillPins(data) {
|
|
48628
48283
|
const filePath = getPinsFilePath2();
|
|
48629
|
-
|
|
48630
|
-
const tmp = `${filePath}.${
|
|
48631
|
-
|
|
48632
|
-
|
|
48284
|
+
import_fs46.default.mkdirSync(import_path44.default.dirname(filePath), { recursive: true });
|
|
48285
|
+
const tmp = `${filePath}.${import_crypto12.default.randomBytes(6).toString("hex")}.tmp`;
|
|
48286
|
+
import_fs46.default.writeFileSync(tmp, JSON.stringify(data, null, 2), { mode: 384 });
|
|
48287
|
+
import_fs46.default.renameSync(tmp, filePath);
|
|
48633
48288
|
}
|
|
48634
48289
|
function removePin2(rootKey) {
|
|
48635
48290
|
const pins = readSkillPins();
|
|
@@ -48673,36 +48328,36 @@ function verifyAndPinRoots(roots) {
|
|
|
48673
48328
|
return { kind: "verified" };
|
|
48674
48329
|
}
|
|
48675
48330
|
function defaultSkillRoots(_cwd) {
|
|
48676
|
-
const marketplaces =
|
|
48331
|
+
const marketplaces = import_path44.default.join(import_os41.default.homedir(), ".claude", "plugins", "marketplaces");
|
|
48677
48332
|
const roots = [];
|
|
48678
48333
|
let registries;
|
|
48679
48334
|
try {
|
|
48680
|
-
registries =
|
|
48335
|
+
registries = import_fs46.default.readdirSync(marketplaces, { withFileTypes: true });
|
|
48681
48336
|
} catch {
|
|
48682
48337
|
return [];
|
|
48683
48338
|
}
|
|
48684
48339
|
for (const registry of registries) {
|
|
48685
48340
|
if (!registry.isDirectory()) continue;
|
|
48686
|
-
const pluginsDir =
|
|
48341
|
+
const pluginsDir = import_path44.default.join(marketplaces, registry.name, "plugins");
|
|
48687
48342
|
let plugins;
|
|
48688
48343
|
try {
|
|
48689
|
-
plugins =
|
|
48344
|
+
plugins = import_fs46.default.readdirSync(pluginsDir, { withFileTypes: true });
|
|
48690
48345
|
} catch {
|
|
48691
48346
|
continue;
|
|
48692
48347
|
}
|
|
48693
48348
|
for (const plugin of plugins) {
|
|
48694
48349
|
if (!plugin.isDirectory()) continue;
|
|
48695
|
-
roots.push(
|
|
48350
|
+
roots.push(import_path44.default.join(pluginsDir, plugin.name));
|
|
48696
48351
|
}
|
|
48697
48352
|
}
|
|
48698
48353
|
return roots;
|
|
48699
48354
|
}
|
|
48700
48355
|
function resolveUserSkillRoot(entry, cwd) {
|
|
48701
48356
|
if (!entry) return null;
|
|
48702
|
-
if (entry.startsWith("~/") || entry === "~") return
|
|
48703
|
-
if (
|
|
48704
|
-
if (!cwd || !
|
|
48705
|
-
return
|
|
48357
|
+
if (entry.startsWith("~/") || entry === "~") return import_path44.default.join(import_os41.default.homedir(), entry.slice(1));
|
|
48358
|
+
if (import_path44.default.isAbsolute(entry)) return entry;
|
|
48359
|
+
if (!cwd || !import_path44.default.isAbsolute(cwd)) return null;
|
|
48360
|
+
return import_path44.default.join(cwd, entry);
|
|
48706
48361
|
}
|
|
48707
48362
|
|
|
48708
48363
|
// src/cli/commands/check.ts
|
|
@@ -48710,12 +48365,12 @@ init_dlp();
|
|
|
48710
48365
|
init_audit();
|
|
48711
48366
|
|
|
48712
48367
|
// src/review-pending.ts
|
|
48713
|
-
var
|
|
48714
|
-
var
|
|
48715
|
-
var
|
|
48368
|
+
var import_fs47 = __toESM(require("fs"));
|
|
48369
|
+
var import_os42 = __toESM(require("os"));
|
|
48370
|
+
var import_path45 = __toESM(require("path"));
|
|
48716
48371
|
init_hasher();
|
|
48717
48372
|
function storePath() {
|
|
48718
|
-
return process.env.NODE9_PENDING_STORE ||
|
|
48373
|
+
return process.env.NODE9_PENDING_STORE || import_path45.default.join(import_os42.default.homedir(), ".node9", "pending-reviews.json");
|
|
48719
48374
|
}
|
|
48720
48375
|
var TTL_TUID_MS = 72 * 60 * 60 * 1e3;
|
|
48721
48376
|
var TTL_MS2 = 6 * 60 * 60 * 1e3;
|
|
@@ -48733,7 +48388,7 @@ function reviewCorrelationKey(payload) {
|
|
|
48733
48388
|
}
|
|
48734
48389
|
function read() {
|
|
48735
48390
|
try {
|
|
48736
|
-
const parsed = JSON.parse(
|
|
48391
|
+
const parsed = JSON.parse(import_fs47.default.readFileSync(storePath(), "utf-8"));
|
|
48737
48392
|
if (parsed && Array.isArray(parsed.entries)) return parsed;
|
|
48738
48393
|
} catch {
|
|
48739
48394
|
}
|
|
@@ -48742,11 +48397,11 @@ function read() {
|
|
|
48742
48397
|
function write(store) {
|
|
48743
48398
|
try {
|
|
48744
48399
|
const p = storePath();
|
|
48745
|
-
const dir =
|
|
48746
|
-
if (!
|
|
48400
|
+
const dir = import_path45.default.dirname(p);
|
|
48401
|
+
if (!import_fs47.default.existsSync(dir)) import_fs47.default.mkdirSync(dir, { recursive: true });
|
|
48747
48402
|
const tmp = `${p}.${process.pid}.tmp`;
|
|
48748
|
-
|
|
48749
|
-
|
|
48403
|
+
import_fs47.default.writeFileSync(tmp, JSON.stringify(store));
|
|
48404
|
+
import_fs47.default.renameSync(tmp, p);
|
|
48750
48405
|
} catch {
|
|
48751
48406
|
}
|
|
48752
48407
|
}
|
|
@@ -48875,9 +48530,9 @@ function registerCheckCommand(program2) {
|
|
|
48875
48530
|
} catch (err2) {
|
|
48876
48531
|
const tempConfig = getConfig();
|
|
48877
48532
|
if (process.env.NODE9_DEBUG === "1" || tempConfig.settings.enableHookLogDebug) {
|
|
48878
|
-
const logPath =
|
|
48533
|
+
const logPath = import_path46.default.join(import_os43.default.homedir(), ".node9", "hook-debug.log");
|
|
48879
48534
|
const errMsg = err2 instanceof Error ? err2.message : String(err2);
|
|
48880
|
-
|
|
48535
|
+
import_fs48.default.appendFileSync(
|
|
48881
48536
|
logPath,
|
|
48882
48537
|
`[${(/* @__PURE__ */ new Date()).toISOString()}] JSON_PARSE_ERROR: ${errMsg}
|
|
48883
48538
|
RAW: ${raw}
|
|
@@ -48890,14 +48545,14 @@ RAW: ${raw}
|
|
|
48890
48545
|
const prompt = typeof payload.prompt === "string" ? payload.prompt : "";
|
|
48891
48546
|
if (process.env.NODE9_DEBUG === "1") {
|
|
48892
48547
|
try {
|
|
48893
|
-
const logPath =
|
|
48894
|
-
if (!
|
|
48895
|
-
|
|
48548
|
+
const logPath = import_path46.default.join(import_os43.default.homedir(), ".node9", "hook-debug.log");
|
|
48549
|
+
if (!import_fs48.default.existsSync(import_path46.default.dirname(logPath)))
|
|
48550
|
+
import_fs48.default.mkdirSync(import_path46.default.dirname(logPath), { recursive: true });
|
|
48896
48551
|
const sanitized = JSON.stringify({
|
|
48897
48552
|
...payload,
|
|
48898
48553
|
prompt: `<redacted, ${prompt.length} bytes>`
|
|
48899
48554
|
});
|
|
48900
|
-
|
|
48555
|
+
import_fs48.default.appendFileSync(logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] STDIN: ${sanitized}
|
|
48901
48556
|
`);
|
|
48902
48557
|
} catch {
|
|
48903
48558
|
}
|
|
@@ -48918,8 +48573,8 @@ RAW: ${raw}
|
|
|
48918
48573
|
);
|
|
48919
48574
|
const reason = `\u{1F6A8} Node9 DLP: ${dlpMatch.patternName} detected in prompt (${dlpMatch.redactedSample}). Prompt was not submitted \u2014 remove the credential and try again.`;
|
|
48920
48575
|
try {
|
|
48921
|
-
const ttyFd =
|
|
48922
|
-
|
|
48576
|
+
const ttyFd = import_fs48.default.openSync("/dev/tty", "w");
|
|
48577
|
+
import_fs48.default.writeSync(
|
|
48923
48578
|
ttyFd,
|
|
48924
48579
|
import_chalk9.default.bgRed.white.bold(`
|
|
48925
48580
|
\u{1F6A8} NODE9 DLP \u2014 PROMPT BLOCKED
|
|
@@ -48929,7 +48584,7 @@ RAW: ${raw}
|
|
|
48929
48584
|
|
|
48930
48585
|
`)
|
|
48931
48586
|
);
|
|
48932
|
-
|
|
48587
|
+
import_fs48.default.closeSync(ttyFd);
|
|
48933
48588
|
} catch {
|
|
48934
48589
|
}
|
|
48935
48590
|
const isCodex = agent2 === "Codex";
|
|
@@ -48948,17 +48603,17 @@ RAW: ${raw}
|
|
|
48948
48603
|
process.exit(2);
|
|
48949
48604
|
}
|
|
48950
48605
|
const payloadCwd = typeof payload.cwd === "string" ? payload.cwd : Array.isArray(payload.workspacePaths) && typeof payload.workspacePaths[0] === "string" ? payload.workspacePaths[0] : void 0;
|
|
48951
|
-
const safeCwdForConfig = typeof payloadCwd === "string" &&
|
|
48606
|
+
const safeCwdForConfig = typeof payloadCwd === "string" && import_path46.default.isAbsolute(payloadCwd) ? payloadCwd : void 0;
|
|
48952
48607
|
const config = getConfig(safeCwdForConfig);
|
|
48953
48608
|
const daemonDown = !isDaemonRunning();
|
|
48954
48609
|
if (config.settings.autoStartDaemon && daemonDown && !process.env.NODE9_NO_AUTO_DAEMON) {
|
|
48955
48610
|
try {
|
|
48956
48611
|
const scriptPath = process.argv[1];
|
|
48957
|
-
if (typeof scriptPath !== "string" || !
|
|
48612
|
+
if (typeof scriptPath !== "string" || !import_path46.default.isAbsolute(scriptPath))
|
|
48958
48613
|
throw new Error("node9: argv[1] is not an absolute path");
|
|
48959
|
-
const resolvedScript =
|
|
48960
|
-
const packageDist =
|
|
48961
|
-
if (!resolvedScript.startsWith(packageDist +
|
|
48614
|
+
const resolvedScript = import_fs48.default.realpathSync(scriptPath);
|
|
48615
|
+
const packageDist = import_fs48.default.realpathSync(import_path46.default.resolve(__dirname, "../.."));
|
|
48616
|
+
if (!resolvedScript.startsWith(packageDist + import_path46.default.sep) && resolvedScript !== packageDist)
|
|
48962
48617
|
throw new Error(
|
|
48963
48618
|
`node9: daemon spawn aborted \u2014 argv[1] (${resolvedScript}) is outside package dist (${packageDist})`
|
|
48964
48619
|
);
|
|
@@ -48976,7 +48631,7 @@ RAW: ${raw}
|
|
|
48976
48631
|
const startupFd = openStartupLogFd();
|
|
48977
48632
|
recordStartupState("starting");
|
|
48978
48633
|
try {
|
|
48979
|
-
const d = (0,
|
|
48634
|
+
const d = (0, import_child_process6.spawn)(process.execPath, [scriptPath, "daemon"], {
|
|
48980
48635
|
detached: true,
|
|
48981
48636
|
stdio: ["ignore", "ignore", startupFd ?? "ignore"],
|
|
48982
48637
|
env: { ...safeEnv, NODE9_AUTO_STARTED: "1" }
|
|
@@ -48988,17 +48643,17 @@ RAW: ${raw}
|
|
|
48988
48643
|
} finally {
|
|
48989
48644
|
if (startupFd !== void 0) {
|
|
48990
48645
|
try {
|
|
48991
|
-
|
|
48646
|
+
import_fs48.default.closeSync(startupFd);
|
|
48992
48647
|
} catch {
|
|
48993
48648
|
}
|
|
48994
48649
|
}
|
|
48995
48650
|
}
|
|
48996
48651
|
} catch (spawnErr) {
|
|
48997
|
-
const logPath =
|
|
48652
|
+
const logPath = import_path46.default.join(import_os43.default.homedir(), ".node9", "hook-debug.log");
|
|
48998
48653
|
const msg = spawnErr instanceof Error ? spawnErr.message : String(spawnErr);
|
|
48999
48654
|
recordStartupState("failed", "spawn-aborted", msg);
|
|
49000
48655
|
try {
|
|
49001
|
-
|
|
48656
|
+
import_fs48.default.appendFileSync(
|
|
49002
48657
|
logPath,
|
|
49003
48658
|
`[${(/* @__PURE__ */ new Date()).toISOString()}] daemon-autostart-failed: ${msg}
|
|
49004
48659
|
`
|
|
@@ -49012,10 +48667,10 @@ RAW: ${raw}
|
|
|
49012
48667
|
);
|
|
49013
48668
|
}
|
|
49014
48669
|
if (process.env.NODE9_DEBUG === "1" || config.settings.enableHookLogDebug) {
|
|
49015
|
-
const logPath =
|
|
49016
|
-
if (!
|
|
49017
|
-
|
|
49018
|
-
|
|
48670
|
+
const logPath = import_path46.default.join(import_os43.default.homedir(), ".node9", "hook-debug.log");
|
|
48671
|
+
if (!import_fs48.default.existsSync(import_path46.default.dirname(logPath)))
|
|
48672
|
+
import_fs48.default.mkdirSync(import_path46.default.dirname(logPath), { recursive: true });
|
|
48673
|
+
import_fs48.default.appendFileSync(logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] STDIN: ${raw}
|
|
49019
48674
|
`);
|
|
49020
48675
|
}
|
|
49021
48676
|
const rawToolName = sanitize2(extractToolName(payload));
|
|
@@ -49029,8 +48684,8 @@ RAW: ${raw}
|
|
|
49029
48684
|
const isHumanDecision = blockedByContext.toLowerCase().includes("user") || blockedByContext.toLowerCase().includes("daemon") || blockedByContext.toLowerCase().includes("decision");
|
|
49030
48685
|
let ttyFd = null;
|
|
49031
48686
|
try {
|
|
49032
|
-
ttyFd =
|
|
49033
|
-
const writeTty = (line) =>
|
|
48687
|
+
ttyFd = import_fs48.default.openSync("/dev/tty", "w");
|
|
48688
|
+
const writeTty = (line) => import_fs48.default.writeSync(ttyFd, line + "\n");
|
|
49034
48689
|
if (blockedByContext.includes("DLP") || blockedByContext.includes("Secret Detected") || blockedByContext.includes("Credential Review")) {
|
|
49035
48690
|
writeTty(import_chalk9.default.bgRed.white.bold(`
|
|
49036
48691
|
\u{1F6A8} NODE9 DLP ALERT \u2014 CREDENTIAL DETECTED `));
|
|
@@ -49049,7 +48704,7 @@ RAW: ${raw}
|
|
|
49049
48704
|
} finally {
|
|
49050
48705
|
if (ttyFd !== null)
|
|
49051
48706
|
try {
|
|
49052
|
-
|
|
48707
|
+
import_fs48.default.closeSync(ttyFd);
|
|
49053
48708
|
} catch {
|
|
49054
48709
|
}
|
|
49055
48710
|
}
|
|
@@ -49110,8 +48765,8 @@ RAW: ${raw}
|
|
|
49110
48765
|
} catch {
|
|
49111
48766
|
}
|
|
49112
48767
|
try {
|
|
49113
|
-
const ttyFd =
|
|
49114
|
-
|
|
48768
|
+
const ttyFd = import_fs48.default.openSync("/dev/tty", "w");
|
|
48769
|
+
import_fs48.default.writeSync(
|
|
49115
48770
|
ttyFd,
|
|
49116
48771
|
import_chalk9.default.yellow(
|
|
49117
48772
|
`
|
|
@@ -49119,7 +48774,7 @@ RAW: ${raw}
|
|
|
49119
48774
|
`
|
|
49120
48775
|
)
|
|
49121
48776
|
);
|
|
49122
|
-
|
|
48777
|
+
import_fs48.default.closeSync(ttyFd);
|
|
49123
48778
|
} catch {
|
|
49124
48779
|
}
|
|
49125
48780
|
if (agent === "GitHub Copilot") {
|
|
@@ -49151,17 +48806,17 @@ RAW: ${raw}
|
|
|
49151
48806
|
const safeSessionId = /^[A-Za-z0-9_\-]{1,128}$/.test(rawSessionId) ? rawSessionId : "";
|
|
49152
48807
|
if (skillPinCfg.enabled && safeSessionId) {
|
|
49153
48808
|
try {
|
|
49154
|
-
const sessionsDir =
|
|
49155
|
-
const flagPath =
|
|
48809
|
+
const sessionsDir = import_path46.default.join(import_os43.default.homedir(), ".node9", "skill-sessions");
|
|
48810
|
+
const flagPath = import_path46.default.join(sessionsDir, `${safeSessionId}.json`);
|
|
49156
48811
|
let flag = null;
|
|
49157
48812
|
try {
|
|
49158
|
-
flag = JSON.parse(
|
|
48813
|
+
flag = JSON.parse(import_fs48.default.readFileSync(flagPath, "utf-8"));
|
|
49159
48814
|
} catch {
|
|
49160
48815
|
}
|
|
49161
48816
|
const writeFlag = (data2) => {
|
|
49162
48817
|
try {
|
|
49163
|
-
|
|
49164
|
-
|
|
48818
|
+
import_fs48.default.mkdirSync(sessionsDir, { recursive: true });
|
|
48819
|
+
import_fs48.default.writeFileSync(
|
|
49165
48820
|
flagPath,
|
|
49166
48821
|
JSON.stringify({ ...data2, timestamp: (/* @__PURE__ */ new Date()).toISOString() }, null, 2),
|
|
49167
48822
|
{ mode: 384 }
|
|
@@ -49172,8 +48827,8 @@ RAW: ${raw}
|
|
|
49172
48827
|
const sendSkillWarn = (detail, recoveryCmd) => {
|
|
49173
48828
|
let ttyFd = null;
|
|
49174
48829
|
try {
|
|
49175
|
-
ttyFd =
|
|
49176
|
-
const w = (line) =>
|
|
48830
|
+
ttyFd = import_fs48.default.openSync("/dev/tty", "w");
|
|
48831
|
+
const w = (line) => import_fs48.default.writeSync(ttyFd, line + "\n");
|
|
49177
48832
|
w(import_chalk9.default.yellow(`
|
|
49178
48833
|
\u26A0\uFE0F Node9: installed skill drift detected`));
|
|
49179
48834
|
w(import_chalk9.default.gray(` ${detail}`));
|
|
@@ -49188,7 +48843,7 @@ RAW: ${raw}
|
|
|
49188
48843
|
} finally {
|
|
49189
48844
|
if (ttyFd !== null)
|
|
49190
48845
|
try {
|
|
49191
|
-
|
|
48846
|
+
import_fs48.default.closeSync(ttyFd);
|
|
49192
48847
|
} catch {
|
|
49193
48848
|
}
|
|
49194
48849
|
}
|
|
@@ -49204,7 +48859,7 @@ RAW: ${raw}
|
|
|
49204
48859
|
return;
|
|
49205
48860
|
}
|
|
49206
48861
|
if (!flag || flag.state !== "verified" && flag.state !== "warned") {
|
|
49207
|
-
const absoluteCwd = typeof payloadCwd === "string" &&
|
|
48862
|
+
const absoluteCwd = typeof payloadCwd === "string" && import_path46.default.isAbsolute(payloadCwd) ? payloadCwd : void 0;
|
|
49208
48863
|
const extraRoots = skillPinCfg.roots;
|
|
49209
48864
|
const resolvedExtra = extraRoots.map((r) => resolveUserSkillRoot(r, absoluteCwd)).filter((r) => typeof r === "string");
|
|
49210
48865
|
const roots = [...defaultSkillRoots(absoluteCwd), ...resolvedExtra];
|
|
@@ -49245,10 +48900,10 @@ RAW: ${raw}
|
|
|
49245
48900
|
}
|
|
49246
48901
|
try {
|
|
49247
48902
|
const cutoff = Date.now() - 7 * 24 * 60 * 60 * 1e3;
|
|
49248
|
-
for (const name of
|
|
49249
|
-
const p =
|
|
48903
|
+
for (const name of import_fs48.default.readdirSync(sessionsDir)) {
|
|
48904
|
+
const p = import_path46.default.join(sessionsDir, name);
|
|
49250
48905
|
try {
|
|
49251
|
-
if (
|
|
48906
|
+
if (import_fs48.default.statSync(p).mtimeMs < cutoff) import_fs48.default.unlinkSync(p);
|
|
49252
48907
|
} catch {
|
|
49253
48908
|
}
|
|
49254
48909
|
}
|
|
@@ -49258,19 +48913,16 @@ RAW: ${raw}
|
|
|
49258
48913
|
} catch (err2) {
|
|
49259
48914
|
if (process.env.NODE9_DEBUG === "1") {
|
|
49260
48915
|
try {
|
|
49261
|
-
const dbg =
|
|
48916
|
+
const dbg = import_path46.default.join(import_os43.default.homedir(), ".node9", "hook-debug.log");
|
|
49262
48917
|
const msg = err2 instanceof Error ? err2.message : String(err2);
|
|
49263
|
-
|
|
48918
|
+
import_fs48.default.appendFileSync(dbg, `[${(/* @__PURE__ */ new Date()).toISOString()}] SKILL_PIN_ERROR: ${msg}
|
|
49264
48919
|
`);
|
|
49265
48920
|
} catch {
|
|
49266
48921
|
}
|
|
49267
48922
|
}
|
|
49268
48923
|
}
|
|
49269
48924
|
}
|
|
49270
|
-
|
|
49271
|
-
await createShadowSnapshot(toolName, toolInput, config.policy.snapshot.ignorePaths);
|
|
49272
|
-
}
|
|
49273
|
-
const safeCwdForAuth = typeof payloadCwd === "string" && import_path47.default.isAbsolute(payloadCwd) ? payloadCwd : void 0;
|
|
48925
|
+
const safeCwdForAuth = typeof payloadCwd === "string" && import_path46.default.isAbsolute(payloadCwd) ? payloadCwd : void 0;
|
|
49274
48926
|
const askMode = resolveAskMode(agent, opts, config);
|
|
49275
48927
|
const result = await authorizeHeadless(toolName, toolInput, meta, {
|
|
49276
48928
|
cwd: safeCwdForAuth,
|
|
@@ -49295,12 +48947,12 @@ RAW: ${raw}
|
|
|
49295
48947
|
}
|
|
49296
48948
|
if (result.noApprovalMechanism && !isDaemonRunning() && !process.env.NODE9_NO_AUTO_DAEMON && !process.stdout.isTTY && config.settings.autoStartDaemon) {
|
|
49297
48949
|
try {
|
|
49298
|
-
const tty =
|
|
49299
|
-
|
|
48950
|
+
const tty = import_fs48.default.openSync("/dev/tty", "w");
|
|
48951
|
+
import_fs48.default.writeSync(
|
|
49300
48952
|
tty,
|
|
49301
48953
|
import_chalk9.default.cyan("\n\u{1F6E1}\uFE0F Node9: Starting approval daemon automatically...\n")
|
|
49302
48954
|
);
|
|
49303
|
-
|
|
48955
|
+
import_fs48.default.closeSync(tty);
|
|
49304
48956
|
} catch {
|
|
49305
48957
|
}
|
|
49306
48958
|
const daemonReady = await autoStartDaemonAndWait();
|
|
@@ -49327,9 +48979,9 @@ RAW: ${raw}
|
|
|
49327
48979
|
});
|
|
49328
48980
|
} catch (err2) {
|
|
49329
48981
|
if (process.env.NODE9_DEBUG === "1") {
|
|
49330
|
-
const logPath =
|
|
48982
|
+
const logPath = import_path46.default.join(import_os43.default.homedir(), ".node9", "hook-debug.log");
|
|
49331
48983
|
const errMsg = err2 instanceof Error ? err2.message : String(err2);
|
|
49332
|
-
|
|
48984
|
+
import_fs48.default.appendFileSync(logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] ERROR: ${errMsg}
|
|
49333
48985
|
`);
|
|
49334
48986
|
}
|
|
49335
48987
|
process.exit(0);
|
|
@@ -49363,9 +49015,9 @@ RAW: ${raw}
|
|
|
49363
49015
|
}
|
|
49364
49016
|
|
|
49365
49017
|
// src/cli/commands/log.ts
|
|
49366
|
-
var
|
|
49367
|
-
var
|
|
49368
|
-
var
|
|
49018
|
+
var import_fs49 = __toESM(require("fs"));
|
|
49019
|
+
var import_path47 = __toESM(require("path"));
|
|
49020
|
+
var import_os44 = __toESM(require("os"));
|
|
49369
49021
|
init_audit();
|
|
49370
49022
|
init_config();
|
|
49371
49023
|
init_daemon();
|
|
@@ -49501,10 +49153,10 @@ function registerLogCommand(program2) {
|
|
|
49501
49153
|
if (rawToolName !== tool) entry.agentToolName = rawToolName;
|
|
49502
49154
|
const payloadSessionId = payload.session_id ?? payload.conversationId;
|
|
49503
49155
|
if (payloadSessionId) entry.sessionId = payloadSessionId;
|
|
49504
|
-
const logPath =
|
|
49505
|
-
if (!
|
|
49506
|
-
|
|
49507
|
-
|
|
49156
|
+
const logPath = import_path47.default.join(import_os44.default.homedir(), ".node9", "audit.log");
|
|
49157
|
+
if (!import_fs49.default.existsSync(import_path47.default.dirname(logPath)))
|
|
49158
|
+
import_fs49.default.mkdirSync(import_path47.default.dirname(logPath), { recursive: true });
|
|
49159
|
+
import_fs49.default.appendFileSync(logPath, JSON.stringify(entry) + "\n");
|
|
49508
49160
|
if ((tool === "Bash" || tool === "bash") && isDaemonRunning()) {
|
|
49509
49161
|
const command = typeof rawInput === "object" && rawInput !== null && "command" in rawInput && typeof rawInput.command === "string" ? rawInput.command : null;
|
|
49510
49162
|
if (command) {
|
|
@@ -49538,7 +49190,7 @@ function registerLogCommand(program2) {
|
|
|
49538
49190
|
}
|
|
49539
49191
|
}
|
|
49540
49192
|
const payloadCwd = typeof payload.cwd === "string" ? payload.cwd : Array.isArray(payload.workspacePaths) && typeof payload.workspacePaths[0] === "string" ? payload.workspacePaths[0] : void 0;
|
|
49541
|
-
const safeCwd = typeof payloadCwd === "string" &&
|
|
49193
|
+
const safeCwd = typeof payloadCwd === "string" && import_path47.default.isAbsolute(payloadCwd) ? payloadCwd : void 0;
|
|
49542
49194
|
const config = getConfig(safeCwd);
|
|
49543
49195
|
if (resolvedReview) {
|
|
49544
49196
|
try {
|
|
@@ -49623,28 +49275,13 @@ function registerLogCommand(program2) {
|
|
|
49623
49275
|
}
|
|
49624
49276
|
}
|
|
49625
49277
|
}
|
|
49626
|
-
if ((tool === "Bash" || tool === "bash") && config.settings.enableUndo === true) {
|
|
49627
|
-
const bashCommand = typeof rawInput === "object" && rawInput !== null && "command" in rawInput && typeof rawInput.command === "string" ? rawInput.command : null;
|
|
49628
|
-
if (bashCommand) {
|
|
49629
|
-
const effectiveCwd = safeCwd ?? process.cwd();
|
|
49630
|
-
const history = getSnapshotHistory();
|
|
49631
|
-
const hasPrior = history.some((e) => e.cwd === effectiveCwd);
|
|
49632
|
-
if (hasPrior) {
|
|
49633
|
-
await createShadowSnapshot(
|
|
49634
|
-
"Bash",
|
|
49635
|
-
{ command: bashCommand },
|
|
49636
|
-
config.policy.snapshot.ignorePaths
|
|
49637
|
-
);
|
|
49638
|
-
}
|
|
49639
|
-
}
|
|
49640
|
-
}
|
|
49641
49278
|
} catch (err2) {
|
|
49642
49279
|
const msg = err2 instanceof Error ? err2.message : String(err2);
|
|
49643
49280
|
process.stderr.write(`[Node9] audit log error: ${msg}
|
|
49644
49281
|
`);
|
|
49645
|
-
const debugPath =
|
|
49282
|
+
const debugPath = import_path47.default.join(import_os44.default.homedir(), ".node9", "hook-debug.log");
|
|
49646
49283
|
try {
|
|
49647
|
-
|
|
49284
|
+
import_fs49.default.appendFileSync(debugPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] LOG_ERROR: ${msg}
|
|
49648
49285
|
`);
|
|
49649
49286
|
} catch {
|
|
49650
49287
|
}
|
|
@@ -49669,15 +49306,15 @@ function registerLogCommand(program2) {
|
|
|
49669
49306
|
|
|
49670
49307
|
// src/cli/commands/shield.ts
|
|
49671
49308
|
var import_chalk10 = __toESM(require("chalk"));
|
|
49672
|
-
var
|
|
49673
|
-
var
|
|
49674
|
-
var
|
|
49309
|
+
var import_fs51 = __toESM(require("fs"));
|
|
49310
|
+
var import_path49 = __toESM(require("path"));
|
|
49311
|
+
var import_os45 = __toESM(require("os"));
|
|
49675
49312
|
init_shields();
|
|
49676
49313
|
init_build();
|
|
49677
49314
|
|
|
49678
49315
|
// src/shields/create.ts
|
|
49679
|
-
var
|
|
49680
|
-
var
|
|
49316
|
+
var import_fs50 = __toESM(require("fs"));
|
|
49317
|
+
var import_path48 = __toESM(require("path"));
|
|
49681
49318
|
init_dist();
|
|
49682
49319
|
init_shields();
|
|
49683
49320
|
init_audit();
|
|
@@ -49697,8 +49334,8 @@ function createShield(def, opts = {}) {
|
|
|
49697
49334
|
error: `"${name}" is a built-in shield \u2014 choose a different name (a user shield with this name would shadow the built-in).`
|
|
49698
49335
|
};
|
|
49699
49336
|
}
|
|
49700
|
-
const filePath =
|
|
49701
|
-
if (!opts.overwrite &&
|
|
49337
|
+
const filePath = import_path48.default.join(USER_SHIELDS_DIR_PATH, `${name}.json`);
|
|
49338
|
+
if (!opts.overwrite && import_fs50.default.existsSync(filePath)) {
|
|
49702
49339
|
return {
|
|
49703
49340
|
ok: false,
|
|
49704
49341
|
error: `Shield "${name}" already exists at ${filePath}. Pass --overwrite to replace it.`
|
|
@@ -49763,8 +49400,8 @@ var COMMUNITY_INDEX_URL = "https://raw.githubusercontent.com/node9ai/node9-proxy
|
|
|
49763
49400
|
function readCloudShields() {
|
|
49764
49401
|
const out = /* @__PURE__ */ new Set();
|
|
49765
49402
|
try {
|
|
49766
|
-
const file =
|
|
49767
|
-
const raw = JSON.parse(
|
|
49403
|
+
const file = import_path49.default.join(import_os45.default.homedir(), ".node9", "rules-cache.json");
|
|
49404
|
+
const raw = JSON.parse(import_fs51.default.readFileSync(file, "utf-8"));
|
|
49768
49405
|
for (const r of raw.rules ?? []) {
|
|
49769
49406
|
const rule = r;
|
|
49770
49407
|
const fromSource = rule.source?.startsWith("SHIELD:") ? rule.source.slice("SHIELD:".length).toLowerCase() : void 0;
|
|
@@ -50081,7 +49718,7 @@ function registerShieldCommand(program2) {
|
|
|
50081
49718
|
if (opts.fromFile) {
|
|
50082
49719
|
let raw;
|
|
50083
49720
|
try {
|
|
50084
|
-
raw = JSON.parse(
|
|
49721
|
+
raw = JSON.parse(import_fs51.default.readFileSync(opts.fromFile, "utf-8"));
|
|
50085
49722
|
} catch (err2) {
|
|
50086
49723
|
console.error(
|
|
50087
49724
|
import_chalk10.default.red(`
|
|
@@ -50201,10 +49838,10 @@ function registerConfigShowCommand(program2) {
|
|
|
50201
49838
|
|
|
50202
49839
|
// src/cli/commands/doctor.ts
|
|
50203
49840
|
var import_chalk11 = __toESM(require("chalk"));
|
|
50204
|
-
var
|
|
50205
|
-
var
|
|
50206
|
-
var
|
|
50207
|
-
var
|
|
49841
|
+
var import_fs53 = __toESM(require("fs"));
|
|
49842
|
+
var import_path51 = __toESM(require("path"));
|
|
49843
|
+
var import_os47 = __toESM(require("os"));
|
|
49844
|
+
var import_child_process7 = require("child_process");
|
|
50208
49845
|
init_daemon();
|
|
50209
49846
|
init_build_id();
|
|
50210
49847
|
init_config();
|
|
@@ -50229,22 +49866,22 @@ function agoLabel(iso, now = Date.now()) {
|
|
|
50229
49866
|
init_startup_log();
|
|
50230
49867
|
|
|
50231
49868
|
// src/utils/undo-leftovers.ts
|
|
50232
|
-
var
|
|
50233
|
-
var
|
|
50234
|
-
var
|
|
49869
|
+
var import_fs52 = __toESM(require("fs"));
|
|
49870
|
+
var import_os46 = __toESM(require("os"));
|
|
49871
|
+
var import_path50 = __toESM(require("path"));
|
|
50235
49872
|
function candidates(homeDir2) {
|
|
50236
|
-
const node9Dir =
|
|
49873
|
+
const node9Dir = import_path50.default.join(homeDir2, ".node9");
|
|
50237
49874
|
return [
|
|
50238
|
-
|
|
50239
|
-
|
|
50240
|
-
|
|
49875
|
+
import_path50.default.join(node9Dir, "snapshots"),
|
|
49876
|
+
import_path50.default.join(node9Dir, "snapshots.json"),
|
|
49877
|
+
import_path50.default.join(node9Dir, "undo_latest.txt")
|
|
50241
49878
|
];
|
|
50242
49879
|
}
|
|
50243
|
-
function undoLeftoverPaths(homeDir2 =
|
|
49880
|
+
function undoLeftoverPaths(homeDir2 = import_os46.default.homedir()) {
|
|
50244
49881
|
const found = [];
|
|
50245
49882
|
for (const p of candidates(homeDir2)) {
|
|
50246
49883
|
try {
|
|
50247
|
-
|
|
49884
|
+
import_fs52.default.lstatSync(p);
|
|
50248
49885
|
found.push(p);
|
|
50249
49886
|
} catch (err2) {
|
|
50250
49887
|
if (err2.code !== "ENOENT") found.push(p);
|
|
@@ -50252,11 +49889,11 @@ function undoLeftoverPaths(homeDir2 = import_os47.default.homedir()) {
|
|
|
50252
49889
|
}
|
|
50253
49890
|
return found;
|
|
50254
49891
|
}
|
|
50255
|
-
function purgeUndoLeftovers(homeDir2 =
|
|
49892
|
+
function purgeUndoLeftovers(homeDir2 = import_os46.default.homedir()) {
|
|
50256
49893
|
const out = { deleted: [], skipped: [], failed: [] };
|
|
50257
49894
|
for (const p of undoLeftoverPaths(homeDir2)) {
|
|
50258
49895
|
try {
|
|
50259
|
-
if (
|
|
49896
|
+
if (import_fs52.default.lstatSync(p).isSymbolicLink()) {
|
|
50260
49897
|
out.skipped.push({
|
|
50261
49898
|
path: p,
|
|
50262
49899
|
reason: "is a symlink \u2014 remove it yourself so nothing else is followed"
|
|
@@ -50269,11 +49906,11 @@ function purgeUndoLeftovers(homeDir2 = import_os47.default.homedir()) {
|
|
|
50269
49906
|
}
|
|
50270
49907
|
let reason = null;
|
|
50271
49908
|
try {
|
|
50272
|
-
|
|
49909
|
+
import_fs52.default.rmSync(p, { recursive: true, force: true });
|
|
50273
49910
|
} catch (err2) {
|
|
50274
49911
|
reason = err2.message;
|
|
50275
49912
|
}
|
|
50276
|
-
if (
|
|
49913
|
+
if (import_fs52.default.existsSync(p)) {
|
|
50277
49914
|
out.failed.push({ path: p, reason: reason ?? "still present after removal" });
|
|
50278
49915
|
} else {
|
|
50279
49916
|
out.deleted.push(p);
|
|
@@ -50285,7 +49922,7 @@ function purgeUndoLeftovers(homeDir2 = import_os47.default.homedir()) {
|
|
|
50285
49922
|
// src/cli/commands/doctor.ts
|
|
50286
49923
|
function registerDoctorCommand(program2, version2) {
|
|
50287
49924
|
program2.command("doctor").description("Check that Node9 is installed and configured correctly").action(async () => {
|
|
50288
|
-
const homeDir2 =
|
|
49925
|
+
const homeDir2 = import_os47.default.homedir();
|
|
50289
49926
|
let failures = 0;
|
|
50290
49927
|
function pass(msg) {
|
|
50291
49928
|
console.log(import_chalk11.default.green(" \u2705 ") + msg);
|
|
@@ -50307,7 +49944,7 @@ function registerDoctorCommand(program2, version2) {
|
|
|
50307
49944
|
`));
|
|
50308
49945
|
section("Binary");
|
|
50309
49946
|
try {
|
|
50310
|
-
const which = (0,
|
|
49947
|
+
const which = (0, import_child_process7.execSync)("which node9", { encoding: "utf-8", timeout: 3e3 }).trim();
|
|
50311
49948
|
pass(`node9 found at ${which}`);
|
|
50312
49949
|
} catch {
|
|
50313
49950
|
warn("node9 not found in $PATH \u2014 hooks may not find it", "Run: npm install -g node9-ai");
|
|
@@ -50322,16 +49959,16 @@ function registerDoctorCommand(program2, version2) {
|
|
|
50322
49959
|
);
|
|
50323
49960
|
}
|
|
50324
49961
|
try {
|
|
50325
|
-
const gitVersion = (0,
|
|
49962
|
+
const gitVersion = (0, import_child_process7.execSync)("git --version", { encoding: "utf-8", timeout: 3e3 }).trim();
|
|
50326
49963
|
pass(gitVersion);
|
|
50327
49964
|
} catch {
|
|
50328
49965
|
warn("git not found", "Install git \u2014 node9 reads repo state for scans and reports");
|
|
50329
49966
|
}
|
|
50330
49967
|
section("Configuration");
|
|
50331
|
-
const globalConfigPath =
|
|
50332
|
-
if (
|
|
49968
|
+
const globalConfigPath = import_path51.default.join(homeDir2, ".node9", "config.json");
|
|
49969
|
+
if (import_fs53.default.existsSync(globalConfigPath)) {
|
|
50333
49970
|
try {
|
|
50334
|
-
JSON.parse(
|
|
49971
|
+
JSON.parse(import_fs53.default.readFileSync(globalConfigPath, "utf-8"));
|
|
50335
49972
|
pass("~/.node9/config.json found and valid");
|
|
50336
49973
|
} catch {
|
|
50337
49974
|
fail("~/.node9/config.json is invalid JSON", "Run: node9 init --force");
|
|
@@ -50346,10 +49983,10 @@ function registerDoctorCommand(program2, version2) {
|
|
|
50346
49983
|
"Remove them when ready: node9 undo --purge"
|
|
50347
49984
|
);
|
|
50348
49985
|
}
|
|
50349
|
-
const projectConfigPath =
|
|
50350
|
-
if (
|
|
49986
|
+
const projectConfigPath = import_path51.default.join(process.cwd(), "node9.config.json");
|
|
49987
|
+
if (import_fs53.default.existsSync(projectConfigPath)) {
|
|
50351
49988
|
try {
|
|
50352
|
-
JSON.parse(
|
|
49989
|
+
JSON.parse(import_fs53.default.readFileSync(projectConfigPath, "utf-8"));
|
|
50353
49990
|
pass("node9.config.json found and valid (project)");
|
|
50354
49991
|
} catch {
|
|
50355
49992
|
fail(
|
|
@@ -50358,8 +49995,8 @@ function registerDoctorCommand(program2, version2) {
|
|
|
50358
49995
|
);
|
|
50359
49996
|
}
|
|
50360
49997
|
}
|
|
50361
|
-
const credsPath =
|
|
50362
|
-
if (
|
|
49998
|
+
const credsPath = import_path51.default.join(homeDir2, ".node9", "credentials.json");
|
|
49999
|
+
if (import_fs53.default.existsSync(credsPath)) {
|
|
50363
50000
|
pass("Cloud credentials found (~/.node9/credentials.json)");
|
|
50364
50001
|
} else {
|
|
50365
50002
|
warn(
|
|
@@ -50425,7 +50062,7 @@ function registerDoctorCommand(program2, version2) {
|
|
|
50425
50062
|
cloudEnabled: !!getConfig().settings.approvers?.cloud
|
|
50426
50063
|
});
|
|
50427
50064
|
if (autostart) warn(autostart.message, autostart.hint);
|
|
50428
|
-
if (
|
|
50065
|
+
if (import_fs53.default.existsSync(import_path51.default.join(import_os47.default.homedir(), ".node9", "credentials.json")) && getConfig().settings.approvers?.cloud) {
|
|
50429
50066
|
section("Policy sync");
|
|
50430
50067
|
const health = readSyncHealth();
|
|
50431
50068
|
if (isPolicyStale(Date.now(), health)) {
|
|
@@ -50443,7 +50080,7 @@ function registerDoctorCommand(program2, version2) {
|
|
|
50443
50080
|
try {
|
|
50444
50081
|
const { shipLagBytes: shipLagBytes2, readWatermark: readWatermark2, AUDIT_SHIP_WATERMARK: AUDIT_SHIP_WATERMARK2 } = await Promise.resolve().then(() => (init_audit_shipper(), audit_shipper_exports));
|
|
50445
50082
|
const cfg = getConfig();
|
|
50446
|
-
const creds =
|
|
50083
|
+
const creds = import_fs53.default.existsSync(import_path51.default.join(import_os47.default.homedir(), ".node9", "credentials.json"));
|
|
50447
50084
|
if (!creds) {
|
|
50448
50085
|
warn("Not logged in \u2014 audit rows stay local", "Run: node9 login <api-key>");
|
|
50449
50086
|
} else if (!cfg.settings.approvers.cloud) {
|
|
@@ -50493,10 +50130,10 @@ function registerDoctorCommand(program2, version2) {
|
|
|
50493
50130
|
|
|
50494
50131
|
// src/cli/commands/audit.ts
|
|
50495
50132
|
var import_chalk12 = __toESM(require("chalk"));
|
|
50496
|
-
var
|
|
50497
|
-
var
|
|
50133
|
+
var import_fs54 = __toESM(require("fs"));
|
|
50134
|
+
var import_path52 = __toESM(require("path"));
|
|
50498
50135
|
init_decision();
|
|
50499
|
-
var
|
|
50136
|
+
var import_os48 = __toESM(require("os"));
|
|
50500
50137
|
function formatRelativeTime(timestamp) {
|
|
50501
50138
|
const diff = Date.now() - new Date(timestamp).getTime();
|
|
50502
50139
|
const sec = Math.floor(diff / 1e3);
|
|
@@ -50509,14 +50146,14 @@ function formatRelativeTime(timestamp) {
|
|
|
50509
50146
|
}
|
|
50510
50147
|
function registerAuditCommand(program2) {
|
|
50511
50148
|
program2.command("audit").description("View local execution audit log").option("--tail <n>", "Number of entries to show", "20").option("--tool <pattern>", "Filter by tool name (substring match)").option("--deny", "Show only denied actions").option("--json", "Output raw JSON").action((options) => {
|
|
50512
|
-
const logPath =
|
|
50513
|
-
if (!
|
|
50149
|
+
const logPath = import_path52.default.join(import_os48.default.homedir(), ".node9", "audit.log");
|
|
50150
|
+
if (!import_fs54.default.existsSync(logPath)) {
|
|
50514
50151
|
console.log(
|
|
50515
50152
|
import_chalk12.default.yellow("No audit logs found. Run node9 with an agent to generate entries.")
|
|
50516
50153
|
);
|
|
50517
50154
|
return;
|
|
50518
50155
|
}
|
|
50519
|
-
const raw =
|
|
50156
|
+
const raw = import_fs54.default.readFileSync(logPath, "utf-8");
|
|
50520
50157
|
const lines = raw.split("\n").filter((l) => l.trim() !== "");
|
|
50521
50158
|
let entries = lines.flatMap((line) => {
|
|
50522
50159
|
try {
|
|
@@ -50578,9 +50215,9 @@ function registerAuditCommand(program2) {
|
|
|
50578
50215
|
var import_chalk13 = __toESM(require("chalk"));
|
|
50579
50216
|
|
|
50580
50217
|
// src/cli/aggregate/report-audit.ts
|
|
50581
|
-
var
|
|
50582
|
-
var
|
|
50583
|
-
var
|
|
50218
|
+
var import_fs55 = __toESM(require("fs"));
|
|
50219
|
+
var import_os49 = __toESM(require("os"));
|
|
50220
|
+
var import_path53 = __toESM(require("path"));
|
|
50584
50221
|
init_costSync();
|
|
50585
50222
|
init_litellm();
|
|
50586
50223
|
init_cost_codex();
|
|
@@ -50664,8 +50301,8 @@ function getDateRange(period, now) {
|
|
|
50664
50301
|
}
|
|
50665
50302
|
}
|
|
50666
50303
|
function parseAuditLog(logPath) {
|
|
50667
|
-
if (!
|
|
50668
|
-
const raw =
|
|
50304
|
+
if (!import_fs55.default.existsSync(logPath)) return [];
|
|
50305
|
+
const raw = import_fs55.default.readFileSync(logPath, "utf-8");
|
|
50669
50306
|
return raw.split("\n").flatMap((line) => {
|
|
50670
50307
|
if (!line.trim()) return [];
|
|
50671
50308
|
try {
|
|
@@ -50719,25 +50356,25 @@ function freezeClaudeCost(acc) {
|
|
|
50719
50356
|
};
|
|
50720
50357
|
}
|
|
50721
50358
|
function processClaudeCostProject(proj, projectsDir, start, end, acc) {
|
|
50722
|
-
const projPath =
|
|
50359
|
+
const projPath = import_path53.default.join(projectsDir, proj);
|
|
50723
50360
|
let files;
|
|
50724
50361
|
try {
|
|
50725
|
-
const stat =
|
|
50362
|
+
const stat = import_fs55.default.statSync(projPath);
|
|
50726
50363
|
if (!stat.isDirectory()) return;
|
|
50727
|
-
files =
|
|
50364
|
+
files = import_fs55.default.readdirSync(projPath).filter((f) => f.endsWith(".jsonl") && !f.startsWith("agent-"));
|
|
50728
50365
|
} catch {
|
|
50729
50366
|
return;
|
|
50730
50367
|
}
|
|
50731
50368
|
const startMs = start.getTime();
|
|
50732
50369
|
for (const file of files) {
|
|
50733
|
-
const filePath =
|
|
50370
|
+
const filePath = import_path53.default.join(projPath, file);
|
|
50734
50371
|
try {
|
|
50735
|
-
if (
|
|
50372
|
+
if (import_fs55.default.statSync(filePath).mtimeMs < startMs) continue;
|
|
50736
50373
|
} catch {
|
|
50737
50374
|
continue;
|
|
50738
50375
|
}
|
|
50739
50376
|
try {
|
|
50740
|
-
const raw =
|
|
50377
|
+
const raw = import_fs55.default.readFileSync(filePath, "utf-8");
|
|
50741
50378
|
for (const line of raw.split("\n")) {
|
|
50742
50379
|
if (!line.trim()) continue;
|
|
50743
50380
|
let entry;
|
|
@@ -50787,10 +50424,10 @@ function processClaudeCostProject(proj, projectsDir, start, end, acc) {
|
|
|
50787
50424
|
}
|
|
50788
50425
|
function loadClaudeCost(start, end, projectsDir) {
|
|
50789
50426
|
const acc = emptyClaudeCostAccumulator();
|
|
50790
|
-
if (!
|
|
50427
|
+
if (!import_fs55.default.existsSync(projectsDir)) return freezeClaudeCost(acc);
|
|
50791
50428
|
let dirs;
|
|
50792
50429
|
try {
|
|
50793
|
-
dirs =
|
|
50430
|
+
dirs = import_fs55.default.readdirSync(projectsDir);
|
|
50794
50431
|
} catch {
|
|
50795
50432
|
return freezeClaudeCost(acc);
|
|
50796
50433
|
}
|
|
@@ -50802,7 +50439,7 @@ function loadClaudeCost(start, end, projectsDir) {
|
|
|
50802
50439
|
function processCodexCostFile(filePath, start, end, acc) {
|
|
50803
50440
|
let lines;
|
|
50804
50441
|
try {
|
|
50805
|
-
lines =
|
|
50442
|
+
lines = import_fs55.default.readFileSync(filePath, "utf-8").split("\n");
|
|
50806
50443
|
} catch {
|
|
50807
50444
|
return;
|
|
50808
50445
|
}
|
|
@@ -50857,31 +50494,31 @@ function processCodexCostFile(filePath, start, end, acc) {
|
|
|
50857
50494
|
}
|
|
50858
50495
|
function listCodexSessionFiles2(sessionsBase) {
|
|
50859
50496
|
const jsonlFiles = [];
|
|
50860
|
-
if (!
|
|
50497
|
+
if (!import_fs55.default.existsSync(sessionsBase)) return jsonlFiles;
|
|
50861
50498
|
try {
|
|
50862
|
-
for (const year of
|
|
50863
|
-
const yearPath =
|
|
50499
|
+
for (const year of import_fs55.default.readdirSync(sessionsBase)) {
|
|
50500
|
+
const yearPath = import_path53.default.join(sessionsBase, year);
|
|
50864
50501
|
try {
|
|
50865
|
-
if (!
|
|
50502
|
+
if (!import_fs55.default.statSync(yearPath).isDirectory()) continue;
|
|
50866
50503
|
} catch {
|
|
50867
50504
|
continue;
|
|
50868
50505
|
}
|
|
50869
|
-
for (const month of
|
|
50870
|
-
const monthPath =
|
|
50506
|
+
for (const month of import_fs55.default.readdirSync(yearPath)) {
|
|
50507
|
+
const monthPath = import_path53.default.join(yearPath, month);
|
|
50871
50508
|
try {
|
|
50872
|
-
if (!
|
|
50509
|
+
if (!import_fs55.default.statSync(monthPath).isDirectory()) continue;
|
|
50873
50510
|
} catch {
|
|
50874
50511
|
continue;
|
|
50875
50512
|
}
|
|
50876
|
-
for (const day of
|
|
50877
|
-
const dayPath =
|
|
50513
|
+
for (const day of import_fs55.default.readdirSync(monthPath)) {
|
|
50514
|
+
const dayPath = import_path53.default.join(monthPath, day);
|
|
50878
50515
|
try {
|
|
50879
|
-
if (!
|
|
50516
|
+
if (!import_fs55.default.statSync(dayPath).isDirectory()) continue;
|
|
50880
50517
|
} catch {
|
|
50881
50518
|
continue;
|
|
50882
50519
|
}
|
|
50883
|
-
for (const file of
|
|
50884
|
-
if (file.endsWith(".jsonl")) jsonlFiles.push(
|
|
50520
|
+
for (const file of import_fs55.default.readdirSync(dayPath)) {
|
|
50521
|
+
if (file.endsWith(".jsonl")) jsonlFiles.push(import_path53.default.join(dayPath, file));
|
|
50885
50522
|
}
|
|
50886
50523
|
}
|
|
50887
50524
|
}
|
|
@@ -50946,13 +50583,13 @@ function freezeGeminiCost(acc) {
|
|
|
50946
50583
|
function processGeminiCostFile(filePath, projectKey, start, end, acc) {
|
|
50947
50584
|
const startMs = start.getTime();
|
|
50948
50585
|
try {
|
|
50949
|
-
if (
|
|
50586
|
+
if (import_fs55.default.statSync(filePath).mtimeMs < startMs) return;
|
|
50950
50587
|
} catch {
|
|
50951
50588
|
return;
|
|
50952
50589
|
}
|
|
50953
50590
|
let raw;
|
|
50954
50591
|
try {
|
|
50955
|
-
raw =
|
|
50592
|
+
raw = import_fs55.default.readFileSync(filePath, "utf-8");
|
|
50956
50593
|
} catch {
|
|
50957
50594
|
return;
|
|
50958
50595
|
}
|
|
@@ -51001,30 +50638,30 @@ function listGeminiSessionFiles2(geminiTmpDir2) {
|
|
|
51001
50638
|
const out = [];
|
|
51002
50639
|
let dirs;
|
|
51003
50640
|
try {
|
|
51004
|
-
if (!
|
|
51005
|
-
dirs =
|
|
50641
|
+
if (!import_fs55.default.statSync(geminiTmpDir2).isDirectory()) return out;
|
|
50642
|
+
dirs = import_fs55.default.readdirSync(geminiTmpDir2);
|
|
51006
50643
|
} catch {
|
|
51007
50644
|
return out;
|
|
51008
50645
|
}
|
|
51009
50646
|
for (const proj of dirs) {
|
|
51010
|
-
const chatsDir =
|
|
50647
|
+
const chatsDir = import_path53.default.join(geminiTmpDir2, proj, "chats");
|
|
51011
50648
|
let files;
|
|
51012
50649
|
try {
|
|
51013
|
-
if (!
|
|
51014
|
-
files =
|
|
50650
|
+
if (!import_fs55.default.statSync(chatsDir).isDirectory()) continue;
|
|
50651
|
+
files = import_fs55.default.readdirSync(chatsDir);
|
|
51015
50652
|
} catch {
|
|
51016
50653
|
continue;
|
|
51017
50654
|
}
|
|
51018
50655
|
for (const f of files) {
|
|
51019
50656
|
if (!f.endsWith(".jsonl")) continue;
|
|
51020
|
-
out.push({ projectKey: proj, file:
|
|
50657
|
+
out.push({ projectKey: proj, file: import_path53.default.join(chatsDir, f) });
|
|
51021
50658
|
}
|
|
51022
50659
|
}
|
|
51023
50660
|
return out;
|
|
51024
50661
|
}
|
|
51025
50662
|
function loadGeminiCost(start, end, geminiTmpDir2) {
|
|
51026
50663
|
const acc = emptyGeminiAccumulator();
|
|
51027
|
-
if (!
|
|
50664
|
+
if (!import_fs55.default.existsSync(geminiTmpDir2)) return freezeGeminiCost(acc);
|
|
51028
50665
|
for (const { projectKey, file } of listGeminiSessionFiles2(geminiTmpDir2)) {
|
|
51029
50666
|
processGeminiCostFile(file, projectKey, start, end, acc);
|
|
51030
50667
|
}
|
|
@@ -51042,11 +50679,11 @@ function dimensionOfBlock(checkedBy, ruleName) {
|
|
|
51042
50679
|
}
|
|
51043
50680
|
function aggregateReportFromAudit(period, opts = {}) {
|
|
51044
50681
|
const now = opts.now ?? /* @__PURE__ */ new Date();
|
|
51045
|
-
const auditLogPath = opts.auditLogPath ??
|
|
51046
|
-
const claudeProjectsDir = opts.claudeProjectsDir ??
|
|
51047
|
-
const codexSessionsDir2 = opts.codexSessionsDir ??
|
|
51048
|
-
const geminiTmpDir2 = opts.geminiTmpDir ??
|
|
51049
|
-
const hasAuditFile =
|
|
50682
|
+
const auditLogPath = opts.auditLogPath ?? import_path53.default.join(import_os49.default.homedir(), ".node9", "audit.log");
|
|
50683
|
+
const claudeProjectsDir = opts.claudeProjectsDir ?? import_path53.default.join(import_os49.default.homedir(), ".claude", "projects");
|
|
50684
|
+
const codexSessionsDir2 = opts.codexSessionsDir ?? import_path53.default.join(import_os49.default.homedir(), ".codex", "sessions");
|
|
50685
|
+
const geminiTmpDir2 = opts.geminiTmpDir ?? import_path53.default.join(import_os49.default.homedir(), ".gemini", "tmp");
|
|
50686
|
+
const hasAuditFile = import_fs55.default.existsSync(auditLogPath);
|
|
51050
50687
|
const allEntries = opts.preloadedAuditEntries ?? parseAuditLog(auditLogPath);
|
|
51051
50688
|
const unackedDlp = allEntries.filter((e) => e.source === "response-dlp");
|
|
51052
50689
|
const { start, end } = getDateRange(period, now);
|
|
@@ -51752,9 +51389,9 @@ function renderTerminalReport(data, responseDlpEntries, excludeTests) {
|
|
|
51752
51389
|
|
|
51753
51390
|
// src/cli/commands/daemon-cmd.ts
|
|
51754
51391
|
var import_chalk14 = __toESM(require("chalk"));
|
|
51755
|
-
var
|
|
51392
|
+
var import_child_process8 = require("child_process");
|
|
51756
51393
|
init_daemon();
|
|
51757
|
-
var
|
|
51394
|
+
var import_fs56 = __toESM(require("fs"));
|
|
51758
51395
|
init_startup_log();
|
|
51759
51396
|
init_daemon2();
|
|
51760
51397
|
var VALID_ACTIONS = "start | stop | restart | status | install | uninstall";
|
|
@@ -51799,7 +51436,7 @@ function registerDaemonCommand(program2) {
|
|
|
51799
51436
|
}
|
|
51800
51437
|
const restartFd = openStartupLogFd();
|
|
51801
51438
|
recordStartupState("starting");
|
|
51802
|
-
const child = (0,
|
|
51439
|
+
const child = (0, import_child_process8.spawn)(process.execPath, [process.argv[1], "daemon"], {
|
|
51803
51440
|
detached: true,
|
|
51804
51441
|
stdio: ["ignore", "ignore", restartFd ?? "ignore"],
|
|
51805
51442
|
env: { ...process.env, NODE9_AUTO_STARTED: "1" }
|
|
@@ -51811,7 +51448,7 @@ function registerDaemonCommand(program2) {
|
|
|
51811
51448
|
child.unref();
|
|
51812
51449
|
if (restartFd !== void 0) {
|
|
51813
51450
|
try {
|
|
51814
|
-
|
|
51451
|
+
import_fs56.default.closeSync(restartFd);
|
|
51815
51452
|
} catch {
|
|
51816
51453
|
}
|
|
51817
51454
|
}
|
|
@@ -51843,7 +51480,7 @@ function registerDaemonCommand(program2) {
|
|
|
51843
51480
|
const startupFd = openStartupLogFd();
|
|
51844
51481
|
try {
|
|
51845
51482
|
recordStartupState("starting");
|
|
51846
|
-
const child = (0,
|
|
51483
|
+
const child = (0, import_child_process8.spawn)(process.execPath, [process.argv[1], "daemon"], {
|
|
51847
51484
|
detached: true,
|
|
51848
51485
|
// Capture the child's stderr: a module-load crash prints its stack there
|
|
51849
51486
|
// and dies before it can record anything itself.
|
|
@@ -51862,7 +51499,7 @@ function registerDaemonCommand(program2) {
|
|
|
51862
51499
|
} finally {
|
|
51863
51500
|
if (startupFd !== void 0) {
|
|
51864
51501
|
try {
|
|
51865
|
-
|
|
51502
|
+
import_fs56.default.closeSync(startupFd);
|
|
51866
51503
|
} catch {
|
|
51867
51504
|
}
|
|
51868
51505
|
}
|
|
@@ -51876,9 +51513,9 @@ function registerDaemonCommand(program2) {
|
|
|
51876
51513
|
|
|
51877
51514
|
// src/cli/commands/status.ts
|
|
51878
51515
|
var import_chalk15 = __toESM(require("chalk"));
|
|
51879
|
-
var
|
|
51880
|
-
var
|
|
51881
|
-
var
|
|
51516
|
+
var import_fs57 = __toESM(require("fs"));
|
|
51517
|
+
var import_path54 = __toESM(require("path"));
|
|
51518
|
+
var import_os50 = __toESM(require("os"));
|
|
51882
51519
|
init_core();
|
|
51883
51520
|
init_daemon();
|
|
51884
51521
|
init_build_id();
|
|
@@ -51965,20 +51602,20 @@ function registerStatusCommand(program2) {
|
|
|
51965
51602
|
console.log("");
|
|
51966
51603
|
const modeLabel = settings.mode === "audit" ? import_chalk15.default.blue("audit") : settings.mode === "strict" ? import_chalk15.default.red("strict") : import_chalk15.default.white("standard");
|
|
51967
51604
|
console.log(` Mode: ${modeLabel}`);
|
|
51968
|
-
const projectConfig =
|
|
51969
|
-
const globalConfig =
|
|
51605
|
+
const projectConfig = import_path54.default.join(process.cwd(), "node9.config.json");
|
|
51606
|
+
const globalConfig = import_path54.default.join(import_os50.default.homedir(), ".node9", "config.json");
|
|
51970
51607
|
console.log(
|
|
51971
|
-
` Local: ${
|
|
51608
|
+
` Local: ${import_fs57.default.existsSync(projectConfig) ? import_chalk15.default.green("Active (node9.config.json)") : import_chalk15.default.gray("Not present")}`
|
|
51972
51609
|
);
|
|
51973
51610
|
console.log(
|
|
51974
|
-
` Global: ${
|
|
51611
|
+
` Global: ${import_fs57.default.existsSync(globalConfig) ? import_chalk15.default.green("Active (~/.node9/config.json)") : import_chalk15.default.gray("Not present")}`
|
|
51975
51612
|
);
|
|
51976
51613
|
if (mergedConfig.policy.sandboxPaths.length > 0) {
|
|
51977
51614
|
console.log(
|
|
51978
51615
|
` Sandbox: ${import_chalk15.default.green(`${mergedConfig.policy.sandboxPaths.length} safe zones active`)}`
|
|
51979
51616
|
);
|
|
51980
51617
|
}
|
|
51981
|
-
const wiring = getAgentWiring(
|
|
51618
|
+
const wiring = getAgentWiring(import_os50.default.homedir()).filter((a) => a.present);
|
|
51982
51619
|
if (wiring.length > 0) {
|
|
51983
51620
|
console.log("");
|
|
51984
51621
|
console.log(import_chalk15.default.bold(" Agent Wiring:"));
|
|
@@ -52013,9 +51650,9 @@ function registerStatusCommand(program2) {
|
|
|
52013
51650
|
|
|
52014
51651
|
// src/cli/commands/init.ts
|
|
52015
51652
|
var import_chalk16 = __toESM(require("chalk"));
|
|
52016
|
-
var
|
|
52017
|
-
var
|
|
52018
|
-
var
|
|
51653
|
+
var import_fs58 = __toESM(require("fs"));
|
|
51654
|
+
var import_path55 = __toESM(require("path"));
|
|
51655
|
+
var import_os51 = __toESM(require("os"));
|
|
52019
51656
|
var import_https6 = __toESM(require("https"));
|
|
52020
51657
|
init_core();
|
|
52021
51658
|
init_setup();
|
|
@@ -52106,16 +51743,16 @@ function registerInitCommand(program2) {
|
|
|
52106
51743
|
}
|
|
52107
51744
|
console.log("");
|
|
52108
51745
|
}
|
|
52109
|
-
const configPath =
|
|
52110
|
-
const isFirstInstall = !
|
|
52111
|
-
if (
|
|
51746
|
+
const configPath = import_path55.default.join(import_os51.default.homedir(), ".node9", "config.json");
|
|
51747
|
+
const isFirstInstall = !import_fs58.default.existsSync(configPath);
|
|
51748
|
+
if (import_fs58.default.existsSync(configPath) && !options.force) {
|
|
52112
51749
|
try {
|
|
52113
|
-
const existing = JSON.parse(
|
|
51750
|
+
const existing = JSON.parse(import_fs58.default.readFileSync(configPath, "utf-8"));
|
|
52114
51751
|
const settings = existing.settings ?? {};
|
|
52115
51752
|
if (settings.mode !== chosenMode) {
|
|
52116
51753
|
settings.mode = chosenMode;
|
|
52117
51754
|
existing.settings = settings;
|
|
52118
|
-
|
|
51755
|
+
import_fs58.default.writeFileSync(configPath, JSON.stringify(existing, null, 2) + "\n");
|
|
52119
51756
|
console.log(import_chalk16.default.green(`\u2705 Mode updated: ${chosenMode}`));
|
|
52120
51757
|
} else {
|
|
52121
51758
|
console.log(import_chalk16.default.blue(`\u2139\uFE0F Config already exists: ${configPath}`));
|
|
@@ -52128,9 +51765,9 @@ function registerInitCommand(program2) {
|
|
|
52128
51765
|
...DEFAULT_CONFIG,
|
|
52129
51766
|
settings: { ...DEFAULT_CONFIG.settings, mode: chosenMode }
|
|
52130
51767
|
};
|
|
52131
|
-
const dir =
|
|
52132
|
-
if (!
|
|
52133
|
-
|
|
51768
|
+
const dir = import_path55.default.dirname(configPath);
|
|
51769
|
+
if (!import_fs58.default.existsSync(dir)) import_fs58.default.mkdirSync(dir, { recursive: true });
|
|
51770
|
+
import_fs58.default.writeFileSync(configPath, JSON.stringify(configToSave, null, 2) + "\n");
|
|
52134
51771
|
console.log(import_chalk16.default.green(`\u2705 Config created: ${configPath}`));
|
|
52135
51772
|
console.log(import_chalk16.default.gray(` Mode: ${chosenMode}`));
|
|
52136
51773
|
}
|
|
@@ -52230,14 +51867,14 @@ function registerInitCommand(program2) {
|
|
|
52230
51867
|
|
|
52231
51868
|
// src/cli/commands/heal.ts
|
|
52232
51869
|
var import_chalk17 = __toESM(require("chalk"));
|
|
52233
|
-
var
|
|
51870
|
+
var import_fs59 = __toESM(require("fs"));
|
|
52234
51871
|
init_agent_wiring();
|
|
52235
51872
|
init_setup();
|
|
52236
51873
|
init_hook_baseline();
|
|
52237
51874
|
var hasHookSurface = (a) => a.hooks.length > 0;
|
|
52238
51875
|
function backupForHeal(file) {
|
|
52239
51876
|
try {
|
|
52240
|
-
if (file &&
|
|
51877
|
+
if (file && import_fs59.default.existsSync(file)) import_fs59.default.copyFileSync(file, `${file}.node9-heal-bak`);
|
|
52241
51878
|
} catch {
|
|
52242
51879
|
}
|
|
52243
51880
|
}
|
|
@@ -52469,7 +52106,7 @@ function registerUndoCommand(program2) {
|
|
|
52469
52106
|
// src/mcp-gateway/index.ts
|
|
52470
52107
|
var import_readline3 = __toESM(require("readline"));
|
|
52471
52108
|
var import_chalk20 = __toESM(require("chalk"));
|
|
52472
|
-
var
|
|
52109
|
+
var import_child_process9 = require("child_process");
|
|
52473
52110
|
var import_execa3 = require("execa");
|
|
52474
52111
|
init_orchestrator();
|
|
52475
52112
|
init_cloud();
|
|
@@ -52601,7 +52238,7 @@ async function runMcpGateway(upstreamCommand, configName) {
|
|
|
52601
52238
|
const safeEnv = Object.fromEntries(
|
|
52602
52239
|
Object.entries(process.env).filter(([k]) => !UPSTREAM_INJECTOR_VARS.has(k))
|
|
52603
52240
|
);
|
|
52604
|
-
const child = (0,
|
|
52241
|
+
const child = (0, import_child_process9.spawn)(executable, cmdArgs, {
|
|
52605
52242
|
stdio: ["pipe", "pipe", "inherit"],
|
|
52606
52243
|
// control stdin/stdout; inherit stderr
|
|
52607
52244
|
shell: false,
|
|
@@ -52974,19 +52611,19 @@ function registerMcpGatewayCommand(program2) {
|
|
|
52974
52611
|
|
|
52975
52612
|
// src/mcp-server/index.ts
|
|
52976
52613
|
var import_readline4 = __toESM(require("readline"));
|
|
52977
|
-
var
|
|
52978
|
-
var
|
|
52979
|
-
var
|
|
52980
|
-
var
|
|
52614
|
+
var import_fs61 = __toESM(require("fs"));
|
|
52615
|
+
var import_os53 = __toESM(require("os"));
|
|
52616
|
+
var import_path57 = __toESM(require("path"));
|
|
52617
|
+
var import_child_process10 = require("child_process");
|
|
52981
52618
|
init_decision();
|
|
52982
52619
|
init_core();
|
|
52983
52620
|
init_daemon();
|
|
52984
52621
|
init_shields();
|
|
52985
52622
|
|
|
52986
52623
|
// src/auth/egress-config.ts
|
|
52987
|
-
var
|
|
52988
|
-
var
|
|
52989
|
-
var
|
|
52624
|
+
var import_fs60 = __toESM(require("fs"));
|
|
52625
|
+
var import_os52 = __toESM(require("os"));
|
|
52626
|
+
var import_path56 = __toESM(require("path"));
|
|
52990
52627
|
var DEFAULT_EGRESS = {
|
|
52991
52628
|
enabled: false,
|
|
52992
52629
|
mode: "review",
|
|
@@ -52995,12 +52632,12 @@ var DEFAULT_EGRESS = {
|
|
|
52995
52632
|
allowPrivate: true
|
|
52996
52633
|
};
|
|
52997
52634
|
function egressConfigPath() {
|
|
52998
|
-
return
|
|
52635
|
+
return import_path56.default.join(import_os52.default.homedir(), ".node9", "config.json");
|
|
52999
52636
|
}
|
|
53000
52637
|
function readEgressRawConfig() {
|
|
53001
52638
|
let text;
|
|
53002
52639
|
try {
|
|
53003
|
-
text =
|
|
52640
|
+
text = import_fs60.default.readFileSync(egressConfigPath(), "utf8");
|
|
53004
52641
|
} catch (err2) {
|
|
53005
52642
|
if (err2.code === "ENOENT") return {};
|
|
53006
52643
|
throw err2;
|
|
@@ -53015,8 +52652,8 @@ function readEgressRawConfig() {
|
|
|
53015
52652
|
}
|
|
53016
52653
|
function writeEgressRawConfig(config) {
|
|
53017
52654
|
const p = egressConfigPath();
|
|
53018
|
-
|
|
53019
|
-
|
|
52655
|
+
import_fs60.default.mkdirSync(import_path56.default.dirname(p), { recursive: true });
|
|
52656
|
+
import_fs60.default.writeFileSync(p, JSON.stringify(config, null, 2) + "\n", { mode: 384 });
|
|
53020
52657
|
}
|
|
53021
52658
|
function applyEgress(config, change) {
|
|
53022
52659
|
const policy = config.policy = config.policy ?? {};
|
|
@@ -53350,13 +52987,13 @@ function handleStatus() {
|
|
|
53350
52987
|
lines.push(`Active shields: ${activeShields.length > 0 ? activeShields.join(", ") : "none"}`);
|
|
53351
52988
|
lines.push(`Smart rules: ${config.policy.smartRules.length} loaded`);
|
|
53352
52989
|
lines.push(`DLP: ${config.policy.dlp?.enabled !== false ? "enabled" : "disabled"}`);
|
|
53353
|
-
const projectConfig =
|
|
53354
|
-
const globalConfig =
|
|
52990
|
+
const projectConfig = import_path57.default.join(process.cwd(), "node9.config.json");
|
|
52991
|
+
const globalConfig = import_path57.default.join(import_os53.default.homedir(), ".node9", "config.json");
|
|
53355
52992
|
lines.push(
|
|
53356
|
-
`Project config (node9.config.json): ${
|
|
52993
|
+
`Project config (node9.config.json): ${import_fs61.default.existsSync(projectConfig) ? "present" : "not found"}`
|
|
53357
52994
|
);
|
|
53358
52995
|
lines.push(
|
|
53359
|
-
`Global config (~/.node9/config.json): ${
|
|
52996
|
+
`Global config (~/.node9/config.json): ${import_fs61.default.existsSync(globalConfig) ? "present" : "not found"}`
|
|
53360
52997
|
);
|
|
53361
52998
|
return lines.join("\n");
|
|
53362
52999
|
}
|
|
@@ -53461,21 +53098,21 @@ function handleEgressDeny(args) {
|
|
|
53461
53098
|
addEgressHost("deny", host);
|
|
53462
53099
|
return `Denied egress to ${host} (deny always wins over allow).`;
|
|
53463
53100
|
}
|
|
53464
|
-
var GLOBAL_CONFIG_PATH =
|
|
53101
|
+
var GLOBAL_CONFIG_PATH = import_path57.default.join(import_os53.default.homedir(), ".node9", "config.json");
|
|
53465
53102
|
var APPROVER_CHANNELS = ["native", "browser", "cloud", "terminal"];
|
|
53466
53103
|
function readGlobalConfigRaw() {
|
|
53467
53104
|
try {
|
|
53468
|
-
if (
|
|
53469
|
-
return JSON.parse(
|
|
53105
|
+
if (import_fs61.default.existsSync(GLOBAL_CONFIG_PATH)) {
|
|
53106
|
+
return JSON.parse(import_fs61.default.readFileSync(GLOBAL_CONFIG_PATH, "utf-8"));
|
|
53470
53107
|
}
|
|
53471
53108
|
} catch {
|
|
53472
53109
|
}
|
|
53473
53110
|
return {};
|
|
53474
53111
|
}
|
|
53475
53112
|
function writeGlobalConfigRaw(data) {
|
|
53476
|
-
const dir =
|
|
53477
|
-
if (!
|
|
53478
|
-
|
|
53113
|
+
const dir = import_path57.default.dirname(GLOBAL_CONFIG_PATH);
|
|
53114
|
+
if (!import_fs61.default.existsSync(dir)) import_fs61.default.mkdirSync(dir, { recursive: true });
|
|
53115
|
+
import_fs61.default.writeFileSync(GLOBAL_CONFIG_PATH, JSON.stringify(data, null, 2) + "\n");
|
|
53479
53116
|
}
|
|
53480
53117
|
function handleApproverList() {
|
|
53481
53118
|
const config = getConfig();
|
|
@@ -53519,9 +53156,9 @@ function handleApproverSet(args) {
|
|
|
53519
53156
|
function handleAuditGet(args) {
|
|
53520
53157
|
const limit = Math.min(typeof args.limit === "number" ? args.limit : 20, 100);
|
|
53521
53158
|
const filter = typeof args.filter === "string" && args.filter !== "all" ? args.filter : null;
|
|
53522
|
-
const auditPath =
|
|
53523
|
-
if (!
|
|
53524
|
-
const rawLines =
|
|
53159
|
+
const auditPath = import_path57.default.join(import_os53.default.homedir(), ".node9", "audit.log");
|
|
53160
|
+
if (!import_fs61.default.existsSync(auditPath)) return "No audit log found.";
|
|
53161
|
+
const rawLines = import_fs61.default.readFileSync(auditPath, "utf-8").trim().split("\n").filter(Boolean);
|
|
53525
53162
|
const wanted = filter === "block" ? "deny" : filter;
|
|
53526
53163
|
const parsed = [];
|
|
53527
53164
|
for (const line of rawLines) {
|
|
@@ -53607,7 +53244,7 @@ function handleRuleAdd(args) {
|
|
|
53607
53244
|
return `Rule "${name}" added to ~/.node9/config.json \u2014 verdict: ${verdict} when ${field} matches "${pattern}"`;
|
|
53608
53245
|
}
|
|
53609
53246
|
function runCliCommand(subArgs) {
|
|
53610
|
-
const result = (0,
|
|
53247
|
+
const result = (0, import_child_process10.spawnSync)(process.execPath, [process.argv[1], ...subArgs], {
|
|
53611
53248
|
encoding: "utf-8",
|
|
53612
53249
|
timeout: 6e4,
|
|
53613
53250
|
// Disable colors — stdout is piped (not a TTY), chalk auto-detects, but be explicit
|
|
@@ -53823,7 +53460,7 @@ function registerTrustCommand(program2) {
|
|
|
53823
53460
|
// src/cli/commands/mcp-pin.ts
|
|
53824
53461
|
var import_chalk23 = __toESM(require("chalk"));
|
|
53825
53462
|
init_mcp_pin();
|
|
53826
|
-
var
|
|
53463
|
+
var import_fs62 = __toESM(require("fs"));
|
|
53827
53464
|
|
|
53828
53465
|
// src/cli/commands/mcp-gateway-cmd.ts
|
|
53829
53466
|
var import_chalk22 = __toESM(require("chalk"));
|
|
@@ -54031,7 +53668,7 @@ function registerMcpPinCommand(program2) {
|
|
|
54031
53668
|
let repoCorrupt = false;
|
|
54032
53669
|
if (found.source === "repo") {
|
|
54033
53670
|
try {
|
|
54034
|
-
const raw =
|
|
53671
|
+
const raw = import_fs62.default.readFileSync(found.path, "utf-8");
|
|
54035
53672
|
const parsed = JSON.parse(raw);
|
|
54036
53673
|
repoEntries = parsed.servers ?? {};
|
|
54037
53674
|
} catch {
|
|
@@ -54624,8 +54261,8 @@ function registerPostureCommand(program2) {
|
|
|
54624
54261
|
var import_chalk29 = __toESM(require("chalk"));
|
|
54625
54262
|
|
|
54626
54263
|
// src/ci-check/fetch.ts
|
|
54627
|
-
var
|
|
54628
|
-
var
|
|
54264
|
+
var import_fs63 = __toESM(require("fs"));
|
|
54265
|
+
var import_path58 = __toESM(require("path"));
|
|
54629
54266
|
var import_node_child_process = require("child_process");
|
|
54630
54267
|
var import_undici = __toESM(require_undici());
|
|
54631
54268
|
var cachedGhToken;
|
|
@@ -54709,7 +54346,7 @@ function parseRepoUrl(input) {
|
|
|
54709
54346
|
function isLocalPath(input) {
|
|
54710
54347
|
if (input.startsWith(".") || input.startsWith("/") || input.startsWith("~")) return true;
|
|
54711
54348
|
try {
|
|
54712
|
-
return
|
|
54349
|
+
return import_fs63.default.existsSync(input) && import_fs63.default.statSync(input).isDirectory();
|
|
54713
54350
|
} catch {
|
|
54714
54351
|
return false;
|
|
54715
54352
|
}
|
|
@@ -54824,10 +54461,10 @@ function readLocalTree(dir) {
|
|
|
54824
54461
|
const files = [];
|
|
54825
54462
|
const notes = [];
|
|
54826
54463
|
const add = (rel) => {
|
|
54827
|
-
const abs =
|
|
54464
|
+
const abs = import_path58.default.join(root, rel);
|
|
54828
54465
|
try {
|
|
54829
|
-
if (
|
|
54830
|
-
files.push({ path: rel, content:
|
|
54466
|
+
if (import_fs63.default.existsSync(abs) && import_fs63.default.statSync(abs).isFile()) {
|
|
54467
|
+
files.push({ path: rel, content: import_fs63.default.readFileSync(abs, "utf8") });
|
|
54831
54468
|
}
|
|
54832
54469
|
} catch {
|
|
54833
54470
|
}
|
|
@@ -54847,7 +54484,7 @@ function readLocalTree(dir) {
|
|
|
54847
54484
|
dirsVisited++;
|
|
54848
54485
|
let entries;
|
|
54849
54486
|
try {
|
|
54850
|
-
entries =
|
|
54487
|
+
entries = import_fs63.default.readdirSync(import_path58.default.join(root, relDir), { withFileTypes: true });
|
|
54851
54488
|
} catch {
|
|
54852
54489
|
return;
|
|
54853
54490
|
}
|
|
@@ -54868,11 +54505,11 @@ function readLocalTree(dir) {
|
|
|
54868
54505
|
`repo is large \u2014 some agent-surface files may be INCOMPLETE (capped at ${MAX_SURFACE_FILES} files / ${MAX_DIRS} dirs).`
|
|
54869
54506
|
);
|
|
54870
54507
|
for (const rel of matches) collect(rel);
|
|
54871
|
-
const wfDir =
|
|
54508
|
+
const wfDir = import_path58.default.join(root, WORKFLOW_DIR);
|
|
54872
54509
|
try {
|
|
54873
|
-
if (
|
|
54874
|
-
for (const name of
|
|
54875
|
-
if (/\.ya?ml$/.test(name)) add(
|
|
54510
|
+
if (import_fs63.default.existsSync(wfDir)) {
|
|
54511
|
+
for (const name of import_fs63.default.readdirSync(wfDir)) {
|
|
54512
|
+
if (/\.ya?ml$/.test(name)) add(import_path58.default.join(WORKFLOW_DIR, name));
|
|
54876
54513
|
}
|
|
54877
54514
|
}
|
|
54878
54515
|
} catch {
|
|
@@ -55177,7 +54814,7 @@ function severityFromScore(score) {
|
|
|
55177
54814
|
if (score >= 1) return "advisory";
|
|
55178
54815
|
return null;
|
|
55179
54816
|
}
|
|
55180
|
-
function analyzeWorkflow(
|
|
54817
|
+
function analyzeWorkflow(path71, content) {
|
|
55181
54818
|
let raw;
|
|
55182
54819
|
try {
|
|
55183
54820
|
raw = (0, import_yaml.parse)(content) ?? {};
|
|
@@ -55303,7 +54940,7 @@ function analyzeWorkflow(path72, content) {
|
|
|
55303
54940
|
dimension: "workflows",
|
|
55304
54941
|
severity,
|
|
55305
54942
|
title,
|
|
55306
|
-
file:
|
|
54943
|
+
file: path71,
|
|
55307
54944
|
signals,
|
|
55308
54945
|
mitigations: mitigations.length ? mitigations : void 0,
|
|
55309
54946
|
fix: head === "root" && privileged ? "Do not check out the untrusted PR head into the workspace root under a privileged trigger (pull_request_target/workflow_run) \u2014 check out the base ref, or isolate the head in a subdir (--add-dir). Add an actor gate and scope the agent tools." : head === "root" ? "This runs under `pull_request` (fork PRs get a read-only token), so the head checkout is low-risk today \u2014 keep it on `pull_request` (not `pull_request_target`) and keep the actor gate + scoped tools." : "Add/verify an actor gate, scope the agent tools to read-only, and env-deny secrets. See Anthropic\u2019s claude-code-action security doc."
|
|
@@ -55379,7 +55016,7 @@ function evalAgentJob(job, wf, raw, untrustedTrigger, reusable) {
|
|
|
55379
55016
|
if (reusable && !loadedGun && SEVERITY_RANK2[severity] > SEVERITY_RANK2.medium) severity = "medium";
|
|
55380
55017
|
return { severity, secrets, injectable, canReadEnv };
|
|
55381
55018
|
}
|
|
55382
|
-
function analyzeWorkflowSecrets(
|
|
55019
|
+
function analyzeWorkflowSecrets(path71, content) {
|
|
55383
55020
|
let raw;
|
|
55384
55021
|
try {
|
|
55385
55022
|
raw = (0, import_yaml.parse)(content) ?? {};
|
|
@@ -55399,7 +55036,7 @@ function analyzeWorkflowSecrets(path72, content) {
|
|
|
55399
55036
|
dimension: "data",
|
|
55400
55037
|
severity: worst.severity,
|
|
55401
55038
|
title: worst.severity === "advisory" ? "Secrets reachable by the agent \u2014 hardening" : "Exfiltratable secrets reachable by an injectable agent",
|
|
55402
|
-
file:
|
|
55039
|
+
file: path71,
|
|
55403
55040
|
signals: [
|
|
55404
55041
|
`agent can reach: ${worst.secrets.map((s) => s.name).join(", ")}`,
|
|
55405
55042
|
worst.injectable ? "the agent is externally triggerable (untrusted trigger, no gate)" : "gated / not externally triggerable \u2014 latent risk only",
|
|
@@ -55426,7 +55063,7 @@ function hookCommands(hooks) {
|
|
|
55426
55063
|
}
|
|
55427
55064
|
return out;
|
|
55428
55065
|
}
|
|
55429
|
-
function analyzeAgentConfig(
|
|
55066
|
+
function analyzeAgentConfig(path71, content) {
|
|
55430
55067
|
let cfg;
|
|
55431
55068
|
try {
|
|
55432
55069
|
cfg = JSON.parse(content);
|
|
@@ -55445,7 +55082,7 @@ function analyzeAgentConfig(path72, content) {
|
|
|
55445
55082
|
dimension: "toolRules",
|
|
55446
55083
|
severity: high ? "high" : "medium",
|
|
55447
55084
|
title: high ? "Agent hook runs UNPINNED/remote third-party code on every action" : "Agent hook runs third-party code in the agent hot path",
|
|
55448
|
-
file:
|
|
55085
|
+
file: path71,
|
|
55449
55086
|
signals: [
|
|
55450
55087
|
`hook command: \`${cmd.slice(0, 120)}\``,
|
|
55451
55088
|
remoteExec ? "fetch-and-run (curl|wget / pipe-to-shell) \u2014 unpinnable remote code execution on every contributor" : unpinned ? "unpinned \u2014 a compromised/yanked package = code execution on every contributor" : "pinned, but still a standing supply-chain dependency in the agent hot path"
|
|
@@ -55465,7 +55102,7 @@ function analyzeAgentConfig(path72, content) {
|
|
|
55465
55102
|
dimension: "toolRules",
|
|
55466
55103
|
severity: hasBackstop ? "medium" : "high",
|
|
55467
55104
|
title: hasBackstop ? "Committed agent config pre-authorizes broad tools" : "Committed agent config pre-authorizes broad tools with no deny backstop",
|
|
55468
|
-
file:
|
|
55105
|
+
file: path71,
|
|
55469
55106
|
signals: [
|
|
55470
55107
|
`broad allow(s): ${broad.slice(0, 5).join(", ")}`,
|
|
55471
55108
|
hasBackstop ? "a `deny` list backstops the broad allow" : "no `deny` entry covers Bash/Write/Edit \u2014 every contributor is pre-authorized for catastrophic tools"
|
|
@@ -55478,16 +55115,16 @@ function analyzeAgentConfig(path72, content) {
|
|
|
55478
55115
|
|
|
55479
55116
|
// src/ci-check/mcp.ts
|
|
55480
55117
|
init_dist();
|
|
55481
|
-
function analyzeMcp(
|
|
55118
|
+
function analyzeMcp(path71, content) {
|
|
55482
55119
|
let cfg;
|
|
55483
55120
|
try {
|
|
55484
55121
|
cfg = JSON.parse(content);
|
|
55485
55122
|
} catch {
|
|
55486
55123
|
return [];
|
|
55487
55124
|
}
|
|
55488
|
-
return analyzeMcpServers(cfg.mcpServers ?? {},
|
|
55125
|
+
return analyzeMcpServers(cfg.mcpServers ?? {}, path71);
|
|
55489
55126
|
}
|
|
55490
|
-
function analyzeMcpServers(servers,
|
|
55127
|
+
function analyzeMcpServers(servers, path71) {
|
|
55491
55128
|
const findings = [];
|
|
55492
55129
|
for (const [name, srv] of Object.entries(servers ?? {})) {
|
|
55493
55130
|
if (!srv || srv.disabled) continue;
|
|
@@ -55498,7 +55135,7 @@ function analyzeMcpServers(servers, path72) {
|
|
|
55498
55135
|
dimension: "mcp",
|
|
55499
55136
|
severity: "medium",
|
|
55500
55137
|
title: `MCP server "${name}" runs an unpinned executable`,
|
|
55501
|
-
file:
|
|
55138
|
+
file: path71,
|
|
55502
55139
|
signals: [`\`${argv.slice(0, 120)}\` \u2014 unversioned/@latest npx`],
|
|
55503
55140
|
fix: "Pin the MCP server package to an exact version so a PR (or a registry compromise) can\u2019t swap the toolchain."
|
|
55504
55141
|
});
|
|
@@ -55512,7 +55149,7 @@ function analyzeMcpServers(servers, path72) {
|
|
|
55512
55149
|
dimension: "mcp",
|
|
55513
55150
|
severity: "high",
|
|
55514
55151
|
title: `MCP server "${name}" has an inline credential`,
|
|
55515
|
-
file:
|
|
55152
|
+
file: path71,
|
|
55516
55153
|
signals: [
|
|
55517
55154
|
`env.${k} matches ${hit.patternName} \u2014 agent-reachable secret committed to the repo`
|
|
55518
55155
|
],
|
|
@@ -55526,7 +55163,7 @@ function analyzeMcpServers(servers, path72) {
|
|
|
55526
55163
|
|
|
55527
55164
|
// src/ci-check/codex.ts
|
|
55528
55165
|
var import_smol_toml5 = require("smol-toml");
|
|
55529
|
-
function analyzeCodexConfig(
|
|
55166
|
+
function analyzeCodexConfig(path71, content) {
|
|
55530
55167
|
let cfg;
|
|
55531
55168
|
try {
|
|
55532
55169
|
cfg = (0, import_smol_toml5.parse)(content);
|
|
@@ -55534,7 +55171,7 @@ function analyzeCodexConfig(path72, content) {
|
|
|
55534
55171
|
return [];
|
|
55535
55172
|
}
|
|
55536
55173
|
const findings = [];
|
|
55537
|
-
findings.push(...analyzeMcpServers(cfg.mcp_servers ?? {},
|
|
55174
|
+
findings.push(...analyzeMcpServers(cfg.mcp_servers ?? {}, path71));
|
|
55538
55175
|
const sandbox = typeof cfg.sandbox_mode === "string" ? cfg.sandbox_mode : "";
|
|
55539
55176
|
const approval = typeof cfg.approval_policy === "string" ? cfg.approval_policy : "";
|
|
55540
55177
|
const fullAccess = /danger-full-access/i.test(sandbox);
|
|
@@ -55549,7 +55186,7 @@ function analyzeCodexConfig(path72, content) {
|
|
|
55549
55186
|
dimension: "toolRules",
|
|
55550
55187
|
severity: fullAccess ? "high" : "medium",
|
|
55551
55188
|
title: fullAccess ? "Codex config grants a full-access sandbox" : "Codex config never requires approval",
|
|
55552
|
-
file:
|
|
55189
|
+
file: path71,
|
|
55553
55190
|
signals,
|
|
55554
55191
|
fix: 'Commit a least-privilege Codex config: prefer `sandbox_mode = "read-only"` (or `"workspace-write"`) and `approval_policy = "on-request"`/`"on-failure"`. A repo-committed config applies to every contributor who runs Codex here.'
|
|
55555
55192
|
});
|
|
@@ -55605,10 +55242,10 @@ function decodeSuspiciousBase64(text) {
|
|
|
55605
55242
|
}
|
|
55606
55243
|
return out;
|
|
55607
55244
|
}
|
|
55608
|
-
function mk(severity, title, signals, fix,
|
|
55609
|
-
return { check: "CI-6", dimension: "instructions", severity, title, file:
|
|
55245
|
+
function mk(severity, title, signals, fix, path71) {
|
|
55246
|
+
return { check: "CI-6", dimension: "instructions", severity, title, file: path71, signals, fix };
|
|
55610
55247
|
}
|
|
55611
|
-
function analyzeInstructionFile(
|
|
55248
|
+
function analyzeInstructionFile(path71, content) {
|
|
55612
55249
|
const findings = [];
|
|
55613
55250
|
const decoded = decodeSuspiciousBase64(content);
|
|
55614
55251
|
if (TAG_CHARS.test(content))
|
|
@@ -55620,7 +55257,7 @@ function analyzeInstructionFile(path72, content) {
|
|
|
55620
55257
|
"contains Unicode tag characters (U+E0000\u2013E007F) \u2014 an invisible instruction-smuggling channel with no legitimate use in text"
|
|
55621
55258
|
],
|
|
55622
55259
|
"Remove the tag characters. Instruction files must be plain, reviewable text.",
|
|
55623
|
-
|
|
55260
|
+
path71
|
|
55624
55261
|
)
|
|
55625
55262
|
);
|
|
55626
55263
|
if (BIDI_OVERRIDE.test(content))
|
|
@@ -55632,7 +55269,7 @@ function analyzeInstructionFile(path72, content) {
|
|
|
55632
55269
|
"contains a bidi override (U+202D/U+202E) \u2014 a Trojan-Source technique that visually reorders text so a human reads something different from what the agent parses"
|
|
55633
55270
|
],
|
|
55634
55271
|
"Remove the bidi override characters.",
|
|
55635
|
-
|
|
55272
|
+
path71
|
|
55636
55273
|
)
|
|
55637
55274
|
);
|
|
55638
55275
|
else if (BIDI_EMBED_ISOLATE.test(content))
|
|
@@ -55644,7 +55281,7 @@ function analyzeInstructionFile(path72, content) {
|
|
|
55644
55281
|
"contains bidi embed/isolate characters (U+202A\u2013202C / U+2066\u20132069) \u2014 legitimate in right-to-left text, but confirm they are not being used to hide or reorder instructions"
|
|
55645
55282
|
],
|
|
55646
55283
|
"Confirm the bidi marks are legitimate RTL formatting; remove otherwise.",
|
|
55647
|
-
|
|
55284
|
+
path71
|
|
55648
55285
|
)
|
|
55649
55286
|
);
|
|
55650
55287
|
const zw = suspiciousZeroWidth(content);
|
|
@@ -55658,7 +55295,7 @@ function analyzeInstructionFile(path72, content) {
|
|
|
55658
55295
|
revealed ? "a zero-width character conceals a prompt-override directive that only appears once the hidden characters are stripped" : "a zero-width character splits a visible Latin word \u2014 a concealment technique (hides text from human review while the agent reads it as contiguous)"
|
|
55659
55296
|
],
|
|
55660
55297
|
"Remove the zero-width characters. Instruction files must be plain, reviewable text.",
|
|
55661
|
-
|
|
55298
|
+
path71
|
|
55662
55299
|
)
|
|
55663
55300
|
);
|
|
55664
55301
|
}
|
|
@@ -55674,7 +55311,7 @@ function analyzeInstructionFile(path72, content) {
|
|
|
55674
55311
|
`contains a prompt-override / role-impersonation directive (\`${m[0].slice(0, 60).trim()}\`)${ovEnc ? " \u2014 concealed in a base64 blob" : ""}`
|
|
55675
55312
|
],
|
|
55676
55313
|
"Remove the override text. An instruction file should not tell the agent to ignore its own rules.",
|
|
55677
|
-
|
|
55314
|
+
path71
|
|
55678
55315
|
)
|
|
55679
55316
|
);
|
|
55680
55317
|
}
|
|
@@ -55686,7 +55323,7 @@ function analyzeInstructionFile(path72, content) {
|
|
|
55686
55323
|
"Instruction directs the agent to fetch and run remote code",
|
|
55687
55324
|
[`\`${fo[0].slice(0, 70).trim()}\` \u2014 fetch-and-obey, outside an install/setup section`],
|
|
55688
55325
|
"Do not instruct the agent to pipe remote content into a shell; pin and vendor scripts instead.",
|
|
55689
|
-
|
|
55326
|
+
path71
|
|
55690
55327
|
)
|
|
55691
55328
|
);
|
|
55692
55329
|
}
|
|
@@ -55698,7 +55335,7 @@ function analyzeInstructionFile(path72, content) {
|
|
|
55698
55335
|
"Instruction points the agent at credential material",
|
|
55699
55336
|
[`references \`${sp[0].slice(0, 50).trim()}\` \u2014 directs the agent toward secrets`],
|
|
55700
55337
|
"Do not reference credential files or paths in agent instructions.",
|
|
55701
|
-
|
|
55338
|
+
path71
|
|
55702
55339
|
)
|
|
55703
55340
|
);
|
|
55704
55341
|
}
|
|
@@ -55710,7 +55347,7 @@ function analyzeInstructionFile(path72, content) {
|
|
|
55710
55347
|
"Instruction directs the agent to send data to an external endpoint",
|
|
55711
55348
|
[`\`${ex[0].slice(0, 70).trim()}\` \u2014 possible exfiltration directive`],
|
|
55712
55349
|
"Remove external post/upload directives from agent instructions.",
|
|
55713
|
-
|
|
55350
|
+
path71
|
|
55714
55351
|
)
|
|
55715
55352
|
);
|
|
55716
55353
|
}
|
|
@@ -56106,14 +55743,14 @@ function registerJailCommand(program2) {
|
|
|
56106
55743
|
|
|
56107
55744
|
// src/cli/commands/sandbox.ts
|
|
56108
55745
|
var import_chalk32 = __toESM(require("chalk"));
|
|
56109
|
-
var
|
|
56110
|
-
var
|
|
56111
|
-
var
|
|
55746
|
+
var import_fs66 = __toESM(require("fs"));
|
|
55747
|
+
var import_path61 = __toESM(require("path"));
|
|
55748
|
+
var import_child_process12 = require("child_process");
|
|
56112
55749
|
init_config();
|
|
56113
55750
|
|
|
56114
55751
|
// src/sandbox/config.ts
|
|
56115
|
-
var
|
|
56116
|
-
var
|
|
55752
|
+
var import_fs64 = __toESM(require("fs"));
|
|
55753
|
+
var import_path59 = __toESM(require("path"));
|
|
56117
55754
|
var import_yaml2 = require("yaml");
|
|
56118
55755
|
var SANDBOX_CONFIG_FILE = "node9.sandbox.yaml";
|
|
56119
55756
|
var FORBIDDEN_ENV = /* @__PURE__ */ new Set(["NODE9_API_KEY", "NODE9_API_URL"]);
|
|
@@ -56186,16 +55823,16 @@ function scaffoldSandboxYaml(agent) {
|
|
|
56186
55823
|
return header + (0, import_yaml2.stringify)(defaultSandboxConfig(agent));
|
|
56187
55824
|
}
|
|
56188
55825
|
function sandboxConfigPath(cwd = process.cwd()) {
|
|
56189
|
-
return
|
|
55826
|
+
return import_path59.default.join(cwd, SANDBOX_CONFIG_FILE);
|
|
56190
55827
|
}
|
|
56191
55828
|
function loadSandboxConfig(cwd = process.cwd(), fallbackAgent = "claude") {
|
|
56192
55829
|
const p = sandboxConfigPath(cwd);
|
|
56193
|
-
if (!
|
|
55830
|
+
if (!import_fs64.default.existsSync(p)) {
|
|
56194
55831
|
throw new Error(`sandbox: ${SANDBOX_CONFIG_FILE} not found \u2014 run \`node9 sandbox new\` first.`);
|
|
56195
55832
|
}
|
|
56196
55833
|
let raw;
|
|
56197
55834
|
try {
|
|
56198
|
-
raw = (0, import_yaml2.parse)(
|
|
55835
|
+
raw = (0, import_yaml2.parse)(import_fs64.default.readFileSync(p, "utf-8"));
|
|
56199
55836
|
} catch (err2) {
|
|
56200
55837
|
throw new Error(
|
|
56201
55838
|
`sandbox: ${SANDBOX_CONFIG_FILE} is not valid YAML \u2014 ${err2.message}`
|
|
@@ -56253,17 +55890,17 @@ function compileAllowlist(input) {
|
|
|
56253
55890
|
init_templates();
|
|
56254
55891
|
|
|
56255
55892
|
// src/sandbox/runtime.ts
|
|
56256
|
-
var
|
|
56257
|
-
var
|
|
56258
|
-
var
|
|
56259
|
-
var
|
|
56260
|
-
var
|
|
55893
|
+
var import_fs65 = __toESM(require("fs"));
|
|
55894
|
+
var import_os54 = __toESM(require("os"));
|
|
55895
|
+
var import_path60 = __toESM(require("path"));
|
|
55896
|
+
var import_crypto13 = __toESM(require("crypto"));
|
|
55897
|
+
var import_child_process11 = require("child_process");
|
|
56261
55898
|
init_templates();
|
|
56262
55899
|
function sandboxDataDir(cwd = process.cwd()) {
|
|
56263
|
-
return
|
|
55900
|
+
return import_path60.default.join(cwd, ".node9", "sandbox", "data");
|
|
56264
55901
|
}
|
|
56265
55902
|
function detectEngine(engine) {
|
|
56266
|
-
const r = (0,
|
|
55903
|
+
const r = (0, import_child_process11.spawnSync)(engine, ["--version"], { encoding: "utf-8" });
|
|
56267
55904
|
if (r.status === 0 && typeof r.stdout === "string") {
|
|
56268
55905
|
return { available: true, version: r.stdout.trim() };
|
|
56269
55906
|
}
|
|
@@ -56271,7 +55908,7 @@ function detectEngine(engine) {
|
|
|
56271
55908
|
}
|
|
56272
55909
|
function agentCredentialsMount(agent) {
|
|
56273
55910
|
const rel = agent === "codex" ? ".codex/auth.json" : ".claude/.credentials.json";
|
|
56274
|
-
return { hostPath:
|
|
55911
|
+
return { hostPath: import_path60.default.join(import_os54.default.homedir(), rel), target: `/home/${RUN_AS_USER}/${rel}` };
|
|
56275
55912
|
}
|
|
56276
55913
|
function buildRunArgs(opts) {
|
|
56277
55914
|
const { config, workspaceHostPath, dataHostPath, allowlistHostPath, agentArgs } = opts;
|
|
@@ -56281,7 +55918,7 @@ function buildRunArgs(opts) {
|
|
|
56281
55918
|
args.push("-v", `${allowlistHostPath}:${ALLOWED_DOMAINS_PATH}:ro`);
|
|
56282
55919
|
if (config.node9.mountAgentCredentials) {
|
|
56283
55920
|
const creds = agentCredentialsMount(config.agent);
|
|
56284
|
-
if (
|
|
55921
|
+
if (import_fs65.default.existsSync(creds.hostPath)) {
|
|
56285
55922
|
args.push("-v", `${creds.hostPath}:${creds.target}`);
|
|
56286
55923
|
}
|
|
56287
55924
|
}
|
|
@@ -56296,33 +55933,33 @@ function buildRunArgs(opts) {
|
|
|
56296
55933
|
return args;
|
|
56297
55934
|
}
|
|
56298
55935
|
function imageContentHash(dockerfile, entrypoint) {
|
|
56299
|
-
return
|
|
55936
|
+
return import_crypto13.default.createHash("sha256").update(dockerfile).update("\0").update(entrypoint).digest("hex").slice(0, 16);
|
|
56300
55937
|
}
|
|
56301
55938
|
function sandboxBuildDir(cwd = process.cwd()) {
|
|
56302
|
-
return
|
|
55939
|
+
return import_path60.default.join(cwd, ".node9", "sandbox", "build");
|
|
56303
55940
|
}
|
|
56304
55941
|
function writeBuildContext(cwd, dockerfile, entrypoint) {
|
|
56305
55942
|
const dir = sandboxBuildDir(cwd);
|
|
56306
|
-
|
|
56307
|
-
|
|
56308
|
-
|
|
55943
|
+
import_fs65.default.mkdirSync(dir, { recursive: true });
|
|
55944
|
+
import_fs65.default.writeFileSync(import_path60.default.join(dir, "Dockerfile"), dockerfile);
|
|
55945
|
+
import_fs65.default.writeFileSync(import_path60.default.join(dir, "entrypoint.sh"), entrypoint);
|
|
56309
55946
|
return dir;
|
|
56310
55947
|
}
|
|
56311
55948
|
function writeAllowlist(cwd, hosts) {
|
|
56312
|
-
const dir =
|
|
56313
|
-
|
|
56314
|
-
const p =
|
|
56315
|
-
|
|
55949
|
+
const dir = import_path60.default.join(cwd, ".node9", "sandbox");
|
|
55950
|
+
import_fs65.default.mkdirSync(dir, { recursive: true });
|
|
55951
|
+
const p = import_path60.default.join(dir, "allowed-domains.txt");
|
|
55952
|
+
import_fs65.default.writeFileSync(p, hosts.join("\n") + "\n");
|
|
56316
55953
|
return p;
|
|
56317
55954
|
}
|
|
56318
55955
|
function resolveHomePath(p) {
|
|
56319
|
-
return p.startsWith("~") ?
|
|
55956
|
+
return p.startsWith("~") ? import_path60.default.join(import_os54.default.homedir(), p.slice(1)) : import_path60.default.resolve(p);
|
|
56320
55957
|
}
|
|
56321
55958
|
|
|
56322
55959
|
// src/cli/commands/sandbox.ts
|
|
56323
55960
|
function seedDataDirConfig(dataDir, sandbox) {
|
|
56324
|
-
|
|
56325
|
-
const configPath =
|
|
55961
|
+
import_fs66.default.mkdirSync(dataDir, { recursive: true });
|
|
55962
|
+
const configPath = import_path61.default.join(dataDir, "config.json");
|
|
56326
55963
|
const seed = {
|
|
56327
55964
|
settings: {
|
|
56328
55965
|
approvers: {
|
|
@@ -56333,7 +55970,7 @@ function seedDataDirConfig(dataDir, sandbox) {
|
|
|
56333
55970
|
}
|
|
56334
55971
|
}
|
|
56335
55972
|
};
|
|
56336
|
-
|
|
55973
|
+
import_fs66.default.writeFileSync(configPath, JSON.stringify(seed, null, 2), { mode: 384 });
|
|
56337
55974
|
}
|
|
56338
55975
|
function registerSandboxCommand(program2, version2) {
|
|
56339
55976
|
const node9Version2 = pinnedNode9Version(version2);
|
|
@@ -56341,13 +55978,13 @@ function registerSandboxCommand(program2, version2) {
|
|
|
56341
55978
|
cmd.command("new").description(`Scaffold ${SANDBOX_CONFIG_FILE} in this project`).option("--agent <agent>", "claude (default) or codex", "claude").action((opts) => {
|
|
56342
55979
|
const agent = opts.agent === "codex" ? "codex" : "claude";
|
|
56343
55980
|
const p = sandboxConfigPath();
|
|
56344
|
-
if (
|
|
55981
|
+
if (import_fs66.default.existsSync(p)) {
|
|
56345
55982
|
console.log(
|
|
56346
55983
|
import_chalk32.default.yellow(` ${SANDBOX_CONFIG_FILE} already exists \u2014 leaving it untouched.`)
|
|
56347
55984
|
);
|
|
56348
55985
|
return;
|
|
56349
55986
|
}
|
|
56350
|
-
|
|
55987
|
+
import_fs66.default.writeFileSync(p, scaffoldSandboxYaml(agent));
|
|
56351
55988
|
console.log(
|
|
56352
55989
|
import_chalk32.default.green(` \u2713 wrote ${SANDBOX_CONFIG_FILE}`) + import_chalk32.default.dim(` (agent: ${agent})`)
|
|
56353
55990
|
);
|
|
@@ -56387,20 +56024,20 @@ function registerSandboxCommand(program2, version2) {
|
|
|
56387
56024
|
const buildDir = writeBuildContext(cwd, dockerfile, entrypoint);
|
|
56388
56025
|
const hash = imageContentHash(dockerfile, entrypoint);
|
|
56389
56026
|
const image = sandbox.runtime.image;
|
|
56390
|
-
const hashFile =
|
|
56391
|
-
const lastHash =
|
|
56392
|
-
const imageExists = (0,
|
|
56027
|
+
const hashFile = import_path61.default.join(sandboxBuildDir(cwd), ".image-hash");
|
|
56028
|
+
const lastHash = import_fs66.default.existsSync(hashFile) ? import_fs66.default.readFileSync(hashFile, "utf-8").trim() : "";
|
|
56029
|
+
const imageExists = (0, import_child_process12.spawnSync)(sandbox.runtime.engine, ["image", "inspect", image], { stdio: "ignore" }).status === 0;
|
|
56393
56030
|
const needBuild = sandbox.runtime.rebuild === "always" || !imageExists || sandbox.runtime.rebuild !== "never" && lastHash !== hash;
|
|
56394
56031
|
if (needBuild) {
|
|
56395
56032
|
console.log(import_chalk32.default.dim(` building ${image} \u2026`));
|
|
56396
|
-
const b = (0,
|
|
56033
|
+
const b = (0, import_child_process12.spawnSync)(sandbox.runtime.engine, ["build", "-t", image, buildDir], {
|
|
56397
56034
|
stdio: "inherit"
|
|
56398
56035
|
});
|
|
56399
56036
|
if (b.status !== 0) {
|
|
56400
56037
|
console.error(import_chalk32.default.red(" build failed."));
|
|
56401
56038
|
process.exit(b.status ?? 1);
|
|
56402
56039
|
}
|
|
56403
|
-
|
|
56040
|
+
import_fs66.default.writeFileSync(hashFile, hash);
|
|
56404
56041
|
}
|
|
56405
56042
|
const dataDir = sandboxDataDir(cwd);
|
|
56406
56043
|
seedDataDirConfig(dataDir, sandbox);
|
|
@@ -56414,7 +56051,7 @@ function registerSandboxCommand(program2, version2) {
|
|
|
56414
56051
|
});
|
|
56415
56052
|
if (sandbox.node9.mountAgentCredentials) {
|
|
56416
56053
|
const creds = agentCredentialsMount(sandbox.agent);
|
|
56417
|
-
if (
|
|
56054
|
+
if (import_fs66.default.existsSync(creds.hostPath)) {
|
|
56418
56055
|
console.log(import_chalk32.default.dim(` mounting ${creds.hostPath} (agent credentials, rw)`));
|
|
56419
56056
|
} else {
|
|
56420
56057
|
console.log(
|
|
@@ -56426,24 +56063,24 @@ function registerSandboxCommand(program2, version2) {
|
|
|
56426
56063
|
import_chalk32.default.green(` \u{1F6E1}\uFE0F ${sandbox.agent} jailed \u2014 ${compiled.allow.length} hosts allowed
|
|
56427
56064
|
`)
|
|
56428
56065
|
);
|
|
56429
|
-
const r = (0,
|
|
56066
|
+
const r = (0, import_child_process12.spawnSync)(sandbox.runtime.engine, runArgs, { stdio: "inherit" });
|
|
56430
56067
|
process.exit(r.status ?? 0);
|
|
56431
56068
|
});
|
|
56432
56069
|
cmd.command("tail").description("Stream the sandbox's audit log (host-side)").action(() => {
|
|
56433
|
-
const auditPath =
|
|
56434
|
-
if (!
|
|
56070
|
+
const auditPath = import_path61.default.join(sandboxDataDir(), "audit.log");
|
|
56071
|
+
if (!import_fs66.default.existsSync(auditPath)) {
|
|
56435
56072
|
console.log(import_chalk32.default.dim(" no sandbox audit yet."));
|
|
56436
56073
|
return;
|
|
56437
56074
|
}
|
|
56438
|
-
(0,
|
|
56075
|
+
(0, import_child_process12.spawnSync)("tail", ["-f", auditPath], { stdio: "inherit" });
|
|
56439
56076
|
});
|
|
56440
56077
|
cmd.command("logs").description("Dump the sandbox's audit log").action(() => {
|
|
56441
|
-
const auditPath =
|
|
56442
|
-
if (!
|
|
56078
|
+
const auditPath = import_path61.default.join(sandboxDataDir(), "audit.log");
|
|
56079
|
+
if (!import_fs66.default.existsSync(auditPath)) {
|
|
56443
56080
|
console.log(import_chalk32.default.dim(" no sandbox audit yet."));
|
|
56444
56081
|
return;
|
|
56445
56082
|
}
|
|
56446
|
-
process.stdout.write(
|
|
56083
|
+
process.stdout.write(import_fs66.default.readFileSync(auditPath, "utf-8"));
|
|
56447
56084
|
});
|
|
56448
56085
|
cmd.command("clean").description("Remove the sandbox image, build context, and data").action(() => {
|
|
56449
56086
|
const cwd = process.cwd();
|
|
@@ -56453,21 +56090,21 @@ function registerSandboxCommand(program2, version2) {
|
|
|
56453
56090
|
} catch {
|
|
56454
56091
|
}
|
|
56455
56092
|
if (sandbox) {
|
|
56456
|
-
(0,
|
|
56093
|
+
(0, import_child_process12.spawnSync)(sandbox.runtime.engine, ["image", "rm", "-f", sandbox.runtime.image], {
|
|
56457
56094
|
stdio: "ignore"
|
|
56458
56095
|
});
|
|
56459
56096
|
}
|
|
56460
|
-
|
|
56097
|
+
import_fs66.default.rmSync(import_path61.default.join(cwd, ".node9", "sandbox"), { recursive: true, force: true });
|
|
56461
56098
|
console.log(import_chalk32.default.green(" \u2713 sandbox image + build + data removed."));
|
|
56462
56099
|
});
|
|
56463
56100
|
}
|
|
56464
56101
|
|
|
56465
56102
|
// src/cli/commands/sessions.ts
|
|
56466
56103
|
var import_chalk33 = __toESM(require("chalk"));
|
|
56467
|
-
var
|
|
56468
|
-
var
|
|
56104
|
+
var import_fs67 = __toESM(require("fs"));
|
|
56105
|
+
var import_path62 = __toESM(require("path"));
|
|
56469
56106
|
init_decision();
|
|
56470
|
-
var
|
|
56107
|
+
var import_os55 = __toESM(require("os"));
|
|
56471
56108
|
init_scan_summary();
|
|
56472
56109
|
init_litellm();
|
|
56473
56110
|
init_cost_gemini();
|
|
@@ -56488,10 +56125,10 @@ function encodeProjectPath(projectPath) {
|
|
|
56488
56125
|
}
|
|
56489
56126
|
function sessionJsonlPath(projectPath, sessionId) {
|
|
56490
56127
|
const encoded = encodeProjectPath(projectPath);
|
|
56491
|
-
return
|
|
56128
|
+
return import_path62.default.join(import_os55.default.homedir(), ".claude", "projects", encoded, `${sessionId}.jsonl`);
|
|
56492
56129
|
}
|
|
56493
56130
|
function projectLabel(projectPath) {
|
|
56494
|
-
return projectPath.replace(
|
|
56131
|
+
return projectPath.replace(import_os55.default.homedir(), "~");
|
|
56495
56132
|
}
|
|
56496
56133
|
function parseHistoryLines(lines) {
|
|
56497
56134
|
const entries = [];
|
|
@@ -56560,10 +56197,10 @@ function parseSessionLines(lines) {
|
|
|
56560
56197
|
return { toolCalls, costUSD, hasSnapshot, modifiedFiles };
|
|
56561
56198
|
}
|
|
56562
56199
|
function loadAuditEntries(auditPath) {
|
|
56563
|
-
const aPath = auditPath ??
|
|
56200
|
+
const aPath = auditPath ?? import_path62.default.join(import_os55.default.homedir(), ".node9", "audit.log");
|
|
56564
56201
|
let raw;
|
|
56565
56202
|
try {
|
|
56566
|
-
raw =
|
|
56203
|
+
raw = import_fs67.default.readFileSync(aPath, "utf-8");
|
|
56567
56204
|
} catch {
|
|
56568
56205
|
return [];
|
|
56569
56206
|
}
|
|
@@ -56599,8 +56236,8 @@ function auditEntriesInWindow(entries, windowStart, windowEnd) {
|
|
|
56599
56236
|
return result;
|
|
56600
56237
|
}
|
|
56601
56238
|
function buildGeminiSessions(days, allAuditEntries) {
|
|
56602
|
-
const tmpDir =
|
|
56603
|
-
if (!
|
|
56239
|
+
const tmpDir = import_path62.default.join(import_os55.default.homedir(), ".gemini", "tmp");
|
|
56240
|
+
if (!import_fs67.default.existsSync(tmpDir)) return [];
|
|
56604
56241
|
const cutoff = days !== null ? (() => {
|
|
56605
56242
|
const d = /* @__PURE__ */ new Date();
|
|
56606
56243
|
d.setDate(d.getDate() - days);
|
|
@@ -56609,35 +56246,35 @@ function buildGeminiSessions(days, allAuditEntries) {
|
|
|
56609
56246
|
})() : null;
|
|
56610
56247
|
let slugDirs;
|
|
56611
56248
|
try {
|
|
56612
|
-
slugDirs =
|
|
56249
|
+
slugDirs = import_fs67.default.readdirSync(tmpDir);
|
|
56613
56250
|
} catch {
|
|
56614
56251
|
return [];
|
|
56615
56252
|
}
|
|
56616
56253
|
const summaries = [];
|
|
56617
56254
|
for (const slug2 of slugDirs) {
|
|
56618
|
-
const slugPath =
|
|
56255
|
+
const slugPath = import_path62.default.join(tmpDir, slug2);
|
|
56619
56256
|
try {
|
|
56620
|
-
if (!
|
|
56257
|
+
if (!import_fs67.default.statSync(slugPath).isDirectory()) continue;
|
|
56621
56258
|
} catch {
|
|
56622
56259
|
continue;
|
|
56623
56260
|
}
|
|
56624
|
-
let projectRoot =
|
|
56261
|
+
let projectRoot = import_path62.default.join(import_os55.default.homedir(), slug2);
|
|
56625
56262
|
try {
|
|
56626
|
-
projectRoot =
|
|
56263
|
+
projectRoot = import_fs67.default.readFileSync(import_path62.default.join(slugPath, ".project_root"), "utf-8").trim();
|
|
56627
56264
|
} catch {
|
|
56628
56265
|
}
|
|
56629
|
-
const chatsDir =
|
|
56630
|
-
if (!
|
|
56266
|
+
const chatsDir = import_path62.default.join(slugPath, "chats");
|
|
56267
|
+
if (!import_fs67.default.existsSync(chatsDir)) continue;
|
|
56631
56268
|
let chatFiles;
|
|
56632
56269
|
try {
|
|
56633
|
-
chatFiles =
|
|
56270
|
+
chatFiles = import_fs67.default.readdirSync(chatsDir).filter((f) => f.endsWith(".json"));
|
|
56634
56271
|
} catch {
|
|
56635
56272
|
continue;
|
|
56636
56273
|
}
|
|
56637
56274
|
for (const chatFile of chatFiles) {
|
|
56638
56275
|
let raw;
|
|
56639
56276
|
try {
|
|
56640
|
-
raw =
|
|
56277
|
+
raw = import_fs67.default.readFileSync(import_path62.default.join(chatsDir, chatFile), "utf-8");
|
|
56641
56278
|
} catch {
|
|
56642
56279
|
continue;
|
|
56643
56280
|
}
|
|
@@ -56717,8 +56354,8 @@ function buildGeminiSessions(days, allAuditEntries) {
|
|
|
56717
56354
|
return summaries;
|
|
56718
56355
|
}
|
|
56719
56356
|
function buildCodexSessions(days, allAuditEntries) {
|
|
56720
|
-
const sessionsBase =
|
|
56721
|
-
if (!
|
|
56357
|
+
const sessionsBase = import_path62.default.join(import_os55.default.homedir(), ".codex", "sessions");
|
|
56358
|
+
if (!import_fs67.default.existsSync(sessionsBase)) return [];
|
|
56722
56359
|
const cutoff = days !== null ? (() => {
|
|
56723
56360
|
const d = /* @__PURE__ */ new Date();
|
|
56724
56361
|
d.setDate(d.getDate() - days);
|
|
@@ -56727,29 +56364,29 @@ function buildCodexSessions(days, allAuditEntries) {
|
|
|
56727
56364
|
})() : null;
|
|
56728
56365
|
const jsonlFiles = [];
|
|
56729
56366
|
try {
|
|
56730
|
-
for (const year of
|
|
56731
|
-
const yearPath =
|
|
56367
|
+
for (const year of import_fs67.default.readdirSync(sessionsBase)) {
|
|
56368
|
+
const yearPath = import_path62.default.join(sessionsBase, year);
|
|
56732
56369
|
try {
|
|
56733
|
-
if (!
|
|
56370
|
+
if (!import_fs67.default.statSync(yearPath).isDirectory()) continue;
|
|
56734
56371
|
} catch {
|
|
56735
56372
|
continue;
|
|
56736
56373
|
}
|
|
56737
|
-
for (const month of
|
|
56738
|
-
const monthPath =
|
|
56374
|
+
for (const month of import_fs67.default.readdirSync(yearPath)) {
|
|
56375
|
+
const monthPath = import_path62.default.join(yearPath, month);
|
|
56739
56376
|
try {
|
|
56740
|
-
if (!
|
|
56377
|
+
if (!import_fs67.default.statSync(monthPath).isDirectory()) continue;
|
|
56741
56378
|
} catch {
|
|
56742
56379
|
continue;
|
|
56743
56380
|
}
|
|
56744
|
-
for (const day of
|
|
56745
|
-
const dayPath =
|
|
56381
|
+
for (const day of import_fs67.default.readdirSync(monthPath)) {
|
|
56382
|
+
const dayPath = import_path62.default.join(monthPath, day);
|
|
56746
56383
|
try {
|
|
56747
|
-
if (!
|
|
56384
|
+
if (!import_fs67.default.statSync(dayPath).isDirectory()) continue;
|
|
56748
56385
|
} catch {
|
|
56749
56386
|
continue;
|
|
56750
56387
|
}
|
|
56751
|
-
for (const file of
|
|
56752
|
-
if (file.endsWith(".jsonl")) jsonlFiles.push(
|
|
56388
|
+
for (const file of import_fs67.default.readdirSync(dayPath)) {
|
|
56389
|
+
if (file.endsWith(".jsonl")) jsonlFiles.push(import_path62.default.join(dayPath, file));
|
|
56753
56390
|
}
|
|
56754
56391
|
}
|
|
56755
56392
|
}
|
|
@@ -56761,7 +56398,7 @@ function buildCodexSessions(days, allAuditEntries) {
|
|
|
56761
56398
|
for (const filePath of jsonlFiles) {
|
|
56762
56399
|
let lines;
|
|
56763
56400
|
try {
|
|
56764
|
-
lines =
|
|
56401
|
+
lines = import_fs67.default.readFileSync(filePath, "utf-8").split("\n");
|
|
56765
56402
|
} catch {
|
|
56766
56403
|
continue;
|
|
56767
56404
|
}
|
|
@@ -56847,10 +56484,10 @@ function buildCodexSessions(days, allAuditEntries) {
|
|
|
56847
56484
|
return summaries;
|
|
56848
56485
|
}
|
|
56849
56486
|
function buildSessions(days, historyPath) {
|
|
56850
|
-
const hPath = historyPath ??
|
|
56487
|
+
const hPath = historyPath ?? import_path62.default.join(import_os55.default.homedir(), ".claude", "history.jsonl");
|
|
56851
56488
|
let historyRaw = "";
|
|
56852
56489
|
try {
|
|
56853
|
-
historyRaw =
|
|
56490
|
+
historyRaw = import_fs67.default.readFileSync(hPath, "utf-8");
|
|
56854
56491
|
} catch {
|
|
56855
56492
|
}
|
|
56856
56493
|
const cutoff = days !== null ? (() => {
|
|
@@ -56874,7 +56511,7 @@ function buildSessions(days, historyPath) {
|
|
|
56874
56511
|
const jsonlFile = sessionJsonlPath(entry.project, entry.sessionId);
|
|
56875
56512
|
let sessionLines = [];
|
|
56876
56513
|
try {
|
|
56877
|
-
sessionLines =
|
|
56514
|
+
sessionLines = import_fs67.default.readFileSync(jsonlFile, "utf-8").split("\n");
|
|
56878
56515
|
} catch {
|
|
56879
56516
|
}
|
|
56880
56517
|
const { toolCalls, costUSD, hasSnapshot, modifiedFiles } = parseSessionLines(sessionLines);
|
|
@@ -57268,12 +56905,12 @@ function registerSessionTaintCommand(program2) {
|
|
|
57268
56905
|
|
|
57269
56906
|
// src/cli/commands/skill-pin.ts
|
|
57270
56907
|
var import_chalk35 = __toESM(require("chalk"));
|
|
57271
|
-
var
|
|
57272
|
-
var
|
|
57273
|
-
var
|
|
56908
|
+
var import_fs68 = __toESM(require("fs"));
|
|
56909
|
+
var import_os56 = __toESM(require("os"));
|
|
56910
|
+
var import_path63 = __toESM(require("path"));
|
|
57274
56911
|
function wipeSkillSessions() {
|
|
57275
56912
|
try {
|
|
57276
|
-
|
|
56913
|
+
import_fs68.default.rmSync(import_path63.default.join(import_os56.default.homedir(), ".node9", "skill-sessions"), {
|
|
57277
56914
|
recursive: true,
|
|
57278
56915
|
force: true
|
|
57279
56916
|
});
|
|
@@ -57355,15 +56992,15 @@ function registerSkillPinCommand(program2) {
|
|
|
57355
56992
|
}
|
|
57356
56993
|
|
|
57357
56994
|
// src/cli/commands/decisions.ts
|
|
57358
|
-
var
|
|
57359
|
-
var
|
|
57360
|
-
var
|
|
56995
|
+
var import_fs69 = __toESM(require("fs"));
|
|
56996
|
+
var import_os57 = __toESM(require("os"));
|
|
56997
|
+
var import_path64 = __toESM(require("path"));
|
|
57361
56998
|
var import_chalk36 = __toESM(require("chalk"));
|
|
57362
|
-
var DECISIONS_FILE2 =
|
|
56999
|
+
var DECISIONS_FILE2 = import_path64.default.join(import_os57.default.homedir(), ".node9", "decisions.json");
|
|
57363
57000
|
function readDecisions() {
|
|
57364
57001
|
try {
|
|
57365
|
-
if (!
|
|
57366
|
-
const raw =
|
|
57002
|
+
if (!import_fs69.default.existsSync(DECISIONS_FILE2)) return {};
|
|
57003
|
+
const raw = import_fs69.default.readFileSync(DECISIONS_FILE2, "utf-8");
|
|
57367
57004
|
const parsed = JSON.parse(raw);
|
|
57368
57005
|
const out = {};
|
|
57369
57006
|
for (const [k, v] of Object.entries(parsed)) {
|
|
@@ -57375,11 +57012,11 @@ function readDecisions() {
|
|
|
57375
57012
|
}
|
|
57376
57013
|
}
|
|
57377
57014
|
function writeDecisions(d) {
|
|
57378
|
-
const dir =
|
|
57379
|
-
if (!
|
|
57015
|
+
const dir = import_path64.default.dirname(DECISIONS_FILE2);
|
|
57016
|
+
if (!import_fs69.default.existsSync(dir)) import_fs69.default.mkdirSync(dir, { recursive: true });
|
|
57380
57017
|
const tmp = `${DECISIONS_FILE2}.${process.pid}.tmp`;
|
|
57381
|
-
|
|
57382
|
-
|
|
57018
|
+
import_fs69.default.writeFileSync(tmp, JSON.stringify(d, null, 2));
|
|
57019
|
+
import_fs69.default.renameSync(tmp, DECISIONS_FILE2);
|
|
57383
57020
|
}
|
|
57384
57021
|
function registerDecisionsCommand(program2) {
|
|
57385
57022
|
const cmd = program2.command("decisions").description('Manage persistent "Always Allow" / "Always Deny" tool decisions');
|
|
@@ -57436,18 +57073,18 @@ Persistent decisions (${entries.length})
|
|
|
57436
57073
|
|
|
57437
57074
|
// src/cli/commands/dlp.ts
|
|
57438
57075
|
var import_chalk37 = __toESM(require("chalk"));
|
|
57439
|
-
var
|
|
57440
|
-
var
|
|
57441
|
-
var
|
|
57442
|
-
var AUDIT_LOG =
|
|
57443
|
-
var RESOLVED_FILE =
|
|
57076
|
+
var import_fs70 = __toESM(require("fs"));
|
|
57077
|
+
var import_path65 = __toESM(require("path"));
|
|
57078
|
+
var import_os58 = __toESM(require("os"));
|
|
57079
|
+
var AUDIT_LOG = import_path65.default.join(import_os58.default.homedir(), ".node9", "audit.log");
|
|
57080
|
+
var RESOLVED_FILE = import_path65.default.join(import_os58.default.homedir(), ".node9", "dlp-resolved.json");
|
|
57444
57081
|
var ANSI_RE = /\x1b(?:\[[0-9;?]*[a-zA-Z]|\][^\x07\x1b]*(?:\x07|\x1b\\)|[@-_])/g;
|
|
57445
57082
|
function stripAnsi(s) {
|
|
57446
57083
|
return s.replace(ANSI_RE, "");
|
|
57447
57084
|
}
|
|
57448
57085
|
function loadResolved() {
|
|
57449
57086
|
try {
|
|
57450
|
-
const raw = JSON.parse(
|
|
57087
|
+
const raw = JSON.parse(import_fs70.default.readFileSync(RESOLVED_FILE, "utf-8"));
|
|
57451
57088
|
return new Set(raw);
|
|
57452
57089
|
} catch {
|
|
57453
57090
|
return /* @__PURE__ */ new Set();
|
|
@@ -57455,13 +57092,13 @@ function loadResolved() {
|
|
|
57455
57092
|
}
|
|
57456
57093
|
function saveResolved(resolved) {
|
|
57457
57094
|
try {
|
|
57458
|
-
|
|
57095
|
+
import_fs70.default.writeFileSync(RESOLVED_FILE, JSON.stringify([...resolved], null, 2), { mode: 384 });
|
|
57459
57096
|
} catch {
|
|
57460
57097
|
}
|
|
57461
57098
|
}
|
|
57462
57099
|
function loadDlpFindings() {
|
|
57463
|
-
if (!
|
|
57464
|
-
return
|
|
57100
|
+
if (!import_fs70.default.existsSync(AUDIT_LOG)) return [];
|
|
57101
|
+
return import_fs70.default.readFileSync(AUDIT_LOG, "utf-8").split("\n").flatMap((line) => {
|
|
57465
57102
|
if (!line.trim()) return [];
|
|
57466
57103
|
try {
|
|
57467
57104
|
const e = JSON.parse(line);
|
|
@@ -57559,15 +57196,15 @@ function registerDlpCommand(program2) {
|
|
|
57559
57196
|
|
|
57560
57197
|
// src/cli/commands/mask.ts
|
|
57561
57198
|
var import_chalk38 = __toESM(require("chalk"));
|
|
57562
|
-
var
|
|
57563
|
-
var
|
|
57564
|
-
var
|
|
57199
|
+
var import_fs71 = __toESM(require("fs"));
|
|
57200
|
+
var import_path66 = __toESM(require("path"));
|
|
57201
|
+
var import_os59 = __toESM(require("os"));
|
|
57565
57202
|
init_dlp();
|
|
57566
57203
|
function findJsonlFiles(dir) {
|
|
57567
57204
|
const results = [];
|
|
57568
|
-
if (!
|
|
57569
|
-
for (const entry of
|
|
57570
|
-
const full =
|
|
57205
|
+
if (!import_fs71.default.existsSync(dir)) return results;
|
|
57206
|
+
for (const entry of import_fs71.default.readdirSync(dir, { withFileTypes: true })) {
|
|
57207
|
+
const full = import_path66.default.join(dir, entry.name);
|
|
57571
57208
|
if (entry.isDirectory()) results.push(...findJsonlFiles(full));
|
|
57572
57209
|
else if (entry.isFile() && entry.name.endsWith(".jsonl")) results.push(full);
|
|
57573
57210
|
}
|
|
@@ -57610,7 +57247,7 @@ function redactJson(obj) {
|
|
|
57610
57247
|
function processFile(filePath, dryRun) {
|
|
57611
57248
|
let raw;
|
|
57612
57249
|
try {
|
|
57613
|
-
raw =
|
|
57250
|
+
raw = import_fs71.default.readFileSync(filePath, "utf-8");
|
|
57614
57251
|
} catch {
|
|
57615
57252
|
return { redactedLines: 0, patterns: [] };
|
|
57616
57253
|
}
|
|
@@ -57642,14 +57279,14 @@ function processFile(filePath, dryRun) {
|
|
|
57642
57279
|
}
|
|
57643
57280
|
}
|
|
57644
57281
|
if (!dryRun && redactedLines > 0) {
|
|
57645
|
-
|
|
57282
|
+
import_fs71.default.writeFileSync(filePath, newLines.join("\n"), "utf-8");
|
|
57646
57283
|
}
|
|
57647
57284
|
return { redactedLines, patterns };
|
|
57648
57285
|
}
|
|
57649
57286
|
function processJsonFile(filePath, dryRun) {
|
|
57650
57287
|
let raw;
|
|
57651
57288
|
try {
|
|
57652
|
-
raw =
|
|
57289
|
+
raw = import_fs71.default.readFileSync(filePath, "utf-8");
|
|
57653
57290
|
} catch {
|
|
57654
57291
|
return { redactedLines: 0, patterns: [] };
|
|
57655
57292
|
}
|
|
@@ -57662,15 +57299,15 @@ function processJsonFile(filePath, dryRun) {
|
|
|
57662
57299
|
const { value, modified, found } = redactJson(parsed);
|
|
57663
57300
|
if (!modified) return { redactedLines: 0, patterns: [] };
|
|
57664
57301
|
if (!dryRun) {
|
|
57665
|
-
|
|
57302
|
+
import_fs71.default.writeFileSync(filePath, JSON.stringify(value, null, 2), "utf-8");
|
|
57666
57303
|
}
|
|
57667
57304
|
return { redactedLines: 1, patterns: found };
|
|
57668
57305
|
}
|
|
57669
57306
|
function findJsonFiles(dir) {
|
|
57670
57307
|
const results = [];
|
|
57671
|
-
if (!
|
|
57672
|
-
for (const entry of
|
|
57673
|
-
const full =
|
|
57308
|
+
if (!import_fs71.default.existsSync(dir)) return results;
|
|
57309
|
+
for (const entry of import_fs71.default.readdirSync(dir, { withFileTypes: true })) {
|
|
57310
|
+
const full = import_path66.default.join(dir, entry.name);
|
|
57674
57311
|
if (entry.isDirectory()) results.push(...findJsonFiles(full));
|
|
57675
57312
|
else if (entry.isFile() && entry.name.endsWith(".json")) results.push(full);
|
|
57676
57313
|
}
|
|
@@ -57679,9 +57316,9 @@ function findJsonFiles(dir) {
|
|
|
57679
57316
|
function registerMaskCommand(program2) {
|
|
57680
57317
|
program2.command("mask").description("Redact plaintext secrets from local AI session history files").option("--dry-run", "show what would be redacted without making changes").option("--all", "scan all history (default: last 30 days)").action(async (options) => {
|
|
57681
57318
|
const dryRun = !!options.dryRun;
|
|
57682
|
-
const home =
|
|
57683
|
-
const claudeDir =
|
|
57684
|
-
const geminiDir =
|
|
57319
|
+
const home = import_os59.default.homedir();
|
|
57320
|
+
const claudeDir = import_path66.default.join(home, ".claude", "projects");
|
|
57321
|
+
const geminiDir = import_path66.default.join(home, ".gemini", "tmp");
|
|
57685
57322
|
const allFiles = [
|
|
57686
57323
|
...findJsonlFiles(claudeDir).map((p) => ({ path: p, type: "jsonl" })),
|
|
57687
57324
|
...findJsonFiles(geminiDir).map((p) => ({ path: p, type: "json" }))
|
|
@@ -57689,7 +57326,7 @@ function registerMaskCommand(program2) {
|
|
|
57689
57326
|
const cutoff = options.all ? null : new Date(Date.now() - 30 * 24 * 60 * 60 * 1e3);
|
|
57690
57327
|
const filtered = cutoff ? allFiles.filter((f) => {
|
|
57691
57328
|
try {
|
|
57692
|
-
return
|
|
57329
|
+
return import_fs71.default.statSync(f.path).mtime >= cutoff;
|
|
57693
57330
|
} catch {
|
|
57694
57331
|
return false;
|
|
57695
57332
|
}
|
|
@@ -57745,7 +57382,7 @@ function registerMaskCommand(program2) {
|
|
|
57745
57382
|
// src/cli.ts
|
|
57746
57383
|
init_blast();
|
|
57747
57384
|
var { version } = JSON.parse(
|
|
57748
|
-
|
|
57385
|
+
import_fs74.default.readFileSync(import_path69.default.join(__dirname, "../package.json"), "utf-8")
|
|
57749
57386
|
);
|
|
57750
57387
|
var program = new import_commander.Command();
|
|
57751
57388
|
program.name("node9").description("The Sudo Command for AI Agents").version(version);
|
|
@@ -57785,7 +57422,7 @@ program.command("signup").description("Create your node9 account / open the dash
|
|
|
57785
57422
|
console.log(" " + import_chalk40.default.dim("Opening ") + import_chalk40.default.cyan.underline(url));
|
|
57786
57423
|
const opener = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
|
|
57787
57424
|
try {
|
|
57788
|
-
const child = (0,
|
|
57425
|
+
const child = (0, import_child_process14.spawn)(opener, [url], {
|
|
57789
57426
|
stdio: "ignore",
|
|
57790
57427
|
detached: true,
|
|
57791
57428
|
shell: process.platform === "win32"
|
|
@@ -57928,16 +57565,16 @@ program.command("uninstall").description("Remove all Node9 hooks and optionally
|
|
|
57928
57565
|
} catch {
|
|
57929
57566
|
}
|
|
57930
57567
|
if (options.purge) {
|
|
57931
|
-
const node9Dir =
|
|
57932
|
-
if (
|
|
57568
|
+
const node9Dir = import_path69.default.join(import_os62.default.homedir(), ".node9");
|
|
57569
|
+
if (import_fs74.default.existsSync(node9Dir)) {
|
|
57933
57570
|
const alsoSnapshots = undoLeftoverPaths().length > 0 ? ", old undo snapshots" : "";
|
|
57934
57571
|
const confirmed = await (0, import_prompts3.confirm)({
|
|
57935
57572
|
message: `Permanently delete ${node9Dir} (config, audit log, credentials${alsoSnapshots})?`,
|
|
57936
57573
|
default: false
|
|
57937
57574
|
});
|
|
57938
57575
|
if (confirmed) {
|
|
57939
|
-
|
|
57940
|
-
if (
|
|
57576
|
+
import_fs74.default.rmSync(node9Dir, { recursive: true });
|
|
57577
|
+
if (import_fs74.default.existsSync(node9Dir)) {
|
|
57941
57578
|
console.error(
|
|
57942
57579
|
import_chalk40.default.red("\n \u26A0\uFE0F ~/.node9/ could not be fully deleted \u2014 remove it manually.")
|
|
57943
57580
|
);
|
|
@@ -58073,7 +57710,7 @@ program.command("tail").description("Stream live agent activity to the terminal"
|
|
|
58073
57710
|
});
|
|
58074
57711
|
program.command("monitor").description("Live interactive dashboard \u2014 activity feed, approvals, security signals").action(async () => {
|
|
58075
57712
|
try {
|
|
58076
|
-
const dashboardPath =
|
|
57713
|
+
const dashboardPath = import_path69.default.join(__dirname, "dashboard.mjs");
|
|
58077
57714
|
const dynamicImport = new Function("id", "return import(id)");
|
|
58078
57715
|
const mod = await dynamicImport(`file://${dashboardPath}`);
|
|
58079
57716
|
await mod.startMonitor();
|
|
@@ -58111,14 +57748,14 @@ Claude Code spawns this command every ~300ms and writes a JSON payload to stdin.
|
|
|
58111
57748
|
Run "node9 addto claude" to register it as the statusLine.`
|
|
58112
57749
|
).argument("[subcommand]", 'Optional: "debug on" / "debug off" to toggle stdin logging').argument("[state]", 'on|off \u2014 used with "debug" subcommand').action(async (subcommand, state) => {
|
|
58113
57750
|
if (subcommand === "debug") {
|
|
58114
|
-
const flagFile =
|
|
57751
|
+
const flagFile = import_path69.default.join(import_os62.default.homedir(), ".node9", "hud-debug");
|
|
58115
57752
|
if (state === "on") {
|
|
58116
|
-
|
|
58117
|
-
|
|
57753
|
+
import_fs74.default.mkdirSync(import_path69.default.dirname(flagFile), { recursive: true });
|
|
57754
|
+
import_fs74.default.writeFileSync(flagFile, "");
|
|
58118
57755
|
console.log("HUD debug logging enabled \u2192 ~/.node9/hud-debug.log");
|
|
58119
57756
|
console.log("Tail it with: tail -f ~/.node9/hud-debug.log");
|
|
58120
57757
|
} else if (state === "off") {
|
|
58121
|
-
if (
|
|
57758
|
+
if (import_fs74.default.existsSync(flagFile)) import_fs74.default.unlinkSync(flagFile);
|
|
58122
57759
|
console.log("HUD debug logging disabled.");
|
|
58123
57760
|
} else {
|
|
58124
57761
|
console.error("Usage: node9 hud debug on|off");
|
|
@@ -58241,9 +57878,9 @@ if (process.argv[2] !== "daemon") {
|
|
|
58241
57878
|
const isCheckHook = process.argv[2] === "check";
|
|
58242
57879
|
if (isCheckHook) {
|
|
58243
57880
|
if (process.env.NODE9_DEBUG === "1" || getConfig().settings.enableHookLogDebug) {
|
|
58244
|
-
const logPath =
|
|
57881
|
+
const logPath = import_path69.default.join(import_os62.default.homedir(), ".node9", "hook-debug.log");
|
|
58245
57882
|
const msg = reason instanceof Error ? reason.message : String(reason);
|
|
58246
|
-
|
|
57883
|
+
import_fs74.default.appendFileSync(logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] UNHANDLED: ${msg}
|
|
58247
57884
|
`);
|
|
58248
57885
|
}
|
|
58249
57886
|
process.exit(0);
|