@teamix-evo/registry 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +123 -0
- package/dist/index.cjs +822 -36
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1774 -24
- package/dist/index.d.ts +1774 -24
- package/dist/index.js +788 -35
- package/dist/index.js.map +1 -1
- package/package.json +14 -10
package/dist/index.cjs
CHANGED
|
@@ -30,6 +30,10 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
+
DesignPackLinkedSchema: () => DesignPackLinkedSchema,
|
|
34
|
+
DesignPackLockSchema: () => DesignPackLockSchema,
|
|
35
|
+
DesignPackManifestSchema: () => DesignPackManifestSchema,
|
|
36
|
+
DesignPackageManifestSchema: () => DesignPackageManifestSchema,
|
|
33
37
|
InstalledManifestSchema: () => InstalledManifestSchema,
|
|
34
38
|
InstalledPackageSchema: () => InstalledPackageSchema,
|
|
35
39
|
InstalledResourceSchema: () => InstalledResourceSchema,
|
|
@@ -37,17 +41,46 @@ __export(index_exports, {
|
|
|
37
41
|
ProjectConfigSchema: () => ProjectConfigSchema,
|
|
38
42
|
ResourceSchema: () => ResourceSchema,
|
|
39
43
|
ResourceTypeSchema: () => ResourceTypeSchema,
|
|
44
|
+
SkillEntrySchema: () => SkillEntrySchema,
|
|
45
|
+
SkillIdeSchema: () => SkillIdeSchema,
|
|
46
|
+
SkillScopeSchema: () => SkillScopeSchema,
|
|
47
|
+
SkillsLockEntrySchema: () => SkillsLockEntrySchema,
|
|
48
|
+
SkillsLockSchema: () => SkillsLockSchema,
|
|
49
|
+
SkillsPackageManifestSchema: () => SkillsPackageManifestSchema,
|
|
50
|
+
TailwindVersionSchema: () => TailwindVersionSchema,
|
|
51
|
+
UiAliasSchema: () => UiAliasSchema,
|
|
52
|
+
UiAliasesSchema: () => UiAliasesSchema,
|
|
53
|
+
UiEntryFileSchema: () => UiEntryFileSchema,
|
|
54
|
+
UiEntrySchema: () => UiEntrySchema,
|
|
55
|
+
UiEntryTypeSchema: () => UiEntryTypeSchema,
|
|
56
|
+
UiPackageManifestSchema: () => UiPackageManifestSchema,
|
|
40
57
|
UpdateStrategySchema: () => UpdateStrategySchema,
|
|
41
58
|
VariantManifestSchema: () => VariantManifestSchema,
|
|
59
|
+
VariantUiPackageCatalogSchema: () => VariantUiPackageCatalogSchema,
|
|
60
|
+
VariantUiPackageManifestSchema: () => VariantUiPackageManifestSchema,
|
|
61
|
+
VariantUiPackageNameSchema: () => VariantUiPackageNameSchema,
|
|
42
62
|
getUpdateAction: () => getUpdateAction,
|
|
43
63
|
hasManagedRegion: () => hasManagedRegion,
|
|
64
|
+
loadDesignPack: () => loadDesignPack,
|
|
65
|
+
loadDesignPackageManifest: () => loadDesignPackageManifest,
|
|
66
|
+
loadSkillsPackageManifest: () => loadSkillsPackageManifest,
|
|
67
|
+
loadUiPackageManifest: () => loadUiPackageManifest,
|
|
44
68
|
loadVariantManifest: () => loadVariantManifest,
|
|
69
|
+
loadVariantUiPackageCatalog: () => loadVariantUiPackageCatalog,
|
|
70
|
+
loadVariantUiPackageManifest: () => loadVariantUiPackageManifest,
|
|
71
|
+
mergeDefaultAndVariant: () => mergeDefaultAndVariant,
|
|
45
72
|
parseManagedRegions: () => parseManagedRegions,
|
|
46
73
|
replaceManagedRegion: () => replaceManagedRegion,
|
|
74
|
+
resolveUiEntryOrder: () => resolveUiEntryOrder,
|
|
47
75
|
shouldUpdate: () => shouldUpdate,
|
|
48
76
|
validateConfig: () => validateConfig,
|
|
49
77
|
validateInstalled: () => validateInstalled,
|
|
50
|
-
validateManifest: () => validateManifest
|
|
78
|
+
validateManifest: () => validateManifest,
|
|
79
|
+
validateSkillsLock: () => validateSkillsLock,
|
|
80
|
+
validateSkillsPackage: () => validateSkillsPackage,
|
|
81
|
+
validateUiDependencyGraph: () => validateUiDependencyGraph,
|
|
82
|
+
validateUiPackage: () => validateUiPackage,
|
|
83
|
+
walkPackTree: () => walkPackTree
|
|
51
84
|
});
|
|
52
85
|
module.exports = __toCommonJS(index_exports);
|
|
53
86
|
|
|
@@ -62,8 +95,11 @@ var ResourceTypeSchema = import_zod.z.enum([
|
|
|
62
95
|
"doc",
|
|
63
96
|
"tokens",
|
|
64
97
|
"ai-rules",
|
|
65
|
-
"config"
|
|
98
|
+
"config",
|
|
99
|
+
"skill"
|
|
66
100
|
]);
|
|
101
|
+
var SkillIdeSchema = import_zod.z.enum(["qoder", "claude"]);
|
|
102
|
+
var SkillScopeSchema = import_zod.z.enum(["project", "global"]);
|
|
67
103
|
var ResourceSchema = import_zod.z.object({
|
|
68
104
|
/** Unique identifier for the resource within the manifest */
|
|
69
105
|
id: import_zod.z.string().min(1),
|
|
@@ -71,7 +107,10 @@ var ResourceSchema = import_zod.z.object({
|
|
|
71
107
|
type: ResourceTypeSchema,
|
|
72
108
|
/** Source path (relative to variant root), typically a template */
|
|
73
109
|
source: import_zod.z.string().min(1),
|
|
74
|
-
/**
|
|
110
|
+
/**
|
|
111
|
+
* Target path (relative to project root) where the resource is installed.
|
|
112
|
+
* For type="skill" this is ignored: the path is computed from skill name + ide + scope.
|
|
113
|
+
*/
|
|
75
114
|
target: import_zod.z.string().min(1),
|
|
76
115
|
/** How the resource is updated */
|
|
77
116
|
updateStrategy: UpdateStrategySchema,
|
|
@@ -80,7 +119,11 @@ var ResourceSchema = import_zod.z.object({
|
|
|
80
119
|
/** IDs of managed regions (only relevant when updateStrategy is "managed") */
|
|
81
120
|
managedRegions: import_zod.z.array(import_zod.z.string()).optional(),
|
|
82
121
|
/** Whether to recursively process directory contents */
|
|
83
|
-
recursive: import_zod.z.boolean().optional()
|
|
122
|
+
recursive: import_zod.z.boolean().optional(),
|
|
123
|
+
/** Supported IDEs (only meaningful when type="skill"; defaults to all when omitted) */
|
|
124
|
+
ides: import_zod.z.array(SkillIdeSchema).optional(),
|
|
125
|
+
/** Default install scope (only meaningful when type="skill"; user can override at install time) */
|
|
126
|
+
scope: SkillScopeSchema.optional()
|
|
84
127
|
});
|
|
85
128
|
var VariantManifestSchema = import_zod.z.object({
|
|
86
129
|
$schema: import_zod.z.string().optional(),
|
|
@@ -104,52 +147,380 @@ var VariantManifestSchema = import_zod.z.object({
|
|
|
104
147
|
/** List of resources provided by this variant */
|
|
105
148
|
resources: import_zod.z.array(ResourceSchema)
|
|
106
149
|
});
|
|
150
|
+
var SkillEntrySchema = import_zod.z.object({
|
|
151
|
+
/** Skill identifier (matches name/folder) */
|
|
152
|
+
id: import_zod.z.string().min(1),
|
|
153
|
+
/** Skill name — must match the directory name and frontmatter `name` */
|
|
154
|
+
name: import_zod.z.string().min(1).regex(
|
|
155
|
+
/^[a-z0-9][a-z0-9-]*$/,
|
|
156
|
+
"Skill name must be lowercase letters, digits, hyphens (no leading hyphen)"
|
|
157
|
+
),
|
|
158
|
+
/** One-line description for skill discovery */
|
|
159
|
+
description: import_zod.z.string().min(1),
|
|
160
|
+
/** Semver version */
|
|
161
|
+
version: import_zod.z.string().regex(/^\d+\.\d+\.\d+/, "Invalid semver version"),
|
|
162
|
+
/** Source path relative to package root — file or directory */
|
|
163
|
+
source: import_zod.z.string().min(1),
|
|
164
|
+
/** Supported IDEs (defaults to both when omitted) */
|
|
165
|
+
ides: import_zod.z.array(SkillIdeSchema).default(["qoder", "claude"]),
|
|
166
|
+
/** Update strategy (defaults to managed) */
|
|
167
|
+
updateStrategy: UpdateStrategySchema.default("managed"),
|
|
168
|
+
/** Managed region IDs to maintain on update */
|
|
169
|
+
managedRegions: import_zod.z.array(import_zod.z.string()).optional(),
|
|
170
|
+
/** Whether the source is a Handlebars template */
|
|
171
|
+
template: import_zod.z.boolean().optional(),
|
|
172
|
+
/**
|
|
173
|
+
* Variant identifier when this skill is bound to a specific design variant
|
|
174
|
+
* (e.g. `"opentrek"`, `"uni-manager"`). Optional — neutral skills (manage,
|
|
175
|
+
* coding-conventions, baseline design-rules) leave it unset.
|
|
176
|
+
*
|
|
177
|
+
* When present, the CLI installs this skill ONLY if the consumer's
|
|
178
|
+
* `.teamix-evo/design/pack.lock.json` records the same variant. MUST equal
|
|
179
|
+
* the variant directory name in `@teamix-evo/design/variants/<name>/`.
|
|
180
|
+
*
|
|
181
|
+
* Mirrors `UiEntrySchema.variant` semantics in @teamix-evo/biz-ui &
|
|
182
|
+
* @teamix-evo/templates per ADR 0014.
|
|
183
|
+
*/
|
|
184
|
+
variant: import_zod.z.string().optional()
|
|
185
|
+
});
|
|
186
|
+
var SkillsPackageManifestSchema = import_zod.z.object({
|
|
187
|
+
$schema: import_zod.z.string().optional(),
|
|
188
|
+
schemaVersion: import_zod.z.literal(1),
|
|
189
|
+
/** Always "skills" for this package */
|
|
190
|
+
package: import_zod.z.literal("skills"),
|
|
191
|
+
/** Semver version of the skills package */
|
|
192
|
+
version: import_zod.z.string().regex(/^\d+\.\d+\.\d+/, "Invalid semver version"),
|
|
193
|
+
/** Engine compatibility */
|
|
194
|
+
engines: import_zod.z.object({
|
|
195
|
+
"teamix-evo": import_zod.z.string().min(1)
|
|
196
|
+
}),
|
|
197
|
+
/** Flat list of skills shipped by this package */
|
|
198
|
+
skills: import_zod.z.array(SkillEntrySchema)
|
|
199
|
+
});
|
|
200
|
+
var UiEntryTypeSchema = import_zod.z.enum([
|
|
201
|
+
"component",
|
|
202
|
+
"hook",
|
|
203
|
+
"util",
|
|
204
|
+
"block",
|
|
205
|
+
"template"
|
|
206
|
+
]);
|
|
207
|
+
var UiAliasSchema = import_zod.z.enum([
|
|
208
|
+
"components",
|
|
209
|
+
"hooks",
|
|
210
|
+
"utils",
|
|
211
|
+
"lib",
|
|
212
|
+
"business",
|
|
213
|
+
"templates"
|
|
214
|
+
]);
|
|
215
|
+
var UiEntryStatusSchema = import_zod.z.enum([
|
|
216
|
+
"stable",
|
|
217
|
+
"experimental",
|
|
218
|
+
"deprecated"
|
|
219
|
+
]);
|
|
220
|
+
var UiEntryFileSchema = import_zod.z.object({
|
|
221
|
+
/** Source path relative to the ui package root (e.g. "src/components/button/button.tsx") */
|
|
222
|
+
source: import_zod.z.string().min(1),
|
|
223
|
+
/** Which alias this file resolves under in the consumer project */
|
|
224
|
+
targetAlias: UiAliasSchema,
|
|
225
|
+
/** Filename written under the alias directory (e.g. "button.tsx") */
|
|
226
|
+
targetName: import_zod.z.string().min(1)
|
|
227
|
+
});
|
|
228
|
+
var UiEntrySchema = import_zod.z.object({
|
|
229
|
+
/** Unique entry identifier within the ui package (e.g. "button") */
|
|
230
|
+
id: import_zod.z.string().min(1).regex(
|
|
231
|
+
/^[a-z0-9][a-z0-9-]*$/,
|
|
232
|
+
"UI entry id must be lowercase letters, digits, hyphens (no leading hyphen)"
|
|
233
|
+
),
|
|
234
|
+
/** Display name (e.g. "Button") */
|
|
235
|
+
name: import_zod.z.string().min(1),
|
|
236
|
+
/** Entry type */
|
|
237
|
+
type: UiEntryTypeSchema,
|
|
238
|
+
/** One-line description for entry discovery and AI guidance */
|
|
239
|
+
description: import_zod.z.string().min(1),
|
|
240
|
+
/** Files this entry ships (typically 1) */
|
|
241
|
+
files: import_zod.z.array(UiEntryFileSchema).min(1),
|
|
242
|
+
/**
|
|
243
|
+
* Optional path to an AI-readable meta document (frontmatter + Markdown).
|
|
244
|
+
* When set, CLI install drops it at `.teamix-evo/design/components/<id>.meta.md`
|
|
245
|
+
* for design's ai-rules to consume.
|
|
246
|
+
*/
|
|
247
|
+
meta: import_zod.z.string().optional(),
|
|
248
|
+
/** Other UI entries this one depends on (e.g. "button" depends on "cn") */
|
|
249
|
+
registryDependencies: import_zod.z.array(import_zod.z.string()).optional(),
|
|
250
|
+
/** npm dependencies required by this entry (name → semver range) */
|
|
251
|
+
dependencies: import_zod.z.record(import_zod.z.string(), import_zod.z.string()).optional(),
|
|
252
|
+
/**
|
|
253
|
+
* How CLI handles this entry on `ui upgrade`.
|
|
254
|
+
* Defaults to `frozen` — user-owned source code, untouched after first install.
|
|
255
|
+
* Upgrade is handled by AI + skill flow (no CLI rewrite). See PLAN §10.9.
|
|
256
|
+
*/
|
|
257
|
+
updateStrategy: UpdateStrategySchema.default("frozen"),
|
|
258
|
+
/**
|
|
259
|
+
* Whether the source file should be passed through Handlebars before write.
|
|
260
|
+
* Most entries don't need templating (use import-rewrite transformer instead).
|
|
261
|
+
*/
|
|
262
|
+
template: import_zod.z.boolean().optional(),
|
|
263
|
+
/**
|
|
264
|
+
* Maturity / lifecycle status of this entry. Defaults to `stable`.
|
|
265
|
+
* See {@link UiEntryStatusSchema} for semantics.
|
|
266
|
+
*/
|
|
267
|
+
status: UiEntryStatusSchema.default("stable"),
|
|
268
|
+
/**
|
|
269
|
+
* Free-text rationale shown to consumers when `status` is `deprecated`.
|
|
270
|
+
* Should explain why the entry is going away and what replaces it.
|
|
271
|
+
*/
|
|
272
|
+
deprecatedReason: import_zod.z.string().optional(),
|
|
273
|
+
/**
|
|
274
|
+
* If this entry is `deprecated`, the id of the entry that supersedes it.
|
|
275
|
+
* Consumers (and AI) should migrate to `replacedBy` rather than this entry.
|
|
276
|
+
*/
|
|
277
|
+
replacedBy: import_zod.z.string().optional(),
|
|
278
|
+
/**
|
|
279
|
+
* Variant identifier when this entry is shipped from a variant-aware
|
|
280
|
+
* package (`@teamix-evo/biz-ui` or `@teamix-evo/templates` per ADR 0014).
|
|
281
|
+
* Optional — entries from `@teamix-evo/ui` (variant-agnostic) leave it unset.
|
|
282
|
+
* MUST equal the variant directory name when present.
|
|
283
|
+
*/
|
|
284
|
+
variant: import_zod.z.string().optional()
|
|
285
|
+
});
|
|
286
|
+
var UiPackageManifestSchema = import_zod.z.object({
|
|
287
|
+
$schema: import_zod.z.string().optional(),
|
|
288
|
+
schemaVersion: import_zod.z.literal(1),
|
|
289
|
+
/** Always "ui" for this package */
|
|
290
|
+
package: import_zod.z.literal("ui"),
|
|
291
|
+
/** Semver version of the ui package */
|
|
292
|
+
version: import_zod.z.string().regex(/^\d+\.\d+\.\d+/, "Invalid semver version"),
|
|
293
|
+
/** Engine compatibility */
|
|
294
|
+
engines: import_zod.z.object({
|
|
295
|
+
"teamix-evo": import_zod.z.string().min(1)
|
|
296
|
+
}),
|
|
297
|
+
/** Flat list of entries shipped by this package */
|
|
298
|
+
entries: import_zod.z.array(UiEntrySchema)
|
|
299
|
+
});
|
|
107
300
|
|
|
108
|
-
// src/schema/
|
|
301
|
+
// src/schema/design-pack.ts
|
|
109
302
|
var import_zod2 = require("zod");
|
|
110
|
-
var
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
303
|
+
var VARIANT_NAME_RE = /^[a-z][a-z0-9-]*$/;
|
|
304
|
+
var SEMVER_RE = /^\d+\.\d+\.\d+/;
|
|
305
|
+
var DesignPackLinkedSchema = import_zod2.z.object({
|
|
306
|
+
"biz-ui": import_zod2.z.string().optional(),
|
|
307
|
+
templates: import_zod2.z.string().optional()
|
|
115
308
|
});
|
|
116
|
-
var
|
|
309
|
+
var DesignPackManifestSchema = import_zod2.z.object({
|
|
117
310
|
$schema: import_zod2.z.string().optional(),
|
|
118
311
|
schemaVersion: import_zod2.z.literal(1),
|
|
312
|
+
/**
|
|
313
|
+
* Pack identifier.
|
|
314
|
+
* - `"default"` for the built-in baseline (only valid name when `extends` is absent)
|
|
315
|
+
* - lowercase kebab-case for variants (`opentrek`, `uni-manager`, `acme-erp`, `_template`)
|
|
316
|
+
*/
|
|
317
|
+
name: import_zod2.z.string().min(1).regex(
|
|
318
|
+
VARIANT_NAME_RE,
|
|
319
|
+
'Pack name must be lowercase letters/digits/hyphens (no leading hyphen). Special: "_template" allowed for the variant scaffold.'
|
|
320
|
+
).or(import_zod2.z.literal("_template")).or(import_zod2.z.literal("default")),
|
|
321
|
+
/** Human-readable display name (e.g. "OpenTrek" for variant id "opentrek"). */
|
|
322
|
+
displayName: import_zod2.z.string().min(1),
|
|
323
|
+
/** Semver. */
|
|
324
|
+
version: import_zod2.z.string().regex(SEMVER_RE, "Invalid semver version"),
|
|
325
|
+
/**
|
|
326
|
+
* Parent pack name. Required for variants, must be omitted for `default`.
|
|
327
|
+
* Currently only `"default"` is a valid parent.
|
|
328
|
+
*/
|
|
329
|
+
extends: import_zod2.z.string().optional(),
|
|
330
|
+
/** Optional one-liner; useful for `design list-variants` output. */
|
|
331
|
+
description: import_zod2.z.string().optional(),
|
|
332
|
+
/** Soft cross-package links (biz-ui / templates with same variant name). */
|
|
333
|
+
linked: DesignPackLinkedSchema.optional()
|
|
334
|
+
});
|
|
335
|
+
var DesignPackageManifestSchema = import_zod2.z.object({
|
|
336
|
+
$schema: import_zod2.z.string().optional(),
|
|
337
|
+
schemaVersion: import_zod2.z.literal(1),
|
|
338
|
+
/** Always `"design"` for this package. */
|
|
339
|
+
package: import_zod2.z.literal("design"),
|
|
340
|
+
/** Semver of the entire design package. */
|
|
341
|
+
version: import_zod2.z.string().regex(SEMVER_RE, "Invalid semver version"),
|
|
342
|
+
/** Engine compatibility. */
|
|
343
|
+
engines: import_zod2.z.object({ "teamix-evo": import_zod2.z.string().min(1) }),
|
|
344
|
+
/** The default baseline pack — always present. */
|
|
345
|
+
default: DesignPackManifestSchema,
|
|
346
|
+
/** All shipped variants (excluding `_template/`). */
|
|
347
|
+
variants: import_zod2.z.array(DesignPackManifestSchema)
|
|
348
|
+
});
|
|
349
|
+
var DesignPackLockSchema = import_zod2.z.object({
|
|
350
|
+
$schema: import_zod2.z.string().optional(),
|
|
351
|
+
schemaVersion: import_zod2.z.literal(1),
|
|
352
|
+
default: import_zod2.z.object({
|
|
353
|
+
version: import_zod2.z.string().regex(SEMVER_RE),
|
|
354
|
+
from: import_zod2.z.string().min(1)
|
|
355
|
+
// e.g. "@teamix-evo/design"
|
|
356
|
+
}),
|
|
357
|
+
variant: import_zod2.z.object({
|
|
358
|
+
name: import_zod2.z.string().min(1),
|
|
359
|
+
displayName: import_zod2.z.string().min(1),
|
|
360
|
+
version: import_zod2.z.string().regex(SEMVER_RE),
|
|
361
|
+
from: import_zod2.z.string().min(1)
|
|
362
|
+
}),
|
|
363
|
+
linked: DesignPackLinkedSchema.optional(),
|
|
364
|
+
installedAt: import_zod2.z.string().datetime()
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
// src/schema/variant-ui-pack.ts
|
|
368
|
+
var import_zod3 = require("zod");
|
|
369
|
+
var SEMVER_RE2 = /^\d+\.\d+\.\d+/;
|
|
370
|
+
var VARIANT_NAME_RE2 = /^[a-z][a-z0-9-]*$/;
|
|
371
|
+
var VariantUiPackageNameSchema = import_zod3.z.enum(["biz-ui", "templates"]);
|
|
372
|
+
var VariantUiPackageManifestSchema = import_zod3.z.object({
|
|
373
|
+
$schema: import_zod3.z.string().optional(),
|
|
374
|
+
schemaVersion: import_zod3.z.literal(1),
|
|
375
|
+
/** Discriminator. */
|
|
376
|
+
package: VariantUiPackageNameSchema,
|
|
377
|
+
/**
|
|
378
|
+
* Variant identifier — lowercase kebab-case, MUST match the parent
|
|
379
|
+
* directory name (e.g. `opentrek` for `variants/opentrek/manifest.json`).
|
|
380
|
+
* `_template` is also accepted for the variant scaffold.
|
|
381
|
+
*/
|
|
382
|
+
variant: import_zod3.z.string().min(1).regex(
|
|
383
|
+
VARIANT_NAME_RE2,
|
|
384
|
+
'Variant id must be lowercase letters/digits/hyphens (no leading hyphen). Special: "_template" allowed.'
|
|
385
|
+
).or(import_zod3.z.literal("_template")),
|
|
386
|
+
/** Semver of this variant. */
|
|
387
|
+
version: import_zod3.z.string().regex(SEMVER_RE2, "Invalid semver version"),
|
|
388
|
+
/** Engine compatibility. */
|
|
389
|
+
engines: import_zod3.z.object({ "teamix-evo": import_zod3.z.string().min(1) }),
|
|
390
|
+
/** Flat list of entries shipped by this variant. */
|
|
391
|
+
entries: import_zod3.z.array(UiEntrySchema)
|
|
392
|
+
}).superRefine((data, ctx) => {
|
|
393
|
+
for (const [i, entry] of data.entries.entries()) {
|
|
394
|
+
if (entry.variant !== void 0 && entry.variant !== data.variant) {
|
|
395
|
+
ctx.addIssue({
|
|
396
|
+
code: import_zod3.z.ZodIssueCode.custom,
|
|
397
|
+
path: ["entries", i, "variant"],
|
|
398
|
+
message: `Entry "${entry.id}" declares variant "${entry.variant}" but lives in manifest of variant "${data.variant}".`
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
});
|
|
403
|
+
var VariantUiPackageCatalogSchema = import_zod3.z.object({
|
|
404
|
+
$schema: import_zod3.z.string().optional(),
|
|
405
|
+
schemaVersion: import_zod3.z.literal(1),
|
|
406
|
+
package: VariantUiPackageNameSchema,
|
|
407
|
+
/** Semver of the entire package. */
|
|
408
|
+
version: import_zod3.z.string().regex(SEMVER_RE2, "Invalid semver version"),
|
|
409
|
+
engines: import_zod3.z.object({ "teamix-evo": import_zod3.z.string().min(1) }),
|
|
410
|
+
/** Variants this package ships (excluding `_template`). */
|
|
411
|
+
variants: import_zod3.z.array(
|
|
412
|
+
import_zod3.z.object({
|
|
413
|
+
name: import_zod3.z.string().min(1).regex(VARIANT_NAME_RE2),
|
|
414
|
+
displayName: import_zod3.z.string().min(1),
|
|
415
|
+
version: import_zod3.z.string().regex(SEMVER_RE2),
|
|
416
|
+
description: import_zod3.z.string().optional()
|
|
417
|
+
})
|
|
418
|
+
)
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
// src/schema/config.ts
|
|
422
|
+
var import_zod4 = require("zod");
|
|
423
|
+
var TailwindVersionSchema = import_zod4.z.literal("v4");
|
|
424
|
+
var UiAliasesSchema = import_zod4.z.object({
|
|
425
|
+
components: import_zod4.z.string().min(1),
|
|
426
|
+
hooks: import_zod4.z.string().min(1),
|
|
427
|
+
utils: import_zod4.z.string().min(1),
|
|
428
|
+
lib: import_zod4.z.string().min(1),
|
|
429
|
+
/** Biz-ui components (variant-bound). Defaults to `src/components/business/`. */
|
|
430
|
+
business: import_zod4.z.string().min(1).default("src/components/business"),
|
|
431
|
+
/** Page templates (variant-bound). Defaults to `src/templates/`. */
|
|
432
|
+
templates: import_zod4.z.string().min(1).default("src/templates")
|
|
433
|
+
});
|
|
434
|
+
var PackageEntrySchema = import_zod4.z.object({
|
|
435
|
+
/** Variant identifier (e.g. "opentrek"; use "_flat" for skills/ui) */
|
|
436
|
+
variant: import_zod4.z.string().min(1),
|
|
437
|
+
/** Semver version string */
|
|
438
|
+
version: import_zod4.z.string().min(1),
|
|
439
|
+
/** Tailwind CSS version this project uses (only meaningful for design package). */
|
|
440
|
+
tailwind: TailwindVersionSchema.optional(),
|
|
441
|
+
/** IDEs this package was installed for (only meaningful for skills package). */
|
|
442
|
+
ides: import_zod4.z.array(SkillIdeSchema).optional(),
|
|
443
|
+
/** Install scope (only meaningful for skills package). */
|
|
444
|
+
scope: SkillScopeSchema.optional(),
|
|
445
|
+
/** Path aliases for ui entry installation (only meaningful for ui package). */
|
|
446
|
+
aliases: UiAliasesSchema.optional(),
|
|
447
|
+
/**
|
|
448
|
+
* Default icon library declared by the project (only meaningful for ui).
|
|
449
|
+
* Declarative only — does NOT trigger code rewrites; ui entries hardcode imports.
|
|
450
|
+
*/
|
|
451
|
+
iconLibrary: import_zod4.z.string().min(1).optional(),
|
|
452
|
+
/** Whether the project uses TSX (true) or JSX (false). ui-specific. */
|
|
453
|
+
tsx: import_zod4.z.boolean().optional(),
|
|
454
|
+
/** Whether to emit React Server Components markers (`"use client"`). ui-specific. */
|
|
455
|
+
rsc: import_zod4.z.boolean().optional()
|
|
456
|
+
});
|
|
457
|
+
var ProjectConfigSchema = import_zod4.z.object({
|
|
458
|
+
$schema: import_zod4.z.string().optional(),
|
|
459
|
+
schemaVersion: import_zod4.z.literal(1),
|
|
119
460
|
/** IDE identifier */
|
|
120
|
-
ide:
|
|
461
|
+
ide: import_zod4.z.string().min(1),
|
|
121
462
|
/** Installed packages keyed by package name */
|
|
122
|
-
packages:
|
|
463
|
+
packages: import_zod4.z.record(import_zod4.z.string(), PackageEntrySchema)
|
|
123
464
|
});
|
|
124
465
|
|
|
125
466
|
// src/schema/installed.ts
|
|
126
|
-
var
|
|
127
|
-
var InstalledResourceSchema =
|
|
467
|
+
var import_zod5 = require("zod");
|
|
468
|
+
var InstalledResourceSchema = import_zod5.z.object({
|
|
128
469
|
/** Resource identifier matching the variant manifest */
|
|
129
|
-
id:
|
|
130
|
-
/** Target path where the resource was installed */
|
|
131
|
-
target:
|
|
470
|
+
id: import_zod5.z.string().min(1),
|
|
471
|
+
/** Target path where the resource was installed (absolute or project-relative) */
|
|
472
|
+
target: import_zod5.z.string().min(1),
|
|
132
473
|
/** Content hash for change detection (e.g. "sha256:...") */
|
|
133
|
-
hash:
|
|
474
|
+
hash: import_zod5.z.string().min(1),
|
|
134
475
|
/** Update strategy that was applied */
|
|
135
|
-
strategy:
|
|
476
|
+
strategy: import_zod5.z.enum(["frozen", "regenerable", "managed"]),
|
|
477
|
+
/** IDE this resource was installed for (skill resources only) */
|
|
478
|
+
ide: SkillIdeSchema.optional(),
|
|
479
|
+
/** Install scope (skill resources only) */
|
|
480
|
+
scope: SkillScopeSchema.optional()
|
|
136
481
|
});
|
|
137
|
-
var InstalledPackageSchema =
|
|
482
|
+
var InstalledPackageSchema = import_zod5.z.object({
|
|
138
483
|
/** Full package name (e.g. "@teamix-evo/design") */
|
|
139
|
-
package:
|
|
140
|
-
/** Variant identifier */
|
|
141
|
-
variant:
|
|
484
|
+
package: import_zod5.z.string().min(1),
|
|
485
|
+
/** Variant identifier (use "_flat" for non-variant packages such as skills) */
|
|
486
|
+
variant: import_zod5.z.string().min(1),
|
|
142
487
|
/** Installed version */
|
|
143
|
-
version:
|
|
488
|
+
version: import_zod5.z.string().min(1),
|
|
144
489
|
/** ISO 8601 timestamp of installation */
|
|
145
|
-
installedAt:
|
|
490
|
+
installedAt: import_zod5.z.string().min(1),
|
|
146
491
|
/** List of installed resources */
|
|
147
|
-
resources:
|
|
492
|
+
resources: import_zod5.z.array(InstalledResourceSchema)
|
|
148
493
|
});
|
|
149
|
-
var InstalledManifestSchema =
|
|
150
|
-
schemaVersion:
|
|
494
|
+
var InstalledManifestSchema = import_zod5.z.object({
|
|
495
|
+
schemaVersion: import_zod5.z.literal(1),
|
|
151
496
|
/** List of installed packages */
|
|
152
|
-
installed:
|
|
497
|
+
installed: import_zod5.z.array(InstalledPackageSchema)
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
// src/schema/skills-lock.ts
|
|
501
|
+
var import_zod6 = require("zod");
|
|
502
|
+
var SkillsLockEntrySchema = import_zod6.z.object({
|
|
503
|
+
/** Semver version installed from upstream */
|
|
504
|
+
version: import_zod6.z.string().min(1),
|
|
505
|
+
/** Upstream package name (typically `@teamix-evo/skills`) */
|
|
506
|
+
from: import_zod6.z.string().min(1),
|
|
507
|
+
/** ISO 8601 install / last-sync timestamp */
|
|
508
|
+
installedAt: import_zod6.z.string().min(1),
|
|
509
|
+
/** Install scope at time of mirror */
|
|
510
|
+
scope: SkillScopeSchema,
|
|
511
|
+
/**
|
|
512
|
+
* IDEs this skill was mirrored to. Each ide ↔ a mirror path under
|
|
513
|
+
* `<projectRoot>/.<ide>/skills/<id>/` (project) or `~/.<ide>/skills/<id>/`
|
|
514
|
+
* (global). The path itself is reconstructed from `scope` + adapter; we
|
|
515
|
+
* record the ide identifier rather than the full path to keep the lock
|
|
516
|
+
* portable across machines.
|
|
517
|
+
*/
|
|
518
|
+
mirroredTo: import_zod6.z.array(SkillIdeSchema)
|
|
519
|
+
});
|
|
520
|
+
var SkillsLockSchema = import_zod6.z.object({
|
|
521
|
+
schemaVersion: import_zod6.z.literal(1),
|
|
522
|
+
/** Map of skill id → lock entry */
|
|
523
|
+
skills: import_zod6.z.record(import_zod6.z.string().min(1), SkillsLockEntrySchema)
|
|
153
524
|
});
|
|
154
525
|
|
|
155
526
|
// src/loader.ts
|
|
@@ -159,8 +530,8 @@ var path = __toESM(require("path"), 1);
|
|
|
159
530
|
// src/validator.ts
|
|
160
531
|
function formatZodError(error) {
|
|
161
532
|
return error.issues.map((issue) => {
|
|
162
|
-
const
|
|
163
|
-
return ` - ${
|
|
533
|
+
const path4 = issue.path.length > 0 ? issue.path.join(".") : "(root)";
|
|
534
|
+
return ` - ${path4}: ${issue.message}`;
|
|
164
535
|
}).join("\n");
|
|
165
536
|
}
|
|
166
537
|
function validateManifest(data) {
|
|
@@ -196,6 +567,126 @@ function validateInstalled(data) {
|
|
|
196
567
|
${formatZodError(result.error)}`
|
|
197
568
|
};
|
|
198
569
|
}
|
|
570
|
+
function validateSkillsLock(data) {
|
|
571
|
+
const result = SkillsLockSchema.safeParse(data);
|
|
572
|
+
if (result.success) {
|
|
573
|
+
return { success: true, data: result.data };
|
|
574
|
+
}
|
|
575
|
+
return {
|
|
576
|
+
success: false,
|
|
577
|
+
error: `Invalid skills lock:
|
|
578
|
+
${formatZodError(result.error)}`
|
|
579
|
+
};
|
|
580
|
+
}
|
|
581
|
+
function validateSkillsPackage(data) {
|
|
582
|
+
const result = SkillsPackageManifestSchema.safeParse(data);
|
|
583
|
+
if (result.success) {
|
|
584
|
+
return { success: true, data: result.data };
|
|
585
|
+
}
|
|
586
|
+
return {
|
|
587
|
+
success: false,
|
|
588
|
+
error: `Invalid skills package manifest:
|
|
589
|
+
${formatZodError(result.error)}`
|
|
590
|
+
};
|
|
591
|
+
}
|
|
592
|
+
function validateUiPackage(data) {
|
|
593
|
+
const parsed = UiPackageManifestSchema.safeParse(data);
|
|
594
|
+
if (!parsed.success) {
|
|
595
|
+
return {
|
|
596
|
+
success: false,
|
|
597
|
+
error: `Invalid ui package manifest:
|
|
598
|
+
${formatZodError(parsed.error)}`
|
|
599
|
+
};
|
|
600
|
+
}
|
|
601
|
+
const graphIssues = validateUiDependencyGraph(parsed.data.entries);
|
|
602
|
+
if (graphIssues.length > 0) {
|
|
603
|
+
return {
|
|
604
|
+
success: false,
|
|
605
|
+
error: `Invalid ui package manifest dependency graph:
|
|
606
|
+
${graphIssues.map((i) => ` - ${i}`).join("\n")}`
|
|
607
|
+
};
|
|
608
|
+
}
|
|
609
|
+
return { success: true, data: parsed.data };
|
|
610
|
+
}
|
|
611
|
+
function validateUiDependencyGraph(entries) {
|
|
612
|
+
const issues = [];
|
|
613
|
+
const idToEntry = /* @__PURE__ */ new Map();
|
|
614
|
+
for (const entry of entries) {
|
|
615
|
+
if (idToEntry.has(entry.id)) {
|
|
616
|
+
issues.push(`duplicate entry id: "${entry.id}"`);
|
|
617
|
+
} else {
|
|
618
|
+
idToEntry.set(entry.id, entry);
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
for (const entry of entries) {
|
|
622
|
+
const deps = entry.registryDependencies ?? [];
|
|
623
|
+
for (const dep of deps) {
|
|
624
|
+
if (!idToEntry.has(dep)) {
|
|
625
|
+
issues.push(
|
|
626
|
+
`entry "${entry.id}" depends on unknown entry "${dep}"`
|
|
627
|
+
);
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
const WHITE = 0;
|
|
632
|
+
const GRAY = 1;
|
|
633
|
+
const BLACK = 2;
|
|
634
|
+
const color = /* @__PURE__ */ new Map();
|
|
635
|
+
for (const id of idToEntry.keys()) color.set(id, WHITE);
|
|
636
|
+
const cycles = [];
|
|
637
|
+
function dfs(id, path4) {
|
|
638
|
+
color.set(id, GRAY);
|
|
639
|
+
path4.push(id);
|
|
640
|
+
const entry = idToEntry.get(id);
|
|
641
|
+
const deps = entry?.registryDependencies ?? [];
|
|
642
|
+
for (const dep of deps) {
|
|
643
|
+
if (!idToEntry.has(dep)) continue;
|
|
644
|
+
const c = color.get(dep);
|
|
645
|
+
if (c === GRAY) {
|
|
646
|
+
const startIdx = path4.indexOf(dep);
|
|
647
|
+
cycles.push([...path4.slice(startIdx), dep]);
|
|
648
|
+
} else if (c === WHITE) {
|
|
649
|
+
dfs(dep, path4);
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
path4.pop();
|
|
653
|
+
color.set(id, BLACK);
|
|
654
|
+
}
|
|
655
|
+
for (const id of idToEntry.keys()) {
|
|
656
|
+
if (color.get(id) === WHITE) dfs(id, []);
|
|
657
|
+
}
|
|
658
|
+
for (const cycle of cycles) {
|
|
659
|
+
issues.push(`cyclic registryDependencies: ${cycle.join(" \u2192 ")}`);
|
|
660
|
+
}
|
|
661
|
+
return issues;
|
|
662
|
+
}
|
|
663
|
+
function resolveUiEntryOrder(entries, requested) {
|
|
664
|
+
const idToEntry = new Map(entries.map((e) => [e.id, e]));
|
|
665
|
+
for (const id of requested) {
|
|
666
|
+
if (!idToEntry.has(id)) {
|
|
667
|
+
throw new Error(`Unknown ui entry: "${id}"`);
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
const graphIssues = validateUiDependencyGraph(entries);
|
|
671
|
+
if (graphIssues.length > 0) {
|
|
672
|
+
throw new Error(
|
|
673
|
+
`UI dependency graph has issues:
|
|
674
|
+
${graphIssues.map((i) => ` - ${i}`).join("\n")}`
|
|
675
|
+
);
|
|
676
|
+
}
|
|
677
|
+
const visited = /* @__PURE__ */ new Set();
|
|
678
|
+
const order = [];
|
|
679
|
+
function visit(id) {
|
|
680
|
+
if (visited.has(id)) return;
|
|
681
|
+
visited.add(id);
|
|
682
|
+
const entry = idToEntry.get(id);
|
|
683
|
+
const deps = entry?.registryDependencies ?? [];
|
|
684
|
+
for (const dep of deps) visit(dep);
|
|
685
|
+
order.push(id);
|
|
686
|
+
}
|
|
687
|
+
for (const id of requested) visit(id);
|
|
688
|
+
return order;
|
|
689
|
+
}
|
|
199
690
|
|
|
200
691
|
// src/loader.ts
|
|
201
692
|
async function loadVariantManifest(packageDir) {
|
|
@@ -225,6 +716,254 @@ async function loadVariantManifest(packageDir) {
|
|
|
225
716
|
}
|
|
226
717
|
return result.data;
|
|
227
718
|
}
|
|
719
|
+
async function loadSkillsPackageManifest(packageDir) {
|
|
720
|
+
const manifestPath = path.join(packageDir, "manifest.json");
|
|
721
|
+
let raw;
|
|
722
|
+
try {
|
|
723
|
+
raw = await fs.readFile(manifestPath, "utf-8");
|
|
724
|
+
} catch (err) {
|
|
725
|
+
const code = err.code;
|
|
726
|
+
if (code === "ENOENT") {
|
|
727
|
+
throw new Error(`Skills manifest not found: ${manifestPath}`);
|
|
728
|
+
}
|
|
729
|
+
throw new Error(
|
|
730
|
+
`Failed to read skills manifest at ${manifestPath}: ${err.message}`
|
|
731
|
+
);
|
|
732
|
+
}
|
|
733
|
+
let data;
|
|
734
|
+
try {
|
|
735
|
+
data = JSON.parse(raw);
|
|
736
|
+
} catch {
|
|
737
|
+
throw new Error(`Invalid JSON in skills manifest at ${manifestPath}`);
|
|
738
|
+
}
|
|
739
|
+
const result = validateSkillsPackage(data);
|
|
740
|
+
if (!result.success) {
|
|
741
|
+
throw new Error(`${result.error}
|
|
742
|
+
File: ${manifestPath}`);
|
|
743
|
+
}
|
|
744
|
+
return result.data;
|
|
745
|
+
}
|
|
746
|
+
async function loadUiPackageManifest(packageDir) {
|
|
747
|
+
const manifestPath = path.join(packageDir, "manifest.json");
|
|
748
|
+
let raw;
|
|
749
|
+
try {
|
|
750
|
+
raw = await fs.readFile(manifestPath, "utf-8");
|
|
751
|
+
} catch (err) {
|
|
752
|
+
const code = err.code;
|
|
753
|
+
if (code === "ENOENT") {
|
|
754
|
+
throw new Error(`UI manifest not found: ${manifestPath}`);
|
|
755
|
+
}
|
|
756
|
+
throw new Error(
|
|
757
|
+
`Failed to read ui manifest at ${manifestPath}: ${err.message}`
|
|
758
|
+
);
|
|
759
|
+
}
|
|
760
|
+
let data;
|
|
761
|
+
try {
|
|
762
|
+
data = JSON.parse(raw);
|
|
763
|
+
} catch {
|
|
764
|
+
throw new Error(`Invalid JSON in ui manifest at ${manifestPath}`);
|
|
765
|
+
}
|
|
766
|
+
const result = validateUiPackage(data);
|
|
767
|
+
if (!result.success) {
|
|
768
|
+
throw new Error(`${result.error}
|
|
769
|
+
File: ${manifestPath}`);
|
|
770
|
+
}
|
|
771
|
+
return result.data;
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
// src/design-pack-loader.ts
|
|
775
|
+
var fs2 = __toESM(require("fs/promises"), 1);
|
|
776
|
+
var path2 = __toESM(require("path"), 1);
|
|
777
|
+
var PACK_METADATA_FILES = /* @__PURE__ */ new Set(["pack.json"]);
|
|
778
|
+
async function loadDesignPack(packDir) {
|
|
779
|
+
const manifestPath = path2.join(packDir, "pack.json");
|
|
780
|
+
let raw;
|
|
781
|
+
try {
|
|
782
|
+
raw = await fs2.readFile(manifestPath, "utf-8");
|
|
783
|
+
} catch (err) {
|
|
784
|
+
const code = err.code;
|
|
785
|
+
if (code === "ENOENT") {
|
|
786
|
+
throw new Error(`Design pack manifest not found: ${manifestPath}`);
|
|
787
|
+
}
|
|
788
|
+
throw new Error(
|
|
789
|
+
`Failed to read design pack manifest at ${manifestPath}: ${err.message}`
|
|
790
|
+
);
|
|
791
|
+
}
|
|
792
|
+
let parsed;
|
|
793
|
+
try {
|
|
794
|
+
parsed = JSON.parse(raw);
|
|
795
|
+
} catch {
|
|
796
|
+
throw new Error(`Invalid JSON in design pack manifest at ${manifestPath}`);
|
|
797
|
+
}
|
|
798
|
+
const result = DesignPackManifestSchema.safeParse(parsed);
|
|
799
|
+
if (!result.success) {
|
|
800
|
+
throw new Error(
|
|
801
|
+
`Invalid design pack manifest:
|
|
802
|
+
${result.error.message}
|
|
803
|
+
File: ${manifestPath}`
|
|
804
|
+
);
|
|
805
|
+
}
|
|
806
|
+
if (result.data.name === "default" && result.data.extends !== void 0) {
|
|
807
|
+
throw new Error(
|
|
808
|
+
`Pack "default" must not have "extends" field: ${manifestPath}`
|
|
809
|
+
);
|
|
810
|
+
}
|
|
811
|
+
if (result.data.name !== "default" && result.data.extends !== "default") {
|
|
812
|
+
throw new Error(
|
|
813
|
+
`Variant pack "${result.data.name}" must declare extends: "default" (got ${JSON.stringify(
|
|
814
|
+
result.data.extends
|
|
815
|
+
)}): ${manifestPath}`
|
|
816
|
+
);
|
|
817
|
+
}
|
|
818
|
+
return result.data;
|
|
819
|
+
}
|
|
820
|
+
async function loadDesignPackageManifest(packageDir) {
|
|
821
|
+
const manifestPath = path2.join(packageDir, "manifest.json");
|
|
822
|
+
let raw;
|
|
823
|
+
try {
|
|
824
|
+
raw = await fs2.readFile(manifestPath, "utf-8");
|
|
825
|
+
} catch (err) {
|
|
826
|
+
const code = err.code;
|
|
827
|
+
if (code === "ENOENT") {
|
|
828
|
+
throw new Error(`Design package manifest not found: ${manifestPath}`);
|
|
829
|
+
}
|
|
830
|
+
throw new Error(
|
|
831
|
+
`Failed to read design package manifest at ${manifestPath}: ${err.message}`
|
|
832
|
+
);
|
|
833
|
+
}
|
|
834
|
+
let parsed;
|
|
835
|
+
try {
|
|
836
|
+
parsed = JSON.parse(raw);
|
|
837
|
+
} catch {
|
|
838
|
+
throw new Error(`Invalid JSON in design package manifest at ${manifestPath}`);
|
|
839
|
+
}
|
|
840
|
+
const result = DesignPackageManifestSchema.safeParse(parsed);
|
|
841
|
+
if (!result.success) {
|
|
842
|
+
throw new Error(
|
|
843
|
+
`Invalid design package manifest:
|
|
844
|
+
${result.error.message}
|
|
845
|
+
File: ${manifestPath}`
|
|
846
|
+
);
|
|
847
|
+
}
|
|
848
|
+
return result.data;
|
|
849
|
+
}
|
|
850
|
+
async function walkPackTree(packDir) {
|
|
851
|
+
const out = [];
|
|
852
|
+
async function recurse(absDir, relDir) {
|
|
853
|
+
const entries = await fs2.readdir(absDir, { withFileTypes: true });
|
|
854
|
+
for (const entry of entries) {
|
|
855
|
+
const abs = path2.join(absDir, entry.name);
|
|
856
|
+
const rel = relDir ? path2.posix.join(relDir, entry.name) : entry.name;
|
|
857
|
+
if (entry.isDirectory()) {
|
|
858
|
+
await recurse(abs, rel);
|
|
859
|
+
} else if (entry.isFile()) {
|
|
860
|
+
if (relDir === "" && PACK_METADATA_FILES.has(entry.name)) continue;
|
|
861
|
+
out.push(rel);
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
try {
|
|
866
|
+
await recurse(packDir, "");
|
|
867
|
+
} catch (err) {
|
|
868
|
+
const code = err.code;
|
|
869
|
+
if (code === "ENOENT") {
|
|
870
|
+
throw new Error(`Pack directory not found: ${packDir}`);
|
|
871
|
+
}
|
|
872
|
+
throw err;
|
|
873
|
+
}
|
|
874
|
+
return out.sort();
|
|
875
|
+
}
|
|
876
|
+
async function mergeDefaultAndVariant(defaultDir, variantDir) {
|
|
877
|
+
const defaultFiles = new Set(await walkPackTree(defaultDir));
|
|
878
|
+
const variantFiles = new Set(await walkPackTree(variantDir));
|
|
879
|
+
const overrides = [];
|
|
880
|
+
const variantAdds = [];
|
|
881
|
+
const defaultPassThrough = [];
|
|
882
|
+
const files = [];
|
|
883
|
+
const allPaths = Array.from(/* @__PURE__ */ new Set([...defaultFiles, ...variantFiles])).sort();
|
|
884
|
+
for (const rel of allPaths) {
|
|
885
|
+
const inDefault = defaultFiles.has(rel);
|
|
886
|
+
const inVariant = variantFiles.has(rel);
|
|
887
|
+
if (inVariant && inDefault) {
|
|
888
|
+
overrides.push(rel);
|
|
889
|
+
files.push({
|
|
890
|
+
relPath: rel,
|
|
891
|
+
sourcePath: path2.join(variantDir, rel),
|
|
892
|
+
origin: "variant"
|
|
893
|
+
});
|
|
894
|
+
} else if (inVariant) {
|
|
895
|
+
variantAdds.push(rel);
|
|
896
|
+
files.push({
|
|
897
|
+
relPath: rel,
|
|
898
|
+
sourcePath: path2.join(variantDir, rel),
|
|
899
|
+
origin: "variant"
|
|
900
|
+
});
|
|
901
|
+
} else {
|
|
902
|
+
defaultPassThrough.push(rel);
|
|
903
|
+
files.push({
|
|
904
|
+
relPath: rel,
|
|
905
|
+
sourcePath: path2.join(defaultDir, rel),
|
|
906
|
+
origin: "default"
|
|
907
|
+
});
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
return { files, overrides, variantAdds, defaultPassThrough };
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
// src/variant-ui-pack-loader.ts
|
|
914
|
+
var fs3 = __toESM(require("fs/promises"), 1);
|
|
915
|
+
var path3 = __toESM(require("path"), 1);
|
|
916
|
+
async function readJson(filePath, kind) {
|
|
917
|
+
let raw;
|
|
918
|
+
try {
|
|
919
|
+
raw = await fs3.readFile(filePath, "utf-8");
|
|
920
|
+
} catch (err) {
|
|
921
|
+
const code = err.code;
|
|
922
|
+
if (code === "ENOENT") {
|
|
923
|
+
throw new Error(`${kind} not found: ${filePath}`);
|
|
924
|
+
}
|
|
925
|
+
throw new Error(
|
|
926
|
+
`Failed to read ${kind} at ${filePath}: ${err.message}`
|
|
927
|
+
);
|
|
928
|
+
}
|
|
929
|
+
try {
|
|
930
|
+
return JSON.parse(raw);
|
|
931
|
+
} catch {
|
|
932
|
+
throw new Error(`Invalid JSON in ${kind} at ${filePath}`);
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
async function loadVariantUiPackageCatalog(packageDir) {
|
|
936
|
+
const manifestPath = path3.join(packageDir, "manifest.json");
|
|
937
|
+
const data = await readJson(manifestPath, "variant-ui catalog");
|
|
938
|
+
const result = VariantUiPackageCatalogSchema.safeParse(data);
|
|
939
|
+
if (!result.success) {
|
|
940
|
+
throw new Error(
|
|
941
|
+
`Invalid catalog:
|
|
942
|
+
${result.error.message}
|
|
943
|
+
File: ${manifestPath}`
|
|
944
|
+
);
|
|
945
|
+
}
|
|
946
|
+
return result.data;
|
|
947
|
+
}
|
|
948
|
+
async function loadVariantUiPackageManifest(variantDir) {
|
|
949
|
+
const manifestPath = path3.join(variantDir, "manifest.json");
|
|
950
|
+
const data = await readJson(manifestPath, "variant-ui manifest");
|
|
951
|
+
const result = VariantUiPackageManifestSchema.safeParse(data);
|
|
952
|
+
if (!result.success) {
|
|
953
|
+
throw new Error(
|
|
954
|
+
`Invalid variant manifest:
|
|
955
|
+
${result.error.message}
|
|
956
|
+
File: ${manifestPath}`
|
|
957
|
+
);
|
|
958
|
+
}
|
|
959
|
+
const dirName = path3.basename(variantDir);
|
|
960
|
+
if (result.data.variant !== dirName) {
|
|
961
|
+
throw new Error(
|
|
962
|
+
`Variant manifest mismatch: variants/${dirName}/manifest.json declares variant="${result.data.variant}". Names must match.`
|
|
963
|
+
);
|
|
964
|
+
}
|
|
965
|
+
return result.data;
|
|
966
|
+
}
|
|
228
967
|
|
|
229
968
|
// src/managed-regions.ts
|
|
230
969
|
var REGION_PATTERN = /<!-- teamix-evo:managed:start id="([^"]+)" -->([\s\S]*?)<!-- teamix-evo:managed:end id="\1" -->/g;
|
|
@@ -233,15 +972,25 @@ var END_MARKER_PATTERN = /<!-- teamix-evo:managed:end id="([^"]+)" -->/g;
|
|
|
233
972
|
function parseManagedRegions(content) {
|
|
234
973
|
const startIds = /* @__PURE__ */ new Set();
|
|
235
974
|
const endIds = /* @__PURE__ */ new Set();
|
|
975
|
+
const startCounts = /* @__PURE__ */ new Map();
|
|
236
976
|
let match;
|
|
237
977
|
const startRe = new RegExp(START_MARKER_PATTERN.source, "g");
|
|
238
978
|
while ((match = startRe.exec(content)) !== null) {
|
|
239
|
-
|
|
979
|
+
const id = match[1];
|
|
980
|
+
startIds.add(id);
|
|
981
|
+
startCounts.set(id, (startCounts.get(id) ?? 0) + 1);
|
|
240
982
|
}
|
|
241
983
|
const endRe = new RegExp(END_MARKER_PATTERN.source, "g");
|
|
242
984
|
while ((match = endRe.exec(content)) !== null) {
|
|
243
985
|
endIds.add(match[1]);
|
|
244
986
|
}
|
|
987
|
+
for (const [id, count] of startCounts) {
|
|
988
|
+
if (count > 1) {
|
|
989
|
+
throw new Error(
|
|
990
|
+
`Duplicate managed region: found ${count} start markers for "${id}". Each id must be unique within a file.`
|
|
991
|
+
);
|
|
992
|
+
}
|
|
993
|
+
}
|
|
245
994
|
for (const id of startIds) {
|
|
246
995
|
if (!endIds.has(id)) {
|
|
247
996
|
throw new Error(
|
|
@@ -274,7 +1023,9 @@ function replaceManagedRegion(content, id, newContent) {
|
|
|
274
1023
|
const startMarker = `<!-- teamix-evo:managed:start id="${id}" -->`;
|
|
275
1024
|
const endMarker = `<!-- teamix-evo:managed:end id="${id}" -->`;
|
|
276
1025
|
const pattern = new RegExp(
|
|
277
|
-
`<!-- teamix-evo:managed:start id="${escapeRegExp(
|
|
1026
|
+
`<!-- teamix-evo:managed:start id="${escapeRegExp(
|
|
1027
|
+
id
|
|
1028
|
+
)}" -->[\\s\\S]*?<!-- teamix-evo:managed:end id="${escapeRegExp(id)}" -->`,
|
|
278
1029
|
"g"
|
|
279
1030
|
);
|
|
280
1031
|
if (!pattern.test(content)) {
|
|
@@ -290,7 +1041,9 @@ ${endMarker}`
|
|
|
290
1041
|
}
|
|
291
1042
|
function hasManagedRegion(content, id) {
|
|
292
1043
|
const pattern = new RegExp(
|
|
293
|
-
`<!-- teamix-evo:managed:start id="${escapeRegExp(
|
|
1044
|
+
`<!-- teamix-evo:managed:start id="${escapeRegExp(
|
|
1045
|
+
id
|
|
1046
|
+
)}" -->[\\s\\S]*?<!-- teamix-evo:managed:end id="${escapeRegExp(id)}" -->`
|
|
294
1047
|
);
|
|
295
1048
|
return pattern.test(content);
|
|
296
1049
|
}
|
|
@@ -334,6 +1087,10 @@ function getUpdateAction(strategy, options) {
|
|
|
334
1087
|
}
|
|
335
1088
|
// Annotate the CommonJS export names for ESM import in node:
|
|
336
1089
|
0 && (module.exports = {
|
|
1090
|
+
DesignPackLinkedSchema,
|
|
1091
|
+
DesignPackLockSchema,
|
|
1092
|
+
DesignPackManifestSchema,
|
|
1093
|
+
DesignPackageManifestSchema,
|
|
337
1094
|
InstalledManifestSchema,
|
|
338
1095
|
InstalledPackageSchema,
|
|
339
1096
|
InstalledResourceSchema,
|
|
@@ -341,16 +1098,45 @@ function getUpdateAction(strategy, options) {
|
|
|
341
1098
|
ProjectConfigSchema,
|
|
342
1099
|
ResourceSchema,
|
|
343
1100
|
ResourceTypeSchema,
|
|
1101
|
+
SkillEntrySchema,
|
|
1102
|
+
SkillIdeSchema,
|
|
1103
|
+
SkillScopeSchema,
|
|
1104
|
+
SkillsLockEntrySchema,
|
|
1105
|
+
SkillsLockSchema,
|
|
1106
|
+
SkillsPackageManifestSchema,
|
|
1107
|
+
TailwindVersionSchema,
|
|
1108
|
+
UiAliasSchema,
|
|
1109
|
+
UiAliasesSchema,
|
|
1110
|
+
UiEntryFileSchema,
|
|
1111
|
+
UiEntrySchema,
|
|
1112
|
+
UiEntryTypeSchema,
|
|
1113
|
+
UiPackageManifestSchema,
|
|
344
1114
|
UpdateStrategySchema,
|
|
345
1115
|
VariantManifestSchema,
|
|
1116
|
+
VariantUiPackageCatalogSchema,
|
|
1117
|
+
VariantUiPackageManifestSchema,
|
|
1118
|
+
VariantUiPackageNameSchema,
|
|
346
1119
|
getUpdateAction,
|
|
347
1120
|
hasManagedRegion,
|
|
1121
|
+
loadDesignPack,
|
|
1122
|
+
loadDesignPackageManifest,
|
|
1123
|
+
loadSkillsPackageManifest,
|
|
1124
|
+
loadUiPackageManifest,
|
|
348
1125
|
loadVariantManifest,
|
|
1126
|
+
loadVariantUiPackageCatalog,
|
|
1127
|
+
loadVariantUiPackageManifest,
|
|
1128
|
+
mergeDefaultAndVariant,
|
|
349
1129
|
parseManagedRegions,
|
|
350
1130
|
replaceManagedRegion,
|
|
1131
|
+
resolveUiEntryOrder,
|
|
351
1132
|
shouldUpdate,
|
|
352
1133
|
validateConfig,
|
|
353
1134
|
validateInstalled,
|
|
354
|
-
validateManifest
|
|
1135
|
+
validateManifest,
|
|
1136
|
+
validateSkillsLock,
|
|
1137
|
+
validateSkillsPackage,
|
|
1138
|
+
validateUiDependencyGraph,
|
|
1139
|
+
validateUiPackage,
|
|
1140
|
+
walkPackTree
|
|
355
1141
|
});
|
|
356
1142
|
//# sourceMappingURL=index.cjs.map
|