rea-agents 2.0.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (273) hide show
  1. package/README.md +103 -38
  2. package/bridge/ghidra/ReaGhidraBridge.java +96 -11
  3. package/dist/application/AndroidApplicationService.js +17 -0
  4. package/dist/application/AppleApplicationService.js +17 -0
  5. package/dist/application/ArtifactExtraction.js +1 -1
  6. package/dist/application/ArtifactInventory/classify.js +42 -0
  7. package/dist/application/ArtifactInventory/hash.js +43 -0
  8. package/dist/application/ArtifactInventory/reader.js +41 -0
  9. package/dist/application/ArtifactInventory/scanCanonical.js +155 -0
  10. package/dist/application/ArtifactInventory/scanReader.js +124 -0
  11. package/dist/application/ArtifactInventory/types.js +10 -0
  12. package/dist/application/ArtifactInventory.js +9 -351
  13. package/dist/application/AuthorizedArtifactInventory.js +2 -2
  14. package/dist/application/BinarySession.js +47 -270
  15. package/dist/application/BinarySessionExecution.js +28 -0
  16. package/dist/application/BinarySessionOpen.js +39 -0
  17. package/dist/application/BinarySessionRecords.js +149 -0
  18. package/dist/application/BinarySessionStatus.js +75 -0
  19. package/dist/application/CapabilityInventory.js +24 -2
  20. package/dist/application/ClientRegistrationStatus.js +11 -4
  21. package/dist/application/CrossVersionInventory.js +8 -2
  22. package/dist/application/CrossVersionInvestigation.js +1 -23
  23. package/dist/application/CrossVersionInvestigationCollections.js +23 -0
  24. package/dist/application/DirectAnalysis.js +47 -44
  25. package/dist/application/Doctor.js +156 -238
  26. package/dist/application/DoctorDiagnostics.js +180 -0
  27. package/dist/application/ElectronBoundaryAnalysis.js +23 -7
  28. package/dist/application/ElectronBoundaryGraphWindows.js +32 -8
  29. package/dist/application/EnhancedToolPagination.js +22 -0
  30. package/dist/application/EnhancedToolTypes.js +4 -0
  31. package/dist/application/EnhancedTools.js +20 -37
  32. package/dist/application/InstrumentedJavaScriptReplayHost.js +36 -0
  33. package/dist/application/InventoryProjectionEvidence.js +41 -0
  34. package/dist/application/InvestigationProviders.js +12 -0
  35. package/dist/application/InvestigationWorkspaceStore.js +24 -10
  36. package/dist/application/JavaScriptArtifactAnalysis.js +45 -6
  37. package/dist/application/JavaScriptArtifactFiles.js +6 -2
  38. package/dist/application/JavaScriptArtifactGraphBuilder.js +23 -1
  39. package/dist/application/JavaScriptArtifactGraphBundlers.js +225 -0
  40. package/dist/application/JavaScriptArtifactGraphContext.js +37 -36
  41. package/dist/application/JavaScriptArtifactGraphDocuments.js +27 -4
  42. package/dist/application/JavaScriptArtifactGraphFindings.js +54 -8
  43. package/dist/application/JavaScriptArtifactGraphStructure.js +29 -101
  44. package/dist/application/JavaScriptArtifactPathResolution.js +269 -0
  45. package/dist/application/JavaScriptArtifactReconstruction.js +1 -1
  46. package/dist/application/JavaScriptJsonModules.js +39 -0
  47. package/dist/application/JavaScriptModuleRelationships.js +262 -0
  48. package/dist/application/JavaScriptReplayPermission.js +16 -0
  49. package/dist/application/JavaScriptReplayService.js +182 -156
  50. package/dist/application/LinuxHopper.js +10 -0
  51. package/dist/application/MacHopper.js +22 -11
  52. package/dist/application/NodeRuntimeCharacterizationService.js +196 -0
  53. package/dist/application/PermissionAuthority.js +106 -63
  54. package/dist/application/ProcessCaptureCapability.js +1 -1
  55. package/dist/application/ProcessCapturePermission.js +13 -0
  56. package/dist/application/ProcessCli.js +2 -12
  57. package/dist/application/ProcessHarness.js +1 -1
  58. package/dist/application/ProcessPairedExperiment.js +72 -0
  59. package/dist/application/ProjectPermissionStore.js +48 -9
  60. package/dist/application/RealHopperAssertions.js +76 -0
  61. package/dist/application/ReconstructionCoverageService.js +69 -0
  62. package/dist/application/ReconstructionCoverageWorkspaceStore.js +31 -0
  63. package/dist/application/RuntimeExecutableDiagnostics.js +172 -0
  64. package/dist/application/Setup.js +148 -260
  65. package/dist/application/SetupClientConfiguration.js +224 -0
  66. package/dist/application/SetupClients.js +24 -2
  67. package/dist/application/SetupPlan.js +124 -12
  68. package/dist/application/SetupSkill.js +54 -36
  69. package/dist/application/SupportedClients.js +1 -0
  70. package/dist/application/Uninstall.js +12 -3
  71. package/dist/application/Upgrade.js +16 -1
  72. package/dist/application/WindowsCapabilities.js +86 -0
  73. package/dist/artifacts/AsarArtifactReader.js +11 -0
  74. package/dist/browser/BrowserProcessStartup.js +88 -0
  75. package/dist/browser/CdpCaptureDocuments.js +12 -8
  76. package/dist/browser/CdpCaptureEventBodyShapes.js +75 -0
  77. package/dist/browser/CdpCaptureEventHandlers.js +336 -0
  78. package/dist/browser/CdpCaptureEventHelpers.js +71 -0
  79. package/dist/browser/CdpCaptureEventState.js +1 -0
  80. package/dist/browser/CdpCaptureEventTypes.js +1 -0
  81. package/dist/browser/CdpCaptureEvents.js +29 -496
  82. package/dist/browser/CdpObservationSession.js +51 -8
  83. package/dist/browser/CdpPageCapture.js +12 -133
  84. package/dist/browser/CdpPageCaptureScripts.js +97 -0
  85. package/dist/browser/CdpPageCaptureWorkers.js +46 -0
  86. package/dist/browser/CdpWebMcpDiscovery.js +38 -14
  87. package/dist/browser/PngVisualDiff.js +9 -2
  88. package/dist/catalogIdentity.js +4 -0
  89. package/dist/cli/artifactCommands.js +82 -0
  90. package/dist/cli/coreAnalysisCommands.js +232 -0
  91. package/dist/cli/managedCommands.js +397 -0
  92. package/dist/cli/managedProjectGraphCommand.js +24 -0
  93. package/dist/cli/options.js +9 -0
  94. package/dist/cli/setupCommands.js +113 -0
  95. package/dist/cli/types.js +1 -0
  96. package/dist/cli/utilityCommands.js +122 -0
  97. package/dist/cli.js +10 -768
  98. package/dist/cliApplicationCommands.js +118 -4
  99. package/dist/cliBrowserAdvancedCommands.js +73 -16
  100. package/dist/cliBrowserCommands.js +39 -115
  101. package/dist/cliCommandNames.js +4 -0
  102. package/dist/cliElectronCommands.js +33 -62
  103. package/dist/cliEvidenceCommands.js +13 -2
  104. package/dist/cliInvestigationCommands.js +53 -10
  105. package/dist/cliObservationOptions.js +137 -0
  106. package/dist/cliPolicyCommands.js +80 -46
  107. package/dist/cliSetup.js +306 -0
  108. package/dist/config/environment.js +107 -0
  109. package/dist/config/parseConfig.js +228 -0
  110. package/dist/config/parsers.js +68 -0
  111. package/dist/config/permissions.js +30 -0
  112. package/dist/config/types.js +1 -0
  113. package/dist/config.js +1 -375
  114. package/dist/contracts/applicationToolContracts.js +134 -0
  115. package/dist/contracts/electronToolContracts.js +51 -3
  116. package/dist/contracts/managedToolContracts.js +8 -3
  117. package/dist/contracts/managedWorkflowToolContracts.js +3 -3
  118. package/dist/contracts/providerSelection.js +2 -0
  119. package/dist/contracts/sessionStatusContract.js +26 -0
  120. package/dist/contracts/toolContractTypes.js +12 -1
  121. package/dist/contracts/toolContracts.js +5 -12
  122. package/dist/contracts/toolEffects.js +14 -0
  123. package/dist/contracts/toolOutputSchemaGroups.js +274 -0
  124. package/dist/contracts/toolOutputSchemaPrimitives.js +328 -0
  125. package/dist/contracts/toolOutputSchemas.js +2 -550
  126. package/dist/domain/analysisErrorPresentation.js +234 -0
  127. package/dist/domain/analysisErrorProjection.js +284 -0
  128. package/dist/domain/androidApplication.js +206 -0
  129. package/dist/domain/appleApplication.js +221 -0
  130. package/dist/domain/artifactComparison.js +34 -15
  131. package/dist/domain/binaryTarget.js +87 -37
  132. package/dist/domain/boundedCartesianProjection.js +15 -0
  133. package/dist/domain/browserObservation.js +1 -285
  134. package/dist/domain/browserObservationSchemas.js +286 -0
  135. package/dist/domain/electronStaticAnalysisBrowser.js +14 -2
  136. package/dist/domain/errors.js +4 -486
  137. package/dist/domain/functionComparison.js +4 -165
  138. package/dist/domain/functionComparisonDimensions.js +164 -0
  139. package/dist/domain/javascriptApplicationVersionItems.js +18 -6
  140. package/dist/domain/javascriptApplicationVersionKeys.js +8 -8
  141. package/dist/domain/javascriptExportInstrumentation.js +97 -0
  142. package/dist/domain/javascriptFeatureTraversal.js +19 -7
  143. package/dist/domain/javascriptRuntimeStaticCandidates.js +3 -1
  144. package/dist/domain/javascriptSemanticAnalysis.js +386 -0
  145. package/dist/domain/javascriptSemanticIr.js +30 -0
  146. package/dist/domain/javascriptSemanticProjection.js +366 -0
  147. package/dist/domain/javascriptSemanticState.js +40 -0
  148. package/dist/domain/javascriptSemanticTraversal.js +22 -0
  149. package/dist/domain/javascriptSemanticValues.js +352 -0
  150. package/dist/domain/javascriptStaticAnalysis.js +5 -221
  151. package/dist/domain/javascriptStaticAnalysisBundler.js +209 -0
  152. package/dist/domain/javascriptStaticAnalysisCalls.js +180 -0
  153. package/dist/domain/javascriptStaticAnalysisHelpers.js +71 -2
  154. package/dist/domain/knownPageCoverage.js +21 -0
  155. package/dist/domain/managedApplicationGraph.js +14 -364
  156. package/dist/domain/managedApplicationGraphCoverage.js +170 -0
  157. package/dist/domain/managedApplicationGraphNodeCoverage.js +6 -0
  158. package/dist/domain/managedApplicationGraphNodes.js +336 -0
  159. package/dist/domain/managedArtifact.js +16 -8
  160. package/dist/domain/managedMemberComparison.js +37 -391
  161. package/dist/domain/managedMemberComparisonCoverage.js +72 -0
  162. package/dist/domain/managedMemberComparisonMatch.js +356 -0
  163. package/dist/domain/managedNativeVerification.js +27 -389
  164. package/dist/domain/managedNativeVerificationMatch.js +272 -0
  165. package/dist/domain/managedNativeVerificationSchemas.js +141 -0
  166. package/dist/domain/managedReconstruction.js +82 -69
  167. package/dist/domain/managedRuntimeCorrelation.js +12 -3
  168. package/dist/domain/nodeRuntimeCharacterization.js +66 -0
  169. package/dist/domain/permissionPolicy.js +2 -0
  170. package/dist/domain/processComparison.js +19 -0
  171. package/dist/domain/processPairedExperiment.js +128 -0
  172. package/dist/domain/reconstructionCoverage.js +387 -0
  173. package/dist/domain/reconstructionCoverageEvaluation.js +212 -0
  174. package/dist/domain/reconstructionVerificationSchemas.js +8 -0
  175. package/dist/domain/replayMachine.js +316 -0
  176. package/dist/domain/replayMachineRuntime.js +215 -0
  177. package/dist/domain/runtimeCharacterization.js +85 -0
  178. package/dist/domain/runtimeIdentification.js +210 -0
  179. package/dist/domain/webBundleAnalyzer.js +3 -409
  180. package/dist/domain/webBundleAnalyzerAst.js +77 -0
  181. package/dist/domain/webBundleAnalyzerInspection.js +307 -0
  182. package/dist/domain/webBundleAnalyzerResult.js +120 -0
  183. package/dist/dotnet/ManagedArtifactInspector.js +50 -29
  184. package/dist/dotnet/ManagedMemberInspector.js +51 -785
  185. package/dist/dotnet/ManagedMemberInspectorCore.js +297 -0
  186. package/dist/dotnet/ManagedMemberInstructionDecoder.js +427 -0
  187. package/dist/dotnet/ManagedMemberRows.js +120 -0
  188. package/dist/dotnet/ManagedMetadataInventory.js +42 -306
  189. package/dist/dotnet/ManagedMetadataInventoryRows.js +292 -0
  190. package/dist/dotnet/ManagedMetadataLayout.js +48 -111
  191. package/dist/dotnet/ManagedMetadataRowSizes.js +54 -0
  192. package/dist/dotnet/ManagedMethodBodyReader.js +143 -0
  193. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +311 -0
  194. package/dist/dotnet/ManagedNativeBoundaryInspector.js +102 -350
  195. package/dist/dotnet/ManagedPeReader.js +59 -28
  196. package/dist/evaluation/CodexAgentEval.js +132 -0
  197. package/dist/generatedPackageMetadata.js +2 -2
  198. package/dist/ghidra/GhidraClient.js +76 -91
  199. package/dist/ghidra/GhidraClientStartup.js +29 -0
  200. package/dist/ghidra/GhidraClientWire.js +34 -0
  201. package/dist/ghidra/GhidraDefaults.js +1 -1
  202. package/dist/ghidra/GhidraDiagnostics.js +6 -1
  203. package/dist/ghidra/GhidraInstallation.js +20 -15
  204. package/dist/ghidra/GhidraLauncher.js +93 -29
  205. package/dist/ghidra/GhidraProvider.js +61 -161
  206. package/dist/ghidra/GhidraProviderCapabilities.js +173 -0
  207. package/dist/ghidra/GhidraSessionValues.js +2 -0
  208. package/dist/ghidra/GhidraSocketConnection.js +44 -7
  209. package/dist/ghidra/GhidraTargetSnapshot.js +30 -0
  210. package/dist/ghidra/GhidraTransport.js +71 -0
  211. package/dist/identity.js +4 -2
  212. package/dist/main/messages.js +5 -0
  213. package/dist/main/reload.js +49 -0
  214. package/dist/main/shutdown.js +25 -0
  215. package/dist/main/startup.js +14 -0
  216. package/dist/main/state.js +26 -0
  217. package/dist/main/transport.js +61 -0
  218. package/dist/main/types.js +1 -0
  219. package/dist/main.js +35 -146
  220. package/dist/process/PrivateRuntimeRoot.js +3 -2
  221. package/dist/process/ProcessOwnership.js +35 -0
  222. package/dist/process/ProviderProcess.js +2 -0
  223. package/dist/replay/JavaScriptReplayWorker.js +64 -50
  224. package/dist/replay/LinuxJavaScriptReplayRunner.js +173 -390
  225. package/dist/replay/LinuxJavaScriptReplaySandbox.js +140 -0
  226. package/dist/replay/ReplayOutcome.js +95 -0
  227. package/dist/replay/ReplayProcessLifecycle.js +71 -0
  228. package/dist/server/ProcessCaptureElicitation.js +157 -0
  229. package/dist/server/createServer.js +124 -56
  230. package/dist/server/javascriptApplicationResult.js +85 -0
  231. package/dist/server/registerApplicationTools/characterization.js +57 -0
  232. package/dist/server/registerApplicationTools/compareVersions.js +34 -0
  233. package/dist/server/registerApplicationTools/controlledReplay.js +38 -0
  234. package/dist/server/registerApplicationTools/coverage.js +84 -0
  235. package/dist/server/registerApplicationTools/helpers.js +42 -0
  236. package/dist/server/registerApplicationTools/traceFeature.js +26 -0
  237. package/dist/server/registerApplicationTools/types.js +1 -0
  238. package/dist/server/registerApplicationTools.js +10 -112
  239. package/dist/server/registerBrowserTools.js +59 -83
  240. package/dist/server/registerElectronTools.js +48 -49
  241. package/dist/server/registerEnhancedTools.js +34 -42
  242. package/dist/server/registerEvidenceResources.js +56 -0
  243. package/dist/server/registerInvestigationTools/helpers.js +74 -0
  244. package/dist/server/registerInvestigationTools/types.js +1 -0
  245. package/dist/server/registerInvestigationTools.js +83 -116
  246. package/dist/server/registerJavaScriptApplicationGraphResource.js +69 -0
  247. package/dist/server/registerManagedTools.js +18 -1
  248. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +65 -0
  249. package/dist/server/registerManagedWorkflowTools/contract.js +8 -0
  250. package/dist/server/registerManagedWorkflowTools/evidence.js +43 -0
  251. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +39 -0
  252. package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +39 -0
  253. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +52 -0
  254. package/dist/server/registerManagedWorkflowTools/types.js +1 -0
  255. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +75 -0
  256. package/dist/server/registerManagedWorkflowTools.js +10 -274
  257. package/dist/server/registerOfficialTools.js +73 -59
  258. package/dist/server/registerSessionRecordTools.js +137 -0
  259. package/dist/server/registerSessionStatusTool.js +97 -26
  260. package/dist/server/registerSessionTools.js +60 -164
  261. package/dist/server/sessionAvailabilityPolicy.js +10 -0
  262. package/dist/server/toolRegistrationOptions.js +101 -3
  263. package/dist/server/toolResult.js +15 -4
  264. package/package.json +11 -11
  265. package/skills/reverse-engineer-anything/SKILL.md +76 -0
  266. package/skills/reverse-engineer-anything/references/controlled-replay.md +12 -0
  267. package/skills/reverse-engineer-anything/references/evidence-workflows.md +33 -0
  268. package/skills/reverse-engineer-anything/references/javascript-applications.md +25 -0
  269. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +36 -0
  270. package/skills/reverse-engineer-anything/references/runtime-observation.md +24 -0
  271. package/scripts/prepare-node-pty.mjs +0 -35
  272. package/scripts/rebuild-native.mjs +0 -22
  273. package/skills/rea-analysis/SKILL.md +0 -222
@@ -1,18 +1,33 @@
1
1
  import { Cli, z } from "incur";
2
2
  import { compareApplicationVersionsEvidence, traceApplicationFeatureEvidence, } from "./application/JavaScriptApplicationWorkflowService.js";
3
3
  import { runControlledReplay } from "./application/JavaScriptReplayService.js";
4
+ import { executeNodeCharacterization, prepareNodeCharacterization, } from "./application/NodeRuntimeCharacterizationService.js";
5
+ import { commitReconstructionCoverage, queryReconstructionCoverage, reconstructionCoverageCommitInputSchema, reconstructionCoverageQueryInputSchema, } from "./application/ReconstructionCoverageService.js";
6
+ import { authorizeFileReadWithDeferredWrite, authorizeRootPermission, } from "./application/DeferredFileAuthorization.js";
4
7
  import { loadConfiguredPermissionAuthority } from "./application/PermissionConfiguration.js";
5
8
  import { CLI_COMMANDS } from "./cliCommandNames.js";
6
9
  import { parseCliJsonInput } from "./cliJsonInput.js";
7
10
  import { logCliCommand } from "./cliLogging.js";
8
- import { AnalysisInputError, projectAnalysisError } from "./domain/errors.js";
11
+ import { AnalysisInputError, projectAnalysisError, } from "./domain/errors.js";
9
12
  import { parseConfig } from "./config.js";
10
13
  import { LinuxJavaScriptReplayRunner } from "./replay/LinuxJavaScriptReplayRunner.js";
11
14
  import { SystemJavaScriptReplayHost } from "./replay/SystemJavaScriptReplayHost.js";
12
15
  /** Register CLI equivalents of provider-neutral application graph workflows. */
13
16
  export const registerApplicationCommands = (cli, logger) => {
14
- registerJsonCommand(cli, logger, CLI_COMMANDS.traceApplicationFeature, "Trace a typed seed through authenticated application Evidence JSON", traceApplicationFeatureEvidence);
15
- registerJsonCommand(cli, logger, CLI_COMMANDS.compareApplicationVersions, "Compare two authenticated JavaScript Application Graph versions", compareApplicationVersionsEvidence);
17
+ registerJsonCommand({
18
+ cli,
19
+ logger,
20
+ name: CLI_COMMANDS.traceApplicationFeature,
21
+ description: "Trace a typed seed through authenticated application Evidence JSON",
22
+ workflow: traceApplicationFeatureEvidence,
23
+ });
24
+ registerJsonCommand({
25
+ cli,
26
+ logger,
27
+ name: CLI_COMMANDS.compareApplicationVersions,
28
+ description: "Compare two authenticated JavaScript Application Graph versions",
29
+ workflow: compareApplicationVersionsEvidence,
30
+ });
16
31
  cli.command(CLI_COMMANDS.runControlledReplay, {
17
32
  description: "Plan or execute an approved extracted-module replay in the Linux sandbox",
18
33
  args: z.object({
@@ -37,8 +52,107 @@ export const registerApplicationCommands = (cli, logger) => {
37
52
  return result.ok ? result.value : projectAnalysisError(result.error);
38
53
  }),
39
54
  });
55
+ registerAuthorizedJsonCommand({
56
+ cli,
57
+ logger,
58
+ name: CLI_COMMANDS.prepareNodeCharacterization,
59
+ description: "Prepare one exact Node/JavaScript characterization without execution",
60
+ workflow: (config, authority, input) => prepareNodeCharacterization(replayDependencies(config, authority), input),
61
+ });
62
+ registerAuthorizedJsonCommand({
63
+ cli,
64
+ logger,
65
+ name: CLI_COMMANDS.executeNodeCharacterization,
66
+ description: "Execute one separately approved exact Node/JavaScript characterization",
67
+ workflow: (config, authority, input) => executeNodeCharacterization(replayDependencies(config, authority), input),
68
+ });
69
+ registerCoverageCommands(cli, logger);
70
+ };
71
+ const registerAuthorizedJsonCommand = ({ cli, logger, name, description, workflow, }) => {
72
+ cli.command(name, {
73
+ description,
74
+ args: z.object({
75
+ inputJson: z.string().describe("Inline workflow JSON or JSON file path"),
76
+ }),
77
+ run: ({ args }) => logCliCommand(logger, name, async () => {
78
+ const input = await parseCliJsonInput(args.inputJson, name);
79
+ if (!input.ok)
80
+ return input.error;
81
+ const configured = await configuredAuthority();
82
+ if (!configured.ok)
83
+ return configured.error;
84
+ const result = await workflow(configured.config, configured.authority, input.value);
85
+ return result.ok ? result.value : projectAnalysisError(result.error);
86
+ }),
87
+ });
88
+ };
89
+ const registerCoverageCommands = (cli, logger) => {
90
+ registerAuthorizedJsonCommand({
91
+ cli,
92
+ logger,
93
+ name: CLI_COMMANDS.commitReconstructionCoverage,
94
+ description: "Commit one canonical reconstruction coverage workspace revision",
95
+ workflow: async (config, authority, input) => {
96
+ const parsed = reconstructionCoverageCommitInputSchema.safeParse(input);
97
+ if (!parsed.success)
98
+ return {
99
+ ok: false,
100
+ error: new AnalysisInputError(CLI_COMMANDS.commitReconstructionCoverage, { cause: parsed.error }),
101
+ };
102
+ const authorization = await authorizeFileReadWithDeferredWrite(authority, {
103
+ path: parsed.data.workspace_path,
104
+ readCapability: "investigation_workspace_read",
105
+ writeCapability: "investigation_workspace_write",
106
+ operation: CLI_COMMANDS.commitReconstructionCoverage,
107
+ });
108
+ if (!authorization.ok)
109
+ return authorization;
110
+ const write = await authorization.value.authorizeWrite();
111
+ if (!write.ok)
112
+ return write;
113
+ return commitReconstructionCoverage(parsed.data, config.evidenceFilePolicy);
114
+ },
115
+ });
116
+ registerAuthorizedJsonCommand({
117
+ cli,
118
+ logger,
119
+ name: CLI_COMMANDS.queryReconstructionCoverage,
120
+ description: "Evaluate one fail-closed reconstruction coverage boundary",
121
+ workflow: async (config, authority, input) => {
122
+ const parsed = reconstructionCoverageQueryInputSchema.safeParse(input);
123
+ if (!parsed.success)
124
+ return {
125
+ ok: false,
126
+ error: new AnalysisInputError(CLI_COMMANDS.queryReconstructionCoverage, { cause: parsed.error }),
127
+ };
128
+ const authorized = await authorizeRootPermission(authority, {
129
+ capability: "investigation_workspace_read",
130
+ roots: [parsed.data.workspace_path],
131
+ access: "read",
132
+ operation: CLI_COMMANDS.queryReconstructionCoverage,
133
+ });
134
+ if (!authorized.ok)
135
+ return authorized;
136
+ return queryReconstructionCoverage(parsed.data, config.evidenceFilePolicy, Date.now());
137
+ },
138
+ });
139
+ };
140
+ const configuredAuthority = async () => {
141
+ const config = parseConfig(process.env);
142
+ if (!config.ok)
143
+ return { ok: false, error: projectAnalysisError(config.error) };
144
+ const authority = await loadConfiguredPermissionAuthority(config.value);
145
+ return authority.ok
146
+ ? { ok: true, config: config.value, authority: authority.value }
147
+ : { ok: false, error: projectAnalysisError(authority.error) };
40
148
  };
41
- const registerJsonCommand = (cli, logger, name, description, workflow) => {
149
+ const replayDependencies = (config, authority) => ({
150
+ policy: config.javascriptReplayPolicy,
151
+ host: new SystemJavaScriptReplayHost(),
152
+ runner: new LinuxJavaScriptReplayRunner(),
153
+ authority,
154
+ });
155
+ const registerJsonCommand = ({ cli, logger, name, description, workflow, }) => {
42
156
  cli.command(name, {
43
157
  description,
44
158
  args: z.object({
@@ -10,8 +10,11 @@ import { discoverWebMcpToolsInputSchema } from "./domain/webMcpDiscovery.js";
10
10
  import { captureWebScreenshotInputSchema, compareWebScreenshotsInputSchema, } from "./domain/webScreenshot.js";
11
11
  import { CLI_COMMANDS } from "./cliCommandNames.js";
12
12
  const scopeOptions = {
13
- allowedOrigins: z.array(z.string().min(1)).optional(),
14
- approved: z.boolean().default(false),
13
+ allowedOrigins: z
14
+ .array(z.string().min(1))
15
+ .optional()
16
+ .describe("Exact origins to observe; defaults to REA_BROWSER_ALLOWED_ORIGINS_JSON"),
17
+ approved: z.boolean().default(false).describe("Approve passive observation"),
15
18
  };
16
19
  /** Register WebMCP, capture-diff, and screenshot CLI equivalents. */
17
20
  export const registerAdvancedBrowserCommands = (cli, logger) => {
@@ -23,19 +26,47 @@ export const registerAdvancedBrowserCommands = (cli, logger) => {
23
26
  const registerWebMcp = (cli, logger) => {
24
27
  cli.command(CLI_COMMANDS.discoverWebMcpTools, {
25
28
  description: "Passively discover page-declared WebMCP tools",
26
- args: z.object({ endpoint: z.string(), targetId: z.string() }),
29
+ args: z.object({
30
+ endpoint: z.string().describe("Configured loopback CDP HTTP endpoint"),
31
+ targetId: z.string().describe("Target ID from list-browser-targets"),
32
+ }),
27
33
  options: z.object({
28
34
  ...scopeOptions,
29
- observationMs: z.number().int().min(0).max(10_000).default(100),
30
- maxTools: z.number().int().min(1).max(5_000).default(500),
35
+ observationMs: z
36
+ .number()
37
+ .int()
38
+ .min(0)
39
+ .max(10_000)
40
+ .default(100)
41
+ .describe("Observation duration in milliseconds"),
42
+ maxTools: z
43
+ .number()
44
+ .int()
45
+ .min(1)
46
+ .max(5_000)
47
+ .default(500)
48
+ .describe("Maximum page-declared WebMCP tools to return"),
31
49
  maxSchemaBytes: z
32
50
  .number()
33
51
  .int()
34
52
  .min(1)
35
53
  .max(1_024 * 1_024)
36
- .default(256 * 1_024),
37
- maxSchemaNodes: z.number().int().min(1).max(100_000).default(5_000),
38
- maxSchemaDepth: z.number().int().min(1).max(100).default(20),
54
+ .default(256 * 1_024)
55
+ .describe("Maximum serialized size of one declared tool schema"),
56
+ maxSchemaNodes: z
57
+ .number()
58
+ .int()
59
+ .min(1)
60
+ .max(100_000)
61
+ .default(5_000)
62
+ .describe("Maximum nodes in one declared tool schema"),
63
+ maxSchemaDepth: z
64
+ .number()
65
+ .int()
66
+ .min(1)
67
+ .max(100)
68
+ .default(20)
69
+ .describe("Maximum nesting depth in one declared tool schema"),
39
70
  }),
40
71
  run: ({ args, options }) => logCliCommand(logger, "discover-webmcp-tools", async () => {
41
72
  const context = await browserContext();
@@ -62,9 +93,18 @@ const registerWebMcp = (cli, logger) => {
62
93
  const registerCaptureDiff = (cli, logger) => {
63
94
  cli.command(CLI_COMMANDS.compareWebCaptures, {
64
95
  description: "Compare two normalized web capture JSON values",
65
- args: z.object({ beforeJson: z.string(), afterJson: z.string() }),
96
+ args: z.object({
97
+ beforeJson: z.string().describe("Earlier normalized web capture JSON"),
98
+ afterJson: z.string().describe("Later normalized web capture JSON"),
99
+ }),
66
100
  options: z.object({
67
- maxChanges: z.number().int().min(1).max(20_000).default(2_000),
101
+ maxChanges: z
102
+ .number()
103
+ .int()
104
+ .min(1)
105
+ .max(20_000)
106
+ .default(2_000)
107
+ .describe("Maximum normalized changes to return"),
68
108
  }),
69
109
  run: ({ args, options }) => logCliCommand(logger, "compare-web-captures", async () => {
70
110
  const before = parseJson(args.beforeJson);
@@ -84,16 +124,23 @@ const registerCaptureDiff = (cli, logger) => {
84
124
  const registerScreenshot = (cli, logger) => {
85
125
  cli.command(CLI_COMMANDS.captureWebScreenshot, {
86
126
  description: "Capture an explicitly approved visible page viewport",
87
- args: z.object({ endpoint: z.string(), targetId: z.string() }),
127
+ args: z.object({
128
+ endpoint: z.string().describe("Configured loopback CDP HTTP endpoint"),
129
+ targetId: z.string().describe("Target ID from list-browser-targets"),
130
+ }),
88
131
  options: z.object({
89
132
  ...scopeOptions,
90
- screenshotApproved: z.boolean().default(false),
133
+ screenshotApproved: z
134
+ .boolean()
135
+ .default(false)
136
+ .describe("Approve capturing the visible page viewport"),
91
137
  maximumImageBytes: z
92
138
  .number()
93
139
  .int()
94
140
  .min(1)
95
141
  .max(8 * 1_024 * 1_024)
96
- .default(4 * 1_024 * 1_024),
142
+ .default(4 * 1_024 * 1_024)
143
+ .describe("Maximum captured PNG size"),
97
144
  }),
98
145
  run: ({ args, options }) => logCliCommand(logger, "capture-web-screenshot", async () => {
99
146
  const context = await browserContext();
@@ -117,15 +164,25 @@ const registerScreenshot = (cli, logger) => {
117
164
  const registerScreenshotDiff = (cli, logger) => {
118
165
  cli.command(CLI_COMMANDS.compareWebScreenshots, {
119
166
  description: "Compare two self-verifying PNG artifact JSON values",
120
- args: z.object({ beforeJson: z.string(), afterJson: z.string() }),
167
+ args: z.object({
168
+ beforeJson: z.string().describe("Earlier screenshot artifact JSON"),
169
+ afterJson: z.string().describe("Later screenshot artifact JSON"),
170
+ }),
121
171
  options: z.object({
122
- channelThreshold: z.number().int().min(0).max(255).default(0),
172
+ channelThreshold: z
173
+ .number()
174
+ .int()
175
+ .min(0)
176
+ .max(255)
177
+ .default(0)
178
+ .describe("Per-channel difference threshold for changed pixels"),
123
179
  maximumPixels: z
124
180
  .number()
125
181
  .int()
126
182
  .min(1)
127
183
  .max(32_000_000)
128
- .default(16_000_000),
184
+ .default(16_000_000)
185
+ .describe("Maximum decoded pixels per screenshot"),
129
186
  }),
130
187
  run: ({ args, options }) => logCliCommand(logger, "compare-web-screenshots", async () => {
131
188
  const parsed = compareWebScreenshotsInputSchema.safeParse({
@@ -9,6 +9,7 @@ import { analyzeWebBundleInputSchema } from "./domain/webBundleAnalysis.js";
9
9
  import { observeWebSessionInputSchema } from "./domain/browserSession.js";
10
10
  import { AnalysisInputError, projectAnalysisError } from "./domain/errors.js";
11
11
  import { CLI_COMMANDS } from "./cliCommandNames.js";
12
+ import { browserPageInspectionOptions } from "./cliObservationOptions.js";
12
13
  const browserScopeOptions = {
13
14
  allowedOrigins: z
14
15
  .array(z.string().min(1))
@@ -16,6 +17,14 @@ const browserScopeOptions = {
16
17
  .describe("Exact origins to observe; defaults to REA_BROWSER_ALLOWED_ORIGINS_JSON"),
17
18
  approved: z.boolean().default(false).describe("Approve passive observation"),
18
19
  };
20
+ const boundedCount = (subject, maximum, fallback, minimum = 1) => z
21
+ .number()
22
+ .int()
23
+ .min(minimum)
24
+ .max(maximum)
25
+ .default(fallback)
26
+ .describe(`Maximum ${subject}`);
27
+ const boundedBytes = (subject, maximum, fallback) => boundedCount(`${subject} in bytes`, maximum, fallback);
19
28
  /** Register CLI equivalents of the passive browser MCP tools. */
20
29
  export const registerBrowserCommands = (cli, logger) => {
21
30
  registerTargetList(cli, logger);
@@ -31,8 +40,13 @@ const registerTargetList = (cli, logger) => {
31
40
  }),
32
41
  options: z.object({
33
42
  ...browserScopeOptions,
34
- offset: z.number().int().min(0).default(0),
35
- limit: z.number().int().min(1).max(200).default(100),
43
+ offset: z
44
+ .number()
45
+ .int()
46
+ .min(0)
47
+ .default(0)
48
+ .describe("Zero-based browser-target offset"),
49
+ limit: boundedCount("browser targets to return", 200, 100),
36
50
  }),
37
51
  run: ({ args, options }) => logCliCommand(logger, "list-browser-targets", async () => {
38
52
  const context = await browserContext();
@@ -59,91 +73,7 @@ const registerPageInspection = (cli, logger) => {
59
73
  endpoint: z.string().describe("Configured loopback CDP HTTP endpoint"),
60
74
  targetId: z.string().describe("Target ID from list-browser-targets"),
61
75
  }),
62
- options: z.object({
63
- ...browserScopeOptions,
64
- observationMs: z.number().int().min(0).max(10_000).default(500),
65
- includeAccessibilityText: z.boolean().default(false),
66
- includeConsoleText: z.boolean().default(false),
67
- consoleTextApproved: z.boolean().default(false),
68
- includeJsonBodyShapes: z.boolean().default(false),
69
- jsonBodySchemaApproved: z.boolean().default(false),
70
- includeWebsocketShapes: z.boolean().default(false),
71
- websocketShapeApproved: z.boolean().default(false),
72
- includeScriptSources: z.boolean().default(false),
73
- includeStorageKeys: z.boolean().default(false),
74
- maxFrames: z.number().int().min(1).max(1_000).default(200),
75
- maxDomNodes: z.number().int().min(1).max(10_000).default(2_000),
76
- maxAxNodes: z.number().int().min(1).max(10_000).default(2_000),
77
- maxAxTextFieldBytes: z
78
- .number()
79
- .int()
80
- .min(1)
81
- .max(16 * 1_024)
82
- .default(1_024),
83
- maxTotalAxTextBytes: z
84
- .number()
85
- .int()
86
- .min(1)
87
- .max(1_024 * 1_024)
88
- .default(64 * 1_024),
89
- maxScripts: z.number().int().min(1).max(1_000).default(200),
90
- maxResources: z.number().int().min(1).max(10_000).default(2_000),
91
- maxWorkers: z.number().int().min(1).max(5_000).default(500),
92
- maxStorageKeys: z.number().int().min(1).max(10_000).default(1_000),
93
- maxScriptSourceBytes: z
94
- .number()
95
- .int()
96
- .min(1)
97
- .max(4 * 1_024 * 1_024)
98
- .default(1_024 * 1_024),
99
- maxTotalScriptSourceBytes: z
100
- .number()
101
- .int()
102
- .min(1)
103
- .max(16 * 1_024 * 1_024)
104
- .default(4 * 1_024 * 1_024),
105
- maxNetworkEvents: z.number().int().min(1).max(10_000).default(1_000),
106
- maxConsoleEvents: z.number().int().min(1).max(2_000).default(200),
107
- maxConsoleTextFieldBytes: z
108
- .number()
109
- .int()
110
- .min(1)
111
- .max(16 * 1_024)
112
- .default(1_024),
113
- maxTotalConsoleTextBytes: z
114
- .number()
115
- .int()
116
- .min(1)
117
- .max(1_024 * 1_024)
118
- .default(64 * 1_024),
119
- maxJsonBodyBytes: z
120
- .number()
121
- .int()
122
- .min(1)
123
- .max(4 * 1_024 * 1_024)
124
- .default(1_024 * 1_024),
125
- maxTotalJsonBodyBytes: z
126
- .number()
127
- .int()
128
- .min(1)
129
- .max(16 * 1_024 * 1_024)
130
- .default(4 * 1_024 * 1_024),
131
- maxJsonShapeNodes: z.number().int().min(1).max(100_000).default(5_000),
132
- maxJsonShapeDepth: z.number().int().min(1).max(100).default(20),
133
- maxWebsocketEvents: z.number().int().min(1).max(5_000).default(500),
134
- maxWebsocketShapeBytes: z
135
- .number()
136
- .int()
137
- .min(1)
138
- .max(1_024 * 1_024)
139
- .default(64 * 1_024),
140
- maxTotalWebsocketShapeBytes: z
141
- .number()
142
- .int()
143
- .min(1)
144
- .max(16 * 1_024 * 1_024)
145
- .default(1_024 * 1_024),
146
- }),
76
+ options: browserPageInspectionOptions,
147
77
  run: ({ args, options }) => logCliCommand(logger, "inspect-web-page", async () => {
148
78
  const context = await browserContext();
149
79
  if (!context.ok)
@@ -204,32 +134,26 @@ const registerBundleAnalysis = (cli, logger) => {
204
134
  }),
205
135
  options: z.object({
206
136
  ...browserScopeOptions,
207
- sourceCaptureApproved: z.boolean().default(false),
208
- observationMs: z.number().int().min(0).max(10_000).default(500),
209
- fetchSourceMaps: z.boolean().default(false),
210
- sourceMapFetchApproved: z.boolean().default(false),
211
- maxFindings: z.number().int().min(1).max(10_000).default(1_000),
212
- maxAstNodes: z.number().int().min(1).max(2_000_000).default(250_000),
213
- maxSourceMaps: z.number().int().min(1).max(1_000).default(100),
214
- maxSourceMapBytes: z
215
- .number()
216
- .int()
217
- .min(1)
218
- .max(16 * 1_024 * 1_024)
219
- .default(4 * 1_024 * 1_024),
220
- maxTotalSourceMapBytes: z
221
- .number()
222
- .int()
223
- .min(1)
224
- .max(64 * 1_024 * 1_024)
225
- .default(16 * 1_024 * 1_024),
226
- maxSourceMapMappings: z
227
- .number()
228
- .int()
229
- .min(1)
230
- .max(100_000)
231
- .default(10_000),
232
- maxOriginalSources: z.number().int().min(1).max(20_000).default(2_000),
137
+ sourceCaptureApproved: z
138
+ .boolean()
139
+ .default(false)
140
+ .describe("Approve capturing bounded script source text"),
141
+ observationMs: boundedCount("observation duration in milliseconds", 10_000, 500, 0),
142
+ fetchSourceMaps: z
143
+ .boolean()
144
+ .default(false)
145
+ .describe("Fetch source maps referenced by captured scripts"),
146
+ sourceMapFetchApproved: z
147
+ .boolean()
148
+ .default(false)
149
+ .describe("Approve fetching referenced source maps from allowed origins"),
150
+ maxFindings: boundedCount("static-analysis findings", 10_000, 1_000),
151
+ maxAstNodes: boundedCount("JavaScript AST nodes", 2_000_000, 250_000),
152
+ maxSourceMaps: boundedCount("source maps", 1_000, 100),
153
+ maxSourceMapBytes: boundedBytes("one source map", 16 * 1_024 * 1_024, 4 * 1_024 * 1_024),
154
+ maxTotalSourceMapBytes: boundedBytes("total source maps", 64 * 1_024 * 1_024, 16 * 1_024 * 1_024),
155
+ maxSourceMapMappings: boundedCount("decoded source-map mappings", 100_000, 10_000),
156
+ maxOriginalSources: boundedCount("original source files", 20_000, 2_000),
233
157
  }),
234
158
  run: ({ args, options }) => logCliCommand(logger, "analyze-web-bundle", async () => {
235
159
  const context = await browserContext();
@@ -271,8 +195,8 @@ const registerObservationSession = (cli, logger) => {
271
195
  }),
272
196
  options: z.object({
273
197
  ...browserScopeOptions,
274
- observationMs: z.number().int().min(1).max(60_000).default(10_000),
275
- maxTimelineEvents: z.number().int().min(1).max(20_000).default(2_000),
198
+ observationMs: boundedCount("observation duration in milliseconds", 60_000, 10_000),
199
+ maxTimelineEvents: boundedCount("timeline events", 20_000, 2_000),
276
200
  }),
277
201
  run: ({ args, options }) => logCliCommand(logger, "observe-web-session", async () => {
278
202
  const context = await browserContext();
@@ -51,6 +51,10 @@ export const CLI_COMMANDS = Object.freeze({
51
51
  traceApplicationFeature: "trace-application-feature",
52
52
  compareApplicationVersions: "compare-application-versions",
53
53
  runControlledReplay: "run-controlled-replay",
54
+ prepareNodeCharacterization: "prepare-node-characterization",
55
+ executeNodeCharacterization: "execute-node-characterization",
56
+ commitReconstructionCoverage: "commit-reconstruction-coverage",
57
+ queryReconstructionCoverage: "query-reconstruction-coverage",
54
58
  });
55
59
  /** Ordered primary CLI inventory; aliases are intentionally excluded. */
56
60
  export const CLI_COMMAND_NAMES = Object.freeze(Object.values(CLI_COMMANDS));
@@ -11,12 +11,13 @@ import { analyzeJavaScriptApplicationInputSchema } from "./domain/javascriptAppl
11
11
  import { AnalysisInputError, projectAnalysisError } from "./domain/errors.js";
12
12
  import { CLI_COMMANDS } from "./cliCommandNames.js";
13
13
  import { parseCliJsonInput } from "./cliJsonInput.js";
14
+ import { electronPageInspectionOptions, javascriptApplicationOptions, } from "./cliObservationOptions.js";
14
15
  const scopeOptions = {
15
16
  allowedFileRoots: z
16
17
  .array(z.string().min(1))
17
18
  .optional()
18
19
  .describe("Filesystem roots; defaults to REA_ELECTRON_FILE_ROOTS_JSON"),
19
- approved: z.boolean().default(false),
20
+ approved: z.boolean().default(false).describe("Approve passive observation"),
20
21
  };
21
22
  /** Register CLI equivalents of the Electron MCP tools. */
22
23
  export const registerElectronCommands = (cli, logger) => {
@@ -42,13 +43,32 @@ const registerJavaScriptRuntimeReconciliationCommand = (cli, logger) => {
42
43
  });
43
44
  };
44
45
  const registerElectronObservationCommands = (cli, logger) => {
46
+ registerElectronTargetList(cli, logger);
47
+ registerElectronPageInspection(cli, logger);
48
+ };
49
+ const registerElectronTargetList = (cli, logger) => {
45
50
  cli.command(CLI_COMMANDS.listElectronTargets, {
46
51
  description: "List root-confined file pages from Electron CDP",
47
- args: z.object({ endpoint: z.string() }),
52
+ args: z.object({
53
+ endpoint: z
54
+ .string()
55
+ .describe("Configured loopback Electron CDP endpoint"),
56
+ }),
48
57
  options: z.object({
49
58
  ...scopeOptions,
50
- offset: z.number().int().min(0).default(0),
51
- limit: z.number().int().min(1).max(200).default(100),
59
+ offset: z
60
+ .number()
61
+ .int()
62
+ .min(0)
63
+ .default(0)
64
+ .describe("Zero-based Electron-target offset"),
65
+ limit: z
66
+ .number()
67
+ .int()
68
+ .min(1)
69
+ .max(200)
70
+ .default(100)
71
+ .describe("Maximum Electron targets to return"),
52
72
  }),
53
73
  run: ({ args, options }) => logCliCommand(logger, "list-electron-targets", async () => {
54
74
  const context = await electronContext();
@@ -67,32 +87,17 @@ const registerElectronObservationCommands = (cli, logger) => {
67
87
  return result.ok ? result.value : cliError(result.error);
68
88
  }),
69
89
  });
90
+ };
91
+ const registerElectronPageInspection = (cli, logger) => {
70
92
  cli.command(CLI_COMMANDS.inspectElectronPage, {
71
93
  description: "Passively inspect one root-confined Electron file page",
72
- args: z.object({ endpoint: z.string(), targetId: z.string() }),
73
- options: z.object({
74
- ...scopeOptions,
75
- observationMs: z.number().int().min(0).max(10_000).default(100),
76
- includeScriptSources: z.boolean().default(false),
77
- sourceCaptureApproved: z.boolean().default(false),
78
- maxFrames: z.number().int().min(1).max(1_000).default(200),
79
- maxDomNodes: z.number().int().min(1).max(10_000).default(2_000),
80
- maxScripts: z.number().int().min(1).max(2_000).default(500),
81
- maxResources: z.number().int().min(1).max(10_000).default(2_000),
82
- maxWorkers: z.number().int().min(1).max(5_000).default(500),
83
- maxScriptSourceBytes: z
84
- .number()
85
- .int()
86
- .min(1)
87
- .max(4 * 1_024 * 1_024)
88
- .default(1_024 * 1_024),
89
- maxTotalScriptSourceBytes: z
90
- .number()
91
- .int()
92
- .min(1)
93
- .max(16 * 1_024 * 1_024)
94
- .default(4 * 1_024 * 1_024),
94
+ args: z.object({
95
+ endpoint: z
96
+ .string()
97
+ .describe("Configured loopback Electron CDP endpoint"),
98
+ targetId: z.string().describe("Target ID from list-electron-targets"),
95
99
  }),
100
+ options: electronPageInspectionOptions,
96
101
  run: ({ args, options }) => logCliCommand(logger, "inspect-electron-page", async () => {
97
102
  const context = await electronContext();
98
103
  if (!context.ok)
@@ -128,41 +133,7 @@ const registerJavaScriptApplicationCommand = (cli, logger) => {
128
133
  args: z.object({
129
134
  path: z.string().describe("Absolute ASAR or extracted application path"),
130
135
  }),
131
- options: z.object({
132
- approved: z.boolean().default(false),
133
- format: z.enum(["auto", "asar", "directory"]).default("auto"),
134
- sourceMapReadApproved: z.boolean().default(false),
135
- maxEntries: z.number().int().min(1).default(8_000),
136
- maxTotalArtifactBytes: z
137
- .number()
138
- .int()
139
- .min(1)
140
- .default(512 * 1_024 * 1_024),
141
- maxArtifactEntryBytes: z
142
- .number()
143
- .int()
144
- .min(1)
145
- .default(128 * 1_024 * 1_024),
146
- maxCompressionRatio: z.number().min(1).default(1_000),
147
- maxDepth: z.number().int().min(1).default(64),
148
- maxPathBytes: z.number().int().min(1).default(4_096),
149
- maxTextFiles: z.number().int().min(1).default(5_000),
150
- maxTotalTextBytes: z
151
- .number()
152
- .int()
153
- .min(1)
154
- .default(128 * 1_024 * 1_024),
155
- maxTextFileBytes: z
156
- .number()
157
- .int()
158
- .min(1)
159
- .default(8 * 1_024 * 1_024),
160
- maxAstNodes: z.number().int().min(1).default(2_000_000),
161
- maxFindings: z.number().int().min(1).default(8_000),
162
- maxModules: z.number().int().min(1).default(20_000),
163
- maxSourceMapSources: z.number().int().min(1).default(5_000),
164
- maxParseMilliseconds: z.number().int().min(1).default(30_000),
165
- }),
136
+ options: javascriptApplicationOptions,
166
137
  run: ({ args, options }) => logCliCommand(logger, CLI_COMMANDS.analyzeJavaScriptApplication, async () => {
167
138
  const context = await electronContext();
168
139
  if (!context.ok)
@@ -56,8 +56,19 @@ export const registerEvidenceCommands = (cli, logger) => {
56
56
  right: z.string().describe("Right Evidence bundle JSON path"),
57
57
  }),
58
58
  options: z.object({
59
- offset: z.number().int().min(0).default(0),
60
- limit: z.number().int().min(1).max(500).default(100),
59
+ offset: z
60
+ .number()
61
+ .int()
62
+ .min(0)
63
+ .default(0)
64
+ .describe("Zero-based changed-record offset"),
65
+ limit: z
66
+ .number()
67
+ .int()
68
+ .min(1)
69
+ .max(500)
70
+ .default(100)
71
+ .describe("Maximum changed records to return"),
61
72
  }),
62
73
  run: ({ args, options }) => logCliCommand(logger, "compare", async () => {
63
74
  const config = parseConfig(process.env);