rea-agents 2.4.0 → 3.0.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.
Files changed (231) hide show
  1. package/README.md +91 -19
  2. package/bridge/ghidra/ReaGhidraBridge.java +524 -4
  3. package/bridge/hopper_bridge.py +313 -28
  4. package/dist/application/AnalysisClientCleanup.js +14 -0
  5. package/dist/application/AnalysisContextQueries.js +130 -0
  6. package/dist/application/AnalysisSnapshotCache.js +4 -2
  7. package/dist/application/ApplicationWorkflowEvidenceResolver.js +31 -13
  8. package/dist/application/ArtifactInventory/scanCanonical.js +1 -1
  9. package/dist/application/BinarySession.js +20 -8
  10. package/dist/application/BinarySessionComposition.js +21 -0
  11. package/dist/application/BinarySessionRecords.js +79 -9
  12. package/dist/application/BinarySessionStatus.js +31 -1
  13. package/dist/application/BrowserEvidence.js +14 -0
  14. package/dist/application/BrowserScenarioCapturePort.js +1 -0
  15. package/dist/application/BrowserScenarioCaptureService.js +53 -0
  16. package/dist/application/BrowserScenarioEvidence.js +40 -0
  17. package/dist/application/CallPathTracing.js +160 -0
  18. package/dist/application/CapabilityInventory.js +84 -14
  19. package/dist/application/ClientRegistrationStatus.js +4 -1
  20. package/dist/application/CompositeProvider.js +10 -1
  21. package/dist/application/DirectAnalysis.js +13 -4
  22. package/dist/application/EnhancedLiteralTracing.js +118 -0
  23. package/dist/application/EnhancedTools.js +71 -127
  24. package/dist/application/EvidenceLedger.js +45 -16
  25. package/dist/application/JavaScriptApplicationWorkflowEvidence.js +13 -0
  26. package/dist/application/JavaScriptApplicationWorkflowService.js +27 -1
  27. package/dist/application/JavaScriptArtifactAnalysis.js +13 -4
  28. package/dist/application/JavaScriptRuntimeObservationEvidence.js +34 -0
  29. package/dist/application/JavaScriptRuntimeObservationPort.js +1 -0
  30. package/dist/application/JavaScriptRuntimeObservationService.js +46 -0
  31. package/dist/application/JavaScriptSemanticGraphAsyncProjection.js +147 -0
  32. package/dist/application/JavaScriptSemanticGraphBuilder.js +34 -6
  33. package/dist/application/JavaScriptSemanticGraphChildProcessProjection.js +156 -0
  34. package/dist/application/JavaScriptSemanticGraphConstruction.js +2 -2
  35. package/dist/application/JavaScriptSemanticGraphDataProjection.js +203 -0
  36. package/dist/application/JavaScriptSemanticGraphFingerprintProjection.js +25 -0
  37. package/dist/application/JavaScriptSemanticGraphFlowProjection.js +129 -8
  38. package/dist/application/JavaScriptSemanticGraphObjectProjection.js +81 -0
  39. package/dist/application/JavaScriptSemanticGraphProjection.js +14 -7
  40. package/dist/application/JavaScriptSemanticGraphResourceProjection.js +59 -0
  41. package/dist/application/JavaScriptSemanticGraphValueProjection.js +77 -0
  42. package/dist/application/LazyAnalysisProvider.js +77 -0
  43. package/dist/application/LoopbackReplay.js +1 -1
  44. package/dist/application/NativeApiInspection.js +80 -0
  45. package/dist/application/ProcessReactiveEffects.js +6 -0
  46. package/dist/application/ProcessReactiveHarness.js +16 -1
  47. package/dist/application/ProjectPermissionStore.js +1 -0
  48. package/dist/application/ReconstructionObligationAuthority.js +72 -0
  49. package/dist/application/ReconstructionObligationCandidates.js +265 -0
  50. package/dist/application/ReconstructionObligationLedgerDiagnostics.js +47 -0
  51. package/dist/application/ReconstructionObligationLedgerEvaluation.js +263 -0
  52. package/dist/application/ReconstructionObligationLedgerProjection.js +86 -0
  53. package/dist/application/ReconstructionObligationLedgerService.js +72 -0
  54. package/dist/application/ReconstructionObligationOriginalCases.js +33 -0
  55. package/dist/application/ReconstructionObligationPolicies.js +132 -0
  56. package/dist/application/ReconstructionReadinessService.js +48 -0
  57. package/dist/application/SessionProviderRouter.js +6 -6
  58. package/dist/application/SetupClientConfiguration.js +4 -2
  59. package/dist/application/runtime.js +26 -9
  60. package/dist/artifacts/ArtifactProvider.js +87 -22
  61. package/dist/browser/BrowserScenarioSecrets.js +53 -0
  62. package/dist/browser/BrowserScenarioSessionPort.js +1 -0
  63. package/dist/browser/CdpBrowserProvider.js +2 -2
  64. package/dist/browser/CdpCaptureDocuments.js +57 -0
  65. package/dist/browser/CdpCaptureStorage.js +71 -29
  66. package/dist/browser/CdpCaptureStorageFingerprints.js +328 -0
  67. package/dist/browser/CdpEndpoint.js +8 -6
  68. package/dist/browser/CdpPageCapture.js +2 -0
  69. package/dist/browser/JavaScriptRuntimeScope.js +38 -0
  70. package/dist/browser/PlaywrightBrowserScenarioProvider.js +259 -0
  71. package/dist/browser/PlaywrightExecutionBoundary.js +42 -0
  72. package/dist/browser/PlaywrightScenarioActions.js +62 -0
  73. package/dist/browser/PlaywrightScenarioArtifacts.js +238 -0
  74. package/dist/browser/PlaywrightScenarioBrowser.js +144 -0
  75. package/dist/browser/PlaywrightScenarioEvents.js +301 -0
  76. package/dist/browser/PlaywrightScenarioSession.js +300 -0
  77. package/dist/browser/V8InspectorCaptureProjection.js +110 -0
  78. package/dist/browser/V8InspectorEndpoint.js +72 -0
  79. package/dist/browser/V8InspectorProvider.js +267 -0
  80. package/dist/catalogIdentity.js +11 -3
  81. package/dist/cli/artifactCommands.js +44 -3
  82. package/dist/cli/coreAnalysisCommands.js +78 -0
  83. package/dist/cli.js +4 -0
  84. package/dist/cliApplicationCommands.js +30 -2
  85. package/dist/cliBrowserAdvancedCommands.js +17 -5
  86. package/dist/cliBrowserCommands.js +1 -0
  87. package/dist/cliBrowserScenarioCommands.js +43 -0
  88. package/dist/cliCommandNames.js +9 -0
  89. package/dist/cliJavaScriptRuntimeCommands.js +164 -0
  90. package/dist/cliObservationOptions.js +4 -0
  91. package/dist/cliPolicyCommands.js +1 -0
  92. package/dist/config/environment.js +12 -0
  93. package/dist/config/parseConfig.js +88 -17
  94. package/dist/contracts/analysisSearchContract.js +14 -0
  95. package/dist/contracts/applicationToolContracts.js +86 -2
  96. package/dist/contracts/applicationWorkflowInputContracts.js +18 -0
  97. package/dist/contracts/artifactToolContracts.js +29 -2
  98. package/dist/contracts/browserProviderToolContracts.js +7 -0
  99. package/dist/contracts/browserScenarioToolContracts.js +81 -0
  100. package/dist/contracts/browserToolContracts.js +88 -98
  101. package/dist/contracts/enhancedInputs.js +35 -6
  102. package/dist/contracts/functionInstructionContract.js +8 -0
  103. package/dist/contracts/functionWorkflowToolContracts.js +30 -0
  104. package/dist/contracts/hopperMemoryContracts.js +22 -0
  105. package/dist/contracts/javascriptApplicationWorkflowExamples.js +42 -0
  106. package/dist/contracts/javascriptRuntimeObservationToolContracts.js +58 -0
  107. package/dist/contracts/promptContracts.js +14 -15
  108. package/dist/contracts/reconstructionReadinessExample.js +436 -0
  109. package/dist/contracts/toolContractExamples.js +8 -0
  110. package/dist/contracts/toolContractTypes.js +1 -0
  111. package/dist/contracts/toolContracts.js +34 -25
  112. package/dist/contracts/toolEffects.js +25 -0
  113. package/dist/contracts/toolOutputSchemaGroups.js +120 -30
  114. package/dist/contracts/toolOutputSchemaPrimitives.js +37 -0
  115. package/dist/domain/analysisErrorPresentation.js +8 -2
  116. package/dist/domain/analysisErrorProjection.js +9 -0
  117. package/dist/domain/artifactInspection.js +347 -0
  118. package/dist/domain/browserCaptureComparison.js +82 -0
  119. package/dist/domain/browserObservation.js +8 -1
  120. package/dist/domain/browserObservationErrors.js +1 -0
  121. package/dist/domain/browserObservationSchemas.js +26 -0
  122. package/dist/domain/browserScenario.js +165 -0
  123. package/dist/domain/browserScenarioCapture.js +57 -0
  124. package/dist/domain/browserScenarioCaptureValues.js +204 -0
  125. package/dist/domain/browserScenarioDiff.js +324 -0
  126. package/dist/domain/browserScenarioDiffValues.js +157 -0
  127. package/dist/domain/browserScenarioNormalization.js +45 -0
  128. package/dist/domain/browserScenarioValues.js +372 -0
  129. package/dist/domain/bytecodeProvider.js +179 -0
  130. package/dist/domain/conformancePackage.js +169 -0
  131. package/dist/domain/conformanceReplay.js +104 -0
  132. package/dist/domain/conformanceTrustGate.js +193 -0
  133. package/dist/domain/customProtocolCapture.js +137 -0
  134. package/dist/domain/eventProcessTree.js +214 -0
  135. package/dist/domain/evidenceBundle.js +47 -0
  136. package/dist/domain/hopperStartupFailure.js +1 -1
  137. package/dist/domain/hopperValues.js +14 -1
  138. package/dist/domain/inputIssueProjection.js +7 -1
  139. package/dist/domain/javascriptRuntimeObservation.js +170 -0
  140. package/dist/domain/javascriptRuntimeReconciliationParsing.js +120 -2
  141. package/dist/domain/javascriptRuntimeReconciliationResult.js +3 -3
  142. package/dist/domain/javascriptRuntimeReconciliationRuntime.js +2 -2
  143. package/dist/domain/javascriptRuntimeReconciliationSchemas.js +1 -1
  144. package/dist/domain/javascriptSemanticAnalysis.js +13 -16
  145. package/dist/domain/javascriptSemanticAsyncEffects.js +253 -0
  146. package/dist/domain/javascriptSemanticChildProcesses.js +237 -0
  147. package/dist/domain/javascriptSemanticDataEffectHelpers.js +125 -0
  148. package/dist/domain/javascriptSemanticDataEffects.js +284 -0
  149. package/dist/domain/javascriptSemanticDerivedAnalysis.js +41 -0
  150. package/dist/domain/javascriptSemanticFingerprints.js +174 -0
  151. package/dist/domain/javascriptSemanticIr.js +21 -1
  152. package/dist/domain/javascriptSemanticObjects.js +115 -0
  153. package/dist/domain/javascriptSemanticPromises.js +290 -0
  154. package/dist/domain/javascriptSemanticResources.js +136 -0
  155. package/dist/domain/javascriptSourceParser.js +15 -0
  156. package/dist/domain/javascriptStaticAnalysis.js +12 -15
  157. package/dist/domain/javascriptStaticAnalysisBundler.js +38 -0
  158. package/dist/domain/javascriptStaticAnalysisCalls.js +23 -1
  159. package/dist/domain/javascriptStaticAnalysisHelpers.js +8 -0
  160. package/dist/domain/mobileApplicationInvestigation.js +159 -0
  161. package/dist/domain/nativeApiBoundary.js +130 -0
  162. package/dist/domain/objcSwiftMetadata.js +150 -0
  163. package/dist/domain/packageAnalysis.js +123 -0
  164. package/dist/domain/peInspection.js +196 -0
  165. package/dist/domain/processCapture.js +8 -2
  166. package/dist/domain/processReactiveScenario.js +1 -0
  167. package/dist/domain/processReactiveTransition.js +9 -4
  168. package/dist/domain/protocolCapture.js +243 -0
  169. package/dist/domain/providerCleanupError.js +11 -0
  170. package/dist/domain/reconstructionObligationLedgerSchemas.js +278 -0
  171. package/dist/domain/reconstructionReadiness.js +121 -0
  172. package/dist/domain/reconstructionReadinessFindingHelpers.js +17 -0
  173. package/dist/domain/reconstructionReadinessIntegrityFindings.js +118 -0
  174. package/dist/domain/reconstructionReadinessJourneyFindings.js +193 -0
  175. package/dist/domain/reconstructionReadinessSchemas.js +240 -0
  176. package/dist/domain/sourceToBundleComparison.js +335 -0
  177. package/dist/domain/sourceToBundleComparisonSchemas.js +133 -0
  178. package/dist/domain/sourceToBundleSignals.js +202 -0
  179. package/dist/domain/webCaptureDiff.js +141 -27
  180. package/dist/domain/webScreenshot.js +1 -1
  181. package/dist/dotnet/ManagedStaticProvider.js +34 -5
  182. package/dist/generatedMcpToolCatalog.js +37 -0
  183. package/dist/generatedPackageMetadata.js +4 -4
  184. package/dist/ghidra/GhidraDefaults.js +1 -1
  185. package/dist/ghidra/GhidraFunctionValues.js +40 -2
  186. package/dist/ghidra/GhidraProviderCapabilities.js +47 -38
  187. package/dist/hopper/HopperCleanup.js +158 -0
  188. package/dist/hopper/HopperClient.js +93 -99
  189. package/dist/hopper/HopperProvider.js +61 -30
  190. package/dist/hopper/HopperRequestQueue.js +215 -0
  191. package/dist/hopper/HopperResponseStream.js +46 -0
  192. package/dist/hopper/protocol.js +63 -20
  193. package/dist/main/transport.js +24 -27
  194. package/dist/main.js +14 -6
  195. package/dist/mcpDoctor.js +27 -4
  196. package/dist/mcpStartupPolicy.js +14 -0
  197. package/dist/process/ProcessCommandIdentity.js +19 -0
  198. package/dist/process/ProcessOwnership.js +11 -8
  199. package/dist/server/DynamicToolAvailability.js +70 -0
  200. package/dist/server/LazyToolCatalog.js +134 -0
  201. package/dist/server/createServer.js +92 -154
  202. package/dist/server/hydrateServerTools.js +191 -0
  203. package/dist/server/lifecycleProgress.js +10 -0
  204. package/dist/server/permissionFailure.js +12 -0
  205. package/dist/server/registerApplicationTools/compareSourceToBundle.js +35 -0
  206. package/dist/server/registerApplicationTools/helpers.js +11 -7
  207. package/dist/server/registerApplicationTools/obligationLedger.js +27 -0
  208. package/dist/server/registerApplicationTools/readiness.js +55 -0
  209. package/dist/server/registerApplicationTools.js +6 -0
  210. package/dist/server/registerArtifactTools.js +9 -1
  211. package/dist/server/registerBrowserScenarioTool.js +25 -0
  212. package/dist/server/registerBrowserTools.js +2 -2
  213. package/dist/server/registerCloseLifecycleTool.js +57 -0
  214. package/dist/server/registerEnhancedTools.js +28 -7
  215. package/dist/server/registerEvidenceResources.js +54 -101
  216. package/dist/server/registerEvidenceTools.js +9 -2
  217. package/dist/server/registerInvestigationTools.js +1 -2
  218. package/dist/server/registerJavaScriptApplicationGraphResource.js +0 -4
  219. package/dist/server/registerJavaScriptRuntimeObservationTools.js +37 -0
  220. package/dist/server/registerReconstructionObligationLedgerResource.js +32 -0
  221. package/dist/server/registerReconstructionReadinessResource.js +32 -0
  222. package/dist/server/registerSessionRecordTools.js +82 -12
  223. package/dist/server/registerSessionStatusTool.js +11 -8
  224. package/dist/server/registerSessionTools.js +32 -58
  225. package/dist/server/sessionAvailabilityPolicy.js +10 -8
  226. package/dist/server/toolRegistrationOptions.js +21 -6
  227. package/dist/server/toolResult.js +12 -0
  228. package/package.json +28 -11
  229. package/scripts/package-runner-bootstrap.mjs +72 -0
  230. package/scripts/rea.mjs +11 -1
  231. package/skills/reverse-engineer-anything/SKILL.md +10 -3
@@ -0,0 +1,32 @@
1
+ import { ResourceNotFoundError, ResourceTemplate, } from "@modelcontextprotocol/server";
2
+ import { reconstructionObligationLedgerPageSchema } from "../domain/reconstructionObligationLedgerSchemas.js";
3
+ /** Expose retained obligation-ledger pages as typed Evidence resources. */
4
+ export const registerReconstructionObligationLedgerResource = (server, session) => {
5
+ server.registerResource("reconstruction-obligation-ledger-page", new ResourceTemplate("rea://evidence/{evidenceId}/reconstruction-obligation-ledger", {
6
+ list: undefined,
7
+ }), {
8
+ title: "Reconstruction obligation ledger page",
9
+ description: "One deterministic Evidence v2-backed obligation page with full-ledger closure digest and summaries.",
10
+ mimeType: "application/json",
11
+ }, (uri, variables) => {
12
+ const evidenceId = variables.evidenceId;
13
+ if (typeof evidenceId !== "string")
14
+ throw new ResourceNotFoundError(uri.href);
15
+ const evidence = session.evidenceById(evidenceId);
16
+ if (evidence === undefined ||
17
+ evidence.predicate_type !== "rea.reconstruction-obligation-ledger/v1")
18
+ throw new ResourceNotFoundError(uri.href);
19
+ const page = reconstructionObligationLedgerPageSchema.safeParse(evidence.normalized_result);
20
+ if (!page.success)
21
+ throw new ResourceNotFoundError(uri.href);
22
+ return {
23
+ contents: [
24
+ {
25
+ uri: uri.href,
26
+ mimeType: "application/json",
27
+ text: JSON.stringify({ evidence_id: evidence.evidence_id, page: page.data }, null, 2),
28
+ },
29
+ ],
30
+ };
31
+ });
32
+ };
@@ -0,0 +1,32 @@
1
+ import { ResourceNotFoundError, ResourceTemplate, } from "@modelcontextprotocol/server";
2
+ import { reconstructionReadinessReportSchema } from "../domain/reconstructionReadinessSchemas.js";
3
+ /** Expose retained full readiness reports outside compact tool responses. */
4
+ export const registerReconstructionReadinessResource = (server, session) => {
5
+ server.registerResource("reconstruction-readiness-report", new ResourceTemplate("rea://evidence/{evidenceId}/reconstruction-readiness-report", {
6
+ list: undefined,
7
+ }), {
8
+ title: "Reconstruction readiness report",
9
+ description: "Full deterministic nine-stage conformance report and replay identity.",
10
+ mimeType: "application/json",
11
+ }, (uri, variables) => {
12
+ const evidenceId = variables.evidenceId;
13
+ if (typeof evidenceId !== "string")
14
+ throw new ResourceNotFoundError(uri.href);
15
+ const evidence = session.evidenceById(evidenceId);
16
+ if (evidence === undefined ||
17
+ evidence.predicate_type !== "rea.reconstruction-readiness-report/v1")
18
+ throw new ResourceNotFoundError(uri.href);
19
+ const report = reconstructionReadinessReportSchema.safeParse(evidence.normalized_result);
20
+ if (!report.success)
21
+ throw new ResourceNotFoundError(uri.href);
22
+ return {
23
+ contents: [
24
+ {
25
+ uri: uri.href,
26
+ mimeType: "application/json",
27
+ text: JSON.stringify({ evidence_id: evidence.evidence_id, report: report.data }, null, 2),
28
+ },
29
+ ],
30
+ };
31
+ });
32
+ };
@@ -1,5 +1,5 @@
1
1
  import { readEvidenceBundle, writeEvidenceBundle, } from "../application/EvidenceBundleFiles.js";
2
- import { exportEvidenceBundleInputSchema, importEvidenceBundleInputSchema, listUnknownsInputSchema, SESSION_TOOL_CONTRACTS, verifyUnknownResolutionInputSchema, } from "../contracts/toolContracts.js";
2
+ import { exportEvidenceBundleInputSchema, importEvidenceBundleInputSchema, listUnknownsInputSchema, snapshotEvidenceBundleInputSchema, SESSION_TOOL_CONTRACTS, verifyUnknownResolutionInputSchema, } from "../contracts/toolContracts.js";
3
3
  import { AnalysisProtocolError, PermissionRequiredError, } from "../domain/errors.js";
4
4
  import { recordUnknownInputSchema, updateUnknownInputSchema, } from "../domain/residualUnknown.js";
5
5
  import { err, ok } from "../domain/result.js";
@@ -10,6 +10,7 @@ import { toCallToolResult } from "./toolResult.js";
10
10
  export const registerEvidenceTools = (registration) => {
11
11
  registerExportEvidenceTool(registration);
12
12
  registerImportEvidenceTool(registration);
13
+ registerSnapshotEvidenceTool(registration);
13
14
  };
14
15
  const registerExportEvidenceTool = ({ server, session, exportContract, filePolicy, permissionAuthority, }) => {
15
16
  server.registerTool(exportContract.name, toolRegistrationOptions(exportContract), async (input) => {
@@ -18,8 +19,6 @@ const registerExportEvidenceTool = ({ server, session, exportContract, filePolic
18
19
  return toCallToolResult(parsedInput, exportContract);
19
20
  const parsed = parsedInput.value;
20
21
  const bundle = session.exportEvidenceBundle();
21
- if (parsed.path === undefined)
22
- return toCallToolResult(ok(bundle), exportContract);
23
22
  const denied = await authorizeEvidencePath({
24
23
  authority: permissionAuthority,
25
24
  capability: "evidence_write",
@@ -35,10 +34,38 @@ const registerExportEvidenceTool = ({ server, session, exportContract, filePolic
35
34
  path: written.value.path,
36
35
  bytes: written.value.bytes,
37
36
  records: bundle.records.length,
37
+ unknowns: bundle.unknowns.length,
38
38
  }), exportContract)
39
39
  : toCallToolResult(written, exportContract);
40
40
  });
41
41
  };
42
+ const registerSnapshotEvidenceTool = ({ server, session, snapshotContract, }) => {
43
+ server.registerTool(snapshotContract.name, toolRegistrationOptions(snapshotContract), (input) => {
44
+ const parsed = safeParseToolInput(snapshotEvidenceBundleInputSchema, input, snapshotContract.name);
45
+ if (!parsed.ok)
46
+ return toCallToolResult(parsed, snapshotContract);
47
+ const snapshot = session.snapshotEvidenceBundle();
48
+ if (!snapshot.ok)
49
+ return toCallToolResult(snapshot, snapshotContract);
50
+ const value = {
51
+ bundle_digest: snapshot.value.bundleDigest,
52
+ bundle_version: snapshot.value.bundleVersion,
53
+ bytes: snapshot.value.bytes,
54
+ records: snapshot.value.records,
55
+ unknowns: snapshot.value.unknowns,
56
+ bundle_uri: snapshot.value.uri,
57
+ };
58
+ return toCallToolResult(ok(value), snapshotContract, {
59
+ resourceLinks: [
60
+ {
61
+ uri: snapshot.value.uri,
62
+ name: snapshot.value.bundleDigest,
63
+ description: "Immutable session-retained Evidence v2 bundle",
64
+ },
65
+ ],
66
+ });
67
+ });
68
+ };
42
69
  const registerImportEvidenceTool = ({ server, session, importContract, filePolicy, permissionAuthority, }) => {
43
70
  server.registerTool(importContract.name, toolRegistrationOptions(importContract), async (input) => {
44
71
  const parsedInput = safeParseToolInput(importEvidenceBundleInputSchema, input, importContract.name);
@@ -58,8 +85,6 @@ const registerImportEvidenceTool = ({ server, session, importContract, filePolic
58
85
  if (!loaded.ok)
59
86
  return toCallToolResult(loaded, importContract);
60
87
  const imported = session.importEvidenceBundle(loaded.value);
61
- if (imported.ok && imported.value > 0)
62
- server.sendResourceListChanged();
63
88
  return imported.ok
64
89
  ? toCallToolResult(ok({
65
90
  imported: imported.value,
@@ -93,22 +118,53 @@ export const registerUnknownTools = ({ server, session, contracts, }) => {
93
118
  if (!parsed.ok)
94
119
  return toCallToolResult(parsed, listContract);
95
120
  const filters = parsed.value;
96
- return toCallToolResult(ok(session.listUnknowns({
121
+ const all = session.listUnknowns({
97
122
  ...(filters.status === undefined ? {} : { status: filters.status }),
98
123
  ...(filters.severity === undefined
99
124
  ? {}
100
125
  : { severity: filters.severity }),
101
126
  ...(filters.domain === undefined ? {} : { domain: filters.domain }),
102
- })), listContract);
127
+ });
128
+ const items = all
129
+ .slice(filters.offset, filters.offset + filters.limit)
130
+ .map((unknown) => ({
131
+ unknown,
132
+ uri: `rea://unknown/${unknown.unknown_id}`,
133
+ }));
134
+ const nextOffset = filters.offset + items.length < all.length
135
+ ? filters.offset + items.length
136
+ : null;
137
+ return toCallToolResult(ok({
138
+ items,
139
+ offset: filters.offset,
140
+ limit: filters.limit,
141
+ total: all.length,
142
+ next_offset: nextOffset,
143
+ has_more: nextOffset !== null,
144
+ }), listContract, {
145
+ resourceLinks: items.map((unknown) => ({
146
+ uri: unknown.uri,
147
+ name: unknown.unknown.unknown_id,
148
+ description: `Current ${unknown.unknown.status} residual unknown revision`,
149
+ })),
150
+ });
103
151
  });
104
152
  server.registerTool(recordContract.name, toolRegistrationOptions(recordContract), (input) => {
105
153
  const parsed = safeParseToolInput(recordUnknownInputSchema, input, recordContract.name);
106
154
  if (!parsed.ok)
107
155
  return toCallToolResult(parsed, recordContract);
108
156
  const result = session.recordUnknown(parsed.value);
109
- if (result.ok)
110
- server.sendResourceListChanged();
111
- return toCallToolResult(result, recordContract);
157
+ return result.ok
158
+ ? toCallToolResult(result, recordContract, {
159
+ resourceLinks: [
160
+ {
161
+ uri: `rea://unknown/${result.value.unknown_id}`,
162
+ name: result.value.unknown_id,
163
+ description: "Current residual unknown head",
164
+ },
165
+ ],
166
+ })
167
+ : toCallToolResult(result, recordContract);
112
168
  });
113
169
  server.registerTool(updateContract.name, toolRegistrationOptions(updateContract), (input) => {
114
170
  const parsed = safeParseToolInput(updateUnknownInputSchema, input, updateContract.name);
@@ -116,8 +172,22 @@ export const registerUnknownTools = ({ server, session, contracts, }) => {
116
172
  return toCallToolResult(parsed, updateContract);
117
173
  const result = session.updateUnknown(parsed.value);
118
174
  if (result.ok)
119
- server.sendResourceListChanged();
120
- return toCallToolResult(result, updateContract);
175
+ void server.server
176
+ .sendResourceUpdated({
177
+ uri: `rea://unknown/${result.value.unknown_id}`,
178
+ })
179
+ .catch(() => undefined);
180
+ return result.ok
181
+ ? toCallToolResult(result, updateContract, {
182
+ resourceLinks: [
183
+ {
184
+ uri: `rea://unknown/${result.value.unknown_id}`,
185
+ name: result.value.unknown_id,
186
+ description: "Updated residual unknown head",
187
+ },
188
+ ],
189
+ })
190
+ : toCallToolResult(result, updateContract);
121
191
  });
122
192
  server.registerTool(verifyContract.name, toolRegistrationOptions(verifyContract), (input) => {
123
193
  const parsed = safeParseToolInput(verifyUnknownResolutionInputSchema, input, verifyContract.name);
@@ -15,9 +15,15 @@ export const registerSessionStatusTool = (options) => {
15
15
  const parsed = parsedInput.value;
16
16
  const client = server.server.getClientVersion();
17
17
  const clientCapabilities = server.server.getClientCapabilities();
18
+ const clientFeatures = {
19
+ elicitation_form: clientCapabilities?.elicitation?.form !== undefined,
20
+ elicitation_url: clientCapabilities?.elicitation?.url !== undefined,
21
+ roots: clientCapabilities?.roots !== undefined,
22
+ sampling: clientCapabilities?.sampling !== undefined,
23
+ };
18
24
  const status = session.status();
19
25
  const statusObject = jsonObjectSchema.parse(status);
20
- const toolAvailability = buildCapabilityInventory(status, availabilityPolicy());
26
+ const toolAvailability = buildCapabilityInventory(status, availabilityPolicy(), clientFeatures);
21
27
  const serverIdentity = createServerIdentity({
22
28
  startedAt,
23
29
  expected: {
@@ -45,12 +51,7 @@ export const registerSessionStatusTool = (options) => {
45
51
  status: statusObject,
46
52
  toolAvailability,
47
53
  serverIdentity,
48
- clientFeatures: {
49
- elicitation_form: clientCapabilities?.elicitation?.form !== undefined,
50
- elicitation_url: clientCapabilities?.elicitation?.url !== undefined,
51
- roots: clientCapabilities?.roots !== undefined,
52
- sampling: clientCapabilities?.sampling !== undefined,
53
- },
54
+ clientFeatures,
54
55
  }),
55
56
  }, contract);
56
57
  });
@@ -86,6 +87,7 @@ const projectSessionStatus = (options) => {
86
87
  next_cursor: nextCursor < filtered.length ? nextCursor : null,
87
88
  has_more: nextCursor < filtered.length,
88
89
  },
90
+ client_features: options.clientFeatures,
89
91
  });
90
92
  }
91
93
  return jsonObjectSchema.parse({
@@ -95,6 +97,7 @@ const projectSessionStatus = (options) => {
95
97
  active_provider: activeProvider,
96
98
  target: open ? targetFrom(options.status) : null,
97
99
  alignment: options.serverIdentity.alignment,
100
+ analysis_activity: options.status.analysis_activity,
98
101
  recommended_actions: recommendedActions(open, options.serverIdentity.alignment.state),
99
102
  });
100
103
  };
@@ -115,7 +118,7 @@ const recommendedActions = (open, alignment) => [
115
118
  : []),
116
119
  ...(!open
117
120
  ? [
118
- "Route the supplied target directly: ASAR/JavaScript to analyze_javascript_application, packages to inventory_artifact, managed PE/CLI to inspect_managed_artifact, browser/Electron runtimes to their list-target tools, and native binaries to open_binary.",
121
+ "For a supplied target, route by format: ASAR/JavaScript to analyze_javascript_application; archive/package to open_binary(path), then inspect_artifact or inventory_artifact on the active target; managed PE/CLI to inspect_managed_artifact; browser/Electron runtimes to their list-target tools; native binaries to open_binary.",
119
122
  ]
120
123
  : [
121
124
  "Continue from the active target with binary_overview or a bounded target-specific query.",
@@ -1,13 +1,13 @@
1
1
  import { z } from "zod";
2
- import { SESSION_TOOL_CONTRACTS } from "../contracts/toolContracts.js";
2
+ import { addressContextInputSchema, navigationContextInputSchema, SESSION_TOOL_CONTRACTS, } from "../contracts/toolContracts.js";
3
3
  import { toCallToolResult } from "./toolResult.js";
4
4
  import { logToolExecution } from "./toolLogging.js";
5
- import { err, ok } from "../domain/result.js";
5
+ import { ok } from "../domain/result.js";
6
6
  import { processScenarioSchema } from "../domain/processCapture.js";
7
7
  import { captureProcessScenario } from "../application/ProcessHarness.js";
8
8
  import { processCapturePermissionRequest } from "../application/ProcessCapturePermission.js";
9
- import { readAnalysisSnapshot, writeAnalysisSnapshot, } from "../application/AnalysisSnapshotFiles.js";
10
- import { AnalysisProtocolError, PermissionRequiredError, UnknownRegistryError, } from "../domain/errors.js";
9
+ import { readAnalysisSnapshot } from "../application/AnalysisSnapshotFiles.js";
10
+ import { UnknownRegistryError } from "../domain/errors.js";
11
11
  import { DENY_EVIDENCE_FILE_POLICY, DENY_PROCESS_POLICY, } from "./sessionToolPolicies.js";
12
12
  import { createProcessCaptureEvidence } from "../application/ProcessEvidence.js";
13
13
  import { registerProcessComparisonTool } from "./registerProcessComparisonTool.js";
@@ -17,7 +17,7 @@ import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
17
17
  import { safeParseToolInput } from "./toolInputValidation.js";
18
18
  import { registerBundleComparisonTool } from "./registerBundleComparisonTool.js";
19
19
  import { registerInvestigationTools } from "./registerInvestigationTools.js";
20
- import { closeBinaryInputSchema, openBinaryInputSchema, } from "../contracts/sessionLifecycleInputs.js";
20
+ import { openBinaryInputSchema } from "../contracts/sessionLifecycleInputs.js";
21
21
  import { registerSessionStatusTool } from "./registerSessionStatusTool.js";
22
22
  import { mcpProgressReporter } from "./mcpProgress.js";
23
23
  import { authorizeProcessCaptureWithElicitation, } from "./ProcessCaptureElicitation.js";
@@ -25,15 +25,9 @@ import { isInputRequiredResult } from "@modelcontextprotocol/server";
25
25
  import { registerEvidenceTools, registerUnknownTools, } from "./registerSessionRecordTools.js";
26
26
  import { registerReplayMachineTool } from "./registerReplayMachineTool.js";
27
27
  import { sessionAvailabilityPolicy, } from "./sessionAvailabilityPolicy.js";
28
- const permissionFailure = (failure) => {
29
- if (failure.ok)
30
- return err(new AnalysisProtocolError("Expected a denied permission"));
31
- return err(failure.error instanceof PermissionRequiredError
32
- ? failure.error
33
- : new AnalysisProtocolError(failure.error.message, {
34
- cause: failure.error,
35
- }));
36
- };
28
+ import { permissionFailure } from "./permissionFailure.js";
29
+ import { registerCloseLifecycleTool } from "./registerCloseLifecycleTool.js";
30
+ import { getNavigationContext, inspectAddressContext, } from "../application/AnalysisContextQueries.js";
37
31
  const recordProcessResidualUnknowns = (session, scenario, evidence, residuals) => {
38
32
  if (scenario.unknown_registry_approved !== true)
39
33
  return ok(null);
@@ -170,49 +164,6 @@ const registerOpenLifecycleTool = ({ server, session, logger, contracts: [openCo
170
164
  : toCallToolResult(opened, openContract);
171
165
  });
172
166
  };
173
- const registerCloseLifecycleTool = ({ server, session, logger, contracts: [, closeContract], snapshotFilePolicy, permissionAuthority, }) => {
174
- server.registerTool(closeContract.name, toolRegistrationOptions(closeContract), async (input) => {
175
- const parsedInput = safeParseToolInput(closeBinaryInputSchema, input, closeContract.name);
176
- if (!parsedInput.ok)
177
- return toCallToolResult(parsedInput, closeContract);
178
- const parsed = parsedInput.value;
179
- if (parsed.snapshot_path === undefined) {
180
- const closed = await logToolExecution(logger, closeContract.name, () => session.close());
181
- if (closed.ok)
182
- server.sendToolListChanged();
183
- return toCallToolResult(closed, closeContract);
184
- }
185
- if (permissionAuthority !== undefined) {
186
- const authorized = await permissionAuthority.authorize({
187
- capability: "snapshot_write",
188
- roots: [parsed.snapshot_path],
189
- executables: [],
190
- environment_names: [],
191
- network: "none",
192
- mount: false,
193
- operation_identity: `close_binary:snapshot:${parsed.snapshot_path}`,
194
- }, "write");
195
- if (!authorized.ok)
196
- return toCallToolResult(permissionFailure(authorized), closeContract);
197
- }
198
- const snapshot = session.exportAnalysisSnapshot();
199
- if (!snapshot.ok)
200
- return toCallToolResult(snapshot, closeContract);
201
- const written = await writeAnalysisSnapshot(snapshot.value, parsed.snapshot_path, parsed.overwrite, snapshotFilePolicy);
202
- if (!written.ok)
203
- return toCallToolResult(written, closeContract);
204
- const closed = await logToolExecution(logger, closeContract.name, () => session.close());
205
- if (closed.ok)
206
- server.sendToolListChanged();
207
- return closed.ok
208
- ? toCallToolResult(ok({
209
- path: written.value.path,
210
- bytes: written.value.bytes,
211
- entries: snapshot.value.entries.length,
212
- }), closeContract)
213
- : toCallToolResult(closed, closeContract);
214
- });
215
- };
216
167
  const registerRecordAndReplayTools = (server, session, logger) => {
217
168
  registerUnknownTools({
218
169
  server,
@@ -221,11 +172,28 @@ const registerRecordAndReplayTools = (server, session, logger) => {
221
172
  });
222
173
  registerReplayMachineTool(server, logger);
223
174
  };
175
+ const registerContextTools = (server, session) => {
176
+ const navigationContract = SESSION_TOOL_CONTRACTS[20];
177
+ const addressContract = SESSION_TOOL_CONTRACTS[21];
178
+ server.registerTool(navigationContract.name, toolRegistrationOptions(navigationContract), async (input, context) => {
179
+ const parsed = safeParseToolInput(navigationContextInputSchema, input, navigationContract.name);
180
+ if (!parsed.ok)
181
+ return toCallToolResult(parsed, navigationContract);
182
+ return toCallToolResult(await getNavigationContext(session, parsed.value, context.mcpReq.signal), navigationContract);
183
+ });
184
+ server.registerTool(addressContract.name, toolRegistrationOptions(addressContract), async (input, context) => {
185
+ const parsed = safeParseToolInput(addressContextInputSchema, input, addressContract.name);
186
+ if (!parsed.ok)
187
+ return toCallToolResult(parsed, addressContract);
188
+ return toCallToolResult(await inspectAddressContext(session, parsed.value, context.mcpReq.signal), addressContract);
189
+ });
190
+ };
224
191
  export const registerSessionTools = (server, session, logger, options = {}) => {
225
192
  const processPolicy = options.processPolicy ?? DENY_PROCESS_POLICY;
226
193
  const evidenceFilePolicy = options.evidenceFilePolicy ?? DENY_EVIDENCE_FILE_POLICY;
227
194
  const analysisSnapshotFilePolicy = options.analysisSnapshotFilePolicy ?? DENY_EVIDENCE_FILE_POLICY;
228
195
  const [openContract, closeContract, statusContract, exportContract, importContract, captureContract, compareContract, compareArtifactsContract, compareFunctionsContract, compareBundlesContract, changedBehaviorContract, callPathContract, staticRuntimeContract, reconstructionContract,] = SESSION_TOOL_CONTRACTS;
196
+ const snapshotContract = SESSION_TOOL_CONTRACTS[19];
229
197
  registerLifecycleTools({
230
198
  server,
231
199
  session,
@@ -233,7 +201,11 @@ export const registerSessionTools = (server, session, logger, options = {}) => {
233
201
  contracts: [openContract, closeContract, statusContract],
234
202
  snapshotFilePolicy: analysisSnapshotFilePolicy,
235
203
  startedAt: options.startedAt ?? new Date().toISOString(),
236
- availabilityPolicy: sessionAvailabilityPolicy(options.availabilityPolicy, processPolicy, evidenceFilePolicy, options.investigationInputRoots ?? []),
204
+ availabilityPolicy: sessionAvailabilityPolicy(options.availabilityPolicy, {
205
+ processPolicy,
206
+ evidenceFilePolicy,
207
+ investigationInputRoots: options.investigationInputRoots ?? [],
208
+ }),
237
209
  ...(options.permissionAuthority === undefined
238
210
  ? {}
239
211
  : { permissionAuthority: options.permissionAuthority }),
@@ -243,6 +215,7 @@ export const registerSessionTools = (server, session, logger, options = {}) => {
243
215
  session,
244
216
  exportContract,
245
217
  importContract,
218
+ snapshotContract,
246
219
  filePolicy: evidenceFilePolicy,
247
220
  ...(options.permissionAuthority === undefined
248
221
  ? {}
@@ -284,4 +257,5 @@ export const registerSessionTools = (server, session, logger, options = {}) => {
284
257
  : { permissionAuthority: options.permissionAuthority }),
285
258
  });
286
259
  registerRecordAndReplayTools(server, session, logger);
260
+ registerContextTools(server, session);
287
261
  };
@@ -1,11 +1,13 @@
1
1
  /** Select configured availability reporting or the target-free defaults. */
2
- export const sessionAvailabilityPolicy = (configured, processPolicy, evidenceFilePolicy, investigationInputRoots) => configured ??
2
+ export const sessionAvailabilityPolicy = (configured, defaults) => configured ??
3
3
  (() => ({
4
- processCaptureEnabled: processPolicy.enabled,
5
- evidenceFileRoots: evidenceFilePolicy.roots.length,
6
- investigationInputRoots: investigationInputRoots.length,
7
- browserObservationEnabled: false,
8
- electronObservationEnabled: false,
9
- javascriptReplayEnabled: false,
10
- managedRuntimeEnabled: false,
4
+ processCaptureEnabled: defaults.processPolicy.enabled,
5
+ evidenceFileRoots: defaults.evidenceFilePolicy.roots.length,
6
+ investigationInputRoots: defaults.investigationInputRoots.length,
7
+ browserObservationEnabled: defaults.optionalFeatures?.browserObservationEnabled ?? false,
8
+ browserScenarioEnabled: defaults.optionalFeatures?.browserScenarioEnabled ?? false,
9
+ electronObservationEnabled: defaults.optionalFeatures?.electronObservationEnabled ?? false,
10
+ v8InspectorObservationEnabled: defaults.optionalFeatures?.v8InspectorObservationEnabled ?? false,
11
+ javascriptReplayEnabled: defaults.optionalFeatures?.javascriptReplayEnabled ?? false,
12
+ managedRuntimeEnabled: defaults.optionalFeatures?.managedRuntimeEnabled ?? false,
11
13
  }));
@@ -1,9 +1,11 @@
1
1
  import { z } from "zod";
2
+ const ADVERTISED_INPUT_SCHEMAS = new WeakMap();
3
+ const ADVERTISED_OUTPUT_SCHEMAS = new WeakMap();
2
4
  /** Project the public contract fields accepted by MCP tool registration. */
3
5
  export const toolRegistrationOptions = (contract) => ({
4
6
  title: contract.title,
5
7
  description: contract.description,
6
- inputSchema: advertisedInputSchema(contract.inputSchema),
8
+ inputSchema: advertisedInputSchema(contract),
7
9
  outputSchema: advertisedOutputSchema(contract.outputSchema),
8
10
  annotations: contract.annotations,
9
11
  });
@@ -12,14 +14,14 @@ export const toolRegistrationOptions = (contract) => ({
12
14
  * The SDK otherwise converts validation failures to text-only JSON-RPC errors
13
15
  * before REA can return its stable structured error envelope.
14
16
  */
15
- const advertisedInputSchema = (schema) => ({
17
+ const advertisedInputSchema = (contract) => ({
16
18
  "~standard": {
17
19
  version: 1,
18
20
  vendor: "rea",
19
21
  validate: (input) => ({ value: input }),
20
22
  jsonSchema: {
21
- input: () => describeProperties(closeObjectSchemas(inputJsonSchema(schema))),
22
- output: () => describeProperties(closeObjectSchemas(inputJsonSchema(schema))),
23
+ input: () => advertisedInputJsonSchema(contract),
24
+ output: () => advertisedInputJsonSchema(contract),
23
25
  },
24
26
  },
25
27
  });
@@ -32,12 +34,25 @@ const advertisedOutputSchema = (schema) => {
32
34
  "~standard": {
33
35
  ...standard,
34
36
  jsonSchema: {
35
- input: () => describeRootProperties(closeObjectSchemas(converter({ target: "draft-2020-12" }))),
36
- output: () => describeRootProperties(closeObjectSchemas(converter({ target: "draft-2020-12" }))),
37
+ input: () => advertisedOutputJsonSchema(schema, converter),
38
+ output: () => advertisedOutputJsonSchema(schema, converter),
37
39
  },
38
40
  },
39
41
  };
40
42
  };
43
+ const advertisedInputJsonSchema = (contract) => cachedJsonSchema(ADVERTISED_INPUT_SCHEMAS, contract.inputSchema, () => ({
44
+ ...describeProperties(closeObjectSchemas(inputJsonSchema(contract.inputSchema))),
45
+ examples: contract.examples.map(({ input }) => input),
46
+ }));
47
+ const advertisedOutputJsonSchema = (schema, converter) => cachedJsonSchema(ADVERTISED_OUTPUT_SCHEMAS, schema, () => describeRootProperties(closeObjectSchemas(converter({ target: "draft-2020-12" }))));
48
+ const cachedJsonSchema = (cache, schema, create) => {
49
+ const cached = cache.get(schema);
50
+ if (cached !== undefined)
51
+ return cached;
52
+ const created = create();
53
+ cache.set(schema, created);
54
+ return created;
55
+ };
41
56
  const inputJsonSchema = (schema) => {
42
57
  const converter = schema["~standard"].jsonSchema?.input;
43
58
  if (converter === undefined)
@@ -49,6 +49,14 @@ const successResult = (value, contract, options) => {
49
49
  : (compactEvidence(value, options.evidenceTextProjection) ??
50
50
  options.evidenceTextProjection)),
51
51
  },
52
+ ...(hasResourceLinks(value, contract, options)
53
+ ? [
54
+ {
55
+ type: "text",
56
+ text: "Full detail is available through MCP resources/read. Copy the opaque URI exactly. In Codex, call read_mcp_resource.",
57
+ },
58
+ ]
59
+ : []),
52
60
  ...evidenceResourceLinks(value, contract.kind === "session" ||
53
61
  options.evidenceResourcesAvailable === true),
54
62
  ...(options.resourceLinks ?? []).map((resource) => ({
@@ -60,6 +68,10 @@ const successResult = (value, contract, options) => {
60
68
  structuredContent: candidate,
61
69
  };
62
70
  };
71
+ const hasResourceLinks = (value, contract, options) => options.resourceLinks !== undefined && options.resourceLinks.length > 0
72
+ ? true
73
+ : evidenceResourceLinks(value, contract.kind === "session" ||
74
+ options.evidenceResourcesAvailable === true).length > 0;
63
75
  const compactEvidence = (value, resultProjection) => {
64
76
  if (typeof value !== "object" ||
65
77
  value === null ||