rea-agents 2.5.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -12
- package/bridge/ghidra/ReaGhidraBridge.java +477 -4
- package/bridge/hopper_bridge.py +54 -4
- package/dist/application/AnalysisContextQueries.js +142 -0
- package/dist/application/AnalysisSnapshotCache.js +4 -2
- package/dist/application/ApplicationWorkflowEvidenceResolver.js +19 -11
- package/dist/application/ArtifactInventory/policy.js +17 -0
- package/dist/application/ArtifactInventory/reader.js +1 -4
- package/dist/application/ArtifactInventory/scanCanonical.js +0 -3
- package/dist/application/ArtifactInventory/scanReader.js +7 -7
- package/dist/application/ArtifactInventory/types.js +1 -5
- package/dist/application/BinarySession.js +19 -20
- package/dist/application/BinarySessionComposition.js +21 -0
- package/dist/application/BinarySessionRecords.js +106 -10
- package/dist/application/BinarySessionStatus.js +11 -5
- package/dist/application/BrowserEvidence.js +3 -5
- package/dist/application/CapabilityClientRequirements.js +26 -0
- package/dist/application/CapabilityInventory.js +140 -55
- package/dist/application/ClientRegistrationStatus.js +4 -1
- package/dist/application/CrossVersionInventory.js +7 -6
- package/dist/application/DirectAnalysis.js +6 -2
- package/dist/application/ElectronActiveEvidence.js +55 -0
- package/dist/application/ElectronActiveObservationPort.js +1 -0
- package/dist/application/ElectronActiveObservationService.js +81 -0
- package/dist/application/EnhancedTools.js +49 -17
- package/dist/application/EvidenceBundleCommands.js +5 -1
- package/dist/application/EvidenceLedger.js +53 -17
- package/dist/application/JavaScriptArtifactAnalysis.js +13 -4
- package/dist/application/JavaScriptReplayPermission.js +1 -1
- package/dist/application/JavaScriptReplayService.js +23 -15
- package/dist/application/LazyAnalysisProvider.js +77 -0
- package/dist/application/LoopbackReplay.js +1 -1
- package/dist/application/ManagedRuntimeCorrelationService.js +9 -5
- package/dist/application/NativeApiInspection.js +80 -0
- package/dist/application/NodeRuntimeCharacterizationService.js +8 -9
- package/dist/application/ProcessCaptureLifecycle.js +5 -0
- package/dist/application/ProcessCli.js +2 -1
- package/dist/application/ProcessHarness.js +8 -3
- package/dist/application/ProcessNormalization.js +2 -1
- package/dist/application/ProjectPermissionStore.js +1 -0
- package/dist/application/ReferenceSourceImport.js +2 -2
- package/dist/application/SessionProviderRouter.js +6 -6
- package/dist/application/SetupClientConfiguration.js +10 -3
- package/dist/application/WindowsCapabilities.js +5 -4
- package/dist/application/runtime.js +26 -9
- package/dist/artifacts/ArtifactProvider.js +8 -10
- package/dist/artifacts/SafeOutputTree.js +7 -8
- package/dist/browser/CdpCaptureStorageFingerprints.js +10 -7
- package/dist/browser/CdpElectronInspection.js +3 -1
- package/dist/browser/JavaScriptRuntimeScope.js +5 -0
- package/dist/browser/PlaywrightBrowserScenarioProvider.js +8 -2
- package/dist/browser/PlaywrightElectronActiveActions.js +324 -0
- package/dist/browser/PlaywrightElectronActiveProvider.js +294 -0
- package/dist/browser/PlaywrightScenarioBrowser.js +4 -4
- package/dist/browser/PlaywrightScenarioSession.js +4 -4
- package/dist/browser/SensitiveTextCapture.js +1 -1
- package/dist/browser/V8InspectorCaptureProjection.js +1 -0
- package/dist/browser/V8InspectorProvider.js +3 -3
- package/dist/catalogIdentity.js +15 -9
- package/dist/cli/artifactCommands.js +5 -3
- package/dist/cli/coreAnalysisCommands.js +41 -0
- package/dist/cli/managedCommands.js +1 -1
- package/dist/cliApplicationCommands.js +2 -2
- package/dist/cliBrowserAdvancedCommands.js +11 -5
- package/dist/cliBrowserCommands.js +14 -7
- package/dist/cliCommandNames.js +2 -0
- package/dist/cliElectronCommands.js +46 -4
- package/dist/cliJavaScriptRuntimeCommands.js +14 -6
- package/dist/cliObservationOptions.js +4 -0
- package/dist/cliPolicyCommands.js +1 -0
- package/dist/config/browserScenario.js +77 -0
- package/dist/config/electronAutomation.js +35 -0
- package/dist/config/environment.js +6 -0
- package/dist/config/javascriptReplay.js +41 -0
- package/dist/config/managedRuntime.js +25 -0
- package/dist/config/parseConfig.js +56 -200
- package/dist/config/parsers.js +10 -1
- package/dist/config/passiveObservation.js +157 -0
- package/dist/config/processCapture.js +47 -0
- package/dist/contracts/applicationToolContracts.js +2 -5
- package/dist/contracts/applicationWorkflowInputContracts.js +86 -96
- package/dist/contracts/artifactToolContracts.js +35 -37
- package/dist/contracts/browserToolContracts.js +2 -2
- package/dist/contracts/electronToolContracts.js +30 -1
- package/dist/contracts/enhancedInputs.js +21 -27
- package/dist/contracts/functionWorkflowToolContracts.js +29 -0
- package/dist/contracts/managedToolContracts.js +4 -9
- package/dist/contracts/managedWorkflowExamples.js +12 -9
- package/dist/contracts/managedWorkflowToolContracts.js +30 -27
- package/dist/contracts/nativeToolContracts.js +2 -3
- package/dist/contracts/promptContracts.js +14 -15
- package/dist/contracts/sessionToolSchemas.js +61 -0
- package/dist/contracts/toolContractExamples.js +4 -0
- package/dist/contracts/toolContractHelpers.js +23 -0
- package/dist/contracts/toolContracts.js +12 -67
- package/dist/contracts/toolEffects.js +19 -0
- package/dist/contracts/toolOutputSchemaGroups.js +66 -11
- package/dist/contracts/toolOutputSchemaPrimitives.js +76 -26
- package/dist/contracts/toolSchemaMetadata.js +128 -0
- package/dist/doctorRuntime.js +1 -1
- package/dist/domain/analysisErrorPresentation.js +8 -2
- package/dist/domain/analysisErrorProjection.js +1 -0
- package/dist/domain/androidApplication.js +2 -0
- package/dist/domain/appleApplication.js +2 -0
- package/dist/domain/binaryTarget.js +7 -5
- package/dist/domain/binaryTargetTypes.js +1 -0
- package/dist/domain/browserCaptureComparison.js +21 -69
- package/dist/domain/browserObservation.js +22 -9
- package/dist/domain/bytecodeProvider.js +177 -0
- package/dist/domain/callPath.js +3 -2
- package/dist/domain/conformancePackage.js +169 -0
- package/dist/domain/conformanceReplay.js +104 -0
- package/dist/domain/conformanceTrustGate.js +328 -0
- package/dist/domain/customProtocolCapture.js +137 -0
- package/dist/domain/electronActiveObservation.js +277 -0
- package/dist/domain/electronObservation.js +15 -11
- package/dist/domain/electronStaticAnalysisValues.js +4 -1
- package/dist/domain/eventProcessTree.js +217 -0
- package/dist/domain/evidenceBundle.js +47 -0
- package/dist/domain/functionComparisonNormalization.js +15 -8
- package/dist/domain/functionDossierEvidence.js +9 -4
- package/dist/domain/hopperStartupFailure.js +1 -1
- package/dist/domain/hopperValues.js +68 -68
- package/dist/domain/inputIssueProjection.js +11 -2
- package/dist/domain/investigationWorkspace.js +16 -15
- package/dist/domain/javascriptExportShapeComparisonSchemas.js +2 -2
- package/dist/domain/javascriptReplay.js +79 -63
- package/dist/domain/javascriptRuntimeObservation.js +1 -0
- package/dist/domain/javascriptRuntimeReconciliationActive.js +89 -0
- package/dist/domain/javascriptRuntimeReconciliationGraph.js +11 -10
- package/dist/domain/javascriptRuntimeReconciliationMatching.js +57 -49
- package/dist/domain/javascriptRuntimeReconciliationParsing.js +5 -1
- package/dist/domain/javascriptRuntimeReconciliationResult.js +21 -14
- package/dist/domain/javascriptRuntimeReconciliationSchemas.js +1 -1
- package/dist/domain/javascriptSemanticAnalysis.js +8 -12
- package/dist/domain/javascriptSourceParser.js +15 -0
- package/dist/domain/javascriptStaticAnalysis.js +8 -12
- package/dist/domain/knownPageCoverage.js +15 -7
- package/dist/domain/mobileApplicationInvestigation.js +159 -0
- package/dist/domain/nativeApiBoundary.js +138 -0
- package/dist/domain/nodeRuntimeCharacterization.js +14 -13
- package/dist/domain/objcSwiftMetadata.js +150 -0
- package/dist/domain/packageAnalysis.js +123 -0
- package/dist/domain/peInspection.js +196 -0
- package/dist/domain/processCaptureReactiveValidation.js +8 -3
- package/dist/domain/processCaptureValidation.js +7 -3
- package/dist/domain/processComparison.js +12 -7
- package/dist/domain/processObservation.js +5 -6
- package/dist/domain/processReactiveMatching.js +14 -7
- package/dist/domain/processReactiveTransition.js +9 -3
- package/dist/domain/processScenario.js +6 -3
- package/dist/domain/processTraceComparison.js +3 -2
- package/dist/domain/protocolCapture.js +245 -0
- package/dist/domain/reconstructionReadinessSchemas.js +30 -2
- package/dist/domain/referenceSourceImportParsing.js +2 -2
- package/dist/domain/replayMachineRuntime.js +5 -3
- package/dist/domain/sourceToBundleComparison.js +2 -2
- package/dist/domain/sourceToBundleComparisonSchemas.js +8 -8
- package/dist/domain/sourceToBundleSignals.js +7 -1
- package/dist/domain/staticRuntimeCorrelation.js +7 -5
- package/dist/domain/webBundleAnalysis.js +14 -14
- package/dist/domain/webCaptureDiff.js +15 -12
- package/dist/dotnet/ManagedNativeBoundaryInspector.js +2 -3
- package/dist/dotnet/ManagedStaticProvider.js +34 -5
- package/dist/generatedMcpToolCatalog.js +37 -0
- package/dist/generatedPackageMetadata.js +4 -4
- package/dist/ghidra/GhidraClient.js +1 -1
- package/dist/ghidra/GhidraClientStartup.js +1 -1
- package/dist/ghidra/GhidraDefaults.js +1 -1
- package/dist/ghidra/GhidraFunctionValues.js +44 -16
- package/dist/ghidra/GhidraInventoryValues.js +57 -47
- package/dist/ghidra/GhidraProvider.js +18 -10
- package/dist/ghidra/GhidraProviderCapabilities.js +45 -39
- package/dist/ghidra/GhidraSocketConnection.js +1 -1
- package/dist/ghidra/protocol.js +19 -42
- package/dist/hopper/BridgeLauncher.js +3 -1
- package/dist/hopper/HopperAnalysisProfile.js +2 -4
- package/dist/hopper/HopperCleanup.js +5 -6
- package/dist/hopper/HopperClient.js +27 -3
- package/dist/hopper/HopperProvider.js +42 -44
- package/dist/hopper/HopperRequestQueue.js +32 -4
- package/dist/hopper/HopperResponseStream.js +2 -2
- package/dist/hopper/LinuxPrivateDisplayProbe.js +16 -10
- package/dist/hopper/protocol.js +63 -21
- package/dist/main/reload.js +1 -6
- package/dist/main/state.js +0 -14
- package/dist/main/transport.js +31 -41
- package/dist/main.js +17 -13
- package/dist/mcpDoctor.js +4 -26
- package/dist/mcpStartupPolicy.js +14 -0
- package/dist/process/PrivateRuntimeRoot.js +17 -0
- package/dist/process/ProcessOwnership.js +64 -128
- package/dist/process/ProcessOwnershipIdentity.js +13 -0
- package/dist/process/ProcessOwnershipObservation.js +88 -0
- package/dist/process/ProcessOwnershipProcessTree.js +22 -0
- package/dist/process/ProviderDeadline.js +8 -12
- package/dist/process/WindowsAuthority.js +32 -0
- package/dist/reference/ReferenceSourceReader.js +3 -3
- package/dist/reference/ReferenceSourceReaderEntries.js +2 -2
- package/dist/replay/JavaScriptReplayWorker.js +95 -11
- package/dist/replay/JavaScriptReplayWorkerTypes.js +1 -0
- package/dist/replay/LinuxJavaScriptReplayRunner.js +10 -15
- package/dist/replay/ReplayOutcome.js +26 -15
- package/dist/replay/ReplayWorkerProtocol.js +34 -29
- package/dist/server/createServer.js +101 -144
- package/dist/server/mcpClientMetadata.js +32 -0
- package/dist/server/registerApplicationTools/characterization.js +6 -13
- package/dist/server/registerApplicationTools/compareExportShapes.js +2 -7
- package/dist/server/registerApplicationTools/compareSourceToBundle.js +2 -7
- package/dist/server/registerApplicationTools/compareVersions.js +3 -8
- package/dist/server/registerApplicationTools/controlledReplay.js +6 -11
- package/dist/server/registerApplicationTools/coverage.js +13 -19
- package/dist/server/registerApplicationTools/obligationLedger.js +1 -6
- package/dist/server/registerApplicationTools/readiness.js +1 -6
- package/dist/server/registerApplicationTools/traceFeature.js +3 -8
- package/dist/server/registerApplicationTools/traceSemantics.js +1 -6
- package/dist/server/registerArtifactComparisonTool.js +12 -16
- package/dist/server/registerBrowserScenarioTool.js +1 -6
- package/dist/server/registerBrowserTools.js +37 -79
- package/dist/server/registerBundleComparisonTool.js +10 -14
- package/dist/server/registerCloseLifecycleTool.js +6 -14
- package/dist/server/registerElectronTools.js +30 -47
- package/dist/server/registerEnhancedTools.js +124 -122
- package/dist/server/registerEvidenceResources.js +50 -101
- package/dist/server/registerEvidenceTools.js +5 -9
- package/dist/server/registerFunctionComparisonTool.js +11 -15
- package/dist/server/registerInvestigationTools.js +42 -59
- package/dist/server/registerJavaScriptApplicationGraphResource.js +0 -4
- package/dist/server/registerJavaScriptRuntimeObservationTools.js +13 -27
- package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +4 -9
- package/dist/server/registerManagedWorkflowTools/contract.js +2 -3
- package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +3 -8
- package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +3 -8
- package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +8 -13
- package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +4 -9
- package/dist/server/registerOfficialTools.js +8 -9
- package/dist/server/registerProcessComparisonTool.js +19 -24
- package/dist/server/registerReconstructionObligationLedgerResource.js +0 -7
- package/dist/server/registerReconstructionReadinessResource.js +0 -7
- package/dist/server/registerReplayMachineTool.js +4 -10
- package/dist/server/registerSessionRecordTools.js +146 -47
- package/dist/server/registerSessionStatusTool.js +14 -29
- package/dist/server/registerSessionTools.js +45 -41
- package/dist/server/sessionAvailabilityPolicy.js +2 -1
- package/dist/server/sessionToolPolicies.js +1 -5
- package/dist/server/toolRegistrationOptions.js +4 -177
- package/dist/server/toolResult.js +14 -18
- package/package.json +35 -16
- package/scripts/electron-active-hook-boundaries.cjs +394 -0
- package/scripts/electron-active-hook.cjs +501 -0
- package/skills/reverse-engineer-anything/SKILL.md +10 -3
- package/dist/server/DynamicToolAvailability.js +0 -70
- package/dist/server/toolInputValidation.js +0 -77
|
@@ -125,13 +125,20 @@ const matchTerminalText = (trigger, context) => {
|
|
|
125
125
|
overflow: false,
|
|
126
126
|
};
|
|
127
127
|
};
|
|
128
|
-
const mergeMatches = (matches) =>
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
})
|
|
128
|
+
const mergeMatches = (matches) => {
|
|
129
|
+
const base = {
|
|
130
|
+
eventIds: [...new Set(matches.flatMap(({ eventIds }) => eventIds))],
|
|
131
|
+
consumeIds: [...new Set(matches.flatMap(({ consumeIds }) => consumeIds))],
|
|
132
|
+
lastOrder: Math.max(-1, ...matches.map(({ lastOrder }) => lastOrder)),
|
|
133
|
+
};
|
|
134
|
+
return matches.every(({ matched }) => matched)
|
|
135
|
+
? { ...base, matched: true, overflow: false }
|
|
136
|
+
: {
|
|
137
|
+
...base,
|
|
138
|
+
matched: false,
|
|
139
|
+
overflow: matches.some(({ overflow }) => overflow),
|
|
140
|
+
};
|
|
141
|
+
};
|
|
135
142
|
const matchEarliestPrefix = (trigger, context) => {
|
|
136
143
|
for (const observation of context.snapshot.observations) {
|
|
137
144
|
if (observation.capture_order <= context.afterOrder)
|
|
@@ -11,6 +11,8 @@ const incrementCounter = (counters, id) => {
|
|
|
11
11
|
};
|
|
12
12
|
/** Commit one uniquely selected transition after its declarative effects succeed. */
|
|
13
13
|
const applyProcessReactiveTransition = (input) => {
|
|
14
|
+
if (input.effectResults.length !== input.transition.actions.length)
|
|
15
|
+
throw new TypeError("Reactive transition effects do not match the admitted actions");
|
|
14
16
|
const outcome = input.transition.target.kind === "finish"
|
|
15
17
|
? input.transition.target.outcome
|
|
16
18
|
: null;
|
|
@@ -31,13 +33,17 @@ const applyProcessReactiveTransition = (input) => {
|
|
|
31
33
|
for (const eventId of input.consumeEventIds)
|
|
32
34
|
consumed.add(eventId);
|
|
33
35
|
const checkpoints = [...input.snapshot.checkpoints];
|
|
34
|
-
for (const [index, action] of input.transition.actions.entries())
|
|
36
|
+
for (const [index, action] of input.transition.actions.entries()) {
|
|
37
|
+
const effect = input.effectResults[index];
|
|
38
|
+
if (effect === undefined)
|
|
39
|
+
throw new TypeError("Reactive transition effect is missing");
|
|
35
40
|
if (action.type === "checkpoint")
|
|
36
41
|
checkpoints.push({
|
|
37
42
|
name: action.name,
|
|
38
|
-
event_id:
|
|
39
|
-
capture_order:
|
|
43
|
+
event_id: effect.observation.event_id,
|
|
44
|
+
capture_order: effect.observation.capture_order,
|
|
40
45
|
});
|
|
46
|
+
}
|
|
41
47
|
const completedCaptureOrder = Math.max(input.observation.capture_order, ...input.effectResults.map(({ observation }) => observation.capture_order));
|
|
42
48
|
let next = {
|
|
43
49
|
...input.snapshot,
|
|
@@ -283,7 +283,9 @@ export const processScenarioSchema = z
|
|
|
283
283
|
.strict()
|
|
284
284
|
.superRefine((scenario, context) => {
|
|
285
285
|
for (let index = 1; index < scenario.events.length; index += 1) {
|
|
286
|
-
|
|
286
|
+
const event = scenario.events[index];
|
|
287
|
+
const previous = scenario.events[index - 1];
|
|
288
|
+
if (eventsOutOfOrder(event, previous)) {
|
|
287
289
|
context.addIssue({
|
|
288
290
|
code: "custom",
|
|
289
291
|
message: "events must be ordered by at_ms",
|
|
@@ -361,15 +363,16 @@ export const processScenarioSchema = z
|
|
|
361
363
|
path: ["replay"],
|
|
362
364
|
});
|
|
363
365
|
});
|
|
366
|
+
const eventsOutOfOrder = (event, previous) => event !== undefined && previous !== undefined && event.at_ms < previous.at_ms;
|
|
364
367
|
/** Parse untrusted process scenario input and apply safe default budgets. */
|
|
365
368
|
export const parseProcessScenario = (input) => processScenarioSchema.parse(input);
|
|
366
369
|
const isWithin = (candidate, root) => resolve(candidate) === resolve(root) ||
|
|
367
370
|
resolve(candidate).startsWith(`${resolve(root)}${resolve(root).endsWith("/") ? "" : "/"}`);
|
|
368
371
|
/** Evaluate scenario authority before any process or filesystem side effect occurs. */
|
|
369
372
|
export const authorizeProcessScenario = (scenario, policy) => {
|
|
370
|
-
if (
|
|
373
|
+
if (policy.status === "disabled")
|
|
371
374
|
return { allowed: false, reason: "process capture is disabled" };
|
|
372
|
-
if (scenario.network_access === "host" &&
|
|
375
|
+
if (scenario.network_access === "host" && policy.networkAccess === "none")
|
|
373
376
|
return {
|
|
374
377
|
allowed: false,
|
|
375
378
|
reason: "host network access is not approved by operator policy",
|
|
@@ -9,8 +9,9 @@ export const compareProcessTraces = (left, right, specificationInput) => {
|
|
|
9
9
|
...validateProcessCapture(left),
|
|
10
10
|
...validateProcessCapture(right),
|
|
11
11
|
];
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
const firstCaptureIssue = captureIssues.at(0);
|
|
13
|
+
if (firstCaptureIssue !== undefined)
|
|
14
|
+
throw new TypeError(`Invalid Process Capture v4: ${firstCaptureIssue.path}`);
|
|
14
15
|
const specification = processTraceSpecificationSchema.parse(specificationInput);
|
|
15
16
|
const leftEvaluation = evaluateProcessTraceSide(left, specification);
|
|
16
17
|
const rightEvaluation = evaluateProcessTraceSide(right, specification);
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { jsonValueSchema } from "./jsonValue.js";
|
|
3
|
+
/** Supported protocol families for structured protocol capture. */
|
|
4
|
+
export const protocolFamilySchema = z.enum([
|
|
5
|
+
"grpc",
|
|
6
|
+
"protobuf",
|
|
7
|
+
"json-rpc",
|
|
8
|
+
"messagepack",
|
|
9
|
+
]);
|
|
10
|
+
/** A decoded field from a protocol message. */
|
|
11
|
+
export const decodedFieldSchema = z.strictObject({
|
|
12
|
+
/** Field name or path within the message structure. */
|
|
13
|
+
path: z.string().min(1),
|
|
14
|
+
/** Wire type or encoding hint. */
|
|
15
|
+
wire_type: z.string().nullable(),
|
|
16
|
+
/** Decoded field value. */
|
|
17
|
+
value: jsonValueSchema.nullable(),
|
|
18
|
+
/** Whether this field value was inferred rather than decoded. */
|
|
19
|
+
inferred: z.boolean().default(false),
|
|
20
|
+
});
|
|
21
|
+
/** Schema inference hypothesis for a repeated message pattern. */
|
|
22
|
+
export const schemaHypothesisSchema = z.strictObject({
|
|
23
|
+
/** Hypothesized field name. */
|
|
24
|
+
field_name: z.string().min(1),
|
|
25
|
+
/** Inferred type. */
|
|
26
|
+
inferred_type: z.string().min(1),
|
|
27
|
+
/** Confidence: 0-1 */
|
|
28
|
+
confidence: z.number().min(0).max(1),
|
|
29
|
+
/** Supporting evidence count. */
|
|
30
|
+
evidence_count: z.number().int().nonnegative(),
|
|
31
|
+
});
|
|
32
|
+
/** Result of decoding a single protocol message. */
|
|
33
|
+
export const protocolMessageSchema = z.strictObject({
|
|
34
|
+
/** Monotonic sequence number. */
|
|
35
|
+
sequence: z.number().int().nonnegative(),
|
|
36
|
+
/** Timestamp in milliseconds. */
|
|
37
|
+
at_ms: z.number().int().nonnegative(),
|
|
38
|
+
/** Protocol family. */
|
|
39
|
+
family: protocolFamilySchema,
|
|
40
|
+
/** Direction of the message. */
|
|
41
|
+
direction: z.enum(["request", "response"]),
|
|
42
|
+
/** Transport endpoint or path (e.g. gRPC method path). */
|
|
43
|
+
endpoint: z.string().nullable(),
|
|
44
|
+
/** Content type of the raw payload. */
|
|
45
|
+
content_type: z.string().nullable(),
|
|
46
|
+
/** Raw payload bytes as base64. */
|
|
47
|
+
raw_payload: z.string().nullable(),
|
|
48
|
+
/** Decoded fields from the payload. */
|
|
49
|
+
decoded_fields: z.array(decodedFieldSchema).default([]),
|
|
50
|
+
/** Inferred schema hypotheses. */
|
|
51
|
+
schema_hypotheses: z.array(schemaHypothesisSchema).default([]),
|
|
52
|
+
/** Whether decoding was truncated. */
|
|
53
|
+
truncated: z.boolean().default(false),
|
|
54
|
+
/** Whether credentials were detected and redacted. */
|
|
55
|
+
credentials_redacted: z.boolean().default(false),
|
|
56
|
+
});
|
|
57
|
+
/** A captured protocol session with messages and inferred schemas. */
|
|
58
|
+
export const protocolCaptureSchema = z.strictObject({
|
|
59
|
+
/** Protocol family for this capture. */
|
|
60
|
+
family: protocolFamilySchema,
|
|
61
|
+
/** Captured messages in order. */
|
|
62
|
+
messages: z.array(protocolMessageSchema).min(0).max(10_000),
|
|
63
|
+
/** Aggregated schema hypotheses across all messages. */
|
|
64
|
+
inferred_schema: z.array(schemaHypothesisSchema).default([]),
|
|
65
|
+
/** Whether any message was truncated. */
|
|
66
|
+
has_truncated: z.boolean().default(false),
|
|
67
|
+
/** Whether credentials were detected and redacted. */
|
|
68
|
+
credentials_detected: z.boolean().default(false),
|
|
69
|
+
});
|
|
70
|
+
/** Classification of a byte sequence as a known protocol family. */
|
|
71
|
+
export function classifyProtocolFamily(contentType, path) {
|
|
72
|
+
if (contentType) {
|
|
73
|
+
if (contentType.includes("application/grpc"))
|
|
74
|
+
return "grpc";
|
|
75
|
+
if (contentType.includes("application/x-protobuf"))
|
|
76
|
+
return "protobuf";
|
|
77
|
+
if (contentType.includes("application/json-rpc"))
|
|
78
|
+
return "json-rpc";
|
|
79
|
+
if (contentType.includes("application/msgpack") ||
|
|
80
|
+
contentType.includes("application/x-msgpack"))
|
|
81
|
+
return "messagepack";
|
|
82
|
+
}
|
|
83
|
+
if (path) {
|
|
84
|
+
if (path.startsWith("/grpc.") || path.includes("/grpc/"))
|
|
85
|
+
return "grpc";
|
|
86
|
+
if (path.includes("/json-rpc") || path.includes("/jsonrpc"))
|
|
87
|
+
return "json-rpc";
|
|
88
|
+
}
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
/** Credential-like field names that should be redacted. */
|
|
92
|
+
const CREDENTIAL_PATTERNS = [
|
|
93
|
+
"password",
|
|
94
|
+
"passwd",
|
|
95
|
+
"secret",
|
|
96
|
+
"token",
|
|
97
|
+
"api_key",
|
|
98
|
+
"apikey",
|
|
99
|
+
"authorization",
|
|
100
|
+
"auth",
|
|
101
|
+
"credential",
|
|
102
|
+
"private_key",
|
|
103
|
+
];
|
|
104
|
+
/** Check if a field path looks like it may contain credentials. */
|
|
105
|
+
export function looksLikeCredential(path) {
|
|
106
|
+
const lower = path.toLowerCase();
|
|
107
|
+
return CREDENTIAL_PATTERNS.some((p) => lower.includes(p));
|
|
108
|
+
}
|
|
109
|
+
/** Decode a JSON-RPC message from raw payload bytes. */
|
|
110
|
+
export function decodeJsonRpc(rawPayload) {
|
|
111
|
+
const text = new TextDecoder().decode(rawPayload);
|
|
112
|
+
const parsed = jsonValueSchema.parse(JSON.parse(text));
|
|
113
|
+
const fields = [];
|
|
114
|
+
if (typeof parsed === "object" && parsed !== null) {
|
|
115
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
116
|
+
if (looksLikeCredential(key)) {
|
|
117
|
+
fields.push({
|
|
118
|
+
path: key,
|
|
119
|
+
wire_type: "json",
|
|
120
|
+
value: "[REDACTED]",
|
|
121
|
+
inferred: false,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
fields.push({
|
|
126
|
+
path: key,
|
|
127
|
+
wire_type: "json",
|
|
128
|
+
value,
|
|
129
|
+
inferred: false,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return { decoded_fields: fields, truncated: false };
|
|
135
|
+
}
|
|
136
|
+
/** Decode a MessagePack message (simplified: only checks basic structure). */
|
|
137
|
+
export function decodeMessagePack(rawPayload) {
|
|
138
|
+
const fields = [];
|
|
139
|
+
// MessagePack uses a single-byte type tag
|
|
140
|
+
if (rawPayload.length === 0) {
|
|
141
|
+
return { decoded_fields: [], truncated: false };
|
|
142
|
+
}
|
|
143
|
+
const tag = rawPayload[0];
|
|
144
|
+
if (tag === undefined)
|
|
145
|
+
return { decoded_fields: [], truncated: false };
|
|
146
|
+
// Map type: 0x80-0x8f (fixmap), 0xde (map16), 0xdf (map32)
|
|
147
|
+
if ((tag >= 0x80 && tag <= 0x8f) || tag === 0xde || tag === 0xdf) {
|
|
148
|
+
fields.push({
|
|
149
|
+
path: "type",
|
|
150
|
+
wire_type: "msgpack",
|
|
151
|
+
value: "map",
|
|
152
|
+
inferred: false,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
// Array type: 0x90-0x9f (fixarray), 0xdc (array16), 0xdd (array32)
|
|
156
|
+
else if ((tag >= 0x90 && tag <= 0x9f) || tag === 0xdc || tag === 0xdd) {
|
|
157
|
+
fields.push({
|
|
158
|
+
path: "type",
|
|
159
|
+
wire_type: "msgpack",
|
|
160
|
+
value: "array",
|
|
161
|
+
inferred: false,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
fields.push({
|
|
166
|
+
path: "type",
|
|
167
|
+
wire_type: "msgpack",
|
|
168
|
+
value: "unknown",
|
|
169
|
+
inferred: true,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
return {
|
|
173
|
+
decoded_fields: fields,
|
|
174
|
+
truncated: rawPayload.length > 10_000,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
/** Decode a gRPC frame (5-byte header + protobuf payload). */
|
|
178
|
+
export function decodeGrpcFrame(rawPayload) {
|
|
179
|
+
// gRPC uses a 5-byte prefix: 1 byte compressed flag + 4 byte length
|
|
180
|
+
if (rawPayload.length < 5) {
|
|
181
|
+
return {
|
|
182
|
+
decoded_fields: [
|
|
183
|
+
{
|
|
184
|
+
path: "error",
|
|
185
|
+
wire_type: "grpc",
|
|
186
|
+
value: "frame too short",
|
|
187
|
+
inferred: false,
|
|
188
|
+
},
|
|
189
|
+
],
|
|
190
|
+
truncated: false,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
const compressed = rawPayload[0] !== 0;
|
|
194
|
+
const length = ((rawPayload[1] ?? 0) << 24) |
|
|
195
|
+
((rawPayload[2] ?? 0) << 16) |
|
|
196
|
+
((rawPayload[3] ?? 0) << 8) |
|
|
197
|
+
(rawPayload[4] ?? 0);
|
|
198
|
+
return {
|
|
199
|
+
decoded_fields: [
|
|
200
|
+
{
|
|
201
|
+
path: "compressed",
|
|
202
|
+
wire_type: "grpc",
|
|
203
|
+
value: compressed,
|
|
204
|
+
inferred: false,
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
path: "message_length",
|
|
208
|
+
wire_type: "grpc",
|
|
209
|
+
value: length,
|
|
210
|
+
inferred: false,
|
|
211
|
+
},
|
|
212
|
+
],
|
|
213
|
+
truncated: length > 10_000,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
/** Infer schema hypotheses from a set of decoded messages. */
|
|
217
|
+
export function inferMessageSchema(messages) {
|
|
218
|
+
const fieldCounts = new Map();
|
|
219
|
+
for (const msg of messages) {
|
|
220
|
+
for (const field of msg.decoded_fields) {
|
|
221
|
+
const existing = fieldCounts.get(field.path);
|
|
222
|
+
if (existing) {
|
|
223
|
+
existing.count++;
|
|
224
|
+
if (field.wire_type)
|
|
225
|
+
existing.types.add(field.wire_type);
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
fieldCounts.set(field.path, {
|
|
229
|
+
count: 1,
|
|
230
|
+
types: new Set(field.wire_type ?? "unknown"),
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
const hypotheses = [];
|
|
236
|
+
for (const [field_name, data] of fieldCounts) {
|
|
237
|
+
hypotheses.push({
|
|
238
|
+
field_name,
|
|
239
|
+
inferred_type: [...data.types].join("|"),
|
|
240
|
+
confidence: Math.min(1, data.count / messages.length || 0),
|
|
241
|
+
evidence_count: data.count,
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
return hypotheses;
|
|
245
|
+
}
|
|
@@ -197,7 +197,21 @@ export const reconstructionReadinessInputSchema = z.strictObject({
|
|
|
197
197
|
closure_history: z.array(closureObservationSchema).min(2).max(1_000),
|
|
198
198
|
delegation_checks: z.array(delegationCheckSchema).min(1).max(1_000),
|
|
199
199
|
replay: replaySchema,
|
|
200
|
-
stages: z
|
|
200
|
+
stages: z
|
|
201
|
+
.array(stageSchema)
|
|
202
|
+
.length(9)
|
|
203
|
+
.superRefine((stages, context) => {
|
|
204
|
+
const seen = new Set();
|
|
205
|
+
stages.forEach((stage, index) => {
|
|
206
|
+
if (seen.has(stage.stage_id))
|
|
207
|
+
context.addIssue({
|
|
208
|
+
code: "custom",
|
|
209
|
+
path: [index, "stage_id"],
|
|
210
|
+
message: "Readiness stage IDs must be unique",
|
|
211
|
+
});
|
|
212
|
+
seen.add(stage.stage_id);
|
|
213
|
+
});
|
|
214
|
+
}),
|
|
201
215
|
});
|
|
202
216
|
const findingSchema = z.strictObject({
|
|
203
217
|
code: stableIdSchema,
|
|
@@ -233,7 +247,21 @@ export const reconstructionReadinessReportSchema = z.strictObject({
|
|
|
233
247
|
cleanup_leak_count: z.number().int().min(0),
|
|
234
248
|
nondeterministic_replay_count: z.number().int().min(0),
|
|
235
249
|
}),
|
|
236
|
-
stages: z
|
|
250
|
+
stages: z
|
|
251
|
+
.array(stageSchema)
|
|
252
|
+
.length(9)
|
|
253
|
+
.superRefine((stages, context) => {
|
|
254
|
+
const seen = new Set();
|
|
255
|
+
stages.forEach((stage, index) => {
|
|
256
|
+
if (seen.has(stage.stage_id))
|
|
257
|
+
context.addIssue({
|
|
258
|
+
code: "custom",
|
|
259
|
+
path: [index, "stage_id"],
|
|
260
|
+
message: "Readiness stage IDs must be unique",
|
|
261
|
+
});
|
|
262
|
+
seen.add(stage.stage_id);
|
|
263
|
+
});
|
|
264
|
+
}),
|
|
237
265
|
findings: z.array(findingSchema).max(10_000),
|
|
238
266
|
evidence_links: z.array(evidenceIdSchema).max(100_000),
|
|
239
267
|
snapshot: reconstructionReadinessInputSchema,
|
|
@@ -199,11 +199,11 @@ const parseWithBabel = (path, source, language) => {
|
|
|
199
199
|
});
|
|
200
200
|
return { ast, parseState: "parsed" };
|
|
201
201
|
}
|
|
202
|
-
catch (
|
|
202
|
+
catch (cause) {
|
|
203
203
|
return {
|
|
204
204
|
ast: undefined,
|
|
205
205
|
parseState: "unknown",
|
|
206
|
-
reason:
|
|
206
|
+
reason: cause instanceof Error ? cause.message : "Parse failed",
|
|
207
207
|
};
|
|
208
208
|
}
|
|
209
209
|
};
|
|
@@ -20,7 +20,7 @@ const replayEventHeadersSchema = z
|
|
|
20
20
|
});
|
|
21
21
|
});
|
|
22
22
|
const replayEventFields = {
|
|
23
|
-
at_ms: z.number().int().
|
|
23
|
+
at_ms: z.number().int().safe().nonnegative(),
|
|
24
24
|
path: z.string().startsWith("/").max(8_192),
|
|
25
25
|
headers: replayEventHeadersSchema,
|
|
26
26
|
body: z.string().max(1_000_000),
|
|
@@ -51,7 +51,8 @@ export const replayMachineEventSchema = z.discriminatedUnion("protocol", [
|
|
|
51
51
|
]);
|
|
52
52
|
const parseJson = (value) => {
|
|
53
53
|
try {
|
|
54
|
-
|
|
54
|
+
const parsed = JSON.parse(value);
|
|
55
|
+
return parsed;
|
|
55
56
|
}
|
|
56
57
|
catch {
|
|
57
58
|
return undefined;
|
|
@@ -70,7 +71,8 @@ const atPath = (value, path) => {
|
|
|
70
71
|
current === null ||
|
|
71
72
|
!Object.hasOwn(current, segment))
|
|
72
73
|
return undefined;
|
|
73
|
-
|
|
74
|
+
const next = Reflect.get(current, segment);
|
|
75
|
+
current = next;
|
|
74
76
|
}
|
|
75
77
|
return current;
|
|
76
78
|
};
|
|
@@ -135,8 +135,8 @@ const comparisonCoverage = (projection, mappings, factors) => ({
|
|
|
135
135
|
const scoringModel = () => ({
|
|
136
136
|
algorithm: "rea-source-to-bundle-signals/v1",
|
|
137
137
|
minimum_candidate_score: 20,
|
|
138
|
-
weights:
|
|
139
|
-
signal
|
|
138
|
+
weights: SOURCE_TO_BUNDLE_SIGNAL_WEIGHTS.map(([signal, weight]) => ({
|
|
139
|
+
signal,
|
|
140
140
|
weight,
|
|
141
141
|
})),
|
|
142
142
|
});
|
|
@@ -6,14 +6,14 @@ const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
|
|
|
6
6
|
const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
|
|
7
7
|
const nodeIdSchema = z.string().regex(/^jag_node_[a-f0-9]{64}$/u);
|
|
8
8
|
const boundedTextSchema = z.string().min(1).max(4_096);
|
|
9
|
-
export const SOURCE_TO_BUNDLE_SIGNAL_WEIGHTS =
|
|
10
|
-
"exact-source-digest"
|
|
11
|
-
"source-map-original-path"
|
|
12
|
-
"current-path-exact"
|
|
13
|
-
"current-path-suffix"
|
|
14
|
-
"basename-match"
|
|
15
|
-
"language-extension"
|
|
16
|
-
|
|
9
|
+
export const SOURCE_TO_BUNDLE_SIGNAL_WEIGHTS = [
|
|
10
|
+
["exact-source-digest", 100],
|
|
11
|
+
["source-map-original-path", 70],
|
|
12
|
+
["current-path-exact", 60],
|
|
13
|
+
["current-path-suffix", 40],
|
|
14
|
+
["basename-match", 20],
|
|
15
|
+
["language-extension", 5],
|
|
16
|
+
];
|
|
17
17
|
const sourceToBundleSignalKindSchema = z.enum([
|
|
18
18
|
"exact-source-digest",
|
|
19
19
|
"source-map-original-path",
|
|
@@ -14,6 +14,12 @@ const PATH_PROPERTIES = [
|
|
|
14
14
|
"declared_path",
|
|
15
15
|
];
|
|
16
16
|
const MAX_PATH_SUFFIXES = 128;
|
|
17
|
+
const signalWeight = (kind) => {
|
|
18
|
+
const entry = SOURCE_TO_BUNDLE_SIGNAL_WEIGHTS.find(([signal]) => signal === kind);
|
|
19
|
+
if (entry === undefined)
|
|
20
|
+
throw new TypeError(`Missing source-to-bundle signal weight: ${kind}`);
|
|
21
|
+
return entry[1];
|
|
22
|
+
};
|
|
17
23
|
/** Keep source-bearing application nodes in stable identifier order. */
|
|
18
24
|
export const sourceBearingNodes = (nodes) => nodes
|
|
19
25
|
.filter(({ kind }) => RELEVANT_NODE_KINDS.has(kind))
|
|
@@ -145,7 +151,7 @@ const candidateSignals = (source, current) => {
|
|
|
145
151
|
};
|
|
146
152
|
const signal = (kind, sourceValue, currentValues) => ({
|
|
147
153
|
kind,
|
|
148
|
-
weight:
|
|
154
|
+
weight: signalWeight(kind),
|
|
149
155
|
source_value: sourceValue,
|
|
150
156
|
current_values: [...new Set(currentValues)].sort(compareText).slice(0, 64),
|
|
151
157
|
});
|
|
@@ -242,11 +242,12 @@ const selectStatic = (evidence, selector) => {
|
|
|
242
242
|
throw new TypeError("Function selector requires function comparison Evidence");
|
|
243
243
|
const result = functionComparisonResultSchema.parse(evidence.normalized_result);
|
|
244
244
|
const matches = result.dimensions.filter(({ dimension }) => dimension === selector.dimension);
|
|
245
|
-
|
|
245
|
+
const match = matches.at(0);
|
|
246
|
+
if (matches.length !== 1 || match === undefined)
|
|
246
247
|
throw new TypeError("Function selector must resolve exactly once");
|
|
247
248
|
return {
|
|
248
|
-
status:
|
|
249
|
-
conclusion_kind:
|
|
249
|
+
status: match.status,
|
|
250
|
+
conclusion_kind: match.conclusion_kind,
|
|
250
251
|
};
|
|
251
252
|
}
|
|
252
253
|
if (evidence.operation !== "compare_artifacts")
|
|
@@ -257,9 +258,10 @@ const selectStatic = (evidence, selector) => {
|
|
|
257
258
|
result.changes.items.length !== result.changes.total)
|
|
258
259
|
throw new TypeError("Static/runtime correlation requires complete artifact comparison pagination");
|
|
259
260
|
const matches = result.changes.items.filter(({ logical_path: path }) => path === selector.logical_path);
|
|
260
|
-
|
|
261
|
+
const match = matches.at(0);
|
|
262
|
+
if (matches.length !== 1 || match === undefined)
|
|
261
263
|
throw new TypeError("Artifact selector must resolve exactly one reported delta");
|
|
262
|
-
const status =
|
|
264
|
+
const status = match.classification;
|
|
263
265
|
return {
|
|
264
266
|
status,
|
|
265
267
|
conclusion_kind: status === "contradiction"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import {
|
|
2
|
+
import { inspectWebPageWithSourceInputSchema } from "./browserObservation.js";
|
|
3
3
|
import { webTextArtifactSchema } from "./webContentArtifact.js";
|
|
4
4
|
const webBundleLimitsSchema = z.object({
|
|
5
5
|
max_findings: z.number().int().min(1).max(10_000).default(1_000),
|
|
@@ -21,12 +21,7 @@ const webBundleLimitsSchema = z.object({
|
|
|
21
21
|
max_original_sources: z.number().int().min(1).max(20_000).default(2_000),
|
|
22
22
|
});
|
|
23
23
|
/** Capture-and-analyze input with separate source and source-map approvals. */
|
|
24
|
-
|
|
25
|
-
.safeExtend({
|
|
26
|
-
include_script_sources: z.literal(true).default(true),
|
|
27
|
-
source_capture_approved: z.literal(true),
|
|
28
|
-
fetch_source_maps: z.boolean().default(false),
|
|
29
|
-
source_map_fetch_approved: z.boolean().default(false),
|
|
24
|
+
const analyzeWebBundleFactsSchema = inspectWebPageWithSourceInputSchema.safeExtend({
|
|
30
25
|
analysis_limits: webBundleLimitsSchema.default({
|
|
31
26
|
max_findings: 1_000,
|
|
32
27
|
max_ast_nodes: 250_000,
|
|
@@ -36,14 +31,19 @@ export const analyzeWebBundleInputSchema = inspectWebPageInputSchema
|
|
|
36
31
|
max_source_map_mappings: 10_000,
|
|
37
32
|
max_original_sources: 2_000,
|
|
38
33
|
}),
|
|
39
|
-
})
|
|
34
|
+
});
|
|
35
|
+
export const analyzeWebBundleInputSchema = z
|
|
36
|
+
.union([
|
|
37
|
+
analyzeWebBundleFactsSchema.safeExtend({
|
|
38
|
+
fetch_source_maps: z.literal(false).default(false),
|
|
39
|
+
source_map_fetch_approved: z.literal(false).default(false),
|
|
40
|
+
}),
|
|
41
|
+
analyzeWebBundleFactsSchema.safeExtend({
|
|
42
|
+
fetch_source_maps: z.literal(true),
|
|
43
|
+
source_map_fetch_approved: z.literal(true),
|
|
44
|
+
}),
|
|
45
|
+
])
|
|
40
46
|
.superRefine((input, context) => {
|
|
41
|
-
if (input.fetch_source_maps && !input.source_map_fetch_approved)
|
|
42
|
-
context.addIssue({
|
|
43
|
-
code: "custom",
|
|
44
|
-
path: ["source_map_fetch_approved"],
|
|
45
|
-
message: "Source-map network fetch requires separate approval",
|
|
46
|
-
});
|
|
47
47
|
if (input.analysis_limits.max_source_map_bytes >
|
|
48
48
|
input.analysis_limits.max_total_source_map_bytes)
|
|
49
49
|
context.addIssue({
|
|
@@ -228,20 +228,23 @@ const accessibilityComparable = (inspection) => {
|
|
|
228
228
|
return { text, nodes, complete };
|
|
229
229
|
};
|
|
230
230
|
const accessibilityProjection = (accessibility, includeText, includeNodes) => {
|
|
231
|
-
const result = {
|
|
232
|
-
total_nodes: accessibility.total_nodes,
|
|
233
|
-
};
|
|
234
231
|
if (!includeNodes)
|
|
235
|
-
return
|
|
232
|
+
return { total_nodes: accessibility.total_nodes };
|
|
236
233
|
const nodeIndexes = new Map(accessibility.nodes.map((node, index) => [node.node_id, index]));
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
234
|
+
return {
|
|
235
|
+
total_nodes: accessibility.total_nodes,
|
|
236
|
+
nodes: accessibility.nodes.map((node) => ({
|
|
237
|
+
parent_index: node.parent_id === null
|
|
238
|
+
? null
|
|
239
|
+
: (nodeIndexes.get(node.parent_id) ?? -1),
|
|
240
|
+
role: node.role,
|
|
241
|
+
ignored: node.ignored,
|
|
242
|
+
states: node.states,
|
|
243
|
+
...(includeText
|
|
244
|
+
? { name: node.name, description: node.description }
|
|
245
|
+
: {}),
|
|
246
|
+
})),
|
|
247
|
+
};
|
|
245
248
|
};
|
|
246
249
|
const storageKeysComparable = (inspection) => sectionsComplete(inspection, ["storage_keys"]);
|
|
247
250
|
const storageComparable = (before, after, keysComplete, usageComplete) => keysComplete &&
|
|
@@ -59,8 +59,7 @@ const emptyInspection = (target, bytes, classification, issues = []) => managedN
|
|
|
59
59
|
"Static inspection does not load or execute target code, so native export resolution is not performed.",
|
|
60
60
|
],
|
|
61
61
|
});
|
|
62
|
-
const readBoundaryInventory = (bytes, pe, limits) => {
|
|
63
|
-
const cli = pe.cli;
|
|
62
|
+
const readBoundaryInventory = (bytes, pe, cli, limits) => {
|
|
64
63
|
const metadataOffset = pe.rvaToOffset(cli.metadata.rva, cli.metadata.size, "cli.metadata");
|
|
65
64
|
const layout = readManagedMetadataLayout(bytes, metadataOffset, cli.metadata.size, limits.maxTableRows);
|
|
66
65
|
const resourceDirectory = {
|
|
@@ -104,7 +103,7 @@ export const inspectManagedNativeBoundariesBytes = (bytes, target, limits) => {
|
|
|
104
103
|
let layout;
|
|
105
104
|
let inventory;
|
|
106
105
|
try {
|
|
107
|
-
({ layout, inventory } = readBoundaryInventory(bytes, pe, limits));
|
|
106
|
+
({ layout, inventory } = readBoundaryInventory(bytes, pe, pe.cli, limits));
|
|
108
107
|
}
|
|
109
108
|
catch (cause) {
|
|
110
109
|
if (!(cause instanceof ManagedReaderFailure))
|