nexus-agents 2.173.3 → 2.173.5

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.
@@ -21,7 +21,7 @@ import {
21
21
  DEFAULT_TASK_TTL_MS,
22
22
  DEFAULT_TOOL_RATE_LIMITS,
23
23
  clampTaskTtl
24
- } from "./chunk-WJHTVYP6.js";
24
+ } from "./chunk-7GIRIDHH.js";
25
25
  import {
26
26
  executeExpert
27
27
  } from "./chunk-MBTEWGZK.js";
@@ -12438,29 +12438,33 @@ function highestConfidenceFailure(failures) {
12438
12438
  }, void 0);
12439
12439
  }
12440
12440
  function classifyExpertFailure(error, detector, taskDescription, signal) {
12441
- if (signal?.aborted === true) {
12442
- return { kind: "permanent", source: "default" };
12443
- }
12444
- if (isRetryableErrorChain(error)) {
12445
- return { kind: "transient", source: "transport" };
12446
- }
12447
- const detection = detector.detect({
12448
- messages: [{ role: "assistant", content: extractErrorMessage(error) }],
12449
- ...taskDescription !== void 0 ? { taskDescription } : {}
12450
- });
12451
- if (detection.hasFailure) {
12452
- const top = highestConfidenceFailure(detection.failures);
12453
- if (top !== void 0) {
12454
- const action = DEFAULT_RECOVERY_STRATEGIES[top.archetype].action;
12455
- return {
12456
- kind: RECOVERABLE_ACTIONS.has(action) ? "transient" : "permanent",
12457
- source: "archetype",
12458
- archetype: top.archetype,
12459
- confidence: top.confidence
12460
- };
12441
+ try {
12442
+ if (signal?.aborted === true) {
12443
+ return { kind: "permanent", source: "default" };
12444
+ }
12445
+ if (isRetryableErrorChain(error)) {
12446
+ return { kind: "transient", source: "transport" };
12447
+ }
12448
+ const detection = detector.detect({
12449
+ messages: [{ role: "assistant", content: extractErrorMessage(error) }],
12450
+ ...taskDescription !== void 0 ? { taskDescription } : {}
12451
+ });
12452
+ if (detection.hasFailure) {
12453
+ const top = highestConfidenceFailure(detection.failures);
12454
+ if (top !== void 0) {
12455
+ const action = DEFAULT_RECOVERY_STRATEGIES[top.archetype].action;
12456
+ return {
12457
+ kind: RECOVERABLE_ACTIONS.has(action) ? "transient" : "permanent",
12458
+ source: "archetype",
12459
+ archetype: top.archetype,
12460
+ confidence: top.confidence
12461
+ };
12462
+ }
12461
12463
  }
12464
+ return { kind: "permanent", source: "default" };
12465
+ } catch {
12466
+ return { kind: "permanent", source: "default" };
12462
12467
  }
12463
- return { kind: "permanent", source: "default" };
12464
12468
  }
12465
12469
  function mergeRecoveryConfig(policy) {
12466
12470
  return {
@@ -12533,27 +12537,47 @@ var RecoverableExpert = class extends Expert {
12533
12537
  return lastClassification.kind === "transient";
12534
12538
  },
12535
12539
  onRetry: (info) => {
12536
- this.recoveryLogger.info("Expert execution retry", {
12537
- expertId: this.expertConfig.id,
12538
- attempt: info.attempt,
12539
- delayMs: info.delayMs,
12540
- classification: lastClassification?.kind,
12541
- source: lastClassification?.source,
12542
- archetype: lastClassification?.archetype
12543
- });
12544
- if (lastClassification?.source === "archetype" && lastClassification.archetype !== void 0) {
12545
- currentTask = this.injectRecoveryGuidance(
12546
- currentTask,
12547
- lastClassification.archetype,
12548
- info
12549
- );
12550
- }
12540
+ currentTask = this.handleRetry(info, lastClassification, currentTask);
12551
12541
  }
12552
12542
  }
12553
12543
  );
12554
12544
  if (outcome.ok) return ok(outcome.value);
12555
12545
  return err(this.annotateExhausted(outcome.error, currentTask, signal));
12556
12546
  }
12547
+ /**
12548
+ * Per-retry callback: logs the attempt and, for a recoverable archetype,
12549
+ * injects archetype-specific guidance into the next attempt's task.
12550
+ *
12551
+ * Returns the (possibly augmented) task. onRetry runs INSIDE withRetry's catch
12552
+ * but is NOT itself try-guarded (adapters/retry.ts:352-359 — the try wraps only
12553
+ * `operation()`), so a throw here would escape withRetry and reject the Promise.
12554
+ * The guidance path re-reads the error (extractErrorMessage) and calls
12555
+ * detector.detect, so a pathological error (#4303 throwing getter) could throw —
12556
+ * guard it: on failure, skip injection and retry with the un-augmented task.
12557
+ */
12558
+ handleRetry(info, classification, currentTask) {
12559
+ this.recoveryLogger.info("Expert execution retry", {
12560
+ expertId: this.expertConfig.id,
12561
+ attempt: info.attempt,
12562
+ delayMs: info.delayMs,
12563
+ classification: classification?.kind,
12564
+ source: classification?.source,
12565
+ archetype: classification?.archetype
12566
+ });
12567
+ if (classification?.source !== "archetype" || classification.archetype === void 0) {
12568
+ return currentTask;
12569
+ }
12570
+ try {
12571
+ return this.injectRecoveryGuidance(currentTask, classification.archetype, info);
12572
+ } catch (guidanceError) {
12573
+ this.recoveryLogger.warn("Skipping recovery guidance injection (threw)", {
12574
+ expertId: this.expertConfig.id,
12575
+ archetype: classification.archetype,
12576
+ error: getErrorMessage(guidanceError)
12577
+ });
12578
+ return currentTask;
12579
+ }
12580
+ }
12557
12581
  /**
12558
12582
  * Builds the annotated failure returned when recovery is exhausted. withRetry
12559
12583
  * skips isRetryable on the final attempt, so the per-attempt `lastClassification`
@@ -46510,11 +46534,15 @@ function buildPrReviewRecord(input) {
46510
46534
  };
46511
46535
  return { ...payload, hash: computePrReviewRecordHash(payload) };
46512
46536
  }
46513
- function resolvePrReviewRecordsPath() {
46537
+ function resolvePrReviewRecordsPath(repoPathOverride) {
46514
46538
  const envPath = process.env[PR_REVIEW_RECORDS_PATH_ENV];
46515
46539
  if (envPath !== void 0 && envPath.trim() !== "") {
46516
46540
  return isAbsolute(envPath) ? envPath : resolve13(envPath);
46517
46541
  }
46542
+ if (repoPathOverride !== void 0 && repoPathOverride.trim() !== "") {
46543
+ const overrideRoot = findRepoRoot(repoPathOverride);
46544
+ if (overrideRoot !== null) return join9(overrideRoot, PR_REVIEW_RECORDS_REL_PATH);
46545
+ }
46518
46546
  const root = findRepoRoot(process.cwd());
46519
46547
  if (root === null) return void 0;
46520
46548
  return join9(root, PR_REVIEW_RECORDS_REL_PATH);
@@ -46553,7 +46581,7 @@ function readPrReviewLedgerTip(filePath, logger58) {
46553
46581
  }
46554
46582
  function persistPrReviewRecord(opts) {
46555
46583
  const logger58 = opts.logger ?? createLogger({ component: "pr-review-record-store" });
46556
- const filePath = opts.filePath ?? resolvePrReviewRecordsPath();
46584
+ const filePath = opts.filePath ?? resolvePrReviewRecordsPath(opts.repoPathOverride);
46557
46585
  if (filePath === void 0) {
46558
46586
  logger58.warn("Cannot persist pr-review record: no records path resolved", {
46559
46587
  prNumber: opts.prNumber
@@ -46610,6 +46638,9 @@ function buildAndPersist(prNumber, baseSha, args) {
46610
46638
  total: reviewCount
46611
46639
  },
46612
46640
  summary: `${aggregate.decision} (${String(counts.approveCount)} approve / ${String(counts.requestChangesCount)} request_changes / ${String(counts.abstainCount)} abstain) \u2014 ${input.prTitle}${coverageSuffix}`,
46641
+ // #4278: lets a caller (e.g. an MCP server whose cwd has no `.git`
46642
+ // ancestor) say where the repo is, so the record isn't silently dropped.
46643
+ ...input.repoPath !== void 0 ? { repoPathOverride: input.repoPath } : {},
46613
46644
  logger: logger58
46614
46645
  });
46615
46646
  if (record === void 0) {
@@ -46791,6 +46822,45 @@ function applyPartialCoverageGate(aggregate, coverage) {
46791
46822
  return aggregate;
46792
46823
  }
46793
46824
 
46825
+ // src/mcp/tools/pr-review-result-mapping.ts
46826
+ function resolveFindings(result) {
46827
+ const raw = result.vote.findings;
46828
+ if (raw !== void 0 && raw.length > 0) {
46829
+ return raw.map((f) => ({
46830
+ summary: f.summary,
46831
+ location: f.location,
46832
+ severity: f.severity,
46833
+ gate: f.gate,
46834
+ claim: f.claim,
46835
+ verified: isFindingVerified(f.gate)
46836
+ }));
46837
+ }
46838
+ return parseFindings(result.vote.reasoning);
46839
+ }
46840
+ function toPrReviewVote(result) {
46841
+ return {
46842
+ role: result.role,
46843
+ decision: mapVoteDecisionToPrDecision(result.vote.decision),
46844
+ confidence: result.vote.confidence,
46845
+ reasoning: result.vote.reasoning,
46846
+ findings: resolveFindings(result),
46847
+ source: result.source,
46848
+ cli: result.cli,
46849
+ processingTimeMs: result.processingTimeMs,
46850
+ ...result.error !== void 0 && { errorMessage: result.error }
46851
+ };
46852
+ }
46853
+ function summarizeReviews(reviews) {
46854
+ return {
46855
+ approveCount: reviews.filter((r) => r.source !== "error" && r.decision === "approve").length,
46856
+ requestChangesCount: reviews.filter(
46857
+ (r) => r.source !== "error" && r.decision === "request_changes"
46858
+ ).length,
46859
+ abstainCount: reviews.filter((r) => r.source !== "error" && r.decision === "abstain").length,
46860
+ errorCount: reviews.filter((r) => r.source === "error").length
46861
+ };
46862
+ }
46863
+
46794
46864
  // src/mcp/tools/pr-review-tool.ts
46795
46865
  var PR_REVIEW_ROLES = [
46796
46866
  "architect",
@@ -46830,6 +46900,9 @@ var PrReviewInputSchema = z93.object({
46830
46900
  baseSha: z93.string().regex(/^[0-9a-f]{40}$/, "baseSha must be a 40-char lowercase hex commit sha").optional().describe(
46831
46901
  "40-hex base commit sha the reviewed diff was computed from (Option-C binding, #4031)"
46832
46902
  ),
46903
+ repoPath: z93.string().max(1024).optional().describe(
46904
+ "Repo root path for persisting the governance pr-review record (overrides cwd auto-detection). Must contain a .git ancestor \u2014 relative paths are resolved against cwd; ignored (falls back to cwd auto-detection) if it is not a real repo root. Env NEXUS_PR_REVIEW_RECORDS_PATH still takes precedence and is unrestricted."
46905
+ ),
46833
46906
  simulate: z93.boolean().default(false).describe("Use simulated voters (testing only; never ship live with this true)"),
46834
46907
  /**
46835
46908
  * Error policy (#4132). `standard` (default) keeps the pre-#4132 aggregation:
@@ -46945,43 +47018,6 @@ ${FINDINGS_FORMAT_INSTRUCTIONS}
46945
47018
  `);
46946
47019
  return parts.join("");
46947
47020
  }
46948
- function resolveFindings(result) {
46949
- const raw = result.vote.findings;
46950
- if (raw !== void 0 && raw.length > 0) {
46951
- return raw.map((f) => ({
46952
- summary: f.summary,
46953
- location: f.location,
46954
- severity: f.severity,
46955
- gate: f.gate,
46956
- claim: f.claim,
46957
- verified: isFindingVerified(f.gate)
46958
- }));
46959
- }
46960
- return parseFindings(result.vote.reasoning);
46961
- }
46962
- function toPrReviewVote(result) {
46963
- return {
46964
- role: result.role,
46965
- decision: mapVoteDecisionToPrDecision(result.vote.decision),
46966
- confidence: result.vote.confidence,
46967
- reasoning: result.vote.reasoning,
46968
- findings: resolveFindings(result),
46969
- source: result.source,
46970
- cli: result.cli,
46971
- processingTimeMs: result.processingTimeMs,
46972
- ...result.error !== void 0 && { errorMessage: result.error }
46973
- };
46974
- }
46975
- function summarizeReviews(reviews) {
46976
- return {
46977
- approveCount: reviews.filter((r) => r.source !== "error" && r.decision === "approve").length,
46978
- requestChangesCount: reviews.filter(
46979
- (r) => r.source !== "error" && r.decision === "request_changes"
46980
- ).length,
46981
- abstainCount: reviews.filter((r) => r.source !== "error" && r.decision === "abstain").length,
46982
- errorCount: reviews.filter((r) => r.source === "error").length
46983
- };
46984
- }
46985
47021
  function resolveAggregate(reviews, input, errorCount, coverage, logger58) {
46986
47022
  const preGate = aggregatePrDecisions(reviews, input.errorPolicy);
46987
47023
  if (preGate.reason !== void 0) {
@@ -54021,4 +54057,4 @@ export {
54021
54057
  shutdownFeedbackSubscriber,
54022
54058
  createEventBusBridge
54023
54059
  };
54024
- //# sourceMappingURL=chunk-GNZ2ZIT3.js.map
54060
+ //# sourceMappingURL=chunk-6YM52YW6.js.map