@lucern/pack-host 0.1.0-alpha.2

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 (104) hide show
  1. package/README.md +64 -0
  2. package/dist/contracts.d.ts +77 -0
  3. package/dist/contracts.js +21 -0
  4. package/dist/contracts.js.map +1 -0
  5. package/dist/convex.config.d.ts +5 -0
  6. package/dist/convex.config.js +9 -0
  7. package/dist/convex.config.js.map +1 -0
  8. package/dist/dependencyResolution.d.ts +18 -0
  9. package/dist/dependencyResolution.js +131 -0
  10. package/dist/dependencyResolution.js.map +1 -0
  11. package/dist/domain-pack/authoring.d.ts +172 -0
  12. package/dist/domain-pack/authoring.js +1896 -0
  13. package/dist/domain-pack/authoring.js.map +1 -0
  14. package/dist/domain-pack/contracts.d.ts +183 -0
  15. package/dist/domain-pack/contracts.js +65 -0
  16. package/dist/domain-pack/contracts.js.map +1 -0
  17. package/dist/domain-pack/index.d.ts +8 -0
  18. package/dist/domain-pack/index.js +3813 -0
  19. package/dist/domain-pack/index.js.map +1 -0
  20. package/dist/domain-pack/ontology/software-entities-v1.d.ts +102 -0
  21. package/dist/domain-pack/ontology/software-entities-v1.js +104 -0
  22. package/dist/domain-pack/ontology/software-entities-v1.js.map +1 -0
  23. package/dist/domain-pack/packs/developer-reasoning.d.ts +14 -0
  24. package/dist/domain-pack/packs/developer-reasoning.js +339 -0
  25. package/dist/domain-pack/packs/developer-reasoning.js.map +1 -0
  26. package/dist/domain-pack/packs/engineering-accelerator.d.ts +11 -0
  27. package/dist/domain-pack/packs/engineering-accelerator.js +1348 -0
  28. package/dist/domain-pack/packs/engineering-accelerator.js.map +1 -0
  29. package/dist/domain-pack/packs/index.d.ts +18 -0
  30. package/dist/domain-pack/packs/index.js +2653 -0
  31. package/dist/domain-pack/packs/index.js.map +1 -0
  32. package/dist/domain-pack/shaping.d.ts +54 -0
  33. package/dist/domain-pack/shaping.js +1013 -0
  34. package/dist/domain-pack/shaping.js.map +1 -0
  35. package/dist/domain-pack/validation.d.ts +26 -0
  36. package/dist/domain-pack/validation.js +775 -0
  37. package/dist/domain-pack/validation.js.map +1 -0
  38. package/dist/domain-pack.d.ts +8 -0
  39. package/dist/domain-pack.js +3813 -0
  40. package/dist/domain-pack.js.map +1 -0
  41. package/dist/index.d.ts +29 -0
  42. package/dist/index.js +5520 -0
  43. package/dist/index.js.map +1 -0
  44. package/dist/lifecycle.d.ts +27 -0
  45. package/dist/lifecycle.js +98 -0
  46. package/dist/lifecycle.js.map +1 -0
  47. package/dist/manifestValidation.d.ts +28 -0
  48. package/dist/manifestValidation.js +253 -0
  49. package/dist/manifestValidation.js.map +1 -0
  50. package/dist/manifests/chat-v1.d.ts +10 -0
  51. package/dist/manifests/chat-v1.js +87 -0
  52. package/dist/manifests/chat-v1.js.map +1 -0
  53. package/dist/manifests/deals-v1.d.ts +10 -0
  54. package/dist/manifests/deals-v1.js +107 -0
  55. package/dist/manifests/deals-v1.js.map +1 -0
  56. package/dist/manifests/decisions-v1.d.ts +10 -0
  57. package/dist/manifests/decisions-v1.js +103 -0
  58. package/dist/manifests/decisions-v1.js.map +1 -0
  59. package/dist/manifests/documents-v1.d.ts +10 -0
  60. package/dist/manifests/documents-v1.js +88 -0
  61. package/dist/manifests/documents-v1.js.map +1 -0
  62. package/dist/manifests/epistemic-algorithms-v1.d.ts +10 -0
  63. package/dist/manifests/epistemic-algorithms-v1.js +107 -0
  64. package/dist/manifests/epistemic-algorithms-v1.js.map +1 -0
  65. package/dist/manifests/graph-visualization-v1.d.ts +10 -0
  66. package/dist/manifests/graph-visualization-v1.js +88 -0
  67. package/dist/manifests/graph-visualization-v1.js.map +1 -0
  68. package/dist/manifests/index.d.ts +23 -0
  69. package/dist/manifests/index.js +955 -0
  70. package/dist/manifests/index.js.map +1 -0
  71. package/dist/manifests/news-v1.d.ts +10 -0
  72. package/dist/manifests/news-v1.js +93 -0
  73. package/dist/manifests/news-v1.js.map +1 -0
  74. package/dist/manifests/philosophy-mode-v1.d.ts +10 -0
  75. package/dist/manifests/philosophy-mode-v1.js +100 -0
  76. package/dist/manifests/philosophy-mode-v1.js.map +1 -0
  77. package/dist/manifests/task-management-v1.d.ts +10 -0
  78. package/dist/manifests/task-management-v1.js +86 -0
  79. package/dist/manifests/task-management-v1.js.map +1 -0
  80. package/dist/manifests/team-analysis-v1.d.ts +10 -0
  81. package/dist/manifests/team-analysis-v1.js +93 -0
  82. package/dist/manifests/team-analysis-v1.js.map +1 -0
  83. package/dist/manifests/themes-v1.d.ts +10 -0
  84. package/dist/manifests/themes-v1.js +118 -0
  85. package/dist/manifests/themes-v1.js.map +1 -0
  86. package/dist/manifests/user-profiles-v1.d.ts +10 -0
  87. package/dist/manifests/user-profiles-v1.js +100 -0
  88. package/dist/manifests/user-profiles-v1.js.map +1 -0
  89. package/dist/manifests.d.ts +14 -0
  90. package/dist/manifests.js +955 -0
  91. package/dist/manifests.js.map +1 -0
  92. package/dist/namespacePolicy.d.ts +26 -0
  93. package/dist/namespacePolicy.js +129 -0
  94. package/dist/namespacePolicy.js.map +1 -0
  95. package/dist/registry.d.ts +13 -0
  96. package/dist/registry.js +1710 -0
  97. package/dist/registry.js.map +1 -0
  98. package/dist/runtime.d.ts +19 -0
  99. package/dist/runtime.js +638 -0
  100. package/dist/runtime.js.map +1 -0
  101. package/dist/serviceContracts.d.ts +18 -0
  102. package/dist/serviceContracts.js +64 -0
  103. package/dist/serviceContracts.js.map +1 -0
  104. package/package.json +48 -0
@@ -0,0 +1,1013 @@
1
+ // src/domain-pack/validation.ts
2
+ function issue(code, message, path, severity = "error") {
3
+ return { code, severity, message, path };
4
+ }
5
+ var KEBAB_CASE = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
6
+ 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-]+)*))?$/;
7
+ var SHAPING_QUESTION_TYPES = /* @__PURE__ */ new Set([
8
+ "validation",
9
+ "falsification",
10
+ "assumption_probe",
11
+ "counterfactual",
12
+ "scope",
13
+ "comparison",
14
+ "mechanism",
15
+ "general"
16
+ ]);
17
+ var RUNTIME_TARGETS = /* @__PURE__ */ new Set(["claude-code", "codex", "hybrid", "portable"]);
18
+ var ONTOLOGY_PROVISION_MODES = /* @__PURE__ */ new Set(["bind", "seed", "extend"]);
19
+ function validateStringArray(values, path, label) {
20
+ if (!values) {
21
+ return [];
22
+ }
23
+ return values.flatMap((value, index) => {
24
+ if (!value?.trim()) {
25
+ return [
26
+ issue(
27
+ "INVALID_SHAPING_CONDITION",
28
+ `${label} must not contain empty strings`,
29
+ `${path}[${index}]`
30
+ )
31
+ ];
32
+ }
33
+ return [];
34
+ });
35
+ }
36
+ function validateRuntimeTargets(values, path) {
37
+ const issues = validateStringArray(values, path, "runtimeTargets");
38
+ for (const [index, value] of (values || []).entries()) {
39
+ if (!RUNTIME_TARGETS.has(value)) {
40
+ issues.push(
41
+ issue(
42
+ "INVALID_RUNTIME_TARGET",
43
+ `Unsupported runtime target "${value}"`,
44
+ `${path}[${index}]`
45
+ )
46
+ );
47
+ }
48
+ }
49
+ return issues;
50
+ }
51
+ function validatePromptBinding(prompt, index) {
52
+ const path = `operatingSystem.prompts[${index}]`;
53
+ const issues = [];
54
+ if (!prompt.promptId?.trim()) {
55
+ issues.push(
56
+ issue(
57
+ "MISSING_PROMPT_ID",
58
+ "prompt binding requires promptId",
59
+ `${path}.promptId`
60
+ )
61
+ );
62
+ }
63
+ if (!prompt.ref?.trim()) {
64
+ issues.push(
65
+ issue("MISSING_PROMPT_REF", "prompt binding requires ref", `${path}.ref`)
66
+ );
67
+ }
68
+ issues.push(
69
+ ...validateRuntimeTargets(prompt.runtimeTargets, `${path}.runtimeTargets`)
70
+ );
71
+ return issues;
72
+ }
73
+ function validateToolBinding(tool, index) {
74
+ const path = `operatingSystem.tools[${index}]`;
75
+ const issues = [];
76
+ if (!tool.toolId?.trim()) {
77
+ issues.push(
78
+ issue("MISSING_TOOL_ID", "tool binding requires toolId", `${path}.toolId`)
79
+ );
80
+ }
81
+ if (!tool.entrypoint?.trim()) {
82
+ issues.push(
83
+ issue(
84
+ "MISSING_TOOL_ENTRYPOINT",
85
+ "tool binding requires entrypoint",
86
+ `${path}.entrypoint`
87
+ )
88
+ );
89
+ }
90
+ issues.push(
91
+ ...validateRuntimeTargets(tool.runtimeTargets, `${path}.runtimeTargets`)
92
+ );
93
+ return issues;
94
+ }
95
+ function validateSetupAsset(asset, index) {
96
+ const path = `operatingSystem.setupAssets[${index}]`;
97
+ const issues = [];
98
+ if (!asset.assetId?.trim()) {
99
+ issues.push(
100
+ issue(
101
+ "MISSING_SETUP_ASSET_ID",
102
+ "setup asset requires assetId",
103
+ `${path}.assetId`
104
+ )
105
+ );
106
+ }
107
+ if (!asset.path?.trim()) {
108
+ issues.push(
109
+ issue(
110
+ "MISSING_SETUP_ASSET_PATH",
111
+ "setup asset requires path",
112
+ `${path}.path`
113
+ )
114
+ );
115
+ }
116
+ issues.push(
117
+ ...validateRuntimeTargets(asset.runtimeTargets, `${path}.runtimeTargets`)
118
+ );
119
+ return issues;
120
+ }
121
+ function validateQuestionTemplate(template, index) {
122
+ const path = `inquiryShaping.questionTemplates[${index}]`;
123
+ const issues = [];
124
+ if (!template.templateId?.trim()) {
125
+ issues.push(
126
+ issue(
127
+ "MISSING_SHAPING_TEMPLATE_ID",
128
+ "question template requires templateId",
129
+ `${path}.templateId`
130
+ )
131
+ );
132
+ }
133
+ if (!template.template?.trim()) {
134
+ issues.push(
135
+ issue(
136
+ "MISSING_SHAPING_TEMPLATE",
137
+ "question template requires template text",
138
+ `${path}.template`
139
+ )
140
+ );
141
+ }
142
+ if (!SHAPING_QUESTION_TYPES.has(template.questionType)) {
143
+ issues.push(
144
+ issue(
145
+ "INVALID_SHAPING_QUESTION_TYPE",
146
+ `Unsupported questionType "${template.questionType}"`,
147
+ `${path}.questionType`
148
+ )
149
+ );
150
+ }
151
+ issues.push(
152
+ ...validateStringArray(
153
+ template.whenObjectiveIncludes,
154
+ `${path}.whenObjectiveIncludes`,
155
+ "whenObjectiveIncludes"
156
+ )
157
+ );
158
+ return issues;
159
+ }
160
+ function validateTaskTemplate(template, index) {
161
+ const path = `inquiryShaping.taskTemplates[${index}]`;
162
+ const issues = [];
163
+ if (!template.templateId?.trim()) {
164
+ issues.push(
165
+ issue(
166
+ "MISSING_TASK_GENERATOR_ID",
167
+ "task template requires templateId",
168
+ `${path}.templateId`
169
+ )
170
+ );
171
+ }
172
+ if (!template.title?.trim()) {
173
+ issues.push(
174
+ issue(
175
+ "MISSING_TASK_GENERATOR_TITLE",
176
+ "task template requires title",
177
+ `${path}.title`
178
+ )
179
+ );
180
+ }
181
+ issues.push(
182
+ ...validateStringArray(
183
+ template.whenObjectiveIncludes,
184
+ `${path}.whenObjectiveIncludes`,
185
+ "whenObjectiveIncludes"
186
+ )
187
+ );
188
+ issues.push(
189
+ ...validateStringArray(
190
+ template.whenQuestionTypes,
191
+ `${path}.whenQuestionTypes`,
192
+ "whenQuestionTypes"
193
+ )
194
+ );
195
+ for (const [questionTypeIndex, questionType] of (template.whenQuestionTypes || []).entries()) {
196
+ if (!SHAPING_QUESTION_TYPES.has(questionType)) {
197
+ issues.push(
198
+ issue(
199
+ "INVALID_TASK_GENERATOR_QUESTION_TYPE",
200
+ `Unsupported whenQuestionTypes value "${questionType}"`,
201
+ `${path}.whenQuestionTypes[${questionTypeIndex}]`
202
+ )
203
+ );
204
+ }
205
+ }
206
+ return issues;
207
+ }
208
+ function validateFrameworkHint(hint, index) {
209
+ const path = `inquiryShaping.frameworkHints[${index}]`;
210
+ const issues = [];
211
+ if (!hint.frameworkName?.trim()) {
212
+ issues.push(
213
+ issue(
214
+ "MISSING_FRAMEWORK_HOOK_NAME",
215
+ "framework hint requires frameworkName",
216
+ `${path}.frameworkName`
217
+ )
218
+ );
219
+ }
220
+ if (hint.boost != null && (!Number.isFinite(hint.boost) || hint.boost < 0)) {
221
+ issues.push(
222
+ issue(
223
+ "INVALID_FRAMEWORK_HOOK_BOOST",
224
+ "framework hint boost must be a non-negative number",
225
+ `${path}.boost`
226
+ )
227
+ );
228
+ }
229
+ issues.push(
230
+ ...validateStringArray(
231
+ hint.whenObjectiveIncludes,
232
+ `${path}.whenObjectiveIncludes`,
233
+ "whenObjectiveIncludes"
234
+ )
235
+ );
236
+ issues.push(
237
+ ...validateStringArray(
238
+ hint.whenQuestionTypes,
239
+ `${path}.whenQuestionTypes`,
240
+ "whenQuestionTypes"
241
+ )
242
+ );
243
+ for (const [questionTypeIndex, questionType] of (hint.whenQuestionTypes || []).entries()) {
244
+ if (!SHAPING_QUESTION_TYPES.has(questionType)) {
245
+ issues.push(
246
+ issue(
247
+ "INVALID_FRAMEWORK_HOOK_QUESTION_TYPE",
248
+ `Unsupported whenQuestionTypes value "${questionType}"`,
249
+ `${path}.whenQuestionTypes[${questionTypeIndex}]`
250
+ )
251
+ );
252
+ }
253
+ }
254
+ return issues;
255
+ }
256
+ function validateTopicTemplate(template, index, knownTopicSlugs) {
257
+ const path = `operatingSystem.topicTemplates[${index}]`;
258
+ const issues = [];
259
+ if (!template.slug?.trim()) {
260
+ issues.push(
261
+ issue(
262
+ "MISSING_TOPIC_TEMPLATE_SLUG",
263
+ "topic template requires slug",
264
+ `${path}.slug`
265
+ )
266
+ );
267
+ } else if (!KEBAB_CASE.test(template.slug)) {
268
+ issues.push(
269
+ issue(
270
+ "INVALID_TOPIC_TEMPLATE_SLUG",
271
+ `topic template slug "${template.slug}" must be kebab-case`,
272
+ `${path}.slug`
273
+ )
274
+ );
275
+ }
276
+ if (!template.name?.trim()) {
277
+ issues.push(
278
+ issue(
279
+ "MISSING_TOPIC_TEMPLATE_NAME",
280
+ "topic template requires name",
281
+ `${path}.name`
282
+ )
283
+ );
284
+ }
285
+ if (!template.description?.trim()) {
286
+ issues.push(
287
+ issue(
288
+ "MISSING_TOPIC_TEMPLATE_DESCRIPTION",
289
+ "topic template requires description",
290
+ `${path}.description`
291
+ )
292
+ );
293
+ }
294
+ if (template.parentSlug && !knownTopicSlugs.has(template.parentSlug)) {
295
+ issues.push(
296
+ issue(
297
+ "UNKNOWN_TOPIC_PARENT",
298
+ `topic template references unknown parent "${template.parentSlug}"`,
299
+ `${path}.parentSlug`
300
+ )
301
+ );
302
+ }
303
+ return issues;
304
+ }
305
+ function validateInstallProfile(profile, index, knownPromptIds, knownToolIds, knownAssetIds, knownTopicSlugs) {
306
+ const path = `operatingSystem.installProfiles[${index}]`;
307
+ const issues = [];
308
+ if (!profile.profileId?.trim()) {
309
+ issues.push(
310
+ issue(
311
+ "MISSING_INSTALL_PROFILE_ID",
312
+ "install profile requires profileId",
313
+ `${path}.profileId`
314
+ )
315
+ );
316
+ }
317
+ if (!profile.name?.trim()) {
318
+ issues.push(
319
+ issue(
320
+ "MISSING_INSTALL_PROFILE_NAME",
321
+ "install profile requires name",
322
+ `${path}.name`
323
+ )
324
+ );
325
+ }
326
+ if (!profile.description?.trim()) {
327
+ issues.push(
328
+ issue(
329
+ "MISSING_INSTALL_PROFILE_DESCRIPTION",
330
+ "install profile requires description",
331
+ `${path}.description`
332
+ )
333
+ );
334
+ }
335
+ if (!RUNTIME_TARGETS.has(profile.runtimeTarget)) {
336
+ issues.push(
337
+ issue(
338
+ "INVALID_RUNTIME_TARGET",
339
+ `Unsupported runtime target "${profile.runtimeTarget}"`,
340
+ `${path}.runtimeTarget`
341
+ )
342
+ );
343
+ }
344
+ for (const [promptIndex, promptId] of profile.promptIds.entries()) {
345
+ if (!knownPromptIds.has(promptId)) {
346
+ issues.push(
347
+ issue(
348
+ "UNKNOWN_PROMPT_REF",
349
+ `install profile references unknown prompt "${promptId}"`,
350
+ `${path}.promptIds[${promptIndex}]`
351
+ )
352
+ );
353
+ }
354
+ }
355
+ for (const [toolIndex, toolId] of profile.toolIds.entries()) {
356
+ if (!knownToolIds.has(toolId)) {
357
+ issues.push(
358
+ issue(
359
+ "UNKNOWN_TOOL_REF",
360
+ `install profile references unknown tool "${toolId}"`,
361
+ `${path}.toolIds[${toolIndex}]`
362
+ )
363
+ );
364
+ }
365
+ }
366
+ for (const [assetIndex, assetId] of profile.assetIds.entries()) {
367
+ if (!knownAssetIds.has(assetId)) {
368
+ issues.push(
369
+ issue(
370
+ "UNKNOWN_SETUP_ASSET_REF",
371
+ `install profile references unknown setup asset "${assetId}"`,
372
+ `${path}.assetIds[${assetIndex}]`
373
+ )
374
+ );
375
+ }
376
+ }
377
+ for (const [topicIndex, topicSlug] of profile.defaultTopicSlugs.entries()) {
378
+ if (!knownTopicSlugs.has(topicSlug)) {
379
+ issues.push(
380
+ issue(
381
+ "UNKNOWN_TOPIC_REF",
382
+ `install profile references unknown topic "${topicSlug}"`,
383
+ `${path}.defaultTopicSlugs[${topicIndex}]`
384
+ )
385
+ );
386
+ }
387
+ }
388
+ return issues;
389
+ }
390
+ function checkDuplicateIds(items, idField, path) {
391
+ const issues = [];
392
+ const seen = /* @__PURE__ */ new Set();
393
+ for (const item of items) {
394
+ const id = item[idField];
395
+ if (seen.has(id)) {
396
+ issues.push(
397
+ issue(
398
+ "DUPLICATE_ID",
399
+ `Duplicate ${idField} "${id}"`,
400
+ `${path}.${idField}`
401
+ )
402
+ );
403
+ }
404
+ seen.add(id);
405
+ }
406
+ return issues;
407
+ }
408
+ function validateDomainPack(pack) {
409
+ const issues = [];
410
+ if (!pack.packId || !pack.packId.trim()) {
411
+ issues.push(issue("MISSING_PACK_ID", "packId is required", "packId"));
412
+ } else if (!KEBAB_CASE.test(pack.packId)) {
413
+ issues.push(
414
+ issue(
415
+ "INVALID_PACK_ID",
416
+ `packId "${pack.packId}" must be kebab-case`,
417
+ "packId"
418
+ )
419
+ );
420
+ }
421
+ if (!pack.name || !pack.name.trim()) {
422
+ issues.push(issue("MISSING_NAME", "name is required", "name"));
423
+ }
424
+ if (!pack.version || !pack.version.trim()) {
425
+ issues.push(issue("MISSING_VERSION", "version is required", "version"));
426
+ } else if (!SEMVER.test(pack.version)) {
427
+ issues.push(
428
+ issue(
429
+ "INVALID_VERSION",
430
+ `version "${pack.version}" must be valid semver`,
431
+ "version"
432
+ )
433
+ );
434
+ }
435
+ if (!pack.ontologyBindings || pack.ontologyBindings.length === 0) {
436
+ issues.push(
437
+ issue(
438
+ "MISSING_ONTOLOGY_BINDINGS",
439
+ "At least one ontologyBinding is required",
440
+ "ontologyBindings"
441
+ )
442
+ );
443
+ } else {
444
+ for (const [i, binding] of pack.ontologyBindings.entries()) {
445
+ if (!binding.ontologyId?.trim()) {
446
+ issues.push(
447
+ issue(
448
+ "MISSING_ONTOLOGY_ID",
449
+ `ontologyBinding[${i}].ontologyId is required`,
450
+ `ontologyBindings[${i}].ontologyId`
451
+ )
452
+ );
453
+ }
454
+ if (!binding.versionConstraint?.trim()) {
455
+ issues.push(
456
+ issue(
457
+ "MISSING_VERSION_CONSTRAINT",
458
+ `ontologyBinding[${i}].versionConstraint is required`,
459
+ `ontologyBindings[${i}].versionConstraint`
460
+ )
461
+ );
462
+ }
463
+ if (binding.provisionMode && !ONTOLOGY_PROVISION_MODES.has(binding.provisionMode)) {
464
+ issues.push(
465
+ issue(
466
+ "INVALID_ONTOLOGY_PROVISION_MODE",
467
+ `Unsupported provisionMode "${binding.provisionMode}"`,
468
+ `ontologyBindings[${i}].provisionMode`
469
+ )
470
+ );
471
+ }
472
+ if (binding.provisionMode && binding.provisionMode !== "bind" && !binding.seedRef?.trim()) {
473
+ issues.push(
474
+ issue(
475
+ "MISSING_ONTOLOGY_SEED_REF",
476
+ `ontologyBinding[${i}] requires seedRef when provisionMode is "${binding.provisionMode}"`,
477
+ `ontologyBindings[${i}].seedRef`
478
+ )
479
+ );
480
+ }
481
+ issues.push(
482
+ ...validateStringArray(
483
+ binding.requiredEntityTypes,
484
+ `ontologyBindings[${i}].requiredEntityTypes`,
485
+ "requiredEntityTypes"
486
+ ),
487
+ ...validateStringArray(
488
+ binding.requiredEdgeTypes,
489
+ `ontologyBindings[${i}].requiredEdgeTypes`,
490
+ "requiredEdgeTypes"
491
+ )
492
+ );
493
+ }
494
+ }
495
+ if (!pack.topicRoots || pack.topicRoots.length === 0) {
496
+ issues.push(
497
+ issue(
498
+ "MISSING_TOPIC_ROOTS",
499
+ "At least one topicRoot is required",
500
+ "topicRoots"
501
+ )
502
+ );
503
+ } else {
504
+ issues.push(
505
+ ...checkDuplicateIds(
506
+ pack.topicRoots,
507
+ "slug",
508
+ "topicRoots"
509
+ )
510
+ );
511
+ }
512
+ if (pack.operatingSystem) {
513
+ const knownRootSlugs = new Set(
514
+ pack.topicRoots?.map((topic) => topic.slug) ?? []
515
+ );
516
+ if (pack.operatingSystem.prompts) {
517
+ issues.push(
518
+ ...checkDuplicateIds(
519
+ pack.operatingSystem.prompts,
520
+ "promptId",
521
+ "operatingSystem.prompts"
522
+ )
523
+ );
524
+ pack.operatingSystem.prompts.forEach((prompt, index) => {
525
+ issues.push(...validatePromptBinding(prompt, index));
526
+ });
527
+ }
528
+ if (pack.operatingSystem.tools) {
529
+ issues.push(
530
+ ...checkDuplicateIds(
531
+ pack.operatingSystem.tools,
532
+ "toolId",
533
+ "operatingSystem.tools"
534
+ )
535
+ );
536
+ pack.operatingSystem.tools.forEach((tool, index) => {
537
+ issues.push(...validateToolBinding(tool, index));
538
+ });
539
+ }
540
+ if (pack.operatingSystem.setupAssets) {
541
+ issues.push(
542
+ ...checkDuplicateIds(
543
+ pack.operatingSystem.setupAssets,
544
+ "assetId",
545
+ "operatingSystem.setupAssets"
546
+ )
547
+ );
548
+ pack.operatingSystem.setupAssets.forEach((asset, index) => {
549
+ issues.push(...validateSetupAsset(asset, index));
550
+ });
551
+ }
552
+ const templateSlugs = /* @__PURE__ */ new Set();
553
+ if (pack.operatingSystem.topicTemplates) {
554
+ issues.push(
555
+ ...checkDuplicateIds(
556
+ pack.operatingSystem.topicTemplates,
557
+ "slug",
558
+ "operatingSystem.topicTemplates"
559
+ )
560
+ );
561
+ pack.operatingSystem.topicTemplates.forEach((template) => {
562
+ if (template.slug) {
563
+ templateSlugs.add(template.slug);
564
+ }
565
+ });
566
+ const knownTopicSlugs = /* @__PURE__ */ new Set([...knownRootSlugs, ...templateSlugs]);
567
+ pack.operatingSystem.topicTemplates.forEach((template, index) => {
568
+ issues.push(...validateTopicTemplate(template, index, knownTopicSlugs));
569
+ });
570
+ }
571
+ if (pack.operatingSystem.installProfiles) {
572
+ issues.push(
573
+ ...checkDuplicateIds(
574
+ pack.operatingSystem.installProfiles,
575
+ "profileId",
576
+ "operatingSystem.installProfiles"
577
+ )
578
+ );
579
+ const knownPromptIds = new Set(
580
+ pack.operatingSystem.prompts?.map((prompt) => prompt.promptId) ?? []
581
+ );
582
+ const knownToolIds = new Set(
583
+ pack.operatingSystem.tools?.map((tool) => tool.toolId) ?? []
584
+ );
585
+ const knownAssetIds = new Set(
586
+ pack.operatingSystem.setupAssets?.map((asset) => asset.assetId) ?? []
587
+ );
588
+ const knownTopicSlugs = /* @__PURE__ */ new Set([...knownRootSlugs, ...templateSlugs]);
589
+ pack.operatingSystem.installProfiles.forEach((profile, index) => {
590
+ issues.push(
591
+ ...validateInstallProfile(
592
+ profile,
593
+ index,
594
+ knownPromptIds,
595
+ knownToolIds,
596
+ knownAssetIds,
597
+ knownTopicSlugs
598
+ )
599
+ );
600
+ });
601
+ }
602
+ }
603
+ if (!pack.roles || pack.roles.length === 0) {
604
+ issues.push(
605
+ issue("MISSING_ROLES", "At least one reasoning role is required", "roles")
606
+ );
607
+ } else {
608
+ issues.push(
609
+ ...checkDuplicateIds(
610
+ pack.roles,
611
+ "roleId",
612
+ "roles"
613
+ )
614
+ );
615
+ }
616
+ const knownGateIds = new Set(pack.gates?.map((g) => g.gateId) ?? []);
617
+ const knownArtifactIds = new Set(
618
+ pack.artifacts?.map((a) => a.artifactId) ?? []
619
+ );
620
+ const knownRoleIds = new Set(pack.roles?.map((r) => r.roleId) ?? []);
621
+ if (pack.gates) {
622
+ issues.push(
623
+ ...checkDuplicateIds(
624
+ pack.gates,
625
+ "gateId",
626
+ "gates"
627
+ )
628
+ );
629
+ for (const [i, gate] of pack.gates.entries()) {
630
+ if (!gate.criteria || gate.criteria.length === 0) {
631
+ issues.push(
632
+ issue(
633
+ "EMPTY_GATE_CRITERIA",
634
+ `Gate "${gate.gateId}" has no criteria`,
635
+ `gates[${i}].criteria`,
636
+ "warning"
637
+ )
638
+ );
639
+ } else {
640
+ issues.push(
641
+ ...checkDuplicateIds(
642
+ gate.criteria,
643
+ "criterionId",
644
+ `gates[${i}].criteria`
645
+ )
646
+ );
647
+ }
648
+ }
649
+ }
650
+ if (pack.artifacts) {
651
+ issues.push(
652
+ ...checkDuplicateIds(
653
+ pack.artifacts,
654
+ "artifactId",
655
+ "artifacts"
656
+ )
657
+ );
658
+ }
659
+ if (pack.workflows) {
660
+ issues.push(
661
+ ...checkDuplicateIds(
662
+ pack.workflows,
663
+ "workflowId",
664
+ "workflows"
665
+ )
666
+ );
667
+ for (const [wi, workflow] of pack.workflows.entries()) {
668
+ for (const gateId of workflow.gateCheckpoints) {
669
+ if (!knownGateIds.has(gateId)) {
670
+ issues.push(
671
+ issue(
672
+ "UNKNOWN_GATE_REF",
673
+ `Workflow "${workflow.workflowId}" references unknown gate "${gateId}"`,
674
+ `workflows[${wi}].gateCheckpoints`
675
+ )
676
+ );
677
+ }
678
+ }
679
+ for (const artifactId of workflow.requiredArtifacts) {
680
+ if (!knownArtifactIds.has(artifactId)) {
681
+ issues.push(
682
+ issue(
683
+ "UNKNOWN_ARTIFACT_REF",
684
+ `Workflow "${workflow.workflowId}" references unknown artifact "${artifactId}"`,
685
+ `workflows[${wi}].requiredArtifacts`
686
+ )
687
+ );
688
+ }
689
+ }
690
+ for (const [si, step] of workflow.steps.entries()) {
691
+ for (const roleId of step.requiredRoles) {
692
+ if (!knownRoleIds.has(roleId)) {
693
+ issues.push(
694
+ issue(
695
+ "UNKNOWN_ROLE_REF",
696
+ `Step "${step.stepId}" references unknown role "${roleId}"`,
697
+ `workflows[${wi}].steps[${si}].requiredRoles`
698
+ )
699
+ );
700
+ }
701
+ }
702
+ if (step.gateId && !knownGateIds.has(step.gateId)) {
703
+ issues.push(
704
+ issue(
705
+ "UNKNOWN_GATE_REF",
706
+ `Step "${step.stepId}" references unknown gate "${step.gateId}"`,
707
+ `workflows[${wi}].steps[${si}].gateId`
708
+ )
709
+ );
710
+ }
711
+ if (step.produces) {
712
+ for (const artifactId of step.produces) {
713
+ if (!knownArtifactIds.has(artifactId)) {
714
+ issues.push(
715
+ issue(
716
+ "UNKNOWN_ARTIFACT_REF",
717
+ `Step "${step.stepId}" references unknown artifact "${artifactId}"`,
718
+ `workflows[${wi}].steps[${si}].produces`
719
+ )
720
+ );
721
+ }
722
+ }
723
+ }
724
+ }
725
+ }
726
+ }
727
+ if (pack.inquiryShaping) {
728
+ if (pack.inquiryShaping.questionTemplates) {
729
+ issues.push(
730
+ ...checkDuplicateIds(
731
+ pack.inquiryShaping.questionTemplates,
732
+ "templateId",
733
+ "inquiryShaping.questionTemplates"
734
+ )
735
+ );
736
+ pack.inquiryShaping.questionTemplates.forEach((template, index) => {
737
+ issues.push(...validateQuestionTemplate(template, index));
738
+ });
739
+ }
740
+ if (pack.inquiryShaping.taskTemplates) {
741
+ issues.push(
742
+ ...checkDuplicateIds(
743
+ pack.inquiryShaping.taskTemplates,
744
+ "templateId",
745
+ "inquiryShaping.taskTemplates"
746
+ )
747
+ );
748
+ pack.inquiryShaping.taskTemplates.forEach((template, index) => {
749
+ issues.push(...validateTaskTemplate(template, index));
750
+ });
751
+ }
752
+ if (pack.inquiryShaping.frameworkHints) {
753
+ issues.push(
754
+ ...checkDuplicateIds(
755
+ pack.inquiryShaping.frameworkHints.map((hint) => ({
756
+ frameworkName: hint.frameworkName
757
+ })),
758
+ "frameworkName",
759
+ "inquiryShaping.frameworkHints"
760
+ )
761
+ );
762
+ pack.inquiryShaping.frameworkHints.forEach((hint, index) => {
763
+ issues.push(...validateFrameworkHint(hint, index));
764
+ });
765
+ }
766
+ }
767
+ return {
768
+ valid: issues.filter((i) => i.severity === "error").length === 0,
769
+ issues
770
+ };
771
+ }
772
+
773
+ // src/domain-pack/shaping.ts
774
+ var QUESTION_PRIORITY_WEIGHT = {
775
+ critical: 0.12,
776
+ high: 0.08,
777
+ medium: 0.04,
778
+ low: 0.01
779
+ };
780
+ var TASK_PRIORITY_WEIGHT = {
781
+ urgent: 0.12,
782
+ high: 0.08,
783
+ medium: 0.04,
784
+ low: 0.01
785
+ };
786
+ function dedupeStrings(values) {
787
+ if (!values || values.length === 0) {
788
+ return void 0;
789
+ }
790
+ const normalized = values.map((value) => value.trim()).filter(Boolean);
791
+ return normalized.length > 0 ? Array.from(new Set(normalized)) : void 0;
792
+ }
793
+ function toKebabCase(value) {
794
+ return value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
795
+ }
796
+ function normalizeCondition(args) {
797
+ return {
798
+ ...dedupeStrings(args.objectiveIncludes) ? { objectiveIncludes: dedupeStrings(args.objectiveIncludes) } : {},
799
+ ...dedupeStrings(args.questionTypes) ? { questionTypes: dedupeStrings(args.questionTypes) } : {}
800
+ };
801
+ }
802
+ function normalizeQuestionType(questionType) {
803
+ return questionType === "scope" ? "clarification" : questionType;
804
+ }
805
+ function questionTemplateToContribution(packId, template) {
806
+ return {
807
+ sourcePackId: packId,
808
+ templateId: template.templateId,
809
+ questionType: normalizeQuestionType(template.questionType),
810
+ priority: template.priority,
811
+ priorityWeight: QUESTION_PRIORITY_WEIGHT[template.priority || "medium"],
812
+ template: template.template,
813
+ condition: normalizeCondition({
814
+ objectiveIncludes: template.whenObjectiveIncludes
815
+ })
816
+ };
817
+ }
818
+ function taskTemplateToContribution(packId, template) {
819
+ return {
820
+ sourcePackId: packId,
821
+ generatorId: template.templateId,
822
+ title: template.title,
823
+ description: template.description,
824
+ taskType: template.taskType,
825
+ priority: template.priority,
826
+ priorityWeight: TASK_PRIORITY_WEIGHT[template.priority || "medium"],
827
+ condition: normalizeCondition({
828
+ objectiveIncludes: template.whenObjectiveIncludes,
829
+ questionTypes: template.whenQuestionTypes
830
+ })
831
+ };
832
+ }
833
+ function frameworkHintToContribution(packId, hint) {
834
+ const hookId = `${packId}:${toKebabCase(hint.frameworkName || "framework")}`;
835
+ return {
836
+ sourcePackId: packId,
837
+ hookId,
838
+ frameworkName: hint.frameworkName,
839
+ boost: hint.boost || 0,
840
+ reason: hint.reason,
841
+ priorityWeight: Math.max(0.02, hint.boost || 0),
842
+ condition: normalizeCondition({
843
+ objectiveIncludes: hint.whenObjectiveIncludes,
844
+ questionTypes: hint.whenQuestionTypes
845
+ })
846
+ };
847
+ }
848
+ function issue2(code, message, path, severity = "error") {
849
+ return { code, message, path, severity };
850
+ }
851
+ function checkDuplicateIds2(items, idField, path) {
852
+ const issues = [];
853
+ const seen = /* @__PURE__ */ new Set();
854
+ for (const item of items) {
855
+ const id = item[idField];
856
+ if (!id) {
857
+ continue;
858
+ }
859
+ if (seen.has(id)) {
860
+ issues.push(
861
+ issue2("DUPLICATE_ID", `Duplicate ${idField} "${id}"`, `${path}.${idField}`)
862
+ );
863
+ }
864
+ seen.add(id);
865
+ }
866
+ return issues;
867
+ }
868
+ function formatRegistrationIssues(packId, issues) {
869
+ return `Invalid shaping contribution registration for ${packId}: ${issues.map((item) => `${item.code} at ${item.path}`).join("; ")}`;
870
+ }
871
+ function buildShapingContribution(pack) {
872
+ const inquiryShaping = pack.inquiryShaping || {};
873
+ return {
874
+ packId: pack.packId,
875
+ questionTemplates: (inquiryShaping.questionTemplates || []).map(
876
+ (template) => questionTemplateToContribution(pack.packId, template)
877
+ ),
878
+ taskGenerators: (inquiryShaping.taskTemplates || []).map(
879
+ (template) => taskTemplateToContribution(pack.packId, template)
880
+ ),
881
+ frameworkHooks: (inquiryShaping.frameworkHints || []).map(
882
+ (hint) => frameworkHintToContribution(pack.packId, hint)
883
+ )
884
+ };
885
+ }
886
+ function validateShapingContribution(contribution) {
887
+ const issues = [];
888
+ if (!contribution.packId?.trim()) {
889
+ issues.push(issue2("MISSING_PACK_ID", "packId is required", "packId"));
890
+ }
891
+ issues.push(
892
+ ...checkDuplicateIds2(
893
+ contribution.questionTemplates,
894
+ "templateId",
895
+ "questionTemplates"
896
+ )
897
+ );
898
+ issues.push(
899
+ ...checkDuplicateIds2(
900
+ contribution.taskGenerators,
901
+ "generatorId",
902
+ "taskGenerators"
903
+ )
904
+ );
905
+ issues.push(
906
+ ...checkDuplicateIds2(
907
+ contribution.frameworkHooks,
908
+ "hookId",
909
+ "frameworkHooks"
910
+ )
911
+ );
912
+ contribution.questionTemplates.forEach((template, index) => {
913
+ if (!template.templateId?.trim()) {
914
+ issues.push(
915
+ issue2(
916
+ "MISSING_TEMPLATE_ID",
917
+ "Question template requires templateId",
918
+ `questionTemplates[${index}].templateId`
919
+ )
920
+ );
921
+ }
922
+ if (!template.template?.trim()) {
923
+ issues.push(
924
+ issue2(
925
+ "MISSING_TEMPLATE",
926
+ "Question template requires template text",
927
+ `questionTemplates[${index}].template`
928
+ )
929
+ );
930
+ }
931
+ });
932
+ contribution.taskGenerators.forEach((generator, index) => {
933
+ if (!generator.generatorId?.trim()) {
934
+ issues.push(
935
+ issue2(
936
+ "MISSING_GENERATOR_ID",
937
+ "Task generator requires generatorId",
938
+ `taskGenerators[${index}].generatorId`
939
+ )
940
+ );
941
+ }
942
+ if (!generator.title?.trim()) {
943
+ issues.push(
944
+ issue2(
945
+ "MISSING_TASK_TITLE",
946
+ "Task generator requires title",
947
+ `taskGenerators[${index}].title`
948
+ )
949
+ );
950
+ }
951
+ });
952
+ contribution.frameworkHooks.forEach((hook, index) => {
953
+ if (!hook.frameworkName?.trim()) {
954
+ issues.push(
955
+ issue2(
956
+ "MISSING_FRAMEWORK_NAME",
957
+ "Framework hook requires frameworkName",
958
+ `frameworkHooks[${index}].frameworkName`
959
+ )
960
+ );
961
+ }
962
+ if (!Number.isFinite(hook.boost) || hook.boost < 0) {
963
+ issues.push(
964
+ issue2(
965
+ "INVALID_FRAMEWORK_BOOST",
966
+ "Framework hook boost must be a non-negative number",
967
+ `frameworkHooks[${index}].boost`
968
+ )
969
+ );
970
+ }
971
+ });
972
+ return {
973
+ valid: issues.every((item) => item.severity !== "error"),
974
+ issues
975
+ };
976
+ }
977
+ function createShapingContributionRegistry(packs = []) {
978
+ const registry = /* @__PURE__ */ new Map();
979
+ const register = (pack) => {
980
+ if (registry.has(pack.packId)) {
981
+ throw new Error(
982
+ `Duplicate shaping contribution registration for ${pack.packId}`
983
+ );
984
+ }
985
+ const packValidation = validateDomainPack(pack);
986
+ if (!packValidation.valid) {
987
+ throw new Error(formatRegistrationIssues(pack.packId, packValidation.issues));
988
+ }
989
+ const contribution = buildShapingContribution(pack);
990
+ const contributionValidation = validateShapingContribution(contribution);
991
+ if (!contributionValidation.valid) {
992
+ throw new Error(
993
+ formatRegistrationIssues(pack.packId, contributionValidation.issues)
994
+ );
995
+ }
996
+ registry.set(pack.packId, contribution);
997
+ return contribution;
998
+ };
999
+ packs.forEach(register);
1000
+ return {
1001
+ register,
1002
+ get(packId) {
1003
+ return registry.get(packId) ?? null;
1004
+ },
1005
+ list() {
1006
+ return Array.from(registry.keys());
1007
+ }
1008
+ };
1009
+ }
1010
+
1011
+ export { buildShapingContribution, createShapingContributionRegistry, validateShapingContribution };
1012
+ //# sourceMappingURL=shaping.js.map
1013
+ //# sourceMappingURL=shaping.js.map