nexus-agents 2.173.8 → 2.173.10

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.
Files changed (123) hide show
  1. package/dist/{child-mcp-config-RSM4VNFS.js → child-mcp-config-WQVDBGZB.js} +2 -2
  2. package/dist/{chunk-KLAVOOWV.js → chunk-56TPDTB2.js} +2 -2
  3. package/dist/{chunk-XPZODTJ6.js → chunk-5VIDSQT4.js} +2 -2
  4. package/dist/{chunk-6N2WQBJU.js → chunk-64EFIWQL.js} +2 -2
  5. package/dist/{chunk-6XMMFCL3.js → chunk-AFSP4TRS.js} +4 -4
  6. package/dist/chunk-AFSP4TRS.js.map +1 -0
  7. package/dist/{chunk-BGKDC7P5.js → chunk-AHILMXB6.js} +2 -2
  8. package/dist/{chunk-VSDI6ASO.js → chunk-AOBRDEJ4.js} +44 -9
  9. package/dist/{chunk-VSDI6ASO.js.map → chunk-AOBRDEJ4.js.map} +1 -1
  10. package/dist/{chunk-NBLCQBR5.js → chunk-AUGARRKD.js} +11 -8
  11. package/dist/{chunk-NBLCQBR5.js.map → chunk-AUGARRKD.js.map} +1 -1
  12. package/dist/{chunk-ATQZERNG.js → chunk-C5IR3XJF.js} +2 -2
  13. package/dist/{chunk-PL57P5LU.js → chunk-C7PQYGIU.js} +4 -4
  14. package/dist/{chunk-YBTBVOVA.js → chunk-CBE4PSYN.js} +4 -4
  15. package/dist/{chunk-XC37XDMH.js → chunk-CEKLFPLW.js} +2 -2
  16. package/dist/{chunk-WAYGXUSM.js → chunk-CQ77TF4Y.js} +1 -1
  17. package/dist/chunk-CQ77TF4Y.js.map +1 -0
  18. package/dist/{chunk-3ZLPS4XC.js → chunk-CYUQQOX5.js} +3 -3
  19. package/dist/{chunk-FVSXYMVW.js → chunk-DLZIL5ZF.js} +3 -3
  20. package/dist/{chunk-GWDGD7GY.js → chunk-E2JBXM62.js} +2 -2
  21. package/dist/{chunk-6WYBSYJ2.js → chunk-ELRDAKU5.js} +3 -3
  22. package/dist/{chunk-V34YWUSC.js → chunk-ELVQNEVY.js} +2 -2
  23. package/dist/{chunk-D6MTIPFD.js → chunk-EO5PS63E.js} +2 -2
  24. package/dist/{chunk-6VT7ODBT.js → chunk-G4UXASR6.js} +2 -2
  25. package/dist/{chunk-7IIVYNLK.js → chunk-IBLUX4UG.js} +2 -2
  26. package/dist/{chunk-66EE7Y2F.js → chunk-KKDOJ5YZ.js} +2 -2
  27. package/dist/{chunk-Q7L6CXIO.js → chunk-KURO5UI7.js} +5 -5
  28. package/dist/{chunk-TOIBWK5Z.js → chunk-NSGH4L2G.js} +2 -2
  29. package/dist/{chunk-MREBZQA6.js → chunk-NXRZWWH5.js} +5 -5
  30. package/dist/{chunk-4IDGRIWO.js → chunk-OI3735FM.js} +3 -3
  31. package/dist/chunk-OI3735FM.js.map +1 -0
  32. package/dist/{chunk-YFTNNQMV.js → chunk-PZNOTWNI.js} +5 -5
  33. package/dist/{chunk-JYI63V47.js → chunk-Q4FKHIBF.js} +4 -4
  34. package/dist/{chunk-3PXN234X.js → chunk-RKIFS2HY.js} +45 -37
  35. package/dist/{chunk-3PXN234X.js.map → chunk-RKIFS2HY.js.map} +1 -1
  36. package/dist/{chunk-CHZF364E.js → chunk-UFGUO4ZI.js} +2 -2
  37. package/dist/{chunk-AEWJKZ5E.js → chunk-V5RQ3ILI.js} +2 -2
  38. package/dist/{chunk-H7HMKGGB.js → chunk-WG7XLXV6.js} +7 -7
  39. package/dist/{chunk-HGHPZ2W3.js → chunk-XTXUHP7P.js} +24 -9
  40. package/dist/chunk-XTXUHP7P.js.map +1 -0
  41. package/dist/{chunk-SGQOW5SD.js → chunk-XYZJBZD4.js} +4 -4
  42. package/dist/{cli-circuit-breaker-4HDWO5Z6.js → cli-circuit-breaker-YIVPZ26C.js} +3 -3
  43. package/dist/cli.js +97 -51
  44. package/dist/cli.js.map +1 -1
  45. package/dist/{composite-router-W6GXLKWB.js → composite-router-DMKVK74J.js} +2 -2
  46. package/dist/{consensus-vote-KTWHGAOH.js → consensus-vote-GVXEDT7M.js} +15 -15
  47. package/dist/{context-retriever-67M3IABW.js → context-retriever-HGJD4TIQ.js} +8 -8
  48. package/dist/{doctor-deep-NPQZPZDO.js → doctor-deep-Y7GMDARH.js} +3 -3
  49. package/dist/{expert-bridge-3AW3OHAY.js → expert-bridge-EUCGQH4Q.js} +4 -4
  50. package/dist/{factory-XSRDHJ34.js → factory-5M3ZNRDT.js} +8 -8
  51. package/dist/{factory-PIXCR3PF.js → factory-6BJFFNMR.js} +5 -5
  52. package/dist/{improvement-review-JQVHCWVU.js → improvement-review-BKAMGCYE.js} +5 -5
  53. package/dist/index.d.ts +22 -0
  54. package/dist/index.js +30 -30
  55. package/dist/{init-opencode-Q6XT7UTP.js → init-opencode-XA2EULH6.js} +5 -5
  56. package/dist/{issue-triage-JCGAF2P3.js → issue-triage-OGORL7WI.js} +6 -6
  57. package/dist/{pr-reviewer-helpers-QBETICKQ.js → pr-reviewer-helpers-LSTI7QOG.js} +5 -5
  58. package/dist/{registry-command-3SKGILCO.js → registry-command-J35FEVJO.js} +2 -2
  59. package/dist/{repo-security-plan-C5RDE3QO.js → repo-security-plan-G6YZGKSR.js} +3 -3
  60. package/dist/{research-helpers-synthesize-J4Z7MY7X.js → research-helpers-synthesize-GJVJDKYN.js} +4 -4
  61. package/dist/{routing-memory-ZZKVDP2K.js → routing-memory-G7K5DLXY.js} +2 -2
  62. package/dist/{session-memory-2QINLWDR.js → session-memory-HCGUJFPT.js} +3 -3
  63. package/dist/{setup-command-UJ5VETUJ.js → setup-command-QKJQ3KWZ.js} +13 -13
  64. package/dist/{setup-config-SUN272BA.js → setup-config-52QPZF6Y.js} +3 -3
  65. package/dist/{setup-custom-api-AEUEX4IF.js → setup-custom-api-VZENW5R3.js} +3 -3
  66. package/dist/{tool-memory-VS2GRBV3.js → tool-memory-B6FWAC27.js} +5 -5
  67. package/dist/{unified-registry-O4FIGTBJ.js → unified-registry-ZBTT4FEB.js} +9 -9
  68. package/dist/{weather-report-3FB5MXHV.js → weather-report-U5WMAJUZ.js} +2 -2
  69. package/package.json +1 -1
  70. package/dist/chunk-4IDGRIWO.js.map +0 -1
  71. package/dist/chunk-6XMMFCL3.js.map +0 -1
  72. package/dist/chunk-HGHPZ2W3.js.map +0 -1
  73. package/dist/chunk-WAYGXUSM.js.map +0 -1
  74. /package/dist/{child-mcp-config-RSM4VNFS.js.map → child-mcp-config-WQVDBGZB.js.map} +0 -0
  75. /package/dist/{chunk-KLAVOOWV.js.map → chunk-56TPDTB2.js.map} +0 -0
  76. /package/dist/{chunk-XPZODTJ6.js.map → chunk-5VIDSQT4.js.map} +0 -0
  77. /package/dist/{chunk-6N2WQBJU.js.map → chunk-64EFIWQL.js.map} +0 -0
  78. /package/dist/{chunk-BGKDC7P5.js.map → chunk-AHILMXB6.js.map} +0 -0
  79. /package/dist/{chunk-ATQZERNG.js.map → chunk-C5IR3XJF.js.map} +0 -0
  80. /package/dist/{chunk-PL57P5LU.js.map → chunk-C7PQYGIU.js.map} +0 -0
  81. /package/dist/{chunk-YBTBVOVA.js.map → chunk-CBE4PSYN.js.map} +0 -0
  82. /package/dist/{chunk-XC37XDMH.js.map → chunk-CEKLFPLW.js.map} +0 -0
  83. /package/dist/{chunk-3ZLPS4XC.js.map → chunk-CYUQQOX5.js.map} +0 -0
  84. /package/dist/{chunk-FVSXYMVW.js.map → chunk-DLZIL5ZF.js.map} +0 -0
  85. /package/dist/{chunk-GWDGD7GY.js.map → chunk-E2JBXM62.js.map} +0 -0
  86. /package/dist/{chunk-6WYBSYJ2.js.map → chunk-ELRDAKU5.js.map} +0 -0
  87. /package/dist/{chunk-V34YWUSC.js.map → chunk-ELVQNEVY.js.map} +0 -0
  88. /package/dist/{chunk-D6MTIPFD.js.map → chunk-EO5PS63E.js.map} +0 -0
  89. /package/dist/{chunk-6VT7ODBT.js.map → chunk-G4UXASR6.js.map} +0 -0
  90. /package/dist/{chunk-7IIVYNLK.js.map → chunk-IBLUX4UG.js.map} +0 -0
  91. /package/dist/{chunk-66EE7Y2F.js.map → chunk-KKDOJ5YZ.js.map} +0 -0
  92. /package/dist/{chunk-Q7L6CXIO.js.map → chunk-KURO5UI7.js.map} +0 -0
  93. /package/dist/{chunk-TOIBWK5Z.js.map → chunk-NSGH4L2G.js.map} +0 -0
  94. /package/dist/{chunk-MREBZQA6.js.map → chunk-NXRZWWH5.js.map} +0 -0
  95. /package/dist/{chunk-YFTNNQMV.js.map → chunk-PZNOTWNI.js.map} +0 -0
  96. /package/dist/{chunk-JYI63V47.js.map → chunk-Q4FKHIBF.js.map} +0 -0
  97. /package/dist/{chunk-CHZF364E.js.map → chunk-UFGUO4ZI.js.map} +0 -0
  98. /package/dist/{chunk-AEWJKZ5E.js.map → chunk-V5RQ3ILI.js.map} +0 -0
  99. /package/dist/{chunk-H7HMKGGB.js.map → chunk-WG7XLXV6.js.map} +0 -0
  100. /package/dist/{chunk-SGQOW5SD.js.map → chunk-XYZJBZD4.js.map} +0 -0
  101. /package/dist/{cli-circuit-breaker-4HDWO5Z6.js.map → cli-circuit-breaker-YIVPZ26C.js.map} +0 -0
  102. /package/dist/{composite-router-W6GXLKWB.js.map → composite-router-DMKVK74J.js.map} +0 -0
  103. /package/dist/{consensus-vote-KTWHGAOH.js.map → consensus-vote-GVXEDT7M.js.map} +0 -0
  104. /package/dist/{context-retriever-67M3IABW.js.map → context-retriever-HGJD4TIQ.js.map} +0 -0
  105. /package/dist/{doctor-deep-NPQZPZDO.js.map → doctor-deep-Y7GMDARH.js.map} +0 -0
  106. /package/dist/{expert-bridge-3AW3OHAY.js.map → expert-bridge-EUCGQH4Q.js.map} +0 -0
  107. /package/dist/{factory-PIXCR3PF.js.map → factory-5M3ZNRDT.js.map} +0 -0
  108. /package/dist/{factory-XSRDHJ34.js.map → factory-6BJFFNMR.js.map} +0 -0
  109. /package/dist/{improvement-review-JQVHCWVU.js.map → improvement-review-BKAMGCYE.js.map} +0 -0
  110. /package/dist/{init-opencode-Q6XT7UTP.js.map → init-opencode-XA2EULH6.js.map} +0 -0
  111. /package/dist/{issue-triage-JCGAF2P3.js.map → issue-triage-OGORL7WI.js.map} +0 -0
  112. /package/dist/{pr-reviewer-helpers-QBETICKQ.js.map → pr-reviewer-helpers-LSTI7QOG.js.map} +0 -0
  113. /package/dist/{registry-command-3SKGILCO.js.map → registry-command-J35FEVJO.js.map} +0 -0
  114. /package/dist/{repo-security-plan-C5RDE3QO.js.map → repo-security-plan-G6YZGKSR.js.map} +0 -0
  115. /package/dist/{research-helpers-synthesize-J4Z7MY7X.js.map → research-helpers-synthesize-GJVJDKYN.js.map} +0 -0
  116. /package/dist/{routing-memory-ZZKVDP2K.js.map → routing-memory-G7K5DLXY.js.map} +0 -0
  117. /package/dist/{session-memory-2QINLWDR.js.map → session-memory-HCGUJFPT.js.map} +0 -0
  118. /package/dist/{setup-command-UJ5VETUJ.js.map → setup-command-QKJQ3KWZ.js.map} +0 -0
  119. /package/dist/{setup-config-SUN272BA.js.map → setup-config-52QPZF6Y.js.map} +0 -0
  120. /package/dist/{setup-custom-api-AEUEX4IF.js.map → setup-custom-api-VZENW5R3.js.map} +0 -0
  121. /package/dist/{tool-memory-VS2GRBV3.js.map → tool-memory-B6FWAC27.js.map} +0 -0
  122. /package/dist/{unified-registry-O4FIGTBJ.js.map → unified-registry-ZBTT4FEB.js.map} +0 -0
  123. /package/dist/{weather-report-3FB5MXHV.js.map → weather-report-U5WMAJUZ.js.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createLogger
3
- } from "./chunk-4IDGRIWO.js";
3
+ } from "./chunk-OI3735FM.js";
4
4
  import "./chunk-AXTD4TFK.js";
5
5
  import "./chunk-DHVMSIT5.js";
6
6
  import "./chunk-ZPWHCABL.js";
@@ -60,4 +60,4 @@ export {
60
60
  generateMcpConfig,
61
61
  getDefaultAllowedTools
62
62
  };
63
- //# sourceMappingURL=child-mcp-config-RSM4VNFS.js.map
63
+ //# sourceMappingURL=child-mcp-config-WQVDBGZB.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getTimeProvider
3
- } from "./chunk-4IDGRIWO.js";
3
+ } from "./chunk-OI3735FM.js";
4
4
 
5
5
  // src/security/audit-trail.ts
6
6
  var MAX_EVENTS = 1e4;
@@ -205,4 +205,4 @@ export {
205
205
  createGraphAuditBridge,
206
206
  createAuditTrail
207
207
  };
208
- //# sourceMappingURL=chunk-KLAVOOWV.js.map
208
+ //# sourceMappingURL=chunk-56TPDTB2.js.map
@@ -8,7 +8,7 @@ import {
8
8
  getTimeProvider,
9
9
  isRateLimitText,
10
10
  ok
11
- } from "./chunk-4IDGRIWO.js";
11
+ } from "./chunk-OI3735FM.js";
12
12
 
13
13
  // src/cli-adapters/circuit-breaker-types.ts
14
14
  var CircuitErrorCode = {
@@ -540,4 +540,4 @@ export {
540
540
  CliCircuitBreakerIntegration,
541
541
  createCliCircuitBreakerIntegration
542
542
  };
543
- //# sourceMappingURL=chunk-XPZODTJ6.js.map
543
+ //# sourceMappingURL=chunk-5VIDSQT4.js.map
@@ -2,7 +2,7 @@ import {
2
2
  CACHE_TIMEOUTS,
3
3
  createLogger,
4
4
  getTimeProvider
5
- } from "./chunk-4IDGRIWO.js";
5
+ } from "./chunk-OI3735FM.js";
6
6
 
7
7
  // src/security/trust-types.ts
8
8
  import { z } from "zod";
@@ -560,4 +560,4 @@ export {
560
560
  resolveReputationGatingMode,
561
561
  gateWithReputation
562
562
  };
563
- //# sourceMappingURL=chunk-6N2WQBJU.js.map
563
+ //# sourceMappingURL=chunk-64EFIWQL.js.map
@@ -3,17 +3,17 @@ import {
3
3
  DECISION_EMOJI,
4
4
  SEVERITY_EMOJI,
5
5
  SEVERITY_ORDER2 as SEVERITY_ORDER
6
- } from "./chunk-WAYGXUSM.js";
6
+ } from "./chunk-CQ77TF4Y.js";
7
7
  import {
8
8
  assessReputation,
9
9
  gateWithReputation,
10
10
  resolveReputationGatingMode,
11
11
  sanitizeInput
12
- } from "./chunk-6N2WQBJU.js";
12
+ } from "./chunk-64EFIWQL.js";
13
13
  import {
14
14
  createLogger,
15
15
  getTimeProvider
16
- } from "./chunk-4IDGRIWO.js";
16
+ } from "./chunk-OI3735FM.js";
17
17
 
18
18
  // src/dogfooding/pr-reviewer-helpers.ts
19
19
  import { randomUUID } from "crypto";
@@ -288,4 +288,4 @@ export {
288
288
  formatReviewComment,
289
289
  createFailedReview
290
290
  };
291
- //# sourceMappingURL=chunk-6XMMFCL3.js.map
291
+ //# sourceMappingURL=chunk-AFSP4TRS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/dogfooding/pr-reviewer-helpers.ts"],"sourcesContent":["/**\n * nexus-agents/dogfooding - PR Reviewer Helpers\n *\n * Helper functions for PR review formatting and aggregation.\n *\n * @module dogfooding/pr-reviewer-helpers\n * (Source: Issue #161, Alignment Roadmap Phase 3)\n */\n\nimport { randomUUID } from 'node:crypto';\nimport type { Result } from '../core/index.js';\nimport { getTimeProvider, createLogger } from '../core/index.js';\nimport type { ScmUserMetadata } from '../scm/types.js';\nimport type {\n PRMetadata,\n PRReviewDraft,\n PRTrustAssessment,\n ExpertReviewResult,\n ReviewFinding,\n ReviewCategory,\n ReviewSeverity,\n ReviewDecision,\n} from './pr-review-types.js';\nimport {\n SEVERITY_ORDER,\n CATEGORY_DISPLAY_NAMES,\n SEVERITY_EMOJI,\n DECISION_EMOJI,\n} from './pr-review-types.js';\nimport { sanitizeInput } from '../security/input-sanitizer.js';\nimport {\n assessReputation,\n gateWithReputation,\n resolveReputationGatingMode,\n} from '../security/reputation-model.js';\nimport type {\n ReputationCache,\n ReputationGateDecision,\n ReputationAssessment,\n GitHubUserMetadata,\n} from '../security/reputation-model.js';\nimport type { ClassifyResult } from '../security/trust-classifier.js';\n\nconst repLogger = createLogger({ component: 'PRReviewer.reputation' });\n\n// =============================================================================\n// Reputation Gating Helpers (#3123, epic #3118 Phase 5)\n// =============================================================================\n\n/**\n * Best-effort account-age lookup for a PR author (#3133, Phase-3 equivalent for\n * the PR path). Returns the author's real account age in days via the provider's\n * `fetchUserMetadata`, or `undefined` on any failure (err Result, unparseable\n * `createdAt`, or an unexpected rejection) — never fabricated, never throws, so\n * the review is never blocked by this lookup.\n */\nexport async function fetchAccountAgeDays(\n provider: { fetchUserMetadata: (u: string) => Promise<Result<ScmUserMetadata, Error>> },\n username: string\n): Promise<number | undefined> {\n try {\n const result = await provider.fetchUserMetadata(username);\n if (!result.ok) return undefined;\n const createdMs = Date.parse(result.value.createdAt);\n if (!Number.isFinite(createdMs)) return undefined;\n return Math.floor((getTimeProvider().now() - createdMs) / 86_400_000);\n } catch {\n return undefined;\n }\n}\n\n/**\n * Assesses the PR author's reputation from the signals available in the PR\n * event: author association + injection flags from the (sanitized) PR body, plus\n * the author's real account age when it was fetched (#3133). `accountAgeDays` is\n * OMITTED when the lookup failed — never fabricated, so the engine skips the\n * `new_account` signal. Returns undefined when reputation is disabled.\n */\nexport function assessPRReputation(\n pr: PRMetadata,\n cache: ReputationCache,\n enableReputation: boolean,\n accountAgeDays: number | undefined\n): ReputationAssessment | undefined {\n if (!enableReputation) return undefined;\n // Only `injectionFlags` is consumed here, and injection detection is\n // role-independent — the userRole arg ('unknown') and the sanitizer's own\n // trustTier output are intentionally irrelevant to this call.\n const sanitizeResult = sanitizeInput(pr.body, 'unknown', pr.author);\n const metadata: GitHubUserMetadata = {\n username: pr.author,\n ...(accountAgeDays !== undefined ? { accountAgeDays } : {}),\n authorAssociation: pr.authorAssociation,\n injectionFlags: sanitizeResult.injectionFlags,\n };\n return assessReputation(metadata, cache);\n}\n\n/** Builds the observability assessment surfaced on the review result (#3123). */\nexport function buildPRTrustAssessment(\n trustResult: ClassifyResult,\n reputation: ReputationAssessment | undefined,\n gateDecision: ReputationGateDecision\n): PRTrustAssessment {\n // Tier-1 (owner/allowlisted) authors cannot be suspicious.\n const isTier1 = trustResult.trustTier === '1';\n return {\n trustTier: trustResult.trustTier,\n userRole: trustResult.userRole,\n isAllowlisted: trustResult.isAllowlisted,\n reputationScore: reputation?.reputationScore,\n suspiciousSignals: isTier1 ? [] : (reputation?.suspiciousSignals ?? []),\n isSuspicious: isTier1 ? false : (reputation?.isSuspicious ?? false),\n enforcedTrustTier: gateDecision.enforcedTier,\n reputationReconciledTier: gateDecision.reconciledTier,\n gatingMode: gateDecision.mode,\n };\n}\n\n/**\n * Assesses the PR author's reputation and applies the gating rollout mode\n * (#3123). Returns the gate decision (for the policy gate) and the assessment\n * surfaced on the result. A suppressed demotion (audit/off) is logged.\n */\nexport function gatePRAuthor(\n pr: PRMetadata,\n trustResult: ClassifyResult,\n accountAgeDays: number | undefined,\n cache: ReputationCache,\n enableReputation: boolean\n): { gateDecision: ReputationGateDecision; trustAssessment: PRTrustAssessment } {\n const reputation = assessPRReputation(pr, cache, enableReputation, accountAgeDays);\n const gateDecision = gateWithReputation(\n trustResult.trustTier,\n reputation,\n resolveReputationGatingMode()\n );\n if (gateDecision.demotionSuppressed) {\n repLogger.warn('Reputation demotion suppressed by gating mode (would block under enforce)', {\n prNumber: pr.number,\n author: pr.author,\n mode: gateDecision.mode,\n classifierTier: trustResult.trustTier,\n reconciledTier: gateDecision.reconciledTier,\n });\n }\n return {\n gateDecision,\n trustAssessment: buildPRTrustAssessment(trustResult, reputation, gateDecision),\n };\n}\n\n// =============================================================================\n// Parsing Helpers\n// =============================================================================\n\nexport function parseSeverity(value: unknown): ReviewSeverity {\n if (typeof value === 'string') {\n const lower = value.toLowerCase();\n if (lower in SEVERITY_ORDER) return lower as ReviewSeverity;\n }\n return 'medium';\n}\n\nexport function parseCategory(value: unknown): ReviewCategory {\n if (typeof value === 'string') {\n const lower = value.toLowerCase();\n if (lower in CATEGORY_DISPLAY_NAMES) return lower as ReviewCategory;\n }\n return 'code_quality';\n}\n\nexport function extractSummary(output: Record<string, unknown>): string {\n if (typeof output.summary === 'string') return output.summary;\n if (typeof output.content === 'string') return output.content;\n if (typeof output.message === 'string') return output.message;\n return 'Review completed';\n}\n\nexport function extractStringField(\n record: Record<string, unknown>,\n ...keys: string[]\n): string | undefined {\n for (const key of keys) {\n const value = record[key];\n if (typeof value === 'string') return value;\n }\n return undefined;\n}\n\n// =============================================================================\n// Finding Parsing\n// =============================================================================\n\nexport function parseFindings(\n output: Record<string, unknown>,\n expertId: string,\n minSeverity: ReviewSeverity\n): ReviewFinding[] {\n const minOrder = SEVERITY_ORDER[minSeverity];\n const sources = collectSources(output);\n\n const findings: ReviewFinding[] = [];\n for (const source of sources) {\n if (!Array.isArray(source)) continue;\n for (const item of source) {\n const finding = parseOneFinding(item, expertId, minOrder);\n if (finding !== null) findings.push(finding);\n }\n }\n return findings;\n}\n\nfunction collectSources(output: Record<string, unknown>): unknown[] {\n return [\n output.findings,\n output.vulnerabilities,\n output.issues,\n (output as { content?: { findings?: unknown } }).content,\n ];\n}\n\nfunction parseOneFinding(item: unknown, expertId: string, minOrder: number): ReviewFinding | null {\n if (typeof item !== 'object' || item === null) return null;\n\n const record = item as Record<string, unknown>;\n const severity = parseSeverity(record.severity);\n if (SEVERITY_ORDER[severity] < minOrder) return null;\n\n return {\n id: randomUUID(),\n category: parseCategory(record.category),\n severity,\n title: extractStringField(record, 'title', 'name') ?? 'Finding',\n description: extractStringField(record, 'description', 'message') ?? '',\n file: typeof record.file === 'string' ? record.file : undefined,\n line: typeof record.line === 'number' ? record.line : undefined,\n suggestion: typeof record.suggestion === 'string' ? record.suggestion : undefined,\n expertId,\n confidence: typeof record.confidence === 'number' ? record.confidence : 0.7,\n };\n}\n\n// =============================================================================\n// Decision Helpers\n// =============================================================================\n\nexport function determineApproval(findings: ReviewFinding[]): boolean {\n const hasBlocking = findings.some((f) => f.severity === 'critical' || f.severity === 'high');\n return !hasBlocking;\n}\n\nexport function determineDecision(\n reviews: ExpertReviewResult[],\n findings: ReviewFinding[]\n): ReviewDecision {\n const hasCritical = findings.some((f) => f.severity === 'critical');\n const hasHigh = findings.some((f) => f.severity === 'high');\n const allApproved = reviews.every((r) => r.approved);\n\n if (hasCritical) return 'request_changes';\n if (hasHigh && !allApproved) return 'request_changes';\n if (findings.length > 0) return 'comment';\n return 'approve';\n}\n\nexport function calculateConsensus(reviews: ExpertReviewResult[]): number {\n if (reviews.length === 0) return 1;\n const approvals = reviews.filter((r) => r.approved).length;\n return approvals / reviews.length;\n}\n\n// =============================================================================\n// Counting Helpers\n// =============================================================================\n\nexport function countBySeverity(findings: ReviewFinding[]): Record<ReviewSeverity, number> {\n const counts: Record<ReviewSeverity, number> = {\n critical: 0,\n high: 0,\n medium: 0,\n low: 0,\n info: 0,\n };\n\n for (const f of findings) {\n counts[f.severity]++;\n }\n\n return counts;\n}\n\nexport function countByCategory(findings: ReviewFinding[]): Record<ReviewCategory, number> {\n const counts: Record<ReviewCategory, number> = {\n security: 0,\n performance: 0,\n code_quality: 0,\n testing: 0,\n documentation: 0,\n architecture: 0,\n };\n\n for (const f of findings) {\n counts[f.category]++;\n }\n\n return counts;\n}\n\nexport function sumFindings(counts: Record<ReviewSeverity, number>): number {\n return Object.values(counts).reduce((a, b) => a + b, 0);\n}\n\n// =============================================================================\n// Summary Generation\n// =============================================================================\n\nexport function generateSummary(\n pr: PRMetadata,\n reviews: ExpertReviewResult[],\n decision: ReviewDecision\n): string {\n const expertSummaries = reviews\n .map((r) => `- **${CATEGORY_DISPLAY_NAMES[r.expertType as ReviewCategory]}**: ${r.summary}`)\n .join('\\n');\n\n return `Reviewed PR #${String(pr.number)}: ${pr.title}\n\n**Decision:** ${decision.replaceAll('_', ' ')}\n**Experts consulted:** ${String(reviews.length)}\n\n${expertSummaries}`;\n}\n\n// =============================================================================\n// GitHub Comment Formatting\n// =============================================================================\n\n/**\n * Formats the review result as a GitHub comment.\n */\nexport function formatReviewComment(result: PRReviewDraft): string {\n const emoji = DECISION_EMOJI[result.decision];\n const decisionText = result.decision.replaceAll('_', ' ').toUpperCase();\n\n const findingsSection = formatFindingsSection(result);\n const statsSection = formatStatsSection(result);\n\n return `## ${emoji} Nexus Agents Review: ${decisionText}\n\n${result.summary}\n\n${findingsSection}\n\n${statsSection}\n\n---\n*Reviewed by [nexus-agents](https://github.com/nexus-substrate/nexus-agents) in ${String(result.totalDurationMs)}ms*`;\n}\n\nfunction formatFindingsSection(result: PRReviewDraft): string {\n const allFindings = result.expertReviews.flatMap((r) => r.findings);\n\n if (allFindings.length === 0) {\n return '_No issues found._';\n }\n\n const sorted = [...allFindings].sort(\n (a, b) => SEVERITY_ORDER[b.severity] - SEVERITY_ORDER[a.severity]\n );\n\n const lines = ['### Findings', ''];\n\n for (const f of sorted) {\n const emoji = SEVERITY_EMOJI[f.severity];\n const loc =\n f.file !== undefined\n ? ` (\\`${f.file}${f.line !== undefined ? `:${String(f.line)}` : ''}\\`)`\n : '';\n lines.push(`${emoji} **${f.title}**${loc}`);\n lines.push(`> ${f.description}`);\n if (f.suggestion !== undefined) {\n lines.push(`> 💡 ${f.suggestion}`);\n }\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n\nfunction formatStatsSection(result: PRReviewDraft): string {\n const { findingsBySeverity } = result;\n const total = sumFindings(findingsBySeverity);\n\n const parts: string[] = [];\n for (const severity of ['critical', 'high', 'medium', 'low', 'info'] as ReviewSeverity[]) {\n const count = findingsBySeverity[severity];\n if (count > 0) {\n parts.push(`${SEVERITY_EMOJI[severity]} ${String(count)} ${severity}`);\n }\n }\n\n return `<details>\n<summary>Review Statistics (${String(total)} findings)</summary>\n\n- Experts: ${String(result.expertCount)}\n- Consensus: ${(result.consensusScore * 100).toFixed(0)}%\n- Duration: ${String(result.totalDurationMs)}ms\n- Findings: ${parts.join(', ') || 'none'}\n\n</details>`;\n}\n\n// =============================================================================\n// Failed Review Factory\n// =============================================================================\n\nexport function createFailedReview(\n expertId: string,\n category: ReviewCategory,\n durationMs: number,\n error: string\n): ExpertReviewResult {\n return {\n expertId,\n expertType: category,\n approved: true, // Don't block on failures\n summary: `Review failed: ${error}`,\n findings: [],\n durationMs,\n confidence: 0,\n };\n}\n"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getErrorMessage
3
- } from "./chunk-4IDGRIWO.js";
3
+ } from "./chunk-OI3735FM.js";
4
4
 
5
5
  // src/cli/setup-config.ts
6
6
  import { copyFileSync, existsSync, mkdirSync, writeFileSync } from "fs";
@@ -77,4 +77,4 @@ function ensureBackup(outputPath) {
77
77
  export {
78
78
  runConfigInitSync
79
79
  };
80
- //# sourceMappingURL=chunk-BGKDC7P5.js.map
80
+ //# sourceMappingURL=chunk-AHILMXB6.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  computeCostDetail
3
- } from "./chunk-66EE7Y2F.js";
3
+ } from "./chunk-KKDOJ5YZ.js";
4
4
  import {
5
5
  DEFAULT_CONSENSUS_CONFIG,
6
6
  DEFAULT_INCREMENTAL_QUORUM_CONFIG,
@@ -18,20 +18,20 @@ import {
18
18
  toolSuccess,
19
19
  withProgressHeartbeat,
20
20
  wrapToolWithTimeout
21
- } from "./chunk-FVSXYMVW.js";
21
+ } from "./chunk-DLZIL5ZF.js";
22
22
  import {
23
23
  createEvent,
24
24
  getGlobalRegistry
25
- } from "./chunk-YBTBVOVA.js";
25
+ } from "./chunk-CBE4PSYN.js";
26
26
  import {
27
27
  getToolMemory
28
- } from "./chunk-JYI63V47.js";
28
+ } from "./chunk-Q4FKHIBF.js";
29
29
  import {
30
30
  authRemediation,
31
31
  delay,
32
32
  getAvailableClis,
33
33
  withTimeout
34
- } from "./chunk-HGHPZ2W3.js";
34
+ } from "./chunk-XTXUHP7P.js";
35
35
  import {
36
36
  AgentError,
37
37
  CLI_NAMES,
@@ -59,7 +59,7 @@ import {
59
59
  registerPersistentOutcomeStoreFactory,
60
60
  resolveClassGuardMs,
61
61
  resolveVoteTimeout
62
- } from "./chunk-4IDGRIWO.js";
62
+ } from "./chunk-OI3735FM.js";
63
63
  import {
64
64
  ensureLearningDir,
65
65
  getOutcomesFile
@@ -5636,6 +5636,30 @@ var DEFAULT_JOB_ENVELOPES = {
5636
5636
  replay: defaultReplayEnvelope,
5637
5637
  collision: defaultCollisionEnvelope
5638
5638
  };
5639
+ var FAILURE_KEYS = [
5640
+ // toolStructuredError
5641
+ { key: "isError", failsWhen: true },
5642
+ // handleConsensusVote and the other Result-shaped handlers
5643
+ { key: "ok", failsWhen: false },
5644
+ // GraphPipelineResult / AdaptiveOrchestratorResult
5645
+ { key: "success", failsWhen: false }
5646
+ ];
5647
+ var DETAIL_KEYS = ["error", "message"];
5648
+ function describeFailureShape(failure) {
5649
+ const suffix = failure.detail === void 0 ? "" : `: ${failure.detail}`;
5650
+ return `Job result reported failure via '${failure.key}'${suffix}`;
5651
+ }
5652
+ function detectFailureShapedResult(result) {
5653
+ if (typeof result !== "object" || result === null) return null;
5654
+ const record = result;
5655
+ for (const { key, failsWhen } of FAILURE_KEYS) {
5656
+ if (record[key] === failsWhen) {
5657
+ const detailKey = DETAIL_KEYS.find((k) => typeof record[k] === "string");
5658
+ return { key, detail: detailKey === void 0 ? void 0 : record[detailKey] };
5659
+ }
5660
+ }
5661
+ return null;
5662
+ }
5639
5663
  function runAsJob(params) {
5640
5664
  const env = params.toEnvelope ?? DEFAULT_JOB_ENVELOPES;
5641
5665
  const idempotency = shortCircuitOrFreshJobId({
@@ -5672,7 +5696,18 @@ async function runJobInBackground(jobId, params) {
5672
5696
  params.run(jobId, params.input, controller.signal),
5673
5697
  guard.expired
5674
5698
  ]);
5675
- writeJobComplete(jobId, params.toolName, result);
5699
+ const failure = detectFailureShapedResult(result);
5700
+ if (failure !== null && params.allowFailureShapedResult === void 0) {
5701
+ writeJobFailed(jobId, params.toolName, describeFailureShape(failure));
5702
+ } else {
5703
+ if (failure !== null) {
5704
+ params.logger?.warn(
5705
+ `Recorded a failure-shaped ${params.toolName} result as complete (opted out)`,
5706
+ { jobId, key: failure.key, reason: params.allowFailureShapedResult }
5707
+ );
5708
+ }
5709
+ writeJobComplete(jobId, params.toolName, result);
5710
+ }
5676
5711
  } catch (err2) {
5677
5712
  const errObj = err2 instanceof Error ? err2 : new Error(String(err2));
5678
5713
  params.logger?.error(`Async ${params.toolName} dispatch failed`, errObj, { jobId });
@@ -5866,7 +5901,7 @@ async function processVotesWithCascade(engineVotes, opts) {
5866
5901
  var CONTRARIAN_ESCALATION_THRESHOLD = 0.8;
5867
5902
  async function runContrarianCheck(proposal, log) {
5868
5903
  try {
5869
- const { executeExpert } = await import("./expert-bridge-3AW3OHAY.js");
5904
+ const { executeExpert } = await import("./expert-bridge-EUCGQH4Q.js");
5870
5905
  const prompt = [
5871
5906
  "You are a contrarian analyst. Your job is to find reasons this proposal should be REJECTED.",
5872
5907
  "Look for: YAGNI (not needed), MISALIGNED (wrong tech/architecture), SECURITY_RISK, SCOPE_CREEP.",
@@ -6393,4 +6428,4 @@ export {
6393
6428
  CONSENSUS_VOTE_OUTPUT_SCHEMA,
6394
6429
  registerConsensusVoteTool
6395
6430
  };
6396
- //# sourceMappingURL=chunk-VSDI6ASO.js.map
6431
+ //# sourceMappingURL=chunk-AOBRDEJ4.js.map