@lucern/pack-host 0.3.0-alpha.9 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/dist/domain-pack/authoring.core.d.ts +161 -0
  2. package/dist/domain-pack/authoring.core.js +411 -0
  3. package/dist/domain-pack/authoring.core.js.map +1 -0
  4. package/dist/domain-pack/authoring.d.ts +12 -170
  5. package/dist/domain-pack/authoring.js +1155 -1098
  6. package/dist/domain-pack/authoring.js.map +1 -1
  7. package/dist/domain-pack/authoring.validation.d.ts +28 -0
  8. package/dist/domain-pack/authoring.validation.js +1944 -0
  9. package/dist/domain-pack/authoring.validation.js.map +1 -0
  10. package/dist/domain-pack/index.d.ts +2 -1
  11. package/dist/domain-pack/index.js +1979 -1917
  12. package/dist/domain-pack/index.js.map +1 -1
  13. package/dist/domain-pack/packs/engineering-accelerator-tail.d.ts +256 -0
  14. package/dist/domain-pack/packs/engineering-accelerator-tail.js +716 -0
  15. package/dist/domain-pack/packs/engineering-accelerator-tail.js.map +1 -0
  16. package/dist/domain-pack/packs/engineering-accelerator.js +790 -785
  17. package/dist/domain-pack/packs/engineering-accelerator.js.map +1 -1
  18. package/dist/domain-pack/packs/index.js +790 -785
  19. package/dist/domain-pack/packs/index.js.map +1 -1
  20. package/dist/domain-pack.d.ts +2 -1
  21. package/dist/domain-pack.js +1979 -1917
  22. package/dist/domain-pack.js.map +1 -1
  23. package/dist/index.d.ts +3 -1
  24. package/dist/index.js +1843 -1661
  25. package/dist/index.js.map +1 -1
  26. package/dist/manifests/chat-v1.js +17 -6
  27. package/dist/manifests/chat-v1.js.map +1 -1
  28. package/dist/manifests/deals-v1.js +10 -7
  29. package/dist/manifests/deals-v1.js.map +1 -1
  30. package/dist/manifests/decisions-v1.js +11 -4
  31. package/dist/manifests/decisions-v1.js.map +1 -1
  32. package/dist/manifests/documents-v1.js +12 -12
  33. package/dist/manifests/documents-v1.js.map +1 -1
  34. package/dist/manifests/epistemic-algorithms-v1.js +11 -6
  35. package/dist/manifests/epistemic-algorithms-v1.js.map +1 -1
  36. package/dist/manifests/graph-visualization-v1.js +9 -5
  37. package/dist/manifests/graph-visualization-v1.js.map +1 -1
  38. package/dist/manifests/index.d.ts +1 -0
  39. package/dist/manifests/index.js +230 -110
  40. package/dist/manifests/index.js.map +1 -1
  41. package/dist/manifests/news-v1.js +12 -13
  42. package/dist/manifests/news-v1.js.map +1 -1
  43. package/dist/manifests/philosophy-mode-v1.js +10 -12
  44. package/dist/manifests/philosophy-mode-v1.js.map +1 -1
  45. package/dist/manifests/sprints-v1.d.ts +10 -0
  46. package/dist/manifests/sprints-v1.js +106 -0
  47. package/dist/manifests/sprints-v1.js.map +1 -0
  48. package/dist/manifests/task-management-v1.js +18 -6
  49. package/dist/manifests/task-management-v1.js.map +1 -1
  50. package/dist/manifests/team-analysis-v1.js +12 -9
  51. package/dist/manifests/team-analysis-v1.js.map +1 -1
  52. package/dist/manifests/themes-v1.js +12 -16
  53. package/dist/manifests/themes-v1.js.map +1 -1
  54. package/dist/manifests/user-profiles-v1.js +9 -13
  55. package/dist/manifests/user-profiles-v1.js.map +1 -1
  56. package/dist/manifests.d.ts +1 -0
  57. package/dist/manifests.js +230 -110
  58. package/dist/manifests.js.map +1 -1
  59. package/dist/proof-attestation.json +1 -1
  60. package/dist/registry.js +229 -109
  61. package/dist/registry.js.map +1 -1
  62. package/package.json +2 -1
@@ -0,0 +1,1944 @@
1
+ // src/domain-pack/contracts.ts
2
+ function dedupeStrings(values) {
3
+ return Array.from(
4
+ new Set(values.map((v) => v.trim()).filter((v) => v.length > 0))
5
+ );
6
+ }
7
+ function normalizeRuntimeTargets(values) {
8
+ return values ? dedupeStrings(values) : void 0;
9
+ }
10
+ function normalizeOntologyBinding(binding) {
11
+ return {
12
+ ...binding,
13
+ requiredEntityTypes: binding.requiredEntityTypes ? dedupeStrings(binding.requiredEntityTypes) : void 0,
14
+ requiredEdgeTypes: binding.requiredEdgeTypes ? dedupeStrings(binding.requiredEdgeTypes) : void 0
15
+ };
16
+ }
17
+ function normalizeOperatingSystem(layer) {
18
+ if (!layer) {
19
+ return;
20
+ }
21
+ return {
22
+ prompts: layer.prompts?.map((prompt) => ({
23
+ ...prompt,
24
+ runtimeTargets: normalizeRuntimeTargets(prompt.runtimeTargets)
25
+ })),
26
+ tools: layer.tools?.map((tool) => ({
27
+ ...tool,
28
+ runtimeTargets: normalizeRuntimeTargets(tool.runtimeTargets)
29
+ })),
30
+ setupAssets: layer.setupAssets?.map((asset) => ({
31
+ ...asset,
32
+ runtimeTargets: normalizeRuntimeTargets(asset.runtimeTargets)
33
+ })),
34
+ topicTemplates: layer.topicTemplates,
35
+ installProfiles: layer.installProfiles?.map((profile) => ({
36
+ ...profile,
37
+ promptIds: dedupeStrings(profile.promptIds),
38
+ toolIds: dedupeStrings(profile.toolIds),
39
+ assetIds: dedupeStrings(profile.assetIds),
40
+ defaultTopicSlugs: dedupeStrings(profile.defaultTopicSlugs)
41
+ }))
42
+ };
43
+ }
44
+ function defineDomainPack(input) {
45
+ return {
46
+ ...input,
47
+ ontologyBindings: input.ontologyBindings.map(normalizeOntologyBinding),
48
+ appPackKeys: input.appPackKeys ? dedupeStrings(input.appPackKeys) : void 0,
49
+ operatingSystem: normalizeOperatingSystem(input.operatingSystem),
50
+ workflows: input.workflows.map((w) => ({
51
+ ...w,
52
+ requiredArtifacts: dedupeStrings(w.requiredArtifacts),
53
+ gateCheckpoints: dedupeStrings(w.gateCheckpoints),
54
+ steps: w.steps.map((s) => ({
55
+ ...s,
56
+ requiredRoles: dedupeStrings(s.requiredRoles),
57
+ produces: s.produces ? dedupeStrings(s.produces) : void 0
58
+ }))
59
+ }))
60
+ };
61
+ }
62
+
63
+ // src/domain-pack/authoring.core.ts
64
+ var DOMAIN_PACK_MANIFEST_KIND = "lucern-domain-pack-manifest";
65
+ var CURRENT_MANIFEST_VERSION = "1.0.0";
66
+ function isPlainObject(value) {
67
+ return typeof value === "object" && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
68
+ }
69
+ function dedupeStrings2(values) {
70
+ if (!values) {
71
+ return void 0;
72
+ }
73
+ return Array.from(
74
+ new Set(values.map((value) => value.trim()).filter((value) => value.length))
75
+ );
76
+ }
77
+ function normalizeRuntimeTargets2(values) {
78
+ return values ? dedupeStrings2(values) : void 0;
79
+ }
80
+ function normalizeFrameworks(frameworks) {
81
+ if (!frameworks) {
82
+ return void 0;
83
+ }
84
+ return frameworks.map((framework) => ({
85
+ ...framework,
86
+ frameworkId: framework.frameworkId.trim(),
87
+ version: framework.version.trim(),
88
+ versionConstraint: framework.versionConstraint?.trim(),
89
+ runtimeTargets: normalizeRuntimeTargets2(framework.runtimeTargets)
90
+ }));
91
+ }
92
+ function normalizeSchemaExtensions(extensions) {
93
+ if (!extensions) {
94
+ return void 0;
95
+ }
96
+ return extensions.map((extension) => ({
97
+ ...extension,
98
+ extensionId: extension.extensionId.trim(),
99
+ target: extension.target,
100
+ description: extension.description.trim(),
101
+ version: extension.version.trim(),
102
+ extends: extension.extends?.trim()
103
+ }));
104
+ }
105
+ function normalizeOntologyExtensions(extensions) {
106
+ if (!extensions) {
107
+ return void 0;
108
+ }
109
+ return extensions.map((extension) => ({
110
+ ...extension,
111
+ extensionId: extension.extensionId.trim(),
112
+ ontologyId: extension.ontologyId.trim(),
113
+ baseVersionConstraint: extension.baseVersionConstraint.trim(),
114
+ entityTypes: extension.entityTypes?.map((entityType) => ({
115
+ ...entityType,
116
+ value: entityType.value.trim(),
117
+ label: entityType.label.trim(),
118
+ description: entityType.description?.trim(),
119
+ subtypes: dedupeStrings2(entityType.subtypes)
120
+ })),
121
+ edgeTypes: extension.edgeTypes?.map((edgeType) => ({
122
+ ...edgeType,
123
+ value: edgeType.value.trim(),
124
+ label: edgeType.label.trim(),
125
+ description: edgeType.description?.trim(),
126
+ sourceTypes: dedupeStrings2(edgeType.sourceTypes),
127
+ targetTypes: dedupeStrings2(edgeType.targetTypes)
128
+ }))
129
+ }));
130
+ }
131
+ function normalizeLineage(lineage) {
132
+ if (!lineage) {
133
+ return { mode: "root" };
134
+ }
135
+ return {
136
+ mode: lineage.mode,
137
+ parentPackId: lineage.parentPackId?.trim(),
138
+ parentVersion: lineage.parentVersion?.trim(),
139
+ parentManifestDigest: lineage.parentManifestDigest?.trim(),
140
+ supersedesPackId: lineage.supersedesPackId?.trim(),
141
+ notes: lineage.notes?.trim()
142
+ };
143
+ }
144
+ function normalizeMetadata(metadata) {
145
+ if (!metadata) {
146
+ return void 0;
147
+ }
148
+ return {
149
+ description: metadata.description?.trim(),
150
+ owner: metadata.owner?.trim(),
151
+ tags: dedupeStrings2(metadata.tags)
152
+ };
153
+ }
154
+ function toDomainPack(pack) {
155
+ return defineDomainPack(pack);
156
+ }
157
+ function defineDomainPackAuthoringManifest(input) {
158
+ return {
159
+ kind: input.kind ?? DOMAIN_PACK_MANIFEST_KIND,
160
+ manifestVersion: input.manifestVersion?.trim() || CURRENT_MANIFEST_VERSION,
161
+ pack: toDomainPack(input.pack),
162
+ frameworks: normalizeFrameworks(input.frameworks),
163
+ schemaExtensions: normalizeSchemaExtensions(input.schemaExtensions),
164
+ ontologyExtensions: normalizeOntologyExtensions(input.ontologyExtensions),
165
+ lineage: normalizeLineage(input.lineage),
166
+ metadata: normalizeMetadata(input.metadata)
167
+ };
168
+ }
169
+ function countManifestArtifacts(manifest) {
170
+ if (!manifest) {
171
+ return {
172
+ topicRoots: 0,
173
+ workflows: 0,
174
+ gates: 0,
175
+ artifacts: 0,
176
+ roles: 0,
177
+ prompts: 0,
178
+ tools: 0,
179
+ setupAssets: 0,
180
+ installProfiles: 0,
181
+ frameworks: 0,
182
+ schemaExtensions: 0,
183
+ ontologyExtensions: 0
184
+ };
185
+ }
186
+ return {
187
+ topicRoots: manifest.pack.topicRoots.length,
188
+ workflows: manifest.pack.workflows.length,
189
+ gates: manifest.pack.gates.length,
190
+ artifacts: manifest.pack.artifacts.length,
191
+ roles: manifest.pack.roles.length,
192
+ prompts: manifest.pack.operatingSystem?.prompts?.length ?? 0,
193
+ tools: manifest.pack.operatingSystem?.tools?.length ?? 0,
194
+ setupAssets: manifest.pack.operatingSystem?.setupAssets?.length ?? 0,
195
+ installProfiles: manifest.pack.operatingSystem?.installProfiles?.length ?? 0,
196
+ frameworks: manifest.frameworks?.length ?? 0,
197
+ schemaExtensions: manifest.schemaExtensions?.length ?? 0,
198
+ ontologyExtensions: manifest.ontologyExtensions?.length ?? 0
199
+ };
200
+ }
201
+ function sortJsonValue(value) {
202
+ if (Array.isArray(value)) {
203
+ return value.map(sortJsonValue);
204
+ }
205
+ if (isPlainObject(value)) {
206
+ return Object.fromEntries(
207
+ Object.entries(value).filter(([, entryValue]) => entryValue !== void 0).sort(([left], [right]) => left.localeCompare(right)).map(([key, entryValue]) => [key, sortJsonValue(entryValue)])
208
+ );
209
+ }
210
+ return value;
211
+ }
212
+ function toYamlScalar(value) {
213
+ if (value === null) {
214
+ return "null";
215
+ }
216
+ if (typeof value === "boolean" || typeof value === "number") {
217
+ return String(value);
218
+ }
219
+ return JSON.stringify(String(value));
220
+ }
221
+ function renderYaml(value, indent = 0) {
222
+ const prefix = " ".repeat(indent);
223
+ if (Array.isArray(value)) {
224
+ if (value.length === 0) {
225
+ return [`${prefix}[]`];
226
+ }
227
+ return value.flatMap((entry) => {
228
+ if (Array.isArray(entry) || isPlainObject(entry)) {
229
+ return [`${prefix}-`, ...renderYaml(entry, indent + 2)];
230
+ }
231
+ return [`${prefix}- ${toYamlScalar(entry)}`];
232
+ });
233
+ }
234
+ if (isPlainObject(value)) {
235
+ const entries = Object.entries(value);
236
+ if (entries.length === 0) {
237
+ return [`${prefix}{}`];
238
+ }
239
+ return entries.flatMap(([key, entryValue]) => {
240
+ if (entryValue === void 0) {
241
+ return [];
242
+ }
243
+ if (Array.isArray(entryValue)) {
244
+ if (entryValue.length === 0) {
245
+ return [`${prefix}${key}: []`];
246
+ }
247
+ return [`${prefix}${key}:`, ...renderYaml(entryValue, indent + 2)];
248
+ }
249
+ if (isPlainObject(entryValue)) {
250
+ if (Object.keys(entryValue).length === 0) {
251
+ return [`${prefix}${key}: {}`];
252
+ }
253
+ return [`${prefix}${key}:`, ...renderYaml(entryValue, indent + 2)];
254
+ }
255
+ return [`${prefix}${key}: ${toYamlScalar(entryValue)}`];
256
+ });
257
+ }
258
+ return [`${prefix}${toYamlScalar(value)}`];
259
+ }
260
+ function countIndent(line) {
261
+ return line.length - line.trimStart().length;
262
+ }
263
+ function parseYamlScalar(raw) {
264
+ const value = raw.trim();
265
+ if (value === "null") {
266
+ return null;
267
+ }
268
+ if (value === "true") {
269
+ return true;
270
+ }
271
+ if (value === "false") {
272
+ return false;
273
+ }
274
+ if (/^-?\d+(?:\.\d+)?$/.test(value)) {
275
+ return Number(value);
276
+ }
277
+ if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
278
+ if (value.startsWith("'")) {
279
+ return value.slice(1, -1).replace(/''/g, "'");
280
+ }
281
+ return JSON.parse(value);
282
+ }
283
+ if (value === "[]") {
284
+ return [];
285
+ }
286
+ if (value === "{}") {
287
+ return {};
288
+ }
289
+ return value;
290
+ }
291
+ function splitYamlKeyValue(trimmed) {
292
+ const separatorIndex = trimmed.indexOf(":");
293
+ if (separatorIndex === -1) {
294
+ throw new Error(`Invalid YAML mapping entry: ${trimmed}`);
295
+ }
296
+ const key = trimmed.slice(0, separatorIndex).trim();
297
+ const value = trimmed.slice(separatorIndex + 1).trim();
298
+ return { key, value: value.length ? value : null };
299
+ }
300
+ function parseYamlDocument(text) {
301
+ const rawLines = text.replace(/\r\n/g, "\n").split("\n").map((line) => line.replace(/\t/g, " "));
302
+ const lines = rawLines.filter((line) => {
303
+ const trimmed = line.trim();
304
+ return trimmed.length > 0 && trimmed !== "---" && trimmed !== "...";
305
+ });
306
+ let index = 0;
307
+ function parseBlock(indent) {
308
+ if (index >= lines.length) {
309
+ return {};
310
+ }
311
+ const currentLine = lines[index];
312
+ const currentIndent = countIndent(currentLine);
313
+ if (currentIndent < indent) {
314
+ return {};
315
+ }
316
+ if (currentLine.trimStart().startsWith("-")) {
317
+ return parseArray(indent);
318
+ }
319
+ return parseObject(indent);
320
+ }
321
+ function parseArray(indent) {
322
+ const items = [];
323
+ while (index < lines.length) {
324
+ const line = lines[index];
325
+ const currentIndent = countIndent(line);
326
+ if (currentIndent < indent) {
327
+ break;
328
+ }
329
+ if (currentIndent !== indent) {
330
+ throw new Error(`Invalid YAML indentation near: ${line.trim()}`);
331
+ }
332
+ const trimmed = line.trimStart();
333
+ if (!trimmed.startsWith("-")) {
334
+ break;
335
+ }
336
+ const rest = trimmed.slice(1).trimStart();
337
+ index += 1;
338
+ if (!rest.length) {
339
+ items.push(parseBlock(indent + 2));
340
+ continue;
341
+ }
342
+ items.push(parseYamlScalar(rest));
343
+ }
344
+ return items;
345
+ }
346
+ function parseObject(indent) {
347
+ const objectValue = {};
348
+ while (index < lines.length) {
349
+ const line = lines[index];
350
+ const currentIndent = countIndent(line);
351
+ if (currentIndent < indent) {
352
+ break;
353
+ }
354
+ if (currentIndent !== indent) {
355
+ throw new Error(`Invalid YAML indentation near: ${line.trim()}`);
356
+ }
357
+ const trimmed = line.trim();
358
+ if (trimmed.startsWith("-")) {
359
+ break;
360
+ }
361
+ const { key, value } = splitYamlKeyValue(trimmed);
362
+ index += 1;
363
+ objectValue[key] = value === null ? parseBlock(indent + 2) : parseYamlScalar(value);
364
+ }
365
+ return objectValue;
366
+ }
367
+ return parseBlock(0);
368
+ }
369
+ function detectDomainPackManifestFormat(source, explicitFormat) {
370
+ if (explicitFormat) {
371
+ return explicitFormat;
372
+ }
373
+ const trimmed = source.trim();
374
+ if (trimmed.startsWith("{")) {
375
+ return "json";
376
+ }
377
+ return "yaml";
378
+ }
379
+ function serializeDomainPackAuthoringManifest(manifest, format = "json") {
380
+ const canonicalValue = sortJsonValue(manifest);
381
+ if (format === "json") {
382
+ return `${JSON.stringify(canonicalValue, null, 2)}
383
+ `;
384
+ }
385
+ return `${renderYaml(canonicalValue).join("\n")}
386
+ `;
387
+ }
388
+ function parseDomainPackAuthoringManifest(source, format) {
389
+ const detectedFormat = detectDomainPackManifestFormat(source, format);
390
+ const parsed = detectedFormat === "json" ? JSON.parse(source) : parseYamlDocument(source);
391
+ if (!isPlainObject(parsed)) {
392
+ throw new Error("Domain pack manifest must parse to an object.");
393
+ }
394
+ if (!("pack" in parsed)) {
395
+ throw new Error("Domain pack manifest requires a top-level pack object.");
396
+ }
397
+ return defineDomainPackAuthoringManifest({
398
+ kind: parsed.kind,
399
+ manifestVersion: parsed.manifestVersion,
400
+ pack: parsed.pack,
401
+ frameworks: parsed.frameworks,
402
+ schemaExtensions: parsed.schemaExtensions,
403
+ ontologyExtensions: parsed.ontologyExtensions,
404
+ lineage: parsed.lineage,
405
+ metadata: parsed.metadata
406
+ });
407
+ }
408
+
409
+ // src/domain-pack/validation.ts
410
+ function issue(code, message, path, severity = "error") {
411
+ return { code, severity, message, path };
412
+ }
413
+ var KEBAB_CASE = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
414
+ var SEMVER = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;
415
+ var SHAPING_QUESTION_TYPES = /* @__PURE__ */ new Set([
416
+ "validation",
417
+ "falsification",
418
+ "assumption_probe",
419
+ "counterfactual",
420
+ "scope",
421
+ "comparison",
422
+ "mechanism",
423
+ "general"
424
+ ]);
425
+ var RUNTIME_TARGETS = /* @__PURE__ */ new Set(["claude-code", "codex", "hybrid", "portable"]);
426
+ var ONTOLOGY_PROVISION_MODES = /* @__PURE__ */ new Set(["bind", "seed", "extend"]);
427
+ function validateStringArray(values, path, label) {
428
+ if (!values) {
429
+ return [];
430
+ }
431
+ return values.flatMap((value, index) => {
432
+ if (!value?.trim()) {
433
+ return [
434
+ issue(
435
+ "INVALID_SHAPING_CONDITION",
436
+ `${label} must not contain empty strings`,
437
+ `${path}[${index}]`
438
+ )
439
+ ];
440
+ }
441
+ return [];
442
+ });
443
+ }
444
+ function validateRuntimeTargets(values, path) {
445
+ const issues = validateStringArray(values, path, "runtimeTargets");
446
+ for (const [index, value] of (values || []).entries()) {
447
+ if (!RUNTIME_TARGETS.has(value)) {
448
+ issues.push(
449
+ issue(
450
+ "INVALID_RUNTIME_TARGET",
451
+ `Unsupported runtime target "${value}"`,
452
+ `${path}[${index}]`
453
+ )
454
+ );
455
+ }
456
+ }
457
+ return issues;
458
+ }
459
+ function validatePromptBinding(prompt, index) {
460
+ const path = `operatingSystem.prompts[${index}]`;
461
+ const issues = [];
462
+ if (!prompt.promptId?.trim()) {
463
+ issues.push(
464
+ issue(
465
+ "MISSING_PROMPT_ID",
466
+ "prompt binding requires promptId",
467
+ `${path}.promptId`
468
+ )
469
+ );
470
+ }
471
+ if (!prompt.ref?.trim()) {
472
+ issues.push(
473
+ issue("MISSING_PROMPT_REF", "prompt binding requires ref", `${path}.ref`)
474
+ );
475
+ }
476
+ issues.push(
477
+ ...validateRuntimeTargets(prompt.runtimeTargets, `${path}.runtimeTargets`)
478
+ );
479
+ return issues;
480
+ }
481
+ function validateToolBinding(tool, index) {
482
+ const path = `operatingSystem.tools[${index}]`;
483
+ const issues = [];
484
+ if (!tool.toolId?.trim()) {
485
+ issues.push(
486
+ issue("MISSING_TOOL_ID", "tool binding requires toolId", `${path}.toolId`)
487
+ );
488
+ }
489
+ if (!tool.entrypoint?.trim()) {
490
+ issues.push(
491
+ issue(
492
+ "MISSING_TOOL_ENTRYPOINT",
493
+ "tool binding requires entrypoint",
494
+ `${path}.entrypoint`
495
+ )
496
+ );
497
+ }
498
+ issues.push(
499
+ ...validateRuntimeTargets(tool.runtimeTargets, `${path}.runtimeTargets`)
500
+ );
501
+ return issues;
502
+ }
503
+ function validateSetupAsset(asset, index) {
504
+ const path = `operatingSystem.setupAssets[${index}]`;
505
+ const issues = [];
506
+ if (!asset.assetId?.trim()) {
507
+ issues.push(
508
+ issue(
509
+ "MISSING_SETUP_ASSET_ID",
510
+ "setup asset requires assetId",
511
+ `${path}.assetId`
512
+ )
513
+ );
514
+ }
515
+ if (!asset.path?.trim()) {
516
+ issues.push(
517
+ issue(
518
+ "MISSING_SETUP_ASSET_PATH",
519
+ "setup asset requires path",
520
+ `${path}.path`
521
+ )
522
+ );
523
+ }
524
+ issues.push(
525
+ ...validateRuntimeTargets(asset.runtimeTargets, `${path}.runtimeTargets`)
526
+ );
527
+ return issues;
528
+ }
529
+ function validateQuestionTemplate(template, index) {
530
+ const path = `inquiryShaping.questionTemplates[${index}]`;
531
+ const issues = [];
532
+ if (!template.templateId?.trim()) {
533
+ issues.push(
534
+ issue(
535
+ "MISSING_SHAPING_TEMPLATE_ID",
536
+ "question template requires templateId",
537
+ `${path}.templateId`
538
+ )
539
+ );
540
+ }
541
+ if (!template.template?.trim()) {
542
+ issues.push(
543
+ issue(
544
+ "MISSING_SHAPING_TEMPLATE",
545
+ "question template requires template text",
546
+ `${path}.template`
547
+ )
548
+ );
549
+ }
550
+ if (!SHAPING_QUESTION_TYPES.has(template.questionType)) {
551
+ issues.push(
552
+ issue(
553
+ "INVALID_SHAPING_QUESTION_TYPE",
554
+ `Unsupported questionType "${template.questionType}"`,
555
+ `${path}.questionType`
556
+ )
557
+ );
558
+ }
559
+ issues.push(
560
+ ...validateStringArray(
561
+ template.whenObjectiveIncludes,
562
+ `${path}.whenObjectiveIncludes`,
563
+ "whenObjectiveIncludes"
564
+ )
565
+ );
566
+ return issues;
567
+ }
568
+ function validateTaskTemplate(template, index) {
569
+ const path = `inquiryShaping.taskTemplates[${index}]`;
570
+ const issues = [];
571
+ if (!template.templateId?.trim()) {
572
+ issues.push(
573
+ issue(
574
+ "MISSING_TASK_GENERATOR_ID",
575
+ "task template requires templateId",
576
+ `${path}.templateId`
577
+ )
578
+ );
579
+ }
580
+ if (!template.title?.trim()) {
581
+ issues.push(
582
+ issue(
583
+ "MISSING_TASK_GENERATOR_TITLE",
584
+ "task template requires title",
585
+ `${path}.title`
586
+ )
587
+ );
588
+ }
589
+ issues.push(
590
+ ...validateStringArray(
591
+ template.whenObjectiveIncludes,
592
+ `${path}.whenObjectiveIncludes`,
593
+ "whenObjectiveIncludes"
594
+ )
595
+ );
596
+ issues.push(
597
+ ...validateStringArray(
598
+ template.whenQuestionTypes,
599
+ `${path}.whenQuestionTypes`,
600
+ "whenQuestionTypes"
601
+ )
602
+ );
603
+ for (const [questionTypeIndex, questionType] of (template.whenQuestionTypes || []).entries()) {
604
+ if (!SHAPING_QUESTION_TYPES.has(questionType)) {
605
+ issues.push(
606
+ issue(
607
+ "INVALID_TASK_GENERATOR_QUESTION_TYPE",
608
+ `Unsupported whenQuestionTypes value "${questionType}"`,
609
+ `${path}.whenQuestionTypes[${questionTypeIndex}]`
610
+ )
611
+ );
612
+ }
613
+ }
614
+ return issues;
615
+ }
616
+ function validateFrameworkHint(hint, index) {
617
+ const path = `inquiryShaping.frameworkHints[${index}]`;
618
+ const issues = [];
619
+ if (!hint.frameworkName?.trim()) {
620
+ issues.push(
621
+ issue(
622
+ "MISSING_FRAMEWORK_HOOK_NAME",
623
+ "framework hint requires frameworkName",
624
+ `${path}.frameworkName`
625
+ )
626
+ );
627
+ }
628
+ if (hint.boost != null && (!Number.isFinite(hint.boost) || hint.boost < 0)) {
629
+ issues.push(
630
+ issue(
631
+ "INVALID_FRAMEWORK_HOOK_BOOST",
632
+ "framework hint boost must be a non-negative number",
633
+ `${path}.boost`
634
+ )
635
+ );
636
+ }
637
+ issues.push(
638
+ ...validateStringArray(
639
+ hint.whenObjectiveIncludes,
640
+ `${path}.whenObjectiveIncludes`,
641
+ "whenObjectiveIncludes"
642
+ )
643
+ );
644
+ issues.push(
645
+ ...validateStringArray(
646
+ hint.whenQuestionTypes,
647
+ `${path}.whenQuestionTypes`,
648
+ "whenQuestionTypes"
649
+ )
650
+ );
651
+ for (const [questionTypeIndex, questionType] of (hint.whenQuestionTypes || []).entries()) {
652
+ if (!SHAPING_QUESTION_TYPES.has(questionType)) {
653
+ issues.push(
654
+ issue(
655
+ "INVALID_FRAMEWORK_HOOK_QUESTION_TYPE",
656
+ `Unsupported whenQuestionTypes value "${questionType}"`,
657
+ `${path}.whenQuestionTypes[${questionTypeIndex}]`
658
+ )
659
+ );
660
+ }
661
+ }
662
+ return issues;
663
+ }
664
+ function validateTopicTemplate(template, index, knownTopicSlugs) {
665
+ const path = `operatingSystem.topicTemplates[${index}]`;
666
+ const issues = [];
667
+ if (!template.slug?.trim()) {
668
+ issues.push(
669
+ issue(
670
+ "MISSING_TOPIC_TEMPLATE_SLUG",
671
+ "topic template requires slug",
672
+ `${path}.slug`
673
+ )
674
+ );
675
+ } else if (!KEBAB_CASE.test(template.slug)) {
676
+ issues.push(
677
+ issue(
678
+ "INVALID_TOPIC_TEMPLATE_SLUG",
679
+ `topic template slug "${template.slug}" must be kebab-case`,
680
+ `${path}.slug`
681
+ )
682
+ );
683
+ }
684
+ if (!template.name?.trim()) {
685
+ issues.push(
686
+ issue(
687
+ "MISSING_TOPIC_TEMPLATE_NAME",
688
+ "topic template requires name",
689
+ `${path}.name`
690
+ )
691
+ );
692
+ }
693
+ if (!template.description?.trim()) {
694
+ issues.push(
695
+ issue(
696
+ "MISSING_TOPIC_TEMPLATE_DESCRIPTION",
697
+ "topic template requires description",
698
+ `${path}.description`
699
+ )
700
+ );
701
+ }
702
+ if (template.parentSlug && !knownTopicSlugs.has(template.parentSlug)) {
703
+ issues.push(
704
+ issue(
705
+ "UNKNOWN_TOPIC_PARENT",
706
+ `topic template references unknown parent "${template.parentSlug}"`,
707
+ `${path}.parentSlug`
708
+ )
709
+ );
710
+ }
711
+ return issues;
712
+ }
713
+ function validateInstallProfile(profile, index, knownPromptIds, knownToolIds, knownAssetIds, knownTopicSlugs) {
714
+ const path = `operatingSystem.installProfiles[${index}]`;
715
+ const issues = [];
716
+ if (!profile.profileId?.trim()) {
717
+ issues.push(
718
+ issue(
719
+ "MISSING_INSTALL_PROFILE_ID",
720
+ "install profile requires profileId",
721
+ `${path}.profileId`
722
+ )
723
+ );
724
+ }
725
+ if (!profile.name?.trim()) {
726
+ issues.push(
727
+ issue(
728
+ "MISSING_INSTALL_PROFILE_NAME",
729
+ "install profile requires name",
730
+ `${path}.name`
731
+ )
732
+ );
733
+ }
734
+ if (!profile.description?.trim()) {
735
+ issues.push(
736
+ issue(
737
+ "MISSING_INSTALL_PROFILE_DESCRIPTION",
738
+ "install profile requires description",
739
+ `${path}.description`
740
+ )
741
+ );
742
+ }
743
+ if (!RUNTIME_TARGETS.has(profile.runtimeTarget)) {
744
+ issues.push(
745
+ issue(
746
+ "INVALID_RUNTIME_TARGET",
747
+ `Unsupported runtime target "${profile.runtimeTarget}"`,
748
+ `${path}.runtimeTarget`
749
+ )
750
+ );
751
+ }
752
+ for (const [promptIndex, promptId] of profile.promptIds.entries()) {
753
+ if (!knownPromptIds.has(promptId)) {
754
+ issues.push(
755
+ issue(
756
+ "UNKNOWN_PROMPT_REF",
757
+ `install profile references unknown prompt "${promptId}"`,
758
+ `${path}.promptIds[${promptIndex}]`
759
+ )
760
+ );
761
+ }
762
+ }
763
+ for (const [toolIndex, toolId] of profile.toolIds.entries()) {
764
+ if (!knownToolIds.has(toolId)) {
765
+ issues.push(
766
+ issue(
767
+ "UNKNOWN_TOOL_REF",
768
+ `install profile references unknown tool "${toolId}"`,
769
+ `${path}.toolIds[${toolIndex}]`
770
+ )
771
+ );
772
+ }
773
+ }
774
+ for (const [assetIndex, assetId] of profile.assetIds.entries()) {
775
+ if (!knownAssetIds.has(assetId)) {
776
+ issues.push(
777
+ issue(
778
+ "UNKNOWN_SETUP_ASSET_REF",
779
+ `install profile references unknown setup asset "${assetId}"`,
780
+ `${path}.assetIds[${assetIndex}]`
781
+ )
782
+ );
783
+ }
784
+ }
785
+ for (const [topicIndex, topicSlug] of profile.defaultTopicSlugs.entries()) {
786
+ if (!knownTopicSlugs.has(topicSlug)) {
787
+ issues.push(
788
+ issue(
789
+ "UNKNOWN_TOPIC_REF",
790
+ `install profile references unknown topic "${topicSlug}"`,
791
+ `${path}.defaultTopicSlugs[${topicIndex}]`
792
+ )
793
+ );
794
+ }
795
+ }
796
+ return issues;
797
+ }
798
+ function checkDuplicateIds(items, idField, path) {
799
+ const issues = [];
800
+ const seen = /* @__PURE__ */ new Set();
801
+ for (const item of items) {
802
+ const id = item[idField];
803
+ if (seen.has(id)) {
804
+ issues.push(
805
+ issue(
806
+ "DUPLICATE_ID",
807
+ `Duplicate ${idField} "${id}"`,
808
+ `${path}.${idField}`
809
+ )
810
+ );
811
+ }
812
+ seen.add(id);
813
+ }
814
+ return issues;
815
+ }
816
+ function validateDomainPack(pack) {
817
+ const issues = [];
818
+ if (!pack.packId || !pack.packId.trim()) {
819
+ issues.push(issue("MISSING_PACK_ID", "packId is required", "packId"));
820
+ } else if (!KEBAB_CASE.test(pack.packId)) {
821
+ issues.push(
822
+ issue(
823
+ "INVALID_PACK_ID",
824
+ `packId "${pack.packId}" must be kebab-case`,
825
+ "packId"
826
+ )
827
+ );
828
+ }
829
+ if (!pack.name || !pack.name.trim()) {
830
+ issues.push(issue("MISSING_NAME", "name is required", "name"));
831
+ }
832
+ if (!pack.version || !pack.version.trim()) {
833
+ issues.push(issue("MISSING_VERSION", "version is required", "version"));
834
+ } else if (!SEMVER.test(pack.version)) {
835
+ issues.push(
836
+ issue(
837
+ "INVALID_VERSION",
838
+ `version "${pack.version}" must be valid semver`,
839
+ "version"
840
+ )
841
+ );
842
+ }
843
+ if (!pack.ontologyBindings || pack.ontologyBindings.length === 0) {
844
+ issues.push(
845
+ issue(
846
+ "MISSING_ONTOLOGY_BINDINGS",
847
+ "At least one ontologyBinding is required",
848
+ "ontologyBindings"
849
+ )
850
+ );
851
+ } else {
852
+ for (const [i, binding] of pack.ontologyBindings.entries()) {
853
+ if (!binding.ontologyId?.trim()) {
854
+ issues.push(
855
+ issue(
856
+ "MISSING_ONTOLOGY_ID",
857
+ `ontologyBinding[${i}].ontologyId is required`,
858
+ `ontologyBindings[${i}].ontologyId`
859
+ )
860
+ );
861
+ }
862
+ if (!binding.versionConstraint?.trim()) {
863
+ issues.push(
864
+ issue(
865
+ "MISSING_VERSION_CONSTRAINT",
866
+ `ontologyBinding[${i}].versionConstraint is required`,
867
+ `ontologyBindings[${i}].versionConstraint`
868
+ )
869
+ );
870
+ }
871
+ if (binding.provisionMode && !ONTOLOGY_PROVISION_MODES.has(binding.provisionMode)) {
872
+ issues.push(
873
+ issue(
874
+ "INVALID_ONTOLOGY_PROVISION_MODE",
875
+ `Unsupported provisionMode "${binding.provisionMode}"`,
876
+ `ontologyBindings[${i}].provisionMode`
877
+ )
878
+ );
879
+ }
880
+ if (binding.provisionMode && binding.provisionMode !== "bind" && !binding.seedRef?.trim()) {
881
+ issues.push(
882
+ issue(
883
+ "MISSING_ONTOLOGY_SEED_REF",
884
+ `ontologyBinding[${i}] requires seedRef when provisionMode is "${binding.provisionMode}"`,
885
+ `ontologyBindings[${i}].seedRef`
886
+ )
887
+ );
888
+ }
889
+ issues.push(
890
+ ...validateStringArray(
891
+ binding.requiredEntityTypes,
892
+ `ontologyBindings[${i}].requiredEntityTypes`,
893
+ "requiredEntityTypes"
894
+ ),
895
+ ...validateStringArray(
896
+ binding.requiredEdgeTypes,
897
+ `ontologyBindings[${i}].requiredEdgeTypes`,
898
+ "requiredEdgeTypes"
899
+ )
900
+ );
901
+ }
902
+ }
903
+ if (!pack.topicRoots || pack.topicRoots.length === 0) {
904
+ issues.push(
905
+ issue(
906
+ "MISSING_TOPIC_ROOTS",
907
+ "At least one topicRoot is required",
908
+ "topicRoots"
909
+ )
910
+ );
911
+ } else {
912
+ issues.push(
913
+ ...checkDuplicateIds(
914
+ pack.topicRoots,
915
+ "slug",
916
+ "topicRoots"
917
+ )
918
+ );
919
+ }
920
+ if (pack.operatingSystem) {
921
+ const knownRootSlugs = new Set(
922
+ pack.topicRoots?.map((topic) => topic.slug) ?? []
923
+ );
924
+ if (pack.operatingSystem.prompts) {
925
+ issues.push(
926
+ ...checkDuplicateIds(
927
+ pack.operatingSystem.prompts,
928
+ "promptId",
929
+ "operatingSystem.prompts"
930
+ )
931
+ );
932
+ pack.operatingSystem.prompts.forEach((prompt, index) => {
933
+ issues.push(...validatePromptBinding(prompt, index));
934
+ });
935
+ }
936
+ if (pack.operatingSystem.tools) {
937
+ issues.push(
938
+ ...checkDuplicateIds(
939
+ pack.operatingSystem.tools,
940
+ "toolId",
941
+ "operatingSystem.tools"
942
+ )
943
+ );
944
+ pack.operatingSystem.tools.forEach((tool, index) => {
945
+ issues.push(...validateToolBinding(tool, index));
946
+ });
947
+ }
948
+ if (pack.operatingSystem.setupAssets) {
949
+ issues.push(
950
+ ...checkDuplicateIds(
951
+ pack.operatingSystem.setupAssets,
952
+ "assetId",
953
+ "operatingSystem.setupAssets"
954
+ )
955
+ );
956
+ pack.operatingSystem.setupAssets.forEach((asset, index) => {
957
+ issues.push(...validateSetupAsset(asset, index));
958
+ });
959
+ }
960
+ const templateSlugs = /* @__PURE__ */ new Set();
961
+ if (pack.operatingSystem.topicTemplates) {
962
+ issues.push(
963
+ ...checkDuplicateIds(
964
+ pack.operatingSystem.topicTemplates,
965
+ "slug",
966
+ "operatingSystem.topicTemplates"
967
+ )
968
+ );
969
+ pack.operatingSystem.topicTemplates.forEach((template) => {
970
+ if (template.slug) {
971
+ templateSlugs.add(template.slug);
972
+ }
973
+ });
974
+ const knownTopicSlugs = /* @__PURE__ */ new Set([...knownRootSlugs, ...templateSlugs]);
975
+ pack.operatingSystem.topicTemplates.forEach((template, index) => {
976
+ issues.push(...validateTopicTemplate(template, index, knownTopicSlugs));
977
+ });
978
+ }
979
+ if (pack.operatingSystem.installProfiles) {
980
+ issues.push(
981
+ ...checkDuplicateIds(
982
+ pack.operatingSystem.installProfiles,
983
+ "profileId",
984
+ "operatingSystem.installProfiles"
985
+ )
986
+ );
987
+ const knownPromptIds = new Set(
988
+ pack.operatingSystem.prompts?.map((prompt) => prompt.promptId) ?? []
989
+ );
990
+ const knownToolIds = new Set(
991
+ pack.operatingSystem.tools?.map((tool) => tool.toolId) ?? []
992
+ );
993
+ const knownAssetIds = new Set(
994
+ pack.operatingSystem.setupAssets?.map((asset) => asset.assetId) ?? []
995
+ );
996
+ const knownTopicSlugs = /* @__PURE__ */ new Set([...knownRootSlugs, ...templateSlugs]);
997
+ pack.operatingSystem.installProfiles.forEach((profile, index) => {
998
+ issues.push(
999
+ ...validateInstallProfile(
1000
+ profile,
1001
+ index,
1002
+ knownPromptIds,
1003
+ knownToolIds,
1004
+ knownAssetIds,
1005
+ knownTopicSlugs
1006
+ )
1007
+ );
1008
+ });
1009
+ }
1010
+ }
1011
+ if (!pack.roles || pack.roles.length === 0) {
1012
+ issues.push(
1013
+ issue("MISSING_ROLES", "At least one reasoning role is required", "roles")
1014
+ );
1015
+ } else {
1016
+ issues.push(
1017
+ ...checkDuplicateIds(
1018
+ pack.roles,
1019
+ "roleId",
1020
+ "roles"
1021
+ )
1022
+ );
1023
+ }
1024
+ const knownGateIds = new Set(pack.gates?.map((g) => g.gateId) ?? []);
1025
+ const knownArtifactIds = new Set(
1026
+ pack.artifacts?.map((a) => a.artifactId) ?? []
1027
+ );
1028
+ const knownRoleIds = new Set(pack.roles?.map((r) => r.roleId) ?? []);
1029
+ if (pack.gates) {
1030
+ issues.push(
1031
+ ...checkDuplicateIds(
1032
+ pack.gates,
1033
+ "gateId",
1034
+ "gates"
1035
+ )
1036
+ );
1037
+ for (const [i, gate] of pack.gates.entries()) {
1038
+ if (!gate.criteria || gate.criteria.length === 0) {
1039
+ issues.push(
1040
+ issue(
1041
+ "EMPTY_GATE_CRITERIA",
1042
+ `Gate "${gate.gateId}" has no criteria`,
1043
+ `gates[${i}].criteria`,
1044
+ "warning"
1045
+ )
1046
+ );
1047
+ } else {
1048
+ issues.push(
1049
+ ...checkDuplicateIds(
1050
+ gate.criteria,
1051
+ "criterionId",
1052
+ `gates[${i}].criteria`
1053
+ )
1054
+ );
1055
+ }
1056
+ }
1057
+ }
1058
+ if (pack.artifacts) {
1059
+ issues.push(
1060
+ ...checkDuplicateIds(
1061
+ pack.artifacts,
1062
+ "artifactId",
1063
+ "artifacts"
1064
+ )
1065
+ );
1066
+ }
1067
+ if (pack.workflows) {
1068
+ issues.push(
1069
+ ...checkDuplicateIds(
1070
+ pack.workflows,
1071
+ "workflowId",
1072
+ "workflows"
1073
+ )
1074
+ );
1075
+ for (const [wi, workflow] of pack.workflows.entries()) {
1076
+ for (const gateId of workflow.gateCheckpoints) {
1077
+ if (!knownGateIds.has(gateId)) {
1078
+ issues.push(
1079
+ issue(
1080
+ "UNKNOWN_GATE_REF",
1081
+ `Workflow "${workflow.workflowId}" references unknown gate "${gateId}"`,
1082
+ `workflows[${wi}].gateCheckpoints`
1083
+ )
1084
+ );
1085
+ }
1086
+ }
1087
+ for (const artifactId of workflow.requiredArtifacts) {
1088
+ if (!knownArtifactIds.has(artifactId)) {
1089
+ issues.push(
1090
+ issue(
1091
+ "UNKNOWN_ARTIFACT_REF",
1092
+ `Workflow "${workflow.workflowId}" references unknown artifact "${artifactId}"`,
1093
+ `workflows[${wi}].requiredArtifacts`
1094
+ )
1095
+ );
1096
+ }
1097
+ }
1098
+ for (const [si, step] of workflow.steps.entries()) {
1099
+ for (const roleId of step.requiredRoles) {
1100
+ if (!knownRoleIds.has(roleId)) {
1101
+ issues.push(
1102
+ issue(
1103
+ "UNKNOWN_ROLE_REF",
1104
+ `Step "${step.stepId}" references unknown role "${roleId}"`,
1105
+ `workflows[${wi}].steps[${si}].requiredRoles`
1106
+ )
1107
+ );
1108
+ }
1109
+ }
1110
+ if (step.gateId && !knownGateIds.has(step.gateId)) {
1111
+ issues.push(
1112
+ issue(
1113
+ "UNKNOWN_GATE_REF",
1114
+ `Step "${step.stepId}" references unknown gate "${step.gateId}"`,
1115
+ `workflows[${wi}].steps[${si}].gateId`
1116
+ )
1117
+ );
1118
+ }
1119
+ if (step.produces) {
1120
+ for (const artifactId of step.produces) {
1121
+ if (!knownArtifactIds.has(artifactId)) {
1122
+ issues.push(
1123
+ issue(
1124
+ "UNKNOWN_ARTIFACT_REF",
1125
+ `Step "${step.stepId}" references unknown artifact "${artifactId}"`,
1126
+ `workflows[${wi}].steps[${si}].produces`
1127
+ )
1128
+ );
1129
+ }
1130
+ }
1131
+ }
1132
+ }
1133
+ }
1134
+ }
1135
+ if (pack.inquiryShaping) {
1136
+ if (pack.inquiryShaping.questionTemplates) {
1137
+ issues.push(
1138
+ ...checkDuplicateIds(
1139
+ pack.inquiryShaping.questionTemplates,
1140
+ "templateId",
1141
+ "inquiryShaping.questionTemplates"
1142
+ )
1143
+ );
1144
+ pack.inquiryShaping.questionTemplates.forEach((template, index) => {
1145
+ issues.push(...validateQuestionTemplate(template, index));
1146
+ });
1147
+ }
1148
+ if (pack.inquiryShaping.taskTemplates) {
1149
+ issues.push(
1150
+ ...checkDuplicateIds(
1151
+ pack.inquiryShaping.taskTemplates,
1152
+ "templateId",
1153
+ "inquiryShaping.taskTemplates"
1154
+ )
1155
+ );
1156
+ pack.inquiryShaping.taskTemplates.forEach((template, index) => {
1157
+ issues.push(...validateTaskTemplate(template, index));
1158
+ });
1159
+ }
1160
+ if (pack.inquiryShaping.frameworkHints) {
1161
+ issues.push(
1162
+ ...checkDuplicateIds(
1163
+ pack.inquiryShaping.frameworkHints.map((hint) => ({
1164
+ frameworkName: hint.frameworkName
1165
+ })),
1166
+ "frameworkName",
1167
+ "inquiryShaping.frameworkHints"
1168
+ )
1169
+ );
1170
+ pack.inquiryShaping.frameworkHints.forEach((hint, index) => {
1171
+ issues.push(...validateFrameworkHint(hint, index));
1172
+ });
1173
+ }
1174
+ }
1175
+ return {
1176
+ valid: issues.filter((i) => i.severity === "error").length === 0,
1177
+ issues
1178
+ };
1179
+ }
1180
+
1181
+ // src/domain-pack/authoring.validation.ts
1182
+ var KEBAB_CASE2 = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
1183
+ var SEMVER2 = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;
1184
+ var LEGACY_PUBLIC_KEYS = /* @__PURE__ */ new Set([
1185
+ "project",
1186
+ "projects",
1187
+ "projectId",
1188
+ "projectIds",
1189
+ "sprint",
1190
+ "sprints",
1191
+ "sprintId",
1192
+ "sprintIds"
1193
+ ]);
1194
+ var SCHEMA_EXTENSION_TARGETS = /* @__PURE__ */ new Set([
1195
+ "artifact",
1196
+ "workflow",
1197
+ "gate",
1198
+ "prompt",
1199
+ "tool",
1200
+ "install-profile",
1201
+ "topic-template"
1202
+ ]);
1203
+ var ONTOLOGY_CONSTRAINT_SEVERITIES = /* @__PURE__ */ new Set([
1204
+ "error",
1205
+ "warning",
1206
+ "informational"
1207
+ ]);
1208
+ var LINEAGE_MODES = /* @__PURE__ */ new Set(["root", "remix", "fork"]);
1209
+ var AUTHORING_TOOL_NAMES = {
1210
+ validate: "validate_domain_pack_manifest",
1211
+ preview: "preview_domain_pack_manifest",
1212
+ publish: "publish_domain_pack_manifest"
1213
+ };
1214
+ function issue2(code, message, path, source, severity = "error") {
1215
+ return { code, message, path, severity, source };
1216
+ }
1217
+ function emptyCounts() {
1218
+ return {
1219
+ topicRoots: 0,
1220
+ workflows: 0,
1221
+ gates: 0,
1222
+ artifacts: 0,
1223
+ roles: 0,
1224
+ prompts: 0,
1225
+ tools: 0,
1226
+ setupAssets: 0,
1227
+ installProfiles: 0,
1228
+ frameworks: 0,
1229
+ schemaExtensions: 0,
1230
+ ontologyExtensions: 0
1231
+ };
1232
+ }
1233
+ function isPlainObject2(value) {
1234
+ return typeof value === "object" && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
1235
+ }
1236
+ function describeParseFailure(error) {
1237
+ return error instanceof Error ? error.message : "Manifest parse failed.";
1238
+ }
1239
+ function asToolDefinition(tool) {
1240
+ return tool;
1241
+ }
1242
+ function detectDomainPackManifestFormat2(source, explicitFormat) {
1243
+ if (explicitFormat) {
1244
+ return explicitFormat;
1245
+ }
1246
+ const trimmed = source.trim();
1247
+ if (trimmed.startsWith("{")) {
1248
+ return "json";
1249
+ }
1250
+ return "yaml";
1251
+ }
1252
+ function validateFrameworks(frameworks) {
1253
+ if (!frameworks) {
1254
+ return [];
1255
+ }
1256
+ const issues = [];
1257
+ const seen = /* @__PURE__ */ new Set();
1258
+ frameworks.forEach((framework, index) => {
1259
+ const path = `frameworks[${index}]`;
1260
+ if (!framework.frameworkId) {
1261
+ issues.push(
1262
+ issue2(
1263
+ "MISSING_FRAMEWORK_ID",
1264
+ "frameworkId is required",
1265
+ `${path}.frameworkId`,
1266
+ "framework"
1267
+ )
1268
+ );
1269
+ } else if (!KEBAB_CASE2.test(framework.frameworkId)) {
1270
+ issues.push(
1271
+ issue2(
1272
+ "INVALID_FRAMEWORK_ID",
1273
+ `frameworkId "${framework.frameworkId}" must be kebab-case`,
1274
+ `${path}.frameworkId`,
1275
+ "framework"
1276
+ )
1277
+ );
1278
+ } else if (seen.has(framework.frameworkId)) {
1279
+ issues.push(
1280
+ issue2(
1281
+ "DUPLICATE_FRAMEWORK_ID",
1282
+ `Duplicate frameworkId "${framework.frameworkId}"`,
1283
+ `${path}.frameworkId`,
1284
+ "framework"
1285
+ )
1286
+ );
1287
+ } else {
1288
+ seen.add(framework.frameworkId);
1289
+ }
1290
+ if (!framework.version) {
1291
+ issues.push(
1292
+ issue2(
1293
+ "MISSING_FRAMEWORK_VERSION",
1294
+ "version is required",
1295
+ `${path}.version`,
1296
+ "framework"
1297
+ )
1298
+ );
1299
+ } else if (!SEMVER2.test(framework.version)) {
1300
+ issues.push(
1301
+ issue2(
1302
+ "INVALID_FRAMEWORK_VERSION",
1303
+ `framework version "${framework.version}" must be valid semver`,
1304
+ `${path}.version`,
1305
+ "framework"
1306
+ )
1307
+ );
1308
+ }
1309
+ });
1310
+ return issues;
1311
+ }
1312
+ function validateSchemaExtensions(extensions) {
1313
+ if (!extensions) {
1314
+ return [];
1315
+ }
1316
+ const issues = [];
1317
+ const seen = /* @__PURE__ */ new Set();
1318
+ extensions.forEach((extension, index) => {
1319
+ const path = `schemaExtensions[${index}]`;
1320
+ if (!extension.extensionId) {
1321
+ issues.push(
1322
+ issue2(
1323
+ "MISSING_SCHEMA_EXTENSION_ID",
1324
+ "extensionId is required",
1325
+ `${path}.extensionId`,
1326
+ "schema-extension"
1327
+ )
1328
+ );
1329
+ } else if (!KEBAB_CASE2.test(extension.extensionId)) {
1330
+ issues.push(
1331
+ issue2(
1332
+ "INVALID_SCHEMA_EXTENSION_ID",
1333
+ `extensionId "${extension.extensionId}" must be kebab-case`,
1334
+ `${path}.extensionId`,
1335
+ "schema-extension"
1336
+ )
1337
+ );
1338
+ } else if (seen.has(extension.extensionId)) {
1339
+ issues.push(
1340
+ issue2(
1341
+ "DUPLICATE_SCHEMA_EXTENSION_ID",
1342
+ `Duplicate schema extension "${extension.extensionId}"`,
1343
+ `${path}.extensionId`,
1344
+ "schema-extension"
1345
+ )
1346
+ );
1347
+ } else {
1348
+ seen.add(extension.extensionId);
1349
+ }
1350
+ if (!SCHEMA_EXTENSION_TARGETS.has(extension.target)) {
1351
+ issues.push(
1352
+ issue2(
1353
+ "INVALID_SCHEMA_EXTENSION_TARGET",
1354
+ `Unsupported schema extension target "${extension.target}"`,
1355
+ `${path}.target`,
1356
+ "schema-extension"
1357
+ )
1358
+ );
1359
+ }
1360
+ if (!extension.description) {
1361
+ issues.push(
1362
+ issue2(
1363
+ "MISSING_SCHEMA_EXTENSION_DESCRIPTION",
1364
+ "description is required",
1365
+ `${path}.description`,
1366
+ "schema-extension"
1367
+ )
1368
+ );
1369
+ }
1370
+ if (!SEMVER2.test(extension.version)) {
1371
+ issues.push(
1372
+ issue2(
1373
+ "INVALID_SCHEMA_EXTENSION_VERSION",
1374
+ `schema extension version "${extension.version}" must be valid semver`,
1375
+ `${path}.version`,
1376
+ "schema-extension"
1377
+ )
1378
+ );
1379
+ }
1380
+ if (!isPlainObject2(extension.schema)) {
1381
+ issues.push(
1382
+ issue2(
1383
+ "INVALID_SCHEMA_EXTENSION_SCHEMA",
1384
+ "schema extension schema must be a plain object",
1385
+ `${path}.schema`,
1386
+ "schema-extension"
1387
+ )
1388
+ );
1389
+ }
1390
+ });
1391
+ return issues;
1392
+ }
1393
+ function validateOntologyExtensions(extensions) {
1394
+ if (!extensions) {
1395
+ return [];
1396
+ }
1397
+ const issues = [];
1398
+ const seen = /* @__PURE__ */ new Set();
1399
+ extensions.forEach((extension, index) => {
1400
+ const path = `ontologyExtensions[${index}]`;
1401
+ if (!extension.extensionId) {
1402
+ issues.push(
1403
+ issue2(
1404
+ "MISSING_ONTOLOGY_EXTENSION_ID",
1405
+ "extensionId is required",
1406
+ `${path}.extensionId`,
1407
+ "ontology-extension"
1408
+ )
1409
+ );
1410
+ } else if (!KEBAB_CASE2.test(extension.extensionId)) {
1411
+ issues.push(
1412
+ issue2(
1413
+ "INVALID_ONTOLOGY_EXTENSION_ID",
1414
+ `extensionId "${extension.extensionId}" must be kebab-case`,
1415
+ `${path}.extensionId`,
1416
+ "ontology-extension"
1417
+ )
1418
+ );
1419
+ } else if (seen.has(extension.extensionId)) {
1420
+ issues.push(
1421
+ issue2(
1422
+ "DUPLICATE_ONTOLOGY_EXTENSION_ID",
1423
+ `Duplicate ontology extension "${extension.extensionId}"`,
1424
+ `${path}.extensionId`,
1425
+ "ontology-extension"
1426
+ )
1427
+ );
1428
+ } else {
1429
+ seen.add(extension.extensionId);
1430
+ }
1431
+ if (!extension.ontologyId) {
1432
+ issues.push(
1433
+ issue2(
1434
+ "MISSING_ONTOLOGY_EXTENSION_TARGET",
1435
+ "ontologyId is required",
1436
+ `${path}.ontologyId`,
1437
+ "ontology-extension"
1438
+ )
1439
+ );
1440
+ }
1441
+ if (!extension.baseVersionConstraint) {
1442
+ issues.push(
1443
+ issue2(
1444
+ "MISSING_ONTOLOGY_BASE_VERSION",
1445
+ "baseVersionConstraint is required",
1446
+ `${path}.baseVersionConstraint`,
1447
+ "ontology-extension"
1448
+ )
1449
+ );
1450
+ }
1451
+ if (extension.additiveOnly !== true) {
1452
+ issues.push(
1453
+ issue2(
1454
+ "NON_MONOTONIC_ONTOLOGY_EXTENSION",
1455
+ "ontology extensions must set additiveOnly=true",
1456
+ `${path}.additiveOnly`,
1457
+ "ontology-extension"
1458
+ )
1459
+ );
1460
+ }
1461
+ const entityTypeValues = /* @__PURE__ */ new Set();
1462
+ extension.entityTypes?.forEach(
1463
+ (entityType, entityTypeIndex) => {
1464
+ const entityPath = `${path}.entityTypes[${entityTypeIndex}]`;
1465
+ if (!entityType.value || !KEBAB_CASE2.test(entityType.value)) {
1466
+ issues.push(
1467
+ issue2(
1468
+ "INVALID_ONTOLOGY_ENTITY_VALUE",
1469
+ "entity extension value must be kebab-case",
1470
+ `${entityPath}.value`,
1471
+ "ontology-extension"
1472
+ )
1473
+ );
1474
+ } else if (entityTypeValues.has(entityType.value)) {
1475
+ issues.push(
1476
+ issue2(
1477
+ "DUPLICATE_ONTOLOGY_ENTITY_VALUE",
1478
+ `Duplicate entity extension value "${entityType.value}"`,
1479
+ `${entityPath}.value`,
1480
+ "ontology-extension"
1481
+ )
1482
+ );
1483
+ } else {
1484
+ entityTypeValues.add(entityType.value);
1485
+ }
1486
+ if (!entityType.label) {
1487
+ issues.push(
1488
+ issue2(
1489
+ "MISSING_ONTOLOGY_ENTITY_LABEL",
1490
+ "entity extension label is required",
1491
+ `${entityPath}.label`,
1492
+ "ontology-extension"
1493
+ )
1494
+ );
1495
+ }
1496
+ }
1497
+ );
1498
+ const edgeTypeValues = /* @__PURE__ */ new Set();
1499
+ extension.edgeTypes?.forEach(
1500
+ (edgeType, edgeTypeIndex) => {
1501
+ const edgePath = `${path}.edgeTypes[${edgeTypeIndex}]`;
1502
+ if (!edgeType.value || !KEBAB_CASE2.test(edgeType.value)) {
1503
+ issues.push(
1504
+ issue2(
1505
+ "INVALID_ONTOLOGY_EDGE_VALUE",
1506
+ "edge extension value must be kebab-case",
1507
+ `${edgePath}.value`,
1508
+ "ontology-extension"
1509
+ )
1510
+ );
1511
+ } else if (edgeTypeValues.has(edgeType.value)) {
1512
+ issues.push(
1513
+ issue2(
1514
+ "DUPLICATE_ONTOLOGY_EDGE_VALUE",
1515
+ `Duplicate edge extension value "${edgeType.value}"`,
1516
+ `${edgePath}.value`,
1517
+ "ontology-extension"
1518
+ )
1519
+ );
1520
+ } else {
1521
+ edgeTypeValues.add(edgeType.value);
1522
+ }
1523
+ if (!edgeType.label) {
1524
+ issues.push(
1525
+ issue2(
1526
+ "MISSING_ONTOLOGY_EDGE_LABEL",
1527
+ "edge extension label is required",
1528
+ `${edgePath}.label`,
1529
+ "ontology-extension"
1530
+ )
1531
+ );
1532
+ }
1533
+ if (edgeType.constraintSeverity && !ONTOLOGY_CONSTRAINT_SEVERITIES.has(edgeType.constraintSeverity)) {
1534
+ issues.push(
1535
+ issue2(
1536
+ "INVALID_ONTOLOGY_EDGE_SEVERITY",
1537
+ `Unsupported constraint severity "${edgeType.constraintSeverity}"`,
1538
+ `${edgePath}.constraintSeverity`,
1539
+ "ontology-extension"
1540
+ )
1541
+ );
1542
+ }
1543
+ }
1544
+ );
1545
+ });
1546
+ return issues;
1547
+ }
1548
+ function validateLineage(lineage, packId) {
1549
+ const issues = [];
1550
+ if (!LINEAGE_MODES.has(lineage.mode)) {
1551
+ issues.push(
1552
+ issue2(
1553
+ "INVALID_LINEAGE_MODE",
1554
+ `Unsupported lineage mode "${lineage.mode}"`,
1555
+ "lineage.mode",
1556
+ "lineage"
1557
+ )
1558
+ );
1559
+ return issues;
1560
+ }
1561
+ if (lineage.mode === "root") {
1562
+ if (lineage.parentPackId || lineage.parentVersion || lineage.supersedesPackId) {
1563
+ issues.push(
1564
+ issue2(
1565
+ "ROOT_LINEAGE_HAS_PARENT",
1566
+ "root lineage cannot declare parent or supersedes metadata",
1567
+ "lineage",
1568
+ "lineage"
1569
+ )
1570
+ );
1571
+ }
1572
+ return issues;
1573
+ }
1574
+ if (!lineage.parentPackId) {
1575
+ issues.push(
1576
+ issue2(
1577
+ "MISSING_LINEAGE_PARENT_PACK",
1578
+ "parentPackId is required for remix or fork lineage",
1579
+ "lineage.parentPackId",
1580
+ "lineage"
1581
+ )
1582
+ );
1583
+ } else if (!KEBAB_CASE2.test(lineage.parentPackId)) {
1584
+ issues.push(
1585
+ issue2(
1586
+ "INVALID_LINEAGE_PARENT_PACK",
1587
+ `parentPackId "${lineage.parentPackId}" must be kebab-case`,
1588
+ "lineage.parentPackId",
1589
+ "lineage"
1590
+ )
1591
+ );
1592
+ }
1593
+ if (!lineage.parentVersion) {
1594
+ issues.push(
1595
+ issue2(
1596
+ "MISSING_LINEAGE_PARENT_VERSION",
1597
+ "parentVersion is required for remix or fork lineage",
1598
+ "lineage.parentVersion",
1599
+ "lineage"
1600
+ )
1601
+ );
1602
+ } else if (!SEMVER2.test(lineage.parentVersion)) {
1603
+ issues.push(
1604
+ issue2(
1605
+ "INVALID_LINEAGE_PARENT_VERSION",
1606
+ `parentVersion "${lineage.parentVersion}" must be valid semver`,
1607
+ "lineage.parentVersion",
1608
+ "lineage"
1609
+ )
1610
+ );
1611
+ }
1612
+ if (lineage.parentPackId && lineage.parentPackId === packId && lineage.parentVersion === void 0) {
1613
+ issues.push(
1614
+ issue2(
1615
+ "SELF_REFERENTIAL_LINEAGE",
1616
+ "lineage parentPackId cannot equal the child packId without an explicit parentVersion",
1617
+ "lineage.parentPackId",
1618
+ "lineage"
1619
+ )
1620
+ );
1621
+ }
1622
+ if (lineage.mode === "remix" && lineage.supersedesPackId) {
1623
+ issues.push(
1624
+ issue2(
1625
+ "REMIX_LINEAGE_SUPERSEDES",
1626
+ "remix lineage cannot declare supersedesPackId",
1627
+ "lineage.supersedesPackId",
1628
+ "lineage"
1629
+ )
1630
+ );
1631
+ }
1632
+ if (lineage.mode === "fork") {
1633
+ if (!lineage.supersedesPackId) {
1634
+ issues.push(
1635
+ issue2(
1636
+ "MISSING_SUPERSEDES_PACK",
1637
+ "fork lineage requires supersedesPackId to model the supersedes edge",
1638
+ "lineage.supersedesPackId",
1639
+ "lineage"
1640
+ )
1641
+ );
1642
+ } else if (!KEBAB_CASE2.test(lineage.supersedesPackId)) {
1643
+ issues.push(
1644
+ issue2(
1645
+ "INVALID_SUPERSEDES_PACK",
1646
+ `supersedesPackId "${lineage.supersedesPackId}" must be kebab-case`,
1647
+ "lineage.supersedesPackId",
1648
+ "lineage"
1649
+ )
1650
+ );
1651
+ }
1652
+ }
1653
+ return issues;
1654
+ }
1655
+ function scanLegacyPublicKeys(value, path = "") {
1656
+ const issues = [];
1657
+ if (Array.isArray(value)) {
1658
+ value.forEach((entry, index) => {
1659
+ issues.push(...scanLegacyPublicKeys(entry, `${path}[${index}]`));
1660
+ });
1661
+ return issues;
1662
+ }
1663
+ if (!isPlainObject2(value)) {
1664
+ return issues;
1665
+ }
1666
+ Object.entries(value).forEach(([key, entryValue]) => {
1667
+ const nextPath = path ? `${path}.${key}` : key;
1668
+ if (LEGACY_PUBLIC_KEYS.has(key)) {
1669
+ issues.push(
1670
+ issue2(
1671
+ "LEGACY_PUBLIC_TERM",
1672
+ `Public manifest field "${key}" uses legacy terminology; expose canonical topic/worktree terms instead.`,
1673
+ nextPath,
1674
+ "terminology"
1675
+ )
1676
+ );
1677
+ }
1678
+ issues.push(...scanLegacyPublicKeys(entryValue, nextPath));
1679
+ });
1680
+ return issues;
1681
+ }
1682
+ function createManifestDigest(manifest) {
1683
+ const data = serializeDomainPackAuthoringManifest(manifest, "json");
1684
+ let h1 = 2166136261 | 0;
1685
+ let h2 = 2166136261 | 0;
1686
+ for (let i = 0; i < data.length; i++) {
1687
+ const c = data.charCodeAt(i);
1688
+ h1 = Math.imul(h1 ^ c, 16777619);
1689
+ h2 = Math.imul(h2 ^ (c >>> 4 | c << 4), 16777619);
1690
+ }
1691
+ return (h1 >>> 0).toString(16).padStart(8, "0") + (h2 >>> 0).toString(16).padStart(8, "0");
1692
+ }
1693
+ function evaluateDomainPackAuthoringManifest(manifest, format = null) {
1694
+ const issues = [];
1695
+ if (manifest.kind !== DOMAIN_PACK_MANIFEST_KIND) {
1696
+ issues.push(
1697
+ issue2(
1698
+ "INVALID_MANIFEST_KIND",
1699
+ `kind must be "${DOMAIN_PACK_MANIFEST_KIND}"`,
1700
+ "kind",
1701
+ "manifest"
1702
+ )
1703
+ );
1704
+ }
1705
+ if (!SEMVER2.test(manifest.manifestVersion)) {
1706
+ issues.push(
1707
+ issue2(
1708
+ "INVALID_MANIFEST_VERSION",
1709
+ `manifestVersion "${manifest.manifestVersion}" must be valid semver`,
1710
+ "manifestVersion",
1711
+ "manifest"
1712
+ )
1713
+ );
1714
+ }
1715
+ issues.push(...validateFrameworks(manifest.frameworks));
1716
+ issues.push(...validateSchemaExtensions(manifest.schemaExtensions));
1717
+ issues.push(...validateOntologyExtensions(manifest.ontologyExtensions));
1718
+ issues.push(...validateLineage(manifest.lineage, manifest.pack.packId));
1719
+ issues.push(...scanLegacyPublicKeys(manifest));
1720
+ const packValidation = validateDomainPack(manifest.pack);
1721
+ issues.push(
1722
+ ...packValidation.issues.map((packIssue) => ({
1723
+ ...packIssue,
1724
+ path: `pack.${packIssue.path}`,
1725
+ source: "pack"
1726
+ }))
1727
+ );
1728
+ return {
1729
+ valid: issues.every((currentIssue) => currentIssue.severity !== "error"),
1730
+ format,
1731
+ manifest,
1732
+ manifestDigest: createManifestDigest(manifest),
1733
+ issues,
1734
+ counts: countManifestArtifacts(manifest)
1735
+ };
1736
+ }
1737
+ function parseFailureResult(error, format) {
1738
+ return {
1739
+ valid: false,
1740
+ format,
1741
+ manifest: null,
1742
+ manifestDigest: null,
1743
+ issues: [
1744
+ issue2(
1745
+ "PARSE_ERROR",
1746
+ describeParseFailure(error),
1747
+ "manifest",
1748
+ "parse"
1749
+ )
1750
+ ],
1751
+ counts: emptyCounts()
1752
+ };
1753
+ }
1754
+ function validateDomainPackAuthoringManifest(manifest) {
1755
+ return evaluateDomainPackAuthoringManifest(
1756
+ defineDomainPackAuthoringManifest(
1757
+ manifest
1758
+ )
1759
+ );
1760
+ }
1761
+ function validateDomainPackAuthoringManifestSource(source, format) {
1762
+ const detectedFormat = detectDomainPackManifestFormat2(source, format);
1763
+ try {
1764
+ const manifest = parseDomainPackAuthoringManifest(source, detectedFormat);
1765
+ return evaluateDomainPackAuthoringManifest(manifest, detectedFormat);
1766
+ } catch (error) {
1767
+ return parseFailureResult(error, detectedFormat);
1768
+ }
1769
+ }
1770
+ function collectRuntimeTargets(manifest) {
1771
+ if (!manifest) {
1772
+ return [];
1773
+ }
1774
+ const targets = /* @__PURE__ */ new Set();
1775
+ manifest.frameworks?.forEach(
1776
+ (framework) => framework.runtimeTargets?.forEach((target) => targets.add(target))
1777
+ );
1778
+ manifest.pack.operatingSystem?.prompts?.forEach(
1779
+ (prompt) => prompt.runtimeTargets?.forEach((target) => targets.add(target))
1780
+ );
1781
+ manifest.pack.operatingSystem?.tools?.forEach(
1782
+ (tool) => tool.runtimeTargets?.forEach((target) => targets.add(target))
1783
+ );
1784
+ manifest.pack.operatingSystem?.setupAssets?.forEach(
1785
+ (asset) => asset.runtimeTargets?.forEach((target) => targets.add(target))
1786
+ );
1787
+ manifest.pack.operatingSystem?.installProfiles?.forEach(
1788
+ (profile) => targets.add(profile.runtimeTarget)
1789
+ );
1790
+ return Array.from(targets).sort();
1791
+ }
1792
+ function describeLineage(lineage) {
1793
+ if (!lineage) {
1794
+ return null;
1795
+ }
1796
+ if (lineage.mode === "root") {
1797
+ return "Root pack with no parent lineage.";
1798
+ }
1799
+ if (lineage.mode === "remix") {
1800
+ return `Remix of ${lineage.parentPackId}@${lineage.parentVersion}.`;
1801
+ }
1802
+ return `Fork of ${lineage.parentPackId}@${lineage.parentVersion} that supersedes ${lineage.supersedesPackId}.`;
1803
+ }
1804
+ function previewDomainPackAuthoringManifest(manifest) {
1805
+ const validation = validateDomainPackAuthoringManifest(manifest);
1806
+ return {
1807
+ ...validation,
1808
+ readyToPublish: validation.valid,
1809
+ canonicalJson: validation.manifest ? serializeDomainPackAuthoringManifest(validation.manifest, "json") : null,
1810
+ canonicalYaml: validation.manifest ? serializeDomainPackAuthoringManifest(validation.manifest, "yaml") : null,
1811
+ lineageSummary: describeLineage(validation.manifest?.lineage ?? null),
1812
+ requiredRuntimeTargets: collectRuntimeTargets(validation.manifest)
1813
+ };
1814
+ }
1815
+ function previewDomainPackAuthoringManifestSource(source, format) {
1816
+ const validation = validateDomainPackAuthoringManifestSource(source, format);
1817
+ return {
1818
+ ...validation,
1819
+ readyToPublish: validation.valid,
1820
+ canonicalJson: validation.manifest ? serializeDomainPackAuthoringManifest(validation.manifest, "json") : null,
1821
+ canonicalYaml: validation.manifest ? serializeDomainPackAuthoringManifest(validation.manifest, "yaml") : null,
1822
+ lineageSummary: describeLineage(validation.manifest?.lineage ?? null),
1823
+ requiredRuntimeTargets: collectRuntimeTargets(validation.manifest)
1824
+ };
1825
+ }
1826
+ function buildLineageEdge(manifest) {
1827
+ const { lineage, pack } = manifest;
1828
+ if (lineage.mode === "root") {
1829
+ return null;
1830
+ }
1831
+ if (lineage.mode === "remix") {
1832
+ return {
1833
+ edgeType: "remixed_from",
1834
+ childPackId: pack.packId,
1835
+ parentPackId: lineage.parentPackId,
1836
+ parentVersion: lineage.parentVersion
1837
+ };
1838
+ }
1839
+ return {
1840
+ edgeType: "supersedes",
1841
+ childPackId: pack.packId,
1842
+ parentPackId: lineage.supersedesPackId,
1843
+ parentVersion: lineage.parentVersion
1844
+ };
1845
+ }
1846
+ function publishDomainPackAuthoringManifest(manifest) {
1847
+ const preview = previewDomainPackAuthoringManifest(manifest);
1848
+ if (!preview.readyToPublish || !preview.manifest || !preview.manifestDigest) {
1849
+ return {
1850
+ published: false,
1851
+ preview,
1852
+ publication: null
1853
+ };
1854
+ }
1855
+ return {
1856
+ published: true,
1857
+ preview,
1858
+ publication: {
1859
+ publicationId: `${preview.manifest.pack.packId}@${preview.manifest.pack.version}`,
1860
+ packId: preview.manifest.pack.packId,
1861
+ version: preview.manifest.pack.version,
1862
+ manifestDigest: preview.manifestDigest,
1863
+ manifest: preview.manifest,
1864
+ lineageEdge: buildLineageEdge(preview.manifest),
1865
+ canonicalJson: preview.canonicalJson,
1866
+ canonicalYaml: preview.canonicalYaml
1867
+ }
1868
+ };
1869
+ }
1870
+ function publishDomainPackAuthoringManifestSource(source, format) {
1871
+ const preview = previewDomainPackAuthoringManifestSource(source, format);
1872
+ if (!preview.readyToPublish || !preview.manifest || !preview.manifestDigest) {
1873
+ return {
1874
+ published: false,
1875
+ preview,
1876
+ publication: null
1877
+ };
1878
+ }
1879
+ return {
1880
+ published: true,
1881
+ preview,
1882
+ publication: {
1883
+ publicationId: `${preview.manifest.pack.packId}@${preview.manifest.pack.version}`,
1884
+ packId: preview.manifest.pack.packId,
1885
+ version: preview.manifest.pack.version,
1886
+ manifestDigest: preview.manifestDigest,
1887
+ manifest: preview.manifest,
1888
+ lineageEdge: buildLineageEdge(preview.manifest),
1889
+ canonicalJson: preview.canonicalJson,
1890
+ canonicalYaml: preview.canonicalYaml
1891
+ }
1892
+ };
1893
+ }
1894
+ function createDomainPackAuthoringTools() {
1895
+ const inputSchema = {
1896
+ type: "object",
1897
+ properties: {
1898
+ manifestText: {
1899
+ type: "string",
1900
+ description: "Domain pack manifest text in JSON or YAML form."
1901
+ },
1902
+ format: {
1903
+ type: "string",
1904
+ enum: ["json", "yaml"],
1905
+ description: "Optional manifest format override."
1906
+ }
1907
+ },
1908
+ required: ["manifestText"],
1909
+ additionalProperties: false
1910
+ };
1911
+ return {
1912
+ validate: asToolDefinition({
1913
+ name: AUTHORING_TOOL_NAMES.validate,
1914
+ description: "Validate a domain pack authoring manifest and return structural, lineage, terminology, and extension issues.",
1915
+ inputSchema,
1916
+ execute: (args) => validateDomainPackAuthoringManifestSource(args.manifestText, args.format)
1917
+ }),
1918
+ preview: asToolDefinition({
1919
+ name: AUTHORING_TOOL_NAMES.preview,
1920
+ description: "Preview a domain pack manifest with canonical JSON/YAML renderings, runtime targets, and publication readiness.",
1921
+ inputSchema,
1922
+ execute: (args) => previewDomainPackAuthoringManifestSource(args.manifestText, args.format)
1923
+ }),
1924
+ publish: asToolDefinition({
1925
+ name: AUTHORING_TOOL_NAMES.publish,
1926
+ description: "Build a publication-ready domain pack artifact when validation passes, including remix/fork lineage metadata.",
1927
+ inputSchema,
1928
+ execute: (args) => publishDomainPackAuthoringManifestSource(args.manifestText, args.format)
1929
+ })
1930
+ };
1931
+ }
1932
+ var domainPackAuthoringValidation = {
1933
+ validateDomainPackAuthoringManifest,
1934
+ validateDomainPackAuthoringManifestSource,
1935
+ previewDomainPackAuthoringManifest,
1936
+ previewDomainPackAuthoringManifestSource,
1937
+ publishDomainPackAuthoringManifest,
1938
+ publishDomainPackAuthoringManifestSource,
1939
+ createDomainPackAuthoringTools
1940
+ };
1941
+
1942
+ export { domainPackAuthoringValidation };
1943
+ //# sourceMappingURL=authoring.validation.js.map
1944
+ //# sourceMappingURL=authoring.validation.js.map