rea-agents 2.3.0 → 2.5.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 +80 -18
- package/bridge/ghidra/ReaGhidraBridge.java +48 -1
- package/bridge/hopper_bridge.py +259 -24
- package/dist/application/AnalysisClientCleanup.js +14 -0
- package/dist/application/ApplicationWorkflowEvidenceResolver.js +31 -13
- package/dist/application/ArtifactExtraction.js +5 -1
- package/dist/application/ArtifactGraphConstruction.js +3 -15
- package/dist/application/ArtifactInventory/classify.js +5 -1
- package/dist/application/ArtifactInventory/reader.js +2 -0
- package/dist/application/BinarySession.js +15 -4
- package/dist/application/BinarySessionStatus.js +32 -1
- package/dist/application/BrowserEvidence.js +14 -0
- package/dist/application/BrowserScenarioCapturePort.js +1 -0
- package/dist/application/BrowserScenarioCaptureService.js +53 -0
- package/dist/application/BrowserScenarioEvidence.js +40 -0
- package/dist/application/CallPathTracing.js +160 -0
- package/dist/application/CapabilityInventory.js +79 -15
- package/dist/application/CompositeProvider.js +10 -1
- package/dist/application/DirectAnalysis.js +7 -2
- package/dist/application/EnhancedLiteralTracing.js +118 -0
- package/dist/application/EnhancedTools.js +35 -121
- package/dist/application/JavaScriptApplicationWorkflowEvidence.js +13 -0
- package/dist/application/JavaScriptApplicationWorkflowService.js +27 -1
- package/dist/application/JavaScriptRuntimeObservationEvidence.js +34 -0
- package/dist/application/JavaScriptRuntimeObservationPort.js +1 -0
- package/dist/application/JavaScriptRuntimeObservationService.js +46 -0
- package/dist/application/JavaScriptSemanticGraphAsyncProjection.js +147 -0
- package/dist/application/JavaScriptSemanticGraphBuilder.js +34 -6
- package/dist/application/JavaScriptSemanticGraphChildProcessProjection.js +156 -0
- package/dist/application/JavaScriptSemanticGraphConstruction.js +2 -2
- package/dist/application/JavaScriptSemanticGraphDataProjection.js +203 -0
- package/dist/application/JavaScriptSemanticGraphFingerprintProjection.js +25 -0
- package/dist/application/JavaScriptSemanticGraphFlowProjection.js +129 -8
- package/dist/application/JavaScriptSemanticGraphObjectProjection.js +81 -0
- package/dist/application/JavaScriptSemanticGraphProjection.js +14 -7
- package/dist/application/JavaScriptSemanticGraphResourceProjection.js +59 -0
- package/dist/application/JavaScriptSemanticGraphValueProjection.js +77 -0
- package/dist/application/ProcessCaptureEnvironment.js +26 -0
- package/dist/application/ProcessCaptureLifecycle.js +1 -0
- package/dist/application/ProcessCheckpoints.js +5 -0
- package/dist/application/ProcessHarness.js +45 -34
- package/dist/application/ProcessNormalization.js +6 -0
- package/dist/application/ProcessReactiveCoordinator.js +10 -3
- package/dist/application/ProcessReactiveEffects.js +15 -1
- package/dist/application/ProcessReactiveHarness.js +100 -0
- package/dist/application/ProcessReactiveObservations.js +101 -16
- package/dist/application/ProjectPermissionStore.js +1 -0
- package/dist/application/ReconstructionObligationAuthority.js +72 -0
- package/dist/application/ReconstructionObligationCandidates.js +265 -0
- package/dist/application/ReconstructionObligationLedgerDiagnostics.js +47 -0
- package/dist/application/ReconstructionObligationLedgerEvaluation.js +263 -0
- package/dist/application/ReconstructionObligationLedgerProjection.js +86 -0
- package/dist/application/ReconstructionObligationLedgerService.js +72 -0
- package/dist/application/ReconstructionObligationOriginalCases.js +33 -0
- package/dist/application/ReconstructionObligationPolicies.js +132 -0
- package/dist/application/ReconstructionReadinessService.js +48 -0
- package/dist/artifacts/ArtifactProvider.js +87 -22
- package/dist/browser/BrowserScenarioSecrets.js +53 -0
- package/dist/browser/BrowserScenarioSessionPort.js +1 -0
- package/dist/browser/CdpBrowserProvider.js +2 -2
- package/dist/browser/CdpCaptureDocuments.js +57 -0
- package/dist/browser/CdpCaptureStorage.js +71 -29
- package/dist/browser/CdpCaptureStorageFingerprints.js +328 -0
- package/dist/browser/CdpEndpoint.js +8 -6
- package/dist/browser/CdpPageCapture.js +2 -0
- package/dist/browser/JavaScriptRuntimeScope.js +38 -0
- package/dist/browser/PlaywrightBrowserScenarioProvider.js +253 -0
- package/dist/browser/PlaywrightExecutionBoundary.js +42 -0
- package/dist/browser/PlaywrightScenarioActions.js +62 -0
- package/dist/browser/PlaywrightScenarioArtifacts.js +238 -0
- package/dist/browser/PlaywrightScenarioBrowser.js +144 -0
- package/dist/browser/PlaywrightScenarioEvents.js +301 -0
- package/dist/browser/PlaywrightScenarioSession.js +300 -0
- package/dist/browser/V8InspectorCaptureProjection.js +110 -0
- package/dist/browser/V8InspectorEndpoint.js +72 -0
- package/dist/browser/V8InspectorProvider.js +267 -0
- package/dist/catalogIdentity.js +8 -0
- package/dist/cli/artifactCommands.js +39 -0
- package/dist/cli/coreAnalysisCommands.js +37 -0
- package/dist/cli.js +4 -0
- package/dist/cliApplicationCommands.js +30 -2
- package/dist/cliBrowserAdvancedCommands.js +17 -5
- package/dist/cliBrowserCommands.js +1 -0
- package/dist/cliBrowserScenarioCommands.js +43 -0
- package/dist/cliCommandNames.js +8 -0
- package/dist/cliJavaScriptRuntimeCommands.js +164 -0
- package/dist/cliObservationOptions.js +4 -0
- package/dist/cliPolicyCommands.js +1 -0
- package/dist/config/environment.js +12 -0
- package/dist/config/parseConfig.js +88 -17
- package/dist/contracts/analysisSearchContract.js +14 -0
- package/dist/contracts/applicationToolContracts.js +86 -2
- package/dist/contracts/applicationWorkflowInputContracts.js +18 -0
- package/dist/contracts/artifactToolContracts.js +22 -0
- package/dist/contracts/browserProviderToolContracts.js +7 -0
- package/dist/contracts/browserScenarioToolContracts.js +81 -0
- package/dist/contracts/browserToolContracts.js +88 -98
- package/dist/contracts/enhancedInputs.js +25 -6
- package/dist/contracts/functionInstructionContract.js +8 -0
- package/dist/contracts/hopperMemoryContracts.js +22 -0
- package/dist/contracts/javascriptApplicationWorkflowExamples.js +42 -0
- package/dist/contracts/javascriptRuntimeObservationToolContracts.js +58 -0
- package/dist/contracts/reconstructionReadinessExample.js +436 -0
- package/dist/contracts/toolContractExamples.js +5 -0
- package/dist/contracts/toolContractTypes.js +1 -0
- package/dist/contracts/toolContracts.js +13 -21
- package/dist/contracts/toolEffects.js +21 -0
- package/dist/contracts/toolOutputSchemaGroups.js +70 -20
- package/dist/contracts/toolOutputSchemaPrimitives.js +40 -0
- package/dist/domain/analysisErrorProjection.js +8 -0
- package/dist/domain/analysisSnapshot.js +2 -0
- package/dist/domain/artifactGraph.js +2 -0
- package/dist/domain/artifactInspection.js +347 -0
- package/dist/domain/binaryTarget.js +3 -6
- package/dist/domain/browserCaptureComparison.js +82 -0
- package/dist/domain/browserObservation.js +8 -1
- package/dist/domain/browserObservationErrors.js +1 -0
- package/dist/domain/browserObservationSchemas.js +26 -0
- package/dist/domain/browserScenario.js +165 -0
- package/dist/domain/browserScenarioCapture.js +57 -0
- package/dist/domain/browserScenarioCaptureValues.js +204 -0
- package/dist/domain/browserScenarioDiff.js +324 -0
- package/dist/domain/browserScenarioDiffValues.js +157 -0
- package/dist/domain/browserScenarioNormalization.js +45 -0
- package/dist/domain/browserScenarioValues.js +372 -0
- package/dist/domain/evidence.js +2 -0
- package/dist/domain/hopperValues.js +10 -0
- package/dist/domain/javascriptRuntimeObservation.js +170 -0
- package/dist/domain/javascriptRuntimeReconciliationParsing.js +120 -2
- package/dist/domain/javascriptRuntimeReconciliationResult.js +3 -3
- package/dist/domain/javascriptRuntimeReconciliationRuntime.js +2 -2
- package/dist/domain/javascriptRuntimeReconciliationSchemas.js +1 -1
- package/dist/domain/javascriptSemanticAnalysis.js +5 -4
- package/dist/domain/javascriptSemanticAsyncEffects.js +253 -0
- package/dist/domain/javascriptSemanticChildProcesses.js +237 -0
- package/dist/domain/javascriptSemanticDataEffectHelpers.js +125 -0
- package/dist/domain/javascriptSemanticDataEffects.js +284 -0
- package/dist/domain/javascriptSemanticDerivedAnalysis.js +41 -0
- package/dist/domain/javascriptSemanticFingerprints.js +174 -0
- package/dist/domain/javascriptSemanticIr.js +21 -1
- package/dist/domain/javascriptSemanticObjects.js +115 -0
- package/dist/domain/javascriptSemanticPromises.js +290 -0
- package/dist/domain/javascriptSemanticResources.js +136 -0
- package/dist/domain/javascriptStaticAnalysis.js +4 -3
- package/dist/domain/javascriptStaticAnalysisBundler.js +38 -0
- package/dist/domain/javascriptStaticAnalysisCalls.js +23 -1
- package/dist/domain/javascriptStaticAnalysisHelpers.js +8 -0
- package/dist/domain/processCapture.js +71 -1
- package/dist/domain/processCaptureReactiveValidation.js +175 -0
- package/dist/domain/processCaptureValidation.js +2 -0
- package/dist/domain/processObservation.js +15 -6
- package/dist/domain/processReactiveRuntime.js +21 -10
- package/dist/domain/processReactiveScenario.js +1 -0
- package/dist/domain/processReactiveTransition.js +17 -10
- package/dist/domain/processScenario.js +21 -0
- package/dist/domain/providerCleanupError.js +11 -0
- package/dist/domain/reconstructionObligationLedgerSchemas.js +278 -0
- package/dist/domain/reconstructionReadiness.js +121 -0
- package/dist/domain/reconstructionReadinessFindingHelpers.js +17 -0
- package/dist/domain/reconstructionReadinessIntegrityFindings.js +118 -0
- package/dist/domain/reconstructionReadinessJourneyFindings.js +193 -0
- package/dist/domain/reconstructionReadinessSchemas.js +240 -0
- package/dist/domain/sourceToBundleComparison.js +335 -0
- package/dist/domain/sourceToBundleComparisonSchemas.js +133 -0
- package/dist/domain/sourceToBundleSignals.js +202 -0
- package/dist/domain/webCaptureDiff.js +141 -27
- package/dist/domain/webScreenshot.js +1 -1
- package/dist/domain/zipPackageFormat.js +20 -0
- package/dist/generatedPackageMetadata.js +1 -1
- package/dist/ghidra/GhidraDefaults.js +1 -1
- package/dist/ghidra/GhidraFunctionValues.js +13 -1
- package/dist/ghidra/GhidraProviderCapabilities.js +7 -0
- package/dist/hopper/HopperCleanup.js +158 -0
- package/dist/hopper/HopperClient.js +69 -99
- package/dist/hopper/HopperProvider.js +20 -1
- package/dist/hopper/HopperRequestQueue.js +187 -0
- package/dist/hopper/HopperResponseStream.js +46 -0
- package/dist/hopper/protocol.js +1 -0
- package/dist/main/transport.js +24 -24
- package/dist/main.js +6 -0
- package/dist/mcpDoctor.js +25 -2
- package/dist/native/NativeMacOSProvider.js +1 -0
- package/dist/process/ProcessCommandIdentity.js +19 -0
- package/dist/process/ProcessOwnership.js +11 -8
- package/dist/server/DynamicToolAvailability.js +70 -0
- package/dist/server/createServer.js +46 -1
- package/dist/server/lifecycleProgress.js +10 -0
- package/dist/server/permissionFailure.js +12 -0
- package/dist/server/registerApplicationTools/compareSourceToBundle.js +35 -0
- package/dist/server/registerApplicationTools/helpers.js +11 -7
- package/dist/server/registerApplicationTools/obligationLedger.js +27 -0
- package/dist/server/registerApplicationTools/readiness.js +55 -0
- package/dist/server/registerApplicationTools.js +6 -0
- package/dist/server/registerArtifactTools.js +9 -1
- package/dist/server/registerBrowserScenarioTool.js +25 -0
- package/dist/server/registerBrowserTools.js +2 -2
- package/dist/server/registerCloseLifecycleTool.js +57 -0
- package/dist/server/registerEnhancedTools.js +16 -5
- package/dist/server/registerEvidenceResources.js +4 -0
- package/dist/server/registerEvidenceTools.js +9 -2
- package/dist/server/registerJavaScriptRuntimeObservationTools.js +37 -0
- package/dist/server/registerReconstructionObligationLedgerResource.js +39 -0
- package/dist/server/registerReconstructionReadinessResource.js +39 -0
- package/dist/server/registerSessionStatusTool.js +11 -8
- package/dist/server/registerSessionTools.js +11 -57
- package/dist/server/sessionAvailabilityPolicy.js +10 -8
- package/package.json +12 -6
- package/skills/reverse-engineer-anything/SKILL.md +4 -3
- package/skills/reverse-engineer-anything/references/native-and-artifacts.md +2 -2
|
@@ -2,9 +2,10 @@ import { z } from "zod";
|
|
|
2
2
|
import { processCaptureComparisonSchema, processCaptureSchema, } from "../domain/processCapture.js";
|
|
3
3
|
import { evidenceBundleSchema } from "../domain/evidenceBundle.js";
|
|
4
4
|
import { residualUnknownSchema } from "../domain/residualUnknown.js";
|
|
5
|
-
import { referenceKindSchema } from "../domain/hopperValues.js";
|
|
5
|
+
import { functionInstructionWindowSchema, referenceKindSchema, } from "../domain/hopperValues.js";
|
|
6
6
|
import { demangleSwiftSchema, inspectMachoSchema, inspectPlistSchema, inspectSignatureSchema, listArchitecturesSchema, } from "../domain/nativeInspection.js";
|
|
7
7
|
import { artifactExtractionResultSchema, artifactInventoryResultSchema, } from "../domain/artifactGraph.js";
|
|
8
|
+
import { artifactInspectionResultSchema } from "../domain/artifactInspection.js";
|
|
8
9
|
import { managedArtifactInspectionSchema, managedMemberInspectionSchema, managedNativeBoundaryInspectionSchema, } from "../domain/managedArtifact.js";
|
|
9
10
|
import { managedMemberComparisonResultSchema } from "../domain/managedMemberComparison.js";
|
|
10
11
|
import { managedNativeVerificationResultSchema } from "../domain/managedNativeVerification.js";
|
|
@@ -20,7 +21,7 @@ import { staticRuntimeCorrelationResultSchema } from "../domain/staticRuntimeCor
|
|
|
20
21
|
import { reconstructionVerificationResultSchema } from "../domain/reconstructionVerification.js";
|
|
21
22
|
import { replayMachineRunOutputSchema } from "../domain/replayMachineRun.js";
|
|
22
23
|
import { analysisErrorProjectionSchema } from "./errorSchemas.js";
|
|
23
|
-
import { addressList, addressedEntry, bounded, containingProcedureResolution, functionDossierOutput, graphNode, lifecycleResultOf, nullableText, pageOutput, procedureIdentity, procedureInfoOutput, evidenceResultOf as resultOf, searchPageOutput, segmentOutput, sessionProvider, providerIdentity, toolAvailability, symbolDiscoveryOutput, targetFormatSchema, targetKindSchema, } from "./toolOutputSchemaPrimitives.js";
|
|
24
|
+
import { addressList, analysisActivity, addressedEntry, bounded, containingProcedureResolution, clientFeatureAvailabilitySchema, functionDossierOutput, graphNode, lifecycleResultOf, nullableText, pageOutput, procedureIdentity, procedureInfoOutput, evidenceResultOf as resultOf, searchPageOutput, segmentOutput, sessionProvider, providerIdentity, toolAvailability, symbolDiscoveryOutput, targetFormatSchema, targetKindSchema, } from "./toolOutputSchemaPrimitives.js";
|
|
24
25
|
/** Exact structured-content schemas shared by direct analysis providers. */
|
|
25
26
|
export const officialOutputSchemas = {
|
|
26
27
|
address_name: resultOf(nullableText),
|
|
@@ -43,6 +44,18 @@ export const officialOutputSchemas = {
|
|
|
43
44
|
procedure_callees: resultOf(addressList),
|
|
44
45
|
procedure_callers: resultOf(addressList),
|
|
45
46
|
procedure_info: procedureInfoOutput,
|
|
47
|
+
read_function_instructions: resultOf(functionInstructionWindowSchema),
|
|
48
|
+
read_bytes: resultOf(z.object({
|
|
49
|
+
address: z.string(),
|
|
50
|
+
requested_bytes: z.number().int().min(1).max(4_096),
|
|
51
|
+
returned_bytes: z.number().int().min(0).max(4_096),
|
|
52
|
+
bytes_hex: z.string().regex(/^(?:[a-f0-9]{2})*$/u),
|
|
53
|
+
complete: z.boolean(),
|
|
54
|
+
})),
|
|
55
|
+
address_to_file_offset: resultOf(z.object({
|
|
56
|
+
address: z.string(),
|
|
57
|
+
file_offset: z.number().int().min(0).max(Number.MAX_SAFE_INTEGER),
|
|
58
|
+
})),
|
|
46
59
|
procedure_references: resultOf(z.object({
|
|
47
60
|
procedure: procedureIdentity,
|
|
48
61
|
direction: z.enum(["incoming", "outgoing"]),
|
|
@@ -69,6 +82,55 @@ export const officialOutputSchemas = {
|
|
|
69
82
|
unset_bookmark: resultOf(z.boolean()),
|
|
70
83
|
xrefs: resultOf(addressList),
|
|
71
84
|
};
|
|
85
|
+
const literalTraceOutput = resultOf(z.object({
|
|
86
|
+
query: z.string(),
|
|
87
|
+
search_mode: z.literal("literal"),
|
|
88
|
+
operations_used: z.number().int().min(0),
|
|
89
|
+
operation_budget: z.number().int().min(1),
|
|
90
|
+
matches: z.array(z.object({
|
|
91
|
+
type: z.enum(["string", "procedure"]),
|
|
92
|
+
address: z.string(),
|
|
93
|
+
value: z.string(),
|
|
94
|
+
})),
|
|
95
|
+
references: z.array(z.object({
|
|
96
|
+
target_address: z.string(),
|
|
97
|
+
source_address: z.string(),
|
|
98
|
+
containing_procedure: containingProcedureResolution,
|
|
99
|
+
})),
|
|
100
|
+
truncated: z.boolean(),
|
|
101
|
+
residual_unknowns: z.array(z.string()),
|
|
102
|
+
}));
|
|
103
|
+
const callPathTraceOutput = resultOf(z.object({
|
|
104
|
+
start: z.string(),
|
|
105
|
+
goal: z.string().nullable(),
|
|
106
|
+
direction: z.enum(["forward", "backward"]),
|
|
107
|
+
goal_status: z.enum(["not_requested", "reached", "not_reached"]),
|
|
108
|
+
nodes: z.array(z.object({
|
|
109
|
+
address: z.string(),
|
|
110
|
+
depth: z.number().int().min(0),
|
|
111
|
+
})),
|
|
112
|
+
edges: z.array(z.object({
|
|
113
|
+
source_address: z.string(),
|
|
114
|
+
target_address: z.string(),
|
|
115
|
+
discovery_depth: z.number().int().min(1),
|
|
116
|
+
})),
|
|
117
|
+
traversal_path: z.array(z.string()),
|
|
118
|
+
failures: z.array(z.object({
|
|
119
|
+
address: z.string(),
|
|
120
|
+
error: analysisErrorProjectionSchema,
|
|
121
|
+
})),
|
|
122
|
+
frontier: z.array(z.string()),
|
|
123
|
+
limits: z.object({
|
|
124
|
+
max_depth: z.number().int().min(1),
|
|
125
|
+
max_nodes: z.number().int().min(1),
|
|
126
|
+
max_operations: z.number().int().min(1),
|
|
127
|
+
nodes_visited: z.number().int().min(1),
|
|
128
|
+
operations_used: z.number().int().min(0),
|
|
129
|
+
}),
|
|
130
|
+
truncated: z.boolean(),
|
|
131
|
+
residual_unknowns: z.array(z.string()),
|
|
132
|
+
limitations: z.array(z.string()),
|
|
133
|
+
}));
|
|
72
134
|
/** Exact structured-content schemas for composed analysis workflows. */
|
|
73
135
|
export const enhancedOutputSchemas = {
|
|
74
136
|
swift_classes: symbolDiscoveryOutput("classes"),
|
|
@@ -126,24 +188,9 @@ export const enhancedOutputSchemas = {
|
|
|
126
188
|
string_count: z.number().int().min(0),
|
|
127
189
|
})),
|
|
128
190
|
analyze_function: functionDossierOutput,
|
|
129
|
-
trace_feature:
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
operations_used: z.number().int().min(0),
|
|
133
|
-
operation_budget: z.number().int().min(1),
|
|
134
|
-
matches: z.array(z.object({
|
|
135
|
-
type: z.enum(["string", "procedure"]),
|
|
136
|
-
address: z.string(),
|
|
137
|
-
value: z.string(),
|
|
138
|
-
})),
|
|
139
|
-
references: z.array(z.object({
|
|
140
|
-
target_address: z.string(),
|
|
141
|
-
source_address: z.string(),
|
|
142
|
-
containing_procedure: containingProcedureResolution,
|
|
143
|
-
})),
|
|
144
|
-
truncated: z.boolean(),
|
|
145
|
-
residual_unknowns: z.array(z.string()),
|
|
146
|
-
})),
|
|
191
|
+
trace_feature: literalTraceOutput,
|
|
192
|
+
find_code_for_string: literalTraceOutput,
|
|
193
|
+
trace_call_path: callPathTraceOutput,
|
|
147
194
|
};
|
|
148
195
|
/** Exact Evidence v2 schemas for provider-neutral native inspection. */
|
|
149
196
|
export const nativeOutputSchemas = {
|
|
@@ -156,6 +203,7 @@ export const nativeOutputSchemas = {
|
|
|
156
203
|
/** Exact Evidence v2 schemas for provider-neutral artifact graph operations. */
|
|
157
204
|
export const artifactOutputSchemas = {
|
|
158
205
|
inventory_artifact: resultOf(artifactInventoryResultSchema),
|
|
206
|
+
inspect_artifact: resultOf(artifactInspectionResultSchema),
|
|
159
207
|
extract_artifact: resultOf(artifactExtractionResultSchema),
|
|
160
208
|
};
|
|
161
209
|
/** Exact Evidence v2 schema for execution-free managed static analysis. */
|
|
@@ -210,6 +258,7 @@ export const sessionOutputSchemas = {
|
|
|
210
258
|
reasons: z.array(z.string()),
|
|
211
259
|
remediation: z.string().nullable(),
|
|
212
260
|
}),
|
|
261
|
+
analysis_activity: analysisActivity,
|
|
213
262
|
recommended_actions: z.array(z.string()),
|
|
214
263
|
}),
|
|
215
264
|
z.object({
|
|
@@ -226,6 +275,7 @@ export const sessionOutputSchemas = {
|
|
|
226
275
|
next_cursor: z.number().int().min(0).nullable(),
|
|
227
276
|
has_more: z.boolean(),
|
|
228
277
|
}),
|
|
278
|
+
client_features: clientFeatureAvailabilitySchema,
|
|
229
279
|
}),
|
|
230
280
|
z.union([
|
|
231
281
|
sessionProvider.extend({
|
|
@@ -27,6 +27,8 @@ export const targetFormatSchema = z.enum([
|
|
|
27
27
|
"zip",
|
|
28
28
|
"ipa",
|
|
29
29
|
"apk",
|
|
30
|
+
"msix",
|
|
31
|
+
"appx",
|
|
30
32
|
"asar",
|
|
31
33
|
"dmg",
|
|
32
34
|
"pkg",
|
|
@@ -44,6 +46,7 @@ const providerCapability = z.object({
|
|
|
44
46
|
operation: z.string(),
|
|
45
47
|
available: z.boolean(),
|
|
46
48
|
reason: z.string().nullable(),
|
|
49
|
+
availability_code: z.enum(PROVIDER_REJECTION_CODES).nullable(),
|
|
47
50
|
input_contract_version: z.number().int().min(1),
|
|
48
51
|
output_contract_version: z.number().int().min(1),
|
|
49
52
|
pagination: z.enum(["none", "offset", "cursor"]),
|
|
@@ -108,6 +111,22 @@ const analysisRun = z
|
|
|
108
111
|
]),
|
|
109
112
|
})
|
|
110
113
|
.nullable();
|
|
114
|
+
export const analysisActivity = z.object({
|
|
115
|
+
status: z.enum(["not_observed", "idle", "busy", "timed_out_busy"]),
|
|
116
|
+
providers: z.array(z.object({
|
|
117
|
+
provider: providerIdentity,
|
|
118
|
+
active: z
|
|
119
|
+
.object({
|
|
120
|
+
request_id: z.number().int().min(1),
|
|
121
|
+
operation: z.string().min(1),
|
|
122
|
+
elapsed_ms: z.number().int().min(0),
|
|
123
|
+
timeout_ms: z.number().int().min(0),
|
|
124
|
+
caller_state: z.enum(["waiting", "timed_out", "cancelled"]),
|
|
125
|
+
})
|
|
126
|
+
.nullable(),
|
|
127
|
+
queued_requests: z.number().int().min(0),
|
|
128
|
+
})),
|
|
129
|
+
});
|
|
111
130
|
const providerRejectionCode = z.enum(PROVIDER_REJECTION_CODES);
|
|
112
131
|
const providerDiagnostics = z.record(z.string(), z.json());
|
|
113
132
|
const providerAvailability = z.discriminatedUnion("status", [
|
|
@@ -150,12 +169,26 @@ const providerTargetSupport = z.discriminatedUnion("status", [
|
|
|
150
169
|
diagnostics: providerDiagnostics,
|
|
151
170
|
}),
|
|
152
171
|
]);
|
|
172
|
+
const clientFeatureNameSchema = z.enum([
|
|
173
|
+
"elicitation_form",
|
|
174
|
+
"elicitation_url",
|
|
175
|
+
"roots",
|
|
176
|
+
"sampling",
|
|
177
|
+
]);
|
|
178
|
+
/** Negotiated MCP client features that affect REA workflow availability. */
|
|
179
|
+
export const clientFeatureAvailabilitySchema = z.object({
|
|
180
|
+
elicitation_form: z.boolean(),
|
|
181
|
+
elicitation_url: z.boolean(),
|
|
182
|
+
roots: z.boolean(),
|
|
183
|
+
sampling: z.boolean(),
|
|
184
|
+
});
|
|
153
185
|
export const toolAvailability = z.object({
|
|
154
186
|
name: z.string(),
|
|
155
187
|
surface: z.string(),
|
|
156
188
|
available: z.boolean(),
|
|
157
189
|
reason: z.enum([
|
|
158
190
|
"available",
|
|
191
|
+
"client_capability_missing",
|
|
159
192
|
"target_required",
|
|
160
193
|
"provider_missing",
|
|
161
194
|
"provider_unavailable",
|
|
@@ -164,6 +197,12 @@ export const toolAvailability = z.object({
|
|
|
164
197
|
"policy_disabled",
|
|
165
198
|
]),
|
|
166
199
|
remediation: z.string().nullable(),
|
|
200
|
+
client_requirements: z.object({
|
|
201
|
+
required: z.array(clientFeatureNameSchema),
|
|
202
|
+
optional: z.array(clientFeatureNameSchema),
|
|
203
|
+
missing_required: z.array(clientFeatureNameSchema),
|
|
204
|
+
missing_optional: z.array(clientFeatureNameSchema),
|
|
205
|
+
}),
|
|
167
206
|
effects: z.strictObject({
|
|
168
207
|
mutatesTarget: z.boolean(),
|
|
169
208
|
mutatesSession: z.boolean(),
|
|
@@ -186,6 +225,7 @@ export const sessionProvider = z.object({
|
|
|
186
225
|
providers: z.array(providerIdentity),
|
|
187
226
|
capabilities: z.array(providerCapability),
|
|
188
227
|
analysis_run: analysisRun,
|
|
228
|
+
analysis_activity: analysisActivity,
|
|
189
229
|
analysis_provider_binding: z
|
|
190
230
|
.object({
|
|
191
231
|
provider: providerIdentity,
|
|
@@ -21,6 +21,8 @@ export const projectAnalysisError = (error) => {
|
|
|
21
21
|
};
|
|
22
22
|
};
|
|
23
23
|
const errorCode = (error) => {
|
|
24
|
+
if (error.cleanupIncomplete)
|
|
25
|
+
return "cleanup_incomplete";
|
|
24
26
|
if (error instanceof ReplayPlanStaleError)
|
|
25
27
|
return "plan_stale";
|
|
26
28
|
if (error instanceof PermissionRequiredError)
|
|
@@ -221,6 +223,12 @@ const providerErrorDetails = (error) => {
|
|
|
221
223
|
return {
|
|
222
224
|
provider_id: error.providerId,
|
|
223
225
|
operation: error.operation,
|
|
226
|
+
...(error.cleanupIncomplete
|
|
227
|
+
? {
|
|
228
|
+
cleanup: "incomplete",
|
|
229
|
+
resources: [...error.cleanupResources],
|
|
230
|
+
}
|
|
231
|
+
: {}),
|
|
224
232
|
...(error.diagnostics === undefined
|
|
225
233
|
? {}
|
|
226
234
|
: { diagnostics: error.diagnostics }),
|
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import canonicalize from "canonicalize";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { artifactInventoryResultSchema, } from "./artifactGraph.js";
|
|
5
|
+
import { evidenceSchema, parseEvidence } from "./evidence.js";
|
|
6
|
+
import { jsonValueSchema } from "./jsonValue.js";
|
|
7
|
+
const boundedTextSchema = z.string().min(1).max(4_096);
|
|
8
|
+
const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
|
|
9
|
+
const artifactIdSchema = z.string().regex(/^art_[a-f0-9]{64}$/u);
|
|
10
|
+
const inspectionLimitsSchema = z.strictObject({
|
|
11
|
+
max_observations: z.number().int().min(1).max(500).default(100),
|
|
12
|
+
max_relationships: z.number().int().min(1).max(500).default(100),
|
|
13
|
+
max_hypotheses: z.number().int().min(1).max(100).default(20),
|
|
14
|
+
max_unexplored_branches: z.number().int().min(1).max(100).default(20),
|
|
15
|
+
max_next_probes: z.number().int().min(1).max(50).default(20),
|
|
16
|
+
max_substeps: z.literal(1).default(1),
|
|
17
|
+
});
|
|
18
|
+
export const artifactInspectionLimitsSchema = inspectionLimitsSchema;
|
|
19
|
+
const inspectionObservationSchema = z.strictObject({
|
|
20
|
+
observation_id: z.string().regex(/^aio_[a-f0-9]{64}$/u),
|
|
21
|
+
kind: z.enum(["root-manifest", "artifact", "occurrence", "integrity"]),
|
|
22
|
+
subject: boundedTextSchema,
|
|
23
|
+
value: jsonValueSchema,
|
|
24
|
+
evidence_id: evidenceIdSchema,
|
|
25
|
+
});
|
|
26
|
+
const inspectionRelationshipSchema = z.strictObject({
|
|
27
|
+
relationship_id: z.string().regex(/^air_[a-f0-9]{64}$/u),
|
|
28
|
+
relation: z.enum([
|
|
29
|
+
"contains",
|
|
30
|
+
"extracts",
|
|
31
|
+
"slice-of",
|
|
32
|
+
"embeds",
|
|
33
|
+
"loads",
|
|
34
|
+
"maps-source",
|
|
35
|
+
"derived-from",
|
|
36
|
+
]),
|
|
37
|
+
source_artifact_id: artifactIdSchema,
|
|
38
|
+
target_artifact_id: artifactIdSchema,
|
|
39
|
+
occurrence_id: z.string().regex(/^occ_[a-f0-9]{64}$/u),
|
|
40
|
+
logical_path: boundedTextSchema.nullable(),
|
|
41
|
+
evidence_id: evidenceIdSchema,
|
|
42
|
+
});
|
|
43
|
+
const inspectionHypothesisSchema = z.strictObject({
|
|
44
|
+
hypothesis_id: z.string().regex(/^aih_[a-f0-9]{64}$/u),
|
|
45
|
+
statement: boundedTextSchema,
|
|
46
|
+
confidence: z.enum(["medium", "low"]),
|
|
47
|
+
basis_evidence_ids: z.array(evidenceIdSchema).min(1).max(8),
|
|
48
|
+
limitation: boundedTextSchema,
|
|
49
|
+
});
|
|
50
|
+
const inspectionContradictionSchema = z.strictObject({
|
|
51
|
+
contradiction_id: z.string().regex(/^aic_[a-f0-9]{64}$/u),
|
|
52
|
+
statement: boundedTextSchema,
|
|
53
|
+
occurrence_id: z.string().regex(/^occ_[a-f0-9]{64}$/u),
|
|
54
|
+
declared_sha256: z.string().regex(/^[a-f0-9]{64}$/u),
|
|
55
|
+
observed_sha256: z.string().regex(/^[a-f0-9]{64}$/u),
|
|
56
|
+
evidence_id: evidenceIdSchema,
|
|
57
|
+
});
|
|
58
|
+
const nextProbeSchema = z.strictObject({
|
|
59
|
+
operation: z.string().min(1).max(128),
|
|
60
|
+
rationale: boundedTextSchema,
|
|
61
|
+
authority: z.enum([
|
|
62
|
+
"artifact-bytes",
|
|
63
|
+
"managed-static-analysis",
|
|
64
|
+
"native-analysis-provider",
|
|
65
|
+
"ast-static-analysis",
|
|
66
|
+
]),
|
|
67
|
+
});
|
|
68
|
+
const unexploredBranchSchema = z.strictObject({
|
|
69
|
+
branch_id: z.string().regex(/^aib_[a-f0-9]{64}$/u),
|
|
70
|
+
reason: z.enum([
|
|
71
|
+
"page-limit",
|
|
72
|
+
"format-specific-analysis-required",
|
|
73
|
+
"unknown-format",
|
|
74
|
+
]),
|
|
75
|
+
detail: boundedTextSchema,
|
|
76
|
+
next_probe: nextProbeSchema.nullable(),
|
|
77
|
+
evidence_id: evidenceIdSchema,
|
|
78
|
+
});
|
|
79
|
+
/** Provider-neutral inspection result with its atomic source Evidence. */
|
|
80
|
+
export const artifactInspectionResultSchema = z.strictObject({
|
|
81
|
+
schema_version: z.literal(1),
|
|
82
|
+
inspection_id: z.string().regex(/^ai_[a-f0-9]{64}$/u),
|
|
83
|
+
subject: z.strictObject({
|
|
84
|
+
manifest_id: z.string().regex(/^agm_[a-f0-9]{64}$/u),
|
|
85
|
+
root_artifact_id: artifactIdSchema,
|
|
86
|
+
root_sha256: z.string().regex(/^[a-f0-9]{64}$/u),
|
|
87
|
+
root_format: z.string().min(1).max(128),
|
|
88
|
+
}),
|
|
89
|
+
substeps: z
|
|
90
|
+
.array(z.strictObject({
|
|
91
|
+
substep_id: z.string().regex(/^ais_[a-f0-9]{64}$/u),
|
|
92
|
+
operation: z.literal("inventory_artifact"),
|
|
93
|
+
status: z.literal("completed"),
|
|
94
|
+
evidence_id: evidenceIdSchema,
|
|
95
|
+
evidence: evidenceSchema,
|
|
96
|
+
}))
|
|
97
|
+
.min(1)
|
|
98
|
+
.max(1),
|
|
99
|
+
observations: z.array(inspectionObservationSchema).max(500),
|
|
100
|
+
derived_relationships: z.array(inspectionRelationshipSchema).max(500),
|
|
101
|
+
hypotheses: z.array(inspectionHypothesisSchema).max(100),
|
|
102
|
+
contradictions: z.array(inspectionContradictionSchema).max(100),
|
|
103
|
+
unexplored_branches: z.array(unexploredBranchSchema).max(100),
|
|
104
|
+
next_probes: z.array(nextProbeSchema).max(50),
|
|
105
|
+
coverage: z.strictObject({
|
|
106
|
+
status: z.enum(["complete-within-substeps", "partial", "truncated"]),
|
|
107
|
+
substeps_completed: z.literal(1),
|
|
108
|
+
observations_retained: z.number().int().min(0),
|
|
109
|
+
observations_omitted: z.number().int().min(0),
|
|
110
|
+
relationships_retained: z.number().int().min(0),
|
|
111
|
+
relationships_omitted: z.number().int().min(0),
|
|
112
|
+
hypotheses_retained: z.number().int().min(0),
|
|
113
|
+
hypotheses_omitted: z.number().int().min(0),
|
|
114
|
+
unexplored_branches_retained: z.number().int().min(0),
|
|
115
|
+
unexplored_branches_omitted: z.number().int().min(0),
|
|
116
|
+
next_probes_retained: z.number().int().min(0),
|
|
117
|
+
next_probes_omitted: z.number().int().min(0),
|
|
118
|
+
}),
|
|
119
|
+
evidence_links: z.array(evidenceIdSchema).min(1).max(1),
|
|
120
|
+
limitations: z.array(boundedTextSchema).max(1_000),
|
|
121
|
+
});
|
|
122
|
+
/** Project one successful inventory Evidence record into an inspection report. */
|
|
123
|
+
export const createArtifactInspection = (inventoryInput, limits) => {
|
|
124
|
+
const inventoryEvidence = parseInventoryEvidence(inventoryInput);
|
|
125
|
+
const inventory = artifactInventoryResultSchema.parse(inventoryEvidence.normalized_result);
|
|
126
|
+
const observations = allObservations(inventory, inventoryEvidence.evidence_id);
|
|
127
|
+
const relationships = allRelationships(inventory, inventoryEvidence.evidence_id);
|
|
128
|
+
const hypotheses = allHypotheses(inventory, inventoryEvidence.evidence_id);
|
|
129
|
+
const nextProbes = probesFor(inventory);
|
|
130
|
+
const branches = allUnexploredBranches(inventory, inventoryEvidence.evidence_id, nextProbes);
|
|
131
|
+
const retained = {
|
|
132
|
+
observations: observations.slice(0, limits.max_observations),
|
|
133
|
+
relationships: relationships.slice(0, limits.max_relationships),
|
|
134
|
+
hypotheses: hypotheses.slice(0, limits.max_hypotheses),
|
|
135
|
+
branches: branches.slice(0, limits.max_unexplored_branches),
|
|
136
|
+
probes: nextProbes.slice(0, limits.max_next_probes),
|
|
137
|
+
};
|
|
138
|
+
const omissions = {
|
|
139
|
+
observations: observations.length - retained.observations.length,
|
|
140
|
+
relationships: relationships.length - retained.relationships.length,
|
|
141
|
+
hypotheses: hypotheses.length - retained.hypotheses.length,
|
|
142
|
+
branches: branches.length - retained.branches.length,
|
|
143
|
+
probes: nextProbes.length - retained.probes.length,
|
|
144
|
+
};
|
|
145
|
+
const semantic = {
|
|
146
|
+
schema_version: 1,
|
|
147
|
+
subject: {
|
|
148
|
+
manifest_id: inventory.manifest.manifest_id,
|
|
149
|
+
root_artifact_id: inventory.manifest.root_artifact_id,
|
|
150
|
+
root_sha256: inventory.manifest.root_sha256,
|
|
151
|
+
root_format: inventory.manifest.root_format,
|
|
152
|
+
},
|
|
153
|
+
substeps: [
|
|
154
|
+
{
|
|
155
|
+
substep_id: `ais_${digestCanonical({
|
|
156
|
+
operation: "inventory_artifact",
|
|
157
|
+
evidence_id: inventoryEvidence.evidence_id,
|
|
158
|
+
})}`,
|
|
159
|
+
operation: "inventory_artifact",
|
|
160
|
+
status: "completed",
|
|
161
|
+
evidence_id: inventoryEvidence.evidence_id,
|
|
162
|
+
evidence: inventoryEvidence,
|
|
163
|
+
},
|
|
164
|
+
],
|
|
165
|
+
observations: retained.observations,
|
|
166
|
+
derived_relationships: retained.relationships,
|
|
167
|
+
hypotheses: retained.hypotheses,
|
|
168
|
+
contradictions: contradictions(inventory, inventoryEvidence.evidence_id),
|
|
169
|
+
unexplored_branches: retained.branches,
|
|
170
|
+
next_probes: retained.probes,
|
|
171
|
+
coverage: {
|
|
172
|
+
status: inspectionCoverage(inventory, omissions),
|
|
173
|
+
substeps_completed: 1,
|
|
174
|
+
observations_retained: retained.observations.length,
|
|
175
|
+
observations_omitted: omissions.observations,
|
|
176
|
+
relationships_retained: retained.relationships.length,
|
|
177
|
+
relationships_omitted: omissions.relationships,
|
|
178
|
+
hypotheses_retained: retained.hypotheses.length,
|
|
179
|
+
hypotheses_omitted: omissions.hypotheses,
|
|
180
|
+
unexplored_branches_retained: retained.branches.length,
|
|
181
|
+
unexplored_branches_omitted: omissions.branches,
|
|
182
|
+
next_probes_retained: retained.probes.length,
|
|
183
|
+
next_probes_omitted: omissions.probes,
|
|
184
|
+
},
|
|
185
|
+
evidence_links: [inventoryEvidence.evidence_id],
|
|
186
|
+
limitations: uniqueSorted([
|
|
187
|
+
...inventory.limitations,
|
|
188
|
+
"Inspection derives bounded static hypotheses and next probes; it does not execute the artifact or claim format-specific semantics.",
|
|
189
|
+
]),
|
|
190
|
+
};
|
|
191
|
+
return artifactInspectionResultSchema.parse({
|
|
192
|
+
...semantic,
|
|
193
|
+
inspection_id: `ai_${digestCanonical(semantic)}`,
|
|
194
|
+
});
|
|
195
|
+
};
|
|
196
|
+
const parseInventoryEvidence = (input) => {
|
|
197
|
+
const evidence = parseEvidence(input);
|
|
198
|
+
if (evidence.operation !== "inventory_artifact")
|
|
199
|
+
throw new TypeError("Artifact inspection substep requires inventory_artifact Evidence");
|
|
200
|
+
return evidence;
|
|
201
|
+
};
|
|
202
|
+
const allObservations = (inventory, evidenceId) => [
|
|
203
|
+
observation("root-manifest", inventory.manifest.root_artifact_id, inventory.manifest, evidenceId),
|
|
204
|
+
...inventory.nodes.items.map((node) => observation("artifact", node.artifact_id, node, evidenceId)),
|
|
205
|
+
...inventory.occurrences.items.map((occurrence) => observation("occurrence", occurrence.occurrence_id, occurrence, evidenceId)),
|
|
206
|
+
...inventory.integrity_contradictions.map((value) => observation("integrity", value.contradiction_id, value, evidenceId)),
|
|
207
|
+
];
|
|
208
|
+
const observation = (kind, subject, value, evidenceId) => {
|
|
209
|
+
const semantic = {
|
|
210
|
+
kind,
|
|
211
|
+
subject,
|
|
212
|
+
value: jsonValueSchema.parse(value),
|
|
213
|
+
evidence_id: evidenceId,
|
|
214
|
+
};
|
|
215
|
+
return { observation_id: `aio_${digestCanonical(semantic)}`, ...semantic };
|
|
216
|
+
};
|
|
217
|
+
const allRelationships = (inventory, evidenceId) => inventory.edges.items.map((edge) => {
|
|
218
|
+
const semantic = {
|
|
219
|
+
relation: edge.relation,
|
|
220
|
+
source_artifact_id: edge.parent_artifact_id,
|
|
221
|
+
target_artifact_id: edge.child_artifact_id,
|
|
222
|
+
occurrence_id: edge.occurrence_id,
|
|
223
|
+
logical_path: edge.logical_path,
|
|
224
|
+
evidence_id: evidenceId,
|
|
225
|
+
};
|
|
226
|
+
return {
|
|
227
|
+
relationship_id: `air_${digestCanonical(semantic)}`,
|
|
228
|
+
...semantic,
|
|
229
|
+
};
|
|
230
|
+
});
|
|
231
|
+
const allHypotheses = (inventory, evidenceId) => {
|
|
232
|
+
const statements = inventory.manifest.root_format === "pe"
|
|
233
|
+
? [
|
|
234
|
+
"The PE artifact may contain managed CLI metadata or native code; inventory bytes alone do not distinguish them.",
|
|
235
|
+
]
|
|
236
|
+
: ["asar", "javascript-bundle"].includes(inventory.manifest.root_format)
|
|
237
|
+
? [
|
|
238
|
+
"The artifact may contain a recoverable JavaScript application graph.",
|
|
239
|
+
]
|
|
240
|
+
: [];
|
|
241
|
+
return statements.map((statement) => {
|
|
242
|
+
const semantic = {
|
|
243
|
+
statement,
|
|
244
|
+
confidence: "low",
|
|
245
|
+
basis_evidence_ids: [evidenceId],
|
|
246
|
+
limitation: "Format classification proposes a bounded follow-up; it is not semantic proof.",
|
|
247
|
+
};
|
|
248
|
+
return { hypothesis_id: `aih_${digestCanonical(semantic)}`, ...semantic };
|
|
249
|
+
});
|
|
250
|
+
};
|
|
251
|
+
const contradictions = (inventory, evidenceId) => inventory.integrity_contradictions.map((value) => {
|
|
252
|
+
const semantic = {
|
|
253
|
+
statement: `Declared integrity for ${value.logical_path} contradicts observed bytes.`,
|
|
254
|
+
occurrence_id: value.occurrence_id,
|
|
255
|
+
declared_sha256: value.declared_sha256,
|
|
256
|
+
observed_sha256: value.observed_sha256,
|
|
257
|
+
evidence_id: evidenceId,
|
|
258
|
+
};
|
|
259
|
+
return {
|
|
260
|
+
contradiction_id: `aic_${digestCanonical(semantic)}`,
|
|
261
|
+
...semantic,
|
|
262
|
+
};
|
|
263
|
+
});
|
|
264
|
+
const probesFor = (inventory) => {
|
|
265
|
+
const format = inventory.manifest.root_format;
|
|
266
|
+
if (["asar", "javascript-bundle", "directory"].includes(format))
|
|
267
|
+
return [
|
|
268
|
+
{
|
|
269
|
+
operation: "analyze_javascript_application",
|
|
270
|
+
rationale: "Recover bounded JavaScript modules, source maps, Electron boundaries, and application relationships.",
|
|
271
|
+
authority: "ast-static-analysis",
|
|
272
|
+
},
|
|
273
|
+
];
|
|
274
|
+
if (format === "pe")
|
|
275
|
+
return [
|
|
276
|
+
{
|
|
277
|
+
operation: "inspect_managed_artifact",
|
|
278
|
+
rationale: "Check execution-free CLI metadata before choosing a deep native provider.",
|
|
279
|
+
authority: "managed-static-analysis",
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
operation: "open_binary",
|
|
283
|
+
rationale: "Open as native code only when managed inspection reports a native or mixed boundary.",
|
|
284
|
+
authority: "native-analysis-provider",
|
|
285
|
+
},
|
|
286
|
+
];
|
|
287
|
+
if (["mach-o", "mach-o-universal", "elf"].includes(format))
|
|
288
|
+
return [
|
|
289
|
+
{
|
|
290
|
+
operation: "open_binary",
|
|
291
|
+
rationale: "Bind one deep native provider before function-level analysis.",
|
|
292
|
+
authority: "native-analysis-provider",
|
|
293
|
+
},
|
|
294
|
+
];
|
|
295
|
+
if (format === "plist")
|
|
296
|
+
return [
|
|
297
|
+
{
|
|
298
|
+
operation: "inspect_plist",
|
|
299
|
+
rationale: "Parse property-list values without executing the artifact.",
|
|
300
|
+
authority: "artifact-bytes",
|
|
301
|
+
},
|
|
302
|
+
];
|
|
303
|
+
return [];
|
|
304
|
+
};
|
|
305
|
+
const allUnexploredBranches = (inventory, evidenceId, nextProbes) => {
|
|
306
|
+
const pages = [
|
|
307
|
+
["nodes", inventory.nodes.next_offset],
|
|
308
|
+
["occurrences", inventory.occurrences.next_offset],
|
|
309
|
+
["relationships", inventory.edges.next_offset],
|
|
310
|
+
];
|
|
311
|
+
const branches = pages.flatMap(([collection, nextOffset]) => nextOffset === null
|
|
312
|
+
? []
|
|
313
|
+
: [
|
|
314
|
+
branch("page-limit", `${collection} continue at offset ${String(nextOffset)}.`, null, evidenceId),
|
|
315
|
+
]);
|
|
316
|
+
branches.push(...nextProbes.map((probe) => branch("format-specific-analysis-required", `${probe.operation} was not run by provider-neutral artifact inspection.`, probe, evidenceId)));
|
|
317
|
+
if (inventory.manifest.root_format === "unknown")
|
|
318
|
+
branches.push(branch("unknown-format", "Artifact bytes did not match an admitted format classifier.", null, evidenceId));
|
|
319
|
+
return branches;
|
|
320
|
+
};
|
|
321
|
+
const branch = (reason, detail, nextProbe, evidenceId) => {
|
|
322
|
+
const semantic = {
|
|
323
|
+
reason,
|
|
324
|
+
detail,
|
|
325
|
+
next_probe: nextProbe,
|
|
326
|
+
evidence_id: evidenceId,
|
|
327
|
+
};
|
|
328
|
+
return { branch_id: `aib_${digestCanonical(semantic)}`, ...semantic };
|
|
329
|
+
};
|
|
330
|
+
const inspectionCoverage = (inventory, omissions) => {
|
|
331
|
+
if (Object.values(omissions).some((count) => count > 0))
|
|
332
|
+
return "truncated";
|
|
333
|
+
return [
|
|
334
|
+
inventory.nodes.next_offset,
|
|
335
|
+
inventory.occurrences.next_offset,
|
|
336
|
+
inventory.edges.next_offset,
|
|
337
|
+
].some((offset) => offset !== null)
|
|
338
|
+
? "partial"
|
|
339
|
+
: "complete-within-substeps";
|
|
340
|
+
};
|
|
341
|
+
const digestCanonical = (value) => {
|
|
342
|
+
const encoded = canonicalize(value);
|
|
343
|
+
if (encoded === undefined)
|
|
344
|
+
throw new TypeError("Artifact inspection could not canonicalize");
|
|
345
|
+
return createHash("sha256").update(encoded).digest("hex");
|
|
346
|
+
};
|
|
347
|
+
const uniqueSorted = (values) => [...new Set(values)].sort((left, right) => left < right ? -1 : left > right ? 1 : 0);
|
|
@@ -6,6 +6,7 @@ import { extname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
|
6
6
|
import { promisify } from "node:util";
|
|
7
7
|
import { BinaryTargetError } from "./errors.js";
|
|
8
8
|
import { err, ok } from "./result.js";
|
|
9
|
+
import { zipPackageFormatForPath } from "./zipPackageFormat.js";
|
|
9
10
|
const execFileAsync = promisify(execFile);
|
|
10
11
|
/**
|
|
11
12
|
* Resolve and classify a readable local target before a provider is selected.
|
|
@@ -71,11 +72,7 @@ const detectArtifactFormat = async (path, handle) => {
|
|
|
71
72
|
magic[1] === 0x4b &&
|
|
72
73
|
[0x03, 0x05, 0x07].includes(magic[2] ?? -1) &&
|
|
73
74
|
[0x04, 0x06, 0x08].includes(magic[3] ?? -1)) {
|
|
74
|
-
return lower
|
|
75
|
-
? "ipa"
|
|
76
|
-
: lower.endsWith(".apk")
|
|
77
|
-
? "apk"
|
|
78
|
-
: "zip";
|
|
75
|
+
return zipPackageFormatForPath(lower) ?? "zip";
|
|
79
76
|
}
|
|
80
77
|
const named = namedArtifactFormat(lower);
|
|
81
78
|
if (named !== undefined)
|
|
@@ -104,7 +101,7 @@ const namedArtifactFormat = (lowerPath) => {
|
|
|
104
101
|
return "source-map";
|
|
105
102
|
return /\.(?:m?js|cjs)$/u.test(lowerPath) ? "javascript" : undefined;
|
|
106
103
|
};
|
|
107
|
-
const isArchiveFormat = (format) => ["zip", "ipa", "apk", "asar", "dmg", "pkg"].includes(format);
|
|
104
|
+
const isArchiveFormat = (format) => ["zip", "ipa", "apk", "msix", "appx", "asar", "dmg", "pkg"].includes(format);
|
|
108
105
|
const sha256Handle = async (handle) => {
|
|
109
106
|
const hash = createHash("sha256");
|
|
110
107
|
const chunk = Buffer.allocUnsafe(64 * 1024);
|