rea-agents 3.1.0 → 3.2.1
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 +72 -95
- package/bridge/ghidra/ReaGhidraBridge.java +609 -841
- package/bridge/hopper_bridge.py +99 -344
- package/dist/application/AbortablePromise.js +6 -3
- package/dist/application/AnalysisSnapshotCache.js +0 -1
- package/dist/application/AnalysisSnapshotFiles.js +7 -7
- package/dist/application/AndroidApplicationService.js +1 -1
- package/dist/application/AppleApplicationService.js +1 -1
- package/dist/application/ArtifactExtraction.js +35 -54
- package/dist/application/ArtifactExtractionDestination.js +17 -0
- package/dist/application/ArtifactGraphConstruction.js +2 -17
- package/dist/application/ArtifactInventory/classify.js +2 -6
- package/dist/application/ArtifactInventory/hash.js +2 -20
- package/dist/application/ArtifactInventory/scanCanonical.js +8 -12
- package/dist/application/ArtifactInventory/scanReader.js +69 -51
- package/dist/application/ArtifactInventory.js +6 -14
- package/dist/application/AuthorizedArtifactInventory.js +3 -13
- package/dist/application/BinarySession.js +41 -13
- package/dist/application/BinarySessionComposition.js +0 -11
- package/dist/application/BinarySessionOpen.js +2 -1
- package/dist/application/BinarySessionRecords.js +5 -93
- package/dist/application/BinarySessionStatus.js +5 -16
- package/dist/application/BinaryTargetResolver.js +216 -0
- package/dist/application/BrowserEvidence.js +42 -58
- package/dist/application/BrowserObservationService.js +3 -6
- package/dist/application/BrowserScenarioCaptureService.js +3 -6
- package/dist/application/BrowserScenarioEvidence.js +3 -3
- package/dist/application/CallPathTracing.js +2 -36
- package/dist/application/CapabilityInventory.js +10 -15
- package/dist/application/ClientConfigurationDocument.js +27 -0
- package/dist/application/ClientRegistrationStatus.js +16 -13
- package/dist/application/CommandShimReplay.js +14 -1
- package/dist/application/DirectAnalysis.js +22 -46
- package/dist/application/DirectAnalysisStatus.js +5 -61
- package/dist/application/Doctor.js +11 -32
- package/dist/application/DoctorDiagnostics.js +1 -2
- package/dist/application/DoctorScope.js +1 -1
- package/dist/application/ElectronActiveEvidence.js +3 -8
- package/dist/application/ElectronActiveObservationService.js +3 -6
- package/dist/application/ElectronBoundaryAnalysis.js +7 -8
- package/dist/application/ElectronBoundaryGraphContext.js +1 -1
- package/dist/application/ElectronBoundaryGraphIpc.js +3 -3
- package/dist/application/ElectronBoundaryGraphNative.js +1 -2
- package/dist/application/ElectronBoundaryGraphWindows.js +6 -8
- package/dist/application/ElectronEvidence.js +4 -7
- package/dist/application/ElectronObservationService.js +5 -9
- package/dist/application/EnhancedLiteralTracing.js +42 -65
- package/dist/application/EnhancedTools.js +76 -44
- package/dist/application/EvidenceBundleCommands.js +11 -11
- package/dist/application/EvidenceBundleFiles.js +9 -15
- package/dist/application/EvidenceLedger.js +6 -41
- package/dist/application/FilesystemSnapshot.js +2 -3
- package/dist/application/InterfaceBuilderAnalysis.js +266 -0
- package/dist/application/InventoryProjectionEvidence.js +4 -2
- package/dist/application/InvestigationProviders.js +1 -1
- package/dist/application/JavaScriptApplicationEvidence.js +2 -5
- package/dist/application/JavaScriptApplicationEvidenceGraph.js +6 -10
- package/dist/application/JavaScriptApplicationService.js +6 -29
- package/dist/application/JavaScriptApplicationWorkflowEvidence.js +5 -5
- package/dist/application/JavaScriptApplicationWorkflowService.js +0 -8
- package/dist/application/JavaScriptArtifactAnalysis.js +38 -127
- package/dist/application/JavaScriptArtifactFiles.js +67 -107
- package/dist/application/JavaScriptArtifactGraphAccumulator.js +0 -7
- package/dist/application/JavaScriptArtifactGraphBuilder.js +7 -58
- package/dist/application/JavaScriptArtifactGraphBundlers.js +1 -6
- package/dist/application/JavaScriptArtifactGraphContext.js +12 -39
- package/dist/application/JavaScriptArtifactGraphDocuments.js +4 -11
- package/dist/application/JavaScriptArtifactGraphEvidence.js +0 -14
- package/dist/application/JavaScriptArtifactGraphFindings.js +3 -3
- package/dist/application/JavaScriptArtifactGraphStructure.js +16 -17
- package/dist/application/JavaScriptArtifactPathResolution.js +61 -49
- package/dist/application/JavaScriptArtifactReconstruction.js +5 -10
- package/dist/application/JavaScriptArtifactReconstructionInput.js +2 -14
- package/dist/application/JavaScriptJsonModules.js +2 -2
- package/dist/application/JavaScriptModuleRelationships.js +22 -27
- package/dist/application/JavaScriptReplayPlanning.js +9 -3
- package/dist/application/JavaScriptReplayService.js +6 -32
- package/dist/application/JavaScriptReturnShapeProjection.js +12 -42
- package/dist/application/JavaScriptRuntimeObservationEvidence.js +7 -8
- package/dist/application/JavaScriptRuntimeObservationService.js +4 -8
- package/dist/application/JavaScriptRuntimeReconciliationEvidence.js +2 -3
- package/dist/application/JavaScriptSemanticGraphBuilder.js +11 -41
- package/dist/application/JavaScriptSemanticGraphConstruction.js +5 -29
- package/dist/application/JavaScriptSemanticGraphEvidence.js +1 -1
- package/dist/application/JavaScriptSemanticGraphFingerprintProjection.js +1 -1
- package/dist/application/JavaScriptSemanticGraphFlowProjection.js +0 -13
- package/dist/application/JavaScriptSemanticGraphProjection.js +1 -3
- package/dist/application/JavaScriptSemanticTraceService.js +1 -10
- package/dist/application/JsonFiles.js +79 -0
- package/dist/application/LinuxHopper.js +11 -9
- package/dist/application/LoopbackReplay.js +26 -23
- package/dist/application/LoopbackReplayRecorder.js +29 -1
- package/dist/application/ManagedApplicationGraphService.js +1 -2
- package/dist/application/ManagedMemberComparisonService.js +11 -41
- package/dist/application/ManagedNativeVerificationService.js +1 -2
- package/dist/application/ManagedReconstructionService.js +1 -1
- package/dist/application/ManagedRuntimeCorrelationService.js +5 -8
- package/dist/application/NativeApiInspection.js +2 -7
- package/dist/application/NativeUiActionTrace.js +394 -0
- package/dist/application/NodeRuntimeCharacterizationService.js +3 -7
- package/dist/application/PermissionAuthority.js +15 -7
- package/dist/application/PermissionFailure.js +5 -0
- package/dist/application/ProcessCaptureAuthority.js +5 -7
- package/dist/application/ProcessCaptureJournal.js +3 -2
- package/dist/application/ProcessCaptureLifecycle.js +5 -12
- package/dist/application/ProcessCheckpoints.js +29 -11
- package/dist/application/ProcessCli.js +6 -16
- package/dist/application/ProcessEvidence.js +5 -7
- package/dist/application/ProcessHarness.js +52 -17
- package/dist/application/ProcessReactiveCoordinator.js +2 -4
- package/dist/application/ProcessReactiveEffects.js +9 -3
- package/dist/application/ProcessReactiveHarness.js +13 -7
- package/dist/application/ProcessSampling.js +2 -4
- package/dist/application/ProcessTimer.js +39 -0
- package/dist/application/ProjectPermissionStore.js +39 -96
- package/dist/application/RealHopperAssertions.js +20 -66
- package/dist/application/ReconstructionCoverageService.js +12 -58
- package/dist/application/ReconstructionObligationAuthority.js +2 -2
- package/dist/application/ReconstructionObligationCandidates.js +4 -4
- package/dist/application/ReconstructionObligationLedgerEvaluation.js +8 -15
- package/dist/application/ReconstructionObligationLedgerProjection.js +3 -7
- package/dist/application/ReconstructionObligationLedgerService.js +19 -38
- package/dist/application/ReferenceSourceImport.js +19 -45
- package/dist/application/ReferenceSourceImportEntries.js +2 -4
- package/dist/application/ReferenceSourceImportPolicy.js +5 -32
- package/dist/application/ReferenceSourceImportTypes.js +0 -16
- package/dist/application/RuntimeExecutableDiagnostics.js +55 -29
- package/dist/application/SessionProviderRouter.js +2 -2
- package/dist/application/Setup.js +1 -3
- package/dist/application/SetupClientConfiguration.js +22 -93
- package/dist/application/SetupRegistrationEnvironment.js +0 -7
- package/dist/application/StoreFileLock.js +119 -0
- package/dist/application/TerminalRenderer.js +2 -3
- package/dist/application/Uninstall.js +9 -14
- package/dist/application/UnknownEvidence.js +1 -1
- package/dist/artifacts/ArtifactPaths.js +2 -5
- package/dist/artifacts/ArtifactProvider.js +36 -58
- package/dist/artifacts/DirectoryArtifactReader.js +13 -8
- package/dist/artifacts/MachOSliceArtifactReader.js +1 -5
- package/dist/artifacts/NativeDmgArtifactReader.js +11 -11
- package/dist/artifacts/NibArchive.js +269 -0
- package/dist/artifacts/SafeOutputTree.js +15 -24
- package/dist/browser/BrowserProcessStartup.js +1 -2
- package/dist/browser/CdpAuthorizedMainFrame.js +16 -0
- package/dist/browser/CdpBrowserProvider.js +3 -13
- package/dist/browser/CdpCanonicalJsonDigest.js +9 -0
- package/dist/browser/CdpCaptureDocuments.js +28 -76
- package/dist/browser/CdpCaptureEventBodyShapes.js +13 -33
- package/dist/browser/CdpCaptureEventHandlers.js +22 -87
- package/dist/browser/CdpCaptureEvents.js +2 -8
- package/dist/browser/CdpCaptureStorage.js +9 -20
- package/dist/browser/CdpCaptureStorageFingerprints.js +85 -98
- package/dist/browser/CdpCaptureValues.js +21 -21
- package/dist/browser/CdpConnection.js +10 -25
- package/dist/browser/CdpElectronInspection.js +26 -50
- package/dist/browser/CdpElectronProvider.js +10 -35
- package/dist/browser/CdpElectronScriptEvents.js +8 -16
- package/dist/browser/CdpElectronScripts.js +6 -35
- package/dist/browser/CdpElectronWorkers.js +6 -10
- package/dist/browser/CdpEndpoint.js +25 -41
- package/dist/browser/CdpObservationSession.js +14 -26
- package/dist/browser/CdpPageCapture.js +34 -48
- package/dist/browser/CdpPageCaptureScripts.js +1 -19
- package/dist/browser/CdpPageCaptureWorkers.js +6 -10
- package/dist/browser/CdpSafeMetadata.js +19 -22
- package/dist/browser/CdpScreenshot.js +3 -5
- package/dist/browser/CdpTargetSession.js +1 -2
- package/dist/browser/CdpWebMcpDiscovery.js +13 -22
- package/dist/browser/ElectronFileScope.js +8 -19
- package/dist/browser/JavaScriptRuntimeScope.js +9 -14
- package/dist/browser/PlaywrightBrowserScenarioProvider.js +31 -64
- package/dist/browser/PlaywrightElectronActiveActions.js +54 -69
- package/dist/browser/PlaywrightElectronActiveProvider.js +14 -34
- package/dist/browser/PlaywrightExecutionBoundary.js +16 -5
- package/dist/browser/PlaywrightScenarioActions.js +3 -7
- package/dist/browser/PlaywrightScenarioArtifacts.js +23 -92
- package/dist/browser/PlaywrightScenarioBrowser.js +3 -5
- package/dist/browser/PlaywrightScenarioEvents.js +45 -94
- package/dist/browser/PlaywrightScenarioSession.js +14 -30
- package/dist/browser/PngVisualDiff.js +22 -14
- package/dist/browser/SensitiveTextCapture.js +0 -17
- package/dist/browser/V8InspectorCaptureProjection.js +7 -8
- package/dist/browser/V8InspectorEndpoint.js +12 -14
- package/dist/browser/V8InspectorProvider.js +20 -61
- package/dist/browser/WebSourceMapFetcher.js +56 -176
- package/dist/catalogIdentity.js +0 -54
- package/dist/cli/artifactCommands.js +49 -77
- package/dist/cli/coreAnalysisCommands.js +83 -133
- package/dist/cli/javascriptApplicationAnalysis.js +1 -9
- package/dist/cli/managedCommands.js +5 -270
- package/dist/cli/setupCommands.js +3 -12
- package/dist/cli/utilityCommands.js +7 -41
- package/dist/cli.js +0 -2
- package/dist/cliApplicationCommands.js +42 -112
- package/dist/cliBrowserAdvancedCommands.js +10 -106
- package/dist/cliBrowserCommands.js +15 -127
- package/dist/cliBrowserContext.js +30 -0
- package/dist/cliCommandNames.js +4 -5
- package/dist/cliElectronCommands.js +8 -72
- package/dist/cliEvidenceCommands.js +8 -77
- package/dist/cliJavaScriptRuntimeCommands.js +9 -91
- package/dist/cliJsonInput.js +4 -14
- package/dist/cliObservationOptions.js +11 -96
- package/dist/cliPolicyCommands.js +2 -17
- package/dist/cliProcessCommands.js +3 -3
- package/dist/cliSetup.js +0 -13
- package/dist/config/browserScenario.js +2 -2
- package/dist/config/environment.js +0 -9
- package/dist/config/parseConfig.js +1 -33
- package/dist/config/parsers.js +6 -27
- package/dist/config/passiveObservation.js +7 -77
- package/dist/config/permissions.js +0 -7
- package/dist/contracts/analysisSearchContract.js +2 -5
- package/dist/contracts/applicationToolContracts.js +56 -109
- package/dist/contracts/applicationWorkflowInputContracts.js +27 -102
- package/dist/contracts/artifactComparisonExample.js +58 -60
- package/dist/contracts/artifactToolContracts.js +20 -67
- package/dist/contracts/browserScenarioToolContracts.js +6 -51
- package/dist/contracts/browserToolContracts.js +8 -73
- package/dist/contracts/electronToolContracts.js +8 -108
- package/dist/contracts/enhancedInputs.js +23 -54
- package/dist/contracts/errorSchemas.js +0 -1
- package/dist/contracts/functionComparisonExample.js +10 -24
- package/dist/contracts/functionInstructionContract.js +1 -3
- package/dist/contracts/functionWorkflowToolContracts.js +2 -2
- package/dist/contracts/hopperMemoryContracts.js +3 -3
- package/dist/contracts/investigationExamples.js +14 -11
- package/dist/contracts/javascriptApplicationWorkflowExamples.js +12 -19
- package/dist/contracts/javascriptRuntimeObservationToolContracts.js +2 -20
- package/dist/contracts/javascriptRuntimeReconciliationExample.js +45 -12
- package/dist/contracts/managedToolContracts.js +6 -95
- package/dist/contracts/managedWorkflowExamples.js +77 -128
- package/dist/contracts/managedWorkflowToolContracts.js +51 -77
- package/dist/contracts/nativeToolContracts.js +7 -11
- package/dist/contracts/processCaptureExample.js +2 -69
- package/dist/contracts/promptContracts.js +49 -67
- package/dist/contracts/providerSelection.js +0 -1
- package/dist/contracts/reconstructionReadinessExample.js +1 -6
- package/dist/contracts/sessionStatusContract.js +1 -17
- package/dist/contracts/sessionToolSchemas.js +6 -15
- package/dist/contracts/toolContractExamples.js +11 -11
- package/dist/contracts/toolContractHelpers.js +0 -4
- package/dist/contracts/toolContracts.js +60 -71
- package/dist/contracts/toolEffects.js +5 -13
- package/dist/contracts/toolOutputSchemaGroups.js +37 -91
- package/dist/contracts/toolOutputSchemaPrimitives.js +16 -56
- package/dist/contracts/toolSchemaMetadata.js +8 -19
- package/dist/contracts/unknownContractExamples.js +0 -2
- package/dist/domain/analysisErrorPresentation.js +46 -54
- package/dist/domain/analysisErrorProjection.js +28 -37
- package/dist/domain/analysisProfile.js +3 -31
- package/dist/domain/analysisSnapshot.js +3 -12
- package/dist/domain/androidApplication.js +15 -54
- package/dist/domain/appleApplication.js +24 -67
- package/dist/domain/artifactComparison.js +11 -29
- package/dist/domain/artifactGraph.js +14 -44
- package/dist/domain/artifactInspection.js +38 -69
- package/dist/domain/artifactInventoryEvidence.js +27 -21
- package/dist/domain/binaryTarget.js +2 -221
- package/dist/domain/browserCaptureComparison.js +47 -24
- package/dist/domain/browserObservation.js +28 -193
- package/dist/domain/browserObservationSchemas.js +5 -23
- package/dist/domain/browserScenario.js +11 -14
- package/dist/domain/browserScenarioCapture.js +11 -12
- package/dist/domain/browserScenarioCaptureValues.js +146 -84
- package/dist/domain/browserScenarioDiff.js +2 -59
- package/dist/domain/browserScenarioDiffEvidence.js +51 -0
- package/dist/domain/browserScenarioDiffValues.js +21 -38
- package/dist/domain/browserScenarioValues.js +80 -109
- package/dist/domain/browserSession.js +4 -7
- package/dist/domain/bundleComparison.js +6 -32
- package/dist/domain/bytecodeProvider.js +20 -19
- package/dist/domain/callPath.js +47 -167
- package/dist/domain/callPathSchemas.js +79 -0
- package/dist/domain/changedBehavior.js +34 -60
- package/dist/domain/completionLedgerGeneration.js +8 -14
- package/dist/domain/conformancePackage.js +126 -97
- package/dist/domain/conformanceReplay.js +36 -8
- package/dist/domain/conformanceTrustGate.js +23 -14
- package/dist/domain/customProtocolCapture.js +1 -1
- package/dist/domain/electronActiveObservation.js +70 -103
- package/dist/domain/electronObservation.js +14 -80
- package/dist/domain/electronStaticAnalysisBrowser.js +36 -46
- package/dist/domain/electronStaticAnalysisIpc.js +38 -14
- package/dist/domain/electronStaticAnalysisNative.js +1 -8
- package/dist/domain/electronStaticAnalysisValues.js +10 -17
- package/dist/domain/errors.js +33 -54
- package/dist/domain/eventProcessTree.js +20 -12
- package/dist/domain/evidence.js +2 -10
- package/dist/domain/evidenceBundle.js +3 -5
- package/dist/domain/evidenceCompletionLedger.js +6 -8
- package/dist/domain/functionComparison.js +4 -14
- package/dist/domain/functionComparisonNormalization.js +4 -11
- package/dist/domain/functionComparisonResults.js +25 -15
- package/dist/domain/functionComparisonSchemas.js +49 -33
- package/dist/domain/functionDossierEvidence.js +31 -156
- package/dist/domain/hopperStartupFailure.js +1 -1
- package/dist/domain/hopperValues.js +15 -136
- package/dist/domain/interfaceBuilderGraph.js +654 -0
- package/dist/domain/javascriptApplicationAnalysis.js +8 -112
- package/dist/domain/javascriptApplicationChangeGraph.js +22 -82
- package/dist/domain/javascriptApplicationEvidenceSchemas.js +59 -47
- package/dist/domain/javascriptApplicationGraph.js +3 -13
- package/dist/domain/javascriptApplicationGraphSchemas.js +12 -34
- package/dist/domain/javascriptApplicationVersionComparison.js +26 -30
- package/dist/domain/javascriptApplicationVersionComparisonSchemas.js +123 -68
- package/dist/domain/javascriptApplicationVersionItems.js +120 -53
- package/dist/domain/javascriptApplicationVersionKeys.js +24 -11
- package/dist/domain/javascriptAstFingerprint.js +25 -58
- package/dist/domain/javascriptAstValues.js +9 -0
- package/dist/domain/javascriptExportInstrumentation.js +2 -4
- package/dist/domain/javascriptExportShapeComparison.js +6 -7
- package/dist/domain/javascriptExportShapeComparisonSchemas.js +68 -75
- package/dist/domain/javascriptExportShapeSelection.js +17 -19
- package/dist/domain/javascriptFeatureSeed.js +20 -12
- package/dist/domain/javascriptFeatureTrace.js +13 -67
- package/dist/domain/javascriptFeatureTraceSchemas.js +24 -52
- package/dist/domain/javascriptFeatureTraversal.js +1 -44
- package/dist/domain/javascriptNativeHandoff.js +1 -1
- package/dist/domain/javascriptReplay.js +24 -41
- package/dist/domain/javascriptRuntimeLoadState.js +3 -8
- package/dist/domain/javascriptRuntimeObservation.js +42 -103
- package/dist/domain/javascriptRuntimeReconciliation.js +1 -3
- package/dist/domain/javascriptRuntimeReconciliationActive.js +8 -17
- package/dist/domain/javascriptRuntimeReconciliationGraph.js +10 -23
- package/dist/domain/javascriptRuntimeReconciliationMatching.js +18 -12
- package/dist/domain/javascriptRuntimeReconciliationParsing.js +16 -45
- package/dist/domain/javascriptRuntimeReconciliationResult.js +4 -5
- package/dist/domain/javascriptRuntimeReconciliationRuntime.js +8 -12
- package/dist/domain/javascriptRuntimeReconciliationSchemas.js +33 -48
- package/dist/domain/javascriptRuntimeStaticCandidates.js +3 -3
- package/dist/domain/javascriptSemanticAnalysis.js +12 -45
- package/dist/domain/javascriptSemanticAsyncEffects.js +1 -9
- package/dist/domain/javascriptSemanticCallResolution.js +6 -16
- package/dist/domain/javascriptSemanticCalls.js +5 -32
- package/dist/domain/javascriptSemanticChildProcesses.js +1 -11
- package/dist/domain/javascriptSemanticCoverage.js +11 -0
- package/dist/domain/javascriptSemanticDataEffectHelpers.js +1 -8
- package/dist/domain/javascriptSemanticDataEffects.js +1 -11
- package/dist/domain/javascriptSemanticFingerprints.js +3 -5
- package/dist/domain/javascriptSemanticGraphSchemas.js +25 -51
- package/dist/domain/javascriptSemanticGraphSerialization.js +2 -13
- package/dist/domain/javascriptSemanticIr.js +1 -29
- package/dist/domain/javascriptSemanticObjects.js +1 -5
- package/dist/domain/javascriptSemanticPrimitives.js +2 -9
- package/dist/domain/javascriptSemanticProjection.js +0 -18
- package/dist/domain/javascriptSemanticPromises.js +9 -16
- package/dist/domain/javascriptSemanticProvenance.js +16 -19
- package/dist/domain/javascriptSemanticQuery.js +17 -139
- package/dist/domain/javascriptSemanticQueryAssessment.js +9 -37
- package/dist/domain/javascriptSemanticQueryIdentity.js +2 -23
- package/dist/domain/javascriptSemanticQuerySchemas.js +14 -107
- package/dist/domain/javascriptSemanticResources.js +1 -6
- package/dist/domain/javascriptSemanticReturns.js +10 -27
- package/dist/domain/javascriptSemanticValueTypes.js +1 -0
- package/dist/domain/javascriptSemanticValues.js +44 -62
- package/dist/domain/javascriptStaticAnalysis.js +21 -43
- package/dist/domain/javascriptStaticAnalysisBundler.js +34 -93
- package/dist/domain/javascriptStaticAnalysisCalls.js +17 -16
- package/dist/domain/javascriptStaticAnalysisFindings.js +3 -19
- package/dist/domain/javascriptStaticAnalysisHelpers.js +47 -88
- package/dist/domain/javascriptStaticAnalysisState.js +1 -5
- package/dist/domain/javascriptStaticAnalysisTypes.js +1 -0
- package/dist/domain/jsonShape.js +7 -33
- package/dist/domain/localPath.js +7 -0
- package/dist/domain/managedApplicationGraph.js +9 -41
- package/dist/domain/managedApplicationGraphCoverage.js +24 -156
- package/dist/domain/managedApplicationGraphNodes.js +10 -13
- package/dist/domain/managedArtifact.js +14 -27
- package/dist/domain/managedMemberComparison.js +90 -92
- package/dist/domain/managedMemberComparisonCoverage.js +11 -33
- package/dist/domain/managedMemberComparisonItems.js +221 -0
- package/dist/domain/managedMemberComparisonMatch.js +8 -208
- package/dist/domain/managedNativeVerification.js +3 -6
- package/dist/domain/managedNativeVerificationMatch.js +55 -59
- package/dist/domain/managedNativeVerificationSchemas.js +83 -47
- package/dist/domain/managedReconstruction.js +19 -23
- package/dist/domain/managedRuntimeCorrelation.js +6 -9
- package/dist/domain/nativeApiBoundary.js +2 -7
- package/dist/domain/nativeInspection.js +0 -2
- package/dist/domain/nativeInvestigationGraph.js +351 -0
- package/dist/domain/nativeValueFlow.js +61 -0
- package/dist/domain/nodeRuntimeCharacterization.js +1 -5
- package/dist/domain/objcSwiftMetadata.js +254 -0
- package/dist/domain/peInspection.js +1 -1
- package/dist/domain/permissionPolicy.js +13 -0
- package/dist/domain/processCapture.js +76 -113
- package/dist/domain/processCaptureExample.js +68 -0
- package/dist/domain/processCaptureParsing.js +21 -0
- package/dist/domain/processCaptureReactiveSchema.js +68 -0
- package/dist/domain/processCaptureValidation.js +1 -7
- package/dist/domain/processComparison.js +3 -12
- package/dist/domain/processReactiveMatching.js +29 -50
- package/dist/domain/processReactiveRuntime.js +4 -8
- package/dist/domain/processReactiveScenario.js +28 -94
- package/dist/domain/processReactiveScenarioPreflight.js +5 -30
- package/dist/domain/processReactiveTransition.js +33 -18
- package/dist/domain/processScenario.js +56 -90
- package/dist/domain/processTraceComparison.js +0 -8
- package/dist/domain/processTraceEvaluation.js +14 -4
- package/dist/domain/processTraceSpecification.js +11 -17
- package/dist/domain/protocolCapture.js +3 -3
- package/dist/domain/reconstructionCoverage.js +62 -129
- package/dist/domain/reconstructionCoverageEvaluation.js +17 -17
- package/dist/domain/reconstructionObligationLedgerSchemas.js +45 -72
- package/dist/domain/reconstructionReadiness.js +1 -2
- package/dist/domain/reconstructionReadinessSchemas.js +36 -38
- package/dist/domain/reconstructionUnknowns.js +3 -3
- package/dist/domain/reconstructionVerification.js +13 -47
- package/dist/domain/reconstructionVerificationSchemas.js +50 -38
- package/dist/domain/referenceSourceGraph.js +53 -61
- package/dist/domain/referenceSourceImportParsing.js +1 -5
- package/dist/domain/replayMachine.js +19 -31
- package/dist/domain/replayMachineRun.js +15 -63
- package/dist/domain/replayMachineRuntime.js +41 -41
- package/dist/domain/replayMachineValues.js +84 -0
- package/dist/domain/residualUnknown.js +25 -30
- package/dist/domain/runtimeCharacterization.js +15 -16
- package/dist/domain/runtimeIdentification.js +48 -47
- package/dist/domain/sourceToBundleComparison.js +9 -85
- package/dist/domain/sourceToBundleComparisonSchemas.js +17 -42
- package/dist/domain/sourceToBundleSignals.js +4 -15
- package/dist/domain/staticRuntimeCorrelation.js +37 -49
- package/dist/domain/symbolAnalysis.js +10 -19
- package/dist/domain/unicodeCodePointOrder.js +12 -0
- package/dist/domain/webBundleAnalysis.js +70 -99
- package/dist/domain/webBundleAnalyzer.js +2 -4
- package/dist/domain/webBundleAnalyzerAst.js +0 -13
- package/dist/domain/webBundleAnalyzerInspection.js +26 -52
- package/dist/domain/webBundleAnalyzerResult.js +7 -24
- package/dist/domain/webCaptureDiff.js +33 -73
- package/dist/domain/webCaptureDiffSchemas.js +86 -0
- package/dist/domain/webContentArtifact.js +1 -10
- package/dist/domain/webMcpDiscovery.js +3 -14
- package/dist/domain/webScreenshot.js +58 -34
- package/dist/domain/zipPackageFormat.js +7 -0
- package/dist/dotnet/ManagedArtifactInspector.js +17 -50
- package/dist/dotnet/ManagedMemberInspector.js +27 -58
- package/dist/dotnet/ManagedMemberInspectorCore.js +14 -51
- package/dist/dotnet/ManagedMemberInstructionDecoder.js +2 -2
- package/dist/dotnet/ManagedMemberRows.js +16 -16
- package/dist/dotnet/ManagedMetadataHeaps.js +26 -8
- package/dist/dotnet/ManagedMetadataInventory.js +21 -30
- package/dist/dotnet/ManagedMetadataInventoryRows.js +57 -63
- package/dist/dotnet/ManagedMetadataLayout.js +3 -5
- package/dist/dotnet/ManagedMethodBodyReader.js +5 -30
- package/dist/dotnet/ManagedNativeBoundaryHelpers.js +19 -49
- package/dist/dotnet/ManagedNativeBoundaryInspector.js +13 -41
- package/dist/dotnet/ManagedPeReader.js +2 -2
- package/dist/dotnet/ManagedStaticProvider.js +13 -71
- package/dist/generatedMcpToolCatalog.js +1 -1
- package/dist/generatedPackageMetadata.js +1 -1
- package/dist/ghidra/GhidraAnalysisProfile.js +3 -8
- package/dist/ghidra/GhidraClient.js +4 -12
- package/dist/ghidra/GhidraClientWire.js +9 -5
- package/dist/ghidra/GhidraDefaults.js +0 -18
- package/dist/ghidra/GhidraDiagnostics.js +0 -2
- package/dist/ghidra/GhidraDoctor.js +16 -12
- package/dist/ghidra/GhidraFunctionValues.js +65 -108
- package/dist/ghidra/GhidraInstallation.js +98 -42
- package/dist/ghidra/GhidraInventoryValues.js +16 -85
- package/dist/ghidra/GhidraLauncher.js +0 -8
- package/dist/ghidra/GhidraProvider.js +15 -22
- package/dist/ghidra/GhidraProviderCapabilities.js +6 -47
- package/dist/ghidra/GhidraRequestQueue.js +6 -30
- package/dist/ghidra/GhidraResponseBuffer.js +1 -7
- package/dist/ghidra/GhidraSessionValues.js +0 -2
- package/dist/ghidra/GhidraTransport.js +4 -7
- package/dist/ghidra/protocol.js +2 -2
- package/dist/hopper/BridgeLauncher.js +112 -36
- package/dist/hopper/HopperAnalysisProfile.js +1 -1
- package/dist/hopper/HopperCleanup.js +6 -3
- package/dist/hopper/HopperClient.js +4 -7
- package/dist/hopper/HopperProcessDiagnostic.js +2 -2
- package/dist/hopper/HopperProvider.js +0 -16
- package/dist/hopper/HopperRequestQueue.js +21 -40
- package/dist/hopper/HopperResponseStream.js +1 -9
- package/dist/hopper/HopperSessionValues.js +3 -2
- package/dist/hopper/HopperTargetLease.js +119 -0
- package/dist/hopper/LinuxPrivateDisplayDiagnostic.js +24 -31
- package/dist/hopper/LinuxPrivateDisplayProbe.js +5 -16
- package/dist/hopper/protocol.js +6 -4
- package/dist/main/reload.js +0 -3
- package/dist/main/shutdown.js +1 -1
- package/dist/main/state.js +0 -9
- package/dist/main/transport.js +0 -5
- package/dist/mcpDoctor.js +25 -45
- package/dist/native/CommandRunner.js +18 -25
- package/dist/native/NativeMacOSProvider.js +13 -38
- package/dist/native/NativeMachoInspection.js +1 -1
- package/dist/process/BoundedFileBytes.js +17 -0
- package/dist/process/ExecFileOutput.js +11 -0
- package/dist/process/PendingOperations.js +8 -6
- package/dist/process/ProcessOwnership.js +3 -2
- package/dist/process/ProcessOwnershipObservation.js +0 -1
- package/dist/process/ProviderProcess.js +7 -28
- package/dist/reference/ReferenceSourceReader.js +8 -24
- package/dist/reference/ReferenceSourceReaderEntries.js +11 -39
- package/dist/reference/ReferenceSourceReaderFile.js +13 -31
- package/dist/reference/ReferenceSourceReaderPaths.js +3 -18
- package/dist/reference/ReferenceSourceReaderValidate.js +3 -6
- package/dist/replay/JavaScriptReplayWorker.js +3 -5
- package/dist/replay/LinuxJavaScriptReplayRunner.js +33 -29
- package/dist/replay/LinuxJavaScriptReplaySandbox.js +0 -19
- package/dist/replay/LinuxRuntimeClosure.js +1 -3
- package/dist/replay/ReplayOutcome.js +1 -3
- package/dist/replay/ReplayProcessLifecycle.js +32 -7
- package/dist/replay/ReplaySeccompFile.js +29 -0
- package/dist/replay/ReplayWorkerProtocol.js +0 -2
- package/dist/replay/SystemJavaScriptReplayHost.js +45 -74
- package/dist/server/ProcessCaptureElicitation.js +4 -8
- package/dist/server/createServer.js +6 -44
- package/dist/server/promptCompletion.js +37 -61
- package/dist/server/recordDerivedEvidence.js +1 -1
- package/dist/server/registerApplicationTools/characterization.js +4 -8
- package/dist/server/registerApplicationTools/compareExportShapes.js +5 -10
- package/dist/server/registerApplicationTools/compareSourceToBundle.js +6 -10
- package/dist/server/registerApplicationTools/compareVersions.js +5 -10
- package/dist/server/registerApplicationTools/controlledReplay.js +3 -5
- package/dist/server/registerApplicationTools/coverage.js +6 -71
- package/dist/server/registerApplicationTools/helpers.js +1 -13
- package/dist/server/registerApplicationTools/obligationLedger.js +3 -2
- package/dist/server/registerApplicationTools/traceFeature.js +5 -9
- package/dist/server/registerApplicationTools/traceSemantics.js +5 -8
- package/dist/server/registerApplicationTools.js +0 -2
- package/dist/server/registerArtifactComparisonTool.js +23 -27
- package/dist/server/registerBrowserScenarioTool.js +4 -4
- package/dist/server/registerBrowserTools.js +5 -8
- package/dist/server/registerBundleComparisonTool.js +5 -7
- package/dist/server/registerCloseLifecycleTool.js +2 -16
- package/dist/server/registerElectronTools.js +10 -29
- package/dist/server/registerEnhancedTools.js +10 -11
- package/dist/server/registerEvidenceTools.js +15 -22
- package/dist/server/registerFunctionComparisonTool.js +30 -25
- package/dist/server/registerInvestigationTools/helpers.js +3 -32
- package/dist/server/registerInvestigationTools.js +20 -116
- package/dist/server/registerJavaScriptRuntimeObservationTools.js +6 -4
- package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +15 -17
- package/dist/server/registerManagedWorkflowTools/evidence.js +19 -35
- package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +3 -8
- package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +3 -8
- package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +10 -14
- package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +9 -15
- package/dist/server/registerOfficialTools.js +1 -43
- package/dist/server/registerProcessComparisonTool.js +33 -23
- package/dist/server/registerPrompts.js +19 -17
- package/dist/server/registerSessionRecordTools.js +10 -156
- package/dist/server/registerSessionStatusTool.js +6 -69
- package/dist/server/registerSessionTools.js +10 -51
- package/dist/server/sessionAvailabilityPolicy.js +0 -2
- package/dist/server/sessionEvidence.js +9 -15
- package/dist/server/sessionToolPolicies.js +0 -8
- package/dist/server/toolResult.js +14 -50
- package/dist/serverIdentity.js +0 -20
- package/install.sh +1 -1
- package/package.json +11 -7
- package/scripts/electron-active-hook.cjs +23 -55
- package/scripts/hopper-demo-x11.py +13 -32
- package/skills/reverse-engineer-anything/SKILL.md +47 -12
- package/skills/reverse-engineer-anything/references/evidence-workflows.md +6 -4
- package/skills/reverse-engineer-anything/references/javascript-applications.md +13 -13
- package/skills/reverse-engineer-anything/references/native-and-artifacts.md +12 -8
- package/dist/application/ApplicationWorkflowEvidenceResolver.js +0 -188
- package/dist/application/BoundedJsonFiles.js +0 -86
- package/dist/application/CrossVersionInventory.js +0 -129
- package/dist/application/CrossVersionInvestigation.js +0 -301
- package/dist/application/CrossVersionInvestigationCollections.js +0 -23
- package/dist/application/CrossVersionInvestigationEvidence.js +0 -64
- package/dist/application/CrossVersionInvestigationReplay.js +0 -170
- package/dist/application/DeferredFileAuthorization.js +0 -61
- package/dist/application/DoctorProjection.js +0 -43
- package/dist/application/EnhancedToolPagination.js +0 -22
- package/dist/application/EvidenceReferenceResolver.js +0 -26
- package/dist/application/InvestigationWorkspaceStore.js +0 -204
- package/dist/application/ProcessPairedExperiment.js +0 -72
- package/dist/application/ReconstructionCoverageWorkspaceStore.js +0 -31
- package/dist/application/ReconstructionReadinessService.js +0 -48
- package/dist/cliInvestigationCommands.js +0 -173
- package/dist/domain/boundedCartesianProjection.js +0 -15
- package/dist/domain/investigationWorkspace.js +0 -347
- package/dist/domain/jsonLimits.js +0 -26
- package/dist/domain/knownPageCoverage.js +0 -29
- package/dist/domain/processPairedExperiment.js +0 -128
- package/dist/server/javascriptApplicationResult.js +0 -106
- package/dist/server/permissionFailure.js +0 -12
- package/dist/server/registerApplicationTools/readiness.js +0 -50
- package/dist/server/registerEvidenceResources.js +0 -315
- package/dist/server/registerJavaScriptApplicationGraphResource.js +0 -65
- package/dist/server/registerReconstructionObligationLedgerResource.js +0 -32
- package/dist/server/registerReconstructionReadinessResource.js +0 -32
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { CdpCaptureCompleteness } from "./CdpCaptureCompleteness.js";
|
|
2
|
-
import {
|
|
2
|
+
import { recordValue, recordsValue, stringValue } from "./CdpCaptureValues.js";
|
|
3
3
|
import { optionalCdpCommand } from "./CdpOptionalCommand.js";
|
|
4
4
|
import { authorizedElectronFile } from "./ElectronFileScope.js";
|
|
5
|
-
/** Inventory
|
|
5
|
+
/** Inventory local worker targets without attaching to them. */
|
|
6
6
|
export const captureElectronWorkers = async (input) => {
|
|
7
7
|
const result = await optionalCdpCommand({
|
|
8
8
|
connection: input.connection,
|
|
@@ -25,15 +25,11 @@ export const captureElectronWorkers = async (input) => {
|
|
|
25
25
|
input.completeness.exclude("workers", "out_of_target_scope");
|
|
26
26
|
continue;
|
|
27
27
|
}
|
|
28
|
-
const path = await authorizedElectronFile(stringValue(target.url) ?? ""
|
|
28
|
+
const path = await authorizedElectronFile(stringValue(target.url) ?? "");
|
|
29
29
|
if (path === undefined) {
|
|
30
30
|
input.completeness.exclude("workers", "out_of_target_scope");
|
|
31
31
|
continue;
|
|
32
32
|
}
|
|
33
|
-
if (workers.length >= input.request.limits.max_workers) {
|
|
34
|
-
input.completeness.truncate("workers");
|
|
35
|
-
continue;
|
|
36
|
-
}
|
|
37
33
|
const targetId = boundedTargetField(target.targetId);
|
|
38
34
|
if (targetId === null) {
|
|
39
35
|
input.completeness.exclude("workers", "invalid_protocol_value");
|
|
@@ -41,7 +37,7 @@ export const captureElectronWorkers = async (input) => {
|
|
|
41
37
|
}
|
|
42
38
|
workers.push({
|
|
43
39
|
target_id: targetId,
|
|
44
|
-
type
|
|
40
|
+
type,
|
|
45
41
|
file_path: path,
|
|
46
42
|
attached: target.attached === true,
|
|
47
43
|
opener_target_id: openerTargetId,
|
|
@@ -51,6 +47,6 @@ export const captureElectronWorkers = async (input) => {
|
|
|
51
47
|
return workers.sort((left, right) => left.target_id.localeCompare(right.target_id));
|
|
52
48
|
};
|
|
53
49
|
const boundedTargetField = (value) => {
|
|
54
|
-
const field =
|
|
55
|
-
return field ===
|
|
50
|
+
const field = stringValue(value);
|
|
51
|
+
return field === undefined || field === "" ? null : field;
|
|
56
52
|
};
|
|
@@ -1,31 +1,28 @@
|
|
|
1
1
|
import { request } from "node:http";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import { AnalysisCancelledError, AnalysisError,
|
|
3
|
+
import { AnalysisCancelledError, AnalysisError, BrowserObservationError, } from "../domain/errors.js";
|
|
4
4
|
import { sanitizeBrowserUrl } from "../domain/browserObservation.js";
|
|
5
|
-
const HTTP_TIMEOUT_MS = 5_000;
|
|
6
|
-
const MAX_VERSION_BYTES = 64 * 1_024;
|
|
7
|
-
const MAX_TARGET_LIST_BYTES = 2 * 1_024 * 1_024;
|
|
8
5
|
const endpointVersionSchema = z.object({
|
|
9
|
-
Browser: z.string().min(1)
|
|
10
|
-
"Protocol-Version": z.string().min(1)
|
|
11
|
-
"User-Agent": z.string()
|
|
12
|
-
"V8-Version": z.string()
|
|
13
|
-
"WebKit-Version": z.string()
|
|
14
|
-
webSocketDebuggerUrl: z.string().min(1)
|
|
6
|
+
Browser: z.string().min(1),
|
|
7
|
+
"Protocol-Version": z.string().min(1),
|
|
8
|
+
"User-Agent": z.string(),
|
|
9
|
+
"V8-Version": z.string(),
|
|
10
|
+
"WebKit-Version": z.string(),
|
|
11
|
+
webSocketDebuggerUrl: z.string().min(1),
|
|
15
12
|
});
|
|
16
13
|
const endpointTargetSchema = z.object({
|
|
17
|
-
id: z.string().min(1)
|
|
18
|
-
type: z.string().min(1)
|
|
19
|
-
title: z.string().
|
|
20
|
-
url: z.string()
|
|
14
|
+
id: z.string().min(1),
|
|
15
|
+
type: z.string().min(1),
|
|
16
|
+
title: z.string().default(""),
|
|
17
|
+
url: z.string(),
|
|
21
18
|
attached: z.boolean().default(false),
|
|
22
|
-
webSocketDebuggerUrl: z.string().min(1).
|
|
19
|
+
webSocketDebuggerUrl: z.string().min(1).optional(),
|
|
23
20
|
});
|
|
24
|
-
const endpointTargetsSchema = z.array(endpointTargetSchema)
|
|
25
|
-
/** Read
|
|
21
|
+
const endpointTargetsSchema = z.array(endpointTargetSchema);
|
|
22
|
+
/** Read CDP discovery endpoints without following redirects. */
|
|
26
23
|
export const discoverCdpEndpoint = async (endpoint, operation, signal) => {
|
|
27
|
-
const versionInput = await
|
|
28
|
-
const targetsInput = await
|
|
24
|
+
const versionInput = await readCdpJson(new URL("/json/version", endpoint), operation, signal);
|
|
25
|
+
const targetsInput = await readCdpJson(new URL("/json/list", endpoint), operation, signal);
|
|
29
26
|
const version = parseCdpEndpointValue(endpointVersionSchema, versionInput, operation);
|
|
30
27
|
const targets = parseCdpEndpointValue(endpointTargetsSchema, targetsInput, operation);
|
|
31
28
|
return {
|
|
@@ -56,7 +53,7 @@ const sanitizeTargetTitle = (value, targetUrl) => {
|
|
|
56
53
|
return sanitizeTargetUrlAlias(value, targetUrl);
|
|
57
54
|
}
|
|
58
55
|
return url.protocol === "http:" || url.protocol === "https:"
|
|
59
|
-
? sanitizeBrowserUrl(value).url
|
|
56
|
+
? sanitizeBrowserUrl(value).url
|
|
60
57
|
: sanitizeTargetUrlAlias(value, targetUrl);
|
|
61
58
|
};
|
|
62
59
|
const sanitizeTargetUrlAlias = (value, targetUrl) => {
|
|
@@ -71,9 +68,7 @@ const sanitizeTargetUrlAlias = (value, targetUrl) => {
|
|
|
71
68
|
if (parsed.pathname !== "/")
|
|
72
69
|
markers.push(parsed.pathname);
|
|
73
70
|
const candidatePattern = new RegExp(`(?:${markers.map(escapeRegExp).join("|")})[^\\s<>"']*`, "gu");
|
|
74
|
-
return value
|
|
75
|
-
.replace(candidatePattern, (candidate) => sanitizeSameOriginTitleUrl(candidate, parsed))
|
|
76
|
-
.slice(0, 16_384);
|
|
71
|
+
return value.replace(candidatePattern, (candidate) => sanitizeSameOriginTitleUrl(candidate, parsed));
|
|
77
72
|
};
|
|
78
73
|
const sanitizeSameOriginTitleUrl = (candidate, target) => {
|
|
79
74
|
let parsed;
|
|
@@ -145,19 +140,17 @@ const safeCdpWebSocketEndpoint = (endpoint, reported, operation) => {
|
|
|
145
140
|
: { scope: "page", targetId: path.targetId, url: parsed.href };
|
|
146
141
|
};
|
|
147
142
|
const cdpWebSocketPath = (pathname) => {
|
|
148
|
-
const browserId = pathIdentifier(pathname, "/devtools/browser/"
|
|
143
|
+
const browserId = pathIdentifier(pathname, "/devtools/browser/");
|
|
149
144
|
if (browserId !== undefined)
|
|
150
145
|
return { scope: "browser" };
|
|
151
|
-
const targetId = pathIdentifier(pathname, "/devtools/page/"
|
|
146
|
+
const targetId = pathIdentifier(pathname, "/devtools/page/");
|
|
152
147
|
return targetId === undefined ? undefined : { scope: "page", targetId };
|
|
153
148
|
};
|
|
154
|
-
const pathIdentifier = (pathname, prefix
|
|
149
|
+
const pathIdentifier = (pathname, prefix) => {
|
|
155
150
|
if (!pathname.startsWith(prefix))
|
|
156
151
|
return undefined;
|
|
157
152
|
const identifier = pathname.slice(prefix.length);
|
|
158
|
-
return identifier.length > 0 &&
|
|
159
|
-
identifier.length <= maximumLength &&
|
|
160
|
-
!identifier.includes("/")
|
|
153
|
+
return identifier.length > 0 && !identifier.includes("/")
|
|
161
154
|
? identifier
|
|
162
155
|
: undefined;
|
|
163
156
|
};
|
|
@@ -174,8 +167,8 @@ const targetWebSocket = (endpoint, target, operation) => {
|
|
|
174
167
|
return {};
|
|
175
168
|
}
|
|
176
169
|
};
|
|
177
|
-
/** Read one
|
|
178
|
-
export const
|
|
170
|
+
/** Read one loopback CDP discovery document without redirects. */
|
|
171
|
+
export const readCdpJson = async (url, operation, signal) => await new Promise((resolve, reject) => {
|
|
179
172
|
if (signal?.aborted === true) {
|
|
180
173
|
reject(new AnalysisCancelledError(operation));
|
|
181
174
|
return;
|
|
@@ -187,15 +180,7 @@ export const readBoundedCdpJson = async (url, maximumBytes, operation, signal) =
|
|
|
187
180
|
return;
|
|
188
181
|
}
|
|
189
182
|
const chunks = [];
|
|
190
|
-
|
|
191
|
-
response.on("data", (chunk) => {
|
|
192
|
-
bytes += chunk.length;
|
|
193
|
-
if (bytes > maximumBytes) {
|
|
194
|
-
response.destroy(new BrowserObservationError(operation, "payload_limit"));
|
|
195
|
-
return;
|
|
196
|
-
}
|
|
197
|
-
chunks.push(chunk);
|
|
198
|
-
});
|
|
183
|
+
response.on("data", (chunk) => chunks.push(chunk));
|
|
199
184
|
response.on("end", () => {
|
|
200
185
|
try {
|
|
201
186
|
resolve(JSON.parse(Buffer.concat(chunks).toString("utf8")));
|
|
@@ -206,7 +191,6 @@ export const readBoundedCdpJson = async (url, maximumBytes, operation, signal) =
|
|
|
206
191
|
});
|
|
207
192
|
response.on("error", (cause) => reject(endpointFailure(cause, operation, signal)));
|
|
208
193
|
});
|
|
209
|
-
request_.setTimeout(HTTP_TIMEOUT_MS, () => request_.destroy(new AnalysisTimeoutError(operation, HTTP_TIMEOUT_MS)));
|
|
210
194
|
request_.on("error", (cause) => reject(endpointFailure(cause, operation, signal)));
|
|
211
195
|
request_.end();
|
|
212
196
|
});
|
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
import { AnalysisCancelledError, BrowserObservationError, } from "../domain/errors.js";
|
|
2
2
|
import { CdpConnection } from "./CdpConnection.js";
|
|
3
3
|
import { CdpCaptureCompleteness } from "./CdpCaptureCompleteness.js";
|
|
4
|
-
import {
|
|
4
|
+
import { authorizedMainFrame } from "./CdpAuthorizedMainFrame.js";
|
|
5
|
+
import { allowedSanitizedUrl, isHttpUrl, numberValue, recordValue, stringValue, } from "./CdpCaptureValues.js";
|
|
5
6
|
import { mainFrameUrl } from "./CdpCaptureDocuments.js";
|
|
6
7
|
/** Observe external user actions without rejecting approved same-origin navigation. */
|
|
7
8
|
export const observeCdpSession = async (context) => {
|
|
8
9
|
const allowedOrigins = new Set(context.input.allowed_origins);
|
|
9
|
-
const initial = await
|
|
10
|
+
const initial = await authorizedMainFrame({
|
|
11
|
+
connection: context.connection,
|
|
12
|
+
sessionId: context.sessionId,
|
|
13
|
+
signal: context.signal,
|
|
14
|
+
allowedOrigins,
|
|
15
|
+
delayOperation: "observe_web_session",
|
|
16
|
+
});
|
|
10
17
|
const initialUrl = mainFrameUrl(initial) ?? "";
|
|
11
18
|
const mainFrameId = frameId(initial);
|
|
12
19
|
if (mainFrameId === undefined)
|
|
13
20
|
throw new BrowserObservationError("inspect_web_page", "protocol_error");
|
|
14
|
-
const capture = new TimelineCapture(
|
|
21
|
+
const capture = new TimelineCapture(allowedOrigins, mainFrameId, initialUrl);
|
|
15
22
|
const removeListener = context.connection.onEvent((event) => {
|
|
16
23
|
if (observationEventMatches(event, context.sessionId))
|
|
17
24
|
capture.ingest(event);
|
|
@@ -19,7 +26,7 @@ export const observeCdpSession = async (context) => {
|
|
|
19
26
|
const removeDisconnectListener = context.connection.onDisconnect(() => capture.targetTerminated());
|
|
20
27
|
try {
|
|
21
28
|
await context.connection.send("Page.enable", {}, context.sessionId, context.signal);
|
|
22
|
-
await context.connection.send("Network.enable", {
|
|
29
|
+
await context.connection.send("Network.enable", {}, context.sessionId, context.signal);
|
|
23
30
|
await context.connection.send("Page.setLifecycleEventsEnabled", { enabled: true }, context.sessionId, context.signal);
|
|
24
31
|
const armedAt = new Date().toISOString();
|
|
25
32
|
await context.progress?.report({
|
|
@@ -39,7 +46,6 @@ export const observeCdpSession = async (context) => {
|
|
|
39
46
|
terminal: true,
|
|
40
47
|
});
|
|
41
48
|
return {
|
|
42
|
-
schema_version: 1,
|
|
43
49
|
browser: context.discovery.version,
|
|
44
50
|
target: {
|
|
45
51
|
target_id: context.target.id,
|
|
@@ -67,7 +73,6 @@ export const observeCdpSession = async (context) => {
|
|
|
67
73
|
}
|
|
68
74
|
};
|
|
69
75
|
class TimelineCapture {
|
|
70
|
-
maximum;
|
|
71
76
|
allowedOrigins;
|
|
72
77
|
mainFrameId;
|
|
73
78
|
timeline = [];
|
|
@@ -77,8 +82,7 @@ class TimelineCapture {
|
|
|
77
82
|
#pendingReload = false;
|
|
78
83
|
#endReason;
|
|
79
84
|
#listeners = new Set();
|
|
80
|
-
constructor(
|
|
81
|
-
this.maximum = maximum;
|
|
85
|
+
constructor(allowedOrigins, mainFrameId, initialUrl) {
|
|
82
86
|
this.allowedOrigins = allowedOrigins;
|
|
83
87
|
this.mainFrameId = mainFrameId;
|
|
84
88
|
this.finalUrl =
|
|
@@ -246,10 +250,6 @@ class TimelineCapture {
|
|
|
246
250
|
#add(options) {
|
|
247
251
|
const { type, params, rawUrl = null, requestId = null, detail = null, } = options;
|
|
248
252
|
const destination = rawUrl == null ? null : scopedUrl(rawUrl, this.allowedOrigins);
|
|
249
|
-
if (this.timeline.length >= this.maximum) {
|
|
250
|
-
this.completeness.drop("timeline_events");
|
|
251
|
-
return;
|
|
252
|
-
}
|
|
253
253
|
this.#sequence += 1;
|
|
254
254
|
this.timeline.push({
|
|
255
255
|
sequence: this.#sequence,
|
|
@@ -257,7 +257,7 @@ class TimelineCapture {
|
|
|
257
257
|
timestamp: Math.max(0, numberValue(params.timestamp) ?? 0),
|
|
258
258
|
frame_id: boundedId(params.frameId),
|
|
259
259
|
loader_id: boundedId(params.loaderId),
|
|
260
|
-
request_id: requestId
|
|
260
|
+
request_id: requestId ?? null,
|
|
261
261
|
url: destination?.scope === "approved" ? destination.url : null,
|
|
262
262
|
destination_scope: destination?.scope ?? null,
|
|
263
263
|
detail,
|
|
@@ -296,18 +296,6 @@ const waitForWindow = async (durationMs, capture, signal) => await new Promise((
|
|
|
296
296
|
if (signal?.aborted === true)
|
|
297
297
|
onAbort();
|
|
298
298
|
});
|
|
299
|
-
const authorizedFrame = async (context, allowedOrigins) => {
|
|
300
|
-
for (let attempt = 0; attempt < 80; attempt += 1) {
|
|
301
|
-
const result = await context.connection.send("Page.getFrameTree", {}, context.sessionId, context.signal);
|
|
302
|
-
const url = mainFrameUrl(result);
|
|
303
|
-
if (allowedSanitizedUrl(url, allowedOrigins) !== undefined)
|
|
304
|
-
return result;
|
|
305
|
-
if (isHttpUrl(url))
|
|
306
|
-
throw new BrowserObservationError("inspect_web_page", "target_not_allowed");
|
|
307
|
-
await delayWithCancellation(25, "observe_web_session", context.signal);
|
|
308
|
-
}
|
|
309
|
-
throw new BrowserObservationError("inspect_web_page", "target_not_allowed");
|
|
310
|
-
};
|
|
311
299
|
const captureFinalUrl = async (context, capture, allowedOrigins) => {
|
|
312
300
|
const result = await context.connection.send("Page.getFrameTree", {}, context.sessionId, context.signal);
|
|
313
301
|
const url = mainFrameUrl(result);
|
|
@@ -329,7 +317,7 @@ const scopedUrl = (value, allowedOrigins) => {
|
|
|
329
317
|
? { url: null, scope: "outside_policy" }
|
|
330
318
|
: { url: null, scope: "unsupported" };
|
|
331
319
|
};
|
|
332
|
-
const boundedId = (value) => stringValue(value)
|
|
320
|
+
const boundedId = (value) => stringValue(value) ?? null;
|
|
333
321
|
const safeDetail = (value) => {
|
|
334
322
|
const detail = stringValue(value)?.toLowerCase();
|
|
335
323
|
return detail !== undefined && /^[a-z0-9_.:-]{1,100}$/u.test(detail)
|
|
@@ -2,10 +2,11 @@ import { BrowserObservationError, } from "../domain/errors.js";
|
|
|
2
2
|
import { stableWebResources } from "../domain/webInventory.js";
|
|
3
3
|
import { CdpConnection } from "./CdpConnection.js";
|
|
4
4
|
import { CdpCaptureEvents } from "./CdpCaptureEvents.js";
|
|
5
|
+
import { authorizedMainFrame } from "./CdpAuthorizedMainFrame.js";
|
|
5
6
|
import { captureStorage } from "./CdpCaptureStorage.js";
|
|
6
7
|
import { optionalCdpCommand } from "./CdpOptionalCommand.js";
|
|
7
8
|
import { captureAccessibility, captureDom, captureFrames, captureResources, mainFrameUrl, } from "./CdpCaptureDocuments.js";
|
|
8
|
-
import { allowedSanitizedUrl, delayWithCancellation,
|
|
9
|
+
import { allowedSanitizedUrl, delayWithCancellation, } from "./CdpCaptureValues.js";
|
|
9
10
|
import { captureScripts } from "./CdpPageCaptureScripts.js";
|
|
10
11
|
import { captureWorkers } from "./CdpPageCaptureWorkers.js";
|
|
11
12
|
/** Capture and normalize one attached page without evaluating page JavaScript. */
|
|
@@ -23,7 +24,7 @@ export const capturePage = async (context) => {
|
|
|
23
24
|
allowedOrigins,
|
|
24
25
|
limitations: [
|
|
25
26
|
"Observation starts when REA attaches; prior network and console activity is unavailable.",
|
|
26
|
-
"Raw network headers, bodies, cookies, storage values, console objects, and WebSocket payloads are never retained; separately approved captures retain only
|
|
27
|
+
"Raw network headers, bodies, cookies, storage values, console objects, and WebSocket payloads are never retained; separately approved captures retain only redacted text or value-free shapes.",
|
|
27
28
|
"Source maps are reported only as declarative URLs and are not fetched.",
|
|
28
29
|
"URL-less scripts and console events without an allowed source URL are excluded because their origin cannot be proven.",
|
|
29
30
|
],
|
|
@@ -41,26 +42,24 @@ const captureAuthorizedPage = async (state) => {
|
|
|
41
42
|
const { connection, sessionId, input, signal } = context;
|
|
42
43
|
await authorizeObservationWindow(state);
|
|
43
44
|
await captureJsonResponseBodies(state);
|
|
44
|
-
const frameResult = await
|
|
45
|
+
const frameResult = await authorizedMainFrame({
|
|
46
|
+
connection: context.connection,
|
|
47
|
+
sessionId: context.sessionId,
|
|
48
|
+
signal: context.signal,
|
|
49
|
+
allowedOrigins,
|
|
50
|
+
delayOperation: context.operation,
|
|
51
|
+
});
|
|
45
52
|
const attachedUrl = mainFrameUrl(frameResult) ?? "";
|
|
46
|
-
const frameCapture = captureFrames(frameResult, allowedOrigins,
|
|
53
|
+
const frameCapture = captureFrames(frameResult, allowedOrigins, undefined, state.events.completeness);
|
|
47
54
|
const frames = frameCapture.items;
|
|
48
|
-
if (frameCapture.total > frames.length)
|
|
49
|
-
state.events.completeness.truncate("frames");
|
|
50
55
|
const captureFrame = frames[0];
|
|
51
56
|
if (captureFrame === undefined)
|
|
52
57
|
throw new BrowserObservationError("inspect_web_page", "target_not_allowed");
|
|
53
58
|
state.events.beginFinalCapture(captureFrame.frame_id);
|
|
54
|
-
const resourceCapture = captureResources(await connection.send("Page.getResourceTree", {}, sessionId, signal), allowedOrigins,
|
|
55
|
-
if (resourceCapture.total > resourceCapture.items.length)
|
|
56
|
-
state.events.completeness.truncate("resources");
|
|
59
|
+
const resourceCapture = captureResources(await connection.send("Page.getResourceTree", {}, sessionId, signal), allowedOrigins, state.events.completeness);
|
|
57
60
|
const resources = stableWebResources(resourceCapture.items.map(publicResource));
|
|
58
61
|
const dom = await capturePageDom(state);
|
|
59
|
-
if (dom.total > dom.nodes.length)
|
|
60
|
-
state.events.completeness.truncate("dom");
|
|
61
62
|
const accessibility = await accessibilityForFrames(state, frames);
|
|
62
|
-
if (accessibility.total > accessibility.nodes.length)
|
|
63
|
-
state.events.completeness.truncate("accessibility");
|
|
64
63
|
const scripts = await captureScripts({
|
|
65
64
|
context,
|
|
66
65
|
events: state.events,
|
|
@@ -68,15 +67,17 @@ const captureAuthorizedPage = async (state) => {
|
|
|
68
67
|
resources,
|
|
69
68
|
frameIds: new Set(frames.map((frame) => frame.frame_id)),
|
|
70
69
|
});
|
|
71
|
-
const
|
|
72
|
-
if (workerCapture.total > workerCapture.items.length)
|
|
73
|
-
state.events.completeness.truncate("workers");
|
|
70
|
+
const workers = await captureWorkers({ context, allowedOrigins, limitations, events: state.events }, new Set(frames.map((frame) => frame.frame_id)));
|
|
74
71
|
const storageCapture = await captureStorage(context, frames[0]?.origin ?? new URL(attachedUrl).origin, limitations);
|
|
75
|
-
if (storageCapture.truncated)
|
|
76
|
-
state.events.completeness.truncate("storage_keys");
|
|
77
72
|
if (!input.include_storage_keys)
|
|
78
73
|
state.events.completeness.exclude("storage_keys", "not_approved", null);
|
|
79
|
-
const completedFrameResult = await
|
|
74
|
+
const completedFrameResult = await authorizedMainFrame({
|
|
75
|
+
connection: context.connection,
|
|
76
|
+
sessionId: context.sessionId,
|
|
77
|
+
signal: context.signal,
|
|
78
|
+
allowedOrigins,
|
|
79
|
+
delayOperation: context.operation,
|
|
80
|
+
});
|
|
80
81
|
const completedUrl = mainFrameUrl(completedFrameResult) ?? "";
|
|
81
82
|
if (state.events.originViolation)
|
|
82
83
|
throw new BrowserObservationError("inspect_web_page", "target_not_allowed");
|
|
@@ -91,7 +92,7 @@ const captureAuthorizedPage = async (state) => {
|
|
|
91
92
|
accessibility,
|
|
92
93
|
scripts: scripts.inventory,
|
|
93
94
|
resources,
|
|
94
|
-
workers
|
|
95
|
+
workers,
|
|
95
96
|
storage: storageCapture.value,
|
|
96
97
|
}),
|
|
97
98
|
sourceMapRequests: scripts.sourceMapRequests,
|
|
@@ -118,9 +119,14 @@ const authorizeObservationWindow = async (state) => {
|
|
|
118
119
|
const { connection, sessionId, signal } = context;
|
|
119
120
|
await report(context.progress, 1, "Enabling passive CDP domains");
|
|
120
121
|
await connection.send("Page.enable", {}, sessionId, signal);
|
|
121
|
-
const initialFrameResult = await
|
|
122
|
-
|
|
123
|
-
.
|
|
122
|
+
const initialFrameResult = await authorizedMainFrame({
|
|
123
|
+
connection: context.connection,
|
|
124
|
+
sessionId: context.sessionId,
|
|
125
|
+
signal: context.signal,
|
|
126
|
+
allowedOrigins,
|
|
127
|
+
delayOperation: context.operation,
|
|
128
|
+
});
|
|
129
|
+
const mainFrame = captureFrames(initialFrameResult, allowedOrigins).items[0];
|
|
124
130
|
if (mainFrame === undefined)
|
|
125
131
|
throw new BrowserObservationError("inspect_web_page", "target_not_allowed");
|
|
126
132
|
events.beginAuthorizedFrame(mainFrame.frame_id);
|
|
@@ -140,7 +146,6 @@ const capturePageDom = async (state) => {
|
|
|
140
146
|
return captureDom(result, allowedOrigins, context.input, state.events.completeness);
|
|
141
147
|
};
|
|
142
148
|
const normalizedInspection = (state, captured) => ({
|
|
143
|
-
schema_version: 2,
|
|
144
149
|
browser: state.context.discovery.version,
|
|
145
150
|
target: normalizedTarget(state.context.target, captured.attachedUrl, state.allowedOrigins),
|
|
146
151
|
capture_window: {
|
|
@@ -183,32 +188,17 @@ const normalizedInspection = (state, captured) => ({
|
|
|
183
188
|
storage: captured.storage,
|
|
184
189
|
limitations: state.limitations,
|
|
185
190
|
});
|
|
186
|
-
const authorizedFrameTree = async (context, allowedOrigins) => {
|
|
187
|
-
for (let attempt = 0; attempt < 80; attempt += 1) {
|
|
188
|
-
const result = await context.connection.send("Page.getFrameTree", {}, context.sessionId, context.signal);
|
|
189
|
-
const currentUrl = mainFrameUrl(result);
|
|
190
|
-
if (allowedSanitizedUrl(currentUrl, allowedOrigins) !== undefined)
|
|
191
|
-
return result;
|
|
192
|
-
if (isHttpUrl(currentUrl))
|
|
193
|
-
throw new BrowserObservationError("inspect_web_page", "target_not_allowed");
|
|
194
|
-
await delayWithCancellation(25, context.operation, context.signal);
|
|
195
|
-
}
|
|
196
|
-
throw new BrowserObservationError("inspect_web_page", "target_not_allowed");
|
|
197
|
-
};
|
|
198
191
|
const enableObservationDomains = async (connection, sessionId, signal) => {
|
|
199
192
|
await connection.send("Runtime.enable", {}, sessionId, signal);
|
|
200
|
-
await connection.send("Debugger.enable", {
|
|
201
|
-
await connection.send("Network.enable", {
|
|
202
|
-
maxTotalBufferSize: 4 * 1_024 * 1_024,
|
|
203
|
-
maxResourceBufferSize: 1_024 * 1_024,
|
|
204
|
-
}, sessionId, signal);
|
|
193
|
+
await connection.send("Debugger.enable", {}, sessionId, signal);
|
|
194
|
+
await connection.send("Network.enable", {}, sessionId, signal);
|
|
205
195
|
};
|
|
206
196
|
const accessibilityForFrames = async (state, frames) => {
|
|
207
197
|
const { context, limitations, events } = state;
|
|
208
198
|
const results = [];
|
|
209
199
|
let unavailable = false;
|
|
210
200
|
for (const frame of frames) {
|
|
211
|
-
const result = await optionalCdpCommand(context, "Accessibility.getFullAXTree", {
|
|
201
|
+
const result = await optionalCdpCommand(context, "Accessibility.getFullAXTree", { frameId: frame.frame_id }, limitations);
|
|
212
202
|
if (result === undefined)
|
|
213
203
|
unavailable = true;
|
|
214
204
|
else
|
|
@@ -216,16 +206,12 @@ const accessibilityForFrames = async (state, frames) => {
|
|
|
216
206
|
}
|
|
217
207
|
if (unavailable)
|
|
218
208
|
events.completeness.unavailable("accessibility");
|
|
219
|
-
const capture = captureAccessibility(results,
|
|
209
|
+
const capture = captureAccessibility(results, {
|
|
220
210
|
includeText: context.input.include_accessibility_text,
|
|
221
|
-
maximumFieldBytes: context.input.limits.max_ax_text_field_bytes,
|
|
222
|
-
maximumTotalBytes: context.input.limits.max_total_ax_text_bytes,
|
|
223
211
|
...(results.length === 0 && unavailable ? { unavailable: true } : {}),
|
|
224
212
|
});
|
|
225
213
|
if (!context.input.include_accessibility_text)
|
|
226
214
|
events.completeness.exclude("accessibility", "not_approved", capture.textCapture.excluded_fields);
|
|
227
|
-
if (capture.textCapture.status === "truncated")
|
|
228
|
-
events.completeness.truncate("accessibility");
|
|
229
215
|
if (capture.treeIncomplete)
|
|
230
216
|
events.completeness.truncate("accessibility");
|
|
231
217
|
return capture;
|
|
@@ -246,7 +232,7 @@ const normalizedTarget = (target, currentUrl, allowedOrigins) => {
|
|
|
246
232
|
return {
|
|
247
233
|
target_id: target.id,
|
|
248
234
|
type: target.type,
|
|
249
|
-
title: target.title
|
|
235
|
+
title: target.title,
|
|
250
236
|
url: url?.url ?? "[unsupported-url]",
|
|
251
237
|
origin: url?.origin ?? "",
|
|
252
238
|
attached: target.attached,
|
|
@@ -8,7 +8,6 @@ export const captureScripts = async (options) => {
|
|
|
8
8
|
frameIds,
|
|
9
9
|
rawResources,
|
|
10
10
|
resources,
|
|
11
|
-
totalSourceBytes: 0,
|
|
12
11
|
};
|
|
13
12
|
const drafts = [];
|
|
14
13
|
for (const script of events.scripts.values())
|
|
@@ -42,26 +41,9 @@ const buildScriptDraft = async (script, state) => {
|
|
|
42
41
|
};
|
|
43
42
|
};
|
|
44
43
|
const captureScriptSource = async (script, state) => {
|
|
45
|
-
const { context
|
|
46
|
-
if (script.length > context.input.limits.max_script_source_bytes) {
|
|
47
|
-
events.completeness.truncate("script_sources");
|
|
48
|
-
return sourceExcluded("declared script length exceeds per-script limit");
|
|
49
|
-
}
|
|
50
|
-
if (state.totalSourceBytes + script.length >
|
|
51
|
-
context.input.limits.max_total_script_source_bytes) {
|
|
52
|
-
events.completeness.truncate("script_sources");
|
|
53
|
-
return sourceExcluded("total script source limit reached");
|
|
54
|
-
}
|
|
44
|
+
const { context } = state;
|
|
55
45
|
const result = requiredRecord(await context.connection.send("Debugger.getScriptSource", { scriptId: script.scriptId }, context.sessionId, context.signal));
|
|
56
46
|
const content = stringValue(result.scriptSource) ?? "";
|
|
57
|
-
const bytes = Buffer.byteLength(content);
|
|
58
|
-
if (bytes > context.input.limits.max_script_source_bytes ||
|
|
59
|
-
state.totalSourceBytes + bytes >
|
|
60
|
-
context.input.limits.max_total_script_source_bytes) {
|
|
61
|
-
events.completeness.truncate("script_sources");
|
|
62
|
-
return sourceExcluded("actual source exceeds configured byte limits");
|
|
63
|
-
}
|
|
64
|
-
state.totalSourceBytes += bytes;
|
|
65
47
|
return sourceResult(content);
|
|
66
48
|
};
|
|
67
49
|
const keyAndBuildInventory = (drafts, scriptCount) => {
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { allowedSanitizedUrl,
|
|
1
|
+
import { allowedSanitizedUrl, isHttpUrl, recordValue, recordsValue, stringValue, } from "./CdpCaptureValues.js";
|
|
2
2
|
import { optionalCdpCommand } from "./CdpOptionalCommand.js";
|
|
3
3
|
export const captureWorkers = async (input, frameIds) => {
|
|
4
4
|
const { context, allowedOrigins, limitations, events } = input;
|
|
5
5
|
const completeness = events.completeness;
|
|
6
6
|
const result = await optionalCdpCommand({ ...context, sessionId: undefined }, "Target.getTargets", {}, limitations);
|
|
7
7
|
const items = [];
|
|
8
|
-
let total = 0;
|
|
9
8
|
if (result === undefined)
|
|
10
9
|
completeness.unavailable("workers");
|
|
11
10
|
for (const target of recordsValue(recordValue(result)?.targetInfos)) {
|
|
@@ -29,18 +28,15 @@ export const captureWorkers = async (input, frameIds) => {
|
|
|
29
28
|
: "unsupported_url");
|
|
30
29
|
continue;
|
|
31
30
|
}
|
|
32
|
-
total += 1;
|
|
33
|
-
if (items.length >= context.input.limits.max_workers)
|
|
34
|
-
continue;
|
|
35
31
|
items.push({
|
|
36
|
-
target_id:
|
|
37
|
-
type
|
|
32
|
+
target_id: stringValue(target.targetId) ?? "",
|
|
33
|
+
type,
|
|
38
34
|
url: url.url,
|
|
39
35
|
origin: url.origin,
|
|
40
36
|
attached: target.attached === true,
|
|
41
|
-
opener_target_id:
|
|
42
|
-
parent_frame_id:
|
|
37
|
+
opener_target_id: stringValue(target.openerId) ?? null,
|
|
38
|
+
parent_frame_id: stringValue(target.parentFrameId) ?? null,
|
|
43
39
|
});
|
|
44
40
|
}
|
|
45
|
-
return
|
|
41
|
+
return items;
|
|
46
42
|
};
|
|
@@ -37,15 +37,15 @@ const normalizedHeaders = (value) => {
|
|
|
37
37
|
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
38
38
|
return new Map();
|
|
39
39
|
const headers = new Map();
|
|
40
|
-
for (const [name, raw] of Object.entries(value)
|
|
41
|
-
const normalized = name.toLowerCase()
|
|
40
|
+
for (const [name, raw] of Object.entries(value)) {
|
|
41
|
+
const normalized = name.toLowerCase();
|
|
42
42
|
const header = typeof raw === "string"
|
|
43
43
|
? raw
|
|
44
44
|
: typeof raw === "number" && Number.isFinite(raw)
|
|
45
45
|
? String(raw)
|
|
46
46
|
: undefined;
|
|
47
47
|
if (header !== undefined)
|
|
48
|
-
headers.set(normalized, header
|
|
48
|
+
headers.set(normalized, header);
|
|
49
49
|
}
|
|
50
50
|
return headers;
|
|
51
51
|
};
|
|
@@ -53,13 +53,13 @@ const parseCsp = (value, baseUrl, allowedOrigins) => {
|
|
|
53
53
|
const directives = [];
|
|
54
54
|
let nonceCount = 0;
|
|
55
55
|
let hashCount = 0;
|
|
56
|
-
for (const rawDirective of (value ?? "").split(";")
|
|
56
|
+
for (const rawDirective of (value ?? "").split(";")) {
|
|
57
57
|
const [rawName, ...tokens] = rawDirective.trim().split(/\s+/u);
|
|
58
58
|
const name = (rawName ?? "").toLowerCase();
|
|
59
|
-
if (!/^[a-z][a-z0-9-]
|
|
59
|
+
if (!/^[a-z][a-z0-9-]*$/u.test(name))
|
|
60
60
|
continue;
|
|
61
61
|
const sources = [];
|
|
62
|
-
for (const token of tokens
|
|
62
|
+
for (const token of tokens) {
|
|
63
63
|
const lower = token.toLowerCase();
|
|
64
64
|
if (lower.startsWith("'nonce-")) {
|
|
65
65
|
nonceCount += 1;
|
|
@@ -80,9 +80,9 @@ const parseCsp = (value, baseUrl, allowedOrigins) => {
|
|
|
80
80
|
const cspSource = (token, baseUrl, allowedOrigins) => {
|
|
81
81
|
const lower = token.toLowerCase();
|
|
82
82
|
if (/^'[a-z0-9-]+'$/u.test(lower))
|
|
83
|
-
return { kind: "keyword", value: lower
|
|
83
|
+
return { kind: "keyword", value: lower };
|
|
84
84
|
if (/^[a-z][a-z0-9+.-]*:$/u.test(lower))
|
|
85
|
-
return { kind: "scheme", value: lower
|
|
85
|
+
return { kind: "scheme", value: lower };
|
|
86
86
|
try {
|
|
87
87
|
const parsed = new URL(token, baseUrl);
|
|
88
88
|
return allowedOrigins.has(parsed.origin)
|
|
@@ -95,8 +95,8 @@ const cspSource = (token, baseUrl, allowedOrigins) => {
|
|
|
95
95
|
};
|
|
96
96
|
const parseLinks = (value, baseUrl, allowedOrigins) => {
|
|
97
97
|
const links = [];
|
|
98
|
-
for (const entry of splitLinkHeader(value ?? "")
|
|
99
|
-
const match = /^\s*<([^>]
|
|
98
|
+
for (const entry of splitLinkHeader(value ?? "")) {
|
|
99
|
+
const match = /^\s*<([^>]*)>(.*)$/u.exec(entry);
|
|
100
100
|
if (match === null)
|
|
101
101
|
continue;
|
|
102
102
|
const parameters = linkParameters(match[2] ?? "");
|
|
@@ -107,8 +107,7 @@ const parseLinks = (value, baseUrl, allowedOrigins) => {
|
|
|
107
107
|
rel: (parameters.get("rel") ?? "")
|
|
108
108
|
.toLowerCase()
|
|
109
109
|
.split(/\s+/u)
|
|
110
|
-
.filter(Boolean)
|
|
111
|
-
.slice(0, 32),
|
|
110
|
+
.filter(Boolean),
|
|
112
111
|
as: boundedHeader(parameters.get("as")),
|
|
113
112
|
type: boundedHeader(parameters.get("type")),
|
|
114
113
|
crossorigin: boundedHeader(parameters.get("crossorigin")),
|
|
@@ -134,15 +133,15 @@ const splitLinkHeader = (value) => {
|
|
|
134
133
|
};
|
|
135
134
|
const linkParameters = (value) => {
|
|
136
135
|
const parameters = new Map();
|
|
137
|
-
for (const raw of value.split(";").slice(1
|
|
136
|
+
for (const raw of value.split(";").slice(1)) {
|
|
138
137
|
const separator = raw.indexOf("=");
|
|
139
138
|
const name = (separator < 0 ? raw : raw.slice(0, separator))
|
|
140
139
|
.trim()
|
|
141
140
|
.toLowerCase();
|
|
142
|
-
if (!/^[a-z][a-z0-9-]
|
|
141
|
+
if (!/^[a-z][a-z0-9-]*$/u.test(name))
|
|
143
142
|
continue;
|
|
144
143
|
const parameter = separator < 0 ? "" : raw.slice(separator + 1).trim();
|
|
145
|
-
parameters.set(name, unquote(parameter)
|
|
144
|
+
parameters.set(name, unquote(parameter));
|
|
146
145
|
}
|
|
147
146
|
return parameters;
|
|
148
147
|
};
|
|
@@ -163,10 +162,8 @@ const permissionFeatures = (value) => [
|
|
|
163
162
|
...new Set((value ?? "")
|
|
164
163
|
.split(",")
|
|
165
164
|
.map((entry) => entry.split("=", 1)[0]?.trim().toLowerCase() ?? "")
|
|
166
|
-
.filter((feature) => /^[a-z][a-z0-9-]
|
|
167
|
-
]
|
|
168
|
-
.sort()
|
|
169
|
-
.slice(0, 200);
|
|
165
|
+
.filter((feature) => /^[a-z][a-z0-9-]*$/u.test(feature))),
|
|
166
|
+
].sort();
|
|
170
167
|
const wellKnownHint = (url) => {
|
|
171
168
|
try {
|
|
172
169
|
const path = new URL(url).pathname.toLowerCase();
|
|
@@ -180,20 +177,20 @@ const wellKnownHint = (url) => {
|
|
|
180
177
|
};
|
|
181
178
|
const agentHint = (mechanism, declaration, url) => ({
|
|
182
179
|
mechanism,
|
|
183
|
-
declaration
|
|
180
|
+
declaration,
|
|
184
181
|
url,
|
|
185
182
|
trust: "page-declared-untrusted",
|
|
186
183
|
});
|
|
187
184
|
const isAgentRel = (value) => ["mcp", "model-context", "ai-plugin", "service-desc"].includes(value);
|
|
188
185
|
const policyToken = (value) => {
|
|
189
186
|
const token = (value ?? "").trim().toLowerCase();
|
|
190
|
-
return /^[a-z][a-z0-9_.-]
|
|
187
|
+
return /^[a-z][a-z0-9_.-]*$/u.test(token) ? token : null;
|
|
191
188
|
};
|
|
192
189
|
const nonnegativeInteger = (value) => {
|
|
193
190
|
const number = numberValue(value === undefined ? undefined : Number(value));
|
|
194
191
|
return number === undefined ? null : Math.max(0, Math.trunc(number));
|
|
195
192
|
};
|
|
196
|
-
const boundedHeader = (value) => value === undefined ? null : value.trim().toLowerCase()
|
|
193
|
+
const boundedHeader = (value) => value === undefined ? null : value.trim().toLowerCase();
|
|
197
194
|
const unquote = (value) => value.startsWith('"') && value.endsWith('"') ? value.slice(1, -1) : value;
|
|
198
195
|
const agentHeaderNames = ["x-model-context", "x-webmcp", "mcp-server"];
|
|
199
196
|
const wellKnownAgentPaths = new Set([
|