rea-agents 2.5.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 (253) hide show
  1. package/README.md +20 -12
  2. package/bridge/ghidra/ReaGhidraBridge.java +477 -4
  3. package/bridge/hopper_bridge.py +54 -4
  4. package/dist/application/AnalysisContextQueries.js +142 -0
  5. package/dist/application/AnalysisSnapshotCache.js +4 -2
  6. package/dist/application/ApplicationWorkflowEvidenceResolver.js +19 -11
  7. package/dist/application/ArtifactInventory/policy.js +17 -0
  8. package/dist/application/ArtifactInventory/reader.js +1 -4
  9. package/dist/application/ArtifactInventory/scanCanonical.js +0 -3
  10. package/dist/application/ArtifactInventory/scanReader.js +7 -7
  11. package/dist/application/ArtifactInventory/types.js +1 -5
  12. package/dist/application/BinarySession.js +19 -20
  13. package/dist/application/BinarySessionComposition.js +21 -0
  14. package/dist/application/BinarySessionRecords.js +106 -10
  15. package/dist/application/BinarySessionStatus.js +11 -5
  16. package/dist/application/BrowserEvidence.js +3 -5
  17. package/dist/application/CapabilityClientRequirements.js +26 -0
  18. package/dist/application/CapabilityInventory.js +140 -55
  19. package/dist/application/ClientRegistrationStatus.js +4 -1
  20. package/dist/application/CrossVersionInventory.js +7 -6
  21. package/dist/application/DirectAnalysis.js +6 -2
  22. package/dist/application/ElectronActiveEvidence.js +55 -0
  23. package/dist/application/ElectronActiveObservationPort.js +1 -0
  24. package/dist/application/ElectronActiveObservationService.js +81 -0
  25. package/dist/application/EnhancedTools.js +49 -17
  26. package/dist/application/EvidenceBundleCommands.js +5 -1
  27. package/dist/application/EvidenceLedger.js +53 -17
  28. package/dist/application/JavaScriptArtifactAnalysis.js +13 -4
  29. package/dist/application/JavaScriptReplayPermission.js +1 -1
  30. package/dist/application/JavaScriptReplayService.js +23 -15
  31. package/dist/application/LazyAnalysisProvider.js +77 -0
  32. package/dist/application/LoopbackReplay.js +1 -1
  33. package/dist/application/ManagedRuntimeCorrelationService.js +9 -5
  34. package/dist/application/NativeApiInspection.js +80 -0
  35. package/dist/application/NodeRuntimeCharacterizationService.js +8 -9
  36. package/dist/application/ProcessCaptureLifecycle.js +5 -0
  37. package/dist/application/ProcessCli.js +2 -1
  38. package/dist/application/ProcessHarness.js +8 -3
  39. package/dist/application/ProcessNormalization.js +2 -1
  40. package/dist/application/ProjectPermissionStore.js +1 -0
  41. package/dist/application/ReferenceSourceImport.js +2 -2
  42. package/dist/application/SessionProviderRouter.js +6 -6
  43. package/dist/application/SetupClientConfiguration.js +10 -3
  44. package/dist/application/WindowsCapabilities.js +5 -4
  45. package/dist/application/runtime.js +26 -9
  46. package/dist/artifacts/ArtifactProvider.js +8 -10
  47. package/dist/artifacts/SafeOutputTree.js +7 -8
  48. package/dist/browser/CdpCaptureStorageFingerprints.js +10 -7
  49. package/dist/browser/CdpElectronInspection.js +3 -1
  50. package/dist/browser/JavaScriptRuntimeScope.js +5 -0
  51. package/dist/browser/PlaywrightBrowserScenarioProvider.js +8 -2
  52. package/dist/browser/PlaywrightElectronActiveActions.js +324 -0
  53. package/dist/browser/PlaywrightElectronActiveProvider.js +294 -0
  54. package/dist/browser/PlaywrightScenarioBrowser.js +4 -4
  55. package/dist/browser/PlaywrightScenarioSession.js +4 -4
  56. package/dist/browser/SensitiveTextCapture.js +1 -1
  57. package/dist/browser/V8InspectorCaptureProjection.js +1 -0
  58. package/dist/browser/V8InspectorProvider.js +3 -3
  59. package/dist/catalogIdentity.js +15 -9
  60. package/dist/cli/artifactCommands.js +5 -3
  61. package/dist/cli/coreAnalysisCommands.js +41 -0
  62. package/dist/cli/managedCommands.js +1 -1
  63. package/dist/cliApplicationCommands.js +2 -2
  64. package/dist/cliBrowserAdvancedCommands.js +11 -5
  65. package/dist/cliBrowserCommands.js +14 -7
  66. package/dist/cliCommandNames.js +2 -0
  67. package/dist/cliElectronCommands.js +46 -4
  68. package/dist/cliJavaScriptRuntimeCommands.js +14 -6
  69. package/dist/cliObservationOptions.js +4 -0
  70. package/dist/cliPolicyCommands.js +1 -0
  71. package/dist/config/browserScenario.js +77 -0
  72. package/dist/config/electronAutomation.js +35 -0
  73. package/dist/config/environment.js +6 -0
  74. package/dist/config/javascriptReplay.js +41 -0
  75. package/dist/config/managedRuntime.js +25 -0
  76. package/dist/config/parseConfig.js +56 -200
  77. package/dist/config/parsers.js +10 -1
  78. package/dist/config/passiveObservation.js +157 -0
  79. package/dist/config/processCapture.js +47 -0
  80. package/dist/contracts/applicationToolContracts.js +2 -5
  81. package/dist/contracts/applicationWorkflowInputContracts.js +86 -96
  82. package/dist/contracts/artifactToolContracts.js +35 -37
  83. package/dist/contracts/browserToolContracts.js +2 -2
  84. package/dist/contracts/electronToolContracts.js +30 -1
  85. package/dist/contracts/enhancedInputs.js +21 -27
  86. package/dist/contracts/functionWorkflowToolContracts.js +29 -0
  87. package/dist/contracts/managedToolContracts.js +4 -9
  88. package/dist/contracts/managedWorkflowExamples.js +12 -9
  89. package/dist/contracts/managedWorkflowToolContracts.js +30 -27
  90. package/dist/contracts/nativeToolContracts.js +2 -3
  91. package/dist/contracts/promptContracts.js +14 -15
  92. package/dist/contracts/sessionToolSchemas.js +61 -0
  93. package/dist/contracts/toolContractExamples.js +4 -0
  94. package/dist/contracts/toolContractHelpers.js +23 -0
  95. package/dist/contracts/toolContracts.js +12 -67
  96. package/dist/contracts/toolEffects.js +19 -0
  97. package/dist/contracts/toolOutputSchemaGroups.js +66 -11
  98. package/dist/contracts/toolOutputSchemaPrimitives.js +76 -26
  99. package/dist/contracts/toolSchemaMetadata.js +128 -0
  100. package/dist/doctorRuntime.js +1 -1
  101. package/dist/domain/analysisErrorPresentation.js +8 -2
  102. package/dist/domain/analysisErrorProjection.js +1 -0
  103. package/dist/domain/androidApplication.js +2 -0
  104. package/dist/domain/appleApplication.js +2 -0
  105. package/dist/domain/binaryTarget.js +7 -5
  106. package/dist/domain/binaryTargetTypes.js +1 -0
  107. package/dist/domain/browserCaptureComparison.js +21 -69
  108. package/dist/domain/browserObservation.js +22 -9
  109. package/dist/domain/bytecodeProvider.js +177 -0
  110. package/dist/domain/callPath.js +3 -2
  111. package/dist/domain/conformancePackage.js +169 -0
  112. package/dist/domain/conformanceReplay.js +104 -0
  113. package/dist/domain/conformanceTrustGate.js +328 -0
  114. package/dist/domain/customProtocolCapture.js +137 -0
  115. package/dist/domain/electronActiveObservation.js +277 -0
  116. package/dist/domain/electronObservation.js +15 -11
  117. package/dist/domain/electronStaticAnalysisValues.js +4 -1
  118. package/dist/domain/eventProcessTree.js +217 -0
  119. package/dist/domain/evidenceBundle.js +47 -0
  120. package/dist/domain/functionComparisonNormalization.js +15 -8
  121. package/dist/domain/functionDossierEvidence.js +9 -4
  122. package/dist/domain/hopperStartupFailure.js +1 -1
  123. package/dist/domain/hopperValues.js +68 -68
  124. package/dist/domain/inputIssueProjection.js +11 -2
  125. package/dist/domain/investigationWorkspace.js +16 -15
  126. package/dist/domain/javascriptExportShapeComparisonSchemas.js +2 -2
  127. package/dist/domain/javascriptReplay.js +79 -63
  128. package/dist/domain/javascriptRuntimeObservation.js +1 -0
  129. package/dist/domain/javascriptRuntimeReconciliationActive.js +89 -0
  130. package/dist/domain/javascriptRuntimeReconciliationGraph.js +11 -10
  131. package/dist/domain/javascriptRuntimeReconciliationMatching.js +57 -49
  132. package/dist/domain/javascriptRuntimeReconciliationParsing.js +5 -1
  133. package/dist/domain/javascriptRuntimeReconciliationResult.js +21 -14
  134. package/dist/domain/javascriptRuntimeReconciliationSchemas.js +1 -1
  135. package/dist/domain/javascriptSemanticAnalysis.js +8 -12
  136. package/dist/domain/javascriptSourceParser.js +15 -0
  137. package/dist/domain/javascriptStaticAnalysis.js +8 -12
  138. package/dist/domain/knownPageCoverage.js +15 -7
  139. package/dist/domain/mobileApplicationInvestigation.js +159 -0
  140. package/dist/domain/nativeApiBoundary.js +138 -0
  141. package/dist/domain/nodeRuntimeCharacterization.js +14 -13
  142. package/dist/domain/objcSwiftMetadata.js +150 -0
  143. package/dist/domain/packageAnalysis.js +123 -0
  144. package/dist/domain/peInspection.js +196 -0
  145. package/dist/domain/processCaptureReactiveValidation.js +8 -3
  146. package/dist/domain/processCaptureValidation.js +7 -3
  147. package/dist/domain/processComparison.js +12 -7
  148. package/dist/domain/processObservation.js +5 -6
  149. package/dist/domain/processReactiveMatching.js +14 -7
  150. package/dist/domain/processReactiveTransition.js +9 -3
  151. package/dist/domain/processScenario.js +6 -3
  152. package/dist/domain/processTraceComparison.js +3 -2
  153. package/dist/domain/protocolCapture.js +245 -0
  154. package/dist/domain/reconstructionReadinessSchemas.js +30 -2
  155. package/dist/domain/referenceSourceImportParsing.js +2 -2
  156. package/dist/domain/replayMachineRuntime.js +5 -3
  157. package/dist/domain/sourceToBundleComparison.js +2 -2
  158. package/dist/domain/sourceToBundleComparisonSchemas.js +8 -8
  159. package/dist/domain/sourceToBundleSignals.js +7 -1
  160. package/dist/domain/staticRuntimeCorrelation.js +7 -5
  161. package/dist/domain/webBundleAnalysis.js +14 -14
  162. package/dist/domain/webCaptureDiff.js +15 -12
  163. package/dist/dotnet/ManagedNativeBoundaryInspector.js +2 -3
  164. package/dist/dotnet/ManagedStaticProvider.js +34 -5
  165. package/dist/generatedMcpToolCatalog.js +37 -0
  166. package/dist/generatedPackageMetadata.js +4 -4
  167. package/dist/ghidra/GhidraClient.js +1 -1
  168. package/dist/ghidra/GhidraClientStartup.js +1 -1
  169. package/dist/ghidra/GhidraDefaults.js +1 -1
  170. package/dist/ghidra/GhidraFunctionValues.js +44 -16
  171. package/dist/ghidra/GhidraInventoryValues.js +57 -47
  172. package/dist/ghidra/GhidraProvider.js +18 -10
  173. package/dist/ghidra/GhidraProviderCapabilities.js +45 -39
  174. package/dist/ghidra/GhidraSocketConnection.js +1 -1
  175. package/dist/ghidra/protocol.js +19 -42
  176. package/dist/hopper/BridgeLauncher.js +3 -1
  177. package/dist/hopper/HopperAnalysisProfile.js +2 -4
  178. package/dist/hopper/HopperCleanup.js +5 -6
  179. package/dist/hopper/HopperClient.js +27 -3
  180. package/dist/hopper/HopperProvider.js +42 -44
  181. package/dist/hopper/HopperRequestQueue.js +32 -4
  182. package/dist/hopper/HopperResponseStream.js +2 -2
  183. package/dist/hopper/LinuxPrivateDisplayProbe.js +16 -10
  184. package/dist/hopper/protocol.js +63 -21
  185. package/dist/main/reload.js +1 -6
  186. package/dist/main/state.js +0 -14
  187. package/dist/main/transport.js +31 -41
  188. package/dist/main.js +17 -13
  189. package/dist/mcpDoctor.js +4 -26
  190. package/dist/mcpStartupPolicy.js +14 -0
  191. package/dist/process/PrivateRuntimeRoot.js +17 -0
  192. package/dist/process/ProcessOwnership.js +64 -128
  193. package/dist/process/ProcessOwnershipIdentity.js +13 -0
  194. package/dist/process/ProcessOwnershipObservation.js +88 -0
  195. package/dist/process/ProcessOwnershipProcessTree.js +22 -0
  196. package/dist/process/ProviderDeadline.js +8 -12
  197. package/dist/process/WindowsAuthority.js +32 -0
  198. package/dist/reference/ReferenceSourceReader.js +3 -3
  199. package/dist/reference/ReferenceSourceReaderEntries.js +2 -2
  200. package/dist/replay/JavaScriptReplayWorker.js +95 -11
  201. package/dist/replay/JavaScriptReplayWorkerTypes.js +1 -0
  202. package/dist/replay/LinuxJavaScriptReplayRunner.js +10 -15
  203. package/dist/replay/ReplayOutcome.js +26 -15
  204. package/dist/replay/ReplayWorkerProtocol.js +34 -29
  205. package/dist/server/createServer.js +101 -144
  206. package/dist/server/mcpClientMetadata.js +32 -0
  207. package/dist/server/registerApplicationTools/characterization.js +6 -13
  208. package/dist/server/registerApplicationTools/compareExportShapes.js +2 -7
  209. package/dist/server/registerApplicationTools/compareSourceToBundle.js +2 -7
  210. package/dist/server/registerApplicationTools/compareVersions.js +3 -8
  211. package/dist/server/registerApplicationTools/controlledReplay.js +6 -11
  212. package/dist/server/registerApplicationTools/coverage.js +13 -19
  213. package/dist/server/registerApplicationTools/obligationLedger.js +1 -6
  214. package/dist/server/registerApplicationTools/readiness.js +1 -6
  215. package/dist/server/registerApplicationTools/traceFeature.js +3 -8
  216. package/dist/server/registerApplicationTools/traceSemantics.js +1 -6
  217. package/dist/server/registerArtifactComparisonTool.js +12 -16
  218. package/dist/server/registerBrowserScenarioTool.js +1 -6
  219. package/dist/server/registerBrowserTools.js +37 -79
  220. package/dist/server/registerBundleComparisonTool.js +10 -14
  221. package/dist/server/registerCloseLifecycleTool.js +6 -14
  222. package/dist/server/registerElectronTools.js +30 -47
  223. package/dist/server/registerEnhancedTools.js +124 -122
  224. package/dist/server/registerEvidenceResources.js +50 -101
  225. package/dist/server/registerEvidenceTools.js +5 -9
  226. package/dist/server/registerFunctionComparisonTool.js +11 -15
  227. package/dist/server/registerInvestigationTools.js +42 -59
  228. package/dist/server/registerJavaScriptApplicationGraphResource.js +0 -4
  229. package/dist/server/registerJavaScriptRuntimeObservationTools.js +13 -27
  230. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +4 -9
  231. package/dist/server/registerManagedWorkflowTools/contract.js +2 -3
  232. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +3 -8
  233. package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +3 -8
  234. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +8 -13
  235. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +4 -9
  236. package/dist/server/registerOfficialTools.js +8 -9
  237. package/dist/server/registerProcessComparisonTool.js +19 -24
  238. package/dist/server/registerReconstructionObligationLedgerResource.js +0 -7
  239. package/dist/server/registerReconstructionReadinessResource.js +0 -7
  240. package/dist/server/registerReplayMachineTool.js +4 -10
  241. package/dist/server/registerSessionRecordTools.js +146 -47
  242. package/dist/server/registerSessionStatusTool.js +14 -29
  243. package/dist/server/registerSessionTools.js +45 -41
  244. package/dist/server/sessionAvailabilityPolicy.js +2 -1
  245. package/dist/server/sessionToolPolicies.js +1 -5
  246. package/dist/server/toolRegistrationOptions.js +4 -177
  247. package/dist/server/toolResult.js +14 -18
  248. package/package.json +35 -16
  249. package/scripts/electron-active-hook-boundaries.cjs +394 -0
  250. package/scripts/electron-active-hook.cjs +501 -0
  251. package/skills/reverse-engineer-anything/SKILL.md +10 -3
  252. package/dist/server/DynamicToolAvailability.js +0 -70
  253. package/dist/server/toolInputValidation.js +0 -77
@@ -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)));
@@ -1,9 +1,7 @@
1
1
  import { evaluateReconstructionReadinessValidated, resolveReconstructionReadinessRequest, } from "../../application/ReconstructionReadinessService.js";
2
2
  import { applicationToolContract } from "../../contracts/applicationToolContracts.js";
3
- import { reconstructionReadinessInputSchema } from "../../domain/reconstructionReadinessSchemas.js";
4
3
  import { reconstructionReadinessReportSchema } from "../../domain/reconstructionReadinessSchemas.js";
5
4
  import { logToolExecution } from "../toolLogging.js";
6
- import { safeParseToolInput } from "../toolInputValidation.js";
7
5
  import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
8
6
  import { toCallToolResult } from "../toolResult.js";
9
7
  import { recordSources } from "./helpers.js";
@@ -11,10 +9,7 @@ const contract = applicationToolContract("evaluate_reconstruction_readiness");
11
9
  /** Register deterministic public-contract reconstruction conformance. */
12
10
  export const registerReconstructionReadinessTool = (server, options) => {
13
11
  server.registerTool(contract.name, toolRegistrationOptions(contract), async (input) => {
14
- const parsed = safeParseToolInput(reconstructionReadinessInputSchema, input, contract.name);
15
- if (!parsed.ok)
16
- return toCallToolResult(parsed, contract);
17
- const resolved = resolveReconstructionReadinessRequest(parsed.value);
12
+ const resolved = resolveReconstructionReadinessRequest(input);
18
13
  if (!resolved.ok)
19
14
  return toCallToolResult(resolved, contract);
20
15
  const result = await logToolExecution(options.logger, contract.name, () => Promise.resolve(evaluateReconstructionReadinessValidated(resolved.value)));
@@ -1,20 +1,15 @@
1
- import { traceApplicationFeatureEvidenceValidated } from "../../application/JavaScriptApplicationWorkflowService.js";
2
1
  import { resolveTraceApplicationFeatureRequestValidated } from "../../application/ApplicationWorkflowEvidenceResolver.js";
2
+ import { traceApplicationFeatureEvidenceValidated } from "../../application/JavaScriptApplicationWorkflowService.js";
3
3
  import { applicationToolContract } from "../../contracts/applicationToolContracts.js";
4
- import { traceApplicationFeatureRequestSchema } from "../../contracts/applicationWorkflowInputContracts.js";
5
4
  import { logToolExecution } from "../toolLogging.js";
6
- import { toCallToolResult } from "../toolResult.js";
7
5
  import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
8
- import { safeParseToolInput } from "../toolInputValidation.js";
6
+ import { toCallToolResult } from "../toolResult.js";
9
7
  import { recordResult, recordSources } from "./helpers.js";
10
8
  const traceContract = applicationToolContract("trace_application_feature");
11
9
  /** Register the provider-neutral JavaScript feature trace tool. */
12
10
  export const registerTraceFeatureTool = (server, options) => {
13
11
  server.registerTool(traceContract.name, toolRegistrationOptions(traceContract), async (input) => {
14
- const parsedInput = safeParseToolInput(traceApplicationFeatureRequestSchema, input, traceContract.name);
15
- if (!parsedInput.ok)
16
- return toCallToolResult(parsedInput, traceContract);
17
- const resolved = resolveTraceApplicationFeatureRequestValidated(parsedInput.value, options.evidenceLookup);
12
+ const resolved = resolveTraceApplicationFeatureRequestValidated(input, options.evidenceLookup);
18
13
  if (!resolved.ok)
19
14
  return toCallToolResult(resolved, traceContract);
20
15
  const parsed = resolved.value;
@@ -1,8 +1,6 @@
1
1
  import { resolveTraceJavaScriptSemanticsRequestValidated } from "../../application/ApplicationWorkflowEvidenceResolver.js";
2
2
  import { traceJavaScriptSemanticsEvidenceValidated } from "../../application/JavaScriptSemanticTraceService.js";
3
3
  import { applicationToolContract } from "../../contracts/applicationToolContracts.js";
4
- import { traceJavaScriptSemanticsRequestSchema } from "../../contracts/applicationWorkflowInputContracts.js";
5
- import { safeParseToolInput } from "../toolInputValidation.js";
6
4
  import { logToolExecution } from "../toolLogging.js";
7
5
  import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
8
6
  import { toCallToolResult } from "../toolResult.js";
@@ -11,10 +9,7 @@ const contract = applicationToolContract("trace_javascript_semantics");
11
9
  /** Register the bounded JavaScript semantic relation trace tool. */
12
10
  export const registerTraceJavaScriptSemanticsTool = (server, options) => {
13
11
  server.registerTool(contract.name, toolRegistrationOptions(contract), async (input) => {
14
- const parsedInput = safeParseToolInput(traceJavaScriptSemanticsRequestSchema, input, contract.name);
15
- if (!parsedInput.ok)
16
- return toCallToolResult(parsedInput, contract);
17
- const resolved = resolveTraceJavaScriptSemanticsRequestValidated(parsedInput.value, options.evidenceLookup);
12
+ const resolved = resolveTraceJavaScriptSemanticsRequestValidated(input, options.evidenceLookup);
18
13
  if (!resolved.ok)
19
14
  return toCallToolResult(resolved, contract);
20
15
  const result = await logToolExecution(options.logger, contract.name, () => Promise.resolve(traceJavaScriptSemanticsEvidenceValidated(resolved.value)));
@@ -1,44 +1,40 @@
1
- import { artifactComparisonInputSchema, compareArtifacts, } from "../domain/artifactComparison.js";
1
+ import { SESSION_TOOL_CONTRACTS } from "../contracts/toolContracts.js";
2
+ import { compareArtifacts } from "../domain/artifactComparison.js";
2
3
  import { createEvidence } from "../domain/evidence.js";
3
4
  import { jsonValueSchema } from "../domain/jsonValue.js";
4
5
  import { recordDerivedEvidence } from "./recordDerivedEvidence.js";
6
+ import { runDerivedOperation } from "./runDerivedOperation.js";
5
7
  import { resolveSessionEvidenceIds } from "./sessionEvidence.js";
6
8
  import { ARTIFACT_COMPARISON_PROVIDER } from "./sessionToolPolicies.js";
7
- import { toCallToolResult } from "./toolResult.js";
8
9
  import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
9
- import { runDerivedOperation } from "./runDerivedOperation.js";
10
- import { safeParseToolInput } from "./toolInputValidation.js";
10
+ import { toCallToolResult } from "./toolResult.js";
11
11
  /** Register Evidence-backed deterministic artifact comparison. */
12
12
  export const registerArtifactComparisonTool = (server, session, contract) => {
13
13
  server.registerTool(contract.name, toolRegistrationOptions(contract), async (input, context) => {
14
- const parsedInput = safeParseToolInput(artifactComparisonInputSchema, input, contract.name);
15
- if (!parsedInput.ok)
16
- return toCallToolResult(parsedInput, contract);
17
- const parsed = parsedInput.value;
18
14
  const expected = {
19
15
  operation: "inventory_artifact",
20
16
  predicate: "rea.analysis/v2",
21
17
  };
22
- const left = resolveSessionEvidenceIds(session, parsed.left_evidence_ids, expected);
18
+ const left = resolveSessionEvidenceIds(session, input.left_evidence_ids, expected);
23
19
  if (!left.ok)
24
20
  return toCallToolResult(left, contract);
25
- const right = resolveSessionEvidenceIds(session, parsed.right_evidence_ids, expected);
21
+ const right = resolveSessionEvidenceIds(session, input.right_evidence_ids, expected);
26
22
  if (!right.ok)
27
23
  return toCallToolResult(right, contract);
28
- const computed = await runDerivedOperation(context, contract.name, () => compareArtifacts(left.value, right.value, parsed.offset, parsed.limit));
24
+ const computed = await runDerivedOperation(context, contract.name, () => compareArtifacts(left.value, right.value, input.offset, input.limit));
29
25
  if (!computed.ok)
30
26
  return toCallToolResult(computed, contract);
31
27
  const comparison = computed.value;
32
- const leftEvidenceIds = parsed.left_evidence_ids;
33
- const rightEvidenceIds = parsed.right_evidence_ids;
28
+ const leftEvidenceIds = input.left_evidence_ids;
29
+ const rightEvidenceIds = input.right_evidence_ids;
34
30
  const evidence = createEvidence(undefined, ARTIFACT_COMPARISON_PROVIDER, {
35
31
  predicateType: "rea.artifact-comparison/v1",
36
32
  operation: contract.name,
37
33
  parameters: {
38
34
  left_evidence_ids: leftEvidenceIds,
39
35
  right_evidence_ids: rightEvidenceIds,
40
- offset: parsed.offset,
41
- limit: parsed.limit,
36
+ offset: input.offset,
37
+ limit: input.limit,
42
38
  },
43
39
  result: jsonValueSchema.parse(comparison),
44
40
  confidence: "derived",
@@ -46,7 +42,7 @@ export const registerArtifactComparisonTool = (server, session, contract) => {
46
42
  limitations: comparison.limitations,
47
43
  evidenceLinks: [...leftEvidenceIds, ...rightEvidenceIds],
48
44
  });
49
- return toCallToolResult(recordDerivedEvidence(session, evidence, artifactUnknownInput(parsed, comparison.status)), contract);
45
+ return toCallToolResult(recordDerivedEvidence(session, evidence, artifactUnknownInput(input, comparison.status)), contract);
50
46
  });
51
47
  };
52
48
  const artifactUnknownInput = (input, status) => {
@@ -1,18 +1,13 @@
1
1
  import { captureBrowserScenario } from "../application/BrowserScenarioCaptureService.js";
2
2
  import { BROWSER_SCENARIO_TOOL_CONTRACTS } from "../contracts/browserScenarioToolContracts.js";
3
- import { browserScenarioSchema } from "../domain/browserScenario.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
  /** Register the controlled browser scenario tool even when policy disables it. */
9
7
  export const registerBrowserScenarioTool = (server, options) => {
10
8
  const [contract] = BROWSER_SCENARIO_TOOL_CONTRACTS;
11
9
  server.registerTool(contract.name, toolRegistrationOptions(contract), async (input, context) => {
12
- const parsed = safeParseToolInput(browserScenarioSchema, input, contract.name);
13
- if (!parsed.ok)
14
- return toCallToolResult(parsed, contract);
15
- const result = await logToolExecution(options.logger, contract.name, () => captureBrowserScenario(options.provider, options.permissionAuthority, parsed.value, { signal: context.mcpReq.signal }));
10
+ const result = await logToolExecution(options.logger, contract.name, () => captureBrowserScenario(options.provider, options.permissionAuthority, input, { signal: context.mcpReq.signal }));
16
11
  if (!result.ok)
17
12
  return toCallToolResult(result, contract);
18
13
  const recorded = options.recordEvidence?.(result.value);
@@ -1,90 +1,48 @@
1
1
  import { analyzeWebBundle, captureWebScreenshot, compareWebCaptureEvidence, compareWebScreenshotEvidence, discoverWebMcpTools, inspectWebPage, listBrowserTargets, observeWebSession, } from "../application/BrowserObservationService.js";
2
2
  import { BROWSER_TOOL_CONTRACTS } from "../contracts/browserToolContracts.js";
3
- import { inspectWebPageInputSchema, listBrowserTargetsInputSchema, } from "../domain/browserObservation.js";
4
- import { analyzeWebBundleInputSchema } from "../domain/webBundleAnalysis.js";
5
- import { observeWebSessionInputSchema } from "../domain/browserSession.js";
6
- import { discoverWebMcpToolsInputSchema } from "../domain/webMcpDiscovery.js";
7
- import { browserCaptureComparisonInputSchema } from "../domain/browserCaptureComparison.js";
8
- import { captureWebScreenshotInputSchema, compareWebScreenshotsInputSchema, } from "../domain/webScreenshot.js";
3
+ import { mcpProgressReporter } from "./mcpProgress.js";
9
4
  import { logToolExecution } from "./toolLogging.js";
10
- import { toCallToolResult } from "./toolResult.js";
11
5
  import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
12
- import { safeParseToolInput } from "./toolInputValidation.js";
13
- import { mcpProgressReporter } from "./mcpProgress.js";
6
+ import { toCallToolResult } from "./toolResult.js";
14
7
  /** Register browser tools even when policy/provider availability denies execution. */
8
+ // oxlint-disable-next-line max-lines-per-function -- direct SDK calls retain each schema-handler type correlation.
15
9
  export const registerBrowserTools = (server, options) => {
16
10
  const [listContract, inspectContract, analyzeContract, sessionContract, webMcpContract, captureDiffContract, screenshotContract, screenshotDiffContract,] = BROWSER_TOOL_CONTRACTS;
17
- registerBrowserTool(server, options, {
18
- contract: listContract,
19
- schema: listBrowserTargetsInputSchema,
20
- execute: (parsed, { signal }) => listBrowserTargets(options.browser, options.permissionAuthority, parsed, {
21
- signal,
22
- }),
23
- });
24
- registerBrowserTool(server, options, {
25
- contract: inspectContract,
26
- schema: inspectWebPageInputSchema,
27
- execute: (parsed, { signal, progress }) => inspectWebPage(options.browser, options.permissionAuthority, parsed, {
28
- signal,
29
- progress,
30
- }),
31
- });
32
- registerBrowserTool(server, options, {
33
- contract: analyzeContract,
34
- schema: analyzeWebBundleInputSchema,
35
- execute: (parsed, { signal, progress }) => analyzeWebBundle(options.browser, options.permissionAuthority, parsed, {
36
- signal,
37
- progress,
38
- }),
39
- });
40
- registerBrowserTool(server, options, {
41
- contract: sessionContract,
42
- schema: observeWebSessionInputSchema,
43
- execute: (parsed, { signal, progress }) => observeWebSession(options.browser, options.permissionAuthority, parsed, {
44
- signal,
45
- progress,
46
- }),
47
- });
48
- registerBrowserTool(server, options, {
49
- contract: webMcpContract,
50
- schema: discoverWebMcpToolsInputSchema,
51
- execute: (parsed, { signal, progress }) => discoverWebMcpTools(options.browser, options.permissionAuthority, parsed, {
52
- signal,
53
- progress,
54
- }),
55
- });
56
- registerBrowserTool(server, options, {
57
- contract: captureDiffContract,
58
- schema: browserCaptureComparisonInputSchema,
59
- execute: (parsed, _context) => compareWebCaptureEvidence(options.browser, parsed),
60
- });
61
- registerBrowserTool(server, options, {
62
- contract: screenshotContract,
63
- schema: captureWebScreenshotInputSchema,
64
- execute: (parsed, { signal, progress }) => captureWebScreenshot(options.browser, options.permissionAuthority, parsed, {
65
- signal,
66
- progress,
67
- }),
68
- });
69
- registerBrowserTool(server, options, {
70
- contract: screenshotDiffContract,
71
- schema: compareWebScreenshotsInputSchema,
72
- execute: (parsed, _context) => compareWebScreenshotEvidence(options.browser, parsed),
73
- });
11
+ server.registerTool(listContract.name, toolRegistrationOptions(listContract), (input, context) => runBrowserTool(options, listContract, { input, context }, (parsed, { signal }) => listBrowserTargets(options.browser, options.permissionAuthority, parsed, {
12
+ signal,
13
+ })));
14
+ server.registerTool(inspectContract.name, toolRegistrationOptions(inspectContract), (input, context) => runBrowserTool(options, inspectContract, { input, context }, (parsed, { signal, progress }) => inspectWebPage(options.browser, options.permissionAuthority, parsed, {
15
+ signal,
16
+ progress,
17
+ })));
18
+ server.registerTool(analyzeContract.name, toolRegistrationOptions(analyzeContract), (input, context) => runBrowserTool(options, analyzeContract, { input, context }, (parsed, { signal, progress }) => analyzeWebBundle(options.browser, options.permissionAuthority, parsed, {
19
+ signal,
20
+ progress,
21
+ })));
22
+ server.registerTool(sessionContract.name, toolRegistrationOptions(sessionContract), (input, context) => runBrowserTool(options, sessionContract, { input, context }, (parsed, { signal, progress }) => observeWebSession(options.browser, options.permissionAuthority, parsed, {
23
+ signal,
24
+ progress,
25
+ })));
26
+ server.registerTool(webMcpContract.name, toolRegistrationOptions(webMcpContract), (input, context) => runBrowserTool(options, webMcpContract, { input, context }, (parsed, { signal, progress }) => discoverWebMcpTools(options.browser, options.permissionAuthority, parsed, {
27
+ signal,
28
+ progress,
29
+ })));
30
+ server.registerTool(captureDiffContract.name, toolRegistrationOptions(captureDiffContract), (input, context) => runBrowserTool(options, captureDiffContract, { input, context }, (parsed) => compareWebCaptureEvidence(options.browser, parsed)));
31
+ server.registerTool(screenshotContract.name, toolRegistrationOptions(screenshotContract), (input, context) => runBrowserTool(options, screenshotContract, { input, context }, (parsed, { signal, progress }) => captureWebScreenshot(options.browser, options.permissionAuthority, parsed, {
32
+ signal,
33
+ progress,
34
+ })));
35
+ server.registerTool(screenshotDiffContract.name, toolRegistrationOptions(screenshotDiffContract), (input, context) => runBrowserTool(options, screenshotDiffContract, { input, context }, (parsed) => compareWebScreenshotEvidence(options.browser, parsed)));
74
36
  };
75
- const registerBrowserTool = (server, options, spec) => {
76
- server.registerTool(spec.contract.name, toolRegistrationOptions(spec.contract), async (input, context) => {
77
- const parsedInput = safeParseToolInput(spec.schema, input, spec.contract.name);
78
- if (!parsedInput.ok)
79
- return toCallToolResult(parsedInput, spec.contract);
80
- const result = await logToolExecution(options.logger, spec.contract.name, () => spec.execute(parsedInput.value, {
81
- signal: context.mcpReq.signal,
82
- progress: mcpProgressReporter(context),
83
- }));
84
- if (!result.ok)
85
- return toCallToolResult(result, spec.contract);
86
- return evidenceResult(options, spec.contract, result.value);
87
- });
37
+ const runBrowserTool = async (options, contract, request, execute) => {
38
+ const { input, context } = request;
39
+ const result = await logToolExecution(options.logger, contract.name, () => execute(input, {
40
+ signal: context.mcpReq.signal,
41
+ progress: mcpProgressReporter(context),
42
+ }));
43
+ if (!result.ok)
44
+ return toCallToolResult(result, contract);
45
+ return evidenceResult(options, contract, result.value);
88
46
  };
89
47
  const evidenceResult = (options, contract, evidence) => {
90
48
  const recorded = options.recordEvidence?.(evidence);
@@ -1,29 +1,25 @@
1
1
  import { readEvidenceBundle } from "../application/EvidenceBundleFiles.js";
2
- import { bundleComparisonInputSchema, compareBundles, } from "../domain/bundleComparison.js";
2
+ import { SESSION_TOOL_CONTRACTS } from "../contracts/toolContracts.js";
3
+ import { compareBundles } from "../domain/bundleComparison.js";
3
4
  import { createEvidence } from "../domain/evidence.js";
4
5
  import { jsonValueSchema } from "../domain/jsonValue.js";
5
6
  import { ok } from "../domain/result.js";
7
+ import { runDerivedOperation } from "./runDerivedOperation.js";
6
8
  import { BUNDLE_COMPARISON_PROVIDER } from "./sessionToolPolicies.js";
7
- import { toCallToolResult } from "./toolResult.js";
8
9
  import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
9
- import { runDerivedOperation } from "./runDerivedOperation.js";
10
- import { safeParseToolInput } from "./toolInputValidation.js";
10
+ import { toCallToolResult } from "./toolResult.js";
11
11
  /** Register canonical Evidence bundle comparison. */
12
12
  export const registerBundleComparisonTool = (server, session, contract, evidenceFilePolicy) => {
13
13
  server.registerTool(contract.name, toolRegistrationOptions(contract), async (input, context) => {
14
- const parsedInput = safeParseToolInput(bundleComparisonInputSchema, input, contract.name);
15
- if (!parsedInput.ok)
16
- return toCallToolResult(parsedInput, contract);
17
- const parsed = parsedInput.value;
18
14
  const [left, right] = await Promise.all([
19
- readEvidenceBundle(parsed.left_bundle_path, evidenceFilePolicy),
20
- readEvidenceBundle(parsed.right_bundle_path, evidenceFilePolicy),
15
+ readEvidenceBundle(input.left_bundle_path, evidenceFilePolicy),
16
+ readEvidenceBundle(input.right_bundle_path, evidenceFilePolicy),
21
17
  ]);
22
18
  if (!left.ok)
23
19
  return toCallToolResult(left, contract);
24
20
  if (!right.ok)
25
21
  return toCallToolResult(right, contract);
26
- const computed = await runDerivedOperation(context, contract.name, () => compareBundles(left.value, right.value, parsed.record_pairs, parsed.offset, parsed.limit));
22
+ const computed = await runDerivedOperation(context, contract.name, () => compareBundles(left.value, right.value, input.record_pairs, input.offset, input.limit));
27
23
  if (!computed.ok)
28
24
  return toCallToolResult(computed, contract);
29
25
  const comparison = computed.value;
@@ -33,9 +29,9 @@ export const registerBundleComparisonTool = (server, session, contract, evidence
33
29
  parameters: {
34
30
  left_bundle_sha256: comparison.left_bundle_sha256,
35
31
  right_bundle_sha256: comparison.right_bundle_sha256,
36
- record_pairs: parsed.record_pairs,
37
- offset: parsed.offset,
38
- limit: parsed.limit,
32
+ record_pairs: input.record_pairs,
33
+ offset: input.offset,
34
+ limit: input.limit,
39
35
  },
40
36
  result: jsonValueSchema.parse(comparison),
41
37
  confidence: "derived",
@@ -1,37 +1,30 @@
1
1
  import { writeAnalysisSnapshot } from "../application/AnalysisSnapshotFiles.js";
2
- import { closeBinaryInputSchema } from "../contracts/sessionLifecycleInputs.js";
3
2
  import { ok } from "../domain/result.js";
4
3
  import { reportLifecycleEnd, reportLifecycleStart, } from "./lifecycleProgress.js";
5
- import { logToolExecution } from "./toolLogging.js";
6
- import { toCallToolResult } from "./toolResult.js";
7
4
  import { mcpProgressReporter } from "./mcpProgress.js";
8
5
  import { permissionFailure } from "./permissionFailure.js";
9
- import { safeParseToolInput } from "./toolInputValidation.js";
6
+ import { logToolExecution } from "./toolLogging.js";
10
7
  import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
8
+ import { toCallToolResult } from "./toolResult.js";
11
9
  /** Register provider cleanup and optional pre-close snapshot persistence. */
12
10
  export const registerCloseLifecycleTool = ({ server, session, logger, contracts: [, closeContract], snapshotFilePolicy, permissionAuthority, }) => {
13
11
  server.registerTool(closeContract.name, toolRegistrationOptions(closeContract), async (input, context) => {
14
- const parsedInput = safeParseToolInput(closeBinaryInputSchema, input, closeContract.name);
15
- if (!parsedInput.ok)
16
- return toCallToolResult(parsedInput, closeContract);
17
- const parsed = parsedInput.value;
18
12
  const progress = mcpProgressReporter(context);
19
- if (parsed.snapshot_path === undefined) {
13
+ if (input.snapshot_path === undefined) {
20
14
  await reportLifecycleStart(progress, closeContract.name);
21
15
  const closed = await logToolExecution(logger, closeContract.name, () => session.close({ progress }));
22
16
  await reportLifecycleEnd(progress, closeContract.name, closed.ok);
23
- server.sendToolListChanged();
24
17
  return toCallToolResult(closed, closeContract);
25
18
  }
26
19
  if (permissionAuthority !== undefined) {
27
20
  const authorized = await permissionAuthority.authorize({
28
21
  capability: "snapshot_write",
29
- roots: [parsed.snapshot_path],
22
+ roots: [input.snapshot_path],
30
23
  executables: [],
31
24
  environment_names: [],
32
25
  network: "none",
33
26
  mount: false,
34
- operation_identity: `close_binary:snapshot:${parsed.snapshot_path}`,
27
+ operation_identity: `close_binary:snapshot:${input.snapshot_path}`,
35
28
  }, "write");
36
29
  if (!authorized.ok)
37
30
  return toCallToolResult(permissionFailure(authorized), closeContract);
@@ -39,13 +32,12 @@ export const registerCloseLifecycleTool = ({ server, session, logger, contracts:
39
32
  const snapshot = session.exportAnalysisSnapshot();
40
33
  if (!snapshot.ok)
41
34
  return toCallToolResult(snapshot, closeContract);
42
- const written = await writeAnalysisSnapshot(snapshot.value, parsed.snapshot_path, parsed.overwrite, snapshotFilePolicy);
35
+ const written = await writeAnalysisSnapshot(snapshot.value, input.snapshot_path, input.overwrite, snapshotFilePolicy);
43
36
  if (!written.ok)
44
37
  return toCallToolResult(written, closeContract);
45
38
  await reportLifecycleStart(progress, closeContract.name, "snapshot written; closing provider");
46
39
  const closed = await logToolExecution(logger, closeContract.name, () => session.close({ progress }));
47
40
  await reportLifecycleEnd(progress, closeContract.name, closed.ok);
48
- server.sendToolListChanged();
49
41
  return closed.ok
50
42
  ? toCallToolResult(ok({
51
43
  path: written.value.path,
@@ -1,63 +1,46 @@
1
+ import { captureElectronScenario } from "../application/ElectronActiveObservationService.js";
2
+ import { inspectElectronPage, listElectronTargets, } from "../application/ElectronObservationService.js";
1
3
  import { analyzeJavaScriptApplicationValidated } from "../application/JavaScriptApplicationService.js";
2
4
  import { reconcileJavaScriptRuntimeEvidenceValidated } from "../application/JavaScriptRuntimeReconciliationService.js";
3
- import { inspectElectronPage, listElectronTargets, } from "../application/ElectronObservationService.js";
4
- import { analyzeJavaScriptApplicationToolInputSchema, ELECTRON_TOOL_CONTRACTS, } from "../contracts/electronToolContracts.js";
5
- import { inspectElectronPageInputSchema, listElectronTargetsInputSchema, } from "../domain/electronObservation.js";
6
- import { reconcileJavaScriptRuntimeInputSchema } from "../domain/javascriptRuntimeReconciliationSchemas.js";
5
+ import { ELECTRON_TOOL_CONTRACTS } from "../contracts/electronToolContracts.js";
6
+ import { summarizeJavaScriptApplicationEvidence } from "./javascriptApplicationResult.js";
7
+ import { mcpProgressReporter } from "./mcpProgress.js";
7
8
  import { logToolExecution } from "./toolLogging.js";
8
- import { toCallToolResult } from "./toolResult.js";
9
9
  import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
10
- import { safeParseToolInput } from "./toolInputValidation.js";
11
- import { mcpProgressReporter } from "./mcpProgress.js";
12
- import { summarizeJavaScriptApplicationEvidence } from "./javascriptApplicationResult.js";
10
+ import { toCallToolResult } from "./toolResult.js";
13
11
  /** Register Electron tools even when provider or permission policy is absent. */
12
+ // oxlint-disable-next-line max-lines-per-function -- direct SDK calls retain each schema-handler type correlation.
14
13
  export const registerElectronTools = (server, options) => {
15
- const [listContract, inspectContract, analyzeContract, reconcileContract] = ELECTRON_TOOL_CONTRACTS;
16
- registerElectronTool(server, options, {
17
- contract: listContract,
18
- schema: listElectronTargetsInputSchema,
19
- execute: (parsed, { signal }) => listElectronTargets(options.electron, options.permissionAuthority, parsed, {
20
- signal,
21
- }),
22
- });
23
- registerElectronTool(server, options, {
24
- contract: inspectContract,
25
- schema: inspectElectronPageInputSchema,
26
- execute: (parsed, { signal, progress }) => inspectElectronPage(options.electron, options.permissionAuthority, parsed, {
27
- signal,
28
- progress,
29
- }),
30
- });
31
- registerElectronTool(server, options, {
32
- contract: analyzeContract,
33
- schema: analyzeJavaScriptApplicationToolInputSchema,
34
- execute: (parsed, { signal, progress }) => analyzeJavaScriptApplicationValidated(options.permissionAuthority, parsed, { signal, progress }),
14
+ const [listContract, inspectContract, analyzeContract, reconcileContract, activeContract,] = ELECTRON_TOOL_CONTRACTS;
15
+ server.registerTool(listContract.name, toolRegistrationOptions(listContract), (input, context) => runElectronTool(options, listContract, { input, context }, (parsed, { signal }) => listElectronTargets(options.electron, options.permissionAuthority, parsed, {
16
+ signal,
17
+ })));
18
+ server.registerTool(inspectContract.name, toolRegistrationOptions(inspectContract), (input, context) => runElectronTool(options, inspectContract, { input, context }, (parsed, { signal, progress }) => inspectElectronPage(options.electron, options.permissionAuthority, parsed, {
19
+ signal,
20
+ progress,
21
+ })));
22
+ server.registerTool(analyzeContract.name, toolRegistrationOptions(analyzeContract), (input, context) => runElectronTool(options, analyzeContract, {
23
+ input,
24
+ context,
35
25
  projectEvidence: (evidence, parsed) => {
36
26
  const summary = summarizeJavaScriptApplicationEvidence(evidence);
37
27
  return parsed.detail === "full"
38
28
  ? { structured: evidence.normalized_result, text: summary }
39
29
  : { structured: summary };
40
30
  },
41
- });
42
- registerElectronTool(server, options, {
43
- contract: reconcileContract,
44
- schema: reconcileJavaScriptRuntimeInputSchema,
45
- execute: (parsed, _context) => Promise.resolve(reconcileJavaScriptRuntimeEvidenceValidated(parsed)),
46
- });
31
+ }, (parsed, { signal, progress }) => analyzeJavaScriptApplicationValidated(options.permissionAuthority, parsed, { signal, progress })));
32
+ server.registerTool(reconcileContract.name, toolRegistrationOptions(reconcileContract), (input, context) => runElectronTool(options, reconcileContract, { input, context }, (parsed) => Promise.resolve(reconcileJavaScriptRuntimeEvidenceValidated(parsed))));
33
+ server.registerTool(activeContract.name, toolRegistrationOptions(activeContract), (input, context) => runElectronTool(options, activeContract, { input, context }, (parsed, { signal, progress }) => captureElectronScenario(options.electronActive, options.permissionAuthority, parsed, { signal, progress })));
47
34
  };
48
- const registerElectronTool = (server, options, spec) => {
49
- server.registerTool(spec.contract.name, toolRegistrationOptions(spec.contract), async (input, context) => {
50
- const parsedInput = safeParseToolInput(spec.schema, input, spec.contract.name);
51
- if (!parsedInput.ok)
52
- return toCallToolResult(parsedInput, spec.contract);
53
- const result = await logToolExecution(options.logger, spec.contract.name, () => spec.execute(parsedInput.value, {
54
- signal: context.mcpReq.signal,
55
- progress: mcpProgressReporter(context),
56
- }));
57
- if (!result.ok)
58
- return toCallToolResult(result, spec.contract);
59
- return evidenceResult(options, spec.contract, result.value, spec.projectEvidence?.(result.value, parsedInput.value));
60
- });
35
+ const runElectronTool = async (options, contract, request, execute) => {
36
+ const { input, context, projectEvidence } = request;
37
+ const result = await logToolExecution(options.logger, contract.name, () => execute(input, {
38
+ signal: context.mcpReq.signal,
39
+ progress: mcpProgressReporter(context),
40
+ }));
41
+ if (!result.ok)
42
+ return toCallToolResult(result, contract);
43
+ return evidenceResult(options, contract, result.value, projectEvidence?.(result.value, input));
61
44
  };
62
45
  const evidenceResult = (options, contract, evidence, projection) => {
63
46
  const recorded = options.recordEvidence?.(evidence);