nexus-agents 2.153.0 → 2.154.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/{chunk-EJXJNWV6.js → chunk-25F6LRU2.js} +3 -3
- package/dist/{chunk-HTXQVLOI.js → chunk-6VYNHHII.js} +2 -2
- package/dist/{chunk-C6S6L5WB.js → chunk-KNVO4P4W.js} +163 -13
- package/dist/chunk-KNVO4P4W.js.map +1 -0
- package/dist/cli.js +3 -3
- package/dist/index.d.ts +56 -3
- package/dist/index.js +2 -2
- package/dist/{setup-command-4WFSYJK2.js → setup-command-OAJCXIMR.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-C6S6L5WB.js.map +0 -1
- /package/dist/{chunk-EJXJNWV6.js.map → chunk-25F6LRU2.js.map} +0 -0
- /package/dist/{chunk-HTXQVLOI.js.map → chunk-6VYNHHII.js.map} +0 -0
- /package/dist/{setup-command-4WFSYJK2.js.map → setup-command-OAJCXIMR.js.map} +0 -0
|
@@ -42,7 +42,7 @@ import {
|
|
|
42
42
|
} from "./chunk-DHVMSIT5.js";
|
|
43
43
|
|
|
44
44
|
// src/version.ts
|
|
45
|
-
var VERSION = true ? "2.
|
|
45
|
+
var VERSION = true ? "2.154.0" : "dev";
|
|
46
46
|
|
|
47
47
|
// src/config/schemas-core.ts
|
|
48
48
|
import { z } from "zod";
|
|
@@ -2132,7 +2132,7 @@ async function runDoctorFix(result) {
|
|
|
2132
2132
|
writeLine2("\u2500".repeat(40));
|
|
2133
2133
|
let fixCount = 0;
|
|
2134
2134
|
if (!result.dataDirectory.rootExists || result.dataDirectory.subdirectories.some((d) => !d.exists || !d.writable)) {
|
|
2135
|
-
const { runSetup } = await import("./setup-command-
|
|
2135
|
+
const { runSetup } = await import("./setup-command-OAJCXIMR.js");
|
|
2136
2136
|
const setupResult = runSetup({
|
|
2137
2137
|
skipMcp: true,
|
|
2138
2138
|
skipRules: true,
|
|
@@ -2245,4 +2245,4 @@ export {
|
|
|
2245
2245
|
startStdioServer,
|
|
2246
2246
|
closeServer
|
|
2247
2247
|
};
|
|
2248
|
-
//# sourceMappingURL=chunk-
|
|
2248
|
+
//# sourceMappingURL=chunk-25F6LRU2.js.map
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
checkSqlite,
|
|
9
9
|
defaultConfig,
|
|
10
10
|
initDataDirectories
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-25F6LRU2.js";
|
|
12
12
|
import {
|
|
13
13
|
BUILT_IN_EXPERTS
|
|
14
14
|
} from "./chunk-ZM4O442V.js";
|
|
@@ -2000,4 +2000,4 @@ export {
|
|
|
2000
2000
|
setupCommand,
|
|
2001
2001
|
setupCommandAsync
|
|
2002
2002
|
};
|
|
2003
|
-
//# sourceMappingURL=chunk-
|
|
2003
|
+
//# sourceMappingURL=chunk-6VYNHHII.js.map
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
DEFAULT_TASK_TTL_MS,
|
|
19
19
|
DEFAULT_TOOL_RATE_LIMITS,
|
|
20
20
|
clampTaskTtl
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-25F6LRU2.js";
|
|
22
22
|
import {
|
|
23
23
|
executeExpert
|
|
24
24
|
} from "./chunk-JYHSZDKL.js";
|
|
@@ -44328,7 +44328,8 @@ function persistPrReviewRecord(opts) {
|
|
|
44328
44328
|
|
|
44329
44329
|
// src/mcp/tools/pr-review-record-producer.ts
|
|
44330
44330
|
function buildAndPersist(prNumber, baseSha, args) {
|
|
44331
|
-
const { input, aggregate, counts, reviewCount, logger: logger58 } = args;
|
|
44331
|
+
const { input, aggregate, counts, reviewCount, logger: logger58, coverage } = args;
|
|
44332
|
+
const coverageSuffix = coverage?.partial === true ? ` [partial coverage: ${String(coverage.reviewedFiles)}/${String(coverage.totalFiles)} files reviewed, dropped: ${coverage.droppedFiles.join(", ")}]` : "";
|
|
44332
44333
|
if (reviewedDiffWasTruncated(input.prDiff)) {
|
|
44333
44334
|
logger58.warn(
|
|
44334
44335
|
"Reviewed diff exceeds the hash byte cap; content past it is unbound in reviewedDiffHash",
|
|
@@ -44348,7 +44349,7 @@ function buildAndPersist(prNumber, baseSha, args) {
|
|
|
44348
44349
|
error: counts.errorCount,
|
|
44349
44350
|
total: reviewCount
|
|
44350
44351
|
},
|
|
44351
|
-
summary: `${aggregate.decision} (${String(counts.approveCount)} approve / ${String(counts.requestChangesCount)} request_changes / ${String(counts.abstainCount)} abstain) \u2014 ${input.prTitle}`,
|
|
44352
|
+
summary: `${aggregate.decision} (${String(counts.approveCount)} approve / ${String(counts.requestChangesCount)} request_changes / ${String(counts.abstainCount)} abstain) \u2014 ${input.prTitle}${coverageSuffix}`,
|
|
44352
44353
|
logger: logger58
|
|
44353
44354
|
});
|
|
44354
44355
|
if (record === void 0) {
|
|
@@ -44403,6 +44404,133 @@ function persistReviewRecord(args) {
|
|
|
44403
44404
|
}
|
|
44404
44405
|
}
|
|
44405
44406
|
|
|
44407
|
+
// src/mcp/tools/pr-review-diff-budget.ts
|
|
44408
|
+
var SENSITIVE_PATH_PATTERNS = Object.freeze([
|
|
44409
|
+
"auth",
|
|
44410
|
+
"crypto",
|
|
44411
|
+
"secret",
|
|
44412
|
+
"credential",
|
|
44413
|
+
"security",
|
|
44414
|
+
"exec",
|
|
44415
|
+
"spawn",
|
|
44416
|
+
"password",
|
|
44417
|
+
"token",
|
|
44418
|
+
".env",
|
|
44419
|
+
"permission",
|
|
44420
|
+
"sql"
|
|
44421
|
+
]);
|
|
44422
|
+
function isSensitivePath(path12) {
|
|
44423
|
+
const lower = path12.toLowerCase();
|
|
44424
|
+
return SENSITIVE_PATH_PATTERNS.some((p) => lower.includes(p));
|
|
44425
|
+
}
|
|
44426
|
+
function byteLen(text) {
|
|
44427
|
+
return Buffer.byteLength(text, "utf-8");
|
|
44428
|
+
}
|
|
44429
|
+
function extractPath(fileText) {
|
|
44430
|
+
const nl = fileText.indexOf("\n");
|
|
44431
|
+
const firstLine = nl === -1 ? fileText : fileText.slice(0, nl);
|
|
44432
|
+
const m = /^diff --git a\/(.+?) b\/(.+)$/.exec(firstLine);
|
|
44433
|
+
if (m !== null) return m[2];
|
|
44434
|
+
return firstLine.replace(/^diff --git\s*/, "").trim();
|
|
44435
|
+
}
|
|
44436
|
+
function splitByFile(diff) {
|
|
44437
|
+
if (diff.length === 0) return [];
|
|
44438
|
+
const headerRe = /^diff --git .*$/gm;
|
|
44439
|
+
const starts = [];
|
|
44440
|
+
let m;
|
|
44441
|
+
while ((m = headerRe.exec(diff)) !== null) {
|
|
44442
|
+
starts.push(m.index);
|
|
44443
|
+
}
|
|
44444
|
+
if (starts.length === 0) {
|
|
44445
|
+
return [{ path: "(unstructured)", text: diff, bytes: byteLen(diff) }];
|
|
44446
|
+
}
|
|
44447
|
+
const files = [];
|
|
44448
|
+
const firstStart = starts[0];
|
|
44449
|
+
if (firstStart > 0) {
|
|
44450
|
+
const text = diff.slice(0, firstStart);
|
|
44451
|
+
files.push({ path: "(preamble)", text, bytes: byteLen(text) });
|
|
44452
|
+
}
|
|
44453
|
+
for (let i = 0; i < starts.length; i++) {
|
|
44454
|
+
const start = starts[i];
|
|
44455
|
+
const end = i + 1 < starts.length ? starts[i + 1] : diff.length;
|
|
44456
|
+
const text = diff.slice(start, end);
|
|
44457
|
+
files.push({ path: extractPath(text), text, bytes: byteLen(text) });
|
|
44458
|
+
}
|
|
44459
|
+
return files;
|
|
44460
|
+
}
|
|
44461
|
+
function truncateWithMarker(file, budget) {
|
|
44462
|
+
const marker = `
|
|
44463
|
+
[... TRUNCATED: file ${file.path} is ${String(file.bytes)} bytes, over the ${String(budget)}-byte review budget; showing a partial prefix \u2014 this file is listed in droppedFiles as partially-seen ...]
|
|
44464
|
+
`;
|
|
44465
|
+
const room = Math.max(0, budget - byteLen(marker));
|
|
44466
|
+
const prefix = Buffer.from(file.text, "utf-8").subarray(0, room).toString("utf-8");
|
|
44467
|
+
return prefix + marker;
|
|
44468
|
+
}
|
|
44469
|
+
function securityFirstPack(files, budget) {
|
|
44470
|
+
const sensitive = files.filter((f) => isSensitivePath(f.path));
|
|
44471
|
+
const rest = files.filter((f) => !isSensitivePath(f.path));
|
|
44472
|
+
const ordered = [...sensitive, ...rest];
|
|
44473
|
+
const segments = [];
|
|
44474
|
+
const reviewedFiles = [];
|
|
44475
|
+
const droppedFiles = [];
|
|
44476
|
+
let used = 0;
|
|
44477
|
+
for (let i = 0; i < ordered.length; i++) {
|
|
44478
|
+
const file = ordered[i];
|
|
44479
|
+
if (used + file.bytes <= budget) {
|
|
44480
|
+
segments.push(file.text);
|
|
44481
|
+
reviewedFiles.push(file.path);
|
|
44482
|
+
used += file.bytes;
|
|
44483
|
+
continue;
|
|
44484
|
+
}
|
|
44485
|
+
if (used === 0) {
|
|
44486
|
+
segments.push(truncateWithMarker(file, budget));
|
|
44487
|
+
reviewedFiles.push(file.path);
|
|
44488
|
+
droppedFiles.push(file.path);
|
|
44489
|
+
} else {
|
|
44490
|
+
droppedFiles.push(file.path);
|
|
44491
|
+
}
|
|
44492
|
+
for (let j = i + 1; j < ordered.length; j++) {
|
|
44493
|
+
droppedFiles.push(ordered[j].path);
|
|
44494
|
+
}
|
|
44495
|
+
break;
|
|
44496
|
+
}
|
|
44497
|
+
return {
|
|
44498
|
+
packed: segments.join(""),
|
|
44499
|
+
reviewedFiles,
|
|
44500
|
+
totalFiles: files.length,
|
|
44501
|
+
droppedFiles,
|
|
44502
|
+
partial: droppedFiles.length > 0
|
|
44503
|
+
};
|
|
44504
|
+
}
|
|
44505
|
+
function packDiffForReview(prDiff, budget) {
|
|
44506
|
+
if (prDiff.length <= budget) {
|
|
44507
|
+
return { coverage: void 0, packedDiff: prDiff, note: "" };
|
|
44508
|
+
}
|
|
44509
|
+
const pack = securityFirstPack(splitByFile(prDiff), budget);
|
|
44510
|
+
const coverage = {
|
|
44511
|
+
reviewedFiles: pack.reviewedFiles.length,
|
|
44512
|
+
totalFiles: pack.totalFiles,
|
|
44513
|
+
droppedFiles: pack.droppedFiles,
|
|
44514
|
+
partial: pack.partial,
|
|
44515
|
+
strategy: "budget"
|
|
44516
|
+
};
|
|
44517
|
+
const note = pack.partial ? `> NOTE: partial review \u2014 ${String(pack.reviewedFiles.length)} of ${String(pack.totalFiles)} files reviewed (security-prioritized; lowest-priority dropped): ${pack.droppedFiles.join(", ")}
|
|
44518
|
+
|
|
44519
|
+
` : "";
|
|
44520
|
+
return { coverage, packedDiff: pack.packed, note };
|
|
44521
|
+
}
|
|
44522
|
+
function applyPartialCoverageGate(aggregate, coverage) {
|
|
44523
|
+
if (coverage?.partial !== true) return aggregate;
|
|
44524
|
+
if (aggregate.decision === "approve" && aggregate.verified) {
|
|
44525
|
+
return {
|
|
44526
|
+
decision: "abstain",
|
|
44527
|
+
verified: false,
|
|
44528
|
+
reason: `no_quorum: partial diff \u2014 ${String(coverage.reviewedFiles)} of ${String(coverage.totalFiles)} files reviewed`
|
|
44529
|
+
};
|
|
44530
|
+
}
|
|
44531
|
+
return aggregate;
|
|
44532
|
+
}
|
|
44533
|
+
|
|
44406
44534
|
// src/mcp/tools/pr-review-tool.ts
|
|
44407
44535
|
var PR_REVIEW_ROLES = [
|
|
44408
44536
|
"architect",
|
|
@@ -44412,13 +44540,16 @@ var PR_REVIEW_ROLES = [
|
|
|
44412
44540
|
"scope_steward"
|
|
44413
44541
|
];
|
|
44414
44542
|
var MAX_DIFF_LENGTH = 5e4;
|
|
44543
|
+
var MAX_DIFF_INPUT_LENGTH = 2e6;
|
|
44415
44544
|
var MAX_REPO_CONTEXT_LENGTH = 2e3;
|
|
44416
44545
|
var MAX_DESCRIPTION_LENGTH = 1e4;
|
|
44417
44546
|
var PR_REVIEW_ASYNC_HINT = "A pr_review run fans out to 5 live LLM voters and can exceed the synchronous MCP request timeout. Retry with `dispatch: 'async'` to get a jobId immediately, then poll get_job_result({ jobId }) for the result.";
|
|
44418
44547
|
var PrReviewInputSchema = z91.object({
|
|
44419
44548
|
prTitle: z91.string().min(1).max(500).describe("PR title"),
|
|
44420
44549
|
prDescription: z91.string().max(MAX_DESCRIPTION_LENGTH).optional().describe("PR body / description"),
|
|
44421
|
-
prDiff: z91.string().min(1).max(
|
|
44550
|
+
prDiff: z91.string().min(1).max(MAX_DIFF_INPUT_LENGTH).describe(
|
|
44551
|
+
`Unified diff text (max ${String(MAX_DIFF_INPUT_LENGTH)} chars). No need to truncate before calling: diffs over ${String(MAX_DIFF_LENGTH)} chars are security-prioritized and PARTIALLY reviewed (lowest-priority whole files dropped; coverage reported on the response, and a partial review can block but never verified-approve).`
|
|
44552
|
+
),
|
|
44422
44553
|
repoContext: z91.string().max(MAX_REPO_CONTEXT_LENGTH).optional().describe(
|
|
44423
44554
|
`Optional one-paragraph repo context (architecture, conventions; max ${String(MAX_REPO_CONTEXT_LENGTH)} chars; trim before calling)`
|
|
44424
44555
|
),
|
|
@@ -44591,19 +44722,36 @@ function summarizeReviews(reviews) {
|
|
|
44591
44722
|
errorCount: reviews.filter((r) => r.source === "error").length
|
|
44592
44723
|
};
|
|
44593
44724
|
}
|
|
44594
|
-
function
|
|
44595
|
-
const
|
|
44596
|
-
if (
|
|
44725
|
+
function resolveAggregate(reviews, input, errorCount, coverage, logger58) {
|
|
44726
|
+
const preGate = aggregatePrDecisions(reviews, input.errorPolicy);
|
|
44727
|
+
if (preGate.reason !== void 0) {
|
|
44597
44728
|
logger58.warn("pr_review degraded to no_quorum under absolute_quorum (#4132)", {
|
|
44598
|
-
reason:
|
|
44729
|
+
reason: preGate.reason,
|
|
44599
44730
|
errorCount
|
|
44600
44731
|
});
|
|
44601
44732
|
}
|
|
44733
|
+
const aggregate = applyPartialCoverageGate(preGate, coverage);
|
|
44734
|
+
if (aggregate !== preGate) {
|
|
44735
|
+
logger58.warn(
|
|
44736
|
+
"pr_review partial review barred from verified-approve \u2014 degraded to no_quorum (#4140)",
|
|
44737
|
+
{ reason: aggregate.reason }
|
|
44738
|
+
);
|
|
44739
|
+
}
|
|
44602
44740
|
return aggregate;
|
|
44603
44741
|
}
|
|
44742
|
+
function preparePanelProposal(input, logger58) {
|
|
44743
|
+
const { coverage, packedDiff, note } = packDiffForReview(input.prDiff, MAX_DIFF_LENGTH);
|
|
44744
|
+
const body = coverage === void 0 ? input : { ...input, prDiff: packedDiff };
|
|
44745
|
+
if (coverage?.partial === true) {
|
|
44746
|
+
logger58.warn(
|
|
44747
|
+
`pr_review diff over budget \u2014 reviewed ${String(coverage.reviewedFiles)} of ${String(coverage.totalFiles)} files, dropped ${String(coverage.droppedFiles.length)}`
|
|
44748
|
+
);
|
|
44749
|
+
}
|
|
44750
|
+
return { proposal: note + buildPrReviewProposal(body), coverage };
|
|
44751
|
+
}
|
|
44604
44752
|
async function executePrReviewBody(input, logger58, gatewayAdapters) {
|
|
44605
44753
|
const start = Date.now();
|
|
44606
|
-
const proposal =
|
|
44754
|
+
const { proposal, coverage } = preparePanelProposal(input, logger58);
|
|
44607
44755
|
const voteResults = await collectRealVotes({
|
|
44608
44756
|
roles: PR_REVIEW_ROLES,
|
|
44609
44757
|
proposal,
|
|
@@ -44613,7 +44761,7 @@ async function executePrReviewBody(input, logger58, gatewayAdapters) {
|
|
|
44613
44761
|
});
|
|
44614
44762
|
const reviews = voteResults.map(toPrReviewVote);
|
|
44615
44763
|
const counts = summarizeReviews(reviews);
|
|
44616
|
-
const aggregate =
|
|
44764
|
+
const aggregate = resolveAggregate(reviews, input, counts.errorCount, coverage, logger58);
|
|
44617
44765
|
let costSummary;
|
|
44618
44766
|
try {
|
|
44619
44767
|
costSummary = recordDecisionCost({
|
|
@@ -44631,7 +44779,8 @@ async function executePrReviewBody(input, logger58, gatewayAdapters) {
|
|
|
44631
44779
|
aggregate,
|
|
44632
44780
|
counts,
|
|
44633
44781
|
reviewCount: reviews.length,
|
|
44634
|
-
logger: logger58
|
|
44782
|
+
logger: logger58,
|
|
44783
|
+
...coverage !== void 0 ? { coverage } : {}
|
|
44635
44784
|
});
|
|
44636
44785
|
const response = {
|
|
44637
44786
|
summary: aggregate.decision,
|
|
@@ -44640,7 +44789,8 @@ async function executePrReviewBody(input, logger58, gatewayAdapters) {
|
|
|
44640
44789
|
reviews,
|
|
44641
44790
|
totalDurationMs: Date.now() - start,
|
|
44642
44791
|
...costSummary !== void 0 ? { costSummary } : {},
|
|
44643
|
-
recordOutcome: recordOutcome3
|
|
44792
|
+
recordOutcome: recordOutcome3,
|
|
44793
|
+
...coverage !== void 0 ? { coverage } : {}
|
|
44644
44794
|
};
|
|
44645
44795
|
return toolSuccess(JSON.stringify(response, null, 2));
|
|
44646
44796
|
}
|
|
@@ -51296,4 +51446,4 @@ export {
|
|
|
51296
51446
|
shutdownFeedbackSubscriber,
|
|
51297
51447
|
createEventBusBridge
|
|
51298
51448
|
};
|
|
51299
|
-
//# sourceMappingURL=chunk-
|
|
51449
|
+
//# sourceMappingURL=chunk-KNVO4P4W.js.map
|