rea-agents 6.0.0 → 6.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 (343) hide show
  1. package/README.md +23 -17
  2. package/bridge/android/ReaJadxBridge.java +14 -5
  3. package/bridge/ghidra/ReaGhidraBridge.java +173 -47
  4. package/bridge/hopper_bridge.py +310 -128
  5. package/bridge/mitmproxy/capture.py +0 -2
  6. package/bridge/native/rea_lldb_tracer.py +630 -94
  7. package/bridge/process/ProcessRunTokenReader.swift +39 -5
  8. package/bridge/pwntools/recorded_crash_impl.py +4 -0
  9. package/dist/android/JadxConfiguration.js +196 -33
  10. package/dist/android/JadxMcpTransport.js +4 -0
  11. package/dist/android/JadxProtocol.js +6 -0
  12. package/dist/android/JadxProvider.js +19 -2
  13. package/dist/android/JadxSession.js +23 -4
  14. package/dist/application/AnalysisContextQueries.js +8 -35
  15. package/dist/application/AnalysisDocument.js +32 -0
  16. package/dist/application/AppBundleExecutable.js +67 -21
  17. package/dist/application/CallPathTracing.js +19 -3
  18. package/dist/application/CapabilityInventory.js +6 -3
  19. package/dist/application/ClientConfigurationDocument.js +871 -6
  20. package/dist/application/ClientRegistrationIdentity.js +26 -5
  21. package/dist/application/ClientRegistrationStatus.js +29 -14
  22. package/dist/application/DirectAnalysis.js +27 -37
  23. package/dist/application/Doctor.js +4 -2
  24. package/dist/application/DoctorScope.js +25 -13
  25. package/dist/application/EnhancedLiteralTracing.js +22 -25
  26. package/dist/application/EnhancedTools.js +13 -11
  27. package/dist/application/EvidenceBundleFiles.js +23 -11
  28. package/dist/application/FunctionAnalysisEvidence.js +2 -3
  29. package/dist/application/InventoryProjectionEvidence.js +4 -3
  30. package/dist/application/InvestigationProviders.js +3 -2
  31. package/dist/application/JsonFiles.js +50 -28
  32. package/dist/application/ProcedureAddressResolution.js +11 -0
  33. package/dist/application/ReconstructionCoverageService.js +7 -4
  34. package/dist/application/ReconstructionObligationLedgerService.js +4 -3
  35. package/dist/application/Setup.js +13 -1
  36. package/dist/application/SetupClientConfiguration.js +10 -15
  37. package/dist/application/SetupHost.js +5 -2
  38. package/dist/application/SetupPlan.js +5 -3
  39. package/dist/application/SupportedClients.js +34 -1
  40. package/dist/application/Uninstall.js +4 -3
  41. package/dist/application/Update.js +18 -3
  42. package/dist/application/UpdateRuntime.js +46 -25
  43. package/dist/application/WebModuleTraceService.js +4 -2
  44. package/dist/application/WebNetworkCaptureService.js +4 -2
  45. package/dist/application/WebRuntimeService.js +5 -3
  46. package/dist/application/WebScriptExportService.js +2 -2
  47. package/dist/application/WebSourceLocationService.js +4 -2
  48. package/dist/application/WorkflowEvidence.js +82 -0
  49. package/dist/application/binary/AnalysisProviderEvaluation.js +21 -5
  50. package/dist/application/binary/AnalysisProviderRegistry.js +2 -0
  51. package/dist/application/binary/AnalysisSnapshotCache.js +3 -6
  52. package/dist/application/binary/BinarySession.js +95 -68
  53. package/dist/application/binary/BinarySessionOpen.js +3 -3
  54. package/dist/application/binary/BinarySessionRecords.js +25 -3
  55. package/dist/application/binary/BinarySessionStatus.js +17 -1
  56. package/dist/application/binary/CompositeProvider.js +13 -0
  57. package/dist/application/binary/LazyAnalysisProvider.js +3 -0
  58. package/dist/application/binaryDiagnostics/BinaryLayoutService.js +4 -2
  59. package/dist/application/binaryDiagnostics/RecordedCrashService.js +4 -2
  60. package/dist/application/evm/EvmInterfaceService.js +4 -2
  61. package/dist/application/investigation/EvidenceLedger.js +21 -7
  62. package/dist/application/investigation/InvestigationRecords.js +8 -0
  63. package/dist/application/javascript/JavaScriptAnalysisControl.js +34 -0
  64. package/dist/application/javascript/JavaScriptApplicationEvidence.js +24 -3
  65. package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +19 -2
  66. package/dist/application/javascript/JavaScriptApplicationService.js +22 -15
  67. package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +5 -5
  68. package/dist/application/javascript/JavaScriptArtifactAnalysis.js +5 -4
  69. package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +39 -7
  70. package/dist/application/javascript/JavaScriptArtifactPathResolution.js +6 -3
  71. package/dist/application/javascript/JavaScriptArtifactReconstruction.js +11 -3
  72. package/dist/application/javascript/JavaScriptModuleRelationships.js +37 -8
  73. package/dist/application/javascript/JavaScriptRecoveryService.js +4 -2
  74. package/dist/application/javascript/JavaScriptRuntimeObservationService.js +3 -1
  75. package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +3 -3
  76. package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +63 -61
  77. package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +23 -1
  78. package/dist/application/managed/ManagedApplicationGraphService.js +4 -3
  79. package/dist/application/managed/ManagedMemberComparisonService.js +7 -4
  80. package/dist/application/managed/ManagedNativeVerificationService.js +4 -3
  81. package/dist/application/managed/ManagedReconstructionService.js +4 -3
  82. package/dist/application/process/ProcessCli.js +14 -6
  83. package/dist/application/process/ProcessEvidence.js +4 -3
  84. package/dist/application/workflowInputError.js +18 -0
  85. package/dist/artifacts/ArtifactProvider.js +12 -2
  86. package/dist/artifacts/MachOSliceArtifactReader.js +98 -14
  87. package/dist/artifacts/NativeDmgArtifactReader.js +13 -6
  88. package/dist/artifacts/apple/AppleAssetCatalogAnalysis.js +22 -3
  89. package/dist/artifacts/apple/InterfaceBuilderAnalysis.js +176 -56
  90. package/dist/artifacts/apple/InterfaceBuilderDecodeBudget.js +195 -0
  91. package/dist/artifacts/apple/KeyedArchiveReader.js +36 -22
  92. package/dist/artifacts/apple/MachoLoadCommandReader.js +92 -31
  93. package/dist/artifacts/apple/NibArchive.js +81 -14
  94. package/dist/artifacts/apple/NibViewHierarchy.js +10 -3
  95. package/dist/artifacts/apple/PlistNumberLiterals.js +164 -0
  96. package/dist/artifacts/inventory/ArtifactGraphConstruction.js +13 -8
  97. package/dist/artifacts/inventory/scanCanonical.js +11 -14
  98. package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +6 -2
  99. package/dist/browser/CdpCaptureCompleteness.js +2 -0
  100. package/dist/browser/CdpCaptureEventHandlers.js +76 -11
  101. package/dist/browser/CdpCaptureEventTypes.js +5 -1
  102. package/dist/browser/CdpCaptureEvents.js +25 -0
  103. package/dist/browser/CdpConnection.js +30 -11
  104. package/dist/browser/CdpOptionalCommand.js +2 -3
  105. package/dist/browser/CdpPageCapture.js +23 -1
  106. package/dist/browser/PlaywrightElectronActiveActions.js +32 -23
  107. package/dist/browser/PlaywrightElectronActiveProjection.js +141 -0
  108. package/dist/browser/PlaywrightElectronActiveProvider.js +123 -124
  109. package/dist/browser/WebSourceMapFetcher.js +426 -72
  110. package/dist/browser/assets/LocalWebScriptArtifacts.js +2 -2
  111. package/dist/browser/history/CaptureFailures.js +37 -1
  112. package/dist/browser/history/CaptureRelease.js +5 -0
  113. package/dist/browser/history/HarCaptureAdapter.js +3 -3
  114. package/dist/browser/history/HarJson.js +3 -2
  115. package/dist/browser/history/HistoricalCaptureDecoder.js +4 -2
  116. package/dist/cli/analysisSelector.js +23 -0
  117. package/dist/cli/applicationCommands.js +2 -3
  118. package/dist/cli/coreBinaryCommands.js +70 -12
  119. package/dist/cli/electronCommands.js +7 -6
  120. package/dist/cli/javascriptApplicationAnalysis.js +7 -3
  121. package/dist/cli/jsonOutput.js +4 -99
  122. package/dist/cli/nativeCallCommands.js +2 -3
  123. package/dist/cli/webRuntimeCommands.js +8 -8
  124. package/dist/cli.js +2 -1
  125. package/dist/cliCommandNames.js +0 -1
  126. package/dist/cliJsonInput.js +9 -4
  127. package/dist/config/environment.js +4 -0
  128. package/dist/config/ghidraStartupTimeout.js +17 -0
  129. package/dist/config/mcpResponseBudget.js +22 -0
  130. package/dist/config/parseConfig.js +2 -1
  131. package/dist/contracts/enhancedInputs.js +5 -3
  132. package/dist/contracts/enhancedToolContracts.js +3 -3
  133. package/dist/contracts/hopperMemoryContracts.js +2 -5
  134. package/dist/contracts/javascript/electronToolContracts.js +1 -1
  135. package/dist/contracts/managed/managedToolContracts.js +2 -4
  136. package/dist/contracts/native/nativeToolContracts.js +4 -2
  137. package/dist/contracts/officialToolContracts.js +14 -15
  138. package/dist/contracts/promptContracts.js +3 -3
  139. package/dist/contracts/sessionLifecycleInputs.js +3 -7
  140. package/dist/contracts/sessionStatusContract.js +2 -4
  141. package/dist/contracts/sessionToolContracts.js +4 -6
  142. package/dist/contracts/sessionToolSchemas.js +2 -5
  143. package/dist/contracts/toolContractExamples.js +0 -1
  144. package/dist/contracts/toolContractHelpers.js +4 -1
  145. package/dist/contracts/toolEffects.js +0 -1
  146. package/dist/contracts/toolOutputSchemaGroups.js +28 -27
  147. package/dist/contracts/toolOutputSchemaPrimitives.js +18 -0
  148. package/dist/contracts/toolSchemaMetadata.js +69 -10
  149. package/dist/contracts/webNetworkCaptureToolContracts.js +1 -1
  150. package/dist/domain/analysisErrorBase.js +8 -3
  151. package/dist/domain/analysisErrorCore.js +3 -1
  152. package/dist/domain/analysisErrorPresentation.js +72 -17
  153. package/dist/domain/analysisErrorProjection.js +106 -27
  154. package/dist/domain/android/androidAnalysis.js +2 -4
  155. package/dist/domain/android/androidApplication.js +17 -9
  156. package/dist/domain/apple/appleApplication.js +41 -14
  157. package/dist/domain/apple/dyldEnvironment.js +73 -0
  158. package/dist/domain/apple/dylibResolution.js +120 -9
  159. package/dist/domain/apple/dylibResolutionFindings.js +9 -7
  160. package/dist/domain/apple/interfaceBuilderGraph.js +25 -13
  161. package/dist/domain/apple/interfaceBuilderKeyedArchive.js +13 -3
  162. package/dist/domain/apple/keyedArchive.js +9 -1
  163. package/dist/domain/apple/machoContainer.js +54 -0
  164. package/dist/domain/apple/plistNumbers.js +76 -0
  165. package/dist/domain/artifactIdentity.js +29 -0
  166. package/dist/domain/artifactInventoryEvidence.js +19 -24
  167. package/dist/domain/bridgeCandidateProjection.js +71 -0
  168. package/dist/domain/browserCompleteness.js +1 -0
  169. package/dist/domain/browserObservationError.js +24 -5
  170. package/dist/domain/browserScenarioValues.js +2 -6
  171. package/dist/domain/bundleComparison.js +3 -2
  172. package/dist/domain/canonicalJsonDigestSteps.js +133 -0
  173. package/dist/domain/canonicalOrdering.js +9 -5
  174. package/dist/domain/changedBehavior.js +6 -6
  175. package/dist/domain/comparisonSourceEvidence.js +40 -0
  176. package/dist/domain/configurationErrors.js +1 -1
  177. package/dist/domain/evidence.js +64 -9
  178. package/dist/domain/evidenceBundle.js +42 -1
  179. package/dist/domain/evidenceErrors.js +12 -1
  180. package/dist/domain/explicitSensitiveFailure.js +17 -1
  181. package/dist/domain/firmware/firmwareAnalysis.js +6 -7
  182. package/dist/domain/hopperErrors.js +23 -2
  183. package/dist/domain/hopperValues.js +51 -8
  184. package/dist/domain/immutableJson.js +114 -0
  185. package/dist/domain/inputIssueProjection.js +3 -0
  186. package/dist/domain/javascript/electronActiveObservation.js +30 -4
  187. package/dist/domain/javascript/electronStaticAnalysisValues.js +6 -12
  188. package/dist/domain/javascript/javascriptApplicationAnalysis.js +71 -23
  189. package/dist/domain/javascript/javascriptApplicationGraph.js +13 -0
  190. package/dist/domain/javascript/javascriptAstValues.js +20 -0
  191. package/dist/domain/javascript/javascriptRecovery.js +3 -8
  192. package/dist/domain/javascript/javascriptSemanticAnalysis.js +97 -2
  193. package/dist/domain/javascript/javascriptSemanticCoverage.js +6 -5
  194. package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +9 -17
  195. package/dist/domain/javascript/javascriptSemanticDataEffects.js +22 -5
  196. package/dist/domain/javascript/javascriptSemanticGraph.js +13 -0
  197. package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +1 -0
  198. package/dist/domain/javascript/javascriptSemanticPrimitives.js +25 -17
  199. package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -4
  200. package/dist/domain/javascript/javascriptSemanticResourceLimits.js +77 -0
  201. package/dist/domain/javascript/javascriptSemanticValues.js +83 -11
  202. package/dist/domain/javascript/javascriptSourceParser.js +6 -2
  203. package/dist/domain/javascript/javascriptStaticAnalysis.js +22 -17
  204. package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +5 -3
  205. package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +14 -4
  206. package/dist/domain/javascript/javascriptStaticAnalysisFindings.js +66 -7
  207. package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +28 -16
  208. package/dist/domain/javascript/javascriptStaticAnalysisState.js +3 -2
  209. package/dist/domain/jsonSerialization.js +109 -0
  210. package/dist/domain/jsonValue.js +90 -6
  211. package/dist/domain/localPath.js +6 -0
  212. package/dist/domain/managed/managedApplicationGraph.js +10 -10
  213. package/dist/domain/managed/managedInspectionEvidence.js +16 -0
  214. package/dist/domain/managed/managedMemberComparisonMatch.js +5 -9
  215. package/dist/domain/managed/managedNativeVerification.js +3 -9
  216. package/dist/domain/native/fileOffsetPartialObservation.js +1 -0
  217. package/dist/domain/native/nativeCallObservation.js +33 -11
  218. package/dist/domain/native/nativeCallPartialObservation.js +33 -0
  219. package/dist/domain/process/processCapture.js +8 -4
  220. package/dist/domain/process/processComparison.js +38 -4
  221. package/dist/domain/process/processScenario.js +11 -10
  222. package/dist/domain/propertyListKeys.js +1 -1
  223. package/dist/domain/propertyListXmlText.js +19 -0
  224. package/dist/domain/providerAdapterError.js +1 -1
  225. package/dist/domain/providerOperationHealth.js +54 -0
  226. package/dist/domain/reconstructionVerification.js +6 -43
  227. package/dist/domain/reconstructionVerificationSchemas.js +2 -2
  228. package/dist/domain/staticRuntimeCorrelation.js +6 -43
  229. package/dist/domain/webBundleAnalysis.js +20 -8
  230. package/dist/domain/webBundleAnalyzerInspection.js +13 -8
  231. package/dist/domain/webBundleAnalyzerResult.js +41 -2
  232. package/dist/domain/webRuntime.js +19 -5
  233. package/dist/domain/webSourceLocation.js +1 -0
  234. package/dist/firmware/FirmwareFiles.js +1 -1
  235. package/dist/generatedPackageMetadata.js +1 -1
  236. package/dist/ghidra/GhidraAnalysisProfile.js +5 -0
  237. package/dist/ghidra/GhidraClient.js +47 -14
  238. package/dist/ghidra/GhidraDiagnostics.js +7 -7
  239. package/dist/ghidra/GhidraFunctionValues.js +10 -7
  240. package/dist/ghidra/GhidraInstallation.js +18 -21
  241. package/dist/ghidra/GhidraInventoryValues.js +14 -4
  242. package/dist/ghidra/GhidraJavaLaunch.js +62 -0
  243. package/dist/ghidra/GhidraLauncher.js +33 -16
  244. package/dist/ghidra/GhidraProviderCapabilities.js +14 -2
  245. package/dist/ghidra/GhidraProviderClient.js +23 -12
  246. package/dist/ghidra/GhidraSessionError.js +11 -7
  247. package/dist/ghidra/GhidraTargetSnapshot.js +47 -12
  248. package/dist/ghidra/GhidraTransport.js +20 -0
  249. package/dist/hopper/BridgeLauncher.js +31 -11
  250. package/dist/hopper/HopperAnalysisProfile.js +62 -4
  251. package/dist/hopper/HopperCleanup.js +15 -3
  252. package/dist/hopper/HopperClient.js +222 -14
  253. package/dist/hopper/HopperFileOffset.js +237 -0
  254. package/dist/hopper/HopperMachOImage.js +196 -0
  255. package/dist/hopper/HopperOperationStage.js +6 -0
  256. package/dist/hopper/HopperProvider.js +63 -9
  257. package/dist/hopper/HopperProviderCapabilities.js +19 -1
  258. package/dist/hopper/HopperRegexSearch.js +137 -0
  259. package/dist/hopper/HopperRegexWorker.js +27 -0
  260. package/dist/hopper/HopperRequestQueue.js +68 -19
  261. package/dist/hopper/HopperTargetLease.js +3 -2
  262. package/dist/inspector/JavaScriptRuntimeScope.js +9 -1
  263. package/dist/inspector/V8InspectorCaptureProjection.js +8 -3
  264. package/dist/inspector/V8InspectorProvider.js +47 -11
  265. package/dist/javascript/sourceMaps/DecodedSourceMap.js +47 -0
  266. package/dist/javascript/sourceMaps/SourceMapCommand.js +16 -0
  267. package/dist/javascript/sourceMaps/SourceMapFormat.js +79 -31
  268. package/dist/javascript/sourceMaps/TraceSourceMap.js +14 -28
  269. package/dist/mcpDoctor.js +62 -2
  270. package/dist/native/AppleDispatchCoverage.js +47 -6
  271. package/dist/native/AppleDispatchDecodeFacts.js +6 -0
  272. package/dist/native/AppleDispatchMetadata.js +6 -3
  273. package/dist/native/AppleMachoFixups.js +48 -24
  274. package/dist/native/AppleMachoSelection.js +32 -16
  275. package/dist/native/AppleObjcCategories.js +6 -2
  276. package/dist/native/AppleObjcDispatchFacets.js +5 -2
  277. package/dist/native/AppleObjcProperties.js +2 -1
  278. package/dist/native/AppleSwiftDispatchFacets.js +27 -21
  279. package/dist/native/AppleSwiftVtables.js +21 -15
  280. package/dist/native/CommandRunner.js +81 -84
  281. package/dist/native/LldbCallTracer.js +365 -102
  282. package/dist/native/LldbRetainedObservations.js +178 -0
  283. package/dist/native/NativeCallObservation.js +62 -3
  284. package/dist/native/NativeMacOSProvider.js +98 -17
  285. package/dist/native/SignatureTargetBinding.js +155 -0
  286. package/dist/native/parsers/lipo.js +71 -1
  287. package/dist/native/pwndbg/PwndbgCoreContext.js +25 -5
  288. package/dist/native/pwntools/RecordedCrashStructureBindings.js +2 -0
  289. package/dist/process/DarwinProcessRunTokenReader.js +8 -9
  290. package/dist/process/ExecFileOutput.js +20 -0
  291. package/dist/process/OwnedCommand.js +7 -2
  292. package/dist/process/ProcessOwnership.js +203 -53
  293. package/dist/process/ProcessOwnershipObservation.js +49 -4
  294. package/dist/process/ProviderProcess.js +38 -7
  295. package/dist/process/capture/ProcessCaptureError.js +2 -2
  296. package/dist/process/capture/ProcessCaptureLifecycle.js +100 -34
  297. package/dist/server/EvidenceMcpServer.js +146 -0
  298. package/dist/server/createServer.js +15 -8
  299. package/dist/server/registerAndroidTools.js +2 -4
  300. package/dist/server/registerApplicationTools/helpers.js +2 -4
  301. package/dist/server/registerArtifactComparisonTool.js +11 -7
  302. package/dist/server/registerBinaryDiagnosticsTools.js +2 -4
  303. package/dist/server/registerBrowserScenarioTool.js +2 -4
  304. package/dist/server/registerBrowserTools.js +2 -4
  305. package/dist/server/registerBundleComparisonTool.js +2 -3
  306. package/dist/server/registerCloseLifecycleTool.js +8 -18
  307. package/dist/server/registerElectronTools.js +2 -4
  308. package/dist/server/registerEnhancedTools.js +18 -59
  309. package/dist/server/registerEvidenceTools.js +2 -4
  310. package/dist/server/registerEvmTools.js +2 -4
  311. package/dist/server/registerFirmwareTools.js +2 -4
  312. package/dist/server/registerFunctionComparisonTool.js +10 -6
  313. package/dist/server/registerInvestigationTools.js +7 -7
  314. package/dist/server/registerJavaScriptRecoveryTool.js +2 -4
  315. package/dist/server/registerJavaScriptRuntimeObservationTools.js +2 -4
  316. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +2 -4
  317. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +2 -4
  318. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +2 -4
  319. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +2 -4
  320. package/dist/server/registerOfficialTools.js +2 -4
  321. package/dist/server/registerProcessComparisonTool.js +71 -45
  322. package/dist/server/registerRecordedCrashTools.js +2 -4
  323. package/dist/server/registerSessionRecordTools.js +5 -6
  324. package/dist/server/registerSessionStatusTool.js +17 -3
  325. package/dist/server/registerSessionTools.js +11 -3
  326. package/dist/server/registerWebModuleTool.js +2 -4
  327. package/dist/server/registerWebNetworkCaptureTool.js +2 -4
  328. package/dist/server/registerWebRuntimeTools.js +3 -7
  329. package/dist/server/registerWebScriptTool.js +2 -4
  330. package/dist/server/registerWebSourceLocationTool.js +2 -4
  331. package/dist/server/runDerivedOperation.js +15 -3
  332. package/dist/server/sessionAvailabilityPolicy.js +0 -1
  333. package/dist/server/toolRegistrationOptions.js +2 -2
  334. package/dist/server/toolResult.js +62 -10
  335. package/dist/server/toolResultEncoding.js +33 -0
  336. package/install.sh +1 -1
  337. package/native/windows/build/manifest.json +1 -1
  338. package/package.json +8 -3
  339. package/scripts/electron-active-hook-boundaries.cjs +18 -20
  340. package/scripts/electron-active-hook.cjs +241 -37
  341. package/skills/reverse-engineer-anything/SKILL.md +11 -3
  342. package/skills/reverse-engineer-anything/references/javascript-applications.md +8 -1
  343. package/dist/ghidra/GhidraDefaults.js +0 -2
@@ -0,0 +1,178 @@
1
+ import { open } from "node:fs/promises";
2
+ import { nativeCallEventSchema } from "../domain/native/nativeCallObservation.js";
3
+ /** Maximum journal size enforced by the LLDB bridge. */
4
+ export const LLDB_OBSERVATION_JOURNAL_MAX_BYTES = 8 * 1024 * 1024;
5
+ const MAX_CAPTURE_BYTES = 1024 * 1024;
6
+ /** Join safely retained journal and process evidence into its failure contract. */
7
+ export const projectLldbPartialObservation = (input) => ({
8
+ kind: "native-call-observation",
9
+ target: input.target,
10
+ process: {
11
+ pid: input.pid ?? null,
12
+ stdout: input.stdout,
13
+ stderr: input.stderr,
14
+ other_stops: input.journal.otherStops,
15
+ },
16
+ debugger: { version: input.version },
17
+ events: input.journal.events,
18
+ coverage: { status: "partial", reason: input.reason },
19
+ limitations: [
20
+ "The LLDB run did not produce a complete native call observation result.",
21
+ "The target SHA-256 identifies the selected artifact; LLDB did not verify the bytes loaded into the process.",
22
+ "Captured output byte counts are observed lower bounds because LLDB did not report final stream counters.",
23
+ ...input.journal.limitations,
24
+ ...(input.journalLimitations ?? []),
25
+ ...(input.limitations ?? []),
26
+ ...(input.pid === undefined ? ["The target PID was unavailable."] : []),
27
+ ...(input.stdout === null
28
+ ? ["The target stdout capture was unavailable."]
29
+ : []),
30
+ ...(input.stderr === null
31
+ ? ["The target stderr capture was unavailable."]
32
+ : []),
33
+ ],
34
+ });
35
+ /** Parse completed JSONL records while retaining valid records around bad ones. */
36
+ export const parseLldbObservationJournal = (bytes) => {
37
+ const completeText = Buffer.from(bytes).toString("utf8");
38
+ const newline = completeText.lastIndexOf("\n");
39
+ const hasTornTail = newline !== completeText.length - 1;
40
+ const events = [];
41
+ const otherStops = [];
42
+ const limitations = [];
43
+ let malformedCount = 0;
44
+ let firstMalformedRow;
45
+ let start = 0;
46
+ let rowNumber = 0;
47
+ while (start <= newline && newline >= 0) {
48
+ const end = completeText.indexOf("\n", start);
49
+ if (end < 0 || end > newline)
50
+ break;
51
+ const line = completeText.slice(start, end);
52
+ start = end + 1;
53
+ if (line.length === 0)
54
+ continue;
55
+ rowNumber += 1;
56
+ const markMalformed = () => {
57
+ malformedCount += 1;
58
+ firstMalformedRow ??= rowNumber;
59
+ };
60
+ let row;
61
+ try {
62
+ row = JSON.parse(line);
63
+ }
64
+ catch {
65
+ markMalformed();
66
+ continue;
67
+ }
68
+ if (typeof row !== "object" ||
69
+ row === null ||
70
+ !("kind" in row) ||
71
+ typeof row.kind !== "string") {
72
+ markMalformed();
73
+ continue;
74
+ }
75
+ if (row.kind === "event" && "event" in row) {
76
+ const event = nativeCallEventSchema.safeParse(row.event);
77
+ if (event.success)
78
+ events.push(event.data);
79
+ else
80
+ markMalformed();
81
+ }
82
+ else if (row.kind === "other-stop" &&
83
+ "reason" in row &&
84
+ typeof row.reason === "string") {
85
+ otherStops.push(row.reason);
86
+ }
87
+ else {
88
+ markMalformed();
89
+ }
90
+ }
91
+ if (malformedCount > 0)
92
+ limitations.push(`${malformedCount} observation journal row(s) were malformed or invalid and ignored (first at row ${String(firstMalformedRow)}).`);
93
+ if (hasTornTail)
94
+ limitations.push("The final observation journal record was incomplete and was ignored.");
95
+ return { events, otherStops, limitations };
96
+ };
97
+ /** Keep reading a bounded prefix across short reads until EOF or the bound. */
98
+ export const readBoundedPrefix = async (requestedBytes, readChunk) => {
99
+ const buffer = Buffer.alloc(requestedBytes);
100
+ let bytesRead = 0;
101
+ while (bytesRead < requestedBytes) {
102
+ const count = await readChunk(buffer, bytesRead, requestedBytes - bytesRead, bytesRead);
103
+ if (count === 0)
104
+ break;
105
+ if (count > requestedBytes - bytesRead)
106
+ throw new Error("The bounded read returned more bytes than requested");
107
+ bytesRead += count;
108
+ }
109
+ return { buffer, bytesRead };
110
+ };
111
+ const readPrefix = (handle, requestedBytes) => readBoundedPrefix(requestedBytes, async (buffer, offset, length, position) => (await handle.read(buffer, offset, length, position)).bytesRead);
112
+ /** Read at most the bridge's journal bound, checking size before allocation. */
113
+ export const readLldbObservationJournal = async (path) => {
114
+ let handle;
115
+ try {
116
+ handle = await open(path, "r");
117
+ const { size } = await handle.stat();
118
+ const length = Math.min(size, LLDB_OBSERVATION_JOURNAL_MAX_BYTES);
119
+ const { buffer, bytesRead } = await readPrefix(handle, length);
120
+ const parsed = parseLldbObservationJournal(buffer.subarray(0, bytesRead));
121
+ const limitations = [
122
+ ...(size > LLDB_OBSERVATION_JOURNAL_MAX_BYTES
123
+ ? [
124
+ "The observation journal exceeded 8 MiB; only its bounded prefix was read.",
125
+ ]
126
+ : []),
127
+ ...(bytesRead < length
128
+ ? [
129
+ "The observation journal became shorter while being read; the available prefix was parsed.",
130
+ ]
131
+ : []),
132
+ ];
133
+ return {
134
+ parsed,
135
+ limitations,
136
+ };
137
+ }
138
+ catch (cause) {
139
+ return {
140
+ parsed: { events: [], otherStops: [], limitations: [] },
141
+ limitations: [
142
+ `The observation journal could not be read: ${cause instanceof Error ? cause.message : String(cause)}`,
143
+ ],
144
+ };
145
+ }
146
+ finally {
147
+ await handle?.close().catch(() => undefined);
148
+ }
149
+ };
150
+ /** Retain an available output prefix without claiming an unreported total. */
151
+ export const readPartialCapture = async (path) => {
152
+ let handle;
153
+ try {
154
+ handle = await open(path, "r");
155
+ const { size } = await handle.stat();
156
+ const length = Math.min(size, MAX_CAPTURE_BYTES);
157
+ const { buffer, bytesRead } = await readPrefix(handle, length);
158
+ return {
159
+ capture: {
160
+ text: buffer.subarray(0, bytesRead).toString("utf8"),
161
+ bytes: Math.max(size, bytesRead),
162
+ truncated: true,
163
+ complete: false,
164
+ },
165
+ limitations: bytesRead < length
166
+ ? [
167
+ "A target output capture became shorter while being read; its retained prefix may be incomplete.",
168
+ ]
169
+ : [],
170
+ };
171
+ }
172
+ catch {
173
+ return null;
174
+ }
175
+ finally {
176
+ await handle?.close().catch(() => undefined);
177
+ }
178
+ };
@@ -2,6 +2,7 @@ import { createHash } from "node:crypto";
2
2
  import { open } from "node:fs/promises";
3
3
  import { AnalysisCancelledError, AnalysisCapabilityUnavailableError, AnalysisInputError, } from "../domain/analysisErrorCore.js";
4
4
  import { EvidenceIntegrityError } from "../domain/evidenceErrors.js";
5
+ import { ProviderAdapterError } from "../domain/providerAdapterError.js";
5
6
  import { nativeCallObservationInputSchema, nativeCallObservationResultSchema, } from "../domain/native/nativeCallObservation.js";
6
7
  import { err, ok } from "../domain/result.js";
7
8
  const OPERATION = "observe_native_calls";
@@ -15,26 +16,42 @@ export const NATIVE_CALL_OBSERVATION_LIMITATIONS = [
15
16
  "The observation window is checked about once a second, and recording pauses the process at every entry, which slows it.",
16
17
  ];
17
18
  /** Launch the active Mach-O under LLDB, record requested call entries, then stop it. */
18
- export const observeNativeCalls = async (target, parameters, tracer, signal) => {
19
+ export const observeNativeCalls = async (target, parameters, tracer, signal, readTargetDigest = fileSha256) => {
19
20
  if (target.kind !== "executable" || target.format !== "mach-o")
20
21
  return err(new AnalysisCapabilityUnavailableError("native-macos", OPERATION, "Native call observation launches a Mach-O executable; the active target is not one"));
21
22
  const parsed = nativeCallObservationInputSchema.safeParse(parameters);
22
23
  if (!parsed.success)
23
24
  return err(new AnalysisInputError(OPERATION, { cause: parsed.error }));
24
25
  // Observe the bytes the session's other Evidence describes.
25
- if ((await fileSha256(target.path, signal)) !== target.sha256)
26
+ let digest;
27
+ try {
28
+ digest = await readTargetDigest(target.path, signal);
29
+ }
30
+ catch (cause) {
31
+ if (signal?.aborted === true || isAbortError(cause))
32
+ return err(new AnalysisCancelledError(OPERATION));
33
+ return err(new ProviderAdapterError("native-macos", OPERATION, {
34
+ diagnostics: {
35
+ reason: "Unable to verify the selected target digest",
36
+ detail: cause instanceof Error ? cause.message : String(cause),
37
+ },
38
+ }));
39
+ }
40
+ if (digest !== target.sha256)
26
41
  return err(new EvidenceIntegrityError("Native call observation target digest changed after session binding"));
27
42
  if (signal?.aborted === true)
28
43
  return err(new AnalysisCancelledError(OPERATION));
29
44
  const traced = await tracer.trace({
30
45
  executable: target.path,
31
46
  architecture: target.architecture,
47
+ expectedSha256: target.sha256,
32
48
  input: parsed.data,
33
49
  }, signal);
34
50
  if (!traced.ok)
35
51
  return traced;
36
52
  return ok(projectNativeCalls(target, parsed.data, traced.value));
37
53
  };
54
+ const isAbortError = (cause) => cause instanceof Error && cause.name === "AbortError";
38
55
  /** Join the request, the tracer's run and REA's own checks into the result contract. */
39
56
  export const projectNativeCalls = (target, input, trace) => {
40
57
  const { run } = trace;
@@ -42,14 +59,31 @@ export const projectNativeCalls = (target, input, trace) => {
42
59
  .filter(({ location_count: count }) => count === 0)
43
60
  .map(({ index }) => index);
44
61
  const eventLimit = run.outcome === "event-limit";
45
- const partial = eventLimit || run.outcome === "stop-limit" || unresolved.length > 0;
62
+ const resourceLimit = run.outcome === "resource-limit";
63
+ const breakpointLocationLimit = run.breakpoint_locations_truncated === true;
64
+ const partial = eventLimit ||
65
+ resourceLimit ||
66
+ breakpointLocationLimit ||
67
+ run.outcome === "duration-elapsed" ||
68
+ run.outcome === "stop-limit" ||
69
+ unresolved.length > 0;
46
70
  return nativeCallObservationResultSchema.parse({
47
71
  target: {
48
72
  path: target.path,
49
73
  sha256: target.sha256,
50
74
  architecture: target.architecture,
51
75
  arguments: input.arguments,
76
+ environment: input.environment,
52
77
  working_directory: input.working_directory ?? null,
78
+ launch_identity: {
79
+ loaded_image_sha256: run.target_identity.loaded_image_sha256,
80
+ file_device: run.target_identity.file_device,
81
+ file_inode: run.target_identity.file_inode,
82
+ selected_file_sha256: run.target_identity.selected_file_sha256,
83
+ module_path: run.target_identity.module_path,
84
+ module_uuid: run.target_identity.module_uuid,
85
+ stable: run.target_identity.stable,
86
+ },
53
87
  },
54
88
  debugger: trace.debugger,
55
89
  process: {
@@ -75,20 +109,35 @@ export const projectNativeCalls = (target, input, trace) => {
75
109
  coverage: {
76
110
  status: partial ? "partial" : "complete",
77
111
  event_limit_reached: eventLimit,
112
+ resource_limit_reached: resourceLimit,
113
+ ...(breakpointLocationLimit
114
+ ? { breakpoint_locations_truncated: true }
115
+ : {}),
78
116
  unresolved_breakpoints: unresolved,
79
117
  },
80
118
  limitations: [
81
119
  ...NATIVE_CALL_OBSERVATION_LIMITATIONS,
120
+ "The selected pathname digest and LLDB module identity are checked around launch. No immutable executable snapshot is used; concurrent in-place mutation or replacement and restoration cannot be ruled out, so the loaded-image digest remains unknown.",
82
121
  ...(eventLimit
83
122
  ? [
84
123
  `Observation stopped at max_events (${input.max_events}); later calls were not recorded and the process was killed.`,
85
124
  ]
86
125
  : []),
126
+ ...(resourceLimit
127
+ ? [
128
+ "Observation stopped before retaining the next complete event because the estimated 8 MiB trace-payload or 65,536-frame aggregate budget was reached; the process was killed.",
129
+ ]
130
+ : []),
87
131
  ...(run.outcome === "duration-elapsed"
88
132
  ? [
89
133
  `The process was still running after duration_ms (${input.duration_ms}) and was killed.`,
90
134
  ]
91
135
  : []),
136
+ ...(run.target_identity.stable
137
+ ? []
138
+ : [
139
+ "LLDB did not provide enough module identity evidence to confirm pathname and module continuity around launch.",
140
+ ]),
92
141
  ...(run.outcome === "stop-limit"
93
142
  ? [
94
143
  "Observation stopped after repeated signal or exception stops; the process was killed.",
@@ -104,9 +153,19 @@ export const projectNativeCalls = (target, input, trace) => {
104
153
  "Breakpoints with many matching locations list only the first 64; location_count gives the total.",
105
154
  ]
106
155
  : []),
156
+ ...(breakpointLocationLimit
157
+ ? [
158
+ "Resolved breakpoint locations exceeded the aggregate 8 MiB metadata budget; omitted locations are counted in location_count. This metadata limit does not change the process outcome.",
159
+ ]
160
+ : []),
107
161
  ...(trace.stdout.truncated || trace.stderr.truncated
108
162
  ? ["Target output beyond 1 MiB per stream is counted but not kept."]
109
163
  : []),
164
+ ...(!trace.stdout.complete || !trace.stderr.complete
165
+ ? [
166
+ "Target output draining did not complete; reported byte counts are observed lower bounds, not stream totals.",
167
+ ]
168
+ : []),
110
169
  ...(run.terminated && trace.terminated
111
170
  ? []
112
171
  : [
@@ -9,7 +9,7 @@ import { open, realpath, stat } from "node:fs/promises";
9
9
  import { z } from "zod";
10
10
  import { createAnalysisExecution, } from "../application/AnalysisProvider.js";
11
11
  import { NATIVE_TOOL_CONTRACTS, } from "../contracts/native/nativeToolContracts.js";
12
- import { AnalysisCancelledError, AnalysisCapabilityUnavailableError, AnalysisInputError, AnalysisOutputError, } from "../domain/analysisErrorCore.js";
12
+ import { AnalysisCancelledError, AnalysisCapabilityUnavailableError, AnalysisInputError, AnalysisOutputError, AnalysisResourceConstraintError, AnalysisTimeoutError, } from "../domain/analysisErrorCore.js";
13
13
  import { BinaryTargetError } from "../domain/configurationErrors.js";
14
14
  import { ProviderAdapterError } from "../domain/providerAdapterError.js";
15
15
  import { AnalysisError } from "../domain/analysisErrorBase.js";
@@ -17,7 +17,8 @@ import { jsonValueSchema } from "../domain/jsonValue.js";
17
17
  import { omittedPrototypeKeysLimitation, parseXmlPropertyList, } from "../domain/propertyListKeys.js";
18
18
  import { demangleSwiftSchema, inspectPlistSchema, inspectSignatureSchema, listArchitecturesSchema, } from "../domain/native/nativeInspection.js";
19
19
  import { err, ok } from "../domain/result.js";
20
- import { NativeCommandFailure, XcrunCommandRunner, } from "./CommandRunner.js";
20
+ import { NATIVE_COMMAND_TIMEOUT_MS, NATIVE_COMMAND_OUTPUT_BUDGET_BYTES, NativeCommandFailure, XcrunCommandRunner, } from "./CommandRunner.js";
21
+ import { withSignatureTarget, verifySignatureTarget, } from "./SignatureTargetBinding.js";
21
22
  import { parseCodeSignature } from "./parsers/codesign.js";
22
23
  import { parseDemangledSymbols } from "./parsers/demangle.js";
23
24
  import { parseLipoArchitectures } from "./parsers/lipo.js";
@@ -192,20 +193,23 @@ class NativeMacOSClient {
192
193
  });
193
194
  }
194
195
  async #inspectSignature(signal) {
195
- const display = await this.#run("inspect_signature", "codesign", ["-d", "--verbose=4", this.target.path], { signal, acceptNonZero: true });
196
+ return withSignatureTarget(this.target, (binding) => this.#inspectBoundSignature(binding, signal), signal);
197
+ }
198
+ async #inspectBoundSignature(binding, signal) {
199
+ const display = await this.#captureSignature(binding, ["-d", "--verbose=4"], signal);
196
200
  if (!display.ok)
197
201
  return display;
198
202
  const unsigned = isNonzeroUnsignedObservation(display.value);
199
203
  const displayFailure = codeSignCaptureFailure(display.value);
200
204
  if (displayFailure !== null)
201
205
  return err(displayFailure);
202
- const requirements = await this.#run("inspect_signature", "codesign", ["-d", "-r-", this.target.path], { signal, acceptNonZero: true });
206
+ const requirements = await this.#captureSignature(binding, ["-d", "-r-"], signal);
203
207
  if (!requirements.ok)
204
208
  return requirements;
205
209
  const requirementsFailure = codeSignCaptureFailure(requirements.value);
206
210
  if (requirementsFailure !== null)
207
211
  return err(requirementsFailure);
208
- const entitlements = await this.#run("inspect_signature", "codesign", ["-d", "--entitlements", ":-", this.target.path], { signal, acceptNonZero: true });
212
+ const entitlements = await this.#captureSignature(binding, ["-d", "--entitlements", ":-"], signal);
209
213
  if (!entitlements.ok)
210
214
  return entitlements;
211
215
  const entitlementsFailure = codeSignCaptureFailure(entitlements.value);
@@ -213,8 +217,8 @@ class NativeMacOSClient {
213
217
  return err(entitlementsFailure);
214
218
  // codesign echoes the resolved executable path in its diagnostics.
215
219
  const parsed = parseCodeSignature(display.value.stderr, unsigned, [
216
- this.target.path,
217
- ...(await canonicalPath(this.target.path)),
220
+ binding.snapshotPath,
221
+ ...(await canonicalPath(binding.snapshotPath)),
218
222
  ]);
219
223
  // The requirement is printed to stdout; stderr echoes the path.
220
224
  const requirementText = /designated\s*=>\s*(.+)$/mu.exec(requirements.value.stdout)?.[1] ?? null;
@@ -223,6 +227,7 @@ class NativeMacOSClient {
223
227
  const captures = [display.value, requirements.value, entitlements.value];
224
228
  const limitations = [
225
229
  ...parsed.limitations,
230
+ "Inspected a digest-verified Mach-O byte snapshot; filesystem-bound signing context and trust validation are not examined.",
226
231
  ...(entitlementValue.omittedPrototypeKeys === 0
227
232
  ? []
228
233
  : [
@@ -233,13 +238,19 @@ class NativeMacOSClient {
233
238
  (isNonzeroUnsignedObservation(requirements.value) ||
234
239
  isNonzeroUnsignedObservation(entitlements.value));
235
240
  if (mixedSigning) {
236
- const slices = await this.#inspectMixedSignatureSlices(parsed.format, requirements.value.exitCode !== 0, entitlements.value.exitCode !== 0, signal);
241
+ const slices = await this.#inspectMixedSignatureSlices(binding, parsed.format, {
242
+ requirements: requirements.value.exitCode,
243
+ entitlements: entitlements.value.exitCode,
244
+ }, signal);
237
245
  if (!slices.ok)
238
246
  return slices;
239
247
  captures.push(...slices.value.captures);
240
248
  limitations.push(...slices.value.limitations);
241
249
  }
242
- const provenance = captures.map((capture) => invocation(capture, this.target.path));
250
+ const provenance = captures.map((capture) => invocation(capture, binding.snapshotPath));
251
+ const version = await verifySignatureTarget(this.target, binding, signal);
252
+ if (!version.ok)
253
+ return version;
243
254
  const result = inspectSignatureSchema.parse({
244
255
  ...parsed,
245
256
  designated_requirement: requirementText,
@@ -254,12 +265,12 @@ class NativeMacOSClient {
254
265
  locations: [],
255
266
  });
256
267
  }
257
- async #inspectMixedSignatureSlices(format, requirementsUnavailable, entitlementsUnavailable, signal) {
268
+ async #inspectMixedSignatureSlices(binding, format, aggregateExits, signal) {
258
269
  const captures = [];
259
270
  const unsigned = [];
260
271
  const unclassified = [];
261
272
  for (const architecture of codeSignArchitectures(format, this.target)) {
262
- const slice = await this.#run("inspect_signature", "codesign", ["-d", "-a", architecture, "--verbose=4", this.target.path], { signal, acceptNonZero: true });
273
+ const slice = await this.#captureSignature(binding, ["-d", "-a", architecture, "--verbose=4"], signal);
263
274
  if (!slice.ok)
264
275
  return slice;
265
276
  captures.push(slice.value);
@@ -277,12 +288,38 @@ class NativeMacOSClient {
277
288
  ];
278
289
  if (unclassified.length > 0)
279
290
  limitations.push(`Signature state could not be classified for Mach-O slices: ${unclassified.join(", ")}.`);
280
- if (requirementsUnavailable)
291
+ if (aggregateExits.requirements !== 0)
281
292
  limitations.push("The aggregate designated requirement is unavailable because Mach-O slices have mixed signing states.");
282
- if (entitlementsUnavailable)
293
+ if (aggregateExits.entitlements !== 0)
283
294
  limitations.push("The aggregate entitlements are unavailable because Mach-O slices have mixed signing states.");
284
295
  return ok({ captures, limitations });
285
296
  }
297
+ async #captureSignature(binding, args, signal) {
298
+ const before = await verifySignatureTarget(this.target, binding, signal);
299
+ if (!before.ok)
300
+ return before;
301
+ let capture;
302
+ try {
303
+ capture = await this.#run("inspect_signature", "codesign", [...args, binding.snapshotPath], {
304
+ signal,
305
+ acceptNonZero: true,
306
+ });
307
+ }
308
+ catch (cause) {
309
+ capture = err(new ProviderAdapterError(IDENTITY.id, "inspect_signature", {
310
+ cause,
311
+ diagnostics: {
312
+ phase: "codesign-capture",
313
+ path: this.target.path,
314
+ reason: cause instanceof Error ? cause.message : String(cause),
315
+ },
316
+ }));
317
+ }
318
+ // Verify failed captures too: a disappearing target is not a codesign
319
+ // execution failure, and later captures must never use another version.
320
+ const after = await verifySignatureTarget(this.target, binding, signal);
321
+ return after.ok ? capture : after;
322
+ }
286
323
  async #inspectPlist(parameters, signal) {
287
324
  const requested = parameters.path;
288
325
  if (requested !== undefined && typeof requested !== "string")
@@ -366,13 +403,57 @@ class NativeMacOSClient {
366
403
  }
367
404
  const isNativeOperation = (operation) => NATIVE_TOOL_CONTRACTS.some(({ name }) => name === operation);
368
405
  const translateCommandFailure = (operation, failure) => {
406
+ const capturedOutput = failure.capture === null
407
+ ? undefined
408
+ : {
409
+ stdout: failure.capture.stdout,
410
+ stderr: failure.capture.stderr,
411
+ truncated: failure.capture.truncated,
412
+ stdout_bytes: failure.capture.stdoutBytes,
413
+ stderr_bytes: failure.capture.stderrBytes,
414
+ exit_code: failure.capture.exitCode,
415
+ signal: failure.capture.signal,
416
+ };
417
+ const cleanup = failure.cleanupFailure === null
418
+ ? undefined
419
+ : {
420
+ reason: failure.cleanupFailure,
421
+ resources: [...failure.cleanupResources],
422
+ };
423
+ const errorOptions = {
424
+ ...(capturedOutput === undefined ? {} : { capturedOutput }),
425
+ ...(cleanup === undefined ? {} : { cleanup }),
426
+ };
369
427
  if (failure.reason === "unavailable")
370
- return new AnalysisCapabilityUnavailableError(IDENTITY.id, operation, `${failure.tool} is unavailable through xcrun.`);
428
+ return new AnalysisCapabilityUnavailableError(IDENTITY.id, operation, `${failure.tool} is unavailable through xcrun.`, errorOptions);
371
429
  if (failure.reason === "cancelled")
372
- return new AnalysisCancelledError(operation);
373
- return new ProviderAdapterError(IDENTITY.id, operation, { cause: failure });
430
+ return new AnalysisCancelledError(operation, errorOptions);
431
+ if (failure.reason === "timeout")
432
+ return new AnalysisTimeoutError(operation, NATIVE_COMMAND_TIMEOUT_MS, errorOptions);
433
+ if (failure.reason === "output-limit")
434
+ return new AnalysisResourceConstraintError(operation, "memory", `Native command output exceeded ${String(NATIVE_COMMAND_OUTPUT_BUDGET_BYTES)} bytes; complete output is required for analysis.`, { max_output_bytes: NATIVE_COMMAND_OUTPUT_BUDGET_BYTES }, errorOptions);
435
+ return new ProviderAdapterError(IDENTITY.id, operation, {
436
+ cause: failure,
437
+ ...errorOptions,
438
+ diagnostics: {
439
+ tool: failure.tool,
440
+ reason: failure.reason,
441
+ exit_code: failure.capture?.exitCode ?? failure.exitCode,
442
+ signal: failure.capture?.signal ?? null,
443
+ stdout_bytes: failure.capture?.stdoutBytes ?? 0,
444
+ stderr_bytes: failure.capture?.stderrBytes ?? 0,
445
+ },
446
+ });
374
447
  };
375
- const translateCodeSignExitFailure = (capture) => translateCommandFailure("inspect_signature", new NativeCommandFailure("codesign", "nonzero-exit", capture.exitCode));
448
+ const translateCodeSignExitFailure = (capture) => translateCommandFailure("inspect_signature", new NativeCommandFailure("codesign", "nonzero-exit", capture.exitCode, undefined, {
449
+ stdout: capture.stdout,
450
+ stderr: capture.stderr,
451
+ stdoutBytes: capture.stdoutBytes,
452
+ stderrBytes: capture.stderrBytes,
453
+ exitCode: capture.exitCode,
454
+ signal: capture.signal,
455
+ truncated: false,
456
+ }));
376
457
  const commandOutput = (capture) => `${capture.stdout}\n${capture.stderr}`;
377
458
  /**
378
459
  * A signed artifact exits zero; its diagnostics can still contain this text