rea-agents 1.7.0 → 2.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.
- package/README.md +112 -59
- package/bridge/ghidra/ReaGhidraBridge.java +96 -11
- package/dist/application/ArtifactExtraction.js +1 -1
- package/dist/application/ArtifactInventory/classify.js +42 -0
- package/dist/application/ArtifactInventory/hash.js +43 -0
- package/dist/application/ArtifactInventory/reader.js +41 -0
- package/dist/application/ArtifactInventory/scanCanonical.js +155 -0
- package/dist/application/ArtifactInventory/scanReader.js +124 -0
- package/dist/application/ArtifactInventory/types.js +10 -0
- package/dist/application/ArtifactInventory.js +9 -351
- package/dist/application/AuthorizedArtifactInventory.js +2 -2
- package/dist/application/BinarySession.js +47 -270
- package/dist/application/BinarySessionExecution.js +28 -0
- package/dist/application/BinarySessionOpen.js +39 -0
- package/dist/application/BinarySessionRecords.js +149 -0
- package/dist/application/BinarySessionStatus.js +75 -0
- package/dist/application/CapabilityInventory.js +42 -2
- package/dist/application/ClientRegistrationStatus.js +1 -1
- package/dist/application/CrossVersionInventory.js +8 -2
- package/dist/application/CrossVersionInvestigation.js +11 -29
- package/dist/application/CrossVersionInvestigationCollections.js +23 -0
- package/dist/application/DirectAnalysis.js +47 -44
- package/dist/application/Doctor.js +165 -197
- package/dist/application/DoctorDiagnostics.js +180 -0
- package/dist/application/ElectronBoundaryAnalysis.js +112 -0
- package/dist/application/ElectronBoundaryGraph.js +9 -0
- package/dist/application/ElectronBoundaryGraphContext.js +62 -0
- package/dist/application/ElectronBoundaryGraphIpc.js +242 -0
- package/dist/application/ElectronBoundaryGraphNative.js +86 -0
- package/dist/application/ElectronBoundaryGraphWindows.js +223 -0
- package/dist/application/EnhancedToolPagination.js +22 -0
- package/dist/application/EnhancedToolTypes.js +4 -0
- package/dist/application/EnhancedTools.js +58 -50
- package/dist/application/InstrumentedJavaScriptReplayHost.js +36 -0
- package/dist/application/InvestigationProviders.js +30 -0
- package/dist/application/InvestigationWorkspaceStore.js +24 -10
- package/dist/application/JavaScriptApplicationEvidence.js +26 -0
- package/dist/application/JavaScriptApplicationEvidenceGraph.js +89 -0
- package/dist/application/JavaScriptApplicationService.js +74 -0
- package/dist/application/JavaScriptApplicationWorkflowEvidence.js +29 -0
- package/dist/application/JavaScriptApplicationWorkflowService.js +90 -0
- package/dist/application/JavaScriptArtifactAnalysis.js +52 -7
- package/dist/application/JavaScriptArtifactFiles.js +6 -2
- package/dist/application/JavaScriptArtifactGraphBuilder.js +82 -17
- package/dist/application/JavaScriptArtifactGraphBundlers.js +225 -0
- package/dist/application/JavaScriptArtifactGraphContext.js +37 -36
- package/dist/application/JavaScriptArtifactGraphDocuments.js +27 -4
- package/dist/application/JavaScriptArtifactGraphEvidence.js +24 -14
- package/dist/application/JavaScriptArtifactGraphFindings.js +54 -8
- package/dist/application/JavaScriptArtifactGraphStructure.js +29 -101
- package/dist/application/JavaScriptArtifactPathResolution.js +269 -0
- package/dist/application/JavaScriptArtifactReconstruction.js +4 -1
- package/dist/application/JavaScriptArtifactReconstructionInput.js +2 -83
- package/dist/application/JavaScriptJsonModules.js +39 -0
- package/dist/application/JavaScriptModuleRelationships.js +262 -0
- package/dist/application/JavaScriptReplayPermission.js +16 -0
- package/dist/application/JavaScriptReplayPlanning.js +201 -0
- package/dist/application/JavaScriptReplayService.js +292 -0
- package/dist/application/JavaScriptRuntimeReconciliationEvidence.js +25 -0
- package/dist/application/JavaScriptRuntimeReconciliationService.js +27 -0
- package/dist/application/LinuxHopper.js +10 -0
- package/dist/application/MacHopper.js +22 -11
- package/dist/application/ManagedApplicationGraphService.js +55 -0
- package/dist/application/ManagedMemberComparisonService.js +122 -0
- package/dist/application/ManagedNativeVerificationService.js +39 -0
- package/dist/application/ManagedReconstructionService.js +58 -0
- package/dist/application/ManagedRuntimeCorrelationService.js +103 -0
- package/dist/application/NodeRuntimeCharacterizationService.js +196 -0
- package/dist/application/PermissionAuthority.js +106 -63
- package/dist/application/ProcessCaptureCapability.js +1 -1
- package/dist/application/ProcessCapturePermission.js +13 -0
- package/dist/application/ProcessCli.js +2 -12
- package/dist/application/ProcessHarness.js +1 -1
- package/dist/application/ProcessSampling.js +15 -11
- package/dist/application/ProjectPermissionStore.js +49 -9
- package/dist/application/RealHopperAssertions.js +76 -0
- package/dist/application/ReconstructionCoverageService.js +69 -0
- package/dist/application/ReconstructionCoverageWorkspaceStore.js +31 -0
- package/dist/application/RuntimeExecutableDiagnostics.js +172 -0
- package/dist/application/Setup.js +147 -259
- package/dist/application/SetupClientConfiguration.js +220 -0
- package/dist/application/SetupClients.js +24 -2
- package/dist/application/SetupPlan.js +123 -12
- package/dist/application/SetupSkill.js +26 -12
- package/dist/application/SupportedClients.js +1 -0
- package/dist/application/Uninstall.js +6 -3
- package/dist/application/WindowsCapabilities.js +86 -0
- package/dist/application/runtime.js +2 -0
- package/dist/artifacts/AsarArtifactReader.js +11 -0
- package/dist/browser/BrowserProcessStartup.js +88 -0
- package/dist/browser/CdpCaptureDocuments.js +12 -8
- package/dist/browser/CdpCaptureEventBodyShapes.js +75 -0
- package/dist/browser/CdpCaptureEventHandlers.js +336 -0
- package/dist/browser/CdpCaptureEventHelpers.js +71 -0
- package/dist/browser/CdpCaptureEventState.js +1 -0
- package/dist/browser/CdpCaptureEventTypes.js +1 -0
- package/dist/browser/CdpCaptureEvents.js +46 -464
- package/dist/browser/CdpElectronInspection.js +106 -162
- package/dist/browser/CdpElectronProvider.js +5 -1
- package/dist/browser/CdpElectronScriptEvents.js +69 -0
- package/dist/browser/CdpElectronScripts.js +94 -0
- package/dist/browser/CdpElectronWorkers.js +56 -0
- package/dist/browser/CdpObservationSession.js +51 -8
- package/dist/browser/CdpPageCapture.js +12 -129
- package/dist/browser/CdpPageCaptureScripts.js +97 -0
- package/dist/browser/CdpPageCaptureWorkers.js +46 -0
- package/dist/browser/CdpWebMcpDiscovery.js +38 -14
- package/dist/browser/PngVisualDiff.js +9 -2
- package/dist/catalogIdentity.js +8 -1
- package/dist/cli/artifactCommands.js +82 -0
- package/dist/cli/coreAnalysisCommands.js +232 -0
- package/dist/cli/managedCommands.js +397 -0
- package/dist/cli/managedProjectGraphCommand.js +24 -0
- package/dist/cli/options.js +9 -0
- package/dist/cli/setupCommands.js +108 -0
- package/dist/cli/types.js +1 -0
- package/dist/cli/utilityCommands.js +122 -0
- package/dist/cli.js +13 -383
- package/dist/cliApplicationCommands.js +176 -0
- package/dist/cliBrowserAdvancedCommands.js +73 -16
- package/dist/cliBrowserCommands.js +39 -115
- package/dist/cliCommandNames.js +17 -0
- package/dist/cliElectronCommands.js +100 -27
- package/dist/cliEvidenceCommands.js +13 -2
- package/dist/cliInvestigationCommands.js +53 -10
- package/dist/cliJsonInput.js +54 -0
- package/dist/cliObservationOptions.js +137 -0
- package/dist/cliPolicyCommands.js +80 -46
- package/dist/cliSetup.js +289 -0
- package/dist/config/environment.js +107 -0
- package/dist/config/parseConfig.js +228 -0
- package/dist/config/parsers.js +68 -0
- package/dist/config/permissions.js +30 -0
- package/dist/config/types.js +1 -0
- package/dist/config.js +1 -292
- package/dist/contracts/applicationToolContracts.js +225 -0
- package/dist/contracts/artifactToolContracts.js +5 -9
- package/dist/contracts/browserToolContracts.js +14 -62
- package/dist/contracts/electronToolContracts.js +45 -19
- package/dist/contracts/errorSchemas.js +1 -0
- package/dist/contracts/investigationExamples.js +0 -6
- package/dist/contracts/javascriptApplicationWorkflowExamples.js +46 -0
- package/dist/contracts/javascriptRuntimeReconciliationExample.js +208 -0
- package/dist/contracts/managedToolContracts.js +153 -0
- package/dist/contracts/managedWorkflowExamples.js +346 -0
- package/dist/contracts/managedWorkflowToolContracts.js +203 -0
- package/dist/contracts/nativeToolContracts.js +2 -6
- package/dist/contracts/promptContracts.js +18 -2
- package/dist/contracts/providerSelection.js +2 -0
- package/dist/contracts/toolContractExamples.js +10 -25
- package/dist/contracts/toolContracts.js +49 -47
- package/dist/contracts/toolEffects.js +174 -0
- package/dist/contracts/toolOutputSchemaGroups.js +232 -0
- package/dist/contracts/toolOutputSchemaPrimitives.js +327 -0
- package/dist/contracts/toolOutputSchemas.js +2 -535
- package/dist/doctorRuntime.js +42 -1
- package/dist/domain/analysisErrorPresentation.js +234 -0
- package/dist/domain/analysisErrorProjection.js +284 -0
- package/dist/domain/artifactComparison.js +37 -19
- package/dist/domain/binaryTarget.js +87 -37
- package/dist/domain/browserObservation.js +1 -282
- package/dist/domain/browserObservationSchemas.js +286 -0
- package/dist/domain/bundleComparison.js +4 -4
- package/dist/domain/electronObservation.js +13 -0
- package/dist/domain/electronStaticAnalysis.js +9 -0
- package/dist/domain/electronStaticAnalysisBrowser.js +206 -0
- package/dist/domain/electronStaticAnalysisIpc.js +171 -0
- package/dist/domain/electronStaticAnalysisNative.js +164 -0
- package/dist/domain/electronStaticAnalysisTypes.js +1 -0
- package/dist/domain/electronStaticAnalysisValues.js +103 -0
- package/dist/domain/errors.js +32 -448
- package/dist/domain/functionComparison.js +4 -165
- package/dist/domain/functionComparisonDimensions.js +164 -0
- package/dist/domain/functionComparisonSchemas.js +3 -8
- package/dist/domain/inputIssueProjection.js +52 -0
- package/dist/domain/javascriptApplicationAnalysis.js +155 -0
- package/dist/domain/javascriptApplicationChangeGraph.js +231 -0
- package/dist/domain/javascriptApplicationEvidenceSchemas.js +18 -0
- package/dist/domain/javascriptApplicationGraph.js +2 -1
- package/dist/domain/javascriptApplicationGraphSchemas.js +7 -0
- package/dist/domain/javascriptApplicationVersionComparison.js +116 -0
- package/dist/domain/javascriptApplicationVersionComparisonSchemas.js +139 -0
- package/dist/domain/javascriptApplicationVersionItems.js +233 -0
- package/dist/domain/javascriptApplicationVersionKeys.js +170 -0
- package/dist/domain/javascriptExportInstrumentation.js +97 -0
- package/dist/domain/javascriptFeatureSeed.js +140 -0
- package/dist/domain/javascriptFeatureTrace.js +232 -0
- package/dist/domain/javascriptFeatureTraceSchemas.js +136 -0
- package/dist/domain/javascriptFeatureTraversal.js +100 -0
- package/dist/domain/javascriptNativeHandoff.js +85 -0
- package/dist/domain/javascriptReplay.js +361 -0
- package/dist/domain/javascriptRuntimeLoadState.js +106 -0
- package/dist/domain/javascriptRuntimeReconciliation.js +42 -0
- package/dist/domain/javascriptRuntimeReconciliationGraph.js +169 -0
- package/dist/domain/javascriptRuntimeReconciliationMatching.js +247 -0
- package/dist/domain/javascriptRuntimeReconciliationParsing.js +160 -0
- package/dist/domain/javascriptRuntimeReconciliationResult.js +119 -0
- package/dist/domain/javascriptRuntimeReconciliationRuntime.js +316 -0
- package/dist/domain/javascriptRuntimeReconciliationSchemas.js +245 -0
- package/dist/domain/javascriptRuntimeStaticCandidates.js +193 -0
- package/dist/domain/javascriptSemanticAnalysis.js +386 -0
- package/dist/domain/javascriptSemanticIr.js +30 -0
- package/dist/domain/javascriptSemanticProjection.js +366 -0
- package/dist/domain/javascriptSemanticState.js +40 -0
- package/dist/domain/javascriptSemanticTraversal.js +22 -0
- package/dist/domain/javascriptSemanticValues.js +352 -0
- package/dist/domain/javascriptStaticAnalysis.js +26 -254
- package/dist/domain/javascriptStaticAnalysisBundler.js +209 -0
- package/dist/domain/javascriptStaticAnalysisCalls.js +180 -0
- package/dist/domain/javascriptStaticAnalysisFindings.js +39 -0
- package/dist/domain/javascriptStaticAnalysisHelpers.js +81 -2
- package/dist/domain/javascriptStaticAnalysisState.js +6 -0
- package/dist/domain/knownPageCoverage.js +21 -0
- package/dist/domain/managedApplicationGraph.js +206 -0
- package/dist/domain/managedApplicationGraphCoverage.js +170 -0
- package/dist/domain/managedApplicationGraphNodeCoverage.js +6 -0
- package/dist/domain/managedApplicationGraphNodes.js +336 -0
- package/dist/domain/managedArtifact.js +452 -0
- package/dist/domain/managedMemberComparison.js +211 -0
- package/dist/domain/managedMemberComparisonCoverage.js +72 -0
- package/dist/domain/managedMemberComparisonMatch.js +356 -0
- package/dist/domain/managedNativeVerification.js +46 -0
- package/dist/domain/managedNativeVerificationMatch.js +272 -0
- package/dist/domain/managedNativeVerificationSchemas.js +141 -0
- package/dist/domain/managedReconstruction.js +196 -0
- package/dist/domain/managedRuntimeCorrelation.js +184 -0
- package/dist/domain/nodeRuntimeCharacterization.js +66 -0
- package/dist/domain/permissionPolicy.js +2 -0
- package/dist/domain/reconstructionCoverage.js +387 -0
- package/dist/domain/reconstructionCoverageEvaluation.js +212 -0
- package/dist/domain/reconstructionVerificationSchemas.js +9 -3
- package/dist/domain/runtimeCharacterization.js +85 -0
- package/dist/domain/webBundleAnalyzer.js +3 -409
- package/dist/domain/webBundleAnalyzerAst.js +77 -0
- package/dist/domain/webBundleAnalyzerInspection.js +307 -0
- package/dist/domain/webBundleAnalyzerResult.js +120 -0
- package/dist/dotnet/ManagedArtifactInspector.js +339 -0
- package/dist/dotnet/ManagedMemberInspector.js +153 -0
- package/dist/dotnet/ManagedMemberInspectorCore.js +297 -0
- package/dist/dotnet/ManagedMemberInstructionDecoder.js +427 -0
- package/dist/dotnet/ManagedMemberRows.js +120 -0
- package/dist/dotnet/ManagedMetadataHeaps.js +131 -0
- package/dist/dotnet/ManagedMetadataInventory.js +104 -0
- package/dist/dotnet/ManagedMetadataInventoryRows.js +292 -0
- package/dist/dotnet/ManagedMetadataLayout.js +259 -0
- package/dist/dotnet/ManagedMetadataRowSizes.js +54 -0
- package/dist/dotnet/ManagedMethodBodyReader.js +143 -0
- package/dist/dotnet/ManagedNativeBoundaryHelpers.js +311 -0
- package/dist/dotnet/ManagedNativeBoundaryInspector.js +143 -0
- package/dist/dotnet/ManagedPeReader.js +188 -0
- package/dist/dotnet/ManagedReaderFailure.js +10 -0
- package/dist/dotnet/ManagedStaticProvider.js +203 -0
- package/dist/generatedPackageMetadata.js +2 -2
- package/dist/ghidra/GhidraClient.js +76 -91
- package/dist/ghidra/GhidraClientStartup.js +29 -0
- package/dist/ghidra/GhidraClientWire.js +34 -0
- package/dist/ghidra/GhidraDefaults.js +1 -1
- package/dist/ghidra/GhidraDiagnostics.js +6 -1
- package/dist/ghidra/GhidraInstallation.js +20 -15
- package/dist/ghidra/GhidraLauncher.js +93 -29
- package/dist/ghidra/GhidraProvider.js +67 -161
- package/dist/ghidra/GhidraProviderCapabilities.js +173 -0
- package/dist/ghidra/GhidraSessionValues.js +2 -0
- package/dist/ghidra/GhidraSocketConnection.js +44 -7
- package/dist/ghidra/GhidraTargetSnapshot.js +30 -0
- package/dist/ghidra/GhidraTransport.js +71 -0
- package/dist/identity.js +3 -2
- package/dist/main/messages.js +5 -0
- package/dist/main/reload.js +49 -0
- package/dist/main/shutdown.js +25 -0
- package/dist/main/startup.js +14 -0
- package/dist/main/state.js +26 -0
- package/dist/main/transport.js +61 -0
- package/dist/main/types.js +1 -0
- package/dist/main.js +35 -132
- package/dist/process/PrivateRuntimeRoot.js +3 -2
- package/dist/process/ProcessOwnership.js +35 -0
- package/dist/process/ProviderProcess.js +2 -0
- package/dist/replay/JavaScriptReplayWorker.js +300 -0
- package/dist/replay/LinuxJavaScriptReplayRunner.js +217 -0
- package/dist/replay/LinuxJavaScriptReplaySandbox.js +140 -0
- package/dist/replay/LinuxRuntimeClosure.js +46 -0
- package/dist/replay/LinuxSeccompPolicy.js +40 -0
- package/dist/replay/ReplayOutcome.js +95 -0
- package/dist/replay/ReplayProcessLifecycle.js +71 -0
- package/dist/replay/ReplayWorkerProtocol.js +55 -0
- package/dist/replay/SystemJavaScriptReplayHost.js +182 -0
- package/dist/server/ProcessCaptureElicitation.js +157 -0
- package/dist/server/createServer.js +158 -41
- package/dist/server/registerApplicationTools/characterization.js +57 -0
- package/dist/server/registerApplicationTools/compareVersions.js +34 -0
- package/dist/server/registerApplicationTools/controlledReplay.js +38 -0
- package/dist/server/registerApplicationTools/coverage.js +84 -0
- package/dist/server/registerApplicationTools/helpers.js +42 -0
- package/dist/server/registerApplicationTools/traceFeature.js +26 -0
- package/dist/server/registerApplicationTools/types.js +1 -0
- package/dist/server/registerApplicationTools.js +13 -0
- package/dist/server/registerArtifactComparisonTool.js +16 -9
- package/dist/server/registerBrowserTools.js +61 -60
- package/dist/server/registerBundleComparisonTool.js +17 -20
- package/dist/server/registerElectronTools.js +39 -12
- package/dist/server/registerEnhancedTools.js +52 -15
- package/dist/server/registerEvidenceResources.js +54 -0
- package/dist/server/registerEvidenceTools.js +5 -1
- package/dist/server/registerFunctionComparisonTool.js +14 -7
- package/dist/server/registerInvestigationTools/helpers.js +74 -0
- package/dist/server/registerInvestigationTools/types.js +1 -0
- package/dist/server/registerInvestigationTools.js +103 -132
- package/dist/server/registerManagedTools.js +6 -0
- package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +65 -0
- package/dist/server/registerManagedWorkflowTools/contract.js +8 -0
- package/dist/server/registerManagedWorkflowTools/evidence.js +43 -0
- package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +39 -0
- package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +39 -0
- package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +52 -0
- package/dist/server/registerManagedWorkflowTools/types.js +1 -0
- package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +75 -0
- package/dist/server/registerManagedWorkflowTools.js +13 -0
- package/dist/server/registerOfficialTools.js +81 -67
- package/dist/server/registerProcessComparisonTool.js +25 -47
- package/dist/server/registerSessionRecordTools.js +137 -0
- package/dist/server/registerSessionStatusTool.js +9 -8
- package/dist/server/registerSessionTools.js +77 -216
- package/dist/server/sessionAvailabilityPolicy.js +10 -0
- package/dist/server/sessionEvidence.js +14 -19
- package/dist/server/toolInputValidation.js +77 -0
- package/dist/server/toolRegistrationOptions.js +177 -2
- package/dist/server/toolResult.js +30 -17
- package/package.json +21 -14
- package/scripts/rea.mjs +1 -1
- package/skills/{rea-analysis → reverse-engineer-anything}/SKILL.md +75 -6
- package/scripts/prepare-node-pty.mjs +0 -35
- package/scripts/rebuild-native.mjs +0 -22
|
@@ -1,28 +1,74 @@
|
|
|
1
1
|
import { Cli, z } from "incur";
|
|
2
2
|
import { inspectElectronPage, listElectronTargets, } from "./application/ElectronObservationService.js";
|
|
3
|
+
import { analyzeJavaScriptApplication } from "./application/JavaScriptApplicationService.js";
|
|
4
|
+
import { reconcileJavaScriptRuntimeEvidence } from "./application/JavaScriptRuntimeReconciliationService.js";
|
|
3
5
|
import { loadConfiguredPermissionAuthority } from "./application/PermissionConfiguration.js";
|
|
4
6
|
import { CdpElectronProvider } from "./browser/CdpElectronProvider.js";
|
|
5
7
|
import { logCliCommand } from "./cliLogging.js";
|
|
6
8
|
import { parseConfig } from "./config.js";
|
|
7
9
|
import { inspectElectronPageInputSchema, listElectronTargetsInputSchema, } from "./domain/electronObservation.js";
|
|
10
|
+
import { analyzeJavaScriptApplicationInputSchema } from "./domain/javascriptApplicationAnalysis.js";
|
|
8
11
|
import { AnalysisInputError, projectAnalysisError } from "./domain/errors.js";
|
|
9
12
|
import { CLI_COMMANDS } from "./cliCommandNames.js";
|
|
13
|
+
import { parseCliJsonInput } from "./cliJsonInput.js";
|
|
14
|
+
import { electronPageInspectionOptions, javascriptApplicationOptions, } from "./cliObservationOptions.js";
|
|
10
15
|
const scopeOptions = {
|
|
11
16
|
allowedFileRoots: z
|
|
12
17
|
.array(z.string().min(1))
|
|
13
18
|
.optional()
|
|
14
19
|
.describe("Filesystem roots; defaults to REA_ELECTRON_FILE_ROOTS_JSON"),
|
|
15
|
-
approved: z.boolean().default(false),
|
|
20
|
+
approved: z.boolean().default(false).describe("Approve passive observation"),
|
|
16
21
|
};
|
|
17
22
|
/** Register CLI equivalents of the Electron MCP tools. */
|
|
18
23
|
export const registerElectronCommands = (cli, logger) => {
|
|
24
|
+
registerElectronObservationCommands(cli, logger);
|
|
25
|
+
registerJavaScriptApplicationCommand(cli, logger);
|
|
26
|
+
registerJavaScriptRuntimeReconciliationCommand(cli, logger);
|
|
27
|
+
};
|
|
28
|
+
const registerJavaScriptRuntimeReconciliationCommand = (cli, logger) => {
|
|
29
|
+
cli.command(CLI_COMMANDS.reconcileJavaScriptRuntime, {
|
|
30
|
+
description: "Reconcile static application and passive runtime Evidence JSON",
|
|
31
|
+
args: z.object({
|
|
32
|
+
inputJson: z
|
|
33
|
+
.string()
|
|
34
|
+
.describe("Inline JSON or a JSON file path matching reconcile_javascript_runtime"),
|
|
35
|
+
}),
|
|
36
|
+
run: ({ args }) => logCliCommand(logger, CLI_COMMANDS.reconcileJavaScriptRuntime, async () => {
|
|
37
|
+
const input = await parseCliJsonInput(args.inputJson, "reconcile_javascript_runtime");
|
|
38
|
+
if (!input.ok)
|
|
39
|
+
return input.error;
|
|
40
|
+
const result = reconcileJavaScriptRuntimeEvidence(input.value);
|
|
41
|
+
return result.ok ? result.value : cliError(result.error);
|
|
42
|
+
}),
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
const registerElectronObservationCommands = (cli, logger) => {
|
|
46
|
+
registerElectronTargetList(cli, logger);
|
|
47
|
+
registerElectronPageInspection(cli, logger);
|
|
48
|
+
};
|
|
49
|
+
const registerElectronTargetList = (cli, logger) => {
|
|
19
50
|
cli.command(CLI_COMMANDS.listElectronTargets, {
|
|
20
51
|
description: "List root-confined file pages from Electron CDP",
|
|
21
|
-
args: z.object({
|
|
52
|
+
args: z.object({
|
|
53
|
+
endpoint: z
|
|
54
|
+
.string()
|
|
55
|
+
.describe("Configured loopback Electron CDP endpoint"),
|
|
56
|
+
}),
|
|
22
57
|
options: z.object({
|
|
23
58
|
...scopeOptions,
|
|
24
|
-
offset: z
|
|
25
|
-
|
|
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"),
|
|
26
72
|
}),
|
|
27
73
|
run: ({ args, options }) => logCliCommand(logger, "list-electron-targets", async () => {
|
|
28
74
|
const context = await electronContext();
|
|
@@ -41,31 +87,17 @@ export const registerElectronCommands = (cli, logger) => {
|
|
|
41
87
|
return result.ok ? result.value : cliError(result.error);
|
|
42
88
|
}),
|
|
43
89
|
});
|
|
90
|
+
};
|
|
91
|
+
const registerElectronPageInspection = (cli, logger) => {
|
|
44
92
|
cli.command(CLI_COMMANDS.inspectElectronPage, {
|
|
45
93
|
description: "Passively inspect one root-confined Electron file page",
|
|
46
|
-
args: z.object({
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
sourceCaptureApproved: z.boolean().default(false),
|
|
52
|
-
maxFrames: z.number().int().min(1).max(1_000).default(200),
|
|
53
|
-
maxDomNodes: z.number().int().min(1).max(10_000).default(2_000),
|
|
54
|
-
maxScripts: z.number().int().min(1).max(2_000).default(500),
|
|
55
|
-
maxResources: z.number().int().min(1).max(10_000).default(2_000),
|
|
56
|
-
maxScriptSourceBytes: z
|
|
57
|
-
.number()
|
|
58
|
-
.int()
|
|
59
|
-
.min(1)
|
|
60
|
-
.max(4 * 1_024 * 1_024)
|
|
61
|
-
.default(1_024 * 1_024),
|
|
62
|
-
maxTotalScriptSourceBytes: z
|
|
63
|
-
.number()
|
|
64
|
-
.int()
|
|
65
|
-
.min(1)
|
|
66
|
-
.max(16 * 1_024 * 1_024)
|
|
67
|
-
.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"),
|
|
68
99
|
}),
|
|
100
|
+
options: electronPageInspectionOptions,
|
|
69
101
|
run: ({ args, options }) => logCliCommand(logger, "inspect-electron-page", async () => {
|
|
70
102
|
const context = await electronContext();
|
|
71
103
|
if (!context.ok)
|
|
@@ -83,6 +115,7 @@ export const registerElectronCommands = (cli, logger) => {
|
|
|
83
115
|
max_dom_nodes: options.maxDomNodes,
|
|
84
116
|
max_scripts: options.maxScripts,
|
|
85
117
|
max_resources: options.maxResources,
|
|
118
|
+
max_workers: options.maxWorkers,
|
|
86
119
|
max_script_source_bytes: options.maxScriptSourceBytes,
|
|
87
120
|
max_total_script_source_bytes: options.maxTotalScriptSourceBytes,
|
|
88
121
|
},
|
|
@@ -94,6 +127,46 @@ export const registerElectronCommands = (cli, logger) => {
|
|
|
94
127
|
}),
|
|
95
128
|
});
|
|
96
129
|
};
|
|
130
|
+
const registerJavaScriptApplicationCommand = (cli, logger) => {
|
|
131
|
+
cli.command(CLI_COMMANDS.analyzeJavaScriptApplication, {
|
|
132
|
+
description: "Statically reconstruct an approved JavaScript/Electron application",
|
|
133
|
+
args: z.object({
|
|
134
|
+
path: z.string().describe("Absolute ASAR or extracted application path"),
|
|
135
|
+
}),
|
|
136
|
+
options: javascriptApplicationOptions,
|
|
137
|
+
run: ({ args, options }) => logCliCommand(logger, CLI_COMMANDS.analyzeJavaScriptApplication, async () => {
|
|
138
|
+
const context = await electronContext();
|
|
139
|
+
if (!context.ok)
|
|
140
|
+
return context.error;
|
|
141
|
+
const parsed = analyzeJavaScriptApplicationInputSchema.safeParse({
|
|
142
|
+
input_path: args.path,
|
|
143
|
+
approved: options.approved,
|
|
144
|
+
format: options.format,
|
|
145
|
+
source_map_read_approved: options.sourceMapReadApproved,
|
|
146
|
+
limits: {
|
|
147
|
+
max_entries: options.maxEntries,
|
|
148
|
+
max_total_artifact_bytes: options.maxTotalArtifactBytes,
|
|
149
|
+
max_artifact_entry_bytes: options.maxArtifactEntryBytes,
|
|
150
|
+
max_compression_ratio: options.maxCompressionRatio,
|
|
151
|
+
max_depth: options.maxDepth,
|
|
152
|
+
max_path_bytes: options.maxPathBytes,
|
|
153
|
+
max_text_files: options.maxTextFiles,
|
|
154
|
+
max_total_text_bytes: options.maxTotalTextBytes,
|
|
155
|
+
max_text_file_bytes: options.maxTextFileBytes,
|
|
156
|
+
max_ast_nodes: options.maxAstNodes,
|
|
157
|
+
max_findings: options.maxFindings,
|
|
158
|
+
max_modules: options.maxModules,
|
|
159
|
+
max_source_map_sources: options.maxSourceMapSources,
|
|
160
|
+
max_parse_milliseconds: options.maxParseMilliseconds,
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
if (!parsed.success)
|
|
164
|
+
return inputError("analyze_javascript_application");
|
|
165
|
+
const result = await analyzeJavaScriptApplication(context.authority, parsed.data);
|
|
166
|
+
return result.ok ? result.value : cliError(result.error);
|
|
167
|
+
}),
|
|
168
|
+
});
|
|
169
|
+
};
|
|
97
170
|
const electronContext = async () => {
|
|
98
171
|
const config = parseConfig(process.env);
|
|
99
172
|
if (!config.ok)
|
|
@@ -110,6 +183,6 @@ const electronContext = async () => {
|
|
|
110
183
|
};
|
|
111
184
|
const inputError = (operation) => cliError(new AnalysisInputError(operation));
|
|
112
185
|
const cliError = (error) => ({
|
|
113
|
-
error: "Electron
|
|
186
|
+
error: "Electron analysis failed",
|
|
114
187
|
...projectAnalysisError(error),
|
|
115
188
|
});
|
|
@@ -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
|
|
60
|
-
|
|
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);
|
|
@@ -11,31 +11,74 @@ const investigationOptionsSchema = z.object({
|
|
|
11
11
|
.boolean()
|
|
12
12
|
.default(false)
|
|
13
13
|
.describe("Approve persistent workspace writes"),
|
|
14
|
-
workspaceName: z
|
|
15
|
-
|
|
14
|
+
workspaceName: z
|
|
15
|
+
.string()
|
|
16
|
+
.trim()
|
|
17
|
+
.min(1)
|
|
18
|
+
.max(200)
|
|
19
|
+
.default("default")
|
|
20
|
+
.describe("Logical name recorded in the investigation workspace"),
|
|
21
|
+
expectedRevision: z
|
|
22
|
+
.number()
|
|
23
|
+
.int()
|
|
24
|
+
.min(1)
|
|
25
|
+
.optional()
|
|
26
|
+
.describe("Required current workspace revision for an atomic update"),
|
|
16
27
|
replayRunId: z
|
|
17
28
|
.string()
|
|
18
29
|
.regex(/^run_[a-f0-9]{64}$/u)
|
|
19
30
|
.optional()
|
|
20
31
|
.describe("Replay one verified complete workspace run without rescanning"),
|
|
21
|
-
maxEntries: z
|
|
32
|
+
maxEntries: z
|
|
33
|
+
.number()
|
|
34
|
+
.int()
|
|
35
|
+
.min(1)
|
|
36
|
+
.max(50_000)
|
|
37
|
+
.default(10_000)
|
|
38
|
+
.describe("Maximum artifact entries to inspect per version"),
|
|
22
39
|
maxTotalBytes: z
|
|
23
40
|
.number()
|
|
24
41
|
.int()
|
|
25
42
|
.min(1)
|
|
26
43
|
.max(Number.MAX_SAFE_INTEGER)
|
|
27
|
-
.default(1_073_741_824)
|
|
44
|
+
.default(1_073_741_824)
|
|
45
|
+
.describe("Maximum total uncompressed artifact content to inspect"),
|
|
28
46
|
maxEntryBytes: z
|
|
29
47
|
.number()
|
|
30
48
|
.int()
|
|
31
49
|
.min(1)
|
|
32
50
|
.max(Number.MAX_SAFE_INTEGER)
|
|
33
|
-
.default(268_435_456)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
51
|
+
.default(268_435_456)
|
|
52
|
+
.describe("Maximum uncompressed content to inspect for one entry"),
|
|
53
|
+
pageSize: z
|
|
54
|
+
.number()
|
|
55
|
+
.int()
|
|
56
|
+
.min(1)
|
|
57
|
+
.max(500)
|
|
58
|
+
.default(500)
|
|
59
|
+
.describe("Maximum graph items loaded per investigation page"),
|
|
60
|
+
changeLimit: z
|
|
61
|
+
.number()
|
|
62
|
+
.int()
|
|
63
|
+
.min(1)
|
|
64
|
+
.max(500)
|
|
65
|
+
.default(500)
|
|
66
|
+
.describe("Maximum version changes to record"),
|
|
67
|
+
integrityPolicy: z
|
|
68
|
+
.enum(["fail", "record-and-continue"])
|
|
69
|
+
.default("fail")
|
|
70
|
+
.describe("Behavior when declared artifact integrity does not match"),
|
|
71
|
+
integrityContinueApproved: z
|
|
72
|
+
.boolean()
|
|
73
|
+
.default(false)
|
|
74
|
+
.describe("Approve continuing after recorded integrity mismatches"),
|
|
75
|
+
maxIntegrityMismatches: z
|
|
76
|
+
.number()
|
|
77
|
+
.int()
|
|
78
|
+
.min(1)
|
|
79
|
+
.max(100)
|
|
80
|
+
.default(10)
|
|
81
|
+
.describe("Maximum integrity mismatches to record before stopping"),
|
|
39
82
|
});
|
|
40
83
|
/** Register the persistent cross-version CLI workflow. */
|
|
41
84
|
export const registerInvestigationCommands = (cli, logger) => {
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { readFile, stat } from "node:fs/promises";
|
|
2
|
+
import { AnalysisInputError, projectAnalysisError } from "./domain/errors.js";
|
|
3
|
+
const MAX_JSON_INPUT_BYTES = 64 * 1_024 * 1_024;
|
|
4
|
+
/** Parse bounded inline JSON or one bounded local JSON file for a CLI workflow. */
|
|
5
|
+
export const parseCliJsonInput = async (value, operation) => {
|
|
6
|
+
const inline = parseJson(value);
|
|
7
|
+
if (inline !== undefined)
|
|
8
|
+
return { ok: true, value: inline };
|
|
9
|
+
if (["{", "["].includes(value.trimStart()[0] ?? ""))
|
|
10
|
+
return { ok: false, error: inputError(operation) };
|
|
11
|
+
try {
|
|
12
|
+
const metadata = await stat(value);
|
|
13
|
+
if (!metadata.isFile())
|
|
14
|
+
return jsonFileError(value, operation, "not-file");
|
|
15
|
+
if (metadata.size > MAX_JSON_INPUT_BYTES)
|
|
16
|
+
return jsonFileError(value, operation, "too-large");
|
|
17
|
+
const bytes = await readFile(value);
|
|
18
|
+
if (bytes.byteLength > MAX_JSON_INPUT_BYTES)
|
|
19
|
+
return jsonFileError(value, operation, "too-large");
|
|
20
|
+
const parsed = parseJson(bytes.toString("utf8"));
|
|
21
|
+
return parsed === undefined
|
|
22
|
+
? jsonFileError(value, operation, "invalid-json")
|
|
23
|
+
: { ok: true, value: parsed };
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return jsonFileError(value, operation, "read-failed");
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
const parseJson = (value) => {
|
|
30
|
+
try {
|
|
31
|
+
return JSON.parse(value);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
const inputError = (operation) => ({
|
|
38
|
+
error: "Application workflow failed",
|
|
39
|
+
...projectAnalysisError(new AnalysisInputError(operation, undefined, [
|
|
40
|
+
{ path: [], reason: "invalid_format", expected: "JSON" },
|
|
41
|
+
])),
|
|
42
|
+
});
|
|
43
|
+
const jsonFileError = (path, operation, reason) => ({
|
|
44
|
+
ok: false,
|
|
45
|
+
error: {
|
|
46
|
+
error: "Application workflow failed",
|
|
47
|
+
...projectAnalysisError(new AnalysisInputError(operation, undefined, reason === "invalid-json"
|
|
48
|
+
? [{ path: [], reason: "invalid_format", expected: "JSON" }]
|
|
49
|
+
: [])),
|
|
50
|
+
input_path: path,
|
|
51
|
+
input_reason: reason,
|
|
52
|
+
maximum_input_bytes: MAX_JSON_INPUT_BYTES,
|
|
53
|
+
},
|
|
54
|
+
});
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { z } from "incur";
|
|
2
|
+
const boundedCount = (subject, maximum, fallback, minimum = 1) => z
|
|
3
|
+
.number()
|
|
4
|
+
.int()
|
|
5
|
+
.min(minimum)
|
|
6
|
+
.max(maximum)
|
|
7
|
+
.default(fallback)
|
|
8
|
+
.describe(`Maximum ${subject}`);
|
|
9
|
+
const boundedBytes = (subject, maximum, fallback) => boundedCount(`${subject} in bytes`, maximum, fallback);
|
|
10
|
+
const positiveCount = (subject, fallback) => z.number().int().min(1).default(fallback).describe(`Maximum ${subject}`);
|
|
11
|
+
const browserScopeOptions = {
|
|
12
|
+
allowedOrigins: z
|
|
13
|
+
.array(z.string().min(1))
|
|
14
|
+
.optional()
|
|
15
|
+
.describe("Exact origins to observe; defaults to REA_BROWSER_ALLOWED_ORIGINS_JSON"),
|
|
16
|
+
approved: z.boolean().default(false).describe("Approve passive observation"),
|
|
17
|
+
};
|
|
18
|
+
export const browserPageInspectionOptions = z.object({
|
|
19
|
+
...browserScopeOptions,
|
|
20
|
+
observationMs: boundedCount("observation duration in milliseconds", 10_000, 500, 0),
|
|
21
|
+
includeAccessibilityText: z
|
|
22
|
+
.boolean()
|
|
23
|
+
.default(false)
|
|
24
|
+
.describe("Include bounded accessibility text"),
|
|
25
|
+
includeConsoleText: z
|
|
26
|
+
.boolean()
|
|
27
|
+
.default(false)
|
|
28
|
+
.describe("Include bounded console message text"),
|
|
29
|
+
consoleTextApproved: z
|
|
30
|
+
.boolean()
|
|
31
|
+
.default(false)
|
|
32
|
+
.describe("Approve capturing console message text"),
|
|
33
|
+
includeJsonBodyShapes: z
|
|
34
|
+
.boolean()
|
|
35
|
+
.default(false)
|
|
36
|
+
.describe("Include structural shapes of JSON response bodies"),
|
|
37
|
+
jsonBodySchemaApproved: z
|
|
38
|
+
.boolean()
|
|
39
|
+
.default(false)
|
|
40
|
+
.describe("Approve inspecting JSON response bodies for structural shapes"),
|
|
41
|
+
includeWebsocketShapes: z
|
|
42
|
+
.boolean()
|
|
43
|
+
.default(false)
|
|
44
|
+
.describe("Include structural shapes of WebSocket payloads"),
|
|
45
|
+
websocketShapeApproved: z
|
|
46
|
+
.boolean()
|
|
47
|
+
.default(false)
|
|
48
|
+
.describe("Approve inspecting WebSocket payloads for structural shapes"),
|
|
49
|
+
includeScriptSources: z
|
|
50
|
+
.boolean()
|
|
51
|
+
.default(false)
|
|
52
|
+
.describe("Include bounded JavaScript source text"),
|
|
53
|
+
includeStorageKeys: z
|
|
54
|
+
.boolean()
|
|
55
|
+
.default(false)
|
|
56
|
+
.describe("Include storage key names without values"),
|
|
57
|
+
maxFrames: boundedCount("page frames", 1_000, 200),
|
|
58
|
+
maxDomNodes: boundedCount("DOM nodes", 10_000, 2_000),
|
|
59
|
+
maxAxNodes: boundedCount("accessibility nodes", 10_000, 2_000),
|
|
60
|
+
maxAxTextFieldBytes: boundedBytes("one accessibility text field", 16 * 1_024, 1_024),
|
|
61
|
+
maxTotalAxTextBytes: boundedBytes("total accessibility text", 1_024 * 1_024, 64 * 1_024),
|
|
62
|
+
maxScripts: boundedCount("scripts", 1_000, 200),
|
|
63
|
+
maxResources: boundedCount("resources", 10_000, 2_000),
|
|
64
|
+
maxWorkers: boundedCount("workers", 5_000, 500),
|
|
65
|
+
maxStorageKeys: boundedCount("storage keys", 10_000, 1_000),
|
|
66
|
+
maxScriptSourceBytes: boundedBytes("one script source", 4 * 1_024 * 1_024, 1_024 * 1_024),
|
|
67
|
+
maxTotalScriptSourceBytes: boundedBytes("total script source", 16 * 1_024 * 1_024, 4 * 1_024 * 1_024),
|
|
68
|
+
maxNetworkEvents: boundedCount("network events", 10_000, 1_000),
|
|
69
|
+
maxConsoleEvents: boundedCount("console events", 2_000, 200),
|
|
70
|
+
maxConsoleTextFieldBytes: boundedBytes("one console text field", 16 * 1_024, 1_024),
|
|
71
|
+
maxTotalConsoleTextBytes: boundedBytes("total console text", 1_024 * 1_024, 64 * 1_024),
|
|
72
|
+
maxJsonBodyBytes: boundedBytes("one JSON response body", 4 * 1_024 * 1_024, 1_024 * 1_024),
|
|
73
|
+
maxTotalJsonBodyBytes: boundedBytes("total JSON response bodies", 16 * 1_024 * 1_024, 4 * 1_024 * 1_024),
|
|
74
|
+
maxJsonShapeNodes: boundedCount("JSON shape nodes", 100_000, 5_000),
|
|
75
|
+
maxJsonShapeDepth: boundedCount("JSON shape depth", 100, 20),
|
|
76
|
+
maxWebsocketEvents: boundedCount("WebSocket events", 5_000, 500),
|
|
77
|
+
maxWebsocketShapeBytes: boundedBytes("one WebSocket shape", 1_024 * 1_024, 64 * 1_024),
|
|
78
|
+
maxTotalWebsocketShapeBytes: boundedBytes("total WebSocket shapes", 16 * 1_024 * 1_024, 1_024 * 1_024),
|
|
79
|
+
});
|
|
80
|
+
const electronScopeOptions = {
|
|
81
|
+
allowedFileRoots: z
|
|
82
|
+
.array(z.string().min(1))
|
|
83
|
+
.optional()
|
|
84
|
+
.describe("Filesystem roots; defaults to REA_ELECTRON_FILE_ROOTS_JSON"),
|
|
85
|
+
approved: z.boolean().default(false).describe("Approve passive observation"),
|
|
86
|
+
};
|
|
87
|
+
export const electronPageInspectionOptions = z.object({
|
|
88
|
+
...electronScopeOptions,
|
|
89
|
+
observationMs: boundedCount("observation duration in milliseconds", 10_000, 100, 0),
|
|
90
|
+
includeScriptSources: z
|
|
91
|
+
.boolean()
|
|
92
|
+
.default(false)
|
|
93
|
+
.describe("Include bounded JavaScript source text"),
|
|
94
|
+
sourceCaptureApproved: z
|
|
95
|
+
.boolean()
|
|
96
|
+
.default(false)
|
|
97
|
+
.describe("Approve capturing bounded script source text"),
|
|
98
|
+
maxFrames: boundedCount("page frames", 1_000, 200),
|
|
99
|
+
maxDomNodes: boundedCount("DOM nodes", 10_000, 2_000),
|
|
100
|
+
maxScripts: boundedCount("scripts", 2_000, 500),
|
|
101
|
+
maxResources: boundedCount("resources", 10_000, 2_000),
|
|
102
|
+
maxWorkers: boundedCount("workers", 5_000, 500),
|
|
103
|
+
maxScriptSourceBytes: boundedBytes("one captured script source", 4 * 1_024 * 1_024, 1_024 * 1_024),
|
|
104
|
+
maxTotalScriptSourceBytes: boundedBytes("total captured script source", 16 * 1_024 * 1_024, 4 * 1_024 * 1_024),
|
|
105
|
+
});
|
|
106
|
+
export const javascriptApplicationOptions = z.object({
|
|
107
|
+
approved: z
|
|
108
|
+
.boolean()
|
|
109
|
+
.default(false)
|
|
110
|
+
.describe("Approve reading the application artifact"),
|
|
111
|
+
format: z
|
|
112
|
+
.enum(["auto", "asar", "directory"])
|
|
113
|
+
.default("auto")
|
|
114
|
+
.describe("Application artifact format"),
|
|
115
|
+
sourceMapReadApproved: z
|
|
116
|
+
.boolean()
|
|
117
|
+
.default(false)
|
|
118
|
+
.describe("Approve reading local source maps referenced by the application"),
|
|
119
|
+
maxEntries: positiveCount("artifact entries to inspect", 8_000),
|
|
120
|
+
maxTotalArtifactBytes: positiveCount("total uncompressed artifact content to inspect", 512 * 1_024 * 1_024),
|
|
121
|
+
maxArtifactEntryBytes: positiveCount("uncompressed content for one artifact entry", 128 * 1_024 * 1_024),
|
|
122
|
+
maxCompressionRatio: z
|
|
123
|
+
.number()
|
|
124
|
+
.min(1)
|
|
125
|
+
.default(1_000)
|
|
126
|
+
.describe("Maximum accepted compressed-to-uncompressed expansion ratio"),
|
|
127
|
+
maxDepth: positiveCount("artifact directory depth", 64),
|
|
128
|
+
maxPathBytes: positiveCount("encoded artifact path length", 4_096),
|
|
129
|
+
maxTextFiles: positiveCount("text files to parse", 5_000),
|
|
130
|
+
maxTotalTextBytes: positiveCount("total text content to parse", 128 * 1_024 * 1_024),
|
|
131
|
+
maxTextFileBytes: positiveCount("size of one parsed text file", 8 * 1_024 * 1_024),
|
|
132
|
+
maxAstNodes: positiveCount("JavaScript AST nodes to parse", 2_000_000),
|
|
133
|
+
maxFindings: positiveCount("static-analysis findings to return", 8_000),
|
|
134
|
+
maxModules: positiveCount("application modules to project", 20_000),
|
|
135
|
+
maxSourceMapSources: positiveCount("original sources from source maps", 5_000),
|
|
136
|
+
maxParseMilliseconds: positiveCount("JavaScript parsing time in milliseconds", 30_000),
|
|
137
|
+
});
|
|
@@ -36,17 +36,40 @@ export const registerPolicyCommands = (cli, logger) => {
|
|
|
36
36
|
cli.command(CLI_COMMANDS.policy, {
|
|
37
37
|
description: "Inspect, explain, or revoke unified local permission grants",
|
|
38
38
|
args: z.object({
|
|
39
|
-
action: z
|
|
40
|
-
|
|
39
|
+
action: z
|
|
40
|
+
.enum(["status", "list", "explain", "revoke"])
|
|
41
|
+
.describe("Permission-policy operation to perform"),
|
|
42
|
+
value: z
|
|
43
|
+
.string()
|
|
44
|
+
.optional()
|
|
45
|
+
.describe("Capability to explain or grant ID to revoke"),
|
|
41
46
|
}),
|
|
42
47
|
options: z.object({
|
|
43
|
-
root: z.string().optional(),
|
|
44
|
-
executable: z
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
root: z.string().optional().describe("Filesystem root to authorize"),
|
|
49
|
+
executable: z
|
|
50
|
+
.string()
|
|
51
|
+
.optional()
|
|
52
|
+
.describe("Executable path to authorize"),
|
|
53
|
+
environmentNames: z
|
|
54
|
+
.array(z.string())
|
|
55
|
+
.default([])
|
|
56
|
+
.describe("Environment variable names the operation may read"),
|
|
57
|
+
origins: z
|
|
58
|
+
.array(z.string())
|
|
59
|
+
.default([])
|
|
60
|
+
.describe("Exact browser origins the operation may access"),
|
|
61
|
+
network: z
|
|
62
|
+
.enum(["none", "loopback", "external"])
|
|
63
|
+
.default("none")
|
|
64
|
+
.describe("Maximum network scope to authorize"),
|
|
65
|
+
mount: z
|
|
66
|
+
.boolean()
|
|
67
|
+
.default(false)
|
|
68
|
+
.describe("Authorize mounting an artifact filesystem"),
|
|
69
|
+
write: z
|
|
70
|
+
.boolean()
|
|
71
|
+
.default(false)
|
|
72
|
+
.describe("Explain the write form of the requested capability"),
|
|
50
73
|
yes: z
|
|
51
74
|
.boolean()
|
|
52
75
|
.default(false)
|
|
@@ -58,56 +81,67 @@ export const registerPolicyCommands = (cli, logger) => {
|
|
|
58
81
|
if (!config.ok)
|
|
59
82
|
return failure(config.error);
|
|
60
83
|
if (args.action === "status")
|
|
61
|
-
return
|
|
62
|
-
reload: "SIGHUP",
|
|
63
|
-
restart_required: false,
|
|
64
|
-
administrator_ceilings: config.value.permissionCeilings,
|
|
65
|
-
project_store: config.value.permissionProjectStore ?? null,
|
|
66
|
-
};
|
|
84
|
+
return policyStatus(config.value);
|
|
67
85
|
if (args.action === "list")
|
|
68
|
-
return
|
|
69
|
-
if (args.action === "revoke")
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
if (permissionProjectRoot === undefined ||
|
|
74
|
-
permissionProjectStore === undefined)
|
|
75
|
-
return { error: "Project policy is not configured" };
|
|
76
|
-
const approval = await approvePolicyRevocation({
|
|
86
|
+
return policyList(config.value);
|
|
87
|
+
if (args.action === "revoke")
|
|
88
|
+
return policyRevoke({
|
|
89
|
+
config: config.value,
|
|
90
|
+
grantId: args.value,
|
|
77
91
|
approved: options.yes,
|
|
78
92
|
interactive: !agent && !formatExplicit && process.stdin.isTTY === true,
|
|
79
|
-
grantId: args.value,
|
|
80
93
|
confirm: confirmPolicyRevocation,
|
|
81
94
|
});
|
|
82
|
-
if (!approval.approved)
|
|
83
|
-
return approval.reason === "required"
|
|
84
|
-
? {
|
|
85
|
-
error: "Policy revoke requires confirmation. Rerun interactively or with --yes.",
|
|
86
|
-
grant_id: args.value,
|
|
87
|
-
}
|
|
88
|
-
: {
|
|
89
|
-
error: "Policy revocation was cancelled",
|
|
90
|
-
grant_id: args.value,
|
|
91
|
-
};
|
|
92
|
-
const revoked = await revokeProjectPermissionGrant(permissionProjectStore, permissionProjectRoot, args.value);
|
|
93
|
-
return revoked.ok && revoked.value
|
|
94
|
-
? {
|
|
95
|
-
revoked: args.value,
|
|
96
|
-
reload: "Send SIGHUP to the REA MCP process",
|
|
97
|
-
}
|
|
98
|
-
: revoked.ok
|
|
99
|
-
? { error: "Grant was not found", grant_id: args.value }
|
|
100
|
-
: { error: revoked.error.message };
|
|
101
|
-
}
|
|
102
95
|
const capability = capabilitySchema.safeParse(args.value);
|
|
103
96
|
if (!capability.success)
|
|
104
97
|
return {
|
|
105
98
|
error: "A registered capability is required for policy explain",
|
|
106
99
|
};
|
|
107
|
-
return
|
|
100
|
+
return policyExplain(config.value, capability.data, options);
|
|
108
101
|
}),
|
|
109
102
|
});
|
|
110
103
|
};
|
|
104
|
+
const policyStatus = (config) => ({
|
|
105
|
+
reload: "SIGHUP",
|
|
106
|
+
restart_required: false,
|
|
107
|
+
administrator_ceilings: config.permissionCeilings,
|
|
108
|
+
project_store: config.permissionProjectStore ?? null,
|
|
109
|
+
});
|
|
110
|
+
const policyList = (config) => readProjectGrants(config).then((result) => result.ok ? { grants: result.grants } : result.error);
|
|
111
|
+
const policyRevoke = async (context) => {
|
|
112
|
+
if (context.grantId === undefined)
|
|
113
|
+
return { error: "Grant ID is required for policy revoke" };
|
|
114
|
+
const { permissionProjectRoot, permissionProjectStore } = context.config;
|
|
115
|
+
if (permissionProjectRoot === undefined ||
|
|
116
|
+
permissionProjectStore === undefined)
|
|
117
|
+
return { error: "Project policy is not configured" };
|
|
118
|
+
const approval = await approvePolicyRevocation({
|
|
119
|
+
approved: context.approved,
|
|
120
|
+
interactive: context.interactive,
|
|
121
|
+
grantId: context.grantId,
|
|
122
|
+
confirm: context.confirm,
|
|
123
|
+
});
|
|
124
|
+
if (!approval.approved)
|
|
125
|
+
return approval.reason === "required"
|
|
126
|
+
? {
|
|
127
|
+
error: "Policy revoke requires confirmation. Rerun interactively or with --yes.",
|
|
128
|
+
grant_id: context.grantId,
|
|
129
|
+
}
|
|
130
|
+
: {
|
|
131
|
+
error: "Policy revocation was cancelled",
|
|
132
|
+
grant_id: context.grantId,
|
|
133
|
+
};
|
|
134
|
+
const revoked = await revokeProjectPermissionGrant(permissionProjectStore, permissionProjectRoot, context.grantId);
|
|
135
|
+
return revoked.ok && revoked.value
|
|
136
|
+
? {
|
|
137
|
+
revoked: context.grantId,
|
|
138
|
+
reload: "Send SIGHUP to the REA MCP process",
|
|
139
|
+
}
|
|
140
|
+
: revoked.ok
|
|
141
|
+
? { error: "Grant was not found", grant_id: context.grantId }
|
|
142
|
+
: { error: revoked.error.message };
|
|
143
|
+
};
|
|
144
|
+
const policyExplain = async (config, capability, options) => explain(config, capability, options);
|
|
111
145
|
const confirmPolicyRevocation = async (grantId) => {
|
|
112
146
|
const prompt = createInterface({
|
|
113
147
|
input: process.stdin,
|