rea-agents 2.0.0 → 2.2.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 (273) hide show
  1. package/README.md +103 -38
  2. package/bridge/ghidra/ReaGhidraBridge.java +96 -11
  3. package/dist/application/AndroidApplicationService.js +17 -0
  4. package/dist/application/AppleApplicationService.js +17 -0
  5. package/dist/application/ArtifactExtraction.js +1 -1
  6. package/dist/application/ArtifactInventory/classify.js +42 -0
  7. package/dist/application/ArtifactInventory/hash.js +43 -0
  8. package/dist/application/ArtifactInventory/reader.js +41 -0
  9. package/dist/application/ArtifactInventory/scanCanonical.js +155 -0
  10. package/dist/application/ArtifactInventory/scanReader.js +124 -0
  11. package/dist/application/ArtifactInventory/types.js +10 -0
  12. package/dist/application/ArtifactInventory.js +9 -351
  13. package/dist/application/AuthorizedArtifactInventory.js +2 -2
  14. package/dist/application/BinarySession.js +47 -270
  15. package/dist/application/BinarySessionExecution.js +28 -0
  16. package/dist/application/BinarySessionOpen.js +39 -0
  17. package/dist/application/BinarySessionRecords.js +149 -0
  18. package/dist/application/BinarySessionStatus.js +75 -0
  19. package/dist/application/CapabilityInventory.js +24 -2
  20. package/dist/application/ClientRegistrationStatus.js +11 -4
  21. package/dist/application/CrossVersionInventory.js +8 -2
  22. package/dist/application/CrossVersionInvestigation.js +1 -23
  23. package/dist/application/CrossVersionInvestigationCollections.js +23 -0
  24. package/dist/application/DirectAnalysis.js +47 -44
  25. package/dist/application/Doctor.js +156 -238
  26. package/dist/application/DoctorDiagnostics.js +180 -0
  27. package/dist/application/ElectronBoundaryAnalysis.js +23 -7
  28. package/dist/application/ElectronBoundaryGraphWindows.js +32 -8
  29. package/dist/application/EnhancedToolPagination.js +22 -0
  30. package/dist/application/EnhancedToolTypes.js +4 -0
  31. package/dist/application/EnhancedTools.js +20 -37
  32. package/dist/application/InstrumentedJavaScriptReplayHost.js +36 -0
  33. package/dist/application/InventoryProjectionEvidence.js +41 -0
  34. package/dist/application/InvestigationProviders.js +12 -0
  35. package/dist/application/InvestigationWorkspaceStore.js +24 -10
  36. package/dist/application/JavaScriptArtifactAnalysis.js +45 -6
  37. package/dist/application/JavaScriptArtifactFiles.js +6 -2
  38. package/dist/application/JavaScriptArtifactGraphBuilder.js +23 -1
  39. package/dist/application/JavaScriptArtifactGraphBundlers.js +225 -0
  40. package/dist/application/JavaScriptArtifactGraphContext.js +37 -36
  41. package/dist/application/JavaScriptArtifactGraphDocuments.js +27 -4
  42. package/dist/application/JavaScriptArtifactGraphFindings.js +54 -8
  43. package/dist/application/JavaScriptArtifactGraphStructure.js +29 -101
  44. package/dist/application/JavaScriptArtifactPathResolution.js +269 -0
  45. package/dist/application/JavaScriptArtifactReconstruction.js +1 -1
  46. package/dist/application/JavaScriptJsonModules.js +39 -0
  47. package/dist/application/JavaScriptModuleRelationships.js +262 -0
  48. package/dist/application/JavaScriptReplayPermission.js +16 -0
  49. package/dist/application/JavaScriptReplayService.js +182 -156
  50. package/dist/application/LinuxHopper.js +10 -0
  51. package/dist/application/MacHopper.js +22 -11
  52. package/dist/application/NodeRuntimeCharacterizationService.js +196 -0
  53. package/dist/application/PermissionAuthority.js +106 -63
  54. package/dist/application/ProcessCaptureCapability.js +1 -1
  55. package/dist/application/ProcessCapturePermission.js +13 -0
  56. package/dist/application/ProcessCli.js +2 -12
  57. package/dist/application/ProcessHarness.js +1 -1
  58. package/dist/application/ProcessPairedExperiment.js +72 -0
  59. package/dist/application/ProjectPermissionStore.js +48 -9
  60. package/dist/application/RealHopperAssertions.js +76 -0
  61. package/dist/application/ReconstructionCoverageService.js +69 -0
  62. package/dist/application/ReconstructionCoverageWorkspaceStore.js +31 -0
  63. package/dist/application/RuntimeExecutableDiagnostics.js +172 -0
  64. package/dist/application/Setup.js +148 -260
  65. package/dist/application/SetupClientConfiguration.js +224 -0
  66. package/dist/application/SetupClients.js +24 -2
  67. package/dist/application/SetupPlan.js +124 -12
  68. package/dist/application/SetupSkill.js +54 -36
  69. package/dist/application/SupportedClients.js +1 -0
  70. package/dist/application/Uninstall.js +12 -3
  71. package/dist/application/Upgrade.js +16 -1
  72. package/dist/application/WindowsCapabilities.js +86 -0
  73. package/dist/artifacts/AsarArtifactReader.js +11 -0
  74. package/dist/browser/BrowserProcessStartup.js +88 -0
  75. package/dist/browser/CdpCaptureDocuments.js +12 -8
  76. package/dist/browser/CdpCaptureEventBodyShapes.js +75 -0
  77. package/dist/browser/CdpCaptureEventHandlers.js +336 -0
  78. package/dist/browser/CdpCaptureEventHelpers.js +71 -0
  79. package/dist/browser/CdpCaptureEventState.js +1 -0
  80. package/dist/browser/CdpCaptureEventTypes.js +1 -0
  81. package/dist/browser/CdpCaptureEvents.js +29 -496
  82. package/dist/browser/CdpObservationSession.js +51 -8
  83. package/dist/browser/CdpPageCapture.js +12 -133
  84. package/dist/browser/CdpPageCaptureScripts.js +97 -0
  85. package/dist/browser/CdpPageCaptureWorkers.js +46 -0
  86. package/dist/browser/CdpWebMcpDiscovery.js +38 -14
  87. package/dist/browser/PngVisualDiff.js +9 -2
  88. package/dist/catalogIdentity.js +4 -0
  89. package/dist/cli/artifactCommands.js +82 -0
  90. package/dist/cli/coreAnalysisCommands.js +232 -0
  91. package/dist/cli/managedCommands.js +397 -0
  92. package/dist/cli/managedProjectGraphCommand.js +24 -0
  93. package/dist/cli/options.js +9 -0
  94. package/dist/cli/setupCommands.js +113 -0
  95. package/dist/cli/types.js +1 -0
  96. package/dist/cli/utilityCommands.js +122 -0
  97. package/dist/cli.js +10 -768
  98. package/dist/cliApplicationCommands.js +118 -4
  99. package/dist/cliBrowserAdvancedCommands.js +73 -16
  100. package/dist/cliBrowserCommands.js +39 -115
  101. package/dist/cliCommandNames.js +4 -0
  102. package/dist/cliElectronCommands.js +33 -62
  103. package/dist/cliEvidenceCommands.js +13 -2
  104. package/dist/cliInvestigationCommands.js +53 -10
  105. package/dist/cliObservationOptions.js +137 -0
  106. package/dist/cliPolicyCommands.js +80 -46
  107. package/dist/cliSetup.js +306 -0
  108. package/dist/config/environment.js +107 -0
  109. package/dist/config/parseConfig.js +228 -0
  110. package/dist/config/parsers.js +68 -0
  111. package/dist/config/permissions.js +30 -0
  112. package/dist/config/types.js +1 -0
  113. package/dist/config.js +1 -375
  114. package/dist/contracts/applicationToolContracts.js +134 -0
  115. package/dist/contracts/electronToolContracts.js +51 -3
  116. package/dist/contracts/managedToolContracts.js +8 -3
  117. package/dist/contracts/managedWorkflowToolContracts.js +3 -3
  118. package/dist/contracts/providerSelection.js +2 -0
  119. package/dist/contracts/sessionStatusContract.js +26 -0
  120. package/dist/contracts/toolContractTypes.js +12 -1
  121. package/dist/contracts/toolContracts.js +5 -12
  122. package/dist/contracts/toolEffects.js +14 -0
  123. package/dist/contracts/toolOutputSchemaGroups.js +274 -0
  124. package/dist/contracts/toolOutputSchemaPrimitives.js +328 -0
  125. package/dist/contracts/toolOutputSchemas.js +2 -550
  126. package/dist/domain/analysisErrorPresentation.js +234 -0
  127. package/dist/domain/analysisErrorProjection.js +284 -0
  128. package/dist/domain/androidApplication.js +206 -0
  129. package/dist/domain/appleApplication.js +221 -0
  130. package/dist/domain/artifactComparison.js +34 -15
  131. package/dist/domain/binaryTarget.js +87 -37
  132. package/dist/domain/boundedCartesianProjection.js +15 -0
  133. package/dist/domain/browserObservation.js +1 -285
  134. package/dist/domain/browserObservationSchemas.js +286 -0
  135. package/dist/domain/electronStaticAnalysisBrowser.js +14 -2
  136. package/dist/domain/errors.js +4 -486
  137. package/dist/domain/functionComparison.js +4 -165
  138. package/dist/domain/functionComparisonDimensions.js +164 -0
  139. package/dist/domain/javascriptApplicationVersionItems.js +18 -6
  140. package/dist/domain/javascriptApplicationVersionKeys.js +8 -8
  141. package/dist/domain/javascriptExportInstrumentation.js +97 -0
  142. package/dist/domain/javascriptFeatureTraversal.js +19 -7
  143. package/dist/domain/javascriptRuntimeStaticCandidates.js +3 -1
  144. package/dist/domain/javascriptSemanticAnalysis.js +386 -0
  145. package/dist/domain/javascriptSemanticIr.js +30 -0
  146. package/dist/domain/javascriptSemanticProjection.js +366 -0
  147. package/dist/domain/javascriptSemanticState.js +40 -0
  148. package/dist/domain/javascriptSemanticTraversal.js +22 -0
  149. package/dist/domain/javascriptSemanticValues.js +352 -0
  150. package/dist/domain/javascriptStaticAnalysis.js +5 -221
  151. package/dist/domain/javascriptStaticAnalysisBundler.js +209 -0
  152. package/dist/domain/javascriptStaticAnalysisCalls.js +180 -0
  153. package/dist/domain/javascriptStaticAnalysisHelpers.js +71 -2
  154. package/dist/domain/knownPageCoverage.js +21 -0
  155. package/dist/domain/managedApplicationGraph.js +14 -364
  156. package/dist/domain/managedApplicationGraphCoverage.js +170 -0
  157. package/dist/domain/managedApplicationGraphNodeCoverage.js +6 -0
  158. package/dist/domain/managedApplicationGraphNodes.js +336 -0
  159. package/dist/domain/managedArtifact.js +16 -8
  160. package/dist/domain/managedMemberComparison.js +37 -391
  161. package/dist/domain/managedMemberComparisonCoverage.js +72 -0
  162. package/dist/domain/managedMemberComparisonMatch.js +356 -0
  163. package/dist/domain/managedNativeVerification.js +27 -389
  164. package/dist/domain/managedNativeVerificationMatch.js +272 -0
  165. package/dist/domain/managedNativeVerificationSchemas.js +141 -0
  166. package/dist/domain/managedReconstruction.js +82 -69
  167. package/dist/domain/managedRuntimeCorrelation.js +12 -3
  168. package/dist/domain/nodeRuntimeCharacterization.js +66 -0
  169. package/dist/domain/permissionPolicy.js +2 -0
  170. package/dist/domain/processComparison.js +19 -0
  171. package/dist/domain/processPairedExperiment.js +128 -0
  172. package/dist/domain/reconstructionCoverage.js +387 -0
  173. package/dist/domain/reconstructionCoverageEvaluation.js +212 -0
  174. package/dist/domain/reconstructionVerificationSchemas.js +8 -0
  175. package/dist/domain/replayMachine.js +316 -0
  176. package/dist/domain/replayMachineRuntime.js +215 -0
  177. package/dist/domain/runtimeCharacterization.js +85 -0
  178. package/dist/domain/runtimeIdentification.js +210 -0
  179. package/dist/domain/webBundleAnalyzer.js +3 -409
  180. package/dist/domain/webBundleAnalyzerAst.js +77 -0
  181. package/dist/domain/webBundleAnalyzerInspection.js +307 -0
  182. package/dist/domain/webBundleAnalyzerResult.js +120 -0
  183. package/dist/dotnet/ManagedArtifactInspector.js +50 -29
  184. package/dist/dotnet/ManagedMemberInspector.js +51 -785
  185. package/dist/dotnet/ManagedMemberInspectorCore.js +297 -0
  186. package/dist/dotnet/ManagedMemberInstructionDecoder.js +427 -0
  187. package/dist/dotnet/ManagedMemberRows.js +120 -0
  188. package/dist/dotnet/ManagedMetadataInventory.js +42 -306
  189. package/dist/dotnet/ManagedMetadataInventoryRows.js +292 -0
  190. package/dist/dotnet/ManagedMetadataLayout.js +48 -111
  191. package/dist/dotnet/ManagedMetadataRowSizes.js +54 -0
  192. package/dist/dotnet/ManagedMethodBodyReader.js +143 -0
  193. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +311 -0
  194. package/dist/dotnet/ManagedNativeBoundaryInspector.js +102 -350
  195. package/dist/dotnet/ManagedPeReader.js +59 -28
  196. package/dist/evaluation/CodexAgentEval.js +132 -0
  197. package/dist/generatedPackageMetadata.js +2 -2
  198. package/dist/ghidra/GhidraClient.js +76 -91
  199. package/dist/ghidra/GhidraClientStartup.js +29 -0
  200. package/dist/ghidra/GhidraClientWire.js +34 -0
  201. package/dist/ghidra/GhidraDefaults.js +1 -1
  202. package/dist/ghidra/GhidraDiagnostics.js +6 -1
  203. package/dist/ghidra/GhidraInstallation.js +20 -15
  204. package/dist/ghidra/GhidraLauncher.js +93 -29
  205. package/dist/ghidra/GhidraProvider.js +61 -161
  206. package/dist/ghidra/GhidraProviderCapabilities.js +173 -0
  207. package/dist/ghidra/GhidraSessionValues.js +2 -0
  208. package/dist/ghidra/GhidraSocketConnection.js +44 -7
  209. package/dist/ghidra/GhidraTargetSnapshot.js +30 -0
  210. package/dist/ghidra/GhidraTransport.js +71 -0
  211. package/dist/identity.js +4 -2
  212. package/dist/main/messages.js +5 -0
  213. package/dist/main/reload.js +49 -0
  214. package/dist/main/shutdown.js +25 -0
  215. package/dist/main/startup.js +14 -0
  216. package/dist/main/state.js +26 -0
  217. package/dist/main/transport.js +61 -0
  218. package/dist/main/types.js +1 -0
  219. package/dist/main.js +35 -146
  220. package/dist/process/PrivateRuntimeRoot.js +3 -2
  221. package/dist/process/ProcessOwnership.js +35 -0
  222. package/dist/process/ProviderProcess.js +2 -0
  223. package/dist/replay/JavaScriptReplayWorker.js +64 -50
  224. package/dist/replay/LinuxJavaScriptReplayRunner.js +173 -390
  225. package/dist/replay/LinuxJavaScriptReplaySandbox.js +140 -0
  226. package/dist/replay/ReplayOutcome.js +95 -0
  227. package/dist/replay/ReplayProcessLifecycle.js +71 -0
  228. package/dist/server/ProcessCaptureElicitation.js +157 -0
  229. package/dist/server/createServer.js +124 -56
  230. package/dist/server/javascriptApplicationResult.js +85 -0
  231. package/dist/server/registerApplicationTools/characterization.js +57 -0
  232. package/dist/server/registerApplicationTools/compareVersions.js +34 -0
  233. package/dist/server/registerApplicationTools/controlledReplay.js +38 -0
  234. package/dist/server/registerApplicationTools/coverage.js +84 -0
  235. package/dist/server/registerApplicationTools/helpers.js +42 -0
  236. package/dist/server/registerApplicationTools/traceFeature.js +26 -0
  237. package/dist/server/registerApplicationTools/types.js +1 -0
  238. package/dist/server/registerApplicationTools.js +10 -112
  239. package/dist/server/registerBrowserTools.js +59 -83
  240. package/dist/server/registerElectronTools.js +48 -49
  241. package/dist/server/registerEnhancedTools.js +34 -42
  242. package/dist/server/registerEvidenceResources.js +56 -0
  243. package/dist/server/registerInvestigationTools/helpers.js +74 -0
  244. package/dist/server/registerInvestigationTools/types.js +1 -0
  245. package/dist/server/registerInvestigationTools.js +83 -116
  246. package/dist/server/registerJavaScriptApplicationGraphResource.js +69 -0
  247. package/dist/server/registerManagedTools.js +18 -1
  248. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +65 -0
  249. package/dist/server/registerManagedWorkflowTools/contract.js +8 -0
  250. package/dist/server/registerManagedWorkflowTools/evidence.js +43 -0
  251. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +39 -0
  252. package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +39 -0
  253. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +52 -0
  254. package/dist/server/registerManagedWorkflowTools/types.js +1 -0
  255. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +75 -0
  256. package/dist/server/registerManagedWorkflowTools.js +10 -274
  257. package/dist/server/registerOfficialTools.js +73 -59
  258. package/dist/server/registerSessionRecordTools.js +137 -0
  259. package/dist/server/registerSessionStatusTool.js +97 -26
  260. package/dist/server/registerSessionTools.js +60 -164
  261. package/dist/server/sessionAvailabilityPolicy.js +10 -0
  262. package/dist/server/toolRegistrationOptions.js +101 -3
  263. package/dist/server/toolResult.js +15 -4
  264. package/package.json +11 -11
  265. package/skills/reverse-engineer-anything/SKILL.md +76 -0
  266. package/skills/reverse-engineer-anything/references/controlled-replay.md +12 -0
  267. package/skills/reverse-engineer-anything/references/evidence-workflows.md +33 -0
  268. package/skills/reverse-engineer-anything/references/javascript-applications.md +25 -0
  269. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +36 -0
  270. package/skills/reverse-engineer-anything/references/runtime-observation.md +24 -0
  271. package/scripts/prepare-node-pty.mjs +0 -35
  272. package/scripts/rebuild-native.mjs +0 -22
  273. package/skills/rea-analysis/SKILL.md +0 -222
@@ -0,0 +1,107 @@
1
+ import { z } from "zod";
2
+ import { isAbsolute } from "node:path";
3
+ import { ConfigurationError } from "../domain/errors.js";
4
+ import { err, ok } from "../domain/result.js";
5
+ import { analysisProviderSelectorSchema } from "../contracts/providerSelection.js";
6
+ const environmentSchema = z
7
+ .object({
8
+ REA_ANALYSIS_PROVIDER: analysisProviderSelectorSchema.default("auto"),
9
+ GHIDRA_INSTALL_DIR: z
10
+ .string()
11
+ .min(1)
12
+ .refine(isAbsolute, "GHIDRA_INSTALL_DIR must be absolute")
13
+ .optional(),
14
+ JAVA_HOME: z
15
+ .string()
16
+ .min(1)
17
+ .refine(isAbsolute, "JAVA_HOME must be absolute")
18
+ .optional(),
19
+ REA_ILSPY_CMD_PATH: z
20
+ .string()
21
+ .min(1)
22
+ .refine(isAbsolute, "REA_ILSPY_CMD_PATH must be absolute")
23
+ .optional(),
24
+ HOPPER_LAUNCHER_PATH: z.string().min(1).optional(),
25
+ HOPPER_TARGET_PATH: z.string().min(1).optional(),
26
+ HOPPER_TARGET_KIND: z
27
+ .enum(["executable", "database"])
28
+ .default("executable"),
29
+ HOPPER_LOADER_ARGS_JSON: z.string().optional(),
30
+ REA_LOG_LEVEL: z
31
+ .enum(["trace", "debug", "info", "warn", "error", "fatal", "silent"])
32
+ .default("info"),
33
+ REA_PROCESS_CAPTURE_ENABLED: z.enum(["true", "false"]).default("false"),
34
+ REA_PROCESS_CAPTURE_AUTO_GRANT: z.enum(["true", "false"]).default("true"),
35
+ REA_ARTIFACT_NATIVE_MOUNT_ENABLED: z
36
+ .enum(["true", "false"])
37
+ .default("false"),
38
+ REA_ARTIFACT_INTEGRITY_CONTINUE_ENABLED: z
39
+ .enum(["true", "false"])
40
+ .default("false"),
41
+ REA_PROCESS_ALLOW_EXTERNAL_NETWORK: z
42
+ .enum(["true", "false"])
43
+ .default("false"),
44
+ REA_PROCESS_EXECUTABLE_ROOTS_JSON: z.string().default("[]"),
45
+ REA_PROCESS_WORKING_ROOTS_JSON: z.string().default("[]"),
46
+ REA_PROCESS_ALLOWED_ENV_JSON: z.string().default("[]"),
47
+ REA_EVIDENCE_ROOTS_JSON: z.string().default("[]"),
48
+ REA_INVESTIGATION_INPUT_ROOTS_JSON: z.string().default("[]"),
49
+ REA_ANALYSIS_SNAPSHOT_ROOTS_JSON: z.string().default("[]"),
50
+ REA_REFERENCE_ROOTS_JSON: z.string().default("[]"),
51
+ REA_REFERENCE_SECRET_PATTERNS_JSON: z.string().default("[]"),
52
+ REA_BROWSER_OBSERVE_ENABLED: z.enum(["true", "false"]).default("false"),
53
+ REA_BROWSER_CDP_ENDPOINTS_JSON: z.string().default("[]"),
54
+ REA_BROWSER_ALLOWED_ORIGINS_JSON: z.string().default("[]"),
55
+ REA_ELECTRON_OBSERVE_ENABLED: z.enum(["true", "false"]).default("false"),
56
+ REA_ELECTRON_CDP_ENDPOINTS_JSON: z.string().default("[]"),
57
+ REA_ELECTRON_FILE_ROOTS_JSON: z.string().default("[]"),
58
+ REA_JAVASCRIPT_REPLAY_ENABLED: z.enum(["true", "false"]).default("false"),
59
+ REA_JAVASCRIPT_REPLAY_ROOTS_JSON: z.string().default("[]"),
60
+ REA_JAVASCRIPT_REPLAY_NODE_PATH: z
61
+ .string()
62
+ .min(1)
63
+ .refine(isAbsolute, "REA_JAVASCRIPT_REPLAY_NODE_PATH must be absolute")
64
+ .default(process.execPath),
65
+ REA_JAVASCRIPT_REPLAY_BWRAP_PATH: z
66
+ .string()
67
+ .min(1)
68
+ .refine(isAbsolute, "REA_JAVASCRIPT_REPLAY_BWRAP_PATH must be absolute")
69
+ .default("/usr/bin/bwrap"),
70
+ REA_JAVASCRIPT_REPLAY_SYSTEMD_RUN_PATH: z
71
+ .string()
72
+ .min(1)
73
+ .refine(isAbsolute, "REA_JAVASCRIPT_REPLAY_SYSTEMD_RUN_PATH must be absolute")
74
+ .default("/usr/bin/systemd-run"),
75
+ REA_JAVASCRIPT_REPLAY_SYSTEMCTL_PATH: z
76
+ .string()
77
+ .min(1)
78
+ .refine(isAbsolute, "REA_JAVASCRIPT_REPLAY_SYSTEMCTL_PATH must be absolute")
79
+ .default("/usr/bin/systemctl"),
80
+ REA_JAVASCRIPT_REPLAY_SHELL_PATH: z
81
+ .string()
82
+ .min(1)
83
+ .refine(isAbsolute, "REA_JAVASCRIPT_REPLAY_SHELL_PATH must be absolute")
84
+ .default("/usr/bin/bash"),
85
+ REA_MANAGED_RUNTIME_ENABLED: z.enum(["true", "false"]).default("false"),
86
+ REA_MANAGED_RUNTIME_ROOTS_JSON: z.string().default("[]"),
87
+ REA_MANAGED_RUNTIME_EXECUTABLE_PATH: z
88
+ .string()
89
+ .min(1)
90
+ .refine(isAbsolute, "REA_MANAGED_RUNTIME_EXECUTABLE_PATH must be absolute")
91
+ .default("/usr/bin/dotnet"),
92
+ REA_PERMISSION_PROJECT_ROOT: z.string().min(1).optional(),
93
+ REA_PERMISSION_PROJECT_STORE: z.string().min(1).optional(),
94
+ })
95
+ .refine((value) => (value.REA_PERMISSION_PROJECT_ROOT === undefined) ===
96
+ (value.REA_PERMISSION_PROJECT_STORE === undefined), {
97
+ message: "REA_PERMISSION_PROJECT_ROOT and REA_PERMISSION_PROJECT_STORE must be configured together",
98
+ });
99
+ export const parseEnvironment = (environment) => {
100
+ const parsed = environmentSchema.safeParse(environment);
101
+ if (!parsed.success) {
102
+ return err(new ConfigurationError("Invalid REA environment configuration", {
103
+ cause: parsed.error,
104
+ }));
105
+ }
106
+ return ok(parsed.data);
107
+ };
@@ -0,0 +1,228 @@
1
+ import { isAbsolute } from "node:path";
2
+ import { ConfigurationError } from "../domain/errors.js";
3
+ import { err, ok } from "../domain/result.js";
4
+ import { parseEnvironment } from "./environment.js";
5
+ import { parseStringArray, parseBrowserArray, parseElectronFileRoots, parseLoaderArgs, } from "./parsers.js";
6
+ import { filePolicy, permissionScope, administratorGrants, browserNetworkScope, } from "./permissions.js";
7
+ import { browserEndpointSchema, browserOriginSchema, } from "../domain/browserObservation.js";
8
+ const DEFAULT_HOPPER_LAUNCHER_PATH = "/Applications/Hopper Disassembler.app/Contents/MacOS/hopper";
9
+ const defaultHopperLauncherPath = () => process.platform === "linux"
10
+ ? "/opt/hopper/bin/Hopper"
11
+ : DEFAULT_HOPPER_LAUNCHER_PATH;
12
+ const parseAllArrays = (env) => {
13
+ const loaderArgs = parseLoaderArgs(env.HOPPER_LOADER_ARGS_JSON);
14
+ if (!loaderArgs.ok)
15
+ return loaderArgs;
16
+ const executableRoots = parseStringArray(env.REA_PROCESS_EXECUTABLE_ROOTS_JSON, "REA_PROCESS_EXECUTABLE_ROOTS_JSON");
17
+ if (!executableRoots.ok)
18
+ return executableRoots;
19
+ const workingRoots = parseStringArray(env.REA_PROCESS_WORKING_ROOTS_JSON, "REA_PROCESS_WORKING_ROOTS_JSON");
20
+ if (!workingRoots.ok)
21
+ return workingRoots;
22
+ const allowedEnvironment = parseStringArray(env.REA_PROCESS_ALLOWED_ENV_JSON, "REA_PROCESS_ALLOWED_ENV_JSON");
23
+ if (!allowedEnvironment.ok)
24
+ return allowedEnvironment;
25
+ const evidenceRoots = parseStringArray(env.REA_EVIDENCE_ROOTS_JSON, "REA_EVIDENCE_ROOTS_JSON");
26
+ if (!evidenceRoots.ok)
27
+ return evidenceRoots;
28
+ const investigationInputRoots = parseStringArray(env.REA_INVESTIGATION_INPUT_ROOTS_JSON, "REA_INVESTIGATION_INPUT_ROOTS_JSON");
29
+ if (!investigationInputRoots.ok)
30
+ return investigationInputRoots;
31
+ const analysisSnapshotRoots = parseStringArray(env.REA_ANALYSIS_SNAPSHOT_ROOTS_JSON, "REA_ANALYSIS_SNAPSHOT_ROOTS_JSON");
32
+ if (!analysisSnapshotRoots.ok)
33
+ return analysisSnapshotRoots;
34
+ const referenceRoots = parseStringArray(env.REA_REFERENCE_ROOTS_JSON, "REA_REFERENCE_ROOTS_JSON");
35
+ if (!referenceRoots.ok)
36
+ return referenceRoots;
37
+ const secretPatterns = parseStringArray(env.REA_REFERENCE_SECRET_PATTERNS_JSON, "REA_REFERENCE_SECRET_PATTERNS_JSON");
38
+ if (!secretPatterns.ok)
39
+ return secretPatterns;
40
+ const browserEndpoints = parseBrowserArray(env.REA_BROWSER_CDP_ENDPOINTS_JSON, "REA_BROWSER_CDP_ENDPOINTS_JSON", browserEndpointSchema, 16);
41
+ if (!browserEndpoints.ok)
42
+ return browserEndpoints;
43
+ const browserOrigins = parseBrowserArray(env.REA_BROWSER_ALLOWED_ORIGINS_JSON, "REA_BROWSER_ALLOWED_ORIGINS_JSON", browserOriginSchema, 32);
44
+ if (!browserOrigins.ok)
45
+ return browserOrigins;
46
+ const electronEndpoints = parseBrowserArray(env.REA_ELECTRON_CDP_ENDPOINTS_JSON, "REA_ELECTRON_CDP_ENDPOINTS_JSON", browserEndpointSchema, 16);
47
+ if (!electronEndpoints.ok)
48
+ return electronEndpoints;
49
+ const electronFileRoots = parseElectronFileRoots(env.REA_ELECTRON_FILE_ROOTS_JSON);
50
+ if (!electronFileRoots.ok)
51
+ return electronFileRoots;
52
+ const javascriptReplayRoots = parseAbsoluteRoots(env.REA_JAVASCRIPT_REPLAY_ROOTS_JSON, "REA_JAVASCRIPT_REPLAY_ROOTS_JSON");
53
+ if (!javascriptReplayRoots.ok)
54
+ return javascriptReplayRoots;
55
+ const managedRuntimeRoots = parseAbsoluteRoots(env.REA_MANAGED_RUNTIME_ROOTS_JSON, "REA_MANAGED_RUNTIME_ROOTS_JSON");
56
+ if (!managedRuntimeRoots.ok)
57
+ return managedRuntimeRoots;
58
+ return ok({
59
+ loaderArgs: loaderArgs.value,
60
+ executableRoots: executableRoots.value,
61
+ workingRoots: workingRoots.value,
62
+ allowedEnvironment: allowedEnvironment.value,
63
+ evidenceRoots: evidenceRoots.value,
64
+ investigationInputRoots: investigationInputRoots.value,
65
+ analysisSnapshotRoots: analysisSnapshotRoots.value,
66
+ referenceRoots: referenceRoots.value,
67
+ secretPatterns: secretPatterns.value,
68
+ browserEndpoints: browserEndpoints.value,
69
+ browserOrigins: browserOrigins.value,
70
+ electronEndpoints: electronEndpoints.value,
71
+ electronFileRoots: electronFileRoots.value,
72
+ javascriptReplayRoots: javascriptReplayRoots.value,
73
+ managedRuntimeRoots: managedRuntimeRoots.value,
74
+ });
75
+ };
76
+ const parseAbsoluteRoots = (value, name) => {
77
+ const parsed = parseStringArray(value, name);
78
+ if (!parsed.ok)
79
+ return parsed;
80
+ return parsed.value.some((root) => !isAbsolute(root))
81
+ ? err(new ConfigurationError(`${name} must encode absolute roots`))
82
+ : parsed;
83
+ };
84
+ const appendProcessCaptureCeiling = (ceilings, env, arrays) => {
85
+ if (env.REA_PROCESS_CAPTURE_ENABLED !== "true")
86
+ return;
87
+ ceilings.push(permissionScope("process_capture", arrays.workingRoots, {
88
+ executables: arrays.executableRoots,
89
+ environment_names: arrays.allowedEnvironment,
90
+ network: env.REA_PROCESS_ALLOW_EXTERNAL_NETWORK === "true" ? "external" : "none",
91
+ }));
92
+ };
93
+ const appendBrowserObservationCeiling = (ceilings, env, arrays) => {
94
+ if (env.REA_BROWSER_OBSERVE_ENABLED !== "true")
95
+ return;
96
+ ceilings.push(permissionScope("browser_observe", [], {
97
+ origins: [...arrays.browserEndpoints, ...arrays.browserOrigins],
98
+ network: browserNetworkScope(arrays.browserOrigins),
99
+ }));
100
+ };
101
+ const appendElectronObservationCeiling = (ceilings, env, arrays) => {
102
+ if (env.REA_ELECTRON_OBSERVE_ENABLED !== "true")
103
+ return;
104
+ ceilings.push(permissionScope("electron_observe", arrays.electronFileRoots, {
105
+ origins: arrays.electronEndpoints,
106
+ network: "loopback",
107
+ }));
108
+ };
109
+ const appendNativeMountCeiling = (ceilings, env) => {
110
+ if (env.REA_ARTIFACT_NATIVE_MOUNT_ENABLED === "true")
111
+ ceilings.push(permissionScope("native_mount", [], { mount: true }));
112
+ };
113
+ const appendJavaScriptReplayCeiling = (ceilings, env, arrays) => {
114
+ if (env.REA_JAVASCRIPT_REPLAY_ENABLED !== "true")
115
+ return;
116
+ ceilings.push(permissionScope("javascript_replay", arrays.javascriptReplayRoots, {
117
+ executables: [
118
+ env.REA_JAVASCRIPT_REPLAY_NODE_PATH,
119
+ env.REA_JAVASCRIPT_REPLAY_BWRAP_PATH,
120
+ env.REA_JAVASCRIPT_REPLAY_SYSTEMD_RUN_PATH,
121
+ env.REA_JAVASCRIPT_REPLAY_SYSTEMCTL_PATH,
122
+ env.REA_JAVASCRIPT_REPLAY_SHELL_PATH,
123
+ ],
124
+ network: "none",
125
+ mount: true,
126
+ }));
127
+ };
128
+ const appendManagedRuntimeCeiling = (ceilings, env, arrays) => {
129
+ if (env.REA_MANAGED_RUNTIME_ENABLED !== "true")
130
+ return;
131
+ ceilings.push(permissionScope("managed_runtime", arrays.managedRuntimeRoots, {
132
+ executables: [env.REA_MANAGED_RUNTIME_EXECUTABLE_PATH],
133
+ network: "none",
134
+ }));
135
+ };
136
+ const buildPermissionCeilings = (env, arrays) => {
137
+ const ceilings = [
138
+ permissionScope("evidence_read", arrays.evidenceRoots),
139
+ permissionScope("evidence_write", arrays.evidenceRoots),
140
+ permissionScope("investigation_input", arrays.investigationInputRoots),
141
+ permissionScope("investigation_workspace_read", arrays.evidenceRoots),
142
+ permissionScope("investigation_workspace_write", arrays.evidenceRoots),
143
+ permissionScope("snapshot_read", arrays.analysisSnapshotRoots),
144
+ permissionScope("snapshot_write", arrays.analysisSnapshotRoots),
145
+ permissionScope("artifact_extract", ["/"]),
146
+ permissionScope("reference_read", arrays.referenceRoots),
147
+ ];
148
+ appendProcessCaptureCeiling(ceilings, env, arrays);
149
+ appendBrowserObservationCeiling(ceilings, env, arrays);
150
+ appendElectronObservationCeiling(ceilings, env, arrays);
151
+ appendNativeMountCeiling(ceilings, env);
152
+ appendJavaScriptReplayCeiling(ceilings, env, arrays);
153
+ appendManagedRuntimeCeiling(ceilings, env, arrays);
154
+ return ceilings;
155
+ };
156
+ const buildAppConfig = (env, arrays, permissionCeilings) => ({
157
+ analysisProvider: env.REA_ANALYSIS_PROVIDER,
158
+ ghidraInstallDir: env.GHIDRA_INSTALL_DIR,
159
+ ghidraJavaHome: env.JAVA_HOME,
160
+ ilspyCmdPath: env.REA_ILSPY_CMD_PATH,
161
+ hopperLauncherPath: env.HOPPER_LAUNCHER_PATH ?? defaultHopperLauncherPath(),
162
+ hopperTargetPath: env.HOPPER_TARGET_PATH,
163
+ hopperTargetKind: env.HOPPER_TARGET_KIND,
164
+ hopperLoaderArgs: arrays.loaderArgs,
165
+ logLevel: env.REA_LOG_LEVEL,
166
+ processExecutionPolicy: {
167
+ enabled: env.REA_PROCESS_CAPTURE_ENABLED === "true",
168
+ executableRoots: arrays.executableRoots,
169
+ workingRoots: arrays.workingRoots,
170
+ allowedEnvironment: arrays.allowedEnvironment,
171
+ allowExternalNetwork: env.REA_PROCESS_ALLOW_EXTERNAL_NETWORK === "true",
172
+ },
173
+ artifactNativeMountEnabled: env.REA_ARTIFACT_NATIVE_MOUNT_ENABLED === "true",
174
+ artifactIntegrityContinueEnabled: env.REA_ARTIFACT_INTEGRITY_CONTINUE_ENABLED === "true",
175
+ evidenceFilePolicy: filePolicy(arrays.evidenceRoots),
176
+ investigationInputRoots: arrays.investigationInputRoots,
177
+ analysisSnapshotFilePolicy: filePolicy(arrays.analysisSnapshotRoots),
178
+ referenceSourcePolicy: {
179
+ roots: arrays.referenceRoots,
180
+ secretPatterns: arrays.secretPatterns,
181
+ maxBytes: 16 * 1024 * 1024,
182
+ maxEntries: 10_000,
183
+ maxDepth: 32,
184
+ maxPathBytes: 4_096,
185
+ },
186
+ browserObservationEnabled: env.REA_BROWSER_OBSERVE_ENABLED === "true",
187
+ browserCdpEndpoints: arrays.browserEndpoints,
188
+ browserAllowedOrigins: arrays.browserOrigins,
189
+ electronObservationEnabled: env.REA_ELECTRON_OBSERVE_ENABLED === "true",
190
+ electronCdpEndpoints: arrays.electronEndpoints,
191
+ electronFileRoots: arrays.electronFileRoots,
192
+ javascriptReplayPolicy: {
193
+ enabled: env.REA_JAVASCRIPT_REPLAY_ENABLED === "true",
194
+ roots: arrays.javascriptReplayRoots,
195
+ nodePath: env.REA_JAVASCRIPT_REPLAY_NODE_PATH,
196
+ bubblewrapPath: env.REA_JAVASCRIPT_REPLAY_BWRAP_PATH,
197
+ systemdRunPath: env.REA_JAVASCRIPT_REPLAY_SYSTEMD_RUN_PATH,
198
+ systemctlPath: env.REA_JAVASCRIPT_REPLAY_SYSTEMCTL_PATH,
199
+ shellPath: env.REA_JAVASCRIPT_REPLAY_SHELL_PATH,
200
+ },
201
+ managedRuntimePolicy: {
202
+ enabled: env.REA_MANAGED_RUNTIME_ENABLED === "true",
203
+ roots: arrays.managedRuntimeRoots,
204
+ executablePath: env.REA_MANAGED_RUNTIME_EXECUTABLE_PATH,
205
+ },
206
+ permissionCeilings,
207
+ administratorPermissionGrants: administratorGrants(env.REA_PROCESS_CAPTURE_AUTO_GRANT === "true"
208
+ ? permissionCeilings
209
+ : permissionCeilings.filter(({ capability }) => capability !== "process_capture")),
210
+ permissionProjectRoot: env.REA_PERMISSION_PROJECT_ROOT,
211
+ permissionProjectStore: env.REA_PERMISSION_PROJECT_STORE,
212
+ });
213
+ /**
214
+ * Parse provider and authority configuration once at the composition root.
215
+ * Explicit loader arguments override REA's header-derived defaults for a
216
+ * supported target, allowing callers to refine Hopper's loader behavior without
217
+ * bypassing REA's path and executable-header checks.
218
+ */
219
+ export const parseConfig = (environment) => {
220
+ const envResult = parseEnvironment(environment);
221
+ if (!envResult.ok)
222
+ return envResult;
223
+ const arraysResult = parseAllArrays(envResult.value);
224
+ if (!arraysResult.ok)
225
+ return arraysResult;
226
+ const permissionCeilings = buildPermissionCeilings(envResult.value, arraysResult.value);
227
+ return ok(buildAppConfig(envResult.value, arraysResult.value, permissionCeilings));
228
+ };
@@ -0,0 +1,68 @@
1
+ import { z } from "zod";
2
+ import { ConfigurationError } from "../domain/errors.js";
3
+ import { err, ok } from "../domain/result.js";
4
+ import {} from "../domain/browserObservation.js";
5
+ import { electronFileRootsSchema } from "../domain/electronObservation.js";
6
+ export const parseStringArray = (encoded, name) => {
7
+ try {
8
+ const parsed = z
9
+ .array(z.string().min(1))
10
+ .max(128)
11
+ .safeParse(JSON.parse(encoded));
12
+ return parsed.success
13
+ ? ok(parsed.data)
14
+ : err(new ConfigurationError(parsed.error.issues.some(({ code }) => code === "too_big")
15
+ ? `${name} must encode at most 128 strings`
16
+ : `${name} must encode an array of strings`, { cause: parsed.error }));
17
+ }
18
+ catch (cause) {
19
+ return err(new ConfigurationError(`${name} must be valid JSON`, { cause }));
20
+ }
21
+ };
22
+ export const parseBrowserArray = (encoded, name, itemSchema, maximum) => {
23
+ try {
24
+ const parsed = z
25
+ .array(itemSchema)
26
+ .max(maximum)
27
+ .safeParse(JSON.parse(encoded));
28
+ return parsed.success
29
+ ? ok([...new Set(parsed.data)].sort())
30
+ : err(new ConfigurationError(`${name} must encode valid browser scopes`, {
31
+ cause: parsed.error,
32
+ }));
33
+ }
34
+ catch (cause) {
35
+ return err(new ConfigurationError(`${name} must be valid JSON`, { cause }));
36
+ }
37
+ };
38
+ export const parseElectronFileRoots = (encoded) => {
39
+ try {
40
+ const decoded = JSON.parse(encoded);
41
+ if (Array.isArray(decoded) && decoded.length === 0)
42
+ return ok([]);
43
+ const parsed = electronFileRootsSchema.safeParse(decoded);
44
+ return parsed.success
45
+ ? ok(parsed.data)
46
+ : err(new ConfigurationError("REA_ELECTRON_FILE_ROOTS_JSON must encode absolute roots", { cause: parsed.error }));
47
+ }
48
+ catch (cause) {
49
+ return err(new ConfigurationError("REA_ELECTRON_FILE_ROOTS_JSON must be valid JSON", { cause }));
50
+ }
51
+ };
52
+ export const parseLoaderArgs = (encoded) => {
53
+ if (encoded === undefined)
54
+ return ok([]);
55
+ let decoded;
56
+ try {
57
+ decoded = JSON.parse(encoded);
58
+ }
59
+ catch (cause) {
60
+ return err(new ConfigurationError("HOPPER_LOADER_ARGS_JSON must be valid JSON", {
61
+ cause,
62
+ }));
63
+ }
64
+ const parsed = z.array(z.string()).safeParse(decoded);
65
+ return parsed.success
66
+ ? ok(parsed.data)
67
+ : err(new ConfigurationError("HOPPER_LOADER_ARGS_JSON must encode an array of strings", { cause: parsed.error }));
68
+ };
@@ -0,0 +1,30 @@
1
+ import { isLiteralLoopbackHostname } from "../domain/browserObservation.js";
2
+ export const filePolicy = (roots) => ({
3
+ roots,
4
+ maxBytes: 64 * 1024 * 1024,
5
+ maxDepth: 64,
6
+ maxStringLength: 1024 * 1024,
7
+ maxNodes: 1_000_000,
8
+ });
9
+ export const permissionScope = (capability, roots, options = {}) => ({
10
+ capability,
11
+ roots,
12
+ executables: options.executables ?? [],
13
+ environment_names: options.environment_names ?? [],
14
+ ...(options.origins === undefined ? {} : { origins: options.origins }),
15
+ network: options.network ?? "none",
16
+ mount: options.mount ?? false,
17
+ });
18
+ export const administratorGrants = (ceilings) => ceilings.map((ceiling) => ({
19
+ ...ceiling,
20
+ grant_id: `administrator:${ceiling.capability}`,
21
+ lifetime: "administrator",
22
+ operation_identity: null,
23
+ expires_at: null,
24
+ }));
25
+ export const browserNetworkScope = (origins) => origins.every((origin) => {
26
+ const hostname = new URL(origin).hostname;
27
+ return isLiteralLoopbackHostname(hostname);
28
+ })
29
+ ? "loopback"
30
+ : "external";
@@ -0,0 +1 @@
1
+ export {};