rea-agents 3.0.0 → 3.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 (219) hide show
  1. package/README.md +14 -16
  2. package/dist/application/AnalysisContextQueries.js +21 -9
  3. package/dist/application/ApplicationWorkflowEvidenceResolver.js +19 -11
  4. package/dist/application/ArtifactInventory/policy.js +17 -0
  5. package/dist/application/ArtifactInventory/reader.js +1 -4
  6. package/dist/application/ArtifactInventory/scanCanonical.js +0 -3
  7. package/dist/application/ArtifactInventory/scanReader.js +7 -7
  8. package/dist/application/ArtifactInventory/types.js +1 -5
  9. package/dist/application/BinarySession.js +14 -16
  10. package/dist/application/BinarySessionRecords.js +31 -5
  11. package/dist/application/BinarySessionStatus.js +11 -5
  12. package/dist/application/BrowserEvidence.js +3 -5
  13. package/dist/application/CapabilityClientRequirements.js +26 -0
  14. package/dist/application/CapabilityInventory.js +134 -63
  15. package/dist/application/CrossVersionInventory.js +7 -6
  16. package/dist/application/ElectronActiveEvidence.js +55 -0
  17. package/dist/application/ElectronActiveObservationPort.js +1 -0
  18. package/dist/application/ElectronActiveObservationService.js +81 -0
  19. package/dist/application/EnhancedTools.js +22 -20
  20. package/dist/application/EvidenceBundleCommands.js +5 -1
  21. package/dist/application/EvidenceLedger.js +8 -1
  22. package/dist/application/JavaScriptReplayPermission.js +1 -1
  23. package/dist/application/JavaScriptReplayService.js +23 -15
  24. package/dist/application/ManagedRuntimeCorrelationService.js +9 -5
  25. package/dist/application/NodeRuntimeCharacterizationService.js +8 -9
  26. package/dist/application/ProcessCaptureLifecycle.js +5 -0
  27. package/dist/application/ProcessCli.js +2 -1
  28. package/dist/application/ProcessHarness.js +8 -3
  29. package/dist/application/ProcessNormalization.js +2 -1
  30. package/dist/application/ProjectPermissionStore.js +1 -0
  31. package/dist/application/ReferenceSourceImport.js +2 -2
  32. package/dist/application/SetupClientConfiguration.js +6 -1
  33. package/dist/application/WindowsCapabilities.js +5 -4
  34. package/dist/artifacts/ArtifactProvider.js +8 -10
  35. package/dist/artifacts/SafeOutputTree.js +7 -8
  36. package/dist/browser/CdpCaptureStorageFingerprints.js +10 -7
  37. package/dist/browser/CdpElectronInspection.js +3 -1
  38. package/dist/browser/JavaScriptRuntimeScope.js +5 -0
  39. package/dist/browser/PlaywrightElectronActiveActions.js +324 -0
  40. package/dist/browser/PlaywrightElectronActiveProvider.js +294 -0
  41. package/dist/browser/PlaywrightScenarioBrowser.js +4 -4
  42. package/dist/browser/PlaywrightScenarioSession.js +4 -4
  43. package/dist/browser/SensitiveTextCapture.js +1 -1
  44. package/dist/browser/V8InspectorCaptureProjection.js +1 -0
  45. package/dist/browser/V8InspectorProvider.js +3 -3
  46. package/dist/catalogIdentity.js +12 -6
  47. package/dist/cli/managedCommands.js +1 -1
  48. package/dist/cliApplicationCommands.js +2 -2
  49. package/dist/cliBrowserAdvancedCommands.js +11 -5
  50. package/dist/cliBrowserCommands.js +14 -7
  51. package/dist/cliCommandNames.js +1 -0
  52. package/dist/cliElectronCommands.js +46 -4
  53. package/dist/cliJavaScriptRuntimeCommands.js +14 -6
  54. package/dist/cliObservationOptions.js +4 -0
  55. package/dist/cliPolicyCommands.js +1 -0
  56. package/dist/config/browserScenario.js +77 -0
  57. package/dist/config/electronAutomation.js +35 -0
  58. package/dist/config/environment.js +6 -0
  59. package/dist/config/javascriptReplay.js +41 -0
  60. package/dist/config/managedRuntime.js +25 -0
  61. package/dist/config/parseConfig.js +56 -200
  62. package/dist/config/parsers.js +10 -1
  63. package/dist/config/passiveObservation.js +157 -0
  64. package/dist/config/processCapture.js +47 -0
  65. package/dist/contracts/applicationToolContracts.js +2 -5
  66. package/dist/contracts/applicationWorkflowInputContracts.js +86 -96
  67. package/dist/contracts/artifactToolContracts.js +27 -34
  68. package/dist/contracts/browserToolContracts.js +2 -2
  69. package/dist/contracts/electronToolContracts.js +30 -1
  70. package/dist/contracts/enhancedInputs.js +13 -29
  71. package/dist/contracts/functionWorkflowToolContracts.js +2 -3
  72. package/dist/contracts/managedToolContracts.js +4 -9
  73. package/dist/contracts/managedWorkflowExamples.js +12 -9
  74. package/dist/contracts/managedWorkflowToolContracts.js +30 -27
  75. package/dist/contracts/nativeToolContracts.js +2 -3
  76. package/dist/contracts/sessionToolSchemas.js +61 -0
  77. package/dist/contracts/toolContractExamples.js +1 -0
  78. package/dist/contracts/toolContractHelpers.js +23 -0
  79. package/dist/contracts/toolContracts.js +5 -77
  80. package/dist/contracts/toolEffects.js +15 -0
  81. package/dist/contracts/toolOutputSchemaGroups.js +17 -2
  82. package/dist/contracts/toolOutputSchemaPrimitives.js +76 -26
  83. package/dist/contracts/toolSchemaMetadata.js +128 -0
  84. package/dist/doctorRuntime.js +1 -1
  85. package/dist/domain/androidApplication.js +2 -0
  86. package/dist/domain/appleApplication.js +2 -0
  87. package/dist/domain/binaryTarget.js +7 -5
  88. package/dist/domain/binaryTargetTypes.js +1 -0
  89. package/dist/domain/browserCaptureComparison.js +21 -69
  90. package/dist/domain/browserObservation.js +22 -9
  91. package/dist/domain/bytecodeProvider.js +33 -35
  92. package/dist/domain/callPath.js +3 -2
  93. package/dist/domain/conformanceReplay.js +3 -3
  94. package/dist/domain/conformanceTrustGate.js +151 -16
  95. package/dist/domain/customProtocolCapture.js +3 -3
  96. package/dist/domain/electronActiveObservation.js +277 -0
  97. package/dist/domain/electronObservation.js +15 -11
  98. package/dist/domain/electronStaticAnalysisValues.js +4 -1
  99. package/dist/domain/eventProcessTree.js +82 -79
  100. package/dist/domain/functionComparisonNormalization.js +15 -8
  101. package/dist/domain/functionDossierEvidence.js +9 -4
  102. package/dist/domain/hopperValues.js +68 -71
  103. package/dist/domain/inputIssueProjection.js +4 -1
  104. package/dist/domain/investigationWorkspace.js +16 -15
  105. package/dist/domain/javascriptExportShapeComparisonSchemas.js +2 -2
  106. package/dist/domain/javascriptReplay.js +79 -63
  107. package/dist/domain/javascriptRuntimeObservation.js +1 -0
  108. package/dist/domain/javascriptRuntimeReconciliationActive.js +89 -0
  109. package/dist/domain/javascriptRuntimeReconciliationGraph.js +11 -10
  110. package/dist/domain/javascriptRuntimeReconciliationMatching.js +57 -49
  111. package/dist/domain/javascriptRuntimeReconciliationParsing.js +5 -1
  112. package/dist/domain/javascriptRuntimeReconciliationResult.js +21 -14
  113. package/dist/domain/javascriptRuntimeReconciliationSchemas.js +1 -1
  114. package/dist/domain/knownPageCoverage.js +15 -7
  115. package/dist/domain/nativeApiBoundary.js +15 -7
  116. package/dist/domain/nodeRuntimeCharacterization.js +14 -13
  117. package/dist/domain/processCaptureReactiveValidation.js +8 -3
  118. package/dist/domain/processCaptureValidation.js +7 -3
  119. package/dist/domain/processComparison.js +12 -7
  120. package/dist/domain/processObservation.js +5 -6
  121. package/dist/domain/processReactiveMatching.js +14 -7
  122. package/dist/domain/processReactiveTransition.js +9 -3
  123. package/dist/domain/processScenario.js +6 -3
  124. package/dist/domain/processTraceComparison.js +3 -2
  125. package/dist/domain/protocolCapture.js +8 -6
  126. package/dist/domain/reconstructionReadinessSchemas.js +30 -2
  127. package/dist/domain/referenceSourceImportParsing.js +2 -2
  128. package/dist/domain/replayMachineRuntime.js +5 -3
  129. package/dist/domain/sourceToBundleComparison.js +2 -2
  130. package/dist/domain/sourceToBundleComparisonSchemas.js +8 -8
  131. package/dist/domain/sourceToBundleSignals.js +7 -1
  132. package/dist/domain/staticRuntimeCorrelation.js +7 -5
  133. package/dist/domain/webBundleAnalysis.js +14 -14
  134. package/dist/domain/webCaptureDiff.js +15 -12
  135. package/dist/dotnet/ManagedNativeBoundaryInspector.js +2 -3
  136. package/dist/generatedMcpToolCatalog.js +1 -1
  137. package/dist/generatedPackageMetadata.js +1 -1
  138. package/dist/ghidra/GhidraClient.js +1 -1
  139. package/dist/ghidra/GhidraClientStartup.js +1 -1
  140. package/dist/ghidra/GhidraFunctionValues.js +17 -15
  141. package/dist/ghidra/GhidraInventoryValues.js +57 -47
  142. package/dist/ghidra/GhidraProvider.js +18 -10
  143. package/dist/ghidra/GhidraProviderCapabilities.js +5 -1
  144. package/dist/ghidra/GhidraSocketConnection.js +1 -1
  145. package/dist/ghidra/protocol.js +19 -42
  146. package/dist/hopper/BridgeLauncher.js +3 -1
  147. package/dist/hopper/HopperAnalysisProfile.js +2 -4
  148. package/dist/hopper/HopperCleanup.js +5 -6
  149. package/dist/hopper/HopperClient.js +1 -1
  150. package/dist/hopper/HopperProvider.js +0 -14
  151. package/dist/hopper/LinuxPrivateDisplayProbe.js +16 -10
  152. package/dist/main/reload.js +1 -6
  153. package/dist/main/state.js +0 -14
  154. package/dist/main/transport.js +30 -37
  155. package/dist/main.js +17 -15
  156. package/dist/mcpDoctor.js +2 -24
  157. package/dist/process/PrivateRuntimeRoot.js +17 -0
  158. package/dist/process/ProcessOwnership.js +64 -128
  159. package/dist/process/ProcessOwnershipIdentity.js +13 -0
  160. package/dist/process/ProcessOwnershipObservation.js +88 -0
  161. package/dist/process/ProcessOwnershipProcessTree.js +22 -0
  162. package/dist/process/ProviderDeadline.js +8 -12
  163. package/dist/process/WindowsAuthority.js +32 -0
  164. package/dist/reference/ReferenceSourceReader.js +3 -3
  165. package/dist/reference/ReferenceSourceReaderEntries.js +2 -2
  166. package/dist/replay/JavaScriptReplayWorker.js +95 -11
  167. package/dist/replay/JavaScriptReplayWorkerTypes.js +1 -0
  168. package/dist/replay/LinuxJavaScriptReplayRunner.js +10 -15
  169. package/dist/replay/ReplayOutcome.js +26 -15
  170. package/dist/replay/ReplayWorkerProtocol.js +34 -29
  171. package/dist/server/createServer.js +158 -94
  172. package/dist/server/mcpClientMetadata.js +32 -0
  173. package/dist/server/registerApplicationTools/characterization.js +6 -13
  174. package/dist/server/registerApplicationTools/compareExportShapes.js +2 -7
  175. package/dist/server/registerApplicationTools/compareSourceToBundle.js +2 -7
  176. package/dist/server/registerApplicationTools/compareVersions.js +3 -8
  177. package/dist/server/registerApplicationTools/controlledReplay.js +6 -11
  178. package/dist/server/registerApplicationTools/coverage.js +13 -19
  179. package/dist/server/registerApplicationTools/obligationLedger.js +1 -6
  180. package/dist/server/registerApplicationTools/readiness.js +1 -6
  181. package/dist/server/registerApplicationTools/traceFeature.js +3 -8
  182. package/dist/server/registerApplicationTools/traceSemantics.js +1 -6
  183. package/dist/server/registerArtifactComparisonTool.js +12 -16
  184. package/dist/server/registerBrowserScenarioTool.js +1 -6
  185. package/dist/server/registerBrowserTools.js +37 -79
  186. package/dist/server/registerBundleComparisonTool.js +10 -14
  187. package/dist/server/registerCloseLifecycleTool.js +6 -14
  188. package/dist/server/registerElectronTools.js +30 -47
  189. package/dist/server/registerEnhancedTools.js +114 -122
  190. package/dist/server/registerEvidenceTools.js +5 -9
  191. package/dist/server/registerFunctionComparisonTool.js +11 -15
  192. package/dist/server/registerInvestigationTools.js +41 -57
  193. package/dist/server/registerJavaScriptRuntimeObservationTools.js +13 -27
  194. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +4 -9
  195. package/dist/server/registerManagedWorkflowTools/contract.js +2 -3
  196. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +3 -8
  197. package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +3 -8
  198. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +8 -13
  199. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +4 -9
  200. package/dist/server/registerOfficialTools.js +8 -9
  201. package/dist/server/registerProcessComparisonTool.js +19 -24
  202. package/dist/server/registerReplayMachineTool.js +4 -10
  203. package/dist/server/registerSessionRecordTools.js +69 -40
  204. package/dist/server/registerSessionStatusTool.js +13 -28
  205. package/dist/server/registerSessionTools.js +36 -52
  206. package/dist/server/sessionAvailabilityPolicy.js +2 -1
  207. package/dist/server/sessionToolPolicies.js +1 -5
  208. package/dist/server/toolRegistrationOptions.js +4 -192
  209. package/dist/server/toolResult.js +2 -18
  210. package/package.json +22 -14
  211. package/scripts/electron-active-hook-boundaries.cjs +394 -0
  212. package/scripts/electron-active-hook.cjs +501 -0
  213. package/scripts/rea.mjs +1 -11
  214. package/skills/reverse-engineer-anything/SKILL.md +2 -2
  215. package/dist/server/DynamicToolAvailability.js +0 -70
  216. package/dist/server/LazyToolCatalog.js +0 -134
  217. package/dist/server/hydrateServerTools.js +0 -191
  218. package/dist/server/toolInputValidation.js +0 -77
  219. package/scripts/package-runner-bootstrap.mjs +0 -72
@@ -1,37 +1,83 @@
1
1
  import { randomBytes } from "node:crypto";
2
2
  import { CLIENT_CAPABILITIES_META_KEY, createRequestStateCodec, McpServer, PROTOCOL_VERSION_META_KEY, } from "@modelcontextprotocol/server";
3
+ import { MANAGED_RUNTIME_DISABLED } from "../application/ManagedRuntimeCorrelationService.js";
3
4
  import { PRODUCT_IDENTITY } from "../identity.js";
4
5
  import { silentLogger } from "../logger.js";
5
- import { registerGuidedPrompts } from "./registerPrompts.js";
6
+ import { LinuxJavaScriptReplayRunner } from "../replay/LinuxJavaScriptReplayRunner.js";
7
+ import { SystemJavaScriptReplayHost } from "../replay/SystemJavaScriptReplayHost.js";
8
+ import { mcpClientMetadata, mcpEnvelopeValue } from "./mcpClientMetadata.js";
9
+ import { PROCESS_CAPTURE_ELICITATION_POLICY, } from "./ProcessCaptureElicitation.js";
10
+ import { registerApplicationTools } from "./registerApplicationTools.js";
11
+ import { registerArtifactTools } from "./registerArtifactTools.js";
12
+ import { registerBrowserScenarioTool } from "./registerBrowserScenarioTool.js";
13
+ import { registerBrowserTools } from "./registerBrowserTools.js";
14
+ import { registerElectronTools } from "./registerElectronTools.js";
15
+ import { registerEnhancedTools } from "./registerEnhancedTools.js";
6
16
  import { registerEvidenceResources } from "./registerEvidenceResources.js";
17
+ import { registerJavaScriptRuntimeObservationTools } from "./registerJavaScriptRuntimeObservationTools.js";
18
+ import { registerManagedTools } from "./registerManagedTools.js";
19
+ import { registerManagedWorkflowTools } from "./registerManagedWorkflowTools.js";
20
+ import { registerNativeTools } from "./registerNativeTools.js";
21
+ import { registerOfficialTools } from "./registerOfficialTools.js";
22
+ import { registerGuidedPrompts } from "./registerPrompts.js";
23
+ import { registerSessionTools } from "./registerSessionTools.js";
7
24
  import { sessionAvailabilityPolicy } from "./sessionAvailabilityPolicy.js";
8
25
  import { DENY_EVIDENCE_FILE_POLICY, DENY_PROCESS_POLICY, } from "./sessionToolPolicies.js";
9
- import { installDynamicToolAvailability } from "./DynamicToolAvailability.js";
10
- const TARGET_FREE_INSTRUCTIONS = "ASAR/JavaScript -> analyze_javascript_application; archive/package -> open_binary(path), then inspect_artifact/inventory_artifact (active target); managed PE/CLI -> inspect_managed_artifact; passive browser/Electron -> list_browser_targets/list_electron_targets; approved browser interaction -> capture_browser_scenario; Node/Electron Inspector -> list_javascript_runtime_targets; native binary/database -> open_binary, then binary_overview. Start with binary_session; call only tools in tools/list. Hidden routes: binary_session detail=capabilities. Use summaries, cite Evidence IDs. Never repeat identical analysis or read full Evidence.";
26
+ const TARGET_FREE_INSTRUCTIONS = "ASAR/JavaScript -> analyze_javascript_application; archive/package -> open_binary(path), then inspect_artifact/inventory_artifact (active target); managed PE/CLI -> inspect_managed_artifact; browser/Electron -> list_browser_targets/list_electron_targets; approved -> capture_browser_scenario/capture_electron_scenario; Node/Electron Inspector -> list_javascript_runtime_targets; native binary/database -> open_binary, then binary_overview. Start with binary_session; use tools/list; capabilities via binary_session. Use summaries, cite Evidence IDs; Never repeat identical analysis or read full Evidence.";
11
27
  const ACTIVE_TARGET_INSTRUCTIONS = "REA analyzes the active reverse-engineering target. Start native analysis with binary_overview, then narrow with analyze_function, literal search, callers, callees, and xrefs. Prefer summary views, never repeat an identical call, and read full Evidence only when the task requires it.";
12
- import { PROCESS_CAPTURE_ELICITATION_POLICY, } from "./ProcessCaptureElicitation.js";
13
- import { LazyToolCatalog } from "./LazyToolCatalog.js";
14
28
  const installSessionToolAvailability = (server, session, options) => {
15
29
  if (session === undefined)
16
30
  return undefined;
17
31
  const policy = sessionAvailabilityPolicy(options.availabilityPolicy, {
18
- processPolicy: options.processPolicy ?? DENY_PROCESS_POLICY,
32
+ processPolicy: options.processPolicy?.() ?? DENY_PROCESS_POLICY,
19
33
  evidenceFilePolicy: options.evidenceFilePolicy ?? DENY_EVIDENCE_FILE_POLICY,
20
34
  investigationInputRoots: options.investigationInputRoots ?? [],
21
35
  optionalFeatures: {
22
36
  browserObservationEnabled: options.browserObservation !== undefined,
23
37
  browserScenarioEnabled: options.browserScenarioCapture !== undefined,
24
38
  electronObservationEnabled: options.electronObservation !== undefined,
39
+ electronAutomationEnabled: options.electronActiveObservation !== undefined &&
40
+ options.permissionAuthority !== undefined,
25
41
  v8InspectorObservationEnabled: options.javascriptRuntimeObservation !== undefined,
26
- javascriptReplayEnabled: options.javascriptReplayPolicy?.enabled ?? false,
27
- managedRuntimeEnabled: options.managedRuntimePolicy?.enabled ?? false,
42
+ javascriptReplayEnabled: options.javascriptReplayPolicy?.().status === "enabled",
43
+ managedRuntimeEnabled: options.managedRuntimePolicy?.().status === "enabled",
28
44
  },
29
45
  });
30
46
  return {
31
47
  policy,
32
- controller: installDynamicToolAvailability(server, session, policy),
33
48
  };
34
49
  };
50
+ const createProcessCaptureElicitation = (stateCodec) => ({
51
+ stateCodec,
52
+ supported: (context) => {
53
+ const envelope = context.mcpReq.envelope;
54
+ const version = mcpEnvelopeValue(envelope, PROTOCOL_VERSION_META_KEY);
55
+ const capabilities = mcpEnvelopeValue(envelope, CLIENT_CAPABILITIES_META_KEY);
56
+ return (typeof version === "string" &&
57
+ PROCESS_CAPTURE_ELICITATION_POLICY.protocolVersions.some((supported) => supported === version) &&
58
+ isRecord(capabilities) &&
59
+ isRecord(capabilities.elicitation) &&
60
+ capabilities.elicitation.form !== undefined);
61
+ },
62
+ now: Date.now,
63
+ consumedNonces: new Map(),
64
+ });
65
+ const createMcpServer = (processCaptureStateCodec, session) => new McpServer({
66
+ name: PRODUCT_IDENTITY.mcpServerKey,
67
+ version: PRODUCT_IDENTITY.packageVersion,
68
+ }, {
69
+ capabilities: {
70
+ resources: { subscribe: true },
71
+ },
72
+ inputRequired: {
73
+ maxRounds: 3,
74
+ roundTimeoutMs: PROCESS_CAPTURE_ELICITATION_POLICY.roundTimeoutMs,
75
+ },
76
+ requestState: { verify: processCaptureStateCodec.verify },
77
+ instructions: session === undefined
78
+ ? ACTIVE_TARGET_INSTRUCTIONS
79
+ : TARGET_FREE_INSTRUCTIONS,
80
+ });
35
81
  /**
36
82
  * Construct one MCP server without acquiring subprocess resources.
37
83
  * Supplying a session adds target lifecycle tools; omitting it retains the
@@ -45,100 +91,44 @@ export const createServer = (analysis, session, options = {}) => {
45
91
  key: randomBytes(32),
46
92
  ttlSeconds: PROCESS_CAPTURE_ELICITATION_POLICY.stateTtlSeconds,
47
93
  });
48
- const server = new McpServer({
49
- name: PRODUCT_IDENTITY.mcpServerKey,
50
- version: PRODUCT_IDENTITY.packageVersion,
51
- }, {
52
- capabilities: {
53
- tools: { listChanged: true },
54
- resources: { listChanged: true, subscribe: true },
55
- },
56
- inputRequired: {
57
- maxRounds: 3,
58
- roundTimeoutMs: PROCESS_CAPTURE_ELICITATION_POLICY.roundTimeoutMs,
59
- },
60
- requestState: { verify: processCaptureStateCodec.verify },
61
- instructions: session === undefined
62
- ? ACTIVE_TARGET_INSTRUCTIONS
63
- : TARGET_FREE_INSTRUCTIONS,
64
- });
65
- const dynamicTools = installSessionToolAvailability(server, session, options);
94
+ const server = createMcpServer(processCaptureStateCodec, session);
95
+ const availability = installSessionToolAvailability(server, session, options);
66
96
  server.server.onclose = () => {
67
97
  permissionAuthority?.clearSessionGrants();
68
98
  };
69
- if (dynamicTools !== undefined)
70
- server.server.oninitialized = () => server.sendToolListChanged();
71
- session?.onAvailabilityChanged?.(() => server.sendToolListChanged());
72
99
  registerServerIdentityResource(server, startedAt);
73
100
  const toolLogger = logger.child({ layer: "server" });
74
101
  const { activeTarget, recordEvidence, recordEvidenceWithUnknown } = createSessionRecorders(server, session);
75
- const processCaptureElicitation = {
76
- stateCodec: processCaptureStateCodec,
77
- supported: (context) => {
78
- const envelope = context.mcpReq.envelope;
79
- const version = envelope?.[PROTOCOL_VERSION_META_KEY];
80
- const capabilities = envelope?.[CLIENT_CAPABILITIES_META_KEY];
81
- return (typeof version === "string" &&
82
- PROCESS_CAPTURE_ELICITATION_POLICY.protocolVersions.some((supported) => supported === version) &&
83
- isRecord(capabilities) &&
84
- isRecord(capabilities.elicitation) &&
85
- capabilities.elicitation.form !== undefined);
86
- },
87
- now: Date.now,
88
- consumedNonces: new Map(),
89
- };
90
- let optionalProviders;
91
- const loadOptionalProviders = () => {
92
- optionalProviders ??= options
93
- .loadOptionalProviders?.()
94
- .catch((cause) => {
95
- optionalProviders = undefined;
96
- throw cause;
97
- });
98
- return optionalProviders;
102
+ const processCaptureElicitation = createProcessCaptureElicitation(processCaptureStateCodec);
103
+ const toolContext = {
104
+ server,
105
+ analysis,
106
+ session,
107
+ options,
108
+ logger: toolLogger,
109
+ permissionAuthority,
110
+ activeTarget,
111
+ recordEvidence,
112
+ recordEvidenceWithUnknown,
99
113
  };
100
- const lazyTools = new LazyToolCatalog(server, async (kind) => {
101
- const needsObservationProviders = kind === "browser-provider" ||
102
- kind === "electron-provider" ||
103
- kind === "runtime-provider";
104
- const [{ hydrateServerToolFamily }, loadedOptionalProviders] = await Promise.all([
105
- import("./hydrateServerTools.js"),
106
- needsObservationProviders ? loadOptionalProviders() : undefined,
107
- ]);
108
- const hydratedOptions = loadedOptionalProviders === undefined
109
- ? options
110
- : { ...options, ...loadedOptionalProviders };
111
- await hydrateServerToolFamily({
112
- kind,
113
- server,
114
- analysis,
115
- session,
116
- options: hydratedOptions,
117
- context: {
118
- logger: toolLogger,
119
- permissionAuthority,
120
- activeTarget,
121
- recordEvidence,
122
- recordEvidenceWithUnknown,
123
- availabilityPolicy: dynamicTools?.policy,
124
- startedAt,
125
- processCaptureElicitation,
126
- },
127
- });
128
- }, session !== undefined);
129
- lazyTools.register();
114
+ registerBinaryAnalysisTools(toolContext);
115
+ registerObservationTools(toolContext);
130
116
  registerGuidedPrompts(server, analysis, session);
131
117
  if (session !== undefined) {
132
118
  registerEvidenceResources(server, session);
119
+ registerSessionTools(server, session, toolLogger, {
120
+ ...options,
121
+ ...(availability === undefined
122
+ ? {}
123
+ : { availabilityPolicy: availability.policy }),
124
+ ...(permissionAuthority === undefined ? {} : { permissionAuthority }),
125
+ startedAt,
126
+ processCaptureElicitation,
127
+ });
133
128
  }
134
- dynamicTools?.controller.synchronize();
135
- const close = server.close.bind(server);
136
- server.close = async () => {
137
- await lazyTools.close();
138
- await close();
139
- };
140
129
  return server;
141
130
  };
131
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
142
132
  const createSessionRecorders = (server, session) => ({
143
133
  activeTarget: session === undefined ? undefined : () => session.activeTarget(),
144
134
  recordEvidence: session === undefined
@@ -154,15 +144,90 @@ const createSessionRecorders = (server, session) => ({
154
144
  return recorded;
155
145
  },
156
146
  });
147
+ const registerBinaryAnalysisTools = ({ server, analysis, session, options, logger, permissionAuthority, activeTarget, recordEvidence, recordEvidenceWithUnknown, }) => {
148
+ const recordUnknown = session === undefined
149
+ ? undefined
150
+ : (input) => session.recordUnknown(input);
151
+ const analysisOptions = {
152
+ logger,
153
+ activeTarget,
154
+ recordEvidence,
155
+ recordUnknown,
156
+ };
157
+ registerOfficialTools(server, analysis, analysisOptions);
158
+ registerEnhancedTools(server, analysis, {
159
+ ...analysisOptions,
160
+ analysisProfile: session === undefined ? undefined : () => session.analysisProfile(),
161
+ });
162
+ const evidenceOptions = { logger, activeTarget, recordEvidence };
163
+ registerNativeTools(server, analysis, evidenceOptions);
164
+ registerArtifactTools(server, analysis, {
165
+ ...evidenceOptions,
166
+ ...(permissionAuthority === undefined ? {} : { permissionAuthority }),
167
+ });
168
+ registerManagedTools(server, analysis, {
169
+ ...evidenceOptions,
170
+ session,
171
+ });
172
+ if (session !== undefined)
173
+ registerManagedWorkflowTools(server, {
174
+ logger,
175
+ recordEvidence,
176
+ recordEvidenceWithUnknown,
177
+ session,
178
+ runtime: {
179
+ policy: options.managedRuntimePolicy ?? (() => MANAGED_RUNTIME_DISABLED),
180
+ authority: permissionAuthority,
181
+ },
182
+ });
183
+ };
184
+ const registerObservationTools = ({ server, session, options, logger, permissionAuthority, recordEvidence, recordEvidenceWithUnknown, }) => {
185
+ const common = { logger, permissionAuthority, recordEvidence };
186
+ registerBrowserTools(server, {
187
+ ...common,
188
+ browser: options.browserObservation,
189
+ });
190
+ registerBrowserScenarioTool(server, {
191
+ ...common,
192
+ provider: options.browserScenarioCapture,
193
+ });
194
+ registerElectronTools(server, {
195
+ ...common,
196
+ electron: options.electronObservation,
197
+ electronActive: options.electronActiveObservation,
198
+ });
199
+ registerJavaScriptRuntimeObservationTools(server, {
200
+ ...common,
201
+ runtime: options.javascriptRuntimeObservation,
202
+ });
203
+ registerApplicationTools(server, {
204
+ logger,
205
+ recordEvidence,
206
+ recordEvidenceWithUnknown,
207
+ evidenceLookup: session === undefined
208
+ ? undefined
209
+ : (evidenceId) => session.evidenceById(evidenceId),
210
+ evidenceFilePolicy: options.evidenceFilePolicy ?? DENY_EVIDENCE_FILE_POLICY,
211
+ permissionAuthority,
212
+ retainCoverageWorkspace: session === undefined
213
+ ? undefined
214
+ : (workspace) => session.retainReconstructionCoverageWorkspace(workspace),
215
+ replay: {
216
+ policy: options.javascriptReplayPolicy ?? (() => ({ status: "disabled" })),
217
+ host: options.javascriptReplayHost ?? new SystemJavaScriptReplayHost(),
218
+ runner: options.javascriptReplayRunner ?? new LinuxJavaScriptReplayRunner(),
219
+ authority: permissionAuthority,
220
+ },
221
+ });
222
+ };
157
223
  const registerServerIdentityResource = (server, startedAt) => {
158
224
  server.registerResource("server-identity", "rea://server/identity", {
159
225
  title: "REA server identity",
160
226
  description: "Live package, SDK, protocol, and catalog identity.",
161
227
  mimeType: "application/json",
162
- }, async (uri) => {
228
+ }, async (uri, context) => {
163
229
  const { createServerIdentity } = await import("../serverIdentity.js");
164
- const client = server.server.getClientVersion();
165
- const protocolVersion = server.server.getNegotiatedProtocolVersion();
230
+ const { client, protocolVersion } = mcpClientMetadata(context);
166
231
  return {
167
232
  contents: [
168
233
  {
@@ -178,4 +243,3 @@ const registerServerIdentityResource = (server, startedAt) => {
178
243
  };
179
244
  });
180
245
  };
181
- const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
@@ -0,0 +1,32 @@
1
+ import { CLIENT_CAPABILITIES_META_KEY, CLIENT_INFO_META_KEY, PROTOCOL_VERSION_META_KEY, } from "@modelcontextprotocol/server";
2
+ /** Client metadata bound to the current SDK request rather than server-global state. */
3
+ export const mcpClientMetadata = (context) => {
4
+ const envelope = context.mcpReq.envelope;
5
+ const client = implementation(mcpEnvelopeValue(envelope, CLIENT_INFO_META_KEY));
6
+ const protocolVersion = mcpEnvelopeValue(envelope, PROTOCOL_VERSION_META_KEY);
7
+ return {
8
+ ...(client === undefined ? {} : { client }),
9
+ clientFeatures: capabilityFeatures(mcpEnvelopeValue(envelope, CLIENT_CAPABILITIES_META_KEY)),
10
+ ...(typeof protocolVersion === "string" ? { protocolVersion } : {}),
11
+ };
12
+ };
13
+ /** Read an SDK-defined metadata key from the SDK's currently opaque envelope type. */
14
+ export const mcpEnvelopeValue = (envelope, key) => (envelope === undefined ? undefined : Reflect.get(envelope, key));
15
+ const implementation = (value) => isRecord(value) &&
16
+ typeof value.name === "string" &&
17
+ typeof value.version === "string"
18
+ ? { name: value.name, version: value.version }
19
+ : undefined;
20
+ const capabilityFeatures = (value) => {
21
+ const capabilities = isRecord(value) ? value : {};
22
+ const elicitation = isRecord(capabilities.elicitation)
23
+ ? capabilities.elicitation
24
+ : {};
25
+ return {
26
+ elicitation_form: elicitation.form !== undefined,
27
+ elicitation_url: elicitation.url !== undefined,
28
+ roots: capabilities.roots !== undefined,
29
+ sampling: capabilities.sampling !== undefined,
30
+ };
31
+ };
32
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
@@ -1,22 +1,18 @@
1
1
  import { executeNodeCharacterization, prepareNodeCharacterization, } from "../../application/NodeRuntimeCharacterizationService.js";
2
2
  import { applicationToolContract } from "../../contracts/applicationToolContracts.js";
3
- import { nodeCharacterizationExecutionInputSchema, nodeCharacterizationExecutionOutputSchema, nodeCharacterizationPreparationInputSchema, nodeCharacterizationPreparationOutputSchema, } from "../../domain/nodeRuntimeCharacterization.js";
4
3
  import { parseEvidence } from "../../domain/evidence.js";
4
+ import { nodeCharacterizationExecutionOutputSchema, nodeCharacterizationPreparationOutputSchema, } from "../../domain/nodeRuntimeCharacterization.js";
5
+ import { mcpProgressReporter } from "../mcpProgress.js";
5
6
  import { logToolExecution } from "../toolLogging.js";
6
- import { toCallToolResult } from "../toolResult.js";
7
7
  import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
8
- import { safeParseToolInput } from "../toolInputValidation.js";
9
- import { mcpProgressReporter } from "../mcpProgress.js";
8
+ import { toCallToolResult } from "../toolResult.js";
10
9
  import { recordSources } from "./helpers.js";
11
10
  const prepareContract = applicationToolContract("prepare_node_characterization");
12
11
  const executeContract = applicationToolContract("execute_node_characterization");
13
12
  /** Register node runtime characterization prepare and execute tools. */
14
13
  export const registerCharacterizationTools = (server, options) => {
15
14
  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, {
15
+ const result = await logToolExecution(options.logger, prepareContract.name, () => prepareNodeCharacterization(options.replay, input, {
20
16
  signal: context.mcpReq.signal,
21
17
  progress: mcpProgressReporter(context),
22
18
  }));
@@ -31,10 +27,7 @@ export const registerCharacterizationTools = (server, options) => {
31
27
  });
32
28
  });
33
29
  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, {
30
+ const result = await logToolExecution(options.logger, executeContract.name, () => executeNodeCharacterization(options.replay, input, {
38
31
  signal: context.mcpReq.signal,
39
32
  progress: mcpProgressReporter(context),
40
33
  }));
@@ -44,7 +37,7 @@ export const registerCharacterizationTools = (server, options) => {
44
37
  const sources = [
45
38
  output.transformation_evidence,
46
39
  ...output.replay.source_evidence,
47
- ...(output.replay.evidence === null ? [] : [output.replay.evidence]),
40
+ output.replay.evidence,
48
41
  output.evidence,
49
42
  ].map((item) => parseEvidence(item));
50
43
  const recorded = recordSources(options.recordEvidence, sources);
@@ -1,21 +1,16 @@
1
1
  import { resolveCompareJavaScriptExportShapesRequestValidated } from "../../application/ApplicationWorkflowEvidenceResolver.js";
2
2
  import { compareJavaScriptExportShapesEvidenceValidated } from "../../application/JavaScriptApplicationWorkflowService.js";
3
3
  import { applicationToolContract } from "../../contracts/applicationToolContracts.js";
4
- import { compareJavaScriptExportShapesRequestSchema } from "../../contracts/applicationWorkflowInputContracts.js";
5
4
  import { javaScriptExportShapeComparisonResultSchema } from "../../domain/javascriptExportShapeComparisonSchemas.js";
6
- import { safeParseToolInput } from "../toolInputValidation.js";
7
5
  import { logToolExecution } from "../toolLogging.js";
8
- import { toCallToolResult } from "../toolResult.js";
9
6
  import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
7
+ import { toCallToolResult } from "../toolResult.js";
10
8
  import { recordResult, recordSources } from "./helpers.js";
11
9
  const contract = applicationToolContract("compare_javascript_export_shapes");
12
10
  /** Register the execution-free exact JavaScript export-shape comparison. */
13
11
  export const registerCompareJavaScriptExportShapesTool = (server, options) => {
14
12
  server.registerTool(contract.name, toolRegistrationOptions(contract), async (input) => {
15
- const parsedInput = safeParseToolInput(compareJavaScriptExportShapesRequestSchema, input, contract.name);
16
- if (!parsedInput.ok)
17
- return toCallToolResult(parsedInput, contract);
18
- const resolved = resolveCompareJavaScriptExportShapesRequestValidated(parsedInput.value, options.evidenceLookup);
13
+ const resolved = resolveCompareJavaScriptExportShapesRequestValidated(input, options.evidenceLookup);
19
14
  if (!resolved.ok)
20
15
  return toCallToolResult(resolved, contract);
21
16
  const parsed = resolved.value;
@@ -1,10 +1,8 @@
1
- import { compareSourceToBundleEvidenceValidated } from "../../application/JavaScriptApplicationWorkflowService.js";
2
1
  import { resolveCompareSourceToBundleRequestValidated } from "../../application/ApplicationWorkflowEvidenceResolver.js";
2
+ import { compareSourceToBundleEvidenceValidated } from "../../application/JavaScriptApplicationWorkflowService.js";
3
3
  import { applicationToolContract } from "../../contracts/applicationToolContracts.js";
4
- import { compareSourceToBundleRequestSchema } from "../../contracts/applicationWorkflowInputContracts.js";
5
4
  import { sourceToBundleComparisonResultSchema } from "../../domain/sourceToBundleComparisonSchemas.js";
6
5
  import { logToolExecution } from "../toolLogging.js";
7
- import { safeParseToolInput } from "../toolInputValidation.js";
8
6
  import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
9
7
  import { toCallToolResult } from "../toolResult.js";
10
8
  import { recordResult, recordSources } from "./helpers.js";
@@ -12,10 +10,7 @@ const contract = applicationToolContract("compare_source_to_bundle");
12
10
  /** Register conservative historical-source to bundle comparison. */
13
11
  export const registerCompareSourceToBundleTool = (server, options) => {
14
12
  server.registerTool(contract.name, toolRegistrationOptions(contract), async (input) => {
15
- const parsedInput = safeParseToolInput(compareSourceToBundleRequestSchema, input, contract.name);
16
- if (!parsedInput.ok)
17
- return toCallToolResult(parsedInput, contract);
18
- const resolved = resolveCompareSourceToBundleRequestValidated(parsedInput.value, options.evidenceLookup);
13
+ const resolved = resolveCompareSourceToBundleRequestValidated(input, options.evidenceLookup);
19
14
  if (!resolved.ok)
20
15
  return toCallToolResult(resolved, contract);
21
16
  const result = await logToolExecution(options.logger, contract.name, () => Promise.resolve(compareSourceToBundleEvidenceValidated(resolved.value)));
@@ -1,21 +1,16 @@
1
- import { compareApplicationVersionsEvidenceValidated } from "../../application/JavaScriptApplicationWorkflowService.js";
2
1
  import { resolveCompareApplicationVersionsRequestValidated } from "../../application/ApplicationWorkflowEvidenceResolver.js";
2
+ import { compareApplicationVersionsEvidenceValidated } from "../../application/JavaScriptApplicationWorkflowService.js";
3
3
  import { applicationToolContract } from "../../contracts/applicationToolContracts.js";
4
- import { compareApplicationVersionsRequestSchema } from "../../contracts/applicationWorkflowInputContracts.js";
5
4
  import { applicationVersionComparisonResultSchema } from "../../domain/javascriptApplicationVersionComparisonSchemas.js";
6
5
  import { logToolExecution } from "../toolLogging.js";
7
- import { toCallToolResult } from "../toolResult.js";
8
6
  import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
9
- import { safeParseToolInput } from "../toolInputValidation.js";
7
+ import { toCallToolResult } from "../toolResult.js";
10
8
  import { recordResult, recordSources } from "./helpers.js";
11
9
  const compareContract = applicationToolContract("compare_application_versions");
12
10
  /** Register the provider-neutral JavaScript version comparison tool. */
13
11
  export const registerCompareApplicationVersionsTool = (server, options) => {
14
12
  server.registerTool(compareContract.name, toolRegistrationOptions(compareContract), async (input) => {
15
- const parsedInput = safeParseToolInput(compareApplicationVersionsRequestSchema, input, compareContract.name);
16
- if (!parsedInput.ok)
17
- return toCallToolResult(parsedInput, compareContract);
18
- const resolved = resolveCompareApplicationVersionsRequestValidated(parsedInput.value, options.evidenceLookup);
13
+ const resolved = resolveCompareApplicationVersionsRequestValidated(input, options.evidenceLookup);
19
14
  if (!resolved.ok)
20
15
  return toCallToolResult(resolved, compareContract);
21
16
  const parsed = resolved.value;
@@ -1,29 +1,24 @@
1
1
  import { runControlledReplayValidated } from "../../application/JavaScriptReplayService.js";
2
2
  import { applicationToolContract } from "../../contracts/applicationToolContracts.js";
3
- import { controlledReplayInputSchema, controlledReplayOutputSchema, } from "../../domain/javascriptReplay.js";
4
3
  import { parseEvidence } from "../../domain/evidence.js";
4
+ import { controlledReplayOutputSchema } from "../../domain/javascriptReplay.js";
5
+ import { mcpProgressReporter } from "../mcpProgress.js";
5
6
  import { logToolExecution } from "../toolLogging.js";
6
- import { toCallToolResult } from "../toolResult.js";
7
7
  import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
8
- import { safeParseToolInput } from "../toolInputValidation.js";
9
- import { mcpProgressReporter } from "../mcpProgress.js";
8
+ import { toCallToolResult } from "../toolResult.js";
10
9
  import { recordSources } from "./helpers.js";
11
10
  const replayContract = applicationToolContract("run_controlled_replay");
12
11
  /** Register the controlled JavaScript replay tool. */
13
12
  export const registerControlledReplayTool = (server, options) => {
14
13
  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, {
14
+ const result = await logToolExecution(options.logger, replayContract.name, () => runControlledReplayValidated(options.replay, input, {
20
15
  signal: context.mcpReq.signal,
21
16
  progress: mcpProgressReporter(context),
22
17
  }));
23
18
  if (!result.ok)
24
19
  return toCallToolResult(result, replayContract);
25
20
  const output = controlledReplayOutputSchema.parse(result.value);
26
- if (output.evidence !== null) {
21
+ if (output.phase === "execute") {
27
22
  const sourcesRecorded = recordSources(options.recordEvidence, output.source_evidence.map((item) => parseEvidence(item)));
28
23
  if (!sourcesRecorded.ok)
29
24
  return toCallToolResult(sourcesRecorded, replayContract);
@@ -32,7 +27,7 @@ export const registerControlledReplayTool = (server, options) => {
32
27
  return toCallToolResult(recorded, replayContract);
33
28
  }
34
29
  return toCallToolResult(result, replayContract, {
35
- evidenceResourcesAvailable: output.evidence !== null && options.recordEvidence !== undefined,
30
+ evidenceResourcesAvailable: output.phase === "execute" && options.recordEvidence !== undefined,
36
31
  });
37
32
  });
38
33
  };
@@ -1,15 +1,13 @@
1
+ import { authorizeFileReadWithDeferredWrite, authorizeRootPermission, } from "../../application/DeferredFileAuthorization.js";
1
2
  import { commitReconstructionCoverage, queryReconstructionCoverage, } from "../../application/ReconstructionCoverageService.js";
2
3
  import { readReconstructionCoverageWorkspace } from "../../application/ReconstructionCoverageWorkspaceStore.js";
3
- import { authorizeFileReadWithDeferredWrite, authorizeRootPermission, } from "../../application/DeferredFileAuthorization.js";
4
4
  import { applicationToolContract } from "../../contracts/applicationToolContracts.js";
5
- import { reconstructionCoverageCommitInputSchema, reconstructionCoverageQueryInputSchema, } from "../../application/ReconstructionCoverageService.js";
6
- import { reconstructionClosureResultSchema } from "../../domain/reconstructionCoverage.js";
7
5
  import { AnalysisCapabilityUnavailableError, EvidenceIntegrityError, } from "../../domain/errors.js";
6
+ import { reconstructionClosureResultSchema } from "../../domain/reconstructionCoverage.js";
8
7
  import { err } from "../../domain/result.js";
9
8
  import { logToolExecution } from "../toolLogging.js";
10
- import { toCallToolResult } from "../toolResult.js";
11
9
  import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
12
- import { safeParseToolInput } from "../toolInputValidation.js";
10
+ import { toCallToolResult } from "../toolResult.js";
13
11
  import { coverageWorkspaceUri } from "./helpers.js";
14
12
  const commitContract = applicationToolContract("commit_reconstruction_coverage");
15
13
  const queryContract = applicationToolContract("query_reconstruction_coverage");
@@ -20,13 +18,10 @@ export const registerCoverageTools = (server, options) => {
20
18
  };
21
19
  const registerCommitTool = (server, options) => {
22
20
  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
21
  if (options.permissionAuthority === undefined)
27
22
  return toCallToolResult(err(new AnalysisCapabilityUnavailableError("rea-reconstruction-coverage", commitContract.name, "workspace permission policy is not configured")), commitContract);
28
23
  const authorization = await authorizeFileReadWithDeferredWrite(options.permissionAuthority, {
29
- path: parsed.value.workspace_path,
24
+ path: input.workspace_path,
30
25
  readCapability: "investigation_workspace_read",
31
26
  writeCapability: "investigation_workspace_write",
32
27
  operation: commitContract.name,
@@ -36,17 +31,19 @@ const registerCommitTool = (server, options) => {
36
31
  const write = await authorization.value.authorizeWrite();
37
32
  if (!write.ok)
38
33
  return toCallToolResult(write, commitContract);
39
- const result = await logToolExecution(options.logger, commitContract.name, () => commitReconstructionCoverage(parsed.value, options.evidenceFilePolicy, { signal: context.mcpReq.signal }));
34
+ const result = await logToolExecution(options.logger, commitContract.name, () => commitReconstructionCoverage(input, options.evidenceFilePolicy, {
35
+ signal: context.mcpReq.signal,
36
+ }));
40
37
  if (!result.ok)
41
38
  return toCallToolResult(result, commitContract);
42
- options.retainCoverageWorkspace?.(parsed.value.workspace);
39
+ options.retainCoverageWorkspace?.(input.workspace);
43
40
  return toCallToolResult(result, commitContract, {
44
41
  resourceLinks: options.retainCoverageWorkspace === undefined
45
42
  ? []
46
43
  : [
47
44
  {
48
- uri: coverageWorkspaceUri(parsed.value.workspace),
49
- name: parsed.value.workspace.workspace_id,
45
+ uri: coverageWorkspaceUri(input.workspace),
46
+ name: input.workspace.workspace_id,
50
47
  description: "Session-retained reconstruction coverage workspace revision",
51
48
  },
52
49
  ],
@@ -55,23 +52,20 @@ const registerCommitTool = (server, options) => {
55
52
  };
56
53
  const registerQueryTool = (server, options) => {
57
54
  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
55
  if (options.permissionAuthority === undefined)
62
56
  return toCallToolResult(err(new AnalysisCapabilityUnavailableError("rea-reconstruction-coverage", queryContract.name, "workspace permission policy is not configured")), queryContract);
63
57
  const authorized = await authorizeRootPermission(options.permissionAuthority, {
64
58
  capability: "investigation_workspace_read",
65
- roots: [parsed.value.workspace_path],
59
+ roots: [input.workspace_path],
66
60
  access: "read",
67
61
  operation: queryContract.name,
68
62
  });
69
63
  if (!authorized.ok)
70
64
  return toCallToolResult(authorized, queryContract);
71
- const result = await logToolExecution(options.logger, queryContract.name, () => queryReconstructionCoverage(parsed.value, options.evidenceFilePolicy, Date.now(), { signal: context.mcpReq.signal }));
65
+ const result = await logToolExecution(options.logger, queryContract.name, () => queryReconstructionCoverage(input, options.evidenceFilePolicy, Date.now(), { signal: context.mcpReq.signal }));
72
66
  if (result.ok && options.retainCoverageWorkspace !== undefined) {
73
67
  const closure = reconstructionClosureResultSchema.parse(result.value);
74
- const loaded = await readReconstructionCoverageWorkspace(parsed.value.workspace_path, options.evidenceFilePolicy);
68
+ const loaded = await readReconstructionCoverageWorkspace(input.workspace_path, options.evidenceFilePolicy);
75
69
  if (!loaded.ok)
76
70
  return toCallToolResult(loaded, queryContract);
77
71
  if (loaded.value === null ||
@@ -1,8 +1,6 @@
1
1
  import { buildReconstructionObligationLedgerEvidenceValidated, resolveReconstructionObligationLedgerRequest, } from "../../application/ReconstructionObligationLedgerService.js";
2
2
  import { applicationToolContract } from "../../contracts/applicationToolContracts.js";
3
- import { reconstructionObligationLedgerInputSchema } from "../../domain/reconstructionObligationLedgerSchemas.js";
4
3
  import { logToolExecution } from "../toolLogging.js";
5
- import { safeParseToolInput } from "../toolInputValidation.js";
6
4
  import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
7
5
  import { toCallToolResult } from "../toolResult.js";
8
6
  import { recordResult, recordSources } from "./helpers.js";
@@ -10,10 +8,7 @@ const contract = applicationToolContract("build_reconstruction_obligation_ledger
10
8
  /** Register conservative reconstruction-obligation generation and closure. */
11
9
  export const registerReconstructionObligationLedgerTool = (server, options) => {
12
10
  server.registerTool(contract.name, toolRegistrationOptions(contract), async (input) => {
13
- const parsed = safeParseToolInput(reconstructionObligationLedgerInputSchema, input, contract.name);
14
- if (!parsed.ok)
15
- return toCallToolResult(parsed, contract);
16
- const resolved = resolveReconstructionObligationLedgerRequest(parsed.value);
11
+ const resolved = resolveReconstructionObligationLedgerRequest(input);
17
12
  if (!resolved.ok)
18
13
  return toCallToolResult(resolved, contract);
19
14
  const result = await logToolExecution(options.logger, contract.name, () => Promise.resolve(buildReconstructionObligationLedgerEvidenceValidated(resolved.value)));