rea-agents 2.1.0 → 2.3.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 (193) hide show
  1. package/README.md +84 -18
  2. package/dist/application/AndroidApplicationService.js +17 -0
  3. package/dist/application/AppleApplicationService.js +17 -0
  4. package/dist/application/ApplicationWorkflowEvidenceResolver.js +162 -0
  5. package/dist/application/BinarySession.js +9 -2
  6. package/dist/application/BinarySessionStatus.js +39 -1
  7. package/dist/application/CapabilityInventory.js +15 -0
  8. package/dist/application/ClientRegistrationStatus.js +11 -4
  9. package/dist/application/CommandShimReplay.js +6 -3
  10. package/dist/application/CompositeProvider.js +5 -2
  11. package/dist/application/DirectAnalysis.js +1 -20
  12. package/dist/application/DirectAnalysisStatus.js +83 -0
  13. package/dist/application/Doctor.js +34 -25
  14. package/dist/application/DoctorDiagnostics.js +1 -4
  15. package/dist/application/DoctorProjection.js +43 -0
  16. package/dist/application/DoctorScope.js +102 -0
  17. package/dist/application/EvidenceReferenceResolver.js +26 -0
  18. package/dist/application/InventoryProjectionEvidence.js +41 -0
  19. package/dist/application/InvestigationProviders.js +12 -0
  20. package/dist/application/JavaScriptApplicationEvidence.js +1 -1
  21. package/dist/application/JavaScriptApplicationEvidenceGraph.js +10 -1
  22. package/dist/application/JavaScriptApplicationService.js +3 -2
  23. package/dist/application/JavaScriptApplicationWorkflowEvidence.js +26 -0
  24. package/dist/application/JavaScriptApplicationWorkflowService.js +49 -1
  25. package/dist/application/JavaScriptArtifactReconstruction.js +7 -0
  26. package/dist/application/JavaScriptModuleRelationships.js +25 -1
  27. package/dist/application/JavaScriptReturnShapeProjection.js +111 -0
  28. package/dist/application/JavaScriptSemanticGraphBuilder.js +294 -0
  29. package/dist/application/JavaScriptSemanticGraphConstruction.js +144 -0
  30. package/dist/application/JavaScriptSemanticGraphEvidence.js +86 -0
  31. package/dist/application/JavaScriptSemanticGraphFlowProjection.js +72 -0
  32. package/dist/application/JavaScriptSemanticGraphProjection.js +33 -0
  33. package/dist/application/JavaScriptSemanticTraceService.js +45 -0
  34. package/dist/application/LoopbackReplay.js +277 -133
  35. package/dist/application/LoopbackReplayRecorder.js +101 -0
  36. package/dist/application/PermissionAuthority.js +7 -3
  37. package/dist/application/ProcessCaptureJournal.js +95 -0
  38. package/dist/application/ProcessCaptureLifecycle.js +24 -13
  39. package/dist/application/ProcessCheckpoints.js +30 -4
  40. package/dist/application/ProcessCli.js +26 -4
  41. package/dist/application/ProcessHarness.js +20 -50
  42. package/dist/application/ProcessNormalization.js +3 -2
  43. package/dist/application/ProcessPairedExperiment.js +72 -0
  44. package/dist/application/ProcessReactiveCoordinator.js +218 -0
  45. package/dist/application/ProcessReactiveEffects.js +133 -0
  46. package/dist/application/ProcessReactiveObservations.js +20 -0
  47. package/dist/application/ProcessSampling.js +2 -0
  48. package/dist/application/SessionProviderRouter.js +7 -6
  49. package/dist/application/Setup.js +14 -13
  50. package/dist/application/SetupClientConfiguration.js +10 -6
  51. package/dist/application/SetupPlan.js +4 -3
  52. package/dist/application/SetupRegistrationEnvironment.js +12 -0
  53. package/dist/application/SetupSkill.js +44 -40
  54. package/dist/application/TerminalRenderer.js +3 -1
  55. package/dist/application/Uninstall.js +7 -1
  56. package/dist/application/Upgrade.js +16 -1
  57. package/dist/browser/CdpEndpoint.js +37 -4
  58. package/dist/catalogIdentity.js +16 -7
  59. package/dist/cli/coreAnalysisCommands.js +34 -2
  60. package/dist/cli/javascriptApplicationAnalysis.js +19 -0
  61. package/dist/cli/setupCommands.js +84 -30
  62. package/dist/cli/utilityCommands.js +10 -2
  63. package/dist/cliApplicationCommands.js +79 -16
  64. package/dist/cliCommandNames.js +3 -0
  65. package/dist/cliElectronCommands.js +23 -33
  66. package/dist/cliObservationOptions.js +1 -1
  67. package/dist/cliOutput.js +56 -0
  68. package/dist/cliProcessCommands.js +32 -1
  69. package/dist/cliSetup.js +55 -29
  70. package/dist/contracts/applicationToolContracts.js +54 -7
  71. package/dist/contracts/applicationWorkflowInputContracts.js +119 -0
  72. package/dist/contracts/electronToolContracts.js +73 -4
  73. package/dist/contracts/javascriptApplicationWorkflowExamples.js +32 -9
  74. package/dist/contracts/managedToolContracts.js +7 -2
  75. package/dist/contracts/processCaptureExample.js +1 -0
  76. package/dist/contracts/replayMachineExample.js +37 -0
  77. package/dist/contracts/sessionStatusContract.js +26 -0
  78. package/dist/contracts/toolContractExamples.js +2 -0
  79. package/dist/contracts/toolContractTypes.js +12 -1
  80. package/dist/contracts/toolContracts.js +8 -11
  81. package/dist/contracts/toolEffects.js +3 -0
  82. package/dist/contracts/toolOutputSchemaGroups.js +53 -9
  83. package/dist/contracts/toolOutputSchemaPrimitives.js +73 -32
  84. package/dist/doctorRuntime.js +41 -0
  85. package/dist/domain/analysisErrorPresentation.js +5 -3
  86. package/dist/domain/analysisErrorProjection.js +7 -1
  87. package/dist/domain/androidApplication.js +206 -0
  88. package/dist/domain/appleApplication.js +221 -0
  89. package/dist/domain/boundedCartesianProjection.js +15 -0
  90. package/dist/domain/changedBehavior.js +5 -4
  91. package/dist/domain/completionLedgerGeneration.js +190 -0
  92. package/dist/domain/errors.js +4 -2
  93. package/dist/domain/evidenceCompletionLedger.js +113 -0
  94. package/dist/domain/hopperStartupFailure.js +9 -0
  95. package/dist/domain/javascriptApplicationAnalysis.js +44 -2
  96. package/dist/domain/javascriptExportShapeComparison.js +145 -0
  97. package/dist/domain/javascriptExportShapeComparisonIdentity.js +11 -0
  98. package/dist/domain/javascriptExportShapeComparisonSchemas.js +277 -0
  99. package/dist/domain/javascriptExportShapeSelection.js +132 -0
  100. package/dist/domain/javascriptExportShapeVariants.js +272 -0
  101. package/dist/domain/javascriptRuntimeReconciliationParsing.js +2 -2
  102. package/dist/domain/javascriptSemanticAnalysis.js +17 -36
  103. package/dist/domain/javascriptSemanticCallResolution.js +129 -0
  104. package/dist/domain/javascriptSemanticCalls.js +269 -0
  105. package/dist/domain/javascriptSemanticGraph.js +356 -0
  106. package/dist/domain/javascriptSemanticGraphSchemas.js +329 -0
  107. package/dist/domain/javascriptSemanticGraphSerialization.js +23 -0
  108. package/dist/domain/javascriptSemanticIr.js +14 -1
  109. package/dist/domain/javascriptSemanticPrimitives.js +36 -0
  110. package/dist/domain/javascriptSemanticProjection.js +36 -4
  111. package/dist/domain/javascriptSemanticProvenance.js +29 -0
  112. package/dist/domain/javascriptSemanticQuery.js +294 -0
  113. package/dist/domain/javascriptSemanticQueryAssessment.js +74 -0
  114. package/dist/domain/javascriptSemanticQueryIdentity.js +86 -0
  115. package/dist/domain/javascriptSemanticQueryRelations.js +15 -0
  116. package/dist/domain/javascriptSemanticQuerySchemas.js +188 -0
  117. package/dist/domain/javascriptSemanticReturns.js +187 -0
  118. package/dist/domain/javascriptSemanticState.js +32 -0
  119. package/dist/domain/javascriptSemanticTraceSchemas.js +14 -0
  120. package/dist/domain/javascriptSemanticValues.js +54 -70
  121. package/dist/domain/processCapture.js +36 -0
  122. package/dist/domain/processCaptureValidation.js +101 -12
  123. package/dist/domain/processComparison.js +96 -24
  124. package/dist/domain/processObservation.js +153 -0
  125. package/dist/domain/processPairedExperiment.js +128 -0
  126. package/dist/domain/processReactiveCheckpointDataflow.js +32 -0
  127. package/dist/domain/processReactiveMatching.js +210 -0
  128. package/dist/domain/processReactiveRuntime.js +109 -0
  129. package/dist/domain/processReactiveScenario.js +361 -0
  130. package/dist/domain/processReactiveScenarioPreflight.js +120 -0
  131. package/dist/domain/processReactiveTransition.js +159 -0
  132. package/dist/domain/processScenario.js +12 -0
  133. package/dist/domain/processTraceComparison.js +43 -0
  134. package/dist/domain/processTraceDimensionProjection.js +50 -0
  135. package/dist/domain/processTraceEvaluation.js +312 -0
  136. package/dist/domain/processTraceSpecification.js +373 -0
  137. package/dist/domain/reconstructionVerification.js +5 -4
  138. package/dist/domain/replayMachine.js +332 -0
  139. package/dist/domain/replayMachineRun.js +216 -0
  140. package/dist/domain/replayMachineRuntime.js +294 -0
  141. package/dist/domain/runtimeIdentification.js +210 -0
  142. package/dist/domain/staticRuntimeCorrelation.js +4 -2
  143. package/dist/evaluation/CodexAgentEval.js +156 -0
  144. package/dist/generatedPackageMetadata.js +2 -2
  145. package/dist/ghidra/GhidraClient.js +13 -2
  146. package/dist/ghidra/GhidraDiagnostics.js +1 -0
  147. package/dist/ghidra/GhidraLauncher.js +7 -3
  148. package/dist/ghidra/GhidraProvider.js +8 -1
  149. package/dist/hopper/BridgeLauncher.js +56 -14
  150. package/dist/hopper/HopperClient.js +23 -10
  151. package/dist/hopper/HopperDiagnostics.js +14 -0
  152. package/dist/hopper/HopperProcessDiagnostic.js +14 -0
  153. package/dist/hopper/HopperProvider.js +8 -1
  154. package/dist/hopper/LinuxPrivateDisplayDiagnostic.js +72 -0
  155. package/dist/hopper/LinuxPrivateDisplayProbe.js +217 -0
  156. package/dist/identity.js +2 -1
  157. package/dist/main/transport.js +2 -0
  158. package/dist/mcpDoctor.js +310 -0
  159. package/dist/process/ProcessOwnership.js +200 -53
  160. package/dist/process/ProviderRunLineage.js +21 -0
  161. package/dist/server/createServer.js +8 -2
  162. package/dist/server/javascriptApplicationResult.js +106 -0
  163. package/dist/server/registerApplicationTools/characterization.js +3 -3
  164. package/dist/server/registerApplicationTools/compareExportShapes.js +37 -0
  165. package/dist/server/registerApplicationTools/compareVersions.js +12 -6
  166. package/dist/server/registerApplicationTools/controlledReplay.js +2 -2
  167. package/dist/server/registerApplicationTools/coverage.js +3 -3
  168. package/dist/server/registerApplicationTools/helpers.js +37 -25
  169. package/dist/server/registerApplicationTools/traceFeature.js +9 -5
  170. package/dist/server/registerApplicationTools/traceSemantics.js +30 -0
  171. package/dist/server/registerApplicationTools.js +4 -0
  172. package/dist/server/registerElectronTools.js +19 -5
  173. package/dist/server/registerEvidenceResources.js +7 -1
  174. package/dist/server/registerJavaScriptApplicationGraphResource.js +69 -0
  175. package/dist/server/registerManagedTools.js +18 -1
  176. package/dist/server/registerProcessComparisonTool.js +17 -7
  177. package/dist/server/registerReplayMachineTool.js +20 -0
  178. package/dist/server/registerSessionStatusTool.js +95 -25
  179. package/dist/server/registerSessionTools.js +12 -7
  180. package/dist/server/sessionAvailabilityPolicy.js +2 -1
  181. package/dist/server/toolResult.js +10 -4
  182. package/dist/serverIdentity.js +19 -0
  183. package/package.json +62 -29
  184. package/scripts/hopper-demo-x11.py +459 -61
  185. package/scripts/prepack.mjs +55 -0
  186. package/scripts/prepare.mjs +28 -0
  187. package/scripts/rea.mjs +26 -5
  188. package/skills/reverse-engineer-anything/SKILL.md +69 -228
  189. package/skills/reverse-engineer-anything/references/controlled-replay.md +12 -0
  190. package/skills/reverse-engineer-anything/references/evidence-workflows.md +33 -0
  191. package/skills/reverse-engineer-anything/references/javascript-applications.md +35 -0
  192. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +36 -0
  193. package/skills/reverse-engineer-anything/references/runtime-observation.md +24 -0
@@ -9,34 +9,46 @@ export const recordSources = (recordEvidence, sources) => {
9
9
  }
10
10
  return { ok: true, value: null };
11
11
  };
12
- export const recordResult = (options, contract, evidence, recordUnknown = false) => {
13
- const recorded = recordUnknown
14
- ? options.recordEvidenceWithUnknown?.(evidence, {
15
- approved: true,
16
- question: "Which application entities remain unmatched or ambiguous across these versions?",
17
- severity: "medium",
18
- domain: "application-version-comparison",
19
- supporting_evidence_ids: [evidence.evidence_id],
20
- contradicting_evidence_ids: [],
21
- required_authority: "shipped-artifact",
22
- required_confidence: "observed",
23
- required_environment: null,
24
- recommended_probes: [
25
- {
26
- operation: "analyze_javascript_application",
27
- rationale: "Repeat static reconstruction with complete artifacts and source maps when available.",
28
- },
29
- {
30
- operation: "reconcile_javascript_runtime",
31
- rationale: "Add approved passive runtime Evidence without promoting it to static fact.",
32
- },
33
- ],
34
- relationships: [],
35
- })
36
- : options.recordEvidence?.(evidence);
12
+ export const recordResult = (options, contract, evidence, unknownKind) => {
13
+ const recorded = unknownKind === undefined
14
+ ? options.recordEvidence?.(evidence)
15
+ : options.recordEvidenceWithUnknown?.(evidence, unknownRegistration(evidence, unknownKind));
37
16
  if (recorded !== undefined && !recorded.ok)
38
17
  return toCallToolResult(recorded, contract);
39
18
  return toCallToolResult({ ok: true, value: evidence }, contract, {
40
19
  evidenceResourcesAvailable: recorded !== undefined,
41
20
  });
42
21
  };
22
+ const unknownRegistration = (evidence, kind) => ({
23
+ approved: true,
24
+ question: kind === "application-version-comparison"
25
+ ? "Which application entities remain unmatched or ambiguous across these versions?"
26
+ : "Which selected JavaScript export return shapes remain dynamic, incomplete, or ambiguously paired?",
27
+ severity: "medium",
28
+ domain: kind,
29
+ supporting_evidence_ids: [evidence.evidence_id],
30
+ contradicting_evidence_ids: [],
31
+ required_authority: "shipped-artifact",
32
+ required_confidence: "observed",
33
+ required_environment: null,
34
+ recommended_probes: [
35
+ {
36
+ operation: "analyze_javascript_application",
37
+ rationale: "Repeat static reconstruction with complete artifacts and source maps when available.",
38
+ },
39
+ ...(kind === "application-version-comparison"
40
+ ? [
41
+ {
42
+ operation: "reconcile_javascript_runtime",
43
+ rationale: "Add approved passive runtime Evidence without promoting it to static fact.",
44
+ },
45
+ ]
46
+ : [
47
+ {
48
+ operation: "run_controlled_replay",
49
+ rationale: "Validate exact approved module behavior separately when runtime semantics are required.",
50
+ },
51
+ ]),
52
+ ],
53
+ relationships: [],
54
+ });
@@ -1,19 +1,23 @@
1
1
  import { traceApplicationFeatureEvidenceValidated } from "../../application/JavaScriptApplicationWorkflowService.js";
2
- import { APPLICATION_TOOL_CONTRACTS } from "../../contracts/applicationToolContracts.js";
3
- import { traceApplicationFeatureInputSchema } from "../../domain/javascriptFeatureTraceSchemas.js";
2
+ import { resolveTraceApplicationFeatureRequestValidated } from "../../application/ApplicationWorkflowEvidenceResolver.js";
3
+ import { applicationToolContract } from "../../contracts/applicationToolContracts.js";
4
+ import { traceApplicationFeatureRequestSchema } from "../../contracts/applicationWorkflowInputContracts.js";
4
5
  import { logToolExecution } from "../toolLogging.js";
5
6
  import { toCallToolResult } from "../toolResult.js";
6
7
  import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
7
8
  import { safeParseToolInput } from "../toolInputValidation.js";
8
9
  import { recordResult, recordSources } from "./helpers.js";
9
- const traceContract = APPLICATION_TOOL_CONTRACTS[0];
10
+ const traceContract = applicationToolContract("trace_application_feature");
10
11
  /** Register the provider-neutral JavaScript feature trace tool. */
11
12
  export const registerTraceFeatureTool = (server, options) => {
12
13
  server.registerTool(traceContract.name, toolRegistrationOptions(traceContract), async (input) => {
13
- const parsedInput = safeParseToolInput(traceApplicationFeatureInputSchema, input, traceContract.name);
14
+ const parsedInput = safeParseToolInput(traceApplicationFeatureRequestSchema, input, traceContract.name);
14
15
  if (!parsedInput.ok)
15
16
  return toCallToolResult(parsedInput, traceContract);
16
- const parsed = parsedInput.value;
17
+ const resolved = resolveTraceApplicationFeatureRequestValidated(parsedInput.value, options.evidenceLookup);
18
+ if (!resolved.ok)
19
+ return toCallToolResult(resolved, traceContract);
20
+ const parsed = resolved.value;
17
21
  const result = await logToolExecution(options.logger, traceContract.name, () => Promise.resolve(traceApplicationFeatureEvidenceValidated(parsed)));
18
22
  if (!result.ok)
19
23
  return toCallToolResult(result, traceContract);
@@ -0,0 +1,30 @@
1
+ import { resolveTraceJavaScriptSemanticsRequestValidated } from "../../application/ApplicationWorkflowEvidenceResolver.js";
2
+ import { traceJavaScriptSemanticsEvidenceValidated } from "../../application/JavaScriptSemanticTraceService.js";
3
+ import { applicationToolContract } from "../../contracts/applicationToolContracts.js";
4
+ import { traceJavaScriptSemanticsRequestSchema } from "../../contracts/applicationWorkflowInputContracts.js";
5
+ import { safeParseToolInput } from "../toolInputValidation.js";
6
+ import { logToolExecution } from "../toolLogging.js";
7
+ import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
8
+ import { toCallToolResult } from "../toolResult.js";
9
+ import { recordResult, recordSources } from "./helpers.js";
10
+ const contract = applicationToolContract("trace_javascript_semantics");
11
+ /** Register the bounded JavaScript semantic relation trace tool. */
12
+ export const registerTraceJavaScriptSemanticsTool = (server, options) => {
13
+ 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);
18
+ if (!resolved.ok)
19
+ return toCallToolResult(resolved, contract);
20
+ const result = await logToolExecution(options.logger, contract.name, () => Promise.resolve(traceJavaScriptSemanticsEvidenceValidated(resolved.value)));
21
+ if (!result.ok)
22
+ return toCallToolResult(result, contract);
23
+ const recorded = recordSources(options.recordEvidence, [
24
+ resolved.value.application,
25
+ ]);
26
+ if (!recorded.ok)
27
+ return toCallToolResult(recorded, contract);
28
+ return recordResult(options, contract, result.value);
29
+ });
30
+ };
@@ -1,12 +1,16 @@
1
1
  import { registerTraceFeatureTool } from "./registerApplicationTools/traceFeature.js";
2
+ import { registerTraceJavaScriptSemanticsTool } from "./registerApplicationTools/traceSemantics.js";
2
3
  import { registerCompareApplicationVersionsTool } from "./registerApplicationTools/compareVersions.js";
4
+ import { registerCompareJavaScriptExportShapesTool } from "./registerApplicationTools/compareExportShapes.js";
3
5
  import { registerControlledReplayTool } from "./registerApplicationTools/controlledReplay.js";
4
6
  import { registerCharacterizationTools } from "./registerApplicationTools/characterization.js";
5
7
  import { registerCoverageTools } from "./registerApplicationTools/coverage.js";
6
8
  /** Register provider-neutral JavaScript application graph workflows. */
7
9
  export const registerApplicationTools = (server, options) => {
8
10
  registerTraceFeatureTool(server, options);
11
+ registerTraceJavaScriptSemanticsTool(server, options);
9
12
  registerCompareApplicationVersionsTool(server, options);
13
+ registerCompareJavaScriptExportShapesTool(server, options);
10
14
  registerControlledReplayTool(server, options);
11
15
  registerCharacterizationTools(server, options);
12
16
  registerCoverageTools(server, options);
@@ -1,15 +1,15 @@
1
1
  import { analyzeJavaScriptApplicationValidated } from "../application/JavaScriptApplicationService.js";
2
2
  import { reconcileJavaScriptRuntimeEvidenceValidated } from "../application/JavaScriptRuntimeReconciliationService.js";
3
3
  import { inspectElectronPage, listElectronTargets, } from "../application/ElectronObservationService.js";
4
- import { ELECTRON_TOOL_CONTRACTS } from "../contracts/electronToolContracts.js";
4
+ import { analyzeJavaScriptApplicationToolInputSchema, ELECTRON_TOOL_CONTRACTS, } from "../contracts/electronToolContracts.js";
5
5
  import { inspectElectronPageInputSchema, listElectronTargetsInputSchema, } from "../domain/electronObservation.js";
6
- import { analyzeJavaScriptApplicationInputSchema } from "../domain/javascriptApplicationAnalysis.js";
7
6
  import { reconcileJavaScriptRuntimeInputSchema } from "../domain/javascriptRuntimeReconciliationSchemas.js";
8
7
  import { logToolExecution } from "./toolLogging.js";
9
8
  import { toCallToolResult } from "./toolResult.js";
10
9
  import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
11
10
  import { safeParseToolInput } from "./toolInputValidation.js";
12
11
  import { mcpProgressReporter } from "./mcpProgress.js";
12
+ import { summarizeJavaScriptApplicationEvidence } from "./javascriptApplicationResult.js";
13
13
  /** Register Electron tools even when provider or permission policy is absent. */
14
14
  export const registerElectronTools = (server, options) => {
15
15
  const [listContract, inspectContract, analyzeContract, reconcileContract] = ELECTRON_TOOL_CONTRACTS;
@@ -30,8 +30,14 @@ export const registerElectronTools = (server, options) => {
30
30
  });
31
31
  registerElectronTool(server, options, {
32
32
  contract: analyzeContract,
33
- schema: analyzeJavaScriptApplicationInputSchema,
33
+ schema: analyzeJavaScriptApplicationToolInputSchema,
34
34
  execute: (parsed, { signal, progress }) => analyzeJavaScriptApplicationValidated(options.permissionAuthority, parsed, { signal, progress }),
35
+ projectEvidence: (evidence, parsed) => {
36
+ const summary = summarizeJavaScriptApplicationEvidence(evidence);
37
+ return parsed.detail === "full"
38
+ ? { structured: evidence.normalized_result, text: summary }
39
+ : { structured: summary };
40
+ },
35
41
  });
36
42
  registerElectronTool(server, options, {
37
43
  contract: reconcileContract,
@@ -50,14 +56,22 @@ const registerElectronTool = (server, options, spec) => {
50
56
  }));
51
57
  if (!result.ok)
52
58
  return toCallToolResult(result, spec.contract);
53
- return evidenceResult(options, spec.contract, result.value);
59
+ return evidenceResult(options, spec.contract, result.value, spec.projectEvidence?.(result.value, parsedInput.value));
54
60
  });
55
61
  };
56
- const evidenceResult = (options, contract, evidence) => {
62
+ const evidenceResult = (options, contract, evidence, projection) => {
57
63
  const recorded = options.recordEvidence?.(evidence);
58
64
  return recorded !== undefined && !recorded.ok
59
65
  ? toCallToolResult(recorded, contract)
60
66
  : toCallToolResult({ ok: true, value: evidence }, contract, {
61
67
  evidenceResourcesAvailable: recorded !== undefined,
68
+ ...(projection === undefined
69
+ ? {}
70
+ : {
71
+ evidenceResultProjection: projection.structured,
72
+ ...(projection.text === undefined
73
+ ? {}
74
+ : { evidenceTextProjection: projection.text }),
75
+ }),
62
76
  });
63
77
  };
@@ -1,6 +1,7 @@
1
1
  import { ResourceNotFoundError, ResourceTemplate, } from "@modelcontextprotocol/server";
2
2
  import { createHash } from "node:crypto";
3
3
  import canonicalize from "canonicalize";
4
+ import { registerJavaScriptApplicationGraphResource } from "./registerJavaScriptApplicationGraphResource.js";
4
5
  const evidenceUri = (evidenceId) => `rea://evidence/${evidenceId}`;
5
6
  /** Expose immutable session-owned Evidence v2 records as MCP resources. */
6
7
  export const registerEvidenceResources = (server, session) => {
@@ -12,6 +13,7 @@ export const registerEvidenceResources = (server, session) => {
12
13
  registerArtifactPageResource(server, session);
13
14
  registerFunctionDossierResource(server, session);
14
15
  registerEvidenceSectionResource(server, session);
16
+ registerJavaScriptApplicationGraphResource(server, session);
15
17
  registerResidualUnknownResource(server, session);
16
18
  };
17
19
  const registerReconstructionCoverageResource = (server, session) => {
@@ -315,7 +317,11 @@ const evidenceSection = (result, section) => {
315
317
  if (section === "process")
316
318
  return pick(result, ["process_samples", "exit", "settlement", "cleanup"]);
317
319
  if (section === "protocol")
318
- return pick(result, ["protocol_events", "shim_events"]);
320
+ return pick(result, [
321
+ "protocol_events",
322
+ "replay_transitions",
323
+ "shim_events",
324
+ ]);
319
325
  const value = result[section];
320
326
  return value === undefined ? undefined : value;
321
327
  };
@@ -0,0 +1,69 @@
1
+ import { ResourceNotFoundError, ResourceTemplate, } from "@modelcontextprotocol/server";
2
+ import { javascriptApplicationAnalysisResultSchema } from "../domain/javascriptApplicationAnalysis.js";
3
+ /** Register deterministic pages over one authenticated JavaScript graph. */
4
+ export const registerJavaScriptApplicationGraphResource = (server, session) => {
5
+ server.registerResource("javascript-application-graph-page", new ResourceTemplate("rea://evidence/{evidenceId}/application-graph/{collection}/offset/{offset}/limit/{limit}", {
6
+ list: undefined,
7
+ complete: {
8
+ evidenceId: (prefix) => session
9
+ .exportEvidenceBundle()
10
+ .records.map(({ evidence_id }) => evidence_id)
11
+ .filter((evidenceId) => evidenceId.startsWith(prefix)),
12
+ collection: (prefix) => ["nodes", "edges"].filter((name) => name.startsWith(prefix)),
13
+ },
14
+ }), {
15
+ title: "JavaScript application graph page",
16
+ description: "One deterministic bounded node or edge page from authenticated JavaScript application Evidence.",
17
+ mimeType: "application/json",
18
+ }, (uri, variables) => {
19
+ const evidenceId = stringVariable(variables.evidenceId, uri.href);
20
+ const collection = stringVariable(variables.collection, uri.href);
21
+ if (collection !== "nodes" && collection !== "edges")
22
+ throw new ResourceNotFoundError(uri.href);
23
+ const offset = pageInteger(variables.offset, uri.href, 0, 100_000);
24
+ const limit = pageInteger(variables.limit, uri.href, 1, 500);
25
+ const evidence = session.evidenceById(evidenceId);
26
+ if (evidence === undefined ||
27
+ evidence.operation !== "analyze_javascript_application")
28
+ throw new ResourceNotFoundError(uri.href);
29
+ const analysis = javascriptApplicationAnalysisResultSchema.safeParse(evidence.normalized_result);
30
+ if (!analysis.success)
31
+ throw new ResourceNotFoundError(uri.href);
32
+ const values = analysis.data.graph[collection];
33
+ const items = values.slice(offset, offset + limit);
34
+ const nextOffset = offset + items.length;
35
+ return {
36
+ contents: [
37
+ {
38
+ uri: uri.href,
39
+ mimeType: "application/json",
40
+ text: JSON.stringify({
41
+ evidence_id: evidence.evidence_id,
42
+ graph_id: analysis.data.graph.graph_id,
43
+ collection,
44
+ items,
45
+ offset,
46
+ limit,
47
+ total: values.length,
48
+ next_offset: nextOffset < values.length ? nextOffset : null,
49
+ has_more: nextOffset < values.length,
50
+ }, null, 2),
51
+ },
52
+ ],
53
+ };
54
+ });
55
+ };
56
+ const stringVariable = (value, uri) => {
57
+ if (typeof value !== "string")
58
+ throw new ResourceNotFoundError(uri);
59
+ return value;
60
+ };
61
+ const pageInteger = (value, uri, minimum, maximum) => {
62
+ const text = stringVariable(value, uri);
63
+ if (!/^\d+$/u.test(text))
64
+ throw new ResourceNotFoundError(uri);
65
+ const parsed = Number(text);
66
+ if (!Number.isSafeInteger(parsed) || parsed < minimum || parsed > maximum)
67
+ throw new ResourceNotFoundError(uri);
68
+ return parsed;
69
+ };
@@ -1,6 +1,23 @@
1
1
  import { MANAGED_TOOL_CONTRACTS } from "../contracts/managedToolContracts.js";
2
+ import { err } from "../domain/result.js";
2
3
  import { registerEvidenceTools } from "./registerEvidenceTools.js";
3
4
  /** Register execution-free managed PE/CLI inspection. */
4
5
  export const registerManagedTools = (server, analysis, options) => {
5
- registerEvidenceTools(server, analysis, MANAGED_TOOL_CONTRACTS, options);
6
+ const targetAwareAnalysis = {
7
+ execute: async (operation, parameters, executionOptions) => {
8
+ const path = operation === "inspect_managed_artifact" &&
9
+ typeof parameters.path === "string"
10
+ ? parameters.path
11
+ : undefined;
12
+ if (path !== undefined && options.session !== undefined) {
13
+ const opened = await options.session.open(path, executionOptions?.signal === undefined
14
+ ? undefined
15
+ : { signal: executionOptions.signal });
16
+ if (!opened.ok)
17
+ return err(opened.error);
18
+ }
19
+ return analysis.execute(operation, parameters, executionOptions);
20
+ },
21
+ };
22
+ registerEvidenceTools(server, targetAwareAnalysis, MANAGED_TOOL_CONTRACTS, options);
6
23
  };
@@ -11,6 +11,11 @@ import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
11
11
  import { runDerivedOperation } from "./runDerivedOperation.js";
12
12
  import { safeParseToolInput } from "./toolInputValidation.js";
13
13
  import { resolveSessionEvidenceIds } from "./sessionEvidence.js";
14
+ const PROCESS_CAPTURE_EVIDENCE = {
15
+ operation: "capture_process_scenario",
16
+ predicate: "rea.process-capture/v4",
17
+ };
18
+ const sourceLocations = (left, right) => [...(left ?? []), ...(right ?? [])];
14
19
  /** Register deterministic process-capture comparison and contradiction tracking. */
15
20
  export const registerProcessComparisonTool = (server, session, contract, now = Date.now) => {
16
21
  server.registerTool(contract.name, toolRegistrationOptions(contract), async (input, context) => {
@@ -18,14 +23,10 @@ export const registerProcessComparisonTool = (server, session, contract, now = D
18
23
  if (!parsedInput.ok)
19
24
  return toCallToolResult(parsedInput, contract);
20
25
  const parsed = parsedInput.value;
21
- const expected = {
22
- operation: "capture_process_scenario",
23
- predicate: "rea.process-capture/v4",
24
- };
25
- const leftRecord = resolveSessionEvidenceIds(session, [parsed.left_evidence_id], expected);
26
+ const leftRecord = resolveSessionEvidenceIds(session, [parsed.left_evidence_id], PROCESS_CAPTURE_EVIDENCE);
26
27
  if (!leftRecord.ok)
27
28
  return toCallToolResult(leftRecord, contract);
28
- const rightRecord = resolveSessionEvidenceIds(session, [parsed.right_evidence_id], expected);
29
+ const rightRecord = resolveSessionEvidenceIds(session, [parsed.right_evidence_id], PROCESS_CAPTURE_EVIDENCE);
29
30
  if (!rightRecord.ok)
30
31
  return toCallToolResult(rightRecord, contract);
31
32
  let comparison;
@@ -38,6 +39,9 @@ export const registerProcessComparisonTool = (server, session, contract, now = D
38
39
  ...(parsed.max_capture_age_ms === undefined
39
40
  ? {}
40
41
  : { maxCaptureAgeMs: parsed.max_capture_age_ms }),
42
+ ...(parsed.trace_spec === undefined
43
+ ? {}
44
+ : { traceSpecification: parsed.trace_spec }),
41
45
  now,
42
46
  }));
43
47
  if (!computed.ok)
@@ -50,18 +54,24 @@ export const registerProcessComparisonTool = (server, session, contract, now = D
50
54
  : "Invalid Process Capture v4")), contract);
51
55
  }
52
56
  const evidence = createEvidence(undefined, PROCESS_PROVIDER, {
53
- predicateType: "rea.process-comparison/v3",
57
+ predicateType: parsed.trace_spec === undefined
58
+ ? "rea.process-comparison/v3"
59
+ : "rea.process-comparison/v4",
54
60
  operation: contract.name,
55
61
  parameters: {
56
62
  left_evidence_id: parsed.left_evidence_id,
57
63
  right_evidence_id: parsed.right_evidence_id,
58
64
  left_normalization: leftCapture.normalization,
59
65
  right_normalization: rightCapture.normalization,
66
+ ...(parsed.trace_spec === undefined
67
+ ? {}
68
+ : { trace_spec: jsonValueSchema.parse(parsed.trace_spec) }),
60
69
  },
61
70
  result: jsonValueSchema.parse(comparison),
62
71
  confidence: "derived",
63
72
  authority: "analyst-inference",
64
73
  limitations: comparison.limitations,
74
+ locations: sourceLocations(leftRecord.value[0]?.locations, rightRecord.value[0]?.locations),
65
75
  evidenceLinks: [parsed.left_evidence_id, parsed.right_evidence_id],
66
76
  });
67
77
  return toCallToolResult(recordDerivedEvidence(session, evidence, comparisonUnknownInput(parsed, comparison)), contract);
@@ -0,0 +1,20 @@
1
+ import { SESSION_TOOL_CONTRACTS } from "../contracts/toolContracts.js";
2
+ import { replayMachineRunInputSchema, runReplayMachine, } from "../domain/replayMachineRun.js";
3
+ import { ok } from "../domain/result.js";
4
+ import { safeParseToolInput } from "./toolInputValidation.js";
5
+ import { logToolExecution } from "./toolLogging.js";
6
+ import { toCallToolResult } from "./toolResult.js";
7
+ import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
8
+ const contract = SESSION_TOOL_CONTRACTS.find(({ name }) => name === "run_replay_machine");
9
+ if (contract === undefined)
10
+ throw new TypeError("Missing run_replay_machine tool contract");
11
+ /** Register direct execution-free finite replay-machine evaluation. */
12
+ export const registerReplayMachineTool = (server, logger) => {
13
+ server.registerTool(contract.name, toolRegistrationOptions(contract), async (input) => {
14
+ const parsed = safeParseToolInput(replayMachineRunInputSchema, input, contract.name);
15
+ if (!parsed.ok)
16
+ return toCallToolResult(parsed, contract);
17
+ const result = await logToolExecution(logger, contract.name, () => Promise.resolve(ok(runReplayMachine(parsed.value))));
18
+ return toCallToolResult(result, contract);
19
+ });
20
+ };
@@ -16,38 +16,108 @@ export const registerSessionStatusTool = (options) => {
16
16
  const client = server.server.getClientVersion();
17
17
  const clientCapabilities = server.server.getClientCapabilities();
18
18
  const status = session.status();
19
+ const statusObject = jsonObjectSchema.parse(status);
20
+ const toolAvailability = buildCapabilityInventory(status, availabilityPolicy());
21
+ const serverIdentity = createServerIdentity({
22
+ startedAt,
23
+ expected: {
24
+ ...(parsed.expected_package_version === undefined
25
+ ? {}
26
+ : { package_version: parsed.expected_package_version }),
27
+ ...(parsed.expected_catalog_digest === undefined
28
+ ? {}
29
+ : { catalog_digest: parsed.expected_catalog_digest }),
30
+ ...(parsed.expected_server_path === undefined
31
+ ? {}
32
+ : { server_path: parsed.expected_server_path }),
33
+ },
34
+ ...(client === undefined ? {} : { client }),
35
+ ...(server.server.getNegotiatedProtocolVersion() === undefined
36
+ ? {}
37
+ : {
38
+ protocolVersion: server.server.getNegotiatedProtocolVersion(),
39
+ }),
40
+ });
19
41
  return toCallToolResult({
20
42
  ok: true,
21
- value: {
22
- ...jsonObjectSchema.parse(status),
23
- tool_availability: buildCapabilityInventory(status, availabilityPolicy()),
24
- client_features: {
43
+ value: projectSessionStatus({
44
+ input: parsed,
45
+ status: statusObject,
46
+ toolAvailability,
47
+ serverIdentity,
48
+ clientFeatures: {
25
49
  elicitation_form: clientCapabilities?.elicitation?.form !== undefined,
26
50
  elicitation_url: clientCapabilities?.elicitation?.url !== undefined,
27
51
  roots: clientCapabilities?.roots !== undefined,
28
52
  sampling: clientCapabilities?.sampling !== undefined,
29
53
  },
30
- server_identity: createServerIdentity({
31
- startedAt,
32
- expected: {
33
- ...(parsed.expected_package_version === undefined
34
- ? {}
35
- : { package_version: parsed.expected_package_version }),
36
- ...(parsed.expected_catalog_digest === undefined
37
- ? {}
38
- : { catalog_digest: parsed.expected_catalog_digest }),
39
- ...(parsed.expected_server_path === undefined
40
- ? {}
41
- : { server_path: parsed.expected_server_path }),
42
- },
43
- ...(client === undefined ? {} : { client }),
44
- ...(server.server.getNegotiatedProtocolVersion() === undefined
45
- ? {}
46
- : {
47
- protocolVersion: server.server.getNegotiatedProtocolVersion(),
48
- }),
49
- }),
50
- },
54
+ }),
51
55
  }, contract);
52
56
  });
53
57
  };
58
+ const projectSessionStatus = (options) => {
59
+ if (options.input.detail === "full")
60
+ return jsonObjectSchema.parse({
61
+ view: "full",
62
+ ...options.status,
63
+ tool_availability: options.toolAvailability,
64
+ client_features: options.clientFeatures,
65
+ server_identity: options.serverIdentity,
66
+ });
67
+ const open = options.status.open === true;
68
+ const activeProvider = activeProviderFrom(options.status);
69
+ if (options.input.detail === "capabilities") {
70
+ const filtered = options.input.capability_family === undefined
71
+ ? options.toolAvailability
72
+ : options.toolAvailability.filter(({ surface }) => surface === options.input.capability_family);
73
+ const items = filtered.slice(options.input.cursor, options.input.cursor + options.input.limit);
74
+ const nextCursor = options.input.cursor + items.length;
75
+ return jsonObjectSchema.parse({
76
+ view: "capabilities",
77
+ open,
78
+ provider: options.status.provider,
79
+ active_provider: activeProvider,
80
+ capability_family: options.input.capability_family ?? null,
81
+ capabilities: {
82
+ items,
83
+ cursor: options.input.cursor,
84
+ limit: options.input.limit,
85
+ total: filtered.length,
86
+ next_cursor: nextCursor < filtered.length ? nextCursor : null,
87
+ has_more: nextCursor < filtered.length,
88
+ },
89
+ });
90
+ }
91
+ return jsonObjectSchema.parse({
92
+ view: "summary",
93
+ open,
94
+ provider: options.status.provider,
95
+ active_provider: activeProvider,
96
+ target: open ? targetFrom(options.status) : null,
97
+ alignment: options.serverIdentity.alignment,
98
+ recommended_actions: recommendedActions(open, options.serverIdentity.alignment.state),
99
+ });
100
+ };
101
+ const activeProviderFrom = (status) => {
102
+ const binding = jsonObjectSchema.safeParse(status.analysis_provider_binding);
103
+ return binding.success ? (binding.data.provider ?? null) : null;
104
+ };
105
+ const targetFrom = (status) => ({
106
+ path: status.path,
107
+ format: status.format,
108
+ kind: status.kind,
109
+ sha256: status.sha256,
110
+ architecture: status.architecture ?? null,
111
+ });
112
+ const recommendedActions = (open, alignment) => [
113
+ ...(alignment === "mcp_server_restart_required"
114
+ ? ["Restart the registered MCP server or client before continuing."]
115
+ : []),
116
+ ...(!open
117
+ ? [
118
+ "Route the supplied target directly: ASAR/JavaScript to analyze_javascript_application, packages to inventory_artifact, managed PE/CLI to inspect_managed_artifact, browser/Electron runtimes to their list-target tools, and native binaries to open_binary.",
119
+ ]
120
+ : [
121
+ "Continue from the active target with binary_overview or a bounded target-specific query.",
122
+ ]),
123
+ ];
@@ -23,7 +23,8 @@ import { mcpProgressReporter } from "./mcpProgress.js";
23
23
  import { authorizeProcessCaptureWithElicitation, } from "./ProcessCaptureElicitation.js";
24
24
  import { isInputRequiredResult } from "@modelcontextprotocol/server";
25
25
  import { registerEvidenceTools, registerUnknownTools, } from "./registerSessionRecordTools.js";
26
- import { sessionAvailabilityPolicy } from "./sessionAvailabilityPolicy.js";
26
+ import { registerReplayMachineTool } from "./registerReplayMachineTool.js";
27
+ import { sessionAvailabilityPolicy, } from "./sessionAvailabilityPolicy.js";
27
28
  const permissionFailure = (failure) => {
28
29
  if (failure.ok)
29
30
  return err(new AnalysisProtocolError("Expected a denied permission"));
@@ -212,6 +213,14 @@ const registerCloseLifecycleTool = ({ server, session, logger, contracts: [, clo
212
213
  : toCallToolResult(closed, closeContract);
213
214
  });
214
215
  };
216
+ const registerRecordAndReplayTools = (server, session, logger) => {
217
+ registerUnknownTools({
218
+ server,
219
+ session,
220
+ contracts: SESSION_TOOL_CONTRACTS,
221
+ });
222
+ registerReplayMachineTool(server, logger);
223
+ };
215
224
  export const registerSessionTools = (server, session, logger, options = {}) => {
216
225
  const processPolicy = options.processPolicy ?? DENY_PROCESS_POLICY;
217
226
  const evidenceFilePolicy = options.evidenceFilePolicy ?? DENY_EVIDENCE_FILE_POLICY;
@@ -224,7 +233,7 @@ export const registerSessionTools = (server, session, logger, options = {}) => {
224
233
  contracts: [openContract, closeContract, statusContract],
225
234
  snapshotFilePolicy: analysisSnapshotFilePolicy,
226
235
  startedAt: options.startedAt ?? new Date().toISOString(),
227
- availabilityPolicy: sessionAvailabilityPolicy(options.availabilityPolicy, processPolicy, evidenceFilePolicy),
236
+ availabilityPolicy: sessionAvailabilityPolicy(options.availabilityPolicy, processPolicy, evidenceFilePolicy, options.investigationInputRoots ?? []),
228
237
  ...(options.permissionAuthority === undefined
229
238
  ? {}
230
239
  : { permissionAuthority: options.permissionAuthority }),
@@ -274,9 +283,5 @@ export const registerSessionTools = (server, session, logger, options = {}) => {
274
283
  ? {}
275
284
  : { permissionAuthority: options.permissionAuthority }),
276
285
  });
277
- registerUnknownTools({
278
- server,
279
- session,
280
- contracts: SESSION_TOOL_CONTRACTS,
281
- });
286
+ registerRecordAndReplayTools(server, session, logger);
282
287
  };
@@ -1,8 +1,9 @@
1
1
  /** Select configured availability reporting or the target-free defaults. */
2
- export const sessionAvailabilityPolicy = (configured, processPolicy, evidenceFilePolicy) => configured ??
2
+ export const sessionAvailabilityPolicy = (configured, processPolicy, evidenceFilePolicy, investigationInputRoots) => configured ??
3
3
  (() => ({
4
4
  processCaptureEnabled: processPolicy.enabled,
5
5
  evidenceFileRoots: evidenceFilePolicy.roots.length,
6
+ investigationInputRoots: investigationInputRoots.length,
6
7
  browserObservationEnabled: false,
7
8
  electronObservationEnabled: false,
8
9
  javascriptReplayEnabled: false,
@@ -22,7 +22,7 @@ const errorResult = (error) => {
22
22
  };
23
23
  };
24
24
  const successResult = (value, contract, options) => {
25
- const candidate = compactEvidence(value) ??
25
+ const candidate = compactEvidence(value, options.evidenceResultProjection) ??
26
26
  (contract.kind === "session" ? { result: value } : value);
27
27
  const parsed = contract.outputSchema.safeParse(candidate);
28
28
  if (!parsed.success) {
@@ -42,7 +42,13 @@ const successResult = (value, contract, options) => {
42
42
  }
43
43
  return {
44
44
  content: [
45
- { type: "text", text: JSON.stringify(parsed.data) },
45
+ {
46
+ type: "text",
47
+ text: JSON.stringify(options.evidenceTextProjection === undefined
48
+ ? parsed.data
49
+ : (compactEvidence(value, options.evidenceTextProjection) ??
50
+ options.evidenceTextProjection)),
51
+ },
46
52
  ...evidenceResourceLinks(value, contract.kind === "session" ||
47
53
  options.evidenceResourcesAvailable === true),
48
54
  ...(options.resourceLinks ?? []).map((resource) => ({
@@ -54,7 +60,7 @@ const successResult = (value, contract, options) => {
54
60
  structuredContent: candidate,
55
61
  };
56
62
  };
57
- const compactEvidence = (value) => {
63
+ const compactEvidence = (value, resultProjection) => {
58
64
  if (typeof value !== "object" ||
59
65
  value === null ||
60
66
  Array.isArray(value) ||
@@ -63,7 +69,7 @@ const compactEvidence = (value) => {
63
69
  !("normalized_result" in value))
64
70
  return undefined;
65
71
  return {
66
- result: value.normalized_result,
72
+ result: resultProjection ?? value.normalized_result,
67
73
  evidence_id: value.evidence_id,
68
74
  evidence_uri: `rea://evidence/${value.evidence_id}`,
69
75
  };