rea-agents 3.0.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -16
- package/dist/application/AnalysisContextQueries.js +21 -9
- 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 +14 -16
- package/dist/application/BinarySessionRecords.js +31 -5
- 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 +134 -63
- package/dist/application/CrossVersionInventory.js +7 -6
- 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 +22 -20
- package/dist/application/EvidenceBundleCommands.js +5 -1
- package/dist/application/EvidenceLedger.js +8 -1
- package/dist/application/JavaScriptReplayPermission.js +1 -1
- package/dist/application/JavaScriptReplayService.js +23 -15
- package/dist/application/ManagedRuntimeCorrelationService.js +9 -5
- 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/SetupClientConfiguration.js +6 -1
- package/dist/application/WindowsCapabilities.js +5 -4
- 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/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 +12 -6
- 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 +1 -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 +27 -34
- package/dist/contracts/browserToolContracts.js +2 -2
- package/dist/contracts/electronToolContracts.js +30 -1
- package/dist/contracts/enhancedInputs.js +13 -29
- package/dist/contracts/functionWorkflowToolContracts.js +2 -3
- 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/sessionToolSchemas.js +61 -0
- package/dist/contracts/toolContractExamples.js +1 -0
- package/dist/contracts/toolContractHelpers.js +23 -0
- package/dist/contracts/toolContracts.js +5 -77
- package/dist/contracts/toolEffects.js +15 -0
- package/dist/contracts/toolOutputSchemaGroups.js +17 -2
- package/dist/contracts/toolOutputSchemaPrimitives.js +76 -26
- package/dist/contracts/toolSchemaMetadata.js +128 -0
- package/dist/doctorRuntime.js +1 -1
- 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 +33 -35
- package/dist/domain/callPath.js +3 -2
- package/dist/domain/conformanceReplay.js +3 -3
- package/dist/domain/conformanceTrustGate.js +151 -16
- package/dist/domain/customProtocolCapture.js +3 -3
- 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 +82 -79
- package/dist/domain/functionComparisonNormalization.js +15 -8
- package/dist/domain/functionDossierEvidence.js +9 -4
- package/dist/domain/hopperValues.js +68 -71
- package/dist/domain/inputIssueProjection.js +4 -1
- 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/knownPageCoverage.js +15 -7
- package/dist/domain/nativeApiBoundary.js +15 -7
- package/dist/domain/nodeRuntimeCharacterization.js +14 -13
- 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 +8 -6
- 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/generatedMcpToolCatalog.js +1 -1
- package/dist/generatedPackageMetadata.js +1 -1
- package/dist/ghidra/GhidraClient.js +1 -1
- package/dist/ghidra/GhidraClientStartup.js +1 -1
- package/dist/ghidra/GhidraFunctionValues.js +17 -15
- package/dist/ghidra/GhidraInventoryValues.js +57 -47
- package/dist/ghidra/GhidraProvider.js +18 -10
- package/dist/ghidra/GhidraProviderCapabilities.js +5 -1
- 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 +1 -1
- package/dist/hopper/HopperProvider.js +0 -14
- package/dist/hopper/LinuxPrivateDisplayProbe.js +16 -10
- package/dist/main/reload.js +1 -6
- package/dist/main/state.js +0 -14
- package/dist/main/transport.js +30 -37
- package/dist/main.js +17 -15
- package/dist/mcpDoctor.js +2 -24
- 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 +158 -94
- 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 +114 -122
- package/dist/server/registerEvidenceTools.js +5 -9
- package/dist/server/registerFunctionComparisonTool.js +11 -15
- package/dist/server/registerInvestigationTools.js +41 -57
- 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/registerReplayMachineTool.js +4 -10
- package/dist/server/registerSessionRecordTools.js +69 -40
- package/dist/server/registerSessionStatusTool.js +13 -28
- package/dist/server/registerSessionTools.js +36 -52
- package/dist/server/sessionAvailabilityPolicy.js +2 -1
- package/dist/server/sessionToolPolicies.js +1 -5
- package/dist/server/toolRegistrationOptions.js +4 -192
- package/dist/server/toolResult.js +2 -18
- package/package.json +22 -14
- package/scripts/electron-active-hook-boundaries.cjs +394 -0
- package/scripts/electron-active-hook.cjs +501 -0
- package/scripts/rea.mjs +1 -11
- package/skills/reverse-engineer-anything/SKILL.md +2 -2
- package/dist/server/DynamicToolAvailability.js +0 -70
- package/dist/server/LazyToolCatalog.js +0 -134
- package/dist/server/hydrateServerTools.js +0 -191
- package/dist/server/toolInputValidation.js +0 -77
- package/scripts/package-runner-bootstrap.mjs +0 -72
|
@@ -20,14 +20,16 @@ const reconcileEntity = (entity, index, layers) => {
|
|
|
20
20
|
const content = index.byCategoryDigest.get(categoryDigestKey(entity.staticKind, entity.sourceSha256)) ?? [];
|
|
21
21
|
const locatedKeys = new Set(locations.map(({ candidate }) => candidateKey(candidate)));
|
|
22
22
|
const combined = content.filter((candidate) => locatedKeys.has(candidateKey(candidate)));
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
const combinedCandidate = combined.at(0);
|
|
24
|
+
if (combined.length === 1 && combinedCandidate !== undefined)
|
|
25
|
+
return matched(entity, combinedCandidate, {
|
|
25
26
|
basis: "content-and-location",
|
|
26
27
|
confidence: "high",
|
|
27
28
|
reason: "content-and-location-match",
|
|
28
29
|
});
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
const contentCandidate = content.at(0);
|
|
31
|
+
if (content.length === 1 && contentCandidate !== undefined) {
|
|
32
|
+
const candidate = contentCandidate;
|
|
31
33
|
const digestBasis = candidate.digests.find(({ sha256 }) => sha256 === entity.sourceSha256)?.basis;
|
|
32
34
|
return matched(entity, candidate, {
|
|
33
35
|
basis: digestBasis ?? "content-sha256",
|
|
@@ -59,8 +61,9 @@ const reconcileEntity = (entity, index, layers) => {
|
|
|
59
61
|
candidates: [],
|
|
60
62
|
});
|
|
61
63
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
+
const location = locations.at(0);
|
|
65
|
+
if (locations.length === 1 && location !== undefined) {
|
|
66
|
+
const located = location;
|
|
64
67
|
return matched(entity, located.candidate, {
|
|
65
68
|
basis: located.mapping.basis,
|
|
66
69
|
confidence: "medium",
|
|
@@ -174,50 +177,55 @@ const createItem = (entity, input) => {
|
|
|
174
177
|
...semantic,
|
|
175
178
|
};
|
|
176
179
|
};
|
|
177
|
-
const reconciliationEvidence = (entity, layer, basis, confidence) =>
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
: {
|
|
203
|
-
status: "partial",
|
|
204
|
-
truncated: false,
|
|
205
|
-
omitted_count: null,
|
|
206
|
-
limits: [],
|
|
180
|
+
const reconciliationEvidence = (entity, layer, basis, confidence) => {
|
|
181
|
+
const observation = entity.node.observations.at(0);
|
|
182
|
+
if (observation === undefined)
|
|
183
|
+
throw new TypeError("Runtime reconciliation entity has no observation");
|
|
184
|
+
return {
|
|
185
|
+
authority: "cross-layer-reconciliation",
|
|
186
|
+
state: "inferred",
|
|
187
|
+
confidence: confidence === "medium" ? "medium" : "high",
|
|
188
|
+
artifact: entity.sourceSha256 === null
|
|
189
|
+
? {
|
|
190
|
+
available: false,
|
|
191
|
+
reason: "not-observed",
|
|
192
|
+
detail: "Runtime source bytes were not captured for this mapping.",
|
|
193
|
+
}
|
|
194
|
+
: {
|
|
195
|
+
available: true,
|
|
196
|
+
artifact_id: `art_${entity.sourceSha256}`,
|
|
197
|
+
sha256: entity.sourceSha256,
|
|
198
|
+
},
|
|
199
|
+
location: observation.evidence.location,
|
|
200
|
+
extractor: {
|
|
201
|
+
name: "rea-javascript-runtime-reconciliation",
|
|
202
|
+
version: "1",
|
|
203
|
+
operation: "reconcile_javascript_runtime",
|
|
204
|
+
executable_sha256: null,
|
|
207
205
|
},
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
206
|
+
coverage: layer.graph.coverage.status === "complete" &&
|
|
207
|
+
entity.capture.scriptsCompleteWithinScope
|
|
208
|
+
? { status: "complete", truncated: false, omitted_count: 0, limits: [] }
|
|
209
|
+
: {
|
|
210
|
+
status: "partial",
|
|
211
|
+
truncated: false,
|
|
212
|
+
omitted_count: null,
|
|
213
|
+
limits: [],
|
|
214
|
+
},
|
|
215
|
+
limitations: [
|
|
216
|
+
basis === "content-sha256" ||
|
|
217
|
+
basis === "module-source-sha256" ||
|
|
218
|
+
basis === "content-and-location"
|
|
219
|
+
? "Equal content digests establish byte identity, not execution causality."
|
|
220
|
+
: "Location correspondence is inferred from an artifact root or caller-declared mapping.",
|
|
221
|
+
"Passive script parsing or target presence does not prove feature execution.",
|
|
222
|
+
],
|
|
223
|
+
evidence_ids: [
|
|
224
|
+
layer.evidence.evidence_id,
|
|
225
|
+
entity.capture.evidence.evidence_id,
|
|
226
|
+
].sort(),
|
|
227
|
+
};
|
|
228
|
+
};
|
|
221
229
|
const strongestLocationBasis = (values) => {
|
|
222
230
|
const bases = new Set(values.map(({ mapping }) => mapping.basis));
|
|
223
231
|
if (bases.has("artifact-path"))
|
|
@@ -9,6 +9,7 @@ import { javascriptRuntimeObservationSchema, javascriptRuntimeKindSchema, } from
|
|
|
9
9
|
import { parseEvidence } from "./evidence.js";
|
|
10
10
|
import { javascriptApplicationAnalysisResultSchema, } from "./javascriptApplicationAnalysis.js";
|
|
11
11
|
import { compareCodePoints, } from "./javascriptApplicationGraph.js";
|
|
12
|
+
import { parseActiveElectronCapture } from "./javascriptRuntimeReconciliationActive.js";
|
|
12
13
|
/** Parse and semantically bind every static analysis Evidence layer. */
|
|
13
14
|
export const parseStaticLayers = (layers) => layers
|
|
14
15
|
.map((layer) => parseStaticLayer(layer))
|
|
@@ -133,7 +134,10 @@ const parseRuntimeCapture = (input) => {
|
|
|
133
134
|
scriptsCompleteWithinScope: false,
|
|
134
135
|
};
|
|
135
136
|
}
|
|
136
|
-
|
|
137
|
+
if (evidence.operation === "capture_electron_scenario") {
|
|
138
|
+
return parseActiveElectronCapture(evidence);
|
|
139
|
+
}
|
|
140
|
+
throw new TypeError("Runtime reconciliation requires inspect_web_page, inspect_electron_page, observe_javascript_runtime, or capture_electron_scenario Evidence");
|
|
137
141
|
};
|
|
138
142
|
const assertV8RuntimeParameters = (evidence, result) => {
|
|
139
143
|
const parameters = z
|
|
@@ -78,27 +78,34 @@ const sourceMapAuthority = (input) => ({
|
|
|
78
78
|
limitation: "Source-map declarations and approved original-source reads retain separate static authority and are not used as primary runtime byte matches.",
|
|
79
79
|
});
|
|
80
80
|
const reconciliationCoverage = (input, completion) => ({
|
|
81
|
-
status: completion.outputTruncated || completion.
|
|
81
|
+
status: completion.outputTruncated || completion.inputStatus === "truncated"
|
|
82
82
|
? "truncated"
|
|
83
|
-
: completion.
|
|
83
|
+
: completion.inputStatus === "partial"
|
|
84
84
|
? "partial"
|
|
85
85
|
: "complete-within-inputs",
|
|
86
|
-
truncated: completion.outputTruncated || completion.
|
|
86
|
+
truncated: completion.outputTruncated || completion.inputStatus === "truncated",
|
|
87
87
|
omitted_runtime_entities: input.runtime.omittedEntities,
|
|
88
88
|
omitted_reconciliation_items: input.matching.omittedItems,
|
|
89
89
|
omitted_static_load_states: input.loadStates.omittedStates,
|
|
90
90
|
omitted_graph_items: input.omittedGraphItems,
|
|
91
91
|
});
|
|
92
|
-
const completionFlags = (input) =>
|
|
93
|
-
|
|
94
|
-
input.
|
|
95
|
-
|
|
96
|
-
input.
|
|
97
|
-
|
|
98
|
-
input.
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
92
|
+
const completionFlags = (input) => {
|
|
93
|
+
const inputTruncated = input.layers.some(({ graph }) => graph.coverage.truncated) ||
|
|
94
|
+
input.captures.some(({ inspection }) => inspection.completeness.conditions.includes("truncated"));
|
|
95
|
+
const inputPartial = input.layers.some(({ graph }) => graph.coverage.status !== "complete") ||
|
|
96
|
+
input.captures.some(({ inspection }) => inspection.completeness.status !== "complete_within_window");
|
|
97
|
+
return {
|
|
98
|
+
outputTruncated: input.runtime.omittedEntities > 0 ||
|
|
99
|
+
input.matching.omittedItems > 0 ||
|
|
100
|
+
input.loadStates.omittedStates > 0 ||
|
|
101
|
+
input.omittedGraphItems > 0,
|
|
102
|
+
inputStatus: inputTruncated
|
|
103
|
+
? "truncated"
|
|
104
|
+
: inputPartial
|
|
105
|
+
? "partial"
|
|
106
|
+
: "complete",
|
|
107
|
+
};
|
|
108
|
+
};
|
|
102
109
|
const reconciliationLimitations = (completion) => uniqueSorted([
|
|
103
110
|
"Only caller-supplied, semantically verified Evidence records were reconciled.",
|
|
104
111
|
"Digest equality establishes byte identity but not code reachability, module initialization, or feature execution.",
|
|
@@ -106,7 +113,7 @@ const reconciliationLimitations = (completion) => uniqueSorted([
|
|
|
106
113
|
"Not-observed means absent from the bounded captures in scope, never globally unloaded.",
|
|
107
114
|
"Caller-declared file and URL mappings are inference inputs and do not expand CDP origin or filesystem-root authority.",
|
|
108
115
|
"Source-map authority remains separate from passive runtime authority.",
|
|
109
|
-
...(completion.
|
|
116
|
+
...(completion.inputStatus !== "complete"
|
|
110
117
|
? ["One or more static graphs or passive captures were incomplete."]
|
|
111
118
|
: []),
|
|
112
119
|
...(completion.outputTruncated
|
|
@@ -133,7 +133,7 @@ const layerSummarySchema = z.strictObject({
|
|
|
133
133
|
const captureSummarySchema = z.strictObject({
|
|
134
134
|
evidence_id: evidenceIdSchema,
|
|
135
135
|
capture_sha256: digestSchema,
|
|
136
|
-
kind: z.enum(["browser", "electron", "v8-inspector"]),
|
|
136
|
+
kind: z.enum(["browser", "electron", "v8-inspector", "electron-active"]),
|
|
137
137
|
target_node_id: nodeIdSchema,
|
|
138
138
|
target_key: boundedTextSchema,
|
|
139
139
|
target_location: boundedTextSchema,
|
|
@@ -11,11 +11,19 @@ export const assessKnownPageCoverage = (page, includedCount = page.items.length)
|
|
|
11
11
|
page.returned === page.total &&
|
|
12
12
|
sourceOmittedCount === 0;
|
|
13
13
|
const omittedCount = Math.max(0, page.total - retainedCount);
|
|
14
|
-
return
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
14
|
+
return sourceComplete && omittedCount === 0
|
|
15
|
+
? {
|
|
16
|
+
complete: true,
|
|
17
|
+
sourceComplete: true,
|
|
18
|
+
includedCount: retainedCount,
|
|
19
|
+
omittedCount: 0,
|
|
20
|
+
sourceOmittedCount: 0,
|
|
21
|
+
}
|
|
22
|
+
: {
|
|
23
|
+
complete: false,
|
|
24
|
+
sourceComplete,
|
|
25
|
+
includedCount: retainedCount,
|
|
26
|
+
omittedCount,
|
|
27
|
+
sourceOmittedCount,
|
|
28
|
+
};
|
|
21
29
|
};
|
|
@@ -13,9 +13,7 @@ const inferenceEvidenceSchema = z
|
|
|
13
13
|
detail: z.string().min(1),
|
|
14
14
|
})
|
|
15
15
|
.strict();
|
|
16
|
-
const
|
|
17
|
-
.object({
|
|
18
|
-
role: z.enum(["return", "parameter"]),
|
|
16
|
+
const inferredBoundaryTypeFacts = {
|
|
19
17
|
ordinal: z.number().int().min(0).nullable(),
|
|
20
18
|
name: z.string().min(1).nullable(),
|
|
21
19
|
data_type: z.string().min(1),
|
|
@@ -28,8 +26,18 @@ const inferredBoundaryTypeSchema = z
|
|
|
28
26
|
"register-or-stack-storage",
|
|
29
27
|
"compiler-generated-variable",
|
|
30
28
|
])),
|
|
31
|
-
}
|
|
32
|
-
|
|
29
|
+
};
|
|
30
|
+
const inferredReturnTypeSchema = z.strictObject({
|
|
31
|
+
...inferredBoundaryTypeFacts,
|
|
32
|
+
role: z.literal("return"),
|
|
33
|
+
ordinal: z.null(),
|
|
34
|
+
name: z.null(),
|
|
35
|
+
});
|
|
36
|
+
const inferredParameterTypeSchema = z.strictObject({
|
|
37
|
+
...inferredBoundaryTypeFacts,
|
|
38
|
+
role: z.literal("parameter"),
|
|
39
|
+
ordinal: z.number().int().min(0),
|
|
40
|
+
});
|
|
33
41
|
const jumpTableDataSourceSchema = z
|
|
34
42
|
.object({
|
|
35
43
|
address: z.string().min(1),
|
|
@@ -68,8 +76,8 @@ const availableNativeApiBoundarySchema = z
|
|
|
68
76
|
provenance: z.string().min(1),
|
|
69
77
|
signature_source: z.string().min(1),
|
|
70
78
|
calling_convention: z.string().min(1),
|
|
71
|
-
return_type:
|
|
72
|
-
parameters: z.array(
|
|
79
|
+
return_type: inferredReturnTypeSchema,
|
|
80
|
+
parameters: z.array(inferredParameterTypeSchema),
|
|
73
81
|
parameters_truncated: z.boolean(),
|
|
74
82
|
jump_tables: z.array(inferredJumpTableSchema),
|
|
75
83
|
jump_tables_truncated: z.boolean(),
|
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import {
|
|
2
|
+
import { controlledReplayExecutionOutputSchema, controlledReplayPlanInputSchema, controlledReplayPlanOutputSchema, } from "./javascriptReplay.js";
|
|
3
3
|
import { javascriptExportInstrumentationInputSchema, javascriptExportTransformationManifestSchema, } from "./javascriptExportInstrumentation.js";
|
|
4
4
|
import { runtimeCharacterizationPlanSchema } from "./runtimeCharacterization.js";
|
|
5
5
|
import { evidenceRecordSchema } from "./evidence.js";
|
|
6
6
|
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
|
|
7
|
+
const nodeCharacterizationExpectedEffectSchema = z.enum([
|
|
8
|
+
"pure",
|
|
9
|
+
"observation-only",
|
|
10
|
+
]);
|
|
11
|
+
const nodeRuntimeCharacterizationPlanSchema = runtimeCharacterizationPlanSchema.extend({
|
|
12
|
+
expected_effect: nodeCharacterizationExpectedEffectSchema,
|
|
13
|
+
});
|
|
7
14
|
export const nodeCharacterizationPreparationInputSchema = z
|
|
8
15
|
.strictObject({
|
|
9
16
|
preparation_approved: z.literal(true),
|
|
10
17
|
selected_alias: z.string().min(1).max(200),
|
|
11
|
-
expected_effect:
|
|
18
|
+
expected_effect: nodeCharacterizationExpectedEffectSchema,
|
|
12
19
|
instrumentation: javascriptExportInstrumentationInputSchema,
|
|
13
|
-
replay:
|
|
20
|
+
replay: controlledReplayPlanInputSchema,
|
|
14
21
|
})
|
|
15
22
|
.superRefine((input, context) => {
|
|
16
|
-
if (input.replay.mode !== "plan")
|
|
17
|
-
context.addIssue({
|
|
18
|
-
code: "custom",
|
|
19
|
-
path: ["replay", "mode"],
|
|
20
|
-
message: "Characterization preparation requires replay plan mode",
|
|
21
|
-
});
|
|
22
23
|
const selected = input.replay.left.modules.filter(({ alias }) => alias === input.selected_alias);
|
|
23
24
|
if (selected.length !== 1 ||
|
|
24
25
|
selected[0]?.path !== input.instrumentation.artifact_path ||
|
|
@@ -50,17 +51,17 @@ export const nodeCharacterizationExecutionInputSchema = z.strictObject({
|
|
|
50
51
|
export const nodeCharacterizationPreparationOutputSchema = z.strictObject({
|
|
51
52
|
schema_version: z.literal(1),
|
|
52
53
|
phase: z.literal("preparation"),
|
|
53
|
-
plan:
|
|
54
|
+
plan: nodeRuntimeCharacterizationPlanSchema,
|
|
54
55
|
transformation: javascriptExportTransformationManifestSchema,
|
|
55
56
|
transformation_evidence: evidenceRecordSchema,
|
|
56
|
-
replay:
|
|
57
|
+
replay: controlledReplayPlanOutputSchema,
|
|
57
58
|
});
|
|
58
59
|
export const nodeCharacterizationExecutionOutputSchema = z.strictObject({
|
|
59
60
|
schema_version: z.literal(1),
|
|
60
61
|
phase: z.literal("execution"),
|
|
61
|
-
plan:
|
|
62
|
+
plan: nodeRuntimeCharacterizationPlanSchema,
|
|
62
63
|
transformation: javascriptExportTransformationManifestSchema,
|
|
63
64
|
transformation_evidence: evidenceRecordSchema,
|
|
64
65
|
evidence: evidenceRecordSchema,
|
|
65
|
-
replay:
|
|
66
|
+
replay: controlledReplayExecutionOutputSchema,
|
|
66
67
|
});
|
|
@@ -118,6 +118,8 @@ const replayTransitions = (scenario, run, observations, require) => {
|
|
|
118
118
|
while ((run.controls[controlIndex]?.after_capture_order ??
|
|
119
119
|
Number.MAX_SAFE_INTEGER) < observation.capture_order) {
|
|
120
120
|
const control = run.controls[controlIndex];
|
|
121
|
+
if (control === undefined)
|
|
122
|
+
break;
|
|
121
123
|
advanceControl(control, controlIndex);
|
|
122
124
|
controlIndex += 1;
|
|
123
125
|
}
|
|
@@ -125,6 +127,8 @@ const replayTransitions = (scenario, run, observations, require) => {
|
|
|
125
127
|
}
|
|
126
128
|
for (; controlIndex < run.controls.length; controlIndex += 1) {
|
|
127
129
|
const control = run.controls[controlIndex];
|
|
130
|
+
if (control === undefined)
|
|
131
|
+
break;
|
|
128
132
|
advanceControl(control, controlIndex);
|
|
129
133
|
}
|
|
130
134
|
require(transitionIndex ===
|
|
@@ -141,10 +145,11 @@ const validateControls = (run, observations, require) => {
|
|
|
141
145
|
require(control.sequence ===
|
|
142
146
|
index, `reactive_run.controls[${String(index)}].sequence`, "reactive control sequence must be contiguous");
|
|
143
147
|
require(admittedOrders.has(control.after_capture_order), `reactive_run.controls[${String(index)}].after_capture_order`, "reactive control cutoff must identify the last admitted observation");
|
|
148
|
+
const previous = run.controls.at(index - 1);
|
|
144
149
|
require(index === 0 ||
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
.after_capture_order, `reactive_run.controls[${String(index)}].after_capture_order`, "reactive control cutoffs must be ordered");
|
|
150
|
+
(previous !== undefined &&
|
|
151
|
+
control.after_capture_order >=
|
|
152
|
+
previous.after_capture_order), `reactive_run.controls[${String(index)}].after_capture_order`, "reactive control cutoffs must be ordered");
|
|
148
153
|
}
|
|
149
154
|
};
|
|
150
155
|
/** Validate one capture's reactive journal by replaying the production reducer. */
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { validateProcessCaptureReactiveRun } from "./processCaptureReactiveValidation.js";
|
|
2
2
|
import { replayMachineSchema } from "./replayMachine.js";
|
|
3
3
|
import { digestProcessCommitment } from "./processScenario.js";
|
|
4
|
-
const orderedTimestamps = (values) => values.every((value, index) =>
|
|
4
|
+
const orderedTimestamps = (values) => values.every((value, index) => {
|
|
5
|
+
const previous = values[index - 1];
|
|
6
|
+
return previous === undefined || value.at_ms >= previous.at_ms;
|
|
7
|
+
});
|
|
8
|
+
const transitionsAreContiguous = (previous, current) => previous !== undefined && previous.state_after === current.state_before;
|
|
5
9
|
const validateCommitments = (capture, require) => {
|
|
6
10
|
const { manifest } = capture;
|
|
7
11
|
require(manifest.scenario.executable_sha256 ===
|
|
@@ -192,9 +196,9 @@ const validateReplayEvents = (capture, require) => {
|
|
|
192
196
|
if (index === 0)
|
|
193
197
|
require(transition.state_before ===
|
|
194
198
|
machine?.initial_state, "replay_transitions", "first replay transition does not start at the declared initial state");
|
|
199
|
+
const previous = capture.replay_transitions[index - 1];
|
|
195
200
|
if (index > 0)
|
|
196
|
-
require(
|
|
197
|
-
transition.state_before, "replay_transitions", "replay transition states are not contiguous");
|
|
201
|
+
require(transitionsAreContiguous(previous, transition), "replay_transitions", "replay transition states are not contiguous");
|
|
198
202
|
}
|
|
199
203
|
};
|
|
200
204
|
/** Recompute v4 commitments and cross-field invariants without side effects. */
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import canonicalize from "canonicalize";
|
|
1
2
|
import { z } from "zod";
|
|
2
3
|
import { validateProcessCapture } from "./processCapture.js";
|
|
3
4
|
import { jsonValueSchema } from "./jsonValue.js";
|
|
@@ -97,6 +98,10 @@ const filesystemObservations = (capture) => [
|
|
|
97
98
|
effects: capture.filesystem_effects,
|
|
98
99
|
},
|
|
99
100
|
];
|
|
101
|
+
const sameJsonValue = (left, right) => {
|
|
102
|
+
const encodedLeft = canonicalize(left);
|
|
103
|
+
return encodedLeft !== undefined && encodedLeft === canonicalize(right);
|
|
104
|
+
};
|
|
100
105
|
/** Canonical observations for one process-comparison dimension. */
|
|
101
106
|
export const processDimensionObservations = (capture, dimension) => {
|
|
102
107
|
switch (dimension) {
|
|
@@ -117,7 +122,7 @@ export const processDimensionObservations = (capture, dimension) => {
|
|
|
117
122
|
}
|
|
118
123
|
};
|
|
119
124
|
const classifyCollection = (left, right) => {
|
|
120
|
-
if (
|
|
125
|
+
if (sameJsonValue(left, right))
|
|
121
126
|
return "unchanged";
|
|
122
127
|
if (left.length === 0)
|
|
123
128
|
return "added";
|
|
@@ -141,7 +146,7 @@ const firstCollectionDivergence = (dimension, left, right) => {
|
|
|
141
146
|
for (let index = 0; index < length; index += 1) {
|
|
142
147
|
const leftValue = left[index] ?? null;
|
|
143
148
|
const rightValue = right[index] ?? null;
|
|
144
|
-
if (
|
|
149
|
+
if (sameJsonValue(leftValue, rightValue))
|
|
145
150
|
continue;
|
|
146
151
|
return {
|
|
147
152
|
status: "found",
|
|
@@ -168,8 +173,9 @@ const assertComparable = (left, right, options) => {
|
|
|
168
173
|
...validateProcessCapture(left),
|
|
169
174
|
...validateProcessCapture(right),
|
|
170
175
|
];
|
|
171
|
-
|
|
172
|
-
|
|
176
|
+
const firstInvalid = invalid.at(0);
|
|
177
|
+
if (firstInvalid !== undefined)
|
|
178
|
+
throw new TypeError(`Invalid Process Capture v4: ${firstInvalid.path}`);
|
|
173
179
|
if (left.schema_version !== right.schema_version ||
|
|
174
180
|
left.manifest.comparison_contract_sha256 !==
|
|
175
181
|
right.manifest.comparison_contract_sha256)
|
|
@@ -239,8 +245,7 @@ const compareDimensions = (left, right, sameNormalization) => {
|
|
|
239
245
|
interaction: classify("interaction", left.interaction_events, right.interaction_events),
|
|
240
246
|
exit: hasUnknown(left, "exit") || hasUnknown(right, "exit")
|
|
241
247
|
? "unknown"
|
|
242
|
-
:
|
|
243
|
-
JSON.stringify({ exit: right.exit, settlement: right.settlement })
|
|
248
|
+
: sameJsonValue({ exit: left.exit, settlement: left.settlement }, { exit: right.exit, settlement: right.settlement })
|
|
244
249
|
? "unchanged"
|
|
245
250
|
: "changed",
|
|
246
251
|
filesystem: classify("filesystem", filesystemObservations(left), filesystemObservations(right)),
|
|
@@ -266,7 +271,7 @@ export const compareProcessCaptures = (left, right, options = {}) => {
|
|
|
266
271
|
trace: compareProcessTraces(left, right, options.traceSpecification),
|
|
267
272
|
};
|
|
268
273
|
}
|
|
269
|
-
const sameNormalization =
|
|
274
|
+
const sameNormalization = sameJsonValue(left.normalization, right.normalization);
|
|
270
275
|
const exactDimensions = compareDimensions(left, right, sameNormalization);
|
|
271
276
|
const trace = options.traceSpecification === undefined
|
|
272
277
|
? undefined
|
|
@@ -52,14 +52,13 @@ export const createProcessObservation = (input) => ({
|
|
|
52
52
|
const atMilliseconds = (value) => {
|
|
53
53
|
if (typeof value !== "object" || value === null)
|
|
54
54
|
return null;
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
return candidate;
|
|
60
|
-
}
|
|
55
|
+
if ("at_ms" in value && isSafeMillisecond(value.at_ms))
|
|
56
|
+
return value.at_ms;
|
|
57
|
+
if ("dispatched_at_ms" in value && isSafeMillisecond(value.dispatched_at_ms))
|
|
58
|
+
return value.dispatched_at_ms;
|
|
61
59
|
return null;
|
|
62
60
|
};
|
|
61
|
+
const isSafeMillisecond = (value) => typeof value === "number" && Number.isSafeInteger(value);
|
|
63
62
|
/** Derive the stable capture-local identity for one normalized observation. */
|
|
64
63
|
export const processObservationSubject = (source, value) => {
|
|
65
64
|
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
@@ -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);
|
|
@@ -109,7 +109,7 @@ export function looksLikeCredential(path) {
|
|
|
109
109
|
/** Decode a JSON-RPC message from raw payload bytes. */
|
|
110
110
|
export function decodeJsonRpc(rawPayload) {
|
|
111
111
|
const text = new TextDecoder().decode(rawPayload);
|
|
112
|
-
const parsed = JSON.parse(text);
|
|
112
|
+
const parsed = jsonValueSchema.parse(JSON.parse(text));
|
|
113
113
|
const fields = [];
|
|
114
114
|
if (typeof parsed === "object" && parsed !== null) {
|
|
115
115
|
for (const [key, value] of Object.entries(parsed)) {
|
|
@@ -125,7 +125,7 @@ export function decodeJsonRpc(rawPayload) {
|
|
|
125
125
|
fields.push({
|
|
126
126
|
path: key,
|
|
127
127
|
wire_type: "json",
|
|
128
|
-
value
|
|
128
|
+
value,
|
|
129
129
|
inferred: false,
|
|
130
130
|
});
|
|
131
131
|
}
|
|
@@ -141,6 +141,8 @@ export function decodeMessagePack(rawPayload) {
|
|
|
141
141
|
return { decoded_fields: [], truncated: false };
|
|
142
142
|
}
|
|
143
143
|
const tag = rawPayload[0];
|
|
144
|
+
if (tag === undefined)
|
|
145
|
+
return { decoded_fields: [], truncated: false };
|
|
144
146
|
// Map type: 0x80-0x8f (fixmap), 0xde (map16), 0xdf (map32)
|
|
145
147
|
if ((tag >= 0x80 && tag <= 0x8f) || tag === 0xde || tag === 0xdf) {
|
|
146
148
|
fields.push({
|
|
@@ -189,10 +191,10 @@ export function decodeGrpcFrame(rawPayload) {
|
|
|
189
191
|
};
|
|
190
192
|
}
|
|
191
193
|
const compressed = rawPayload[0] !== 0;
|
|
192
|
-
const length = (rawPayload[1] << 24) |
|
|
193
|
-
(rawPayload[2] << 16) |
|
|
194
|
-
(rawPayload[3] << 8) |
|
|
195
|
-
rawPayload[4];
|
|
194
|
+
const length = ((rawPayload[1] ?? 0) << 24) |
|
|
195
|
+
((rawPayload[2] ?? 0) << 16) |
|
|
196
|
+
((rawPayload[3] ?? 0) << 8) |
|
|
197
|
+
(rawPayload[4] ?? 0);
|
|
196
198
|
return {
|
|
197
199
|
decoded_fields: [
|
|
198
200
|
{
|