@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.
- package/README.md +64 -0
- package/dist/contracts.d.ts +77 -0
- package/dist/contracts.js +21 -0
- package/dist/contracts.js.map +1 -0
- package/dist/convex.config.d.ts +5 -0
- package/dist/convex.config.js +9 -0
- package/dist/convex.config.js.map +1 -0
- package/dist/dependencyResolution.d.ts +18 -0
- package/dist/dependencyResolution.js +131 -0
- package/dist/dependencyResolution.js.map +1 -0
- package/dist/domain-pack/authoring.d.ts +172 -0
- package/dist/domain-pack/authoring.js +1896 -0
- package/dist/domain-pack/authoring.js.map +1 -0
- package/dist/domain-pack/contracts.d.ts +183 -0
- package/dist/domain-pack/contracts.js +65 -0
- package/dist/domain-pack/contracts.js.map +1 -0
- package/dist/domain-pack/index.d.ts +8 -0
- package/dist/domain-pack/index.js +3813 -0
- package/dist/domain-pack/index.js.map +1 -0
- package/dist/domain-pack/ontology/software-entities-v1.d.ts +102 -0
- package/dist/domain-pack/ontology/software-entities-v1.js +104 -0
- package/dist/domain-pack/ontology/software-entities-v1.js.map +1 -0
- package/dist/domain-pack/packs/developer-reasoning.d.ts +14 -0
- package/dist/domain-pack/packs/developer-reasoning.js +339 -0
- package/dist/domain-pack/packs/developer-reasoning.js.map +1 -0
- package/dist/domain-pack/packs/engineering-accelerator.d.ts +11 -0
- package/dist/domain-pack/packs/engineering-accelerator.js +1348 -0
- package/dist/domain-pack/packs/engineering-accelerator.js.map +1 -0
- package/dist/domain-pack/packs/index.d.ts +18 -0
- package/dist/domain-pack/packs/index.js +2653 -0
- package/dist/domain-pack/packs/index.js.map +1 -0
- package/dist/domain-pack/shaping.d.ts +54 -0
- package/dist/domain-pack/shaping.js +1013 -0
- package/dist/domain-pack/shaping.js.map +1 -0
- package/dist/domain-pack/validation.d.ts +26 -0
- package/dist/domain-pack/validation.js +775 -0
- package/dist/domain-pack/validation.js.map +1 -0
- package/dist/domain-pack.d.ts +8 -0
- package/dist/domain-pack.js +3813 -0
- package/dist/domain-pack.js.map +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.js +5520 -0
- package/dist/index.js.map +1 -0
- package/dist/lifecycle.d.ts +27 -0
- package/dist/lifecycle.js +98 -0
- package/dist/lifecycle.js.map +1 -0
- package/dist/manifestValidation.d.ts +28 -0
- package/dist/manifestValidation.js +253 -0
- package/dist/manifestValidation.js.map +1 -0
- package/dist/manifests/chat-v1.d.ts +10 -0
- package/dist/manifests/chat-v1.js +87 -0
- package/dist/manifests/chat-v1.js.map +1 -0
- package/dist/manifests/deals-v1.d.ts +10 -0
- package/dist/manifests/deals-v1.js +107 -0
- package/dist/manifests/deals-v1.js.map +1 -0
- package/dist/manifests/decisions-v1.d.ts +10 -0
- package/dist/manifests/decisions-v1.js +103 -0
- package/dist/manifests/decisions-v1.js.map +1 -0
- package/dist/manifests/documents-v1.d.ts +10 -0
- package/dist/manifests/documents-v1.js +88 -0
- package/dist/manifests/documents-v1.js.map +1 -0
- package/dist/manifests/epistemic-algorithms-v1.d.ts +10 -0
- package/dist/manifests/epistemic-algorithms-v1.js +107 -0
- package/dist/manifests/epistemic-algorithms-v1.js.map +1 -0
- package/dist/manifests/graph-visualization-v1.d.ts +10 -0
- package/dist/manifests/graph-visualization-v1.js +88 -0
- package/dist/manifests/graph-visualization-v1.js.map +1 -0
- package/dist/manifests/index.d.ts +23 -0
- package/dist/manifests/index.js +955 -0
- package/dist/manifests/index.js.map +1 -0
- package/dist/manifests/news-v1.d.ts +10 -0
- package/dist/manifests/news-v1.js +93 -0
- package/dist/manifests/news-v1.js.map +1 -0
- package/dist/manifests/philosophy-mode-v1.d.ts +10 -0
- package/dist/manifests/philosophy-mode-v1.js +100 -0
- package/dist/manifests/philosophy-mode-v1.js.map +1 -0
- package/dist/manifests/task-management-v1.d.ts +10 -0
- package/dist/manifests/task-management-v1.js +86 -0
- package/dist/manifests/task-management-v1.js.map +1 -0
- package/dist/manifests/team-analysis-v1.d.ts +10 -0
- package/dist/manifests/team-analysis-v1.js +93 -0
- package/dist/manifests/team-analysis-v1.js.map +1 -0
- package/dist/manifests/themes-v1.d.ts +10 -0
- package/dist/manifests/themes-v1.js +118 -0
- package/dist/manifests/themes-v1.js.map +1 -0
- package/dist/manifests/user-profiles-v1.d.ts +10 -0
- package/dist/manifests/user-profiles-v1.js +100 -0
- package/dist/manifests/user-profiles-v1.js.map +1 -0
- package/dist/manifests.d.ts +14 -0
- package/dist/manifests.js +955 -0
- package/dist/manifests.js.map +1 -0
- package/dist/namespacePolicy.d.ts +26 -0
- package/dist/namespacePolicy.js +129 -0
- package/dist/namespacePolicy.js.map +1 -0
- package/dist/registry.d.ts +13 -0
- package/dist/registry.js +1710 -0
- package/dist/registry.js.map +1 -0
- package/dist/runtime.d.ts +19 -0
- package/dist/runtime.js +638 -0
- package/dist/runtime.js.map +1 -0
- package/dist/serviceContracts.d.ts +18 -0
- package/dist/serviceContracts.js +64 -0
- package/dist/serviceContracts.js.map +1 -0
- package/package.json +48 -0
|
@@ -0,0 +1,775 @@
|
|
|
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
|
+
export { validateDomainPack };
|
|
774
|
+
//# sourceMappingURL=validation.js.map
|
|
775
|
+
//# sourceMappingURL=validation.js.map
|