rea-agents 2.0.0 → 2.1.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 (246) hide show
  1. package/README.md +78 -32
  2. package/bridge/ghidra/ReaGhidraBridge.java +96 -11
  3. package/dist/application/ArtifactExtraction.js +1 -1
  4. package/dist/application/ArtifactInventory/classify.js +42 -0
  5. package/dist/application/ArtifactInventory/hash.js +43 -0
  6. package/dist/application/ArtifactInventory/reader.js +41 -0
  7. package/dist/application/ArtifactInventory/scanCanonical.js +155 -0
  8. package/dist/application/ArtifactInventory/scanReader.js +124 -0
  9. package/dist/application/ArtifactInventory/types.js +10 -0
  10. package/dist/application/ArtifactInventory.js +9 -351
  11. package/dist/application/AuthorizedArtifactInventory.js +2 -2
  12. package/dist/application/BinarySession.js +47 -270
  13. package/dist/application/BinarySessionExecution.js +28 -0
  14. package/dist/application/BinarySessionOpen.js +39 -0
  15. package/dist/application/BinarySessionRecords.js +149 -0
  16. package/dist/application/BinarySessionStatus.js +75 -0
  17. package/dist/application/CapabilityInventory.js +24 -2
  18. package/dist/application/ClientRegistrationStatus.js +1 -1
  19. package/dist/application/CrossVersionInventory.js +8 -2
  20. package/dist/application/CrossVersionInvestigation.js +1 -23
  21. package/dist/application/CrossVersionInvestigationCollections.js +23 -0
  22. package/dist/application/DirectAnalysis.js +47 -44
  23. package/dist/application/Doctor.js +156 -238
  24. package/dist/application/DoctorDiagnostics.js +180 -0
  25. package/dist/application/ElectronBoundaryAnalysis.js +23 -7
  26. package/dist/application/ElectronBoundaryGraphWindows.js +32 -8
  27. package/dist/application/EnhancedToolPagination.js +22 -0
  28. package/dist/application/EnhancedToolTypes.js +4 -0
  29. package/dist/application/EnhancedTools.js +20 -37
  30. package/dist/application/InstrumentedJavaScriptReplayHost.js +36 -0
  31. package/dist/application/InvestigationWorkspaceStore.js +24 -10
  32. package/dist/application/JavaScriptArtifactAnalysis.js +45 -6
  33. package/dist/application/JavaScriptArtifactFiles.js +6 -2
  34. package/dist/application/JavaScriptArtifactGraphBuilder.js +23 -1
  35. package/dist/application/JavaScriptArtifactGraphBundlers.js +225 -0
  36. package/dist/application/JavaScriptArtifactGraphContext.js +37 -36
  37. package/dist/application/JavaScriptArtifactGraphDocuments.js +27 -4
  38. package/dist/application/JavaScriptArtifactGraphFindings.js +54 -8
  39. package/dist/application/JavaScriptArtifactGraphStructure.js +29 -101
  40. package/dist/application/JavaScriptArtifactPathResolution.js +269 -0
  41. package/dist/application/JavaScriptArtifactReconstruction.js +1 -1
  42. package/dist/application/JavaScriptJsonModules.js +39 -0
  43. package/dist/application/JavaScriptModuleRelationships.js +262 -0
  44. package/dist/application/JavaScriptReplayPermission.js +16 -0
  45. package/dist/application/JavaScriptReplayService.js +182 -156
  46. package/dist/application/LinuxHopper.js +10 -0
  47. package/dist/application/MacHopper.js +22 -11
  48. package/dist/application/NodeRuntimeCharacterizationService.js +196 -0
  49. package/dist/application/PermissionAuthority.js +106 -63
  50. package/dist/application/ProcessCaptureCapability.js +1 -1
  51. package/dist/application/ProcessCapturePermission.js +13 -0
  52. package/dist/application/ProcessCli.js +2 -12
  53. package/dist/application/ProcessHarness.js +1 -1
  54. package/dist/application/ProjectPermissionStore.js +48 -9
  55. package/dist/application/RealHopperAssertions.js +76 -0
  56. package/dist/application/ReconstructionCoverageService.js +69 -0
  57. package/dist/application/ReconstructionCoverageWorkspaceStore.js +31 -0
  58. package/dist/application/RuntimeExecutableDiagnostics.js +172 -0
  59. package/dist/application/Setup.js +147 -259
  60. package/dist/application/SetupClientConfiguration.js +220 -0
  61. package/dist/application/SetupClients.js +24 -2
  62. package/dist/application/SetupPlan.js +123 -12
  63. package/dist/application/SetupSkill.js +26 -12
  64. package/dist/application/SupportedClients.js +1 -0
  65. package/dist/application/Uninstall.js +6 -3
  66. package/dist/application/WindowsCapabilities.js +86 -0
  67. package/dist/artifacts/AsarArtifactReader.js +11 -0
  68. package/dist/browser/BrowserProcessStartup.js +88 -0
  69. package/dist/browser/CdpCaptureDocuments.js +12 -8
  70. package/dist/browser/CdpCaptureEventBodyShapes.js +75 -0
  71. package/dist/browser/CdpCaptureEventHandlers.js +336 -0
  72. package/dist/browser/CdpCaptureEventHelpers.js +71 -0
  73. package/dist/browser/CdpCaptureEventState.js +1 -0
  74. package/dist/browser/CdpCaptureEventTypes.js +1 -0
  75. package/dist/browser/CdpCaptureEvents.js +29 -496
  76. package/dist/browser/CdpObservationSession.js +51 -8
  77. package/dist/browser/CdpPageCapture.js +12 -133
  78. package/dist/browser/CdpPageCaptureScripts.js +97 -0
  79. package/dist/browser/CdpPageCaptureWorkers.js +46 -0
  80. package/dist/browser/CdpWebMcpDiscovery.js +38 -14
  81. package/dist/browser/PngVisualDiff.js +9 -2
  82. package/dist/catalogIdentity.js +4 -0
  83. package/dist/cli/artifactCommands.js +82 -0
  84. package/dist/cli/coreAnalysisCommands.js +232 -0
  85. package/dist/cli/managedCommands.js +397 -0
  86. package/dist/cli/managedProjectGraphCommand.js +24 -0
  87. package/dist/cli/options.js +9 -0
  88. package/dist/cli/setupCommands.js +108 -0
  89. package/dist/cli/types.js +1 -0
  90. package/dist/cli/utilityCommands.js +122 -0
  91. package/dist/cli.js +10 -768
  92. package/dist/cliApplicationCommands.js +118 -4
  93. package/dist/cliBrowserAdvancedCommands.js +73 -16
  94. package/dist/cliBrowserCommands.js +39 -115
  95. package/dist/cliCommandNames.js +4 -0
  96. package/dist/cliElectronCommands.js +33 -62
  97. package/dist/cliEvidenceCommands.js +13 -2
  98. package/dist/cliInvestigationCommands.js +53 -10
  99. package/dist/cliObservationOptions.js +137 -0
  100. package/dist/cliPolicyCommands.js +80 -46
  101. package/dist/cliSetup.js +289 -0
  102. package/dist/config/environment.js +107 -0
  103. package/dist/config/parseConfig.js +228 -0
  104. package/dist/config/parsers.js +68 -0
  105. package/dist/config/permissions.js +30 -0
  106. package/dist/config/types.js +1 -0
  107. package/dist/config.js +1 -375
  108. package/dist/contracts/applicationToolContracts.js +134 -0
  109. package/dist/contracts/managedToolContracts.js +1 -1
  110. package/dist/contracts/managedWorkflowToolContracts.js +3 -3
  111. package/dist/contracts/providerSelection.js +2 -0
  112. package/dist/contracts/toolContracts.js +2 -2
  113. package/dist/contracts/toolEffects.js +14 -0
  114. package/dist/contracts/toolOutputSchemaGroups.js +232 -0
  115. package/dist/contracts/toolOutputSchemaPrimitives.js +327 -0
  116. package/dist/contracts/toolOutputSchemas.js +2 -550
  117. package/dist/domain/analysisErrorPresentation.js +234 -0
  118. package/dist/domain/analysisErrorProjection.js +284 -0
  119. package/dist/domain/artifactComparison.js +34 -15
  120. package/dist/domain/binaryTarget.js +87 -37
  121. package/dist/domain/browserObservation.js +1 -285
  122. package/dist/domain/browserObservationSchemas.js +286 -0
  123. package/dist/domain/electronStaticAnalysisBrowser.js +14 -2
  124. package/dist/domain/errors.js +4 -486
  125. package/dist/domain/functionComparison.js +4 -165
  126. package/dist/domain/functionComparisonDimensions.js +164 -0
  127. package/dist/domain/javascriptApplicationVersionItems.js +18 -6
  128. package/dist/domain/javascriptApplicationVersionKeys.js +8 -8
  129. package/dist/domain/javascriptExportInstrumentation.js +97 -0
  130. package/dist/domain/javascriptFeatureTraversal.js +19 -7
  131. package/dist/domain/javascriptRuntimeStaticCandidates.js +3 -1
  132. package/dist/domain/javascriptSemanticAnalysis.js +386 -0
  133. package/dist/domain/javascriptSemanticIr.js +30 -0
  134. package/dist/domain/javascriptSemanticProjection.js +366 -0
  135. package/dist/domain/javascriptSemanticState.js +40 -0
  136. package/dist/domain/javascriptSemanticTraversal.js +22 -0
  137. package/dist/domain/javascriptSemanticValues.js +352 -0
  138. package/dist/domain/javascriptStaticAnalysis.js +5 -221
  139. package/dist/domain/javascriptStaticAnalysisBundler.js +209 -0
  140. package/dist/domain/javascriptStaticAnalysisCalls.js +180 -0
  141. package/dist/domain/javascriptStaticAnalysisHelpers.js +71 -2
  142. package/dist/domain/knownPageCoverage.js +21 -0
  143. package/dist/domain/managedApplicationGraph.js +14 -364
  144. package/dist/domain/managedApplicationGraphCoverage.js +170 -0
  145. package/dist/domain/managedApplicationGraphNodeCoverage.js +6 -0
  146. package/dist/domain/managedApplicationGraphNodes.js +336 -0
  147. package/dist/domain/managedArtifact.js +16 -8
  148. package/dist/domain/managedMemberComparison.js +37 -391
  149. package/dist/domain/managedMemberComparisonCoverage.js +72 -0
  150. package/dist/domain/managedMemberComparisonMatch.js +356 -0
  151. package/dist/domain/managedNativeVerification.js +27 -389
  152. package/dist/domain/managedNativeVerificationMatch.js +272 -0
  153. package/dist/domain/managedNativeVerificationSchemas.js +141 -0
  154. package/dist/domain/managedReconstruction.js +82 -69
  155. package/dist/domain/managedRuntimeCorrelation.js +12 -3
  156. package/dist/domain/nodeRuntimeCharacterization.js +66 -0
  157. package/dist/domain/permissionPolicy.js +2 -0
  158. package/dist/domain/reconstructionCoverage.js +387 -0
  159. package/dist/domain/reconstructionCoverageEvaluation.js +212 -0
  160. package/dist/domain/reconstructionVerificationSchemas.js +8 -0
  161. package/dist/domain/runtimeCharacterization.js +85 -0
  162. package/dist/domain/webBundleAnalyzer.js +3 -409
  163. package/dist/domain/webBundleAnalyzerAst.js +77 -0
  164. package/dist/domain/webBundleAnalyzerInspection.js +307 -0
  165. package/dist/domain/webBundleAnalyzerResult.js +120 -0
  166. package/dist/dotnet/ManagedArtifactInspector.js +50 -29
  167. package/dist/dotnet/ManagedMemberInspector.js +51 -785
  168. package/dist/dotnet/ManagedMemberInspectorCore.js +297 -0
  169. package/dist/dotnet/ManagedMemberInstructionDecoder.js +427 -0
  170. package/dist/dotnet/ManagedMemberRows.js +120 -0
  171. package/dist/dotnet/ManagedMetadataInventory.js +42 -306
  172. package/dist/dotnet/ManagedMetadataInventoryRows.js +292 -0
  173. package/dist/dotnet/ManagedMetadataLayout.js +48 -111
  174. package/dist/dotnet/ManagedMetadataRowSizes.js +54 -0
  175. package/dist/dotnet/ManagedMethodBodyReader.js +143 -0
  176. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +311 -0
  177. package/dist/dotnet/ManagedNativeBoundaryInspector.js +102 -350
  178. package/dist/dotnet/ManagedPeReader.js +59 -28
  179. package/dist/generatedPackageMetadata.js +2 -2
  180. package/dist/ghidra/GhidraClient.js +76 -91
  181. package/dist/ghidra/GhidraClientStartup.js +29 -0
  182. package/dist/ghidra/GhidraClientWire.js +34 -0
  183. package/dist/ghidra/GhidraDefaults.js +1 -1
  184. package/dist/ghidra/GhidraDiagnostics.js +6 -1
  185. package/dist/ghidra/GhidraInstallation.js +20 -15
  186. package/dist/ghidra/GhidraLauncher.js +93 -29
  187. package/dist/ghidra/GhidraProvider.js +61 -161
  188. package/dist/ghidra/GhidraProviderCapabilities.js +173 -0
  189. package/dist/ghidra/GhidraSessionValues.js +2 -0
  190. package/dist/ghidra/GhidraSocketConnection.js +44 -7
  191. package/dist/ghidra/GhidraTargetSnapshot.js +30 -0
  192. package/dist/ghidra/GhidraTransport.js +71 -0
  193. package/dist/identity.js +3 -2
  194. package/dist/main/messages.js +5 -0
  195. package/dist/main/reload.js +49 -0
  196. package/dist/main/shutdown.js +25 -0
  197. package/dist/main/startup.js +14 -0
  198. package/dist/main/state.js +26 -0
  199. package/dist/main/transport.js +61 -0
  200. package/dist/main/types.js +1 -0
  201. package/dist/main.js +35 -146
  202. package/dist/process/PrivateRuntimeRoot.js +3 -2
  203. package/dist/process/ProcessOwnership.js +35 -0
  204. package/dist/process/ProviderProcess.js +2 -0
  205. package/dist/replay/JavaScriptReplayWorker.js +64 -50
  206. package/dist/replay/LinuxJavaScriptReplayRunner.js +173 -390
  207. package/dist/replay/LinuxJavaScriptReplaySandbox.js +140 -0
  208. package/dist/replay/ReplayOutcome.js +95 -0
  209. package/dist/replay/ReplayProcessLifecycle.js +71 -0
  210. package/dist/server/ProcessCaptureElicitation.js +157 -0
  211. package/dist/server/createServer.js +119 -54
  212. package/dist/server/registerApplicationTools/characterization.js +57 -0
  213. package/dist/server/registerApplicationTools/compareVersions.js +34 -0
  214. package/dist/server/registerApplicationTools/controlledReplay.js +38 -0
  215. package/dist/server/registerApplicationTools/coverage.js +84 -0
  216. package/dist/server/registerApplicationTools/helpers.js +42 -0
  217. package/dist/server/registerApplicationTools/traceFeature.js +26 -0
  218. package/dist/server/registerApplicationTools/types.js +1 -0
  219. package/dist/server/registerApplicationTools.js +10 -112
  220. package/dist/server/registerBrowserTools.js +59 -83
  221. package/dist/server/registerElectronTools.js +31 -46
  222. package/dist/server/registerEnhancedTools.js +34 -42
  223. package/dist/server/registerEvidenceResources.js +54 -0
  224. package/dist/server/registerInvestigationTools/helpers.js +74 -0
  225. package/dist/server/registerInvestigationTools/types.js +1 -0
  226. package/dist/server/registerInvestigationTools.js +83 -116
  227. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +65 -0
  228. package/dist/server/registerManagedWorkflowTools/contract.js +8 -0
  229. package/dist/server/registerManagedWorkflowTools/evidence.js +43 -0
  230. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +39 -0
  231. package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +39 -0
  232. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +52 -0
  233. package/dist/server/registerManagedWorkflowTools/types.js +1 -0
  234. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +75 -0
  235. package/dist/server/registerManagedWorkflowTools.js +10 -274
  236. package/dist/server/registerOfficialTools.js +73 -59
  237. package/dist/server/registerSessionRecordTools.js +137 -0
  238. package/dist/server/registerSessionStatusTool.js +2 -1
  239. package/dist/server/registerSessionTools.js +60 -164
  240. package/dist/server/sessionAvailabilityPolicy.js +10 -0
  241. package/dist/server/toolRegistrationOptions.js +101 -3
  242. package/dist/server/toolResult.js +5 -0
  243. package/package.json +10 -11
  244. package/skills/{rea-analysis → reverse-engineer-anything}/SKILL.md +20 -7
  245. package/scripts/prepare-node-pty.mjs +0 -35
  246. package/scripts/rebuild-native.mjs +0 -22
@@ -1,4 +1,5 @@
1
- import { McpServer } from "@modelcontextprotocol/server";
1
+ import { randomBytes } from "node:crypto";
2
+ import { CLIENT_CAPABILITIES_META_KEY, createRequestStateCodec, McpServer, PROTOCOL_VERSION_META_KEY, } from "@modelcontextprotocol/server";
2
3
  import { PRODUCT_IDENTITY } from "../identity.js";
3
4
  import { registerEnhancedTools } from "./registerEnhancedTools.js";
4
5
  import { registerOfficialTools } from "./registerOfficialTools.js";
@@ -16,6 +17,7 @@ import { registerElectronTools } from "./registerElectronTools.js";
16
17
  import { registerApplicationTools } from "./registerApplicationTools.js";
17
18
  import { LinuxJavaScriptReplayRunner } from "../replay/LinuxJavaScriptReplayRunner.js";
18
19
  import { SystemJavaScriptReplayHost } from "../replay/SystemJavaScriptReplayHost.js";
20
+ import { PROCESS_CAPTURE_ELICITATION_POLICY, } from "./ProcessCaptureElicitation.js";
19
21
  /**
20
22
  * Construct one MCP server without acquiring subprocess resources.
21
23
  * Supplying a session adds target lifecycle tools; omitting it retains the
@@ -24,6 +26,11 @@ import { SystemJavaScriptReplayHost } from "../replay/SystemJavaScriptReplayHost
24
26
  export const createServer = (analysis, session, options = {}) => {
25
27
  const startedAt = new Date().toISOString();
26
28
  const logger = options.logger ?? silentLogger;
29
+ const permissionAuthority = options.permissionAuthority?.createConnectionAuthority();
30
+ const processCaptureStateCodec = createRequestStateCodec({
31
+ key: randomBytes(32),
32
+ ttlSeconds: PROCESS_CAPTURE_ELICITATION_POLICY.stateTtlSeconds,
33
+ });
27
34
  const server = new McpServer({
28
35
  name: PRODUCT_IDENTITY.mcpServerKey,
29
36
  version: PRODUCT_IDENTITY.packageVersion,
@@ -32,17 +39,88 @@ export const createServer = (analysis, session, options = {}) => {
32
39
  tools: { listChanged: true },
33
40
  resources: { listChanged: true },
34
41
  },
42
+ inputRequired: {
43
+ maxRounds: 3,
44
+ roundTimeoutMs: PROCESS_CAPTURE_ELICITATION_POLICY.roundTimeoutMs,
45
+ },
46
+ requestState: { verify: processCaptureStateCodec.verify },
35
47
  instructions: session === undefined
36
48
  ? "Reverse-engineering tools for an active analysis target. Start with binary_overview."
37
49
  : "Reverse-engineering tools for configured analysis providers. Open a target with open_binary, then start with binary_overview.",
38
50
  });
51
+ server.server.onclose = () => {
52
+ permissionAuthority?.clearSessionGrants();
53
+ };
39
54
  session?.onAvailabilityChanged?.(() => server.sendToolListChanged());
55
+ registerServerIdentityResource(server, startedAt);
56
+ const toolLogger = logger.child({ layer: "server" });
57
+ const { activeTarget, recordEvidence, recordEvidenceWithUnknown } = createSessionRecorders(server, session);
58
+ const toolContext = {
59
+ server,
60
+ analysis,
61
+ session,
62
+ options,
63
+ logger: toolLogger,
64
+ permissionAuthority,
65
+ activeTarget,
66
+ recordEvidence,
67
+ recordEvidenceWithUnknown,
68
+ };
69
+ registerBinaryAnalysisTools(toolContext);
70
+ registerObservationTools(toolContext);
71
+ registerGuidedPrompts(server, analysis, session);
72
+ if (session !== undefined) {
73
+ registerEvidenceResources(server, session);
74
+ registerSessionTools(server, session, toolLogger, {
75
+ ...options,
76
+ ...(permissionAuthority === undefined ? {} : { permissionAuthority }),
77
+ startedAt,
78
+ processCaptureElicitation: {
79
+ stateCodec: processCaptureStateCodec,
80
+ supported: (context) => {
81
+ const envelope = context.mcpReq.envelope;
82
+ const version = envelope?.[PROTOCOL_VERSION_META_KEY];
83
+ const capabilities = envelope?.[CLIENT_CAPABILITIES_META_KEY];
84
+ return (typeof version === "string" &&
85
+ PROCESS_CAPTURE_ELICITATION_POLICY.protocolVersions.some((supported) => supported === version) &&
86
+ isRecord(capabilities) &&
87
+ isRecord(capabilities.elicitation) &&
88
+ capabilities.elicitation.form !== undefined);
89
+ },
90
+ now: Date.now,
91
+ consumedNonces: new Map(),
92
+ },
93
+ });
94
+ }
95
+ return server;
96
+ };
97
+ const createSessionRecorders = (server, session) => ({
98
+ activeTarget: session === undefined ? undefined : () => session.activeTarget(),
99
+ recordEvidence: session === undefined
100
+ ? undefined
101
+ : (evidence) => {
102
+ const recorded = session.recordEvidence(evidence);
103
+ if (recorded.ok && recorded.value === "added")
104
+ server.sendResourceListChanged();
105
+ return recorded;
106
+ },
107
+ recordEvidenceWithUnknown: session === undefined
108
+ ? undefined
109
+ : (evidence, input) => {
110
+ const recorded = session.recordEvidenceWithUnknown(evidence, input);
111
+ if (recorded.ok)
112
+ server.sendResourceListChanged();
113
+ return recorded;
114
+ },
115
+ });
116
+ const registerServerIdentityResource = (server, startedAt) => {
40
117
  server.registerResource("server-identity", "rea://server/identity", {
41
118
  title: "REA server identity",
42
119
  description: "Live package, SDK, protocol, and catalog identity.",
43
120
  mimeType: "application/json",
44
121
  }, (uri) => {
45
122
  const client = server.server.getClientVersion();
123
+ const protocolVersion = server.server.getNegotiatedProtocolVersion();
46
124
  return {
47
125
  contents: [
48
126
  {
@@ -51,72 +129,49 @@ export const createServer = (analysis, session, options = {}) => {
51
129
  text: JSON.stringify(createServerIdentity({
52
130
  startedAt,
53
131
  ...(client === undefined ? {} : { client }),
54
- ...(server.server.getNegotiatedProtocolVersion() === undefined
55
- ? {}
56
- : {
57
- protocolVersion: server.server.getNegotiatedProtocolVersion(),
58
- }),
132
+ ...(protocolVersion === undefined ? {} : { protocolVersion }),
59
133
  }), null, 2),
60
134
  },
61
135
  ],
62
136
  };
63
137
  });
64
- const toolLogger = logger.child({ layer: "server" });
65
- const activeTarget = session === undefined ? undefined : () => session.activeTarget();
66
- const recordEvidence = session === undefined
67
- ? undefined
68
- : (evidence) => {
69
- const recorded = session.recordEvidence(evidence);
70
- if (recorded.ok && recorded.value === "added")
71
- server.sendResourceListChanged();
72
- return recorded;
73
- };
74
- const recordEvidenceWithUnknown = session === undefined
138
+ };
139
+ const registerBinaryAnalysisTools = ({ server, analysis, session, options, logger, permissionAuthority, activeTarget, recordEvidence, recordEvidenceWithUnknown, }) => {
140
+ const recordUnknown = session === undefined
75
141
  ? undefined
76
- : (evidence, input) => {
77
- const recorded = session.recordEvidenceWithUnknown(evidence, input);
78
- if (recorded.ok)
79
- server.sendResourceListChanged();
80
- return recorded;
81
- };
142
+ : (input) => session.recordUnknown(input);
82
143
  registerOfficialTools(server, analysis, {
83
- logger: toolLogger,
144
+ logger,
84
145
  activeTarget,
85
146
  recordEvidence,
86
- recordUnknown: session === undefined
87
- ? undefined
88
- : (input) => session.recordUnknown(input),
147
+ recordUnknown,
89
148
  });
90
149
  registerEnhancedTools(server, analysis, {
91
- logger: toolLogger,
150
+ logger,
92
151
  activeTarget,
93
152
  analysisProfile: session === undefined ? undefined : () => session.analysisProfile(),
94
153
  recordEvidence,
95
- recordUnknown: session === undefined
96
- ? undefined
97
- : (input) => session.recordUnknown(input),
154
+ recordUnknown,
98
155
  });
99
156
  registerNativeTools(server, analysis, {
100
- logger: toolLogger,
157
+ logger,
101
158
  activeTarget,
102
159
  recordEvidence,
103
160
  });
104
161
  registerArtifactTools(server, analysis, {
105
- logger: toolLogger,
162
+ logger,
106
163
  activeTarget,
107
164
  recordEvidence,
108
- ...(options.permissionAuthority === undefined
109
- ? {}
110
- : { permissionAuthority: options.permissionAuthority }),
165
+ ...(permissionAuthority === undefined ? {} : { permissionAuthority }),
111
166
  });
112
167
  registerManagedTools(server, analysis, {
113
- logger: toolLogger,
168
+ logger,
114
169
  activeTarget,
115
170
  recordEvidence,
116
171
  });
117
172
  if (session !== undefined)
118
173
  registerManagedWorkflowTools(server, {
119
- logger: toolLogger,
174
+ logger,
120
175
  recordEvidence,
121
176
  recordEvidenceWithUnknown,
122
177
  session,
@@ -126,25 +181,43 @@ export const createServer = (analysis, session, options = {}) => {
126
181
  roots: [],
127
182
  executablePath: "/usr/bin/dotnet",
128
183
  },
129
- authority: options.permissionAuthority,
184
+ authority: permissionAuthority,
130
185
  },
131
186
  });
187
+ };
188
+ const registerObservationTools = ({ server, session, options, logger, permissionAuthority, recordEvidence, recordEvidenceWithUnknown, }) => {
132
189
  registerBrowserTools(server, {
133
- logger: toolLogger,
190
+ logger,
134
191
  browser: options.browserObservation,
135
- permissionAuthority: options.permissionAuthority,
192
+ permissionAuthority,
136
193
  recordEvidence,
137
194
  });
138
195
  registerElectronTools(server, {
139
- logger: toolLogger,
196
+ logger,
140
197
  electron: options.electronObservation,
141
- permissionAuthority: options.permissionAuthority,
198
+ permissionAuthority,
142
199
  recordEvidence,
143
200
  });
144
201
  registerApplicationTools(server, {
145
- logger: toolLogger,
202
+ logger,
146
203
  recordEvidence,
147
204
  recordEvidenceWithUnknown,
205
+ evidenceFilePolicy: options.evidenceFilePolicy ?? {
206
+ roots: [],
207
+ maxBytes: 1,
208
+ maxDepth: 1,
209
+ maxStringLength: 1,
210
+ maxNodes: 1,
211
+ },
212
+ permissionAuthority,
213
+ retainCoverageWorkspace: session === undefined
214
+ ? undefined
215
+ : (workspace) => {
216
+ const retained = session.retainReconstructionCoverageWorkspace(workspace);
217
+ if (retained === "added")
218
+ server.sendResourceListChanged();
219
+ return retained;
220
+ },
148
221
  replay: {
149
222
  policy: options.javascriptReplayPolicy ?? {
150
223
  enabled: false,
@@ -157,16 +230,8 @@ export const createServer = (analysis, session, options = {}) => {
157
230
  },
158
231
  host: options.javascriptReplayHost ?? new SystemJavaScriptReplayHost(),
159
232
  runner: options.javascriptReplayRunner ?? new LinuxJavaScriptReplayRunner(),
160
- authority: options.permissionAuthority,
233
+ authority: permissionAuthority,
161
234
  },
162
235
  });
163
- registerGuidedPrompts(server, analysis, session);
164
- if (session !== undefined) {
165
- registerEvidenceResources(server, session);
166
- registerSessionTools(server, session, toolLogger, {
167
- ...options,
168
- startedAt,
169
- });
170
- }
171
- return server;
172
236
  };
237
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
@@ -0,0 +1,57 @@
1
+ import { executeNodeCharacterization, prepareNodeCharacterization, } from "../../application/NodeRuntimeCharacterizationService.js";
2
+ import { APPLICATION_TOOL_CONTRACTS } from "../../contracts/applicationToolContracts.js";
3
+ import { nodeCharacterizationExecutionInputSchema, nodeCharacterizationExecutionOutputSchema, nodeCharacterizationPreparationInputSchema, nodeCharacterizationPreparationOutputSchema, } from "../../domain/nodeRuntimeCharacterization.js";
4
+ import { parseEvidence } from "../../domain/evidence.js";
5
+ import { logToolExecution } from "../toolLogging.js";
6
+ import { toCallToolResult } from "../toolResult.js";
7
+ import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
8
+ import { safeParseToolInput } from "../toolInputValidation.js";
9
+ import { mcpProgressReporter } from "../mcpProgress.js";
10
+ import { recordSources } from "./helpers.js";
11
+ const prepareContract = APPLICATION_TOOL_CONTRACTS[3];
12
+ const executeContract = APPLICATION_TOOL_CONTRACTS[4];
13
+ /** Register node runtime characterization prepare and execute tools. */
14
+ export const registerCharacterizationTools = (server, options) => {
15
+ server.registerTool(prepareContract.name, toolRegistrationOptions(prepareContract), async (input, context) => {
16
+ const parsed = safeParseToolInput(nodeCharacterizationPreparationInputSchema, input, prepareContract.name);
17
+ if (!parsed.ok)
18
+ return toCallToolResult(parsed, prepareContract);
19
+ const result = await logToolExecution(options.logger, prepareContract.name, () => prepareNodeCharacterization(options.replay, parsed.value, {
20
+ signal: context.mcpReq.signal,
21
+ progress: mcpProgressReporter(context),
22
+ }));
23
+ if (!result.ok)
24
+ return toCallToolResult(result, prepareContract);
25
+ const output = nodeCharacterizationPreparationOutputSchema.parse(result.value);
26
+ const recorded = options.recordEvidence?.(parseEvidence(output.transformation_evidence));
27
+ if (recorded !== undefined && !recorded.ok)
28
+ return toCallToolResult(recorded, prepareContract);
29
+ return toCallToolResult(result, prepareContract, {
30
+ evidenceResourcesAvailable: options.recordEvidence !== undefined,
31
+ });
32
+ });
33
+ server.registerTool(executeContract.name, toolRegistrationOptions(executeContract), async (input, context) => {
34
+ const parsed = safeParseToolInput(nodeCharacterizationExecutionInputSchema, input, executeContract.name);
35
+ if (!parsed.ok)
36
+ return toCallToolResult(parsed, executeContract);
37
+ const result = await logToolExecution(options.logger, executeContract.name, () => executeNodeCharacterization(options.replay, parsed.value, {
38
+ signal: context.mcpReq.signal,
39
+ progress: mcpProgressReporter(context),
40
+ }));
41
+ if (!result.ok)
42
+ return toCallToolResult(result, executeContract);
43
+ const output = nodeCharacterizationExecutionOutputSchema.parse(result.value);
44
+ const sources = [
45
+ output.transformation_evidence,
46
+ ...output.replay.source_evidence,
47
+ ...(output.replay.evidence === null ? [] : [output.replay.evidence]),
48
+ output.evidence,
49
+ ].map((item) => parseEvidence(item));
50
+ const recorded = recordSources(options.recordEvidence, sources);
51
+ if (!recorded.ok)
52
+ return toCallToolResult(recorded, executeContract);
53
+ return toCallToolResult(result, executeContract, {
54
+ evidenceResourcesAvailable: options.recordEvidence !== undefined,
55
+ });
56
+ });
57
+ };
@@ -0,0 +1,34 @@
1
+ import { compareApplicationVersionsEvidenceValidated } from "../../application/JavaScriptApplicationWorkflowService.js";
2
+ import { APPLICATION_TOOL_CONTRACTS } from "../../contracts/applicationToolContracts.js";
3
+ import { compareApplicationVersionsInputSchema } from "../../domain/javascriptApplicationVersionComparisonSchemas.js";
4
+ import { applicationVersionComparisonResultSchema } from "../../domain/javascriptApplicationVersionComparisonSchemas.js";
5
+ import { logToolExecution } from "../toolLogging.js";
6
+ import { toCallToolResult } from "../toolResult.js";
7
+ import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
8
+ import { safeParseToolInput } from "../toolInputValidation.js";
9
+ import { recordResult, recordSources } from "./helpers.js";
10
+ const compareContract = APPLICATION_TOOL_CONTRACTS[1];
11
+ /** Register the provider-neutral JavaScript version comparison tool. */
12
+ export const registerCompareApplicationVersionsTool = (server, options) => {
13
+ server.registerTool(compareContract.name, toolRegistrationOptions(compareContract), async (input) => {
14
+ const parsedInput = safeParseToolInput(compareApplicationVersionsInputSchema, input, compareContract.name);
15
+ if (!parsedInput.ok)
16
+ return toCallToolResult(parsedInput, compareContract);
17
+ const parsed = parsedInput.value;
18
+ const result = await logToolExecution(options.logger, compareContract.name, () => Promise.resolve(compareApplicationVersionsEvidenceValidated(parsed)));
19
+ if (!result.ok)
20
+ return toCallToolResult(result, compareContract);
21
+ const sources = [
22
+ parsed.left,
23
+ parsed.right,
24
+ ...parsed.left_native_observations,
25
+ ...parsed.right_native_observations,
26
+ ];
27
+ const recorded = recordSources(options.recordEvidence, sources);
28
+ if (!recorded.ok)
29
+ return toCallToolResult(recorded, compareContract);
30
+ const comparison = applicationVersionComparisonResultSchema.parse(result.value.normalized_result);
31
+ const unknown = comparison.summary.unknown > 0;
32
+ return recordResult(options, compareContract, result.value, parsed.unknown_registry_approved === true && unknown);
33
+ });
34
+ };
@@ -0,0 +1,38 @@
1
+ import { runControlledReplayValidated } from "../../application/JavaScriptReplayService.js";
2
+ import { APPLICATION_TOOL_CONTRACTS } from "../../contracts/applicationToolContracts.js";
3
+ import { controlledReplayInputSchema, controlledReplayOutputSchema, } from "../../domain/javascriptReplay.js";
4
+ import { parseEvidence } from "../../domain/evidence.js";
5
+ import { logToolExecution } from "../toolLogging.js";
6
+ import { toCallToolResult } from "../toolResult.js";
7
+ import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
8
+ import { safeParseToolInput } from "../toolInputValidation.js";
9
+ import { mcpProgressReporter } from "../mcpProgress.js";
10
+ import { recordSources } from "./helpers.js";
11
+ const replayContract = APPLICATION_TOOL_CONTRACTS[2];
12
+ /** Register the controlled JavaScript replay tool. */
13
+ export const registerControlledReplayTool = (server, options) => {
14
+ server.registerTool(replayContract.name, toolRegistrationOptions(replayContract), async (input, context) => {
15
+ const parsedInput = safeParseToolInput(controlledReplayInputSchema, input, replayContract.name);
16
+ if (!parsedInput.ok)
17
+ return toCallToolResult(parsedInput, replayContract);
18
+ const parsed = parsedInput.value;
19
+ const result = await logToolExecution(options.logger, replayContract.name, () => runControlledReplayValidated(options.replay, parsed, {
20
+ signal: context.mcpReq.signal,
21
+ progress: mcpProgressReporter(context),
22
+ }));
23
+ if (!result.ok)
24
+ return toCallToolResult(result, replayContract);
25
+ const output = controlledReplayOutputSchema.parse(result.value);
26
+ if (output.evidence !== null) {
27
+ const sourcesRecorded = recordSources(options.recordEvidence, output.source_evidence.map((item) => parseEvidence(item)));
28
+ if (!sourcesRecorded.ok)
29
+ return toCallToolResult(sourcesRecorded, replayContract);
30
+ const recorded = options.recordEvidence?.(parseEvidence(output.evidence));
31
+ if (recorded !== undefined && !recorded.ok)
32
+ return toCallToolResult(recorded, replayContract);
33
+ }
34
+ return toCallToolResult(result, replayContract, {
35
+ evidenceResourcesAvailable: output.evidence !== null && options.recordEvidence !== undefined,
36
+ });
37
+ });
38
+ };
@@ -0,0 +1,84 @@
1
+ import { commitReconstructionCoverage, queryReconstructionCoverage, } from "../../application/ReconstructionCoverageService.js";
2
+ import { readReconstructionCoverageWorkspace } from "../../application/ReconstructionCoverageWorkspaceStore.js";
3
+ import { authorizeFileReadWithDeferredWrite, authorizeRootPermission, } from "../../application/DeferredFileAuthorization.js";
4
+ import { APPLICATION_TOOL_CONTRACTS } from "../../contracts/applicationToolContracts.js";
5
+ import { reconstructionCoverageCommitInputSchema, reconstructionCoverageQueryInputSchema, } from "../../application/ReconstructionCoverageService.js";
6
+ import { reconstructionClosureResultSchema } from "../../domain/reconstructionCoverage.js";
7
+ import { AnalysisCapabilityUnavailableError, EvidenceIntegrityError, } from "../../domain/errors.js";
8
+ import { err } from "../../domain/result.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 { coverageWorkspaceUri } from "./helpers.js";
14
+ const commitContract = APPLICATION_TOOL_CONTRACTS[5];
15
+ const queryContract = APPLICATION_TOOL_CONTRACTS[6];
16
+ /** Register reconstruction coverage commit and query tools. */
17
+ export const registerCoverageTools = (server, options) => {
18
+ registerCommitTool(server, options);
19
+ registerQueryTool(server, options);
20
+ };
21
+ const registerCommitTool = (server, options) => {
22
+ server.registerTool(commitContract.name, toolRegistrationOptions(commitContract), async (input, context) => {
23
+ const parsed = safeParseToolInput(reconstructionCoverageCommitInputSchema, input, commitContract.name);
24
+ if (!parsed.ok)
25
+ return toCallToolResult(parsed, commitContract);
26
+ if (options.permissionAuthority === undefined)
27
+ return toCallToolResult(err(new AnalysisCapabilityUnavailableError("rea-reconstruction-coverage", commitContract.name, "workspace permission policy is not configured")), commitContract);
28
+ const authorization = await authorizeFileReadWithDeferredWrite(options.permissionAuthority, {
29
+ path: parsed.value.workspace_path,
30
+ readCapability: "investigation_workspace_read",
31
+ writeCapability: "investigation_workspace_write",
32
+ operation: commitContract.name,
33
+ });
34
+ if (!authorization.ok)
35
+ return toCallToolResult(authorization, commitContract);
36
+ const write = await authorization.value.authorizeWrite();
37
+ if (!write.ok)
38
+ return toCallToolResult(write, commitContract);
39
+ const result = await logToolExecution(options.logger, commitContract.name, () => commitReconstructionCoverage(parsed.value, options.evidenceFilePolicy, { signal: context.mcpReq.signal }));
40
+ if (!result.ok)
41
+ return toCallToolResult(result, commitContract);
42
+ options.retainCoverageWorkspace?.(parsed.value.workspace);
43
+ return toCallToolResult(result, commitContract, {
44
+ resourceLinks: options.retainCoverageWorkspace === undefined
45
+ ? []
46
+ : [
47
+ {
48
+ uri: coverageWorkspaceUri(parsed.value.workspace),
49
+ name: parsed.value.workspace.workspace_id,
50
+ description: "Session-retained reconstruction coverage workspace revision",
51
+ },
52
+ ],
53
+ });
54
+ });
55
+ };
56
+ const registerQueryTool = (server, options) => {
57
+ server.registerTool(queryContract.name, toolRegistrationOptions(queryContract), async (input, context) => {
58
+ const parsed = safeParseToolInput(reconstructionCoverageQueryInputSchema, input, queryContract.name);
59
+ if (!parsed.ok)
60
+ return toCallToolResult(parsed, queryContract);
61
+ if (options.permissionAuthority === undefined)
62
+ return toCallToolResult(err(new AnalysisCapabilityUnavailableError("rea-reconstruction-coverage", queryContract.name, "workspace permission policy is not configured")), queryContract);
63
+ const authorized = await authorizeRootPermission(options.permissionAuthority, {
64
+ capability: "investigation_workspace_read",
65
+ roots: [parsed.value.workspace_path],
66
+ access: "read",
67
+ operation: queryContract.name,
68
+ });
69
+ if (!authorized.ok)
70
+ return toCallToolResult(authorized, queryContract);
71
+ const result = await logToolExecution(options.logger, queryContract.name, () => queryReconstructionCoverage(parsed.value, options.evidenceFilePolicy, Date.now(), { signal: context.mcpReq.signal }));
72
+ if (result.ok && options.retainCoverageWorkspace !== undefined) {
73
+ const closure = reconstructionClosureResultSchema.parse(result.value);
74
+ const loaded = await readReconstructionCoverageWorkspace(parsed.value.workspace_path, options.evidenceFilePolicy);
75
+ if (!loaded.ok)
76
+ return toCallToolResult(loaded, queryContract);
77
+ if (loaded.value === null ||
78
+ loaded.value.revision_sha256 !== closure.workspace_revision_sha256)
79
+ return toCallToolResult(err(new EvidenceIntegrityError("workspace changed while its closure was being retained")), queryContract);
80
+ options.retainCoverageWorkspace(loaded.value);
81
+ }
82
+ return toCallToolResult(result, queryContract);
83
+ });
84
+ };
@@ -0,0 +1,42 @@
1
+ import { APPLICATION_TOOL_CONTRACTS } from "../../contracts/applicationToolContracts.js";
2
+ import { toCallToolResult } from "../toolResult.js";
3
+ export const coverageWorkspaceUri = (workspace) => `rea://reconstruction-coverage/${workspace.workspace_id}/revision/${String(workspace.revision)}`;
4
+ export const recordSources = (recordEvidence, sources) => {
5
+ for (const source of sources) {
6
+ const recorded = recordEvidence?.(source);
7
+ if (recorded !== undefined && !recorded.ok)
8
+ return recorded;
9
+ }
10
+ return { ok: true, value: null };
11
+ };
12
+ export const recordResult = (options, contract, evidence, recordUnknown = false) => {
13
+ const recorded = recordUnknown
14
+ ? options.recordEvidenceWithUnknown?.(evidence, {
15
+ approved: true,
16
+ question: "Which application entities remain unmatched or ambiguous across these versions?",
17
+ severity: "medium",
18
+ domain: "application-version-comparison",
19
+ supporting_evidence_ids: [evidence.evidence_id],
20
+ contradicting_evidence_ids: [],
21
+ required_authority: "shipped-artifact",
22
+ required_confidence: "observed",
23
+ required_environment: null,
24
+ recommended_probes: [
25
+ {
26
+ operation: "analyze_javascript_application",
27
+ rationale: "Repeat static reconstruction with complete artifacts and source maps when available.",
28
+ },
29
+ {
30
+ operation: "reconcile_javascript_runtime",
31
+ rationale: "Add approved passive runtime Evidence without promoting it to static fact.",
32
+ },
33
+ ],
34
+ relationships: [],
35
+ })
36
+ : options.recordEvidence?.(evidence);
37
+ if (recorded !== undefined && !recorded.ok)
38
+ return toCallToolResult(recorded, contract);
39
+ return toCallToolResult({ ok: true, value: evidence }, contract, {
40
+ evidenceResourcesAvailable: recorded !== undefined,
41
+ });
42
+ };
@@ -0,0 +1,26 @@
1
+ import { traceApplicationFeatureEvidenceValidated } from "../../application/JavaScriptApplicationWorkflowService.js";
2
+ import { APPLICATION_TOOL_CONTRACTS } from "../../contracts/applicationToolContracts.js";
3
+ import { traceApplicationFeatureInputSchema } from "../../domain/javascriptFeatureTraceSchemas.js";
4
+ import { logToolExecution } from "../toolLogging.js";
5
+ import { toCallToolResult } from "../toolResult.js";
6
+ import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
7
+ import { safeParseToolInput } from "../toolInputValidation.js";
8
+ import { recordResult, recordSources } from "./helpers.js";
9
+ const traceContract = APPLICATION_TOOL_CONTRACTS[0];
10
+ /** Register the provider-neutral JavaScript feature trace tool. */
11
+ export const registerTraceFeatureTool = (server, options) => {
12
+ server.registerTool(traceContract.name, toolRegistrationOptions(traceContract), async (input) => {
13
+ const parsedInput = safeParseToolInput(traceApplicationFeatureInputSchema, input, traceContract.name);
14
+ if (!parsedInput.ok)
15
+ return toCallToolResult(parsedInput, traceContract);
16
+ const parsed = parsedInput.value;
17
+ const result = await logToolExecution(options.logger, traceContract.name, () => Promise.resolve(traceApplicationFeatureEvidenceValidated(parsed)));
18
+ if (!result.ok)
19
+ return toCallToolResult(result, traceContract);
20
+ const sources = [parsed.application, ...parsed.native_observations];
21
+ const recorded = recordSources(options.recordEvidence, sources);
22
+ if (!recorded.ok)
23
+ return toCallToolResult(recorded, traceContract);
24
+ return recordResult(options, traceContract, result.value);
25
+ });
26
+ };
@@ -0,0 +1 @@
1
+ export {};