@svashevchenko/ez-know 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3237 @@
1
+ // src/rest-server.ts
2
+ import { existsSync as existsSync3 } from "node:fs";
3
+ import { fileURLToPath } from "node:url";
4
+
5
+ // packages/rest/src/app.ts
6
+ import { access } from "node:fs/promises";
7
+ import { resolve as resolve5 } from "node:path";
8
+ import fastifyStatic from "@fastify/static";
9
+ import Fastify from "fastify";
10
+
11
+ // packages/core/src/knowledge/schema.ts
12
+ import { extendZodWithOpenApi } from "@asteasolutions/zod-to-openapi";
13
+ import { z } from "zod/v4";
14
+ extendZodWithOpenApi(z);
15
+ var confidenceSchema = z.object({
16
+ score: z.number().min(0).max(1),
17
+ level: z.enum(["Low", "Medium", "High"]),
18
+ reason: z.string().optional()
19
+ });
20
+ var certaintySchema = z.enum([
21
+ "confirmed",
22
+ "direct_evidence",
23
+ "inferred",
24
+ "weak_inference",
25
+ "unknown"
26
+ ]);
27
+ var withConfidenceSchema = z.object({
28
+ certainty: certaintySchema,
29
+ confidence: confidenceSchema,
30
+ evidence_ids: z.array(z.string()),
31
+ questions: z.array(z.string())
32
+ });
33
+ var evidenceSchema = z.object({
34
+ id: z.string(),
35
+ source_type: z.enum([
36
+ "code",
37
+ "test",
38
+ "ui_text",
39
+ "translation",
40
+ "api",
41
+ "route",
42
+ "schema",
43
+ "comment",
44
+ "documentation",
45
+ "repowise_search",
46
+ "human",
47
+ "increment_description",
48
+ "git_diff"
49
+ ]),
50
+ description: z.string(),
51
+ location: z.object({
52
+ path: z.string().optional(),
53
+ symbol: z.string().optional(),
54
+ route: z.string().optional(),
55
+ api: z.string().optional(),
56
+ query: z.string().optional()
57
+ }).optional(),
58
+ supports: z.array(z.string()),
59
+ excerpt: z.string().optional(),
60
+ confidence: confidenceSchema
61
+ });
62
+ var domainSchema = withConfidenceSchema.extend({
63
+ id: z.string(),
64
+ name: z.string(),
65
+ purpose: z.string(),
66
+ why_it_exists: z.string().optional(),
67
+ entity_ids: z.array(z.string()),
68
+ capability_ids: z.array(z.string())
69
+ });
70
+ var entityTechnicalRepresentationSchema = z.object({
71
+ kind: z.enum([
72
+ "type",
73
+ "api",
74
+ "route",
75
+ "database",
76
+ "ui_label",
77
+ "translation",
78
+ "unknown"
79
+ ]),
80
+ name: z.string(),
81
+ location_hint: z.string().optional()
82
+ });
83
+ var entitySchema = withConfidenceSchema.extend({
84
+ id: z.string(),
85
+ name: z.string(),
86
+ business_definition: z.string(),
87
+ description: z.string(),
88
+ purpose: z.string().optional(),
89
+ aliases: z.array(z.string()),
90
+ ambiguous_terms: z.array(z.string()),
91
+ technical_representations: z.array(entityTechnicalRepresentationSchema),
92
+ domain_ids: z.array(z.string()),
93
+ state_values: z.array(z.string()).optional(),
94
+ relationship_ids: z.array(z.string()),
95
+ capability_ids: z.array(z.string()),
96
+ feature_ids: z.array(z.string()),
97
+ rule_ids: z.array(z.string())
98
+ });
99
+ var relationshipSchema = withConfidenceSchema.extend({
100
+ id: z.string(),
101
+ from_entity_id: z.string(),
102
+ to_entity_id: z.string(),
103
+ relationship_type: z.enum([
104
+ "has_many",
105
+ "has_one",
106
+ "belongs_to",
107
+ "depends_on",
108
+ "references",
109
+ "transitions_to",
110
+ "unknown"
111
+ ]),
112
+ description: z.string()
113
+ });
114
+ var capabilitySchema = withConfidenceSchema.extend({
115
+ id: z.string(),
116
+ name: z.string(),
117
+ description: z.string(),
118
+ why_it_exists: z.string().optional(),
119
+ domain_ids: z.array(z.string()),
120
+ entity_ids: z.array(z.string()),
121
+ parent_capability_ids: z.array(z.string()),
122
+ child_capability_ids: z.array(z.string()),
123
+ feature_ids: z.array(z.string())
124
+ });
125
+ var featureSchema = withConfidenceSchema.extend({
126
+ id: z.string(),
127
+ name: z.string(),
128
+ description: z.string(),
129
+ purpose: z.string().optional(),
130
+ why_it_exists: z.string().optional(),
131
+ domain_ids: z.array(z.string()),
132
+ capability_ids: z.array(z.string()),
133
+ entity_ids: z.array(z.string()),
134
+ rule_ids: z.array(z.string()),
135
+ constraint_ids: z.array(z.string())
136
+ });
137
+ var ruleConditionSchema = z.object({
138
+ subject: z.string(),
139
+ field: z.string().optional(),
140
+ operator: z.enum([
141
+ "equals",
142
+ "not_equals",
143
+ "contains",
144
+ "not_contains",
145
+ "exists",
146
+ "not_exists",
147
+ "greater_than",
148
+ "less_than",
149
+ "succeeds",
150
+ "fails",
151
+ "unknown"
152
+ ]),
153
+ value: z.unknown().optional()
154
+ });
155
+ var ruleTriggerSchema = z.object({
156
+ actor: z.string(),
157
+ action: z.string(),
158
+ subject: z.string().optional(),
159
+ field: z.string().optional(),
160
+ operator: z.enum([
161
+ "equals",
162
+ "not_equals",
163
+ "contains",
164
+ "not_contains",
165
+ "exists",
166
+ "not_exists",
167
+ "greater_than",
168
+ "less_than",
169
+ "succeeds",
170
+ "fails",
171
+ "unknown"
172
+ ]).optional(),
173
+ value: z.unknown().optional()
174
+ });
175
+ var ruleEffectSchema = z.object({
176
+ effect: z.enum([
177
+ "allow_action",
178
+ "disallow_action",
179
+ "hide_action",
180
+ "disable_action",
181
+ "require_action",
182
+ "show_message",
183
+ "change_state",
184
+ "calculate_value",
185
+ "unknown"
186
+ ]),
187
+ action: z.string().optional(),
188
+ message: z.string().optional(),
189
+ target_state: z.string().optional(),
190
+ value: z.unknown().optional()
191
+ });
192
+ var businessRuleSchema = withConfidenceSchema.extend({
193
+ id: z.string(),
194
+ name: z.string(),
195
+ statement: z.string(),
196
+ rule_type: z.enum([
197
+ "validation",
198
+ "permission",
199
+ "state_transition",
200
+ "visibility",
201
+ "workflow",
202
+ "calculation",
203
+ "integration",
204
+ "integration_behavior",
205
+ "data_consistency",
206
+ "acceptance_criterion",
207
+ "unknown"
208
+ ]),
209
+ behavior_type: z.enum([
210
+ "allow",
211
+ "disallow",
212
+ "require",
213
+ "calculate",
214
+ "show",
215
+ "hide",
216
+ "transition",
217
+ "notify",
218
+ "block",
219
+ "default",
220
+ "unknown"
221
+ ]),
222
+ applies_to: z.object({
223
+ domain_ids: z.array(z.string()).optional(),
224
+ entity_ids: z.array(z.string()).optional(),
225
+ capability_ids: z.array(z.string()).optional(),
226
+ feature_ids: z.array(z.string()).optional()
227
+ }),
228
+ condition: z.object({
229
+ given: z.array(ruleConditionSchema),
230
+ when: z.array(ruleTriggerSchema),
231
+ then: z.array(ruleEffectSchema)
232
+ }).optional(),
233
+ enforcement: z.object({
234
+ level: z.enum([
235
+ "ui",
236
+ "api",
237
+ "backend",
238
+ "database",
239
+ "external_system",
240
+ "unknown"
241
+ ]),
242
+ description: z.string().optional()
243
+ }).optional(),
244
+ related_constraint_ids: z.array(z.string()),
245
+ rationale_ids: z.array(z.string())
246
+ });
247
+ var constraintSchema = withConfidenceSchema.extend({
248
+ id: z.string(),
249
+ name: z.string(),
250
+ description: z.string(),
251
+ constraint_type: z.enum([
252
+ "business",
253
+ "technical",
254
+ "regulatory",
255
+ "compliance",
256
+ "integration",
257
+ "legacy",
258
+ "architecture",
259
+ "infrastructure",
260
+ "performance",
261
+ "security",
262
+ "operational",
263
+ "data_model",
264
+ "unknown"
265
+ ]),
266
+ cause: z.object({
267
+ source: z.string(),
268
+ source_type: z.enum([
269
+ "external_system",
270
+ "database",
271
+ "framework",
272
+ "infrastructure",
273
+ "architecture",
274
+ "policy",
275
+ "regulation",
276
+ "business_process",
277
+ "legacy_code",
278
+ "unknown"
279
+ ]),
280
+ description: z.string()
281
+ }).optional(),
282
+ impact: z.object({
283
+ affected_change_types: z.array(z.string()),
284
+ severity: z.enum(["low", "medium", "high", "critical", "unknown"]),
285
+ description: z.string()
286
+ }).optional(),
287
+ applies_to: z.object({
288
+ domain_ids: z.array(z.string()).optional(),
289
+ entity_ids: z.array(z.string()).optional(),
290
+ capability_ids: z.array(z.string()).optional(),
291
+ feature_ids: z.array(z.string()).optional(),
292
+ business_rule_ids: z.array(z.string()).optional()
293
+ }),
294
+ workaround: z.object({
295
+ exists: z.enum(["yes", "no", "unknown"]),
296
+ description: z.string().optional()
297
+ }).optional(),
298
+ removability: z.object({
299
+ can_be_removed_by_refactor: z.enum(["yes", "no", "partially", "unknown"]),
300
+ requires: z.array(z.string()),
301
+ risk: z.enum(["low", "medium", "high", "critical", "unknown"])
302
+ }).optional()
303
+ });
304
+ var rationaleSchema = withConfidenceSchema.extend({
305
+ id: z.string(),
306
+ statement: z.string(),
307
+ explains: z.array(z.string())
308
+ });
309
+ var questionSchema = z.object({
310
+ id: z.string(),
311
+ question: z.string(),
312
+ category: z.enum([
313
+ "rationale",
314
+ "business_rule",
315
+ "constraint",
316
+ "terminology",
317
+ "domain_boundary",
318
+ "lifecycle",
319
+ "permission",
320
+ "legacy",
321
+ "ownership",
322
+ "enforcement"
323
+ ]),
324
+ reason: z.string(),
325
+ impact: z.string().optional(),
326
+ related_ids: z.array(z.string()),
327
+ evidence_ids: z.array(z.string()),
328
+ priority: z.enum(["low", "medium", "high"]),
329
+ status: z.enum(["open", "answered", "obsolete"]),
330
+ answer: z.string().nullable().optional(),
331
+ answered_by: z.string().nullable().optional(),
332
+ answered_at: z.string().nullable().optional()
333
+ });
334
+ var conflictSchema = z.object({
335
+ id: z.string(),
336
+ type: z.enum([
337
+ "domain_boundary",
338
+ "terminology",
339
+ "rule_conflict",
340
+ "rationale_conflict",
341
+ "entity_duplicate",
342
+ "relationship_conflict"
343
+ ]),
344
+ description: z.string(),
345
+ related_ids: z.array(z.string()),
346
+ evidence_ids: z.array(z.string()),
347
+ status: z.enum(["needs_human_input", "resolved", "obsolete"]),
348
+ questions: z.array(z.string()),
349
+ resolution: z.string().optional(),
350
+ resolved_by_evidence_id: z.string().optional()
351
+ });
352
+ var knowledgeCollectionSchemas = {
353
+ domains: z.array(domainSchema),
354
+ entities: z.array(entitySchema),
355
+ relationships: z.array(relationshipSchema),
356
+ capabilities: z.array(capabilitySchema),
357
+ features: z.array(featureSchema),
358
+ business_rules: z.array(businessRuleSchema),
359
+ constraints: z.array(constraintSchema),
360
+ rationales: z.array(rationaleSchema),
361
+ evidence: z.array(evidenceSchema),
362
+ questions: z.array(questionSchema),
363
+ conflicts: z.array(conflictSchema)
364
+ };
365
+
366
+ // packages/core/src/knowledge/extraction-registry.ts
367
+ var KNOWLEDGE_EXTRACTION_TYPE_REGISTRY = {
368
+ domains: {
369
+ collection: "domains",
370
+ title: "Domains",
371
+ storageFile: "domain.json",
372
+ idConvention: {
373
+ pattern: "domain.<domain-slug>",
374
+ prefix: "domain",
375
+ example: "domain.orders"
376
+ },
377
+ schemaName: "Domain",
378
+ schema: domainSchema,
379
+ guideFilePath: "packages/core/src/knowledge/guides/domains.md",
380
+ aliases: []
381
+ },
382
+ entities: {
383
+ collection: "entities",
384
+ title: "Entities",
385
+ storageFile: "entities.json",
386
+ idConvention: {
387
+ pattern: "entity.<domain-slug>.<entity-slug>",
388
+ prefix: "entity",
389
+ example: "entity.orders.order"
390
+ },
391
+ schemaName: "Entity",
392
+ schema: entitySchema,
393
+ guideFilePath: "packages/core/src/knowledge/guides/entities.md",
394
+ aliases: []
395
+ },
396
+ relationships: {
397
+ collection: "relationships",
398
+ title: "Relationships",
399
+ storageFile: "relationships.json",
400
+ idConvention: {
401
+ pattern: "rel.<domain-slug>.<relationship-slug>",
402
+ prefix: "rel",
403
+ example: "rel.orders.order-has-items"
404
+ },
405
+ schemaName: "EntityRelationship",
406
+ schema: relationshipSchema,
407
+ guideFilePath: "packages/core/src/knowledge/guides/relationships.md",
408
+ aliases: ["entity-relationships"]
409
+ },
410
+ capabilities: {
411
+ collection: "capabilities",
412
+ title: "Capabilities",
413
+ storageFile: "capabilities.json",
414
+ idConvention: {
415
+ pattern: "cap.<domain-slug>.<capability-slug>",
416
+ prefix: "cap",
417
+ example: "cap.orders.order-lifecycle"
418
+ },
419
+ schemaName: "Capability",
420
+ schema: capabilitySchema,
421
+ guideFilePath: "packages/core/src/knowledge/guides/capabilities.md",
422
+ aliases: []
423
+ },
424
+ features: {
425
+ collection: "features",
426
+ title: "Features",
427
+ storageFile: "features.json",
428
+ idConvention: {
429
+ pattern: "feature.<domain-slug>.<feature-slug>",
430
+ prefix: "feature",
431
+ example: "feature.orders.cancel-order"
432
+ },
433
+ schemaName: "Feature",
434
+ schema: featureSchema,
435
+ guideFilePath: "packages/core/src/knowledge/guides/features.md",
436
+ aliases: []
437
+ },
438
+ business_rules: {
439
+ collection: "business_rules",
440
+ title: "Business Rules",
441
+ storageFile: "business-rules.json",
442
+ idConvention: {
443
+ pattern: "rule.<domain-slug>.<rule-slug>",
444
+ prefix: "rule",
445
+ example: "rule.orders.no-direct-cancel-paid-order"
446
+ },
447
+ schemaName: "BusinessRule",
448
+ schema: businessRuleSchema,
449
+ guideFilePath: "packages/core/src/knowledge/guides/business-rules.md",
450
+ aliases: ["business-rules"]
451
+ },
452
+ constraints: {
453
+ collection: "constraints",
454
+ title: "Constraints",
455
+ storageFile: "constraints.json",
456
+ idConvention: {
457
+ pattern: "constraint.<domain-slug>.<constraint-slug>",
458
+ prefix: "constraint",
459
+ example: "constraint.orders.erp-sync-one-way"
460
+ },
461
+ schemaName: "Constraint",
462
+ schema: constraintSchema,
463
+ guideFilePath: "packages/core/src/knowledge/guides/constraints.md",
464
+ aliases: []
465
+ },
466
+ rationales: {
467
+ collection: "rationales",
468
+ title: "Rationales",
469
+ storageFile: "rationales.json",
470
+ idConvention: {
471
+ pattern: "why.<domain-slug>.<rationale-slug>",
472
+ prefix: "why",
473
+ example: "why.orders.refund-required-for-paid-order"
474
+ },
475
+ schemaName: "Rationale",
476
+ schema: rationaleSchema,
477
+ guideFilePath: "packages/core/src/knowledge/guides/rationales.md",
478
+ aliases: []
479
+ },
480
+ evidence: {
481
+ collection: "evidence",
482
+ title: "Evidence",
483
+ storageFile: "evidence.json",
484
+ idConvention: {
485
+ pattern: "ev.<domain-slug>.<evidence-slug>",
486
+ prefix: "ev",
487
+ example: "ev.orders.cancel-disabled-paid"
488
+ },
489
+ schemaName: "Evidence",
490
+ schema: evidenceSchema,
491
+ guideFilePath: "packages/core/src/knowledge/guides/evidence.md",
492
+ aliases: []
493
+ },
494
+ questions: {
495
+ collection: "questions",
496
+ title: "Questions",
497
+ storageFile: "questions.json",
498
+ idConvention: {
499
+ pattern: "q.<domain-slug>.<question-slug>",
500
+ prefix: "q",
501
+ example: "q.orders.paid-cancel-rationale"
502
+ },
503
+ schemaName: "Question",
504
+ schema: questionSchema,
505
+ guideFilePath: "packages/core/src/knowledge/guides/questions.md",
506
+ aliases: []
507
+ },
508
+ conflicts: {
509
+ collection: "conflicts",
510
+ title: "Conflicts",
511
+ storageFile: "conflicts.json",
512
+ idConvention: {
513
+ pattern: "conflict.<domain-slug>.<conflict-slug>",
514
+ prefix: "conflict",
515
+ example: "conflict.invoice-domain"
516
+ },
517
+ schemaName: "Conflict",
518
+ schema: conflictSchema,
519
+ guideFilePath: "packages/core/src/knowledge/guides/conflicts.md",
520
+ aliases: []
521
+ }
522
+ };
523
+ var KNOWLEDGE_EXTRACTION_TYPES = Object.values(
524
+ KNOWLEDGE_EXTRACTION_TYPE_REGISTRY
525
+ );
526
+ var KNOWLEDGE_EXTRACTION_TYPE_LOOKUP = new Map(
527
+ KNOWLEDGE_EXTRACTION_TYPES.flatMap((definition) => [
528
+ [definition.collection, definition],
529
+ ...definition.aliases.map((alias) => [alias, definition])
530
+ ])
531
+ );
532
+
533
+ // packages/core/src/knowledge/extraction-resources.ts
534
+ import { z as z2 } from "zod/v4";
535
+
536
+ // packages/core/src/knowledge/loader.ts
537
+ import { existsSync } from "node:fs";
538
+ import { readFile } from "node:fs/promises";
539
+ import { basename, join } from "node:path";
540
+ import { z as z3 } from "zod/v4";
541
+
542
+ // packages/core/src/knowledge/root.ts
543
+ import { resolve } from "node:path";
544
+ function resolveKnowledgeRootFromEnv(envValue, cwd = process.cwd()) {
545
+ return envValue ? resolve(cwd, envValue) : resolve(cwd, "ez-know");
546
+ }
547
+
548
+ // packages/core/src/knowledge/loader.ts
549
+ var COLLECTION_SCHEMAS = {
550
+ domains: z3.array(domainSchema),
551
+ entities: z3.array(entitySchema),
552
+ relationships: z3.array(relationshipSchema),
553
+ capabilities: z3.array(capabilitySchema),
554
+ features: z3.array(featureSchema),
555
+ business_rules: z3.array(businessRuleSchema),
556
+ constraints: z3.array(constraintSchema),
557
+ rationales: z3.array(rationaleSchema),
558
+ evidence: z3.array(evidenceSchema),
559
+ questions: z3.array(questionSchema),
560
+ conflicts: z3.array(conflictSchema)
561
+ };
562
+ var COLLECTION_DEFINITIONS = KNOWLEDGE_EXTRACTION_TYPE_REGISTRY;
563
+ var KnowledgeStoreLoadError = class extends Error {
564
+ diagnostics;
565
+ constructor(message, diagnostics) {
566
+ super(message);
567
+ this.name = "KnowledgeStoreLoadError";
568
+ this.diagnostics = diagnostics;
569
+ }
570
+ };
571
+ function resolveKnowledgeRoot(envValue, cwd = process.cwd()) {
572
+ return resolveKnowledgeRootFromEnv(envValue, cwd);
573
+ }
574
+ async function discoverDomainFolders(rootDir) {
575
+ const { readdir: readdir2 } = await import("node:fs/promises");
576
+ const discovered = [];
577
+ const entries = await readdir2(rootDir, { withFileTypes: true });
578
+ for (const entry of entries) {
579
+ if (entry.isDirectory() && !entry.name.startsWith(".")) {
580
+ discovered.push(join(rootDir, entry.name));
581
+ }
582
+ }
583
+ discovered.sort((left, right) => left.localeCompare(right));
584
+ return discovered;
585
+ }
586
+ function readDiagnostic(kind, path, message, id) {
587
+ return {
588
+ kind,
589
+ path,
590
+ id,
591
+ message
592
+ };
593
+ }
594
+ async function readCanonicalFile(filePath, schema) {
595
+ let raw;
596
+ try {
597
+ raw = await readFile(filePath, "utf8");
598
+ } catch (error) {
599
+ throw new KnowledgeStoreLoadError(
600
+ `Failed to read canonical knowledge file: ${filePath}`,
601
+ [
602
+ readDiagnostic(
603
+ "missing_domain_file",
604
+ filePath,
605
+ `Unable to read canonical file: ${filePath}`
606
+ )
607
+ ]
608
+ );
609
+ }
610
+ let parsed;
611
+ try {
612
+ parsed = JSON.parse(raw);
613
+ } catch (error) {
614
+ throw new KnowledgeStoreLoadError(
615
+ `Invalid JSON in canonical knowledge file: ${filePath}`,
616
+ [readDiagnostic("invalid_json", filePath, `Invalid JSON in ${filePath}`)]
617
+ );
618
+ }
619
+ try {
620
+ return schema.parse(parsed);
621
+ } catch (error) {
622
+ throw new KnowledgeStoreLoadError(
623
+ `Invalid knowledge schema in canonical file: ${filePath}`,
624
+ [
625
+ readDiagnostic(
626
+ "invalid_shape",
627
+ filePath,
628
+ `Invalid canonical file shape in ${filePath}`
629
+ )
630
+ ]
631
+ );
632
+ }
633
+ }
634
+ function validateIdPrefix(collection, id, domainSlug) {
635
+ const definition = COLLECTION_DEFINITIONS[collection];
636
+ if (collection === "domains") {
637
+ const expectedId = `domain.${domainSlug}`;
638
+ if (id !== expectedId) {
639
+ return `Expected ${id} to equal ${expectedId}`;
640
+ }
641
+ return void 0;
642
+ }
643
+ const expectedPrefix = `${definition.idConvention.prefix}.${domainSlug}.`;
644
+ if (!id.startsWith(expectedPrefix)) {
645
+ return `Expected ${id} to start with ${expectedPrefix}`;
646
+ }
647
+ return void 0;
648
+ }
649
+ function getDomainId(domainSlug) {
650
+ return `domain.${domainSlug}`;
651
+ }
652
+ function emptyStore(rootDir) {
653
+ return {
654
+ rootDir,
655
+ sourceFiles: [],
656
+ domains: [],
657
+ entities: [],
658
+ relationships: [],
659
+ capabilities: [],
660
+ features: [],
661
+ business_rules: [],
662
+ constraints: [],
663
+ rationales: [],
664
+ evidence: [],
665
+ questions: [],
666
+ conflicts: [],
667
+ byCollection: {
668
+ domains: /* @__PURE__ */ new Map(),
669
+ entities: /* @__PURE__ */ new Map(),
670
+ relationships: /* @__PURE__ */ new Map(),
671
+ capabilities: /* @__PURE__ */ new Map(),
672
+ features: /* @__PURE__ */ new Map(),
673
+ business_rules: /* @__PURE__ */ new Map(),
674
+ constraints: /* @__PURE__ */ new Map(),
675
+ rationales: /* @__PURE__ */ new Map(),
676
+ evidence: /* @__PURE__ */ new Map(),
677
+ questions: /* @__PURE__ */ new Map(),
678
+ conflicts: /* @__PURE__ */ new Map()
679
+ },
680
+ byId: /* @__PURE__ */ new Map(),
681
+ reverseReferences: /* @__PURE__ */ new Map(),
682
+ diagnostics: []
683
+ };
684
+ }
685
+ function addRecord(store, collection, record, diagnostics) {
686
+ if (store.byId.has(record.id)) {
687
+ diagnostics.push(
688
+ readDiagnostic(
689
+ "duplicate_id",
690
+ void 0,
691
+ `Duplicate knowledge id detected: ${record.id}`,
692
+ record.id
693
+ )
694
+ );
695
+ return;
696
+ }
697
+ store.byId.set(record.id, record);
698
+ store.byCollection[collection].set(record.id, record);
699
+ store[collection].push(record);
700
+ }
701
+ function validateFolderRecordIds(collection, records, domainSlug, diagnostics) {
702
+ for (const record of records) {
703
+ const message = validateIdPrefix(collection, record.id, domainSlug);
704
+ if (message) {
705
+ diagnostics.push(
706
+ readDiagnostic("invalid_domain_id", void 0, message, record.id)
707
+ );
708
+ }
709
+ }
710
+ }
711
+ function collectReferenceIds(record) {
712
+ if ("relationship_type" in record) {
713
+ return [
714
+ record.from_entity_id,
715
+ record.to_entity_id
716
+ ];
717
+ }
718
+ if ("business_definition" in record) {
719
+ const entity = record;
720
+ return [
721
+ ...entity.domain_ids,
722
+ ...entity.relationship_ids,
723
+ ...entity.capability_ids,
724
+ ...entity.feature_ids,
725
+ ...entity.rule_ids
726
+ ];
727
+ }
728
+ if ("behavior_type" in record) {
729
+ const rule = record;
730
+ return [
731
+ ...rule.applies_to.domain_ids ?? [],
732
+ ...rule.applies_to.entity_ids ?? [],
733
+ ...rule.applies_to.capability_ids ?? [],
734
+ ...rule.applies_to.feature_ids ?? [],
735
+ ...rule.related_constraint_ids,
736
+ ...rule.rationale_ids
737
+ ];
738
+ }
739
+ if ("constraint_type" in record) {
740
+ const constraint = record;
741
+ return [
742
+ ...constraint.applies_to.domain_ids ?? [],
743
+ ...constraint.applies_to.entity_ids ?? [],
744
+ ...constraint.applies_to.capability_ids ?? [],
745
+ ...constraint.applies_to.feature_ids ?? [],
746
+ ...constraint.applies_to.business_rule_ids ?? []
747
+ ];
748
+ }
749
+ if ("parent_capability_ids" in record) {
750
+ const capability = record;
751
+ return [
752
+ ...capability.domain_ids,
753
+ ...capability.entity_ids,
754
+ ...capability.parent_capability_ids,
755
+ ...capability.child_capability_ids,
756
+ ...capability.feature_ids
757
+ ];
758
+ }
759
+ if ("rule_ids" in record && "constraint_ids" in record) {
760
+ const feature = record;
761
+ return [
762
+ ...feature.domain_ids,
763
+ ...feature.capability_ids,
764
+ ...feature.entity_ids,
765
+ ...feature.rule_ids,
766
+ ...feature.constraint_ids
767
+ ];
768
+ }
769
+ if ("entity_ids" in record && "capability_ids" in record && "why_it_exists" in record && !("business_definition" in record) && !("parent_capability_ids" in record) && !("constraint_ids" in record) && !("rule_ids" in record)) {
770
+ const domain = record;
771
+ return [...domain.entity_ids, ...domain.capability_ids];
772
+ }
773
+ if ("explains" in record) {
774
+ return record.explains;
775
+ }
776
+ if ("source_type" in record) {
777
+ return record.supports;
778
+ }
779
+ if ("priority" in record) {
780
+ const question = record;
781
+ return [...question.related_ids, ...question.evidence_ids];
782
+ }
783
+ const conflict = record;
784
+ return [
785
+ ...conflict.related_ids,
786
+ ...conflict.evidence_ids,
787
+ ...conflict.questions
788
+ ];
789
+ }
790
+ function buildReverseReferences(store) {
791
+ for (const record of store.byId.values()) {
792
+ const references = collectReferenceIds(record);
793
+ for (const referenceId of references) {
794
+ const reverse = store.reverseReferences.get(referenceId) ?? [];
795
+ reverse.push(record.id);
796
+ store.reverseReferences.set(referenceId, reverse);
797
+ }
798
+ }
799
+ }
800
+ function validateReferences(store, diagnostics) {
801
+ for (const record of store.byId.values()) {
802
+ for (const referenceId of collectReferenceIds(record)) {
803
+ if (!store.byId.has(referenceId)) {
804
+ diagnostics.push(
805
+ readDiagnostic(
806
+ "invalid_reference",
807
+ void 0,
808
+ `Unknown reference id "${referenceId}" from record "${record.id}"`,
809
+ record.id
810
+ )
811
+ );
812
+ }
813
+ }
814
+ }
815
+ }
816
+ function finalizeStore(store, diagnostics) {
817
+ store.diagnostics = diagnostics;
818
+ if (diagnostics.length > 0) {
819
+ throw new KnowledgeStoreLoadError(
820
+ diagnostics.map((diagnostic) => diagnostic.message).join("; "),
821
+ diagnostics
822
+ );
823
+ }
824
+ return store;
825
+ }
826
+ async function loadKnowledgeStoreFromRoot(rootDir) {
827
+ if (!existsSync(rootDir)) {
828
+ throw new KnowledgeStoreLoadError(
829
+ `Knowledge root does not exist: ${rootDir}`,
830
+ [
831
+ readDiagnostic(
832
+ "missing_root",
833
+ rootDir,
834
+ `Knowledge root does not exist: ${rootDir}`
835
+ )
836
+ ]
837
+ );
838
+ }
839
+ const diagnostics = [];
840
+ const store = emptyStore(rootDir);
841
+ const domainFolders = await discoverDomainFolders(rootDir);
842
+ const sourceFiles = [];
843
+ for (const domainFolder of domainFolders) {
844
+ const domainSlug = basename(domainFolder);
845
+ const domainFile = join(
846
+ domainFolder,
847
+ COLLECTION_DEFINITIONS.domains.storageFile
848
+ );
849
+ if (!existsSync(domainFile)) {
850
+ diagnostics.push(
851
+ readDiagnostic(
852
+ "missing_domain_file",
853
+ domainFile,
854
+ `Missing canonical domain file: ${domainFile}`
855
+ )
856
+ );
857
+ continue;
858
+ }
859
+ const domain = await readCanonicalFile(
860
+ domainFile,
861
+ domainSchema
862
+ );
863
+ sourceFiles.push(domainFile);
864
+ validateFolderRecordIds("domains", [domain], domainSlug, diagnostics);
865
+ const domainId = getDomainId(domainSlug);
866
+ if (domain.id !== domainId) {
867
+ diagnostics.push(
868
+ readDiagnostic(
869
+ "invalid_domain_id",
870
+ domainFile,
871
+ `Domain id "${domain.id}" must match folder slug "${domainSlug}"`,
872
+ domain.id
873
+ )
874
+ );
875
+ }
876
+ addRecord(store, "domains", domain, diagnostics);
877
+ for (const collection of Object.keys(
878
+ COLLECTION_DEFINITIONS
879
+ )) {
880
+ if (collection === "domains") {
881
+ continue;
882
+ }
883
+ const fileName = COLLECTION_DEFINITIONS[collection].storageFile;
884
+ const filePath = join(domainFolder, fileName);
885
+ if (!existsSync(filePath)) {
886
+ continue;
887
+ }
888
+ const parsed = await readCanonicalFile(
889
+ filePath,
890
+ COLLECTION_SCHEMAS[collection]
891
+ );
892
+ sourceFiles.push(filePath);
893
+ validateFolderRecordIds(
894
+ collection,
895
+ parsed,
896
+ domainSlug,
897
+ diagnostics
898
+ );
899
+ for (const record of parsed) {
900
+ addRecord(store, collection, record, diagnostics);
901
+ }
902
+ }
903
+ }
904
+ store.sourceFiles = sourceFiles.sort(
905
+ (left, right) => left.localeCompare(right)
906
+ );
907
+ buildReverseReferences(store);
908
+ validateReferences(store, diagnostics);
909
+ return finalizeStore(store, diagnostics);
910
+ }
911
+ async function loadKnowledgeStoreFromEnv(envValue, cwd = process.cwd()) {
912
+ const rootDir = resolveKnowledgeRoot(envValue, cwd);
913
+ if (!rootDir || !existsSync(rootDir)) {
914
+ return void 0;
915
+ }
916
+ return loadKnowledgeStoreFromRoot(rootDir);
917
+ }
918
+
919
+ // packages/core/src/knowledge/patch/storage.ts
920
+ import { existsSync as existsSync2 } from "node:fs";
921
+ import { mkdir, readFile as readFile2, readdir, writeFile } from "node:fs/promises";
922
+ import { isAbsolute, join as join3, normalize, resolve as resolve4, sep } from "node:path";
923
+ import "zod/v4";
924
+
925
+ // packages/core/src/knowledge/patch/constants.ts
926
+ var KNOWLEDGE_PATCH_SCHEMA_VERSION = 1;
927
+ var KNOWLEDGE_PATCH_FOLDER_NAME = ".patches";
928
+ var SUPPORTED_OPERATION_TYPES = Object.keys(
929
+ KNOWLEDGE_EXTRACTION_TYPE_REGISTRY
930
+ );
931
+ var supportedOperationTypeSet = new Set(
932
+ SUPPORTED_OPERATION_TYPES
933
+ );
934
+
935
+ // packages/core/src/knowledge/patch/paths.ts
936
+ import { join as join2 } from "node:path";
937
+ function getKnowledgeRoot(envValue, cwd = process.cwd()) {
938
+ return resolveKnowledgeRootFromEnv(envValue, cwd);
939
+ }
940
+ function resolveKnowledgePatchRoot(envValue, cwd = process.cwd()) {
941
+ return join2(getKnowledgeRoot(envValue, cwd), KNOWLEDGE_PATCH_FOLDER_NAME);
942
+ }
943
+ function resolveKnowledgePatchDirectory(envValue, patchId, cwd = process.cwd()) {
944
+ return join2(resolveKnowledgePatchRoot(envValue, cwd), patchId);
945
+ }
946
+ function patchMetadataPath(patchDir) {
947
+ return join2(patchDir, "patch.json");
948
+ }
949
+ function patchOperationsPath(patchDir) {
950
+ return join2(patchDir, "operations.json");
951
+ }
952
+
953
+ // packages/core/src/knowledge/patch/schemas.ts
954
+ import { z as z4 } from "zod/v4";
955
+ var patchStatusSchema = z4.enum(["draft", "closed"]);
956
+ var canonicalOperationTypeSchema = z4.string().trim().min(1).superRefine((value, ctx) => {
957
+ if (!supportedOperationTypeSet.has(value)) {
958
+ ctx.addIssue({
959
+ code: "custom",
960
+ message: `Unsupported patch operation type "${value}". Supported types: ${SUPPORTED_OPERATION_TYPES.join(
961
+ ", "
962
+ )}`
963
+ });
964
+ }
965
+ }).transform((value) => value);
966
+ var knowledgePatchMetadataSchema = z4.object({
967
+ id: z4.string().min(1),
968
+ title: z4.string().trim().min(1),
969
+ description: z4.string().trim().min(1).optional(),
970
+ status: patchStatusSchema,
971
+ rootFolder: z4.string().trim().min(1),
972
+ omittedFiles: z4.array(
973
+ z4.object({
974
+ path: z4.string().trim().min(1),
975
+ reason: z4.string().trim().min(1)
976
+ })
977
+ ),
978
+ schemaVersion: z4.literal(KNOWLEDGE_PATCH_SCHEMA_VERSION),
979
+ createdAt: z4.string().datetime({ offset: true }),
980
+ updatedAt: z4.string().datetime({ offset: true }),
981
+ closedAt: z4.string().datetime({ offset: true }).optional()
982
+ });
983
+ var operationBaseSchema = z4.object({
984
+ id: z4.string().min(1),
985
+ type: canonicalOperationTypeSchema,
986
+ domain: z4.string().trim().min(1)
987
+ });
988
+ var knowledgePatchCreateOperationSchema = operationBaseSchema.extend({
989
+ kind: z4.literal("create"),
990
+ payload: z4.record(z4.string(), z4.unknown())
991
+ });
992
+ var knowledgePatchUpdateOperationSchema = operationBaseSchema.extend({
993
+ kind: z4.literal("update"),
994
+ targetId: z4.string().min(1),
995
+ payload: z4.record(z4.string(), z4.unknown())
996
+ });
997
+ var knowledgePatchDeleteOperationSchema = operationBaseSchema.extend({
998
+ kind: z4.literal("delete"),
999
+ targetId: z4.string().min(1),
1000
+ reason: z4.string().trim().min(1)
1001
+ });
1002
+ var knowledgePatchOperationSchema = z4.discriminatedUnion("kind", [
1003
+ knowledgePatchCreateOperationSchema,
1004
+ knowledgePatchUpdateOperationSchema,
1005
+ knowledgePatchDeleteOperationSchema
1006
+ ]);
1007
+ var knowledgePatchOperationsEnvelopeSchema = z4.object({
1008
+ schemaVersion: z4.literal(KNOWLEDGE_PATCH_SCHEMA_VERSION),
1009
+ operations: z4.array(knowledgePatchOperationSchema)
1010
+ });
1011
+ var knowledgePatchDiagnosticSchema = z4.object({
1012
+ severity: z4.enum(["error", "critical"]),
1013
+ code: z4.string(),
1014
+ message: z4.string(),
1015
+ patchId: z4.string().optional(),
1016
+ operationId: z4.string().optional(),
1017
+ targetId: z4.string().optional(),
1018
+ path: z4.array(z4.union([z4.string(), z4.number()])).optional(),
1019
+ supportedTypes: z4.array(z4.string()).optional()
1020
+ });
1021
+ var knowledgePatchValidationResultSchema = z4.object({
1022
+ valid: z4.boolean(),
1023
+ fingerprint: z4.string().optional(),
1024
+ diagnostics: z4.array(knowledgePatchDiagnosticSchema),
1025
+ operationCount: z4.number().int().nonnegative(),
1026
+ appliedOperationIds: z4.array(z4.string()),
1027
+ affectedFiles: z4.array(z4.string())
1028
+ });
1029
+ var knowledgePatchApplyApprovalSchema = z4.object({
1030
+ approved: z4.boolean(),
1031
+ validationFingerprint: z4.string().min(1)
1032
+ });
1033
+ var createPatchInputSchema = z4.object({
1034
+ title: z4.string().trim().min(1),
1035
+ description: z4.string().trim().min(1).optional(),
1036
+ rootFolder: z4.string().trim().min(1),
1037
+ omittedFiles: z4.array(
1038
+ z4.object({
1039
+ path: z4.string().trim().min(1),
1040
+ reason: z4.string().trim().min(1)
1041
+ })
1042
+ ).optional()
1043
+ });
1044
+ var addOperationInputSchema = z4.discriminatedUnion("kind", [
1045
+ knowledgePatchCreateOperationSchema.omit({ id: true }).extend({
1046
+ id: z4.string().min(1).optional()
1047
+ }),
1048
+ knowledgePatchUpdateOperationSchema.omit({ id: true }).extend({
1049
+ id: z4.string().min(1).optional()
1050
+ }),
1051
+ knowledgePatchDeleteOperationSchema.omit({ id: true }).extend({
1052
+ id: z4.string().min(1).optional()
1053
+ })
1054
+ ]);
1055
+ var updateOperationInputSchema = z4.object({
1056
+ operationId: z4.string().min(1),
1057
+ operation: addOperationInputSchema
1058
+ });
1059
+ var updatePatchMetadataInputSchema = z4.object({
1060
+ rootFolder: z4.string().trim().min(1).optional(),
1061
+ omittedFiles: z4.array(
1062
+ z4.object({
1063
+ path: z4.string().trim().min(1),
1064
+ reason: z4.string().trim().min(1)
1065
+ })
1066
+ )
1067
+ });
1068
+ var knowledgePatchToolInputSchema = z4.discriminatedUnion("action", [
1069
+ z4.object({
1070
+ action: z4.literal("create"),
1071
+ patch: createPatchInputSchema
1072
+ }),
1073
+ z4.object({
1074
+ action: z4.literal("list")
1075
+ }),
1076
+ z4.object({
1077
+ action: z4.literal("get"),
1078
+ patchId: z4.string().min(1)
1079
+ }),
1080
+ z4.object({
1081
+ action: z4.literal("add_operation"),
1082
+ patchId: z4.string().min(1),
1083
+ operation: addOperationInputSchema
1084
+ }),
1085
+ z4.object({
1086
+ action: z4.literal("update_operation"),
1087
+ patchId: z4.string().min(1),
1088
+ update: updateOperationInputSchema
1089
+ }),
1090
+ z4.object({
1091
+ action: z4.literal("update_metadata"),
1092
+ patchId: z4.string().min(1),
1093
+ metadata: updatePatchMetadataInputSchema
1094
+ }),
1095
+ z4.object({
1096
+ action: z4.literal("delete_operation"),
1097
+ patchId: z4.string().min(1),
1098
+ operationId: z4.string().min(1)
1099
+ }),
1100
+ z4.object({
1101
+ action: z4.literal("validate"),
1102
+ patchId: z4.string().min(1)
1103
+ }),
1104
+ z4.object({
1105
+ action: z4.literal("close"),
1106
+ patchId: z4.string().min(1)
1107
+ })
1108
+ ]);
1109
+ var knowledgePatchApplyToolInputSchema = z4.object({
1110
+ patchId: z4.string().min(1),
1111
+ approval: knowledgePatchApplyApprovalSchema
1112
+ });
1113
+
1114
+ // packages/core/src/knowledge/patch/utils.ts
1115
+ function buildDiagnostic(diagnostic) {
1116
+ return knowledgePatchDiagnosticSchema.parse(diagnostic);
1117
+ }
1118
+
1119
+ // packages/core/src/knowledge/patch/storage.ts
1120
+ async function readJsonFile(filePath, schema) {
1121
+ const raw = await readFile2(filePath, "utf8");
1122
+ const parsed = JSON.parse(raw);
1123
+ return schema.parse(parsed);
1124
+ }
1125
+ async function loadPatchStateByDir(patchDir) {
1126
+ const patch = await readJsonFile(
1127
+ patchMetadataPath(patchDir),
1128
+ knowledgePatchMetadataSchema
1129
+ );
1130
+ const envelope = await readJsonFile(
1131
+ patchOperationsPath(patchDir),
1132
+ knowledgePatchOperationsEnvelopeSchema
1133
+ );
1134
+ return {
1135
+ patch,
1136
+ operations: envelope.operations
1137
+ };
1138
+ }
1139
+ async function readKnowledgePatch(envValue, patchId, cwd = process.cwd()) {
1140
+ const patchDir = resolveKnowledgePatchDirectory(envValue, patchId, cwd);
1141
+ return loadPatchStateByDir(patchDir);
1142
+ }
1143
+ async function listKnowledgePatches(envValue, cwd = process.cwd()) {
1144
+ const patchRoot = resolveKnowledgePatchRoot(envValue, cwd);
1145
+ if (!existsSync2(patchRoot)) {
1146
+ return [];
1147
+ }
1148
+ const entries = await readdir(patchRoot, { withFileTypes: true });
1149
+ const summaries = [];
1150
+ for (const entry of entries) {
1151
+ if (!entry.isDirectory()) {
1152
+ continue;
1153
+ }
1154
+ const patchDir = join3(patchRoot, entry.name);
1155
+ const state = await loadPatchStateByDir(patchDir);
1156
+ summaries.push({
1157
+ id: state.patch.id,
1158
+ status: state.patch.status,
1159
+ title: state.patch.title,
1160
+ description: state.patch.description,
1161
+ rootFolder: state.patch.rootFolder,
1162
+ omittedFiles: state.patch.omittedFiles,
1163
+ operationCount: state.operations.length,
1164
+ createdAt: state.patch.createdAt,
1165
+ updatedAt: state.patch.updatedAt
1166
+ });
1167
+ }
1168
+ summaries.sort(
1169
+ (left, right) => left.createdAt === right.createdAt ? left.id.localeCompare(right.id) : left.createdAt.localeCompare(right.createdAt)
1170
+ );
1171
+ return summaries;
1172
+ }
1173
+
1174
+ // packages/core/src/knowledge/patch/simulation.ts
1175
+ function cloneStoreState(store) {
1176
+ const byCollection = Object.fromEntries(
1177
+ SUPPORTED_OPERATION_TYPES.map((collection) => [
1178
+ collection,
1179
+ new Map(store.byCollection[collection])
1180
+ ])
1181
+ );
1182
+ return {
1183
+ byCollection,
1184
+ byId: new Map(store.byId)
1185
+ };
1186
+ }
1187
+ function validateRecordIdForDomain(type, id, domain) {
1188
+ const definition = KNOWLEDGE_EXTRACTION_TYPE_REGISTRY[type];
1189
+ if (type === "domains") {
1190
+ const expectedId = `domain.${domain}`;
1191
+ return id === expectedId ? void 0 : `Expected domain record id "${id}" to equal "${expectedId}".`;
1192
+ }
1193
+ const expectedPrefix = `${definition.idConvention.prefix}.${domain}.`;
1194
+ return id.startsWith(expectedPrefix) ? void 0 : `Expected record id "${id}" to start with "${expectedPrefix}".`;
1195
+ }
1196
+ function collectReferenceIds2(record) {
1197
+ if ("relationship_type" in record) {
1198
+ return [
1199
+ record.from_entity_id,
1200
+ record.to_entity_id
1201
+ ];
1202
+ }
1203
+ if ("business_definition" in record) {
1204
+ const entity = record;
1205
+ return [
1206
+ ...entity.domain_ids,
1207
+ ...entity.relationship_ids,
1208
+ ...entity.capability_ids,
1209
+ ...entity.feature_ids,
1210
+ ...entity.rule_ids
1211
+ ];
1212
+ }
1213
+ if ("behavior_type" in record) {
1214
+ const rule = record;
1215
+ return [
1216
+ ...rule.applies_to.domain_ids ?? [],
1217
+ ...rule.applies_to.entity_ids ?? [],
1218
+ ...rule.applies_to.capability_ids ?? [],
1219
+ ...rule.applies_to.feature_ids ?? [],
1220
+ ...rule.related_constraint_ids,
1221
+ ...rule.rationale_ids
1222
+ ];
1223
+ }
1224
+ if ("constraint_type" in record) {
1225
+ const constraint = record;
1226
+ return [
1227
+ ...constraint.applies_to.domain_ids ?? [],
1228
+ ...constraint.applies_to.entity_ids ?? [],
1229
+ ...constraint.applies_to.capability_ids ?? [],
1230
+ ...constraint.applies_to.feature_ids ?? [],
1231
+ ...constraint.applies_to.business_rule_ids ?? []
1232
+ ];
1233
+ }
1234
+ if ("parent_capability_ids" in record) {
1235
+ const capability = record;
1236
+ return [
1237
+ ...capability.domain_ids,
1238
+ ...capability.entity_ids,
1239
+ ...capability.parent_capability_ids,
1240
+ ...capability.child_capability_ids,
1241
+ ...capability.feature_ids
1242
+ ];
1243
+ }
1244
+ if ("rule_ids" in record && "constraint_ids" in record) {
1245
+ const feature = record;
1246
+ return [
1247
+ ...feature.domain_ids,
1248
+ ...feature.capability_ids,
1249
+ ...feature.entity_ids,
1250
+ ...feature.rule_ids,
1251
+ ...feature.constraint_ids
1252
+ ];
1253
+ }
1254
+ if ("entity_ids" in record && "capability_ids" in record && "why_it_exists" in record && !("business_definition" in record) && !("parent_capability_ids" in record) && !("constraint_ids" in record) && !("rule_ids" in record)) {
1255
+ const domain = record;
1256
+ return [...domain.entity_ids, ...domain.capability_ids];
1257
+ }
1258
+ if ("explains" in record) {
1259
+ return record.explains;
1260
+ }
1261
+ if ("source_type" in record) {
1262
+ return record.supports;
1263
+ }
1264
+ if ("priority" in record) {
1265
+ const question = record;
1266
+ return [...question.related_ids, ...question.evidence_ids];
1267
+ }
1268
+ const conflict = record;
1269
+ return [
1270
+ ...conflict.related_ids,
1271
+ ...conflict.evidence_ids,
1272
+ ...conflict.questions,
1273
+ ...conflict.resolved_by_evidence_id ? [conflict.resolved_by_evidence_id] : []
1274
+ ];
1275
+ }
1276
+ function parsePatchRecord(operation, diagnostics) {
1277
+ const definition = KNOWLEDGE_EXTRACTION_TYPE_REGISTRY[operation.type];
1278
+ if (operation.kind === "delete") {
1279
+ return void 0;
1280
+ }
1281
+ const parsed = definition.schema.safeParse(operation.payload);
1282
+ if (!parsed.success) {
1283
+ diagnostics.push(
1284
+ buildDiagnostic({
1285
+ severity: "error",
1286
+ code: "invalid_payload",
1287
+ message: `Operation "${operation.id}" payload is invalid for type "${operation.type}".`,
1288
+ operationId: operation.id,
1289
+ path: ["operations", operation.id, "payload"]
1290
+ })
1291
+ );
1292
+ return void 0;
1293
+ }
1294
+ return parsed.data;
1295
+ }
1296
+ function simulateKnowledgePatch(store, operations, patchId) {
1297
+ const state = cloneStoreState(store);
1298
+ const diagnostics = [];
1299
+ const deleteTargets = [];
1300
+ const appliedOperationIds = [];
1301
+ for (const operation of operations) {
1302
+ if (!supportedOperationTypeSet.has(operation.type)) {
1303
+ diagnostics.push(
1304
+ buildDiagnostic({
1305
+ severity: "error",
1306
+ code: "invalid_type",
1307
+ message: `Unsupported patch operation type "${operation.type}".`,
1308
+ patchId,
1309
+ operationId: operation.id,
1310
+ supportedTypes: SUPPORTED_OPERATION_TYPES
1311
+ })
1312
+ );
1313
+ continue;
1314
+ }
1315
+ if (operation.kind === "delete") {
1316
+ const existing = state.byCollection[operation.type].get(
1317
+ operation.targetId
1318
+ );
1319
+ if (!existing) {
1320
+ diagnostics.push(
1321
+ buildDiagnostic({
1322
+ severity: "error",
1323
+ code: "missing_target",
1324
+ message: `Delete target "${operation.targetId}" does not exist in "${operation.type}".`,
1325
+ patchId,
1326
+ operationId: operation.id,
1327
+ targetId: operation.targetId
1328
+ })
1329
+ );
1330
+ continue;
1331
+ }
1332
+ state.byCollection[operation.type].delete(operation.targetId);
1333
+ state.byId.delete(operation.targetId);
1334
+ deleteTargets.push(operation.targetId);
1335
+ appliedOperationIds.push(operation.id);
1336
+ continue;
1337
+ }
1338
+ const parsedRecord = parsePatchRecord(operation, diagnostics);
1339
+ if (!parsedRecord) {
1340
+ continue;
1341
+ }
1342
+ const idMessage = validateRecordIdForDomain(
1343
+ operation.type,
1344
+ parsedRecord.id,
1345
+ operation.domain
1346
+ );
1347
+ if (idMessage) {
1348
+ diagnostics.push(
1349
+ buildDiagnostic({
1350
+ severity: "error",
1351
+ code: "invalid_id_convention",
1352
+ message: idMessage,
1353
+ patchId,
1354
+ operationId: operation.id,
1355
+ targetId: parsedRecord.id
1356
+ })
1357
+ );
1358
+ continue;
1359
+ }
1360
+ if (operation.kind === "create" && state.byId.has(parsedRecord.id)) {
1361
+ diagnostics.push(
1362
+ buildDiagnostic({
1363
+ severity: "error",
1364
+ code: "duplicate_id",
1365
+ message: `Create operation would duplicate existing id "${parsedRecord.id}".`,
1366
+ patchId,
1367
+ operationId: operation.id,
1368
+ targetId: parsedRecord.id
1369
+ })
1370
+ );
1371
+ continue;
1372
+ }
1373
+ if (operation.kind === "update") {
1374
+ if (parsedRecord.id !== operation.targetId) {
1375
+ diagnostics.push(
1376
+ buildDiagnostic({
1377
+ severity: "error",
1378
+ code: "update_target_mismatch",
1379
+ message: `Update payload id "${parsedRecord.id}" must match target "${operation.targetId}".`,
1380
+ patchId,
1381
+ operationId: operation.id,
1382
+ targetId: operation.targetId
1383
+ })
1384
+ );
1385
+ continue;
1386
+ }
1387
+ if (!state.byCollection[operation.type].has(operation.targetId)) {
1388
+ diagnostics.push(
1389
+ buildDiagnostic({
1390
+ severity: "error",
1391
+ code: "missing_target",
1392
+ message: `Update target "${operation.targetId}" does not exist in "${operation.type}".`,
1393
+ patchId,
1394
+ operationId: operation.id,
1395
+ targetId: operation.targetId
1396
+ })
1397
+ );
1398
+ continue;
1399
+ }
1400
+ }
1401
+ state.byCollection[operation.type].set(parsedRecord.id, parsedRecord);
1402
+ state.byId.set(parsedRecord.id, parsedRecord);
1403
+ appliedOperationIds.push(operation.id);
1404
+ }
1405
+ for (const record of state.byId.values()) {
1406
+ for (const referenceId of collectReferenceIds2(record)) {
1407
+ if (!state.byId.has(referenceId)) {
1408
+ diagnostics.push(
1409
+ buildDiagnostic({
1410
+ severity: "error",
1411
+ code: "invalid_reference",
1412
+ message: `Record "${record.id}" references unknown id "${referenceId}".`,
1413
+ patchId,
1414
+ targetId: record.id
1415
+ })
1416
+ );
1417
+ }
1418
+ }
1419
+ }
1420
+ const inboundReferenceMap = /* @__PURE__ */ new Map();
1421
+ for (const record of state.byId.values()) {
1422
+ for (const referenceId of collectReferenceIds2(record)) {
1423
+ const inbound = inboundReferenceMap.get(referenceId) ?? [];
1424
+ inbound.push(record.id);
1425
+ inboundReferenceMap.set(referenceId, inbound);
1426
+ }
1427
+ }
1428
+ for (const deleteTarget of deleteTargets) {
1429
+ const inbound = inboundReferenceMap.get(deleteTarget) ?? [];
1430
+ if (inbound.length > 0) {
1431
+ diagnostics.push(
1432
+ buildDiagnostic({
1433
+ severity: "error",
1434
+ code: "delete_has_inbound_references",
1435
+ message: `Delete target "${deleteTarget}" still has inbound references from: ${inbound.join(
1436
+ ", "
1437
+ )}`,
1438
+ patchId,
1439
+ targetId: deleteTarget
1440
+ })
1441
+ );
1442
+ }
1443
+ }
1444
+ return {
1445
+ state,
1446
+ diagnostics,
1447
+ appliedOperationIds,
1448
+ deleteTargets
1449
+ };
1450
+ }
1451
+
1452
+ // packages/core/src/knowledge/effective-state.ts
1453
+ function toSimulationStore(rootDir, sourceFiles, state) {
1454
+ const store = {
1455
+ rootDir,
1456
+ sourceFiles,
1457
+ domains: [...state.byCollection.domains.values()],
1458
+ entities: [...state.byCollection.entities.values()],
1459
+ relationships: [...state.byCollection.relationships.values()],
1460
+ capabilities: [...state.byCollection.capabilities.values()],
1461
+ features: [...state.byCollection.features.values()],
1462
+ business_rules: [...state.byCollection.business_rules.values()],
1463
+ constraints: [...state.byCollection.constraints.values()],
1464
+ rationales: [...state.byCollection.rationales.values()],
1465
+ evidence: [...state.byCollection.evidence.values()],
1466
+ questions: [...state.byCollection.questions.values()],
1467
+ conflicts: [...state.byCollection.conflicts.values()],
1468
+ byCollection: state.byCollection,
1469
+ byId: state.byId,
1470
+ reverseReferences: /* @__PURE__ */ new Map(),
1471
+ diagnostics: []
1472
+ };
1473
+ for (const record of store.byId.values()) {
1474
+ for (const referenceId of collectReferenceIds2(record)) {
1475
+ const reverse = store.reverseReferences.get(referenceId) ?? [];
1476
+ reverse.push(record.id);
1477
+ store.reverseReferences.set(referenceId, reverse);
1478
+ }
1479
+ }
1480
+ return store;
1481
+ }
1482
+ function selectOrderedPatches(patches, options) {
1483
+ const visiblePatches = options.includeAllStatuses ? patches : patches.filter((patch) => patch.status === "draft");
1484
+ if (!options.selectedPatchId) {
1485
+ return visiblePatches;
1486
+ }
1487
+ const selectedIndex = visiblePatches.findIndex(
1488
+ (patch) => patch.id === options.selectedPatchId
1489
+ );
1490
+ if (selectedIndex === -1) {
1491
+ throw new Error(`Patch "${options.selectedPatchId}" was not found.`);
1492
+ }
1493
+ const endIndex = options.includeSelectedPatch === false ? selectedIndex : selectedIndex + 1;
1494
+ return visiblePatches.slice(0, endIndex);
1495
+ }
1496
+ async function composeEffectiveKnowledgeState(store, envValue, options = {}, cwd = process.cwd()) {
1497
+ const orderedPatches = selectOrderedPatches(
1498
+ await listKnowledgePatches(envValue, cwd),
1499
+ options
1500
+ );
1501
+ let currentState = store;
1502
+ const provenance = /* @__PURE__ */ new Map();
1503
+ const diagnostics = [];
1504
+ for (const patch of orderedPatches) {
1505
+ const patchState = await readKnowledgePatch(envValue, patch.id, cwd);
1506
+ const simulation = simulateKnowledgePatch(
1507
+ currentState,
1508
+ patchState.operations,
1509
+ patch.id
1510
+ );
1511
+ diagnostics.push(...simulation.diagnostics);
1512
+ for (const operationId of simulation.appliedOperationIds) {
1513
+ const operation = patchState.operations.find(
1514
+ (entry) => entry.id === operationId
1515
+ );
1516
+ if (!operation || operation.kind === "delete") {
1517
+ continue;
1518
+ }
1519
+ const recordId = operation.kind === "update" ? operation.targetId : operation.payload.id;
1520
+ const existing = provenance.get(recordId);
1521
+ const patchIds = new Set(existing?.patchIds ?? []);
1522
+ patchIds.add(patch.id);
1523
+ provenance.set(recordId, {
1524
+ patchIds: [...patchIds],
1525
+ patched: true
1526
+ });
1527
+ }
1528
+ currentState = toSimulationStore(
1529
+ store.rootDir,
1530
+ store.sourceFiles,
1531
+ simulation.state
1532
+ );
1533
+ }
1534
+ return {
1535
+ store: currentState,
1536
+ patches: orderedPatches,
1537
+ patchIds: orderedPatches.map((patch) => patch.id),
1538
+ provenance,
1539
+ diagnostics
1540
+ };
1541
+ }
1542
+ async function loadEffectiveKnowledgeStoreFromRoot(rootDir, options = {}) {
1543
+ const store = await loadKnowledgeStoreFromRoot(rootDir);
1544
+ return composeEffectiveKnowledgeState(store, rootDir, options);
1545
+ }
1546
+
1547
+ // packages/core/src/knowledge/graphql.ts
1548
+ import {
1549
+ GraphQLBoolean,
1550
+ GraphQLFloat,
1551
+ GraphQLID,
1552
+ GraphQLList,
1553
+ GraphQLObjectType,
1554
+ GraphQLSchema,
1555
+ GraphQLString,
1556
+ graphql
1557
+ } from "graphql";
1558
+ function stringifyValue(value) {
1559
+ if (value === void 0 || value === null) {
1560
+ return null;
1561
+ }
1562
+ return typeof value === "string" ? value : JSON.stringify(value);
1563
+ }
1564
+ var confidenceType = new GraphQLObjectType({
1565
+ name: "Confidence",
1566
+ fields: {
1567
+ score: { type: GraphQLFloat },
1568
+ level: { type: GraphQLString },
1569
+ reason: { type: GraphQLString }
1570
+ }
1571
+ });
1572
+ var locationType = new GraphQLObjectType({
1573
+ name: "EvidenceLocation",
1574
+ fields: {
1575
+ path: { type: GraphQLString },
1576
+ symbol: { type: GraphQLString },
1577
+ route: { type: GraphQLString },
1578
+ api: { type: GraphQLString },
1579
+ query: { type: GraphQLString }
1580
+ }
1581
+ });
1582
+ var evidenceType = new GraphQLObjectType({
1583
+ name: "Evidence",
1584
+ fields: () => ({
1585
+ id: { type: GraphQLID },
1586
+ source_type: { type: GraphQLString },
1587
+ description: { type: GraphQLString },
1588
+ location: { type: locationType },
1589
+ supports: { type: new GraphQLList(GraphQLID) },
1590
+ excerpt: { type: GraphQLString },
1591
+ confidence: { type: confidenceType }
1592
+ })
1593
+ });
1594
+ var entityTechnicalRepresentationType = new GraphQLObjectType({
1595
+ name: "EntityTechnicalRepresentation",
1596
+ fields: {
1597
+ kind: { type: GraphQLString },
1598
+ name: { type: GraphQLString },
1599
+ location_hint: { type: GraphQLString }
1600
+ }
1601
+ });
1602
+ var entityType = new GraphQLObjectType({
1603
+ name: "Entity",
1604
+ fields: () => ({
1605
+ id: { type: GraphQLID },
1606
+ name: { type: GraphQLString },
1607
+ business_definition: { type: GraphQLString },
1608
+ description: { type: GraphQLString },
1609
+ purpose: { type: GraphQLString },
1610
+ aliases: { type: new GraphQLList(GraphQLString) },
1611
+ ambiguous_terms: { type: new GraphQLList(GraphQLString) },
1612
+ technical_representations: {
1613
+ type: new GraphQLList(entityTechnicalRepresentationType)
1614
+ },
1615
+ domain_ids: { type: new GraphQLList(GraphQLID) },
1616
+ state_values: { type: new GraphQLList(GraphQLString) },
1617
+ relationship_ids: { type: new GraphQLList(GraphQLID) },
1618
+ capability_ids: { type: new GraphQLList(GraphQLID) },
1619
+ feature_ids: { type: new GraphQLList(GraphQLID) },
1620
+ rule_ids: { type: new GraphQLList(GraphQLID) },
1621
+ domains: {
1622
+ type: new GraphQLList(domainType),
1623
+ resolve: (entity, _args, context) => resolveByIds(context, "domains", entity.domain_ids)
1624
+ },
1625
+ relationships: {
1626
+ type: new GraphQLList(entityRelationshipType),
1627
+ resolve: (entity, _args, context) => resolveByIds(context, "relationships", entity.relationship_ids)
1628
+ },
1629
+ capabilities: {
1630
+ type: new GraphQLList(capabilityType),
1631
+ resolve: (entity, _args, context) => resolveByIds(context, "capabilities", entity.capability_ids)
1632
+ },
1633
+ features: {
1634
+ type: new GraphQLList(featureType),
1635
+ resolve: (entity, _args, context) => resolveByIds(context, "features", entity.feature_ids)
1636
+ },
1637
+ business_rules: {
1638
+ type: new GraphQLList(businessRuleType),
1639
+ resolve: (entity, _args, context) => resolveByIds(context, "business_rules", entity.rule_ids)
1640
+ },
1641
+ certainty: { type: GraphQLString },
1642
+ confidence: { type: confidenceType }
1643
+ })
1644
+ });
1645
+ var ruleConditionType = new GraphQLObjectType({
1646
+ name: "RuleCondition",
1647
+ fields: {
1648
+ subject: { type: GraphQLString },
1649
+ field: { type: GraphQLString },
1650
+ operator: { type: GraphQLString },
1651
+ value: {
1652
+ type: GraphQLString,
1653
+ resolve: (condition) => stringifyValue(condition.value)
1654
+ }
1655
+ }
1656
+ });
1657
+ var ruleTriggerType = new GraphQLObjectType({
1658
+ name: "RuleTrigger",
1659
+ fields: {
1660
+ actor: { type: GraphQLString },
1661
+ action: { type: GraphQLString },
1662
+ subject: { type: GraphQLString },
1663
+ field: { type: GraphQLString },
1664
+ operator: { type: GraphQLString },
1665
+ value: {
1666
+ type: GraphQLString,
1667
+ resolve: (trigger) => stringifyValue(trigger.value)
1668
+ }
1669
+ }
1670
+ });
1671
+ var ruleEffectType = new GraphQLObjectType({
1672
+ name: "RuleEffect",
1673
+ fields: {
1674
+ effect: { type: GraphQLString },
1675
+ action: { type: GraphQLString },
1676
+ message: { type: GraphQLString },
1677
+ target_state: { type: GraphQLString },
1678
+ value: {
1679
+ type: GraphQLString,
1680
+ resolve: (effect) => stringifyValue(effect.value)
1681
+ }
1682
+ }
1683
+ });
1684
+ var businessRuleConditionType = new GraphQLObjectType({
1685
+ name: "BusinessRuleCondition",
1686
+ fields: {
1687
+ given: { type: new GraphQLList(ruleConditionType) },
1688
+ when: { type: new GraphQLList(ruleTriggerType) },
1689
+ then: { type: new GraphQLList(ruleEffectType) }
1690
+ }
1691
+ });
1692
+ var businessRuleAppliesToType = new GraphQLObjectType({
1693
+ name: "BusinessRuleAppliesTo",
1694
+ fields: {
1695
+ domain_ids: { type: new GraphQLList(GraphQLID) },
1696
+ entity_ids: { type: new GraphQLList(GraphQLID) },
1697
+ capability_ids: { type: new GraphQLList(GraphQLID) },
1698
+ feature_ids: { type: new GraphQLList(GraphQLID) }
1699
+ }
1700
+ });
1701
+ var businessRuleEnforcementType = new GraphQLObjectType({
1702
+ name: "BusinessRuleEnforcement",
1703
+ fields: {
1704
+ level: { type: GraphQLString },
1705
+ description: { type: GraphQLString }
1706
+ }
1707
+ });
1708
+ var businessRuleType = new GraphQLObjectType({
1709
+ name: "BusinessRule",
1710
+ fields: () => ({
1711
+ id: { type: GraphQLID },
1712
+ name: { type: GraphQLString },
1713
+ statement: { type: GraphQLString },
1714
+ rule_type: { type: GraphQLString },
1715
+ behavior_type: { type: GraphQLString },
1716
+ applies_to: { type: businessRuleAppliesToType },
1717
+ condition: { type: businessRuleConditionType },
1718
+ enforcement: { type: businessRuleEnforcementType },
1719
+ related_constraint_ids: { type: new GraphQLList(GraphQLID) },
1720
+ rationale_ids: { type: new GraphQLList(GraphQLID) },
1721
+ certainty: { type: GraphQLString },
1722
+ confidence: { type: confidenceType }
1723
+ })
1724
+ });
1725
+ var constraintCauseType = new GraphQLObjectType({
1726
+ name: "ConstraintCause",
1727
+ fields: {
1728
+ source: { type: GraphQLString },
1729
+ source_type: { type: GraphQLString },
1730
+ description: { type: GraphQLString }
1731
+ }
1732
+ });
1733
+ var constraintImpactType = new GraphQLObjectType({
1734
+ name: "ConstraintImpact",
1735
+ fields: {
1736
+ affected_change_types: { type: new GraphQLList(GraphQLString) },
1737
+ severity: { type: GraphQLString },
1738
+ description: { type: GraphQLString }
1739
+ }
1740
+ });
1741
+ var constraintAppliesToType = new GraphQLObjectType({
1742
+ name: "ConstraintAppliesTo",
1743
+ fields: {
1744
+ domain_ids: { type: new GraphQLList(GraphQLID) },
1745
+ entity_ids: { type: new GraphQLList(GraphQLID) },
1746
+ capability_ids: { type: new GraphQLList(GraphQLID) },
1747
+ feature_ids: { type: new GraphQLList(GraphQLID) },
1748
+ business_rule_ids: { type: new GraphQLList(GraphQLID) }
1749
+ }
1750
+ });
1751
+ var constraintWorkaroundType = new GraphQLObjectType({
1752
+ name: "ConstraintWorkaround",
1753
+ fields: {
1754
+ exists: { type: GraphQLString },
1755
+ description: { type: GraphQLString }
1756
+ }
1757
+ });
1758
+ var constraintRemovabilityType = new GraphQLObjectType({
1759
+ name: "ConstraintRemovability",
1760
+ fields: {
1761
+ can_be_removed_by_refactor: { type: GraphQLString },
1762
+ requires: { type: new GraphQLList(GraphQLString) },
1763
+ risk: { type: GraphQLString }
1764
+ }
1765
+ });
1766
+ var constraintType = new GraphQLObjectType({
1767
+ name: "Constraint",
1768
+ fields: () => ({
1769
+ id: { type: GraphQLID },
1770
+ name: { type: GraphQLString },
1771
+ description: { type: GraphQLString },
1772
+ constraint_type: { type: GraphQLString },
1773
+ cause: { type: constraintCauseType },
1774
+ impact: { type: constraintImpactType },
1775
+ applies_to: { type: constraintAppliesToType },
1776
+ workaround: { type: constraintWorkaroundType },
1777
+ removability: { type: constraintRemovabilityType },
1778
+ certainty: { type: GraphQLString },
1779
+ confidence: { type: confidenceType }
1780
+ })
1781
+ });
1782
+ var rationaleType = new GraphQLObjectType({
1783
+ name: "Rationale",
1784
+ fields: () => ({
1785
+ id: { type: GraphQLID },
1786
+ statement: { type: GraphQLString },
1787
+ explains: { type: new GraphQLList(GraphQLID) },
1788
+ certainty: { type: GraphQLString },
1789
+ confidence: { type: confidenceType }
1790
+ })
1791
+ });
1792
+ var questionType = new GraphQLObjectType({
1793
+ name: "Question",
1794
+ fields: () => ({
1795
+ id: { type: GraphQLID },
1796
+ question: { type: GraphQLString },
1797
+ category: { type: GraphQLString },
1798
+ reason: { type: GraphQLString },
1799
+ impact: { type: GraphQLString },
1800
+ related_ids: { type: new GraphQLList(GraphQLID) },
1801
+ evidence_ids: { type: new GraphQLList(GraphQLID) },
1802
+ priority: { type: GraphQLString },
1803
+ status: { type: GraphQLString },
1804
+ answer: { type: GraphQLString },
1805
+ answered_by: { type: GraphQLString },
1806
+ answered_at: { type: GraphQLString }
1807
+ })
1808
+ });
1809
+ var conflictType = new GraphQLObjectType({
1810
+ name: "Conflict",
1811
+ fields: () => ({
1812
+ id: { type: GraphQLID },
1813
+ type: { type: GraphQLString },
1814
+ description: { type: GraphQLString },
1815
+ related_ids: { type: new GraphQLList(GraphQLID) },
1816
+ evidence_ids: { type: new GraphQLList(GraphQLID) },
1817
+ status: { type: GraphQLString },
1818
+ questions: { type: new GraphQLList(GraphQLID) },
1819
+ resolution: { type: GraphQLString },
1820
+ resolved_by_evidence_id: { type: GraphQLID }
1821
+ })
1822
+ });
1823
+ var domainType = new GraphQLObjectType({
1824
+ name: "Domain",
1825
+ fields: () => ({
1826
+ id: { type: GraphQLID },
1827
+ name: { type: GraphQLString },
1828
+ purpose: { type: GraphQLString },
1829
+ why_it_exists: { type: GraphQLString },
1830
+ entity_ids: { type: new GraphQLList(GraphQLID) },
1831
+ capability_ids: { type: new GraphQLList(GraphQLID) },
1832
+ entities: {
1833
+ type: new GraphQLList(entityType),
1834
+ resolve: (domain, _args, context) => resolveByIds(context, "entities", domain.entity_ids)
1835
+ },
1836
+ capabilities: {
1837
+ type: new GraphQLList(capabilityType),
1838
+ resolve: (domain, _args, context) => resolveByIds(context, "capabilities", domain.capability_ids)
1839
+ },
1840
+ certainty: { type: GraphQLString },
1841
+ confidence: { type: confidenceType }
1842
+ })
1843
+ });
1844
+ var entityRelationshipType = new GraphQLObjectType({
1845
+ name: "EntityRelationship",
1846
+ fields: () => ({
1847
+ id: { type: GraphQLID },
1848
+ from_entity_id: { type: GraphQLID },
1849
+ to_entity_id: { type: GraphQLID },
1850
+ relationship_type: { type: GraphQLString },
1851
+ description: { type: GraphQLString },
1852
+ from_entity: {
1853
+ type: entityType,
1854
+ resolve: (relationship, _args, context) => resolveByIds(context, "entities", [relationship.from_entity_id])[0] ?? null
1855
+ },
1856
+ to_entity: {
1857
+ type: entityType,
1858
+ resolve: (relationship, _args, context) => resolveByIds(context, "entities", [relationship.to_entity_id])[0] ?? null
1859
+ },
1860
+ certainty: { type: GraphQLString },
1861
+ confidence: { type: confidenceType }
1862
+ })
1863
+ });
1864
+ var capabilityType = new GraphQLObjectType({
1865
+ name: "Capability",
1866
+ fields: () => ({
1867
+ id: { type: GraphQLID },
1868
+ name: { type: GraphQLString },
1869
+ description: { type: GraphQLString },
1870
+ why_it_exists: { type: GraphQLString },
1871
+ domain_ids: { type: new GraphQLList(GraphQLID) },
1872
+ entity_ids: { type: new GraphQLList(GraphQLID) },
1873
+ parent_capability_ids: { type: new GraphQLList(GraphQLID) },
1874
+ child_capability_ids: { type: new GraphQLList(GraphQLID) },
1875
+ feature_ids: { type: new GraphQLList(GraphQLID) },
1876
+ domains: {
1877
+ type: new GraphQLList(domainType),
1878
+ resolve: (capability, _args, context) => resolveByIds(context, "domains", capability.domain_ids)
1879
+ },
1880
+ entities: {
1881
+ type: new GraphQLList(entityType),
1882
+ resolve: (capability, _args, context) => resolveByIds(context, "entities", capability.entity_ids)
1883
+ },
1884
+ parent_capabilities: {
1885
+ type: new GraphQLList(capabilityType),
1886
+ resolve: (capability, _args, context) => resolveByIds(context, "capabilities", capability.parent_capability_ids)
1887
+ },
1888
+ child_capabilities: {
1889
+ type: new GraphQLList(capabilityType),
1890
+ resolve: (capability, _args, context) => resolveByIds(context, "capabilities", capability.child_capability_ids)
1891
+ },
1892
+ features: {
1893
+ type: new GraphQLList(featureType),
1894
+ resolve: (capability, _args, context) => resolveByIds(context, "features", capability.feature_ids)
1895
+ },
1896
+ certainty: { type: GraphQLString },
1897
+ confidence: { type: confidenceType }
1898
+ })
1899
+ });
1900
+ var featureType = new GraphQLObjectType({
1901
+ name: "Feature",
1902
+ fields: () => ({
1903
+ id: { type: GraphQLID },
1904
+ name: { type: GraphQLString },
1905
+ description: { type: GraphQLString },
1906
+ purpose: { type: GraphQLString },
1907
+ why_it_exists: { type: GraphQLString },
1908
+ domain_ids: { type: new GraphQLList(GraphQLID) },
1909
+ capability_ids: { type: new GraphQLList(GraphQLID) },
1910
+ entity_ids: { type: new GraphQLList(GraphQLID) },
1911
+ rule_ids: { type: new GraphQLList(GraphQLID) },
1912
+ constraint_ids: { type: new GraphQLList(GraphQLID) },
1913
+ domains: {
1914
+ type: new GraphQLList(domainType),
1915
+ resolve: (feature, _args, context) => resolveByIds(context, "domains", feature.domain_ids)
1916
+ },
1917
+ capabilities: {
1918
+ type: new GraphQLList(capabilityType),
1919
+ resolve: (feature, _args, context) => resolveByIds(context, "capabilities", feature.capability_ids)
1920
+ },
1921
+ entities: {
1922
+ type: new GraphQLList(entityType),
1923
+ resolve: (feature, _args, context) => resolveByIds(context, "entities", feature.entity_ids)
1924
+ },
1925
+ business_rules: {
1926
+ type: new GraphQLList(businessRuleType),
1927
+ resolve: (feature, _args, context) => resolveByIds(context, "business_rules", feature.rule_ids)
1928
+ },
1929
+ constraints: {
1930
+ type: new GraphQLList(constraintType),
1931
+ resolve: (feature, _args, context) => resolveByIds(context, "constraints", feature.constraint_ids)
1932
+ },
1933
+ certainty: { type: GraphQLString },
1934
+ confidence: { type: confidenceType }
1935
+ })
1936
+ });
1937
+ function resolveCollection(store, collection) {
1938
+ if (!store) {
1939
+ return [];
1940
+ }
1941
+ return store[collection];
1942
+ }
1943
+ function resolveByIds(store, collection, ids) {
1944
+ if (!store || !ids?.length) {
1945
+ return [];
1946
+ }
1947
+ const typedCollection = store.byCollection[collection];
1948
+ return ids.map((id) => typedCollection.get(id)).filter((item) => item !== void 0);
1949
+ }
1950
+ var queryType = new GraphQLObjectType({
1951
+ name: "Query",
1952
+ fields: () => ({
1953
+ store_available: {
1954
+ type: GraphQLBoolean,
1955
+ resolve: (_source, _args, context) => Boolean(context)
1956
+ },
1957
+ domains: {
1958
+ type: new GraphQLList(domainType),
1959
+ resolve: (_source, _args, context) => resolveCollection(context, "domains")
1960
+ },
1961
+ domain: {
1962
+ type: domainType,
1963
+ args: {
1964
+ id: { type: GraphQLID }
1965
+ },
1966
+ resolve: (_source, args, context) => context?.byCollection.domains.get(args.id) ?? null
1967
+ },
1968
+ entities: {
1969
+ type: new GraphQLList(entityType),
1970
+ resolve: (_source, _args, context) => resolveCollection(context, "entities")
1971
+ },
1972
+ entity: {
1973
+ type: entityType,
1974
+ args: {
1975
+ id: { type: GraphQLID }
1976
+ },
1977
+ resolve: (_source, args, context) => context?.byCollection.entities.get(args.id) ?? null
1978
+ },
1979
+ relationships: {
1980
+ type: new GraphQLList(entityRelationshipType),
1981
+ resolve: (_source, _args, context) => resolveCollection(context, "relationships")
1982
+ },
1983
+ capabilities: {
1984
+ type: new GraphQLList(capabilityType),
1985
+ resolve: (_source, _args, context) => resolveCollection(context, "capabilities")
1986
+ },
1987
+ capability: {
1988
+ type: capabilityType,
1989
+ args: {
1990
+ id: { type: GraphQLID }
1991
+ },
1992
+ resolve: (_source, args, context) => context?.byCollection.capabilities.get(args.id) ?? null
1993
+ },
1994
+ features: {
1995
+ type: new GraphQLList(featureType),
1996
+ resolve: (_source, _args, context) => resolveCollection(context, "features")
1997
+ },
1998
+ feature: {
1999
+ type: featureType,
2000
+ args: {
2001
+ id: { type: GraphQLID }
2002
+ },
2003
+ resolve: (_source, args, context) => context?.byCollection.features.get(args.id) ?? null
2004
+ },
2005
+ business_rules: {
2006
+ type: new GraphQLList(businessRuleType),
2007
+ resolve: (_source, _args, context) => resolveCollection(context, "business_rules")
2008
+ },
2009
+ business_rule: {
2010
+ type: businessRuleType,
2011
+ args: {
2012
+ id: { type: GraphQLID }
2013
+ },
2014
+ resolve: (_source, args, context) => context?.byCollection.business_rules.get(args.id) ?? null
2015
+ },
2016
+ constraints: {
2017
+ type: new GraphQLList(constraintType),
2018
+ resolve: (_source, _args, context) => resolveCollection(context, "constraints")
2019
+ },
2020
+ constraint: {
2021
+ type: constraintType,
2022
+ args: {
2023
+ id: { type: GraphQLID }
2024
+ },
2025
+ resolve: (_source, args, context) => context?.byCollection.constraints.get(args.id) ?? null
2026
+ },
2027
+ rationales: {
2028
+ type: new GraphQLList(rationaleType),
2029
+ resolve: (_source, _args, context) => resolveCollection(context, "rationales")
2030
+ },
2031
+ rationale: {
2032
+ type: rationaleType,
2033
+ args: {
2034
+ id: { type: GraphQLID }
2035
+ },
2036
+ resolve: (_source, args, context) => context?.byCollection.rationales.get(args.id) ?? null
2037
+ },
2038
+ evidence: {
2039
+ type: new GraphQLList(evidenceType),
2040
+ resolve: (_source, _args, context) => resolveCollection(context, "evidence")
2041
+ },
2042
+ question: {
2043
+ type: questionType,
2044
+ args: {
2045
+ id: { type: GraphQLID }
2046
+ },
2047
+ resolve: (_source, args, context) => context?.byCollection.questions.get(args.id) ?? null
2048
+ },
2049
+ questions: {
2050
+ type: new GraphQLList(questionType),
2051
+ resolve: (_source, _args, context) => resolveCollection(context, "questions")
2052
+ },
2053
+ conflict: {
2054
+ type: conflictType,
2055
+ args: {
2056
+ id: { type: GraphQLID }
2057
+ },
2058
+ resolve: (_source, args, context) => context?.byCollection.conflicts.get(args.id) ?? null
2059
+ },
2060
+ conflicts: {
2061
+ type: new GraphQLList(conflictType),
2062
+ resolve: (_source, _args, context) => resolveCollection(context, "conflicts")
2063
+ }
2064
+ })
2065
+ });
2066
+ var knowledgeGraphSchema = new GraphQLSchema({
2067
+ query: queryType
2068
+ });
2069
+
2070
+ // packages/core/src/knowledge/patch/scope-audit.ts
2071
+ import { z as z6 } from "zod/v4";
2072
+ var compareScopeWithEvidenceInputSchema = z6.object({
2073
+ patchId: z6.string().min(1),
2074
+ rootFolder: z6.string().trim().min(1).optional()
2075
+ });
2076
+ var compareScopeWithEvidenceResultSchema = z6.object({
2077
+ patchId: z6.string().min(1),
2078
+ rootFolder: z6.string().min(1),
2079
+ scopeFiles: z6.array(z6.string()),
2080
+ coveredFiles: z6.array(z6.string()),
2081
+ omittedFiles: z6.array(
2082
+ z6.object({
2083
+ path: z6.string(),
2084
+ reason: z6.string()
2085
+ })
2086
+ ),
2087
+ uncoveredFiles: z6.array(z6.string()),
2088
+ outOfRootEvidenceFiles: z6.array(z6.string()),
2089
+ message: z6.string()
2090
+ });
2091
+
2092
+ // packages/core/src/knowledge/schema-discovery.ts
2093
+ import {
2094
+ isAbstractType,
2095
+ isCompositeType,
2096
+ isListType,
2097
+ isNonNullType,
2098
+ isObjectType,
2099
+ isScalarType,
2100
+ isUnionType
2101
+ } from "graphql";
2102
+
2103
+ // packages/rest/src/constants.ts
2104
+ var REST_SERVICE_NAME = "ez-know-rest";
2105
+ var REST_V1_PREFIX = "/api/v1";
2106
+ var REST_OPENAPI_PATH = "/api/openapi.json";
2107
+ var REST_DOCS_PATH = "/api/docs";
2108
+ var REST_HEALTH_PATH = "/api/health";
2109
+ var REST_PATCHES_ROUTE = "patches";
2110
+ var REST_PATCH_PREVIEW_ROUTE = "patches/:patchId/preview";
2111
+ var REST_PATCH_PREVIEW_PATH = "patches/{patchId}/preview";
2112
+ var REST_COLLECTIONS = [
2113
+ { route: "domains", collection: "domains", label: "Domains" },
2114
+ { route: "entities", collection: "entities", label: "Entities" },
2115
+ {
2116
+ route: "relationships",
2117
+ collection: "relationships",
2118
+ label: "Relationships"
2119
+ },
2120
+ {
2121
+ route: "capabilities",
2122
+ collection: "capabilities",
2123
+ label: "Capabilities"
2124
+ },
2125
+ { route: "features", collection: "features", label: "Features" },
2126
+ {
2127
+ route: "business-rules",
2128
+ collection: "business_rules",
2129
+ label: "Business rules"
2130
+ },
2131
+ { route: "constraints", collection: "constraints", label: "Constraints" },
2132
+ { route: "rationales", collection: "rationales", label: "Rationales" },
2133
+ { route: "evidence", collection: "evidence", label: "Evidence" },
2134
+ { route: "questions", collection: "questions", label: "Questions" },
2135
+ { route: "conflicts", collection: "conflicts", label: "Conflicts" }
2136
+ ];
2137
+ var REST_COLLECTION_ROUTE_LOOKUP = new Map(
2138
+ REST_COLLECTIONS.map((definition) => [definition.route, definition])
2139
+ );
2140
+
2141
+ // packages/rest/src/docs.ts
2142
+ function buildSwaggerUiHtml(openApiPath = REST_OPENAPI_PATH) {
2143
+ return `<!doctype html>
2144
+ <html lang="en">
2145
+ <head>
2146
+ <meta charset="utf-8" />
2147
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
2148
+ <title>ez-know REST API</title>
2149
+ <link
2150
+ rel="stylesheet"
2151
+ href="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css"
2152
+ />
2153
+ <style>
2154
+ html,
2155
+ body {
2156
+ margin: 0;
2157
+ padding: 0;
2158
+ background: #0f172a;
2159
+ }
2160
+
2161
+ #swagger-ui {
2162
+ background: #fff;
2163
+ }
2164
+ </style>
2165
+ </head>
2166
+ <body>
2167
+ <div id="swagger-ui"></div>
2168
+ <script src="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js" crossorigin="anonymous"></script>
2169
+ <script>
2170
+ window.ui = SwaggerUIBundle({
2171
+ url: '${openApiPath}',
2172
+ dom_id: '#swagger-ui',
2173
+ deepLinking: true,
2174
+ presets: [SwaggerUIBundle.presets.apis],
2175
+ });
2176
+ </script>
2177
+ </body>
2178
+ </html>`;
2179
+ }
2180
+
2181
+ // packages/rest/src/openapi.ts
2182
+ import {
2183
+ extendZodWithOpenApi as extendZodWithOpenApi2,
2184
+ OpenAPIRegistry,
2185
+ OpenApiGeneratorV3
2186
+ } from "@asteasolutions/zod-to-openapi";
2187
+ import { z as z7 } from "zod/v4";
2188
+
2189
+ // packages/rest/src/schema-registry.ts
2190
+ var REST_COLLECTION_SCHEMA_REGISTRY = {
2191
+ domains: {
2192
+ itemName: "Domain",
2193
+ itemSchema: domainSchema,
2194
+ collectionResponseName: "DomainCollectionResponse",
2195
+ itemResponseName: "DomainItemResponse"
2196
+ },
2197
+ entities: {
2198
+ itemName: "Entity",
2199
+ itemSchema: entitySchema,
2200
+ collectionResponseName: "EntityCollectionResponse",
2201
+ itemResponseName: "EntityItemResponse"
2202
+ },
2203
+ relationships: {
2204
+ itemName: "EntityRelationship",
2205
+ itemSchema: relationshipSchema,
2206
+ collectionResponseName: "EntityRelationshipCollectionResponse",
2207
+ itemResponseName: "EntityRelationshipItemResponse"
2208
+ },
2209
+ capabilities: {
2210
+ itemName: "Capability",
2211
+ itemSchema: capabilitySchema,
2212
+ collectionResponseName: "CapabilityCollectionResponse",
2213
+ itemResponseName: "CapabilityItemResponse"
2214
+ },
2215
+ features: {
2216
+ itemName: "Feature",
2217
+ itemSchema: featureSchema,
2218
+ collectionResponseName: "FeatureCollectionResponse",
2219
+ itemResponseName: "FeatureItemResponse"
2220
+ },
2221
+ business_rules: {
2222
+ itemName: "BusinessRule",
2223
+ itemSchema: businessRuleSchema,
2224
+ collectionResponseName: "BusinessRuleCollectionResponse",
2225
+ itemResponseName: "BusinessRuleItemResponse"
2226
+ },
2227
+ constraints: {
2228
+ itemName: "Constraint",
2229
+ itemSchema: constraintSchema,
2230
+ collectionResponseName: "ConstraintCollectionResponse",
2231
+ itemResponseName: "ConstraintItemResponse"
2232
+ },
2233
+ rationales: {
2234
+ itemName: "Rationale",
2235
+ itemSchema: rationaleSchema,
2236
+ collectionResponseName: "RationaleCollectionResponse",
2237
+ itemResponseName: "RationaleItemResponse"
2238
+ },
2239
+ evidence: {
2240
+ itemName: "Evidence",
2241
+ itemSchema: evidenceSchema,
2242
+ collectionResponseName: "EvidenceCollectionResponse",
2243
+ itemResponseName: "EvidenceItemResponse"
2244
+ },
2245
+ questions: {
2246
+ itemName: "Question",
2247
+ itemSchema: questionSchema,
2248
+ collectionResponseName: "QuestionCollectionResponse",
2249
+ itemResponseName: "QuestionItemResponse"
2250
+ },
2251
+ conflicts: {
2252
+ itemName: "Conflict",
2253
+ itemSchema: conflictSchema,
2254
+ collectionResponseName: "ConflictCollectionResponse",
2255
+ itemResponseName: "ConflictItemResponse"
2256
+ }
2257
+ };
2258
+ function getRestCollectionSchemaDefinition(collection) {
2259
+ return REST_COLLECTION_SCHEMA_REGISTRY[collection];
2260
+ }
2261
+ var REST_CONFIDENCE_SCHEMA = confidenceSchema;
2262
+ var REST_CERTAINTY_SCHEMA = certaintySchema;
2263
+
2264
+ // packages/rest/src/openapi.ts
2265
+ extendZodWithOpenApi2(z7);
2266
+ var openApiRegistry = new OpenAPIRegistry();
2267
+ var restErrorResponseSchema = openApiRegistry.register(
2268
+ "RestErrorResponse",
2269
+ z7.object({
2270
+ error: z7.object({
2271
+ code: z7.string(),
2272
+ message: z7.string()
2273
+ })
2274
+ }).openapi({
2275
+ description: "Standard REST error envelope."
2276
+ })
2277
+ );
2278
+ var restHealthResponseSchema = openApiRegistry.register(
2279
+ "RestHealthResponse",
2280
+ z7.object({
2281
+ service: z7.string(),
2282
+ status: z7.literal("ok"),
2283
+ storeAvailable: z7.boolean()
2284
+ }).openapi({
2285
+ description: "Service health payload."
2286
+ })
2287
+ );
2288
+ var restPatchSummarySchema = openApiRegistry.register(
2289
+ "RestPatchSummary",
2290
+ z7.object({
2291
+ id: z7.string(),
2292
+ status: z7.string(),
2293
+ title: z7.string(),
2294
+ description: z7.string().optional(),
2295
+ rootFolder: z7.string(),
2296
+ omittedFiles: z7.array(
2297
+ z7.object({
2298
+ path: z7.string(),
2299
+ reason: z7.string()
2300
+ })
2301
+ ),
2302
+ operationCount: z7.number().int().min(0),
2303
+ createdAt: z7.string(),
2304
+ updatedAt: z7.string()
2305
+ }).openapi({
2306
+ description: "Patch inventory summary."
2307
+ })
2308
+ );
2309
+ var restPatchProvenanceEntrySchema = openApiRegistry.register(
2310
+ "RestPatchProvenanceEntry",
2311
+ z7.object({
2312
+ patchIds: z7.array(z7.string()),
2313
+ patched: z7.boolean()
2314
+ }).openapi({
2315
+ description: "Patch provenance for a previewed record."
2316
+ })
2317
+ );
2318
+ var restPatchFacetItemSchema = openApiRegistry.register(
2319
+ "RestPatchFacetItem",
2320
+ z7.object({
2321
+ id: z7.string(),
2322
+ label: z7.string(),
2323
+ patched: z7.boolean(),
2324
+ provenancePatchIds: z7.array(z7.string())
2325
+ }).openapi({
2326
+ description: "Patch-aware facet option."
2327
+ })
2328
+ );
2329
+ var confidenceRef = openApiRegistry.register(
2330
+ "Confidence",
2331
+ REST_CONFIDENCE_SCHEMA
2332
+ );
2333
+ var certaintyRef = openApiRegistry.register(
2334
+ "Certainty",
2335
+ REST_CERTAINTY_SCHEMA
2336
+ );
2337
+ var restOpenApiDocumentSchema = openApiRegistry.register(
2338
+ "RestOpenApiDocument",
2339
+ z7.record(z7.string(), z7.unknown())
2340
+ );
2341
+ var previewCollectionResponseSchemas = /* @__PURE__ */ new Map();
2342
+ for (const collection of REST_COLLECTIONS) {
2343
+ const schemaDefinition = getRestCollectionSchemaDefinition(
2344
+ collection.collection
2345
+ );
2346
+ const schemaShape = schemaDefinition.itemSchema.shape;
2347
+ const itemSchemaSource = schemaShape && "certainty" in schemaShape && "confidence" in schemaShape ? schemaDefinition.itemSchema.extend({
2348
+ certainty: certaintyRef,
2349
+ confidence: confidenceRef
2350
+ }) : schemaShape && "confidence" in schemaShape ? schemaDefinition.itemSchema.extend({
2351
+ confidence: confidenceRef
2352
+ }) : schemaDefinition.itemSchema;
2353
+ const itemSchema = openApiRegistry.register(
2354
+ schemaDefinition.itemName,
2355
+ itemSchemaSource
2356
+ );
2357
+ const previewItemSchema = openApiRegistry.register(
2358
+ `${schemaDefinition.itemName}PreviewRecord`,
2359
+ itemSchemaSource.extend({
2360
+ patched: z7.boolean(),
2361
+ provenancePatchIds: z7.array(z7.string())
2362
+ })
2363
+ );
2364
+ const collectionResponseSchema = openApiRegistry.register(
2365
+ schemaDefinition.collectionResponseName,
2366
+ z7.object({
2367
+ items: z7.array(itemSchema),
2368
+ count: z7.number().int().min(0)
2369
+ }).openapi({
2370
+ description: `${schemaDefinition.itemName} collection response.`
2371
+ })
2372
+ );
2373
+ const previewCollectionResponseSchema = openApiRegistry.register(
2374
+ `${schemaDefinition.itemName}PreviewCollectionResponse`,
2375
+ z7.object({
2376
+ items: z7.array(previewItemSchema),
2377
+ count: z7.number().int().min(0)
2378
+ }).openapi({
2379
+ description: `${schemaDefinition.itemName} preview collection response.`
2380
+ })
2381
+ );
2382
+ previewCollectionResponseSchemas.set(
2383
+ collection.collection,
2384
+ previewCollectionResponseSchema
2385
+ );
2386
+ const itemResponseSchema = openApiRegistry.register(
2387
+ schemaDefinition.itemResponseName,
2388
+ z7.object({
2389
+ item: itemSchema
2390
+ }).openapi({
2391
+ description: `${schemaDefinition.itemName} item response.`
2392
+ })
2393
+ );
2394
+ openApiRegistry.registerPath({
2395
+ method: "get",
2396
+ path: `${REST_V1_PREFIX}/${collection.route}`,
2397
+ summary: `List ${collection.label.toLowerCase()}`,
2398
+ responses: {
2399
+ 200: {
2400
+ description: "Default Response",
2401
+ content: {
2402
+ "application/json": {
2403
+ schema: collectionResponseSchema
2404
+ }
2405
+ }
2406
+ },
2407
+ 404: {
2408
+ description: "Default Response",
2409
+ content: {
2410
+ "application/json": {
2411
+ schema: restErrorResponseSchema
2412
+ }
2413
+ }
2414
+ },
2415
+ 503: {
2416
+ description: "Default Response",
2417
+ content: {
2418
+ "application/json": {
2419
+ schema: restErrorResponseSchema
2420
+ }
2421
+ }
2422
+ }
2423
+ }
2424
+ });
2425
+ openApiRegistry.registerPath({
2426
+ method: "get",
2427
+ path: `${REST_V1_PREFIX}/${collection.route}/{id}`,
2428
+ summary: `Get ${collection.label.toLowerCase()} by id`,
2429
+ request: {
2430
+ params: z7.object({
2431
+ id: z7.string()
2432
+ })
2433
+ },
2434
+ responses: {
2435
+ 200: {
2436
+ description: "Default Response",
2437
+ content: {
2438
+ "application/json": {
2439
+ schema: itemResponseSchema
2440
+ }
2441
+ }
2442
+ },
2443
+ 404: {
2444
+ description: "Default Response",
2445
+ content: {
2446
+ "application/json": {
2447
+ schema: restErrorResponseSchema
2448
+ }
2449
+ }
2450
+ },
2451
+ 503: {
2452
+ description: "Default Response",
2453
+ content: {
2454
+ "application/json": {
2455
+ schema: restErrorResponseSchema
2456
+ }
2457
+ }
2458
+ }
2459
+ }
2460
+ });
2461
+ }
2462
+ var restPatchInventoryResponseSchema = openApiRegistry.register(
2463
+ "RestPatchInventoryResponse",
2464
+ z7.object({
2465
+ items: z7.array(restPatchSummarySchema),
2466
+ count: z7.number().int().min(0)
2467
+ }).openapi({
2468
+ description: "Patch inventory response."
2469
+ })
2470
+ );
2471
+ var restPatchPreviewResponseSchema = openApiRegistry.register(
2472
+ "RestPatchPreviewResponse",
2473
+ z7.object({
2474
+ selectedPatchId: z7.string(),
2475
+ prefixPatchIds: z7.array(z7.string()),
2476
+ patches: z7.array(restPatchSummarySchema),
2477
+ provenance: z7.record(z7.string(), restPatchProvenanceEntrySchema),
2478
+ facets: z7.object({
2479
+ domains: z7.array(restPatchFacetItemSchema),
2480
+ entities: z7.array(restPatchFacetItemSchema)
2481
+ }).strict(),
2482
+ collections: z7.object({
2483
+ domains: previewCollectionResponseSchemas.get("domains"),
2484
+ entities: previewCollectionResponseSchemas.get("entities"),
2485
+ relationships: previewCollectionResponseSchemas.get("relationships"),
2486
+ capabilities: previewCollectionResponseSchemas.get("capabilities"),
2487
+ features: previewCollectionResponseSchemas.get("features"),
2488
+ business_rules: previewCollectionResponseSchemas.get("business_rules"),
2489
+ constraints: previewCollectionResponseSchemas.get("constraints"),
2490
+ rationales: previewCollectionResponseSchemas.get("rationales"),
2491
+ evidence: previewCollectionResponseSchemas.get("evidence"),
2492
+ questions: previewCollectionResponseSchemas.get("questions"),
2493
+ conflicts: previewCollectionResponseSchemas.get("conflicts")
2494
+ }).strict()
2495
+ }).openapi({
2496
+ description: "Patch-aware preview snapshot response."
2497
+ })
2498
+ );
2499
+ openApiRegistry.registerPath({
2500
+ method: "get",
2501
+ path: `${REST_V1_PREFIX}/${REST_PATCHES_ROUTE}`,
2502
+ summary: "List patch inventory",
2503
+ responses: {
2504
+ 200: {
2505
+ description: "Default Response",
2506
+ content: {
2507
+ "application/json": {
2508
+ schema: restPatchInventoryResponseSchema
2509
+ }
2510
+ }
2511
+ },
2512
+ 404: {
2513
+ description: "Default Response",
2514
+ content: {
2515
+ "application/json": {
2516
+ schema: restErrorResponseSchema
2517
+ }
2518
+ }
2519
+ }
2520
+ }
2521
+ });
2522
+ openApiRegistry.registerPath({
2523
+ method: "get",
2524
+ path: `${REST_V1_PREFIX}/${REST_PATCH_PREVIEW_PATH}`,
2525
+ summary: "Preview a patch prefix",
2526
+ request: {
2527
+ params: z7.object({
2528
+ patchId: z7.string()
2529
+ })
2530
+ },
2531
+ responses: {
2532
+ 200: {
2533
+ description: "Default Response",
2534
+ content: {
2535
+ "application/json": {
2536
+ schema: restPatchPreviewResponseSchema
2537
+ }
2538
+ }
2539
+ },
2540
+ 404: {
2541
+ description: "Default Response",
2542
+ content: {
2543
+ "application/json": {
2544
+ schema: restErrorResponseSchema
2545
+ }
2546
+ }
2547
+ },
2548
+ 503: {
2549
+ description: "Default Response",
2550
+ content: {
2551
+ "application/json": {
2552
+ schema: restErrorResponseSchema
2553
+ }
2554
+ }
2555
+ }
2556
+ }
2557
+ });
2558
+ openApiRegistry.registerPath({
2559
+ method: "get",
2560
+ path: REST_HEALTH_PATH,
2561
+ summary: "Service health",
2562
+ responses: {
2563
+ 200: {
2564
+ description: "Default Response",
2565
+ content: {
2566
+ "application/json": {
2567
+ schema: restHealthResponseSchema
2568
+ }
2569
+ }
2570
+ }
2571
+ }
2572
+ });
2573
+ openApiRegistry.registerPath({
2574
+ method: "get",
2575
+ path: REST_OPENAPI_PATH,
2576
+ summary: "OpenAPI document",
2577
+ responses: {
2578
+ 200: {
2579
+ description: "Default Response",
2580
+ content: {
2581
+ "application/json": {
2582
+ schema: restOpenApiDocumentSchema
2583
+ }
2584
+ }
2585
+ }
2586
+ }
2587
+ });
2588
+ openApiRegistry.registerPath({
2589
+ method: "get",
2590
+ path: REST_DOCS_PATH,
2591
+ summary: "Swagger UI",
2592
+ responses: {
2593
+ 200: {
2594
+ description: "Default Response",
2595
+ content: {
2596
+ "text/html": {
2597
+ schema: z7.string()
2598
+ }
2599
+ }
2600
+ }
2601
+ }
2602
+ });
2603
+ function buildRestOpenApiDocument() {
2604
+ return new OpenApiGeneratorV3(openApiRegistry.definitions).generateDocument({
2605
+ openapi: "3.1.0",
2606
+ info: {
2607
+ title: "ez-know REST API",
2608
+ version: "0.1.0",
2609
+ description: "Read-only HTTP interface for loaded ez-know knowledge collections."
2610
+ },
2611
+ servers: [{ url: "/" }]
2612
+ });
2613
+ }
2614
+ var REST_OPENAPI_DOCUMENT = buildRestOpenApiDocument();
2615
+
2616
+ // packages/rest/src/preview.ts
2617
+ function buildPreviewRecord(record, provenance) {
2618
+ return {
2619
+ ...structuredClone(record),
2620
+ patched: Boolean(provenance?.patched),
2621
+ provenancePatchIds: provenance?.patchIds ?? []
2622
+ };
2623
+ }
2624
+ function buildFacetItem(record, provenance) {
2625
+ const label = "name" in record && typeof record.name === "string" ? record.name : "question" in record && typeof record.question === "string" ? record.question : record.description ?? "";
2626
+ return {
2627
+ id: record.id,
2628
+ label,
2629
+ patched: Boolean(provenance?.patched),
2630
+ provenancePatchIds: provenance?.patchIds ?? []
2631
+ };
2632
+ }
2633
+ function buildCollectionPreview(records, provenance) {
2634
+ const items = records.map(
2635
+ (record) => buildPreviewRecord(record, provenance.get(record.id))
2636
+ );
2637
+ return {
2638
+ items,
2639
+ count: items.length
2640
+ };
2641
+ }
2642
+ async function buildPatchInventory(envValue, cwd = process.cwd()) {
2643
+ return listKnowledgePatches(envValue, cwd);
2644
+ }
2645
+ function getCollectionNames() {
2646
+ return [
2647
+ "domains",
2648
+ "entities",
2649
+ "relationships",
2650
+ "capabilities",
2651
+ "features",
2652
+ "business_rules",
2653
+ "constraints",
2654
+ "rationales",
2655
+ "evidence",
2656
+ "questions",
2657
+ "conflicts"
2658
+ ];
2659
+ }
2660
+ function emptyPreviewCollections() {
2661
+ const emptyCollection = { items: [], count: 0 };
2662
+ return {
2663
+ domains: structuredClone(emptyCollection),
2664
+ entities: structuredClone(emptyCollection),
2665
+ relationships: structuredClone(emptyCollection),
2666
+ capabilities: structuredClone(emptyCollection),
2667
+ features: structuredClone(emptyCollection),
2668
+ business_rules: structuredClone(emptyCollection),
2669
+ constraints: structuredClone(emptyCollection),
2670
+ rationales: structuredClone(emptyCollection),
2671
+ evidence: structuredClone(emptyCollection),
2672
+ questions: structuredClone(emptyCollection),
2673
+ conflicts: structuredClone(emptyCollection)
2674
+ };
2675
+ }
2676
+ async function buildPatchPreview(selectedPatchId, knowledgeRoot) {
2677
+ const patches = await listKnowledgePatches(knowledgeRoot);
2678
+ const selectedIndex = patches.findIndex(
2679
+ (patch) => patch.id === selectedPatchId
2680
+ );
2681
+ if (selectedIndex === -1) {
2682
+ throw new Error(`Patch "${selectedPatchId}" was not found.`);
2683
+ }
2684
+ const prefixPatches = patches.slice(0, selectedIndex + 1);
2685
+ const effectiveState = await loadEffectiveKnowledgeStoreFromRoot(
2686
+ knowledgeRoot,
2687
+ { selectedPatchId }
2688
+ );
2689
+ const currentState = effectiveState.store;
2690
+ const provenanceMap = new Map(
2691
+ effectiveState.provenance.entries()
2692
+ );
2693
+ const collections = emptyPreviewCollections();
2694
+ const provenanceObject = Object.fromEntries(provenanceMap.entries());
2695
+ for (const collection of getCollectionNames()) {
2696
+ const records = currentState[collection];
2697
+ const previewCollection = buildCollectionPreview(records, provenanceMap);
2698
+ collections[collection] = previewCollection;
2699
+ }
2700
+ const domainItems = currentState.domains.map(
2701
+ (record) => buildFacetItem(record, provenanceMap.get(record.id))
2702
+ );
2703
+ const entityItems = currentState.entities.map(
2704
+ (record) => buildFacetItem(record, provenanceMap.get(record.id))
2705
+ );
2706
+ return {
2707
+ selectedPatchId,
2708
+ prefixPatchIds: effectiveState.patchIds,
2709
+ patches: prefixPatches,
2710
+ provenance: provenanceObject,
2711
+ facets: {
2712
+ domains: domainItems,
2713
+ entities: entityItems
2714
+ },
2715
+ collections
2716
+ };
2717
+ }
2718
+
2719
+ // packages/rest/src/payloads.ts
2720
+ function buildHealthPayload(serviceName, store) {
2721
+ return {
2722
+ service: serviceName,
2723
+ status: "ok",
2724
+ storeAvailable: store !== void 0
2725
+ };
2726
+ }
2727
+ function buildErrorPayload(code, message) {
2728
+ return {
2729
+ error: {
2730
+ code,
2731
+ message
2732
+ }
2733
+ };
2734
+ }
2735
+ function buildCollectionPayload(items) {
2736
+ return {
2737
+ items,
2738
+ count: items.length
2739
+ };
2740
+ }
2741
+ function buildItemPayload(item) {
2742
+ return {
2743
+ item
2744
+ };
2745
+ }
2746
+
2747
+ // packages/rest/src/schemas.ts
2748
+ var restObjectSchema = {
2749
+ type: "object",
2750
+ required: ["id"],
2751
+ properties: {
2752
+ id: {
2753
+ type: "string"
2754
+ }
2755
+ },
2756
+ additionalProperties: true
2757
+ };
2758
+ var restErrorResponseSchema2 = {
2759
+ type: "object",
2760
+ required: ["error"],
2761
+ properties: {
2762
+ error: {
2763
+ type: "object",
2764
+ required: ["code", "message"],
2765
+ properties: {
2766
+ code: { type: "string" },
2767
+ message: { type: "string" }
2768
+ },
2769
+ additionalProperties: false
2770
+ }
2771
+ },
2772
+ additionalProperties: false
2773
+ };
2774
+ var restHealthResponseSchema2 = {
2775
+ type: "object",
2776
+ required: ["service", "status", "storeAvailable"],
2777
+ properties: {
2778
+ service: { type: "string" },
2779
+ status: { type: "string", const: "ok" },
2780
+ storeAvailable: { type: "boolean" }
2781
+ },
2782
+ additionalProperties: false
2783
+ };
2784
+ var restCollectionResponseSchema = {
2785
+ type: "object",
2786
+ required: ["items", "count"],
2787
+ properties: {
2788
+ items: {
2789
+ type: "array",
2790
+ items: restObjectSchema
2791
+ },
2792
+ count: {
2793
+ type: "integer",
2794
+ minimum: 0
2795
+ }
2796
+ },
2797
+ additionalProperties: false
2798
+ };
2799
+ var restPatchSummarySchema2 = {
2800
+ type: "object",
2801
+ required: [
2802
+ "id",
2803
+ "status",
2804
+ "title",
2805
+ "rootFolder",
2806
+ "omittedFiles",
2807
+ "operationCount",
2808
+ "createdAt",
2809
+ "updatedAt"
2810
+ ],
2811
+ properties: {
2812
+ id: { type: "string" },
2813
+ status: { type: "string" },
2814
+ title: { type: "string" },
2815
+ description: { type: "string" },
2816
+ rootFolder: { type: "string" },
2817
+ omittedFiles: {
2818
+ type: "array",
2819
+ items: {
2820
+ type: "object",
2821
+ required: ["path", "reason"],
2822
+ properties: {
2823
+ path: { type: "string" },
2824
+ reason: { type: "string" }
2825
+ },
2826
+ additionalProperties: false
2827
+ }
2828
+ },
2829
+ operationCount: { type: "integer", minimum: 0 },
2830
+ createdAt: { type: "string" },
2831
+ updatedAt: { type: "string" }
2832
+ },
2833
+ additionalProperties: false
2834
+ };
2835
+ var restPatchProvenanceEntrySchema2 = {
2836
+ type: "object",
2837
+ required: ["patchIds", "patched"],
2838
+ properties: {
2839
+ patchIds: {
2840
+ type: "array",
2841
+ items: { type: "string" }
2842
+ },
2843
+ patched: { type: "boolean" }
2844
+ },
2845
+ additionalProperties: false
2846
+ };
2847
+ var restPatchFacetItemSchema2 = {
2848
+ type: "object",
2849
+ required: ["id", "label", "patched", "provenancePatchIds"],
2850
+ properties: {
2851
+ id: { type: "string" },
2852
+ label: { type: "string" },
2853
+ patched: { type: "boolean" },
2854
+ provenancePatchIds: {
2855
+ type: "array",
2856
+ items: { type: "string" }
2857
+ }
2858
+ },
2859
+ additionalProperties: false
2860
+ };
2861
+ var restPatchPreviewRecordSchema = {
2862
+ type: "object",
2863
+ required: ["patched", "provenancePatchIds"],
2864
+ properties: {
2865
+ patched: { type: "boolean" },
2866
+ provenancePatchIds: {
2867
+ type: "array",
2868
+ items: { type: "string" }
2869
+ }
2870
+ },
2871
+ additionalProperties: true
2872
+ };
2873
+ var restPatchPreviewCollectionSchema = {
2874
+ type: "object",
2875
+ required: ["items", "count"],
2876
+ properties: {
2877
+ items: {
2878
+ type: "array",
2879
+ items: restPatchPreviewRecordSchema
2880
+ },
2881
+ count: {
2882
+ type: "integer",
2883
+ minimum: 0
2884
+ }
2885
+ },
2886
+ additionalProperties: false
2887
+ };
2888
+ var restPatchInventoryResponseSchema2 = {
2889
+ type: "object",
2890
+ required: ["items", "count"],
2891
+ properties: {
2892
+ items: {
2893
+ type: "array",
2894
+ items: restPatchSummarySchema2
2895
+ },
2896
+ count: {
2897
+ type: "integer",
2898
+ minimum: 0
2899
+ }
2900
+ },
2901
+ additionalProperties: false
2902
+ };
2903
+ var restPatchPreviewResponseSchema2 = {
2904
+ type: "object",
2905
+ required: [
2906
+ "selectedPatchId",
2907
+ "prefixPatchIds",
2908
+ "patches",
2909
+ "provenance",
2910
+ "facets",
2911
+ "collections"
2912
+ ],
2913
+ properties: {
2914
+ selectedPatchId: { type: "string" },
2915
+ prefixPatchIds: {
2916
+ type: "array",
2917
+ items: { type: "string" }
2918
+ },
2919
+ patches: {
2920
+ type: "array",
2921
+ items: restPatchSummarySchema2
2922
+ },
2923
+ provenance: {
2924
+ type: "object",
2925
+ additionalProperties: restPatchProvenanceEntrySchema2
2926
+ },
2927
+ facets: {
2928
+ type: "object",
2929
+ required: ["domains", "entities"],
2930
+ properties: {
2931
+ domains: {
2932
+ type: "array",
2933
+ items: restPatchFacetItemSchema2
2934
+ },
2935
+ entities: {
2936
+ type: "array",
2937
+ items: restPatchFacetItemSchema2
2938
+ }
2939
+ },
2940
+ additionalProperties: false
2941
+ },
2942
+ collections: {
2943
+ type: "object",
2944
+ required: [
2945
+ "domains",
2946
+ "entities",
2947
+ "relationships",
2948
+ "capabilities",
2949
+ "features",
2950
+ "business_rules",
2951
+ "constraints",
2952
+ "rationales",
2953
+ "evidence",
2954
+ "questions",
2955
+ "conflicts"
2956
+ ],
2957
+ properties: {
2958
+ domains: restPatchPreviewCollectionSchema,
2959
+ entities: restPatchPreviewCollectionSchema,
2960
+ relationships: restPatchPreviewCollectionSchema,
2961
+ capabilities: restPatchPreviewCollectionSchema,
2962
+ features: restPatchPreviewCollectionSchema,
2963
+ business_rules: restPatchPreviewCollectionSchema,
2964
+ constraints: restPatchPreviewCollectionSchema,
2965
+ rationales: restPatchPreviewCollectionSchema,
2966
+ evidence: restPatchPreviewCollectionSchema,
2967
+ questions: restPatchPreviewCollectionSchema,
2968
+ conflicts: restPatchPreviewCollectionSchema
2969
+ },
2970
+ additionalProperties: false
2971
+ }
2972
+ },
2973
+ additionalProperties: false
2974
+ };
2975
+ var restItemResponseSchema = {
2976
+ type: "object",
2977
+ required: ["item"],
2978
+ properties: {
2979
+ item: restObjectSchema
2980
+ },
2981
+ additionalProperties: false
2982
+ };
2983
+ var restOpenApiDocumentSchema2 = {
2984
+ type: "object",
2985
+ additionalProperties: true
2986
+ };
2987
+
2988
+ // packages/rest/src/routes.ts
2989
+ function getCollectionRecords(store, collection) {
2990
+ return store[collection];
2991
+ }
2992
+ function getCollectionRecordById(store, collection, id) {
2993
+ return store.byCollection[collection].get(id);
2994
+ }
2995
+ function buildItemParamsSchema() {
2996
+ return {
2997
+ type: "object",
2998
+ required: ["id"],
2999
+ properties: {
3000
+ id: { type: "string" }
3001
+ },
3002
+ additionalProperties: false
3003
+ };
3004
+ }
3005
+ function getPatchRoot(store) {
3006
+ return store?.rootDir ?? process.env.EZ_KNOW_ROOT;
3007
+ }
3008
+ async function loadEffectiveRestStore(store) {
3009
+ if (!store) {
3010
+ return void 0;
3011
+ }
3012
+ const effectiveState = await loadEffectiveKnowledgeStoreFromRoot(
3013
+ store.rootDir
3014
+ );
3015
+ return effectiveState.store;
3016
+ }
3017
+ function registerCollectionRoutes(app, store, collection) {
3018
+ app.get(
3019
+ `${REST_V1_PREFIX}/${collection.route}`,
3020
+ {
3021
+ schema: {
3022
+ response: {
3023
+ 200: restCollectionResponseSchema,
3024
+ 404: restErrorResponseSchema2,
3025
+ 503: restErrorResponseSchema2
3026
+ }
3027
+ }
3028
+ },
3029
+ async (_request, reply) => {
3030
+ const effectiveStore = await loadEffectiveRestStore(store);
3031
+ if (!effectiveStore) {
3032
+ reply.code(503);
3033
+ return buildErrorPayload(
3034
+ "missing_store",
3035
+ "Knowledge store is unavailable."
3036
+ );
3037
+ }
3038
+ return buildCollectionPayload(
3039
+ getCollectionRecords(effectiveStore, collection.collection)
3040
+ );
3041
+ }
3042
+ );
3043
+ app.get(
3044
+ `${REST_V1_PREFIX}/${collection.route}/:id`,
3045
+ {
3046
+ schema: {
3047
+ params: buildItemParamsSchema(),
3048
+ response: {
3049
+ 200: restItemResponseSchema,
3050
+ 404: restErrorResponseSchema2,
3051
+ 503: restErrorResponseSchema2
3052
+ }
3053
+ }
3054
+ },
3055
+ async (request, reply) => {
3056
+ const effectiveStore = await loadEffectiveRestStore(store);
3057
+ if (!effectiveStore) {
3058
+ reply.code(503);
3059
+ return buildErrorPayload(
3060
+ "missing_store",
3061
+ "Knowledge store is unavailable."
3062
+ );
3063
+ }
3064
+ const item = getCollectionRecordById(
3065
+ effectiveStore,
3066
+ collection.collection,
3067
+ request.params.id
3068
+ );
3069
+ if (!item) {
3070
+ reply.code(404);
3071
+ return buildErrorPayload(
3072
+ "unknown_item",
3073
+ `No item with id "${request.params.id}" exists in ${collection.collection}.`
3074
+ );
3075
+ }
3076
+ return buildItemPayload(item);
3077
+ }
3078
+ );
3079
+ }
3080
+ async function registerRestRoutes(app, store) {
3081
+ app.get(
3082
+ REST_HEALTH_PATH,
3083
+ {
3084
+ schema: {
3085
+ response: {
3086
+ 200: restHealthResponseSchema2
3087
+ }
3088
+ }
3089
+ },
3090
+ async () => buildHealthPayload(REST_SERVICE_NAME, store)
3091
+ );
3092
+ app.get(
3093
+ REST_OPENAPI_PATH,
3094
+ {
3095
+ schema: {
3096
+ response: {
3097
+ 200: restOpenApiDocumentSchema2
3098
+ }
3099
+ }
3100
+ },
3101
+ async () => REST_OPENAPI_DOCUMENT
3102
+ );
3103
+ app.get(
3104
+ REST_DOCS_PATH,
3105
+ {
3106
+ schema: {
3107
+ response: {
3108
+ 200: {
3109
+ type: "string"
3110
+ }
3111
+ }
3112
+ }
3113
+ },
3114
+ async (_request, reply) => {
3115
+ reply.type("text/html; charset=utf-8");
3116
+ return buildSwaggerUiHtml(REST_OPENAPI_PATH);
3117
+ }
3118
+ );
3119
+ app.get(
3120
+ `${REST_V1_PREFIX}/${REST_PATCHES_ROUTE}`,
3121
+ {
3122
+ schema: {
3123
+ response: {
3124
+ 200: restPatchInventoryResponseSchema2,
3125
+ 404: restErrorResponseSchema2
3126
+ }
3127
+ }
3128
+ },
3129
+ async () => buildCollectionPayload(await buildPatchInventory(getPatchRoot(store)))
3130
+ );
3131
+ app.get(
3132
+ `${REST_V1_PREFIX}/${REST_PATCH_PREVIEW_ROUTE}`,
3133
+ {
3134
+ schema: {
3135
+ params: {
3136
+ type: "object",
3137
+ required: ["patchId"],
3138
+ properties: {
3139
+ patchId: { type: "string" }
3140
+ },
3141
+ additionalProperties: false
3142
+ },
3143
+ response: {
3144
+ 200: restPatchPreviewResponseSchema2,
3145
+ 404: restErrorResponseSchema2,
3146
+ 503: restErrorResponseSchema2
3147
+ }
3148
+ }
3149
+ },
3150
+ async (request, reply) => {
3151
+ if (!store) {
3152
+ reply.code(503);
3153
+ return buildErrorPayload(
3154
+ "missing_store",
3155
+ "Knowledge store is unavailable."
3156
+ );
3157
+ }
3158
+ try {
3159
+ return await buildPatchPreview(request.params.patchId, store.rootDir);
3160
+ } catch (error) {
3161
+ reply.code(404);
3162
+ return buildErrorPayload(
3163
+ "unknown_patch",
3164
+ error instanceof Error ? error.message : "Patch not found."
3165
+ );
3166
+ }
3167
+ }
3168
+ );
3169
+ for (const collection of REST_COLLECTIONS) {
3170
+ registerCollectionRoutes(app, store, collection);
3171
+ }
3172
+ }
3173
+
3174
+ // packages/rest/src/app.ts
3175
+ async function buildRestApp(store, options = {}) {
3176
+ const app = Fastify({
3177
+ logger: false
3178
+ });
3179
+ await registerRestRoutes(app, store);
3180
+ if (options.staticRoot) {
3181
+ try {
3182
+ const staticRoot = resolve5(options.staticRoot);
3183
+ await access(staticRoot);
3184
+ await app.register(fastifyStatic, {
3185
+ root: staticRoot,
3186
+ prefix: "/"
3187
+ });
3188
+ } catch {
3189
+ }
3190
+ }
3191
+ await app.ready();
3192
+ return app;
3193
+ }
3194
+
3195
+ // packages/rest/src/run.ts
3196
+ function parsePort(value, fallback) {
3197
+ if (!value) {
3198
+ return fallback;
3199
+ }
3200
+ const parsed = Number(value);
3201
+ if (!Number.isInteger(parsed) || parsed <= 0) {
3202
+ throw new Error(`Invalid REST port: ${value}`);
3203
+ }
3204
+ return parsed;
3205
+ }
3206
+ async function startRestServer(options = {}) {
3207
+ const host = options.host ?? process.env.EZ_KNOW_REST_HOST ?? "127.0.0.1";
3208
+ const port = options.port ?? parsePort(process.env.EZ_KNOW_REST_PORT ?? process.env.PORT, 3e3);
3209
+ const knowledgeStore = await loadKnowledgeStoreFromEnv(
3210
+ process.env.EZ_KNOW_ROOT
3211
+ );
3212
+ const app = await buildRestApp(knowledgeStore, {
3213
+ staticRoot: options.staticRoot
3214
+ });
3215
+ await app.listen({ port, host });
3216
+ console.log(`ez-know REST service listening on http://${host}:${port}`);
3217
+ return app;
3218
+ }
3219
+
3220
+ // src/rest-server.ts
3221
+ function resolveRestStaticRoot() {
3222
+ const distPublicRoot = fileURLToPath(new URL("../public", import.meta.url));
3223
+ if (existsSync3(distPublicRoot)) {
3224
+ return distPublicRoot;
3225
+ }
3226
+ const webDistRoot = fileURLToPath(
3227
+ new URL("../packages/web/dist", import.meta.url)
3228
+ );
3229
+ if (existsSync3(webDistRoot)) {
3230
+ return webDistRoot;
3231
+ }
3232
+ return void 0;
3233
+ }
3234
+ await startRestServer({
3235
+ staticRoot: resolveRestStaticRoot()
3236
+ });
3237
+ //# sourceMappingURL=server.js.map