rea-agents 1.7.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 (333) hide show
  1. package/README.md +112 -59
  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 +42 -2
  18. package/dist/application/ClientRegistrationStatus.js +1 -1
  19. package/dist/application/CrossVersionInventory.js +8 -2
  20. package/dist/application/CrossVersionInvestigation.js +11 -29
  21. package/dist/application/CrossVersionInvestigationCollections.js +23 -0
  22. package/dist/application/DirectAnalysis.js +47 -44
  23. package/dist/application/Doctor.js +165 -197
  24. package/dist/application/DoctorDiagnostics.js +180 -0
  25. package/dist/application/ElectronBoundaryAnalysis.js +112 -0
  26. package/dist/application/ElectronBoundaryGraph.js +9 -0
  27. package/dist/application/ElectronBoundaryGraphContext.js +62 -0
  28. package/dist/application/ElectronBoundaryGraphIpc.js +242 -0
  29. package/dist/application/ElectronBoundaryGraphNative.js +86 -0
  30. package/dist/application/ElectronBoundaryGraphWindows.js +223 -0
  31. package/dist/application/EnhancedToolPagination.js +22 -0
  32. package/dist/application/EnhancedToolTypes.js +4 -0
  33. package/dist/application/EnhancedTools.js +58 -50
  34. package/dist/application/InstrumentedJavaScriptReplayHost.js +36 -0
  35. package/dist/application/InvestigationProviders.js +30 -0
  36. package/dist/application/InvestigationWorkspaceStore.js +24 -10
  37. package/dist/application/JavaScriptApplicationEvidence.js +26 -0
  38. package/dist/application/JavaScriptApplicationEvidenceGraph.js +89 -0
  39. package/dist/application/JavaScriptApplicationService.js +74 -0
  40. package/dist/application/JavaScriptApplicationWorkflowEvidence.js +29 -0
  41. package/dist/application/JavaScriptApplicationWorkflowService.js +90 -0
  42. package/dist/application/JavaScriptArtifactAnalysis.js +52 -7
  43. package/dist/application/JavaScriptArtifactFiles.js +6 -2
  44. package/dist/application/JavaScriptArtifactGraphBuilder.js +82 -17
  45. package/dist/application/JavaScriptArtifactGraphBundlers.js +225 -0
  46. package/dist/application/JavaScriptArtifactGraphContext.js +37 -36
  47. package/dist/application/JavaScriptArtifactGraphDocuments.js +27 -4
  48. package/dist/application/JavaScriptArtifactGraphEvidence.js +24 -14
  49. package/dist/application/JavaScriptArtifactGraphFindings.js +54 -8
  50. package/dist/application/JavaScriptArtifactGraphStructure.js +29 -101
  51. package/dist/application/JavaScriptArtifactPathResolution.js +269 -0
  52. package/dist/application/JavaScriptArtifactReconstruction.js +4 -1
  53. package/dist/application/JavaScriptArtifactReconstructionInput.js +2 -83
  54. package/dist/application/JavaScriptJsonModules.js +39 -0
  55. package/dist/application/JavaScriptModuleRelationships.js +262 -0
  56. package/dist/application/JavaScriptReplayPermission.js +16 -0
  57. package/dist/application/JavaScriptReplayPlanning.js +201 -0
  58. package/dist/application/JavaScriptReplayService.js +292 -0
  59. package/dist/application/JavaScriptRuntimeReconciliationEvidence.js +25 -0
  60. package/dist/application/JavaScriptRuntimeReconciliationService.js +27 -0
  61. package/dist/application/LinuxHopper.js +10 -0
  62. package/dist/application/MacHopper.js +22 -11
  63. package/dist/application/ManagedApplicationGraphService.js +55 -0
  64. package/dist/application/ManagedMemberComparisonService.js +122 -0
  65. package/dist/application/ManagedNativeVerificationService.js +39 -0
  66. package/dist/application/ManagedReconstructionService.js +58 -0
  67. package/dist/application/ManagedRuntimeCorrelationService.js +103 -0
  68. package/dist/application/NodeRuntimeCharacterizationService.js +196 -0
  69. package/dist/application/PermissionAuthority.js +106 -63
  70. package/dist/application/ProcessCaptureCapability.js +1 -1
  71. package/dist/application/ProcessCapturePermission.js +13 -0
  72. package/dist/application/ProcessCli.js +2 -12
  73. package/dist/application/ProcessHarness.js +1 -1
  74. package/dist/application/ProcessSampling.js +15 -11
  75. package/dist/application/ProjectPermissionStore.js +49 -9
  76. package/dist/application/RealHopperAssertions.js +76 -0
  77. package/dist/application/ReconstructionCoverageService.js +69 -0
  78. package/dist/application/ReconstructionCoverageWorkspaceStore.js +31 -0
  79. package/dist/application/RuntimeExecutableDiagnostics.js +172 -0
  80. package/dist/application/Setup.js +147 -259
  81. package/dist/application/SetupClientConfiguration.js +220 -0
  82. package/dist/application/SetupClients.js +24 -2
  83. package/dist/application/SetupPlan.js +123 -12
  84. package/dist/application/SetupSkill.js +26 -12
  85. package/dist/application/SupportedClients.js +1 -0
  86. package/dist/application/Uninstall.js +6 -3
  87. package/dist/application/WindowsCapabilities.js +86 -0
  88. package/dist/application/runtime.js +2 -0
  89. package/dist/artifacts/AsarArtifactReader.js +11 -0
  90. package/dist/browser/BrowserProcessStartup.js +88 -0
  91. package/dist/browser/CdpCaptureDocuments.js +12 -8
  92. package/dist/browser/CdpCaptureEventBodyShapes.js +75 -0
  93. package/dist/browser/CdpCaptureEventHandlers.js +336 -0
  94. package/dist/browser/CdpCaptureEventHelpers.js +71 -0
  95. package/dist/browser/CdpCaptureEventState.js +1 -0
  96. package/dist/browser/CdpCaptureEventTypes.js +1 -0
  97. package/dist/browser/CdpCaptureEvents.js +46 -464
  98. package/dist/browser/CdpElectronInspection.js +106 -162
  99. package/dist/browser/CdpElectronProvider.js +5 -1
  100. package/dist/browser/CdpElectronScriptEvents.js +69 -0
  101. package/dist/browser/CdpElectronScripts.js +94 -0
  102. package/dist/browser/CdpElectronWorkers.js +56 -0
  103. package/dist/browser/CdpObservationSession.js +51 -8
  104. package/dist/browser/CdpPageCapture.js +12 -129
  105. package/dist/browser/CdpPageCaptureScripts.js +97 -0
  106. package/dist/browser/CdpPageCaptureWorkers.js +46 -0
  107. package/dist/browser/CdpWebMcpDiscovery.js +38 -14
  108. package/dist/browser/PngVisualDiff.js +9 -2
  109. package/dist/catalogIdentity.js +8 -1
  110. package/dist/cli/artifactCommands.js +82 -0
  111. package/dist/cli/coreAnalysisCommands.js +232 -0
  112. package/dist/cli/managedCommands.js +397 -0
  113. package/dist/cli/managedProjectGraphCommand.js +24 -0
  114. package/dist/cli/options.js +9 -0
  115. package/dist/cli/setupCommands.js +108 -0
  116. package/dist/cli/types.js +1 -0
  117. package/dist/cli/utilityCommands.js +122 -0
  118. package/dist/cli.js +13 -383
  119. package/dist/cliApplicationCommands.js +176 -0
  120. package/dist/cliBrowserAdvancedCommands.js +73 -16
  121. package/dist/cliBrowserCommands.js +39 -115
  122. package/dist/cliCommandNames.js +17 -0
  123. package/dist/cliElectronCommands.js +100 -27
  124. package/dist/cliEvidenceCommands.js +13 -2
  125. package/dist/cliInvestigationCommands.js +53 -10
  126. package/dist/cliJsonInput.js +54 -0
  127. package/dist/cliObservationOptions.js +137 -0
  128. package/dist/cliPolicyCommands.js +80 -46
  129. package/dist/cliSetup.js +289 -0
  130. package/dist/config/environment.js +107 -0
  131. package/dist/config/parseConfig.js +228 -0
  132. package/dist/config/parsers.js +68 -0
  133. package/dist/config/permissions.js +30 -0
  134. package/dist/config/types.js +1 -0
  135. package/dist/config.js +1 -292
  136. package/dist/contracts/applicationToolContracts.js +225 -0
  137. package/dist/contracts/artifactToolContracts.js +5 -9
  138. package/dist/contracts/browserToolContracts.js +14 -62
  139. package/dist/contracts/electronToolContracts.js +45 -19
  140. package/dist/contracts/errorSchemas.js +1 -0
  141. package/dist/contracts/investigationExamples.js +0 -6
  142. package/dist/contracts/javascriptApplicationWorkflowExamples.js +46 -0
  143. package/dist/contracts/javascriptRuntimeReconciliationExample.js +208 -0
  144. package/dist/contracts/managedToolContracts.js +153 -0
  145. package/dist/contracts/managedWorkflowExamples.js +346 -0
  146. package/dist/contracts/managedWorkflowToolContracts.js +203 -0
  147. package/dist/contracts/nativeToolContracts.js +2 -6
  148. package/dist/contracts/promptContracts.js +18 -2
  149. package/dist/contracts/providerSelection.js +2 -0
  150. package/dist/contracts/toolContractExamples.js +10 -25
  151. package/dist/contracts/toolContracts.js +49 -47
  152. package/dist/contracts/toolEffects.js +174 -0
  153. package/dist/contracts/toolOutputSchemaGroups.js +232 -0
  154. package/dist/contracts/toolOutputSchemaPrimitives.js +327 -0
  155. package/dist/contracts/toolOutputSchemas.js +2 -535
  156. package/dist/doctorRuntime.js +42 -1
  157. package/dist/domain/analysisErrorPresentation.js +234 -0
  158. package/dist/domain/analysisErrorProjection.js +284 -0
  159. package/dist/domain/artifactComparison.js +37 -19
  160. package/dist/domain/binaryTarget.js +87 -37
  161. package/dist/domain/browserObservation.js +1 -282
  162. package/dist/domain/browserObservationSchemas.js +286 -0
  163. package/dist/domain/bundleComparison.js +4 -4
  164. package/dist/domain/electronObservation.js +13 -0
  165. package/dist/domain/electronStaticAnalysis.js +9 -0
  166. package/dist/domain/electronStaticAnalysisBrowser.js +206 -0
  167. package/dist/domain/electronStaticAnalysisIpc.js +171 -0
  168. package/dist/domain/electronStaticAnalysisNative.js +164 -0
  169. package/dist/domain/electronStaticAnalysisTypes.js +1 -0
  170. package/dist/domain/electronStaticAnalysisValues.js +103 -0
  171. package/dist/domain/errors.js +32 -448
  172. package/dist/domain/functionComparison.js +4 -165
  173. package/dist/domain/functionComparisonDimensions.js +164 -0
  174. package/dist/domain/functionComparisonSchemas.js +3 -8
  175. package/dist/domain/inputIssueProjection.js +52 -0
  176. package/dist/domain/javascriptApplicationAnalysis.js +155 -0
  177. package/dist/domain/javascriptApplicationChangeGraph.js +231 -0
  178. package/dist/domain/javascriptApplicationEvidenceSchemas.js +18 -0
  179. package/dist/domain/javascriptApplicationGraph.js +2 -1
  180. package/dist/domain/javascriptApplicationGraphSchemas.js +7 -0
  181. package/dist/domain/javascriptApplicationVersionComparison.js +116 -0
  182. package/dist/domain/javascriptApplicationVersionComparisonSchemas.js +139 -0
  183. package/dist/domain/javascriptApplicationVersionItems.js +233 -0
  184. package/dist/domain/javascriptApplicationVersionKeys.js +170 -0
  185. package/dist/domain/javascriptExportInstrumentation.js +97 -0
  186. package/dist/domain/javascriptFeatureSeed.js +140 -0
  187. package/dist/domain/javascriptFeatureTrace.js +232 -0
  188. package/dist/domain/javascriptFeatureTraceSchemas.js +136 -0
  189. package/dist/domain/javascriptFeatureTraversal.js +100 -0
  190. package/dist/domain/javascriptNativeHandoff.js +85 -0
  191. package/dist/domain/javascriptReplay.js +361 -0
  192. package/dist/domain/javascriptRuntimeLoadState.js +106 -0
  193. package/dist/domain/javascriptRuntimeReconciliation.js +42 -0
  194. package/dist/domain/javascriptRuntimeReconciliationGraph.js +169 -0
  195. package/dist/domain/javascriptRuntimeReconciliationMatching.js +247 -0
  196. package/dist/domain/javascriptRuntimeReconciliationParsing.js +160 -0
  197. package/dist/domain/javascriptRuntimeReconciliationResult.js +119 -0
  198. package/dist/domain/javascriptRuntimeReconciliationRuntime.js +316 -0
  199. package/dist/domain/javascriptRuntimeReconciliationSchemas.js +245 -0
  200. package/dist/domain/javascriptRuntimeStaticCandidates.js +193 -0
  201. package/dist/domain/javascriptSemanticAnalysis.js +386 -0
  202. package/dist/domain/javascriptSemanticIr.js +30 -0
  203. package/dist/domain/javascriptSemanticProjection.js +366 -0
  204. package/dist/domain/javascriptSemanticState.js +40 -0
  205. package/dist/domain/javascriptSemanticTraversal.js +22 -0
  206. package/dist/domain/javascriptSemanticValues.js +352 -0
  207. package/dist/domain/javascriptStaticAnalysis.js +26 -254
  208. package/dist/domain/javascriptStaticAnalysisBundler.js +209 -0
  209. package/dist/domain/javascriptStaticAnalysisCalls.js +180 -0
  210. package/dist/domain/javascriptStaticAnalysisFindings.js +39 -0
  211. package/dist/domain/javascriptStaticAnalysisHelpers.js +81 -2
  212. package/dist/domain/javascriptStaticAnalysisState.js +6 -0
  213. package/dist/domain/knownPageCoverage.js +21 -0
  214. package/dist/domain/managedApplicationGraph.js +206 -0
  215. package/dist/domain/managedApplicationGraphCoverage.js +170 -0
  216. package/dist/domain/managedApplicationGraphNodeCoverage.js +6 -0
  217. package/dist/domain/managedApplicationGraphNodes.js +336 -0
  218. package/dist/domain/managedArtifact.js +452 -0
  219. package/dist/domain/managedMemberComparison.js +211 -0
  220. package/dist/domain/managedMemberComparisonCoverage.js +72 -0
  221. package/dist/domain/managedMemberComparisonMatch.js +356 -0
  222. package/dist/domain/managedNativeVerification.js +46 -0
  223. package/dist/domain/managedNativeVerificationMatch.js +272 -0
  224. package/dist/domain/managedNativeVerificationSchemas.js +141 -0
  225. package/dist/domain/managedReconstruction.js +196 -0
  226. package/dist/domain/managedRuntimeCorrelation.js +184 -0
  227. package/dist/domain/nodeRuntimeCharacterization.js +66 -0
  228. package/dist/domain/permissionPolicy.js +2 -0
  229. package/dist/domain/reconstructionCoverage.js +387 -0
  230. package/dist/domain/reconstructionCoverageEvaluation.js +212 -0
  231. package/dist/domain/reconstructionVerificationSchemas.js +9 -3
  232. package/dist/domain/runtimeCharacterization.js +85 -0
  233. package/dist/domain/webBundleAnalyzer.js +3 -409
  234. package/dist/domain/webBundleAnalyzerAst.js +77 -0
  235. package/dist/domain/webBundleAnalyzerInspection.js +307 -0
  236. package/dist/domain/webBundleAnalyzerResult.js +120 -0
  237. package/dist/dotnet/ManagedArtifactInspector.js +339 -0
  238. package/dist/dotnet/ManagedMemberInspector.js +153 -0
  239. package/dist/dotnet/ManagedMemberInspectorCore.js +297 -0
  240. package/dist/dotnet/ManagedMemberInstructionDecoder.js +427 -0
  241. package/dist/dotnet/ManagedMemberRows.js +120 -0
  242. package/dist/dotnet/ManagedMetadataHeaps.js +131 -0
  243. package/dist/dotnet/ManagedMetadataInventory.js +104 -0
  244. package/dist/dotnet/ManagedMetadataInventoryRows.js +292 -0
  245. package/dist/dotnet/ManagedMetadataLayout.js +259 -0
  246. package/dist/dotnet/ManagedMetadataRowSizes.js +54 -0
  247. package/dist/dotnet/ManagedMethodBodyReader.js +143 -0
  248. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +311 -0
  249. package/dist/dotnet/ManagedNativeBoundaryInspector.js +143 -0
  250. package/dist/dotnet/ManagedPeReader.js +188 -0
  251. package/dist/dotnet/ManagedReaderFailure.js +10 -0
  252. package/dist/dotnet/ManagedStaticProvider.js +203 -0
  253. package/dist/generatedPackageMetadata.js +2 -2
  254. package/dist/ghidra/GhidraClient.js +76 -91
  255. package/dist/ghidra/GhidraClientStartup.js +29 -0
  256. package/dist/ghidra/GhidraClientWire.js +34 -0
  257. package/dist/ghidra/GhidraDefaults.js +1 -1
  258. package/dist/ghidra/GhidraDiagnostics.js +6 -1
  259. package/dist/ghidra/GhidraInstallation.js +20 -15
  260. package/dist/ghidra/GhidraLauncher.js +93 -29
  261. package/dist/ghidra/GhidraProvider.js +67 -161
  262. package/dist/ghidra/GhidraProviderCapabilities.js +173 -0
  263. package/dist/ghidra/GhidraSessionValues.js +2 -0
  264. package/dist/ghidra/GhidraSocketConnection.js +44 -7
  265. package/dist/ghidra/GhidraTargetSnapshot.js +30 -0
  266. package/dist/ghidra/GhidraTransport.js +71 -0
  267. package/dist/identity.js +3 -2
  268. package/dist/main/messages.js +5 -0
  269. package/dist/main/reload.js +49 -0
  270. package/dist/main/shutdown.js +25 -0
  271. package/dist/main/startup.js +14 -0
  272. package/dist/main/state.js +26 -0
  273. package/dist/main/transport.js +61 -0
  274. package/dist/main/types.js +1 -0
  275. package/dist/main.js +35 -132
  276. package/dist/process/PrivateRuntimeRoot.js +3 -2
  277. package/dist/process/ProcessOwnership.js +35 -0
  278. package/dist/process/ProviderProcess.js +2 -0
  279. package/dist/replay/JavaScriptReplayWorker.js +300 -0
  280. package/dist/replay/LinuxJavaScriptReplayRunner.js +217 -0
  281. package/dist/replay/LinuxJavaScriptReplaySandbox.js +140 -0
  282. package/dist/replay/LinuxRuntimeClosure.js +46 -0
  283. package/dist/replay/LinuxSeccompPolicy.js +40 -0
  284. package/dist/replay/ReplayOutcome.js +95 -0
  285. package/dist/replay/ReplayProcessLifecycle.js +71 -0
  286. package/dist/replay/ReplayWorkerProtocol.js +55 -0
  287. package/dist/replay/SystemJavaScriptReplayHost.js +182 -0
  288. package/dist/server/ProcessCaptureElicitation.js +157 -0
  289. package/dist/server/createServer.js +158 -41
  290. package/dist/server/registerApplicationTools/characterization.js +57 -0
  291. package/dist/server/registerApplicationTools/compareVersions.js +34 -0
  292. package/dist/server/registerApplicationTools/controlledReplay.js +38 -0
  293. package/dist/server/registerApplicationTools/coverage.js +84 -0
  294. package/dist/server/registerApplicationTools/helpers.js +42 -0
  295. package/dist/server/registerApplicationTools/traceFeature.js +26 -0
  296. package/dist/server/registerApplicationTools/types.js +1 -0
  297. package/dist/server/registerApplicationTools.js +13 -0
  298. package/dist/server/registerArtifactComparisonTool.js +16 -9
  299. package/dist/server/registerBrowserTools.js +61 -60
  300. package/dist/server/registerBundleComparisonTool.js +17 -20
  301. package/dist/server/registerElectronTools.js +39 -12
  302. package/dist/server/registerEnhancedTools.js +52 -15
  303. package/dist/server/registerEvidenceResources.js +54 -0
  304. package/dist/server/registerEvidenceTools.js +5 -1
  305. package/dist/server/registerFunctionComparisonTool.js +14 -7
  306. package/dist/server/registerInvestigationTools/helpers.js +74 -0
  307. package/dist/server/registerInvestigationTools/types.js +1 -0
  308. package/dist/server/registerInvestigationTools.js +103 -132
  309. package/dist/server/registerManagedTools.js +6 -0
  310. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +65 -0
  311. package/dist/server/registerManagedWorkflowTools/contract.js +8 -0
  312. package/dist/server/registerManagedWorkflowTools/evidence.js +43 -0
  313. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +39 -0
  314. package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +39 -0
  315. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +52 -0
  316. package/dist/server/registerManagedWorkflowTools/types.js +1 -0
  317. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +75 -0
  318. package/dist/server/registerManagedWorkflowTools.js +13 -0
  319. package/dist/server/registerOfficialTools.js +81 -67
  320. package/dist/server/registerProcessComparisonTool.js +25 -47
  321. package/dist/server/registerSessionRecordTools.js +137 -0
  322. package/dist/server/registerSessionStatusTool.js +9 -8
  323. package/dist/server/registerSessionTools.js +77 -216
  324. package/dist/server/sessionAvailabilityPolicy.js +10 -0
  325. package/dist/server/sessionEvidence.js +14 -19
  326. package/dist/server/toolInputValidation.js +77 -0
  327. package/dist/server/toolRegistrationOptions.js +177 -2
  328. package/dist/server/toolResult.js +30 -17
  329. package/package.json +21 -14
  330. package/scripts/rea.mjs +1 -1
  331. package/skills/{rea-analysis → reverse-engineer-anything}/SKILL.md +75 -6
  332. package/scripts/prepare-node-pty.mjs +0 -35
  333. package/scripts/rebuild-native.mjs +0 -22
@@ -1,5 +1,4 @@
1
1
  import { constants } from "node:fs";
2
- import { createReadStream } from "node:fs";
3
2
  import { createHash } from "node:crypto";
4
3
  import { access, open, readFile, realpath, stat, } from "node:fs/promises";
5
4
  import { execFile } from "node:child_process";
@@ -22,43 +21,42 @@ export const parseBinaryTarget = async (input, cwd = process.cwd(), hostArchitec
22
21
  if (!resolved.ok)
23
22
  return err(resolved.error);
24
23
  const path = resolved.value;
25
- if (!(await stat(path)).isFile())
26
- return err(new BinaryTargetError(path, "target is not a regular file"));
27
- if (targetKind === "database" ||
28
- (targetKind === undefined && path.toLowerCase().endsWith(".hop")))
29
- return ok({
30
- path,
31
- sourcePath: canonical,
32
- sha256: await sha256File(path),
33
- kind: "database",
34
- format: "analysis-database",
35
- });
36
24
  const handle = await open(path, "r");
37
- let detected;
38
25
  try {
26
+ if (!(await handle.stat()).isFile())
27
+ return err(new BinaryTargetError(path, "target is not a regular file"));
28
+ if (targetKind === "database" ||
29
+ (targetKind === undefined && path.toLowerCase().endsWith(".hop")))
30
+ return ok({
31
+ path,
32
+ sourcePath: canonical,
33
+ sha256: await sha256Handle(handle),
34
+ kind: "database",
35
+ format: "analysis-database",
36
+ });
39
37
  const artifactFormat = await detectArtifactFormat(path, handle);
40
38
  if (artifactFormat !== undefined)
41
39
  return ok({
42
40
  path,
43
41
  sourcePath: canonical,
44
- sha256: await sha256File(path),
42
+ sha256: await sha256Handle(handle),
45
43
  kind: isArchiveFormat(artifactFormat) ? "archive" : "artifact",
46
44
  format: artifactFormat,
47
45
  });
48
- detected = await readExecutableMetadata(handle, hostArchitecture);
46
+ const detected = await readExecutableMetadata(handle, hostArchitecture);
47
+ if (!detected.ok)
48
+ return err(new BinaryTargetError(path, detected.error));
49
+ return ok({
50
+ path,
51
+ sourcePath: canonical,
52
+ sha256: await sha256Handle(handle),
53
+ kind: "executable",
54
+ ...detected.value,
55
+ });
49
56
  }
50
57
  finally {
51
58
  await handle.close();
52
59
  }
53
- if (!detected.ok)
54
- return err(new BinaryTargetError(path, detected.error));
55
- return ok({
56
- path,
57
- sourcePath: canonical,
58
- sha256: await sha256File(path),
59
- kind: "executable",
60
- ...detected.value,
61
- });
62
60
  }
63
61
  catch (cause) {
64
62
  return err(new BinaryTargetError(candidate, "path is not readable", { cause }));
@@ -107,10 +105,17 @@ const namedArtifactFormat = (lowerPath) => {
107
105
  return /\.(?:m?js|cjs)$/u.test(lowerPath) ? "javascript" : undefined;
108
106
  };
109
107
  const isArchiveFormat = (format) => ["zip", "ipa", "apk", "asar", "dmg", "pkg"].includes(format);
110
- const sha256File = async (path) => {
108
+ const sha256Handle = async (handle) => {
111
109
  const hash = createHash("sha256");
112
- for await (const chunk of createReadStream(path))
113
- hash.update(chunk);
110
+ const chunk = Buffer.allocUnsafe(64 * 1024);
111
+ let position = 0;
112
+ while (true) {
113
+ const observed = await handle.read(chunk, 0, chunk.length, position);
114
+ if (observed.bytesRead === 0)
115
+ break;
116
+ hash.update(chunk.subarray(0, observed.bytesRead));
117
+ position += observed.bytesRead;
118
+ }
114
119
  return hash.digest("hex");
115
120
  };
116
121
  const resolveAppBundle = async (path) => {
@@ -184,13 +189,7 @@ const readExecutableMetadata = async (handle, hostArchitecture) => {
184
189
  const bytes = prefix.subarray(0, prefixRead.bytesRead);
185
190
  if (bytes.length >= 64 && bytes[0] === 0x4d && bytes[1] === 0x5a) {
186
191
  const offset = bytes.readUInt32LE(0x3c);
187
- if (offset > bytes.length - 6) {
188
- const record = Buffer.alloc(6);
189
- const recordRead = await handle.read(record, 0, record.length, offset);
190
- return recordRead.bytesRead === record.length
191
- ? parsePeRecord(record)
192
- : err("invalid or truncated PE header");
193
- }
192
+ return readPeMetadata(handle, offset);
194
193
  }
195
194
  if (bytes.length >= 8) {
196
195
  const magic = bytes.readUInt32BE(0);
@@ -207,6 +206,20 @@ const readExecutableMetadata = async (handle, hostArchitecture) => {
207
206
  }
208
207
  return parseExecutableHeader(bytes, hostArchitecture);
209
208
  };
209
+ const readPeMetadata = async (handle, offset) => {
210
+ const fileHeader = Buffer.alloc(24);
211
+ const fileHeaderRead = await handle.read(fileHeader, 0, fileHeader.length, offset);
212
+ if (fileHeaderRead.bytesRead !== fileHeader.length)
213
+ return err("invalid or truncated PE header");
214
+ const optionalHeaderSize = fileHeader.readUInt16LE(20);
215
+ if (optionalHeaderSize > 4096)
216
+ return err("invalid PE optional header size");
217
+ const record = Buffer.alloc(24 + optionalHeaderSize);
218
+ const recordRead = await handle.read(record, 0, record.length, offset);
219
+ return recordRead.bytesRead === record.length
220
+ ? parsePeRecord(record)
221
+ : err("invalid or truncated PE header");
222
+ };
210
223
  /**
211
224
  * Parse supported executable headers without I/O. The caller supplies the host
212
225
  * architecture used for deterministic FAT Mach-O slice selection.
@@ -294,22 +307,59 @@ const parsePe = (bytes) => {
294
307
  if (bytes.length < 64)
295
308
  return err("truncated PE DOS header");
296
309
  const offset = bytes.readUInt32LE(0x3c);
297
- if (offset > bytes.length - 6)
310
+ if (offset > bytes.length - 24)
298
311
  return err("invalid or truncated PE header");
299
- return parsePeRecord(bytes.subarray(offset, offset + 6));
312
+ return parsePeRecord(bytes.subarray(offset));
300
313
  };
301
314
  const parsePeRecord = (record) => {
302
- if (record.length < 6 || record.toString("binary", 0, 4) !== "PE\u0000\u0000")
315
+ if (record.length < 24 ||
316
+ record.toString("binary", 0, 4) !== "PE\u0000\u0000")
303
317
  return err("invalid or truncated PE header");
304
318
  const architecture = peArchitecture(record.readUInt16LE(4));
305
319
  if (architecture === undefined)
306
320
  return err("unsupported PE architecture");
321
+ const optionalHeaderSize = record.readUInt16LE(20);
322
+ if (optionalHeaderSize > 4096 || record.length < 24 + optionalHeaderSize)
323
+ return err("invalid or truncated PE optional header");
324
+ const optionalHeader = record.subarray(24, 24 + optionalHeaderSize);
325
+ const managed = peManagedStatus(optionalHeader, architecture);
326
+ if (!managed.ok)
327
+ return managed;
328
+ const characteristics = record.readUInt16LE(22);
307
329
  return ok({
308
330
  format: "pe",
309
331
  architecture,
310
332
  availableArchitectures: [architecture],
333
+ executableRole: (characteristics & 0x0002) === 0
334
+ ? "non-executable"
335
+ : (characteristics & 0x2000) === 0
336
+ ? "application"
337
+ : "shared-library",
338
+ managed: managed.value,
311
339
  });
312
340
  };
341
+ const peManagedStatus = (optionalHeader, architecture) => {
342
+ if (optionalHeader.length < 2)
343
+ return err("truncated PE optional header");
344
+ const magic = optionalHeader.readUInt16LE(0);
345
+ const expectedMagic = architecture === "x86_64" || architecture === "arm64" ? 0x20b : 0x10b;
346
+ if (magic !== expectedMagic)
347
+ return err("PE optional-header magic does not match its architecture");
348
+ const directoryOffset = magic === 0x20b ? 112 : 96;
349
+ const directoryCountOffset = directoryOffset - 4;
350
+ if (optionalHeader.length < directoryCountOffset + 4)
351
+ return err("truncated PE optional header");
352
+ const directoryCount = optionalHeader.readUInt32LE(directoryCountOffset);
353
+ const requiredBytes = directoryOffset + directoryCount * 8;
354
+ if (!Number.isSafeInteger(requiredBytes) ||
355
+ requiredBytes > optionalHeader.length)
356
+ return err("truncated PE data-directory table");
357
+ if (directoryCount <= 14)
358
+ return ok(false);
359
+ const cliDirectory = directoryOffset + 14 * 8;
360
+ return ok(optionalHeader.readUInt32LE(cliDirectory) !== 0 ||
361
+ optionalHeader.readUInt32LE(cliDirectory + 4) !== 0);
362
+ };
313
363
  const machArchitecture = (cpu) => {
314
364
  switch (cpu) {
315
365
  case 7:
@@ -1,7 +1,5 @@
1
1
  import { z } from "zod";
2
- import { browserCompletenessSchema } from "./browserCompleteness.js";
3
- import { webTextArtifactSchema } from "./webContentArtifact.js";
4
- import { jsonShapeSchema } from "./jsonShape.js";
2
+ export { browserTargetListSchema, webPageInspectionSchema, } from "./browserObservationSchemas.js";
5
3
  const parseExactOrigin = (value) => {
6
4
  let url;
7
5
  try {
@@ -306,282 +304,3 @@ export const sanitizeBrowserUrl = (value) => {
306
304
  redacted: wasTruncated || hadCredentials || hadFragment || names.length > 0,
307
305
  };
308
306
  };
309
- const browserVersionSchema = z.object({
310
- product: z.string(),
311
- protocol_version: z.string(),
312
- revision: z.string(),
313
- user_agent: z.string(),
314
- js_version: z.string(),
315
- });
316
- const browserTargetSchema = z.object({
317
- target_id: z.string(),
318
- type: z.string(),
319
- title: z.string(),
320
- url: z.string(),
321
- origin: z.string(),
322
- attached: z.boolean(),
323
- });
324
- /** Bounded and policy-filtered browser target discovery result. */
325
- export const browserTargetListSchema = z.object({
326
- schema_version: z.literal(1),
327
- browser: browserVersionSchema,
328
- targets: z.object({
329
- items: z.array(browserTargetSchema),
330
- offset: z.number().int().min(0),
331
- limit: z.number().int().min(1),
332
- total: z.number().int().min(0),
333
- next_offset: z.number().int().min(0).nullable(),
334
- has_more: z.boolean(),
335
- }),
336
- excluded: z.object({
337
- disallowed_origin: z.number().int().min(0),
338
- unsupported_url: z.number().int().min(0),
339
- non_page: z.number().int().min(0),
340
- }),
341
- limitations: z.array(z.string()),
342
- });
343
- const browserFrameSchema = z.object({
344
- frame_id: z.string(),
345
- parent_frame_id: z.string().nullable(),
346
- url: z.string(),
347
- origin: z.string().nullable(),
348
- });
349
- const browserDomNodeSchema = z.object({
350
- index: z.number().int().min(0),
351
- parent_index: z.number().int().min(-1),
352
- node_type: z.number().int().min(0),
353
- node_name: z.string(),
354
- node_value_length: z.number().int().min(0),
355
- attribute_names: z.array(z.string()),
356
- });
357
- const browserAxNodeSchema = z.object({
358
- node_id: z.string(),
359
- parent_id: z.string().nullable(),
360
- role: z.string().nullable(),
361
- name: z.string().nullable(),
362
- description: z.string().nullable(),
363
- ignored: z.boolean(),
364
- });
365
- const browserScriptSourceSchema = z.discriminatedUnion("included", [
366
- z.object({ included: z.literal(false), reason: z.string() }),
367
- z.object({
368
- included: z.literal(true),
369
- artifact: webTextArtifactSchema,
370
- }),
371
- ]);
372
- const browserResourceReconciliationSchema = z.discriminatedUnion("status", [
373
- z.object({ status: z.literal("exact"), resource_key: z.string() }),
374
- z.object({
375
- status: z.literal("ambiguous"),
376
- candidate_resource_keys: z.array(z.string()),
377
- }),
378
- z.object({
379
- status: z.literal("unmatched"),
380
- reason: z.literal("no_exact_sanitized_url"),
381
- }),
382
- ]);
383
- const browserScriptSchema = z.object({
384
- script_key: z.string().regex(/^scr_[a-f0-9]{64}(?:_[0-9]+)?$/u),
385
- url: z.string(),
386
- origin: z.string().nullable(),
387
- cdp_hash: z.string(),
388
- length: z.number().int().min(0),
389
- is_module: z.boolean(),
390
- language: z.string().nullable(),
391
- source_map_url: z.string().nullable(),
392
- resource_reconciliation: browserResourceReconciliationSchema,
393
- source: browserScriptSourceSchema,
394
- });
395
- const browserResourceSchema = z.object({
396
- resource_key: z.string().regex(/^res_[a-f0-9]{64}$/u),
397
- url: z.string(),
398
- origin: z.string().nullable(),
399
- type: z.string(),
400
- mime_type: z.string(),
401
- content_size: z.number().min(0).nullable(),
402
- });
403
- const browserNetworkRequestSchema = z.object({
404
- request_id: z.string(),
405
- url: z.string(),
406
- origin: z.string().nullable(),
407
- method: z.string(),
408
- resource_type: z.string().nullable(),
409
- status: z.number().nullable(),
410
- mime_type: z.string().nullable(),
411
- encoded_data_length: z.number().min(0).nullable(),
412
- initiator: z.object({
413
- type: z.string(),
414
- url: z.string().nullable(),
415
- line: z.number().int().min(0).nullable(),
416
- column: z.number().int().min(0).nullable(),
417
- }),
418
- body_shapes: z.object({
419
- status: z.enum([
420
- "not_approved",
421
- "included",
422
- "partial",
423
- "unavailable",
424
- "truncated",
425
- ]),
426
- request: jsonShapeSchema.nullable(),
427
- response: jsonShapeSchema.nullable(),
428
- }),
429
- });
430
- const browserConsoleEventSchema = z.object({
431
- type: z.string(),
432
- timestamp: z.number(),
433
- argument_types: z.array(z.string()),
434
- url: z.string().nullable(),
435
- line: z.number().int().min(0).nullable(),
436
- column: z.number().int().min(0).nullable(),
437
- text_capture: z.object({
438
- status: z.enum(["not_approved", "included", "truncated"]),
439
- values: z.array(z.object({
440
- argument_index: z.number().int().min(0),
441
- type: z.string(),
442
- text: z.string(),
443
- })),
444
- retained_bytes: z.number().int().min(0),
445
- truncated_values: z.number().int().min(0),
446
- }),
447
- });
448
- const browserWebSocketEventSchema = z.object({
449
- request_id: z.string(),
450
- direction: z.enum(["sent", "received"]),
451
- opcode: z.number().int().min(0),
452
- payload_bytes: z.number().int().min(0),
453
- payload_shape: z
454
- .object({
455
- format: z.enum(["json", "text", "binary"]),
456
- json_shape: jsonShapeSchema.nullable(),
457
- truncated: z.boolean(),
458
- })
459
- .nullable(),
460
- });
461
- const browserWorkerSchema = z.object({
462
- target_id: z.string(),
463
- type: z.string(),
464
- url: z.string(),
465
- origin: z.string().nullable(),
466
- attached: z.boolean(),
467
- });
468
- const browserCspSourceSchema = z.object({
469
- kind: z.enum([
470
- "keyword",
471
- "scheme",
472
- "approved_origin",
473
- "external_origin",
474
- "other",
475
- ]),
476
- value: z.string().nullable(),
477
- });
478
- const browserLinkMetadataSchema = z.object({
479
- href: z.string().nullable(),
480
- destination_scope: z.enum(["approved", "outside_policy", "unsupported"]),
481
- rel: z.array(z.string()),
482
- as: z.string().nullable(),
483
- type: z.string().nullable(),
484
- crossorigin: z.string().nullable(),
485
- });
486
- const browserAgentHintSchema = z.object({
487
- mechanism: z.enum([
488
- "link_rel",
489
- "dom_link_rel",
490
- "well_known_resource",
491
- "response_header",
492
- ]),
493
- declaration: z.string(),
494
- url: z.string().nullable(),
495
- trust: z.literal("page-declared-untrusted"),
496
- });
497
- const browserSafeMetadataSchema = z.object({
498
- responses: z.array(z.object({
499
- request_id: z.string(),
500
- url: z.string(),
501
- mime_type: z.string().nullable(),
502
- content_length: z.number().int().min(0).nullable(),
503
- content_encoding: z.string().nullable(),
504
- csp: z.object({
505
- directives: z.array(z.object({
506
- name: z.string(),
507
- sources: z.array(browserCspSourceSchema),
508
- })),
509
- nonce_count: z.number().int().min(0),
510
- hash_count: z.number().int().min(0),
511
- }),
512
- links: z.array(browserLinkMetadataSchema),
513
- policies: z.object({
514
- coop: z.string().nullable(),
515
- coep: z.string().nullable(),
516
- corp: z.string().nullable(),
517
- referrer_policy: z.string().nullable(),
518
- x_content_type_options: z.string().nullable(),
519
- permissions_policy_features: z.array(z.string()),
520
- }),
521
- })),
522
- dom_urls: z.array(z.object({
523
- node_index: z.number().int().min(0),
524
- attribute: z.enum(["href", "src", "action", "formaction", "poster"]),
525
- url: z.string().nullable(),
526
- destination_scope: z.enum(["approved", "outside_policy", "unsupported"]),
527
- })),
528
- agent_hints: z.array(browserAgentHintSchema),
529
- excluded_dom_urls: z.number().int().min(0),
530
- headers_allowlisted: z.literal(true),
531
- });
532
- /** Provider-neutral normalized result for one passive web-page observation. */
533
- export const webPageInspectionSchema = z.object({
534
- schema_version: z.literal(2),
535
- browser: browserVersionSchema,
536
- target: browserTargetSchema,
537
- capture_window: z.object({
538
- started_at: z.iso.datetime(),
539
- ended_at: z.iso.datetime(),
540
- observation_ms: z.number().int().min(0),
541
- }),
542
- completeness: browserCompletenessSchema,
543
- frames: z.array(browserFrameSchema),
544
- dom: z.object({
545
- total_nodes: z.number().int().min(0),
546
- nodes: z.array(browserDomNodeSchema),
547
- }),
548
- accessibility: z.object({
549
- total_nodes: z.number().int().min(0),
550
- text_capture: z.object({
551
- status: z.enum(["not_approved", "included", "truncated", "unavailable"]),
552
- retained_bytes: z.number().int().min(0),
553
- excluded_fields: z.number().int().min(0),
554
- truncated_fields: z.number().int().min(0),
555
- }),
556
- nodes: z.array(browserAxNodeSchema),
557
- }),
558
- scripts: z.object({
559
- total: z.number().int().min(0),
560
- items: z.array(browserScriptSchema),
561
- }),
562
- resources: z.array(browserResourceSchema),
563
- network: z.object({
564
- requests: z.array(browserNetworkRequestSchema),
565
- websocket_events: z.array(browserWebSocketEventSchema),
566
- coverage_started_at: z.iso.datetime(),
567
- prior_activity_available: z.literal(false),
568
- }),
569
- console: z.object({
570
- events: z.array(browserConsoleEventSchema),
571
- coverage_started_at: z.iso.datetime(),
572
- prior_activity_available: z.literal(false),
573
- }),
574
- workers: z.array(browserWorkerSchema),
575
- metadata: browserSafeMetadataSchema,
576
- storage: z.object({
577
- origin: z.string(),
578
- usage_bytes: z.number().min(0).nullable(),
579
- quota_bytes: z.number().min(0).nullable(),
580
- local_storage_keys: z.array(z.string()),
581
- session_storage_keys: z.array(z.string()),
582
- indexed_db_names: z.array(z.string()),
583
- cache_names: z.array(z.string()),
584
- values_redacted: z.literal(true),
585
- }),
586
- limitations: z.array(z.string()),
587
- });