rea-agents 2.2.0 → 2.4.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 +57 -10
- package/dist/application/ApplicationWorkflowEvidenceResolver.js +162 -0
- 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 +9 -2
- package/dist/application/BinarySessionStatus.js +40 -1
- package/dist/application/CapabilityInventory.js +26 -3
- package/dist/application/CommandShimReplay.js +6 -3
- package/dist/application/CompositeProvider.js +5 -2
- package/dist/application/DirectAnalysis.js +1 -20
- package/dist/application/DirectAnalysisStatus.js +83 -0
- package/dist/application/Doctor.js +34 -25
- package/dist/application/DoctorDiagnostics.js +1 -4
- package/dist/application/DoctorProjection.js +43 -0
- package/dist/application/DoctorScope.js +102 -0
- package/dist/application/EvidenceReferenceResolver.js +26 -0
- package/dist/application/JavaScriptApplicationEvidence.js +1 -1
- package/dist/application/JavaScriptApplicationEvidenceGraph.js +10 -1
- package/dist/application/JavaScriptApplicationService.js +3 -2
- package/dist/application/JavaScriptApplicationWorkflowEvidence.js +26 -0
- package/dist/application/JavaScriptApplicationWorkflowService.js +49 -1
- package/dist/application/JavaScriptArtifactReconstruction.js +7 -0
- package/dist/application/JavaScriptModuleRelationships.js +25 -1
- package/dist/application/JavaScriptReturnShapeProjection.js +111 -0
- package/dist/application/JavaScriptSemanticGraphBuilder.js +294 -0
- package/dist/application/JavaScriptSemanticGraphConstruction.js +144 -0
- package/dist/application/JavaScriptSemanticGraphEvidence.js +86 -0
- package/dist/application/JavaScriptSemanticGraphFlowProjection.js +72 -0
- package/dist/application/JavaScriptSemanticGraphProjection.js +33 -0
- package/dist/application/JavaScriptSemanticTraceService.js +45 -0
- package/dist/application/LoopbackReplay.js +277 -133
- package/dist/application/LoopbackReplayRecorder.js +101 -0
- package/dist/application/PermissionAuthority.js +7 -3
- package/dist/application/ProcessCaptureEnvironment.js +26 -0
- package/dist/application/ProcessCaptureJournal.js +95 -0
- package/dist/application/ProcessCaptureLifecycle.js +25 -13
- package/dist/application/ProcessCheckpoints.js +35 -4
- package/dist/application/ProcessCli.js +26 -4
- package/dist/application/ProcessHarness.js +64 -83
- package/dist/application/ProcessNormalization.js +9 -2
- package/dist/application/ProcessReactiveCoordinator.js +225 -0
- package/dist/application/ProcessReactiveEffects.js +141 -0
- package/dist/application/ProcessReactiveHarness.js +85 -0
- package/dist/application/ProcessReactiveObservations.js +105 -0
- package/dist/application/ProcessSampling.js +2 -0
- package/dist/application/SessionProviderRouter.js +7 -6
- package/dist/application/Setup.js +11 -10
- package/dist/application/SetupPlan.js +1 -1
- package/dist/application/SetupRegistrationEnvironment.js +12 -0
- package/dist/application/TerminalRenderer.js +3 -1
- package/dist/browser/CdpEndpoint.js +37 -4
- package/dist/catalogIdentity.js +16 -7
- package/dist/cli/coreAnalysisCommands.js +34 -2
- package/dist/cli/javascriptApplicationAnalysis.js +19 -0
- package/dist/cli/setupCommands.js +81 -32
- package/dist/cli/utilityCommands.js +10 -2
- package/dist/cliApplicationCommands.js +79 -16
- package/dist/cliCommandNames.js +3 -0
- package/dist/cliElectronCommands.js +23 -33
- package/dist/cliObservationOptions.js +1 -1
- package/dist/cliOutput.js +56 -0
- package/dist/cliProcessCommands.js +32 -1
- package/dist/cliSetup.js +30 -21
- package/dist/contracts/applicationToolContracts.js +54 -7
- package/dist/contracts/applicationWorkflowInputContracts.js +119 -0
- package/dist/contracts/electronToolContracts.js +53 -32
- package/dist/contracts/javascriptApplicationWorkflowExamples.js +32 -9
- package/dist/contracts/processCaptureExample.js +1 -0
- package/dist/contracts/replayMachineExample.js +37 -0
- package/dist/contracts/toolContractExamples.js +2 -0
- package/dist/contracts/toolContracts.js +5 -1
- package/dist/contracts/toolEffects.js +3 -0
- package/dist/contracts/toolOutputSchemaGroups.js +2 -0
- package/dist/contracts/toolOutputSchemaPrimitives.js +43 -0
- package/dist/doctorRuntime.js +41 -0
- package/dist/domain/analysisErrorPresentation.js +5 -3
- package/dist/domain/analysisErrorProjection.js +7 -1
- package/dist/domain/analysisSnapshot.js +2 -0
- package/dist/domain/artifactGraph.js +2 -0
- package/dist/domain/binaryTarget.js +3 -6
- package/dist/domain/changedBehavior.js +5 -4
- package/dist/domain/completionLedgerGeneration.js +190 -0
- package/dist/domain/errors.js +4 -2
- package/dist/domain/evidence.js +2 -0
- package/dist/domain/evidenceCompletionLedger.js +113 -0
- package/dist/domain/hopperStartupFailure.js +9 -0
- package/dist/domain/javascriptApplicationAnalysis.js +44 -2
- package/dist/domain/javascriptExportShapeComparison.js +145 -0
- package/dist/domain/javascriptExportShapeComparisonIdentity.js +11 -0
- package/dist/domain/javascriptExportShapeComparisonSchemas.js +277 -0
- package/dist/domain/javascriptExportShapeSelection.js +132 -0
- package/dist/domain/javascriptExportShapeVariants.js +272 -0
- package/dist/domain/javascriptRuntimeReconciliationParsing.js +2 -2
- package/dist/domain/javascriptSemanticAnalysis.js +17 -36
- package/dist/domain/javascriptSemanticCallResolution.js +129 -0
- package/dist/domain/javascriptSemanticCalls.js +269 -0
- package/dist/domain/javascriptSemanticGraph.js +356 -0
- package/dist/domain/javascriptSemanticGraphSchemas.js +329 -0
- package/dist/domain/javascriptSemanticGraphSerialization.js +23 -0
- package/dist/domain/javascriptSemanticIr.js +14 -1
- package/dist/domain/javascriptSemanticPrimitives.js +36 -0
- package/dist/domain/javascriptSemanticProjection.js +36 -4
- package/dist/domain/javascriptSemanticProvenance.js +29 -0
- package/dist/domain/javascriptSemanticQuery.js +294 -0
- package/dist/domain/javascriptSemanticQueryAssessment.js +74 -0
- package/dist/domain/javascriptSemanticQueryIdentity.js +86 -0
- package/dist/domain/javascriptSemanticQueryRelations.js +15 -0
- package/dist/domain/javascriptSemanticQuerySchemas.js +188 -0
- package/dist/domain/javascriptSemanticReturns.js +187 -0
- package/dist/domain/javascriptSemanticState.js +32 -0
- package/dist/domain/javascriptSemanticTraceSchemas.js +14 -0
- package/dist/domain/javascriptSemanticValues.js +54 -70
- package/dist/domain/processCapture.js +100 -0
- package/dist/domain/processCaptureReactiveValidation.js +175 -0
- package/dist/domain/processCaptureValidation.js +103 -12
- package/dist/domain/processComparison.js +78 -25
- package/dist/domain/processObservation.js +162 -0
- package/dist/domain/processReactiveCheckpointDataflow.js +32 -0
- package/dist/domain/processReactiveMatching.js +210 -0
- package/dist/domain/processReactiveRuntime.js +120 -0
- package/dist/domain/processReactiveScenario.js +361 -0
- package/dist/domain/processReactiveScenarioPreflight.js +120 -0
- package/dist/domain/processReactiveTransition.js +161 -0
- package/dist/domain/processScenario.js +33 -0
- package/dist/domain/processTraceComparison.js +43 -0
- package/dist/domain/processTraceDimensionProjection.js +50 -0
- package/dist/domain/processTraceEvaluation.js +312 -0
- package/dist/domain/processTraceSpecification.js +373 -0
- package/dist/domain/reconstructionVerification.js +5 -4
- package/dist/domain/replayMachine.js +18 -2
- package/dist/domain/replayMachineRun.js +216 -0
- package/dist/domain/replayMachineRuntime.js +88 -9
- package/dist/domain/staticRuntimeCorrelation.js +4 -2
- package/dist/domain/zipPackageFormat.js +20 -0
- package/dist/evaluation/CodexAgentEval.js +24 -0
- package/dist/generatedPackageMetadata.js +1 -1
- package/dist/ghidra/GhidraClient.js +13 -2
- package/dist/ghidra/GhidraDiagnostics.js +1 -0
- package/dist/ghidra/GhidraLauncher.js +7 -3
- package/dist/ghidra/GhidraProvider.js +8 -1
- package/dist/hopper/BridgeLauncher.js +56 -14
- package/dist/hopper/HopperClient.js +23 -10
- package/dist/hopper/HopperDiagnostics.js +14 -0
- package/dist/hopper/HopperProcessDiagnostic.js +14 -0
- package/dist/hopper/HopperProvider.js +8 -1
- package/dist/hopper/LinuxPrivateDisplayDiagnostic.js +72 -0
- package/dist/hopper/LinuxPrivateDisplayProbe.js +217 -0
- package/dist/main/transport.js +2 -0
- package/dist/mcpDoctor.js +310 -0
- package/dist/native/NativeMacOSProvider.js +1 -0
- package/dist/process/ProcessOwnership.js +200 -53
- package/dist/process/ProviderRunLineage.js +21 -0
- package/dist/server/createServer.js +4 -1
- package/dist/server/javascriptApplicationResult.js +22 -1
- package/dist/server/registerApplicationTools/characterization.js +3 -3
- package/dist/server/registerApplicationTools/compareExportShapes.js +37 -0
- package/dist/server/registerApplicationTools/compareVersions.js +12 -6
- package/dist/server/registerApplicationTools/controlledReplay.js +2 -2
- package/dist/server/registerApplicationTools/coverage.js +3 -3
- package/dist/server/registerApplicationTools/helpers.js +37 -25
- package/dist/server/registerApplicationTools/traceFeature.js +9 -5
- package/dist/server/registerApplicationTools/traceSemantics.js +30 -0
- package/dist/server/registerApplicationTools.js +4 -0
- package/dist/server/registerEvidenceResources.js +5 -1
- package/dist/server/registerProcessComparisonTool.js +17 -7
- package/dist/server/registerReplayMachineTool.js +20 -0
- package/dist/server/registerSessionTools.js +12 -7
- package/dist/server/sessionAvailabilityPolicy.js +2 -1
- package/dist/serverIdentity.js +19 -0
- package/package.json +62 -30
- package/scripts/hopper-demo-x11.py +459 -61
- package/scripts/prepack.mjs +55 -0
- package/scripts/prepare.mjs +28 -0
- package/scripts/rea.mjs +26 -5
- package/skills/reverse-engineer-anything/SKILL.md +4 -3
- package/skills/reverse-engineer-anything/references/javascript-applications.md +10 -0
- package/skills/reverse-engineer-anything/references/native-and-artifacts.md +2 -2
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { applicationGraphEvidenceSchema } from "./javascriptApplicationEvidenceSchemas.js";
|
|
3
|
+
import { isJsonWithinLimits } from "./jsonLimits.js";
|
|
4
|
+
import { jsonValueSchema } from "./jsonValue.js";
|
|
5
|
+
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
|
|
6
|
+
const boundedTextSchema = z.string().min(1).max(4_096);
|
|
7
|
+
const semanticNodeIdSchema = z.string().regex(/^jsrg_node_[a-f0-9]{64}$/u);
|
|
8
|
+
const semanticRelationIdSchema = z
|
|
9
|
+
.string()
|
|
10
|
+
.regex(/^jsrg_relation_[a-f0-9]{64}$/u);
|
|
11
|
+
const semanticUnknownIdSchema = z
|
|
12
|
+
.string()
|
|
13
|
+
.regex(/^jsrg_unknown_[a-f0-9]{64}$/u);
|
|
14
|
+
/** Semantic entity kinds admitted by JavaScript Semantic Relation Graph v1. */
|
|
15
|
+
export const JAVASCRIPT_SEMANTIC_NODE_KINDS = [
|
|
16
|
+
"module",
|
|
17
|
+
"function",
|
|
18
|
+
"parameter",
|
|
19
|
+
"binding",
|
|
20
|
+
"expression",
|
|
21
|
+
"literal",
|
|
22
|
+
"property-slot",
|
|
23
|
+
"call-site",
|
|
24
|
+
"return-site",
|
|
25
|
+
"closure-capture",
|
|
26
|
+
"promise",
|
|
27
|
+
"task",
|
|
28
|
+
"event",
|
|
29
|
+
"listener",
|
|
30
|
+
"timer",
|
|
31
|
+
"child-process",
|
|
32
|
+
"stdio",
|
|
33
|
+
"signal",
|
|
34
|
+
"config-source",
|
|
35
|
+
"request",
|
|
36
|
+
"response",
|
|
37
|
+
"boundary",
|
|
38
|
+
"resource",
|
|
39
|
+
"unknown-frontier",
|
|
40
|
+
];
|
|
41
|
+
/** Required semantic-analysis coverage families. */
|
|
42
|
+
export const JAVASCRIPT_SEMANTIC_RELATION_FAMILIES = [
|
|
43
|
+
"boundary",
|
|
44
|
+
"call-flow",
|
|
45
|
+
"child-process",
|
|
46
|
+
"closure",
|
|
47
|
+
"configuration",
|
|
48
|
+
"data-flow",
|
|
49
|
+
"event",
|
|
50
|
+
"object-flow",
|
|
51
|
+
"promise-ownership",
|
|
52
|
+
"request",
|
|
53
|
+
"resource-lifecycle",
|
|
54
|
+
"timer",
|
|
55
|
+
];
|
|
56
|
+
/** Directed semantic relations admitted by graph v1. */
|
|
57
|
+
export const JAVASCRIPT_SEMANTIC_RELATIONS = [
|
|
58
|
+
"acquires",
|
|
59
|
+
"aggregates",
|
|
60
|
+
"aliases",
|
|
61
|
+
"argument-to-parameter",
|
|
62
|
+
"awaits",
|
|
63
|
+
"calls",
|
|
64
|
+
"cancels-timer",
|
|
65
|
+
"captures",
|
|
66
|
+
"chains",
|
|
67
|
+
"coerces",
|
|
68
|
+
"connects-stdio",
|
|
69
|
+
"consumed-by",
|
|
70
|
+
"constructs-request",
|
|
71
|
+
"creates-promise",
|
|
72
|
+
"defaults",
|
|
73
|
+
"defines",
|
|
74
|
+
"destructures",
|
|
75
|
+
"detaches-task",
|
|
76
|
+
"dispatches-candidate",
|
|
77
|
+
"forwards-signal",
|
|
78
|
+
"listens-error",
|
|
79
|
+
"listens-exit",
|
|
80
|
+
"owns",
|
|
81
|
+
"overrides",
|
|
82
|
+
"parses",
|
|
83
|
+
"reads",
|
|
84
|
+
"reads-argv",
|
|
85
|
+
"reads-config",
|
|
86
|
+
"reads-environment",
|
|
87
|
+
"reads-property",
|
|
88
|
+
"registers-listener",
|
|
89
|
+
"releases",
|
|
90
|
+
"removes-listener",
|
|
91
|
+
"returns-task",
|
|
92
|
+
"returns-to-call",
|
|
93
|
+
"schedules-timer",
|
|
94
|
+
"spawns",
|
|
95
|
+
"spreads",
|
|
96
|
+
"supplies-argv",
|
|
97
|
+
"supplies-env",
|
|
98
|
+
"supplies-request-field",
|
|
99
|
+
"validates",
|
|
100
|
+
"writes",
|
|
101
|
+
"writes-property",
|
|
102
|
+
];
|
|
103
|
+
/** Map each semantic relation to its coverage family. */
|
|
104
|
+
export const JAVASCRIPT_SEMANTIC_RELATION_FAMILY = {
|
|
105
|
+
acquires: "resource-lifecycle",
|
|
106
|
+
aggregates: "promise-ownership",
|
|
107
|
+
aliases: "data-flow",
|
|
108
|
+
"argument-to-parameter": "call-flow",
|
|
109
|
+
awaits: "promise-ownership",
|
|
110
|
+
calls: "call-flow",
|
|
111
|
+
"cancels-timer": "timer",
|
|
112
|
+
captures: "closure",
|
|
113
|
+
chains: "promise-ownership",
|
|
114
|
+
coerces: "boundary",
|
|
115
|
+
"connects-stdio": "child-process",
|
|
116
|
+
"consumed-by": "request",
|
|
117
|
+
"constructs-request": "request",
|
|
118
|
+
"creates-promise": "promise-ownership",
|
|
119
|
+
defaults: "configuration",
|
|
120
|
+
defines: "data-flow",
|
|
121
|
+
destructures: "object-flow",
|
|
122
|
+
"detaches-task": "promise-ownership",
|
|
123
|
+
"dispatches-candidate": "event",
|
|
124
|
+
"forwards-signal": "child-process",
|
|
125
|
+
"listens-error": "child-process",
|
|
126
|
+
"listens-exit": "child-process",
|
|
127
|
+
owns: "promise-ownership",
|
|
128
|
+
overrides: "configuration",
|
|
129
|
+
parses: "boundary",
|
|
130
|
+
reads: "data-flow",
|
|
131
|
+
"reads-argv": "configuration",
|
|
132
|
+
"reads-config": "configuration",
|
|
133
|
+
"reads-environment": "configuration",
|
|
134
|
+
"reads-property": "object-flow",
|
|
135
|
+
"registers-listener": "event",
|
|
136
|
+
releases: "resource-lifecycle",
|
|
137
|
+
"removes-listener": "event",
|
|
138
|
+
"returns-task": "promise-ownership",
|
|
139
|
+
"returns-to-call": "call-flow",
|
|
140
|
+
"schedules-timer": "timer",
|
|
141
|
+
spawns: "child-process",
|
|
142
|
+
spreads: "object-flow",
|
|
143
|
+
"supplies-argv": "child-process",
|
|
144
|
+
"supplies-env": "child-process",
|
|
145
|
+
"supplies-request-field": "request",
|
|
146
|
+
validates: "boundary",
|
|
147
|
+
writes: "data-flow",
|
|
148
|
+
"writes-property": "object-flow",
|
|
149
|
+
};
|
|
150
|
+
const relativePathSchema = z
|
|
151
|
+
.string()
|
|
152
|
+
.min(1)
|
|
153
|
+
.max(4_096)
|
|
154
|
+
.refine((path) => !path.startsWith("/") &&
|
|
155
|
+
!path.includes("\\") &&
|
|
156
|
+
path.split("/").every((part) => !["", ".", ".."].includes(part)), "Expected a normalized relative POSIX path without traversal");
|
|
157
|
+
const sourcePointSchema = z.strictObject({
|
|
158
|
+
line: z.number().int().min(1),
|
|
159
|
+
column: z.number().int().min(0),
|
|
160
|
+
});
|
|
161
|
+
const sourceRangeSchema = z
|
|
162
|
+
.strictObject({ start: sourcePointSchema, end: sourcePointSchema })
|
|
163
|
+
.superRefine((range, context) => {
|
|
164
|
+
if (range.end.line < range.start.line ||
|
|
165
|
+
(range.end.line === range.start.line &&
|
|
166
|
+
range.end.column < range.start.column))
|
|
167
|
+
context.addIssue({
|
|
168
|
+
code: "custom",
|
|
169
|
+
path: ["end"],
|
|
170
|
+
message: "Source range end must not precede its start",
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
const semanticPropertiesSchema = z
|
|
174
|
+
.record(z.string().min(1).max(128), jsonValueSchema)
|
|
175
|
+
.superRefine((properties, context) => {
|
|
176
|
+
if (Object.keys(properties).length > 64)
|
|
177
|
+
context.addIssue({
|
|
178
|
+
code: "custom",
|
|
179
|
+
message: "Semantic properties exceed 64 keys",
|
|
180
|
+
});
|
|
181
|
+
if (!isJsonWithinLimits(properties, {
|
|
182
|
+
maxDepth: 6,
|
|
183
|
+
maxNodes: 512,
|
|
184
|
+
maxStringLength: 4_096,
|
|
185
|
+
}))
|
|
186
|
+
context.addIssue({
|
|
187
|
+
code: "custom",
|
|
188
|
+
message: "Semantic properties exceed structural limits",
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
const semanticNodeIdentitySchema = z.strictObject({
|
|
192
|
+
artifact_sha256: digestSchema,
|
|
193
|
+
module_path: relativePathSchema,
|
|
194
|
+
source_range: sourceRangeSchema.nullable(),
|
|
195
|
+
role_key: z.string().min(1).max(1_024),
|
|
196
|
+
});
|
|
197
|
+
/** One semantic entity before its canonical identifier is derived. */
|
|
198
|
+
export const javaScriptSemanticNodeInputSchema = z.strictObject({
|
|
199
|
+
kind: z.enum(JAVASCRIPT_SEMANTIC_NODE_KINDS),
|
|
200
|
+
identity: semanticNodeIdentitySchema,
|
|
201
|
+
function_node_id: semanticNodeIdSchema.nullable(),
|
|
202
|
+
application_node_ids: z
|
|
203
|
+
.array(z.string().regex(/^jag_node_[a-f0-9]{64}$/u))
|
|
204
|
+
.max(64),
|
|
205
|
+
label: z.string().min(1).max(1_024).nullable(),
|
|
206
|
+
properties: semanticPropertiesSchema,
|
|
207
|
+
evidence: applicationGraphEvidenceSchema,
|
|
208
|
+
});
|
|
209
|
+
/** One exact, artifact-version semantic entity. */
|
|
210
|
+
export const javaScriptSemanticNodeSchema = javaScriptSemanticNodeInputSchema.extend({
|
|
211
|
+
node_id: semanticNodeIdSchema,
|
|
212
|
+
identifier_strategy: z.strictObject({
|
|
213
|
+
strategy: z.literal("semantic-content-sha256"),
|
|
214
|
+
stability: z.literal("artifact-version"),
|
|
215
|
+
}),
|
|
216
|
+
});
|
|
217
|
+
/** One directed semantic relationship before its ID is derived. */
|
|
218
|
+
export const javaScriptSemanticRelationInputSchema = z.strictObject({
|
|
219
|
+
source_node_id: semanticNodeIdSchema,
|
|
220
|
+
target_node_id: semanticNodeIdSchema,
|
|
221
|
+
relation: z.enum(JAVASCRIPT_SEMANTIC_RELATIONS),
|
|
222
|
+
resolution: z.enum(["resolved", "candidate"]),
|
|
223
|
+
properties: semanticPropertiesSchema,
|
|
224
|
+
evidence: applicationGraphEvidenceSchema,
|
|
225
|
+
});
|
|
226
|
+
/** One canonical directed semantic relationship. */
|
|
227
|
+
export const javaScriptSemanticRelationSchema = javaScriptSemanticRelationInputSchema.extend({
|
|
228
|
+
relation_id: semanticRelationIdSchema,
|
|
229
|
+
identifier_strategy: z.strictObject({
|
|
230
|
+
strategy: z.literal("semantic-content-sha256"),
|
|
231
|
+
stability: z.literal("relationship-exact"),
|
|
232
|
+
}),
|
|
233
|
+
});
|
|
234
|
+
/** Reasons semantic analysis can leave an explicit frontier. */
|
|
235
|
+
export const JAVASCRIPT_SEMANTIC_UNKNOWN_REASONS = [
|
|
236
|
+
"ambiguous-target",
|
|
237
|
+
"bound-reached",
|
|
238
|
+
"dynamic-call",
|
|
239
|
+
"dynamic-property",
|
|
240
|
+
"eval-or-generated-code",
|
|
241
|
+
"incomplete-module",
|
|
242
|
+
"missing-source",
|
|
243
|
+
"unsupported-syntax",
|
|
244
|
+
];
|
|
245
|
+
/** One unresolved semantic frontier before its ID is derived. */
|
|
246
|
+
export const javaScriptSemanticUnknownInputSchema = z.strictObject({
|
|
247
|
+
node_id: semanticNodeIdSchema.nullable(),
|
|
248
|
+
family: z.enum(JAVASCRIPT_SEMANTIC_RELATION_FAMILIES),
|
|
249
|
+
relation_kinds: z.array(z.enum(JAVASCRIPT_SEMANTIC_RELATIONS)).min(1).max(45),
|
|
250
|
+
reason: z.enum(JAVASCRIPT_SEMANTIC_UNKNOWN_REASONS),
|
|
251
|
+
detail: boundedTextSchema,
|
|
252
|
+
candidate_node_ids: z.array(semanticNodeIdSchema).max(1_000),
|
|
253
|
+
evidence: applicationGraphEvidenceSchema,
|
|
254
|
+
});
|
|
255
|
+
/** One canonical unresolved semantic frontier. */
|
|
256
|
+
export const javaScriptSemanticUnknownSchema = javaScriptSemanticUnknownInputSchema.extend({
|
|
257
|
+
unknown_id: semanticUnknownIdSchema,
|
|
258
|
+
});
|
|
259
|
+
const fingerprintComponentsSchema = z.strictObject({
|
|
260
|
+
parameter_arity: z.number().int().min(0).max(10_000),
|
|
261
|
+
normalized_ast_sha256: digestSchema,
|
|
262
|
+
control_flow_sha256: digestSchema,
|
|
263
|
+
relation_shape_sha256: digestSchema,
|
|
264
|
+
literal_set_sha256: digestSchema,
|
|
265
|
+
effects: z
|
|
266
|
+
.array(z.enum([
|
|
267
|
+
"async",
|
|
268
|
+
"child-process",
|
|
269
|
+
"event",
|
|
270
|
+
"network",
|
|
271
|
+
"promise",
|
|
272
|
+
"resource",
|
|
273
|
+
"timer",
|
|
274
|
+
]))
|
|
275
|
+
.max(7),
|
|
276
|
+
});
|
|
277
|
+
/** One bounded rename-resistant function fingerprint. */
|
|
278
|
+
export const javaScriptSemanticFingerprintInputSchema = z.strictObject({
|
|
279
|
+
function_node_id: semanticNodeIdSchema,
|
|
280
|
+
algorithm: z.literal("rea.javascript-semantic-function/v1"),
|
|
281
|
+
status: z.enum(["complete", "partial", "unavailable"]),
|
|
282
|
+
components: fingerprintComponentsSchema,
|
|
283
|
+
limitations: z.array(boundedTextSchema).max(100),
|
|
284
|
+
evidence: applicationGraphEvidenceSchema,
|
|
285
|
+
});
|
|
286
|
+
/** One canonical function fingerprint record. */
|
|
287
|
+
export const javaScriptSemanticFingerprintSchema = javaScriptSemanticFingerprintInputSchema.extend({
|
|
288
|
+
fingerprint_id: z.string().regex(/^jsrg_fingerprint_[a-f0-9]{64}$/u),
|
|
289
|
+
fingerprint_sha256: digestSchema,
|
|
290
|
+
});
|
|
291
|
+
const familyCoverageSchema = z.strictObject({
|
|
292
|
+
family: z.enum(JAVASCRIPT_SEMANTIC_RELATION_FAMILIES),
|
|
293
|
+
status: z.enum(["complete", "partial", "unknown", "unsupported"]),
|
|
294
|
+
retained_relations: z.number().int().min(0),
|
|
295
|
+
omitted_relations: z.number().int().min(0).nullable(),
|
|
296
|
+
unknown_ids: z.array(semanticUnknownIdSchema).max(100_000),
|
|
297
|
+
});
|
|
298
|
+
const graphCoverageSchema = z.strictObject({
|
|
299
|
+
status: z.enum(["complete", "partial", "unknown", "unavailable"]),
|
|
300
|
+
truncated: z.boolean(),
|
|
301
|
+
omitted_nodes: z.number().int().min(0).nullable(),
|
|
302
|
+
omitted_relations: z.number().int().min(0).nullable(),
|
|
303
|
+
limits: z
|
|
304
|
+
.array(z.strictObject({
|
|
305
|
+
name: z.string().min(1).max(128),
|
|
306
|
+
value: z.number().int().min(0),
|
|
307
|
+
unit: z.enum(["items", "bytes", "milliseconds", "depth", "other"]),
|
|
308
|
+
}))
|
|
309
|
+
.max(32),
|
|
310
|
+
families: z.array(familyCoverageSchema).length(12),
|
|
311
|
+
});
|
|
312
|
+
/** Graph content before its top-level commitment is derived. */
|
|
313
|
+
export const javaScriptSemanticGraphInputSchema = z.strictObject({
|
|
314
|
+
schema: z.literal("JavaScriptSemanticRelationGraph"),
|
|
315
|
+
schema_version: z.literal(1),
|
|
316
|
+
root_artifact_sha256: digestSchema,
|
|
317
|
+
application_graph_id: z.string().regex(/^jag_[a-f0-9]{64}$/u),
|
|
318
|
+
root_node_ids: z.array(semanticNodeIdSchema).min(1).max(10_000),
|
|
319
|
+
nodes: z.array(javaScriptSemanticNodeSchema).min(1).max(100_000),
|
|
320
|
+
relations: z.array(javaScriptSemanticRelationSchema).max(200_000),
|
|
321
|
+
fingerprints: z.array(javaScriptSemanticFingerprintSchema).max(20_000),
|
|
322
|
+
unknowns: z.array(javaScriptSemanticUnknownSchema).max(100_000),
|
|
323
|
+
coverage: graphCoverageSchema,
|
|
324
|
+
limitations: z.array(boundedTextSchema).max(1_000),
|
|
325
|
+
});
|
|
326
|
+
/** Stored JavaScript Semantic Relation Graph v1. */
|
|
327
|
+
export const javaScriptSemanticGraphRecordSchema = javaScriptSemanticGraphInputSchema.extend({
|
|
328
|
+
graph_id: z.string().regex(/^jsrg_[a-f0-9]{64}$/u),
|
|
329
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import canonicalize from "canonicalize";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { javaScriptSemanticGraphSchema, } from "./javascriptSemanticGraph.js";
|
|
4
|
+
const canonicalJson = (value) => {
|
|
5
|
+
const encoded = canonicalize(value);
|
|
6
|
+
if (encoded === undefined)
|
|
7
|
+
throw new TypeError("JavaScript semantic graph could not canonicalize data");
|
|
8
|
+
return encoded;
|
|
9
|
+
};
|
|
10
|
+
/** Parse a stored semantic graph and reject unsupported versions or stale IDs. */
|
|
11
|
+
export const parseJavaScriptSemanticGraph = (input) => {
|
|
12
|
+
const envelope = z
|
|
13
|
+
.object({ schema: z.string(), schema_version: z.number() })
|
|
14
|
+
.passthrough()
|
|
15
|
+
.safeParse(input);
|
|
16
|
+
if (envelope.success &&
|
|
17
|
+
envelope.data.schema === "JavaScriptSemanticRelationGraph" &&
|
|
18
|
+
envelope.data.schema_version !== 1)
|
|
19
|
+
throw new TypeError(`Unsupported JavaScript Semantic Relation Graph schema version: ${String(envelope.data.schema_version)}`);
|
|
20
|
+
return javaScriptSemanticGraphSchema.parse(input);
|
|
21
|
+
};
|
|
22
|
+
/** Serialize a verified semantic graph as canonical JSON. */
|
|
23
|
+
export const serializeJavaScriptSemanticGraph = (input) => canonicalJson(parseJavaScriptSemanticGraph(input));
|
|
@@ -5,6 +5,13 @@ export const DEFAULT_JAVASCRIPT_SEMANTIC_LIMITS = {
|
|
|
5
5
|
maxCallables: 20_000,
|
|
6
6
|
maxReferences: 100_000,
|
|
7
7
|
maxModuleLinks: 20_000,
|
|
8
|
+
maxReturnSites: 20_000,
|
|
9
|
+
maxCallSites: 20_000,
|
|
10
|
+
maxCallArguments: 100_000,
|
|
11
|
+
maxArgumentFlows: 100_000,
|
|
12
|
+
maxCallReturnFlows: 100_000,
|
|
13
|
+
maxClosureCaptures: 100_000,
|
|
14
|
+
maxFrontiers: 20_000,
|
|
8
15
|
maxValueDepth: 16,
|
|
9
16
|
maxUnionValues: 32,
|
|
10
17
|
maxObjectProperties: 256,
|
|
@@ -16,12 +23,18 @@ export const semanticBinding = (ir, bindingId) => ir.bindings.find(({ bindingId:
|
|
|
16
23
|
/** Fail-closed result when Babel cannot produce an inert syntax tree. */
|
|
17
24
|
export const failedJavaScriptSemanticIr = () => ({
|
|
18
25
|
schema: "JavaScriptSemanticIR",
|
|
19
|
-
schemaVersion:
|
|
26
|
+
schemaVersion: 3,
|
|
20
27
|
scopes: [],
|
|
21
28
|
bindings: [],
|
|
22
29
|
callables: [],
|
|
23
30
|
references: [],
|
|
24
31
|
moduleLinks: [],
|
|
32
|
+
callSites: [],
|
|
33
|
+
argumentFlows: [],
|
|
34
|
+
callReturnFlows: [],
|
|
35
|
+
callResultFlows: [],
|
|
36
|
+
closureCaptures: [],
|
|
37
|
+
frontiers: [],
|
|
25
38
|
coverage: { status: "failed", omittedCount: null, limitsReached: [] },
|
|
26
39
|
limitations: [
|
|
27
40
|
"JavaScript parsing failed; no semantic absence claim is available.",
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import * as t from "@babel/types";
|
|
2
|
+
import { reachSemanticValueLimit, semanticPrimitiveKey, } from "./javascriptSemanticProvenance.js";
|
|
3
|
+
import { compareCodePoints } from "./javascriptStaticAnalysisHelpers.js";
|
|
4
|
+
/** Normalize one bounded collection of possible primitive values. */
|
|
5
|
+
export const semanticPrimitiveSet = (values, state) => {
|
|
6
|
+
const unique = [
|
|
7
|
+
...new Map(values.map((value) => [semanticPrimitiveKey(value), value])).values(),
|
|
8
|
+
].sort((left, right) => compareCodePoints(semanticPrimitiveKey(left), semanticPrimitiveKey(right)));
|
|
9
|
+
if (unique.length > state.limits.maxUnionValues) {
|
|
10
|
+
reachSemanticValueLimit(state, "maxUnionValues");
|
|
11
|
+
return {
|
|
12
|
+
status: "limit-reached",
|
|
13
|
+
reason: "maxUnionValues reached.",
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
const only = unique[0];
|
|
17
|
+
return unique.length === 1 && only !== undefined
|
|
18
|
+
? { status: "literal", value: only }
|
|
19
|
+
: { status: "union", values: unique };
|
|
20
|
+
};
|
|
21
|
+
/** Read the primitive candidates retained in one lattice value. */
|
|
22
|
+
export const semanticPrimitiveCandidates = (value) => value.status === "literal"
|
|
23
|
+
? [value.value]
|
|
24
|
+
: value.status === "union"
|
|
25
|
+
? value.values
|
|
26
|
+
: null;
|
|
27
|
+
/** Parse one Babel primitive literal without evaluating code. */
|
|
28
|
+
export const semanticPrimitiveValue = (node) => {
|
|
29
|
+
if (t.isStringLiteral(node) || t.isNumericLiteral(node))
|
|
30
|
+
return { found: true, value: node.value };
|
|
31
|
+
if (t.isBooleanLiteral(node))
|
|
32
|
+
return { found: true, value: node.value };
|
|
33
|
+
if (t.isNullLiteral(node))
|
|
34
|
+
return { found: true, value: null };
|
|
35
|
+
return { found: false };
|
|
36
|
+
};
|
|
@@ -13,8 +13,9 @@ export const collectSemanticCallable = (input) => {
|
|
|
13
13
|
reachSemanticLimit(state, "maxCallables");
|
|
14
14
|
return;
|
|
15
15
|
}
|
|
16
|
+
const callableId = semanticCallableIdForNode(node) ?? "callable:unknown:-1:-1";
|
|
16
17
|
state.callables.push({
|
|
17
|
-
callableId
|
|
18
|
+
callableId,
|
|
18
19
|
kind,
|
|
19
20
|
name: callableName(node, parent),
|
|
20
21
|
containerScopeId: containerScope.scopeId,
|
|
@@ -22,7 +23,15 @@ export const collectSemanticCallable = (input) => {
|
|
|
22
23
|
? null
|
|
23
24
|
: bodyScope.scopeId,
|
|
24
25
|
location: range(node),
|
|
26
|
+
returnSites: [],
|
|
27
|
+
returnCoverage: {
|
|
28
|
+
status: "partial",
|
|
29
|
+
retainedCount: 0,
|
|
30
|
+
omittedCount: null,
|
|
31
|
+
limitsReached: [],
|
|
32
|
+
},
|
|
25
33
|
});
|
|
34
|
+
state.callableNodesById.set(callableId, node);
|
|
26
35
|
};
|
|
27
36
|
/** Collect one static import/export relationship for later composition. */
|
|
28
37
|
export const collectSemanticModuleLink = (node, state) => {
|
|
@@ -46,6 +55,7 @@ export const collectSemanticModuleLink = (node, state) => {
|
|
|
46
55
|
importedName: null,
|
|
47
56
|
localName: defaultDeclarationName(node.declaration),
|
|
48
57
|
exportedName: "default",
|
|
58
|
+
callableId: semanticCallableIdForNode(node.declaration),
|
|
49
59
|
location: range(node),
|
|
50
60
|
});
|
|
51
61
|
else if (t.isVariableDeclarator(node))
|
|
@@ -61,7 +71,7 @@ export const collectSemanticReferences = (program, state) => {
|
|
|
61
71
|
enter: (node, parent) => {
|
|
62
72
|
if (!t.isIdentifier(node) || parent === null)
|
|
63
73
|
return;
|
|
64
|
-
const role =
|
|
74
|
+
const role = semanticReferenceRole(node, parent);
|
|
65
75
|
if (role === null)
|
|
66
76
|
return;
|
|
67
77
|
const key = `${String(node.start)}:${role}:${node.name}`;
|
|
@@ -205,6 +215,7 @@ const collectNamedExports = (node, state) => {
|
|
|
205
215
|
importedName: null,
|
|
206
216
|
localName,
|
|
207
217
|
exportedName: localName,
|
|
218
|
+
callableId: declarationCallableId(node.declaration, localName),
|
|
208
219
|
location: range(node.declaration),
|
|
209
220
|
});
|
|
210
221
|
for (const specifier of node.specifiers)
|
|
@@ -265,6 +276,7 @@ const collectCommonJsExport = (node, state) => {
|
|
|
265
276
|
importedName: origin?.importedPath.at(-1) ?? null,
|
|
266
277
|
localName: t.isIdentifier(node.right) ? node.right.name : null,
|
|
267
278
|
exportedName,
|
|
279
|
+
callableId: semanticCallableIdForNode(node.right),
|
|
268
280
|
location: range(node),
|
|
269
281
|
});
|
|
270
282
|
};
|
|
@@ -273,9 +285,29 @@ const addModuleLink = (state, link) => {
|
|
|
273
285
|
reachSemanticLimit(state, "maxModuleLinks");
|
|
274
286
|
return;
|
|
275
287
|
}
|
|
276
|
-
state.moduleLinks.push(link);
|
|
288
|
+
state.moduleLinks.push({ ...link, callableId: link.callableId ?? null });
|
|
289
|
+
};
|
|
290
|
+
/** Deterministic callable identity shared by collection and return recovery. */
|
|
291
|
+
export const semanticCallableIdForNode = (node) => {
|
|
292
|
+
const kind = callableKind(node);
|
|
293
|
+
return kind === undefined
|
|
294
|
+
? null
|
|
295
|
+
: `callable:${kind}:${String(node.start ?? -1)}:${String(node.end ?? -1)}`;
|
|
296
|
+
};
|
|
297
|
+
const declarationCallableId = (declaration, localName) => {
|
|
298
|
+
if ((t.isFunctionDeclaration(declaration) ||
|
|
299
|
+
t.isClassDeclaration(declaration)) &&
|
|
300
|
+
declaration.id?.name === localName)
|
|
301
|
+
return semanticCallableIdForNode(declaration);
|
|
302
|
+
if (!t.isVariableDeclaration(declaration))
|
|
303
|
+
return null;
|
|
304
|
+
const declarator = declaration.declarations.find(({ id }) => t.isIdentifier(id, { name: localName }));
|
|
305
|
+
return declarator?.init === null || declarator?.init === undefined
|
|
306
|
+
? null
|
|
307
|
+
: semanticCallableIdForNode(declarator.init);
|
|
277
308
|
};
|
|
278
|
-
|
|
309
|
+
/** Classify one identifier occurrence consistently with semantic references. */
|
|
310
|
+
export const semanticReferenceRole = (node, parent) => {
|
|
279
311
|
if (isDeclarationIdentifier(node, parent) || isNonReferenceKey(node, parent))
|
|
280
312
|
return null;
|
|
281
313
|
if ((t.isAssignmentExpression(parent) && parent.left === node) ||
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { compareCodePoints } from "./javascriptStaticAnalysisHelpers.js";
|
|
2
|
+
/** Construct one immutable semantic provenance value. */
|
|
3
|
+
export const semanticProvenance = (status, origins, reason) => ({ status, origins, reason });
|
|
4
|
+
/** Normalize bounded exact module origins into one provenance classification. */
|
|
5
|
+
export const semanticOriginsProvenance = (origins, state) => {
|
|
6
|
+
const unique = uniqueSemanticOrigins(origins);
|
|
7
|
+
if (unique.length > state.limits.maxUnionValues)
|
|
8
|
+
return semanticLimitProvenance(state, "maxUnionValues");
|
|
9
|
+
return unique.length === 1
|
|
10
|
+
? semanticProvenance("module", unique, null)
|
|
11
|
+
: semanticProvenance("ambiguous", unique, "Multiple module origins.");
|
|
12
|
+
};
|
|
13
|
+
/** Deduplicate and canonically order module origins. */
|
|
14
|
+
export const uniqueSemanticOrigins = (origins) => [
|
|
15
|
+
...new Map(origins.map((origin) => [semanticOriginKey(origin), origin])).values(),
|
|
16
|
+
].sort((left, right) => compareCodePoints(semanticOriginKey(left), semanticOriginKey(right)));
|
|
17
|
+
/** Mark and return an explicit provenance-limit value. */
|
|
18
|
+
export const semanticLimitProvenance = (state, limit) => {
|
|
19
|
+
reachSemanticValueLimit(state, limit);
|
|
20
|
+
return semanticProvenance("limit-reached", [], `${limit} reached.`);
|
|
21
|
+
};
|
|
22
|
+
/** Record one value-lattice limit against the shared semantic analysis state. */
|
|
23
|
+
export const reachSemanticValueLimit = (state, limit) => {
|
|
24
|
+
state.limitsReached.add(limit);
|
|
25
|
+
state.omittedCount += 1;
|
|
26
|
+
};
|
|
27
|
+
const semanticOriginKey = (origin) => `${origin.specifier}\0${origin.importedPath.join("\0")}`;
|
|
28
|
+
/** Canonically distinguish primitive values across type boundaries. */
|
|
29
|
+
export const semanticPrimitiveKey = (value) => `${value === null ? "null" : typeof value}:${JSON.stringify(value)}`;
|