rea-agents 3.0.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (219) hide show
  1. package/README.md +14 -16
  2. package/dist/application/AnalysisContextQueries.js +21 -9
  3. package/dist/application/ApplicationWorkflowEvidenceResolver.js +19 -11
  4. package/dist/application/ArtifactInventory/policy.js +17 -0
  5. package/dist/application/ArtifactInventory/reader.js +1 -4
  6. package/dist/application/ArtifactInventory/scanCanonical.js +0 -3
  7. package/dist/application/ArtifactInventory/scanReader.js +7 -7
  8. package/dist/application/ArtifactInventory/types.js +1 -5
  9. package/dist/application/BinarySession.js +14 -16
  10. package/dist/application/BinarySessionRecords.js +31 -5
  11. package/dist/application/BinarySessionStatus.js +11 -5
  12. package/dist/application/BrowserEvidence.js +3 -5
  13. package/dist/application/CapabilityClientRequirements.js +26 -0
  14. package/dist/application/CapabilityInventory.js +134 -63
  15. package/dist/application/CrossVersionInventory.js +7 -6
  16. package/dist/application/ElectronActiveEvidence.js +55 -0
  17. package/dist/application/ElectronActiveObservationPort.js +1 -0
  18. package/dist/application/ElectronActiveObservationService.js +81 -0
  19. package/dist/application/EnhancedTools.js +22 -20
  20. package/dist/application/EvidenceBundleCommands.js +5 -1
  21. package/dist/application/EvidenceLedger.js +8 -1
  22. package/dist/application/JavaScriptReplayPermission.js +1 -1
  23. package/dist/application/JavaScriptReplayService.js +23 -15
  24. package/dist/application/ManagedRuntimeCorrelationService.js +9 -5
  25. package/dist/application/NodeRuntimeCharacterizationService.js +8 -9
  26. package/dist/application/ProcessCaptureLifecycle.js +5 -0
  27. package/dist/application/ProcessCli.js +2 -1
  28. package/dist/application/ProcessHarness.js +8 -3
  29. package/dist/application/ProcessNormalization.js +2 -1
  30. package/dist/application/ProjectPermissionStore.js +1 -0
  31. package/dist/application/ReferenceSourceImport.js +2 -2
  32. package/dist/application/SetupClientConfiguration.js +6 -1
  33. package/dist/application/WindowsCapabilities.js +5 -4
  34. package/dist/artifacts/ArtifactProvider.js +8 -10
  35. package/dist/artifacts/SafeOutputTree.js +7 -8
  36. package/dist/browser/CdpCaptureStorageFingerprints.js +10 -7
  37. package/dist/browser/CdpElectronInspection.js +3 -1
  38. package/dist/browser/JavaScriptRuntimeScope.js +5 -0
  39. package/dist/browser/PlaywrightElectronActiveActions.js +324 -0
  40. package/dist/browser/PlaywrightElectronActiveProvider.js +294 -0
  41. package/dist/browser/PlaywrightScenarioBrowser.js +4 -4
  42. package/dist/browser/PlaywrightScenarioSession.js +4 -4
  43. package/dist/browser/SensitiveTextCapture.js +1 -1
  44. package/dist/browser/V8InspectorCaptureProjection.js +1 -0
  45. package/dist/browser/V8InspectorProvider.js +3 -3
  46. package/dist/catalogIdentity.js +12 -6
  47. package/dist/cli/managedCommands.js +1 -1
  48. package/dist/cliApplicationCommands.js +2 -2
  49. package/dist/cliBrowserAdvancedCommands.js +11 -5
  50. package/dist/cliBrowserCommands.js +14 -7
  51. package/dist/cliCommandNames.js +1 -0
  52. package/dist/cliElectronCommands.js +46 -4
  53. package/dist/cliJavaScriptRuntimeCommands.js +14 -6
  54. package/dist/cliObservationOptions.js +4 -0
  55. package/dist/cliPolicyCommands.js +1 -0
  56. package/dist/config/browserScenario.js +77 -0
  57. package/dist/config/electronAutomation.js +35 -0
  58. package/dist/config/environment.js +6 -0
  59. package/dist/config/javascriptReplay.js +41 -0
  60. package/dist/config/managedRuntime.js +25 -0
  61. package/dist/config/parseConfig.js +56 -200
  62. package/dist/config/parsers.js +10 -1
  63. package/dist/config/passiveObservation.js +157 -0
  64. package/dist/config/processCapture.js +47 -0
  65. package/dist/contracts/applicationToolContracts.js +2 -5
  66. package/dist/contracts/applicationWorkflowInputContracts.js +86 -96
  67. package/dist/contracts/artifactToolContracts.js +27 -34
  68. package/dist/contracts/browserToolContracts.js +2 -2
  69. package/dist/contracts/electronToolContracts.js +30 -1
  70. package/dist/contracts/enhancedInputs.js +13 -29
  71. package/dist/contracts/functionWorkflowToolContracts.js +2 -3
  72. package/dist/contracts/managedToolContracts.js +4 -9
  73. package/dist/contracts/managedWorkflowExamples.js +12 -9
  74. package/dist/contracts/managedWorkflowToolContracts.js +30 -27
  75. package/dist/contracts/nativeToolContracts.js +2 -3
  76. package/dist/contracts/sessionToolSchemas.js +61 -0
  77. package/dist/contracts/toolContractExamples.js +1 -0
  78. package/dist/contracts/toolContractHelpers.js +23 -0
  79. package/dist/contracts/toolContracts.js +5 -77
  80. package/dist/contracts/toolEffects.js +15 -0
  81. package/dist/contracts/toolOutputSchemaGroups.js +17 -2
  82. package/dist/contracts/toolOutputSchemaPrimitives.js +76 -26
  83. package/dist/contracts/toolSchemaMetadata.js +128 -0
  84. package/dist/doctorRuntime.js +1 -1
  85. package/dist/domain/androidApplication.js +2 -0
  86. package/dist/domain/appleApplication.js +2 -0
  87. package/dist/domain/binaryTarget.js +7 -5
  88. package/dist/domain/binaryTargetTypes.js +1 -0
  89. package/dist/domain/browserCaptureComparison.js +21 -69
  90. package/dist/domain/browserObservation.js +22 -9
  91. package/dist/domain/bytecodeProvider.js +33 -35
  92. package/dist/domain/callPath.js +3 -2
  93. package/dist/domain/conformanceReplay.js +3 -3
  94. package/dist/domain/conformanceTrustGate.js +151 -16
  95. package/dist/domain/customProtocolCapture.js +3 -3
  96. package/dist/domain/electronActiveObservation.js +277 -0
  97. package/dist/domain/electronObservation.js +15 -11
  98. package/dist/domain/electronStaticAnalysisValues.js +4 -1
  99. package/dist/domain/eventProcessTree.js +82 -79
  100. package/dist/domain/functionComparisonNormalization.js +15 -8
  101. package/dist/domain/functionDossierEvidence.js +9 -4
  102. package/dist/domain/hopperValues.js +68 -71
  103. package/dist/domain/inputIssueProjection.js +4 -1
  104. package/dist/domain/investigationWorkspace.js +16 -15
  105. package/dist/domain/javascriptExportShapeComparisonSchemas.js +2 -2
  106. package/dist/domain/javascriptReplay.js +79 -63
  107. package/dist/domain/javascriptRuntimeObservation.js +1 -0
  108. package/dist/domain/javascriptRuntimeReconciliationActive.js +89 -0
  109. package/dist/domain/javascriptRuntimeReconciliationGraph.js +11 -10
  110. package/dist/domain/javascriptRuntimeReconciliationMatching.js +57 -49
  111. package/dist/domain/javascriptRuntimeReconciliationParsing.js +5 -1
  112. package/dist/domain/javascriptRuntimeReconciliationResult.js +21 -14
  113. package/dist/domain/javascriptRuntimeReconciliationSchemas.js +1 -1
  114. package/dist/domain/knownPageCoverage.js +15 -7
  115. package/dist/domain/nativeApiBoundary.js +15 -7
  116. package/dist/domain/nodeRuntimeCharacterization.js +14 -13
  117. package/dist/domain/processCaptureReactiveValidation.js +8 -3
  118. package/dist/domain/processCaptureValidation.js +7 -3
  119. package/dist/domain/processComparison.js +12 -7
  120. package/dist/domain/processObservation.js +5 -6
  121. package/dist/domain/processReactiveMatching.js +14 -7
  122. package/dist/domain/processReactiveTransition.js +9 -3
  123. package/dist/domain/processScenario.js +6 -3
  124. package/dist/domain/processTraceComparison.js +3 -2
  125. package/dist/domain/protocolCapture.js +8 -6
  126. package/dist/domain/reconstructionReadinessSchemas.js +30 -2
  127. package/dist/domain/referenceSourceImportParsing.js +2 -2
  128. package/dist/domain/replayMachineRuntime.js +5 -3
  129. package/dist/domain/sourceToBundleComparison.js +2 -2
  130. package/dist/domain/sourceToBundleComparisonSchemas.js +8 -8
  131. package/dist/domain/sourceToBundleSignals.js +7 -1
  132. package/dist/domain/staticRuntimeCorrelation.js +7 -5
  133. package/dist/domain/webBundleAnalysis.js +14 -14
  134. package/dist/domain/webCaptureDiff.js +15 -12
  135. package/dist/dotnet/ManagedNativeBoundaryInspector.js +2 -3
  136. package/dist/generatedMcpToolCatalog.js +1 -1
  137. package/dist/generatedPackageMetadata.js +1 -1
  138. package/dist/ghidra/GhidraClient.js +1 -1
  139. package/dist/ghidra/GhidraClientStartup.js +1 -1
  140. package/dist/ghidra/GhidraFunctionValues.js +17 -15
  141. package/dist/ghidra/GhidraInventoryValues.js +57 -47
  142. package/dist/ghidra/GhidraProvider.js +18 -10
  143. package/dist/ghidra/GhidraProviderCapabilities.js +5 -1
  144. package/dist/ghidra/GhidraSocketConnection.js +1 -1
  145. package/dist/ghidra/protocol.js +19 -42
  146. package/dist/hopper/BridgeLauncher.js +3 -1
  147. package/dist/hopper/HopperAnalysisProfile.js +2 -4
  148. package/dist/hopper/HopperCleanup.js +5 -6
  149. package/dist/hopper/HopperClient.js +1 -1
  150. package/dist/hopper/HopperProvider.js +0 -14
  151. package/dist/hopper/LinuxPrivateDisplayProbe.js +16 -10
  152. package/dist/main/reload.js +1 -6
  153. package/dist/main/state.js +0 -14
  154. package/dist/main/transport.js +30 -37
  155. package/dist/main.js +17 -15
  156. package/dist/mcpDoctor.js +2 -24
  157. package/dist/process/PrivateRuntimeRoot.js +17 -0
  158. package/dist/process/ProcessOwnership.js +64 -128
  159. package/dist/process/ProcessOwnershipIdentity.js +13 -0
  160. package/dist/process/ProcessOwnershipObservation.js +88 -0
  161. package/dist/process/ProcessOwnershipProcessTree.js +22 -0
  162. package/dist/process/ProviderDeadline.js +8 -12
  163. package/dist/process/WindowsAuthority.js +32 -0
  164. package/dist/reference/ReferenceSourceReader.js +3 -3
  165. package/dist/reference/ReferenceSourceReaderEntries.js +2 -2
  166. package/dist/replay/JavaScriptReplayWorker.js +95 -11
  167. package/dist/replay/JavaScriptReplayWorkerTypes.js +1 -0
  168. package/dist/replay/LinuxJavaScriptReplayRunner.js +10 -15
  169. package/dist/replay/ReplayOutcome.js +26 -15
  170. package/dist/replay/ReplayWorkerProtocol.js +34 -29
  171. package/dist/server/createServer.js +158 -94
  172. package/dist/server/mcpClientMetadata.js +32 -0
  173. package/dist/server/registerApplicationTools/characterization.js +6 -13
  174. package/dist/server/registerApplicationTools/compareExportShapes.js +2 -7
  175. package/dist/server/registerApplicationTools/compareSourceToBundle.js +2 -7
  176. package/dist/server/registerApplicationTools/compareVersions.js +3 -8
  177. package/dist/server/registerApplicationTools/controlledReplay.js +6 -11
  178. package/dist/server/registerApplicationTools/coverage.js +13 -19
  179. package/dist/server/registerApplicationTools/obligationLedger.js +1 -6
  180. package/dist/server/registerApplicationTools/readiness.js +1 -6
  181. package/dist/server/registerApplicationTools/traceFeature.js +3 -8
  182. package/dist/server/registerApplicationTools/traceSemantics.js +1 -6
  183. package/dist/server/registerArtifactComparisonTool.js +12 -16
  184. package/dist/server/registerBrowserScenarioTool.js +1 -6
  185. package/dist/server/registerBrowserTools.js +37 -79
  186. package/dist/server/registerBundleComparisonTool.js +10 -14
  187. package/dist/server/registerCloseLifecycleTool.js +6 -14
  188. package/dist/server/registerElectronTools.js +30 -47
  189. package/dist/server/registerEnhancedTools.js +114 -122
  190. package/dist/server/registerEvidenceTools.js +5 -9
  191. package/dist/server/registerFunctionComparisonTool.js +11 -15
  192. package/dist/server/registerInvestigationTools.js +41 -57
  193. package/dist/server/registerJavaScriptRuntimeObservationTools.js +13 -27
  194. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +4 -9
  195. package/dist/server/registerManagedWorkflowTools/contract.js +2 -3
  196. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +3 -8
  197. package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +3 -8
  198. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +8 -13
  199. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +4 -9
  200. package/dist/server/registerOfficialTools.js +8 -9
  201. package/dist/server/registerProcessComparisonTool.js +19 -24
  202. package/dist/server/registerReplayMachineTool.js +4 -10
  203. package/dist/server/registerSessionRecordTools.js +69 -40
  204. package/dist/server/registerSessionStatusTool.js +13 -28
  205. package/dist/server/registerSessionTools.js +36 -52
  206. package/dist/server/sessionAvailabilityPolicy.js +2 -1
  207. package/dist/server/sessionToolPolicies.js +1 -5
  208. package/dist/server/toolRegistrationOptions.js +4 -192
  209. package/dist/server/toolResult.js +2 -18
  210. package/package.json +22 -14
  211. package/scripts/electron-active-hook-boundaries.cjs +394 -0
  212. package/scripts/electron-active-hook.cjs +501 -0
  213. package/scripts/rea.mjs +1 -11
  214. package/skills/reverse-engineer-anything/SKILL.md +2 -2
  215. package/dist/server/DynamicToolAvailability.js +0 -70
  216. package/dist/server/LazyToolCatalog.js +0 -134
  217. package/dist/server/hydrateServerTools.js +0 -191
  218. package/dist/server/toolInputValidation.js +0 -77
  219. package/scripts/package-runner-bootstrap.mjs +0 -72
@@ -1,12 +1,15 @@
1
1
  import { Cli, z } from "incur";
2
2
  import { inspectElectronPage, listElectronTargets, } from "./application/ElectronObservationService.js";
3
+ import { captureElectronScenario } from "./application/ElectronActiveObservationService.js";
3
4
  import { reconcileJavaScriptRuntimeEvidence } from "./application/JavaScriptRuntimeReconciliationService.js";
4
5
  import { loadConfiguredPermissionAuthority } from "./application/PermissionConfiguration.js";
5
6
  import { CdpElectronProvider } from "./browser/CdpElectronProvider.js";
7
+ import { PlaywrightElectronActiveProvider } from "./browser/PlaywrightElectronActiveProvider.js";
6
8
  import { logCliCommand } from "./cliLogging.js";
7
9
  import { parseConfig } from "./config.js";
8
10
  import { inspectElectronPageInputSchema, listElectronTargetsInputSchema, } from "./domain/electronObservation.js";
9
- import { AnalysisInputError, projectAnalysisError } from "./domain/errors.js";
11
+ import { electronActiveObservationInputSchema } from "./domain/electronActiveObservation.js";
12
+ import { AnalysisCapabilityUnavailableError, AnalysisInputError, projectAnalysisError, } from "./domain/errors.js";
10
13
  import { CLI_COMMANDS } from "./cliCommandNames.js";
11
14
  import { parseCliJsonInput } from "./cliJsonInput.js";
12
15
  import { electronPageInspectionOptions, javascriptApplicationOptions, } from "./cliObservationOptions.js";
@@ -21,9 +24,33 @@ const scopeOptions = {
21
24
  /** Register CLI equivalents of the Electron MCP tools. */
22
25
  export const registerElectronCommands = (cli, logger) => {
23
26
  registerElectronObservationCommands(cli, logger);
27
+ registerElectronActiveCommand(cli, logger);
24
28
  registerJavaScriptApplicationCommand(cli, logger);
25
29
  registerJavaScriptRuntimeReconciliationCommand(cli, logger);
26
30
  };
31
+ const registerElectronActiveCommand = (cli, logger) => {
32
+ cli.command(CLI_COMMANDS.captureElectronScenario, {
33
+ description: "Run one approved, bounded owned Electron scenario",
34
+ args: z.object({
35
+ inputJson: z
36
+ .string()
37
+ .describe("Inline JSON or a JSON file matching capture_electron_scenario"),
38
+ }),
39
+ run: ({ args }) => logCliCommand(logger, CLI_COMMANDS.captureElectronScenario, async () => {
40
+ const input = await parseCliJsonInput(args.inputJson, "capture_electron_scenario");
41
+ if (!input.ok)
42
+ return input.error;
43
+ const parsed = electronActiveObservationInputSchema.safeParse(input.value);
44
+ if (!parsed.success)
45
+ return inputError("capture_electron_scenario");
46
+ const context = await electronContext();
47
+ if (!context.ok)
48
+ return context.error;
49
+ const result = await captureElectronScenario(context.activeProvider, context.authority, parsed.data);
50
+ return result.ok ? result.value : cliError(result.error);
51
+ }),
52
+ });
53
+ };
27
54
  const registerJavaScriptRuntimeReconciliationCommand = (cli, logger) => {
28
55
  cli.command(CLI_COMMANDS.reconcileJavaScriptRuntime, {
29
56
  description: "Reconcile static application and passive runtime Evidence JSON",
@@ -70,7 +97,7 @@ const registerElectronTargetList = (cli, logger) => {
70
97
  .describe("Maximum Electron targets to return"),
71
98
  }),
72
99
  run: ({ args, options }) => logCliCommand(logger, "list-electron-targets", async () => {
73
- const context = await electronContext();
100
+ const context = await electronObservationContext("list_electron_targets");
74
101
  if (!context.ok)
75
102
  return context.error;
76
103
  const parsed = listElectronTargetsInputSchema.safeParse({
@@ -98,7 +125,7 @@ const registerElectronPageInspection = (cli, logger) => {
98
125
  }),
99
126
  options: electronPageInspectionOptions,
100
127
  run: ({ args, options }) => logCliCommand(logger, "inspect-electron-page", async () => {
101
- const context = await electronContext();
128
+ const context = await electronObservationContext("inspect_electron_page");
102
129
  if (!context.ok)
103
130
  return context.error;
104
131
  const parsed = inspectElectronPageInputSchema.safeParse({
@@ -168,7 +195,22 @@ const electronContext = async () => {
168
195
  ok: true,
169
196
  authority: authority.value,
170
197
  provider: new CdpElectronProvider(),
171
- allowedFileRoots: config.value.electronFileRoots,
198
+ activeProvider: new PlaywrightElectronActiveProvider(),
199
+ observationPolicy: config.value.electronObservationPolicy,
200
+ };
201
+ };
202
+ const electronObservationContext = async (operation) => {
203
+ const context = await electronContext();
204
+ if (!context.ok)
205
+ return context;
206
+ if (context.observationPolicy.status === "disabled")
207
+ return {
208
+ ok: false,
209
+ error: cliError(new AnalysisCapabilityUnavailableError("rea-cdp-electron", operation, "Electron observation is disabled; configure exact endpoints and file roots before enabling it")),
210
+ };
211
+ return {
212
+ ...context,
213
+ allowedFileRoots: context.observationPolicy.fileRoots,
172
214
  };
173
215
  };
174
216
  const inputError = (operation) => cliError(new AnalysisInputError(operation));
@@ -5,8 +5,9 @@ import { V8InspectorProvider } from "./browser/V8InspectorProvider.js";
5
5
  import { CLI_COMMANDS } from "./cliCommandNames.js";
6
6
  import { logCliCommand } from "./cliLogging.js";
7
7
  import { parseConfig } from "./config.js";
8
+ import { v8InspectorLocationScopes } from "./config/passiveObservation.js";
8
9
  import { javascriptRuntimeKindSchema, listJavaScriptRuntimeTargetsInputSchema, observeJavaScriptRuntimeInputSchema, } from "./domain/javascriptRuntimeObservation.js";
9
- import { AnalysisInputError, projectAnalysisError } from "./domain/errors.js";
10
+ import { AnalysisCapabilityUnavailableError, AnalysisInputError, projectAnalysisError, } from "./domain/errors.js";
10
11
  const scopeOptions = {
11
12
  allowedFileRoots: z
12
13
  .array(z.string().min(1))
@@ -89,7 +90,7 @@ export const registerJavaScriptRuntimeObservationCommands = (cli, logger) => {
89
90
  }),
90
91
  options: listOptionsSchema,
91
92
  run: ({ args, options }) => logCliCommand(logger, CLI_COMMANDS.listJavaScriptRuntimeTargets, async () => {
92
- const context = await runtimeContext();
93
+ const context = await runtimeContext("list_javascript_runtime_targets");
93
94
  if (!context.ok)
94
95
  return context.error;
95
96
  const parsed = listJavaScriptRuntimeTargetsInputSchema.safeParse({
@@ -116,7 +117,7 @@ export const registerJavaScriptRuntimeObservationCommands = (cli, logger) => {
116
117
  }),
117
118
  options: observeOptionsSchema,
118
119
  run: ({ args, options }) => logCliCommand(logger, CLI_COMMANDS.observeJavaScriptRuntime, async () => {
119
- const context = await runtimeContext();
120
+ const context = await runtimeContext("observe_javascript_runtime");
120
121
  if (!context.ok)
121
122
  return context.error;
122
123
  const parsed = observeJavaScriptRuntimeInputSchema.safeParse({
@@ -142,19 +143,26 @@ export const registerJavaScriptRuntimeObservationCommands = (cli, logger) => {
142
143
  }),
143
144
  });
144
145
  };
145
- const runtimeContext = async () => {
146
+ const runtimeContext = async (operation) => {
146
147
  const config = parseConfig(process.env);
147
148
  if (!config.ok)
148
149
  return { ok: false, error: cliError(config.error) };
150
+ const policy = config.value.v8InspectorObservationPolicy;
151
+ if (policy.status === "disabled")
152
+ return {
153
+ ok: false,
154
+ error: cliError(new AnalysisCapabilityUnavailableError("rea-v8-inspector", operation, "V8 Inspector observation is disabled; configure exact endpoints and file or origin scopes before enabling it")),
155
+ };
149
156
  const authority = await loadConfiguredPermissionAuthority(config.value);
150
157
  if (!authority.ok)
151
158
  return { ok: false, error: cliError(authority.error) };
159
+ const scopes = v8InspectorLocationScopes(policy.locations);
152
160
  return {
153
161
  ok: true,
154
162
  authority: authority.value,
155
163
  provider: new V8InspectorProvider(),
156
- allowedFileRoots: config.value.v8InspectorFileRoots,
157
- allowedOrigins: config.value.v8InspectorAllowedOrigins,
164
+ allowedFileRoots: scopes.fileRoots,
165
+ allowedOrigins: scopes.allowedOrigins,
158
166
  };
159
167
  };
160
168
  const inputError = (operation) => cliError(new AnalysisInputError(operation));
@@ -50,6 +50,10 @@ export const browserPageInspectionOptions = z.object({
50
50
  .boolean()
51
51
  .default(false)
52
52
  .describe("Include bounded JavaScript source text"),
53
+ sourceCaptureApproved: z
54
+ .boolean()
55
+ .default(false)
56
+ .describe("Approve capturing bounded script source text"),
53
57
  includeStorageKeys: z
54
58
  .boolean()
55
59
  .default(false)
@@ -11,6 +11,7 @@ const capabilitySchema = z.enum([
11
11
  "browser_observe",
12
12
  "browser_automate",
13
13
  "electron_observe",
14
+ "electron_automate",
14
15
  "evidence_read",
15
16
  "evidence_write",
16
17
  "investigation_input",
@@ -0,0 +1,77 @@
1
+ import { ConfigurationError } from "../domain/errors.js";
2
+ import { err, ok } from "../domain/result.js";
3
+ import { browserEndpointSchema, browserOriginSchema, } from "../domain/browserObservation.js";
4
+ import { parseAbsoluteRoots, parseBrowserArray, parseStringArray, } from "./parsers.js";
5
+ import { browserNetworkScope, permissionScope } from "./permissions.js";
6
+ /** Parse controlled browser scenarios into a closed disabled or enabled policy. */
7
+ export const parseBrowserScenarioPolicy = (env) => {
8
+ const executableRoots = parseAbsoluteRoots(env.REA_BROWSER_SCENARIO_EXECUTABLE_ROOTS_JSON, "REA_BROWSER_SCENARIO_EXECUTABLE_ROOTS_JSON");
9
+ if (!executableRoots.ok)
10
+ return executableRoots;
11
+ const cdpEndpoints = parseBrowserArray(env.REA_BROWSER_SCENARIO_CDP_ENDPOINTS_JSON, "REA_BROWSER_SCENARIO_CDP_ENDPOINTS_JSON", browserEndpointSchema, 16);
12
+ if (!cdpEndpoints.ok)
13
+ return cdpEndpoints;
14
+ const allowedOrigins = parseBrowserArray(env.REA_BROWSER_SCENARIO_ALLOWED_ORIGINS_JSON, "REA_BROWSER_SCENARIO_ALLOWED_ORIGINS_JSON", browserOriginSchema, 32);
15
+ if (!allowedOrigins.ok)
16
+ return allowedOrigins;
17
+ const allowedEnvironment = parseStringArray(env.REA_BROWSER_SCENARIO_ALLOWED_ENV_JSON, "REA_BROWSER_SCENARIO_ALLOWED_ENV_JSON");
18
+ if (!allowedEnvironment.ok)
19
+ return allowedEnvironment;
20
+ if (env.REA_BROWSER_SCENARIO_ENABLED !== "true")
21
+ return ok({ status: "disabled" });
22
+ const [firstOrigin, ...remainingOrigins] = allowedOrigins.value;
23
+ if (firstOrigin === undefined)
24
+ return err(new ConfigurationError("REA_BROWSER_SCENARIO_ALLOWED_ORIGINS_JSON must encode at least one exact origin when browser scenarios are enabled"));
25
+ const target = parseTargetPolicy(executableRoots.value, cdpEndpoints.value);
26
+ if (!target.ok)
27
+ return target;
28
+ return ok({
29
+ status: "enabled",
30
+ target: target.value,
31
+ allowedOrigins: [firstOrigin, ...remainingOrigins],
32
+ allowedEnvironment: allowedEnvironment.value,
33
+ });
34
+ };
35
+ /** Add the separately permissioned controlled-browser ceiling. */
36
+ export const appendBrowserScenarioCeiling = (ceilings, policy) => {
37
+ if (policy.status === "disabled")
38
+ return;
39
+ const { executableRoots, cdpEndpoints } = targetScopes(policy.target);
40
+ ceilings.push(permissionScope("browser_automate", [], {
41
+ executables: executableRoots,
42
+ environment_names: policy.allowedEnvironment,
43
+ origins: [...cdpEndpoints, ...policy.allowedOrigins],
44
+ network: browserNetworkScope(policy.allowedOrigins),
45
+ }));
46
+ };
47
+ const parseTargetPolicy = (executableRoots, cdpEndpoints) => {
48
+ const [firstExecutableRoot, ...remainingExecutableRoots] = executableRoots;
49
+ const [firstCdpEndpoint, ...remainingCdpEndpoints] = cdpEndpoints;
50
+ if (firstExecutableRoot !== undefined && firstCdpEndpoint !== undefined)
51
+ return ok({
52
+ access: "launch-or-attach",
53
+ executableRoots: [firstExecutableRoot, ...remainingExecutableRoots],
54
+ cdpEndpoints: [firstCdpEndpoint, ...remainingCdpEndpoints],
55
+ });
56
+ if (firstExecutableRoot !== undefined)
57
+ return ok({
58
+ access: "launch",
59
+ executableRoots: [firstExecutableRoot, ...remainingExecutableRoots],
60
+ });
61
+ if (firstCdpEndpoint !== undefined)
62
+ return ok({
63
+ access: "attach",
64
+ cdpEndpoints: [firstCdpEndpoint, ...remainingCdpEndpoints],
65
+ });
66
+ return err(new ConfigurationError("Browser scenarios require at least one executable root or loopback CDP endpoint when enabled"));
67
+ };
68
+ const targetScopes = (target) => {
69
+ switch (target.access) {
70
+ case "launch":
71
+ return { executableRoots: target.executableRoots, cdpEndpoints: [] };
72
+ case "attach":
73
+ return { executableRoots: [], cdpEndpoints: target.cdpEndpoints };
74
+ case "launch-or-attach":
75
+ return target;
76
+ }
77
+ };
@@ -0,0 +1,35 @@
1
+ import { ConfigurationError } from "../domain/errors.js";
2
+ import { err, ok } from "../domain/result.js";
3
+ import { permissionScope } from "./permissions.js";
4
+ import { parseAbsoluteRoots } from "./parsers.js";
5
+ /** Parse active Electron automation into a closed disabled or enabled policy. */
6
+ export const parseElectronAutomationPolicy = (env) => {
7
+ const executableRoots = parseAbsoluteRoots(env.REA_ELECTRON_AUTOMATE_EXECUTABLE_ROOTS_JSON, "REA_ELECTRON_AUTOMATE_EXECUTABLE_ROOTS_JSON");
8
+ if (!executableRoots.ok)
9
+ return executableRoots;
10
+ const applicationRoots = parseAbsoluteRoots(env.REA_ELECTRON_AUTOMATE_APPLICATION_ROOTS_JSON, "REA_ELECTRON_AUTOMATE_APPLICATION_ROOTS_JSON");
11
+ if (!applicationRoots.ok)
12
+ return applicationRoots;
13
+ if (env.REA_ELECTRON_AUTOMATE_ENABLED !== "true")
14
+ return ok({ status: "disabled" });
15
+ const [firstExecutableRoot, ...remainingExecutableRoots] = executableRoots.value;
16
+ if (firstExecutableRoot === undefined)
17
+ return err(new ConfigurationError("REA_ELECTRON_AUTOMATE_EXECUTABLE_ROOTS_JSON must encode at least one absolute root when Electron automation is enabled"));
18
+ const [firstApplicationRoot, ...remainingApplicationRoots] = applicationRoots.value;
19
+ if (firstApplicationRoot === undefined)
20
+ return err(new ConfigurationError("REA_ELECTRON_AUTOMATE_APPLICATION_ROOTS_JSON must encode at least one absolute root when Electron automation is enabled"));
21
+ return ok({
22
+ status: "enabled",
23
+ executableRoots: [firstExecutableRoot, ...remainingExecutableRoots],
24
+ applicationRoots: [firstApplicationRoot, ...remainingApplicationRoots],
25
+ });
26
+ };
27
+ /** Add the separately permissioned, no-network Electron automation ceiling. */
28
+ export const appendElectronAutomationCeiling = (ceilings, policy) => {
29
+ if (policy.status === "disabled")
30
+ return;
31
+ ceilings.push(permissionScope("electron_automate", policy.applicationRoots, {
32
+ executables: policy.executableRoots,
33
+ network: "external",
34
+ }));
35
+ };
@@ -61,6 +61,12 @@ const environmentSchema = z
61
61
  REA_ELECTRON_OBSERVE_ENABLED: z.enum(["true", "false"]).default("false"),
62
62
  REA_ELECTRON_CDP_ENDPOINTS_JSON: z.string().default("[]"),
63
63
  REA_ELECTRON_FILE_ROOTS_JSON: z.string().default("[]"),
64
+ REA_ELECTRON_AUTOMATE_ENABLED: z.enum(["true", "false"]).default("false"),
65
+ REA_ELECTRON_AUTOMATE_AUTO_GRANT: z
66
+ .enum(["true", "false"])
67
+ .default("false"),
68
+ REA_ELECTRON_AUTOMATE_EXECUTABLE_ROOTS_JSON: z.string().default("[]"),
69
+ REA_ELECTRON_AUTOMATE_APPLICATION_ROOTS_JSON: z.string().default("[]"),
64
70
  REA_V8_INSPECTOR_OBSERVE_ENABLED: z
65
71
  .enum(["true", "false"])
66
72
  .default("false"),
@@ -0,0 +1,41 @@
1
+ import { ConfigurationError } from "../domain/errors.js";
2
+ import { err, ok } from "../domain/result.js";
3
+ import { parseAbsoluteRoots } from "./parsers.js";
4
+ import { permissionScope } from "./permissions.js";
5
+ /** Parse controlled replay configuration into disabled or fully enabled state. */
6
+ export const parseJavaScriptReplayPolicy = (env) => {
7
+ const roots = parseAbsoluteRoots(env.REA_JAVASCRIPT_REPLAY_ROOTS_JSON, "REA_JAVASCRIPT_REPLAY_ROOTS_JSON");
8
+ if (!roots.ok)
9
+ return roots;
10
+ if (env.REA_JAVASCRIPT_REPLAY_ENABLED !== "true")
11
+ return ok({ status: "disabled" });
12
+ const [firstRoot, ...remainingRoots] = roots.value;
13
+ if (firstRoot === undefined)
14
+ return err(new ConfigurationError("REA_JAVASCRIPT_REPLAY_ROOTS_JSON must encode at least one absolute root when JavaScript replay is enabled"));
15
+ return ok({
16
+ status: "enabled",
17
+ roots: [firstRoot, ...remainingRoots],
18
+ nodePath: env.REA_JAVASCRIPT_REPLAY_NODE_PATH,
19
+ bubblewrapPath: env.REA_JAVASCRIPT_REPLAY_BWRAP_PATH,
20
+ systemdRunPath: env.REA_JAVASCRIPT_REPLAY_SYSTEMD_RUN_PATH,
21
+ systemctlPath: env.REA_JAVASCRIPT_REPLAY_SYSTEMCTL_PATH,
22
+ shellPath: env.REA_JAVASCRIPT_REPLAY_SHELL_PATH,
23
+ });
24
+ };
25
+ /** Add the exact controlled replay ceiling when replay is enabled. */
26
+ export const appendJavaScriptReplayCeiling = (ceilings, policy) => {
27
+ if (policy.status === "disabled")
28
+ return;
29
+ ceilings.push(permissionScope("javascript_replay", policy.roots, {
30
+ executables: replayExecutables(policy),
31
+ network: "none",
32
+ mount: true,
33
+ }));
34
+ };
35
+ const replayExecutables = (policy) => [
36
+ policy.nodePath,
37
+ policy.bubblewrapPath,
38
+ policy.systemdRunPath,
39
+ policy.systemctlPath,
40
+ policy.shellPath,
41
+ ];
@@ -0,0 +1,25 @@
1
+ import { ConfigurationError } from "../domain/errors.js";
2
+ import { err, ok } from "../domain/result.js";
3
+ import { permissionScope } from "./permissions.js";
4
+ /** Parse managed runtime correlation into a closed disabled or enabled policy. */
5
+ export const parseManagedRuntimePolicy = (env, roots) => {
6
+ if (env.REA_MANAGED_RUNTIME_ENABLED !== "true")
7
+ return ok({ status: "disabled" });
8
+ const [firstRoot, ...remainingRoots] = roots;
9
+ if (firstRoot === undefined)
10
+ return err(new ConfigurationError("REA_MANAGED_RUNTIME_ROOTS_JSON must encode at least one absolute root when managed runtime correlation is enabled"));
11
+ return ok({
12
+ status: "enabled",
13
+ roots: [firstRoot, ...remainingRoots],
14
+ executablePath: env.REA_MANAGED_RUNTIME_EXECUTABLE_PATH,
15
+ });
16
+ };
17
+ /** Add the separately permissioned, no-network managed runtime ceiling. */
18
+ export const appendManagedRuntimeCeiling = (ceilings, policy) => {
19
+ if (policy.status === "disabled")
20
+ return;
21
+ ceilings.push(permissionScope("managed_runtime", policy.roots, {
22
+ executables: [policy.executablePath],
23
+ network: "none",
24
+ }));
25
+ };