nexus-agents 4.1.1 → 4.1.3
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/{chunk-ZBLX5SPO.js → chunk-HKHOJHQO.js} +2 -2
- package/dist/{chunk-RCSHGEIL.js → chunk-MBVEKLJO.js} +3 -3
- package/dist/{chunk-UFWTULMJ.js → chunk-ZZLKJ3OB.js} +51 -11
- package/dist/{chunk-UFWTULMJ.js.map → chunk-ZZLKJ3OB.js.map} +1 -1
- package/dist/cli.js +3 -3
- package/dist/index.d.ts +10 -5
- package/dist/index.js +2 -2
- package/dist/{setup-command-S2VR7PE7.js → setup-command-HEDE6RSE.js} +3 -3
- package/package.json +1 -1
- /package/dist/{chunk-ZBLX5SPO.js.map → chunk-HKHOJHQO.js.map} +0 -0
- /package/dist/{chunk-RCSHGEIL.js.map → chunk-MBVEKLJO.js.map} +0 -0
- /package/dist/{setup-command-S2VR7PE7.js.map → setup-command-HEDE6RSE.js.map} +0 -0
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
checkSqlite,
|
|
9
9
|
defaultConfig,
|
|
10
10
|
initDataDirectories
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-MBVEKLJO.js";
|
|
12
12
|
import {
|
|
13
13
|
BUILT_IN_EXPERTS
|
|
14
14
|
} from "./chunk-YPNQPT2F.js";
|
|
@@ -2001,4 +2001,4 @@ export {
|
|
|
2001
2001
|
setupCommand,
|
|
2002
2002
|
setupCommandAsync
|
|
2003
2003
|
};
|
|
2004
|
-
//# sourceMappingURL=chunk-
|
|
2004
|
+
//# sourceMappingURL=chunk-HKHOJHQO.js.map
|
|
@@ -52,7 +52,7 @@ import {
|
|
|
52
52
|
} from "./chunk-OQLFRJCW.js";
|
|
53
53
|
|
|
54
54
|
// src/version.ts
|
|
55
|
-
var VERSION = true ? "4.1.
|
|
55
|
+
var VERSION = true ? "4.1.3" : "dev";
|
|
56
56
|
|
|
57
57
|
// src/config/schemas-core.ts
|
|
58
58
|
import { z } from "zod";
|
|
@@ -2339,7 +2339,7 @@ async function runDoctorFix(result) {
|
|
|
2339
2339
|
writeLine2("\u2500".repeat(40));
|
|
2340
2340
|
let fixCount = 0;
|
|
2341
2341
|
if (!result.dataDirectory.rootExists || result.dataDirectory.subdirectories.some((d) => !d.exists || !d.writable)) {
|
|
2342
|
-
const { runSetup } = await import("./setup-command-
|
|
2342
|
+
const { runSetup } = await import("./setup-command-HEDE6RSE.js");
|
|
2343
2343
|
const setupResult = runSetup({
|
|
2344
2344
|
skipMcp: true,
|
|
2345
2345
|
skipRules: true,
|
|
@@ -2452,4 +2452,4 @@ export {
|
|
|
2452
2452
|
startStdioServer,
|
|
2453
2453
|
closeServer
|
|
2454
2454
|
};
|
|
2455
|
-
//# sourceMappingURL=chunk-
|
|
2455
|
+
//# sourceMappingURL=chunk-MBVEKLJO.js.map
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
DEFAULT_TASK_TTL_MS,
|
|
23
23
|
DEFAULT_TOOL_RATE_LIMITS,
|
|
24
24
|
clampTaskTtl
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-MBVEKLJO.js";
|
|
26
26
|
import {
|
|
27
27
|
executeExpert
|
|
28
28
|
} from "./chunk-4Z2Z52C7.js";
|
|
@@ -44545,7 +44545,10 @@ function buildHarnessResult(planResult, tasks) {
|
|
|
44545
44545
|
tasks,
|
|
44546
44546
|
voteIterations: planResult.iterations,
|
|
44547
44547
|
qaIterations: 0,
|
|
44548
|
-
|
|
44548
|
+
// Harness mode hands the tasks back for someone else to implement, so the
|
|
44549
|
+
// scan never ran. `securityPassed: false` alone would read as a rejection.
|
|
44550
|
+
securityPassed: false,
|
|
44551
|
+
securityRan: false
|
|
44549
44552
|
};
|
|
44550
44553
|
}
|
|
44551
44554
|
async function runImplSecurityPhase(planResult, tasks, stages, sid, qualityGateMode) {
|
|
@@ -44560,7 +44563,9 @@ async function runImplSecurityPhase(planResult, tasks, stages, sid, qualityGateM
|
|
|
44560
44563
|
tasks: implResult.completedTasks.length > 0 ? implResult.completedTasks : tasks,
|
|
44561
44564
|
voteIterations: planResult.iterations,
|
|
44562
44565
|
qaIterations: implResult.totalIterations,
|
|
44563
|
-
|
|
44566
|
+
// The gate short-circuited before the scan — absence, not a verdict.
|
|
44567
|
+
securityPassed: false,
|
|
44568
|
+
securityRan: false
|
|
44564
44569
|
};
|
|
44565
44570
|
}
|
|
44566
44571
|
const security = await withStep(
|
|
@@ -44581,7 +44586,8 @@ async function runImplSecurityPhase(planResult, tasks, stages, sid, qualityGateM
|
|
|
44581
44586
|
tasks: implResult.completedTasks.length > 0 ? implResult.completedTasks : tasks,
|
|
44582
44587
|
voteIterations: planResult.iterations,
|
|
44583
44588
|
qaIterations: implResult.totalIterations,
|
|
44584
|
-
securityPassed: security.passed
|
|
44589
|
+
securityPassed: security.passed,
|
|
44590
|
+
securityRan: true
|
|
44585
44591
|
};
|
|
44586
44592
|
}
|
|
44587
44593
|
async function runQualityGateStage(stages, mode) {
|
|
@@ -48442,6 +48448,8 @@ async function loadAuditEvents(dir, logger59) {
|
|
|
48442
48448
|
const entries = await fs9.readdir(dir);
|
|
48443
48449
|
const auditFiles = entries.filter((name) => name.startsWith("audit-") && name.endsWith(".jsonl")).sort();
|
|
48444
48450
|
const events = [];
|
|
48451
|
+
let skippedLines = 0;
|
|
48452
|
+
let unreadableFiles = 0;
|
|
48445
48453
|
for (const filename of auditFiles) {
|
|
48446
48454
|
const fullPath = path8.join(dir, filename);
|
|
48447
48455
|
let content;
|
|
@@ -48450,6 +48458,7 @@ async function loadAuditEvents(dir, logger59) {
|
|
|
48450
48458
|
} catch (cause) {
|
|
48451
48459
|
const msg = cause instanceof Error ? cause.message : String(cause);
|
|
48452
48460
|
logger59.warn("Skipping unreadable audit log file", { filename, error: msg });
|
|
48461
|
+
unreadableFiles++;
|
|
48453
48462
|
continue;
|
|
48454
48463
|
}
|
|
48455
48464
|
for (const line of content.split("\n")) {
|
|
@@ -48464,14 +48473,16 @@ async function loadAuditEvents(dir, logger59) {
|
|
|
48464
48473
|
filename,
|
|
48465
48474
|
error: validated.error.message
|
|
48466
48475
|
});
|
|
48476
|
+
skippedLines++;
|
|
48467
48477
|
}
|
|
48468
48478
|
} catch (cause) {
|
|
48469
48479
|
const msg = cause instanceof Error ? cause.message : String(cause);
|
|
48470
48480
|
logger59.warn("Skipping unparseable audit event", { filename, error: msg });
|
|
48481
|
+
skippedLines++;
|
|
48471
48482
|
}
|
|
48472
48483
|
}
|
|
48473
48484
|
}
|
|
48474
|
-
return { events, fileCount: auditFiles.length };
|
|
48485
|
+
return { events, fileCount: auditFiles.length, skippedLines, unreadableFiles };
|
|
48475
48486
|
}
|
|
48476
48487
|
async function handler2(args, ctx) {
|
|
48477
48488
|
const parsed = VerifyAuditChainInputSchema.safeParse(args);
|
|
@@ -48498,12 +48509,17 @@ async function handler2(args, ctx) {
|
|
|
48498
48509
|
message: `logDir "${resolvedDir}" is not a directory`
|
|
48499
48510
|
});
|
|
48500
48511
|
}
|
|
48501
|
-
const { events, fileCount } = await loadAuditEvents(
|
|
48512
|
+
const { events, fileCount, skippedLines, unreadableFiles } = await loadAuditEvents(
|
|
48513
|
+
resolvedDir,
|
|
48514
|
+
ctx.logger
|
|
48515
|
+
);
|
|
48502
48516
|
const verification = verifyChain(events);
|
|
48503
48517
|
const response = {
|
|
48504
48518
|
logDir: resolvedDir,
|
|
48505
48519
|
fileCount,
|
|
48506
48520
|
eventCount: events.length,
|
|
48521
|
+
...skippedLines > 0 ? { skippedLines } : {},
|
|
48522
|
+
...unreadableFiles > 0 ? { unreadableFiles } : {},
|
|
48507
48523
|
verification
|
|
48508
48524
|
};
|
|
48509
48525
|
return toolSuccess(JSON.stringify(response, null, 2));
|
|
@@ -48515,7 +48531,7 @@ function registerVerifyAuditChainTool(server, deps) {
|
|
|
48515
48531
|
"Filesystem path to the FileAuditStorage log directory. Tool reads all `audit-*.jsonl` files and verifies the combined hash chain."
|
|
48516
48532
|
)
|
|
48517
48533
|
};
|
|
48518
|
-
const description = "Verify the hash chain of a persisted FileAuditStorage audit log. Reads all `audit-*.jsonl` files in the given directory, parses events, and runs `verifyChain()` to detect tampering. Returns a structured result with eventCount, fileCount, and one of three tamper signals if detected (hash_mismatch, previous_hash_mismatch, missing_hash). Read-only \u2014 never writes or deletes events.";
|
|
48534
|
+
const description = "Verify the hash chain of a persisted FileAuditStorage audit log. Reads all `audit-*.jsonl` files in the given directory, parses events, and runs `verifyChain()` to detect tampering. Returns a structured result with eventCount, fileCount, and one of three tamper signals if detected (hash_mismatch, previous_hash_mismatch, missing_hash). Reports skippedLines/unreadableFiles when part of the log could not be read, so a verdict over a partial log is never mistaken for a complete one. Read-only \u2014 never writes or deletes events.";
|
|
48519
48535
|
const secureHandler = createSecureHandler(handler2, {
|
|
48520
48536
|
toolName: "verify_audit_chain",
|
|
48521
48537
|
rateLimiter: deps.rateLimiter,
|
|
@@ -49766,6 +49782,13 @@ function buildStructuredOutput(result, simulated) {
|
|
|
49766
49782
|
...simulated ? { simulated: true } : {},
|
|
49767
49783
|
completed: result.completed,
|
|
49768
49784
|
securityPassed: result.securityPassed,
|
|
49785
|
+
// #4772: these two are what make `completed: false` legible. Without them a
|
|
49786
|
+
// caller cannot tell a failed planner from a successful dry run, or a
|
|
49787
|
+
// security rejection from a gate that never ran — which is the whole point
|
|
49788
|
+
// of the fields. They were added to DevPipelineResult and then not listed
|
|
49789
|
+
// here, so they never reached the MCP surface.
|
|
49790
|
+
...result.securityRan !== void 0 ? { securityRan: result.securityRan } : {},
|
|
49791
|
+
...result.planStatus !== void 0 ? { planStatus: result.planStatus } : {},
|
|
49769
49792
|
voteIterations: result.voteIterations,
|
|
49770
49793
|
qaIterations: result.qaIterations,
|
|
49771
49794
|
plan: result.plan,
|
|
@@ -50237,13 +50260,26 @@ function detectEngineFailure(result) {
|
|
|
50237
50260
|
const record = result;
|
|
50238
50261
|
if (record["success"] === false) {
|
|
50239
50262
|
const detail = typeof record["error"] === "string" ? record["error"] : "no error message";
|
|
50240
|
-
return `Engine reported failure: ${detail}
|
|
50263
|
+
return { message: `Engine reported failure: ${detail}` };
|
|
50241
50264
|
}
|
|
50242
50265
|
if (record["completed"] === false) {
|
|
50243
|
-
return
|
|
50266
|
+
return { message: describeIncompletePipeline(record), detail: record };
|
|
50244
50267
|
}
|
|
50245
50268
|
return null;
|
|
50246
50269
|
}
|
|
50270
|
+
function describeIncompletePipeline(record) {
|
|
50271
|
+
const prefix = "Engine reported failure:";
|
|
50272
|
+
if (record["planStatus"] === "empty") {
|
|
50273
|
+
return `${prefix} the planner returned no plan, so nothing was built`;
|
|
50274
|
+
}
|
|
50275
|
+
if (record["securityRan"] === true) {
|
|
50276
|
+
return `${prefix} the security gate rejected the change`;
|
|
50277
|
+
}
|
|
50278
|
+
if (record["securityRan"] === false) {
|
|
50279
|
+
return `${prefix} the run stopped before the security gate, which never ran`;
|
|
50280
|
+
}
|
|
50281
|
+
return `${prefix} the dev pipeline did not complete`;
|
|
50282
|
+
}
|
|
50247
50283
|
async function executeRunBody(input, logger59, trustTier, gatewayAdapters) {
|
|
50248
50284
|
try {
|
|
50249
50285
|
const exec2 = await executeGoal(input, {
|
|
@@ -50262,7 +50298,11 @@ async function executeRunBody(input, logger59, trustTier, gatewayAdapters) {
|
|
|
50262
50298
|
decisionId: exec2.decisionId,
|
|
50263
50299
|
strategy: exec2.strategy
|
|
50264
50300
|
});
|
|
50265
|
-
return toolStructuredError({
|
|
50301
|
+
return toolStructuredError({
|
|
50302
|
+
errorCategory: "business",
|
|
50303
|
+
message: engineFailure.message,
|
|
50304
|
+
...engineFailure.detail !== void 0 ? { detail: engineFailure.detail } : {}
|
|
50305
|
+
});
|
|
50266
50306
|
}
|
|
50267
50307
|
return toolSuccess(JSON.stringify(exec2, null, 2));
|
|
50268
50308
|
} catch (err2) {
|
|
@@ -54416,4 +54456,4 @@ export {
|
|
|
54416
54456
|
shutdownFeedbackSubscriber,
|
|
54417
54457
|
createEventBusBridge
|
|
54418
54458
|
};
|
|
54419
|
-
//# sourceMappingURL=chunk-
|
|
54459
|
+
//# sourceMappingURL=chunk-ZZLKJ3OB.js.map
|