rea-agents 2.0.0 → 2.2.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 +103 -38
- package/bridge/ghidra/ReaGhidraBridge.java +96 -11
- package/dist/application/AndroidApplicationService.js +17 -0
- package/dist/application/AppleApplicationService.js +17 -0
- package/dist/application/ArtifactExtraction.js +1 -1
- package/dist/application/ArtifactInventory/classify.js +42 -0
- package/dist/application/ArtifactInventory/hash.js +43 -0
- package/dist/application/ArtifactInventory/reader.js +41 -0
- package/dist/application/ArtifactInventory/scanCanonical.js +155 -0
- package/dist/application/ArtifactInventory/scanReader.js +124 -0
- package/dist/application/ArtifactInventory/types.js +10 -0
- package/dist/application/ArtifactInventory.js +9 -351
- package/dist/application/AuthorizedArtifactInventory.js +2 -2
- package/dist/application/BinarySession.js +47 -270
- package/dist/application/BinarySessionExecution.js +28 -0
- package/dist/application/BinarySessionOpen.js +39 -0
- package/dist/application/BinarySessionRecords.js +149 -0
- package/dist/application/BinarySessionStatus.js +75 -0
- package/dist/application/CapabilityInventory.js +24 -2
- package/dist/application/ClientRegistrationStatus.js +11 -4
- package/dist/application/CrossVersionInventory.js +8 -2
- package/dist/application/CrossVersionInvestigation.js +1 -23
- package/dist/application/CrossVersionInvestigationCollections.js +23 -0
- package/dist/application/DirectAnalysis.js +47 -44
- package/dist/application/Doctor.js +156 -238
- package/dist/application/DoctorDiagnostics.js +180 -0
- package/dist/application/ElectronBoundaryAnalysis.js +23 -7
- package/dist/application/ElectronBoundaryGraphWindows.js +32 -8
- package/dist/application/EnhancedToolPagination.js +22 -0
- package/dist/application/EnhancedToolTypes.js +4 -0
- package/dist/application/EnhancedTools.js +20 -37
- package/dist/application/InstrumentedJavaScriptReplayHost.js +36 -0
- package/dist/application/InventoryProjectionEvidence.js +41 -0
- package/dist/application/InvestigationProviders.js +12 -0
- package/dist/application/InvestigationWorkspaceStore.js +24 -10
- package/dist/application/JavaScriptArtifactAnalysis.js +45 -6
- package/dist/application/JavaScriptArtifactFiles.js +6 -2
- package/dist/application/JavaScriptArtifactGraphBuilder.js +23 -1
- package/dist/application/JavaScriptArtifactGraphBundlers.js +225 -0
- package/dist/application/JavaScriptArtifactGraphContext.js +37 -36
- package/dist/application/JavaScriptArtifactGraphDocuments.js +27 -4
- package/dist/application/JavaScriptArtifactGraphFindings.js +54 -8
- package/dist/application/JavaScriptArtifactGraphStructure.js +29 -101
- package/dist/application/JavaScriptArtifactPathResolution.js +269 -0
- package/dist/application/JavaScriptArtifactReconstruction.js +1 -1
- package/dist/application/JavaScriptJsonModules.js +39 -0
- package/dist/application/JavaScriptModuleRelationships.js +262 -0
- package/dist/application/JavaScriptReplayPermission.js +16 -0
- package/dist/application/JavaScriptReplayService.js +182 -156
- package/dist/application/LinuxHopper.js +10 -0
- package/dist/application/MacHopper.js +22 -11
- package/dist/application/NodeRuntimeCharacterizationService.js +196 -0
- package/dist/application/PermissionAuthority.js +106 -63
- package/dist/application/ProcessCaptureCapability.js +1 -1
- package/dist/application/ProcessCapturePermission.js +13 -0
- package/dist/application/ProcessCli.js +2 -12
- package/dist/application/ProcessHarness.js +1 -1
- package/dist/application/ProcessPairedExperiment.js +72 -0
- package/dist/application/ProjectPermissionStore.js +48 -9
- package/dist/application/RealHopperAssertions.js +76 -0
- package/dist/application/ReconstructionCoverageService.js +69 -0
- package/dist/application/ReconstructionCoverageWorkspaceStore.js +31 -0
- package/dist/application/RuntimeExecutableDiagnostics.js +172 -0
- package/dist/application/Setup.js +148 -260
- package/dist/application/SetupClientConfiguration.js +224 -0
- package/dist/application/SetupClients.js +24 -2
- package/dist/application/SetupPlan.js +124 -12
- package/dist/application/SetupSkill.js +54 -36
- package/dist/application/SupportedClients.js +1 -0
- package/dist/application/Uninstall.js +12 -3
- package/dist/application/Upgrade.js +16 -1
- package/dist/application/WindowsCapabilities.js +86 -0
- package/dist/artifacts/AsarArtifactReader.js +11 -0
- package/dist/browser/BrowserProcessStartup.js +88 -0
- package/dist/browser/CdpCaptureDocuments.js +12 -8
- package/dist/browser/CdpCaptureEventBodyShapes.js +75 -0
- package/dist/browser/CdpCaptureEventHandlers.js +336 -0
- package/dist/browser/CdpCaptureEventHelpers.js +71 -0
- package/dist/browser/CdpCaptureEventState.js +1 -0
- package/dist/browser/CdpCaptureEventTypes.js +1 -0
- package/dist/browser/CdpCaptureEvents.js +29 -496
- package/dist/browser/CdpObservationSession.js +51 -8
- package/dist/browser/CdpPageCapture.js +12 -133
- package/dist/browser/CdpPageCaptureScripts.js +97 -0
- package/dist/browser/CdpPageCaptureWorkers.js +46 -0
- package/dist/browser/CdpWebMcpDiscovery.js +38 -14
- package/dist/browser/PngVisualDiff.js +9 -2
- package/dist/catalogIdentity.js +4 -0
- package/dist/cli/artifactCommands.js +82 -0
- package/dist/cli/coreAnalysisCommands.js +232 -0
- package/dist/cli/managedCommands.js +397 -0
- package/dist/cli/managedProjectGraphCommand.js +24 -0
- package/dist/cli/options.js +9 -0
- package/dist/cli/setupCommands.js +113 -0
- package/dist/cli/types.js +1 -0
- package/dist/cli/utilityCommands.js +122 -0
- package/dist/cli.js +10 -768
- package/dist/cliApplicationCommands.js +118 -4
- package/dist/cliBrowserAdvancedCommands.js +73 -16
- package/dist/cliBrowserCommands.js +39 -115
- package/dist/cliCommandNames.js +4 -0
- package/dist/cliElectronCommands.js +33 -62
- package/dist/cliEvidenceCommands.js +13 -2
- package/dist/cliInvestigationCommands.js +53 -10
- package/dist/cliObservationOptions.js +137 -0
- package/dist/cliPolicyCommands.js +80 -46
- package/dist/cliSetup.js +306 -0
- package/dist/config/environment.js +107 -0
- package/dist/config/parseConfig.js +228 -0
- package/dist/config/parsers.js +68 -0
- package/dist/config/permissions.js +30 -0
- package/dist/config/types.js +1 -0
- package/dist/config.js +1 -375
- package/dist/contracts/applicationToolContracts.js +134 -0
- package/dist/contracts/electronToolContracts.js +51 -3
- package/dist/contracts/managedToolContracts.js +8 -3
- package/dist/contracts/managedWorkflowToolContracts.js +3 -3
- package/dist/contracts/providerSelection.js +2 -0
- package/dist/contracts/sessionStatusContract.js +26 -0
- package/dist/contracts/toolContractTypes.js +12 -1
- package/dist/contracts/toolContracts.js +5 -12
- package/dist/contracts/toolEffects.js +14 -0
- package/dist/contracts/toolOutputSchemaGroups.js +274 -0
- package/dist/contracts/toolOutputSchemaPrimitives.js +328 -0
- package/dist/contracts/toolOutputSchemas.js +2 -550
- package/dist/domain/analysisErrorPresentation.js +234 -0
- package/dist/domain/analysisErrorProjection.js +284 -0
- package/dist/domain/androidApplication.js +206 -0
- package/dist/domain/appleApplication.js +221 -0
- package/dist/domain/artifactComparison.js +34 -15
- package/dist/domain/binaryTarget.js +87 -37
- package/dist/domain/boundedCartesianProjection.js +15 -0
- package/dist/domain/browserObservation.js +1 -285
- package/dist/domain/browserObservationSchemas.js +286 -0
- package/dist/domain/electronStaticAnalysisBrowser.js +14 -2
- package/dist/domain/errors.js +4 -486
- package/dist/domain/functionComparison.js +4 -165
- package/dist/domain/functionComparisonDimensions.js +164 -0
- package/dist/domain/javascriptApplicationVersionItems.js +18 -6
- package/dist/domain/javascriptApplicationVersionKeys.js +8 -8
- package/dist/domain/javascriptExportInstrumentation.js +97 -0
- package/dist/domain/javascriptFeatureTraversal.js +19 -7
- package/dist/domain/javascriptRuntimeStaticCandidates.js +3 -1
- package/dist/domain/javascriptSemanticAnalysis.js +386 -0
- package/dist/domain/javascriptSemanticIr.js +30 -0
- package/dist/domain/javascriptSemanticProjection.js +366 -0
- package/dist/domain/javascriptSemanticState.js +40 -0
- package/dist/domain/javascriptSemanticTraversal.js +22 -0
- package/dist/domain/javascriptSemanticValues.js +352 -0
- package/dist/domain/javascriptStaticAnalysis.js +5 -221
- package/dist/domain/javascriptStaticAnalysisBundler.js +209 -0
- package/dist/domain/javascriptStaticAnalysisCalls.js +180 -0
- package/dist/domain/javascriptStaticAnalysisHelpers.js +71 -2
- package/dist/domain/knownPageCoverage.js +21 -0
- package/dist/domain/managedApplicationGraph.js +14 -364
- package/dist/domain/managedApplicationGraphCoverage.js +170 -0
- package/dist/domain/managedApplicationGraphNodeCoverage.js +6 -0
- package/dist/domain/managedApplicationGraphNodes.js +336 -0
- package/dist/domain/managedArtifact.js +16 -8
- package/dist/domain/managedMemberComparison.js +37 -391
- package/dist/domain/managedMemberComparisonCoverage.js +72 -0
- package/dist/domain/managedMemberComparisonMatch.js +356 -0
- package/dist/domain/managedNativeVerification.js +27 -389
- package/dist/domain/managedNativeVerificationMatch.js +272 -0
- package/dist/domain/managedNativeVerificationSchemas.js +141 -0
- package/dist/domain/managedReconstruction.js +82 -69
- package/dist/domain/managedRuntimeCorrelation.js +12 -3
- package/dist/domain/nodeRuntimeCharacterization.js +66 -0
- package/dist/domain/permissionPolicy.js +2 -0
- package/dist/domain/processComparison.js +19 -0
- package/dist/domain/processPairedExperiment.js +128 -0
- package/dist/domain/reconstructionCoverage.js +387 -0
- package/dist/domain/reconstructionCoverageEvaluation.js +212 -0
- package/dist/domain/reconstructionVerificationSchemas.js +8 -0
- package/dist/domain/replayMachine.js +316 -0
- package/dist/domain/replayMachineRuntime.js +215 -0
- package/dist/domain/runtimeCharacterization.js +85 -0
- package/dist/domain/runtimeIdentification.js +210 -0
- package/dist/domain/webBundleAnalyzer.js +3 -409
- package/dist/domain/webBundleAnalyzerAst.js +77 -0
- package/dist/domain/webBundleAnalyzerInspection.js +307 -0
- package/dist/domain/webBundleAnalyzerResult.js +120 -0
- package/dist/dotnet/ManagedArtifactInspector.js +50 -29
- package/dist/dotnet/ManagedMemberInspector.js +51 -785
- package/dist/dotnet/ManagedMemberInspectorCore.js +297 -0
- package/dist/dotnet/ManagedMemberInstructionDecoder.js +427 -0
- package/dist/dotnet/ManagedMemberRows.js +120 -0
- package/dist/dotnet/ManagedMetadataInventory.js +42 -306
- package/dist/dotnet/ManagedMetadataInventoryRows.js +292 -0
- package/dist/dotnet/ManagedMetadataLayout.js +48 -111
- package/dist/dotnet/ManagedMetadataRowSizes.js +54 -0
- package/dist/dotnet/ManagedMethodBodyReader.js +143 -0
- package/dist/dotnet/ManagedNativeBoundaryHelpers.js +311 -0
- package/dist/dotnet/ManagedNativeBoundaryInspector.js +102 -350
- package/dist/dotnet/ManagedPeReader.js +59 -28
- package/dist/evaluation/CodexAgentEval.js +132 -0
- package/dist/generatedPackageMetadata.js +2 -2
- package/dist/ghidra/GhidraClient.js +76 -91
- package/dist/ghidra/GhidraClientStartup.js +29 -0
- package/dist/ghidra/GhidraClientWire.js +34 -0
- package/dist/ghidra/GhidraDefaults.js +1 -1
- package/dist/ghidra/GhidraDiagnostics.js +6 -1
- package/dist/ghidra/GhidraInstallation.js +20 -15
- package/dist/ghidra/GhidraLauncher.js +93 -29
- package/dist/ghidra/GhidraProvider.js +61 -161
- package/dist/ghidra/GhidraProviderCapabilities.js +173 -0
- package/dist/ghidra/GhidraSessionValues.js +2 -0
- package/dist/ghidra/GhidraSocketConnection.js +44 -7
- package/dist/ghidra/GhidraTargetSnapshot.js +30 -0
- package/dist/ghidra/GhidraTransport.js +71 -0
- package/dist/identity.js +4 -2
- package/dist/main/messages.js +5 -0
- package/dist/main/reload.js +49 -0
- package/dist/main/shutdown.js +25 -0
- package/dist/main/startup.js +14 -0
- package/dist/main/state.js +26 -0
- package/dist/main/transport.js +61 -0
- package/dist/main/types.js +1 -0
- package/dist/main.js +35 -146
- package/dist/process/PrivateRuntimeRoot.js +3 -2
- package/dist/process/ProcessOwnership.js +35 -0
- package/dist/process/ProviderProcess.js +2 -0
- package/dist/replay/JavaScriptReplayWorker.js +64 -50
- package/dist/replay/LinuxJavaScriptReplayRunner.js +173 -390
- package/dist/replay/LinuxJavaScriptReplaySandbox.js +140 -0
- package/dist/replay/ReplayOutcome.js +95 -0
- package/dist/replay/ReplayProcessLifecycle.js +71 -0
- package/dist/server/ProcessCaptureElicitation.js +157 -0
- package/dist/server/createServer.js +124 -56
- package/dist/server/javascriptApplicationResult.js +85 -0
- package/dist/server/registerApplicationTools/characterization.js +57 -0
- package/dist/server/registerApplicationTools/compareVersions.js +34 -0
- package/dist/server/registerApplicationTools/controlledReplay.js +38 -0
- package/dist/server/registerApplicationTools/coverage.js +84 -0
- package/dist/server/registerApplicationTools/helpers.js +42 -0
- package/dist/server/registerApplicationTools/traceFeature.js +26 -0
- package/dist/server/registerApplicationTools/types.js +1 -0
- package/dist/server/registerApplicationTools.js +10 -112
- package/dist/server/registerBrowserTools.js +59 -83
- package/dist/server/registerElectronTools.js +48 -49
- package/dist/server/registerEnhancedTools.js +34 -42
- package/dist/server/registerEvidenceResources.js +56 -0
- package/dist/server/registerInvestigationTools/helpers.js +74 -0
- package/dist/server/registerInvestigationTools/types.js +1 -0
- package/dist/server/registerInvestigationTools.js +83 -116
- package/dist/server/registerJavaScriptApplicationGraphResource.js +69 -0
- package/dist/server/registerManagedTools.js +18 -1
- package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +65 -0
- package/dist/server/registerManagedWorkflowTools/contract.js +8 -0
- package/dist/server/registerManagedWorkflowTools/evidence.js +43 -0
- package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +39 -0
- package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +39 -0
- package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +52 -0
- package/dist/server/registerManagedWorkflowTools/types.js +1 -0
- package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +75 -0
- package/dist/server/registerManagedWorkflowTools.js +10 -274
- package/dist/server/registerOfficialTools.js +73 -59
- package/dist/server/registerSessionRecordTools.js +137 -0
- package/dist/server/registerSessionStatusTool.js +97 -26
- package/dist/server/registerSessionTools.js +60 -164
- package/dist/server/sessionAvailabilityPolicy.js +10 -0
- package/dist/server/toolRegistrationOptions.js +101 -3
- package/dist/server/toolResult.js +15 -4
- package/package.json +11 -11
- package/skills/reverse-engineer-anything/SKILL.md +76 -0
- package/skills/reverse-engineer-anything/references/controlled-replay.md +12 -0
- package/skills/reverse-engineer-anything/references/evidence-workflows.md +33 -0
- package/skills/reverse-engineer-anything/references/javascript-applications.md +25 -0
- package/skills/reverse-engineer-anything/references/native-and-artifacts.md +36 -0
- package/skills/reverse-engineer-anything/references/runtime-observation.md +24 -0
- package/scripts/prepare-node-pty.mjs +0 -35
- package/scripts/rebuild-native.mjs +0 -22
- package/skills/rea-analysis/SKILL.md +0 -222
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { addArtifactContainsEdge,
|
|
2
|
-
import { artifactObservationEvidence,
|
|
1
|
+
import { addArtifactContainsEdge, addUnavailableStaticParseScope, artifactFileNodeKind, artifactLocalIdentity, createElectronRoleNode, linkElectronRoleToAsset, } from "./JavaScriptArtifactGraphContext.js";
|
|
2
|
+
import { artifactObservationEvidence, completeReconstructionCoverage, staticInferenceEvidence, } from "./JavaScriptArtifactGraphEvidence.js";
|
|
3
|
+
import { resolveArtifactPathByContext } from "./JavaScriptArtifactPathResolution.js";
|
|
4
|
+
export { addJavaScriptBundlerNodes } from "./JavaScriptArtifactGraphBundlers.js";
|
|
3
5
|
/** Create the exact root artifact node from the inventory manifest. */
|
|
4
6
|
export const createJavaScriptArtifactRootNode = (accumulator, snapshot) => {
|
|
5
7
|
const root = snapshot.nodes.find(({ artifact_id: id }) => id === snapshot.manifest.root_artifact_id);
|
|
@@ -130,6 +132,14 @@ export const addJavaScriptArtifactFiles = (context) => {
|
|
|
130
132
|
operation: "parse-package-json",
|
|
131
133
|
limitation: packageValue.limitation ?? "Package metadata could not be parsed.",
|
|
132
134
|
});
|
|
135
|
+
const jsonValue = context.analysis.json_modules.find(({ path }) => path === file.path);
|
|
136
|
+
if (jsonValue !== undefined && jsonValue.status !== "included")
|
|
137
|
+
addUnavailableStaticParseScope(context, {
|
|
138
|
+
file,
|
|
139
|
+
asset: target,
|
|
140
|
+
operation: "parse-json-module",
|
|
141
|
+
limitation: jsonValue.limitation ?? "JSON module content could not be parsed.",
|
|
142
|
+
});
|
|
133
143
|
const sourceMap = context.analysis.source_maps.find(({ path }) => path === file.path);
|
|
134
144
|
if (sourceMap !== undefined &&
|
|
135
145
|
(sourceMap.status === "invalid" || sourceMap.status === "not-approved"))
|
|
@@ -209,95 +219,9 @@ export const addJavaScriptPackageNodes = (context) => {
|
|
|
209
219
|
}
|
|
210
220
|
return roots;
|
|
211
221
|
};
|
|
212
|
-
/** Project Webpack/Rspack chunk and factory literals recovered from AST. */
|
|
213
|
-
export const addJavaScriptBundlerNodes = (context) => {
|
|
214
|
-
for (const analyzed of context.analysis.files) {
|
|
215
|
-
const { file, javascript } = analyzed;
|
|
216
|
-
const asset = context.assetNodes.get(file.path);
|
|
217
|
-
if (javascript === null || asset === undefined)
|
|
218
|
-
continue;
|
|
219
|
-
const coverage = javascriptAnalysisCoverage(javascript, context.input);
|
|
220
|
-
for (const registration of javascript.bundler_registrations) {
|
|
221
|
-
const chunkKey = `${registration.runtime}:${registration.chunk_keys.join(",")}`;
|
|
222
|
-
const chunk = context.accumulator.addNode({
|
|
223
|
-
kind: "javascript-chunk",
|
|
224
|
-
identity: artifactLocalIdentity(file.sha256, "bundler-chunk", chunkKey),
|
|
225
|
-
observations: [
|
|
226
|
-
{
|
|
227
|
-
label: chunkKey,
|
|
228
|
-
properties: {
|
|
229
|
-
path: file.path,
|
|
230
|
-
bundler: registration.bundler,
|
|
231
|
-
runtime: registration.runtime,
|
|
232
|
-
chunk_keys: registration.chunk_keys,
|
|
233
|
-
omitted_chunk_keys: registration.omitted_chunk_keys,
|
|
234
|
-
unknown_chunk_keys: registration.unknown_chunk_keys,
|
|
235
|
-
module_count: registration.modules.length,
|
|
236
|
-
},
|
|
237
|
-
evidence: astObservationEvidence({
|
|
238
|
-
sha256: file.sha256,
|
|
239
|
-
path: file.path,
|
|
240
|
-
range: registration.location,
|
|
241
|
-
operation: "extract-bundler-registration",
|
|
242
|
-
coverage,
|
|
243
|
-
limitations: javascript.limitations,
|
|
244
|
-
}),
|
|
245
|
-
},
|
|
246
|
-
],
|
|
247
|
-
});
|
|
248
|
-
addAstContainsEdge(context, {
|
|
249
|
-
source: asset,
|
|
250
|
-
target: chunk,
|
|
251
|
-
file,
|
|
252
|
-
range: registration.location,
|
|
253
|
-
coverage,
|
|
254
|
-
properties: { bundler: registration.bundler },
|
|
255
|
-
});
|
|
256
|
-
for (const moduleValue of registration.modules) {
|
|
257
|
-
const module = context.accumulator.addNode({
|
|
258
|
-
kind: "javascript-module",
|
|
259
|
-
identity: artifactLocalIdentity(file.sha256, `${registration.runtime}:module`, moduleValue.module_key),
|
|
260
|
-
observations: [
|
|
261
|
-
{
|
|
262
|
-
label: moduleValue.module_key,
|
|
263
|
-
properties: {
|
|
264
|
-
path: file.path,
|
|
265
|
-
bundler: registration.bundler,
|
|
266
|
-
runtime: registration.runtime,
|
|
267
|
-
module_key: moduleValue.module_key,
|
|
268
|
-
source_sha256: moduleValue.source_sha256,
|
|
269
|
-
structural_fingerprint_sha256: moduleValue.structural_fingerprint_sha256,
|
|
270
|
-
structural_fingerprint_algorithm: moduleValue.structural_fingerprint_algorithm,
|
|
271
|
-
structural_fingerprint_status: moduleValue.structural_fingerprint_status,
|
|
272
|
-
exports: moduleValue.exports,
|
|
273
|
-
exports_truncated: moduleValue.exports_truncated,
|
|
274
|
-
},
|
|
275
|
-
evidence: astObservationEvidence({
|
|
276
|
-
sha256: file.sha256,
|
|
277
|
-
path: file.path,
|
|
278
|
-
range: moduleValue.location,
|
|
279
|
-
operation: "extract-bundler-module",
|
|
280
|
-
coverage,
|
|
281
|
-
limitations: javascript.limitations,
|
|
282
|
-
}),
|
|
283
|
-
},
|
|
284
|
-
],
|
|
285
|
-
});
|
|
286
|
-
context.moduleNodes.set(moduleLookupKey(file.path, moduleValue.module_key), module);
|
|
287
|
-
addAstContainsEdge(context, {
|
|
288
|
-
source: chunk,
|
|
289
|
-
target: module,
|
|
290
|
-
file,
|
|
291
|
-
range: moduleValue.location,
|
|
292
|
-
coverage,
|
|
293
|
-
properties: { module_key: moduleValue.module_key },
|
|
294
|
-
});
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
};
|
|
299
222
|
const createFileTarget = (context, file, javascript) => {
|
|
300
223
|
const kind = artifactFileNodeKind(file.kind);
|
|
224
|
+
const json = context.analysis.json_modules.find(({ path }) => path === file.path);
|
|
301
225
|
return context.accumulator.addNode({
|
|
302
226
|
kind,
|
|
303
227
|
identity: {
|
|
@@ -316,6 +240,9 @@ const createFileTarget = (context, file, javascript) => {
|
|
|
316
240
|
file_kind: file.kind,
|
|
317
241
|
text_status: file.text.included ? "included" : file.text.reason,
|
|
318
242
|
parse_status: javascript?.parse_status ?? null,
|
|
243
|
+
json_parse_status: json?.status ?? null,
|
|
244
|
+
json_top_level_keys: json?.top_level_keys ?? [],
|
|
245
|
+
omitted_json_top_level_keys: json?.omitted_top_level_keys ?? 0,
|
|
319
246
|
vendor_markers: javascript?.vendors ?? [],
|
|
320
247
|
},
|
|
321
248
|
evidence: artifactObservationEvidence({
|
|
@@ -328,13 +255,6 @@ const createFileTarget = (context, file, javascript) => {
|
|
|
328
255
|
],
|
|
329
256
|
});
|
|
330
257
|
};
|
|
331
|
-
const artifactFileNodeKind = (kind) => kind === "javascript"
|
|
332
|
-
? "javascript-asset"
|
|
333
|
-
: kind === "source-map"
|
|
334
|
-
? "source-map"
|
|
335
|
-
: kind === "native-addon"
|
|
336
|
-
? "native-addon"
|
|
337
|
-
: "artifact";
|
|
338
258
|
const createAsarEntry = (context, file) => {
|
|
339
259
|
const isAsar = context.snapshot.manifest.root_format === "asar" ||
|
|
340
260
|
file.container_sha256 !== context.snapshot.manifest.root_sha256;
|
|
@@ -370,12 +290,16 @@ const createAsarEntry = (context, file) => {
|
|
|
370
290
|
const addPackageRole = (context, input) => {
|
|
371
291
|
if (input.declaredPath === null)
|
|
372
292
|
return;
|
|
373
|
-
const
|
|
293
|
+
const resolution = resolveArtifactPathByContext({
|
|
294
|
+
declaredPath: input.declaredPath,
|
|
295
|
+
sourcePath: input.packageFile.path,
|
|
296
|
+
context: "package-entrypoint",
|
|
297
|
+
files: context.filesByPath,
|
|
298
|
+
});
|
|
374
299
|
const role = createElectronRoleNode(context, {
|
|
375
300
|
kind: input.kind,
|
|
376
301
|
anchor: input.packageFile,
|
|
377
|
-
|
|
378
|
-
resolvedPath,
|
|
302
|
+
resolution,
|
|
379
303
|
mechanism: input.kind === "electron-main"
|
|
380
304
|
? "package.json:main"
|
|
381
305
|
: "package.json:renderer",
|
|
@@ -386,19 +310,23 @@ const addPackageRole = (context, input) => {
|
|
|
386
310
|
relation: "loads",
|
|
387
311
|
properties: {
|
|
388
312
|
declared_path: input.declaredPath,
|
|
389
|
-
|
|
313
|
+
resolution_context: resolution.resolution_context,
|
|
314
|
+
resolved_path: resolution.resolved_path,
|
|
315
|
+
resolution_status: resolution.resolution_status,
|
|
316
|
+
limitations: resolution.limitations,
|
|
390
317
|
},
|
|
391
318
|
evidence: staticInferenceEvidence({
|
|
392
319
|
sha256: input.packageFile.sha256,
|
|
393
320
|
path: input.packageFile.path,
|
|
394
321
|
operation: "discover-package-entrypoint",
|
|
395
322
|
coverage: completeReconstructionCoverage(),
|
|
323
|
+
limitations: resolution.limitations,
|
|
396
324
|
}),
|
|
397
325
|
});
|
|
398
326
|
linkElectronRoleToAsset(context, {
|
|
399
327
|
role,
|
|
400
328
|
anchor: input.packageFile,
|
|
401
|
-
|
|
329
|
+
resolution,
|
|
402
330
|
});
|
|
403
331
|
};
|
|
404
332
|
const containerProperties = (container) => ({
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import { builtinModules } from "node:module";
|
|
2
|
+
import { posix } from "node:path";
|
|
3
|
+
const EXTENSIONS = [
|
|
4
|
+
".js",
|
|
5
|
+
".cjs",
|
|
6
|
+
".mjs",
|
|
7
|
+
".ts",
|
|
8
|
+
".tsx",
|
|
9
|
+
".json",
|
|
10
|
+
".html",
|
|
11
|
+
".node",
|
|
12
|
+
];
|
|
13
|
+
const MAX_PACKAGE_DEPTH = 4;
|
|
14
|
+
const NODE_BUILTINS = new Set(builtinModules.map((name) => name.replace(/^node:/u, "")));
|
|
15
|
+
/** Resolve one declaration under its exact syntax/metadata context. */
|
|
16
|
+
export const resolveArtifactPathByContext = (input) => resolveAtDepth(input, 0);
|
|
17
|
+
const resolveAtDepth = (input, packageDepth) => {
|
|
18
|
+
const rejected = rejectDeclaration(input);
|
|
19
|
+
if (rejected !== null)
|
|
20
|
+
return rejected;
|
|
21
|
+
const candidate = contextualCandidate(input);
|
|
22
|
+
if (typeof candidate !== "string")
|
|
23
|
+
return candidate;
|
|
24
|
+
const confined = confineCandidate(input, candidate);
|
|
25
|
+
if (typeof confined !== "string")
|
|
26
|
+
return confined;
|
|
27
|
+
const resolved = resolveCandidate(input, confined, packageDepth);
|
|
28
|
+
return outcome(input, resolved.status, resolved.resolvedPath, resolved.limitations);
|
|
29
|
+
};
|
|
30
|
+
const rejectDeclaration = (input) => {
|
|
31
|
+
const declared = input.declaredPath;
|
|
32
|
+
if (declared.length === 0)
|
|
33
|
+
return outcome(input, "rejected", null, ["The declared path is empty."]);
|
|
34
|
+
if (declared.length > 4_096)
|
|
35
|
+
return outcome(input, "rejected", null, [
|
|
36
|
+
"The declared path exceeds the 4096-character resolution bound.",
|
|
37
|
+
]);
|
|
38
|
+
if (declared.includes("\0") || declared.includes("\\"))
|
|
39
|
+
return outcome(input, "rejected", null, [
|
|
40
|
+
"NUL and backslash path syntax are not admitted for canonical artifact paths.",
|
|
41
|
+
]);
|
|
42
|
+
if (/%(?:2e|2f|5c)/iu.test(declared))
|
|
43
|
+
return outcome(input, "rejected", null, [
|
|
44
|
+
"Encoded dot or separator bytes are rejected before artifact path resolution.",
|
|
45
|
+
]);
|
|
46
|
+
return null;
|
|
47
|
+
};
|
|
48
|
+
const contextualCandidate = (input) => {
|
|
49
|
+
const { context } = input;
|
|
50
|
+
const declared = context === "module-specifier" || context === "html-reference"
|
|
51
|
+
? stripQueryAndFragment(input.declaredPath)
|
|
52
|
+
: input.declaredPath;
|
|
53
|
+
if (context === "html-reference")
|
|
54
|
+
return htmlCandidate(input);
|
|
55
|
+
if (context === "module-specifier") {
|
|
56
|
+
const fileUrl = fileUrlPath(declared);
|
|
57
|
+
if (fileUrl !== undefined)
|
|
58
|
+
return fileUrl;
|
|
59
|
+
if (hasScheme(declared))
|
|
60
|
+
return outcome(input, "external", null, [
|
|
61
|
+
"URL and Node builtin schemes are outside static artifact module resolution.",
|
|
62
|
+
]);
|
|
63
|
+
if (!declared.startsWith(".") && !declared.startsWith("/"))
|
|
64
|
+
return bareModuleCandidate(input, declared);
|
|
65
|
+
}
|
|
66
|
+
else if (hasScheme(declared))
|
|
67
|
+
return outcome(input, "external", null, [
|
|
68
|
+
"URL schemes are outside this local artifact path context.",
|
|
69
|
+
]);
|
|
70
|
+
const relative = declared.startsWith("/") ? declared.slice(1) : declared;
|
|
71
|
+
return declared.startsWith("/")
|
|
72
|
+
? relative
|
|
73
|
+
: posix.join(posix.dirname(input.sourcePath), relative);
|
|
74
|
+
};
|
|
75
|
+
const bareModuleCandidate = (input, declared) => {
|
|
76
|
+
const packageName = barePackageName(declared);
|
|
77
|
+
if (packageName === null ||
|
|
78
|
+
NODE_BUILTINS.has(packageName) ||
|
|
79
|
+
declared.startsWith("#"))
|
|
80
|
+
return outcome(input, "external", null, [
|
|
81
|
+
"The bare specifier is a Node builtin, package import map, or invalid package name.",
|
|
82
|
+
]);
|
|
83
|
+
if (declared !== packageName)
|
|
84
|
+
return outcome(input, "external", null, [
|
|
85
|
+
"Bare package subpaths remain unresolved unless an exact package-exports subpath model is available.",
|
|
86
|
+
]);
|
|
87
|
+
const source = input.files.get(input.sourcePath);
|
|
88
|
+
let directory = posix.dirname(input.sourcePath);
|
|
89
|
+
while (true) {
|
|
90
|
+
const candidate = posix.join(directory, "node_modules", declared);
|
|
91
|
+
if (hasContainerCandidate(input.files, candidate, source?.container_sha256))
|
|
92
|
+
return candidate;
|
|
93
|
+
if (directory === "." || directory === "")
|
|
94
|
+
break;
|
|
95
|
+
directory = posix.dirname(directory);
|
|
96
|
+
}
|
|
97
|
+
return outcome(input, "external", null, [
|
|
98
|
+
"No matching bare package was inventoried in an enclosing node_modules directory.",
|
|
99
|
+
]);
|
|
100
|
+
};
|
|
101
|
+
const barePackageName = (specifier) => {
|
|
102
|
+
const segments = specifier.split("/");
|
|
103
|
+
if (specifier.startsWith("@"))
|
|
104
|
+
return segments.length >= 2 && segments[0] !== "" && segments[1] !== ""
|
|
105
|
+
? `${segments[0]}/${segments[1]}`
|
|
106
|
+
: null;
|
|
107
|
+
return segments[0] === "" ? null : (segments[0] ?? null);
|
|
108
|
+
};
|
|
109
|
+
const hasContainerCandidate = (files, candidate, containerSha256) => [...directCandidates(candidate), posix.join(candidate, "package.json")].some((path) => {
|
|
110
|
+
const file = files.get(path);
|
|
111
|
+
return (file !== undefined &&
|
|
112
|
+
(containerSha256 === undefined ||
|
|
113
|
+
file.container_sha256 === containerSha256));
|
|
114
|
+
});
|
|
115
|
+
const htmlCandidate = (input) => {
|
|
116
|
+
const declared = stripQueryAndFragment(input.declaredPath);
|
|
117
|
+
if (hasScheme(declared))
|
|
118
|
+
return outcome(input, "external", null, [
|
|
119
|
+
"External HTML references are not mapped to local artifact assets.",
|
|
120
|
+
]);
|
|
121
|
+
if (declared.startsWith("/"))
|
|
122
|
+
return declared.slice(1);
|
|
123
|
+
const base = input.htmlBaseHref;
|
|
124
|
+
if (base === undefined || base === null || base === "")
|
|
125
|
+
return posix.join(posix.dirname(input.sourcePath), declared);
|
|
126
|
+
if (hasScheme(base))
|
|
127
|
+
return outcome(input, "external", null, [
|
|
128
|
+
"The document base href is external, so its script reference is not a local artifact path.",
|
|
129
|
+
]);
|
|
130
|
+
const basePath = base.startsWith("/")
|
|
131
|
+
? base.slice(1)
|
|
132
|
+
: posix.join(posix.dirname(input.sourcePath), base);
|
|
133
|
+
const baseDirectory = base.endsWith("/") ? basePath : posix.dirname(basePath);
|
|
134
|
+
return posix.join(baseDirectory, declared);
|
|
135
|
+
};
|
|
136
|
+
const confineCandidate = (input, candidate) => {
|
|
137
|
+
const normalized = posix.normalize(candidate);
|
|
138
|
+
if (normalized === ".." ||
|
|
139
|
+
normalized.startsWith("../") ||
|
|
140
|
+
normalized.startsWith("/"))
|
|
141
|
+
return outcome(input, "rejected", null, [
|
|
142
|
+
"The resolved candidate escapes the canonical artifact root.",
|
|
143
|
+
]);
|
|
144
|
+
return normalized === "." ? "" : normalized;
|
|
145
|
+
};
|
|
146
|
+
const resolveCandidate = (input, candidate, packageDepth) => {
|
|
147
|
+
const source = input.files.get(input.sourcePath);
|
|
148
|
+
for (const path of directCandidates(candidate)) {
|
|
149
|
+
const target = input.files.get(path);
|
|
150
|
+
if (target !== undefined &&
|
|
151
|
+
(source === undefined ||
|
|
152
|
+
target.container_sha256 === source.container_sha256))
|
|
153
|
+
return { resolvedPath: path, status: "resolved", limitations: [] };
|
|
154
|
+
}
|
|
155
|
+
if (packageDepth >= MAX_PACKAGE_DEPTH)
|
|
156
|
+
return {
|
|
157
|
+
resolvedPath: null,
|
|
158
|
+
status: "unavailable",
|
|
159
|
+
limitations: [
|
|
160
|
+
`Directory package resolution exceeded its ${String(MAX_PACKAGE_DEPTH)}-package recursion bound.`,
|
|
161
|
+
],
|
|
162
|
+
};
|
|
163
|
+
const packagePath = posix.join(candidate, "package.json");
|
|
164
|
+
const packageFile = input.files.get(packagePath);
|
|
165
|
+
if (packageFile === undefined ||
|
|
166
|
+
(source !== undefined &&
|
|
167
|
+
packageFile.container_sha256 !== source.container_sha256))
|
|
168
|
+
return notFoundCandidate();
|
|
169
|
+
if (!packageFile.text.included)
|
|
170
|
+
return {
|
|
171
|
+
resolvedPath: null,
|
|
172
|
+
status: "unavailable",
|
|
173
|
+
limitations: [
|
|
174
|
+
`Directory package metadata ${packagePath} was inventoried but its text is unavailable: ${packageFile.text.reason}.`,
|
|
175
|
+
],
|
|
176
|
+
};
|
|
177
|
+
const main = packageEntry(packageFile.text.value, input.moduleKind);
|
|
178
|
+
if (main.status === "invalid")
|
|
179
|
+
return {
|
|
180
|
+
resolvedPath: null,
|
|
181
|
+
status: "unavailable",
|
|
182
|
+
limitations: [
|
|
183
|
+
`Directory package metadata ${packagePath} is not valid bounded package JSON.`,
|
|
184
|
+
],
|
|
185
|
+
};
|
|
186
|
+
if (main.status === "missing")
|
|
187
|
+
return notFoundCandidate();
|
|
188
|
+
const nested = resolveAtDepth({
|
|
189
|
+
declaredPath: main.value,
|
|
190
|
+
sourcePath: packagePath,
|
|
191
|
+
context: "package-entrypoint",
|
|
192
|
+
files: input.files,
|
|
193
|
+
}, packageDepth + 1);
|
|
194
|
+
return {
|
|
195
|
+
resolvedPath: nested.resolved_path,
|
|
196
|
+
status: nested.resolution_status,
|
|
197
|
+
limitations: nested.limitations,
|
|
198
|
+
};
|
|
199
|
+
};
|
|
200
|
+
const directCandidates = (candidate) => [
|
|
201
|
+
candidate,
|
|
202
|
+
...EXTENSIONS.map((extension) => `${candidate}${extension}`),
|
|
203
|
+
...EXTENSIONS.map((extension) => posix.join(candidate, `index${extension}`)),
|
|
204
|
+
];
|
|
205
|
+
const packageEntry = (text, moduleKind) => {
|
|
206
|
+
try {
|
|
207
|
+
const value = JSON.parse(text);
|
|
208
|
+
if (typeof value !== "object" || value === null)
|
|
209
|
+
return { status: "invalid" };
|
|
210
|
+
const rawExports = Reflect.get(value, "exports");
|
|
211
|
+
if (rawExports !== undefined)
|
|
212
|
+
return packageExport(rawExports, moduleKind);
|
|
213
|
+
const preferred = moduleKind === "import"
|
|
214
|
+
? [Reflect.get(value, "module"), Reflect.get(value, "main")]
|
|
215
|
+
: [Reflect.get(value, "main"), Reflect.get(value, "module")];
|
|
216
|
+
const entry = preferred.find((candidate) => candidate !== undefined);
|
|
217
|
+
if (entry === undefined)
|
|
218
|
+
return { status: "missing" };
|
|
219
|
+
return boundedPackagePath(entry);
|
|
220
|
+
}
|
|
221
|
+
catch {
|
|
222
|
+
return { status: "invalid" };
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
const packageExport = (value, moduleKind) => {
|
|
226
|
+
if (typeof value === "string")
|
|
227
|
+
return boundedPackagePath(value);
|
|
228
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
229
|
+
return { status: "invalid" };
|
|
230
|
+
const root = Reflect.get(value, ".") ?? value;
|
|
231
|
+
if (typeof root === "string")
|
|
232
|
+
return boundedPackagePath(root);
|
|
233
|
+
if (typeof root !== "object" || root === null || Array.isArray(root))
|
|
234
|
+
return { status: "invalid" };
|
|
235
|
+
const condition = Reflect.get(root, moduleKind ?? "default") ?? Reflect.get(root, "default");
|
|
236
|
+
return boundedPackagePath(condition);
|
|
237
|
+
};
|
|
238
|
+
const boundedPackagePath = (value) => typeof value === "string" && value.length > 0 && value.length <= 4_096
|
|
239
|
+
? { status: "value", value }
|
|
240
|
+
: { status: "invalid" };
|
|
241
|
+
const notFoundCandidate = () => ({
|
|
242
|
+
resolvedPath: null,
|
|
243
|
+
status: "not-found",
|
|
244
|
+
limitations: [
|
|
245
|
+
"No bounded extension, directory package, or index candidate exists in the inventoried artifact container.",
|
|
246
|
+
],
|
|
247
|
+
});
|
|
248
|
+
const hasScheme = (value) => /^[A-Za-z][A-Za-z+.-]*:/u.test(value);
|
|
249
|
+
const fileUrlPath = (value) => {
|
|
250
|
+
if (!value.startsWith("file://"))
|
|
251
|
+
return undefined;
|
|
252
|
+
try {
|
|
253
|
+
const url = new URL(value);
|
|
254
|
+
if (url.protocol !== "file:" || url.hostname !== "")
|
|
255
|
+
return undefined;
|
|
256
|
+
return decodeURIComponent(url.pathname).replace(/^\/+/, "");
|
|
257
|
+
}
|
|
258
|
+
catch {
|
|
259
|
+
return undefined;
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
const stripQueryAndFragment = (value) => value.split("#", 1)[0]?.split("?", 1)[0] ?? "";
|
|
263
|
+
const outcome = (input, status, resolvedPath, limitations) => ({
|
|
264
|
+
declared_path: input.declaredPath,
|
|
265
|
+
resolution_context: input.context,
|
|
266
|
+
resolved_path: resolvedPath,
|
|
267
|
+
resolution_status: status,
|
|
268
|
+
limitations,
|
|
269
|
+
});
|
|
@@ -15,7 +15,7 @@ export const reconstructJavaScriptArtifact = async (rawInput, signal) => {
|
|
|
15
15
|
abortIfNeeded(signal);
|
|
16
16
|
const path = await realpath(input.input_path);
|
|
17
17
|
const format = await resolveFormat(path, input);
|
|
18
|
-
const snapshot = await scanCanonicalArtifactInventory(path, artifactLimitsForReconstruction(input), signal);
|
|
18
|
+
const snapshot = await scanCanonicalArtifactInventory(path, artifactLimitsForReconstruction(input), { signal });
|
|
19
19
|
if (snapshot.manifest.root_format !== format)
|
|
20
20
|
throw new ArtifactReaderFailure("format", `Artifact inventory classified ${path} as ${snapshot.manifest.root_format}, not ${format}`);
|
|
21
21
|
const reader = createReader(path, format);
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/** Parse one approved JSON module without evaluating JavaScript or resolving imports. */
|
|
2
|
+
export const analyzeJavaScriptJsonModule = (file) => {
|
|
3
|
+
if (!file.text.included)
|
|
4
|
+
return {
|
|
5
|
+
path: file.path,
|
|
6
|
+
sha256: file.sha256,
|
|
7
|
+
status: "unavailable",
|
|
8
|
+
top_level_keys: [],
|
|
9
|
+
omitted_top_level_keys: null,
|
|
10
|
+
limitation: `JSON module text was unavailable: ${file.text.reason}.`,
|
|
11
|
+
};
|
|
12
|
+
let value;
|
|
13
|
+
try {
|
|
14
|
+
value = JSON.parse(file.text.value);
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return {
|
|
18
|
+
path: file.path,
|
|
19
|
+
sha256: file.sha256,
|
|
20
|
+
status: "invalid",
|
|
21
|
+
top_level_keys: [],
|
|
22
|
+
omitted_top_level_keys: 0,
|
|
23
|
+
limitation: "JSON module is not valid JSON.",
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
const keys = typeof value === "object" && value !== null && !Array.isArray(value)
|
|
27
|
+
? Object.keys(value).sort(compareCodePoints)
|
|
28
|
+
: [];
|
|
29
|
+
const retained = keys.slice(0, 128);
|
|
30
|
+
return {
|
|
31
|
+
path: file.path,
|
|
32
|
+
sha256: file.sha256,
|
|
33
|
+
status: "included",
|
|
34
|
+
top_level_keys: retained,
|
|
35
|
+
omitted_top_level_keys: keys.length - retained.length,
|
|
36
|
+
limitation: null,
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
const compareCodePoints = (left, right) => left < right ? -1 : left > right ? 1 : 0;
|