@teamix-evo/registry 0.2.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/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,
@@ -40,6 +44,8 @@ __export(index_exports, {
40
44
  SkillEntrySchema: () => SkillEntrySchema,
41
45
  SkillIdeSchema: () => SkillIdeSchema,
42
46
  SkillScopeSchema: () => SkillScopeSchema,
47
+ SkillsLockEntrySchema: () => SkillsLockEntrySchema,
48
+ SkillsLockSchema: () => SkillsLockSchema,
43
49
  SkillsPackageManifestSchema: () => SkillsPackageManifestSchema,
44
50
  TailwindVersionSchema: () => TailwindVersionSchema,
45
51
  UiAliasSchema: () => UiAliasSchema,
@@ -50,11 +56,19 @@ __export(index_exports, {
50
56
  UiPackageManifestSchema: () => UiPackageManifestSchema,
51
57
  UpdateStrategySchema: () => UpdateStrategySchema,
52
58
  VariantManifestSchema: () => VariantManifestSchema,
59
+ VariantUiPackageCatalogSchema: () => VariantUiPackageCatalogSchema,
60
+ VariantUiPackageManifestSchema: () => VariantUiPackageManifestSchema,
61
+ VariantUiPackageNameSchema: () => VariantUiPackageNameSchema,
53
62
  getUpdateAction: () => getUpdateAction,
54
63
  hasManagedRegion: () => hasManagedRegion,
64
+ loadDesignPack: () => loadDesignPack,
65
+ loadDesignPackageManifest: () => loadDesignPackageManifest,
55
66
  loadSkillsPackageManifest: () => loadSkillsPackageManifest,
56
67
  loadUiPackageManifest: () => loadUiPackageManifest,
57
68
  loadVariantManifest: () => loadVariantManifest,
69
+ loadVariantUiPackageCatalog: () => loadVariantUiPackageCatalog,
70
+ loadVariantUiPackageManifest: () => loadVariantUiPackageManifest,
71
+ mergeDefaultAndVariant: () => mergeDefaultAndVariant,
58
72
  parseManagedRegions: () => parseManagedRegions,
59
73
  replaceManagedRegion: () => replaceManagedRegion,
60
74
  resolveUiEntryOrder: () => resolveUiEntryOrder,
@@ -62,9 +76,11 @@ __export(index_exports, {
62
76
  validateConfig: () => validateConfig,
63
77
  validateInstalled: () => validateInstalled,
64
78
  validateManifest: () => validateManifest,
79
+ validateSkillsLock: () => validateSkillsLock,
65
80
  validateSkillsPackage: () => validateSkillsPackage,
66
81
  validateUiDependencyGraph: () => validateUiDependencyGraph,
67
- validateUiPackage: () => validateUiPackage
82
+ validateUiPackage: () => validateUiPackage,
83
+ walkPackTree: () => walkPackTree
68
84
  });
69
85
  module.exports = __toCommonJS(index_exports);
70
86
 
@@ -152,7 +168,20 @@ var SkillEntrySchema = import_zod.z.object({
152
168
  /** Managed region IDs to maintain on update */
153
169
  managedRegions: import_zod.z.array(import_zod.z.string()).optional(),
154
170
  /** Whether the source is a Handlebars template */
155
- template: import_zod.z.boolean().optional()
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()
156
185
  });
157
186
  var SkillsPackageManifestSchema = import_zod.z.object({
158
187
  $schema: import_zod.z.string().optional(),
@@ -172,9 +201,17 @@ var UiEntryTypeSchema = import_zod.z.enum([
172
201
  "component",
173
202
  "hook",
174
203
  "util",
175
- "block"
204
+ "block",
205
+ "template"
206
+ ]);
207
+ var UiAliasSchema = import_zod.z.enum([
208
+ "components",
209
+ "hooks",
210
+ "utils",
211
+ "lib",
212
+ "business",
213
+ "templates"
176
214
  ]);
177
- var UiAliasSchema = import_zod.z.enum(["components", "hooks", "utils", "lib"]);
178
215
  var UiEntryStatusSchema = import_zod.z.enum([
179
216
  "stable",
180
217
  "experimental",
@@ -237,7 +274,14 @@ var UiEntrySchema = import_zod.z.object({
237
274
  * If this entry is `deprecated`, the id of the entry that supersedes it.
238
275
  * Consumers (and AI) should migrate to `replacedBy` rather than this entry.
239
276
  */
240
- replacedBy: import_zod.z.string().optional()
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()
241
285
  });
242
286
  var UiPackageManifestSchema = import_zod.z.object({
243
287
  $schema: import_zod.z.string().optional(),
@@ -254,24 +298,148 @@ var UiPackageManifestSchema = import_zod.z.object({
254
298
  entries: import_zod.z.array(UiEntrySchema)
255
299
  });
256
300
 
257
- // src/schema/config.ts
301
+ // src/schema/design-pack.ts
258
302
  var import_zod2 = require("zod");
259
- var TailwindVersionSchema = import_zod2.z.enum(["v3", "v4"]);
260
- var UiAliasesSchema = import_zod2.z.object({
261
- components: import_zod2.z.string().min(1),
262
- hooks: import_zod2.z.string().min(1),
263
- utils: import_zod2.z.string().min(1),
264
- lib: import_zod2.z.string().min(1)
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()
308
+ });
309
+ var DesignPackManifestSchema = import_zod2.z.object({
310
+ $schema: import_zod2.z.string().optional(),
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")
265
433
  });
266
- var PackageEntrySchema = import_zod2.z.object({
434
+ var PackageEntrySchema = import_zod4.z.object({
267
435
  /** Variant identifier (e.g. "opentrek"; use "_flat" for skills/ui) */
268
- variant: import_zod2.z.string().min(1),
436
+ variant: import_zod4.z.string().min(1),
269
437
  /** Semver version string */
270
- version: import_zod2.z.string().min(1),
438
+ version: import_zod4.z.string().min(1),
271
439
  /** Tailwind CSS version this project uses (only meaningful for design package). */
272
440
  tailwind: TailwindVersionSchema.optional(),
273
441
  /** IDEs this package was installed for (only meaningful for skills package). */
274
- ides: import_zod2.z.array(SkillIdeSchema).optional(),
442
+ ides: import_zod4.z.array(SkillIdeSchema).optional(),
275
443
  /** Install scope (only meaningful for skills package). */
276
444
  scope: SkillScopeSchema.optional(),
277
445
  /** Path aliases for ui entry installation (only meaningful for ui package). */
@@ -280,53 +448,79 @@ var PackageEntrySchema = import_zod2.z.object({
280
448
  * Default icon library declared by the project (only meaningful for ui).
281
449
  * Declarative only — does NOT trigger code rewrites; ui entries hardcode imports.
282
450
  */
283
- iconLibrary: import_zod2.z.string().min(1).optional(),
451
+ iconLibrary: import_zod4.z.string().min(1).optional(),
284
452
  /** Whether the project uses TSX (true) or JSX (false). ui-specific. */
285
- tsx: import_zod2.z.boolean().optional(),
453
+ tsx: import_zod4.z.boolean().optional(),
286
454
  /** Whether to emit React Server Components markers (`"use client"`). ui-specific. */
287
- rsc: import_zod2.z.boolean().optional()
455
+ rsc: import_zod4.z.boolean().optional()
288
456
  });
289
- var ProjectConfigSchema = import_zod2.z.object({
290
- $schema: import_zod2.z.string().optional(),
291
- schemaVersion: import_zod2.z.literal(1),
457
+ var ProjectConfigSchema = import_zod4.z.object({
458
+ $schema: import_zod4.z.string().optional(),
459
+ schemaVersion: import_zod4.z.literal(1),
292
460
  /** IDE identifier */
293
- ide: import_zod2.z.string().min(1),
461
+ ide: import_zod4.z.string().min(1),
294
462
  /** Installed packages keyed by package name */
295
- packages: import_zod2.z.record(import_zod2.z.string(), PackageEntrySchema)
463
+ packages: import_zod4.z.record(import_zod4.z.string(), PackageEntrySchema)
296
464
  });
297
465
 
298
466
  // src/schema/installed.ts
299
- var import_zod3 = require("zod");
300
- var InstalledResourceSchema = import_zod3.z.object({
467
+ var import_zod5 = require("zod");
468
+ var InstalledResourceSchema = import_zod5.z.object({
301
469
  /** Resource identifier matching the variant manifest */
302
- id: import_zod3.z.string().min(1),
470
+ id: import_zod5.z.string().min(1),
303
471
  /** Target path where the resource was installed (absolute or project-relative) */
304
- target: import_zod3.z.string().min(1),
472
+ target: import_zod5.z.string().min(1),
305
473
  /** Content hash for change detection (e.g. "sha256:...") */
306
- hash: import_zod3.z.string().min(1),
474
+ hash: import_zod5.z.string().min(1),
307
475
  /** Update strategy that was applied */
308
- strategy: import_zod3.z.enum(["frozen", "regenerable", "managed"]),
476
+ strategy: import_zod5.z.enum(["frozen", "regenerable", "managed"]),
309
477
  /** IDE this resource was installed for (skill resources only) */
310
478
  ide: SkillIdeSchema.optional(),
311
479
  /** Install scope (skill resources only) */
312
480
  scope: SkillScopeSchema.optional()
313
481
  });
314
- var InstalledPackageSchema = import_zod3.z.object({
482
+ var InstalledPackageSchema = import_zod5.z.object({
315
483
  /** Full package name (e.g. "@teamix-evo/design") */
316
- package: import_zod3.z.string().min(1),
484
+ package: import_zod5.z.string().min(1),
317
485
  /** Variant identifier (use "_flat" for non-variant packages such as skills) */
318
- variant: import_zod3.z.string().min(1),
486
+ variant: import_zod5.z.string().min(1),
319
487
  /** Installed version */
320
- version: import_zod3.z.string().min(1),
488
+ version: import_zod5.z.string().min(1),
321
489
  /** ISO 8601 timestamp of installation */
322
- installedAt: import_zod3.z.string().min(1),
490
+ installedAt: import_zod5.z.string().min(1),
323
491
  /** List of installed resources */
324
- resources: import_zod3.z.array(InstalledResourceSchema)
492
+ resources: import_zod5.z.array(InstalledResourceSchema)
325
493
  });
326
- var InstalledManifestSchema = import_zod3.z.object({
327
- schemaVersion: import_zod3.z.literal(1),
494
+ var InstalledManifestSchema = import_zod5.z.object({
495
+ schemaVersion: import_zod5.z.literal(1),
328
496
  /** List of installed packages */
329
- installed: import_zod3.z.array(InstalledPackageSchema)
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)
330
524
  });
331
525
 
332
526
  // src/loader.ts
@@ -336,8 +530,8 @@ var path = __toESM(require("path"), 1);
336
530
  // src/validator.ts
337
531
  function formatZodError(error) {
338
532
  return error.issues.map((issue) => {
339
- const path2 = issue.path.length > 0 ? issue.path.join(".") : "(root)";
340
- return ` - ${path2}: ${issue.message}`;
533
+ const path4 = issue.path.length > 0 ? issue.path.join(".") : "(root)";
534
+ return ` - ${path4}: ${issue.message}`;
341
535
  }).join("\n");
342
536
  }
343
537
  function validateManifest(data) {
@@ -373,6 +567,17 @@ function validateInstalled(data) {
373
567
  ${formatZodError(result.error)}`
374
568
  };
375
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
+ }
376
581
  function validateSkillsPackage(data) {
377
582
  const result = SkillsPackageManifestSchema.safeParse(data);
378
583
  if (result.success) {
@@ -429,22 +634,22 @@ function validateUiDependencyGraph(entries) {
429
634
  const color = /* @__PURE__ */ new Map();
430
635
  for (const id of idToEntry.keys()) color.set(id, WHITE);
431
636
  const cycles = [];
432
- function dfs(id, path2) {
637
+ function dfs(id, path4) {
433
638
  color.set(id, GRAY);
434
- path2.push(id);
639
+ path4.push(id);
435
640
  const entry = idToEntry.get(id);
436
641
  const deps = entry?.registryDependencies ?? [];
437
642
  for (const dep of deps) {
438
643
  if (!idToEntry.has(dep)) continue;
439
644
  const c = color.get(dep);
440
645
  if (c === GRAY) {
441
- const startIdx = path2.indexOf(dep);
442
- cycles.push([...path2.slice(startIdx), dep]);
646
+ const startIdx = path4.indexOf(dep);
647
+ cycles.push([...path4.slice(startIdx), dep]);
443
648
  } else if (c === WHITE) {
444
- dfs(dep, path2);
649
+ dfs(dep, path4);
445
650
  }
446
651
  }
447
- path2.pop();
652
+ path4.pop();
448
653
  color.set(id, BLACK);
449
654
  }
450
655
  for (const id of idToEntry.keys()) {
@@ -566,6 +771,200 @@ async function loadUiPackageManifest(packageDir) {
566
771
  return result.data;
567
772
  }
568
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
+ }
967
+
569
968
  // src/managed-regions.ts
570
969
  var REGION_PATTERN = /<!-- teamix-evo:managed:start id="([^"]+)" -->([\s\S]*?)<!-- teamix-evo:managed:end id="\1" -->/g;
571
970
  var START_MARKER_PATTERN = /<!-- teamix-evo:managed:start id="([^"]+)" -->/g;
@@ -688,6 +1087,10 @@ function getUpdateAction(strategy, options) {
688
1087
  }
689
1088
  // Annotate the CommonJS export names for ESM import in node:
690
1089
  0 && (module.exports = {
1090
+ DesignPackLinkedSchema,
1091
+ DesignPackLockSchema,
1092
+ DesignPackManifestSchema,
1093
+ DesignPackageManifestSchema,
691
1094
  InstalledManifestSchema,
692
1095
  InstalledPackageSchema,
693
1096
  InstalledResourceSchema,
@@ -698,6 +1101,8 @@ function getUpdateAction(strategy, options) {
698
1101
  SkillEntrySchema,
699
1102
  SkillIdeSchema,
700
1103
  SkillScopeSchema,
1104
+ SkillsLockEntrySchema,
1105
+ SkillsLockSchema,
701
1106
  SkillsPackageManifestSchema,
702
1107
  TailwindVersionSchema,
703
1108
  UiAliasSchema,
@@ -708,11 +1113,19 @@ function getUpdateAction(strategy, options) {
708
1113
  UiPackageManifestSchema,
709
1114
  UpdateStrategySchema,
710
1115
  VariantManifestSchema,
1116
+ VariantUiPackageCatalogSchema,
1117
+ VariantUiPackageManifestSchema,
1118
+ VariantUiPackageNameSchema,
711
1119
  getUpdateAction,
712
1120
  hasManagedRegion,
1121
+ loadDesignPack,
1122
+ loadDesignPackageManifest,
713
1123
  loadSkillsPackageManifest,
714
1124
  loadUiPackageManifest,
715
1125
  loadVariantManifest,
1126
+ loadVariantUiPackageCatalog,
1127
+ loadVariantUiPackageManifest,
1128
+ mergeDefaultAndVariant,
716
1129
  parseManagedRegions,
717
1130
  replaceManagedRegion,
718
1131
  resolveUiEntryOrder,
@@ -720,8 +1133,10 @@ function getUpdateAction(strategy, options) {
720
1133
  validateConfig,
721
1134
  validateInstalled,
722
1135
  validateManifest,
1136
+ validateSkillsLock,
723
1137
  validateSkillsPackage,
724
1138
  validateUiDependencyGraph,
725
- validateUiPackage
1139
+ validateUiPackage,
1140
+ walkPackTree
726
1141
  });
727
1142
  //# sourceMappingURL=index.cjs.map