rea-agents 2.4.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/BinarySession.js +15 -4
- package/dist/application/BinarySessionStatus.js +31 -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 +68 -12
- 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/ProcessReactiveEffects.js +6 -0
- package/dist/application/ProcessReactiveHarness.js +16 -1
- 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 +37 -0
- package/dist/domain/analysisErrorProjection.js +8 -0
- package/dist/domain/artifactInspection.js +347 -0
- 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/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 +8 -2
- package/dist/domain/processReactiveScenario.js +1 -0
- package/dist/domain/processReactiveTransition.js +9 -4
- 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/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/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 +2 -2
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { enhancedInputSchemas } from "../contracts/enhancedInputs.js";
|
|
2
2
|
import { AnalysisCancelledError, AnalysisOutputError, projectAnalysisError, } from "../domain/errors.js";
|
|
3
|
-
import { addressDistance,
|
|
3
|
+
import { addressDistance, parseDocuments, parseFunctionDossier, parseListCount, parseRelatedAddresses, parseSegments, } from "../domain/hopperValues.js";
|
|
4
4
|
import { err, ok } from "../domain/result.js";
|
|
5
5
|
import { categorizeSwiftTypes, discoverObjcClasses, discoverObjcProtocols, discoverSwiftClasses, } from "../domain/symbolAnalysis.js";
|
|
6
6
|
import { invalidEnhancedInput, } from "./EnhancedToolTypes.js";
|
|
7
7
|
import { readAllAddressed } from "./EnhancedToolPagination.js";
|
|
8
|
+
import { traceCallPath } from "./CallPathTracing.js";
|
|
9
|
+
import { traceLiteralFeature } from "./EnhancedLiteralTracing.js";
|
|
8
10
|
/**
|
|
9
11
|
* Composes direct provider operations into bounded reverse-engineering tools.
|
|
10
12
|
* Direct callers use `execute`; adapters that own validation use
|
|
@@ -17,6 +19,10 @@ export class EnhancedTools {
|
|
|
17
19
|
}
|
|
18
20
|
/** Parse an untrusted direct-call input once, then dispatch exhaustively. */
|
|
19
21
|
execute(name, input, signal) {
|
|
22
|
+
if (name === "trace_feature" ||
|
|
23
|
+
name === "find_code_for_string" ||
|
|
24
|
+
name === "trace_call_path")
|
|
25
|
+
return this.#executeTracing(name, input, signal);
|
|
20
26
|
switch (name) {
|
|
21
27
|
case "swift_classes": {
|
|
22
28
|
const parsed = enhancedInputSchemas.swift_classes.safeParse(input);
|
|
@@ -64,12 +70,6 @@ export class EnhancedTools {
|
|
|
64
70
|
? this.executeValidated({ name, input: parsed.data }, signal)
|
|
65
71
|
: invalidEnhancedInput(name, parsed.error);
|
|
66
72
|
}
|
|
67
|
-
case "trace_feature": {
|
|
68
|
-
const parsed = enhancedInputSchemas.trace_feature.safeParse(input);
|
|
69
|
-
return parsed.success
|
|
70
|
-
? this.executeValidated({ name, input: parsed.data }, signal)
|
|
71
|
-
: invalidEnhancedInput(name, parsed.error);
|
|
72
|
-
}
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
/** Dispatch input already parsed by a trusted adapter boundary. */
|
|
@@ -94,9 +94,27 @@ export class EnhancedTools {
|
|
|
94
94
|
case "analyze_function":
|
|
95
95
|
return this.#analyzeFunction(call.input, signal);
|
|
96
96
|
case "trace_feature":
|
|
97
|
-
return this.#
|
|
97
|
+
return traceLiteralFeature((name, arguments_, operationSignal) => this.#call(name, arguments_, operationSignal), call.input, "feature", signal);
|
|
98
|
+
case "find_code_for_string":
|
|
99
|
+
return traceLiteralFeature((name, arguments_, operationSignal) => this.#call(name, arguments_, operationSignal), call.input, "string", signal);
|
|
100
|
+
case "trace_call_path":
|
|
101
|
+
return traceCallPath((name, arguments_, operationSignal) => this.#call(name, arguments_, operationSignal), call.input, signal);
|
|
98
102
|
}
|
|
99
103
|
}
|
|
104
|
+
#executeTracing(name, input, signal) {
|
|
105
|
+
const parsed = enhancedInputSchemas[name].safeParse(input);
|
|
106
|
+
if (!parsed.success)
|
|
107
|
+
return invalidEnhancedInput(name, parsed.error);
|
|
108
|
+
if (name === "trace_call_path")
|
|
109
|
+
return this.executeValidated({
|
|
110
|
+
name,
|
|
111
|
+
input: enhancedInputSchemas.trace_call_path.parse(parsed.data),
|
|
112
|
+
}, signal);
|
|
113
|
+
return this.executeValidated({
|
|
114
|
+
name,
|
|
115
|
+
input: enhancedInputSchemas[name].parse(parsed.data),
|
|
116
|
+
}, signal);
|
|
117
|
+
}
|
|
100
118
|
async #analyzeFunction(input, signal) {
|
|
101
119
|
const result = await this.#call("analyze_function", input, signal);
|
|
102
120
|
return result.ok ? parseFunctionDossier(result.value) : result;
|
|
@@ -217,18 +235,18 @@ export class EnhancedTools {
|
|
|
217
235
|
});
|
|
218
236
|
}
|
|
219
237
|
async #binaryOverview(input, signal) {
|
|
220
|
-
const [segmentsResult, documentsResult,
|
|
238
|
+
const [segmentsResult, documentsResult, proceduresResult, stringsResult] = await Promise.all([
|
|
221
239
|
this.#call("list_segments", {}, signal),
|
|
222
240
|
this.#call("list_documents", {}, signal),
|
|
223
|
-
this.#
|
|
224
|
-
this.#call("list_strings", {}, signal),
|
|
241
|
+
this.#call("list_procedures", { offset: 0, limit: 1 }, signal),
|
|
242
|
+
this.#call("list_strings", { offset: 0, limit: 1 }, signal),
|
|
225
243
|
]);
|
|
226
244
|
if (!segmentsResult.ok)
|
|
227
245
|
return segmentsResult;
|
|
228
246
|
if (!documentsResult.ok)
|
|
229
247
|
return documentsResult;
|
|
230
|
-
if (!
|
|
231
|
-
return
|
|
248
|
+
if (!proceduresResult.ok)
|
|
249
|
+
return proceduresResult;
|
|
232
250
|
if (!stringsResult.ok)
|
|
233
251
|
return stringsResult;
|
|
234
252
|
const segments = parseSegments(segmentsResult.value);
|
|
@@ -237,6 +255,9 @@ export class EnhancedTools {
|
|
|
237
255
|
const documents = parseDocuments(documentsResult.value);
|
|
238
256
|
if (!documents.ok)
|
|
239
257
|
return documents;
|
|
258
|
+
const procedureCount = parseListCount(proceduresResult.value, "procedures");
|
|
259
|
+
if (!procedureCount.ok)
|
|
260
|
+
return procedureCount;
|
|
240
261
|
const stringCount = parseListCount(stringsResult.value, "strings");
|
|
241
262
|
if (!stringCount.ok)
|
|
242
263
|
return stringCount;
|
|
@@ -249,117 +270,10 @@ export class EnhancedTools {
|
|
|
249
270
|
? { name, start, end, length: addressDistance(start, end) }
|
|
250
271
|
: { name, start, end }),
|
|
251
272
|
segment_count: segments.value.length,
|
|
252
|
-
procedure_count:
|
|
273
|
+
procedure_count: procedureCount.value,
|
|
253
274
|
string_count: stringCount.value,
|
|
254
275
|
});
|
|
255
276
|
}
|
|
256
|
-
async #traceFeature(input, signal) {
|
|
257
|
-
const searched = await this.#literalMatches(input, signal);
|
|
258
|
-
if (!searched.ok)
|
|
259
|
-
return searched;
|
|
260
|
-
const residual = new Set();
|
|
261
|
-
const traced = await this.#traceReferences(searched.value.matches, input.limit, input.max_operations - searched.value.operations, signal);
|
|
262
|
-
if (!traced.ok)
|
|
263
|
-
return traced;
|
|
264
|
-
for (const reason of traced.value.residual)
|
|
265
|
-
residual.add(reason);
|
|
266
|
-
const operations = searched.value.operations + traced.value.operations;
|
|
267
|
-
if (operations >= input.max_operations)
|
|
268
|
-
residual.add("Investigation reached the operation budget.");
|
|
269
|
-
if (searched.value.matches.length >= input.limit)
|
|
270
|
-
residual.add("Literal matches reached the configured limit.");
|
|
271
|
-
return ok({
|
|
272
|
-
query: input.query,
|
|
273
|
-
search_mode: "literal",
|
|
274
|
-
operations_used: operations,
|
|
275
|
-
operation_budget: input.max_operations,
|
|
276
|
-
matches: searched.value.matches,
|
|
277
|
-
references: traced.value.references,
|
|
278
|
-
truncated: residual.size > 0,
|
|
279
|
-
residual_unknowns: [...residual],
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
async #literalMatches(input, signal) {
|
|
283
|
-
let operations = 0;
|
|
284
|
-
const matches = [];
|
|
285
|
-
const needle = input.case_sensitive
|
|
286
|
-
? input.query
|
|
287
|
-
: input.query.toLowerCase();
|
|
288
|
-
for (const [tool, type] of [
|
|
289
|
-
["list_strings", "string"],
|
|
290
|
-
["list_procedures", "procedure"],
|
|
291
|
-
]) {
|
|
292
|
-
let offset = 0;
|
|
293
|
-
while (operations < input.max_operations &&
|
|
294
|
-
matches.length < input.limit) {
|
|
295
|
-
operations += 1;
|
|
296
|
-
const result = await this.#call(tool, { offset, limit: 500 }, signal);
|
|
297
|
-
if (!result.ok)
|
|
298
|
-
return result;
|
|
299
|
-
const page = parseAddressedPage(result.value);
|
|
300
|
-
if (!page.ok)
|
|
301
|
-
return page;
|
|
302
|
-
for (const item of page.value.items) {
|
|
303
|
-
const haystack = input.case_sensitive
|
|
304
|
-
? item.name
|
|
305
|
-
: item.name.toLowerCase();
|
|
306
|
-
if (haystack.includes(needle))
|
|
307
|
-
matches.push({ type, address: item.address, value: item.name });
|
|
308
|
-
if (matches.length >= input.limit)
|
|
309
|
-
break;
|
|
310
|
-
}
|
|
311
|
-
if (!page.value.hasMore || page.value.nextOffset === null)
|
|
312
|
-
break;
|
|
313
|
-
offset = page.value.nextOffset;
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
return ok({ matches, operations });
|
|
317
|
-
}
|
|
318
|
-
async #traceReferences(matches, limit, operationBudget, signal) {
|
|
319
|
-
let operations = 0;
|
|
320
|
-
const references = [];
|
|
321
|
-
const residual = new Set();
|
|
322
|
-
for (const match of matches) {
|
|
323
|
-
if (operations >= operationBudget) {
|
|
324
|
-
residual.add("Reference traversal stopped at the operation budget.");
|
|
325
|
-
break;
|
|
326
|
-
}
|
|
327
|
-
operations += 1;
|
|
328
|
-
const xrefs = await this.#call("xrefs", { address: match.address }, signal);
|
|
329
|
-
if (!xrefs.ok)
|
|
330
|
-
return xrefs;
|
|
331
|
-
if (!Array.isArray(xrefs.value))
|
|
332
|
-
return err(new AnalysisOutputError("xrefs", "provider returned a non-array result"));
|
|
333
|
-
for (const source of xrefs.value) {
|
|
334
|
-
if (typeof source !== "string")
|
|
335
|
-
return err(new AnalysisOutputError("xrefs", "provider returned a non-address value"));
|
|
336
|
-
if (operations >= operationBudget) {
|
|
337
|
-
residual.add("Containing-procedure resolution stopped at the operation budget.");
|
|
338
|
-
break;
|
|
339
|
-
}
|
|
340
|
-
operations += 1;
|
|
341
|
-
const resolved = await this.#call("resolve_containing_procedure", { address: source }, signal);
|
|
342
|
-
if (!resolved.ok)
|
|
343
|
-
return resolved;
|
|
344
|
-
references.push({
|
|
345
|
-
target_address: match.address,
|
|
346
|
-
source_address: source,
|
|
347
|
-
containing_procedure: resolved.value,
|
|
348
|
-
});
|
|
349
|
-
if (references.length >= limit) {
|
|
350
|
-
residual.add("Reference results reached the configured limit.");
|
|
351
|
-
break;
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
if (references.length >= limit)
|
|
355
|
-
break;
|
|
356
|
-
}
|
|
357
|
-
return ok({
|
|
358
|
-
references,
|
|
359
|
-
operations,
|
|
360
|
-
residual: [...residual],
|
|
361
|
-
});
|
|
362
|
-
}
|
|
363
277
|
async #allAddressed(tool, signal) {
|
|
364
278
|
return readAllAddressed({
|
|
365
279
|
call: (name, arguments_, operationSignal) => this.#call(name, arguments_, operationSignal),
|
|
@@ -40,6 +40,19 @@ export const createApplicationVersionComparisonEvidence = (parameters, result) =
|
|
|
40
40
|
limitations: result.limitations,
|
|
41
41
|
evidenceLinks: result.evidence_links,
|
|
42
42
|
});
|
|
43
|
+
/** Create derived Evidence for one historical-source to bundle comparison. */
|
|
44
|
+
export const createSourceToBundleComparisonEvidence = (parameters, result) => createEvidence(undefined, JAVASCRIPT_APPLICATION_WORKFLOW_PROVIDER, {
|
|
45
|
+
predicateType: "rea.source-to-bundle-comparison/v1",
|
|
46
|
+
operation: "compare_source_to_bundle",
|
|
47
|
+
parameters,
|
|
48
|
+
result: jsonValueSchema.parse(result),
|
|
49
|
+
rawResult: null,
|
|
50
|
+
confidence: "inferred",
|
|
51
|
+
authority: "analyst-inference",
|
|
52
|
+
environment: null,
|
|
53
|
+
limitations: result.limitations,
|
|
54
|
+
evidenceLinks: result.evidence_links,
|
|
55
|
+
});
|
|
43
56
|
/** Create derived Evidence for one bounded static export-shape comparison. */
|
|
44
57
|
export const createJavaScriptExportShapeComparisonEvidence = (parameters, result) => createEvidence(undefined, JAVASCRIPT_APPLICATION_WORKFLOW_PROVIDER, {
|
|
45
58
|
predicateType: "rea.javascript-export-shape-comparison/v1",
|
|
@@ -8,8 +8,10 @@ import { compareJavaScriptExportShapesInputSchema } from "../domain/javascriptEx
|
|
|
8
8
|
import { traceApplicationFeature } from "../domain/javascriptFeatureTrace.js";
|
|
9
9
|
import { traceApplicationFeatureInputSchema } from "../domain/javascriptFeatureTraceSchemas.js";
|
|
10
10
|
import { err, ok } from "../domain/result.js";
|
|
11
|
+
import { compareSourceToBundle } from "../domain/sourceToBundleComparison.js";
|
|
12
|
+
import { compareSourceToBundleInputSchema } from "../domain/sourceToBundleComparisonSchemas.js";
|
|
11
13
|
import { parseApplicationGraphEvidence, parseNativeApplicationEvidence, } from "./JavaScriptApplicationEvidenceGraph.js";
|
|
12
|
-
import { createApplicationFeatureTraceEvidence, createApplicationVersionComparisonEvidence, createJavaScriptExportShapeComparisonEvidence, } from "./JavaScriptApplicationWorkflowEvidence.js";
|
|
14
|
+
import { createApplicationFeatureTraceEvidence, createApplicationVersionComparisonEvidence, createJavaScriptExportShapeComparisonEvidence, createSourceToBundleComparisonEvidence, } from "./JavaScriptApplicationWorkflowEvidence.js";
|
|
13
15
|
/** Authenticate Evidence and derive one bounded cross-layer feature trace. */
|
|
14
16
|
export const traceApplicationFeatureEvidence = (rawInput) => {
|
|
15
17
|
const operation = "trace_application_feature";
|
|
@@ -87,6 +89,30 @@ export const compareApplicationVersionsEvidenceValidated = (input) => {
|
|
|
87
89
|
return workflowFailure(operation, cause);
|
|
88
90
|
}
|
|
89
91
|
};
|
|
92
|
+
/** Compare source and bundle inputs already parsed by a trusted adapter. */
|
|
93
|
+
export const compareSourceToBundleEvidenceValidated = (input) => {
|
|
94
|
+
const operation = "compare_source_to_bundle";
|
|
95
|
+
try {
|
|
96
|
+
const application = parseApplicationGraphEvidence(input.application);
|
|
97
|
+
const result = compareSourceToBundle({
|
|
98
|
+
reference: input.reference,
|
|
99
|
+
application: {
|
|
100
|
+
evidenceId: application.evidence.evidence_id,
|
|
101
|
+
rootArtifactSha256: application.rootArtifactSha256,
|
|
102
|
+
graph: application.graph,
|
|
103
|
+
},
|
|
104
|
+
limits: input.limits,
|
|
105
|
+
});
|
|
106
|
+
return ok(createSourceToBundleComparisonEvidence({
|
|
107
|
+
reference_root_sha256: input.reference.root_sha256,
|
|
108
|
+
application_evidence_id: application.evidence.evidence_id,
|
|
109
|
+
limits: input.limits,
|
|
110
|
+
}, result));
|
|
111
|
+
}
|
|
112
|
+
catch (cause) {
|
|
113
|
+
return workflowFailure(operation, cause);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
90
116
|
/**
|
|
91
117
|
* Authenticate both graphs and compare one exact export return shape.
|
|
92
118
|
* @public
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { createEvidence, } from "../domain/evidence.js";
|
|
2
|
+
import { jsonValueSchema } from "../domain/jsonValue.js";
|
|
3
|
+
/** Create deterministic Evidence v2 for one passive Inspector operation. */
|
|
4
|
+
export const createJavaScriptRuntimeObservationEvidence = (operation, input, result, provider) => createEvidence(undefined, provider, {
|
|
5
|
+
predicateType: operation === "list_javascript_runtime_targets"
|
|
6
|
+
? "rea.javascript-runtime-target-list/v1"
|
|
7
|
+
: "rea.javascript-runtime-observation/v1",
|
|
8
|
+
operation,
|
|
9
|
+
parameters: parameters(input),
|
|
10
|
+
result: jsonValueSchema.parse(result),
|
|
11
|
+
rawResult: null,
|
|
12
|
+
confidence: "observed",
|
|
13
|
+
authority: "external-service",
|
|
14
|
+
environment: {
|
|
15
|
+
id: `${result.runtime.product}@${result.runtime.protocol_version}`,
|
|
16
|
+
platform: process.platform,
|
|
17
|
+
architecture: process.arch,
|
|
18
|
+
isolation: "none",
|
|
19
|
+
},
|
|
20
|
+
limitations: result.limitations,
|
|
21
|
+
});
|
|
22
|
+
const parameters = (input) => ({
|
|
23
|
+
inspector_endpoint: input.inspector_endpoint,
|
|
24
|
+
allowed_file_roots: input.allowed_file_roots,
|
|
25
|
+
allowed_origins: input.allowed_origins,
|
|
26
|
+
...("target_id" in input
|
|
27
|
+
? {
|
|
28
|
+
target_id: input.target_id,
|
|
29
|
+
runtime_kind: input.runtime_kind,
|
|
30
|
+
observation_ms: input.observation_ms,
|
|
31
|
+
limits: input.limits,
|
|
32
|
+
}
|
|
33
|
+
: { offset: input.offset, limit: input.limit }),
|
|
34
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { createJavaScriptRuntimeObservationEvidence } from "./JavaScriptRuntimeObservationEvidence.js";
|
|
2
|
+
import { AnalysisCapabilityUnavailableError, AnalysisProtocolError, PermissionRequiredError, } from "../domain/errors.js";
|
|
3
|
+
import { err, ok } from "../domain/result.js";
|
|
4
|
+
/** Authorize and list attachable Node/Electron Inspector targets. */
|
|
5
|
+
export const listJavaScriptRuntimeTargets = async (provider, authority, input, options = {}) => {
|
|
6
|
+
const ready = await prepare(provider, authority, input, "list_javascript_runtime_targets");
|
|
7
|
+
if (!ready.ok)
|
|
8
|
+
return ready;
|
|
9
|
+
const result = await ready.value.listTargets(input, options);
|
|
10
|
+
return result.ok
|
|
11
|
+
? ok(createJavaScriptRuntimeObservationEvidence("list_javascript_runtime_targets", input, result.value, ready.value.identity()))
|
|
12
|
+
: result;
|
|
13
|
+
};
|
|
14
|
+
/** Authorize one bounded attach-only Inspector observation. */
|
|
15
|
+
export const observeJavaScriptRuntime = async (provider, authority, input, options = {}) => {
|
|
16
|
+
const ready = await prepare(provider, authority, input, "observe_javascript_runtime");
|
|
17
|
+
if (!ready.ok)
|
|
18
|
+
return ready;
|
|
19
|
+
const result = await ready.value.observe(input, options);
|
|
20
|
+
return result.ok
|
|
21
|
+
? ok(createJavaScriptRuntimeObservationEvidence("observe_javascript_runtime", input, result.value, ready.value.identity()))
|
|
22
|
+
: result;
|
|
23
|
+
};
|
|
24
|
+
const prepare = async (provider, authority, input, operation) => {
|
|
25
|
+
if (authority === undefined)
|
|
26
|
+
return err(new AnalysisCapabilityUnavailableError("rea-v8-inspector", operation, "V8 Inspector observation permission policy is not configured"));
|
|
27
|
+
const authorized = await authority.authorize({
|
|
28
|
+
capability: "v8_inspector_observe",
|
|
29
|
+
roots: input.allowed_file_roots,
|
|
30
|
+
executables: [],
|
|
31
|
+
environment_names: [],
|
|
32
|
+
origins: [input.inspector_endpoint, ...input.allowed_origins],
|
|
33
|
+
network: "loopback",
|
|
34
|
+
mount: false,
|
|
35
|
+
operation_identity: `${operation}:${"target_id" in input ? input.target_id : input.inspector_endpoint}`,
|
|
36
|
+
}, "read");
|
|
37
|
+
if (!authorized.ok)
|
|
38
|
+
return err(authorized.error instanceof PermissionRequiredError
|
|
39
|
+
? authorized.error
|
|
40
|
+
: new AnalysisProtocolError(authorized.error.message, {
|
|
41
|
+
cause: authorized.error,
|
|
42
|
+
}));
|
|
43
|
+
return provider === undefined
|
|
44
|
+
? err(new AnalysisCapabilityUnavailableError("rea-v8-inspector", operation, "V8 Inspector observation provider is not configured"))
|
|
45
|
+
: ok(provider);
|
|
46
|
+
};
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { createJavaScriptSemanticGraphUnknown } from "../domain/javascriptSemanticGraph.js";
|
|
2
|
+
import { addSemanticGraphNode, addSemanticGraphRelation, addSemanticGraphUnknown, constructSemanticGraphNode, } from "./JavaScriptSemanticGraphConstruction.js";
|
|
3
|
+
import { unknownSemanticEvidence } from "./JavaScriptSemanticGraphEvidence.js";
|
|
4
|
+
import { semanticCallSiteAt, } from "./JavaScriptSemanticGraphFlowProjection.js";
|
|
5
|
+
/** Project literal EventEmitter registrations, removals, and dispatches. */
|
|
6
|
+
export const projectSemanticEvents = (context) => {
|
|
7
|
+
const eventNodes = new Map();
|
|
8
|
+
for (const operation of context.ir.eventOperations) {
|
|
9
|
+
const eventKey = operation.eventName === null
|
|
10
|
+
? operation.eventId
|
|
11
|
+
: `${operation.emitterKey}\u0000${operation.eventName}`;
|
|
12
|
+
const event = eventNodes.get(eventKey) ?? addEventNode(context, operation, eventKey);
|
|
13
|
+
if (event === null)
|
|
14
|
+
continue;
|
|
15
|
+
eventNodes.set(eventKey, event);
|
|
16
|
+
const relation = eventRelation(operation);
|
|
17
|
+
if (operation.kind === "dispatch")
|
|
18
|
+
addSemanticGraphRelation(context.state, {
|
|
19
|
+
source: eventEmitterNode(context, operation),
|
|
20
|
+
target: event,
|
|
21
|
+
relation,
|
|
22
|
+
resolution: operation.resolution === "complete" ? "resolved" : "candidate",
|
|
23
|
+
});
|
|
24
|
+
else {
|
|
25
|
+
const listener = addListenerNode(context, operation);
|
|
26
|
+
addSemanticGraphRelation(context.state, {
|
|
27
|
+
source: event,
|
|
28
|
+
target: listener,
|
|
29
|
+
relation,
|
|
30
|
+
resolution: operation.resolution === "complete" ? "resolved" : "candidate",
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
if (operation.resolution !== "complete")
|
|
34
|
+
addEventUnknown(context, operation, event, relation);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
const addEventNode = (context, operation, eventKey) => addSemanticGraphNode(context.state, constructSemanticGraphNode(context.file, {
|
|
38
|
+
kind: "event",
|
|
39
|
+
roleKey: `event:${eventKey}`,
|
|
40
|
+
location: operation.eventName === null ? operation.location : null,
|
|
41
|
+
label: operation.eventName,
|
|
42
|
+
functionNodeId: null,
|
|
43
|
+
properties: {
|
|
44
|
+
emitter_key: operation.emitterKey,
|
|
45
|
+
event_name: operation.eventName,
|
|
46
|
+
},
|
|
47
|
+
}, context.state));
|
|
48
|
+
const addListenerNode = (context, operation) => addSemanticGraphNode(context.state, constructSemanticGraphNode(context.file, {
|
|
49
|
+
kind: "listener",
|
|
50
|
+
roleKey: `listener:${operation.eventId}`,
|
|
51
|
+
location: operation.listenerLocation ?? operation.location,
|
|
52
|
+
label: operation.eventName === null
|
|
53
|
+
? operation.method
|
|
54
|
+
: `${operation.method}:${operation.eventName}`,
|
|
55
|
+
functionNodeId: operation.ownerCallableId === null
|
|
56
|
+
? null
|
|
57
|
+
: (context.callableNodes.get(operation.ownerCallableId)?.node_id ??
|
|
58
|
+
null),
|
|
59
|
+
properties: {
|
|
60
|
+
emitter_key: operation.emitterKey,
|
|
61
|
+
event_name: operation.eventName,
|
|
62
|
+
method: operation.method,
|
|
63
|
+
},
|
|
64
|
+
}, context.state));
|
|
65
|
+
const eventEmitterNode = (context, operation) => (operation.emitterBindingId === null
|
|
66
|
+
? undefined
|
|
67
|
+
: context.bindingNodes.get(operation.emitterBindingId)) ??
|
|
68
|
+
(operation.ownerCallableId === null
|
|
69
|
+
? context.moduleNode
|
|
70
|
+
: (context.callableNodes.get(operation.ownerCallableId) ??
|
|
71
|
+
context.moduleNode));
|
|
72
|
+
const eventRelation = (operation) => operation.kind === "register"
|
|
73
|
+
? "registers-listener"
|
|
74
|
+
: operation.kind === "remove"
|
|
75
|
+
? "removes-listener"
|
|
76
|
+
: "dispatches-candidate";
|
|
77
|
+
const addEventUnknown = (context, operation, event, relation) => {
|
|
78
|
+
addSemanticGraphUnknown(context.state, createJavaScriptSemanticGraphUnknown({
|
|
79
|
+
node_id: event.node_id,
|
|
80
|
+
family: "event",
|
|
81
|
+
relation_kinds: [relation],
|
|
82
|
+
reason: "ambiguous-target",
|
|
83
|
+
detail: operation.eventName === null
|
|
84
|
+
? `Dynamic ${operation.method} event name remains unresolved.`
|
|
85
|
+
: `Static ${operation.method} emitter identity is partial.`,
|
|
86
|
+
candidate_node_ids: [],
|
|
87
|
+
evidence: unknownSemanticEvidence(context.file, operation.location),
|
|
88
|
+
}));
|
|
89
|
+
};
|
|
90
|
+
/** Project Node timer scheduling and exact local handle cancellation. */
|
|
91
|
+
export const projectSemanticTimers = (context) => {
|
|
92
|
+
const timerNodes = new Map(context.ir.timerOperations.flatMap((operation) => {
|
|
93
|
+
if (operation.kind !== "schedule")
|
|
94
|
+
return [];
|
|
95
|
+
const owner = operation.ownerCallableId === null
|
|
96
|
+
? undefined
|
|
97
|
+
: context.callableNodes.get(operation.ownerCallableId);
|
|
98
|
+
const timer = addSemanticGraphNode(context.state, constructSemanticGraphNode(context.file, {
|
|
99
|
+
kind: "timer",
|
|
100
|
+
roleKey: operation.timerId,
|
|
101
|
+
location: operation.location,
|
|
102
|
+
label: operation.method,
|
|
103
|
+
functionNodeId: owner?.node_id ?? null,
|
|
104
|
+
properties: {
|
|
105
|
+
delay_milliseconds: operation.delayMilliseconds,
|
|
106
|
+
method: operation.method,
|
|
107
|
+
},
|
|
108
|
+
}, context.state));
|
|
109
|
+
return timer === null ? [] : [[operation.timerId, timer]];
|
|
110
|
+
}));
|
|
111
|
+
for (const operation of context.ir.timerOperations)
|
|
112
|
+
if (operation.kind === "schedule")
|
|
113
|
+
projectTimerSchedule(context, operation, timerNodes);
|
|
114
|
+
else
|
|
115
|
+
projectTimerCancellation(context, operation, timerNodes);
|
|
116
|
+
};
|
|
117
|
+
const projectTimerSchedule = (context, operation, timerNodes) => {
|
|
118
|
+
addSemanticGraphRelation(context.state, {
|
|
119
|
+
source: semanticCallSiteAt(context, operation.location),
|
|
120
|
+
target: timerNodes.get(operation.timerId),
|
|
121
|
+
relation: "schedules-timer",
|
|
122
|
+
resolution: "resolved",
|
|
123
|
+
});
|
|
124
|
+
};
|
|
125
|
+
const projectTimerCancellation = (context, operation, timerNodes) => {
|
|
126
|
+
const callSite = semanticCallSiteAt(context, operation.location);
|
|
127
|
+
const target = operation.linkedTimerId === null
|
|
128
|
+
? undefined
|
|
129
|
+
: timerNodes.get(operation.linkedTimerId);
|
|
130
|
+
addSemanticGraphRelation(context.state, {
|
|
131
|
+
source: callSite,
|
|
132
|
+
target,
|
|
133
|
+
relation: "cancels-timer",
|
|
134
|
+
resolution: operation.resolution === "complete" ? "resolved" : "candidate",
|
|
135
|
+
});
|
|
136
|
+
if (operation.resolution === "complete")
|
|
137
|
+
return;
|
|
138
|
+
addSemanticGraphUnknown(context.state, createJavaScriptSemanticGraphUnknown({
|
|
139
|
+
node_id: callSite?.node_id ?? null,
|
|
140
|
+
family: "timer",
|
|
141
|
+
relation_kinds: ["cancels-timer"],
|
|
142
|
+
reason: "ambiguous-target",
|
|
143
|
+
detail: `Static ${operation.method} handle resolution was ${operation.resolution}.`,
|
|
144
|
+
candidate_node_ids: [],
|
|
145
|
+
evidence: unknownSemanticEvidence(context.file, operation.location),
|
|
146
|
+
}));
|
|
147
|
+
};
|
|
@@ -1,16 +1,25 @@
|
|
|
1
1
|
import { createJavaScriptSemanticGraph, } from "../domain/javascriptSemanticGraph.js";
|
|
2
2
|
import { JAVASCRIPT_SEMANTIC_RELATION_FAMILIES, JAVASCRIPT_SEMANTIC_RELATION_FAMILY, } from "../domain/javascriptSemanticGraphSchemas.js";
|
|
3
|
+
import { sourceRangesEqual as rangesEqual } from "../domain/javascriptStaticAnalysisHelpers.js";
|
|
4
|
+
import { projectSemanticEvents, projectSemanticTimers, } from "./JavaScriptSemanticGraphAsyncProjection.js";
|
|
5
|
+
import { projectSemanticChildProcesses } from "./JavaScriptSemanticGraphChildProcessProjection.js";
|
|
6
|
+
import { projectSemanticBoundaries, projectSemanticConfiguration, projectSemanticRequests, } from "./JavaScriptSemanticGraphDataProjection.js";
|
|
7
|
+
import { projectSemanticResources } from "./JavaScriptSemanticGraphResourceProjection.js";
|
|
8
|
+
import { projectSemanticObjects } from "./JavaScriptSemanticGraphObjectProjection.js";
|
|
9
|
+
import { projectSemanticValues } from "./JavaScriptSemanticGraphValueProjection.js";
|
|
3
10
|
import { inferredSemanticEvidenceAt } from "./JavaScriptSemanticGraphEvidence.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
11
|
+
import { projectSemanticFunctionFingerprints } from "./JavaScriptSemanticGraphFingerprintProjection.js";
|
|
12
|
+
import { projectSemanticClosureCaptures, projectSemanticFrontiers, projectSemanticPromises, projectSemanticReturnValues, semanticRecoveryLimits, } from "./JavaScriptSemanticGraphFlowProjection.js";
|
|
13
|
+
import { owningSemanticCallableNode, semanticFamilyStatus, semanticNodesWithinRange, } from "./JavaScriptSemanticGraphProjection.js";
|
|
6
14
|
import { addSemanticFallbackRoot as addFallbackRoot, addSemanticGraphNode as addNode, addSemanticGraphRelation as addRelation, constructSemanticGraphNode as semanticNode, createSemanticGraphProjectionState as emptyState, MAX_APPLICATION_NODE_IDS_PER_SEMANTIC_NODE, MAX_SEMANTIC_GRAPH_NODES, MAX_SEMANTIC_GRAPH_RELATIONS, MAX_SEMANTIC_GRAPH_UNKNOWNS, } from "./JavaScriptSemanticGraphConstruction.js";
|
|
7
15
|
/** Project bounded per-file semantic IR into an artifact-bound companion graph. */
|
|
8
16
|
export const buildJavaScriptSemanticGraph = ({ rootArtifactSha256, applicationGraph, analysis, }) => {
|
|
9
17
|
const state = emptyState(applicationGraph);
|
|
18
|
+
const fingerprints = [];
|
|
10
19
|
for (const analyzed of analysis.files) {
|
|
11
20
|
if (analyzed.semantic === null)
|
|
12
21
|
continue;
|
|
13
|
-
projectFile(analyzed.file, analyzed.semantic.ir, state);
|
|
22
|
+
fingerprints.push(...projectFile(analyzed.file, analyzed.semantic.ir, state));
|
|
14
23
|
}
|
|
15
24
|
if (state.roots.size === 0)
|
|
16
25
|
addFallbackRoot(rootArtifactSha256, state);
|
|
@@ -25,7 +34,7 @@ export const buildJavaScriptSemanticGraph = ({ rootArtifactSha256, applicationGr
|
|
|
25
34
|
root_node_ids: [...state.roots],
|
|
26
35
|
nodes: [...state.nodes.values()],
|
|
27
36
|
relations: [...state.relations.values()],
|
|
28
|
-
fingerprints
|
|
37
|
+
fingerprints,
|
|
29
38
|
unknowns,
|
|
30
39
|
coverage: {
|
|
31
40
|
status: truncated ? "partial" : "unknown",
|
|
@@ -68,7 +77,15 @@ export const buildJavaScriptSemanticGraph = ({ rootArtifactSha256, applicationGr
|
|
|
68
77
|
limitations: [
|
|
69
78
|
"The semantic graph contains static syntax observations and conservative relationship candidates; it does not claim runtime execution.",
|
|
70
79
|
"Local data flow does not claim control-flow-sensitive reaching definitions or arbitrary dynamic property resolution.",
|
|
71
|
-
"
|
|
80
|
+
"Promise ownership covers explicit unshadowed Promise construction, static factories, aggregation, chaining, and await syntax only.",
|
|
81
|
+
"Function fingerprints are bounded static candidates; equal digests can remain ambiguous and do not prove behavioral equivalence.",
|
|
82
|
+
"Event extraction covers EventEmitter-style literal registrations, removals, and dispatch candidates; dynamic names remain unknown.",
|
|
83
|
+
"Timer extraction covers global or node:timers scheduling and exact local-handle cancellation.",
|
|
84
|
+
"Child-process extraction covers asynchronous node:child_process creation, literal argv/env/stdio options, exit/error listeners, and kill signals.",
|
|
85
|
+
"Configuration extraction covers process.env, process.argv, node:fs reads, and direct logical defaults.",
|
|
86
|
+
"Request extraction covers fetch, WebSocket, node:http/node:https construction, direct option fields, and exact local response consumers.",
|
|
87
|
+
"Boundary extraction covers unshadowed JSON/global coercions plus parse and validation method candidates.",
|
|
88
|
+
"Resource extraction covers built-in filesystem/network acquisition and exact local close/destroy/end handles.",
|
|
72
89
|
...(truncated
|
|
73
90
|
? [
|
|
74
91
|
"Semantic graph projection reached one or more explicit hard limits.",
|
|
@@ -86,7 +103,7 @@ const projectFile = (file, ir, state) => {
|
|
|
86
103
|
functionNodeId: null,
|
|
87
104
|
}, state));
|
|
88
105
|
if (moduleNode === null)
|
|
89
|
-
return;
|
|
106
|
+
return [];
|
|
90
107
|
state.roots.add(moduleNode.node_id);
|
|
91
108
|
const callableNodes = new Map(ir.callables.flatMap((callable) => {
|
|
92
109
|
const node = addNode(state, semanticNode(file, {
|
|
@@ -130,9 +147,20 @@ const projectFile = (file, ir, state) => {
|
|
|
130
147
|
])),
|
|
131
148
|
};
|
|
132
149
|
projectDefinitionsAndReferences(context);
|
|
150
|
+
projectSemanticValues(context);
|
|
151
|
+
projectSemanticObjects(context);
|
|
133
152
|
projectCalls(context);
|
|
153
|
+
projectSemanticPromises(context);
|
|
154
|
+
projectSemanticEvents(context);
|
|
155
|
+
projectSemanticTimers(context);
|
|
156
|
+
projectSemanticChildProcesses(context);
|
|
157
|
+
projectSemanticConfiguration(context);
|
|
158
|
+
projectSemanticRequests(context);
|
|
159
|
+
projectSemanticBoundaries(context);
|
|
160
|
+
projectSemanticResources(context);
|
|
134
161
|
projectSemanticClosureCaptures(context);
|
|
135
162
|
projectSemanticFrontiers(context);
|
|
163
|
+
return projectSemanticFunctionFingerprints(file, ir, callableNodes);
|
|
136
164
|
};
|
|
137
165
|
const createReturnSiteNodes = (file, ir, callables, state) => {
|
|
138
166
|
const result = new Map();
|