rea-agents 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (246) hide show
  1. package/README.md +78 -32
  2. package/bridge/ghidra/ReaGhidraBridge.java +96 -11
  3. package/dist/application/ArtifactExtraction.js +1 -1
  4. package/dist/application/ArtifactInventory/classify.js +42 -0
  5. package/dist/application/ArtifactInventory/hash.js +43 -0
  6. package/dist/application/ArtifactInventory/reader.js +41 -0
  7. package/dist/application/ArtifactInventory/scanCanonical.js +155 -0
  8. package/dist/application/ArtifactInventory/scanReader.js +124 -0
  9. package/dist/application/ArtifactInventory/types.js +10 -0
  10. package/dist/application/ArtifactInventory.js +9 -351
  11. package/dist/application/AuthorizedArtifactInventory.js +2 -2
  12. package/dist/application/BinarySession.js +47 -270
  13. package/dist/application/BinarySessionExecution.js +28 -0
  14. package/dist/application/BinarySessionOpen.js +39 -0
  15. package/dist/application/BinarySessionRecords.js +149 -0
  16. package/dist/application/BinarySessionStatus.js +75 -0
  17. package/dist/application/CapabilityInventory.js +24 -2
  18. package/dist/application/ClientRegistrationStatus.js +1 -1
  19. package/dist/application/CrossVersionInventory.js +8 -2
  20. package/dist/application/CrossVersionInvestigation.js +1 -23
  21. package/dist/application/CrossVersionInvestigationCollections.js +23 -0
  22. package/dist/application/DirectAnalysis.js +47 -44
  23. package/dist/application/Doctor.js +156 -238
  24. package/dist/application/DoctorDiagnostics.js +180 -0
  25. package/dist/application/ElectronBoundaryAnalysis.js +23 -7
  26. package/dist/application/ElectronBoundaryGraphWindows.js +32 -8
  27. package/dist/application/EnhancedToolPagination.js +22 -0
  28. package/dist/application/EnhancedToolTypes.js +4 -0
  29. package/dist/application/EnhancedTools.js +20 -37
  30. package/dist/application/InstrumentedJavaScriptReplayHost.js +36 -0
  31. package/dist/application/InvestigationWorkspaceStore.js +24 -10
  32. package/dist/application/JavaScriptArtifactAnalysis.js +45 -6
  33. package/dist/application/JavaScriptArtifactFiles.js +6 -2
  34. package/dist/application/JavaScriptArtifactGraphBuilder.js +23 -1
  35. package/dist/application/JavaScriptArtifactGraphBundlers.js +225 -0
  36. package/dist/application/JavaScriptArtifactGraphContext.js +37 -36
  37. package/dist/application/JavaScriptArtifactGraphDocuments.js +27 -4
  38. package/dist/application/JavaScriptArtifactGraphFindings.js +54 -8
  39. package/dist/application/JavaScriptArtifactGraphStructure.js +29 -101
  40. package/dist/application/JavaScriptArtifactPathResolution.js +269 -0
  41. package/dist/application/JavaScriptArtifactReconstruction.js +1 -1
  42. package/dist/application/JavaScriptJsonModules.js +39 -0
  43. package/dist/application/JavaScriptModuleRelationships.js +262 -0
  44. package/dist/application/JavaScriptReplayPermission.js +16 -0
  45. package/dist/application/JavaScriptReplayService.js +182 -156
  46. package/dist/application/LinuxHopper.js +10 -0
  47. package/dist/application/MacHopper.js +22 -11
  48. package/dist/application/NodeRuntimeCharacterizationService.js +196 -0
  49. package/dist/application/PermissionAuthority.js +106 -63
  50. package/dist/application/ProcessCaptureCapability.js +1 -1
  51. package/dist/application/ProcessCapturePermission.js +13 -0
  52. package/dist/application/ProcessCli.js +2 -12
  53. package/dist/application/ProcessHarness.js +1 -1
  54. package/dist/application/ProjectPermissionStore.js +48 -9
  55. package/dist/application/RealHopperAssertions.js +76 -0
  56. package/dist/application/ReconstructionCoverageService.js +69 -0
  57. package/dist/application/ReconstructionCoverageWorkspaceStore.js +31 -0
  58. package/dist/application/RuntimeExecutableDiagnostics.js +172 -0
  59. package/dist/application/Setup.js +147 -259
  60. package/dist/application/SetupClientConfiguration.js +220 -0
  61. package/dist/application/SetupClients.js +24 -2
  62. package/dist/application/SetupPlan.js +123 -12
  63. package/dist/application/SetupSkill.js +26 -12
  64. package/dist/application/SupportedClients.js +1 -0
  65. package/dist/application/Uninstall.js +6 -3
  66. package/dist/application/WindowsCapabilities.js +86 -0
  67. package/dist/artifacts/AsarArtifactReader.js +11 -0
  68. package/dist/browser/BrowserProcessStartup.js +88 -0
  69. package/dist/browser/CdpCaptureDocuments.js +12 -8
  70. package/dist/browser/CdpCaptureEventBodyShapes.js +75 -0
  71. package/dist/browser/CdpCaptureEventHandlers.js +336 -0
  72. package/dist/browser/CdpCaptureEventHelpers.js +71 -0
  73. package/dist/browser/CdpCaptureEventState.js +1 -0
  74. package/dist/browser/CdpCaptureEventTypes.js +1 -0
  75. package/dist/browser/CdpCaptureEvents.js +29 -496
  76. package/dist/browser/CdpObservationSession.js +51 -8
  77. package/dist/browser/CdpPageCapture.js +12 -133
  78. package/dist/browser/CdpPageCaptureScripts.js +97 -0
  79. package/dist/browser/CdpPageCaptureWorkers.js +46 -0
  80. package/dist/browser/CdpWebMcpDiscovery.js +38 -14
  81. package/dist/browser/PngVisualDiff.js +9 -2
  82. package/dist/catalogIdentity.js +4 -0
  83. package/dist/cli/artifactCommands.js +82 -0
  84. package/dist/cli/coreAnalysisCommands.js +232 -0
  85. package/dist/cli/managedCommands.js +397 -0
  86. package/dist/cli/managedProjectGraphCommand.js +24 -0
  87. package/dist/cli/options.js +9 -0
  88. package/dist/cli/setupCommands.js +108 -0
  89. package/dist/cli/types.js +1 -0
  90. package/dist/cli/utilityCommands.js +122 -0
  91. package/dist/cli.js +10 -768
  92. package/dist/cliApplicationCommands.js +118 -4
  93. package/dist/cliBrowserAdvancedCommands.js +73 -16
  94. package/dist/cliBrowserCommands.js +39 -115
  95. package/dist/cliCommandNames.js +4 -0
  96. package/dist/cliElectronCommands.js +33 -62
  97. package/dist/cliEvidenceCommands.js +13 -2
  98. package/dist/cliInvestigationCommands.js +53 -10
  99. package/dist/cliObservationOptions.js +137 -0
  100. package/dist/cliPolicyCommands.js +80 -46
  101. package/dist/cliSetup.js +289 -0
  102. package/dist/config/environment.js +107 -0
  103. package/dist/config/parseConfig.js +228 -0
  104. package/dist/config/parsers.js +68 -0
  105. package/dist/config/permissions.js +30 -0
  106. package/dist/config/types.js +1 -0
  107. package/dist/config.js +1 -375
  108. package/dist/contracts/applicationToolContracts.js +134 -0
  109. package/dist/contracts/managedToolContracts.js +1 -1
  110. package/dist/contracts/managedWorkflowToolContracts.js +3 -3
  111. package/dist/contracts/providerSelection.js +2 -0
  112. package/dist/contracts/toolContracts.js +2 -2
  113. package/dist/contracts/toolEffects.js +14 -0
  114. package/dist/contracts/toolOutputSchemaGroups.js +232 -0
  115. package/dist/contracts/toolOutputSchemaPrimitives.js +327 -0
  116. package/dist/contracts/toolOutputSchemas.js +2 -550
  117. package/dist/domain/analysisErrorPresentation.js +234 -0
  118. package/dist/domain/analysisErrorProjection.js +284 -0
  119. package/dist/domain/artifactComparison.js +34 -15
  120. package/dist/domain/binaryTarget.js +87 -37
  121. package/dist/domain/browserObservation.js +1 -285
  122. package/dist/domain/browserObservationSchemas.js +286 -0
  123. package/dist/domain/electronStaticAnalysisBrowser.js +14 -2
  124. package/dist/domain/errors.js +4 -486
  125. package/dist/domain/functionComparison.js +4 -165
  126. package/dist/domain/functionComparisonDimensions.js +164 -0
  127. package/dist/domain/javascriptApplicationVersionItems.js +18 -6
  128. package/dist/domain/javascriptApplicationVersionKeys.js +8 -8
  129. package/dist/domain/javascriptExportInstrumentation.js +97 -0
  130. package/dist/domain/javascriptFeatureTraversal.js +19 -7
  131. package/dist/domain/javascriptRuntimeStaticCandidates.js +3 -1
  132. package/dist/domain/javascriptSemanticAnalysis.js +386 -0
  133. package/dist/domain/javascriptSemanticIr.js +30 -0
  134. package/dist/domain/javascriptSemanticProjection.js +366 -0
  135. package/dist/domain/javascriptSemanticState.js +40 -0
  136. package/dist/domain/javascriptSemanticTraversal.js +22 -0
  137. package/dist/domain/javascriptSemanticValues.js +352 -0
  138. package/dist/domain/javascriptStaticAnalysis.js +5 -221
  139. package/dist/domain/javascriptStaticAnalysisBundler.js +209 -0
  140. package/dist/domain/javascriptStaticAnalysisCalls.js +180 -0
  141. package/dist/domain/javascriptStaticAnalysisHelpers.js +71 -2
  142. package/dist/domain/knownPageCoverage.js +21 -0
  143. package/dist/domain/managedApplicationGraph.js +14 -364
  144. package/dist/domain/managedApplicationGraphCoverage.js +170 -0
  145. package/dist/domain/managedApplicationGraphNodeCoverage.js +6 -0
  146. package/dist/domain/managedApplicationGraphNodes.js +336 -0
  147. package/dist/domain/managedArtifact.js +16 -8
  148. package/dist/domain/managedMemberComparison.js +37 -391
  149. package/dist/domain/managedMemberComparisonCoverage.js +72 -0
  150. package/dist/domain/managedMemberComparisonMatch.js +356 -0
  151. package/dist/domain/managedNativeVerification.js +27 -389
  152. package/dist/domain/managedNativeVerificationMatch.js +272 -0
  153. package/dist/domain/managedNativeVerificationSchemas.js +141 -0
  154. package/dist/domain/managedReconstruction.js +82 -69
  155. package/dist/domain/managedRuntimeCorrelation.js +12 -3
  156. package/dist/domain/nodeRuntimeCharacterization.js +66 -0
  157. package/dist/domain/permissionPolicy.js +2 -0
  158. package/dist/domain/reconstructionCoverage.js +387 -0
  159. package/dist/domain/reconstructionCoverageEvaluation.js +212 -0
  160. package/dist/domain/reconstructionVerificationSchemas.js +8 -0
  161. package/dist/domain/runtimeCharacterization.js +85 -0
  162. package/dist/domain/webBundleAnalyzer.js +3 -409
  163. package/dist/domain/webBundleAnalyzerAst.js +77 -0
  164. package/dist/domain/webBundleAnalyzerInspection.js +307 -0
  165. package/dist/domain/webBundleAnalyzerResult.js +120 -0
  166. package/dist/dotnet/ManagedArtifactInspector.js +50 -29
  167. package/dist/dotnet/ManagedMemberInspector.js +51 -785
  168. package/dist/dotnet/ManagedMemberInspectorCore.js +297 -0
  169. package/dist/dotnet/ManagedMemberInstructionDecoder.js +427 -0
  170. package/dist/dotnet/ManagedMemberRows.js +120 -0
  171. package/dist/dotnet/ManagedMetadataInventory.js +42 -306
  172. package/dist/dotnet/ManagedMetadataInventoryRows.js +292 -0
  173. package/dist/dotnet/ManagedMetadataLayout.js +48 -111
  174. package/dist/dotnet/ManagedMetadataRowSizes.js +54 -0
  175. package/dist/dotnet/ManagedMethodBodyReader.js +143 -0
  176. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +311 -0
  177. package/dist/dotnet/ManagedNativeBoundaryInspector.js +102 -350
  178. package/dist/dotnet/ManagedPeReader.js +59 -28
  179. package/dist/generatedPackageMetadata.js +2 -2
  180. package/dist/ghidra/GhidraClient.js +76 -91
  181. package/dist/ghidra/GhidraClientStartup.js +29 -0
  182. package/dist/ghidra/GhidraClientWire.js +34 -0
  183. package/dist/ghidra/GhidraDefaults.js +1 -1
  184. package/dist/ghidra/GhidraDiagnostics.js +6 -1
  185. package/dist/ghidra/GhidraInstallation.js +20 -15
  186. package/dist/ghidra/GhidraLauncher.js +93 -29
  187. package/dist/ghidra/GhidraProvider.js +61 -161
  188. package/dist/ghidra/GhidraProviderCapabilities.js +173 -0
  189. package/dist/ghidra/GhidraSessionValues.js +2 -0
  190. package/dist/ghidra/GhidraSocketConnection.js +44 -7
  191. package/dist/ghidra/GhidraTargetSnapshot.js +30 -0
  192. package/dist/ghidra/GhidraTransport.js +71 -0
  193. package/dist/identity.js +3 -2
  194. package/dist/main/messages.js +5 -0
  195. package/dist/main/reload.js +49 -0
  196. package/dist/main/shutdown.js +25 -0
  197. package/dist/main/startup.js +14 -0
  198. package/dist/main/state.js +26 -0
  199. package/dist/main/transport.js +61 -0
  200. package/dist/main/types.js +1 -0
  201. package/dist/main.js +35 -146
  202. package/dist/process/PrivateRuntimeRoot.js +3 -2
  203. package/dist/process/ProcessOwnership.js +35 -0
  204. package/dist/process/ProviderProcess.js +2 -0
  205. package/dist/replay/JavaScriptReplayWorker.js +64 -50
  206. package/dist/replay/LinuxJavaScriptReplayRunner.js +173 -390
  207. package/dist/replay/LinuxJavaScriptReplaySandbox.js +140 -0
  208. package/dist/replay/ReplayOutcome.js +95 -0
  209. package/dist/replay/ReplayProcessLifecycle.js +71 -0
  210. package/dist/server/ProcessCaptureElicitation.js +157 -0
  211. package/dist/server/createServer.js +119 -54
  212. package/dist/server/registerApplicationTools/characterization.js +57 -0
  213. package/dist/server/registerApplicationTools/compareVersions.js +34 -0
  214. package/dist/server/registerApplicationTools/controlledReplay.js +38 -0
  215. package/dist/server/registerApplicationTools/coverage.js +84 -0
  216. package/dist/server/registerApplicationTools/helpers.js +42 -0
  217. package/dist/server/registerApplicationTools/traceFeature.js +26 -0
  218. package/dist/server/registerApplicationTools/types.js +1 -0
  219. package/dist/server/registerApplicationTools.js +10 -112
  220. package/dist/server/registerBrowserTools.js +59 -83
  221. package/dist/server/registerElectronTools.js +31 -46
  222. package/dist/server/registerEnhancedTools.js +34 -42
  223. package/dist/server/registerEvidenceResources.js +54 -0
  224. package/dist/server/registerInvestigationTools/helpers.js +74 -0
  225. package/dist/server/registerInvestigationTools/types.js +1 -0
  226. package/dist/server/registerInvestigationTools.js +83 -116
  227. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +65 -0
  228. package/dist/server/registerManagedWorkflowTools/contract.js +8 -0
  229. package/dist/server/registerManagedWorkflowTools/evidence.js +43 -0
  230. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +39 -0
  231. package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +39 -0
  232. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +52 -0
  233. package/dist/server/registerManagedWorkflowTools/types.js +1 -0
  234. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +75 -0
  235. package/dist/server/registerManagedWorkflowTools.js +10 -274
  236. package/dist/server/registerOfficialTools.js +73 -59
  237. package/dist/server/registerSessionRecordTools.js +137 -0
  238. package/dist/server/registerSessionStatusTool.js +2 -1
  239. package/dist/server/registerSessionTools.js +60 -164
  240. package/dist/server/sessionAvailabilityPolicy.js +10 -0
  241. package/dist/server/toolRegistrationOptions.js +101 -3
  242. package/dist/server/toolResult.js +5 -0
  243. package/package.json +10 -11
  244. package/skills/{rea-analysis → reverse-engineer-anything}/SKILL.md +20 -7
  245. package/scripts/prepare-node-pty.mjs +0 -35
  246. package/scripts/rebuild-native.mjs +0 -22
@@ -1,12 +1,11 @@
1
1
  import { z } from "zod";
2
- import { exportEvidenceBundleInputSchema, importEvidenceBundleInputSchema, listUnknownsInputSchema, SESSION_TOOL_CONTRACTS, verifyUnknownResolutionInputSchema, } from "../contracts/toolContracts.js";
2
+ import { SESSION_TOOL_CONTRACTS } from "../contracts/toolContracts.js";
3
3
  import { toCallToolResult } from "./toolResult.js";
4
4
  import { logToolExecution } from "./toolLogging.js";
5
5
  import { err, ok } from "../domain/result.js";
6
6
  import { processScenarioSchema } from "../domain/processCapture.js";
7
7
  import { captureProcessScenario } from "../application/ProcessHarness.js";
8
- import { recordUnknownInputSchema, updateUnknownInputSchema, } from "../domain/residualUnknown.js";
9
- import { readEvidenceBundle, writeEvidenceBundle, } from "../application/EvidenceBundleFiles.js";
8
+ import { processCapturePermissionRequest } from "../application/ProcessCapturePermission.js";
10
9
  import { readAnalysisSnapshot, writeAnalysisSnapshot, } from "../application/AnalysisSnapshotFiles.js";
11
10
  import { AnalysisProtocolError, PermissionRequiredError, UnknownRegistryError, } from "../domain/errors.js";
12
11
  import { DENY_EVIDENCE_FILE_POLICY, DENY_PROCESS_POLICY, } from "./sessionToolPolicies.js";
@@ -21,6 +20,10 @@ import { registerInvestigationTools } from "./registerInvestigationTools.js";
21
20
  import { closeBinaryInputSchema, openBinaryInputSchema, } from "../contracts/sessionLifecycleInputs.js";
22
21
  import { registerSessionStatusTool } from "./registerSessionStatusTool.js";
23
22
  import { mcpProgressReporter } from "./mcpProgress.js";
23
+ import { authorizeProcessCaptureWithElicitation, } from "./ProcessCaptureElicitation.js";
24
+ import { isInputRequiredResult } from "@modelcontextprotocol/server";
25
+ import { registerEvidenceTools, registerUnknownTools, } from "./registerSessionRecordTools.js";
26
+ import { sessionAvailabilityPolicy } from "./sessionAvailabilityPolicy.js";
24
27
  const permissionFailure = (failure) => {
25
28
  if (failure.ok)
26
29
  return err(new AnalysisProtocolError("Expected a denied permission"));
@@ -59,25 +62,19 @@ const recordProcessResidualUnknowns = (session, scenario, evidence, residuals) =
59
62
  }
60
63
  return ok(null);
61
64
  };
62
- const registerProcessTools = ({ server, session, logger, processPolicy, captureContract, permissionAuthority, }) => {
65
+ const registerProcessTools = ({ server, session, logger, processPolicy, captureContract, permissionAuthority, processCaptureElicitation, }) => {
63
66
  server.registerTool(captureContract.name, toolRegistrationOptions(captureContract), async (input, context) => {
64
67
  const parsedInput = safeParseToolInput(processScenarioSchema, input, captureContract.name);
65
68
  if (!parsedInput.ok)
66
69
  return toCallToolResult(parsedInput, captureContract);
67
70
  const scenario = parsedInput.value;
68
71
  if (permissionAuthority !== undefined) {
69
- const authorized = await permissionAuthority.authorize({
70
- capability: "process_capture",
71
- roots: [scenario.working_directory, ...scenario.filesystem_roots],
72
- executables: [scenario.executable],
73
- environment_names: [
74
- ...Object.keys(scenario.environment),
75
- ...scenario.inherit_environment,
76
- ],
77
- network: scenario.network_access === "host" ? "external" : "none",
78
- mount: false,
79
- operation_identity: `capture_process_scenario:${scenario.executable}`,
80
- }, "read");
72
+ const request = processCapturePermissionRequest(scenario);
73
+ const authorized = processCaptureElicitation === undefined
74
+ ? await permissionAuthority.authorize(request, "read")
75
+ : await authorizeProcessCaptureWithElicitation(permissionAuthority, request, context, processCaptureElicitation);
76
+ if (isInputRequiredResult(authorized))
77
+ return authorized;
81
78
  if (!authorized.ok)
82
79
  return toCallToolResult(permissionFailure(authorized), captureContract);
83
80
  }
@@ -108,111 +105,19 @@ const registerProcessTools = ({ server, session, logger, processPolicy, captureC
108
105
  return toCallToolResult(ok(evidence), captureContract);
109
106
  });
110
107
  };
111
- const registerEvidenceTools = ({ server, session, exportContract, importContract, filePolicy, permissionAuthority, }) => {
112
- server.registerTool(exportContract.name, toolRegistrationOptions(exportContract), async (input) => {
113
- const parsedInput = safeParseToolInput(exportEvidenceBundleInputSchema, input, exportContract.name);
114
- if (!parsedInput.ok)
115
- return toCallToolResult(parsedInput, exportContract);
116
- const parsed = parsedInput.value;
117
- const bundle = session.exportEvidenceBundle();
118
- if (parsed.path === undefined)
119
- return toCallToolResult(ok(bundle), exportContract);
120
- if (permissionAuthority !== undefined) {
121
- const authorized = await permissionAuthority.authorize({
122
- capability: "evidence_write",
123
- roots: [parsed.path],
124
- executables: [],
125
- environment_names: [],
126
- network: "none",
127
- mount: false,
128
- operation_identity: `export_evidence:${parsed.path}`,
129
- }, "write");
130
- if (!authorized.ok)
131
- return toCallToolResult(permissionFailure(authorized), exportContract);
132
- }
133
- const written = await writeEvidenceBundle(bundle, parsed.path, parsed.overwrite, filePolicy);
134
- return written.ok
135
- ? toCallToolResult(ok({
136
- path: written.value.path,
137
- bytes: written.value.bytes,
138
- records: bundle.records.length,
139
- }), exportContract)
140
- : toCallToolResult(written, exportContract);
141
- });
142
- server.registerTool(importContract.name, toolRegistrationOptions(importContract), async (input) => {
143
- const parsedInput = safeParseToolInput(importEvidenceBundleInputSchema, input, importContract.name);
144
- if (!parsedInput.ok)
145
- return toCallToolResult(parsedInput, importContract);
146
- const path = parsedInput.value.path;
147
- if (permissionAuthority !== undefined) {
148
- const authorized = await permissionAuthority.authorize({
149
- capability: "evidence_read",
150
- roots: [path],
151
- executables: [],
152
- environment_names: [],
153
- network: "none",
154
- mount: false,
155
- operation_identity: `import_evidence:${path}`,
156
- }, "read");
157
- if (!authorized.ok)
158
- return toCallToolResult(permissionFailure(authorized), importContract);
159
- }
160
- const loaded = await readEvidenceBundle(path, filePolicy);
161
- if (!loaded.ok)
162
- return toCallToolResult(loaded, importContract);
163
- const imported = session.importEvidenceBundle(loaded.value);
164
- if (imported.ok && imported.value > 0)
165
- server.sendResourceListChanged();
166
- return imported.ok
167
- ? toCallToolResult(ok({
168
- imported: imported.value,
169
- total: session.exportEvidenceBundle().records.length,
170
- }), importContract)
171
- : toCallToolResult(imported, importContract);
172
- });
173
- };
174
- const registerUnknownTools = ({ server, session, contracts: [listContract, recordContract, updateContract, verifyContract], }) => {
175
- server.registerTool(listContract.name, toolRegistrationOptions(listContract), (input) => {
176
- const parsedInput = safeParseToolInput(listUnknownsInputSchema, input, listContract.name);
177
- if (!parsedInput.ok)
178
- return toCallToolResult(parsedInput, listContract);
179
- const filters = parsedInput.value;
180
- return toCallToolResult(ok(session.listUnknowns({
181
- ...(filters.status === undefined ? {} : { status: filters.status }),
182
- ...(filters.severity === undefined
183
- ? {}
184
- : { severity: filters.severity }),
185
- ...(filters.domain === undefined ? {} : { domain: filters.domain }),
186
- })), listContract);
187
- });
188
- server.registerTool(recordContract.name, toolRegistrationOptions(recordContract), (input) => {
189
- const parsedInput = safeParseToolInput(recordUnknownInputSchema, input, recordContract.name);
190
- if (!parsedInput.ok)
191
- return toCallToolResult(parsedInput, recordContract);
192
- const recorded = session.recordUnknown(parsedInput.value);
193
- if (recorded.ok)
194
- server.sendResourceListChanged();
195
- return toCallToolResult(recorded, recordContract);
196
- });
197
- server.registerTool(updateContract.name, toolRegistrationOptions(updateContract), (input) => {
198
- const parsedInput = safeParseToolInput(updateUnknownInputSchema, input, updateContract.name);
199
- if (!parsedInput.ok)
200
- return toCallToolResult(parsedInput, updateContract);
201
- const updated = session.updateUnknown(parsedInput.value);
202
- if (updated.ok)
203
- server.sendResourceListChanged();
204
- return toCallToolResult(updated, updateContract);
205
- });
206
- server.registerTool(verifyContract.name, toolRegistrationOptions(verifyContract), (input) => {
207
- const parsedInput = safeParseToolInput(verifyUnknownResolutionInputSchema, input, verifyContract.name);
208
- if (!parsedInput.ok)
209
- return toCallToolResult(parsedInput, verifyContract);
210
- const unknownId = parsedInput.value.unknown_id;
211
- return toCallToolResult(session.verifyUnknownResolution(unknownId), verifyContract);
108
+ const registerLifecycleTools = (registration) => {
109
+ const { server, session, contracts, startedAt, availabilityPolicy } = registration;
110
+ registerOpenLifecycleTool(registration);
111
+ registerCloseLifecycleTool(registration);
112
+ registerSessionStatusTool({
113
+ server,
114
+ session,
115
+ contract: contracts[2],
116
+ startedAt,
117
+ availabilityPolicy,
212
118
  });
213
119
  };
214
- const registerLifecycleTools = ({ server, session, logger, contracts, snapshotFilePolicy, startedAt, availabilityPolicy, permissionAuthority, }) => {
215
- const [openContract, closeContract, statusContract] = contracts;
120
+ const registerOpenLifecycleTool = ({ server, session, logger, contracts: [openContract], snapshotFilePolicy, permissionAuthority, }) => {
216
121
  server.registerTool(openContract.name, toolRegistrationOptions(openContract), async (input, context) => {
217
122
  const parsedInput = safeParseToolInput(openBinaryInputSchema, input, openContract.name);
218
123
  if (!parsedInput.ok)
@@ -263,54 +168,55 @@ const registerLifecycleTools = ({ server, session, logger, contracts, snapshotFi
263
168
  }, openContract)
264
169
  : toCallToolResult(opened, openContract);
265
170
  });
171
+ };
172
+ const registerCloseLifecycleTool = ({ server, session, logger, contracts: [, closeContract], snapshotFilePolicy, permissionAuthority, }) => {
266
173
  server.registerTool(closeContract.name, toolRegistrationOptions(closeContract), async (input) => {
267
174
  const parsedInput = safeParseToolInput(closeBinaryInputSchema, input, closeContract.name);
268
175
  if (!parsedInput.ok)
269
176
  return toCallToolResult(parsedInput, closeContract);
270
177
  const parsed = parsedInput.value;
271
- if (parsed.snapshot_path !== undefined) {
272
- if (permissionAuthority !== undefined) {
273
- const authorized = await permissionAuthority.authorize({
274
- capability: "snapshot_write",
275
- roots: [parsed.snapshot_path],
276
- executables: [],
277
- environment_names: [],
278
- network: "none",
279
- mount: false,
280
- operation_identity: `close_binary:snapshot:${parsed.snapshot_path}`,
281
- }, "write");
282
- if (!authorized.ok)
283
- return toCallToolResult(permissionFailure(authorized), closeContract);
284
- }
285
- const snapshot = session.exportAnalysisSnapshot();
286
- if (!snapshot.ok)
287
- return toCallToolResult(snapshot, closeContract);
288
- const written = await writeAnalysisSnapshot(snapshot.value, parsed.snapshot_path, parsed.overwrite, snapshotFilePolicy);
289
- if (!written.ok)
290
- return toCallToolResult(written, closeContract);
178
+ if (parsed.snapshot_path === undefined) {
291
179
  const closed = await logToolExecution(logger, closeContract.name, () => session.close());
292
180
  if (closed.ok)
293
181
  server.sendToolListChanged();
294
- return closed.ok
295
- ? toCallToolResult(ok({
296
- path: written.value.path,
297
- bytes: written.value.bytes,
298
- entries: snapshot.value.entries.length,
299
- }), closeContract)
300
- : toCallToolResult(closed, closeContract);
182
+ return toCallToolResult(closed, closeContract);
301
183
  }
184
+ if (permissionAuthority !== undefined) {
185
+ const authorized = await permissionAuthority.authorize({
186
+ capability: "snapshot_write",
187
+ roots: [parsed.snapshot_path],
188
+ executables: [],
189
+ environment_names: [],
190
+ network: "none",
191
+ mount: false,
192
+ operation_identity: `close_binary:snapshot:${parsed.snapshot_path}`,
193
+ }, "write");
194
+ if (!authorized.ok)
195
+ return toCallToolResult(permissionFailure(authorized), closeContract);
196
+ }
197
+ const snapshot = session.exportAnalysisSnapshot();
198
+ if (!snapshot.ok)
199
+ return toCallToolResult(snapshot, closeContract);
200
+ const written = await writeAnalysisSnapshot(snapshot.value, parsed.snapshot_path, parsed.overwrite, snapshotFilePolicy);
201
+ if (!written.ok)
202
+ return toCallToolResult(written, closeContract);
302
203
  const closed = await logToolExecution(logger, closeContract.name, () => session.close());
303
204
  if (closed.ok)
304
205
  server.sendToolListChanged();
305
- return toCallToolResult(closed, closeContract);
206
+ return closed.ok
207
+ ? toCallToolResult(ok({
208
+ path: written.value.path,
209
+ bytes: written.value.bytes,
210
+ entries: snapshot.value.entries.length,
211
+ }), closeContract)
212
+ : toCallToolResult(closed, closeContract);
306
213
  });
307
- registerSessionStatusTool(server, session, statusContract, startedAt, availabilityPolicy);
308
214
  };
309
215
  export const registerSessionTools = (server, session, logger, options = {}) => {
310
216
  const processPolicy = options.processPolicy ?? DENY_PROCESS_POLICY;
311
217
  const evidenceFilePolicy = options.evidenceFilePolicy ?? DENY_EVIDENCE_FILE_POLICY;
312
218
  const analysisSnapshotFilePolicy = options.analysisSnapshotFilePolicy ?? DENY_EVIDENCE_FILE_POLICY;
313
- const [openContract, closeContract, statusContract, exportContract, importContract, captureContract, compareContract, compareArtifactsContract, compareFunctionsContract, compareBundlesContract, changedBehaviorContract, callPathContract, staticRuntimeContract, reconstructionContract, listUnknownContract, recordUnknownContract, updateUnknownContract, verifyUnknownContract,] = SESSION_TOOL_CONTRACTS;
219
+ const [openContract, closeContract, statusContract, exportContract, importContract, captureContract, compareContract, compareArtifactsContract, compareFunctionsContract, compareBundlesContract, changedBehaviorContract, callPathContract, staticRuntimeContract, reconstructionContract,] = SESSION_TOOL_CONTRACTS;
314
220
  registerLifecycleTools({
315
221
  server,
316
222
  session,
@@ -318,15 +224,7 @@ export const registerSessionTools = (server, session, logger, options = {}) => {
318
224
  contracts: [openContract, closeContract, statusContract],
319
225
  snapshotFilePolicy: analysisSnapshotFilePolicy,
320
226
  startedAt: options.startedAt ?? new Date().toISOString(),
321
- availabilityPolicy: options.availabilityPolicy ??
322
- (() => ({
323
- processCaptureEnabled: processPolicy.enabled,
324
- evidenceFileRoots: evidenceFilePolicy.roots.length,
325
- browserObservationEnabled: false,
326
- electronObservationEnabled: false,
327
- javascriptReplayEnabled: false,
328
- managedRuntimeEnabled: false,
329
- })),
227
+ availabilityPolicy: sessionAvailabilityPolicy(options.availabilityPolicy, processPolicy, evidenceFilePolicy),
330
228
  ...(options.permissionAuthority === undefined
331
229
  ? {}
332
230
  : { permissionAuthority: options.permissionAuthority }),
@@ -350,6 +248,9 @@ export const registerSessionTools = (server, session, logger, options = {}) => {
350
248
  ...(options.permissionAuthority === undefined
351
249
  ? {}
352
250
  : { permissionAuthority: options.permissionAuthority }),
251
+ ...(options.processCaptureElicitation === undefined
252
+ ? {}
253
+ : { processCaptureElicitation: options.processCaptureElicitation }),
353
254
  });
354
255
  registerProcessComparisonTool(server, session, compareContract);
355
256
  registerArtifactComparisonTool(server, session, compareArtifactsContract);
@@ -376,11 +277,6 @@ export const registerSessionTools = (server, session, logger, options = {}) => {
376
277
  registerUnknownTools({
377
278
  server,
378
279
  session,
379
- contracts: [
380
- listUnknownContract,
381
- recordUnknownContract,
382
- updateUnknownContract,
383
- verifyUnknownContract,
384
- ],
280
+ contracts: SESSION_TOOL_CONTRACTS,
385
281
  });
386
282
  };
@@ -0,0 +1,10 @@
1
+ /** Select configured availability reporting or the target-free defaults. */
2
+ export const sessionAvailabilityPolicy = (configured, processPolicy, evidenceFilePolicy) => configured ??
3
+ (() => ({
4
+ processCaptureEnabled: processPolicy.enabled,
5
+ evidenceFileRoots: evidenceFilePolicy.roots.length,
6
+ browserObservationEnabled: false,
7
+ electronObservationEnabled: false,
8
+ javascriptReplayEnabled: false,
9
+ managedRuntimeEnabled: false,
10
+ }));
@@ -32,8 +32,8 @@ const advertisedOutputSchema = (schema) => {
32
32
  "~standard": {
33
33
  ...standard,
34
34
  jsonSchema: {
35
- input: () => closeObjectSchemas(converter({ target: "draft-2020-12" })),
36
- output: () => closeObjectSchemas(converter({ target: "draft-2020-12" })),
35
+ input: () => describeRootProperties(closeObjectSchemas(converter({ target: "draft-2020-12" }))),
36
+ output: () => describeRootProperties(closeObjectSchemas(converter({ target: "draft-2020-12" }))),
37
37
  },
38
38
  },
39
39
  };
@@ -70,7 +70,7 @@ const describeProperties = (value) => Object.fromEntries(Object.entries(value).m
70
70
  isObject(schema) && typeof schema.description !== "string"
71
71
  ? {
72
72
  ...describeProperties(schema),
73
- description: property.replaceAll("_", " "),
73
+ description: fallbackPropertyDescription(property),
74
74
  }
75
75
  : describeValue(schema),
76
76
  ])),
@@ -81,4 +81,102 @@ const describeValue = (value) => {
81
81
  return value.map(describeValue);
82
82
  return isObject(value) ? describeProperties(value) : value;
83
83
  };
84
+ const describeRootProperties = (value) => {
85
+ const properties = value.properties;
86
+ if (!isObject(properties))
87
+ return { ...value };
88
+ return {
89
+ ...value,
90
+ properties: Object.fromEntries(Object.entries(properties).map(([property, schema]) => [
91
+ property,
92
+ isObject(schema) && typeof schema.description !== "string"
93
+ ? {
94
+ ...schema,
95
+ description: fallbackPropertyDescription(property),
96
+ }
97
+ : schema,
98
+ ])),
99
+ };
100
+ };
101
+ const PROPERTY_DESCRIPTIONS = {
102
+ addresses: "Ordered provider-normalized procedure addresses to analyze.",
103
+ approved: "Explicit operator approval to perform this operation.",
104
+ after: "The later or right-hand observation to compare.",
105
+ before: "The earlier or left-hand observation to compare.",
106
+ boundary_id: "Exact reconstruction boundary identifier to evaluate.",
107
+ case_sensitive: "Whether text matching distinguishes uppercase and lowercase.",
108
+ cdp_endpoint: "Approved literal loopback Chrome DevTools Protocol endpoint.",
109
+ comment: "Exact analyst comment text to write.",
110
+ comparisons: "Validated comparison Evidence records to aggregate.",
111
+ coverage: "Exact reconstruction-coverage commitment to verify.",
112
+ detail: "Requested response detail level.",
113
+ direction: "Direction in which to traverse or compare relationships.",
114
+ document: "Exact provider document or program identity.",
115
+ error: "Structured, caller-actionable error when the operation fails.",
116
+ evidence: "Evidence v2 record produced by this operation.",
117
+ evidence_id: "Stable identifier of the recorded Evidence v2 observation.",
118
+ evidence_uri: "Session resource URI for the recorded Evidence v2 observation.",
119
+ executable: "Approved absolute path of the executable to run.",
120
+ format: "Declared input artifact format.",
121
+ name: "Exact name used by this operation.",
122
+ pattern: "Text or bounded pattern used to filter matching results.",
123
+ phase: "Current plan or execution phase of the operation.",
124
+ plan: "Content-bound execution plan and its approval commitment.",
125
+ query: "Non-empty feature or text query to investigate.",
126
+ question: "Concrete unresolved question to retain for later investigation.",
127
+ result: "Primary structured result returned by this operation.",
128
+ left: "Left-hand input used for comparison or differential execution.",
129
+ limit: "Maximum number of results to return in this page.",
130
+ limits: "Bounded resource-consumption and result-size limits for this operation.",
131
+ mode: "Operation mode that selects the requested behavior.",
132
+ offset: "Zero-based index of the first result to return.",
133
+ overwrite: "Whether an existing destination may be replaced.",
134
+ path: "Local filesystem path used by this operation.",
135
+ provider_id: "Exact deep-analysis provider ID, or automatic selection when omitted.",
136
+ right: "Right-hand input used for comparison or differential execution.",
137
+ schema_version: "Version of this structured result schema.",
138
+ source_evidence: "Evidence records supporting the prepared source transformation.",
139
+ status: "Current lifecycle or verification status.",
140
+ summary: "Concise evidence-backed summary of the result.",
141
+ symbols: "Ordered bounded Swift symbols to demangle.",
142
+ target_id: "Exact authorized CDP target identifier.",
143
+ unknown_id: "Exact residual-unknown identifier.",
144
+ unknown_registry_approved: "Explicit approval to record bounded residual uncertainty in the session registry.",
145
+ workspace_path: "Approved local path of the persistent investigation workspace.",
146
+ };
147
+ const fallbackPropertyDescription = (property) => {
148
+ const explicit = PROPERTY_DESCRIPTIONS[property];
149
+ if (explicit !== undefined)
150
+ return explicit;
151
+ const words = property.replaceAll("_", " ");
152
+ if (property.endsWith("_approved"))
153
+ return `Explicit operator approval for ${words.slice(0, -9)}.`;
154
+ if (property.endsWith("_offset"))
155
+ return `Zero-based index of the first ${words.slice(0, -7)} to return.`;
156
+ if (property.endsWith("_limit"))
157
+ return `Maximum number of ${words.slice(0, -6)} entries to return.`;
158
+ if (property.startsWith("max_"))
159
+ return `Maximum permitted ${words.slice(4)} for this operation.`;
160
+ if (property.startsWith("include_"))
161
+ return `Whether to include ${words.slice(8)} in the result.`;
162
+ if (property.startsWith("expected_"))
163
+ return `Expected ${words.slice(9)} used to reject stale or mismatched input.`;
164
+ if (property.endsWith("_sha256"))
165
+ return `Exact SHA-256 digest of ${words.slice(0, -7)}.`;
166
+ if (property.endsWith("_evidence_id"))
167
+ return `Exact Evidence v2 identifier for the ${words.slice(0, -12)} observation.`;
168
+ if (property.endsWith("_evidence_ids"))
169
+ return `Ordered Evidence v2 identifiers for the ${words.slice(0, -13)} observations.`;
170
+ if (property.endsWith("_path"))
171
+ return `Local filesystem path for ${words.slice(0, -5)}.`;
172
+ if (property.endsWith("_uri"))
173
+ return `Canonical URI for ${words.slice(0, -4)}.`;
174
+ if (property.endsWith("_bytes"))
175
+ return `Bounded byte count for ${words.slice(0, -6)}.`;
176
+ if (property.endsWith("_root") || property.endsWith("_roots"))
177
+ return `Approved canonical filesystem ${words}.`;
178
+ if (property.startsWith("is_") || property.startsWith("has_"))
179
+ return `Whether ${words}.`;
180
+ return `Value for ${words}.`;
181
+ };
84
182
  const isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
@@ -45,6 +45,11 @@ const successResult = (value, contract, options) => {
45
45
  { type: "text", text: JSON.stringify(parsed.data) },
46
46
  ...evidenceResourceLinks(value, contract.kind === "session" ||
47
47
  options.evidenceResourcesAvailable === true),
48
+ ...(options.resourceLinks ?? []).map((resource) => ({
49
+ type: "resource_link",
50
+ ...resource,
51
+ mimeType: "application/json",
52
+ })),
48
53
  ],
49
54
  structuredContent: candidate,
50
55
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rea-agents",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Reverse engineer anything from your terminal or agent with one CLI and MCP server.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -30,7 +30,8 @@
30
30
  },
31
31
  "type": "module",
32
32
  "bin": {
33
- "rea": "scripts/rea.mjs"
33
+ "rea": "scripts/rea.mjs",
34
+ "rea-agents": "scripts/rea.mjs"
34
35
  },
35
36
  "engines": {
36
37
  "node": "^22.19.0 || >=24.11.0"
@@ -42,8 +43,6 @@
42
43
  "bridge/hopper_bridge.py",
43
44
  "bridge/ghidra/ReaGhidraBridge.java",
44
45
  "scripts/rea.mjs",
45
- "scripts/prepare-node-pty.mjs",
46
- "scripts/rebuild-native.mjs",
47
46
  "scripts/hopper-demo-x11.py",
48
47
  "skills",
49
48
  "README.md",
@@ -66,7 +65,6 @@
66
65
  "scan:todos": "node scripts/scan-todos.mjs",
67
66
  "start": "node scripts/rea.mjs mcp",
68
67
  "pretest": "npm run build",
69
- "postinstall": "node scripts/prepare-node-pty.mjs",
70
68
  "test": "vitest run",
71
69
  "pretest:coverage": "npm run build",
72
70
  "test:coverage": "vitest run --coverage.enabled --coverage.provider=v8",
@@ -75,6 +73,7 @@
75
73
  "typecheck": "tsc --noEmit",
76
74
  "verify:hopper": "npm run build && node scripts/verify-real-hopper.mjs",
77
75
  "verify:ghidra": "npm run build && node scripts/verify-real-ghidra.mjs",
76
+ "verify:ghidra:windows": "npm run build && npm run build:ghidra-windows-fixture && node scripts/verify-real-ghidra-windows.mjs",
78
77
  "verify:browser": "npm run build && node scripts/verify-real-browser.mjs",
79
78
  "verify:javascript-runtime": "npm run build && node scripts/verify-local-javascript-runtime.mjs",
80
79
  "verify:application-workflows": "npm run build && node scripts/verify-local-application-workflows.mjs",
@@ -83,8 +82,11 @@
83
82
  "verify:hopper:linux": "npm run build && node scripts/verify-real-hopper-linux.mjs",
84
83
  "verify:setup:linux": "npm run build && node scripts/verify-linux-setup-e2e.mjs",
85
84
  "build:fixtures": "node scripts/build-conformance-fixtures.mjs",
85
+ "build:ghidra-windows-fixture": "node scripts/create-ghidra-windows-fixture.mjs",
86
86
  "verify:fixtures": "npm run build:fixtures && node scripts/verify-conformance-fixtures.mjs",
87
87
  "verify:package": "npm run build && node scripts/verify-package.mjs",
88
+ "verify:package:windows": "npm run build && node scripts/verify-windows-package.mjs",
89
+ "probe:windows-capabilities": "npm run build && node scripts/windows-capabilities.mjs",
88
90
  "verify:published": "node scripts/verify-published-package.mjs",
89
91
  "config:print": "node scripts/print-mcp-config.mjs",
90
92
  "docs:generate": "npm run build && node scripts/generate-skill-metadata.mjs && node scripts/generate-product-catalog.mjs && typedoc && node scripts/generate-error-schema.mjs",
@@ -92,8 +94,7 @@
92
94
  "docs:error-schema": "npm run build && node scripts/generate-error-schema.mjs",
93
95
  "prepack": "npm run deps:check && node scripts/generate-skill-metadata.mjs --check",
94
96
  "prepublishOnly": "npm run deps:check && node scripts/generate-skill-metadata.mjs --check",
95
- "prepare": "npm run build && husky",
96
- "rebuild:native": "node scripts/rebuild-native.mjs"
97
+ "prepare": "npm run build && husky"
97
98
  },
98
99
  "lint-staged": {
99
100
  "*.{ts,mjs,json,md,yml,yaml}": "prettier --write",
@@ -102,8 +103,10 @@
102
103
  "dependencies": {
103
104
  "@babel/parser": "8.0.4",
104
105
  "@babel/types": "8.0.4",
106
+ "@clack/prompts": "1.7.0",
105
107
  "@electron/asar": "4.2.0",
106
108
  "@jridgewell/trace-mapping": "0.3.31",
109
+ "@lydell/node-pty": "1.1.0",
107
110
  "@modelcontextprotocol/server": "2.0.0-beta.4",
108
111
  "@xterm/addon-serialize": "0.14.0",
109
112
  "@xterm/headless": "6.0.0",
@@ -115,7 +118,6 @@
115
118
  "ignore": "7.0.6",
116
119
  "incur": "0.4.13",
117
120
  "isomorphic-git": "1.38.7",
118
- "node-pty": "1.1.0",
119
121
  "pino": "9.14.0",
120
122
  "plist": "5.0.0",
121
123
  "semver": "7.8.5",
@@ -141,8 +143,5 @@
141
143
  "typedoc": "0.28.20",
142
144
  "typescript": "5.9.3",
143
145
  "vitest": "4.1.10"
144
- },
145
- "allowScripts": {
146
- "node-pty@1.1.0": true
147
146
  }
148
147
  }
@@ -1,10 +1,10 @@
1
1
  ---
2
- name: rea-analysis
3
- description: Reverse engineer native, Electron/JavaScript, and web applications with REA. Connect static artifacts to passive runtime evidence, explain how features work, and build a version tailored to the user's project.
2
+ name: reverse-engineer-anything
3
+ description: Reverse engineer native, Electron/JavaScript, and web application artifacts or runtimes with REA. Connect static artifacts to passive runtime evidence, explain how features work, and build a version tailored to the user's project. Skip REA setup for ordinary source-repository architecture analysis.
4
4
  metadata:
5
- version: "20"
6
- tool_count: 91
7
- catalog_digest: "bdf382596e1a00ffc9d59de287b2ad647eeebe629c48a8f8cf158b300363ce53"
5
+ version: "22"
6
+ tool_count: 95
7
+ catalog_digest: "e0c341749f488a869b62ab9b48c9236c60c91317ac60c8427f12a830cb900ae0"
8
8
  ---
9
9
 
10
10
  # REA
@@ -95,15 +95,28 @@ literal approval and `evidence_write` authority after sandbox cleanup.
95
95
 
96
96
  Identify the app and what the user wants to understand or build. Do not ask for information they already provided.
97
97
 
98
+ First decide whether REA evidence is needed. When the complete source repository
99
+ is available and the request is ordinary source-level architecture, code-flow,
100
+ or implementation analysis, use normal repository tools and skip REA readiness,
101
+ setup, and binary-provider commands. Use REA only when the request needs evidence
102
+ from a binary, package, built artifact, decompilation, passive application
103
+ runtime, controlled replay, or comparison against behavior not established by
104
+ the available source. If the source is available but the requested claim still
105
+ depends on built or runtime behavior, explain that distinction and continue with
106
+ the relevant REA workflow.
107
+
98
108
  If the app is missing, ask which app they want to reverse engineer. If the app is known but the goal is unclear, ask what they want to understand or build, and offer to start with an overview. Never require the user to supply a program path, address, architecture, or reverse-engineering terminology.
99
109
 
100
110
  Notes is only a documentation example. Never select an app unless the user names it or confirms it.
101
111
 
102
112
  ## Ensure REA is ready
103
113
 
104
- 1. Run `npx -y rea-agents doctor`.
114
+ Run this section only after the request-routing decision establishes that REA
115
+ evidence is needed.
116
+
117
+ 1. Run `npx -y rea-agents@latest doctor`.
105
118
  2. If setup is needed, tell the user REA needs to install its local binary-analysis tools. Do not lead with implementation details or assume the user knows reverse-engineering products.
106
- 3. Before installing external software, obtain approval and identify what will be installed. If deeper analysis needs Hopper, describe it as REA's local analysis engine and note that it is a separate Mac app with its own license. Then run `npx -y rea-agents setup --yes`.
119
+ 3. Before installing external software, obtain approval and identify what will be installed. If deeper analysis needs Hopper, describe it as REA's local analysis engine and note that it is a separate Mac app with its own license. Then run `npx -y rea-agents@latest setup --yes`.
107
120
  4. If macOS or an installer requests human input, tell the user exactly what needs attention. After they finish, rerun setup and doctor.
108
121
  5. If setup registers a new MCP server, tell the user to restart their agent to load all REA tools. Direct CLI commands remain available before restart.
109
122
 
@@ -1,35 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { chmod, lstat } from "node:fs/promises";
4
- import { createRequire } from "node:module";
5
- import { dirname, join } from "node:path";
6
- import { fileURLToPath } from "node:url";
7
-
8
- if (process.platform !== "win32") {
9
- const require = createRequire(import.meta.url);
10
- const packageRoot = dirname(
11
- require.resolve("node-pty/package.json", {
12
- paths: [dirname(fileURLToPath(import.meta.url))],
13
- }),
14
- );
15
- const helperPath = join(
16
- packageRoot,
17
- "prebuilds",
18
- `${process.platform}-${process.arch}`,
19
- "spawn-helper",
20
- );
21
-
22
- try {
23
- const helper = await lstat(helperPath);
24
- if (!helper.isFile() || helper.isSymbolicLink()) {
25
- throw new Error("node-pty spawn helper is not a regular file");
26
- }
27
- await chmod(helperPath, helper.mode | 0o111);
28
- } catch (error) {
29
- if (error instanceof Error && "code" in error && error.code === "ENOENT") {
30
- // Source builds place their correctly-modeled helper under build/Release.
31
- } else {
32
- throw error;
33
- }
34
- }
35
- }
@@ -1,22 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { spawn } from "node:child_process";
4
-
5
- const npm = process.platform === "win32" ? "npm.cmd" : "npm";
6
- const child = spawn(npm, ["rebuild", "node-pty"], {
7
- stdio: "inherit",
8
- env: { ...process.env, npm_config_build_from_source: "true" },
9
- });
10
-
11
- child.once("error", (error) => {
12
- console.error(`Unable to rebuild node-pty: ${error.message}`);
13
- process.exitCode = 1;
14
- });
15
- child.once("exit", (code, signal) => {
16
- if (signal !== null) {
17
- console.error(`node-pty rebuild terminated by ${signal}`);
18
- process.exitCode = 1;
19
- return;
20
- }
21
- process.exitCode = code ?? 1;
22
- });