@neat.is/types 0.6.4 → 0.7.1

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/dist/index.js CHANGED
@@ -22,7 +22,16 @@ var EdgeType = {
22
22
  // Static module dependency between two FileNodes within a service (ADR-092,
23
23
  // file-awareness.md §10). Compile-time, not runtime — represents one file
24
24
  // importing another. Distinct from CALLS which records runtime invocations.
25
- IMPORTS: "IMPORTS"
25
+ IMPORTS: "IMPORTS",
26
+ // Static heritage between two SymbolNodes (ADR-158 §3). `INHERITS` records a
27
+ // class's `extends` clause (`class ──INHERITS──▶ superclass`); `IMPLEMENTS`
28
+ // records an `implements` clause (`class ──IMPLEMENTS──▶ implemented`). Both
29
+ // are symbol→symbol, EXTRACTED, minted only when the parent name resolves to
30
+ // exactly one known SymbolNode — same-file or through the import graph — never
31
+ // fuzzy-matched. A parent that resolves to nothing (external package,
32
+ // re-export chain, an interface, which is not a SymbolNode) emits no edge.
33
+ INHERITS: "INHERITS",
34
+ IMPLEMENTS: "IMPLEMENTS"
26
35
  };
27
36
  var NodeType = {
28
37
  ServiceNode: "ServiceNode",
@@ -72,7 +81,18 @@ var NodeType = {
72
81
  // edge that carries `lastObserved` and decays OBSERVED → STALE on CONNECTS_TO's
73
82
  // own staleness threshold when the channel goes quiet. See
74
83
  // docs/contracts/otel-ingest.md.
75
- WebSocketChannelNode: "WebSocketChannelNode"
84
+ WebSocketChannelNode: "WebSocketChannelNode",
85
+ // A symbol under a file — a function, method, constructor, or class
86
+ // definition — at definition-span granularity (ADR-158). Static-first: the
87
+ // extractor mints one per definition and the file owns it through a
88
+ // `file ──CONTAINS──▶ symbol` edge, one containment level below
89
+ // `service ──CONTAINS──▶ file`. It carries its `{ startLine, endLine }`
90
+ // definition span, which is the fusion key ingest joins a span's `code.line`
91
+ // against to land an OBSERVED edge on the calling symbol rather than only its
92
+ // file (observed-first edges, one grain finer than §4 file grain). The node is
93
+ // language-neutral; the per-language tree-sitter extractor is the adapter. See
94
+ // docs/contracts/static-extraction.md and docs/contracts/file-awareness.md §1.
95
+ SymbolNode: "SymbolNode"
76
96
  };
77
97
  var NodeTypeSchema = z.enum([
78
98
  NodeType.ServiceNode,
@@ -84,145 +104,216 @@ var NodeTypeSchema = z.enum([
84
104
  NodeType.RouteNode,
85
105
  NodeType.GraphQLOperationNode,
86
106
  NodeType.GrpcMethodNode,
87
- NodeType.WebSocketChannelNode
107
+ NodeType.WebSocketChannelNode,
108
+ NodeType.SymbolNode
88
109
  ]);
89
110
 
90
111
  // src/nodes.ts
112
+ import { z as z3 } from "zod";
113
+
114
+ // src/edges.ts
91
115
  import { z as z2 } from "zod";
92
- var CompatibleDriverSchema = z2.object({
93
- name: z2.string(),
94
- minVersion: z2.string()
116
+ var ProvenanceSchema = z2.enum([
117
+ Provenance.EXTRACTED,
118
+ Provenance.INFERRED,
119
+ Provenance.OBSERVED,
120
+ Provenance.STALE
121
+ ]);
122
+ var EdgeTypeSchema = z2.enum([
123
+ EdgeType.CALLS,
124
+ EdgeType.DEPENDS_ON,
125
+ EdgeType.CONNECTS_TO,
126
+ EdgeType.CONFIGURED_BY,
127
+ EdgeType.PUBLISHES_TO,
128
+ EdgeType.CONSUMES_FROM,
129
+ EdgeType.RUNS_ON,
130
+ EdgeType.CONTAINS,
131
+ EdgeType.IMPORTS,
132
+ EdgeType.INHERITS,
133
+ EdgeType.IMPLEMENTS
134
+ ]);
135
+ var EdgeEvidenceSchema = z2.object({
136
+ file: z2.string(),
137
+ line: z2.number().int().nonnegative().optional(),
138
+ snippet: z2.string().optional(),
139
+ // HTTP shape of a recognised client call site (ADR-119). Present on a
140
+ // client↔route CALLS edge so the edge records the method + path-template the
141
+ // client named, alongside the file:line it named them at. Absent on every
142
+ // other edge — a config or infra edge has no HTTP method.
143
+ method: z2.string().optional(),
144
+ pathTemplate: z2.string().optional()
145
+ });
146
+ var EdgeSignalSchema = z2.object({
147
+ spanCount: z2.number().int().nonnegative(),
148
+ errorCount: z2.number().int().nonnegative(),
149
+ lastObservedAgeMs: z2.number().nonnegative().optional()
95
150
  });
96
- var DiscoveredViaSchema = z2.enum(["static", "otel", "merged"]);
97
- var ServiceNodeSchema = z2.object({
151
+ var GraphEdgeSchema = z2.object({
98
152
  id: z2.string(),
99
- type: z2.literal(NodeType.ServiceNode),
100
- name: z2.string(),
101
- language: z2.string(),
153
+ source: z2.string(),
154
+ target: z2.string(),
155
+ type: EdgeTypeSchema,
156
+ provenance: ProvenanceSchema,
157
+ confidence: z2.number().min(0).max(1).optional(),
158
+ lastObserved: z2.string().datetime().optional(),
159
+ callCount: z2.number().int().nonnegative().optional(),
160
+ evidence: EdgeEvidenceSchema.optional(),
161
+ signal: EdgeSignalSchema.optional(),
162
+ // OBSERVED grain (ADR-142): `file` when the edge originates from a source
163
+ // file's call site (a `file:` source + `evidence`), `service` for the coarse
164
+ // fallback where no call site was captured. Makes "service-grained only as a
165
+ // labeled fallback" (connector gate #803) a stored, machine-readable fact
166
+ // instead of a re-derivation from the source prefix. `.optional()` — EXTRACTED
167
+ // edges and legacy snapshots carry none; an OBSERVED edge is backfilled on its
168
+ // next observation.
169
+ grain: z2.enum(["file", "service"]).optional()
170
+ });
171
+
172
+ // src/nodes.ts
173
+ var CompatibleDriverSchema = z3.object({
174
+ name: z3.string(),
175
+ minVersion: z3.string()
176
+ });
177
+ var DiscoveredViaSchema = z3.enum(["static", "otel", "merged"]);
178
+ var ServiceNodeSchema = z3.object({
179
+ id: z3.string(),
180
+ type: z3.literal(NodeType.ServiceNode),
181
+ name: z3.string(),
182
+ language: z3.string(),
102
183
  // Deployment environment from the OTel `deployment.environment.name` attr
103
184
  // (with `deployment.environment` and resource-attr fallbacks). The literal
104
185
  // `'unknown'` is the honest sentinel when no env signal is present; static
105
186
  // extraction never sees env at extract time, so its ServiceNodes carry
106
187
  // `undefined` here and the id stays in the env-less wire format
107
188
  // `service:<name>`. See ADR-074 §2 and docs/contracts/env-dimension.md.
108
- env: z2.string().optional(),
189
+ env: z3.string().optional(),
109
190
  // Framework recorded by the static extractor when the install plan
110
191
  // dispatches a framework-specific path (Next.js, Remix, SvelteKit, Nuxt,
111
192
  // Astro). Optional enrichment — `undefined` for lib-only packages and
112
193
  // ambiguous repos. See ADR-074 §3 / docs/contracts/framework-installers.md.
113
- framework: z2.string().optional(),
194
+ framework: z3.string().optional(),
114
195
  // The hosting platform a static extractor recognized this service as
115
196
  // deployed to (`'cloudflare'` today) — a free string, same discipline as
116
197
  // `framework`, so a future platform needs no schema change. This is the
117
198
  // frontend's icon key at the service-rollup level (ADR-133,
118
199
  // docs/contracts/static-extraction.md).
119
- platform: z2.string().optional(),
200
+ platform: z3.string().optional(),
120
201
  discoveredVia: DiscoveredViaSchema.optional(),
121
- version: z2.string().optional(),
122
- dbConnectionTarget: z2.string().optional(),
123
- repoPath: z2.string().optional(),
124
- owner: z2.string().optional(),
125
- dependencies: z2.record(z2.string(), z2.string()).optional(),
202
+ version: z3.string().optional(),
203
+ dbConnectionTarget: z3.string().optional(),
204
+ repoPath: z3.string().optional(),
205
+ owner: z3.string().optional(),
206
+ dependencies: z3.record(z3.string(), z3.string()).optional(),
126
207
  // Hostnames OTel spans might mention for this service: compose service
127
208
  // names, k8s metadata.name (and the cluster-DNS variants), Dockerfile
128
209
  // labels, etc. resolveServiceId in ingest.ts checks these before falling
129
210
  // back to a FRONTIER placeholder.
130
- aliases: z2.array(z2.string()).optional(),
211
+ aliases: z3.array(z3.string()).optional(),
131
212
  // Optional. If set, services declare their `engines.node` here so γ #74's
132
213
  // node-engine compat check has something to test against.
133
- nodeEngine: z2.string().optional(),
134
- incompatibilities: z2.array(
214
+ nodeEngine: z3.string().optional(),
215
+ incompatibilities: z3.array(
135
216
  // Discriminated by `kind`. `driver-engine` is the original shape and
136
217
  // stays default for backward compatibility — older snapshots without a
137
218
  // `kind` field still parse via the union's `.optional()` discriminator
138
219
  // fallback. New kinds came in with γ #74.
139
- z2.union([
140
- z2.object({
141
- kind: z2.literal("driver-engine").optional(),
142
- driver: z2.string(),
143
- driverVersion: z2.string(),
144
- engine: z2.string(),
145
- engineVersion: z2.string(),
146
- reason: z2.string()
220
+ z3.union([
221
+ z3.object({
222
+ kind: z3.literal("driver-engine").optional(),
223
+ driver: z3.string(),
224
+ driverVersion: z3.string(),
225
+ engine: z3.string(),
226
+ engineVersion: z3.string(),
227
+ reason: z3.string()
147
228
  }),
148
- z2.object({
149
- kind: z2.literal("node-engine"),
150
- package: z2.string(),
151
- packageVersion: z2.string().optional(),
152
- requiredNodeVersion: z2.string(),
153
- declaredNodeEngine: z2.string().optional(),
154
- reason: z2.string()
229
+ z3.object({
230
+ kind: z3.literal("node-engine"),
231
+ package: z3.string(),
232
+ packageVersion: z3.string().optional(),
233
+ requiredNodeVersion: z3.string(),
234
+ declaredNodeEngine: z3.string().optional(),
235
+ reason: z3.string()
155
236
  }),
156
- z2.object({
157
- kind: z2.literal("package-conflict"),
158
- package: z2.string(),
159
- packageVersion: z2.string().optional(),
160
- requires: z2.object({
161
- name: z2.string(),
162
- minVersion: z2.string()
237
+ z3.object({
238
+ kind: z3.literal("package-conflict"),
239
+ package: z3.string(),
240
+ packageVersion: z3.string().optional(),
241
+ requires: z3.object({
242
+ name: z3.string(),
243
+ minVersion: z3.string()
163
244
  }),
164
- foundVersion: z2.string().optional(),
165
- reason: z2.string()
245
+ foundVersion: z3.string().optional(),
246
+ reason: z3.string()
166
247
  }),
167
- z2.object({
168
- kind: z2.literal("deprecated-api"),
169
- package: z2.string(),
170
- packageVersion: z2.string().optional(),
171
- reason: z2.string()
248
+ z3.object({
249
+ kind: z3.literal("deprecated-api"),
250
+ package: z3.string(),
251
+ packageVersion: z3.string().optional(),
252
+ reason: z3.string()
172
253
  })
173
254
  ])
174
255
  ).optional()
175
256
  });
176
- var DatabaseNodeSchema = z2.object({
177
- id: z2.string(),
178
- type: z2.literal(NodeType.DatabaseNode),
179
- name: z2.string(),
180
- engine: z2.string(),
181
- engineVersion: z2.string(),
182
- compatibleDrivers: z2.array(CompatibleDriverSchema),
183
- host: z2.string().optional(),
184
- port: z2.number().optional(),
257
+ var DatabaseNodeSchema = z3.object({
258
+ id: z3.string(),
259
+ type: z3.literal(NodeType.DatabaseNode),
260
+ name: z3.string(),
261
+ engine: z3.string(),
262
+ engineVersion: z3.string(),
263
+ compatibleDrivers: z3.array(CompatibleDriverSchema),
264
+ host: z3.string().optional(),
265
+ port: z3.number().optional(),
185
266
  discoveredVia: DiscoveredViaSchema.optional()
186
267
  });
187
- var ConfigNodeSchema = z2.object({
188
- id: z2.string(),
189
- type: z2.literal(NodeType.ConfigNode),
190
- name: z2.string(),
191
- path: z2.string(),
192
- fileType: z2.string()
268
+ var ConfigNodeSchema = z3.object({
269
+ id: z3.string(),
270
+ type: z3.literal(NodeType.ConfigNode),
271
+ name: z3.string(),
272
+ path: z3.string(),
273
+ fileType: z3.string()
193
274
  });
194
- var InfraNodeSchema = z2.object({
195
- id: z2.string(),
196
- type: z2.literal(NodeType.InfraNode),
197
- name: z2.string(),
198
- provider: z2.string(),
199
- region: z2.string().optional(),
200
- kind: z2.string().optional()
275
+ var ColumnAttrSchema = z3.object({
276
+ name: z3.string(),
277
+ provenances: z3.array(ProvenanceSchema),
278
+ confidence: z3.number().min(0).max(1)
201
279
  });
202
- var FrontierNodeSchema = z2.object({
203
- id: z2.string(),
204
- type: z2.literal(NodeType.FrontierNode),
205
- name: z2.string(),
206
- host: z2.string(),
207
- firstObserved: z2.string().datetime().optional(),
208
- lastObserved: z2.string().datetime().optional()
280
+ var InfraNodeSchema = z3.object({
281
+ id: z3.string(),
282
+ type: z3.literal(NodeType.InfraNode),
283
+ name: z3.string(),
284
+ provider: z3.string(),
285
+ region: z3.string().optional(),
286
+ kind: z3.string().optional(),
287
+ // Column-grain attributes on a table InfraNode (`sql-table`, `supabase-table`).
288
+ // Absent on a non-table InfraNode (a project node, a queue, a route). Optional
289
+ // schema growth (ADR-031); ADR-157 stamps the snapshot version because the field
290
+ // records a new grain the graph can now carry. See docs/contracts/schema.md.
291
+ columns: z3.array(ColumnAttrSchema).optional()
209
292
  });
210
- var FileNodeSchema = z2.object({
211
- id: z2.string(),
212
- type: z2.literal(NodeType.FileNode),
213
- service: z2.string(),
214
- path: z2.string(),
215
- language: z2.string().optional(),
293
+ var FrontierNodeSchema = z3.object({
294
+ id: z3.string(),
295
+ type: z3.literal(NodeType.FrontierNode),
296
+ name: z3.string(),
297
+ host: z3.string(),
298
+ firstObserved: z3.string().datetime().optional(),
299
+ lastObserved: z3.string().datetime().optional()
300
+ });
301
+ var FileNodeSchema = z3.object({
302
+ id: z3.string(),
303
+ type: z3.literal(NodeType.FileNode),
304
+ service: z3.string(),
305
+ path: z3.string(),
306
+ language: z3.string().optional(),
216
307
  discoveredVia: DiscoveredViaSchema.optional(),
217
308
  // The raw compiled `dist/...js` frame an OBSERVED call site was captured on,
218
309
  // preserved for diagnostic when ingest resolved it through a source map to
219
310
  // this original `src/...ts` (file-awareness.md §4 / `code.original_filepath`).
220
311
  // Absent when the call site was already source-grained.
221
- originalPath: z2.string().optional(),
312
+ originalPath: z3.string().optional(),
222
313
  // The hosting platform this file is the entry point for (`'cloudflare'`
223
314
  // today) — set on a Worker/Pages-Function's entry file only, mirroring
224
315
  // ServiceNode's own `platform` field. See `platformName` below.
225
- platform: z2.string().optional(),
316
+ platform: z3.string().optional(),
226
317
  // The platform's own name for this file's service, when the platform names
227
318
  // things differently than NEAT's manifest-derived serviceId (a Cloudflare
228
319
  // Worker's wrangler.toml/jsonc `name`, not `package.json#name`). This is the
@@ -230,52 +321,67 @@ var FileNodeSchema = z2.object({
230
321
  // connector's resolveTarget looks up against to fuse an OBSERVED signal onto
231
322
  // this exact FileNode (ADR-133, docs/contracts/static-extraction.md /
232
323
  // docs/contracts/connectors.md).
233
- platformName: z2.string().optional()
324
+ platformName: z3.string().optional()
234
325
  });
235
- var RouteNodeSchema = z2.object({
236
- id: z2.string(),
237
- type: z2.literal(NodeType.RouteNode),
238
- name: z2.string(),
239
- service: z2.string(),
240
- method: z2.string(),
241
- pathTemplate: z2.string(),
242
- path: z2.string(),
243
- line: z2.number().int().nonnegative().optional(),
244
- framework: z2.string().optional(),
326
+ var RouteNodeSchema = z3.object({
327
+ id: z3.string(),
328
+ type: z3.literal(NodeType.RouteNode),
329
+ name: z3.string(),
330
+ service: z3.string(),
331
+ method: z3.string(),
332
+ pathTemplate: z3.string(),
333
+ path: z3.string(),
334
+ line: z3.number().int().nonnegative().optional(),
335
+ framework: z3.string().optional(),
245
336
  discoveredVia: DiscoveredViaSchema.optional()
246
337
  });
247
- var GraphQLOperationNodeSchema = z2.object({
248
- id: z2.string(),
249
- type: z2.literal(NodeType.GraphQLOperationNode),
250
- name: z2.string(),
251
- service: z2.string(),
252
- operationType: z2.string(),
253
- operationName: z2.string(),
254
- path: z2.string().optional(),
255
- line: z2.number().int().nonnegative().optional(),
338
+ var GraphQLOperationNodeSchema = z3.object({
339
+ id: z3.string(),
340
+ type: z3.literal(NodeType.GraphQLOperationNode),
341
+ name: z3.string(),
342
+ service: z3.string(),
343
+ operationType: z3.string(),
344
+ operationName: z3.string(),
345
+ path: z3.string().optional(),
346
+ line: z3.number().int().nonnegative().optional(),
256
347
  discoveredVia: DiscoveredViaSchema.optional()
257
348
  });
258
- var GrpcMethodNodeSchema = z2.object({
259
- id: z2.string(),
260
- type: z2.literal(NodeType.GrpcMethodNode),
261
- name: z2.string(),
262
- rpcService: z2.string(),
263
- rpcMethod: z2.string(),
264
- path: z2.string().optional(),
265
- line: z2.number().int().nonnegative().optional(),
349
+ var GrpcMethodNodeSchema = z3.object({
350
+ id: z3.string(),
351
+ type: z3.literal(NodeType.GrpcMethodNode),
352
+ name: z3.string(),
353
+ rpcService: z3.string(),
354
+ rpcMethod: z3.string(),
355
+ path: z3.string().optional(),
356
+ line: z3.number().int().nonnegative().optional(),
266
357
  discoveredVia: DiscoveredViaSchema.optional()
267
358
  });
268
- var WebSocketChannelNodeSchema = z2.object({
269
- id: z2.string(),
270
- type: z2.literal(NodeType.WebSocketChannelNode),
271
- name: z2.string(),
272
- service: z2.string(),
273
- channel: z2.string(),
274
- path: z2.string().optional(),
275
- line: z2.number().int().nonnegative().optional(),
359
+ var WebSocketChannelNodeSchema = z3.object({
360
+ id: z3.string(),
361
+ type: z3.literal(NodeType.WebSocketChannelNode),
362
+ name: z3.string(),
363
+ service: z3.string(),
364
+ channel: z3.string(),
365
+ path: z3.string().optional(),
366
+ line: z3.number().int().nonnegative().optional(),
276
367
  discoveredVia: DiscoveredViaSchema.optional()
277
368
  });
278
- var GraphNodeSchema = z2.discriminatedUnion("type", [
369
+ var SymbolKindSchema = z3.enum(["function", "method", "constructor", "class"]);
370
+ var SymbolSpanSchema = z3.object({
371
+ startLine: z3.number().int().nonnegative(),
372
+ endLine: z3.number().int().nonnegative()
373
+ });
374
+ var SymbolNodeSchema = z3.object({
375
+ id: z3.string(),
376
+ type: z3.literal(NodeType.SymbolNode),
377
+ kind: SymbolKindSchema,
378
+ qualname: z3.string(),
379
+ span: SymbolSpanSchema,
380
+ service: z3.string(),
381
+ relPath: z3.string(),
382
+ discoveredVia: DiscoveredViaSchema.optional()
383
+ });
384
+ var GraphNodeSchema = z3.discriminatedUnion("type", [
279
385
  ServiceNodeSchema,
280
386
  DatabaseNodeSchema,
281
387
  ConfigNodeSchema,
@@ -285,65 +391,10 @@ var GraphNodeSchema = z2.discriminatedUnion("type", [
285
391
  RouteNodeSchema,
286
392
  GraphQLOperationNodeSchema,
287
393
  GrpcMethodNodeSchema,
288
- WebSocketChannelNodeSchema
394
+ WebSocketChannelNodeSchema,
395
+ SymbolNodeSchema
289
396
  ]);
290
397
 
291
- // src/edges.ts
292
- import { z as z3 } from "zod";
293
- var ProvenanceSchema = z3.enum([
294
- Provenance.EXTRACTED,
295
- Provenance.INFERRED,
296
- Provenance.OBSERVED,
297
- Provenance.STALE
298
- ]);
299
- var EdgeTypeSchema = z3.enum([
300
- EdgeType.CALLS,
301
- EdgeType.DEPENDS_ON,
302
- EdgeType.CONNECTS_TO,
303
- EdgeType.CONFIGURED_BY,
304
- EdgeType.PUBLISHES_TO,
305
- EdgeType.CONSUMES_FROM,
306
- EdgeType.RUNS_ON,
307
- EdgeType.CONTAINS,
308
- EdgeType.IMPORTS
309
- ]);
310
- var EdgeEvidenceSchema = z3.object({
311
- file: z3.string(),
312
- line: z3.number().int().nonnegative().optional(),
313
- snippet: z3.string().optional(),
314
- // HTTP shape of a recognised client call site (ADR-119). Present on a
315
- // client↔route CALLS edge so the edge records the method + path-template the
316
- // client named, alongside the file:line it named them at. Absent on every
317
- // other edge — a config or infra edge has no HTTP method.
318
- method: z3.string().optional(),
319
- pathTemplate: z3.string().optional()
320
- });
321
- var EdgeSignalSchema = z3.object({
322
- spanCount: z3.number().int().nonnegative(),
323
- errorCount: z3.number().int().nonnegative(),
324
- lastObservedAgeMs: z3.number().nonnegative().optional()
325
- });
326
- var GraphEdgeSchema = z3.object({
327
- id: z3.string(),
328
- source: z3.string(),
329
- target: z3.string(),
330
- type: EdgeTypeSchema,
331
- provenance: ProvenanceSchema,
332
- confidence: z3.number().min(0).max(1).optional(),
333
- lastObserved: z3.string().datetime().optional(),
334
- callCount: z3.number().int().nonnegative().optional(),
335
- evidence: EdgeEvidenceSchema.optional(),
336
- signal: EdgeSignalSchema.optional(),
337
- // OBSERVED grain (ADR-142): `file` when the edge originates from a source
338
- // file's call site (a `file:` source + `evidence`), `service` for the coarse
339
- // fallback where no call site was captured. Makes "service-grained only as a
340
- // labeled fallback" (connector gate #803) a stored, machine-readable fact
341
- // instead of a re-derivation from the source prefix. `.optional()` — EXTRACTED
342
- // edges and legacy snapshots carry none; an OBSERVED edge is backfilled on its
343
- // next observation.
344
- grain: z3.enum(["file", "service"]).optional()
345
- });
346
-
347
398
  // src/events.ts
348
399
  import { z as z4 } from "zod";
349
400
  var SpanAttributesSchema = z4.record(
@@ -493,6 +544,7 @@ var ROUTE_PREFIX = "route:";
493
544
  var GRAPHQL_OP_PREFIX = "graphql:";
494
545
  var GRPC_METHOD_PREFIX = "grpc:";
495
546
  var WEBSOCKET_CHANNEL_PREFIX = "ws:";
547
+ var SYMBOL_PREFIX = "symbol:";
496
548
  var ENV_UNKNOWN = "unknown";
497
549
  function serviceId(name, env) {
498
550
  if (env === void 0 || env === ENV_UNKNOWN) return `${SERVICE_PREFIX}${name}`;
@@ -612,6 +664,34 @@ function parseWebsocketChannelId(id) {
612
664
  if (service.length === 0 || channel.length === 0) return null;
613
665
  return { service, channel };
614
666
  }
667
+ function symbolId(service, relPath, qualname, disambiguator) {
668
+ const base = `${SYMBOL_PREFIX}${service}:${relPath}#${qualname}`;
669
+ return disambiguator === void 0 ? base : `${base}~${disambiguator}`;
670
+ }
671
+ function parseSymbolId(id) {
672
+ if (!id.startsWith(SYMBOL_PREFIX)) return null;
673
+ const rest = id.slice(SYMBOL_PREFIX.length);
674
+ const colon = rest.indexOf(":");
675
+ if (colon === -1) return null;
676
+ const service = rest.slice(0, colon);
677
+ const tail = rest.slice(colon + 1);
678
+ const hash = tail.lastIndexOf("#");
679
+ if (hash === -1) return null;
680
+ const relPath = tail.slice(0, hash);
681
+ let qualname = tail.slice(hash + 1);
682
+ if (service.length === 0 || relPath.length === 0 || qualname.length === 0) return null;
683
+ let disambiguator;
684
+ const tilde = qualname.lastIndexOf("~");
685
+ if (tilde !== -1) {
686
+ const suffix = qualname.slice(tilde + 1);
687
+ if (suffix.length > 0 && /^\d+$/.test(suffix)) {
688
+ disambiguator = Number(suffix);
689
+ qualname = qualname.slice(0, tilde);
690
+ }
691
+ }
692
+ if (qualname.length === 0) return null;
693
+ return { service, relPath, qualname, ...disambiguator !== void 0 ? { disambiguator } : {} };
694
+ }
615
695
  var EDGE_ARROW = "->";
616
696
  function extractedEdgeId(source, target, type) {
617
697
  return `${type}:${source}${EDGE_ARROW}${target}`;
@@ -834,14 +914,20 @@ var commonFields = {
834
914
  var MissingObservedDivergenceSchema = z8.object({
835
915
  type: z8.literal("missing-observed"),
836
916
  ...commonFields,
837
- edgeType: EdgeTypeSchema,
838
- extracted: GraphEdgeSchema
917
+ edgeType: EdgeTypeSchema.optional(),
918
+ extracted: GraphEdgeSchema.optional(),
919
+ // Column locus (ADR-157 §4): the `sql-table` node id and the declared-only column.
920
+ table: z8.string().optional(),
921
+ column: z8.string().optional()
839
922
  });
840
923
  var MissingExtractedDivergenceSchema = z8.object({
841
924
  type: z8.literal("missing-extracted"),
842
925
  ...commonFields,
843
- edgeType: EdgeTypeSchema,
844
- observed: GraphEdgeSchema
926
+ edgeType: EdgeTypeSchema.optional(),
927
+ observed: GraphEdgeSchema.optional(),
928
+ // Column locus (ADR-157 §4): the `sql-table` node id and the observed-only column.
929
+ table: z8.string().optional(),
930
+ column: z8.string().optional()
845
931
  });
846
932
  var CompatibilityVerdictSchema = z8.enum(["incompatible", "deprecated", "unknown"]);
847
933
  var VersionMismatchDivergenceSchema = z8.object({
@@ -1094,6 +1180,7 @@ export {
1094
1180
  BlastRadiusResultSchema,
1095
1181
  BlastRadiusRuleSchema,
1096
1182
  CheckPoliciesScopeSchema,
1183
+ ColumnAttrSchema,
1097
1184
  CompatRuleRefSchema,
1098
1185
  CompatViolationDivergenceSchema,
1099
1186
  CompatibilityRuleSchema,
@@ -1174,6 +1261,9 @@ export {
1174
1261
  StaleEventSchema,
1175
1262
  StaleEventsResponseSchema,
1176
1263
  StructuralRuleSchema,
1264
+ SymbolKindSchema,
1265
+ SymbolNodeSchema,
1266
+ SymbolSpanSchema,
1177
1267
  TransitiveDependenciesResultSchema,
1178
1268
  TransitiveDependencySchema,
1179
1269
  VersionMismatchDivergenceSchema,
@@ -1202,10 +1292,12 @@ export {
1202
1292
  parseInfraId,
1203
1293
  parseRouteId,
1204
1294
  parseServiceId,
1295
+ parseSymbolId,
1205
1296
  parseWebsocketChannelId,
1206
1297
  passesExtractedFloor,
1207
1298
  routeId,
1208
1299
  serviceId,
1300
+ symbolId,
1209
1301
  websocketChannelId
1210
1302
  };
1211
1303
  //# sourceMappingURL=index.js.map