@node9/proxy 2.44.0 → 2.45.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 +49 -65
- package/dist/cli.mjs +49 -65
- package/dist/dashboard.mjs +5917 -4507
- package/dist/scan-ink.mjs +9 -10
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -35079,12 +35079,6 @@ function isReadable(filePath) {
|
|
|
35079
35079
|
return false;
|
|
35080
35080
|
}
|
|
35081
35081
|
}
|
|
35082
|
-
function scoreLabel(score) {
|
|
35083
|
-
if (score >= 80) return import_chalk3.default.green(`${score}/100 Good`);
|
|
35084
|
-
if (score >= 50) return import_chalk3.default.yellow(`${score}/100 Moderate risk`);
|
|
35085
|
-
if (score >= 25) return import_chalk3.default.red(`${score}/100 High risk`);
|
|
35086
|
-
return import_chalk3.default.red.bold(`${score}/100 Critical`);
|
|
35087
|
-
}
|
|
35088
35082
|
function runBlast() {
|
|
35089
35083
|
const home = import_os42.default.homedir();
|
|
35090
35084
|
const cwd = process.cwd();
|
|
@@ -35115,7 +35109,7 @@ function registerBlastCommand(program2) {
|
|
|
35115
35109
|
program2.command("blast").description("Map what an AI agent can currently reach on this machine").action(() => {
|
|
35116
35110
|
const home = import_os42.default.homedir();
|
|
35117
35111
|
const cwd = process.cwd();
|
|
35118
|
-
const { reachable, envFindings
|
|
35112
|
+
const { reachable, envFindings } = runBlast();
|
|
35119
35113
|
const width = labelColumnWidth([
|
|
35120
35114
|
...reachable.map((p) => p.label),
|
|
35121
35115
|
...envFindings.map((f) => f.key)
|
|
@@ -35147,21 +35141,24 @@ function registerBlastCommand(program2) {
|
|
|
35147
35141
|
console.log(" " + import_chalk3.default.dim("\u2500".repeat(70)));
|
|
35148
35142
|
if (reachable.length === 0 && envFindings.length === 0) {
|
|
35149
35143
|
console.log(" " + import_chalk3.default.green("\u2705 No sensitive files or environment secrets found."));
|
|
35150
|
-
console.log(" Security Score: " + scoreLabel(score));
|
|
35151
35144
|
} else {
|
|
35152
35145
|
console.log(
|
|
35153
|
-
|
|
35154
|
-
`
|
|
35155
|
-
)
|
|
35146
|
+
import_chalk3.default.bold(
|
|
35147
|
+
` ${reachable.length} file${reachable.length !== 1 ? "s" : ""} and ${envFindings.length} env var${envFindings.length !== 1 ? "s" : ""}`
|
|
35148
|
+
) + import_chalk3.default.dim(" every AI agent you start can read.")
|
|
35156
35149
|
);
|
|
35157
35150
|
console.log("");
|
|
35158
35151
|
console.log(
|
|
35159
35152
|
import_chalk3.default.dim(
|
|
35160
|
-
"
|
|
35153
|
+
" Run `node9 shield enable project-jail` to restrict agent file access.\n Run `node9 mask` to redact secrets from existing session history."
|
|
35161
35154
|
)
|
|
35162
35155
|
);
|
|
35163
35156
|
}
|
|
35164
35157
|
console.log("");
|
|
35158
|
+
console.log(
|
|
35159
|
+
import_chalk3.default.dim(" Machine score: ") + import_chalk3.default.cyan("node9 posture") + import_chalk3.default.dim(" (this list is its Secrets section)")
|
|
35160
|
+
);
|
|
35161
|
+
console.log("");
|
|
35165
35162
|
});
|
|
35166
35163
|
}
|
|
35167
35164
|
var import_chalk3, import_fs49, import_path51, import_os42;
|
|
@@ -35274,13 +35271,14 @@ var init_scan_derive = __esm({
|
|
|
35274
35271
|
});
|
|
35275
35272
|
|
|
35276
35273
|
// src/protection.ts
|
|
35277
|
-
|
|
35274
|
+
function isProtectiveShield(name) {
|
|
35275
|
+
return PROTECTIVE_SHIELDS.has(name);
|
|
35276
|
+
}
|
|
35277
|
+
var PROTECTIVE_SHIELDS;
|
|
35278
35278
|
var init_protection = __esm({
|
|
35279
35279
|
"src/protection.ts"() {
|
|
35280
35280
|
"use strict";
|
|
35281
|
-
|
|
35282
|
-
"project-jail": 0.7
|
|
35283
|
-
};
|
|
35281
|
+
PROTECTIVE_SHIELDS = /* @__PURE__ */ new Set(["project-jail"]);
|
|
35284
35282
|
}
|
|
35285
35283
|
});
|
|
35286
35284
|
|
|
@@ -35321,20 +35319,6 @@ var init_scan_json = __esm({
|
|
|
35321
35319
|
function defaultHistoryPath() {
|
|
35322
35320
|
return import_path52.default.join(import_os43.default.homedir(), ".node9", "scan-history.json");
|
|
35323
35321
|
}
|
|
35324
|
-
function readPreviousScan(opts = {}) {
|
|
35325
|
-
const filePath = opts.path ?? defaultHistoryPath();
|
|
35326
|
-
try {
|
|
35327
|
-
if (!import_fs50.default.existsSync(filePath)) return null;
|
|
35328
|
-
const raw = import_fs50.default.readFileSync(filePath, "utf8");
|
|
35329
|
-
const parsed = JSON.parse(raw);
|
|
35330
|
-
if (!Array.isArray(parsed) || parsed.length === 0) return null;
|
|
35331
|
-
const last = parsed[parsed.length - 1];
|
|
35332
|
-
if (!isValidRecord(last)) return null;
|
|
35333
|
-
return last;
|
|
35334
|
-
} catch {
|
|
35335
|
-
return null;
|
|
35336
|
-
}
|
|
35337
|
-
}
|
|
35338
35322
|
function appendScanHistory(record2, opts = {}) {
|
|
35339
35323
|
const filePath = opts.path ?? defaultHistoryPath();
|
|
35340
35324
|
const cap = opts.cap ?? SCAN_HISTORY_CAP;
|
|
@@ -35362,15 +35346,6 @@ function appendScanHistory(record2, opts = {}) {
|
|
|
35362
35346
|
);
|
|
35363
35347
|
}
|
|
35364
35348
|
}
|
|
35365
|
-
function computeScanDelta(current, previous, now = Date.now()) {
|
|
35366
|
-
if (!previous) return null;
|
|
35367
|
-
const prevMs = Date.parse(previous.timestamp);
|
|
35368
|
-
if (Number.isNaN(prevMs)) return null;
|
|
35369
|
-
const scoreDelta = current.score - previous.score;
|
|
35370
|
-
const daysAgo = Math.max(0, Math.floor((now - prevMs) / 864e5));
|
|
35371
|
-
if (scoreDelta === 0 && daysAgo === 0) return null;
|
|
35372
|
-
return { scoreDelta, daysAgo };
|
|
35373
|
-
}
|
|
35374
35349
|
function isValidRecord(x) {
|
|
35375
35350
|
if (typeof x !== "object" || x === null) return false;
|
|
35376
35351
|
const r = x;
|
|
@@ -36032,7 +36007,7 @@ async function runUploadHistory(opts) {
|
|
|
36032
36007
|
` Parsed ${linesParsed.toLocaleString()} JSONL lines from ${filesScanned} session${filesScanned === 1 ? "" : "s"} (skipped ${linesSkipped} malformed)`
|
|
36033
36008
|
)
|
|
36034
36009
|
);
|
|
36035
|
-
console.log(import_chalk5.default.gray(` Findings: ${findings.length}
|
|
36010
|
+
console.log(import_chalk5.default.gray(` Findings: ${findings.length}`));
|
|
36036
36011
|
const scanUrl = creds.apiUrl.endsWith("/policies/sync") ? creds.apiUrl.replace(/\/policies\/sync$/, "/scan/report") : `${creds.apiUrl.replace(/\/$/, "")}/scan/report`;
|
|
36037
36012
|
await postJson(scanUrl, creds.apiKey, {
|
|
36038
36013
|
...summary,
|
|
@@ -37813,6 +37788,9 @@ function renderCompactScorecard(input) {
|
|
|
37813
37788
|
);
|
|
37814
37789
|
console.log("");
|
|
37815
37790
|
}
|
|
37791
|
+
console.log(
|
|
37792
|
+
import_chalk6.default.dim("\u2192 Machine score: run ") + import_chalk6.default.cyan("node9 posture") + import_chalk6.default.dim(" for this machine's score and what to fix first.")
|
|
37793
|
+
);
|
|
37816
37794
|
console.log(
|
|
37817
37795
|
import_chalk6.default.dim("\u2192 ") + import_chalk6.default.cyan("npx node9-ai scan") + import_chalk6.default.dim(" run this on your machine")
|
|
37818
37796
|
);
|
|
@@ -37923,6 +37901,9 @@ function renderNarrativeScorecard(input) {
|
|
|
37923
37901
|
}
|
|
37924
37902
|
console.log("");
|
|
37925
37903
|
}
|
|
37904
|
+
console.log(
|
|
37905
|
+
import_chalk6.default.dim("\u2192 Machine score: run ") + import_chalk6.default.cyan("node9 posture") + import_chalk6.default.dim(" for this machine's score and what to fix first.")
|
|
37906
|
+
);
|
|
37926
37907
|
console.log(
|
|
37927
37908
|
import_chalk6.default.dim("\u2192 ") + import_chalk6.default.cyan("npx node9-ai scan") + import_chalk6.default.dim(" run this on your machine")
|
|
37928
37909
|
);
|
|
@@ -38165,24 +38146,24 @@ function renderPanelScorecard(input, now = /* @__PURE__ */ new Date()) {
|
|
|
38165
38146
|
const shieldImpacts = rollupByShield(summary.sections);
|
|
38166
38147
|
const shieldLines = [];
|
|
38167
38148
|
const ranked = [...shieldImpacts].sort((a, b) => {
|
|
38168
|
-
const
|
|
38169
|
-
const
|
|
38170
|
-
if (
|
|
38149
|
+
const aProt = isProtectiveShield(a.shieldName) ? 1 : 0;
|
|
38150
|
+
const bProt = isProtectiveShield(b.shieldName) ? 1 : 0;
|
|
38151
|
+
if (aProt !== bProt) return bProt - aProt;
|
|
38171
38152
|
return b.totalCatches - a.totalCatches;
|
|
38172
38153
|
});
|
|
38173
38154
|
for (const impact of ranked) {
|
|
38174
38155
|
if (impact.totalCatches === 0) continue;
|
|
38175
|
-
const
|
|
38156
|
+
const protective = isProtectiveShield(impact.shieldName);
|
|
38176
38157
|
const isOn = enabledSet.has(impact.shieldName);
|
|
38177
|
-
const icon =
|
|
38158
|
+
const icon = protective ? "\u{1F6E1}\uFE0F " : "\u2610 ";
|
|
38178
38159
|
const wouldCatch = `catches ${impact.totalCatches} op${impact.totalCatches !== 1 ? "s" : ""}`;
|
|
38179
|
-
const suffix = isOn ? "\u2713 enabled" :
|
|
38160
|
+
const suffix = isOn ? "\u2713 enabled" : protective ? "\u2192 blocks these reads in-path" : "";
|
|
38180
38161
|
shieldLines.push(
|
|
38181
38162
|
mkLine(
|
|
38182
|
-
[icon,
|
|
38163
|
+
[icon, protective ? import_chalk6.default.cyan : import_chalk6.default.dim],
|
|
38183
38164
|
[impact.shieldName.padEnd(14), import_chalk6.default.bold],
|
|
38184
38165
|
[wouldCatch.padEnd(22), import_chalk6.default.dim],
|
|
38185
|
-
[suffix, isOn ||
|
|
38166
|
+
[suffix, isOn || protective ? import_chalk6.default.green.bold : import_chalk6.default.dim]
|
|
38186
38167
|
)
|
|
38187
38168
|
);
|
|
38188
38169
|
if (impact.topRuleLabels.length > 0) {
|
|
@@ -38211,10 +38192,10 @@ function renderPanelScorecard(input, now = /* @__PURE__ */ new Date()) {
|
|
|
38211
38192
|
shieldLines.push(mkLine([" no hits in your history \u2014 install proactively", import_chalk6.default.dim]));
|
|
38212
38193
|
}
|
|
38213
38194
|
const topRec = ranked.find(
|
|
38214
|
-
(r) => r.totalCatches > 0 && (
|
|
38195
|
+
(r) => r.totalCatches > 0 && isProtectiveShield(r.shieldName) && !enabledSet.has(r.shieldName)
|
|
38215
38196
|
);
|
|
38216
38197
|
const allCovered = !topRec && ranked.some(
|
|
38217
|
-
(r) => r.totalCatches > 0 && (
|
|
38198
|
+
(r) => r.totalCatches > 0 && isProtectiveShield(r.shieldName) && enabledSet.has(r.shieldName)
|
|
38218
38199
|
);
|
|
38219
38200
|
if (topRec) {
|
|
38220
38201
|
const cta = `\u2192 node9 shield enable ${topRec.shieldName} (start here \u2014 widest coverage)`;
|
|
@@ -38419,9 +38400,7 @@ function registerScanCommand(program2) {
|
|
|
38419
38400
|
process.stdout.write(JSON.stringify(envelope, null, 2) + "\n");
|
|
38420
38401
|
return;
|
|
38421
38402
|
}
|
|
38422
|
-
let scanDelta2 = null;
|
|
38423
38403
|
if (!screenshotMode) {
|
|
38424
|
-
const previous = readPreviousScan();
|
|
38425
38404
|
const currentRecord = {
|
|
38426
38405
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
38427
38406
|
score: blast.score,
|
|
@@ -38433,7 +38412,6 @@ function registerScanCommand(program2) {
|
|
|
38433
38412
|
totalCalls: scan.totalToolCalls
|
|
38434
38413
|
};
|
|
38435
38414
|
appendScanHistory(currentRecord);
|
|
38436
|
-
scanDelta2 = computeScanDelta(currentRecord, previous);
|
|
38437
38415
|
}
|
|
38438
38416
|
if (options.compact) {
|
|
38439
38417
|
renderCompactScorecard({
|
|
@@ -38472,19 +38450,9 @@ function registerScanCommand(program2) {
|
|
|
38472
38450
|
}
|
|
38473
38451
|
{
|
|
38474
38452
|
const totalRisky = scan.canaryFindings.length + totalFindings + scan.dlpFindings.length;
|
|
38475
|
-
|
|
38476
|
-
const severityDisplay = score.band === "critical" ? import_chalk6.default.red.bold(score.label) : score.color(score.label);
|
|
38477
|
-
const trendSuffix = (() => {
|
|
38478
|
-
if (!scanDelta2) return "";
|
|
38479
|
-
const { scoreDelta, daysAgo } = scanDelta2;
|
|
38480
|
-
if (scoreDelta === 0) return "";
|
|
38481
|
-
const arrow = scoreDelta > 0 ? import_chalk6.default.green(`\u25B2${scoreDelta}`) : import_chalk6.default.red(`\u25BC${Math.abs(scoreDelta)}`);
|
|
38482
|
-
const since = daysAgo === 0 ? "today" : daysAgo === 1 ? "yesterday" : `${daysAgo} days ago`;
|
|
38483
|
-
return import_chalk6.default.dim(" \xB7 ") + arrow + import_chalk6.default.dim(` since ${since}`);
|
|
38484
|
-
})();
|
|
38485
|
-
if (!useInkForHero) {
|
|
38453
|
+
if (!useInkForHero && totalRisky > 0) {
|
|
38486
38454
|
console.log(
|
|
38487
|
-
" " +
|
|
38455
|
+
" " + import_chalk6.default.red.bold(`${totalRisky} risky operation${totalRisky !== 1 ? "s" : ""}`) + import_chalk6.default.dim(" in the scanned history")
|
|
38488
38456
|
);
|
|
38489
38457
|
}
|
|
38490
38458
|
const cardParts = [];
|
|
@@ -38566,6 +38534,10 @@ function registerScanCommand(program2) {
|
|
|
38566
38534
|
keyed
|
|
38567
38535
|
});
|
|
38568
38536
|
}
|
|
38537
|
+
console.log(
|
|
38538
|
+
import_chalk6.default.dim(" Machine score: run ") + import_chalk6.default.cyan("node9 posture") + import_chalk6.default.dim(" for this machine's score and what to fix first.")
|
|
38539
|
+
);
|
|
38540
|
+
console.log("");
|
|
38569
38541
|
const cta = isWired ? "\u2705 node9 is active" : "\u2192 install node9 to enable protection";
|
|
38570
38542
|
console.log(" " + import_chalk6.default.green(cta));
|
|
38571
38543
|
console.log(
|
|
@@ -38760,6 +38732,10 @@ function registerScanCommand(program2) {
|
|
|
38760
38732
|
);
|
|
38761
38733
|
console.log("");
|
|
38762
38734
|
}
|
|
38735
|
+
console.log(
|
|
38736
|
+
import_chalk6.default.dim(" Machine score: run ") + import_chalk6.default.cyan("node9 posture") + import_chalk6.default.dim(" for this machine's score and what to fix first.")
|
|
38737
|
+
);
|
|
38738
|
+
console.log("");
|
|
38763
38739
|
if (isWired) {
|
|
38764
38740
|
console.log(import_chalk6.default.green(" \u2705 node9 is active \u2014 your future sessions are protected."));
|
|
38765
38741
|
console.log(
|
|
@@ -78234,6 +78210,7 @@ init_agent_wiring();
|
|
|
78234
78210
|
init_codex_trust();
|
|
78235
78211
|
init_sync();
|
|
78236
78212
|
init_service();
|
|
78213
|
+
init_posture();
|
|
78237
78214
|
function printAgentSection(label3, hookPairs, wrapped) {
|
|
78238
78215
|
console.log(import_chalk22.default.bold(` ${label3}`));
|
|
78239
78216
|
for (const { name, present } of hookPairs) {
|
|
@@ -78314,6 +78291,13 @@ function registerStatusCommand(program2) {
|
|
|
78314
78291
|
console.log("");
|
|
78315
78292
|
const modeLabel = levelLabel(settings.mode);
|
|
78316
78293
|
console.log(` Mode: ${modeLabel}`);
|
|
78294
|
+
const posture = await runPosture().catch(() => null);
|
|
78295
|
+
if (posture) {
|
|
78296
|
+
const tier = posture.tier === "good" ? import_chalk22.default.green("Good") : posture.tier === "at-risk" ? import_chalk22.default.yellow("At risk") : import_chalk22.default.red("Critical");
|
|
78297
|
+
console.log(
|
|
78298
|
+
` Score: ${import_chalk22.default.bold(`${posture.score}/100`)} (${tier})` + import_chalk22.default.gray(" \xB7 node9 posture for the breakdown")
|
|
78299
|
+
);
|
|
78300
|
+
}
|
|
78317
78301
|
const wsGoverned = mergedConfig.policySource === "workspace";
|
|
78318
78302
|
if (wsGoverned) {
|
|
78319
78303
|
console.log(` Policy: ${import_chalk22.default.cyan("Workspace config (app.node9.ai)")}`);
|
package/dist/cli.mjs
CHANGED
|
@@ -35073,12 +35073,6 @@ function isReadable(filePath) {
|
|
|
35073
35073
|
return false;
|
|
35074
35074
|
}
|
|
35075
35075
|
}
|
|
35076
|
-
function scoreLabel(score) {
|
|
35077
|
-
if (score >= 80) return chalk3.green(`${score}/100 Good`);
|
|
35078
|
-
if (score >= 50) return chalk3.yellow(`${score}/100 Moderate risk`);
|
|
35079
|
-
if (score >= 25) return chalk3.red(`${score}/100 High risk`);
|
|
35080
|
-
return chalk3.red.bold(`${score}/100 Critical`);
|
|
35081
|
-
}
|
|
35082
35076
|
function runBlast() {
|
|
35083
35077
|
const home = os43.homedir();
|
|
35084
35078
|
const cwd = process.cwd();
|
|
@@ -35109,7 +35103,7 @@ function registerBlastCommand(program2) {
|
|
|
35109
35103
|
program2.command("blast").description("Map what an AI agent can currently reach on this machine").action(() => {
|
|
35110
35104
|
const home = os43.homedir();
|
|
35111
35105
|
const cwd = process.cwd();
|
|
35112
|
-
const { reachable, envFindings
|
|
35106
|
+
const { reachable, envFindings } = runBlast();
|
|
35113
35107
|
const width = labelColumnWidth([
|
|
35114
35108
|
...reachable.map((p) => p.label),
|
|
35115
35109
|
...envFindings.map((f) => f.key)
|
|
@@ -35141,21 +35135,24 @@ function registerBlastCommand(program2) {
|
|
|
35141
35135
|
console.log(" " + chalk3.dim("\u2500".repeat(70)));
|
|
35142
35136
|
if (reachable.length === 0 && envFindings.length === 0) {
|
|
35143
35137
|
console.log(" " + chalk3.green("\u2705 No sensitive files or environment secrets found."));
|
|
35144
|
-
console.log(" Security Score: " + scoreLabel(score));
|
|
35145
35138
|
} else {
|
|
35146
35139
|
console.log(
|
|
35147
|
-
|
|
35148
|
-
`
|
|
35149
|
-
)
|
|
35140
|
+
chalk3.bold(
|
|
35141
|
+
` ${reachable.length} file${reachable.length !== 1 ? "s" : ""} and ${envFindings.length} env var${envFindings.length !== 1 ? "s" : ""}`
|
|
35142
|
+
) + chalk3.dim(" every AI agent you start can read.")
|
|
35150
35143
|
);
|
|
35151
35144
|
console.log("");
|
|
35152
35145
|
console.log(
|
|
35153
35146
|
chalk3.dim(
|
|
35154
|
-
"
|
|
35147
|
+
" Run `node9 shield enable project-jail` to restrict agent file access.\n Run `node9 mask` to redact secrets from existing session history."
|
|
35155
35148
|
)
|
|
35156
35149
|
);
|
|
35157
35150
|
}
|
|
35158
35151
|
console.log("");
|
|
35152
|
+
console.log(
|
|
35153
|
+
chalk3.dim(" Machine score: ") + chalk3.cyan("node9 posture") + chalk3.dim(" (this list is its Secrets section)")
|
|
35154
|
+
);
|
|
35155
|
+
console.log("");
|
|
35159
35156
|
});
|
|
35160
35157
|
}
|
|
35161
35158
|
var init_blast = __esm({
|
|
@@ -35263,13 +35260,14 @@ var init_scan_derive = __esm({
|
|
|
35263
35260
|
});
|
|
35264
35261
|
|
|
35265
35262
|
// src/protection.ts
|
|
35266
|
-
|
|
35263
|
+
function isProtectiveShield(name) {
|
|
35264
|
+
return PROTECTIVE_SHIELDS.has(name);
|
|
35265
|
+
}
|
|
35266
|
+
var PROTECTIVE_SHIELDS;
|
|
35267
35267
|
var init_protection = __esm({
|
|
35268
35268
|
"src/protection.ts"() {
|
|
35269
35269
|
"use strict";
|
|
35270
|
-
|
|
35271
|
-
"project-jail": 0.7
|
|
35272
|
-
};
|
|
35270
|
+
PROTECTIVE_SHIELDS = /* @__PURE__ */ new Set(["project-jail"]);
|
|
35273
35271
|
}
|
|
35274
35272
|
});
|
|
35275
35273
|
|
|
@@ -35313,20 +35311,6 @@ import os44 from "os";
|
|
|
35313
35311
|
function defaultHistoryPath() {
|
|
35314
35312
|
return path54.join(os44.homedir(), ".node9", "scan-history.json");
|
|
35315
35313
|
}
|
|
35316
|
-
function readPreviousScan(opts = {}) {
|
|
35317
|
-
const filePath = opts.path ?? defaultHistoryPath();
|
|
35318
|
-
try {
|
|
35319
|
-
if (!fs52.existsSync(filePath)) return null;
|
|
35320
|
-
const raw = fs52.readFileSync(filePath, "utf8");
|
|
35321
|
-
const parsed = JSON.parse(raw);
|
|
35322
|
-
if (!Array.isArray(parsed) || parsed.length === 0) return null;
|
|
35323
|
-
const last = parsed[parsed.length - 1];
|
|
35324
|
-
if (!isValidRecord(last)) return null;
|
|
35325
|
-
return last;
|
|
35326
|
-
} catch {
|
|
35327
|
-
return null;
|
|
35328
|
-
}
|
|
35329
|
-
}
|
|
35330
35314
|
function appendScanHistory(record2, opts = {}) {
|
|
35331
35315
|
const filePath = opts.path ?? defaultHistoryPath();
|
|
35332
35316
|
const cap = opts.cap ?? SCAN_HISTORY_CAP;
|
|
@@ -35354,15 +35338,6 @@ function appendScanHistory(record2, opts = {}) {
|
|
|
35354
35338
|
);
|
|
35355
35339
|
}
|
|
35356
35340
|
}
|
|
35357
|
-
function computeScanDelta(current, previous, now = Date.now()) {
|
|
35358
|
-
if (!previous) return null;
|
|
35359
|
-
const prevMs = Date.parse(previous.timestamp);
|
|
35360
|
-
if (Number.isNaN(prevMs)) return null;
|
|
35361
|
-
const scoreDelta = current.score - previous.score;
|
|
35362
|
-
const daysAgo = Math.max(0, Math.floor((now - prevMs) / 864e5));
|
|
35363
|
-
if (scoreDelta === 0 && daysAgo === 0) return null;
|
|
35364
|
-
return { scoreDelta, daysAgo };
|
|
35365
|
-
}
|
|
35366
35341
|
function isValidRecord(x) {
|
|
35367
35342
|
if (typeof x !== "object" || x === null) return false;
|
|
35368
35343
|
const r = x;
|
|
@@ -36026,7 +36001,7 @@ async function runUploadHistory(opts) {
|
|
|
36026
36001
|
` Parsed ${linesParsed.toLocaleString()} JSONL lines from ${filesScanned} session${filesScanned === 1 ? "" : "s"} (skipped ${linesSkipped} malformed)`
|
|
36027
36002
|
)
|
|
36028
36003
|
);
|
|
36029
|
-
console.log(chalk5.gray(` Findings: ${findings.length}
|
|
36004
|
+
console.log(chalk5.gray(` Findings: ${findings.length}`));
|
|
36030
36005
|
const scanUrl = creds.apiUrl.endsWith("/policies/sync") ? creds.apiUrl.replace(/\/policies\/sync$/, "/scan/report") : `${creds.apiUrl.replace(/\/$/, "")}/scan/report`;
|
|
36031
36006
|
await postJson(scanUrl, creds.apiKey, {
|
|
36032
36007
|
...summary,
|
|
@@ -37807,6 +37782,9 @@ function renderCompactScorecard(input) {
|
|
|
37807
37782
|
);
|
|
37808
37783
|
console.log("");
|
|
37809
37784
|
}
|
|
37785
|
+
console.log(
|
|
37786
|
+
chalk6.dim("\u2192 Machine score: run ") + chalk6.cyan("node9 posture") + chalk6.dim(" for this machine's score and what to fix first.")
|
|
37787
|
+
);
|
|
37810
37788
|
console.log(
|
|
37811
37789
|
chalk6.dim("\u2192 ") + chalk6.cyan("npx node9-ai scan") + chalk6.dim(" run this on your machine")
|
|
37812
37790
|
);
|
|
@@ -37917,6 +37895,9 @@ function renderNarrativeScorecard(input) {
|
|
|
37917
37895
|
}
|
|
37918
37896
|
console.log("");
|
|
37919
37897
|
}
|
|
37898
|
+
console.log(
|
|
37899
|
+
chalk6.dim("\u2192 Machine score: run ") + chalk6.cyan("node9 posture") + chalk6.dim(" for this machine's score and what to fix first.")
|
|
37900
|
+
);
|
|
37920
37901
|
console.log(
|
|
37921
37902
|
chalk6.dim("\u2192 ") + chalk6.cyan("npx node9-ai scan") + chalk6.dim(" run this on your machine")
|
|
37922
37903
|
);
|
|
@@ -38159,24 +38140,24 @@ function renderPanelScorecard(input, now = /* @__PURE__ */ new Date()) {
|
|
|
38159
38140
|
const shieldImpacts = rollupByShield(summary.sections);
|
|
38160
38141
|
const shieldLines = [];
|
|
38161
38142
|
const ranked = [...shieldImpacts].sort((a, b) => {
|
|
38162
|
-
const
|
|
38163
|
-
const
|
|
38164
|
-
if (
|
|
38143
|
+
const aProt = isProtectiveShield(a.shieldName) ? 1 : 0;
|
|
38144
|
+
const bProt = isProtectiveShield(b.shieldName) ? 1 : 0;
|
|
38145
|
+
if (aProt !== bProt) return bProt - aProt;
|
|
38165
38146
|
return b.totalCatches - a.totalCatches;
|
|
38166
38147
|
});
|
|
38167
38148
|
for (const impact of ranked) {
|
|
38168
38149
|
if (impact.totalCatches === 0) continue;
|
|
38169
|
-
const
|
|
38150
|
+
const protective = isProtectiveShield(impact.shieldName);
|
|
38170
38151
|
const isOn = enabledSet.has(impact.shieldName);
|
|
38171
|
-
const icon =
|
|
38152
|
+
const icon = protective ? "\u{1F6E1}\uFE0F " : "\u2610 ";
|
|
38172
38153
|
const wouldCatch = `catches ${impact.totalCatches} op${impact.totalCatches !== 1 ? "s" : ""}`;
|
|
38173
|
-
const suffix = isOn ? "\u2713 enabled" :
|
|
38154
|
+
const suffix = isOn ? "\u2713 enabled" : protective ? "\u2192 blocks these reads in-path" : "";
|
|
38174
38155
|
shieldLines.push(
|
|
38175
38156
|
mkLine(
|
|
38176
|
-
[icon,
|
|
38157
|
+
[icon, protective ? chalk6.cyan : chalk6.dim],
|
|
38177
38158
|
[impact.shieldName.padEnd(14), chalk6.bold],
|
|
38178
38159
|
[wouldCatch.padEnd(22), chalk6.dim],
|
|
38179
|
-
[suffix, isOn ||
|
|
38160
|
+
[suffix, isOn || protective ? chalk6.green.bold : chalk6.dim]
|
|
38180
38161
|
)
|
|
38181
38162
|
);
|
|
38182
38163
|
if (impact.topRuleLabels.length > 0) {
|
|
@@ -38205,10 +38186,10 @@ function renderPanelScorecard(input, now = /* @__PURE__ */ new Date()) {
|
|
|
38205
38186
|
shieldLines.push(mkLine([" no hits in your history \u2014 install proactively", chalk6.dim]));
|
|
38206
38187
|
}
|
|
38207
38188
|
const topRec = ranked.find(
|
|
38208
|
-
(r) => r.totalCatches > 0 && (
|
|
38189
|
+
(r) => r.totalCatches > 0 && isProtectiveShield(r.shieldName) && !enabledSet.has(r.shieldName)
|
|
38209
38190
|
);
|
|
38210
38191
|
const allCovered = !topRec && ranked.some(
|
|
38211
|
-
(r) => r.totalCatches > 0 && (
|
|
38192
|
+
(r) => r.totalCatches > 0 && isProtectiveShield(r.shieldName) && enabledSet.has(r.shieldName)
|
|
38212
38193
|
);
|
|
38213
38194
|
if (topRec) {
|
|
38214
38195
|
const cta = `\u2192 node9 shield enable ${topRec.shieldName} (start here \u2014 widest coverage)`;
|
|
@@ -38413,9 +38394,7 @@ function registerScanCommand(program2) {
|
|
|
38413
38394
|
process.stdout.write(JSON.stringify(envelope, null, 2) + "\n");
|
|
38414
38395
|
return;
|
|
38415
38396
|
}
|
|
38416
|
-
let scanDelta2 = null;
|
|
38417
38397
|
if (!screenshotMode) {
|
|
38418
|
-
const previous = readPreviousScan();
|
|
38419
38398
|
const currentRecord = {
|
|
38420
38399
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
38421
38400
|
score: blast.score,
|
|
@@ -38427,7 +38406,6 @@ function registerScanCommand(program2) {
|
|
|
38427
38406
|
totalCalls: scan.totalToolCalls
|
|
38428
38407
|
};
|
|
38429
38408
|
appendScanHistory(currentRecord);
|
|
38430
|
-
scanDelta2 = computeScanDelta(currentRecord, previous);
|
|
38431
38409
|
}
|
|
38432
38410
|
if (options.compact) {
|
|
38433
38411
|
renderCompactScorecard({
|
|
@@ -38466,19 +38444,9 @@ function registerScanCommand(program2) {
|
|
|
38466
38444
|
}
|
|
38467
38445
|
{
|
|
38468
38446
|
const totalRisky = scan.canaryFindings.length + totalFindings + scan.dlpFindings.length;
|
|
38469
|
-
|
|
38470
|
-
const severityDisplay = score.band === "critical" ? chalk6.red.bold(score.label) : score.color(score.label);
|
|
38471
|
-
const trendSuffix = (() => {
|
|
38472
|
-
if (!scanDelta2) return "";
|
|
38473
|
-
const { scoreDelta, daysAgo } = scanDelta2;
|
|
38474
|
-
if (scoreDelta === 0) return "";
|
|
38475
|
-
const arrow = scoreDelta > 0 ? chalk6.green(`\u25B2${scoreDelta}`) : chalk6.red(`\u25BC${Math.abs(scoreDelta)}`);
|
|
38476
|
-
const since = daysAgo === 0 ? "today" : daysAgo === 1 ? "yesterday" : `${daysAgo} days ago`;
|
|
38477
|
-
return chalk6.dim(" \xB7 ") + arrow + chalk6.dim(` since ${since}`);
|
|
38478
|
-
})();
|
|
38479
|
-
if (!useInkForHero) {
|
|
38447
|
+
if (!useInkForHero && totalRisky > 0) {
|
|
38480
38448
|
console.log(
|
|
38481
|
-
" " +
|
|
38449
|
+
" " + chalk6.red.bold(`${totalRisky} risky operation${totalRisky !== 1 ? "s" : ""}`) + chalk6.dim(" in the scanned history")
|
|
38482
38450
|
);
|
|
38483
38451
|
}
|
|
38484
38452
|
const cardParts = [];
|
|
@@ -38560,6 +38528,10 @@ function registerScanCommand(program2) {
|
|
|
38560
38528
|
keyed
|
|
38561
38529
|
});
|
|
38562
38530
|
}
|
|
38531
|
+
console.log(
|
|
38532
|
+
chalk6.dim(" Machine score: run ") + chalk6.cyan("node9 posture") + chalk6.dim(" for this machine's score and what to fix first.")
|
|
38533
|
+
);
|
|
38534
|
+
console.log("");
|
|
38563
38535
|
const cta = isWired ? "\u2705 node9 is active" : "\u2192 install node9 to enable protection";
|
|
38564
38536
|
console.log(" " + chalk6.green(cta));
|
|
38565
38537
|
console.log(
|
|
@@ -38754,6 +38726,10 @@ function registerScanCommand(program2) {
|
|
|
38754
38726
|
);
|
|
38755
38727
|
console.log("");
|
|
38756
38728
|
}
|
|
38729
|
+
console.log(
|
|
38730
|
+
chalk6.dim(" Machine score: run ") + chalk6.cyan("node9 posture") + chalk6.dim(" for this machine's score and what to fix first.")
|
|
38731
|
+
);
|
|
38732
|
+
console.log("");
|
|
38757
38733
|
if (isWired) {
|
|
38758
38734
|
console.log(chalk6.green(" \u2705 node9 is active \u2014 your future sessions are protected."));
|
|
38759
38735
|
console.log(
|
|
@@ -78214,6 +78190,7 @@ import chalk22 from "chalk";
|
|
|
78214
78190
|
import fs88 from "fs";
|
|
78215
78191
|
import path86 from "path";
|
|
78216
78192
|
import os73 from "os";
|
|
78193
|
+
init_posture();
|
|
78217
78194
|
function printAgentSection(label3, hookPairs, wrapped) {
|
|
78218
78195
|
console.log(chalk22.bold(` ${label3}`));
|
|
78219
78196
|
for (const { name, present } of hookPairs) {
|
|
@@ -78294,6 +78271,13 @@ function registerStatusCommand(program2) {
|
|
|
78294
78271
|
console.log("");
|
|
78295
78272
|
const modeLabel = levelLabel(settings.mode);
|
|
78296
78273
|
console.log(` Mode: ${modeLabel}`);
|
|
78274
|
+
const posture = await runPosture().catch(() => null);
|
|
78275
|
+
if (posture) {
|
|
78276
|
+
const tier = posture.tier === "good" ? chalk22.green("Good") : posture.tier === "at-risk" ? chalk22.yellow("At risk") : chalk22.red("Critical");
|
|
78277
|
+
console.log(
|
|
78278
|
+
` Score: ${chalk22.bold(`${posture.score}/100`)} (${tier})` + chalk22.gray(" \xB7 node9 posture for the breakdown")
|
|
78279
|
+
);
|
|
78280
|
+
}
|
|
78297
78281
|
const wsGoverned = mergedConfig.policySource === "workspace";
|
|
78298
78282
|
if (wsGoverned) {
|
|
78299
78283
|
console.log(` Policy: ${chalk22.cyan("Workspace config (app.node9.ai)")}`);
|