rea-agents 2.0.0 → 2.2.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 (273) hide show
  1. package/README.md +103 -38
  2. package/bridge/ghidra/ReaGhidraBridge.java +96 -11
  3. package/dist/application/AndroidApplicationService.js +17 -0
  4. package/dist/application/AppleApplicationService.js +17 -0
  5. package/dist/application/ArtifactExtraction.js +1 -1
  6. package/dist/application/ArtifactInventory/classify.js +42 -0
  7. package/dist/application/ArtifactInventory/hash.js +43 -0
  8. package/dist/application/ArtifactInventory/reader.js +41 -0
  9. package/dist/application/ArtifactInventory/scanCanonical.js +155 -0
  10. package/dist/application/ArtifactInventory/scanReader.js +124 -0
  11. package/dist/application/ArtifactInventory/types.js +10 -0
  12. package/dist/application/ArtifactInventory.js +9 -351
  13. package/dist/application/AuthorizedArtifactInventory.js +2 -2
  14. package/dist/application/BinarySession.js +47 -270
  15. package/dist/application/BinarySessionExecution.js +28 -0
  16. package/dist/application/BinarySessionOpen.js +39 -0
  17. package/dist/application/BinarySessionRecords.js +149 -0
  18. package/dist/application/BinarySessionStatus.js +75 -0
  19. package/dist/application/CapabilityInventory.js +24 -2
  20. package/dist/application/ClientRegistrationStatus.js +11 -4
  21. package/dist/application/CrossVersionInventory.js +8 -2
  22. package/dist/application/CrossVersionInvestigation.js +1 -23
  23. package/dist/application/CrossVersionInvestigationCollections.js +23 -0
  24. package/dist/application/DirectAnalysis.js +47 -44
  25. package/dist/application/Doctor.js +156 -238
  26. package/dist/application/DoctorDiagnostics.js +180 -0
  27. package/dist/application/ElectronBoundaryAnalysis.js +23 -7
  28. package/dist/application/ElectronBoundaryGraphWindows.js +32 -8
  29. package/dist/application/EnhancedToolPagination.js +22 -0
  30. package/dist/application/EnhancedToolTypes.js +4 -0
  31. package/dist/application/EnhancedTools.js +20 -37
  32. package/dist/application/InstrumentedJavaScriptReplayHost.js +36 -0
  33. package/dist/application/InventoryProjectionEvidence.js +41 -0
  34. package/dist/application/InvestigationProviders.js +12 -0
  35. package/dist/application/InvestigationWorkspaceStore.js +24 -10
  36. package/dist/application/JavaScriptArtifactAnalysis.js +45 -6
  37. package/dist/application/JavaScriptArtifactFiles.js +6 -2
  38. package/dist/application/JavaScriptArtifactGraphBuilder.js +23 -1
  39. package/dist/application/JavaScriptArtifactGraphBundlers.js +225 -0
  40. package/dist/application/JavaScriptArtifactGraphContext.js +37 -36
  41. package/dist/application/JavaScriptArtifactGraphDocuments.js +27 -4
  42. package/dist/application/JavaScriptArtifactGraphFindings.js +54 -8
  43. package/dist/application/JavaScriptArtifactGraphStructure.js +29 -101
  44. package/dist/application/JavaScriptArtifactPathResolution.js +269 -0
  45. package/dist/application/JavaScriptArtifactReconstruction.js +1 -1
  46. package/dist/application/JavaScriptJsonModules.js +39 -0
  47. package/dist/application/JavaScriptModuleRelationships.js +262 -0
  48. package/dist/application/JavaScriptReplayPermission.js +16 -0
  49. package/dist/application/JavaScriptReplayService.js +182 -156
  50. package/dist/application/LinuxHopper.js +10 -0
  51. package/dist/application/MacHopper.js +22 -11
  52. package/dist/application/NodeRuntimeCharacterizationService.js +196 -0
  53. package/dist/application/PermissionAuthority.js +106 -63
  54. package/dist/application/ProcessCaptureCapability.js +1 -1
  55. package/dist/application/ProcessCapturePermission.js +13 -0
  56. package/dist/application/ProcessCli.js +2 -12
  57. package/dist/application/ProcessHarness.js +1 -1
  58. package/dist/application/ProcessPairedExperiment.js +72 -0
  59. package/dist/application/ProjectPermissionStore.js +48 -9
  60. package/dist/application/RealHopperAssertions.js +76 -0
  61. package/dist/application/ReconstructionCoverageService.js +69 -0
  62. package/dist/application/ReconstructionCoverageWorkspaceStore.js +31 -0
  63. package/dist/application/RuntimeExecutableDiagnostics.js +172 -0
  64. package/dist/application/Setup.js +148 -260
  65. package/dist/application/SetupClientConfiguration.js +224 -0
  66. package/dist/application/SetupClients.js +24 -2
  67. package/dist/application/SetupPlan.js +124 -12
  68. package/dist/application/SetupSkill.js +54 -36
  69. package/dist/application/SupportedClients.js +1 -0
  70. package/dist/application/Uninstall.js +12 -3
  71. package/dist/application/Upgrade.js +16 -1
  72. package/dist/application/WindowsCapabilities.js +86 -0
  73. package/dist/artifacts/AsarArtifactReader.js +11 -0
  74. package/dist/browser/BrowserProcessStartup.js +88 -0
  75. package/dist/browser/CdpCaptureDocuments.js +12 -8
  76. package/dist/browser/CdpCaptureEventBodyShapes.js +75 -0
  77. package/dist/browser/CdpCaptureEventHandlers.js +336 -0
  78. package/dist/browser/CdpCaptureEventHelpers.js +71 -0
  79. package/dist/browser/CdpCaptureEventState.js +1 -0
  80. package/dist/browser/CdpCaptureEventTypes.js +1 -0
  81. package/dist/browser/CdpCaptureEvents.js +29 -496
  82. package/dist/browser/CdpObservationSession.js +51 -8
  83. package/dist/browser/CdpPageCapture.js +12 -133
  84. package/dist/browser/CdpPageCaptureScripts.js +97 -0
  85. package/dist/browser/CdpPageCaptureWorkers.js +46 -0
  86. package/dist/browser/CdpWebMcpDiscovery.js +38 -14
  87. package/dist/browser/PngVisualDiff.js +9 -2
  88. package/dist/catalogIdentity.js +4 -0
  89. package/dist/cli/artifactCommands.js +82 -0
  90. package/dist/cli/coreAnalysisCommands.js +232 -0
  91. package/dist/cli/managedCommands.js +397 -0
  92. package/dist/cli/managedProjectGraphCommand.js +24 -0
  93. package/dist/cli/options.js +9 -0
  94. package/dist/cli/setupCommands.js +113 -0
  95. package/dist/cli/types.js +1 -0
  96. package/dist/cli/utilityCommands.js +122 -0
  97. package/dist/cli.js +10 -768
  98. package/dist/cliApplicationCommands.js +118 -4
  99. package/dist/cliBrowserAdvancedCommands.js +73 -16
  100. package/dist/cliBrowserCommands.js +39 -115
  101. package/dist/cliCommandNames.js +4 -0
  102. package/dist/cliElectronCommands.js +33 -62
  103. package/dist/cliEvidenceCommands.js +13 -2
  104. package/dist/cliInvestigationCommands.js +53 -10
  105. package/dist/cliObservationOptions.js +137 -0
  106. package/dist/cliPolicyCommands.js +80 -46
  107. package/dist/cliSetup.js +306 -0
  108. package/dist/config/environment.js +107 -0
  109. package/dist/config/parseConfig.js +228 -0
  110. package/dist/config/parsers.js +68 -0
  111. package/dist/config/permissions.js +30 -0
  112. package/dist/config/types.js +1 -0
  113. package/dist/config.js +1 -375
  114. package/dist/contracts/applicationToolContracts.js +134 -0
  115. package/dist/contracts/electronToolContracts.js +51 -3
  116. package/dist/contracts/managedToolContracts.js +8 -3
  117. package/dist/contracts/managedWorkflowToolContracts.js +3 -3
  118. package/dist/contracts/providerSelection.js +2 -0
  119. package/dist/contracts/sessionStatusContract.js +26 -0
  120. package/dist/contracts/toolContractTypes.js +12 -1
  121. package/dist/contracts/toolContracts.js +5 -12
  122. package/dist/contracts/toolEffects.js +14 -0
  123. package/dist/contracts/toolOutputSchemaGroups.js +274 -0
  124. package/dist/contracts/toolOutputSchemaPrimitives.js +328 -0
  125. package/dist/contracts/toolOutputSchemas.js +2 -550
  126. package/dist/domain/analysisErrorPresentation.js +234 -0
  127. package/dist/domain/analysisErrorProjection.js +284 -0
  128. package/dist/domain/androidApplication.js +206 -0
  129. package/dist/domain/appleApplication.js +221 -0
  130. package/dist/domain/artifactComparison.js +34 -15
  131. package/dist/domain/binaryTarget.js +87 -37
  132. package/dist/domain/boundedCartesianProjection.js +15 -0
  133. package/dist/domain/browserObservation.js +1 -285
  134. package/dist/domain/browserObservationSchemas.js +286 -0
  135. package/dist/domain/electronStaticAnalysisBrowser.js +14 -2
  136. package/dist/domain/errors.js +4 -486
  137. package/dist/domain/functionComparison.js +4 -165
  138. package/dist/domain/functionComparisonDimensions.js +164 -0
  139. package/dist/domain/javascriptApplicationVersionItems.js +18 -6
  140. package/dist/domain/javascriptApplicationVersionKeys.js +8 -8
  141. package/dist/domain/javascriptExportInstrumentation.js +97 -0
  142. package/dist/domain/javascriptFeatureTraversal.js +19 -7
  143. package/dist/domain/javascriptRuntimeStaticCandidates.js +3 -1
  144. package/dist/domain/javascriptSemanticAnalysis.js +386 -0
  145. package/dist/domain/javascriptSemanticIr.js +30 -0
  146. package/dist/domain/javascriptSemanticProjection.js +366 -0
  147. package/dist/domain/javascriptSemanticState.js +40 -0
  148. package/dist/domain/javascriptSemanticTraversal.js +22 -0
  149. package/dist/domain/javascriptSemanticValues.js +352 -0
  150. package/dist/domain/javascriptStaticAnalysis.js +5 -221
  151. package/dist/domain/javascriptStaticAnalysisBundler.js +209 -0
  152. package/dist/domain/javascriptStaticAnalysisCalls.js +180 -0
  153. package/dist/domain/javascriptStaticAnalysisHelpers.js +71 -2
  154. package/dist/domain/knownPageCoverage.js +21 -0
  155. package/dist/domain/managedApplicationGraph.js +14 -364
  156. package/dist/domain/managedApplicationGraphCoverage.js +170 -0
  157. package/dist/domain/managedApplicationGraphNodeCoverage.js +6 -0
  158. package/dist/domain/managedApplicationGraphNodes.js +336 -0
  159. package/dist/domain/managedArtifact.js +16 -8
  160. package/dist/domain/managedMemberComparison.js +37 -391
  161. package/dist/domain/managedMemberComparisonCoverage.js +72 -0
  162. package/dist/domain/managedMemberComparisonMatch.js +356 -0
  163. package/dist/domain/managedNativeVerification.js +27 -389
  164. package/dist/domain/managedNativeVerificationMatch.js +272 -0
  165. package/dist/domain/managedNativeVerificationSchemas.js +141 -0
  166. package/dist/domain/managedReconstruction.js +82 -69
  167. package/dist/domain/managedRuntimeCorrelation.js +12 -3
  168. package/dist/domain/nodeRuntimeCharacterization.js +66 -0
  169. package/dist/domain/permissionPolicy.js +2 -0
  170. package/dist/domain/processComparison.js +19 -0
  171. package/dist/domain/processPairedExperiment.js +128 -0
  172. package/dist/domain/reconstructionCoverage.js +387 -0
  173. package/dist/domain/reconstructionCoverageEvaluation.js +212 -0
  174. package/dist/domain/reconstructionVerificationSchemas.js +8 -0
  175. package/dist/domain/replayMachine.js +316 -0
  176. package/dist/domain/replayMachineRuntime.js +215 -0
  177. package/dist/domain/runtimeCharacterization.js +85 -0
  178. package/dist/domain/runtimeIdentification.js +210 -0
  179. package/dist/domain/webBundleAnalyzer.js +3 -409
  180. package/dist/domain/webBundleAnalyzerAst.js +77 -0
  181. package/dist/domain/webBundleAnalyzerInspection.js +307 -0
  182. package/dist/domain/webBundleAnalyzerResult.js +120 -0
  183. package/dist/dotnet/ManagedArtifactInspector.js +50 -29
  184. package/dist/dotnet/ManagedMemberInspector.js +51 -785
  185. package/dist/dotnet/ManagedMemberInspectorCore.js +297 -0
  186. package/dist/dotnet/ManagedMemberInstructionDecoder.js +427 -0
  187. package/dist/dotnet/ManagedMemberRows.js +120 -0
  188. package/dist/dotnet/ManagedMetadataInventory.js +42 -306
  189. package/dist/dotnet/ManagedMetadataInventoryRows.js +292 -0
  190. package/dist/dotnet/ManagedMetadataLayout.js +48 -111
  191. package/dist/dotnet/ManagedMetadataRowSizes.js +54 -0
  192. package/dist/dotnet/ManagedMethodBodyReader.js +143 -0
  193. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +311 -0
  194. package/dist/dotnet/ManagedNativeBoundaryInspector.js +102 -350
  195. package/dist/dotnet/ManagedPeReader.js +59 -28
  196. package/dist/evaluation/CodexAgentEval.js +132 -0
  197. package/dist/generatedPackageMetadata.js +2 -2
  198. package/dist/ghidra/GhidraClient.js +76 -91
  199. package/dist/ghidra/GhidraClientStartup.js +29 -0
  200. package/dist/ghidra/GhidraClientWire.js +34 -0
  201. package/dist/ghidra/GhidraDefaults.js +1 -1
  202. package/dist/ghidra/GhidraDiagnostics.js +6 -1
  203. package/dist/ghidra/GhidraInstallation.js +20 -15
  204. package/dist/ghidra/GhidraLauncher.js +93 -29
  205. package/dist/ghidra/GhidraProvider.js +61 -161
  206. package/dist/ghidra/GhidraProviderCapabilities.js +173 -0
  207. package/dist/ghidra/GhidraSessionValues.js +2 -0
  208. package/dist/ghidra/GhidraSocketConnection.js +44 -7
  209. package/dist/ghidra/GhidraTargetSnapshot.js +30 -0
  210. package/dist/ghidra/GhidraTransport.js +71 -0
  211. package/dist/identity.js +4 -2
  212. package/dist/main/messages.js +5 -0
  213. package/dist/main/reload.js +49 -0
  214. package/dist/main/shutdown.js +25 -0
  215. package/dist/main/startup.js +14 -0
  216. package/dist/main/state.js +26 -0
  217. package/dist/main/transport.js +61 -0
  218. package/dist/main/types.js +1 -0
  219. package/dist/main.js +35 -146
  220. package/dist/process/PrivateRuntimeRoot.js +3 -2
  221. package/dist/process/ProcessOwnership.js +35 -0
  222. package/dist/process/ProviderProcess.js +2 -0
  223. package/dist/replay/JavaScriptReplayWorker.js +64 -50
  224. package/dist/replay/LinuxJavaScriptReplayRunner.js +173 -390
  225. package/dist/replay/LinuxJavaScriptReplaySandbox.js +140 -0
  226. package/dist/replay/ReplayOutcome.js +95 -0
  227. package/dist/replay/ReplayProcessLifecycle.js +71 -0
  228. package/dist/server/ProcessCaptureElicitation.js +157 -0
  229. package/dist/server/createServer.js +124 -56
  230. package/dist/server/javascriptApplicationResult.js +85 -0
  231. package/dist/server/registerApplicationTools/characterization.js +57 -0
  232. package/dist/server/registerApplicationTools/compareVersions.js +34 -0
  233. package/dist/server/registerApplicationTools/controlledReplay.js +38 -0
  234. package/dist/server/registerApplicationTools/coverage.js +84 -0
  235. package/dist/server/registerApplicationTools/helpers.js +42 -0
  236. package/dist/server/registerApplicationTools/traceFeature.js +26 -0
  237. package/dist/server/registerApplicationTools/types.js +1 -0
  238. package/dist/server/registerApplicationTools.js +10 -112
  239. package/dist/server/registerBrowserTools.js +59 -83
  240. package/dist/server/registerElectronTools.js +48 -49
  241. package/dist/server/registerEnhancedTools.js +34 -42
  242. package/dist/server/registerEvidenceResources.js +56 -0
  243. package/dist/server/registerInvestigationTools/helpers.js +74 -0
  244. package/dist/server/registerInvestigationTools/types.js +1 -0
  245. package/dist/server/registerInvestigationTools.js +83 -116
  246. package/dist/server/registerJavaScriptApplicationGraphResource.js +69 -0
  247. package/dist/server/registerManagedTools.js +18 -1
  248. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +65 -0
  249. package/dist/server/registerManagedWorkflowTools/contract.js +8 -0
  250. package/dist/server/registerManagedWorkflowTools/evidence.js +43 -0
  251. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +39 -0
  252. package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +39 -0
  253. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +52 -0
  254. package/dist/server/registerManagedWorkflowTools/types.js +1 -0
  255. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +75 -0
  256. package/dist/server/registerManagedWorkflowTools.js +10 -274
  257. package/dist/server/registerOfficialTools.js +73 -59
  258. package/dist/server/registerSessionRecordTools.js +137 -0
  259. package/dist/server/registerSessionStatusTool.js +97 -26
  260. package/dist/server/registerSessionTools.js +60 -164
  261. package/dist/server/sessionAvailabilityPolicy.js +10 -0
  262. package/dist/server/toolRegistrationOptions.js +101 -3
  263. package/dist/server/toolResult.js +15 -4
  264. package/package.json +11 -11
  265. package/skills/reverse-engineer-anything/SKILL.md +76 -0
  266. package/skills/reverse-engineer-anything/references/controlled-replay.md +12 -0
  267. package/skills/reverse-engineer-anything/references/evidence-workflows.md +33 -0
  268. package/skills/reverse-engineer-anything/references/javascript-applications.md +25 -0
  269. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +36 -0
  270. package/skills/reverse-engineer-anything/references/runtime-observation.md +24 -0
  271. package/scripts/prepare-node-pty.mjs +0 -35
  272. package/scripts/rebuild-native.mjs +0 -22
  273. package/skills/rea-analysis/SKILL.md +0 -222
@@ -1,115 +1,13 @@
1
- import { compareApplicationVersionsEvidenceValidated, traceApplicationFeatureEvidenceValidated, } from "../application/JavaScriptApplicationWorkflowService.js";
2
- import { runControlledReplayValidated, } from "../application/JavaScriptReplayService.js";
3
- import { APPLICATION_TOOL_CONTRACTS } from "../contracts/applicationToolContracts.js";
4
- import { compareApplicationVersionsInputSchema } from "../domain/javascriptApplicationVersionComparisonSchemas.js";
5
- import { applicationVersionComparisonResultSchema } from "../domain/javascriptApplicationVersionComparisonSchemas.js";
6
- import { traceApplicationFeatureInputSchema } from "../domain/javascriptFeatureTraceSchemas.js";
7
- import { parseEvidence } from "../domain/evidence.js";
8
- import { controlledReplayInputSchema, controlledReplayOutputSchema, } from "../domain/javascriptReplay.js";
9
- import { logToolExecution } from "./toolLogging.js";
10
- import { toCallToolResult } from "./toolResult.js";
11
- import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
12
- import { safeParseToolInput } from "./toolInputValidation.js";
13
- import { mcpProgressReporter } from "./mcpProgress.js";
1
+ import { registerTraceFeatureTool } from "./registerApplicationTools/traceFeature.js";
2
+ import { registerCompareApplicationVersionsTool } from "./registerApplicationTools/compareVersions.js";
3
+ import { registerControlledReplayTool } from "./registerApplicationTools/controlledReplay.js";
4
+ import { registerCharacterizationTools } from "./registerApplicationTools/characterization.js";
5
+ import { registerCoverageTools } from "./registerApplicationTools/coverage.js";
14
6
  /** Register provider-neutral JavaScript application graph workflows. */
15
7
  export const registerApplicationTools = (server, options) => {
16
- const [traceContract, compareContract, replayContract] = APPLICATION_TOOL_CONTRACTS;
17
- server.registerTool(traceContract.name, toolRegistrationOptions(traceContract), async (input) => {
18
- const parsedInput = safeParseToolInput(traceApplicationFeatureInputSchema, input, traceContract.name);
19
- if (!parsedInput.ok)
20
- return toCallToolResult(parsedInput, traceContract);
21
- const parsed = parsedInput.value;
22
- const result = await logToolExecution(options.logger, traceContract.name, () => Promise.resolve(traceApplicationFeatureEvidenceValidated(parsed)));
23
- if (!result.ok)
24
- return toCallToolResult(result, traceContract);
25
- const sources = [parsed.application, ...parsed.native_observations];
26
- const recorded = recordSources(options.recordEvidence, sources);
27
- if (!recorded.ok)
28
- return toCallToolResult(recorded, traceContract);
29
- return recordResult(options, traceContract, result.value);
30
- });
31
- server.registerTool(compareContract.name, toolRegistrationOptions(compareContract), async (input) => {
32
- const parsedInput = safeParseToolInput(compareApplicationVersionsInputSchema, input, compareContract.name);
33
- if (!parsedInput.ok)
34
- return toCallToolResult(parsedInput, compareContract);
35
- const parsed = parsedInput.value;
36
- const result = await logToolExecution(options.logger, compareContract.name, () => Promise.resolve(compareApplicationVersionsEvidenceValidated(parsed)));
37
- if (!result.ok)
38
- return toCallToolResult(result, compareContract);
39
- const sources = [
40
- parsed.left,
41
- parsed.right,
42
- ...parsed.left_native_observations,
43
- ...parsed.right_native_observations,
44
- ];
45
- const recorded = recordSources(options.recordEvidence, sources);
46
- if (!recorded.ok)
47
- return toCallToolResult(recorded, compareContract);
48
- const comparison = applicationVersionComparisonResultSchema.parse(result.value.normalized_result);
49
- const unknown = comparison.summary.unknown > 0;
50
- return recordResult(options, compareContract, result.value, parsed.unknown_registry_approved === true && unknown);
51
- });
52
- server.registerTool(replayContract.name, toolRegistrationOptions(replayContract), async (input, context) => {
53
- const parsedInput = safeParseToolInput(controlledReplayInputSchema, input, replayContract.name);
54
- if (!parsedInput.ok)
55
- return toCallToolResult(parsedInput, replayContract);
56
- const parsed = parsedInput.value;
57
- const result = await logToolExecution(options.logger, replayContract.name, () => runControlledReplayValidated(options.replay, parsed, {
58
- signal: context.mcpReq.signal,
59
- progress: mcpProgressReporter(context),
60
- }));
61
- if (!result.ok)
62
- return toCallToolResult(result, replayContract);
63
- const output = controlledReplayOutputSchema.parse(result.value);
64
- if (output.evidence !== null) {
65
- const sourcesRecorded = recordSources(options.recordEvidence, output.source_evidence.map((item) => parseEvidence(item)));
66
- if (!sourcesRecorded.ok)
67
- return toCallToolResult(sourcesRecorded, replayContract);
68
- const recorded = options.recordEvidence?.(parseEvidence(output.evidence));
69
- if (recorded !== undefined && !recorded.ok)
70
- return toCallToolResult(recorded, replayContract);
71
- }
72
- return toCallToolResult(result, replayContract, {
73
- evidenceResourcesAvailable: output.evidence !== null && options.recordEvidence !== undefined,
74
- });
75
- });
76
- };
77
- const recordSources = (recordEvidence, sources) => {
78
- for (const source of sources) {
79
- const recorded = recordEvidence?.(source);
80
- if (recorded !== undefined && !recorded.ok)
81
- return recorded;
82
- }
83
- return { ok: true, value: null };
84
- };
85
- const recordResult = (options, contract, evidence, recordUnknown = false) => {
86
- const recorded = recordUnknown
87
- ? options.recordEvidenceWithUnknown?.(evidence, {
88
- approved: true,
89
- question: "Which application entities remain unmatched or ambiguous across these versions?",
90
- severity: "medium",
91
- domain: "application-version-comparison",
92
- supporting_evidence_ids: [evidence.evidence_id],
93
- contradicting_evidence_ids: [],
94
- required_authority: "shipped-artifact",
95
- required_confidence: "observed",
96
- required_environment: null,
97
- recommended_probes: [
98
- {
99
- operation: "analyze_javascript_application",
100
- rationale: "Repeat static reconstruction with complete artifacts and source maps when available.",
101
- },
102
- {
103
- operation: "reconcile_javascript_runtime",
104
- rationale: "Add approved passive runtime Evidence without promoting it to static fact.",
105
- },
106
- ],
107
- relationships: [],
108
- })
109
- : options.recordEvidence?.(evidence);
110
- if (recorded !== undefined && !recorded.ok)
111
- return toCallToolResult(recorded, contract);
112
- return toCallToolResult({ ok: true, value: evidence }, contract, {
113
- evidenceResourcesAvailable: recorded !== undefined,
114
- });
8
+ registerTraceFeatureTool(server, options);
9
+ registerCompareApplicationVersionsTool(server, options);
10
+ registerControlledReplayTool(server, options);
11
+ registerCharacterizationTools(server, options);
12
+ registerCoverageTools(server, options);
115
13
  };
@@ -14,100 +14,76 @@ import { mcpProgressReporter } from "./mcpProgress.js";
14
14
  /** Register browser tools even when policy/provider availability denies execution. */
15
15
  export const registerBrowserTools = (server, options) => {
16
16
  const [listContract, inspectContract, analyzeContract, sessionContract, webMcpContract, captureDiffContract, screenshotContract, screenshotDiffContract,] = BROWSER_TOOL_CONTRACTS;
17
- server.registerTool(listContract.name, toolRegistrationOptions(listContract), async (input, context) => {
18
- const parsedInput = safeParseToolInput(listBrowserTargetsInputSchema, input, listContract.name);
19
- if (!parsedInput.ok)
20
- return toCallToolResult(parsedInput, listContract);
21
- const parsed = parsedInput.value;
22
- const result = await logToolExecution(options.logger, listContract.name, () => listBrowserTargets(options.browser, options.permissionAuthority, parsed, { signal: context.mcpReq.signal }));
23
- if (!result.ok)
24
- return toCallToolResult(result, listContract);
25
- return evidenceResult(options, listContract, result.value);
17
+ registerBrowserTool(server, options, {
18
+ contract: listContract,
19
+ schema: listBrowserTargetsInputSchema,
20
+ execute: (parsed, { signal }) => listBrowserTargets(options.browser, options.permissionAuthority, parsed, {
21
+ signal,
22
+ }),
26
23
  });
27
- server.registerTool(inspectContract.name, toolRegistrationOptions(inspectContract), async (input, context) => {
28
- const parsedInput = safeParseToolInput(inspectWebPageInputSchema, input, inspectContract.name);
29
- if (!parsedInput.ok)
30
- return toCallToolResult(parsedInput, inspectContract);
31
- const parsed = parsedInput.value;
32
- const result = await logToolExecution(options.logger, inspectContract.name, () => inspectWebPage(options.browser, options.permissionAuthority, parsed, {
33
- signal: context.mcpReq.signal,
34
- progress: mcpProgressReporter(context),
35
- }));
36
- if (!result.ok)
37
- return toCallToolResult(result, inspectContract);
38
- return evidenceResult(options, inspectContract, result.value);
24
+ registerBrowserTool(server, options, {
25
+ contract: inspectContract,
26
+ schema: inspectWebPageInputSchema,
27
+ execute: (parsed, { signal, progress }) => inspectWebPage(options.browser, options.permissionAuthority, parsed, {
28
+ signal,
29
+ progress,
30
+ }),
39
31
  });
40
- server.registerTool(analyzeContract.name, toolRegistrationOptions(analyzeContract), async (input, context) => {
41
- const parsedInput = safeParseToolInput(analyzeWebBundleInputSchema, input, analyzeContract.name);
42
- if (!parsedInput.ok)
43
- return toCallToolResult(parsedInput, analyzeContract);
44
- const parsed = parsedInput.value;
45
- const result = await logToolExecution(options.logger, analyzeContract.name, () => analyzeWebBundle(options.browser, options.permissionAuthority, parsed, {
46
- signal: context.mcpReq.signal,
47
- progress: mcpProgressReporter(context),
48
- }));
49
- if (!result.ok)
50
- return toCallToolResult(result, analyzeContract);
51
- return evidenceResult(options, analyzeContract, result.value);
32
+ registerBrowserTool(server, options, {
33
+ contract: analyzeContract,
34
+ schema: analyzeWebBundleInputSchema,
35
+ execute: (parsed, { signal, progress }) => analyzeWebBundle(options.browser, options.permissionAuthority, parsed, {
36
+ signal,
37
+ progress,
38
+ }),
52
39
  });
53
- server.registerTool(sessionContract.name, toolRegistrationOptions(sessionContract), async (input, context) => {
54
- const parsedInput = safeParseToolInput(observeWebSessionInputSchema, input, sessionContract.name);
55
- if (!parsedInput.ok)
56
- return toCallToolResult(parsedInput, sessionContract);
57
- const parsed = parsedInput.value;
58
- const result = await logToolExecution(options.logger, sessionContract.name, () => observeWebSession(options.browser, options.permissionAuthority, parsed, {
59
- signal: context.mcpReq.signal,
60
- progress: mcpProgressReporter(context),
61
- }));
62
- if (!result.ok)
63
- return toCallToolResult(result, sessionContract);
64
- return evidenceResult(options, sessionContract, result.value);
40
+ registerBrowserTool(server, options, {
41
+ contract: sessionContract,
42
+ schema: observeWebSessionInputSchema,
43
+ execute: (parsed, { signal, progress }) => observeWebSession(options.browser, options.permissionAuthority, parsed, {
44
+ signal,
45
+ progress,
46
+ }),
65
47
  });
66
- server.registerTool(webMcpContract.name, toolRegistrationOptions(webMcpContract), async (input, context) => {
67
- const parsedInput = safeParseToolInput(discoverWebMcpToolsInputSchema, input, webMcpContract.name);
68
- if (!parsedInput.ok)
69
- return toCallToolResult(parsedInput, webMcpContract);
70
- const parsed = parsedInput.value;
71
- const result = await logToolExecution(options.logger, webMcpContract.name, () => discoverWebMcpTools(options.browser, options.permissionAuthority, parsed, {
72
- signal: context.mcpReq.signal,
73
- progress: mcpProgressReporter(context),
74
- }));
75
- if (!result.ok)
76
- return toCallToolResult(result, webMcpContract);
77
- return evidenceResult(options, webMcpContract, result.value);
48
+ registerBrowserTool(server, options, {
49
+ contract: webMcpContract,
50
+ schema: discoverWebMcpToolsInputSchema,
51
+ execute: (parsed, { signal, progress }) => discoverWebMcpTools(options.browser, options.permissionAuthority, parsed, {
52
+ signal,
53
+ progress,
54
+ }),
78
55
  });
79
- server.registerTool(captureDiffContract.name, toolRegistrationOptions(captureDiffContract), async (input) => {
80
- const parsedInput = safeParseToolInput(compareWebCapturesInputSchema, input, captureDiffContract.name);
81
- if (!parsedInput.ok)
82
- return toCallToolResult(parsedInput, captureDiffContract);
83
- const parsed = parsedInput.value;
84
- const result = await logToolExecution(options.logger, captureDiffContract.name, () => compareWebCaptureEvidence(options.browser, parsed));
85
- if (!result.ok)
86
- return toCallToolResult(result, captureDiffContract);
87
- return evidenceResult(options, captureDiffContract, result.value);
56
+ registerBrowserTool(server, options, {
57
+ contract: captureDiffContract,
58
+ schema: compareWebCapturesInputSchema,
59
+ execute: (parsed, _context) => compareWebCaptureEvidence(options.browser, parsed),
60
+ });
61
+ registerBrowserTool(server, options, {
62
+ contract: screenshotContract,
63
+ schema: captureWebScreenshotInputSchema,
64
+ execute: (parsed, { signal, progress }) => captureWebScreenshot(options.browser, options.permissionAuthority, parsed, {
65
+ signal,
66
+ progress,
67
+ }),
88
68
  });
89
- server.registerTool(screenshotContract.name, toolRegistrationOptions(screenshotContract), async (input, context) => {
90
- const parsedInput = safeParseToolInput(captureWebScreenshotInputSchema, input, screenshotContract.name);
69
+ registerBrowserTool(server, options, {
70
+ contract: screenshotDiffContract,
71
+ schema: compareWebScreenshotsInputSchema,
72
+ execute: (parsed, _context) => compareWebScreenshotEvidence(options.browser, parsed),
73
+ });
74
+ };
75
+ const registerBrowserTool = (server, options, spec) => {
76
+ server.registerTool(spec.contract.name, toolRegistrationOptions(spec.contract), async (input, context) => {
77
+ const parsedInput = safeParseToolInput(spec.schema, input, spec.contract.name);
91
78
  if (!parsedInput.ok)
92
- return toCallToolResult(parsedInput, screenshotContract);
93
- const parsed = parsedInput.value;
94
- const result = await logToolExecution(options.logger, screenshotContract.name, () => captureWebScreenshot(options.browser, options.permissionAuthority, parsed, {
79
+ return toCallToolResult(parsedInput, spec.contract);
80
+ const result = await logToolExecution(options.logger, spec.contract.name, () => spec.execute(parsedInput.value, {
95
81
  signal: context.mcpReq.signal,
96
82
  progress: mcpProgressReporter(context),
97
83
  }));
98
84
  if (!result.ok)
99
- return toCallToolResult(result, screenshotContract);
100
- return evidenceResult(options, screenshotContract, result.value);
101
- });
102
- server.registerTool(screenshotDiffContract.name, toolRegistrationOptions(screenshotDiffContract), async (input) => {
103
- const parsedInput = safeParseToolInput(compareWebScreenshotsInputSchema, input, screenshotDiffContract.name);
104
- if (!parsedInput.ok)
105
- return toCallToolResult(parsedInput, screenshotDiffContract);
106
- const parsed = parsedInput.value;
107
- const result = await logToolExecution(options.logger, screenshotDiffContract.name, () => compareWebScreenshotEvidence(options.browser, parsed));
108
- if (!result.ok)
109
- return toCallToolResult(result, screenshotDiffContract);
110
- return evidenceResult(options, screenshotDiffContract, result.value);
85
+ return toCallToolResult(result, spec.contract);
86
+ return evidenceResult(options, spec.contract, result.value);
111
87
  });
112
88
  };
113
89
  const evidenceResult = (options, contract, evidence) => {
@@ -1,78 +1,77 @@
1
1
  import { analyzeJavaScriptApplicationValidated } from "../application/JavaScriptApplicationService.js";
2
2
  import { reconcileJavaScriptRuntimeEvidenceValidated } from "../application/JavaScriptRuntimeReconciliationService.js";
3
3
  import { inspectElectronPage, listElectronTargets, } from "../application/ElectronObservationService.js";
4
- import { ELECTRON_TOOL_CONTRACTS } from "../contracts/electronToolContracts.js";
4
+ import { analyzeJavaScriptApplicationToolInputSchema, ELECTRON_TOOL_CONTRACTS, } from "../contracts/electronToolContracts.js";
5
5
  import { inspectElectronPageInputSchema, listElectronTargetsInputSchema, } from "../domain/electronObservation.js";
6
- import { analyzeJavaScriptApplicationInputSchema } from "../domain/javascriptApplicationAnalysis.js";
7
6
  import { reconcileJavaScriptRuntimeInputSchema } from "../domain/javascriptRuntimeReconciliationSchemas.js";
8
7
  import { logToolExecution } from "./toolLogging.js";
9
8
  import { toCallToolResult } from "./toolResult.js";
10
9
  import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
11
10
  import { safeParseToolInput } from "./toolInputValidation.js";
12
11
  import { mcpProgressReporter } from "./mcpProgress.js";
12
+ import { summarizeJavaScriptApplicationEvidence } from "./javascriptApplicationResult.js";
13
13
  /** Register Electron tools even when provider or permission policy is absent. */
14
14
  export const registerElectronTools = (server, options) => {
15
15
  const [listContract, inspectContract, analyzeContract, reconcileContract] = ELECTRON_TOOL_CONTRACTS;
16
- server.registerTool(listContract.name, toolRegistrationOptions(listContract), async (input, context) => {
17
- const parsedInput = safeParseToolInput(listElectronTargetsInputSchema, input, listContract.name);
18
- if (!parsedInput.ok)
19
- return toCallToolResult(parsedInput, listContract);
20
- const parsed = parsedInput.value;
21
- const result = await logToolExecution(options.logger, listContract.name, () => listElectronTargets(options.electron, options.permissionAuthority, parsed, { signal: context.mcpReq.signal }));
22
- if (!result.ok)
23
- return toCallToolResult(result, listContract);
24
- return evidenceResult(options, listContract, result.value);
16
+ registerElectronTool(server, options, {
17
+ contract: listContract,
18
+ schema: listElectronTargetsInputSchema,
19
+ execute: (parsed, { signal }) => listElectronTargets(options.electron, options.permissionAuthority, parsed, {
20
+ signal,
21
+ }),
25
22
  });
26
- server.registerTool(inspectContract.name, toolRegistrationOptions(inspectContract), async (input, context) => {
27
- const parsedInput = safeParseToolInput(inspectElectronPageInputSchema, input, inspectContract.name);
28
- if (!parsedInput.ok)
29
- return toCallToolResult(parsedInput, inspectContract);
30
- const parsed = parsedInput.value;
31
- const result = await logToolExecution(options.logger, inspectContract.name, () => inspectElectronPage(options.electron, options.permissionAuthority, parsed, {
32
- signal: context.mcpReq.signal,
33
- progress: mcpProgressReporter(context),
34
- }));
35
- if (!result.ok)
36
- return toCallToolResult(result, inspectContract);
37
- return evidenceResult(options, inspectContract, result.value);
23
+ registerElectronTool(server, options, {
24
+ contract: inspectContract,
25
+ schema: inspectElectronPageInputSchema,
26
+ execute: (parsed, { signal, progress }) => inspectElectronPage(options.electron, options.permissionAuthority, parsed, {
27
+ signal,
28
+ progress,
29
+ }),
38
30
  });
39
- server.registerTool(analyzeContract.name, toolRegistrationOptions(analyzeContract), async (input, context) => {
40
- const parsedInput = safeParseToolInput(analyzeJavaScriptApplicationInputSchema, input, analyzeContract.name);
31
+ registerElectronTool(server, options, {
32
+ contract: analyzeContract,
33
+ schema: analyzeJavaScriptApplicationToolInputSchema,
34
+ execute: (parsed, { signal, progress }) => analyzeJavaScriptApplicationValidated(options.permissionAuthority, parsed, { signal, progress }),
35
+ projectEvidence: (evidence, parsed) => {
36
+ const summary = summarizeJavaScriptApplicationEvidence(evidence);
37
+ return parsed.detail === "full"
38
+ ? { structured: evidence.normalized_result, text: summary }
39
+ : { structured: summary };
40
+ },
41
+ });
42
+ registerElectronTool(server, options, {
43
+ contract: reconcileContract,
44
+ schema: reconcileJavaScriptRuntimeInputSchema,
45
+ execute: (parsed, _context) => Promise.resolve(reconcileJavaScriptRuntimeEvidenceValidated(parsed)),
46
+ });
47
+ };
48
+ const registerElectronTool = (server, options, spec) => {
49
+ server.registerTool(spec.contract.name, toolRegistrationOptions(spec.contract), async (input, context) => {
50
+ const parsedInput = safeParseToolInput(spec.schema, input, spec.contract.name);
41
51
  if (!parsedInput.ok)
42
- return toCallToolResult(parsedInput, analyzeContract);
43
- const parsed = parsedInput.value;
44
- const result = await logToolExecution(options.logger, analyzeContract.name, () => analyzeJavaScriptApplicationValidated(options.permissionAuthority, parsed, {
52
+ return toCallToolResult(parsedInput, spec.contract);
53
+ const result = await logToolExecution(options.logger, spec.contract.name, () => spec.execute(parsedInput.value, {
45
54
  signal: context.mcpReq.signal,
46
55
  progress: mcpProgressReporter(context),
47
56
  }));
48
57
  if (!result.ok)
49
- return toCallToolResult(result, analyzeContract);
50
- return evidenceResult(options, analyzeContract, result.value);
51
- });
52
- server.registerTool(reconcileContract.name, toolRegistrationOptions(reconcileContract), async (input) => {
53
- const parsedInput = safeParseToolInput(reconcileJavaScriptRuntimeInputSchema, input, reconcileContract.name);
54
- if (!parsedInput.ok)
55
- return toCallToolResult(parsedInput, reconcileContract);
56
- const parsed = parsedInput.value;
57
- const result = await logToolExecution(options.logger, reconcileContract.name, () => Promise.resolve(reconcileJavaScriptRuntimeEvidenceValidated(parsed)));
58
- if (!result.ok)
59
- return toCallToolResult(result, reconcileContract);
60
- for (const source of [
61
- ...parsed.static_layers.map(({ analysis }) => analysis),
62
- ...parsed.runtime_observations,
63
- ]) {
64
- const recorded = options.recordEvidence?.(source);
65
- if (recorded !== undefined && !recorded.ok)
66
- return toCallToolResult(recorded, reconcileContract);
67
- }
68
- return evidenceResult(options, reconcileContract, result.value);
58
+ return toCallToolResult(result, spec.contract);
59
+ return evidenceResult(options, spec.contract, result.value, spec.projectEvidence?.(result.value, parsedInput.value));
69
60
  });
70
61
  };
71
- const evidenceResult = (options, contract, evidence) => {
62
+ const evidenceResult = (options, contract, evidence, projection) => {
72
63
  const recorded = options.recordEvidence?.(evidence);
73
64
  return recorded !== undefined && !recorded.ok
74
65
  ? toCallToolResult(recorded, contract)
75
66
  : toCallToolResult({ ok: true, value: evidence }, contract, {
76
67
  evidenceResourcesAvailable: recorded !== undefined,
68
+ ...(projection === undefined
69
+ ? {}
70
+ : {
71
+ evidenceResultProjection: projection.structured,
72
+ ...(projection.text === undefined
73
+ ? {}
74
+ : { evidenceTextProjection: projection.text }),
75
+ }),
77
76
  });
78
77
  };
@@ -1,10 +1,9 @@
1
1
  import { EnhancedTools, } from "../application/EnhancedTools.js";
2
- import { enhancedToolNameSchema } from "../contracts/enhancedInputs.js";
2
+ import { enhancedInputSchemas, enhancedToolNameSchema, } from "../contracts/enhancedInputs.js";
3
3
  import { ENHANCED_TOOL_CONTRACTS, } from "../contracts/toolContracts.js";
4
4
  import { toCallToolResult } from "./toolResult.js";
5
5
  import { logToolExecution } from "./toolLogging.js";
6
6
  import { createEvidence } from "../domain/evidence.js";
7
- import { enhancedInputSchemas } from "../contracts/enhancedInputs.js";
8
7
  import { AnalysisInputError, UnknownRegistryError } from "../domain/errors.js";
9
8
  import { ok } from "../domain/result.js";
10
9
  import { mcpProgressReporter } from "./mcpProgress.js";
@@ -83,50 +82,43 @@ const registerEnhancedTool = (server, services, contract, registration) => {
83
82
  });
84
83
  };
85
84
  const jsonParameters = (input) => Object.fromEntries(Object.entries(input).filter((entry) => entry[1] !== undefined));
85
+ const ENHANCED_INPUT_PARSERS = {
86
+ swift_classes: (input) => safeParseToolInput(enhancedInputSchemas.swift_classes, input, "swift_classes"),
87
+ get_objc_classes: (input) => safeParseToolInput(enhancedInputSchemas.get_objc_classes, input, "get_objc_classes"),
88
+ get_objc_protocols: (input) => safeParseToolInput(enhancedInputSchemas.get_objc_protocols, input, "get_objc_protocols"),
89
+ batch_decompile: (input) => safeParseToolInput(enhancedInputSchemas.batch_decompile, input, "batch_decompile"),
90
+ get_call_graph: (input) => safeParseToolInput(enhancedInputSchemas.get_call_graph, input, "get_call_graph"),
91
+ analyze_swift_types: (input) => safeParseToolInput(enhancedInputSchemas.analyze_swift_types, input, "analyze_swift_types"),
92
+ find_xrefs_to_name: (input) => safeParseToolInput(enhancedInputSchemas.find_xrefs_to_name, input, "find_xrefs_to_name"),
93
+ binary_overview: (input) => safeParseToolInput(enhancedInputSchemas.binary_overview, input, "binary_overview"),
94
+ analyze_function: (input) => safeParseToolInput(enhancedInputSchemas.analyze_function, input, "analyze_function"),
95
+ trace_feature: (input) => safeParseToolInput(enhancedInputSchemas.trace_feature, input, "trace_feature"),
96
+ };
86
97
  const parseEnhancedCall = (name, input) => {
87
98
  switch (name) {
88
- case "swift_classes": {
89
- const parsed = safeParseToolInput(enhancedInputSchemas.swift_classes, input, name);
90
- return parsed.ok ? ok({ name, input: parsed.value }) : parsed;
91
- }
92
- case "get_objc_classes": {
93
- const parsed = safeParseToolInput(enhancedInputSchemas.get_objc_classes, input, name);
94
- return parsed.ok ? ok({ name, input: parsed.value }) : parsed;
95
- }
96
- case "get_objc_protocols": {
97
- const parsed = safeParseToolInput(enhancedInputSchemas.get_objc_protocols, input, name);
98
- return parsed.ok ? ok({ name, input: parsed.value }) : parsed;
99
- }
100
- case "batch_decompile": {
101
- const parsed = safeParseToolInput(enhancedInputSchemas.batch_decompile, input, name);
102
- return parsed.ok ? ok({ name, input: parsed.value }) : parsed;
103
- }
104
- case "get_call_graph": {
105
- const parsed = safeParseToolInput(enhancedInputSchemas.get_call_graph, input, name);
106
- return parsed.ok ? ok({ name, input: parsed.value }) : parsed;
107
- }
108
- case "analyze_swift_types": {
109
- const parsed = safeParseToolInput(enhancedInputSchemas.analyze_swift_types, input, name);
110
- return parsed.ok ? ok({ name, input: parsed.value }) : parsed;
111
- }
112
- case "find_xrefs_to_name": {
113
- const parsed = safeParseToolInput(enhancedInputSchemas.find_xrefs_to_name, input, name);
114
- return parsed.ok ? ok({ name, input: parsed.value }) : parsed;
115
- }
116
- case "binary_overview": {
117
- const parsed = safeParseToolInput(enhancedInputSchemas.binary_overview, input, name);
118
- return parsed.ok ? ok({ name, input: parsed.value }) : parsed;
119
- }
120
- case "analyze_function": {
121
- const parsed = safeParseToolInput(enhancedInputSchemas.analyze_function, input, name);
122
- return parsed.ok ? ok({ name, input: parsed.value }) : parsed;
123
- }
124
- case "trace_feature": {
125
- const parsed = safeParseToolInput(enhancedInputSchemas.trace_feature, input, name);
126
- return parsed.ok ? ok({ name, input: parsed.value }) : parsed;
127
- }
99
+ case "swift_classes":
100
+ return mapEnhancedCall(ENHANCED_INPUT_PARSERS.swift_classes(input), (value) => ({ name, input: value }));
101
+ case "get_objc_classes":
102
+ return mapEnhancedCall(ENHANCED_INPUT_PARSERS.get_objc_classes(input), (value) => ({ name, input: value }));
103
+ case "get_objc_protocols":
104
+ return mapEnhancedCall(ENHANCED_INPUT_PARSERS.get_objc_protocols(input), (value) => ({ name, input: value }));
105
+ case "batch_decompile":
106
+ return mapEnhancedCall(ENHANCED_INPUT_PARSERS.batch_decompile(input), (value) => ({ name, input: value }));
107
+ case "get_call_graph":
108
+ return mapEnhancedCall(ENHANCED_INPUT_PARSERS.get_call_graph(input), (value) => ({ name, input: value }));
109
+ case "analyze_swift_types":
110
+ return mapEnhancedCall(ENHANCED_INPUT_PARSERS.analyze_swift_types(input), (value) => ({ name, input: value }));
111
+ case "find_xrefs_to_name":
112
+ return mapEnhancedCall(ENHANCED_INPUT_PARSERS.find_xrefs_to_name(input), (value) => ({ name, input: value }));
113
+ case "binary_overview":
114
+ return mapEnhancedCall(ENHANCED_INPUT_PARSERS.binary_overview(input), (value) => ({ name, input: value }));
115
+ case "analyze_function":
116
+ return mapEnhancedCall(ENHANCED_INPUT_PARSERS.analyze_function(input), (value) => ({ name, input: value }));
117
+ case "trace_feature":
118
+ return mapEnhancedCall(ENHANCED_INPUT_PARSERS.trace_feature(input), (value) => ({ name, input: value }));
128
119
  }
129
120
  };
121
+ const mapEnhancedCall = (parsed, project) => parsed.ok ? ok(project(parsed.value)) : parsed;
130
122
  const recordWorkflowUnknowns = ({ name, input, result, evidenceId, recordUnknown, }) => {
131
123
  if (name !== "trace_feature" ||
132
124
  input.unknown_registry_approved !== true ||
@@ -1,9 +1,50 @@
1
1
  import { ResourceNotFoundError, ResourceTemplate, } from "@modelcontextprotocol/server";
2
2
  import { createHash } from "node:crypto";
3
3
  import canonicalize from "canonicalize";
4
+ import { registerJavaScriptApplicationGraphResource } from "./registerJavaScriptApplicationGraphResource.js";
4
5
  const evidenceUri = (evidenceId) => `rea://evidence/${evidenceId}`;
5
6
  /** Expose immutable session-owned Evidence v2 records as MCP resources. */
6
7
  export const registerEvidenceResources = (server, session) => {
8
+ registerReconstructionCoverageResource(server, session);
9
+ registerInvestigationWorkspaceResource(server, session);
10
+ registerSessionEvidenceResource(server, session);
11
+ registerActiveResidualUnknownsResource(server, session);
12
+ registerAnalysisSnapshotResource(server, session);
13
+ registerArtifactPageResource(server, session);
14
+ registerFunctionDossierResource(server, session);
15
+ registerEvidenceSectionResource(server, session);
16
+ registerJavaScriptApplicationGraphResource(server, session);
17
+ registerResidualUnknownResource(server, session);
18
+ };
19
+ const registerReconstructionCoverageResource = (server, session) => {
20
+ server.registerResource("reconstruction-coverage-revision", new ResourceTemplate("rea://reconstruction-coverage/{workspaceId}/revision/{revision}", {
21
+ list: () => ({
22
+ resources: session
23
+ .reconstructionCoverageWorkspaces()
24
+ .map((workspace) => ({
25
+ uri: coverageWorkspaceUri(workspace.workspace_id, workspace.revision),
26
+ name: `${workspace.workspace_id} revision ${String(workspace.revision)}`,
27
+ title: `${workspace.name} coverage revision ${String(workspace.revision)}`,
28
+ description: "Immutable evidence-backed reconstruction coverage workspace revision.",
29
+ mimeType: "application/json",
30
+ })),
31
+ }),
32
+ }), {
33
+ title: "Reconstruction coverage revision",
34
+ description: "Canonical CAS-linked surfaces, owners, claims, verifiers, evidence, and completion boundaries.",
35
+ mimeType: "application/json",
36
+ }, (uri, variables) => {
37
+ const workspaceId = stringVariable(variables.workspaceId, uri.href);
38
+ const revisionText = stringVariable(variables.revision, uri.href);
39
+ if (!/^\d+$/u.test(revisionText))
40
+ throw new ResourceNotFoundError(uri.href);
41
+ const workspace = session.reconstructionCoverageWorkspace(workspaceId, Number(revisionText));
42
+ if (workspace === undefined)
43
+ throw new ResourceNotFoundError(uri.href);
44
+ return jsonResource(uri.href, workspace);
45
+ });
46
+ };
47
+ const registerInvestigationWorkspaceResource = (server, session) => {
7
48
  server.registerResource("investigation-workspace-revision", new ResourceTemplate("rea://workspace/{workspaceId}/revision/{revision}", {
8
49
  list: () => ({
9
50
  resources: session.investigationWorkspaces().map((workspace) => ({
@@ -40,6 +81,8 @@ export const registerEvidenceResources = (server, session) => {
40
81
  throw new ResourceNotFoundError(uri.href);
41
82
  return jsonResource(uri.href, workspace);
42
83
  });
84
+ };
85
+ const registerSessionEvidenceResource = (server, session) => {
43
86
  server.registerResource("session-evidence", new ResourceTemplate("rea://evidence/{evidenceId}", {
44
87
  list: () => ({
45
88
  resources: session.exportEvidenceBundle().records.map((evidence) => ({
@@ -77,11 +120,15 @@ export const registerEvidenceResources = (server, session) => {
77
120
  ],
78
121
  };
79
122
  });
123
+ };
124
+ const registerActiveResidualUnknownsResource = (server, session) => {
80
125
  server.registerResource("active-residual-unknowns", "rea://unknowns/active", {
81
126
  title: "Active residual unknowns",
82
127
  description: "Current unresolved session-owned residual unknown heads.",
83
128
  mimeType: "application/json",
84
129
  }, (uri) => jsonResource(uri.href, session.listUnknowns().filter(({ status }) => status !== "resolved")));
130
+ };
131
+ const registerAnalysisSnapshotResource = (server, session) => {
85
132
  server.registerResource("analysis-snapshot", new ResourceTemplate("rea://snapshot/{snapshotDigest}", {
86
133
  list: () => {
87
134
  const snapshot = session.exportAnalysisSnapshot();
@@ -111,6 +158,8 @@ export const registerEvidenceResources = (server, session) => {
111
158
  throw new ResourceNotFoundError(uri.href);
112
159
  return jsonResource(uri.href, snapshot.value);
113
160
  });
161
+ };
162
+ const registerArtifactPageResource = (server, session) => {
114
163
  server.registerResource("artifact-page", new ResourceTemplate("rea://artifact/{manifestId}/{collection}", {
115
164
  list: undefined,
116
165
  complete: {
@@ -143,6 +192,8 @@ export const registerEvidenceResources = (server, session) => {
143
192
  limitations: evidence.limitations,
144
193
  });
145
194
  });
195
+ };
196
+ const registerFunctionDossierResource = (server, session) => {
146
197
  server.registerResource("function-dossier", new ResourceTemplate("rea://function/{targetSha256}/{address}", {
147
198
  list: undefined,
148
199
  }), {
@@ -161,6 +212,8 @@ export const registerEvidenceResources = (server, session) => {
161
212
  throw new ResourceNotFoundError(uri.href);
162
213
  return jsonResource(uri.href, evidence);
163
214
  });
215
+ };
216
+ const registerEvidenceSectionResource = (server, session) => {
164
217
  server.registerResource("evidence-section", new ResourceTemplate("rea://evidence/{evidenceId}/section/{section}", {
165
218
  list: undefined,
166
219
  complete: {
@@ -191,6 +244,8 @@ export const registerEvidenceResources = (server, session) => {
191
244
  value,
192
245
  });
193
246
  });
247
+ };
248
+ const registerResidualUnknownResource = (server, session) => {
194
249
  server.registerResource("residual-unknown", new ResourceTemplate("rea://unknown/{unknownId}", {
195
250
  list: () => ({
196
251
  resources: session.listUnknowns().map((unknown) => ({
@@ -224,6 +279,7 @@ export const registerEvidenceResources = (server, session) => {
224
279
  return jsonResource(uri.href, { current: unknown, history });
225
280
  });
226
281
  };
282
+ const coverageWorkspaceUri = (workspaceId, revision) => `rea://reconstruction-coverage/${workspaceId}/revision/${String(revision)}`;
227
283
  const workspaceUri = (workspaceId, revision) => `rea://workspace/${workspaceId}/revision/${String(revision)}`;
228
284
  const EVIDENCE_SECTIONS = [
229
285
  "result",