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