rea-agents 1.6.0 → 2.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 (238) hide show
  1. package/README.md +157 -66
  2. package/bridge/ghidra/ReaGhidraBridge.java +2075 -0
  3. package/bridge/hopper_bridge.py +13 -3
  4. package/dist/application/AbortablePromise.js +25 -0
  5. package/dist/application/AnalysisProvider.js +3 -0
  6. package/dist/application/AnalysisProviderEvaluation.js +60 -0
  7. package/dist/application/AnalysisProviderRegistry.js +228 -0
  8. package/dist/application/AnalysisSnapshotCache.js +41 -21
  9. package/dist/application/AnalysisSnapshotFiles.js +5 -6
  10. package/dist/application/BinarySession.js +218 -101
  11. package/dist/application/CapabilityInventory.js +18 -0
  12. package/dist/application/CompositeProvider.js +20 -8
  13. package/dist/application/CrossVersionInvestigation.js +10 -6
  14. package/dist/application/DirectAnalysis.js +49 -35
  15. package/dist/application/Doctor.js +110 -8
  16. package/dist/application/ElectronBoundaryAnalysis.js +96 -0
  17. package/dist/application/ElectronBoundaryGraph.js +9 -0
  18. package/dist/application/ElectronBoundaryGraphContext.js +62 -0
  19. package/dist/application/ElectronBoundaryGraphIpc.js +242 -0
  20. package/dist/application/ElectronBoundaryGraphNative.js +86 -0
  21. package/dist/application/ElectronBoundaryGraphWindows.js +199 -0
  22. package/dist/application/EnhancedTools.js +39 -14
  23. package/dist/application/InvestigationProviders.js +41 -0
  24. package/dist/application/JavaScriptApplicationEvidence.js +26 -0
  25. package/dist/application/JavaScriptApplicationEvidenceGraph.js +89 -0
  26. package/dist/application/JavaScriptApplicationService.js +74 -0
  27. package/dist/application/JavaScriptApplicationWorkflowEvidence.js +29 -0
  28. package/dist/application/JavaScriptApplicationWorkflowService.js +90 -0
  29. package/dist/application/JavaScriptArtifactAnalysis.js +305 -0
  30. package/dist/application/JavaScriptArtifactAnalysisTypes.js +1 -0
  31. package/dist/application/JavaScriptArtifactFiles.js +231 -0
  32. package/dist/application/JavaScriptArtifactGraphAccumulator.js +54 -0
  33. package/dist/application/JavaScriptArtifactGraphBuilder.js +144 -0
  34. package/dist/application/JavaScriptArtifactGraphContext.js +205 -0
  35. package/dist/application/JavaScriptArtifactGraphDocuments.js +108 -0
  36. package/dist/application/JavaScriptArtifactGraphEvidence.js +99 -0
  37. package/dist/application/JavaScriptArtifactGraphFindings.js +271 -0
  38. package/dist/application/JavaScriptArtifactGraphStructure.js +409 -0
  39. package/dist/application/JavaScriptArtifactReconstruction.js +77 -0
  40. package/dist/application/JavaScriptArtifactReconstructionInput.js +18 -0
  41. package/dist/application/JavaScriptReplayPlanning.js +201 -0
  42. package/dist/application/JavaScriptReplayService.js +266 -0
  43. package/dist/application/JavaScriptRuntimeReconciliationEvidence.js +25 -0
  44. package/dist/application/JavaScriptRuntimeReconciliationService.js +27 -0
  45. package/dist/application/MacHopper.js +20 -4
  46. package/dist/application/ManagedApplicationGraphService.js +55 -0
  47. package/dist/application/ManagedMemberComparisonService.js +122 -0
  48. package/dist/application/ManagedNativeVerificationService.js +39 -0
  49. package/dist/application/ManagedReconstructionService.js +58 -0
  50. package/dist/application/ManagedRuntimeCorrelationService.js +103 -0
  51. package/dist/application/PermissionAuthority.js +1 -1
  52. package/dist/application/ProcessCaptureLifecycle.js +1 -1
  53. package/dist/application/ProcessHarness.js +1 -1
  54. package/dist/application/ProcessSampling.js +16 -12
  55. package/dist/application/ProjectPermissionStore.js +1 -0
  56. package/dist/application/SessionProviderRouter.js +219 -0
  57. package/dist/application/Setup.js +84 -60
  58. package/dist/application/SetupClients.js +1 -1
  59. package/dist/application/SetupPlan.js +9 -2
  60. package/dist/application/SupportedClients.js +40 -16
  61. package/dist/application/Upgrade.js +1 -1
  62. package/dist/application/runtime.js +11 -6
  63. package/dist/artifacts/AsarArtifactReader.js +23 -3
  64. package/dist/browser/CdpBrowserProvider.js +4 -2
  65. package/dist/browser/CdpCaptureEvents.js +49 -0
  66. package/dist/browser/CdpElectronInspection.js +106 -162
  67. package/dist/browser/CdpElectronProvider.js +9 -3
  68. package/dist/browser/CdpElectronScriptEvents.js +69 -0
  69. package/dist/browser/CdpElectronScripts.js +94 -0
  70. package/dist/browser/CdpElectronWorkers.js +56 -0
  71. package/dist/browser/CdpEndpoint.js +14 -1
  72. package/dist/browser/CdpPageCapture.js +8 -4
  73. package/dist/catalogIdentity.js +6 -42
  74. package/dist/cli.js +446 -34
  75. package/dist/cliApplicationCommands.js +62 -0
  76. package/dist/cliBrowserAdvancedCommands.js +5 -4
  77. package/dist/cliBrowserCommands.js +5 -4
  78. package/dist/cliCommandNames.js +56 -0
  79. package/dist/cliElectronCommands.js +106 -3
  80. package/dist/cliEvidenceCommands.js +4 -3
  81. package/dist/cliInvestigationCommands.js +2 -1
  82. package/dist/cliJsonInput.js +54 -0
  83. package/dist/cliPolicyCommands.js +2 -1
  84. package/dist/cliProcessCommands.js +3 -2
  85. package/dist/config.js +101 -2
  86. package/dist/contracts/applicationToolContracts.js +91 -0
  87. package/dist/contracts/artifactToolContracts.js +5 -9
  88. package/dist/contracts/browserToolContracts.js +14 -62
  89. package/dist/contracts/electronToolContracts.js +45 -19
  90. package/dist/contracts/enhancedInputs.js +2 -2
  91. package/dist/contracts/errorSchemas.js +1 -0
  92. package/dist/contracts/investigationExamples.js +0 -6
  93. package/dist/contracts/javascriptApplicationWorkflowExamples.js +46 -0
  94. package/dist/contracts/javascriptRuntimeReconciliationExample.js +208 -0
  95. package/dist/contracts/managedToolContracts.js +153 -0
  96. package/dist/contracts/managedWorkflowExamples.js +346 -0
  97. package/dist/contracts/managedWorkflowToolContracts.js +203 -0
  98. package/dist/contracts/nativeToolContracts.js +2 -6
  99. package/dist/contracts/promptContracts.js +18 -2
  100. package/dist/contracts/providerSelection.js +28 -0
  101. package/dist/contracts/sessionLifecycleInputs.js +2 -0
  102. package/dist/contracts/toolContractExamples.js +10 -25
  103. package/dist/contracts/toolContracts.js +69 -65
  104. package/dist/contracts/toolEffects.js +160 -0
  105. package/dist/contracts/toolOutputSchemas.js +152 -42
  106. package/dist/doctorRuntime.js +47 -0
  107. package/dist/domain/analysisProfile.js +78 -0
  108. package/dist/domain/analysisSnapshot.js +92 -46
  109. package/dist/domain/artifactComparison.js +3 -4
  110. package/dist/domain/artifactGraph.js +1 -0
  111. package/dist/domain/binaryTarget.js +4 -29
  112. package/dist/domain/browserObservation.js +3 -0
  113. package/dist/domain/bundleComparison.js +4 -4
  114. package/dist/domain/electronObservation.js +13 -0
  115. package/dist/domain/electronStaticAnalysis.js +9 -0
  116. package/dist/domain/electronStaticAnalysisBrowser.js +194 -0
  117. package/dist/domain/electronStaticAnalysisIpc.js +171 -0
  118. package/dist/domain/electronStaticAnalysisNative.js +164 -0
  119. package/dist/domain/electronStaticAnalysisTypes.js +1 -0
  120. package/dist/domain/electronStaticAnalysisValues.js +103 -0
  121. package/dist/domain/errors.js +148 -7
  122. package/dist/domain/evidence.js +44 -5
  123. package/dist/domain/evidenceBundle.js +9 -7
  124. package/dist/domain/functionComparison.js +9 -3
  125. package/dist/domain/functionComparisonNormalization.js +37 -0
  126. package/dist/domain/functionComparisonSchemas.js +3 -8
  127. package/dist/domain/functionDossierEvidence.js +4 -1
  128. package/dist/domain/hopperValues.js +66 -9
  129. package/dist/domain/inputIssueProjection.js +52 -0
  130. package/dist/domain/investigationWorkspace.js +2 -1
  131. package/dist/domain/javascriptApplicationAnalysis.js +155 -0
  132. package/dist/domain/javascriptApplicationChangeGraph.js +231 -0
  133. package/dist/domain/javascriptApplicationEvidenceSchemas.js +379 -0
  134. package/dist/domain/javascriptApplicationGraph.js +282 -0
  135. package/dist/domain/javascriptApplicationGraphSchemas.js +139 -0
  136. package/dist/domain/javascriptApplicationVersionComparison.js +116 -0
  137. package/dist/domain/javascriptApplicationVersionComparisonSchemas.js +139 -0
  138. package/dist/domain/javascriptApplicationVersionItems.js +221 -0
  139. package/dist/domain/javascriptApplicationVersionKeys.js +170 -0
  140. package/dist/domain/javascriptAstFingerprint.js +143 -0
  141. package/dist/domain/javascriptFeatureSeed.js +140 -0
  142. package/dist/domain/javascriptFeatureTrace.js +232 -0
  143. package/dist/domain/javascriptFeatureTraceSchemas.js +136 -0
  144. package/dist/domain/javascriptFeatureTraversal.js +88 -0
  145. package/dist/domain/javascriptNativeHandoff.js +85 -0
  146. package/dist/domain/javascriptReplay.js +361 -0
  147. package/dist/domain/javascriptRuntimeLoadState.js +106 -0
  148. package/dist/domain/javascriptRuntimeReconciliation.js +42 -0
  149. package/dist/domain/javascriptRuntimeReconciliationGraph.js +169 -0
  150. package/dist/domain/javascriptRuntimeReconciliationMatching.js +247 -0
  151. package/dist/domain/javascriptRuntimeReconciliationParsing.js +160 -0
  152. package/dist/domain/javascriptRuntimeReconciliationResult.js +119 -0
  153. package/dist/domain/javascriptRuntimeReconciliationRuntime.js +316 -0
  154. package/dist/domain/javascriptRuntimeReconciliationSchemas.js +245 -0
  155. package/dist/domain/javascriptRuntimeStaticCandidates.js +191 -0
  156. package/dist/domain/javascriptStaticAnalysis.js +346 -0
  157. package/dist/domain/javascriptStaticAnalysisFindings.js +39 -0
  158. package/dist/domain/javascriptStaticAnalysisHelpers.js +274 -0
  159. package/dist/domain/javascriptStaticAnalysisState.js +23 -0
  160. package/dist/domain/javascriptStaticAnalysisTypes.js +1 -0
  161. package/dist/domain/managedApplicationGraph.js +556 -0
  162. package/dist/domain/managedArtifact.js +444 -0
  163. package/dist/domain/managedMemberComparison.js +565 -0
  164. package/dist/domain/managedNativeVerification.js +408 -0
  165. package/dist/domain/managedReconstruction.js +183 -0
  166. package/dist/domain/managedRuntimeCorrelation.js +175 -0
  167. package/dist/domain/reconstructionVerificationSchemas.js +1 -3
  168. package/dist/dotnet/ManagedArtifactInspector.js +318 -0
  169. package/dist/dotnet/ManagedMemberInspector.js +887 -0
  170. package/dist/dotnet/ManagedMetadataHeaps.js +131 -0
  171. package/dist/dotnet/ManagedMetadataInventory.js +368 -0
  172. package/dist/dotnet/ManagedMetadataLayout.js +322 -0
  173. package/dist/dotnet/ManagedNativeBoundaryInspector.js +391 -0
  174. package/dist/dotnet/ManagedPeReader.js +157 -0
  175. package/dist/dotnet/ManagedReaderFailure.js +10 -0
  176. package/dist/dotnet/ManagedStaticProvider.js +203 -0
  177. package/dist/generatedPackageMetadata.js +2 -2
  178. package/dist/ghidra/GhidraAnalysisProfile.js +37 -0
  179. package/dist/ghidra/GhidraClient.js +400 -0
  180. package/dist/ghidra/GhidraClientTypes.js +1 -0
  181. package/dist/ghidra/GhidraDefaults.js +20 -0
  182. package/dist/ghidra/GhidraDiagnostics.js +43 -0
  183. package/dist/ghidra/GhidraDoctor.js +59 -0
  184. package/dist/ghidra/GhidraFunctionValues.js +264 -0
  185. package/dist/ghidra/GhidraInstallation.js +239 -0
  186. package/dist/ghidra/GhidraInventoryValues.js +217 -0
  187. package/dist/ghidra/GhidraLauncher.js +139 -0
  188. package/dist/ghidra/GhidraProvider.js +366 -0
  189. package/dist/ghidra/GhidraRequestQueue.js +98 -0
  190. package/dist/ghidra/GhidraResponseBuffer.js +31 -0
  191. package/dist/ghidra/GhidraResponseRouter.js +24 -0
  192. package/dist/ghidra/GhidraSessionError.js +39 -0
  193. package/dist/ghidra/GhidraSessionValues.js +62 -0
  194. package/dist/ghidra/GhidraSocketConnection.js +46 -0
  195. package/dist/ghidra/protocol.js +69 -0
  196. package/dist/hopper/BridgeLauncher.js +19 -54
  197. package/dist/hopper/HopperAnalysisProfile.js +106 -0
  198. package/dist/hopper/HopperClient.js +154 -162
  199. package/dist/hopper/HopperProvider.js +99 -7
  200. package/dist/hopper/HopperSessionValues.js +27 -0
  201. package/dist/hopper/HopperSocketConnection.js +31 -0
  202. package/dist/main.js +14 -0
  203. package/dist/native/NativeMacOSProvider.js +3 -1
  204. package/dist/process/PendingOperations.js +59 -0
  205. package/dist/process/PrivateRuntimeRoot.js +33 -0
  206. package/dist/process/ProviderDeadline.js +95 -0
  207. package/dist/process/ProviderProcess.js +275 -0
  208. package/dist/replay/JavaScriptReplayWorker.js +286 -0
  209. package/dist/replay/LinuxJavaScriptReplayRunner.js +434 -0
  210. package/dist/replay/LinuxRuntimeClosure.js +46 -0
  211. package/dist/replay/LinuxSeccompPolicy.js +40 -0
  212. package/dist/replay/ReplayWorkerProtocol.js +55 -0
  213. package/dist/replay/SystemJavaScriptReplayHost.js +182 -0
  214. package/dist/server/createServer.js +53 -0
  215. package/dist/server/promptCompletion.js +9 -3
  216. package/dist/server/registerApplicationTools.js +115 -0
  217. package/dist/server/registerArtifactComparisonTool.js +16 -9
  218. package/dist/server/registerBrowserTools.js +33 -8
  219. package/dist/server/registerBundleComparisonTool.js +17 -20
  220. package/dist/server/registerElectronTools.js +45 -3
  221. package/dist/server/registerEnhancedTools.js +67 -19
  222. package/dist/server/registerEvidenceTools.js +5 -1
  223. package/dist/server/registerFunctionComparisonTool.js +14 -7
  224. package/dist/server/registerInvestigationTools.js +21 -17
  225. package/dist/server/registerManagedTools.js +6 -0
  226. package/dist/server/registerManagedWorkflowTools.js +277 -0
  227. package/dist/server/registerOfficialTools.js +11 -8
  228. package/dist/server/registerProcessComparisonTool.js +25 -47
  229. package/dist/server/registerSessionStatusTool.js +7 -7
  230. package/dist/server/registerSessionTools.js +57 -87
  231. package/dist/server/sessionEvidence.js +14 -19
  232. package/dist/server/toolInputValidation.js +77 -0
  233. package/dist/server/toolRegistrationOptions.js +79 -2
  234. package/dist/server/toolResult.js +25 -17
  235. package/package.json +17 -7
  236. package/scripts/rea.mjs +36 -2
  237. package/skills/rea-analysis/SKILL.md +59 -3
  238. /package/dist/{application → process}/ProcessOwnership.js +0 -0
@@ -0,0 +1,203 @@
1
+ import { createHash } from "node:crypto";
2
+ import { readFile, stat } from "node:fs/promises";
3
+ import { createAnalysisExecution, } from "../application/AnalysisProvider.js";
4
+ import { MANAGED_STATIC_PROVIDER } from "../application/InvestigationProviders.js";
5
+ import { MANAGED_TOOL_CONTRACTS, managedArtifactInputSchema, managedMemberInputSchema, managedNativeBoundaryInputSchema, } from "../contracts/managedToolContracts.js";
6
+ import { AnalysisCancelledError, AnalysisCapabilityUnavailableError, EvidenceIntegrityError, ProviderAdapterError, } from "../domain/errors.js";
7
+ import { err, ok } from "../domain/result.js";
8
+ import { inspectManagedArtifactBytes } from "./ManagedArtifactInspector.js";
9
+ import { inspectManagedMembersBytes } from "./ManagedMemberInspector.js";
10
+ import { inspectManagedNativeBoundariesBytes } from "./ManagedNativeBoundaryInspector.js";
11
+ const IDENTITY = Object.freeze(MANAGED_STATIC_PROVIDER);
12
+ /** Execution-free managed PE/CLI auxiliary provider. */
13
+ export class ManagedStaticProvider {
14
+ #capabilities = Object.freeze(MANAGED_TOOL_CONTRACTS.map((contract) => Object.freeze({
15
+ provider: IDENTITY,
16
+ operation: contract.name,
17
+ inputContractVersion: 1,
18
+ outputContractVersion: 1,
19
+ available: true,
20
+ reason: null,
21
+ pagination: "offset",
22
+ exhaustive: false,
23
+ effects: Object.freeze({
24
+ mutatesArtifact: false,
25
+ launchesProcess: false,
26
+ mayShowUi: false,
27
+ mayAccessNetwork: false,
28
+ mayWriteFilesystem: false,
29
+ changesPermissions: false,
30
+ requiresRoot: false,
31
+ }),
32
+ limits: Object.freeze({
33
+ maxResults: 500,
34
+ maxPayloadBytes: 4 * 1024 * 1024,
35
+ timeoutMs: null,
36
+ }),
37
+ limitations: limitationsFor(contract.name),
38
+ })));
39
+ identity() {
40
+ return IDENTITY;
41
+ }
42
+ capabilities() {
43
+ return this.#capabilities;
44
+ }
45
+ createClient(target) {
46
+ return new ManagedStaticClient(target);
47
+ }
48
+ }
49
+ class ManagedStaticClient {
50
+ target;
51
+ constructor(target) {
52
+ this.target = target;
53
+ }
54
+ async execute(operation, parameters, options) {
55
+ if (operation === "health")
56
+ return ok(createAnalysisExecution(null, IDENTITY));
57
+ if (!isManagedOperation(operation))
58
+ return err(new AnalysisCapabilityUnavailableError(IDENTITY.id, operation, "Operation is not implemented by the managed static provider."));
59
+ if (this.target.format !== "pe")
60
+ return err(new AnalysisCapabilityUnavailableError(IDENTITY.id, operation, `Managed static triage requires a PE target; observed ${this.target.format}.`));
61
+ try {
62
+ if (options?.signal?.aborted === true)
63
+ return err(new AnalysisCancelledError(operation));
64
+ const maxFileBytes = maxRequestedFileBytes(operation, parameters);
65
+ const metadata = await stat(this.target.path);
66
+ if (metadata.size > maxFileBytes)
67
+ return err(new AnalysisCapabilityUnavailableError(IDENTITY.id, operation, `Artifact size ${String(metadata.size)} exceeds max_file_bytes ${String(maxFileBytes)}.`));
68
+ const bytes = await readFile(this.target.path, options?.signal === undefined ? undefined : { signal: options.signal });
69
+ if (bytes.length > maxFileBytes)
70
+ return err(new AnalysisCapabilityUnavailableError(IDENTITY.id, operation, `Artifact grew beyond max_file_bytes ${String(maxFileBytes)} while it was read.`));
71
+ const observedDigest = createHash("sha256").update(bytes).digest("hex");
72
+ if (observedDigest !== this.target.sha256)
73
+ return err(new EvidenceIntegrityError(`Managed artifact digest changed after open: expected ${this.target.sha256}, observed ${observedDigest} at ${this.target.path}`));
74
+ const result = inspectManagedOperation(operation, parameters, bytes, this.target);
75
+ return ok(createAnalysisExecution(result, IDENTITY, {
76
+ rawResult: null,
77
+ limitations: result.limitations,
78
+ subject: this.target,
79
+ locations: managedLocations(result),
80
+ }));
81
+ }
82
+ catch (cause) {
83
+ if (options?.signal?.aborted === true)
84
+ return err(new AnalysisCancelledError(operation));
85
+ return err(new ProviderAdapterError(IDENTITY.id, operation, { cause }));
86
+ }
87
+ }
88
+ close() {
89
+ return Promise.resolve();
90
+ }
91
+ }
92
+ const isManagedOperation = (operation) => MANAGED_TOOL_CONTRACTS.some(({ name }) => name === operation);
93
+ const limitationsFor = (operation) => Object.freeze(operation === "inspect_managed_artifact"
94
+ ? [
95
+ "This capability inventories PE/CLI identity only; inspect_managed_members admits bounded metadata members, signatures, and CIL anchors.",
96
+ "It never loads the target assembly, resolves dependencies through a CLR, decompiles C#, or executes target code.",
97
+ ]
98
+ : operation === "inspect_managed_native_boundaries"
99
+ ? [
100
+ "This capability inventories managed declarations for native boundaries only; native exports, thunks, and addresses require separate native-provider evidence.",
101
+ "It never loads the target assembly, resolves dependencies through a CLR, decompiles C#, or executes target code.",
102
+ ]
103
+ : [
104
+ "This capability decodes bounded PE/CLI metadata members, signatures, and file-backed method bodies; decompiled C# and cross-build matching are separate future contracts.",
105
+ "It never loads the target assembly, resolves dependencies through a CLR, decompiles C#, or executes target code.",
106
+ ]);
107
+ const maxRequestedFileBytes = (operation, parameters) => {
108
+ if (operation === "inspect_managed_artifact")
109
+ return managedArtifactInputSchema.parse(parameters).max_file_bytes;
110
+ if (operation === "inspect_managed_native_boundaries")
111
+ return managedNativeBoundaryInputSchema.parse(parameters).max_file_bytes;
112
+ return managedMemberInputSchema.parse(parameters).max_file_bytes;
113
+ };
114
+ const inspectManagedOperation = (operation, parameters, bytes, target) => {
115
+ if (operation === "inspect_managed_artifact") {
116
+ const input = managedArtifactInputSchema.parse(parameters);
117
+ return inspectManagedArtifactBytes(bytes, target, {
118
+ referenceOffset: input.reference_offset,
119
+ referenceLimit: input.reference_limit,
120
+ resourceOffset: input.resource_offset,
121
+ resourceLimit: input.resource_limit,
122
+ attributeOffset: input.attribute_offset,
123
+ attributeLimit: input.attribute_limit,
124
+ maxMetadataBytes: input.max_metadata_bytes,
125
+ maxTableRows: input.max_table_rows,
126
+ maxHeapItemBytes: input.max_heap_item_bytes,
127
+ });
128
+ }
129
+ if (operation === "inspect_managed_native_boundaries") {
130
+ const input = managedNativeBoundaryInputSchema.parse(parameters);
131
+ return inspectManagedNativeBoundariesBytes(bytes, target, {
132
+ moduleRefOffset: input.module_ref_offset,
133
+ moduleRefLimit: input.module_ref_limit,
134
+ importOffset: input.import_offset,
135
+ importLimit: input.import_limit,
136
+ implementationOffset: input.implementation_offset,
137
+ implementationLimit: input.implementation_limit,
138
+ maxMetadataBytes: input.max_metadata_bytes,
139
+ maxTableRows: input.max_table_rows,
140
+ maxHeapItemBytes: input.max_heap_item_bytes,
141
+ });
142
+ }
143
+ const input = managedMemberInputSchema.parse(parameters);
144
+ return inspectManagedMembersBytes(bytes, target, {
145
+ typeOffset: input.type_offset,
146
+ typeLimit: input.type_limit,
147
+ methodOffset: input.method_offset,
148
+ methodLimit: input.method_limit,
149
+ fieldOffset: input.field_offset,
150
+ fieldLimit: input.field_limit,
151
+ memberRefOffset: input.member_ref_offset,
152
+ memberRefLimit: input.member_ref_limit,
153
+ edgeOffset: input.edge_offset,
154
+ edgeLimit: input.edge_limit,
155
+ instructionAnchorLimit: input.instruction_anchor_limit,
156
+ maxMetadataBytes: input.max_metadata_bytes,
157
+ maxTableRows: input.max_table_rows,
158
+ maxHeapItemBytes: input.max_heap_item_bytes,
159
+ maxMethodBodyBytes: input.max_method_body_bytes,
160
+ maxMethodInstructions: input.max_method_instructions,
161
+ });
162
+ };
163
+ const managedLocations = (result) => {
164
+ if ("pe" in result) {
165
+ if (result.pe.cli === null)
166
+ return [{ kind: "file-offset", offset: 0 }];
167
+ return [
168
+ {
169
+ kind: "file-offset-range",
170
+ start: result.pe.cli.header_offset,
171
+ end: result.pe.cli.header_offset + result.pe.cli.header_size,
172
+ },
173
+ ...[result.module, result.assembly]
174
+ .filter((value) => value !== null)
175
+ .map((value) => ({
176
+ kind: "file-offset",
177
+ offset: value.row_offset,
178
+ })),
179
+ ];
180
+ }
181
+ if ("methods" in result)
182
+ return [
183
+ ...(result.module === null
184
+ ? [{ kind: "file-offset", offset: 0 }]
185
+ : [{ kind: "file-offset", offset: result.module.row_offset }]),
186
+ ...result.methods.items
187
+ .filter((method) => method.body.file_offset !== null)
188
+ .slice(0, 8)
189
+ .map((method) => ({
190
+ kind: "file-offset",
191
+ offset: method.body.file_offset ?? 0,
192
+ })),
193
+ ];
194
+ return [
195
+ ...(result.module === null
196
+ ? [{ kind: "file-offset", offset: 0 }]
197
+ : [{ kind: "file-offset", offset: result.module.row_offset }]),
198
+ ...result.pinvoke_imports.items.slice(0, 8).map((mapping) => ({
199
+ kind: "file-offset",
200
+ offset: mapping.row_offset,
201
+ })),
202
+ ];
203
+ };
@@ -1,9 +1,9 @@
1
1
  /** Generated from package.json and package-lock.json; do not edit. */
2
2
  export const PACKAGE_METADATA = {
3
3
  name: "rea-agents",
4
- version: "1.6.0",
4
+ version: "2.0.0",
5
5
  serverSdkVersion: "2.0.0-beta.4",
6
6
  clientSdkVersion: "2.0.0-beta.4",
7
7
  coreSdkVersion: "2.0.0-beta.4",
8
- skillVersion: "14",
8
+ skillVersion: "20",
9
9
  };
@@ -0,0 +1,37 @@
1
+ import { createAnalysisProfile } from "../domain/analysisProfile.js";
2
+ import { AnalysisCancelledError, ProviderAdapterError, } from "../domain/errors.js";
3
+ import { err, ok } from "../domain/result.js";
4
+ import { GHIDRA_ANALYSIS_TIMEOUT_SECONDS, GHIDRA_MAX_CPU, GHIDRA_MAX_HEAP, } from "./GhidraDefaults.js";
5
+ /** Resolve version-bound, deterministic semantics before Ghidra imports a target. */
6
+ export const resolveGhidraAnalysisProfile = (target, identity, installation, signal) => {
7
+ if (signal?.aborted === true)
8
+ return Promise.resolve(err(new AnalysisCancelledError("open_binary")));
9
+ if (target.kind !== "executable")
10
+ return Promise.resolve(ok({ profile: null, compatibility: {} }));
11
+ const version = installation.providerVersion;
12
+ if (!installation.available || version === null)
13
+ return Promise.resolve(err(new ProviderAdapterError(identity.id, "resolve_analysis_profile")));
14
+ const provider = { ...identity, version };
15
+ return Promise.resolve(ok({
16
+ profile: createAnalysisProfile(provider, 1, {
17
+ target_kind: target.kind,
18
+ target_format: target.format,
19
+ architecture: target.architecture ?? null,
20
+ available_architectures: [
21
+ ...(target.availableArchitectures ?? []),
22
+ ].sort(),
23
+ import_mode: "ephemeral-read-only",
24
+ loader: "auto-from-header",
25
+ language_id: "auto-from-header",
26
+ compiler_spec_id: "auto-default",
27
+ analyzer_preset: "ghidra-default",
28
+ analysis_timeout_seconds: GHIDRA_ANALYSIS_TIMEOUT_SECONDS,
29
+ max_cpu: GHIDRA_MAX_CPU,
30
+ max_heap: GHIDRA_MAX_HEAP,
31
+ }),
32
+ compatibility: {
33
+ languageId: "auto",
34
+ compilerSpecId: "auto",
35
+ },
36
+ }));
37
+ };
@@ -0,0 +1,400 @@
1
+ import { randomBytes, randomUUID } from "node:crypto";
2
+ import { access } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ import { err, ok } from "../domain/result.js";
5
+ import { silentLogger } from "../logger.js";
6
+ import { PendingOperations } from "../process/PendingOperations.js";
7
+ import { PrivateRuntimeRoot } from "../process/PrivateRuntimeRoot.js";
8
+ import { ProviderStartupDeadline } from "../process/ProviderDeadline.js";
9
+ import { ProviderProcessSupervisor, } from "../process/ProviderProcess.js";
10
+ import { GHIDRA_MAX_LINE_BYTES, GHIDRA_MAX_QUEUED_REQUESTS, GHIDRA_REQUEST_TIMEOUT_MS, GHIDRA_STARTUP_TIMEOUT_MS, } from "./GhidraDefaults.js";
11
+ import { createGhidraDiagnostics } from "./GhidraDiagnostics.js";
12
+ import { GhidraResponseBuffer } from "./GhidraResponseBuffer.js";
13
+ import { GhidraResponseRouter } from "./GhidraResponseRouter.js";
14
+ import { GhidraRequestQueue } from "./GhidraRequestQueue.js";
15
+ import { bindGhidraSessionFailure, GhidraSessionError, } from "./GhidraSessionError.js";
16
+ import { isGhidraShutdownAcknowledgement, parseGhidraSessionInfo, } from "./GhidraSessionValues.js";
17
+ import { attachGhidraSocket, connectGhidraSocketOnce, } from "./GhidraSocketConnection.js";
18
+ const SHUTDOWN_TIMEOUT_MS = 10_000;
19
+ const SESSION_ROOT = "/tmp";
20
+ /** Owns one authenticated, private, read-only Ghidra headless session. */
21
+ export class GhidraClient {
22
+ #options;
23
+ #pending = new PendingOperations();
24
+ #logger;
25
+ #socket;
26
+ #detachSocket;
27
+ #launch;
28
+ #process;
29
+ #runtimeRoot;
30
+ #token;
31
+ #runId;
32
+ #nextId = 1;
33
+ #closing = false;
34
+ #processSnapshot;
35
+ #lastDiagnostics = {};
36
+ #startupController;
37
+ #startPromise;
38
+ #closePromise;
39
+ #failure = bindGhidraSessionFailure(() => this.#diagnostics());
40
+ #requestQueue;
41
+ #responseRouter = new GhidraResponseRouter({
42
+ pending: this.#pending,
43
+ nextId: () => this.#nextId,
44
+ remoteFailure: (failure) => this.#failure("remote", failure.message, failure, {
45
+ remoteCode: failure.code,
46
+ }),
47
+ protocolFailure: (message, cause) => this.#abortProtocol(message, cause),
48
+ });
49
+ #responseBuffer = new GhidraResponseBuffer({
50
+ maxLineBytes: GHIDRA_MAX_LINE_BYTES,
51
+ onLine: (line) => this.#responseRouter.route(line),
52
+ onFailure: (message) => this.#abortProtocol(message),
53
+ });
54
+ #onSocketData = (chunk) => this.#responseBuffer.push(chunk);
55
+ #onSocketError = () => {
56
+ this.#failAll(this.#failure("process", "Ghidra bridge socket failed"));
57
+ };
58
+ #onSocketClose = () => {
59
+ if (!this.#closing)
60
+ this.#failAll(this.#failure("process", "Ghidra bridge socket closed"));
61
+ };
62
+ constructor(options) {
63
+ this.#logger = options.logger ?? silentLogger;
64
+ this.#options = {
65
+ ...options,
66
+ requestTimeoutMs: options.requestTimeoutMs ?? GHIDRA_REQUEST_TIMEOUT_MS,
67
+ startupTimeoutMs: options.startupTimeoutMs ?? GHIDRA_STARTUP_TIMEOUT_MS,
68
+ };
69
+ this.#requestQueue = new GhidraRequestQueue(GHIDRA_MAX_QUEUED_REQUESTS, (method, parameters, requestOptions) => this.#request(method, parameters, requestOptions), (kind, message, timeoutMs) => this.#failure(kind, message, undefined, timeoutMs === undefined ? {} : { timeoutMs }));
70
+ }
71
+ /** Launch Ghidra once and require its exact post-analysis handshake. */
72
+ start(signal) {
73
+ if (this.#closePromise !== undefined)
74
+ return this.#closePromise.then(() => this.start(signal));
75
+ if (this.#startPromise !== undefined)
76
+ return this.#startPromise;
77
+ const controller = new AbortController();
78
+ const onAbort = () => controller.abort(signal?.reason);
79
+ if (signal?.aborted === true)
80
+ onAbort();
81
+ else
82
+ signal?.addEventListener("abort", onAbort, { once: true });
83
+ const started = this.#start(controller.signal);
84
+ this.#startupController = controller;
85
+ this.#startPromise = started;
86
+ const reset = () => {
87
+ signal?.removeEventListener("abort", onAbort);
88
+ if (this.#startPromise === started) {
89
+ this.#startPromise = undefined;
90
+ if (this.#startupController === controller)
91
+ this.#startupController = undefined;
92
+ }
93
+ };
94
+ void started.then((result) => {
95
+ signal?.removeEventListener("abort", onAbort);
96
+ if (!result.ok)
97
+ reset();
98
+ }, reset);
99
+ return started;
100
+ }
101
+ /** Revalidate live bridge, provider, run, and profile metadata. */
102
+ async ping(options = {}) {
103
+ const started = await this.start(options.signal);
104
+ if (!started.ok)
105
+ return started;
106
+ const result = await this.#request("ping", {}, options);
107
+ if (!result.ok)
108
+ return result;
109
+ return this.#parseSessionInfo(result.value);
110
+ }
111
+ /** Execute one admitted operation through the bounded per-Program queue. */
112
+ async callTool(operation, parameters, options = {}) {
113
+ const started = await this.start(options.signal);
114
+ if (!started.ok)
115
+ return started;
116
+ return this.#requestQueue.run(operation, parameters, {
117
+ ...(options.signal === undefined ? {} : { signal: options.signal }),
118
+ timeoutMs: options.timeoutMs ?? this.#options.requestTimeoutMs,
119
+ });
120
+ }
121
+ /** Stop the owned process group and remove all project/runtime artifacts. */
122
+ close() {
123
+ const starting = this.#startPromise;
124
+ const controller = this.#startupController;
125
+ controller?.abort();
126
+ this.#closePromise ??= Promise.resolve().then(() => this.#close(starting, controller));
127
+ return this.#closePromise;
128
+ }
129
+ /** Latest bounded local diagnostics, with bearer material redacted. */
130
+ diagnostics() {
131
+ return structuredClone(this.#diagnostics());
132
+ }
133
+ async #start(signal) {
134
+ if (signal.aborted)
135
+ return err(this.#failure("cancelled", "Ghidra startup was cancelled"));
136
+ if (this.#socket !== undefined || this.#runtimeRoot !== undefined)
137
+ return err(this.#failure("protocol", "Ghidra client is already started"));
138
+ const deadline = new ProviderStartupDeadline(this.#options.startupTimeoutMs, signal);
139
+ try {
140
+ return await this.#startWithin(deadline);
141
+ }
142
+ finally {
143
+ deadline.dispose();
144
+ }
145
+ }
146
+ async #startWithin(deadline) {
147
+ try {
148
+ this.#runtimeRoot = await PrivateRuntimeRoot.create({
149
+ parent: SESSION_ROOT,
150
+ prefix: "rea-ghidra-",
151
+ });
152
+ }
153
+ catch (cause) {
154
+ return err(this.#failure("start", "Ghidra runtime root creation failed", cause));
155
+ }
156
+ if (deadline.signal.aborted)
157
+ return this.#startupInterrupted(deadline);
158
+ const socketPath = join(this.#runtimeRoot.path, "bridge.sock");
159
+ this.#token = randomBytes(32).toString("hex");
160
+ this.#runId = randomUUID();
161
+ const launched = await this.#options.launcher
162
+ .launch({
163
+ runtimeRoot: this.#runtimeRoot.path,
164
+ socketPath,
165
+ token: this.#token,
166
+ runId: this.#runId,
167
+ targetPath: this.#options.targetPath,
168
+ providerVersion: this.#options.providerVersion,
169
+ profileDigest: this.#options.profileDigest,
170
+ }, { signal: deadline.signal })
171
+ .catch((cause) => err(this.#failure("start", "Ghidra launcher failed", cause)));
172
+ if (!launched.ok) {
173
+ const failure = deadline.signal.aborted
174
+ ? this.#interruptionFailure(deadline)
175
+ : launched.error instanceof GhidraSessionError
176
+ ? launched.error
177
+ : this.#failure("start", launched.error.message, launched.error);
178
+ await this.#cleanup();
179
+ return err(failure);
180
+ }
181
+ this.#launch = launched.value;
182
+ this.#process = new ProviderProcessSupervisor(launched.value, {
183
+ onDiagnostic: (event) => this.#onProcessDiagnostic(event),
184
+ });
185
+ const connected = await this.#connect(socketPath, deadline);
186
+ if (!connected.ok) {
187
+ const failure = connected.error;
188
+ await this.#cleanup();
189
+ return err(failure);
190
+ }
191
+ const ping = await this.#request("ping", {}, {
192
+ signal: deadline.signal,
193
+ timeoutMs: deadline.remainingMs(),
194
+ });
195
+ if (!ping.ok) {
196
+ const failure = deadline.signal.aborted
197
+ ? this.#interruptionFailure(deadline)
198
+ : ping.error;
199
+ await this.#cleanup();
200
+ return err(failure);
201
+ }
202
+ const parsed = this.#parseSessionInfo(ping.value);
203
+ if (!parsed.ok || parsed.value.analysis_timed_out) {
204
+ const failure = parsed.ok
205
+ ? this.#failure("analysis_timeout", "Ghidra auto-analysis reached its per-file deadline")
206
+ : parsed.error;
207
+ await this.#cleanup();
208
+ return err(failure);
209
+ }
210
+ return parsed;
211
+ }
212
+ async #connect(socketPath, deadline) {
213
+ while (deadline.remainingMs() > 0) {
214
+ if (deadline.signal.aborted)
215
+ return err(this.#interruptionFailure(deadline));
216
+ if (this.#closing)
217
+ return err(this.#failure("cancelled", "Ghidra startup was closed"));
218
+ if (this.#processSnapshot?.exitCode !== undefined)
219
+ return err(this.#failure("process", "Ghidra exited before bridge startup"));
220
+ try {
221
+ await access(socketPath);
222
+ }
223
+ catch {
224
+ if ((await deadline.wait(50)) === "aborted")
225
+ return err(this.#interruptionFailure(deadline));
226
+ continue;
227
+ }
228
+ const connected = await connectGhidraSocketOnce(socketPath, deadline.signal);
229
+ if (connected.ok) {
230
+ this.#socket = connected.value;
231
+ this.#detachSocket = attachGhidraSocket(connected.value, {
232
+ data: this.#onSocketData,
233
+ error: this.#onSocketError,
234
+ close: this.#onSocketClose,
235
+ });
236
+ return ok(undefined);
237
+ }
238
+ if ((await deadline.wait(50)) === "aborted")
239
+ return err(this.#interruptionFailure(deadline));
240
+ }
241
+ return err(this.#failure("timeout", "Ghidra startup deadline elapsed", undefined, {
242
+ timeoutMs: this.#options.startupTimeoutMs,
243
+ }));
244
+ }
245
+ async #request(method, params, options) {
246
+ const socket = this.#socket;
247
+ const token = this.#token;
248
+ if (socket === undefined || socket.destroyed || token === undefined)
249
+ return err(this.#failure("process", "Ghidra bridge is unavailable"));
250
+ if (options.signal?.aborted === true)
251
+ return err(this.#failure("cancelled", "Ghidra request was cancelled"));
252
+ const id = this.#nextId++;
253
+ const timeoutMs = options.timeoutMs ?? this.#options.requestTimeoutMs;
254
+ if (timeoutMs <= 0)
255
+ return err(this.#failure("timeout", "Ghidra request deadline elapsed", undefined, {
256
+ timeoutMs,
257
+ }));
258
+ const response = this.#pending.wait(id, {
259
+ timeoutMs,
260
+ ...(options.signal === undefined ? {} : { signal: options.signal }),
261
+ timeoutValue: () => err(this.#failure("timeout", "Ghidra bridge request timed out", undefined, { timeoutMs })),
262
+ cancelledValue: () => err(this.#failure("cancelled", "Ghidra request was cancelled")),
263
+ });
264
+ socket.write(`${JSON.stringify({ id, token, method, params })}\n`, (cause) => {
265
+ if (cause !== undefined && cause !== null)
266
+ this.#pending.settle(id, err(this.#failure("process", "Ghidra bridge write failed", cause)));
267
+ });
268
+ const result = await response;
269
+ this.#logger[result.ok ? "debug" : "warn"]({ method, status: result.ok ? "ok" : "error" }, "Ghidra bridge request completed");
270
+ return result;
271
+ }
272
+ #parseSessionInfo(value) {
273
+ const runId = this.#runId;
274
+ if (runId === undefined)
275
+ return err(this.#failure("protocol", "Ghidra run identity is missing"));
276
+ const parsed = parseGhidraSessionInfo(value, {
277
+ runId,
278
+ providerVersion: this.#options.providerVersion,
279
+ profileDigest: this.#options.profileDigest,
280
+ });
281
+ if (parsed.ok)
282
+ return parsed;
283
+ return err(this.#failure("protocol", "Ghidra bridge handshake is invalid", parsed.error));
284
+ }
285
+ async #close(starting, controller) {
286
+ try {
287
+ await starting?.catch(() => undefined);
288
+ await this.#cleanup();
289
+ }
290
+ finally {
291
+ if (this.#startPromise === starting)
292
+ this.#startPromise = undefined;
293
+ if (this.#startupController === controller)
294
+ this.#startupController = undefined;
295
+ this.#closePromise = undefined;
296
+ }
297
+ }
298
+ async #cleanup() {
299
+ this.#closing = true;
300
+ try {
301
+ this.#requestQueue.failQueued(this.#failure("process", "Ghidra session closed"));
302
+ const socket = this.#socket;
303
+ if (socket !== undefined && !socket.destroyed) {
304
+ const shutdown = await this.#request("shutdown", {}, {
305
+ timeoutMs: SHUTDOWN_TIMEOUT_MS,
306
+ }).catch(() => err(this.#failure("process", "Ghidra shutdown request failed")));
307
+ if (!shutdown.ok || !isGhidraShutdownAcknowledgement(shutdown.value))
308
+ this.#logger.warn({ status: shutdown.ok ? "invalid-acknowledgement" : "failed" }, "Ghidra bridge shutdown was not confirmed");
309
+ }
310
+ this.#failAll(this.#failure("process", "Ghidra session closed"));
311
+ this.#detachSocket?.();
312
+ this.#detachSocket = undefined;
313
+ socket?.destroy();
314
+ this.#socket = undefined;
315
+ if (this.#process !== undefined) {
316
+ await this.#process.waitForExit(500);
317
+ this.#processSnapshot = this.#process.snapshot();
318
+ const stopped = await this.#process.stop();
319
+ this.#processSnapshot = this.#process.snapshot();
320
+ if (stopped.status === "incomplete") {
321
+ this.#options.onDiagnostic?.({
322
+ type: "cleanup-incomplete",
323
+ reason: stopped.reason,
324
+ });
325
+ this.#logger.warn({ reason: stopped.reason }, "Ghidra process cleanup failed closed");
326
+ }
327
+ }
328
+ this.#lastDiagnostics = this.#diagnostics();
329
+ this.#process = undefined;
330
+ this.#launch = undefined;
331
+ const runtimeRoot = this.#runtimeRoot;
332
+ this.#runtimeRoot = undefined;
333
+ await runtimeRoot?.close();
334
+ this.#token = undefined;
335
+ this.#runId = undefined;
336
+ this.#responseBuffer.reset();
337
+ }
338
+ finally {
339
+ this.#closing = false;
340
+ }
341
+ }
342
+ #onProcessDiagnostic(event) {
343
+ if (event.type === "output") {
344
+ this.#options.onDiagnostic?.({
345
+ type: "launcher-output",
346
+ stream: event.stream,
347
+ bytes: event.bytes,
348
+ totalBytes: event.totalBytes,
349
+ truncated: event.truncated,
350
+ });
351
+ return;
352
+ }
353
+ if (event.type === "error") {
354
+ this.#logger.warn({ message: event.message }, "Ghidra process emitted an error");
355
+ return;
356
+ }
357
+ this.#processSnapshot = event.snapshot;
358
+ this.#options.onDiagnostic?.({
359
+ type: "launcher-exit",
360
+ code: event.code,
361
+ signal: event.signal,
362
+ });
363
+ if (!this.#closing)
364
+ this.#failAll(this.#failure("process", "Ghidra process exited"));
365
+ }
366
+ #abortProtocol(message, cause) {
367
+ this.#failAll(this.#failure("protocol", message, cause));
368
+ this.#socket?.destroy();
369
+ }
370
+ #failAll(error) {
371
+ this.#pending.failAll(() => err(error));
372
+ }
373
+ async #startupInterrupted(deadline) {
374
+ const failure = this.#interruptionFailure(deadline);
375
+ await this.#cleanup();
376
+ return err(failure);
377
+ }
378
+ #interruptionFailure(deadline) {
379
+ return deadline.cancelled
380
+ ? this.#failure("cancelled", "Ghidra startup was cancelled")
381
+ : this.#failure("timeout", "Ghidra startup deadline elapsed", undefined, {
382
+ timeoutMs: deadline.timeoutMs,
383
+ });
384
+ }
385
+ #diagnostics() {
386
+ const snapshot = this.#process?.snapshot() ?? this.#processSnapshot;
387
+ return createGhidraDiagnostics({
388
+ targetPath: this.#options.targetPath,
389
+ providerVersion: this.#options.providerVersion,
390
+ profileDigest: this.#options.profileDigest,
391
+ ...(this.#runtimeRoot === undefined
392
+ ? {}
393
+ : { runtimeRoot: this.#runtimeRoot.path }),
394
+ ...(this.#launch === undefined ? {} : { launch: this.#launch }),
395
+ ...(snapshot === undefined ? {} : { snapshot }),
396
+ ...(this.#token === undefined ? {} : { token: this.#token }),
397
+ previous: this.#lastDiagnostics,
398
+ });
399
+ }
400
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,20 @@
1
+ /** Maximum wall-clock analysis time passed to Ghidra for one imported file. */
2
+ export const GHIDRA_ANALYSIS_TIMEOUT_SECONDS = 300;
3
+ /** Maximum CPU cores made available to one headless analysis. */
4
+ export const GHIDRA_MAX_CPU = 2;
5
+ /** Explicit JVM heap ceiling for one headless provider process. */
6
+ export const GHIDRA_MAX_HEAP = "2G";
7
+ /** Absolute import, analysis, bridge, and health startup deadline. */
8
+ export const GHIDRA_STARTUP_TIMEOUT_MS = 330_000;
9
+ /** Default bounded wait for one established bridge request. */
10
+ export const GHIDRA_REQUEST_TIMEOUT_MS = 10_000;
11
+ /** Per-function ceiling passed to Ghidra's native decompiler process. */
12
+ export const GHIDRA_DECOMPILE_TIMEOUT_SECONDS = 30;
13
+ /** Socket deadline leaves bounded time to project a native decompiler timeout. */
14
+ export const GHIDRA_DECOMPILE_REQUEST_TIMEOUT_MS = 35_000;
15
+ /** Maximum active plus queued calls for one serial headless Program. */
16
+ export const GHIDRA_MAX_QUEUED_REQUESTS = 32;
17
+ /** Maximum encoded response line accepted from the Java bridge. */
18
+ export const GHIDRA_MAX_LINE_BYTES = 1024 * 1024;
19
+ /** Version of REA's Java bridge handshake and request protocol. */
20
+ export const GHIDRA_BRIDGE_VERSION = 3;