@neat.is/types 0.2.5
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 +629 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1731 -0
- package/dist/index.d.ts +1731 -0
- package/dist/index.js +546 -0
- package/dist/index.js.map +1 -0
- package/package.json +42 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,546 @@
|
|
|
1
|
+
// src/constants.ts
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
var Provenance = {
|
|
4
|
+
EXTRACTED: "EXTRACTED",
|
|
5
|
+
INFERRED: "INFERRED",
|
|
6
|
+
OBSERVED: "OBSERVED",
|
|
7
|
+
STALE: "STALE",
|
|
8
|
+
FRONTIER: "FRONTIER"
|
|
9
|
+
};
|
|
10
|
+
var EdgeType = {
|
|
11
|
+
CALLS: "CALLS",
|
|
12
|
+
DEPENDS_ON: "DEPENDS_ON",
|
|
13
|
+
CONNECTS_TO: "CONNECTS_TO",
|
|
14
|
+
CONFIGURED_BY: "CONFIGURED_BY",
|
|
15
|
+
PUBLISHES_TO: "PUBLISHES_TO",
|
|
16
|
+
CONSUMES_FROM: "CONSUMES_FROM",
|
|
17
|
+
RUNS_ON: "RUNS_ON"
|
|
18
|
+
};
|
|
19
|
+
var NodeType = {
|
|
20
|
+
ServiceNode: "ServiceNode",
|
|
21
|
+
DatabaseNode: "DatabaseNode",
|
|
22
|
+
ConfigNode: "ConfigNode",
|
|
23
|
+
InfraNode: "InfraNode",
|
|
24
|
+
FrontierNode: "FrontierNode"
|
|
25
|
+
};
|
|
26
|
+
var NodeTypeSchema = z.enum([
|
|
27
|
+
NodeType.ServiceNode,
|
|
28
|
+
NodeType.DatabaseNode,
|
|
29
|
+
NodeType.ConfigNode,
|
|
30
|
+
NodeType.InfraNode,
|
|
31
|
+
NodeType.FrontierNode
|
|
32
|
+
]);
|
|
33
|
+
|
|
34
|
+
// src/nodes.ts
|
|
35
|
+
import { z as z2 } from "zod";
|
|
36
|
+
var CompatibleDriverSchema = z2.object({
|
|
37
|
+
name: z2.string(),
|
|
38
|
+
minVersion: z2.string()
|
|
39
|
+
});
|
|
40
|
+
var DiscoveredViaSchema = z2.enum(["static", "otel", "merged"]);
|
|
41
|
+
var ServiceNodeSchema = z2.object({
|
|
42
|
+
id: z2.string(),
|
|
43
|
+
type: z2.literal(NodeType.ServiceNode),
|
|
44
|
+
name: z2.string(),
|
|
45
|
+
language: z2.string(),
|
|
46
|
+
discoveredVia: DiscoveredViaSchema.optional(),
|
|
47
|
+
version: z2.string().optional(),
|
|
48
|
+
dbConnectionTarget: z2.string().optional(),
|
|
49
|
+
repoPath: z2.string().optional(),
|
|
50
|
+
dependencies: z2.record(z2.string(), z2.string()).optional(),
|
|
51
|
+
// Hostnames OTel spans might mention for this service: compose service
|
|
52
|
+
// names, k8s metadata.name (and the cluster-DNS variants), Dockerfile
|
|
53
|
+
// labels, etc. resolveServiceId in ingest.ts checks these before falling
|
|
54
|
+
// back to a FRONTIER placeholder.
|
|
55
|
+
aliases: z2.array(z2.string()).optional(),
|
|
56
|
+
// Optional. If set, services declare their `engines.node` here so γ #74's
|
|
57
|
+
// node-engine compat check has something to test against.
|
|
58
|
+
nodeEngine: z2.string().optional(),
|
|
59
|
+
incompatibilities: z2.array(
|
|
60
|
+
// Discriminated by `kind`. `driver-engine` is the original shape and
|
|
61
|
+
// stays default for backward compatibility — older snapshots without a
|
|
62
|
+
// `kind` field still parse via the union's `.optional()` discriminator
|
|
63
|
+
// fallback. New kinds came in with γ #74.
|
|
64
|
+
z2.union([
|
|
65
|
+
z2.object({
|
|
66
|
+
kind: z2.literal("driver-engine").optional(),
|
|
67
|
+
driver: z2.string(),
|
|
68
|
+
driverVersion: z2.string(),
|
|
69
|
+
engine: z2.string(),
|
|
70
|
+
engineVersion: z2.string(),
|
|
71
|
+
reason: z2.string()
|
|
72
|
+
}),
|
|
73
|
+
z2.object({
|
|
74
|
+
kind: z2.literal("node-engine"),
|
|
75
|
+
package: z2.string(),
|
|
76
|
+
packageVersion: z2.string().optional(),
|
|
77
|
+
requiredNodeVersion: z2.string(),
|
|
78
|
+
declaredNodeEngine: z2.string().optional(),
|
|
79
|
+
reason: z2.string()
|
|
80
|
+
}),
|
|
81
|
+
z2.object({
|
|
82
|
+
kind: z2.literal("package-conflict"),
|
|
83
|
+
package: z2.string(),
|
|
84
|
+
packageVersion: z2.string().optional(),
|
|
85
|
+
requires: z2.object({
|
|
86
|
+
name: z2.string(),
|
|
87
|
+
minVersion: z2.string()
|
|
88
|
+
}),
|
|
89
|
+
foundVersion: z2.string().optional(),
|
|
90
|
+
reason: z2.string()
|
|
91
|
+
}),
|
|
92
|
+
z2.object({
|
|
93
|
+
kind: z2.literal("deprecated-api"),
|
|
94
|
+
package: z2.string(),
|
|
95
|
+
packageVersion: z2.string().optional(),
|
|
96
|
+
reason: z2.string()
|
|
97
|
+
})
|
|
98
|
+
])
|
|
99
|
+
).optional()
|
|
100
|
+
});
|
|
101
|
+
var DatabaseNodeSchema = z2.object({
|
|
102
|
+
id: z2.string(),
|
|
103
|
+
type: z2.literal(NodeType.DatabaseNode),
|
|
104
|
+
name: z2.string(),
|
|
105
|
+
engine: z2.string(),
|
|
106
|
+
engineVersion: z2.string(),
|
|
107
|
+
compatibleDrivers: z2.array(CompatibleDriverSchema),
|
|
108
|
+
host: z2.string().optional(),
|
|
109
|
+
port: z2.number().optional(),
|
|
110
|
+
discoveredVia: DiscoveredViaSchema.optional()
|
|
111
|
+
});
|
|
112
|
+
var ConfigNodeSchema = z2.object({
|
|
113
|
+
id: z2.string(),
|
|
114
|
+
type: z2.literal(NodeType.ConfigNode),
|
|
115
|
+
name: z2.string(),
|
|
116
|
+
path: z2.string(),
|
|
117
|
+
fileType: z2.string()
|
|
118
|
+
});
|
|
119
|
+
var InfraNodeSchema = z2.object({
|
|
120
|
+
id: z2.string(),
|
|
121
|
+
type: z2.literal(NodeType.InfraNode),
|
|
122
|
+
name: z2.string(),
|
|
123
|
+
provider: z2.string(),
|
|
124
|
+
region: z2.string().optional(),
|
|
125
|
+
kind: z2.string().optional()
|
|
126
|
+
});
|
|
127
|
+
var FrontierNodeSchema = z2.object({
|
|
128
|
+
id: z2.string(),
|
|
129
|
+
type: z2.literal(NodeType.FrontierNode),
|
|
130
|
+
name: z2.string(),
|
|
131
|
+
host: z2.string(),
|
|
132
|
+
firstObserved: z2.string().datetime().optional(),
|
|
133
|
+
lastObserved: z2.string().datetime().optional()
|
|
134
|
+
});
|
|
135
|
+
var GraphNodeSchema = z2.discriminatedUnion("type", [
|
|
136
|
+
ServiceNodeSchema,
|
|
137
|
+
DatabaseNodeSchema,
|
|
138
|
+
ConfigNodeSchema,
|
|
139
|
+
InfraNodeSchema,
|
|
140
|
+
FrontierNodeSchema
|
|
141
|
+
]);
|
|
142
|
+
|
|
143
|
+
// src/edges.ts
|
|
144
|
+
import { z as z3 } from "zod";
|
|
145
|
+
var ProvenanceSchema = z3.enum([
|
|
146
|
+
Provenance.EXTRACTED,
|
|
147
|
+
Provenance.INFERRED,
|
|
148
|
+
Provenance.OBSERVED,
|
|
149
|
+
Provenance.STALE,
|
|
150
|
+
Provenance.FRONTIER
|
|
151
|
+
]);
|
|
152
|
+
var EdgeTypeSchema = z3.enum([
|
|
153
|
+
EdgeType.CALLS,
|
|
154
|
+
EdgeType.DEPENDS_ON,
|
|
155
|
+
EdgeType.CONNECTS_TO,
|
|
156
|
+
EdgeType.CONFIGURED_BY,
|
|
157
|
+
EdgeType.PUBLISHES_TO,
|
|
158
|
+
EdgeType.CONSUMES_FROM,
|
|
159
|
+
EdgeType.RUNS_ON
|
|
160
|
+
]);
|
|
161
|
+
var EdgeEvidenceSchema = z3.object({
|
|
162
|
+
file: z3.string(),
|
|
163
|
+
line: z3.number().int().nonnegative(),
|
|
164
|
+
snippet: z3.string()
|
|
165
|
+
});
|
|
166
|
+
var EdgeSignalSchema = z3.object({
|
|
167
|
+
spanCount: z3.number().int().nonnegative(),
|
|
168
|
+
errorCount: z3.number().int().nonnegative(),
|
|
169
|
+
lastObservedAgeMs: z3.number().nonnegative().optional()
|
|
170
|
+
});
|
|
171
|
+
var GraphEdgeSchema = z3.object({
|
|
172
|
+
id: z3.string(),
|
|
173
|
+
source: z3.string(),
|
|
174
|
+
target: z3.string(),
|
|
175
|
+
type: EdgeTypeSchema,
|
|
176
|
+
provenance: ProvenanceSchema,
|
|
177
|
+
confidence: z3.number().min(0).max(1).optional(),
|
|
178
|
+
lastObserved: z3.string().datetime().optional(),
|
|
179
|
+
callCount: z3.number().int().nonnegative().optional(),
|
|
180
|
+
evidence: EdgeEvidenceSchema.optional(),
|
|
181
|
+
signal: EdgeSignalSchema.optional()
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// src/events.ts
|
|
185
|
+
import { z as z4 } from "zod";
|
|
186
|
+
var ErrorEventSchema = z4.object({
|
|
187
|
+
id: z4.string(),
|
|
188
|
+
timestamp: z4.string().datetime(),
|
|
189
|
+
service: z4.string(),
|
|
190
|
+
traceId: z4.string(),
|
|
191
|
+
spanId: z4.string(),
|
|
192
|
+
errorType: z4.string().optional(),
|
|
193
|
+
errorMessage: z4.string(),
|
|
194
|
+
// OTLP span events with name="exception" carry richer error data than
|
|
195
|
+
// status.message. When present, these fields capture the exception type
|
|
196
|
+
// and stacktrace from the SDK that recorded the error. ADR-031 schema
|
|
197
|
+
// growth — added without a shape change because both fields are optional.
|
|
198
|
+
exceptionType: z4.string().optional(),
|
|
199
|
+
exceptionStacktrace: z4.string().optional(),
|
|
200
|
+
affectedNode: z4.string()
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
// src/results.ts
|
|
204
|
+
import { z as z5 } from "zod";
|
|
205
|
+
var RootCauseResultSchema = z5.object({
|
|
206
|
+
rootCauseNode: z5.string(),
|
|
207
|
+
rootCauseReason: z5.string(),
|
|
208
|
+
traversalPath: z5.array(z5.string()),
|
|
209
|
+
edgeProvenances: z5.array(ProvenanceSchema),
|
|
210
|
+
confidence: z5.number().min(0).max(1),
|
|
211
|
+
fixRecommendation: z5.string().optional()
|
|
212
|
+
});
|
|
213
|
+
var BlastRadiusAffectedNodeSchema = z5.object({
|
|
214
|
+
nodeId: z5.string(),
|
|
215
|
+
// Distance from the origin in BFS hops. The origin itself is never in
|
|
216
|
+
// affectedNodes, so distance 0 has no meaning — the BFS at traverse.ts
|
|
217
|
+
// already skips frame 0. Tightening to positive() locks that invariant
|
|
218
|
+
// mechanically (ADR-038, issue #138).
|
|
219
|
+
distance: z5.number().int().positive(),
|
|
220
|
+
edgeProvenance: ProvenanceSchema,
|
|
221
|
+
// path: origin → ... → nodeId. Length === distance + 1. Surfaced from the
|
|
222
|
+
// BFS predecessor chain so consumers don't have to reconstruct it from
|
|
223
|
+
// distance + the graph (ADR-038, issue #137).
|
|
224
|
+
path: z5.array(z5.string()).min(2),
|
|
225
|
+
// confidence: confidenceFromMix(...edgesAlongPath). Multiplicative cascade —
|
|
226
|
+
// each hop is independent evidence and uncertainty compounds. ADR-036.
|
|
227
|
+
confidence: z5.number().min(0).max(1)
|
|
228
|
+
});
|
|
229
|
+
var BlastRadiusResultSchema = z5.object({
|
|
230
|
+
origin: z5.string(),
|
|
231
|
+
affectedNodes: z5.array(BlastRadiusAffectedNodeSchema),
|
|
232
|
+
totalAffected: z5.number().int().nonnegative()
|
|
233
|
+
});
|
|
234
|
+
var TransitiveDependencySchema = z5.object({
|
|
235
|
+
nodeId: z5.string(),
|
|
236
|
+
// Distance from the origin in BFS hops. The origin itself is never in
|
|
237
|
+
// dependencies, so distance is positive (>= 1).
|
|
238
|
+
distance: z5.number().int().positive(),
|
|
239
|
+
// Type of the edge that brought traversal to this node (CALLS,
|
|
240
|
+
// CONNECTS_TO, DEPENDS_ON, etc.).
|
|
241
|
+
edgeType: EdgeTypeSchema,
|
|
242
|
+
// Provenance of that edge.
|
|
243
|
+
provenance: ProvenanceSchema
|
|
244
|
+
});
|
|
245
|
+
var TransitiveDependenciesResultSchema = z5.object({
|
|
246
|
+
origin: z5.string(),
|
|
247
|
+
depth: z5.number().int().positive(),
|
|
248
|
+
dependencies: z5.array(TransitiveDependencySchema),
|
|
249
|
+
total: z5.number().int().nonnegative()
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
// src/identity.ts
|
|
253
|
+
var SERVICE_PREFIX = "service:";
|
|
254
|
+
var DATABASE_PREFIX = "database:";
|
|
255
|
+
var CONFIG_PREFIX = "config:";
|
|
256
|
+
var INFRA_PREFIX = "infra:";
|
|
257
|
+
var FRONTIER_PREFIX = "frontier:";
|
|
258
|
+
function serviceId(name) {
|
|
259
|
+
return `${SERVICE_PREFIX}${name}`;
|
|
260
|
+
}
|
|
261
|
+
function parseServiceId(id) {
|
|
262
|
+
return id.startsWith(SERVICE_PREFIX) ? id.slice(SERVICE_PREFIX.length) : null;
|
|
263
|
+
}
|
|
264
|
+
function databaseId(host) {
|
|
265
|
+
return `${DATABASE_PREFIX}${host}`;
|
|
266
|
+
}
|
|
267
|
+
function parseDatabaseId(id) {
|
|
268
|
+
return id.startsWith(DATABASE_PREFIX) ? id.slice(DATABASE_PREFIX.length) : null;
|
|
269
|
+
}
|
|
270
|
+
function configId(relPath) {
|
|
271
|
+
return `${CONFIG_PREFIX}${relPath}`;
|
|
272
|
+
}
|
|
273
|
+
function parseConfigId(id) {
|
|
274
|
+
return id.startsWith(CONFIG_PREFIX) ? id.slice(CONFIG_PREFIX.length) : null;
|
|
275
|
+
}
|
|
276
|
+
function infraId(kind, name) {
|
|
277
|
+
return `${INFRA_PREFIX}${kind}:${name}`;
|
|
278
|
+
}
|
|
279
|
+
function parseInfraId(id) {
|
|
280
|
+
if (!id.startsWith(INFRA_PREFIX)) return null;
|
|
281
|
+
const rest = id.slice(INFRA_PREFIX.length);
|
|
282
|
+
const colon = rest.indexOf(":");
|
|
283
|
+
if (colon === -1) return null;
|
|
284
|
+
return { kind: rest.slice(0, colon), name: rest.slice(colon + 1) };
|
|
285
|
+
}
|
|
286
|
+
function frontierId(host) {
|
|
287
|
+
return `${FRONTIER_PREFIX}${host}`;
|
|
288
|
+
}
|
|
289
|
+
function parseFrontierId(id) {
|
|
290
|
+
return id.startsWith(FRONTIER_PREFIX) ? id.slice(FRONTIER_PREFIX.length) : null;
|
|
291
|
+
}
|
|
292
|
+
var EDGE_ARROW = "->";
|
|
293
|
+
function extractedEdgeId(source, target, type) {
|
|
294
|
+
return `${type}:${source}${EDGE_ARROW}${target}`;
|
|
295
|
+
}
|
|
296
|
+
function observedEdgeId(source, target, type) {
|
|
297
|
+
return `${type}:OBSERVED:${source}${EDGE_ARROW}${target}`;
|
|
298
|
+
}
|
|
299
|
+
function inferredEdgeId(source, target, type) {
|
|
300
|
+
return `${type}:INFERRED:${source}${EDGE_ARROW}${target}`;
|
|
301
|
+
}
|
|
302
|
+
function frontierEdgeId(source, target, type) {
|
|
303
|
+
return `${type}:FRONTIER:${source}${EDGE_ARROW}${target}`;
|
|
304
|
+
}
|
|
305
|
+
function parseEdgeId(id) {
|
|
306
|
+
const arrowIdx = id.lastIndexOf(EDGE_ARROW);
|
|
307
|
+
if (arrowIdx === -1) return null;
|
|
308
|
+
const left = id.slice(0, arrowIdx);
|
|
309
|
+
const target = id.slice(arrowIdx + EDGE_ARROW.length);
|
|
310
|
+
if (!left || !target) return null;
|
|
311
|
+
const firstColon = left.indexOf(":");
|
|
312
|
+
if (firstColon === -1) return null;
|
|
313
|
+
const type = left.slice(0, firstColon);
|
|
314
|
+
const rest = left.slice(firstColon + 1);
|
|
315
|
+
for (const prov of ["OBSERVED", "INFERRED", "FRONTIER"]) {
|
|
316
|
+
if (rest.startsWith(`${prov}:`)) {
|
|
317
|
+
return { type, provenance: prov, source: rest.slice(prov.length + 1), target };
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
return { type, provenance: "EXTRACTED", source: rest, target };
|
|
321
|
+
}
|
|
322
|
+
var PROV_RANK = Object.freeze({
|
|
323
|
+
OBSERVED: 3,
|
|
324
|
+
INFERRED: 2,
|
|
325
|
+
EXTRACTED: 1,
|
|
326
|
+
STALE: 0,
|
|
327
|
+
FRONTIER: 0
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
// src/policy.ts
|
|
331
|
+
import { z as z6 } from "zod";
|
|
332
|
+
var PolicySeveritySchema = z6.enum(["info", "warning", "error", "critical"]);
|
|
333
|
+
var PolicyActionSchema = z6.enum(["log", "alert", "block"]);
|
|
334
|
+
var StructuralRuleSchema = z6.object({
|
|
335
|
+
type: z6.literal("structural"),
|
|
336
|
+
// Node type the rule applies to. Every node of this type must satisfy the
|
|
337
|
+
// edge requirement below.
|
|
338
|
+
fromNodeType: NodeTypeSchema,
|
|
339
|
+
// Required outbound edge type from each fromNodeType node.
|
|
340
|
+
edgeType: EdgeTypeSchema,
|
|
341
|
+
// Required target node type at the other end of the edge.
|
|
342
|
+
toNodeType: NodeTypeSchema
|
|
343
|
+
});
|
|
344
|
+
var CompatibilityRuleSchema = z6.object({
|
|
345
|
+
type: z6.literal("compatibility"),
|
|
346
|
+
// Optional kind narrowing. When omitted, all four compat shapes
|
|
347
|
+
// (driver-engine, node-engine, package-conflict, deprecated-api) run.
|
|
348
|
+
kind: z6.enum(["driver-engine", "node-engine", "package-conflict", "deprecated-api"]).optional()
|
|
349
|
+
});
|
|
350
|
+
var ProvenanceRuleSchema = z6.object({
|
|
351
|
+
type: z6.literal("provenance"),
|
|
352
|
+
// Edge type the rule applies to.
|
|
353
|
+
edgeType: EdgeTypeSchema,
|
|
354
|
+
// Target node id (e.g. 'service:payments') that incoming edges of edgeType
|
|
355
|
+
// must satisfy. Optional — when omitted, the rule runs against every edge
|
|
356
|
+
// of edgeType regardless of target.
|
|
357
|
+
targetNodeId: z6.string().optional(),
|
|
358
|
+
// Required provenance (single value or one-of). The audit fails if the
|
|
359
|
+
// observed edge's provenance is not in this set.
|
|
360
|
+
required: z6.union([ProvenanceSchema, z6.array(ProvenanceSchema).min(1)])
|
|
361
|
+
});
|
|
362
|
+
var OwnershipRuleSchema = z6.object({
|
|
363
|
+
type: z6.literal("ownership"),
|
|
364
|
+
// Node type the rule applies to. ServiceNode is the common case; the
|
|
365
|
+
// discriminator stays generic so future node types can opt in.
|
|
366
|
+
nodeType: NodeTypeSchema,
|
|
367
|
+
// Field name on the node attributes that must be non-empty. Defaults to
|
|
368
|
+
// 'owner' if omitted.
|
|
369
|
+
field: z6.string().default("owner")
|
|
370
|
+
});
|
|
371
|
+
var BlastRadiusRuleSchema = z6.object({
|
|
372
|
+
type: z6.literal("blast-radius"),
|
|
373
|
+
// Node type the rule applies to (ServiceNode is the common case).
|
|
374
|
+
nodeType: NodeTypeSchema,
|
|
375
|
+
// Cap on `totalAffected` from getBlastRadius. Inclusive — a node hitting
|
|
376
|
+
// exactly this number passes; > maxAffected fails.
|
|
377
|
+
maxAffected: z6.number().int().positive(),
|
|
378
|
+
// Depth to evaluate against. Defaults to the contract's blast-radius
|
|
379
|
+
// default (10) when omitted.
|
|
380
|
+
depth: z6.number().int().positive().optional()
|
|
381
|
+
});
|
|
382
|
+
var PolicyRuleSchema = z6.discriminatedUnion("type", [
|
|
383
|
+
StructuralRuleSchema,
|
|
384
|
+
CompatibilityRuleSchema,
|
|
385
|
+
ProvenanceRuleSchema,
|
|
386
|
+
OwnershipRuleSchema,
|
|
387
|
+
BlastRadiusRuleSchema
|
|
388
|
+
]);
|
|
389
|
+
var PolicySchema = z6.object({
|
|
390
|
+
// Unique within the file. Duplicates fail PolicyFileSchema.parse.
|
|
391
|
+
id: z6.string().min(1),
|
|
392
|
+
name: z6.string().min(1),
|
|
393
|
+
description: z6.string().optional(),
|
|
394
|
+
severity: PolicySeveritySchema,
|
|
395
|
+
// When omitted, the engine derives a default from severity per ADR-044
|
|
396
|
+
// (info→log, warning→alert, error→alert, critical→block).
|
|
397
|
+
onViolation: PolicyActionSchema.optional(),
|
|
398
|
+
rule: PolicyRuleSchema
|
|
399
|
+
});
|
|
400
|
+
var PolicyFileSchema = z6.object({
|
|
401
|
+
version: z6.literal(1),
|
|
402
|
+
policies: z6.array(PolicySchema)
|
|
403
|
+
}).superRefine((file, ctx) => {
|
|
404
|
+
const seen = /* @__PURE__ */ new Set();
|
|
405
|
+
for (const [i, p] of file.policies.entries()) {
|
|
406
|
+
if (seen.has(p.id)) {
|
|
407
|
+
ctx.addIssue({
|
|
408
|
+
code: z6.ZodIssueCode.custom,
|
|
409
|
+
path: ["policies", i, "id"],
|
|
410
|
+
message: `duplicate policy id "${p.id}"`
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
seen.add(p.id);
|
|
414
|
+
}
|
|
415
|
+
});
|
|
416
|
+
var HypotheticalActionSchema = z6.discriminatedUnion("kind", [
|
|
417
|
+
z6.object({
|
|
418
|
+
kind: z6.literal("promote-frontier"),
|
|
419
|
+
// The FrontierNode id that would be promoted.
|
|
420
|
+
frontierId: z6.string().min(1)
|
|
421
|
+
}),
|
|
422
|
+
z6.object({
|
|
423
|
+
kind: z6.literal("add-edge"),
|
|
424
|
+
source: z6.string().min(1),
|
|
425
|
+
target: z6.string().min(1),
|
|
426
|
+
edgeType: EdgeTypeSchema,
|
|
427
|
+
provenance: ProvenanceSchema
|
|
428
|
+
})
|
|
429
|
+
]);
|
|
430
|
+
var PoliciesCheckBodySchema = z6.object({
|
|
431
|
+
hypotheticalAction: HypotheticalActionSchema.optional()
|
|
432
|
+
});
|
|
433
|
+
var CheckPoliciesScopeSchema = z6.union([
|
|
434
|
+
z6.enum(["all", "unresolved"]),
|
|
435
|
+
z6.object({ policyId: z6.string().min(1) })
|
|
436
|
+
]);
|
|
437
|
+
var PolicyViolationSchema = z6.object({
|
|
438
|
+
// ${policy.id}:${violation-context}. The violation-context is shape-
|
|
439
|
+
// specific (e.g. nodeId for structural; edgeId for provenance).
|
|
440
|
+
id: z6.string().min(1),
|
|
441
|
+
policyId: z6.string().min(1),
|
|
442
|
+
policyName: z6.string().min(1),
|
|
443
|
+
severity: PolicySeveritySchema,
|
|
444
|
+
// Resolved at evaluation time — either the explicit policy.onViolation or
|
|
445
|
+
// the severity-derived default per ADR-044.
|
|
446
|
+
onViolation: PolicyActionSchema,
|
|
447
|
+
ruleType: z6.enum(["structural", "compatibility", "provenance", "ownership", "blast-radius"]),
|
|
448
|
+
subject: z6.object({
|
|
449
|
+
nodeId: z6.string().optional(),
|
|
450
|
+
edgeId: z6.string().optional(),
|
|
451
|
+
path: z6.array(z6.string()).optional()
|
|
452
|
+
}).refine(
|
|
453
|
+
(s) => s.nodeId !== void 0 || s.edgeId !== void 0 || s.path !== void 0,
|
|
454
|
+
{ message: "subject must carry at least one of nodeId, edgeId, path" }
|
|
455
|
+
),
|
|
456
|
+
message: z6.string().min(1),
|
|
457
|
+
observedAt: z6.string().datetime()
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
// src/registry.ts
|
|
461
|
+
import { z as z7 } from "zod";
|
|
462
|
+
var RegistryStatusSchema = z7.enum(["active", "paused", "broken"]);
|
|
463
|
+
var RegistryEntrySchema = z7.object({
|
|
464
|
+
// Unique within the registry. Project-scoped operations (`neat watch
|
|
465
|
+
// --project <name>`, `neatd reload <name>`) key on this. Collisions are a
|
|
466
|
+
// hard error at registration time.
|
|
467
|
+
name: z7.string().min(1),
|
|
468
|
+
// Resolved absolute path on disk. Path normalisation is what keeps two
|
|
469
|
+
// `neat init` calls from different relative paths from creating two entries
|
|
470
|
+
// for the same directory.
|
|
471
|
+
path: z7.string().min(1),
|
|
472
|
+
// ISO8601, set at first registration.
|
|
473
|
+
registeredAt: z7.string(),
|
|
474
|
+
// ISO8601, updated whenever the daemon successfully sees the project.
|
|
475
|
+
// Optional because a freshly-registered project hasn't been seen yet.
|
|
476
|
+
lastSeenAt: z7.string().optional(),
|
|
477
|
+
// Languages detected at `init` time. Free-form strings keyed off the
|
|
478
|
+
// installer modules — `'javascript'`, `'python'`, …
|
|
479
|
+
languages: z7.array(z7.string()),
|
|
480
|
+
status: RegistryStatusSchema
|
|
481
|
+
});
|
|
482
|
+
var RegistryFileSchema = z7.object({
|
|
483
|
+
version: z7.literal(1),
|
|
484
|
+
projects: z7.array(RegistryEntrySchema)
|
|
485
|
+
});
|
|
486
|
+
var EMPTY_REGISTRY = { version: 1, projects: [] };
|
|
487
|
+
export {
|
|
488
|
+
BlastRadiusAffectedNodeSchema,
|
|
489
|
+
BlastRadiusResultSchema,
|
|
490
|
+
BlastRadiusRuleSchema,
|
|
491
|
+
CheckPoliciesScopeSchema,
|
|
492
|
+
CompatibilityRuleSchema,
|
|
493
|
+
CompatibleDriverSchema,
|
|
494
|
+
ConfigNodeSchema,
|
|
495
|
+
DatabaseNodeSchema,
|
|
496
|
+
DiscoveredViaSchema,
|
|
497
|
+
EMPTY_REGISTRY,
|
|
498
|
+
EdgeEvidenceSchema,
|
|
499
|
+
EdgeSignalSchema,
|
|
500
|
+
EdgeType,
|
|
501
|
+
EdgeTypeSchema,
|
|
502
|
+
ErrorEventSchema,
|
|
503
|
+
FrontierNodeSchema,
|
|
504
|
+
GraphEdgeSchema,
|
|
505
|
+
GraphNodeSchema,
|
|
506
|
+
HypotheticalActionSchema,
|
|
507
|
+
InfraNodeSchema,
|
|
508
|
+
NodeType,
|
|
509
|
+
NodeTypeSchema,
|
|
510
|
+
OwnershipRuleSchema,
|
|
511
|
+
PROV_RANK,
|
|
512
|
+
PoliciesCheckBodySchema,
|
|
513
|
+
PolicyActionSchema,
|
|
514
|
+
PolicyFileSchema,
|
|
515
|
+
PolicyRuleSchema,
|
|
516
|
+
PolicySchema,
|
|
517
|
+
PolicySeveritySchema,
|
|
518
|
+
PolicyViolationSchema,
|
|
519
|
+
Provenance,
|
|
520
|
+
ProvenanceRuleSchema,
|
|
521
|
+
ProvenanceSchema,
|
|
522
|
+
RegistryEntrySchema,
|
|
523
|
+
RegistryFileSchema,
|
|
524
|
+
RegistryStatusSchema,
|
|
525
|
+
RootCauseResultSchema,
|
|
526
|
+
ServiceNodeSchema,
|
|
527
|
+
StructuralRuleSchema,
|
|
528
|
+
TransitiveDependenciesResultSchema,
|
|
529
|
+
TransitiveDependencySchema,
|
|
530
|
+
configId,
|
|
531
|
+
databaseId,
|
|
532
|
+
extractedEdgeId,
|
|
533
|
+
frontierEdgeId,
|
|
534
|
+
frontierId,
|
|
535
|
+
inferredEdgeId,
|
|
536
|
+
infraId,
|
|
537
|
+
observedEdgeId,
|
|
538
|
+
parseConfigId,
|
|
539
|
+
parseDatabaseId,
|
|
540
|
+
parseEdgeId,
|
|
541
|
+
parseFrontierId,
|
|
542
|
+
parseInfraId,
|
|
543
|
+
parseServiceId,
|
|
544
|
+
serviceId
|
|
545
|
+
};
|
|
546
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts","../src/nodes.ts","../src/edges.ts","../src/events.ts","../src/results.ts","../src/identity.ts","../src/policy.ts","../src/registry.ts"],"sourcesContent":["export const Provenance = {\n EXTRACTED: 'EXTRACTED',\n INFERRED: 'INFERRED',\n OBSERVED: 'OBSERVED',\n STALE: 'STALE',\n FRONTIER: 'FRONTIER',\n} as const\n\nexport type ProvenanceValue = (typeof Provenance)[keyof typeof Provenance]\n\nexport const EdgeType = {\n CALLS: 'CALLS',\n DEPENDS_ON: 'DEPENDS_ON',\n CONNECTS_TO: 'CONNECTS_TO',\n CONFIGURED_BY: 'CONFIGURED_BY',\n PUBLISHES_TO: 'PUBLISHES_TO',\n CONSUMES_FROM: 'CONSUMES_FROM',\n RUNS_ON: 'RUNS_ON',\n} as const\n\nexport type EdgeTypeValue = (typeof EdgeType)[keyof typeof EdgeType]\n\nexport const NodeType = {\n ServiceNode: 'ServiceNode',\n DatabaseNode: 'DatabaseNode',\n ConfigNode: 'ConfigNode',\n InfraNode: 'InfraNode',\n FrontierNode: 'FrontierNode',\n} as const\n\nexport type NodeTypeValue = (typeof NodeType)[keyof typeof NodeType]\n\nimport { z } from 'zod'\n\n// Zod-side mirror of NodeType, exported for schemas that need to discriminate\n// or filter by node type at parse time (policy rules, traversal results, etc.).\n// Adding a new node type means adding it to NodeType above and to this enum.\nexport const NodeTypeSchema = z.enum([\n NodeType.ServiceNode,\n NodeType.DatabaseNode,\n NodeType.ConfigNode,\n NodeType.InfraNode,\n NodeType.FrontierNode,\n])\n","import { z } from 'zod'\nimport { NodeType } from './constants.js'\n\nexport const CompatibleDriverSchema = z.object({\n name: z.string(),\n minVersion: z.string(),\n})\nexport type CompatibleDriver = z.infer<typeof CompatibleDriverSchema>\n\n// How NEAT first learned of a node. Static-extraction fills in the rich\n// fields (language, version, dependencies); OTel ingest can also create a\n// minimal node when it sees a span for an unknown peer. When both layers\n// recorded the same node, the value is 'merged'. ADR-031 schema growth.\nexport const DiscoveredViaSchema = z.enum(['static', 'otel', 'merged'])\nexport type DiscoveredVia = z.infer<typeof DiscoveredViaSchema>\n\nexport const ServiceNodeSchema = z.object({\n id: z.string(),\n type: z.literal(NodeType.ServiceNode),\n name: z.string(),\n language: z.string(),\n discoveredVia: DiscoveredViaSchema.optional(),\n version: z.string().optional(),\n dbConnectionTarget: z.string().optional(),\n repoPath: z.string().optional(),\n dependencies: z.record(z.string(), z.string()).optional(),\n // Hostnames OTel spans might mention for this service: compose service\n // names, k8s metadata.name (and the cluster-DNS variants), Dockerfile\n // labels, etc. resolveServiceId in ingest.ts checks these before falling\n // back to a FRONTIER placeholder.\n aliases: z.array(z.string()).optional(),\n // Optional. If set, services declare their `engines.node` here so γ #74's\n // node-engine compat check has something to test against.\n nodeEngine: z.string().optional(),\n incompatibilities: z\n .array(\n // Discriminated by `kind`. `driver-engine` is the original shape and\n // stays default for backward compatibility — older snapshots without a\n // `kind` field still parse via the union's `.optional()` discriminator\n // fallback. New kinds came in with γ #74.\n z.union([\n z.object({\n kind: z.literal('driver-engine').optional(),\n driver: z.string(),\n driverVersion: z.string(),\n engine: z.string(),\n engineVersion: z.string(),\n reason: z.string(),\n }),\n z.object({\n kind: z.literal('node-engine'),\n package: z.string(),\n packageVersion: z.string().optional(),\n requiredNodeVersion: z.string(),\n declaredNodeEngine: z.string().optional(),\n reason: z.string(),\n }),\n z.object({\n kind: z.literal('package-conflict'),\n package: z.string(),\n packageVersion: z.string().optional(),\n requires: z.object({\n name: z.string(),\n minVersion: z.string(),\n }),\n foundVersion: z.string().optional(),\n reason: z.string(),\n }),\n z.object({\n kind: z.literal('deprecated-api'),\n package: z.string(),\n packageVersion: z.string().optional(),\n reason: z.string(),\n }),\n ]),\n )\n .optional(),\n})\nexport type ServiceNode = z.infer<typeof ServiceNodeSchema>\n\nexport const DatabaseNodeSchema = z.object({\n id: z.string(),\n type: z.literal(NodeType.DatabaseNode),\n name: z.string(),\n engine: z.string(),\n engineVersion: z.string(),\n compatibleDrivers: z.array(CompatibleDriverSchema),\n host: z.string().optional(),\n port: z.number().optional(),\n discoveredVia: DiscoveredViaSchema.optional(),\n})\nexport type DatabaseNode = z.infer<typeof DatabaseNodeSchema>\n\nexport const ConfigNodeSchema = z.object({\n id: z.string(),\n type: z.literal(NodeType.ConfigNode),\n name: z.string(),\n path: z.string(),\n fileType: z.string(),\n})\nexport type ConfigNode = z.infer<typeof ConfigNodeSchema>\n\nexport const InfraNodeSchema = z.object({\n id: z.string(),\n type: z.literal(NodeType.InfraNode),\n name: z.string(),\n provider: z.string(),\n region: z.string().optional(),\n kind: z.string().optional(),\n})\nexport type InfraNode = z.infer<typeof InfraNodeSchema>\n\n// Placeholder for a span peer the ingest layer couldn't resolve to a known\n// ServiceNode. Lives at id `frontier:<host>` and gets replaced by the real\n// service once a later extraction round records that host as an alias.\nexport const FrontierNodeSchema = z.object({\n id: z.string(),\n type: z.literal(NodeType.FrontierNode),\n name: z.string(),\n host: z.string(),\n firstObserved: z.string().datetime().optional(),\n lastObserved: z.string().datetime().optional(),\n})\nexport type FrontierNode = z.infer<typeof FrontierNodeSchema>\n\nexport const GraphNodeSchema = z.discriminatedUnion('type', [\n ServiceNodeSchema,\n DatabaseNodeSchema,\n ConfigNodeSchema,\n InfraNodeSchema,\n FrontierNodeSchema,\n])\nexport type GraphNode = z.infer<typeof GraphNodeSchema>\n","import { z } from 'zod'\nimport { EdgeType, Provenance } from './constants.js'\n\nexport const ProvenanceSchema = z.enum([\n Provenance.EXTRACTED,\n Provenance.INFERRED,\n Provenance.OBSERVED,\n Provenance.STALE,\n Provenance.FRONTIER,\n])\n\nexport const EdgeTypeSchema = z.enum([\n EdgeType.CALLS,\n EdgeType.DEPENDS_ON,\n EdgeType.CONNECTS_TO,\n EdgeType.CONFIGURED_BY,\n EdgeType.PUBLISHES_TO,\n EdgeType.CONSUMES_FROM,\n EdgeType.RUNS_ON,\n])\n\nexport const EdgeEvidenceSchema = z.object({\n file: z.string(),\n line: z.number().int().nonnegative(),\n snippet: z.string(),\n})\nexport type EdgeEvidence = z.infer<typeof EdgeEvidenceSchema>\n\n// Runtime signal for per-edge confidence (γ #76). Populated by ingest. Three\n// continuous numbers stand in for the previous coarse 0.3/0.5/0.7/1.0 ladder:\n// how much traffic, how clean, and how recent.\nexport const EdgeSignalSchema = z.object({\n spanCount: z.number().int().nonnegative(),\n errorCount: z.number().int().nonnegative(),\n lastObservedAgeMs: z.number().nonnegative().optional(),\n})\nexport type EdgeSignal = z.infer<typeof EdgeSignalSchema>\n\nexport const GraphEdgeSchema = z.object({\n id: z.string(),\n source: z.string(),\n target: z.string(),\n type: EdgeTypeSchema,\n provenance: ProvenanceSchema,\n confidence: z.number().min(0).max(1).optional(),\n lastObserved: z.string().datetime().optional(),\n callCount: z.number().int().nonnegative().optional(),\n evidence: EdgeEvidenceSchema.optional(),\n signal: EdgeSignalSchema.optional(),\n})\nexport type GraphEdge = z.infer<typeof GraphEdgeSchema>\n","import { z } from 'zod'\n\nexport const ErrorEventSchema = z.object({\n id: z.string(),\n timestamp: z.string().datetime(),\n service: z.string(),\n traceId: z.string(),\n spanId: z.string(),\n errorType: z.string().optional(),\n errorMessage: z.string(),\n // OTLP span events with name=\"exception\" carry richer error data than\n // status.message. When present, these fields capture the exception type\n // and stacktrace from the SDK that recorded the error. ADR-031 schema\n // growth — added without a shape change because both fields are optional.\n exceptionType: z.string().optional(),\n exceptionStacktrace: z.string().optional(),\n affectedNode: z.string(),\n})\nexport type ErrorEvent = z.infer<typeof ErrorEventSchema>\n","import { z } from 'zod'\nimport { ProvenanceSchema, EdgeTypeSchema } from './edges.js'\n\nexport const RootCauseResultSchema = z.object({\n rootCauseNode: z.string(),\n rootCauseReason: z.string(),\n traversalPath: z.array(z.string()),\n edgeProvenances: z.array(ProvenanceSchema),\n confidence: z.number().min(0).max(1),\n fixRecommendation: z.string().optional(),\n})\nexport type RootCauseResult = z.infer<typeof RootCauseResultSchema>\n\nexport const BlastRadiusAffectedNodeSchema = z.object({\n nodeId: z.string(),\n // Distance from the origin in BFS hops. The origin itself is never in\n // affectedNodes, so distance 0 has no meaning — the BFS at traverse.ts\n // already skips frame 0. Tightening to positive() locks that invariant\n // mechanically (ADR-038, issue #138).\n distance: z.number().int().positive(),\n edgeProvenance: ProvenanceSchema,\n // path: origin → ... → nodeId. Length === distance + 1. Surfaced from the\n // BFS predecessor chain so consumers don't have to reconstruct it from\n // distance + the graph (ADR-038, issue #137).\n path: z.array(z.string()).min(2),\n // confidence: confidenceFromMix(...edgesAlongPath). Multiplicative cascade —\n // each hop is independent evidence and uncertainty compounds. ADR-036.\n confidence: z.number().min(0).max(1),\n})\nexport type BlastRadiusAffectedNode = z.infer<typeof BlastRadiusAffectedNodeSchema>\n\nexport const BlastRadiusResultSchema = z.object({\n origin: z.string(),\n affectedNodes: z.array(BlastRadiusAffectedNodeSchema),\n totalAffected: z.number().int().nonnegative(),\n})\nexport type BlastRadiusResult = z.infer<typeof BlastRadiusResultSchema>\n\n// Transitive get_dependencies (issue #144). Flat list with distance, edge\n// type, and provenance per dependency. Sibling shape to BlastRadius but\n// thinner — no path tracking, no confidence cascade. Use cases live in the\n// MCP get_dependencies tool (\"what does X depend on, transitively?\").\nexport const TransitiveDependencySchema = z.object({\n nodeId: z.string(),\n // Distance from the origin in BFS hops. The origin itself is never in\n // dependencies, so distance is positive (>= 1).\n distance: z.number().int().positive(),\n // Type of the edge that brought traversal to this node (CALLS,\n // CONNECTS_TO, DEPENDS_ON, etc.).\n edgeType: EdgeTypeSchema,\n // Provenance of that edge.\n provenance: ProvenanceSchema,\n})\nexport type TransitiveDependency = z.infer<typeof TransitiveDependencySchema>\n\nexport const TransitiveDependenciesResultSchema = z.object({\n origin: z.string(),\n depth: z.number().int().positive(),\n dependencies: z.array(TransitiveDependencySchema),\n total: z.number().int().nonnegative(),\n})\nexport type TransitiveDependenciesResult = z.infer<typeof TransitiveDependenciesResultSchema>\n","// Identity helpers — the single source of truth for node and edge id wire\n// format. See ADR-028 (nodes), ADR-029 (edges), and docs/contracts/identity.md\n// + docs/contracts/provenance.md.\n//\n// Producers construct ids via these helpers; consumers parse via the inverses.\n// Hand-rolled template literals like `service:${name}` or\n// `${type}:OBSERVED:${source}->${target}` are contract violations\n// (caught by packages/core/test/audits/contracts.test.ts).\n\nconst SERVICE_PREFIX = 'service:'\nconst DATABASE_PREFIX = 'database:'\nconst CONFIG_PREFIX = 'config:'\nconst INFRA_PREFIX = 'infra:'\nconst FRONTIER_PREFIX = 'frontier:'\n\n// ServiceNode id: `service:<name>` where <name> is the manifest name verbatim\n// (package.json#name for JS/TS, pyproject [project].name for Python). Names\n// with slashes (e.g. scoped npm packages `@org/foo`) are kept as-is — no\n// transformation. See ADR-028 §5 for workspace-collision deferral.\nexport function serviceId(name: string): string {\n return `${SERVICE_PREFIX}${name}`\n}\n\nexport function parseServiceId(id: string): string | null {\n return id.startsWith(SERVICE_PREFIX) ? id.slice(SERVICE_PREFIX.length) : null\n}\n\n// DatabaseNode id: `database:<host>`. Port is intentionally excluded; two DBs\n// on the same host different ports collide. See ADR-028 §6 for deferral.\nexport function databaseId(host: string): string {\n return `${DATABASE_PREFIX}${host}`\n}\n\nexport function parseDatabaseId(id: string): string | null {\n return id.startsWith(DATABASE_PREFIX) ? id.slice(DATABASE_PREFIX.length) : null\n}\n\n// ConfigNode id: `config:<relPath>` where <relPath> is the path relative to\n// the scan root, with forward slashes regardless of platform. ConfigNodes\n// record file existence only (ADR-016).\nexport function configId(relPath: string): string {\n return `${CONFIG_PREFIX}${relPath}`\n}\n\nexport function parseConfigId(id: string): string | null {\n return id.startsWith(CONFIG_PREFIX) ? id.slice(CONFIG_PREFIX.length) : null\n}\n\n// InfraNode id: `infra:<kind>:<name>`. <kind> is a free string sub-type\n// (kafka-topic, redis, grpc-service, lambda, queue, etc.) per ADR-022.\nexport function infraId(kind: string, name: string): string {\n return `${INFRA_PREFIX}${kind}:${name}`\n}\n\nexport function parseInfraId(id: string): { kind: string; name: string } | null {\n if (!id.startsWith(INFRA_PREFIX)) return null\n const rest = id.slice(INFRA_PREFIX.length)\n const colon = rest.indexOf(':')\n if (colon === -1) return null\n return { kind: rest.slice(0, colon), name: rest.slice(colon + 1) }\n}\n\n// FrontierNode id: `frontier:<host>` where <host> is host:port from the OTel\n// peer attribute. Promoted to a typed node id (typically serviceId(...)) once\n// an alias resolves; the FrontierNode is removed and edges are rewritten.\nexport function frontierId(host: string): string {\n return `${FRONTIER_PREFIX}${host}`\n}\n\nexport function parseFrontierId(id: string): string | null {\n return id.startsWith(FRONTIER_PREFIX) ? id.slice(FRONTIER_PREFIX.length) : null\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Edge ids (ADR-029)\n// ──────────────────────────────────────────────────────────────────────────\n//\n// Edge id wire format per provenance:\n// EXTRACTED: `${type}:${source}->${target}`\n// OBSERVED: `${type}:OBSERVED:${source}->${target}`\n// INFERRED: `${type}:INFERRED:${source}->${target}`\n// FRONTIER: `${type}:FRONTIER:${source}->${target}`\n// STALE never appears in an edge id; STALE is a transition of an existing\n// OBSERVED edge (ADR-024), not a creation pattern.\n//\n// Multiple edges between the same node pair coexist under distinct provenance\n// ids — that's what makes the EXTRACTED+OBSERVED coexistence rule\n// (contracts.md Rule 2) mechanically possible.\n\nconst EDGE_ARROW = '->'\n\nexport function extractedEdgeId(source: string, target: string, type: string): string {\n return `${type}:${source}${EDGE_ARROW}${target}`\n}\n\nexport function observedEdgeId(source: string, target: string, type: string): string {\n return `${type}:OBSERVED:${source}${EDGE_ARROW}${target}`\n}\n\nexport function inferredEdgeId(source: string, target: string, type: string): string {\n return `${type}:INFERRED:${source}${EDGE_ARROW}${target}`\n}\n\nexport function frontierEdgeId(source: string, target: string, type: string): string {\n return `${type}:FRONTIER:${source}${EDGE_ARROW}${target}`\n}\n\n// Parse an edge id into its parts. Returns null if the input is not a\n// well-formed edge id — covers all four provenance variants. Useful for\n// consumers (traversal, MCP, persist) that need to walk back from an id.\n//\n// Note: EXTRACTED ids have no provenance segment, so we detect them by\n// checking whether the second segment matches a known provenance marker.\nexport function parseEdgeId(id: string): {\n type: string\n provenance: 'EXTRACTED' | 'OBSERVED' | 'INFERRED' | 'FRONTIER'\n source: string\n target: string\n} | null {\n const arrowIdx = id.lastIndexOf(EDGE_ARROW)\n if (arrowIdx === -1) return null\n const left = id.slice(0, arrowIdx)\n const target = id.slice(arrowIdx + EDGE_ARROW.length)\n if (!left || !target) return null\n\n // left is one of:\n // `${type}:${source}` → EXTRACTED\n // `${type}:OBSERVED:${source}` → OBSERVED\n // `${type}:INFERRED:${source}` → INFERRED\n // `${type}:FRONTIER:${source}` → FRONTIER\n const firstColon = left.indexOf(':')\n if (firstColon === -1) return null\n const type = left.slice(0, firstColon)\n const rest = left.slice(firstColon + 1)\n\n for (const prov of ['OBSERVED', 'INFERRED', 'FRONTIER'] as const) {\n if (rest.startsWith(`${prov}:`)) {\n return { type, provenance: prov, source: rest.slice(prov.length + 1), target }\n }\n }\n return { type, provenance: 'EXTRACTED', source: rest, target }\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Provenance ranking (ADR-029)\n// ──────────────────────────────────────────────────────────────────────────\n//\n// Canonical priority used by traversal and any consumer that needs to pick\n// a single edge between two nodes when multiple provenance variants exist.\n// Higher number = higher trust = preferred.\n//\n// FRONTIER is ranked 0 alongside STALE for the case where it does end up in\n// a comparison set, but contracts.md Rule 3 says traversal must skip FRONTIER\n// edges entirely — so this rank is rarely consulted for FRONTIER in practice.\nexport const PROV_RANK: Readonly<Record<'OBSERVED' | 'INFERRED' | 'EXTRACTED' | 'STALE' | 'FRONTIER', number>> = Object.freeze({\n OBSERVED: 3,\n INFERRED: 2,\n EXTRACTED: 1,\n STALE: 0,\n FRONTIER: 0,\n})\n","import { z } from 'zod'\nimport { ProvenanceSchema, EdgeTypeSchema } from './edges.js'\nimport { NodeTypeSchema } from './constants.js'\n\n// Policy schema (ADR-042). Lives at <projectRoot>/policy.json. Loaded at\n// startup and reloaded on file change. Five rule types, discriminated by\n// `rule.type`. Adding a new rule type requires an ADR amendment plus a\n// corresponding evaluator in the engine (ADR-043).\n\nexport const PolicySeveritySchema = z.enum(['info', 'warning', 'error', 'critical'])\nexport type PolicySeverity = z.infer<typeof PolicySeveritySchema>\n\nexport const PolicyActionSchema = z.enum(['log', 'alert', 'block'])\nexport type PolicyAction = z.infer<typeof PolicyActionSchema>\n\n// rule.type === 'structural' — asserts the existence of an edge between\n// node-type pairs. e.g. \"every ServiceNode must have a CONNECTS_TO edge to a\n// DatabaseNode.\"\nexport const StructuralRuleSchema = z.object({\n type: z.literal('structural'),\n // Node type the rule applies to. Every node of this type must satisfy the\n // edge requirement below.\n fromNodeType: NodeTypeSchema,\n // Required outbound edge type from each fromNodeType node.\n edgeType: EdgeTypeSchema,\n // Required target node type at the other end of the edge.\n toNodeType: NodeTypeSchema,\n})\nexport type StructuralRule = z.infer<typeof StructuralRuleSchema>\n\n// rule.type === 'compatibility' — re-runs `compat.ts` against current graph\n// state. Catches OBSERVED-vs-EXTRACTED divergence: a service whose compat\n// shape failed at extract time stays flagged on every evaluation.\nexport const CompatibilityRuleSchema = z.object({\n type: z.literal('compatibility'),\n // Optional kind narrowing. When omitted, all four compat shapes\n // (driver-engine, node-engine, package-conflict, deprecated-api) run.\n kind: z\n .enum(['driver-engine', 'node-engine', 'package-conflict', 'deprecated-api'])\n .optional(),\n})\nexport type CompatibilityRule = z.infer<typeof CompatibilityRuleSchema>\n\n// rule.type === 'provenance' — asserts that edges of a given type to a given\n// target carry a specific provenance (or one of a set). e.g. \"every CALLS\n// edge to service:payments must have OBSERVED provenance.\"\nexport const ProvenanceRuleSchema = z.object({\n type: z.literal('provenance'),\n // Edge type the rule applies to.\n edgeType: EdgeTypeSchema,\n // Target node id (e.g. 'service:payments') that incoming edges of edgeType\n // must satisfy. Optional — when omitted, the rule runs against every edge\n // of edgeType regardless of target.\n targetNodeId: z.string().optional(),\n // Required provenance (single value or one-of). The audit fails if the\n // observed edge's provenance is not in this set.\n required: z.union([ProvenanceSchema, z.array(ProvenanceSchema).min(1)]),\n})\nexport type ProvenanceRule = z.infer<typeof ProvenanceRuleSchema>\n\n// rule.type === 'ownership' — every node of nodeType must declare an `owner`\n// field. The field name lives on the node attributes; the rule fires when a\n// node of the type doesn't carry it (or carries an empty string).\nexport const OwnershipRuleSchema = z.object({\n type: z.literal('ownership'),\n // Node type the rule applies to. ServiceNode is the common case; the\n // discriminator stays generic so future node types can opt in.\n nodeType: NodeTypeSchema,\n // Field name on the node attributes that must be non-empty. Defaults to\n // 'owner' if omitted.\n field: z.string().default('owner'),\n})\nexport type OwnershipRule = z.infer<typeof OwnershipRuleSchema>\n\n// rule.type === 'blast-radius' — no node of the given type may have more\n// than `maxAffected` transitively-affected downstream nodes. Computed via\n// getBlastRadius at evaluation time.\nexport const BlastRadiusRuleSchema = z.object({\n type: z.literal('blast-radius'),\n // Node type the rule applies to (ServiceNode is the common case).\n nodeType: NodeTypeSchema,\n // Cap on `totalAffected` from getBlastRadius. Inclusive — a node hitting\n // exactly this number passes; > maxAffected fails.\n maxAffected: z.number().int().positive(),\n // Depth to evaluate against. Defaults to the contract's blast-radius\n // default (10) when omitted.\n depth: z.number().int().positive().optional(),\n})\nexport type BlastRadiusRule = z.infer<typeof BlastRadiusRuleSchema>\n\nexport const PolicyRuleSchema = z.discriminatedUnion('type', [\n StructuralRuleSchema,\n CompatibilityRuleSchema,\n ProvenanceRuleSchema,\n OwnershipRuleSchema,\n BlastRadiusRuleSchema,\n])\nexport type PolicyRule = z.infer<typeof PolicyRuleSchema>\n\nexport const PolicySchema = z.object({\n // Unique within the file. Duplicates fail PolicyFileSchema.parse.\n id: z.string().min(1),\n name: z.string().min(1),\n description: z.string().optional(),\n severity: PolicySeveritySchema,\n // When omitted, the engine derives a default from severity per ADR-044\n // (info→log, warning→alert, error→alert, critical→block).\n onViolation: PolicyActionSchema.optional(),\n rule: PolicyRuleSchema,\n})\nexport type Policy = z.infer<typeof PolicySchema>\n\n// Top-level shape of policy.json. version: z.literal(1) — bumping requires\n// an ADR amendment per the schema-growth contract (ADR-031).\nexport const PolicyFileSchema = z\n .object({\n version: z.literal(1),\n policies: z.array(PolicySchema),\n })\n .superRefine((file, ctx) => {\n // id uniqueness is enforced at parse time, not at registry-add time.\n // Duplicates collapse silently otherwise — we'd evaluate the second one\n // and lose the first.\n const seen = new Set<string>()\n for (const [i, p] of file.policies.entries()) {\n if (seen.has(p.id)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['policies', i, 'id'],\n message: `duplicate policy id \"${p.id}\"`,\n })\n }\n seen.add(p.id)\n }\n })\nexport type PolicyFile = z.infer<typeof PolicyFileSchema>\n\n// Emitted by the evaluator. Appended to policy-violations.ndjson.\n// Deterministic id (per ADR-043) means re-evaluating the same graph + same\n// policies produces the same violation ids; the writer skips duplicates.\n// Hypothetical action for POST /policies/check (ADR-045). Each action shape\n// names a candidate change to the graph; the engine simulates it and returns\n// any violations that *would* result. MVP scope is the two action shapes\n// below; new shapes need an ADR amendment.\nexport const HypotheticalActionSchema = z.discriminatedUnion('kind', [\n z.object({\n kind: z.literal('promote-frontier'),\n // The FrontierNode id that would be promoted.\n frontierId: z.string().min(1),\n }),\n z.object({\n kind: z.literal('add-edge'),\n source: z.string().min(1),\n target: z.string().min(1),\n edgeType: EdgeTypeSchema,\n provenance: ProvenanceSchema,\n }),\n])\nexport type HypotheticalAction = z.infer<typeof HypotheticalActionSchema>\n\n// Body of POST /policies/check.\nexport const PoliciesCheckBodySchema = z.object({\n hypotheticalAction: HypotheticalActionSchema.optional(),\n})\nexport type PoliciesCheckBody = z.infer<typeof PoliciesCheckBodySchema>\n\n// Scope filter for the check_policies MCP tool. 'all' (default) returns\n// every current violation; 'unresolved' is reserved for future resolution\n// tracking and behaves like 'all' for the MVP; { policyId } narrows to one\n// named policy.\nexport const CheckPoliciesScopeSchema = z.union([\n z.enum(['all', 'unresolved']),\n z.object({ policyId: z.string().min(1) }),\n])\nexport type CheckPoliciesScope = z.infer<typeof CheckPoliciesScopeSchema>\n\nexport const PolicyViolationSchema = z.object({\n // ${policy.id}:${violation-context}. The violation-context is shape-\n // specific (e.g. nodeId for structural; edgeId for provenance).\n id: z.string().min(1),\n policyId: z.string().min(1),\n policyName: z.string().min(1),\n severity: PolicySeveritySchema,\n // Resolved at evaluation time — either the explicit policy.onViolation or\n // the severity-derived default per ADR-044.\n onViolation: PolicyActionSchema,\n ruleType: z.enum(['structural', 'compatibility', 'provenance', 'ownership', 'blast-radius']),\n subject: z\n .object({\n nodeId: z.string().optional(),\n edgeId: z.string().optional(),\n path: z.array(z.string()).optional(),\n })\n .refine(\n (s) => s.nodeId !== undefined || s.edgeId !== undefined || s.path !== undefined,\n { message: 'subject must carry at least one of nodeId, edgeId, path' },\n ),\n message: z.string().min(1),\n observedAt: z.string().datetime(),\n})\nexport type PolicyViolation = z.infer<typeof PolicyViolationSchema>\n","import { z } from 'zod'\n\n// Machine-level project registry (ADR-048). Single file at\n// `~/.neat/projects.json`, per-user, machine-local. The wire shape lives here\n// so the registry module and the daemon agree on it without a circular\n// dependency through @neat.is/core.\n\nexport const RegistryStatusSchema = z.enum(['active', 'paused', 'broken'])\nexport type RegistryStatus = z.infer<typeof RegistryStatusSchema>\n\nexport const RegistryEntrySchema = z.object({\n // Unique within the registry. Project-scoped operations (`neat watch\n // --project <name>`, `neatd reload <name>`) key on this. Collisions are a\n // hard error at registration time.\n name: z.string().min(1),\n // Resolved absolute path on disk. Path normalisation is what keeps two\n // `neat init` calls from different relative paths from creating two entries\n // for the same directory.\n path: z.string().min(1),\n // ISO8601, set at first registration.\n registeredAt: z.string(),\n // ISO8601, updated whenever the daemon successfully sees the project.\n // Optional because a freshly-registered project hasn't been seen yet.\n lastSeenAt: z.string().optional(),\n // Languages detected at `init` time. Free-form strings keyed off the\n // installer modules — `'javascript'`, `'python'`, …\n languages: z.array(z.string()),\n status: RegistryStatusSchema,\n})\nexport type RegistryEntry = z.infer<typeof RegistryEntrySchema>\n\nexport const RegistryFileSchema = z.object({\n version: z.literal(1),\n projects: z.array(RegistryEntrySchema),\n})\nexport type RegistryFile = z.infer<typeof RegistryFileSchema>\n\nexport const EMPTY_REGISTRY: RegistryFile = { version: 1, projects: [] }\n"],"mappings":";AAgCA,SAAS,SAAS;AAhCX,IAAM,aAAa;AAAA,EACxB,WAAW;AAAA,EACX,UAAU;AAAA,EACV,UAAU;AAAA,EACV,OAAO;AAAA,EACP,UAAU;AACZ;AAIO,IAAM,WAAW;AAAA,EACtB,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,eAAe;AAAA,EACf,cAAc;AAAA,EACd,eAAe;AAAA,EACf,SAAS;AACX;AAIO,IAAM,WAAW;AAAA,EACtB,aAAa;AAAA,EACb,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,cAAc;AAChB;AASO,IAAM,iBAAiB,EAAE,KAAK;AAAA,EACnC,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AACX,CAAC;;;AC3CD,SAAS,KAAAA,UAAS;AAGX,IAAM,yBAAyBC,GAAE,OAAO;AAAA,EAC7C,MAAMA,GAAE,OAAO;AAAA,EACf,YAAYA,GAAE,OAAO;AACvB,CAAC;AAOM,IAAM,sBAAsBA,GAAE,KAAK,CAAC,UAAU,QAAQ,QAAQ,CAAC;AAG/D,IAAM,oBAAoBA,GAAE,OAAO;AAAA,EACxC,IAAIA,GAAE,OAAO;AAAA,EACb,MAAMA,GAAE,QAAQ,SAAS,WAAW;AAAA,EACpC,MAAMA,GAAE,OAAO;AAAA,EACf,UAAUA,GAAE,OAAO;AAAA,EACnB,eAAe,oBAAoB,SAAS;AAAA,EAC5C,SAASA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,oBAAoBA,GAAE,OAAO,EAAE,SAAS;AAAA,EACxC,UAAUA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC9B,cAAcA,GAAE,OAAOA,GAAE,OAAO,GAAGA,GAAE,OAAO,CAAC,EAAE,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA,EAKxD,SAASA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS;AAAA;AAAA;AAAA,EAGtC,YAAYA,GAAE,OAAO,EAAE,SAAS;AAAA,EAChC,mBAAmBA,GAChB;AAAA;AAAA;AAAA;AAAA;AAAA,IAKCA,GAAE,MAAM;AAAA,MACNA,GAAE,OAAO;AAAA,QACP,MAAMA,GAAE,QAAQ,eAAe,EAAE,SAAS;AAAA,QAC1C,QAAQA,GAAE,OAAO;AAAA,QACjB,eAAeA,GAAE,OAAO;AAAA,QACxB,QAAQA,GAAE,OAAO;AAAA,QACjB,eAAeA,GAAE,OAAO;AAAA,QACxB,QAAQA,GAAE,OAAO;AAAA,MACnB,CAAC;AAAA,MACDA,GAAE,OAAO;AAAA,QACP,MAAMA,GAAE,QAAQ,aAAa;AAAA,QAC7B,SAASA,GAAE,OAAO;AAAA,QAClB,gBAAgBA,GAAE,OAAO,EAAE,SAAS;AAAA,QACpC,qBAAqBA,GAAE,OAAO;AAAA,QAC9B,oBAAoBA,GAAE,OAAO,EAAE,SAAS;AAAA,QACxC,QAAQA,GAAE,OAAO;AAAA,MACnB,CAAC;AAAA,MACDA,GAAE,OAAO;AAAA,QACP,MAAMA,GAAE,QAAQ,kBAAkB;AAAA,QAClC,SAASA,GAAE,OAAO;AAAA,QAClB,gBAAgBA,GAAE,OAAO,EAAE,SAAS;AAAA,QACpC,UAAUA,GAAE,OAAO;AAAA,UACjB,MAAMA,GAAE,OAAO;AAAA,UACf,YAAYA,GAAE,OAAO;AAAA,QACvB,CAAC;AAAA,QACD,cAAcA,GAAE,OAAO,EAAE,SAAS;AAAA,QAClC,QAAQA,GAAE,OAAO;AAAA,MACnB,CAAC;AAAA,MACDA,GAAE,OAAO;AAAA,QACP,MAAMA,GAAE,QAAQ,gBAAgB;AAAA,QAChC,SAASA,GAAE,OAAO;AAAA,QAClB,gBAAgBA,GAAE,OAAO,EAAE,SAAS;AAAA,QACpC,QAAQA,GAAE,OAAO;AAAA,MACnB,CAAC;AAAA,IACH,CAAC;AAAA,EACH,EACC,SAAS;AACd,CAAC;AAGM,IAAM,qBAAqBA,GAAE,OAAO;AAAA,EACzC,IAAIA,GAAE,OAAO;AAAA,EACb,MAAMA,GAAE,QAAQ,SAAS,YAAY;AAAA,EACrC,MAAMA,GAAE,OAAO;AAAA,EACf,QAAQA,GAAE,OAAO;AAAA,EACjB,eAAeA,GAAE,OAAO;AAAA,EACxB,mBAAmBA,GAAE,MAAM,sBAAsB;AAAA,EACjD,MAAMA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC1B,MAAMA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC1B,eAAe,oBAAoB,SAAS;AAC9C,CAAC;AAGM,IAAM,mBAAmBA,GAAE,OAAO;AAAA,EACvC,IAAIA,GAAE,OAAO;AAAA,EACb,MAAMA,GAAE,QAAQ,SAAS,UAAU;AAAA,EACnC,MAAMA,GAAE,OAAO;AAAA,EACf,MAAMA,GAAE,OAAO;AAAA,EACf,UAAUA,GAAE,OAAO;AACrB,CAAC;AAGM,IAAM,kBAAkBA,GAAE,OAAO;AAAA,EACtC,IAAIA,GAAE,OAAO;AAAA,EACb,MAAMA,GAAE,QAAQ,SAAS,SAAS;AAAA,EAClC,MAAMA,GAAE,OAAO;AAAA,EACf,UAAUA,GAAE,OAAO;AAAA,EACnB,QAAQA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,MAAMA,GAAE,OAAO,EAAE,SAAS;AAC5B,CAAC;AAMM,IAAM,qBAAqBA,GAAE,OAAO;AAAA,EACzC,IAAIA,GAAE,OAAO;AAAA,EACb,MAAMA,GAAE,QAAQ,SAAS,YAAY;AAAA,EACrC,MAAMA,GAAE,OAAO;AAAA,EACf,MAAMA,GAAE,OAAO;AAAA,EACf,eAAeA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EAC9C,cAAcA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAC/C,CAAC;AAGM,IAAM,kBAAkBA,GAAE,mBAAmB,QAAQ;AAAA,EAC1D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;;;ACnID,SAAS,KAAAC,UAAS;AAGX,IAAM,mBAAmBC,GAAE,KAAK;AAAA,EACrC,WAAW;AAAA,EACX,WAAW;AAAA,EACX,WAAW;AAAA,EACX,WAAW;AAAA,EACX,WAAW;AACb,CAAC;AAEM,IAAM,iBAAiBA,GAAE,KAAK;AAAA,EACnC,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AACX,CAAC;AAEM,IAAM,qBAAqBA,GAAE,OAAO;AAAA,EACzC,MAAMA,GAAE,OAAO;AAAA,EACf,MAAMA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EACnC,SAASA,GAAE,OAAO;AACpB,CAAC;AAMM,IAAM,mBAAmBA,GAAE,OAAO;AAAA,EACvC,WAAWA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EACxC,YAAYA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EACzC,mBAAmBA,GAAE,OAAO,EAAE,YAAY,EAAE,SAAS;AACvD,CAAC;AAGM,IAAM,kBAAkBA,GAAE,OAAO;AAAA,EACtC,IAAIA,GAAE,OAAO;AAAA,EACb,QAAQA,GAAE,OAAO;AAAA,EACjB,QAAQA,GAAE,OAAO;AAAA,EACjB,MAAM;AAAA,EACN,YAAY;AAAA,EACZ,YAAYA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EAC9C,cAAcA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EAC7C,WAAWA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS;AAAA,EACnD,UAAU,mBAAmB,SAAS;AAAA,EACtC,QAAQ,iBAAiB,SAAS;AACpC,CAAC;;;ACjDD,SAAS,KAAAC,UAAS;AAEX,IAAM,mBAAmBA,GAAE,OAAO;AAAA,EACvC,IAAIA,GAAE,OAAO;AAAA,EACb,WAAWA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,SAASA,GAAE,OAAO;AAAA,EAClB,SAASA,GAAE,OAAO;AAAA,EAClB,QAAQA,GAAE,OAAO;AAAA,EACjB,WAAWA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,cAAcA,GAAE,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,EAKvB,eAAeA,GAAE,OAAO,EAAE,SAAS;AAAA,EACnC,qBAAqBA,GAAE,OAAO,EAAE,SAAS;AAAA,EACzC,cAAcA,GAAE,OAAO;AACzB,CAAC;;;ACjBD,SAAS,KAAAC,UAAS;AAGX,IAAM,wBAAwBC,GAAE,OAAO;AAAA,EAC5C,eAAeA,GAAE,OAAO;AAAA,EACxB,iBAAiBA,GAAE,OAAO;AAAA,EAC1B,eAAeA,GAAE,MAAMA,GAAE,OAAO,CAAC;AAAA,EACjC,iBAAiBA,GAAE,MAAM,gBAAgB;AAAA,EACzC,YAAYA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC;AAAA,EACnC,mBAAmBA,GAAE,OAAO,EAAE,SAAS;AACzC,CAAC;AAGM,IAAM,gCAAgCA,GAAE,OAAO;AAAA,EACpD,QAAQA,GAAE,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,EAKjB,UAAUA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,EACpC,gBAAgB;AAAA;AAAA;AAAA;AAAA,EAIhB,MAAMA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,IAAI,CAAC;AAAA;AAAA;AAAA,EAG/B,YAAYA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC;AACrC,CAAC;AAGM,IAAM,0BAA0BA,GAAE,OAAO;AAAA,EAC9C,QAAQA,GAAE,OAAO;AAAA,EACjB,eAAeA,GAAE,MAAM,6BAA6B;AAAA,EACpD,eAAeA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAC9C,CAAC;AAOM,IAAM,6BAA6BA,GAAE,OAAO;AAAA,EACjD,QAAQA,GAAE,OAAO;AAAA;AAAA;AAAA,EAGjB,UAAUA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA;AAAA;AAAA,EAGpC,UAAU;AAAA;AAAA,EAEV,YAAY;AACd,CAAC;AAGM,IAAM,qCAAqCA,GAAE,OAAO;AAAA,EACzD,QAAQA,GAAE,OAAO;AAAA,EACjB,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,EACjC,cAAcA,GAAE,MAAM,0BAA0B;AAAA,EAChD,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AACtC,CAAC;;;ACnDD,IAAM,iBAAiB;AACvB,IAAM,kBAAkB;AACxB,IAAM,gBAAgB;AACtB,IAAM,eAAe;AACrB,IAAM,kBAAkB;AAMjB,SAAS,UAAU,MAAsB;AAC9C,SAAO,GAAG,cAAc,GAAG,IAAI;AACjC;AAEO,SAAS,eAAe,IAA2B;AACxD,SAAO,GAAG,WAAW,cAAc,IAAI,GAAG,MAAM,eAAe,MAAM,IAAI;AAC3E;AAIO,SAAS,WAAW,MAAsB;AAC/C,SAAO,GAAG,eAAe,GAAG,IAAI;AAClC;AAEO,SAAS,gBAAgB,IAA2B;AACzD,SAAO,GAAG,WAAW,eAAe,IAAI,GAAG,MAAM,gBAAgB,MAAM,IAAI;AAC7E;AAKO,SAAS,SAAS,SAAyB;AAChD,SAAO,GAAG,aAAa,GAAG,OAAO;AACnC;AAEO,SAAS,cAAc,IAA2B;AACvD,SAAO,GAAG,WAAW,aAAa,IAAI,GAAG,MAAM,cAAc,MAAM,IAAI;AACzE;AAIO,SAAS,QAAQ,MAAc,MAAsB;AAC1D,SAAO,GAAG,YAAY,GAAG,IAAI,IAAI,IAAI;AACvC;AAEO,SAAS,aAAa,IAAmD;AAC9E,MAAI,CAAC,GAAG,WAAW,YAAY,EAAG,QAAO;AACzC,QAAM,OAAO,GAAG,MAAM,aAAa,MAAM;AACzC,QAAM,QAAQ,KAAK,QAAQ,GAAG;AAC9B,MAAI,UAAU,GAAI,QAAO;AACzB,SAAO,EAAE,MAAM,KAAK,MAAM,GAAG,KAAK,GAAG,MAAM,KAAK,MAAM,QAAQ,CAAC,EAAE;AACnE;AAKO,SAAS,WAAW,MAAsB;AAC/C,SAAO,GAAG,eAAe,GAAG,IAAI;AAClC;AAEO,SAAS,gBAAgB,IAA2B;AACzD,SAAO,GAAG,WAAW,eAAe,IAAI,GAAG,MAAM,gBAAgB,MAAM,IAAI;AAC7E;AAkBA,IAAM,aAAa;AAEZ,SAAS,gBAAgB,QAAgB,QAAgB,MAAsB;AACpF,SAAO,GAAG,IAAI,IAAI,MAAM,GAAG,UAAU,GAAG,MAAM;AAChD;AAEO,SAAS,eAAe,QAAgB,QAAgB,MAAsB;AACnF,SAAO,GAAG,IAAI,aAAa,MAAM,GAAG,UAAU,GAAG,MAAM;AACzD;AAEO,SAAS,eAAe,QAAgB,QAAgB,MAAsB;AACnF,SAAO,GAAG,IAAI,aAAa,MAAM,GAAG,UAAU,GAAG,MAAM;AACzD;AAEO,SAAS,eAAe,QAAgB,QAAgB,MAAsB;AACnF,SAAO,GAAG,IAAI,aAAa,MAAM,GAAG,UAAU,GAAG,MAAM;AACzD;AAQO,SAAS,YAAY,IAKnB;AACP,QAAM,WAAW,GAAG,YAAY,UAAU;AAC1C,MAAI,aAAa,GAAI,QAAO;AAC5B,QAAM,OAAO,GAAG,MAAM,GAAG,QAAQ;AACjC,QAAM,SAAS,GAAG,MAAM,WAAW,WAAW,MAAM;AACpD,MAAI,CAAC,QAAQ,CAAC,OAAQ,QAAO;AAO7B,QAAM,aAAa,KAAK,QAAQ,GAAG;AACnC,MAAI,eAAe,GAAI,QAAO;AAC9B,QAAM,OAAO,KAAK,MAAM,GAAG,UAAU;AACrC,QAAM,OAAO,KAAK,MAAM,aAAa,CAAC;AAEtC,aAAW,QAAQ,CAAC,YAAY,YAAY,UAAU,GAAY;AAChE,QAAI,KAAK,WAAW,GAAG,IAAI,GAAG,GAAG;AAC/B,aAAO,EAAE,MAAM,YAAY,MAAM,QAAQ,KAAK,MAAM,KAAK,SAAS,CAAC,GAAG,OAAO;AAAA,IAC/E;AAAA,EACF;AACA,SAAO,EAAE,MAAM,YAAY,aAAa,QAAQ,MAAM,OAAO;AAC/D;AAaO,IAAM,YAAoG,OAAO,OAAO;AAAA,EAC7H,UAAU;AAAA,EACV,UAAU;AAAA,EACV,WAAW;AAAA,EACX,OAAO;AAAA,EACP,UAAU;AACZ,CAAC;;;AChKD,SAAS,KAAAC,UAAS;AASX,IAAM,uBAAuBC,GAAE,KAAK,CAAC,QAAQ,WAAW,SAAS,UAAU,CAAC;AAG5E,IAAM,qBAAqBA,GAAE,KAAK,CAAC,OAAO,SAAS,OAAO,CAAC;AAM3D,IAAM,uBAAuBA,GAAE,OAAO;AAAA,EAC3C,MAAMA,GAAE,QAAQ,YAAY;AAAA;AAAA;AAAA,EAG5B,cAAc;AAAA;AAAA,EAEd,UAAU;AAAA;AAAA,EAEV,YAAY;AACd,CAAC;AAMM,IAAM,0BAA0BA,GAAE,OAAO;AAAA,EAC9C,MAAMA,GAAE,QAAQ,eAAe;AAAA;AAAA;AAAA,EAG/B,MAAMA,GACH,KAAK,CAAC,iBAAiB,eAAe,oBAAoB,gBAAgB,CAAC,EAC3E,SAAS;AACd,CAAC;AAMM,IAAM,uBAAuBA,GAAE,OAAO;AAAA,EAC3C,MAAMA,GAAE,QAAQ,YAAY;AAAA;AAAA,EAE5B,UAAU;AAAA;AAAA;AAAA;AAAA,EAIV,cAAcA,GAAE,OAAO,EAAE,SAAS;AAAA;AAAA;AAAA,EAGlC,UAAUA,GAAE,MAAM,CAAC,kBAAkBA,GAAE,MAAM,gBAAgB,EAAE,IAAI,CAAC,CAAC,CAAC;AACxE,CAAC;AAMM,IAAM,sBAAsBA,GAAE,OAAO;AAAA,EAC1C,MAAMA,GAAE,QAAQ,WAAW;AAAA;AAAA;AAAA,EAG3B,UAAU;AAAA;AAAA;AAAA,EAGV,OAAOA,GAAE,OAAO,EAAE,QAAQ,OAAO;AACnC,CAAC;AAMM,IAAM,wBAAwBA,GAAE,OAAO;AAAA,EAC5C,MAAMA,GAAE,QAAQ,cAAc;AAAA;AAAA,EAE9B,UAAU;AAAA;AAAA;AAAA,EAGV,aAAaA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA;AAAA;AAAA,EAGvC,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;AAC9C,CAAC;AAGM,IAAM,mBAAmBA,GAAE,mBAAmB,QAAQ;AAAA,EAC3D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAGM,IAAM,eAAeA,GAAE,OAAO;AAAA;AAAA,EAEnC,IAAIA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACpB,MAAMA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACtB,aAAaA,GAAE,OAAO,EAAE,SAAS;AAAA,EACjC,UAAU;AAAA;AAAA;AAAA,EAGV,aAAa,mBAAmB,SAAS;AAAA,EACzC,MAAM;AACR,CAAC;AAKM,IAAM,mBAAmBA,GAC7B,OAAO;AAAA,EACN,SAASA,GAAE,QAAQ,CAAC;AAAA,EACpB,UAAUA,GAAE,MAAM,YAAY;AAChC,CAAC,EACA,YAAY,CAAC,MAAM,QAAQ;AAI1B,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,CAAC,GAAG,CAAC,KAAK,KAAK,SAAS,QAAQ,GAAG;AAC5C,QAAI,KAAK,IAAI,EAAE,EAAE,GAAG;AAClB,UAAI,SAAS;AAAA,QACX,MAAMA,GAAE,aAAa;AAAA,QACrB,MAAM,CAAC,YAAY,GAAG,IAAI;AAAA,QAC1B,SAAS,wBAAwB,EAAE,EAAE;AAAA,MACvC,CAAC;AAAA,IACH;AACA,SAAK,IAAI,EAAE,EAAE;AAAA,EACf;AACF,CAAC;AAUI,IAAM,2BAA2BA,GAAE,mBAAmB,QAAQ;AAAA,EACnEA,GAAE,OAAO;AAAA,IACP,MAAMA,GAAE,QAAQ,kBAAkB;AAAA;AAAA,IAElC,YAAYA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC9B,CAAC;AAAA,EACDA,GAAE,OAAO;AAAA,IACP,MAAMA,GAAE,QAAQ,UAAU;AAAA,IAC1B,QAAQA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,IACxB,QAAQA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,IACxB,UAAU;AAAA,IACV,YAAY;AAAA,EACd,CAAC;AACH,CAAC;AAIM,IAAM,0BAA0BA,GAAE,OAAO;AAAA,EAC9C,oBAAoB,yBAAyB,SAAS;AACxD,CAAC;AAOM,IAAM,2BAA2BA,GAAE,MAAM;AAAA,EAC9CA,GAAE,KAAK,CAAC,OAAO,YAAY,CAAC;AAAA,EAC5BA,GAAE,OAAO,EAAE,UAAUA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC;AAC1C,CAAC;AAGM,IAAM,wBAAwBA,GAAE,OAAO;AAAA;AAAA;AAAA,EAG5C,IAAIA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACpB,UAAUA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC1B,YAAYA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC5B,UAAU;AAAA;AAAA;AAAA,EAGV,aAAa;AAAA,EACb,UAAUA,GAAE,KAAK,CAAC,cAAc,iBAAiB,cAAc,aAAa,cAAc,CAAC;AAAA,EAC3F,SAASA,GACN,OAAO;AAAA,IACN,QAAQA,GAAE,OAAO,EAAE,SAAS;AAAA,IAC5B,QAAQA,GAAE,OAAO,EAAE,SAAS;AAAA,IAC5B,MAAMA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACrC,CAAC,EACA;AAAA,IACC,CAAC,MAAM,EAAE,WAAW,UAAa,EAAE,WAAW,UAAa,EAAE,SAAS;AAAA,IACtE,EAAE,SAAS,0DAA0D;AAAA,EACvE;AAAA,EACF,SAASA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACzB,YAAYA,GAAE,OAAO,EAAE,SAAS;AAClC,CAAC;;;ACvMD,SAAS,KAAAC,UAAS;AAOX,IAAM,uBAAuBA,GAAE,KAAK,CAAC,UAAU,UAAU,QAAQ,CAAC;AAGlE,IAAM,sBAAsBA,GAAE,OAAO;AAAA;AAAA;AAAA;AAAA,EAI1C,MAAMA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA,EAItB,MAAMA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA;AAAA,EAEtB,cAAcA,GAAE,OAAO;AAAA;AAAA;AAAA,EAGvB,YAAYA,GAAE,OAAO,EAAE,SAAS;AAAA;AAAA;AAAA,EAGhC,WAAWA,GAAE,MAAMA,GAAE,OAAO,CAAC;AAAA,EAC7B,QAAQ;AACV,CAAC;AAGM,IAAM,qBAAqBA,GAAE,OAAO;AAAA,EACzC,SAASA,GAAE,QAAQ,CAAC;AAAA,EACpB,UAAUA,GAAE,MAAM,mBAAmB;AACvC,CAAC;AAGM,IAAM,iBAA+B,EAAE,SAAS,GAAG,UAAU,CAAC,EAAE;","names":["z","z","z","z","z","z","z","z","z","z"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@neat.is/types",
|
|
3
|
+
"version": "0.2.5",
|
|
4
|
+
"description": "Shared Zod schemas, types, and runtime constants for NEAT",
|
|
5
|
+
"license": "BUSL-1.1",
|
|
6
|
+
"homepage": "https://neat.is",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/NEAT-Technologies/Neat.git",
|
|
10
|
+
"directory": "packages/types"
|
|
11
|
+
},
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"access": "public"
|
|
14
|
+
},
|
|
15
|
+
"type": "module",
|
|
16
|
+
"main": "./dist/index.cjs",
|
|
17
|
+
"module": "./dist/index.js",
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"import": "./dist/index.js",
|
|
23
|
+
"require": "./dist/index.cjs"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"files": ["dist"],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsup",
|
|
29
|
+
"prepublishOnly": "npm run build",
|
|
30
|
+
"test": "vitest run",
|
|
31
|
+
"lint": "eslint src",
|
|
32
|
+
"clean": "rm -rf dist .turbo"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"zod": "^3.23.8"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"tsup": "^8.3.0",
|
|
39
|
+
"typescript": "^5.6.0",
|
|
40
|
+
"vitest": "^2.1.0"
|
|
41
|
+
}
|
|
42
|
+
}
|