nexus-agents 8.126.7 → 8.126.8

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.
@@ -19,10 +19,10 @@ import {
19
19
  toolSuccessStructured,
20
20
  withProgressHeartbeat,
21
21
  wrapToolWithTimeout
22
- } from "./chunk-E5MQ3T2S.js";
22
+ } from "./chunk-VIUYADVF.js";
23
23
  import {
24
24
  VERSION
25
- } from "./chunk-6DGRFX3Z.js";
25
+ } from "./chunk-HLH2ZX2H.js";
26
26
  import {
27
27
  allOf
28
28
  } from "./chunk-EZNIYU5T.js";
@@ -9359,4 +9359,4 @@ export {
9359
9359
  CONSENSUS_VOTE_TOOL_SCHEMA,
9360
9360
  registerConsensusVoteTool
9361
9361
  };
9362
- //# sourceMappingURL=chunk-LJVK72YZ.js.map
9362
+ //# sourceMappingURL=chunk-4GBV353B.js.map
@@ -16,7 +16,7 @@ import {
16
16
  VERSION,
17
17
  isNodeVersionSupported,
18
18
  recordServerTransport
19
- } from "./chunk-6DGRFX3Z.js";
19
+ } from "./chunk-HLH2ZX2H.js";
20
20
  import {
21
21
  allOf,
22
22
  anyOf
@@ -1525,7 +1525,7 @@ async function runDoctorFix(result) {
1525
1525
  writeLine2("\u2500".repeat(40));
1526
1526
  let fixCount = 0;
1527
1527
  if (!result.dataDirectory.rootExists || result.dataDirectory.subdirectories.some((d) => !d.exists || !d.writable)) {
1528
- const { initDataDirectories: initDataDirectories2, describeDataDirFix: describeDataDirFix2 } = await import("./setup-data-dir-IPQWYMYN.js");
1528
+ const { initDataDirectories: initDataDirectories2, describeDataDirFix: describeDataDirFix2 } = await import("./setup-data-dir-A2SL5GPT.js");
1529
1529
  const outcome = describeDataDirFix2(initDataDirectories2());
1530
1530
  writeLine2(outcome.line);
1531
1531
  if (outcome.counted) fixCount++;
@@ -1627,4 +1627,4 @@ export {
1627
1627
  startStdioServer,
1628
1628
  closeServer
1629
1629
  };
1630
- //# sourceMappingURL=chunk-LOVFYJRO.js.map
1630
+ //# sourceMappingURL=chunk-EAHEHACP.js.map
@@ -4,7 +4,7 @@ import {
4
4
 
5
5
  // src/version.ts
6
6
  import semver from "semver";
7
- var VERSION = true ? "8.126.7" : "dev";
7
+ var VERSION = true ? "8.126.8" : "dev";
8
8
  var NODE_ENGINE_RANGE = ">=22.5.0";
9
9
  function isNodeVersionSupported(version) {
10
10
  return semver.satisfies(version, NODE_ENGINE_RANGE);
@@ -106,4 +106,4 @@ export {
106
106
  contextForLogging,
107
107
  measuredTrustTier
108
108
  };
109
- //# sourceMappingURL=chunk-6DGRFX3Z.js.map
109
+ //# sourceMappingURL=chunk-HLH2ZX2H.js.map
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-GKVLVN3L.js";
10
10
  import {
11
11
  withPrerequisite
12
- } from "./chunk-2MLSLRGF.js";
12
+ } from "./chunk-V3XRPKI4.js";
13
13
  import {
14
14
  generateSecurityPlan
15
15
  } from "./chunk-JRKVQTG6.js";
@@ -41,7 +41,7 @@ import {
41
41
  import {
42
42
  DEFAULT_TASK_TTL_MS,
43
43
  clampTaskTtl
44
- } from "./chunk-LOVFYJRO.js";
44
+ } from "./chunk-EAHEHACP.js";
45
45
  import {
46
46
  executeExpert
47
47
  } from "./chunk-7PS44443.js";
@@ -96,7 +96,7 @@ import {
96
96
  withFileLock,
97
97
  withWarnings,
98
98
  writeJobCancelled
99
- } from "./chunk-LJVK72YZ.js";
99
+ } from "./chunk-4GBV353B.js";
100
100
  import {
101
101
  NOOP_NOTIFIER,
102
102
  RateLimiter,
@@ -122,12 +122,12 @@ import {
122
122
  toolSuccessStructured,
123
123
  withProgressHeartbeat,
124
124
  wrapToolWithTimeout
125
- } from "./chunk-E5MQ3T2S.js";
125
+ } from "./chunk-VIUYADVF.js";
126
126
  import {
127
127
  VERSION,
128
128
  createRequestContext,
129
129
  measuredTrustTier
130
- } from "./chunk-6DGRFX3Z.js";
130
+ } from "./chunk-HLH2ZX2H.js";
131
131
  import {
132
132
  allOf,
133
133
  anyOf
@@ -45855,6 +45855,8 @@ var PrReviewRecordSchema = z98.object({
45855
45855
  voteCounts: PrReviewVoteCountsSchema,
45856
45856
  /** Truncated human-readable review summary for the reviewer record. */
45857
45857
  summary: z98.string(),
45858
+ /** Aggregate explanation; absent on older records. Hash-covered when present. */
45859
+ reason: z98.string().optional(),
45858
45860
  /** Optional correlation/decision id linking to the cost rollup / trace. */
45859
45861
  correlationId: z98.string().min(1).optional(),
45860
45862
  /**
@@ -45930,6 +45932,7 @@ function computePrReviewRecordHash(payload) {
45930
45932
  total: payload.voteCounts.total
45931
45933
  },
45932
45934
  summary: payload.summary,
45935
+ ...payload.reason !== void 0 ? { reason: payload.reason } : {},
45933
45936
  correlationId: payload.correlationId ?? null,
45934
45937
  // #4459 provenance, INSIDE the hash. This projection is an explicit
45935
45938
  // allowlist, so a schema field omitted here would sit OUTSIDE
@@ -45978,8 +45981,10 @@ import { dirname as dirname3, isAbsolute as isAbsolute2, join as join10, resolve
45978
45981
  var PR_REVIEW_RECORDS_REL_PATH = "governance/pr-review-records.jsonl";
45979
45982
  var PR_REVIEW_RECORDS_PATH_ENV = "NEXUS_PR_REVIEW_RECORDS_PATH";
45980
45983
  var MAX_SUMMARY_RECORD_CHARS = 500;
45984
+ function truncatePrReviewSummary(summary) {
45985
+ return summary.length > MAX_SUMMARY_RECORD_CHARS ? summary.slice(0, MAX_SUMMARY_RECORD_CHARS) + "..." : summary;
45986
+ }
45981
45987
  function buildPrReviewRecord(input) {
45982
- const summaryTruncated = input.summary.length > MAX_SUMMARY_RECORD_CHARS ? input.summary.slice(0, MAX_SUMMARY_RECORD_CHARS) + "..." : input.summary;
45983
45988
  const payload = {
45984
45989
  version: "1.4",
45985
45990
  sequence: input.sequence ?? 0,
@@ -45996,7 +46001,8 @@ function buildPrReviewRecord(input) {
45996
46001
  error: input.voteCounts.error,
45997
46002
  total: input.voteCounts.total
45998
46003
  },
45999
- summary: summaryTruncated,
46004
+ summary: truncatePrReviewSummary(input.summary),
46005
+ ...input.reason !== void 0 ? { reason: input.reason } : {},
46000
46006
  ...input.diffProvenance !== void 0 ? { diffProvenance: input.diffProvenance } : {},
46001
46007
  ...input.sanitization !== void 0 ? { sanitization: input.sanitization } : {},
46002
46008
  ...input.coverage !== void 0 ? { coverage: input.coverage } : {},
@@ -47054,7 +47060,7 @@ function buildVotingInput(plan, config) {
47054
47060
  }
47055
47061
  async function executeSingleVote(plan, config, log) {
47056
47062
  try {
47057
- const { executeVoting } = await import("./consensus-vote-VPIKEDTH.js");
47063
+ const { executeVoting } = await import("./consensus-vote-BIY6PV6F.js");
47058
47064
  const input = buildVotingInput(plan, config);
47059
47065
  const result = await executeVoting(input, log);
47060
47066
  return parseVotingResult(result);
@@ -48201,7 +48207,7 @@ function createVoteStage({ config, startStage }) {
48201
48207
  const strategy = config.votingStrategy ?? "higher_order";
48202
48208
  await postProgress(config, "Vote", `Running consensus with ${strategy} strategy...`);
48203
48209
  try {
48204
- const { executeVoting } = await import("./consensus-vote-VPIKEDTH.js");
48210
+ const { executeVoting } = await import("./consensus-vote-BIY6PV6F.js");
48205
48211
  const proposal = buildVoteProposal(plan, research);
48206
48212
  const votingResult = await executeVoting(
48207
48213
  {
@@ -49859,7 +49865,37 @@ function createAuditStageRegistry() {
49859
49865
  }
49860
49866
 
49861
49867
  // src/mcp/tools/pr-review-findings.ts
49868
+ import { posix } from "node:path";
49862
49869
  import { parse as parseYaml3 } from "yaml";
49870
+ function findingsAgree(left, right, leftRole, rightRole, repoPath) {
49871
+ if (leftRole === rightRole || !left.verified || !right.verified) return false;
49872
+ const a = normalizeFindingLocation(left.location, repoPath);
49873
+ const b = normalizeFindingLocation(right.location, repoPath);
49874
+ return a !== void 0 && a.file === b?.file && a.start <= b.end + 3 && b.start <= a.end + 3;
49875
+ }
49876
+ function normalizeFindingLocation(location, repoPath) {
49877
+ const citation = location.trim().replace(/^`(.*)`$/, "$1").replaceAll("\\", "/");
49878
+ const match = /^(.+?):L?(\d+)(?:-L?(\d+))?(?::\d+)?$/.exec(citation);
49879
+ if (match === null) return void 0;
49880
+ const file = normalizeFindingPath(match[1]?.trim() ?? "", repoPath);
49881
+ const lines = parseFindingLines(match[2], match[3]);
49882
+ if (file === void 0 || lines === void 0) return void 0;
49883
+ return { file, ...lines };
49884
+ }
49885
+ function parseFindingLines(startText, endText) {
49886
+ const start = Number(startText);
49887
+ const end = Number(endText ?? startText);
49888
+ if (!Number.isSafeInteger(start) || start < 1 || !Number.isSafeInteger(end) || end < start)
49889
+ return void 0;
49890
+ return { start, end };
49891
+ }
49892
+ function normalizeFindingPath(path9, repoPath) {
49893
+ if (path9 === "") return void 0;
49894
+ const root = repoPath ?? findRepoRoot(process.cwd()) ?? process.cwd();
49895
+ const file = posix.isAbsolute(path9) ? posix.relative(root.replaceAll("\\", "/"), path9) : posix.normalize(path9).replace(/^[ab]\//, "");
49896
+ if (file === "" || file === "." || file.endsWith("/")) return void 0;
49897
+ return file;
49898
+ }
49863
49899
  function isFindingVerified(gate) {
49864
49900
  if (gate.reread_cited_line !== "passed") return false;
49865
49901
  if (gate.traced_call_path !== "passed") return false;
@@ -50357,6 +50393,7 @@ function buildAndPersist(prNumber, baseSha, args) {
50357
50393
  ...disclosure !== void 0 ? { sanitization: disclosure } : {},
50358
50394
  ...coverageFields ?? {},
50359
50395
  verdict: aggregate.decision,
50396
+ ...aggregate.reason !== void 0 ? { reason: aggregate.reason } : {},
50360
50397
  verified: aggregate.verified,
50361
50398
  voteCounts: {
50362
50399
  approve: counts.approveCount,
@@ -50562,45 +50599,6 @@ async function preparePanelForReview(input, roles, opts, logger58) {
50562
50599
  return { ...packed, seats };
50563
50600
  }
50564
50601
 
50565
- // src/mcp/tools/pr-review-result-mapping.ts
50566
- function resolveFindings(result) {
50567
- const raw = result.vote.findings;
50568
- if (raw !== void 0 && raw.length > 0) {
50569
- return raw.map((f) => ({
50570
- summary: f.summary,
50571
- location: f.location,
50572
- severity: f.severity,
50573
- gate: f.gate,
50574
- claim: f.claim,
50575
- verified: isFindingVerified(f.gate)
50576
- }));
50577
- }
50578
- return parseFindings(result.vote.reasoning);
50579
- }
50580
- function toPrReviewVote(result) {
50581
- return {
50582
- role: result.role,
50583
- decision: mapVoteDecisionToPrDecision(result.vote.decision),
50584
- confidence: result.vote.confidence,
50585
- reasoning: result.vote.reasoning,
50586
- findings: resolveFindings(result),
50587
- source: result.source,
50588
- cli: result.cli,
50589
- processingTimeMs: result.processingTimeMs,
50590
- ...result.error !== void 0 && { errorMessage: result.error }
50591
- };
50592
- }
50593
- function summarizeReviews(reviews) {
50594
- const judged = reviews.filter((r) => !isAbsentSeat(r));
50595
- return {
50596
- approveCount: judged.filter((r) => r.decision === "approve").length,
50597
- requestChangesCount: judged.filter((r) => r.decision === "request_changes").length,
50598
- abstainCount: judged.filter((r) => r.decision === "abstain").length,
50599
- errorCount: reviews.filter((r) => r.source === "error").length,
50600
- unverifiableCount: reviews.filter((r) => r.source === "unverifiable").length
50601
- };
50602
- }
50603
-
50604
50602
  // src/mcp/tools/pr-review-tool.ts
50605
50603
  var PR_REVIEW_ROLES = [
50606
50604
  "architect",
@@ -50681,16 +50679,14 @@ function mapVoteDecisionToPrDecision(voteDecision) {
50681
50679
  return voteDecision;
50682
50680
  }
50683
50681
  var SOFT_BLOCK_REQUEST_CHANGES_THRESHOLD = 3;
50684
- function aggregatePrDecisions(reviews, errorPolicy = "standard") {
50682
+ function aggregatePrDecisions(reviews, errorPolicy = "standard", repoPath) {
50685
50683
  const valid = reviews.filter((r) => !isAbsentSeat(r));
50686
50684
  const complete = () => valid.length === reviews.length;
50687
50685
  const incompleteReason = `incomplete panel: ${String(valid.length)} of ${String(reviews.length)} voters responded`;
50688
50686
  const panelVerdict = (decision) => complete() ? { decision, verified: true } : { decision, verified: false, reason: incompleteReason };
50689
50687
  if (valid.length === 0) return panelVerdict("abstain");
50690
- const hasVerifiedBlocker = valid.some(
50691
- (r) => r.decision === "request_changes" && r.findings.some((f) => f.verified)
50692
- );
50693
- if (hasVerifiedBlocker) return { decision: "request_changes", verified: true };
50688
+ const findingBlocker = aggregateBlockingFindings(valid, repoPath);
50689
+ if (findingBlocker !== void 0) return findingBlocker;
50694
50690
  const requestChangesVoters = valid.filter((r) => r.decision === "request_changes").length;
50695
50691
  if (requestChangesVoters >= SOFT_BLOCK_REQUEST_CHANGES_THRESHOLD) {
50696
50692
  return { decision: "request_changes", verified: false };
@@ -50699,32 +50695,20 @@ function aggregatePrDecisions(reviews, errorPolicy = "standard") {
50699
50695
  if (errorPolicy === "absolute_quorum") {
50700
50696
  return absoluteQuorumApprove(reviews, valid);
50701
50697
  }
50698
+ if (valid.length < 2)
50699
+ return {
50700
+ decision: "abstain",
50701
+ verified: false,
50702
+ reason: "insufficient reviewers: 1 reviewer; needs second reviewer"
50703
+ };
50702
50704
  return panelVerdict("approve");
50703
50705
  }
50704
50706
  return panelVerdict("abstain");
50705
50707
  }
50706
- function absoluteQuorumApprove(reviews, valid) {
50707
- const errorCount = reviews.length - valid.length;
50708
- const erroredRoles = reviews.filter(isAbsentSeat).map((r) => r.role);
50709
- const catfish = valid.find((r) => r.role === "catfish");
50710
- const catfishApproved = catfish?.decision === "approve";
50711
- const panelComplete = valid.length === PR_REVIEW_ROLES.length;
50712
- if (errorCount > 0 || !catfishApproved || !panelComplete) {
50713
- const missing = catfishApproved ? [] : ["catfish"];
50714
- const named = [...erroredRoles, ...missing];
50715
- const list = named.length > 0 ? named.join(", ") : "incomplete panel";
50716
- return {
50717
- decision: "abstain",
50718
- verified: false,
50719
- reason: `no_quorum: re-run \u2014 voter(s) [${list}] errored/missing (absolute_quorum)`
50720
- };
50721
- }
50722
- return { decision: "approve", verified: true };
50723
- }
50724
50708
  function resolveAggregate(reviews, input, absent, coverage, logger58) {
50725
- const preGate = aggregatePrDecisions(reviews, input.errorPolicy);
50709
+ const preGate = aggregatePrDecisions(reviews, input.errorPolicy, input.repoPath);
50726
50710
  if (preGate.reason !== void 0) {
50727
- logger58.warn("pr_review degraded to no_quorum under absolute_quorum (#4132)", {
50711
+ logger58.warn("pr_review aggregate is unverified", {
50728
50712
  reason: preGate.reason,
50729
50713
  absentCount: absent.errorCount + absent.unverifiableCount,
50730
50714
  errorCount: absent.errorCount,
@@ -50785,6 +50769,7 @@ async function executePrReviewBody(input, logger58, opts = {}) {
50785
50769
  });
50786
50770
  const response = {
50787
50771
  summary: aggregate.decision,
50772
+ ...aggregate.reason !== void 0 ? { reason: aggregate.reason } : {},
50788
50773
  verified: aggregate.verified,
50789
50774
  ...counts,
50790
50775
  reviews,
@@ -50895,6 +50880,103 @@ function registerPrReviewTool(server, deps) {
50895
50880
  logger58.info("Registered pr_review tool");
50896
50881
  }
50897
50882
 
50883
+ // src/mcp/tools/pr-review-result-mapping.ts
50884
+ function resolveFindings(result) {
50885
+ const raw = result.vote.findings;
50886
+ if (raw !== void 0 && raw.length > 0) {
50887
+ return raw.map((f) => ({
50888
+ summary: f.summary,
50889
+ location: f.location,
50890
+ severity: f.severity,
50891
+ gate: f.gate,
50892
+ claim: f.claim,
50893
+ verified: isFindingVerified(f.gate)
50894
+ }));
50895
+ }
50896
+ return parseFindings(result.vote.reasoning);
50897
+ }
50898
+ function toPrReviewVote(result) {
50899
+ return {
50900
+ role: result.role,
50901
+ decision: mapVoteDecisionToPrDecision(result.vote.decision),
50902
+ confidence: result.vote.confidence,
50903
+ reasoning: result.vote.reasoning,
50904
+ findings: resolveFindings(result),
50905
+ source: result.source,
50906
+ cli: result.cli,
50907
+ processingTimeMs: result.processingTimeMs,
50908
+ ...result.error !== void 0 && { errorMessage: result.error }
50909
+ };
50910
+ }
50911
+ function summarizeReviews(reviews) {
50912
+ const judged = reviews.filter((r) => !isAbsentSeat(r));
50913
+ return {
50914
+ approveCount: judged.filter((r) => r.decision === "approve").length,
50915
+ requestChangesCount: judged.filter((r) => r.decision === "request_changes").length,
50916
+ abstainCount: judged.filter((r) => r.decision === "abstain").length,
50917
+ errorCount: reviews.filter((r) => r.source === "error").length,
50918
+ unverifiableCount: reviews.filter((r) => r.source === "unverifiable").length
50919
+ };
50920
+ }
50921
+ function formatFindingLocation(location, maxChars) {
50922
+ const sanitized = location.replace(/[\p{Cc}\u2028\u2029]+/gu, " ").replace(/`/g, "'").slice(0, maxChars);
50923
+ return `\`${sanitized}\``;
50924
+ }
50925
+ function describeUnconfirmedFindings(reviewers) {
50926
+ const first = reviewers[0];
50927
+ if (first === void 0) return "";
50928
+ const lone = reviewers.length === 1;
50929
+ const prefix = lone ? `unconfirmed: 1 reviewer (${first.role}) at ` : `unconfirmed: ${String(reviewers.length)} reviewers (`;
50930
+ const suffix = lone ? "; needs second reviewer" : ") found non-overlapping issues; needs agreement";
50931
+ const locations = (maxChars) => reviewers.map(
50932
+ ({ role, finding }) => lone ? formatFindingLocation(finding.location, maxChars) : `${role} at ${formatFindingLocation(finding.location, maxChars)}`
50933
+ ).join(", ");
50934
+ const available = MAX_SUMMARY_RECORD_CHARS - prefix.length - suffix.length - locations(0).length;
50935
+ const locationLimit = Math.min(120, Math.floor(available / reviewers.length));
50936
+ return `${prefix}${locations(locationLimit)}${suffix}`;
50937
+ }
50938
+ function aggregateBlockingFindings(valid, repoPath) {
50939
+ const blockers = valid.filter((r) => r.decision === "request_changes").flatMap(
50940
+ (r) => r.findings.filter((f) => f.verified).map((finding) => ({ role: r.role, finding }))
50941
+ );
50942
+ const first = blockers[0];
50943
+ if (first === void 0) return void 0;
50944
+ for (const [index, left] of blockers.entries()) {
50945
+ for (const right of blockers.slice(index + 1)) {
50946
+ if (findingsAgree(left.finding, right.finding, left.role, right.role, repoPath)) {
50947
+ return { decision: "request_changes", verified: true };
50948
+ }
50949
+ }
50950
+ }
50951
+ const reviewers = /* @__PURE__ */ new Map();
50952
+ for (const blocker of blockers) {
50953
+ if (!reviewers.has(blocker.role)) reviewers.set(blocker.role, blocker);
50954
+ }
50955
+ return {
50956
+ decision: "request_changes",
50957
+ verified: false,
50958
+ reason: describeUnconfirmedFindings([...reviewers.values()])
50959
+ };
50960
+ }
50961
+ function absoluteQuorumApprove(reviews, valid) {
50962
+ const errorCount = reviews.length - valid.length;
50963
+ const erroredRoles = reviews.filter(isAbsentSeat).map((r) => r.role);
50964
+ const catfish = valid.find((r) => r.role === "catfish");
50965
+ const catfishApproved = catfish?.decision === "approve";
50966
+ const panelComplete = valid.length === PR_REVIEW_ROLES.length;
50967
+ if (errorCount > 0 || !catfishApproved || !panelComplete) {
50968
+ const missing = catfishApproved ? [] : ["catfish"];
50969
+ const named = [...erroredRoles, ...missing];
50970
+ const list = named.length > 0 ? named.join(", ") : "incomplete panel";
50971
+ return {
50972
+ decision: "abstain",
50973
+ verified: false,
50974
+ reason: `no_quorum: re-run \u2014 voter(s) [${list}] errored/missing (absolute_quorum)`
50975
+ };
50976
+ }
50977
+ return { decision: "approve", verified: true };
50978
+ }
50979
+
50898
50980
  // src/mcp/tools/survey-oss-landscape.ts
50899
50981
  import { z as z103 } from "zod";
50900
50982
  var SurveyOssLandscapeInputSchema = z103.object({
@@ -57736,6 +57818,7 @@ export {
57736
57818
  registerRunTool,
57737
57819
  registerListAvailableModelsTool,
57738
57820
  buildPrReviewProposal,
57821
+ toPrReviewVote,
57739
57822
  PR_REVIEW_ROLES,
57740
57823
  MAX_DIFF_LENGTH,
57741
57824
  PrReviewInputSchema,
@@ -57762,4 +57845,4 @@ export {
57762
57845
  initializeSandbox,
57763
57846
  getSandboxMode
57764
57847
  };
57765
- //# sourceMappingURL=chunk-X5UZRBR5.js.map
57848
+ //# sourceMappingURL=chunk-PV4UOIWR.js.map