rea-agents 5.0.0 → 6.0.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 (275) hide show
  1. package/README.md +157 -650
  2. package/bridge/mitmproxy/capture.py +210 -0
  3. package/bridge/native/rea_lldb_tracer.py +303 -0
  4. package/bridge/process/ProcessRunTokenReader.swift +263 -0
  5. package/bridge/process/ProcessRunTokenReaderMain.swift +35 -0
  6. package/bridge/pwndbg/core_context.py +101 -0
  7. package/bridge/pwndbg/launch.py +39 -0
  8. package/bridge/pwndbg/launch_impl.py +34 -0
  9. package/bridge/pwntools/decoder_runtime.py +59 -0
  10. package/bridge/pwntools/layout.py +39 -0
  11. package/bridge/pwntools/layout_impl.py +309 -0
  12. package/bridge/pwntools/recorded_crash.py +39 -0
  13. package/bridge/pwntools/recorded_crash_impl.py +143 -0
  14. package/dist/android/JadxProvider.js +1 -0
  15. package/dist/application/CapabilityInventory.js +21 -0
  16. package/dist/application/DirectAnalysis.js +97 -23
  17. package/dist/application/EvidenceBundleFiles.js +1 -1
  18. package/dist/application/ReconstructionObligationCandidates.js +5 -1
  19. package/dist/application/WebNetworkCapturePort.js +1 -0
  20. package/dist/application/WebNetworkCaptureService.js +132 -0
  21. package/dist/application/WindowsCapabilities.js +1 -1
  22. package/dist/application/binary/AnalysisSnapshotCache.js +49 -6
  23. package/dist/application/binary/BinarySession.js +38 -10
  24. package/dist/application/binary/BinarySessionOpen.js +16 -3
  25. package/dist/application/binary/BinarySessionRecords.js +20 -0
  26. package/dist/application/binaryDiagnostics/BinaryLayoutPort.js +1 -0
  27. package/dist/application/binaryDiagnostics/BinaryLayoutService.js +57 -0
  28. package/dist/application/binaryDiagnostics/RecordedCrashPort.js +1 -0
  29. package/dist/application/binaryDiagnostics/RecordedCrashService.js +60 -0
  30. package/dist/application/evm/EvmInterfacePort.js +1 -0
  31. package/dist/application/evm/EvmInterfaceService.js +62 -0
  32. package/dist/application/javascript/JavaScriptApplicationEvidence.js +1 -2
  33. package/dist/application/javascript/JavaScriptApplicationService.js +15 -2
  34. package/dist/application/javascript/JavaScriptArtifactAnalysis.js +42 -23
  35. package/dist/application/javascript/JavaScriptArtifactGraphDocuments.js +26 -2
  36. package/dist/application/javascript/JavaScriptArtifactPathResolution.js +74 -24
  37. package/dist/application/javascript/JavaScriptArtifactReconstruction.js +23 -10
  38. package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +7 -7
  39. package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +145 -70
  40. package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +14 -15
  41. package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +41 -1
  42. package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +7 -7
  43. package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +5 -9
  44. package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +3 -3
  45. package/dist/application/javascript/JavaScriptSemanticGraphProjection.js +118 -12
  46. package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +3 -3
  47. package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +5 -5
  48. package/dist/application/{ProcessCli.js → process/ProcessCli.js} +10 -10
  49. package/dist/application/{ProcessEvidence.js → process/ProcessEvidence.js} +4 -4
  50. package/dist/artifacts/ArtifactProvider.js +30 -3
  51. package/dist/artifacts/ArtifactProviderMetadata.js +2 -1
  52. package/dist/artifacts/ZipArtifactReader.js +3 -0
  53. package/dist/artifacts/apple/DylibResolutionReader.js +259 -0
  54. package/dist/artifacts/apple/MachoLoadCommandReader.js +294 -0
  55. package/dist/{application → artifacts/extraction}/ArtifactExtraction.js +10 -10
  56. package/dist/{application → artifacts/inventory}/ArtifactGraphConstruction.js +3 -3
  57. package/dist/{application → artifacts/inventory}/ArtifactInventory.js +4 -4
  58. package/dist/{application/ArtifactInventory → artifacts/inventory}/classify.js +2 -2
  59. package/dist/{application/ArtifactInventory → artifacts/inventory}/reader.js +5 -5
  60. package/dist/{application/ArtifactInventory → artifacts/inventory}/scanCanonical.js +3 -3
  61. package/dist/{application/ArtifactInventory → artifacts/inventory}/scanReader.js +5 -5
  62. package/dist/artifacts/readStableArtifact.js +20 -4
  63. package/dist/browser/CdpCaptureEventHandlers.js +90 -2
  64. package/dist/browser/CdpCaptureEvents.js +9 -0
  65. package/dist/browser/PlaywrightElectronActiveProvider.js +12 -3
  66. package/dist/browser/history/CaptureFailures.js +101 -0
  67. package/dist/browser/history/CaptureFormatError.js +10 -0
  68. package/dist/browser/history/CaptureRedaction.js +65 -0
  69. package/dist/browser/history/CaptureRelease.js +12 -0
  70. package/dist/browser/history/HarCapture.js +165 -0
  71. package/dist/browser/history/HarCaptureAdapter.js +20 -0
  72. package/dist/browser/history/HarCaptureProcess.js +57 -0
  73. package/dist/browser/history/HarJson.js +91 -0
  74. package/dist/browser/history/HarSchema.js +72 -0
  75. package/dist/browser/history/HistoricalCaptureDecoder.js +186 -0
  76. package/dist/browser/history/HistoricalCaptureFormatAdapter.js +1 -0
  77. package/dist/browser/history/MitmproxyCaptureAdapter.js +42 -0
  78. package/dist/cli/artifactCommands.js +26 -1
  79. package/dist/cli/binaryDiagnosticsCommands.js +39 -0
  80. package/dist/cli/coreAnalysisCommands.js +2 -2
  81. package/dist/cli/coreBinaryCommands.js +8 -8
  82. package/dist/cli/electronCommands.js +16 -9
  83. package/dist/cli/evmCommands.js +24 -0
  84. package/dist/cli/firmwareCommands.js +6 -3
  85. package/dist/cli/javascriptApplicationAnalysis.js +16 -3
  86. package/dist/cli/jsonOutput.js +133 -0
  87. package/dist/cli/nativeCallCommands.js +35 -0
  88. package/dist/cli/processCommands.js +1 -1
  89. package/dist/cli/streamedJsonOutput.js +56 -0
  90. package/dist/cli/utilityCommands.js +2 -0
  91. package/dist/cli/webNetworkCaptureCommands.js +40 -0
  92. package/dist/cli.js +9 -3
  93. package/dist/cliBrowserScenarioCommands.js +2 -2
  94. package/dist/cliCommandNames.js +6 -0
  95. package/dist/cliJsonInput.js +30 -1
  96. package/dist/cliOutput.js +21 -6
  97. package/dist/composition/binaryDiagnostics.js +8 -0
  98. package/dist/composition/evm.js +4 -0
  99. package/dist/composition/webNetworkCaptures.js +6 -0
  100. package/dist/contracts/artifactToolContracts.js +6 -0
  101. package/dist/contracts/browserCaptureToolInputSchema.js +43 -0
  102. package/dist/contracts/browserToolContracts.js +4 -3
  103. package/dist/contracts/errorSchemas.js +8 -1
  104. package/dist/contracts/evm/evmToolContracts.js +20 -0
  105. package/dist/contracts/investigationExamples.js +2 -2
  106. package/dist/contracts/managed/managedToolContracts.js +7 -3
  107. package/dist/contracts/native/binaryDiagnosticsToolContracts.js +42 -0
  108. package/dist/contracts/native/nativeToolContracts.js +17 -1
  109. package/dist/contracts/officialToolContracts.js +12 -9
  110. package/dist/contracts/process/processCaptureExample.js +2 -0
  111. package/dist/contracts/sessionLifecycleInputs.js +22 -5
  112. package/dist/contracts/sessionStatusContract.js +10 -2
  113. package/dist/contracts/sessionToolContracts.js +8 -1
  114. package/dist/contracts/sessionToolSchemas.js +10 -3
  115. package/dist/contracts/toolContractExamples.js +1 -1
  116. package/dist/contracts/toolContracts.js +6 -0
  117. package/dist/contracts/toolEffects.js +30 -0
  118. package/dist/contracts/toolOutputSchemaGroups.js +5 -1
  119. package/dist/contracts/toolOutputSchemaPrimitives.js +1 -1
  120. package/dist/contracts/webNetworkCaptureToolContracts.js +24 -0
  121. package/dist/domain/analysisErrorBase.js +15 -0
  122. package/dist/domain/analysisErrorCore.js +59 -5
  123. package/dist/domain/analysisErrorPresentation.js +29 -1
  124. package/dist/domain/analysisErrorProjection.js +52 -2
  125. package/dist/domain/analysisSnapshot.js +166 -2
  126. package/dist/domain/apple/dyldPaths.js +81 -0
  127. package/dist/domain/apple/dylibResolution.js +367 -0
  128. package/dist/domain/apple/dylibResolutionFindings.js +75 -0
  129. package/dist/domain/artifactPathSyntax.js +1 -1
  130. package/dist/domain/browserObservation.js +1 -1
  131. package/dist/domain/browserObservationSchemas.js +13 -0
  132. package/dist/domain/browserScenarioValues.js +9 -2
  133. package/dist/domain/callPathSchemas.js +1 -1
  134. package/dist/domain/canonicalDigest.js +13 -1
  135. package/dist/domain/changedBehavior.js +3 -3
  136. package/dist/domain/comparisonStatus.js +2 -30
  137. package/dist/domain/conformanceTrustGate.js +0 -16
  138. package/dist/domain/evidence.js +17 -5
  139. package/dist/domain/evm/evmInterface.js +63 -0
  140. package/dist/domain/explicitSensitiveFailure.js +92 -0
  141. package/dist/domain/explicitSensitiveValues.js +10 -0
  142. package/dist/domain/firmware/firmwareAnalysis.js +8 -1
  143. package/dist/domain/javascript/electronActiveObservation.js +9 -4
  144. package/dist/domain/javascript/htmlArtifactReferences.js +40 -0
  145. package/dist/domain/javascript/javascriptExportShapeComparison.js +21 -5
  146. package/dist/domain/javascript/javascriptExportShapeVariants.js +0 -10
  147. package/dist/domain/javascript/javascriptSemanticGraph.js +21 -5
  148. package/dist/domain/jsonValue.js +4 -0
  149. package/dist/domain/localPath.js +2 -0
  150. package/dist/domain/native/binaryLayout.js +357 -0
  151. package/dist/domain/native/nativeCallObservation.js +164 -0
  152. package/dist/domain/native/objcSwiftMetadata.js +0 -39
  153. package/dist/domain/native/recordedCrash.js +266 -0
  154. package/dist/domain/native/recordedCrashNoteCoverage.js +73 -0
  155. package/dist/domain/{processCapture.js → process/processCapture.js} +139 -2
  156. package/dist/domain/{processCaptureExample.js → process/processCaptureExample.js} +5 -0
  157. package/dist/domain/process/processCaptureParsing.js +54 -0
  158. package/dist/domain/{processCaptureValidation.js → process/processCaptureValidation.js} +18 -2
  159. package/dist/domain/{processComparison.js → process/processComparison.js} +1 -1
  160. package/dist/domain/{processObservation.js → process/processObservation.js} +1 -1
  161. package/dist/domain/{processTraceSpecification.js → process/processTraceSpecification.js} +1 -1
  162. package/dist/domain/providerSelectionError.js +4 -2
  163. package/dist/domain/reconstructionVerification.js +3 -3
  164. package/dist/domain/reconstructionVerificationSchemas.js +1 -1
  165. package/dist/domain/residualUnknown.js +3 -2
  166. package/dist/domain/staticRuntimeCorrelation.js +3 -3
  167. package/dist/domain/webCaptureDiff.js +1 -0
  168. package/dist/domain/webNetworkCapture.js +118 -0
  169. package/dist/domain/webNetworkCaptureCoordinates.js +58 -0
  170. package/dist/dotnet/ManagedExceptionRegionValidation.js +41 -0
  171. package/dist/dotnet/ManagedMemberInspector.js +4 -2
  172. package/dist/dotnet/ManagedMemberInspectorCore.js +38 -32
  173. package/dist/dotnet/ManagedMemberInstructionDecoder.js +23 -7
  174. package/dist/dotnet/ManagedMemberRows.js +14 -3
  175. package/dist/dotnet/ManagedMetadataHeaps.js +20 -2
  176. package/dist/dotnet/ManagedMetadataInventory.js +38 -28
  177. package/dist/dotnet/ManagedMetadataInventoryRows.js +24 -10
  178. package/dist/dotnet/ManagedMethodBodyReader.js +7 -1
  179. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +15 -3
  180. package/dist/dotnet/ManagedNativeBoundaryInspector.js +3 -1
  181. package/dist/dotnet/ManagedPeReader.js +11 -0
  182. package/dist/evm/EvmBytecodeCarrier.js +21 -0
  183. package/dist/evm/EvmWorkerLimits.js +40 -0
  184. package/dist/evm/EvmoleFailures.js +126 -0
  185. package/dist/evm/EvmoleInterfaceAdapter.js +53 -0
  186. package/dist/evm/EvmoleInterfaceProvider.js +273 -0
  187. package/dist/evm/EvmoleInterfaceWorker.js +87 -0
  188. package/dist/evm/EvmoleRelease.js +16 -0
  189. package/dist/firmware/FirmwareCommand.js +1 -0
  190. package/dist/generatedPackageMetadata.js +2 -2
  191. package/dist/ghidra/GhidraLauncher.js +1 -0
  192. package/dist/ghidra/GhidraProvider.js +2 -2
  193. package/dist/ghidra/GhidraProviderCapabilities.js +1 -1
  194. package/dist/hopper/BridgeLauncher.js +2 -0
  195. package/dist/hopper/LinuxPrivateDisplayProbe.js +4 -2
  196. package/dist/javascript/recovery/WakaruCommand.js +3 -0
  197. package/dist/javascript/sourceMaps/SourceMapCommand.js +1 -0
  198. package/dist/native/CommandRunner.js +2 -1
  199. package/dist/native/LldbCallTracer.js +278 -0
  200. package/dist/native/NativeCallObservation.js +135 -0
  201. package/dist/native/NativeMacOSProvider.js +19 -3
  202. package/dist/native/NativeMacOSProviderMetadata.js +8 -3
  203. package/dist/native/pwndbg/PwndbgCoreContext.js +160 -0
  204. package/dist/native/pwntools/PwntoolsDecoder.js +203 -0
  205. package/dist/native/pwntools/PwntoolsFailures.js +180 -0
  206. package/dist/native/pwntools/PwntoolsLayoutProvider.js +36 -0
  207. package/dist/native/pwntools/PwntoolsRecordedCrashProvider.js +75 -0
  208. package/dist/native/pwntools/PwntoolsRelease.js +19 -0
  209. package/dist/native/pwntools/PwntoolsResourceLimits.js +76 -0
  210. package/dist/native/pwntools/RecordedCrashSourceBindings.js +46 -0
  211. package/dist/native/pwntools/RecordedCrashStructureBindings.js +101 -0
  212. package/dist/process/DarwinProcessRunTokenReader.js +294 -0
  213. package/dist/process/OwnedCommand.js +113 -0
  214. package/dist/process/ProcessOwnership.js +263 -33
  215. package/dist/process/ProcessOwnershipObservation.js +161 -24
  216. package/dist/process/ProviderProcess.js +30 -3
  217. package/dist/{application → process/capture}/ProcessCaptureCapability.js +15 -0
  218. package/dist/{application → process/capture}/ProcessCaptureError.js +17 -1
  219. package/dist/process/capture/ProcessCaptureLifecycle.js +615 -0
  220. package/dist/{application → process/capture}/ProcessHarness.js +195 -29
  221. package/dist/{application → process/capture}/ProcessSampling.js +2 -2
  222. package/dist/server/createServer.js +22 -0
  223. package/dist/server/promptCompletion.js +10 -3
  224. package/dist/server/registerBinaryDiagnosticsTools.js +17 -0
  225. package/dist/server/registerEvidenceTools.js +1 -1
  226. package/dist/server/registerEvmTools.js +17 -0
  227. package/dist/server/registerProcessComparisonTool.js +1 -1
  228. package/dist/server/registerRecordedCrashTools.js +17 -0
  229. package/dist/server/registerSessionTools.js +2 -2
  230. package/dist/server/registerWebNetworkCaptureTool.js +28 -0
  231. package/dist/server/sessionAvailabilityPolicy.js +3 -0
  232. package/dist/server/sessionToolPolicies.js +1 -1
  233. package/dist/server/toolResult.js +1 -1
  234. package/native/windows/build/manifest.json +2 -2
  235. package/native/windows/build/rea-windows-x64.node +0 -0
  236. package/package.json +37 -9
  237. package/scripts/rea.mjs +11 -3
  238. package/skills/reverse-engineer-anything/SKILL.md +23 -3
  239. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +29 -0
  240. package/third_party/README.md +60 -0
  241. package/third_party/evmole/LICENSE +21 -0
  242. package/third_party/evmole/README.md +22 -0
  243. package/third_party/pwndbg/LICENSE.md +21 -0
  244. package/third_party/pwndbg/README.md +23 -0
  245. package/third_party/pwntools/README.md +40 -0
  246. package/dist/application/AuthorizedArtifactInventory.js +0 -7
  247. package/dist/application/ProcessCaptureLifecycle.js +0 -299
  248. package/dist/application/StoreFileLock.js +0 -124
  249. package/dist/contracts/processCaptureExample.js +0 -2
  250. package/dist/domain/bytecodeProvider.js +0 -178
  251. package/dist/domain/customProtocolCapture.js +0 -137
  252. package/dist/domain/eventProcessTree.js +0 -225
  253. package/dist/domain/mobileApplicationInvestigation.js +0 -159
  254. package/dist/domain/packageAnalysis.js +0 -123
  255. package/dist/domain/peInspection.js +0 -197
  256. package/dist/domain/processCaptureParsing.js +0 -21
  257. package/dist/domain/protocolCapture.js +0 -217
  258. package/dist/domain/runtimeIdentification.js +0 -212
  259. package/dist/generatedMcpToolCatalog.js +0 -37
  260. /package/dist/application/{ArtifactExtractionDestination.js → artifacts/ArtifactExtractionDestination.js} +0 -0
  261. /package/dist/{application/ArtifactInventory → artifacts/inventory}/policy.js +0 -0
  262. /package/dist/{application/ArtifactInventory → artifacts/inventory}/types.js +0 -0
  263. /package/dist/domain/{processEvidenceProvider.js → process/processEvidenceProvider.js} +0 -0
  264. /package/dist/domain/{processScenario.js → process/processScenario.js} +0 -0
  265. /package/dist/domain/{processTraceComparison.js → process/processTraceComparison.js} +0 -0
  266. /package/dist/domain/{processTraceDimensionProjection.js → process/processTraceDimensionProjection.js} +0 -0
  267. /package/dist/domain/{processTraceEvaluation.js → process/processTraceEvaluation.js} +0 -0
  268. /package/dist/{application → process/capture}/FilesystemSnapshot.js +0 -0
  269. /package/dist/{application → process/capture}/ProcessCaptureEnvironment.js +0 -0
  270. /package/dist/{application → process/capture}/ProcessCaptureJournal.js +0 -0
  271. /package/dist/{application → process/capture}/ProcessFilesystemEffects.js +0 -0
  272. /package/dist/{application → process/capture}/ProcessNormalization.js +0 -0
  273. /package/dist/{application → process/capture}/ProcessScenarioRuntimeValidation.js +0 -0
  274. /package/dist/{application → process/capture}/ProcessTimer.js +0 -0
  275. /package/dist/{application → process/capture}/TerminalRenderer.js +0 -0
@@ -0,0 +1,35 @@
1
+ import { z } from "incur";
2
+ import { runProviderAnalysis } from "../composition/directAnalysis.js";
3
+ import { CLI_COMMANDS } from "../cliCommandNames.js";
4
+ import { parseCliJsonInput } from "../cliJsonInput.js";
5
+ import { logCliCommand } from "../cliLogging.js";
6
+ import { AnalysisInputError } from "../domain/analysisErrorCore.js";
7
+ import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
8
+ import { projectInputIssues } from "../domain/inputIssueProjection.js";
9
+ import { jsonValueSchema } from "../domain/jsonValue.js";
10
+ import { nativeCallObservationInputSchema } from "../domain/native/nativeCallObservation.js";
11
+ const OPERATION = "observe_native_calls";
12
+ /** `observe-native-calls <path> <input-json>`: the MCP input object as JSON. */
13
+ export const registerNativeCallCommands = (cli, logger) => {
14
+ cli.command(CLI_COMMANDS.observeNativeCalls, {
15
+ description: "Launch a Mach-O under LLDB and record entries into selected functions or Objective-C methods",
16
+ args: z.object({
17
+ path: z.string().describe("Mach-O or app path"),
18
+ inputJson: z
19
+ .string()
20
+ .describe("Inline JSON or a JSON file path: breakpoints, arguments, environment, duration_ms, max_events, argument_registers, backtrace_frames"),
21
+ }),
22
+ run: ({ args }) => logCliCommand(logger, CLI_COMMANDS.observeNativeCalls, async () => {
23
+ const input = await parseCliJsonInput(args.inputJson, OPERATION);
24
+ if (!input.ok)
25
+ return input.error;
26
+ const parsed = nativeCallObservationInputSchema.safeParse(input.value);
27
+ if (!parsed.success)
28
+ return {
29
+ error: "Analysis failed",
30
+ ...projectAnalysisError(new AnalysisInputError(OPERATION, undefined, projectInputIssues(parsed.error.issues, input.value))),
31
+ };
32
+ return runProviderAnalysis(args.path, OPERATION, z.record(z.string(), jsonValueSchema).parse(parsed.data), logger);
33
+ }),
34
+ });
35
+ };
@@ -1,5 +1,5 @@
1
1
  import { Cli, z } from "incur";
2
- import { captureProcessScenarioFile, compareProcessEvidenceFiles, isProcessCliFailure, } from "../application/ProcessCli.js";
2
+ import { captureProcessScenarioFile, compareProcessEvidenceFiles, isProcessCliFailure, } from "../application/process/ProcessCli.js";
3
3
  import { logCliCommand } from "../cliLogging.js";
4
4
  import { CLI_COMMANDS } from "../cliCommandNames.js";
5
5
  /** Register direct process capture and comparison commands. */
@@ -0,0 +1,56 @@
1
+ import {} from "node:stream";
2
+ import { Filter } from "incur";
3
+ import { parseCliOutputArguments } from "../cliOutput.js";
4
+ import { writeJsonOutput } from "./jsonOutput.js";
5
+ /** Preserve Incur's JSON controls while streaming the complete result. */
6
+ export const createStreamedCliJsonOutput = (arguments_, destination) => {
7
+ const options = parseCliOutputArguments(arguments_);
8
+ if (options.parseError ||
9
+ options.tokenCount ||
10
+ options.tokenWindow ||
11
+ (options.format !== "json" && options.format !== "jsonl"))
12
+ return undefined;
13
+ const format = options.format;
14
+ let handled = false;
15
+ let failed = false;
16
+ return {
17
+ get handled() {
18
+ return handled;
19
+ },
20
+ get failed() {
21
+ return failed;
22
+ },
23
+ async write(value, metadata) {
24
+ if (metadata.format !== format)
25
+ return false;
26
+ const filtered = options.filterOutput
27
+ ? Filter.apply(value, Filter.parse(options.filterOutput))
28
+ : value;
29
+ const meta = {
30
+ command: metadata.command,
31
+ duration: metadata.duration,
32
+ };
33
+ const document = options.fullOutput
34
+ ? filtered === undefined
35
+ ? { ok: true, meta }
36
+ : { ok: true, data: filtered, meta }
37
+ : filtered === undefined ||
38
+ filtered === null ||
39
+ typeof filtered === "function" ||
40
+ typeof filtered === "symbol"
41
+ ? {}
42
+ : filtered;
43
+ // Once writing starts, a failed destination must not receive a second
44
+ // document from Incur's error formatter.
45
+ handled = true;
46
+ try {
47
+ await writeJsonOutput(document, destination, format);
48
+ }
49
+ catch (cause) {
50
+ failed = true;
51
+ throw cause;
52
+ }
53
+ return true;
54
+ },
55
+ };
56
+ };
@@ -13,9 +13,11 @@ import { logCliCommand } from "../cliLogging.js";
13
13
  import { CLI_COMMANDS } from "../cliCommandNames.js";
14
14
  import { swiftSymbolsSchema } from "../contracts/native/nativeToolContracts.js";
15
15
  import { isReferenceSourceImportCliFailure } from "./referenceSourceImportStatus.js";
16
+ import { registerNativeCallCommands } from "./nativeCallCommands.js";
16
17
  export const registerUtilityCommands = (cli, logger, environment = process.env) => {
17
18
  registerCapabilityCommands(cli, logger);
18
19
  registerNativeCommands(cli, logger);
20
+ registerNativeCallCommands(cli, logger);
19
21
  for (const [command, operation] of [
20
22
  [CLI_COMMANDS.observeNativeUi, "observe_native_ui"],
21
23
  [CLI_COMMANDS.captureNativeUiScenario, "capture_native_ui_scenario"],
@@ -0,0 +1,40 @@
1
+ import { z } from "incur";
2
+ import { createWebNetworkCaptureService } from "../composition/webNetworkCaptures.js";
3
+ import { CLI_COMMANDS } from "../cliCommandNames.js";
4
+ import { logCliCommand } from "../cliLogging.js";
5
+ import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
6
+ import { withCommandCancellation } from "./commandCancellation.js";
7
+ /** Expose offline historical capture inspection with the same selection contract as MCP. */
8
+ export const registerWebNetworkCaptureCommands = (cli, logger, environment) => {
9
+ const service = createWebNetworkCaptureService(environment);
10
+ cli.command(CLI_COMMANDS.inspectWebNetworkCapture, {
11
+ description: "Inspect retained HAR or native mitmproxy records without fetching recorded URLs",
12
+ args: z.object({
13
+ capturePath: z.string().describe("Absolute local capture path"),
14
+ format: z.enum(["har", "mitmproxy"]).describe("Producer capture format"),
15
+ }),
16
+ options: z.object({
17
+ record: z
18
+ .array(z.coerce.number().int().nonnegative())
19
+ .optional()
20
+ .describe("Zero-based producer ordinals; repeat to select several"),
21
+ sensitiveValue: z
22
+ .array(z.string().min(1))
23
+ .default([])
24
+ .describe("Literal string values explicitly marked sensitive; repeat as needed"),
25
+ }),
26
+ run: ({ args, options }) => withCommandCancellation((signal) => logCliCommand(logger, CLI_COMMANDS.inspectWebNetworkCapture, async () => {
27
+ const result = await service.inspect({
28
+ capture_path: args.capturePath,
29
+ format: args.format,
30
+ sensitive_values: options.sensitiveValue,
31
+ ...(options.record === undefined
32
+ ? {}
33
+ : { record_ordinals: options.record }),
34
+ }, { signal });
35
+ return result.ok
36
+ ? result.value
37
+ : projectAnalysisError(result.error);
38
+ })),
39
+ });
40
+ };
package/dist/cli.js CHANGED
@@ -1,3 +1,5 @@
1
+ import { registerEvmCommands } from "./cli/evmCommands.js";
2
+ import { registerBinaryDiagnosticsCommands } from "./cli/binaryDiagnosticsCommands.js";
1
3
  import { Cli } from "incur";
2
4
  import { createLogger, parseLogLevel } from "./logger.js";
3
5
  import { PRODUCT_IDENTITY } from "./identity.js";
@@ -15,6 +17,7 @@ import { registerWebScriptCommands } from "./cli/webScriptCommands.js";
15
17
  import { registerWebModuleCommands } from "./cli/webModuleCommands.js";
16
18
  import { registerWebSourceLocationCommands } from "./cli/webSourceLocationCommands.js";
17
19
  import { registerWebRuntimeCommands } from "./cli/webRuntimeCommands.js";
20
+ import { registerWebNetworkCaptureCommands } from "./cli/webNetworkCaptureCommands.js";
18
21
  import { registerJavaScriptRecoveryCommands } from "./cli/javascriptRecoveryCommands.js";
19
22
  import { registerAdvancedBrowserCommands } from "./cli/browserAdvancedCommands.js";
20
23
  import { registerBrowserScenarioCommands } from "./cliBrowserScenarioCommands.js";
@@ -26,7 +29,7 @@ import { registerApplicationCommands } from "./cli/applicationCommands.js";
26
29
  * Analysis commands acquire and close their own sessions; bare `mcp` and
27
30
  * `--mcp` are intercepted by the executable dispatcher before this module loads.
28
31
  */
29
- export const createCli = (environment = process.env) => {
32
+ export const createCli = (environment = process.env, resultOutput) => {
30
33
  const logger = createLogger("cli", environment.REA_LOG_LEVEL === undefined
31
34
  ? "silent"
32
35
  : parseLogLevel(environment.REA_LOG_LEVEL));
@@ -40,12 +43,14 @@ export const createCli = (environment = process.env) => {
40
43
  sync: false,
41
44
  });
42
45
  registerSetupCommands(cli, logger);
43
- registerCoreAnalysisCommands(cli, logger);
46
+ registerCoreAnalysisCommands(cli, logger, resultOutput);
44
47
  registerUtilityCommands(cli, logger, environment);
48
+ registerEvmCommands(cli, logger, environment);
45
49
  registerArtifactCommands(cli, logger);
46
50
  registerManagedCommands(cli, logger);
47
51
  registerAndroidCommands(cli, logger, environment);
48
52
  registerFirmwareCommands(cli, logger, environment);
53
+ registerBinaryDiagnosticsCommands(cli, logger, environment);
49
54
  registerEvidenceCommands(cli, logger);
50
55
  registerProcessCommands(cli, logger, environment);
51
56
  registerBrowserCommands(cli, logger);
@@ -53,10 +58,11 @@ export const createCli = (environment = process.env) => {
53
58
  registerWebModuleCommands(cli, logger, environment);
54
59
  registerWebSourceLocationCommands(cli, logger, environment);
55
60
  registerWebRuntimeCommands(cli, logger);
61
+ registerWebNetworkCaptureCommands(cli, logger, environment);
56
62
  registerJavaScriptRecoveryCommands(cli, logger, environment);
57
63
  registerAdvancedBrowserCommands(cli, logger);
58
64
  registerBrowserScenarioCommands(cli, logger);
59
- registerElectronCommands(cli, logger);
65
+ registerElectronCommands(cli, logger, resultOutput);
60
66
  registerJavaScriptRuntimeObservationCommands(cli, logger);
61
67
  registerApplicationCommands(cli, logger);
62
68
  return cli;
@@ -3,7 +3,7 @@ import { z } from "zod";
3
3
  import { captureBrowserScenario } from "./application/BrowserScenarioCaptureService.js";
4
4
  import { createBrowserScenarioProvider } from "./composition/browserScenario.js";
5
5
  import { CLI_COMMANDS } from "./cliCommandNames.js";
6
- import { parseCliJsonInput } from "./cliJsonInput.js";
6
+ import { parseCliJsonInput, resolveCliJsonPaths } from "./cliJsonInput.js";
7
7
  import { logCliCommand } from "./cliLogging.js";
8
8
  import { AnalysisInputError } from "./domain/analysisErrorCore.js";
9
9
  import { projectAnalysisError } from "./domain/analysisErrorProjection.js";
@@ -23,7 +23,7 @@ export const registerBrowserScenarioCommands = (cli, logger) => {
23
23
  const input = await parseCliJsonInput(args.inputJson, OPERATION);
24
24
  if (!input.ok)
25
25
  return input.error;
26
- const scenario = browserScenarioSchema.safeParse(input.value);
26
+ const scenario = browserScenarioSchema.safeParse(resolveCliJsonPaths(input.value, [["browser", "executable_path"]]));
27
27
  if (!scenario.success)
28
28
  return cliError(new AnalysisInputError(OPERATION, { cause: scenario.error }, projectInputIssues(scenario.error.issues, input.value)));
29
29
  const result = await captureBrowserScenario(createBrowserScenarioProvider(), scenario.data);
@@ -1,5 +1,7 @@
1
1
  /** Canonical names used by every one-shot CLI command registration. */
2
2
  export const CLI_COMMANDS = Object.freeze({
3
+ inspectEvmInterface: "inspect-evm-interface",
4
+ inspectWebNetworkCapture: "inspect-web-network-capture",
3
5
  observeWebExecution: "observe-web-execution",
4
6
  inspectWebEventListeners: "inspect-web-event-listeners",
5
7
  traceWebSourceLocation: "trace-web-source-location",
@@ -27,6 +29,7 @@ export const CLI_COMMANDS = Object.freeze({
27
29
  extractArtifact: "extract-artifact",
28
30
  decodeInterfaceBuilder: "decode-interface-builder",
29
31
  inspectKeyedArchive: "inspect-keyed-archive",
32
+ traceDylibResolution: "trace-dylib-resolution",
30
33
  inspectNativeDataType: "inspect-native-data-type",
31
34
  inspectNativeLoadImage: "inspect-native-load-image",
32
35
  readBytes: "read-bytes",
@@ -36,6 +39,8 @@ export const CLI_COMMANDS = Object.freeze({
36
39
  resolveNativeCallTargets: "resolve-native-call-targets",
37
40
  inspectAssetCatalog: "inspect-asset-catalog",
38
41
  inspectManagedArtifact: "inspect-managed-artifact",
42
+ inspectRecordedCrash: "inspect-recorded-crash",
43
+ inspectBinaryLayout: "inspect-binary-layout",
39
44
  inspectFirmwareRegions: "inspect-firmware-regions",
40
45
  extractFirmware: "extract-firmware",
41
46
  inspectAndroidPackage: "inspect-android-package",
@@ -50,6 +55,7 @@ export const CLI_COMMANDS = Object.freeze({
50
55
  importManagedReconstruction: "import-managed-reconstruction",
51
56
  projectManagedApplicationGraph: "project-managed-application-graph",
52
57
  observeNativeUi: "observe-native-ui",
58
+ observeNativeCalls: "observe-native-calls",
53
59
  captureNativeUiScenario: "capture-native-ui-scenario",
54
60
  inspectMacho: "inspect-macho",
55
61
  inspectSignature: "inspect-signature",
@@ -1,4 +1,5 @@
1
1
  import { readFile } from "node:fs/promises";
2
+ import { resolve } from "node:path";
2
3
  import { AnalysisInputError } from "./domain/analysisErrorCore.js";
3
4
  import { projectAnalysisError } from "./domain/analysisErrorProjection.js";
4
5
  import { safeParseJson } from "./domain/safeJson.js";
@@ -23,10 +24,38 @@ export const parseCliJsonInput = async (value, operation) => {
23
24
  return jsonFileError(value, operation, "read-failed", cause);
24
25
  }
25
26
  };
27
+ /**
28
+ * Resolve named string fields of CLI-supplied JSON against the operator
29
+ * working directory. Each entry is a key path from the document root; only
30
+ * fields holding strings are resolved, everything else passes through
31
+ * untouched. Shared MCP contracts reject relative paths, so CLI workflows
32
+ * resolve operator-relative values before validation.
33
+ */
34
+ export const resolveCliJsonPaths = (value, paths) => {
35
+ let resolved = value;
36
+ for (const keys of paths)
37
+ resolved = resolveJsonPath(resolved, keys);
38
+ return resolved;
39
+ };
40
+ const resolveJsonPath = (value, keys) => {
41
+ const [head, ...tail] = keys;
42
+ if (typeof value !== "object" || value === null || Array.isArray(value))
43
+ return value;
44
+ const entries = Object.entries(value).map(([key, entry]) => {
45
+ if (key !== head)
46
+ return [key, entry];
47
+ if (tail.length === 0)
48
+ return [key, typeof entry === "string" ? resolve(entry) : entry];
49
+ return [key, resolveJsonPath(entry, tail)];
50
+ });
51
+ return Object.fromEntries(entries);
52
+ };
26
53
  const cannotBeAnExistingFile = (cause) => typeof cause === "object" &&
27
54
  cause !== null &&
28
55
  "code" in cause &&
29
- (cause.code === "ENOENT" || cause.code === "ENAMETOOLONG");
56
+ (cause.code === "ENOENT" ||
57
+ cause.code === "ENAMETOOLONG" ||
58
+ cause.code === "ENOTDIR");
30
59
  const hasExplicitJsonFileExtension = (value) => value.toLowerCase().endsWith(".json");
31
60
  const parseJson = (value) => {
32
61
  let text;
package/dist/cliOutput.js CHANGED
@@ -10,10 +10,21 @@ const validationError = (value) => {
10
10
  return value.error.code === "VALIDATION_ERROR" ? value.error : undefined;
11
11
  return undefined;
12
12
  };
13
- const parseCliOutputArguments = (arguments_) => {
13
+ /** Read effective Incur output controls at the executable boundary. */
14
+ export const parseCliOutputArguments = (arguments_) => {
14
15
  let format = "toon";
15
- let filterOutput = false;
16
+ let filterOutput;
17
+ let fullOutput = false;
18
+ let tokenCount = false;
16
19
  let tokenWindow = false;
20
+ const parsed = (parseError) => ({
21
+ filterOutput,
22
+ format,
23
+ fullOutput,
24
+ parseError,
25
+ tokenCount,
26
+ tokenWindow: parseError ? false : tokenWindow,
27
+ });
17
28
  for (let index = 0; index < arguments_.length; index += 1) {
18
29
  const argument = arguments_[index];
19
30
  // Incur scans builtins across `--` and accepts only spaced value forms.
@@ -28,7 +39,7 @@ const parseCliOutputArguments = (arguments_) => {
28
39
  // Incur stops parsing at an invalid format before applying any later
29
40
  // output controls. Let it report that malformed flag itself.
30
41
  if (!INCUR_OUTPUT_FORMATS.has(value))
31
- return { filterOutput, format, parseError: true, tokenWindow: false };
42
+ return parsed(true);
32
43
  format = value;
33
44
  index += 1;
34
45
  }
@@ -36,7 +47,7 @@ const parseCliOutputArguments = (arguments_) => {
36
47
  }
37
48
  if (argument === "--filter-output") {
38
49
  if (arguments_[index + 1]) {
39
- filterOutput = true;
50
+ filterOutput = arguments_[index + 1];
40
51
  index += 1;
41
52
  }
42
53
  continue;
@@ -46,14 +57,18 @@ const parseCliOutputArguments = (arguments_) => {
46
57
  if (value) {
47
58
  const numericValue = Number(value);
48
59
  if (!Number.isFinite(numericValue) || value.trim() === "")
49
- return { filterOutput, format, parseError: true, tokenWindow: false };
60
+ return parsed(true);
50
61
  tokenWindow = true;
51
62
  index += 1;
52
63
  }
53
64
  continue;
54
65
  }
66
+ if (argument === "--full-output")
67
+ fullOutput = true;
68
+ if (argument === "--token-count")
69
+ tokenCount = true;
55
70
  }
56
- return { filterOutput, format, parseError: false, tokenWindow };
71
+ return parsed(false);
57
72
  };
58
73
  /** Reject text-window controls that would corrupt a structured document. */
59
74
  export const validateCliOutputArguments = (arguments_) => {
@@ -0,0 +1,8 @@
1
+ import { RecordedCrashService } from "../application/binaryDiagnostics/RecordedCrashService.js";
2
+ import { PwntoolsRecordedCrashProvider } from "../native/pwntools/PwntoolsRecordedCrashProvider.js";
3
+ import { BinaryLayoutService } from "../application/binaryDiagnostics/BinaryLayoutService.js";
4
+ import { PwntoolsLayoutProvider } from "../native/pwntools/PwntoolsLayoutProvider.js";
5
+ /** Compose the offline adapter without import-time I/O or dependency acquisition. */
6
+ export const createBinaryLayoutService = (environment = process.env) => new BinaryLayoutService(new PwntoolsLayoutProvider(environment));
7
+ /** Compose recorded-core inspection without acquiring a debugger or toolchain. */
8
+ export const createRecordedCrashService = (environment = process.env) => new RecordedCrashService(new PwntoolsRecordedCrashProvider(environment));
@@ -0,0 +1,4 @@
1
+ import { EvmInterfaceService } from "../application/evm/EvmInterfaceService.js";
2
+ import { EvmoleInterfaceProvider } from "../evm/EvmoleInterfaceProvider.js";
3
+ /** Compose offline interface analysis without import-time I/O or dependency acquisition. */
4
+ export const createEvmInterfaceService = (environment = process.env) => new EvmInterfaceService(new EvmoleInterfaceProvider(environment));
@@ -0,0 +1,6 @@
1
+ import { WebNetworkCaptureService } from "../application/WebNetworkCaptureService.js";
2
+ import { HistoricalCaptureDecoder } from "../browser/history/HistoricalCaptureDecoder.js";
3
+ import { HarCaptureAdapter } from "../browser/history/HarCaptureAdapter.js";
4
+ import { MitmproxyCaptureAdapter } from "../browser/history/MitmproxyCaptureAdapter.js";
5
+ /** Compose offline format adapters without import-time reads, installation or process startup. */
6
+ export const createWebNetworkCaptureService = (environment = process.env) => new WebNetworkCaptureService(new HistoricalCaptureDecoder([new HarCaptureAdapter(), new MitmproxyCaptureAdapter(environment)], environment));
@@ -4,6 +4,7 @@ import { jsonValueSchema } from "../domain/jsonValue.js";
4
4
  import { toolContractMetadata } from "./toolEffects.js";
5
5
  import { requireOutputSchema } from "./toolOutputSchemaPrimitives.js";
6
6
  import { appleAssetCatalogInputSchema } from "../domain/apple/appleAssetCatalog.js";
7
+ import { dylibResolutionInputSchema } from "../domain/apple/dylibResolution.js";
7
8
  import { keyedArchiveInputSchema } from "../domain/apple/keyedArchive.js";
8
9
  /** Exact caller boundary for deterministic artifact inventory. */
9
10
  export const artifactInventoryInputSchema = z.strictObject({
@@ -22,6 +23,10 @@ const examples = {
22
23
  decode_interface_builder: {},
23
24
  inspect_asset_catalog: { offset: 0, limit: 1000 },
24
25
  inspect_keyed_archive: { path: "Contents/Resources/Model.plist" },
26
+ trace_dylib_resolution: {
27
+ roots: ["Contents/MacOS/App"],
28
+ architecture: "arm64",
29
+ },
25
30
  };
26
31
  const artifact = (name, description, inputSchema) => {
27
32
  const outputSchema = requireOutputSchema(artifactOutputSchemas, name);
@@ -51,6 +56,7 @@ export const ARTIFACT_TOOL_CONTRACTS = [
51
56
  })),
52
57
  artifact("inspect_keyed_archive", "Inspect one Foundation NSKeyedArchiver plist in the active app bundle as original object-table nodes, class descriptors, named roots, and UID edges. Preserves shared and cyclic references without instantiating classes. The path is relative to the bundle; root selection and object pagination preserve original identities.", keyedArchiveInputSchema),
53
58
  artifact("inspect_asset_catalog", "Inspect compiled Assets.car metadata in an active Apple app bundle. Returns stable paginated catalog and rendition records with raw assetutil metadata and catalog digests; rendition bytes are not extracted.", appleAssetCatalogInputSchema),
59
+ artifact("trace_dylib_resolution", "Trace how dyld would resolve each Mach-O dylib load for the active Mach-O, or for every executable in the active .app bundle (the main app, XPC services, extensions, login items, helpers). Expands @executable_path, @loader_path, and @rpath through each process's LC_RPATH stack in dependents-first load order, and reports every candidate path with its outcome, the resolved image and digest, weak, re-export, and upward flags, and derived findings such as unresolved required loads or absent earlier @rpath candidates. Pure header parsing: nothing is executed, and absolute or system paths outside the analyzed root stay undetermined. Select roots or one architecture to narrow large bundles.", dylibResolutionInputSchema),
54
60
  ];
55
61
  /** Provider operations; inventory remains an internal primitive of inspection. */
56
62
  export const ARTIFACT_ANALYSIS_OPERATIONS = [
@@ -0,0 +1,43 @@
1
+ import { browserCaptureComparisonInputSchema } from "../domain/browserCaptureComparison.js";
2
+ import { browserScenarioCaptureSchema } from "../domain/browserScenarioCapture.js";
3
+ import { captureSnapshotSchema } from "../domain/webCaptureDiffSchemas.js";
4
+ // Captures are complete producer results to pass back unchanged, rather than
5
+ // analyst-authored options. Describe that boundary without embedding the entire
6
+ // inspection result schema in every comparison input. The cloned parser still
7
+ // validates every nested field using the canonical domain schemas.
8
+ const passiveCaptureInputSchema = captureSnapshotSchema.clone(captureSnapshotSchema.def);
9
+ passiveCaptureInputSchema._zod.toJSONSchema = () => ({
10
+ type: "object",
11
+ properties: {
12
+ inspection: {
13
+ type: "object",
14
+ description: "Complete result object returned by inspect_web_page. Pass the entire result unchanged, including capture identity, observations, completeness, and limitations. Every nested field is validated by REA.",
15
+ },
16
+ webmcp: {
17
+ anyOf: [{ type: "object" }, { type: "null" }],
18
+ default: null,
19
+ description: "Complete result object returned by discover_webmcp_tools for this capture, or null when it was not recorded. Pass the entire result unchanged. Every nested field is validated by REA.",
20
+ },
21
+ },
22
+ required: ["inspection"],
23
+ });
24
+ const scenarioCaptureInputSchema = browserScenarioCaptureSchema.clone(browserScenarioCaptureSchema.def);
25
+ scenarioCaptureInputSchema._zod.toJSONSchema = () => ({
26
+ type: "object",
27
+ description: "Complete result object returned by capture_browser_scenario. Pass the entire result unchanged, including browser and scenario identity, steps, events, artifact contents and digests, completeness, and limitations. Every nested field is validated by REA.",
28
+ });
29
+ /** Advertise capture round trips while retaining full runtime validation. */
30
+ export const browserCaptureToolInputSchema = browserCaptureComparisonInputSchema.safeExtend({
31
+ before: passiveCaptureInputSchema
32
+ .optional()
33
+ .describe("Earlier passive web-page capture with complete producer results."),
34
+ after: passiveCaptureInputSchema
35
+ .optional()
36
+ .describe("Later passive web-page capture with complete producer results."),
37
+ before_scenario: scenarioCaptureInputSchema
38
+ .optional()
39
+ .describe("Earlier complete result object returned by capture_browser_scenario."),
40
+ after_scenario: scenarioCaptureInputSchema
41
+ .optional()
42
+ .describe("Later complete result object returned by capture_browser_scenario."),
43
+ });
@@ -2,10 +2,11 @@ import { browserTargetListSchema, inspectWebPageInputSchema, listBrowserTargetsI
2
2
  import { analyzeWebBundleInputSchema, webBundleAnalysisSchema, } from "../domain/webBundleAnalysis.js";
3
3
  import { observeWebSessionInputSchema, webObservationSessionSchema, } from "../domain/browserSession.js";
4
4
  import { discoverWebMcpToolsInputSchema, webMcpDiscoverySchema, } from "../domain/webMcpDiscovery.js";
5
- import { browserCaptureComparisonInputSchema, browserCaptureComparisonSchema, } from "../domain/browserCaptureComparison.js";
5
+ import { browserCaptureComparisonSchema } from "../domain/browserCaptureComparison.js";
6
6
  import { captureWebScreenshotInputSchema, compareWebScreenshotsInputSchema, webScreenshotDiffSchema, webScreenshotSchema, } from "../domain/webScreenshot.js";
7
7
  import { toolContractMetadata } from "./toolEffects.js";
8
8
  import { evidenceResultOf } from "./toolOutputSchemas.js";
9
+ import { browserCaptureToolInputSchema } from "./browserCaptureToolInputSchema.js";
9
10
  const evidenceResult = evidenceResultOf;
10
11
  const listOutputSchema = evidenceResult(browserTargetListSchema);
11
12
  const inspectionOutputSchema = evidenceResult(webPageInspectionSchema);
@@ -181,9 +182,9 @@ export const BROWSER_TOOL_CONTRACTS = [
181
182
  {
182
183
  name: "compare_web_captures",
183
184
  ...toolContractMetadata("compare_web_captures"),
184
- description: "Compare passive web captures by providing before and after, or compare recorded scenarios by providing before_scenario and after_scenario with an optional normalization policy. Use exactly one input group. Scenario comparison aligns exact step IDs, records deterministic literal normalization, and returns every artifact-level difference plus alignment failures inline. Missing or truncated evidence never proves equality.",
185
+ description: "Compare passive web captures by providing before and after, each with the complete inspect_web_page result in inspection and an optional complete discover_webmcp_tools result in webmcp; or compare recorded scenarios by passing complete capture_browser_scenario results in before_scenario and after_scenario with an optional normalization policy. Use exactly one input group. Scenario comparison aligns exact step IDs, records deterministic literal normalization, and returns every artifact-level difference plus alignment failures inline. Missing or truncated evidence never proves equality.",
185
186
  kind: "browser-provider",
186
- inputSchema: browserCaptureComparisonInputSchema,
187
+ inputSchema: browserCaptureToolInputSchema,
187
188
  outputSchema: captureDiffOutputSchema,
188
189
  examples: [
189
190
  {
@@ -1,11 +1,14 @@
1
1
  import { z } from "zod";
2
+ import { jsonValueSchema } from "../domain/jsonValue.js";
2
3
  const categorySchema = z.enum([
3
4
  "invalid_input",
4
5
  "unsupported_provider",
6
+ "unsupported_target",
5
7
  "integrity_mismatch",
6
8
  "truncated",
7
9
  "cancelled",
8
10
  "timeout",
11
+ "resource_constraint",
9
12
  "unavailable",
10
13
  "execution_failure",
11
14
  ]);
@@ -20,17 +23,21 @@ const common = {
20
23
  retryable: z.boolean(),
21
24
  remediation: remediationSchema,
22
25
  };
23
- const genericDetails = z.record(z.string(), z.json()).optional();
26
+ const genericDetails = z.record(z.string(), jsonValueSchema).optional();
24
27
  const generic = (code) => z
25
28
  .object({ code: z.literal(code), ...common, details: genericDetails })
26
29
  .strict();
27
30
  /** Stable discriminated schema shared by every CLI and MCP error surface. */
28
31
  export const analysisErrorProjectionSchema = z.discriminatedUnion("code", [
29
32
  generic("invalid_request"),
33
+ generic("access_denied"),
34
+ generic("artifact_changed"),
30
35
  generic("unreadable_output"),
31
36
  generic("capability_unavailable"),
37
+ generic("unsupported_target"),
32
38
  generic("provider_unavailable"),
33
39
  generic("provider_timeout"),
40
+ generic("resource_constraint"),
34
41
  generic("cancelled"),
35
42
  z
36
43
  .object({
@@ -0,0 +1,20 @@
1
+ import { inspectEvmInterfaceInputSchema, evmInterfaceSchema, } from "../../domain/evm/evmInterface.js";
2
+ import { toolContractMetadata } from "../toolEffects.js";
3
+ import { evidenceResultOf } from "../toolOutputSchemas.js";
4
+ /** Target-free EVM capabilities are independent of archive/Apple artifact providers. */
5
+ export const EVM_TOOL_CONTRACTS = [
6
+ {
7
+ name: "inspect_evm_interface",
8
+ ...toolContractMetadata("inspect_evm_interface"),
9
+ kind: "artifact-provider",
10
+ description: "Inspect an explicit local flat EVM bytecode carrier and infer dispatch selectors, argument strings and mutability without executing the target or accessing a chain/RPC endpoint. Choose raw or hex encoding explicitly. Returns original carrier and decoded-byte SHA-256, full bytecode and interface candidates inline as inferred Evidence; bytecode kind, hardfork, deployed authenticity and discovery completeness remain unknown. Initial real-verified Linux x64 profile uses unchanged bundled EVMole 0.9.3/WASM in a bounded owned worker; EOF-style EF00 containers are unsupported. No signature lookup, wallet action or transaction broadcast.",
11
+ inputSchema: inspectEvmInterfaceInputSchema,
12
+ outputSchema: evidenceResultOf(evmInterfaceSchema),
13
+ examples: [
14
+ {
15
+ title: "Inspect a local runtime bytecode hex carrier",
16
+ input: { path: "/artifacts/runtime.hex", encoding: "hex" },
17
+ },
18
+ ],
19
+ },
20
+ ];
@@ -1,9 +1,9 @@
1
1
  import { compareFunctions } from "../domain/functionComparison.js";
2
2
  import { createEvidence } from "../domain/evidence.js";
3
3
  import { jsonValueSchema } from "../domain/jsonValue.js";
4
- import { compareProcessCaptures, parseProcessCapture, } from "../domain/processCapture.js";
4
+ import { compareProcessCaptures, parseProcessCapture, } from "../domain/process/processCapture.js";
5
5
  import { FUNCTION_COMPARISON_EXAMPLE } from "./functionComparisonExample.js";
6
- import { EMPTY_PROCESS_CAPTURE_EXAMPLE } from "./processCaptureExample.js";
6
+ import { EMPTY_PROCESS_CAPTURE_EXAMPLE } from "./process/processCaptureExample.js";
7
7
  const comparison = compareFunctions(FUNCTION_COMPARISON_EXAMPLE.left, FUNCTION_COMPARISON_EXAMPLE.right);
8
8
  export const FUNCTION_COMPARISON_EVIDENCE = createEvidence(undefined, {
9
9
  id: "rea-function-comparison",
@@ -2,13 +2,17 @@ import { z } from "zod";
2
2
  import { managedOutputSchemas } from "../toolOutputSchemas.js";
3
3
  import { toolContractMetadata } from "../toolEffects.js";
4
4
  import { requireOutputSchema } from "../toolOutputSchemaPrimitives.js";
5
+ import { isAbsoluteLocalPath } from "../../domain/localPath.js";
5
6
  /** Exact caller boundary for execution-free PE/CLI triage and identity. */
6
- const managedTargetInputSchema = z.object({
7
+ const managedTargetInputSchema = z.strictObject({
7
8
  path: z
8
9
  .string()
9
10
  .min(1)
10
- .optional()
11
- .describe("Explicit managed PE/CLI path; omit to reuse the previously selected managed target"),
11
+ .refine(isAbsoluteLocalPath, {
12
+ message: "path must be an absolute local filesystem path (for example /tmp/Example.dll or C:\\Example.dll)",
13
+ })
14
+ .describe("Explicit absolute managed PE/CLI path; omit to reuse the previously selected managed target")
15
+ .optional(),
12
16
  });
13
17
  export const managedArtifactInputSchema = managedTargetInputSchema;
14
18
  /** Exact caller boundary for execution-free metadata/signature/IL inspection. */
@@ -0,0 +1,42 @@
1
+ import { inspectRecordedCrashInputSchema, recordedCrashSchema, } from "../../domain/native/recordedCrash.js";
2
+ import { inspectBinaryLayoutInputSchema, binaryLayoutSchema, } from "../../domain/native/binaryLayout.js";
3
+ import { toolContractMetadata } from "../toolEffects.js";
4
+ import { evidenceResultOf } from "../toolOutputSchemas.js";
5
+ /** Offline binary diagnostics are independent of macOS process/UI providers. */
6
+ export const BINARY_DIAGNOSTICS_TOOL_CONTRACTS = [
7
+ {
8
+ name: "inspect_binary_layout",
9
+ ...toolContractMetadata("inspect_binary_layout"),
10
+ kind: "native-provider",
11
+ description: "Inspect an explicit local binary without launching it as a host process. Returns file-backed section/segment ranges, linked addresses, original symbol/REL/RELA table identities, complete encoded RELR tables and upstream-derived offsets with unknown per-word locations/addends, raw name bytes, dependency/interpreter names and static mitigation inferences inline with artifact SHA-256 Evidence. Initial profile: ELF64 x86-64 little-endian EXEC/DYN/REL on Linux x64 via caller-supplied Python with unchanged pwntools 4.15.0, pyelftools 0.33 and Unicorn 2.1.2. Runtime addresses/library paths, overall relocation inventory completeness and complete derived GOT/PLT coverage remain unknown. Zero executable entry values mean absence; relocatable entries are not applicable. Upstream can emulate PLT instructions with Unicorn for derived static maps. Uses bounded complete output and owned temporary files/processes; malformed, unsupported or oversized objects return no partial success.",
12
+ inputSchema: inspectBinaryLayoutInputSchema,
13
+ outputSchema: evidenceResultOf(binaryLayoutSchema),
14
+ examples: [
15
+ {
16
+ title: "Inspect ELF linked and file layout",
17
+ input: { path: "/artifacts/application.elf" },
18
+ },
19
+ ],
20
+ },
21
+ {
22
+ name: "inspect_recorded_crash",
23
+ ...toolContractMetadata("inspect_recorded_crash"),
24
+ kind: "native-provider",
25
+ description: "Inspect a supplied Linux ELF64 amd64 little-endian core without launching its target or attaching to any live PID. Returns all recorded segments, raw note owners/descriptors and source ranges, every Linux CORE PRSTATUS thread/register and SIGINFO fields inline with SHA-256 Evidence. Historical PID is recorded metadata; current process/file identity, note coverage and signal-thread associations stay unknown. Optionally add derived core-only GDB/pwndbg mapping candidates through explicit BYO configuration; zero map flags mean unknown permissions. Uses the same stable snapshot for both stages, bounded complete output and owned cleanup. Initial Linux x64 profile: unchanged pwntools 4.15.0/pyelftools 0.33/Unicorn 2.1.2; optional unchanged pwndbg 2026.09.15. No implicit executable/library pairing, GDB command language, host configuration changes or dependency installation.",
26
+ inputSchema: inspectRecordedCrashInputSchema,
27
+ outputSchema: evidenceResultOf(recordedCrashSchema),
28
+ examples: [
29
+ {
30
+ title: "Inspect recorded registers and signal evidence",
31
+ input: { path: "/artifacts/crash.core" },
32
+ },
33
+ {
34
+ title: "Add core-only debugger mapping candidates",
35
+ input: {
36
+ path: "/artifacts/crash.core",
37
+ include_debugger_context: true,
38
+ },
39
+ },
40
+ ],
41
+ },
42
+ ];