@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.cjs CHANGED
@@ -26,6 +26,7 @@ __export(index_exports, {
26
26
  BlastRadiusResultSchema: () => BlastRadiusResultSchema,
27
27
  BlastRadiusRuleSchema: () => BlastRadiusRuleSchema,
28
28
  CheckPoliciesScopeSchema: () => CheckPoliciesScopeSchema,
29
+ ColumnAttrSchema: () => ColumnAttrSchema,
29
30
  CompatRuleRefSchema: () => CompatRuleRefSchema,
30
31
  CompatViolationDivergenceSchema: () => CompatViolationDivergenceSchema,
31
32
  CompatibilityRuleSchema: () => CompatibilityRuleSchema,
@@ -106,6 +107,9 @@ __export(index_exports, {
106
107
  StaleEventSchema: () => StaleEventSchema,
107
108
  StaleEventsResponseSchema: () => StaleEventsResponseSchema,
108
109
  StructuralRuleSchema: () => StructuralRuleSchema,
110
+ SymbolKindSchema: () => SymbolKindSchema,
111
+ SymbolNodeSchema: () => SymbolNodeSchema,
112
+ SymbolSpanSchema: () => SymbolSpanSchema,
109
113
  TransitiveDependenciesResultSchema: () => TransitiveDependenciesResultSchema,
110
114
  TransitiveDependencySchema: () => TransitiveDependencySchema,
111
115
  VersionMismatchDivergenceSchema: () => VersionMismatchDivergenceSchema,
@@ -134,10 +138,12 @@ __export(index_exports, {
134
138
  parseInfraId: () => parseInfraId,
135
139
  parseRouteId: () => parseRouteId,
136
140
  parseServiceId: () => parseServiceId,
141
+ parseSymbolId: () => parseSymbolId,
137
142
  parseWebsocketChannelId: () => parseWebsocketChannelId,
138
143
  passesExtractedFloor: () => passesExtractedFloor,
139
144
  routeId: () => routeId,
140
145
  serviceId: () => serviceId,
146
+ symbolId: () => symbolId,
141
147
  websocketChannelId: () => websocketChannelId
142
148
  });
143
149
  module.exports = __toCommonJS(index_exports);
@@ -166,7 +172,16 @@ var EdgeType = {
166
172
  // Static module dependency between two FileNodes within a service (ADR-092,
167
173
  // file-awareness.md §10). Compile-time, not runtime — represents one file
168
174
  // importing another. Distinct from CALLS which records runtime invocations.
169
- IMPORTS: "IMPORTS"
175
+ IMPORTS: "IMPORTS",
176
+ // Static heritage between two SymbolNodes (ADR-158 §3). `INHERITS` records a
177
+ // class's `extends` clause (`class ──INHERITS──▶ superclass`); `IMPLEMENTS`
178
+ // records an `implements` clause (`class ──IMPLEMENTS──▶ implemented`). Both
179
+ // are symbol→symbol, EXTRACTED, minted only when the parent name resolves to
180
+ // exactly one known SymbolNode — same-file or through the import graph — never
181
+ // fuzzy-matched. A parent that resolves to nothing (external package,
182
+ // re-export chain, an interface, which is not a SymbolNode) emits no edge.
183
+ INHERITS: "INHERITS",
184
+ IMPLEMENTS: "IMPLEMENTS"
170
185
  };
171
186
  var NodeType = {
172
187
  ServiceNode: "ServiceNode",
@@ -216,7 +231,18 @@ var NodeType = {
216
231
  // edge that carries `lastObserved` and decays OBSERVED → STALE on CONNECTS_TO's
217
232
  // own staleness threshold when the channel goes quiet. See
218
233
  // docs/contracts/otel-ingest.md.
219
- WebSocketChannelNode: "WebSocketChannelNode"
234
+ WebSocketChannelNode: "WebSocketChannelNode",
235
+ // A symbol under a file — a function, method, constructor, or class
236
+ // definition — at definition-span granularity (ADR-158). Static-first: the
237
+ // extractor mints one per definition and the file owns it through a
238
+ // `file ──CONTAINS──▶ symbol` edge, one containment level below
239
+ // `service ──CONTAINS──▶ file`. It carries its `{ startLine, endLine }`
240
+ // definition span, which is the fusion key ingest joins a span's `code.line`
241
+ // against to land an OBSERVED edge on the calling symbol rather than only its
242
+ // file (observed-first edges, one grain finer than §4 file grain). The node is
243
+ // language-neutral; the per-language tree-sitter extractor is the adapter. See
244
+ // docs/contracts/static-extraction.md and docs/contracts/file-awareness.md §1.
245
+ SymbolNode: "SymbolNode"
220
246
  };
221
247
  var NodeTypeSchema = import_zod.z.enum([
222
248
  NodeType.ServiceNode,
@@ -228,145 +254,216 @@ var NodeTypeSchema = import_zod.z.enum([
228
254
  NodeType.RouteNode,
229
255
  NodeType.GraphQLOperationNode,
230
256
  NodeType.GrpcMethodNode,
231
- NodeType.WebSocketChannelNode
257
+ NodeType.WebSocketChannelNode,
258
+ NodeType.SymbolNode
232
259
  ]);
233
260
 
234
261
  // src/nodes.ts
262
+ var import_zod3 = require("zod");
263
+
264
+ // src/edges.ts
235
265
  var import_zod2 = require("zod");
236
- var CompatibleDriverSchema = import_zod2.z.object({
237
- name: import_zod2.z.string(),
238
- minVersion: import_zod2.z.string()
266
+ var ProvenanceSchema = import_zod2.z.enum([
267
+ Provenance.EXTRACTED,
268
+ Provenance.INFERRED,
269
+ Provenance.OBSERVED,
270
+ Provenance.STALE
271
+ ]);
272
+ var EdgeTypeSchema = import_zod2.z.enum([
273
+ EdgeType.CALLS,
274
+ EdgeType.DEPENDS_ON,
275
+ EdgeType.CONNECTS_TO,
276
+ EdgeType.CONFIGURED_BY,
277
+ EdgeType.PUBLISHES_TO,
278
+ EdgeType.CONSUMES_FROM,
279
+ EdgeType.RUNS_ON,
280
+ EdgeType.CONTAINS,
281
+ EdgeType.IMPORTS,
282
+ EdgeType.INHERITS,
283
+ EdgeType.IMPLEMENTS
284
+ ]);
285
+ var EdgeEvidenceSchema = import_zod2.z.object({
286
+ file: import_zod2.z.string(),
287
+ line: import_zod2.z.number().int().nonnegative().optional(),
288
+ snippet: import_zod2.z.string().optional(),
289
+ // HTTP shape of a recognised client call site (ADR-119). Present on a
290
+ // client↔route CALLS edge so the edge records the method + path-template the
291
+ // client named, alongside the file:line it named them at. Absent on every
292
+ // other edge — a config or infra edge has no HTTP method.
293
+ method: import_zod2.z.string().optional(),
294
+ pathTemplate: import_zod2.z.string().optional()
295
+ });
296
+ var EdgeSignalSchema = import_zod2.z.object({
297
+ spanCount: import_zod2.z.number().int().nonnegative(),
298
+ errorCount: import_zod2.z.number().int().nonnegative(),
299
+ lastObservedAgeMs: import_zod2.z.number().nonnegative().optional()
239
300
  });
240
- var DiscoveredViaSchema = import_zod2.z.enum(["static", "otel", "merged"]);
241
- var ServiceNodeSchema = import_zod2.z.object({
301
+ var GraphEdgeSchema = import_zod2.z.object({
242
302
  id: import_zod2.z.string(),
243
- type: import_zod2.z.literal(NodeType.ServiceNode),
244
- name: import_zod2.z.string(),
245
- language: import_zod2.z.string(),
303
+ source: import_zod2.z.string(),
304
+ target: import_zod2.z.string(),
305
+ type: EdgeTypeSchema,
306
+ provenance: ProvenanceSchema,
307
+ confidence: import_zod2.z.number().min(0).max(1).optional(),
308
+ lastObserved: import_zod2.z.string().datetime().optional(),
309
+ callCount: import_zod2.z.number().int().nonnegative().optional(),
310
+ evidence: EdgeEvidenceSchema.optional(),
311
+ signal: EdgeSignalSchema.optional(),
312
+ // OBSERVED grain (ADR-142): `file` when the edge originates from a source
313
+ // file's call site (a `file:` source + `evidence`), `service` for the coarse
314
+ // fallback where no call site was captured. Makes "service-grained only as a
315
+ // labeled fallback" (connector gate #803) a stored, machine-readable fact
316
+ // instead of a re-derivation from the source prefix. `.optional()` — EXTRACTED
317
+ // edges and legacy snapshots carry none; an OBSERVED edge is backfilled on its
318
+ // next observation.
319
+ grain: import_zod2.z.enum(["file", "service"]).optional()
320
+ });
321
+
322
+ // src/nodes.ts
323
+ var CompatibleDriverSchema = import_zod3.z.object({
324
+ name: import_zod3.z.string(),
325
+ minVersion: import_zod3.z.string()
326
+ });
327
+ var DiscoveredViaSchema = import_zod3.z.enum(["static", "otel", "merged"]);
328
+ var ServiceNodeSchema = import_zod3.z.object({
329
+ id: import_zod3.z.string(),
330
+ type: import_zod3.z.literal(NodeType.ServiceNode),
331
+ name: import_zod3.z.string(),
332
+ language: import_zod3.z.string(),
246
333
  // Deployment environment from the OTel `deployment.environment.name` attr
247
334
  // (with `deployment.environment` and resource-attr fallbacks). The literal
248
335
  // `'unknown'` is the honest sentinel when no env signal is present; static
249
336
  // extraction never sees env at extract time, so its ServiceNodes carry
250
337
  // `undefined` here and the id stays in the env-less wire format
251
338
  // `service:<name>`. See ADR-074 §2 and docs/contracts/env-dimension.md.
252
- env: import_zod2.z.string().optional(),
339
+ env: import_zod3.z.string().optional(),
253
340
  // Framework recorded by the static extractor when the install plan
254
341
  // dispatches a framework-specific path (Next.js, Remix, SvelteKit, Nuxt,
255
342
  // Astro). Optional enrichment — `undefined` for lib-only packages and
256
343
  // ambiguous repos. See ADR-074 §3 / docs/contracts/framework-installers.md.
257
- framework: import_zod2.z.string().optional(),
344
+ framework: import_zod3.z.string().optional(),
258
345
  // The hosting platform a static extractor recognized this service as
259
346
  // deployed to (`'cloudflare'` today) — a free string, same discipline as
260
347
  // `framework`, so a future platform needs no schema change. This is the
261
348
  // frontend's icon key at the service-rollup level (ADR-133,
262
349
  // docs/contracts/static-extraction.md).
263
- platform: import_zod2.z.string().optional(),
350
+ platform: import_zod3.z.string().optional(),
264
351
  discoveredVia: DiscoveredViaSchema.optional(),
265
- version: import_zod2.z.string().optional(),
266
- dbConnectionTarget: import_zod2.z.string().optional(),
267
- repoPath: import_zod2.z.string().optional(),
268
- owner: import_zod2.z.string().optional(),
269
- dependencies: import_zod2.z.record(import_zod2.z.string(), import_zod2.z.string()).optional(),
352
+ version: import_zod3.z.string().optional(),
353
+ dbConnectionTarget: import_zod3.z.string().optional(),
354
+ repoPath: import_zod3.z.string().optional(),
355
+ owner: import_zod3.z.string().optional(),
356
+ dependencies: import_zod3.z.record(import_zod3.z.string(), import_zod3.z.string()).optional(),
270
357
  // Hostnames OTel spans might mention for this service: compose service
271
358
  // names, k8s metadata.name (and the cluster-DNS variants), Dockerfile
272
359
  // labels, etc. resolveServiceId in ingest.ts checks these before falling
273
360
  // back to a FRONTIER placeholder.
274
- aliases: import_zod2.z.array(import_zod2.z.string()).optional(),
361
+ aliases: import_zod3.z.array(import_zod3.z.string()).optional(),
275
362
  // Optional. If set, services declare their `engines.node` here so γ #74's
276
363
  // node-engine compat check has something to test against.
277
- nodeEngine: import_zod2.z.string().optional(),
278
- incompatibilities: import_zod2.z.array(
364
+ nodeEngine: import_zod3.z.string().optional(),
365
+ incompatibilities: import_zod3.z.array(
279
366
  // Discriminated by `kind`. `driver-engine` is the original shape and
280
367
  // stays default for backward compatibility — older snapshots without a
281
368
  // `kind` field still parse via the union's `.optional()` discriminator
282
369
  // fallback. New kinds came in with γ #74.
283
- import_zod2.z.union([
284
- import_zod2.z.object({
285
- kind: import_zod2.z.literal("driver-engine").optional(),
286
- driver: import_zod2.z.string(),
287
- driverVersion: import_zod2.z.string(),
288
- engine: import_zod2.z.string(),
289
- engineVersion: import_zod2.z.string(),
290
- reason: import_zod2.z.string()
370
+ import_zod3.z.union([
371
+ import_zod3.z.object({
372
+ kind: import_zod3.z.literal("driver-engine").optional(),
373
+ driver: import_zod3.z.string(),
374
+ driverVersion: import_zod3.z.string(),
375
+ engine: import_zod3.z.string(),
376
+ engineVersion: import_zod3.z.string(),
377
+ reason: import_zod3.z.string()
291
378
  }),
292
- import_zod2.z.object({
293
- kind: import_zod2.z.literal("node-engine"),
294
- package: import_zod2.z.string(),
295
- packageVersion: import_zod2.z.string().optional(),
296
- requiredNodeVersion: import_zod2.z.string(),
297
- declaredNodeEngine: import_zod2.z.string().optional(),
298
- reason: import_zod2.z.string()
379
+ import_zod3.z.object({
380
+ kind: import_zod3.z.literal("node-engine"),
381
+ package: import_zod3.z.string(),
382
+ packageVersion: import_zod3.z.string().optional(),
383
+ requiredNodeVersion: import_zod3.z.string(),
384
+ declaredNodeEngine: import_zod3.z.string().optional(),
385
+ reason: import_zod3.z.string()
299
386
  }),
300
- import_zod2.z.object({
301
- kind: import_zod2.z.literal("package-conflict"),
302
- package: import_zod2.z.string(),
303
- packageVersion: import_zod2.z.string().optional(),
304
- requires: import_zod2.z.object({
305
- name: import_zod2.z.string(),
306
- minVersion: import_zod2.z.string()
387
+ import_zod3.z.object({
388
+ kind: import_zod3.z.literal("package-conflict"),
389
+ package: import_zod3.z.string(),
390
+ packageVersion: import_zod3.z.string().optional(),
391
+ requires: import_zod3.z.object({
392
+ name: import_zod3.z.string(),
393
+ minVersion: import_zod3.z.string()
307
394
  }),
308
- foundVersion: import_zod2.z.string().optional(),
309
- reason: import_zod2.z.string()
395
+ foundVersion: import_zod3.z.string().optional(),
396
+ reason: import_zod3.z.string()
310
397
  }),
311
- import_zod2.z.object({
312
- kind: import_zod2.z.literal("deprecated-api"),
313
- package: import_zod2.z.string(),
314
- packageVersion: import_zod2.z.string().optional(),
315
- reason: import_zod2.z.string()
398
+ import_zod3.z.object({
399
+ kind: import_zod3.z.literal("deprecated-api"),
400
+ package: import_zod3.z.string(),
401
+ packageVersion: import_zod3.z.string().optional(),
402
+ reason: import_zod3.z.string()
316
403
  })
317
404
  ])
318
405
  ).optional()
319
406
  });
320
- var DatabaseNodeSchema = import_zod2.z.object({
321
- id: import_zod2.z.string(),
322
- type: import_zod2.z.literal(NodeType.DatabaseNode),
323
- name: import_zod2.z.string(),
324
- engine: import_zod2.z.string(),
325
- engineVersion: import_zod2.z.string(),
326
- compatibleDrivers: import_zod2.z.array(CompatibleDriverSchema),
327
- host: import_zod2.z.string().optional(),
328
- port: import_zod2.z.number().optional(),
407
+ var DatabaseNodeSchema = import_zod3.z.object({
408
+ id: import_zod3.z.string(),
409
+ type: import_zod3.z.literal(NodeType.DatabaseNode),
410
+ name: import_zod3.z.string(),
411
+ engine: import_zod3.z.string(),
412
+ engineVersion: import_zod3.z.string(),
413
+ compatibleDrivers: import_zod3.z.array(CompatibleDriverSchema),
414
+ host: import_zod3.z.string().optional(),
415
+ port: import_zod3.z.number().optional(),
329
416
  discoveredVia: DiscoveredViaSchema.optional()
330
417
  });
331
- var ConfigNodeSchema = import_zod2.z.object({
332
- id: import_zod2.z.string(),
333
- type: import_zod2.z.literal(NodeType.ConfigNode),
334
- name: import_zod2.z.string(),
335
- path: import_zod2.z.string(),
336
- fileType: import_zod2.z.string()
418
+ var ConfigNodeSchema = import_zod3.z.object({
419
+ id: import_zod3.z.string(),
420
+ type: import_zod3.z.literal(NodeType.ConfigNode),
421
+ name: import_zod3.z.string(),
422
+ path: import_zod3.z.string(),
423
+ fileType: import_zod3.z.string()
337
424
  });
338
- var InfraNodeSchema = import_zod2.z.object({
339
- id: import_zod2.z.string(),
340
- type: import_zod2.z.literal(NodeType.InfraNode),
341
- name: import_zod2.z.string(),
342
- provider: import_zod2.z.string(),
343
- region: import_zod2.z.string().optional(),
344
- kind: import_zod2.z.string().optional()
425
+ var ColumnAttrSchema = import_zod3.z.object({
426
+ name: import_zod3.z.string(),
427
+ provenances: import_zod3.z.array(ProvenanceSchema),
428
+ confidence: import_zod3.z.number().min(0).max(1)
345
429
  });
346
- var FrontierNodeSchema = import_zod2.z.object({
347
- id: import_zod2.z.string(),
348
- type: import_zod2.z.literal(NodeType.FrontierNode),
349
- name: import_zod2.z.string(),
350
- host: import_zod2.z.string(),
351
- firstObserved: import_zod2.z.string().datetime().optional(),
352
- lastObserved: import_zod2.z.string().datetime().optional()
430
+ var InfraNodeSchema = import_zod3.z.object({
431
+ id: import_zod3.z.string(),
432
+ type: import_zod3.z.literal(NodeType.InfraNode),
433
+ name: import_zod3.z.string(),
434
+ provider: import_zod3.z.string(),
435
+ region: import_zod3.z.string().optional(),
436
+ kind: import_zod3.z.string().optional(),
437
+ // Column-grain attributes on a table InfraNode (`sql-table`, `supabase-table`).
438
+ // Absent on a non-table InfraNode (a project node, a queue, a route). Optional
439
+ // schema growth (ADR-031); ADR-157 stamps the snapshot version because the field
440
+ // records a new grain the graph can now carry. See docs/contracts/schema.md.
441
+ columns: import_zod3.z.array(ColumnAttrSchema).optional()
353
442
  });
354
- var FileNodeSchema = import_zod2.z.object({
355
- id: import_zod2.z.string(),
356
- type: import_zod2.z.literal(NodeType.FileNode),
357
- service: import_zod2.z.string(),
358
- path: import_zod2.z.string(),
359
- language: import_zod2.z.string().optional(),
443
+ var FrontierNodeSchema = import_zod3.z.object({
444
+ id: import_zod3.z.string(),
445
+ type: import_zod3.z.literal(NodeType.FrontierNode),
446
+ name: import_zod3.z.string(),
447
+ host: import_zod3.z.string(),
448
+ firstObserved: import_zod3.z.string().datetime().optional(),
449
+ lastObserved: import_zod3.z.string().datetime().optional()
450
+ });
451
+ var FileNodeSchema = import_zod3.z.object({
452
+ id: import_zod3.z.string(),
453
+ type: import_zod3.z.literal(NodeType.FileNode),
454
+ service: import_zod3.z.string(),
455
+ path: import_zod3.z.string(),
456
+ language: import_zod3.z.string().optional(),
360
457
  discoveredVia: DiscoveredViaSchema.optional(),
361
458
  // The raw compiled `dist/...js` frame an OBSERVED call site was captured on,
362
459
  // preserved for diagnostic when ingest resolved it through a source map to
363
460
  // this original `src/...ts` (file-awareness.md §4 / `code.original_filepath`).
364
461
  // Absent when the call site was already source-grained.
365
- originalPath: import_zod2.z.string().optional(),
462
+ originalPath: import_zod3.z.string().optional(),
366
463
  // The hosting platform this file is the entry point for (`'cloudflare'`
367
464
  // today) — set on a Worker/Pages-Function's entry file only, mirroring
368
465
  // ServiceNode's own `platform` field. See `platformName` below.
369
- platform: import_zod2.z.string().optional(),
466
+ platform: import_zod3.z.string().optional(),
370
467
  // The platform's own name for this file's service, when the platform names
371
468
  // things differently than NEAT's manifest-derived serviceId (a Cloudflare
372
469
  // Worker's wrangler.toml/jsonc `name`, not `package.json#name`). This is the
@@ -374,52 +471,67 @@ var FileNodeSchema = import_zod2.z.object({
374
471
  // connector's resolveTarget looks up against to fuse an OBSERVED signal onto
375
472
  // this exact FileNode (ADR-133, docs/contracts/static-extraction.md /
376
473
  // docs/contracts/connectors.md).
377
- platformName: import_zod2.z.string().optional()
474
+ platformName: import_zod3.z.string().optional()
378
475
  });
379
- var RouteNodeSchema = import_zod2.z.object({
380
- id: import_zod2.z.string(),
381
- type: import_zod2.z.literal(NodeType.RouteNode),
382
- name: import_zod2.z.string(),
383
- service: import_zod2.z.string(),
384
- method: import_zod2.z.string(),
385
- pathTemplate: import_zod2.z.string(),
386
- path: import_zod2.z.string(),
387
- line: import_zod2.z.number().int().nonnegative().optional(),
388
- framework: import_zod2.z.string().optional(),
476
+ var RouteNodeSchema = import_zod3.z.object({
477
+ id: import_zod3.z.string(),
478
+ type: import_zod3.z.literal(NodeType.RouteNode),
479
+ name: import_zod3.z.string(),
480
+ service: import_zod3.z.string(),
481
+ method: import_zod3.z.string(),
482
+ pathTemplate: import_zod3.z.string(),
483
+ path: import_zod3.z.string(),
484
+ line: import_zod3.z.number().int().nonnegative().optional(),
485
+ framework: import_zod3.z.string().optional(),
389
486
  discoveredVia: DiscoveredViaSchema.optional()
390
487
  });
391
- var GraphQLOperationNodeSchema = import_zod2.z.object({
392
- id: import_zod2.z.string(),
393
- type: import_zod2.z.literal(NodeType.GraphQLOperationNode),
394
- name: import_zod2.z.string(),
395
- service: import_zod2.z.string(),
396
- operationType: import_zod2.z.string(),
397
- operationName: import_zod2.z.string(),
398
- path: import_zod2.z.string().optional(),
399
- line: import_zod2.z.number().int().nonnegative().optional(),
488
+ var GraphQLOperationNodeSchema = import_zod3.z.object({
489
+ id: import_zod3.z.string(),
490
+ type: import_zod3.z.literal(NodeType.GraphQLOperationNode),
491
+ name: import_zod3.z.string(),
492
+ service: import_zod3.z.string(),
493
+ operationType: import_zod3.z.string(),
494
+ operationName: import_zod3.z.string(),
495
+ path: import_zod3.z.string().optional(),
496
+ line: import_zod3.z.number().int().nonnegative().optional(),
400
497
  discoveredVia: DiscoveredViaSchema.optional()
401
498
  });
402
- var GrpcMethodNodeSchema = import_zod2.z.object({
403
- id: import_zod2.z.string(),
404
- type: import_zod2.z.literal(NodeType.GrpcMethodNode),
405
- name: import_zod2.z.string(),
406
- rpcService: import_zod2.z.string(),
407
- rpcMethod: import_zod2.z.string(),
408
- path: import_zod2.z.string().optional(),
409
- line: import_zod2.z.number().int().nonnegative().optional(),
499
+ var GrpcMethodNodeSchema = import_zod3.z.object({
500
+ id: import_zod3.z.string(),
501
+ type: import_zod3.z.literal(NodeType.GrpcMethodNode),
502
+ name: import_zod3.z.string(),
503
+ rpcService: import_zod3.z.string(),
504
+ rpcMethod: import_zod3.z.string(),
505
+ path: import_zod3.z.string().optional(),
506
+ line: import_zod3.z.number().int().nonnegative().optional(),
410
507
  discoveredVia: DiscoveredViaSchema.optional()
411
508
  });
412
- var WebSocketChannelNodeSchema = import_zod2.z.object({
413
- id: import_zod2.z.string(),
414
- type: import_zod2.z.literal(NodeType.WebSocketChannelNode),
415
- name: import_zod2.z.string(),
416
- service: import_zod2.z.string(),
417
- channel: import_zod2.z.string(),
418
- path: import_zod2.z.string().optional(),
419
- line: import_zod2.z.number().int().nonnegative().optional(),
509
+ var WebSocketChannelNodeSchema = import_zod3.z.object({
510
+ id: import_zod3.z.string(),
511
+ type: import_zod3.z.literal(NodeType.WebSocketChannelNode),
512
+ name: import_zod3.z.string(),
513
+ service: import_zod3.z.string(),
514
+ channel: import_zod3.z.string(),
515
+ path: import_zod3.z.string().optional(),
516
+ line: import_zod3.z.number().int().nonnegative().optional(),
420
517
  discoveredVia: DiscoveredViaSchema.optional()
421
518
  });
422
- var GraphNodeSchema = import_zod2.z.discriminatedUnion("type", [
519
+ var SymbolKindSchema = import_zod3.z.enum(["function", "method", "constructor", "class"]);
520
+ var SymbolSpanSchema = import_zod3.z.object({
521
+ startLine: import_zod3.z.number().int().nonnegative(),
522
+ endLine: import_zod3.z.number().int().nonnegative()
523
+ });
524
+ var SymbolNodeSchema = import_zod3.z.object({
525
+ id: import_zod3.z.string(),
526
+ type: import_zod3.z.literal(NodeType.SymbolNode),
527
+ kind: SymbolKindSchema,
528
+ qualname: import_zod3.z.string(),
529
+ span: SymbolSpanSchema,
530
+ service: import_zod3.z.string(),
531
+ relPath: import_zod3.z.string(),
532
+ discoveredVia: DiscoveredViaSchema.optional()
533
+ });
534
+ var GraphNodeSchema = import_zod3.z.discriminatedUnion("type", [
423
535
  ServiceNodeSchema,
424
536
  DatabaseNodeSchema,
425
537
  ConfigNodeSchema,
@@ -429,65 +541,10 @@ var GraphNodeSchema = import_zod2.z.discriminatedUnion("type", [
429
541
  RouteNodeSchema,
430
542
  GraphQLOperationNodeSchema,
431
543
  GrpcMethodNodeSchema,
432
- WebSocketChannelNodeSchema
544
+ WebSocketChannelNodeSchema,
545
+ SymbolNodeSchema
433
546
  ]);
434
547
 
435
- // src/edges.ts
436
- var import_zod3 = require("zod");
437
- var ProvenanceSchema = import_zod3.z.enum([
438
- Provenance.EXTRACTED,
439
- Provenance.INFERRED,
440
- Provenance.OBSERVED,
441
- Provenance.STALE
442
- ]);
443
- var EdgeTypeSchema = import_zod3.z.enum([
444
- EdgeType.CALLS,
445
- EdgeType.DEPENDS_ON,
446
- EdgeType.CONNECTS_TO,
447
- EdgeType.CONFIGURED_BY,
448
- EdgeType.PUBLISHES_TO,
449
- EdgeType.CONSUMES_FROM,
450
- EdgeType.RUNS_ON,
451
- EdgeType.CONTAINS,
452
- EdgeType.IMPORTS
453
- ]);
454
- var EdgeEvidenceSchema = import_zod3.z.object({
455
- file: import_zod3.z.string(),
456
- line: import_zod3.z.number().int().nonnegative().optional(),
457
- snippet: import_zod3.z.string().optional(),
458
- // HTTP shape of a recognised client call site (ADR-119). Present on a
459
- // client↔route CALLS edge so the edge records the method + path-template the
460
- // client named, alongside the file:line it named them at. Absent on every
461
- // other edge — a config or infra edge has no HTTP method.
462
- method: import_zod3.z.string().optional(),
463
- pathTemplate: import_zod3.z.string().optional()
464
- });
465
- var EdgeSignalSchema = import_zod3.z.object({
466
- spanCount: import_zod3.z.number().int().nonnegative(),
467
- errorCount: import_zod3.z.number().int().nonnegative(),
468
- lastObservedAgeMs: import_zod3.z.number().nonnegative().optional()
469
- });
470
- var GraphEdgeSchema = import_zod3.z.object({
471
- id: import_zod3.z.string(),
472
- source: import_zod3.z.string(),
473
- target: import_zod3.z.string(),
474
- type: EdgeTypeSchema,
475
- provenance: ProvenanceSchema,
476
- confidence: import_zod3.z.number().min(0).max(1).optional(),
477
- lastObserved: import_zod3.z.string().datetime().optional(),
478
- callCount: import_zod3.z.number().int().nonnegative().optional(),
479
- evidence: EdgeEvidenceSchema.optional(),
480
- signal: EdgeSignalSchema.optional(),
481
- // OBSERVED grain (ADR-142): `file` when the edge originates from a source
482
- // file's call site (a `file:` source + `evidence`), `service` for the coarse
483
- // fallback where no call site was captured. Makes "service-grained only as a
484
- // labeled fallback" (connector gate #803) a stored, machine-readable fact
485
- // instead of a re-derivation from the source prefix. `.optional()` — EXTRACTED
486
- // edges and legacy snapshots carry none; an OBSERVED edge is backfilled on its
487
- // next observation.
488
- grain: import_zod3.z.enum(["file", "service"]).optional()
489
- });
490
-
491
548
  // src/events.ts
492
549
  var import_zod4 = require("zod");
493
550
  var SpanAttributesSchema = import_zod4.z.record(
@@ -637,6 +694,7 @@ var ROUTE_PREFIX = "route:";
637
694
  var GRAPHQL_OP_PREFIX = "graphql:";
638
695
  var GRPC_METHOD_PREFIX = "grpc:";
639
696
  var WEBSOCKET_CHANNEL_PREFIX = "ws:";
697
+ var SYMBOL_PREFIX = "symbol:";
640
698
  var ENV_UNKNOWN = "unknown";
641
699
  function serviceId(name, env) {
642
700
  if (env === void 0 || env === ENV_UNKNOWN) return `${SERVICE_PREFIX}${name}`;
@@ -756,6 +814,34 @@ function parseWebsocketChannelId(id) {
756
814
  if (service.length === 0 || channel.length === 0) return null;
757
815
  return { service, channel };
758
816
  }
817
+ function symbolId(service, relPath, qualname, disambiguator) {
818
+ const base = `${SYMBOL_PREFIX}${service}:${relPath}#${qualname}`;
819
+ return disambiguator === void 0 ? base : `${base}~${disambiguator}`;
820
+ }
821
+ function parseSymbolId(id) {
822
+ if (!id.startsWith(SYMBOL_PREFIX)) return null;
823
+ const rest = id.slice(SYMBOL_PREFIX.length);
824
+ const colon = rest.indexOf(":");
825
+ if (colon === -1) return null;
826
+ const service = rest.slice(0, colon);
827
+ const tail = rest.slice(colon + 1);
828
+ const hash = tail.lastIndexOf("#");
829
+ if (hash === -1) return null;
830
+ const relPath = tail.slice(0, hash);
831
+ let qualname = tail.slice(hash + 1);
832
+ if (service.length === 0 || relPath.length === 0 || qualname.length === 0) return null;
833
+ let disambiguator;
834
+ const tilde = qualname.lastIndexOf("~");
835
+ if (tilde !== -1) {
836
+ const suffix = qualname.slice(tilde + 1);
837
+ if (suffix.length > 0 && /^\d+$/.test(suffix)) {
838
+ disambiguator = Number(suffix);
839
+ qualname = qualname.slice(0, tilde);
840
+ }
841
+ }
842
+ if (qualname.length === 0) return null;
843
+ return { service, relPath, qualname, ...disambiguator !== void 0 ? { disambiguator } : {} };
844
+ }
759
845
  var EDGE_ARROW = "->";
760
846
  function extractedEdgeId(source, target, type) {
761
847
  return `${type}:${source}${EDGE_ARROW}${target}`;
@@ -978,14 +1064,20 @@ var commonFields = {
978
1064
  var MissingObservedDivergenceSchema = import_zod8.z.object({
979
1065
  type: import_zod8.z.literal("missing-observed"),
980
1066
  ...commonFields,
981
- edgeType: EdgeTypeSchema,
982
- extracted: GraphEdgeSchema
1067
+ edgeType: EdgeTypeSchema.optional(),
1068
+ extracted: GraphEdgeSchema.optional(),
1069
+ // Column locus (ADR-157 §4): the `sql-table` node id and the declared-only column.
1070
+ table: import_zod8.z.string().optional(),
1071
+ column: import_zod8.z.string().optional()
983
1072
  });
984
1073
  var MissingExtractedDivergenceSchema = import_zod8.z.object({
985
1074
  type: import_zod8.z.literal("missing-extracted"),
986
1075
  ...commonFields,
987
- edgeType: EdgeTypeSchema,
988
- observed: GraphEdgeSchema
1076
+ edgeType: EdgeTypeSchema.optional(),
1077
+ observed: GraphEdgeSchema.optional(),
1078
+ // Column locus (ADR-157 §4): the `sql-table` node id and the observed-only column.
1079
+ table: import_zod8.z.string().optional(),
1080
+ column: import_zod8.z.string().optional()
989
1081
  });
990
1082
  var CompatibilityVerdictSchema = import_zod8.z.enum(["incompatible", "deprecated", "unknown"]);
991
1083
  var VersionMismatchDivergenceSchema = import_zod8.z.object({
@@ -1239,6 +1331,7 @@ function passesExtractedFloor(confidence) {
1239
1331
  BlastRadiusResultSchema,
1240
1332
  BlastRadiusRuleSchema,
1241
1333
  CheckPoliciesScopeSchema,
1334
+ ColumnAttrSchema,
1242
1335
  CompatRuleRefSchema,
1243
1336
  CompatViolationDivergenceSchema,
1244
1337
  CompatibilityRuleSchema,
@@ -1319,6 +1412,9 @@ function passesExtractedFloor(confidence) {
1319
1412
  StaleEventSchema,
1320
1413
  StaleEventsResponseSchema,
1321
1414
  StructuralRuleSchema,
1415
+ SymbolKindSchema,
1416
+ SymbolNodeSchema,
1417
+ SymbolSpanSchema,
1322
1418
  TransitiveDependenciesResultSchema,
1323
1419
  TransitiveDependencySchema,
1324
1420
  VersionMismatchDivergenceSchema,
@@ -1347,10 +1443,12 @@ function passesExtractedFloor(confidence) {
1347
1443
  parseInfraId,
1348
1444
  parseRouteId,
1349
1445
  parseServiceId,
1446
+ parseSymbolId,
1350
1447
  parseWebsocketChannelId,
1351
1448
  passesExtractedFloor,
1352
1449
  routeId,
1353
1450
  serviceId,
1451
+ symbolId,
1354
1452
  websocketChannelId
1355
1453
  });
1356
1454
  //# sourceMappingURL=index.cjs.map