rea-agents 6.3.0 → 6.4.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 (487) hide show
  1. package/README.md +7 -4
  2. package/bridge/ghidra/ReaGhidraApplySeeds.java +151 -0
  3. package/bridge/ghidra/ReaGhidraBridge.java +597 -209
  4. package/bridge/ghidra/ReaGhidraNoReturnFix.java +123 -0
  5. package/dist/adb/AdbConfiguration.js +88 -0
  6. package/dist/adb/AdbDeviceOutput.js +186 -0
  7. package/dist/adb/AdbProvider.js +1190 -0
  8. package/dist/adb/AdbShellOutput.js +309 -0
  9. package/dist/android/AndroidTargetSnapshot.js +104 -22
  10. package/dist/android/JadxConfiguration.js +44 -24
  11. package/dist/android/JadxProvider.js +51 -19
  12. package/dist/apktool/ApktoolConfiguration.js +84 -0
  13. package/dist/apktool/ApktoolDecodeOutput.js +59 -0
  14. package/dist/apktool/ApktoolProvider.js +506 -0
  15. package/dist/application/AnalysisProvider.js +8 -2
  16. package/dist/application/AppBundleExecutable.js +27 -22
  17. package/dist/application/BinaryTargetResolver.js +22 -2
  18. package/dist/application/CapabilityInventory.js +11 -1
  19. package/dist/application/ClientConfigurationDocument.js +70 -0
  20. package/dist/application/ClientConfigurationFiles.js +91 -0
  21. package/dist/application/ClientRegistrationEnvironment.js +35 -0
  22. package/dist/application/ClientRegistrationStatus.js +66 -31
  23. package/dist/application/DirectAnalysis.js +2 -2
  24. package/dist/application/DirectAnalysisCleanup.js +1 -1
  25. package/dist/application/DirectAnalysisStatus.js +1 -1
  26. package/dist/application/Doctor.js +5 -3
  27. package/dist/application/DoctorDiagnostics.js +1 -1
  28. package/dist/application/EvidenceBundleCommands.js +6 -12
  29. package/dist/application/GeminiClientSettings.js +139 -0
  30. package/dist/application/HermesClientHome.js +115 -0
  31. package/dist/application/HopperDownload.js +39 -0
  32. package/dist/application/InvestigationProviders.js +6 -0
  33. package/dist/application/JsonFiles.js +6 -5
  34. package/dist/{cliJsonFile.js → application/JsonInputFile.js} +108 -35
  35. package/dist/application/LinuxHopper.js +4 -12
  36. package/dist/application/MacHopper.js +172 -149
  37. package/dist/application/MipsElfAbiFlags.js +140 -0
  38. package/dist/application/ProviderOperationExecution.js +31 -0
  39. package/dist/application/ReconstructionObligationCandidates.js +9 -3
  40. package/dist/application/ReferenceSourceImport.js +76 -29
  41. package/dist/application/ReferenceSourceImportEntries.js +18 -9
  42. package/dist/application/ReferenceSourceImportPolicy.js +99 -23
  43. package/dist/application/ReferenceSourceImportTypes.js +30 -22
  44. package/dist/application/ReferenceSourceVcsAdapter.js +145 -30
  45. package/dist/application/RegularFileRead.js +93 -7
  46. package/dist/application/Setup.js +54 -6
  47. package/dist/application/SetupClientConfiguration.js +116 -16
  48. package/dist/application/SetupHost.js +102 -24
  49. package/dist/application/SetupPlan.js +5 -8
  50. package/dist/application/SetupSkill.js +58 -39
  51. package/dist/application/SupportedClients.js +290 -65
  52. package/dist/application/Uninstall.js +158 -10
  53. package/dist/application/UpdateMaintenance.js +17 -21
  54. package/dist/application/Utf8JsonInput.js +7 -0
  55. package/dist/application/WebScriptExportService.js +131 -65
  56. package/dist/application/WebSourceLocationService.js +3 -0
  57. package/dist/application/adb/AdbDeviceAnalysisPort.js +1 -0
  58. package/dist/application/adb/AdbDeviceAnalysisService.js +13 -0
  59. package/dist/application/analysisView/AnalysisViewService.js +40 -2
  60. package/dist/application/apktool/ApktoolResourceAnalysisPort.js +1 -0
  61. package/dist/application/apktool/ApktoolResourceAnalysisService.js +13 -0
  62. package/dist/application/binary/AnalysisClientCleanup.js +0 -24
  63. package/dist/application/binary/BinarySession.js +2 -1
  64. package/dist/application/binaryDiagnostics/BinaryLayoutService.js +2 -1
  65. package/dist/application/binaryDiagnostics/PeResourcesPort.js +1 -0
  66. package/dist/application/binaryDiagnostics/PeResourcesService.js +111 -0
  67. package/dist/application/binaryDiagnostics/RecordedCrashService.js +2 -1
  68. package/dist/application/evm/EvmInterfaceService.js +3 -0
  69. package/dist/application/firmware/FirmwareAnalysisService.js +3 -0
  70. package/dist/application/investigation/InspectEvidenceBundle.js +18 -0
  71. package/dist/application/javascript/ElectronBoundaryGraphContext.js +3 -2
  72. package/dist/application/javascript/ElectronBoundaryGraphIpc.js +2 -2
  73. package/dist/application/javascript/ElectronBoundaryGraphNative.js +19 -6
  74. package/dist/application/javascript/ElectronBoundaryGraphWindows.js +3 -3
  75. package/dist/application/javascript/JavaScriptApplicationService.js +22 -11
  76. package/dist/application/javascript/JavaScriptApplicationWorkflowEvidence.js +5 -6
  77. package/dist/application/javascript/JavaScriptArtifactAnalysis.js +171 -30
  78. package/dist/application/javascript/JavaScriptArtifactGraphAccumulator.js +14 -16
  79. package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +67 -19
  80. package/dist/application/javascript/JavaScriptArtifactGraphBundlers.js +4 -3
  81. package/dist/application/javascript/JavaScriptArtifactGraphContext.js +11 -5
  82. package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +19 -16
  83. package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +92 -10
  84. package/dist/application/javascript/JavaScriptArtifactPathResolution.js +258 -235
  85. package/dist/application/javascript/JavaScriptArtifactReconstruction.js +115 -26
  86. package/dist/application/javascript/JavaScriptArtifactReconstructionInput.js +4 -1
  87. package/dist/application/javascript/JavaScriptModuleRelationships.js +6 -4
  88. package/dist/application/javascript/JavaScriptRecoveryService.js +3 -0
  89. package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +9 -3
  90. package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +199 -61
  91. package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +12 -19
  92. package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +4 -1
  93. package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +5 -3
  94. package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +5 -3
  95. package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +19 -8
  96. package/dist/application/jeb/JebAnalysisPort.js +1 -0
  97. package/dist/application/jeb/JebAnalysisService.js +13 -0
  98. package/dist/application/managed/ManagedApplicationGraphService.js +1 -1
  99. package/dist/application/native/NativeUiActionTrace.js +16 -8
  100. package/dist/application/native/NativeValueTrace.js +23 -6
  101. package/dist/application/process/ProcessCli.js +25 -20
  102. package/dist/artifacts/ArtifactPaths.js +129 -8
  103. package/dist/artifacts/ArtifactProvider.js +20 -15
  104. package/dist/artifacts/ArtifactReader.js +23 -0
  105. package/dist/artifacts/ArtifactResourceScope.js +100 -0
  106. package/dist/artifacts/AsarArtifactReader.js +176 -102
  107. package/dist/artifacts/AsarHeader.js +24 -0
  108. package/dist/artifacts/DirectoryArtifactReader.js +168 -65
  109. package/dist/artifacts/MachOSliceArtifactReader.js +116 -39
  110. package/dist/artifacts/NativeDmgArtifactReader.js +29 -22
  111. package/dist/artifacts/SafeOutputTree.js +245 -70
  112. package/dist/artifacts/SafeOutputTreeCleanup.js +45 -0
  113. package/dist/artifacts/SafeOutputTreeCreationFailure.js +20 -0
  114. package/dist/artifacts/SafeOutputTreeIdentity.js +42 -0
  115. package/dist/artifacts/SafeOutputTreeReadback.js +33 -0
  116. package/dist/artifacts/ZipArtifactReader.js +77 -27
  117. package/dist/artifacts/apple/InterfaceBuilderAnalysis.js +58 -18
  118. package/dist/artifacts/apple/InterfaceBuilderDecodeBudget.js +62 -24
  119. package/dist/artifacts/apple/KeyedArchiveReader.js +32 -13
  120. package/dist/artifacts/extraction/ArtifactExtraction.js +110 -86
  121. package/dist/artifacts/inventory/ArtifactGraphConstruction.js +110 -43
  122. package/dist/artifacts/inventory/ArtifactInventory.js +5 -4
  123. package/dist/artifacts/inventory/classify.js +75 -32
  124. package/dist/artifacts/inventory/hashStableRootArtifact.js +48 -15
  125. package/dist/artifacts/inventory/reader.js +13 -5
  126. package/dist/artifacts/inventory/scanCanonical.js +62 -25
  127. package/dist/artifacts/inventory/scanReader.js +38 -11
  128. package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +15 -9
  129. package/dist/artifacts/javascript/JavaScriptSourceAnalysis.js +3 -0
  130. package/dist/browser/BrowserScenarioPartialObservation.js +8 -2
  131. package/dist/browser/BrowserScenarioSecrets.js +52 -37
  132. package/dist/browser/CdpBrowserProvider.js +5 -0
  133. package/dist/browser/CdpCaptureDocuments.js +40 -6
  134. package/dist/browser/CdpCaptureDomSvg.js +210 -0
  135. package/dist/browser/CdpCaptureEventBodyShapes.js +4 -8
  136. package/dist/browser/CdpCaptureEventHandlers.js +26 -9
  137. package/dist/browser/CdpCaptureEvents.js +4 -9
  138. package/dist/browser/CdpConnection.js +22 -5
  139. package/dist/browser/CdpPageCapture.js +1 -1
  140. package/dist/browser/CdpTargetSession.js +30 -34
  141. package/dist/browser/CdpWebMcpDiscovery.js +32 -10
  142. package/dist/browser/ElectronFileScope.js +99 -9
  143. package/dist/browser/PlaywrightBrowserScenarioProvider.js +60 -4
  144. package/dist/browser/PlaywrightElectronActiveProvider.js +11 -6
  145. package/dist/browser/PlaywrightScenarioArtifacts.js +5 -5
  146. package/dist/browser/PlaywrightScenarioBrowser.js +69 -7
  147. package/dist/browser/PlaywrightScenarioSession.js +127 -54
  148. package/dist/browser/PlaywrightScenarioStorage.js +507 -0
  149. package/dist/browser/PngVisualDiff.js +198 -29
  150. package/dist/browser/WebSourceMapFetcher.js +3 -3
  151. package/dist/browser/assets/LocalWebScriptArtifacts.js +3 -1
  152. package/dist/browser/assets/PublishWebScripts.js +75 -20
  153. package/dist/browser/assets/WebArtifactReads.js +23 -1
  154. package/dist/browser/assets/WebSourceLocationArtifacts.js +1 -0
  155. package/dist/browser/execution/CdpExecutionCapture.js +3 -3
  156. package/dist/browser/execution/CdpPreciseCoverage.js +5 -8
  157. package/dist/browser/history/HarCapture.js +14 -0
  158. package/dist/browser/history/HarCaptureProcess.js +2 -10
  159. package/dist/browser/history/MitmproxyCaptureAdapter.js +3 -1
  160. package/dist/browser/modules/WebModuleArtifacts.js +1 -0
  161. package/dist/cli/adbCommands.js +337 -0
  162. package/dist/cli/analysisViewCommands.js +39 -1
  163. package/dist/cli/apktoolCommands.js +53 -0
  164. package/dist/cli/artifactCommands.js +8 -11
  165. package/dist/cli/binaryDiagnosticsCommands.js +19 -1
  166. package/dist/cli/browserAdvancedCommands.js +65 -36
  167. package/dist/cli/coreBinaryCommands.js +0 -5
  168. package/dist/cli/coreNativeCommands.js +1 -14
  169. package/dist/cli/electronCommands.js +6 -1
  170. package/dist/cli/evmCommands.js +13 -4
  171. package/dist/cli/firmwareCommands.js +7 -2
  172. package/dist/cli/javascriptApplicationAnalysis.js +17 -1
  173. package/dist/cli/javascriptRecoveryCommands.js +22 -15
  174. package/dist/cli/jebCommands.js +99 -0
  175. package/dist/cli/jsonOutput.js +11 -4
  176. package/dist/cli/referenceSourceImportStatus.js +7 -0
  177. package/dist/cli/setupCommands.js +15 -3
  178. package/dist/cli/utilityCommands.js +66 -18
  179. package/dist/cli/webScriptCommands.js +20 -1
  180. package/dist/cli/webSourceLocationCommands.js +21 -9
  181. package/dist/cli.js +6 -0
  182. package/dist/cliBrowserScenarioCommands.js +2 -1
  183. package/dist/cliCommandNames.js +32 -0
  184. package/dist/cliJsonInput.js +2 -2
  185. package/dist/cliObservationOptions.js +3 -0
  186. package/dist/composition/adb.js +3 -0
  187. package/dist/composition/apktool.js +3 -0
  188. package/dist/composition/binaryDiagnostics.js +4 -0
  189. package/dist/composition/directAnalysis.js +12 -4
  190. package/dist/composition/javascriptAnalysisWorkerProcess.js +48 -0
  191. package/dist/composition/jeb.js +6 -0
  192. package/dist/config/environment.js +10 -0
  193. package/dist/config/ghidraLanguageOverride.js +9 -0
  194. package/dist/config/mcpInputSchemaProfile.js +27 -0
  195. package/dist/config/parseConfig.js +28 -1
  196. package/dist/contracts/adb/adbToolContracts.js +353 -0
  197. package/dist/contracts/advertisedInputExamples.js +48 -0
  198. package/dist/contracts/analysisDetail.js +10 -0
  199. package/dist/contracts/analysisViewToolContracts.js +17 -2
  200. package/dist/contracts/apktool/apktoolToolContracts.js +33 -0
  201. package/dist/contracts/artifactToolContracts.js +8 -5
  202. package/dist/contracts/browserToolContracts.js +1 -1
  203. package/dist/contracts/compactInputSchema.js +256 -0
  204. package/dist/contracts/functionWorkflowToolContracts.js +1 -1
  205. package/dist/contracts/inputSchemaPresentation.js +10 -10
  206. package/dist/contracts/javascript/electronToolContracts.js +15 -3
  207. package/dist/contracts/javascript/javascriptRecoveryToolContracts.js +1 -1
  208. package/dist/contracts/jeb/jebToolContracts.js +64 -0
  209. package/dist/contracts/native/binaryDiagnosticsToolContracts.js +25 -3
  210. package/dist/contracts/officialToolContracts.js +5 -5
  211. package/dist/contracts/sessionToolContracts.js +2 -2
  212. package/dist/contracts/sessionToolSchemas.js +6 -2
  213. package/dist/contracts/toolContractExamples.js +6 -0
  214. package/dist/contracts/toolContractTypes.js +3 -0
  215. package/dist/contracts/toolContracts.js +6 -0
  216. package/dist/contracts/toolEffects.js +167 -0
  217. package/dist/contracts/toolOutputSchemaGroups.js +5 -3
  218. package/dist/contracts/toolSchemaMetadata.js +82 -7
  219. package/dist/domain/adb/adbDeviceAnalysis.js +583 -0
  220. package/dist/domain/analysisErrorCleanup.js +29 -0
  221. package/dist/domain/analysisErrorPresentation.js +18 -6
  222. package/dist/domain/analysisErrorProjection.js +4 -1
  223. package/dist/domain/analysisSnapshot.js +2 -1
  224. package/dist/domain/analysisView/analysisView.js +52 -2
  225. package/dist/domain/analysisView/binaryLayoutView.js +2 -0
  226. package/dist/domain/analysisView/javascriptApplicationView.js +2 -0
  227. package/dist/domain/analysisView/nativeFunctionView.js +155 -0
  228. package/dist/domain/android/androidApplication.js +25 -20
  229. package/dist/domain/apktool/apktoolResourceAnalysis.js +77 -0
  230. package/dist/domain/apple/appleApplication.js +40 -23
  231. package/dist/domain/apple/appleBundleAnatomy.js +95 -28
  232. package/dist/domain/apple/dyldPaths.js +9 -1
  233. package/dist/domain/apple/dylibResolution.js +2 -2
  234. package/dist/domain/apple/interfaceBuilderGraph.js +22 -19
  235. package/dist/domain/apple/interfaceBuilderKeyedArchive.js +10 -1
  236. package/dist/domain/artifactComparison.js +35 -7
  237. package/dist/domain/artifactGraph.js +5 -3
  238. package/dist/domain/artifactIdentity.js +30 -2
  239. package/dist/domain/artifactInspection.js +3 -43
  240. package/dist/domain/artifactIntegrityPolicy.js +10 -0
  241. package/dist/domain/artifactInventoryEvidence.js +11 -12
  242. package/dist/domain/artifactPathSyntax.js +1 -1
  243. package/dist/domain/binaryTarget.js +16 -0
  244. package/dist/domain/binaryTargetTypes.js +8 -1
  245. package/dist/domain/browserObservationSchemas.js +8 -4
  246. package/dist/domain/canonicalJsonDigestSteps.js +34 -12
  247. package/dist/domain/compactStringIdentity.js +9 -0
  248. package/dist/domain/evidence.js +2 -1
  249. package/dist/domain/evidenceRecordSummary.js +144 -0
  250. package/dist/domain/inputIssueProjection.js +16 -1
  251. package/dist/domain/javascript/electronStaticAnalysisBrowser.js +12 -13
  252. package/dist/domain/javascript/electronStaticAnalysisIpc.js +11 -20
  253. package/dist/domain/javascript/electronStaticAnalysisNative.js +70 -40
  254. package/dist/domain/javascript/electronStaticAnalysisValues.js +16 -0
  255. package/dist/domain/javascript/javascriptAnalysisResourceControls.js +45 -0
  256. package/dist/domain/javascript/javascriptApplicationAnalysis.js +4 -1
  257. package/dist/domain/javascript/javascriptApplicationChangeGraph.js +6 -6
  258. package/dist/domain/javascript/javascriptApplicationGraph.js +79 -18
  259. package/dist/domain/javascript/javascriptApplicationProjectionResources.js +35 -0
  260. package/dist/domain/javascript/javascriptApplicationVersionItems.js +28 -12
  261. package/dist/domain/javascript/javascriptApplicationVersionKeys.js +9 -1
  262. package/dist/domain/javascript/javascriptAstFingerprint.js +58 -31
  263. package/dist/domain/javascript/javascriptAstValues.js +32 -0
  264. package/dist/domain/javascript/javascriptElectronMemberWrites.js +50 -0
  265. package/dist/domain/javascript/javascriptModuleSemanticIr.js +15 -0
  266. package/dist/domain/javascript/javascriptNativeHandoff.js +6 -1
  267. package/dist/domain/javascript/javascriptRpcEndpoints.js +253 -0
  268. package/dist/domain/javascript/javascriptRuntimeLoadState.js +1 -3
  269. package/dist/domain/javascript/javascriptRuntimeReconciliationGraph.js +7 -2
  270. package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +8 -11
  271. package/dist/domain/javascript/javascriptSemanticAnalysis.js +190 -33
  272. package/dist/domain/javascript/javascriptSemanticCallableResults.js +42 -0
  273. package/dist/domain/javascript/javascriptSemanticCalls.js +8 -1
  274. package/dist/domain/javascript/javascriptSemanticDerivedAnalysis.js +15 -4
  275. package/dist/domain/javascript/javascriptSemanticFileProjection.js +1 -0
  276. package/dist/domain/javascript/javascriptSemanticFingerprints.js +42 -41
  277. package/dist/domain/javascript/javascriptSemanticGraph.js +69 -23
  278. package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +2 -10
  279. package/dist/domain/javascript/javascriptSemanticIterationSources.js +40 -7
  280. package/dist/domain/javascript/javascriptSemanticMemberMutations.js +341 -87
  281. package/dist/domain/javascript/javascriptSemanticMutationValues.js +78 -35
  282. package/dist/domain/javascript/javascriptSemanticObjectReferences.js +381 -0
  283. package/dist/domain/javascript/javascriptSemanticObjects.js +7 -1
  284. package/dist/domain/javascript/javascriptSemanticProjection.js +52 -14
  285. package/dist/domain/javascript/javascriptSemanticPropertyPaths.js +77 -0
  286. package/dist/domain/javascript/javascriptSemanticQuery.js +27 -29
  287. package/dist/domain/javascript/javascriptSemanticQueryIdentity.js +1 -3
  288. package/dist/domain/javascript/javascriptSemanticReturnedReferences.js +219 -0
  289. package/dist/domain/javascript/javascriptSemanticReturns.js +13 -23
  290. package/dist/domain/javascript/javascriptSemanticState.js +22 -2
  291. package/dist/domain/javascript/javascriptSemanticTraversal.js +19 -1
  292. package/dist/domain/javascript/javascriptSemanticValues.js +47 -19
  293. package/dist/domain/javascript/javascriptSourceAnalysis.js +1 -0
  294. package/dist/domain/javascript/javascriptStaticAnalysis.js +29 -17
  295. package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +8 -6
  296. package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +49 -5
  297. package/dist/domain/javascript/javascriptStaticAnalysisFindings.js +8 -4
  298. package/dist/domain/javascript/javascriptStaticAnalysisState.js +1 -0
  299. package/dist/domain/jeb/jebAnalysis.js +114 -0
  300. package/dist/domain/jsonShape.js +63 -52
  301. package/dist/domain/jsonValue.js +3 -0
  302. package/dist/domain/managed/managedApplicationGraph.js +37 -0
  303. package/dist/domain/managed/managedApplicationGraphCoverage.js +8 -2
  304. package/dist/domain/managed/managedApplicationGraphNodes.js +32 -22
  305. package/dist/domain/managed/managedArtifact.js +1 -0
  306. package/dist/domain/managed/managedInspectionEvidence.js +13 -0
  307. package/dist/domain/native/nativeAotPe.js +1408 -0
  308. package/dist/domain/native/nativeInstruction.js +21 -0
  309. package/dist/domain/native/nativeMetadataRecovery.js +79 -6
  310. package/dist/domain/native/peResources.js +94 -0
  311. package/dist/domain/nativeConvention.js +33 -0
  312. package/dist/domain/process/processCapture.js +91 -1
  313. package/dist/domain/process/processCaptureExample.js +24 -0
  314. package/dist/domain/process/processCaptureValidation.js +79 -0
  315. package/dist/domain/process/processScenario.js +59 -7
  316. package/dist/domain/propertyListKeys.js +3 -1
  317. package/dist/domain/referenceSourceGraph.js +25 -16
  318. package/dist/domain/referenceSourceImportParsing.js +6 -3
  319. package/dist/domain/referenceSourcePathIdentity.js +22 -0
  320. package/dist/domain/referenceSourceRequireBindings.js +137 -0
  321. package/dist/domain/webBundleAnalyzerInspection.js +14 -2
  322. package/dist/domain/webCaptureDiff.js +102 -4
  323. package/dist/domain/webScriptExportError.js +10 -4
  324. package/dist/domain/webScriptExportPlan.js +7 -13
  325. package/dist/domain/zipPackageFormat.js +4 -1
  326. package/dist/domain/zodCollectionSteps.js +24 -0
  327. package/dist/dotnet/ManagedArtifactInspector.js +55 -43
  328. package/dist/dotnet/ManagedDecodeBudget.js +80 -0
  329. package/dist/dotnet/ManagedMemberInspector.js +13 -6
  330. package/dist/dotnet/ManagedMemberInspectorCore.js +2 -2
  331. package/dist/dotnet/ManagedMemberInstructionDecoder.js +4 -2
  332. package/dist/dotnet/ManagedMemberRows.js +9 -4
  333. package/dist/dotnet/ManagedMetadataHeaps.js +15 -5
  334. package/dist/dotnet/ManagedMetadataInventoryRows.js +20 -11
  335. package/dist/dotnet/ManagedMetadataLayout.js +10 -4
  336. package/dist/dotnet/ManagedMethodBodyReader.js +8 -3
  337. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +3 -2
  338. package/dist/dotnet/ManagedNativeBoundaryInspector.js +49 -34
  339. package/dist/dotnet/ManagedPeReader.js +41 -25
  340. package/dist/dotnet/ManagedReaderFailure.js +2 -1
  341. package/dist/dotnet/ManagedStaticProvider.js +55 -24
  342. package/dist/evaluation/AgentEvaluationReport.js +9 -5
  343. package/dist/evaluation/CodexAgentEval.js +43 -13
  344. package/dist/evm/EvmoleFailures.js +0 -2
  345. package/dist/evm/EvmoleInterfaceProvider.js +67 -2
  346. package/dist/filesystem/OwnedDirectoryHandle.js +29 -0
  347. package/dist/filesystem/OwnedFileHandle.js +36 -0
  348. package/dist/filesystem/RegularFile.js +33 -1
  349. package/dist/filesystem/StableFileHash.js +46 -0
  350. package/dist/filesystem/readFileHandleChunks.js +26 -0
  351. package/dist/firmware/FirmwareCommand.js +25 -3
  352. package/dist/firmware/FirmwareFiles.js +23 -8
  353. package/dist/firmware/FirmwareProvider.js +156 -32
  354. package/dist/firmware/FirmwarePublication.js +24 -3
  355. package/dist/firmware/FirmwareRelease.js +1 -0
  356. package/dist/generatedPackageMetadata.js +2 -2
  357. package/dist/ghidra/GhidraAnalysisProfile.js +55 -4
  358. package/dist/ghidra/GhidraAnalysisSeeds.js +211 -0
  359. package/dist/ghidra/GhidraClient.js +76 -4
  360. package/dist/ghidra/GhidraDiagnostics.js +11 -8
  361. package/dist/ghidra/GhidraFunctionValues.js +26 -2
  362. package/dist/ghidra/GhidraInstallation.js +1 -1
  363. package/dist/ghidra/GhidraInventoryValues.js +23 -1
  364. package/dist/ghidra/GhidraLanguageCatalog.js +99 -0
  365. package/dist/ghidra/GhidraLauncher.js +80 -39
  366. package/dist/ghidra/GhidraLoadImageAttest.js +49 -2
  367. package/dist/ghidra/GhidraMipsProfile.js +79 -0
  368. package/dist/ghidra/GhidraProvider.js +57 -9
  369. package/dist/ghidra/GhidraProviderCapabilities.js +18 -8
  370. package/dist/ghidra/GhidraProviderClient.js +282 -21
  371. package/dist/ghidra/GhidraSessionValues.js +9 -2
  372. package/dist/hopper/HopperAnalysisProfile.js +2 -0
  373. package/dist/hopper/HopperClient.js +15 -6
  374. package/dist/hopper/HopperMachOImage.js +2 -0
  375. package/dist/hopper/HopperProvider.js +13 -2
  376. package/dist/ida/IdaOperationRunner.js +8 -2
  377. package/dist/ida/IdaProvider.js +7 -0
  378. package/dist/ida/IdaSessionClient.js +3 -1
  379. package/dist/ida/IdaWorkspace.js +4 -2
  380. package/dist/javascript/analysis/JavaScriptAnalysisTransfer.js +326 -0
  381. package/dist/javascript/analysis/JavaScriptAnalysisWorker.js +520 -0
  382. package/dist/javascript/analysis/JavaScriptAnalysisWorkerProtocol.js +63 -0
  383. package/dist/javascript/analysis/JavaScriptAnalysisWorkerSchemas.js +521 -0
  384. package/dist/javascript/analysis/JavaScriptAnalysisWorkerServer.js +116 -0
  385. package/dist/javascript/recovery/RecoveryFiles.js +18 -7
  386. package/dist/javascript/recovery/WakaruCommand.js +22 -9
  387. package/dist/javascript/recovery/WakaruExecution.js +11 -7
  388. package/dist/javascript/recovery/WakaruProvider.js +139 -16
  389. package/dist/javascript/recovery/WakaruPublication.js +14 -4
  390. package/dist/javascript/recovery/WakaruRelease.js +10 -3
  391. package/dist/javascript/recovery/WakaruReport.js +12 -7
  392. package/dist/javascript/recovery/WakaruVersion.js +24 -0
  393. package/dist/javascript/sourceMaps/SourceMapCommand.js +16 -3
  394. package/dist/javascript/sourceMaps/SourceMapDecoder.js +63 -7
  395. package/dist/javascript/sourceMaps/SourceMapFormat.js +15 -4
  396. package/dist/jeb/JebMcpConnection.js +179 -0
  397. package/dist/jeb/JebMcpEndpoint.js +40 -0
  398. package/dist/jeb/JebProvider.js +299 -0
  399. package/dist/mcpDoctor.js +15 -6
  400. package/dist/native/AppleDispatchCoverage.js +25 -12
  401. package/dist/native/AppleDispatchMetadata.js +14 -7
  402. package/dist/native/AppleMachoFixups.js +71 -15
  403. package/dist/native/AppleMachoSelection.js +23 -3
  404. package/dist/native/NativeMacOSProvider.js +91 -16
  405. package/dist/native/NativeMachoInspection.js +11 -7
  406. package/dist/native/NativeUiHelperRuntime.js +6 -1
  407. package/dist/native/NativeUiObservation.js +4 -3
  408. package/dist/native/pe/PeResourceLayout.js +120 -0
  409. package/dist/native/pe/PeResourceParser.js +286 -0
  410. package/dist/native/pe/PeResourcesProvider.js +63 -0
  411. package/dist/process/BoundedFileBytes.js +30 -7
  412. package/dist/process/DarwinProcessRunTokenReader.js +8 -3
  413. package/dist/process/OwnedCommand.js +4 -3
  414. package/dist/process/ProcessOwnership.js +104 -112
  415. package/dist/process/ProcessOwnershipObservation.js +96 -39
  416. package/dist/process/ProcessOwnershipProcessTree.js +4 -4
  417. package/dist/process/ProcessRunTokenObservations.js +48 -0
  418. package/dist/process/ProviderDiagnosticRedaction.js +17 -0
  419. package/dist/process/ProviderProcess.js +4 -3
  420. package/dist/process/capture/FilesystemSnapshot.js +28 -4
  421. package/dist/process/capture/ProcessCaptureLifecycle.js +350 -59
  422. package/dist/process/capture/ProcessCaptureProgress.js +62 -0
  423. package/dist/process/capture/ProcessHarness.js +194 -26
  424. package/dist/process/capture/ProcessNormalization.js +3 -1
  425. package/dist/process/capture/ProcessScenarioRuntimeValidation.js +5 -2
  426. package/dist/process/capture/TerminalRenderer.js +24 -7
  427. package/dist/reference/ReferenceSourceReader.js +22 -5
  428. package/dist/reference/ReferenceSourceReaderEntries.js +114 -51
  429. package/dist/reference/ReferenceSourceReaderErrors.js +12 -0
  430. package/dist/reference/ReferenceSourceReaderFile.js +50 -10
  431. package/dist/reference/ReferenceSourceReaderValidate.js +4 -4
  432. package/dist/server/EvidenceMcpServer.js +36 -1
  433. package/dist/server/admittedToolOperation.js +9 -0
  434. package/dist/server/contractToolHandler.js +21 -0
  435. package/dist/server/createServer.js +97 -25
  436. package/dist/server/registerAdbTools.js +36 -0
  437. package/dist/server/registerAnalysisViewTool.js +4 -9
  438. package/dist/server/registerAndroidTools.js +3 -12
  439. package/dist/server/registerApktoolTools.js +14 -0
  440. package/dist/server/registerApplicationTools/compareExportShapes.js +4 -6
  441. package/dist/server/registerApplicationTools/compareSourceToBundle.js +4 -5
  442. package/dist/server/registerApplicationTools/compareVersions.js +3 -2
  443. package/dist/server/registerApplicationTools/coverage.js +3 -2
  444. package/dist/server/registerApplicationTools/obligationLedger.js +3 -2
  445. package/dist/server/registerApplicationTools/projectMobileApplicationGraph.js +3 -2
  446. package/dist/server/registerApplicationTools/traceFeature.js +3 -2
  447. package/dist/server/registerApplicationTools/traceSemantics.js +4 -5
  448. package/dist/server/registerArtifactComparisonTool.js +5 -2
  449. package/dist/server/registerBinaryDiagnosticsTools.js +16 -4
  450. package/dist/server/registerBrowserScenarioTool.js +10 -7
  451. package/dist/server/registerBrowserTools.js +12 -9
  452. package/dist/server/registerBundleComparisonTool.js +16 -2
  453. package/dist/server/registerCloseLifecycleTool.js +32 -3
  454. package/dist/server/registerElectronTools.js +28 -10
  455. package/dist/server/registerEvmTools.js +4 -9
  456. package/dist/server/registerFirmwareTools.js +3 -11
  457. package/dist/server/registerFunctionComparisonTool.js +5 -2
  458. package/dist/server/registerJavaScriptRecoveryTool.js +4 -9
  459. package/dist/server/registerJavaScriptRuntimeObservationTools.js +9 -6
  460. package/dist/server/registerJebTools.js +16 -0
  461. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +4 -6
  462. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +3 -2
  463. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +3 -2
  464. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +3 -2
  465. package/dist/server/registerPeResourcesTool.js +9 -0
  466. package/dist/server/registerProcessComparisonTool.js +5 -2
  467. package/dist/server/registerRecordedCrashTools.js +4 -9
  468. package/dist/server/registerSessionRecordTools.js +2 -1
  469. package/dist/server/registerSessionTools.js +49 -18
  470. package/dist/server/registerWebModuleTool.js +4 -9
  471. package/dist/server/registerWebNetworkCaptureTool.js +4 -9
  472. package/dist/server/registerWebRuntimeTools.js +6 -5
  473. package/dist/server/registerWebScriptTool.js +6 -3
  474. package/dist/server/registerWebSourceLocationTool.js +4 -9
  475. package/dist/server/toolResult.js +21 -2
  476. package/dist/windows/WindowsPrivateRuntime.js +12 -5
  477. package/install.sh +7 -4
  478. package/licenses/nativeaot-parser-MIT.txt +28 -0
  479. package/native/windows/build/manifest.json +2 -2
  480. package/native/windows/build/rea-windows-x64.node +0 -0
  481. package/package.json +33 -5
  482. package/scripts/rea.mjs +16 -1
  483. package/skills/reverse-engineer-anything/SKILL.md +52 -51
  484. package/skills/reverse-engineer-anything/references/connection-and-recovery.md +127 -0
  485. package/skills/reverse-engineer-anything/references/evidence-workflows.md +8 -0
  486. package/skills/reverse-engineer-anything/references/javascript-applications.md +92 -13
  487. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +22 -1
@@ -42,6 +42,42 @@ export const isSidecar = (path) => {
42
42
  return (segments.includes("__MACOSX") || (segments.at(-1) ?? "").startsWith("._"));
43
43
  };
44
44
  export const isWithin = (path, root) => root === "." || path === root || path.startsWith(`${root}/`);
45
+ /**
46
+ * English (en-US) case fold used only for Apple's fixed anatomy vocabulary.
47
+ * Reported paths keep the archive spelling. Inventory identity stays case-sensitive.
48
+ */
49
+ export const anatomyNameIs = (actual, expected) => actual.toLocaleLowerCase("en-US") === expected.toLocaleLowerCase("en-US");
50
+ /** Directory entry that folds to one vocabulary word. The exact spelling wins. */
51
+ export const anatomyChild = (names, expected) => {
52
+ if (names === undefined)
53
+ return null;
54
+ let exact;
55
+ let folded;
56
+ for (const name of names) {
57
+ if (name === expected)
58
+ exact = name;
59
+ else if (anatomyNameIs(name, expected) &&
60
+ (folded === undefined || compare(name, folded) < 0))
61
+ folded = name;
62
+ }
63
+ return exact ?? folded ?? null;
64
+ };
65
+ /**
66
+ * Whether `path`'s tail matches anatomy vocabulary. `*` matches one segment
67
+ * that is not itself a vocabulary comparison.
68
+ */
69
+ export const anatomyTailMatches = (path, expected) => {
70
+ const actual = path.split("/");
71
+ if (actual.length < expected.length)
72
+ return false;
73
+ const tail = actual.slice(-expected.length);
74
+ return expected.every((name, index) => {
75
+ const segment = tail[index];
76
+ if (segment === undefined || segment.length === 0)
77
+ return false;
78
+ return name === "*" || anatomyNameIs(segment, name);
79
+ });
80
+ };
45
81
  /**
46
82
  * Outermost iOS (`Payload/X.app`) and macOS (`X.app/Contents/…`) applications.
47
83
  * An inventoried `.app` directory is its own root, `.`.
@@ -55,13 +91,16 @@ export const applicationRoots = (entries, subject) => {
55
91
  for (const { path } of entries) {
56
92
  if (isSidecar(path))
57
93
  continue;
58
- const ios = /^(Payload\/[^/]+\.app)(?:\/|$)/u.exec(path);
59
- if (ios?.[1] !== undefined) {
60
- found.add(ios[1]);
94
+ const segments = path.split("/");
95
+ const app = segments[1];
96
+ if (anatomyNameIs(segments[0] ?? "", "Payload") &&
97
+ app !== undefined &&
98
+ /\.app$/iu.test(app)) {
99
+ found.add(`${segments[0]}/${app}`);
61
100
  continue;
62
101
  }
63
- const segments = path.split("/");
64
- const index = segments.findIndex((segment, position) => /\.app$/iu.test(segment) && segments[position + 1] === "Contents");
102
+ const index = segments.findIndex((segment, position) => /\.app$/iu.test(segment) &&
103
+ anatomyNameIs(segments[position + 1] ?? "", "Contents"));
65
104
  if (index >= 0)
66
105
  found.add(segments.slice(0, index + 1).join("/"));
67
106
  }
@@ -142,9 +181,9 @@ const enclosingBundle = (path, bundles) => {
142
181
  };
143
182
  const bundleLayout = (bundle, tree) => {
144
183
  const names = tree.children.get(directoryOf(bundle));
145
- if (names?.has("Contents") === true)
184
+ if (anatomyChild(names, "Contents") !== null)
146
185
  return "macos-deep";
147
- if (names?.has("Versions") === true)
186
+ if (anatomyChild(names, "Versions") !== null)
148
187
  return "versioned-framework";
149
188
  return "shallow";
150
189
  };
@@ -163,15 +202,18 @@ const bundleRole = (bundle) => {
163
202
  if (name.endsWith(".dext"))
164
203
  return "driver-extension";
165
204
  if (name.endsWith(".bundle")) {
166
- if (container === "PlugIns")
205
+ if (anatomyNameIs(container ?? "", "PlugIns"))
167
206
  return "plug-in";
168
- return container === "Resources" ? "resource-bundle" : "bundle";
207
+ return anatomyNameIs(container ?? "", "Resources")
208
+ ? "resource-bundle"
209
+ : "bundle";
169
210
  }
170
211
  if (!name.endsWith(".app"))
171
212
  return "plug-in";
172
- if (container === "LoginItems" && segments.at(-3) === "Library")
213
+ if (anatomyNameIs(container ?? "", "LoginItems") &&
214
+ anatomyNameIs(segments.at(-3) ?? "", "Library"))
173
215
  return "login-item";
174
- if (container === "Helpers")
216
+ if (anatomyNameIs(container ?? "", "Helpers"))
175
217
  return "helper-application";
176
218
  return "nested-application";
177
219
  };
@@ -183,42 +225,67 @@ const directFiles = (directory, tree) => [...(tree.children.get(directory) ?? []
183
225
  /** Content directories; `Versions/Current` is a symlink outside the inventory. */
184
226
  const contentDirectories = (bundle, layout, tree) => {
185
227
  const directory = directoryOf(bundle);
186
- if (layout === "macos-deep")
187
- return [joinPath(directory, "Contents")];
228
+ if (layout === "macos-deep") {
229
+ const contents = namedChild(tree, directory, "Contents");
230
+ return contents === null ? [] : [contents];
231
+ }
188
232
  if (layout === "shallow")
189
233
  return [directory];
190
- const versions = joinPath(directory, "Versions");
234
+ const versions = namedChild(tree, directory, "Versions");
235
+ if (versions === null)
236
+ return [];
191
237
  // Only real version directories count: Current is a symlink, and files
192
238
  // such as .DS_Store are not versions.
193
239
  return [...(tree.children.get(versions) ?? [])]
194
- .filter((version) => version !== "Current")
240
+ .filter((version) => !anatomyNameIs(version, "Current"))
195
241
  .map((version) => joinPath(versions, version))
196
242
  .filter((version) => tree.directories.has(version))
197
243
  .sort(compare);
198
244
  };
245
+ /** Child path using the archive's spelling of one anatomy name. */
246
+ const namedChild = (tree, directory, expected) => {
247
+ const name = anatomyChild(tree.children.get(directory), expected);
248
+ return name === null ? null : joinPath(directory, name);
249
+ };
199
250
  const infoPlistPath = (bundle, layout, tree) => {
200
251
  const directories = contentDirectories(bundle, layout, tree);
201
252
  // With several real versions, Versions/Current (a symlink outside the
202
253
  // inventory) decides which plist applies, so the plist stays unknown.
203
254
  if (directories.length !== 1)
204
255
  return null;
205
- const candidates = directories
206
- .map((directory) => joinPath(directory, layout === "versioned-framework"
207
- ? "Resources/Info.plist"
208
- : "Info.plist"))
209
- .filter((path) => tree.files.has(path));
210
- return candidates.length === 1 ? (candidates[0] ?? null) : null;
256
+ const directory = directories[0];
257
+ if (directory === undefined)
258
+ return null;
259
+ const parent = layout === "versioned-framework"
260
+ ? namedChild(tree, directory, "Resources")
261
+ : directory;
262
+ if (parent === null)
263
+ return null;
264
+ const info = namedChild(tree, parent, "Info.plist");
265
+ return info !== null && tree.files.has(info) ? info : null;
211
266
  };
212
267
  const executableCandidates = (bundle, layout, tree) => contentDirectories(bundle, layout, tree)
213
- .flatMap((directory) => directFiles(layout === "macos-deep" ? joinPath(directory, "MacOS") : directory, tree))
268
+ .flatMap((directory) => {
269
+ const executableDirectory = layout === "macos-deep"
270
+ ? namedChild(tree, directory, "MacOS")
271
+ : directory;
272
+ return executableDirectory === null
273
+ ? []
274
+ : directFiles(executableDirectory, tree);
275
+ })
214
276
  .filter((path) => MACH_O_FORMATS.includes(tree.files.get(path)?.format ?? ""));
215
277
  const signingPaths = (bundle, layout, tree) => contentDirectories(bundle, layout, tree)
216
- .flatMap((directory) => [
217
- joinPath(directory, "_CodeSignature/CodeResources"),
218
- joinPath(directory, "embedded.provisionprofile"),
219
- joinPath(directory, "embedded.mobileprovision"),
220
- ])
221
- .filter((path) => tree.files.has(path))
278
+ .flatMap((directory) => {
279
+ const signature = namedChild(tree, directory, "_CodeSignature");
280
+ return [
281
+ signature === null
282
+ ? null
283
+ : namedChild(tree, signature, "CodeResources"),
284
+ namedChild(tree, directory, "embedded.provisionprofile"),
285
+ namedChild(tree, directory, "embedded.mobileprovision"),
286
+ ];
287
+ })
288
+ .filter((path) => path !== null && tree.files.has(path))
222
289
  .sort(compare);
223
290
  /** Platforms of application roots whose layout was observed, not assumed. */
224
291
  export const platformsOf = (bundles) => [
@@ -11,6 +11,8 @@ export const resolveTreePath = async (view, input) => {
11
11
  let hops = 0;
12
12
  while (pending.length > 0) {
13
13
  const segment = pending.shift() ?? "";
14
+ if (segment === ".")
15
+ continue;
14
16
  if (segment === "..") {
15
17
  if (resolved.length === 0)
16
18
  return { kind: "escapes" };
@@ -40,7 +42,13 @@ export const resolveTreePath = async (view, input) => {
40
42
  ? { kind: "file", path: resolved.join("/") }
41
43
  : { kind: "not-file" };
42
44
  };
43
- const segmentsOf = (path) => path.split("/").filter((segment) => segment !== "" && segment !== ".");
45
+ const segmentsOf = (path) => {
46
+ const segments = path.split("/").filter((segment) => segment !== "");
47
+ // a trailing slash requires a directory, just like a final dot component.
48
+ if (path.endsWith("/"))
49
+ segments.push(".");
50
+ return segments;
51
+ };
44
52
  export const directoryOf = (path) => {
45
53
  const index = path.lastIndexOf("/");
46
54
  return index < 0 ? "" : path.slice(0, index);
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { compatibleSlice, directoryOf, expandPrefix, joinPath, resolveTreePath, } from "./dyldPaths.js";
2
+ import { compatibleSlice, directoryOf, expandPrefix, resolveTreePath, } from "./dyldPaths.js";
3
3
  import { digestSchema } from "../digests.js";
4
4
  import { hasApplicableDyldOverrides, embeddedDyldOverrides, } from "./dyldEnvironment.js";
5
5
  import { DYLIB_RESOLUTION_LIMITATIONS, deriveFindings, } from "./dylibResolutionFindings.js";
@@ -169,7 +169,7 @@ const candidateTemplates = (dependency, loader, context) => {
169
169
  scope: base.scope,
170
170
  path: base.scope === "outside"
171
171
  ? `${base.path.replace(/\/+$/u, "")}/${rest}`
172
- : joinPath(base.path, rest),
172
+ : `${base.path}${base.path === "" ? "" : "/"}${rest}`,
173
173
  };
174
174
  return { expansion, source: "rpath", rpath, rpathOwner: owner };
175
175
  }));
@@ -30,13 +30,16 @@ export const buildInterfaceBuilderAnalysis = (input) => {
30
30
  let omittedHierarchyReferences = 0;
31
31
  for (const document of input.documents.slice(0, input.limits.max_documents)) {
32
32
  const parsed = parseInterfaceBuilderRecords(document.raw);
33
- const prefix = `ib:${document.relativePath}:`;
33
+ const prefix = `ib:${JSON.stringify(document.relativePath)}:`;
34
+ const graphId = (kind, parts = []) => `${prefix}${kind}:${JSON.stringify(parts)}`;
34
35
  const rootId = `${prefix}root`;
35
36
  const objectIds = new Set(parsed.objects.map(({ id }) => id));
36
37
  const evidenceFor = (description) => [
37
38
  {
38
39
  kind: "interface_builder_resource",
39
- description: `${document.relativePath}: ${description}`,
40
+ // artifact_path names the archive; repeating it here cost a path per
41
+ // node and edge.
42
+ description,
40
43
  location: { address: null, file_offset: null },
41
44
  artifact_path: document.relativePath,
42
45
  artifact_sha256: document.archiveSha256,
@@ -66,7 +69,7 @@ export const buildInterfaceBuilderAnalysis = (input) => {
66
69
  addNode(rootNode);
67
70
  let documentObjectCount = 0;
68
71
  for (const object of parsed.objects.slice(0, input.limits.max_objects)) {
69
- const id = `${prefix}object:${object.id}`;
72
+ const id = graphId("object", [object.id]);
70
73
  const kind = object.kind === "other" ? "unknown" : object.kind;
71
74
  if (!addNode({
72
75
  id,
@@ -88,7 +91,7 @@ export const buildInterfaceBuilderAnalysis = (input) => {
88
91
  let hierarchyEdgeCount = 0;
89
92
  let documentOmittedConnections = 0;
90
93
  let documentOmittedHierarchyEdges = 0;
91
- const objectNodeId = (objectId) => `${prefix}object:${objectId}`;
94
+ const objectNodeId = (objectId) => graphId("object", [objectId]);
92
95
  const addEdge = (edge, isHierarchy) => {
93
96
  if (isHierarchy
94
97
  ? hierarchyEdgeCount >= input.limits.max_objects
@@ -181,7 +184,7 @@ export const buildInterfaceBuilderAnalysis = (input) => {
181
184
  const known = objectIds.has(objectId);
182
185
  const childId = known
183
186
  ? objectNodeId(objectId)
184
- : `${prefix}unknown:${objectId}`;
187
+ : graphId("unknown", [objectId]);
185
188
  if (!known &&
186
189
  !addNode({
187
190
  id: childId,
@@ -192,7 +195,7 @@ export const buildInterfaceBuilderAnalysis = (input) => {
192
195
  evidence: evidenceFor(`hierarchy item ${objectId}`),
193
196
  }))
194
197
  hierarchyTruncated = true;
195
- connect(`${prefix}hierarchy:${parentId}:${childId}`, parentId, childId, "contains", `hierarchy ${objectId}`);
198
+ connect(graphId("hierarchy", [parentId, childId]), parentId, childId, "contains", `hierarchy ${objectId}`);
196
199
  nextParent = childId;
197
200
  hierarchyCount += 1;
198
201
  }
@@ -216,10 +219,10 @@ export const buildInterfaceBuilderAnalysis = (input) => {
216
219
  });
217
220
  const destinationId = item.destination_id === null ? null : objectNodeId(item.destination_id);
218
221
  if (item.kind === "action") {
219
- const actionId = `${prefix}action:${item.id}`;
222
+ const actionId = graphId("action", [item.id]);
220
223
  const selectorId = item.label === null
221
224
  ? null
222
- : `${prefix}selector:${item.destination_id ?? "unknown"}:${item.label}`;
225
+ : graphId("selector", [item.destination_id, item.label]);
223
226
  addNode({
224
227
  id: actionId,
225
228
  kind: "action",
@@ -232,7 +235,7 @@ export const buildInterfaceBuilderAnalysis = (input) => {
232
235
  },
233
236
  evidence: evidenceFor(`action ${item.id}`),
234
237
  });
235
- connect(`${actionId}:source`, sourceId, actionId, "target_action", `action source ${item.source_id}`);
238
+ connect(graphId("action-edge", [item.id, "source"]), sourceId, actionId, "target_action", `action source ${item.source_id}`);
236
239
  if (selectorId !== null) {
237
240
  addNode({
238
241
  id: selectorId,
@@ -242,15 +245,15 @@ export const buildInterfaceBuilderAnalysis = (input) => {
242
245
  attributes: { destination_id: item.destination_id },
243
246
  evidence: evidenceFor(`selector ${item.label}`),
244
247
  });
245
- connect(`${actionId}:selector`, actionId, selectorId, "target_action", `selector ${item.label}`);
248
+ connect(graphId("action-edge", [item.id, "selector"]), actionId, selectorId, "target_action", `selector ${item.label}`);
246
249
  }
247
250
  if (destinationId === null || !nodes.has(destinationId))
248
- connect(`${actionId}:destination`, actionId, null, "target_action", `action destination ${item.destination_id ?? "missing"}`, "destination_object_missing_or_external");
251
+ connect(graphId("action-edge", [item.id, "destination"]), actionId, null, "target_action", `action destination ${item.destination_id ?? "missing"}`, "destination_object_missing_or_external");
249
252
  else
250
- connect(`${actionId}:destination`, actionId, destinationId, "target_action", `action destination ${item.destination_id}`);
253
+ connect(graphId("action-edge", [item.id, "destination"]), actionId, destinationId, "target_action", `action destination ${item.destination_id}`);
251
254
  }
252
255
  else if (item.kind === "outlet") {
253
- const outletId = `${prefix}outlet:${item.id}`;
256
+ const outletId = graphId("outlet", [item.id]);
254
257
  addNode({
255
258
  id: outletId,
256
259
  kind: "outlet",
@@ -259,20 +262,20 @@ export const buildInterfaceBuilderAnalysis = (input) => {
259
262
  attributes: item.attributes,
260
263
  evidence: evidenceFor(`outlet ${item.id}`),
261
264
  });
262
- connect(`${outletId}:source`, sourceId, outletId, "contains", `outlet source ${item.source_id}`);
265
+ connect(graphId("outlet-edge", [item.id, "source"]), sourceId, outletId, "contains", `outlet source ${item.source_id}`);
263
266
  if (destinationId === null || !nodes.has(destinationId))
264
- connect(`${outletId}:destination`, outletId, null, "outlet_to", `outlet ${item.label ?? item.id}`, "destination_object_missing_or_external");
267
+ connect(graphId("outlet-edge", [item.id, "destination"]), outletId, null, "outlet_to", `outlet ${item.label ?? item.id}`, "destination_object_missing_or_external");
265
268
  else
266
- connect(`${outletId}:destination`, outletId, destinationId, "outlet_to", `outlet ${item.label ?? item.id}`);
269
+ connect(graphId("outlet-edge", [item.id, "destination"]), outletId, destinationId, "outlet_to", `outlet ${item.label ?? item.id}`);
267
270
  }
268
271
  else if (item.kind === "segue") {
269
272
  if (destinationId === null || !nodes.has(destinationId))
270
- connect(`${prefix}segue:${index}`, sourceId, null, "segue_to", `segue ${item.label ?? item.id}`, "destination_scene_missing");
273
+ connect(graphId("segue", [index]), sourceId, null, "segue_to", `segue ${item.label ?? item.id}`, "destination_scene_missing");
271
274
  else
272
- connect(`${prefix}segue:${index}`, sourceId, destinationId, "segue_to", `segue ${item.label ?? item.id}`);
275
+ connect(graphId("segue", [index]), sourceId, destinationId, "segue_to", `segue ${item.label ?? item.id}`);
273
276
  }
274
277
  else {
275
- connect(`${prefix}unknown-connection:${index}`, sourceId, null, "contains", `connection type ${item.kind}`, "unsupported_connection_type");
278
+ connect(graphId("unknown-connection", [index]), sourceId, null, "contains", `connection type ${item.kind}`, "unsupported_connection_type");
276
279
  }
277
280
  }
278
281
  const objectsTruncated = parsed.omittedObjects > 0 || parsed.objects.length > documentObjectCount;
@@ -44,12 +44,21 @@ export const parseInterfaceBuilderRecords = (value) => {
44
44
  const attributes = record(raw);
45
45
  const className = firstString(attributes["customClass"], attributes["class"], attributes["isa"]);
46
46
  const label = firstString(attributes["label"], attributes["title"], attributes["name"], className);
47
+ // class_name, name, and id already carry these values; repeating them in
48
+ // attributes doubled them on every graph node.
49
+ const carried = new Set();
50
+ if (attributes["customClass"] === className)
51
+ carried.add("customClass");
52
+ if (attributes["label"] === label)
53
+ carried.add("label");
54
+ if (attributes["objectID"] === id)
55
+ carried.add("objectID");
47
56
  objects.push(objectNode.parse({
48
57
  id,
49
58
  kind: classifyObject(className),
50
59
  class_name: className,
51
60
  name: label ?? id,
52
- attributes: jsonSafeRecord(attributes),
61
+ attributes: jsonSafeRecord(Object.fromEntries(Object.entries(attributes).filter(([key]) => !carried.has(key)))),
53
62
  }));
54
63
  }
55
64
  for (const [sourceId, rawConnections] of Object.entries(connectionsRaw)) {
@@ -5,6 +5,7 @@ import { evidenceSchema } from "./evidence.js";
5
5
  import { parseArtifactInventoryEvidence, } from "./artifactInventoryEvidence.js";
6
6
  import { prefixedDigestSchema } from "./../domain/digests.js";
7
7
  import { canonicalJson } from "./comparisonSemantics.js";
8
+ import { ZIP_NON_ENTRY_TAIL_LIMITATION } from "./zipPackageFormat.js";
8
9
  const evidenceIdSchema = prefixedDigestSchema("ev");
9
10
  const comparisonStatusSchema = z.enum([
10
11
  "unchanged",
@@ -95,6 +96,12 @@ export const compareArtifacts = (leftEvidence, rightEvidence) => {
95
96
  ...left.evidence.map(({ evidence_id: id }) => id),
96
97
  ...right.evidence.map(({ evidence_id: id }) => id),
97
98
  ], leftCovered && rightCovered);
99
+ const rootChange = rootHashChange(left.inventory, right.inventory, changes, [
100
+ ...left.evidence.map(({ evidence_id: id }) => id),
101
+ ...right.evidence.map(({ evidence_id: id }) => id),
102
+ ]);
103
+ if (rootChange !== null)
104
+ changes.push(rootChange);
98
105
  const summary = summarize(left.inventory, right.inventory, changes, leftCovered && rightCovered);
99
106
  return artifactComparisonResultSchema.parse({
100
107
  status: !leftComplete || !rightComplete
@@ -251,18 +258,20 @@ const relationsByPath = (inventory) => {
251
258
  const output = new Map();
252
259
  const occurrences = new Map(inventory.occurrences.map((item) => [item.occurrence_id, item]));
253
260
  for (const edge of inventory.edges) {
254
- const path = edge.logical_path ?? ".";
255
- const values = output.get(path);
256
261
  const occurrence = occurrences.get(edge.occurrence_id);
262
+ // An incomplete inventory can omit the occurrence that names the child.
263
+ if (occurrence?.artifact_id === null || occurrence === undefined)
264
+ continue;
265
+ const path = occurrence.logical_path;
266
+ const values = output.get(path);
257
267
  const projection = {
258
- parent_logical_path: occurrence?.parent_occurrence_id === null ||
259
- occurrence?.parent_occurrence_id === undefined
268
+ parent_logical_path: occurrence.parent_occurrence_id === null
260
269
  ? null
261
270
  : (occurrences.get(occurrence.parent_occurrence_id)?.logical_path ??
262
271
  null),
263
- child_artifact_id: edge.child_artifact_id,
272
+ child_artifact_id: occurrence.artifact_id,
264
273
  relation: edge.relation,
265
- logical_path: edge.logical_path,
274
+ logical_path: occurrence.logical_path,
266
275
  producer: edge.producer,
267
276
  };
268
277
  if (values === undefined)
@@ -302,4 +311,23 @@ const summarize = (left, right, changes, covered) => {
302
311
  counts.contradiction),
303
312
  };
304
313
  };
305
- const hasCoverageLimitation = (limitations) => limitations.some((limitation) => !/integrity contradiction\(s\) were recorded/u.test(limitation));
314
+ const hasCoverageLimitation = (limitations) => limitations.some((limitation) => limitation !== ZIP_NON_ENTRY_TAIL_LIMITATION &&
315
+ !/integrity contradiction\(s\) were recorded/u.test(limitation));
316
+ const rootHashChange = (left, right, changes, evidenceLinks) => {
317
+ if (left.manifest.root_sha256 === right.manifest.root_sha256)
318
+ return null;
319
+ if (changes.some((change) => change.logical_path === "." && change.dimensions.includes("content")))
320
+ return null;
321
+ const leftRoot = left.occurrences.find((occurrence) => occurrence.logical_path === ".");
322
+ const rightRoot = right.occurrences.find((occurrence) => occurrence.logical_path === ".");
323
+ return {
324
+ classification: "changed",
325
+ logical_path: ".",
326
+ dimensions: ["content"],
327
+ left_occurrence_id: leftRoot?.occurrence_id ?? null,
328
+ right_occurrence_id: rightRoot?.occurrence_id ?? null,
329
+ left_artifact_id: leftRoot?.artifact_id ?? null,
330
+ right_artifact_id: rightRoot?.artifact_id ?? null,
331
+ evidence_links: [...evidenceLinks],
332
+ };
333
+ };
@@ -134,12 +134,14 @@ export const integrityContradictionSchema = z.object({
134
134
  provenance: z.literal("container-integrity-metadata-versus-observed-bytes"),
135
135
  limitations: z.array(z.string()).min(1),
136
136
  });
137
- /** Parent-child derivation relation between two content-addressed artifacts. */
137
+ /**
138
+ * Parent-child derivation relation between two content-addressed artifacts.
139
+ * The child artifact and its logical path are those of the edge's occurrence.
140
+ */
138
141
  const artifactEdgeSchema = z.object({
139
142
  edge_id: edgeIdSchema,
140
143
  ordinal: z.number().int().min(0),
141
144
  parent_artifact_id: artifactIdSchema,
142
- child_artifact_id: artifactIdSchema,
143
145
  relation: z.enum([
144
146
  "contains",
145
147
  "extracts",
@@ -150,7 +152,6 @@ const artifactEdgeSchema = z.object({
150
152
  "derived-from",
151
153
  ]),
152
154
  occurrence_id: occurrenceIdSchema,
153
- logical_path: boundedRelativePathSchema.nullable(),
154
155
  producer: artifactCommandSchema.nullable(),
155
156
  });
156
157
  /** Stable cryptographic commitment and counts for a complete artifact graph. */
@@ -203,5 +204,6 @@ export const artifactExtractionResultSchema = z.object({
203
204
  residual_paths: z.array(boundedRelativePathSchema),
204
205
  }),
205
206
  provenance: z.array(artifactCommandSchema),
207
+ integrity_contradictions: z.array(integrityContradictionSchema),
206
208
  limitations: z.array(z.string()),
207
209
  });
@@ -1,4 +1,23 @@
1
+ import { posix } from "node:path";
1
2
  import { digestCanonicalValue } from "./canonicalDigest.js";
3
+ /** NFC spelling of a logical archive path. Inventory and path joins share it. */
4
+ export const logicalPathNfc = (value) => value.normalize("NFC");
5
+ /**
6
+ * Lexical join against an inventoried logical path. The result is NFC.
7
+ * `"."` is the archive root. A path that escapes the root, or that contains
8
+ * NUL, is left in a form the caller can report; `logicalPathEscapesRoot`
9
+ * is then true.
10
+ */
11
+ export const normalizeJoinedLogicalPath = (value) => {
12
+ if (value.includes("\0"))
13
+ return value;
14
+ return logicalPathNfc(posix.normalize(value.replaceAll("\\", "/")).replace(/^\.\//u, ""));
15
+ };
16
+ /** Whether a joined logical path leaves the archive root. */
17
+ export const logicalPathEscapesRoot = (path) => path.includes("\0") ||
18
+ path === ".." ||
19
+ path.startsWith("../") ||
20
+ path.startsWith("/");
2
21
  /** Content-address an artifact independently of where it was observed. */
3
22
  export const artifactIdForContent = (sha256) => `art_${digestCanonicalValue({ sha256 }, "Artifact")}`;
4
23
  /** Identify an occurrence by its root and exact logical location. */
@@ -25,5 +44,14 @@ export const artifactContradictionId = (input) => `ic_${digestCanonicalValue({
25
44
  declared_sha256: input.declaredSha256,
26
45
  observed_sha256: input.observedSha256,
27
46
  }, "Artifact")}`;
28
- /** Identify an edge by its semantic relationship and exact occurrence. */
29
- export const artifactEdgeId = (semantic) => `edge_${digestCanonicalValue(semantic, "Artifact")}`;
47
+ /**
48
+ * Identify an edge by its semantic relationship and exact occurrence. The
49
+ * child artifact and logical path come from that occurrence.
50
+ */
51
+ export const artifactEdgeId = (edge, occurrence) => `edge_${digestCanonicalValue({
52
+ parent_artifact_id: edge.parent_artifact_id,
53
+ child_artifact_id: occurrence.artifact_id,
54
+ relation: edge.relation,
55
+ occurrence_id: edge.occurrence_id,
56
+ logical_path: occurrence.logical_path,
57
+ }, "Artifact")}`;
@@ -10,28 +10,11 @@ const evidenceIdSchema = prefixedDigestSchema("ev");
10
10
  const artifactIdSchema = prefixedDigestSchema("art");
11
11
  const inspectionObservationSchema = z.strictObject({
12
12
  observation_id: prefixedDigestSchema("aio"),
13
- kind: z.enum(["root-manifest", "artifact", "occurrence", "integrity"]),
13
+ kind: z.enum(["root-manifest", "integrity"]),
14
14
  subject: textSchema,
15
15
  value: jsonValueSchema,
16
16
  evidence_id: evidenceIdSchema,
17
17
  });
18
- const inspectionRelationshipSchema = z.strictObject({
19
- relationship_id: prefixedDigestSchema("air"),
20
- relation: z.enum([
21
- "contains",
22
- "extracts",
23
- "slice-of",
24
- "embeds",
25
- "loads",
26
- "maps-source",
27
- "derived-from",
28
- ]),
29
- source_artifact_id: artifactIdSchema,
30
- target_artifact_id: artifactIdSchema,
31
- occurrence_id: prefixedDigestSchema("occ"),
32
- logical_path: textSchema.nullable(),
33
- evidence_id: evidenceIdSchema,
34
- });
35
18
  const inspectionHypothesisSchema = z.strictObject({
36
19
  hypothesis_id: prefixedDigestSchema("aih"),
37
20
  statement: textSchema,
@@ -83,7 +66,6 @@ export const artifactInspectionResultSchema = z.strictObject({
83
66
  }))
84
67
  .min(1),
85
68
  observations: z.array(inspectionObservationSchema),
86
- derived_relationships: z.array(inspectionRelationshipSchema),
87
69
  hypotheses: z.array(inspectionHypothesisSchema),
88
70
  contradictions: z.array(inspectionContradictionSchema),
89
71
  unexplored_branches: z.array(unexploredBranchSchema),
@@ -93,8 +75,6 @@ export const artifactInspectionResultSchema = z.strictObject({
93
75
  substeps_completed: z.literal(1),
94
76
  observations_retained: z.number().int().min(0),
95
77
  observations_omitted: z.number().int().min(0),
96
- relationships_retained: z.number().int().min(0),
97
- relationships_omitted: z.number().int().min(0),
98
78
  hypotheses_retained: z.number().int().min(0),
99
79
  hypotheses_omitted: z.number().int().min(0),
100
80
  unexplored_branches_retained: z.number().int().min(0),
@@ -110,20 +90,17 @@ export const createArtifactInspection = (inventoryInput) => {
110
90
  const inventoryEvidence = parseInventoryEvidence(inventoryInput);
111
91
  const inventory = artifactInventoryResultSchema.parse(inventoryEvidence.normalized_result);
112
92
  const observations = allObservations(inventory, inventoryEvidence.evidence_id);
113
- const relationships = allRelationships(inventory, inventoryEvidence.evidence_id);
114
93
  const hypotheses = allHypotheses(inventory, inventoryEvidence.evidence_id);
115
94
  const nextProbes = probesFor(inventory);
116
95
  const branches = allUnexploredBranches(inventory, inventoryEvidence.evidence_id, nextProbes);
117
96
  const retained = {
118
97
  observations,
119
- relationships,
120
98
  hypotheses,
121
99
  branches,
122
100
  probes: nextProbes,
123
101
  };
124
102
  const omissions = {
125
103
  observations: 0,
126
- relationships: 0,
127
104
  hypotheses: 0,
128
105
  branches: 0,
129
106
  probes: 0,
@@ -148,7 +125,6 @@ export const createArtifactInspection = (inventoryInput) => {
148
125
  },
149
126
  ],
150
127
  observations: retained.observations,
151
- derived_relationships: retained.relationships,
152
128
  hypotheses: retained.hypotheses,
153
129
  contradictions: contradictions(inventory, inventoryEvidence.evidence_id),
154
130
  unexplored_branches: retained.branches,
@@ -158,8 +134,6 @@ export const createArtifactInspection = (inventoryInput) => {
158
134
  substeps_completed: 1,
159
135
  observations_retained: retained.observations.length,
160
136
  observations_omitted: omissions.observations,
161
- relationships_retained: retained.relationships.length,
162
- relationships_omitted: omissions.relationships,
163
137
  hypotheses_retained: retained.hypotheses.length,
164
138
  hypotheses_omitted: omissions.hypotheses,
165
139
  unexplored_branches_retained: retained.branches.length,
@@ -184,10 +158,10 @@ const parseInventoryEvidence = (input) => {
184
158
  throw new TypeError("Artifact inspection substep requires inventory_artifact Evidence");
185
159
  return evidence;
186
160
  };
161
+ // Artifact, occurrence, and edge records stay in the nested inventory Evidence;
162
+ // restating each one here would repeat the complete graph in every result.
187
163
  const allObservations = (inventory, evidenceId) => [
188
164
  observation("root-manifest", inventory.manifest.root_artifact_id, inventory.manifest, evidenceId),
189
- ...inventory.nodes.map((node) => observation("artifact", node.artifact_id, node, evidenceId)),
190
- ...inventory.occurrences.map((occurrence) => observation("occurrence", occurrence.occurrence_id, occurrence, evidenceId)),
191
165
  ...inventory.integrity_contradictions.map((value) => observation("integrity", value.contradiction_id, value, evidenceId)),
192
166
  ];
193
167
  const observation = (kind, subject, value, evidenceId) => {
@@ -202,20 +176,6 @@ const observation = (kind, subject, value, evidenceId) => {
202
176
  ...semantic,
203
177
  };
204
178
  };
205
- const allRelationships = (inventory, evidenceId) => inventory.edges.map((edge) => {
206
- const semantic = {
207
- relation: edge.relation,
208
- source_artifact_id: edge.parent_artifact_id,
209
- target_artifact_id: edge.child_artifact_id,
210
- occurrence_id: edge.occurrence_id,
211
- logical_path: edge.logical_path,
212
- evidence_id: evidenceId,
213
- };
214
- return {
215
- relationship_id: `air_${digestCanonicalValue(semantic, "Artifact inspection")}`,
216
- ...semantic,
217
- };
218
- });
219
179
  const allHypotheses = (inventory, evidenceId) => {
220
180
  const statements = inventory.manifest.root_format === "pe"
221
181
  ? [
@@ -0,0 +1,10 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * Caller choice for declared-versus-observed artifact integrity mismatches.
4
+ *
5
+ * `fail` rejects the operation; `record-and-continue` keeps the observed bytes
6
+ * as explicitly untrusted Evidence and reports each contradiction.
7
+ */
8
+ export const artifactIntegrityPolicySchema = z
9
+ .enum(["fail", "record-and-continue"])
10
+ .default("fail");