@dalexto/lexsys-cli 0.0.3 → 0.0.5

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 CHANGED
@@ -5,6 +5,7 @@
5
5
  **Source of truth for:** Package role, command surface, core module boundaries
6
6
  **Full CLI reference:** [docs/reference/cli/CLI.md](../../docs/reference/cli/CLI.md)
7
7
  **Verified against:** `packages/cli/src/`
8
+ **Last reviewed:** 2026-05-30
8
9
 
9
10
  ---
10
11
 
@@ -50,8 +51,9 @@ Installed via `npm install -g lexsys` or run directly with `pnpm exec lexsys`.
50
51
  | `lexsys init next [directory]` | Scaffold a new Next.js App Router consumer (pinned Next.js 15.3.3) |
51
52
  | `lexsys add <component>` | Install one or more components into the consumer project |
52
53
  | `lexsys update [component]` | Update installed components; `--sync`, `--utilities`, `--styles`, `--force` |
54
+ | `lexsys reset [component]` | Restore components from registry templates (backup + overwrite) |
53
55
  | `lexsys list` | List available registry components |
54
- | `lexsys status` | Show installed component versions vs registry versions |
56
+ | `lexsys status` | Show installed components and template drift vs registry |
55
57
  | `lexsys doctor` | Check project health and config validity |
56
58
  | `lexsys config` | Read or modify `lexsys.config.json` |
57
59
  | `lexsys registry` | Inspect the active registry source |
@@ -69,20 +71,11 @@ Installed via `npm install -g lexsys` or run directly with `pnpm exec lexsys`.
69
71
 
70
72
  ---
71
73
 
72
- ## Core Modules
73
-
74
- | Module | Role |
75
- | --------------------------- | --------------------------------------------------------------------------- |
76
- | `core/config.ts` | Read/write `lexsys.config.json`; defines `LexsysConfig` schema and defaults |
77
- | `core/installer.ts` | File copy, conflict detection, idempotent installs |
78
- | `core/registry-provider.ts` | Selects local vs remote registry source |
79
- | `core/registry-resolver.ts` | Resolves registry items, utilities, and styles from active registry |
80
- | `core/tailwind-setup.ts` | Detects and wires Tailwind v4 CSS entrypoint |
81
- | `core/vite-scaffold.ts` | Detects and patches Vite config for Tailwind plugin |
82
- | `core/package-manager.ts` | Detects npm/pnpm/yarn and runs installs |
83
- | `core/context.ts` | Process-level `cwd` override via `--cwd` flag |
84
- | `core/flags.ts` | Shared flag parsing utilities |
85
- | `core/cli-error.ts` | Typed CLI error class and top-level error handler |
74
+ ## Source layout
75
+
76
+ Domain modules under `packages/cli/src/`: `config/`, `install/`, `registry/`,
77
+ `commands/`, `scaffold/`, `utils/`. Command behavior and config schema:
78
+ [docs/reference/cli/CLI.md](../../docs/reference/cli/CLI.md).
86
79
 
87
80
  ---
88
81
 
@@ -0,0 +1 @@
1
+ export declare const runReset: (args: string[]) => Promise<void>;
@@ -15,7 +15,7 @@ export interface LexsysConfig {
15
15
  paths: LexsysPathsConfig;
16
16
  aliases: LexsysAliasesConfig;
17
17
  tailwind: LexsysTailwindConfig;
18
- installed?: Record<string, string>;
18
+ installed?: string[];
19
19
  registryUrl?: string | null;
20
20
  }
21
21
  export interface LexsysTailwindConfig {
@@ -0,0 +1,6 @@
1
+ export declare const isLegacyInstalledRecord: (value: unknown) => boolean;
2
+ export declare const normalizeInstalled: (value: unknown) => string[];
3
+ export declare const isInstalled: (installed: string[], name: string) => boolean;
4
+ export declare const addInstalled: (installed: string[], itemName: string) => string[];
5
+ export declare const removeInstalled: (installed: string[], itemName: string) => string[];
6
+ export declare const findInstalledKey: (installed: string[], name: string) => string | undefined;
package/dist/index.js CHANGED
@@ -37,6 +37,38 @@ var handleCliError = (error) => {
37
37
  }
38
38
  process.exit(1);
39
39
  };
40
+
41
+ // src/config/installed.ts
42
+ var isLegacyInstalledRecord = (value) => {
43
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
44
+ };
45
+ var normalizeInstalled = (value) => {
46
+ if (Array.isArray(value)) {
47
+ return value.filter((entry) => typeof entry === "string");
48
+ }
49
+ if (value && typeof value === "object" && !Array.isArray(value)) {
50
+ return Object.keys(value);
51
+ }
52
+ return [];
53
+ };
54
+ var isInstalled = (installed, name) => {
55
+ const normalized = name.toLowerCase();
56
+ return installed.some((entry) => entry.toLowerCase() === normalized);
57
+ };
58
+ var addInstalled = (installed, itemName) => {
59
+ if (isInstalled(installed, itemName)) {
60
+ return installed;
61
+ }
62
+ return [...installed, itemName];
63
+ };
64
+ var removeInstalled = (installed, itemName) => {
65
+ const normalized = itemName.toLowerCase();
66
+ return installed.filter((entry) => entry.toLowerCase() !== normalized);
67
+ };
68
+ var findInstalledKey = (installed, name) => {
69
+ const normalized = name.toLowerCase();
70
+ return installed.find((entry) => entry.toLowerCase() === normalized);
71
+ };
40
72
  var hashContent = (content) => {
41
73
  return createHash("sha256").update(content, "utf-8").digest("hex");
42
74
  };
@@ -98,7 +130,7 @@ var defaultConfig = {
98
130
  paths: defaultPathsConfig,
99
131
  aliases: defaultAliasesConfig,
100
132
  tailwind: defaultTailwindConfig,
101
- installed: {},
133
+ installed: [],
102
134
  registryUrl: null
103
135
  };
104
136
  var getConfigPath = () => {
@@ -111,7 +143,7 @@ var loadConfig = async () => {
111
143
  }
112
144
  const content = await readFile(configPath, "utf-8");
113
145
  const parsed = JSON.parse(content);
114
- return {
146
+ const config = {
115
147
  ...defaultConfig,
116
148
  ...parsed,
117
149
  paths: {
@@ -125,23 +157,43 @@ var loadConfig = async () => {
125
157
  tailwind: {
126
158
  ...defaultTailwindConfig,
127
159
  ...parsed.tailwind
128
- }
160
+ },
161
+ installed: normalizeInstalled(parsed.installed)
129
162
  };
163
+ if (isLegacyInstalledRecord(parsed.installed)) {
164
+ await saveConfig(config);
165
+ }
166
+ return config;
130
167
  };
131
168
  var saveConfig = async (config) => {
132
169
  const configPath = getConfigPath();
133
170
  await writeFile(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
134
171
  };
135
- var crossLayerImportPatterns = [
172
+ var monorepoCrossLayerPatterns = [
136
173
  /\.\.\/\.\.\/primitives\//g,
137
174
  /\.\.\/\.\.\/blocks\//g,
138
175
  /\.\.\/\.\.\/templates\//g
139
176
  ];
177
+ var registryTemplateLayers = ["primitives", "blocks", "templates"];
178
+ var toFlatSiblingImportPath = (importPath) => {
179
+ const segments = importPath.split("/").filter(Boolean);
180
+ if (segments.length >= 2) {
181
+ return `../${segments.join("/")}`;
182
+ }
183
+ const name = segments[0] ?? importPath;
184
+ return `../${name}/${name}`;
185
+ };
140
186
  var rewriteCrossLayerImports = (content) => {
141
187
  let rewritten = content;
142
- for (const pattern of crossLayerImportPatterns) {
188
+ for (const pattern of monorepoCrossLayerPatterns) {
143
189
  rewritten = rewritten.replace(pattern, "../");
144
190
  }
191
+ for (const layer of registryTemplateLayers) {
192
+ const pattern = new RegExp(`from "@/components/${layer}/([^"]+)"`, "g");
193
+ rewritten = rewritten.replace(pattern, (_, importPath) => {
194
+ return `from "${toFlatSiblingImportPath(importPath)}"`;
195
+ });
196
+ }
145
197
  return rewritten;
146
198
  };
147
199
  var prepareInstalledFileContent = (content, item) => {
@@ -738,7 +790,7 @@ var isRegistryItem = (value) => {
738
790
  return false;
739
791
  }
740
792
  const item = value;
741
- return typeof item.name === "string" && typeof item.canonicalName === "string" && typeof item.version === "string" && typeof item.type === "string" && typeof item.category === "string" && Array.isArray(item.aliases) && isStringArray(item.files) && isStringArray(item.dependencies) && isStringArray(item.registryDependencies) && isStringArray(item.utilities) && isStringArray(item.styles) && typeof item.target === "string";
793
+ return typeof item.name === "string" && typeof item.canonicalName === "string" && typeof item.type === "string" && typeof item.category === "string" && Array.isArray(item.aliases) && isStringArray(item.files) && isStringArray(item.dependencies) && isStringArray(item.registryDependencies) && isStringArray(item.utilities) && isStringArray(item.styles) && typeof item.target === "string";
742
794
  };
743
795
  var findInvalidRegistryItemIndex = (items) => {
744
796
  return items.findIndex((item) => {
@@ -1106,7 +1158,7 @@ var runAdd = async (args2) => {
1106
1158
  console.log("Dry run: no files or dependencies will be changed.\n");
1107
1159
  console.log("Components:");
1108
1160
  for (const item of resolvedItems) {
1109
- console.log(`- ${item.canonicalName} v${item.version}`);
1161
+ console.log(`- ${item.canonicalName}`);
1110
1162
  }
1111
1163
  console.log("\nDependencies:");
1112
1164
  for (const dependency of dependencies) {
@@ -1145,11 +1197,9 @@ var runAdd = async (args2) => {
1145
1197
  }
1146
1198
  console.log("");
1147
1199
  }
1148
- const installed = {
1149
- ...config.installed ?? {}
1150
- };
1200
+ let installed = [...config.installed ?? []];
1151
1201
  for (const item of successfullyInstalled) {
1152
- installed[item.name] = item.version;
1202
+ installed = addInstalled(installed, item.name);
1153
1203
  }
1154
1204
  await saveConfig({
1155
1205
  ...config,
@@ -1253,13 +1303,13 @@ var runDoctor = async (options = {}) => {
1253
1303
  if (registryFailed && options.noFallback) {
1254
1304
  return;
1255
1305
  }
1256
- const installed = config.installed ?? {};
1257
- if (Object.keys(installed).length) {
1306
+ const installed = config.installed ?? [];
1307
+ if (installed.length) {
1258
1308
  console.log("\nTracked components:");
1259
- for (const [name, version] of Object.entries(installed)) {
1309
+ for (const name of installed) {
1260
1310
  const item = await findItem(name);
1261
1311
  if (!item) {
1262
- console.log(`\xD7 ${name} v${version} (missing from registry)`);
1312
+ console.log(`\xD7 ${name} (missing from registry)`);
1263
1313
  continue;
1264
1314
  }
1265
1315
  const componentPath = join(
@@ -1268,9 +1318,7 @@ var runDoctor = async (options = {}) => {
1268
1318
  );
1269
1319
  const exists = await fileExists(componentPath);
1270
1320
  const layer = getInstallLayer(item) ?? "unknown";
1271
- console.log(
1272
- `${exists ? "\u2713" : "\xD7"} ${item.canonicalName} v${version} (${layer})`
1273
- );
1321
+ console.log(`${exists ? "\u2713" : "\xD7"} ${item.canonicalName} (${layer})`);
1274
1322
  }
1275
1323
  }
1276
1324
  };
@@ -1324,7 +1372,7 @@ Options
1324
1372
  --all, -a Update all tracked components
1325
1373
  --styles, -S Update generated token/theme CSS files
1326
1374
  --utilities, -u Update shared utility files
1327
- --sync Refresh tracked components even when versions match
1375
+ --sync Refresh tracked components even when templates already match
1328
1376
  --dry-run, -d Preview update without writing files
1329
1377
  --force, -f Write conflicted updates after creating backups
1330
1378
  --yes, -y Auto-confirm safe prompts
@@ -1363,6 +1411,24 @@ Usage
1363
1411
  Options
1364
1412
  --no-fallback Fail instead of falling back to local registry
1365
1413
  --help, -h Show this help
1414
+ `,
1415
+ reset: `
1416
+ Usage
1417
+ lexsys reset [component...]
1418
+
1419
+ Options
1420
+ --dry-run, -d Preview reset without writing files
1421
+ --with-deps, -w Also reset installed registry dependencies in the closure
1422
+ --no-fallback Fail instead of falling back to local registry
1423
+ --cwd, -C <path> Run from a different project directory
1424
+ --help, -h Show this help
1425
+
1426
+ Run without arguments for guided reset picker.
1427
+
1428
+ Examples
1429
+ lexsys reset button
1430
+ lexsys reset sidebar --with-deps
1431
+ lexsys reset button --dry-run
1366
1432
  `,
1367
1433
  uninstall: `
1368
1434
  Usage
@@ -1445,6 +1511,7 @@ Scaffold
1445
1511
  Components
1446
1512
  add <component...> Install components into your project [alias: a]
1447
1513
  update [component...] Update installed components [alias: up]
1514
+ reset [component...] Restore components from registry templates
1448
1515
  uninstall [component...] Remove installed components [alias: rm]
1449
1516
 
1450
1517
  Inspect
@@ -2387,7 +2454,6 @@ var runList = async (options = {}) => {
2387
2454
  const simplified = registryItems3.map((item) => ({
2388
2455
  name: item.name,
2389
2456
  canonicalName: item.canonicalName,
2390
- version: item.version,
2391
2457
  category: item.category,
2392
2458
  layer: getInstallLayer(item)
2393
2459
  }));
@@ -2409,9 +2475,7 @@ var runList = async (options = {}) => {
2409
2475
  }
2410
2476
  console.log(`${layerLabels[layer] ?? layer}:`);
2411
2477
  for (const item of items) {
2412
- console.log(
2413
- `- ${item.canonicalName} v${item.version} (${item.category})`
2414
- );
2478
+ console.log(`- ${item.canonicalName} (${item.category})`);
2415
2479
  }
2416
2480
  console.log("");
2417
2481
  }
@@ -2435,7 +2499,7 @@ var printRegistrySummary = (result) => {
2435
2499
  for (const item of result.items) {
2436
2500
  const remoteFileCount = item.remoteFiles?.length ?? 0;
2437
2501
  console.log(
2438
- `- ${item.canonicalName} v${item.version} (${item.type}/${item.category}, remote files: ${remoteFileCount})`
2502
+ `- ${item.canonicalName} (${item.type}/${item.category}, remote files: ${remoteFileCount})`
2439
2503
  );
2440
2504
  }
2441
2505
  };
@@ -2521,12 +2585,43 @@ var runRegistry = async (options = {}) => {
2521
2585
  process.exitCode = 1;
2522
2586
  }
2523
2587
  };
2588
+ var getComponentDriftStatus = async (name) => {
2589
+ const item = await findItem(name);
2590
+ if (!item) {
2591
+ return "missing";
2592
+ }
2593
+ const hasDrift = await itemHasTemplateDrift(item);
2594
+ return hasDrift ? "drift" : "in-sync";
2595
+ };
2596
+ var itemHasTemplateDrift = async (item) => {
2597
+ const config = await loadConfig();
2598
+ const installTarget = resolveItemInstallTarget(config, item);
2599
+ for (const file of item.files) {
2600
+ const fileName = file.split("/").at(-1);
2601
+ if (!fileName) {
2602
+ return true;
2603
+ }
2604
+ const targetPath = join(getCwd(), installTarget, fileName);
2605
+ if (!await fileExists(targetPath)) {
2606
+ return true;
2607
+ }
2608
+ const preparedContent = prepareInstalledFileContent(
2609
+ await readFile(getRegistryTemplatePath(file), "utf-8"),
2610
+ item
2611
+ );
2612
+ const targetContent = await readFile(targetPath, "utf-8");
2613
+ if (!hashesAreEqual(preparedContent, targetContent)) {
2614
+ return true;
2615
+ }
2616
+ }
2617
+ return false;
2618
+ };
2524
2619
 
2525
2620
  // src/commands/status.ts
2526
2621
  var runStatus = async (options = {}) => {
2527
2622
  const config = await loadConfig();
2528
- const installed = config.installed ?? {};
2529
- if (!Object.keys(installed).length) {
2623
+ const installed = config.installed ?? [];
2624
+ if (!installed.length) {
2530
2625
  console.log("No Lexsys components are currently tracked.");
2531
2626
  return;
2532
2627
  }
@@ -2541,14 +2636,15 @@ var runStatus = async (options = {}) => {
2541
2636
  return;
2542
2637
  }
2543
2638
  console.log("Installed Lexsys components:\n");
2544
- for (const [name, installedVersion] of Object.entries(installed)) {
2639
+ for (const name of installed) {
2545
2640
  const item = await findItem(name);
2546
2641
  if (!item) {
2547
- console.log(`- ${name} v${installedVersion} (missing from registry)`);
2642
+ console.log(`- ${name} (missing from registry)`);
2548
2643
  continue;
2549
2644
  }
2550
- const status = item.version === installedVersion ? "up to date" : `update available: v${installedVersion} \u2192 v${item.version}`;
2551
- console.log(`- ${item.canonicalName} v${installedVersion} (${status})`);
2645
+ const driftStatus = await getComponentDriftStatus(name);
2646
+ const status = driftStatus === "drift" ? "out of sync with registry" : "up to date with registry";
2647
+ console.log(`- ${item.canonicalName} (${status})`);
2552
2648
  }
2553
2649
  };
2554
2650
 
@@ -2573,7 +2669,7 @@ var computeRegistryClosure = (rootNames, items) => {
2573
2669
  return closure;
2574
2670
  };
2575
2671
  var findOrphanInstalledItems = (removedTargetNames, remainingInstalled, items) => {
2576
- const remainingNames = Object.keys(remainingInstalled);
2672
+ const remainingNames = remainingInstalled;
2577
2673
  const removedDependencyNames = /* @__PURE__ */ new Set();
2578
2674
  for (const removedName of removedTargetNames) {
2579
2675
  const closure = computeRegistryClosure([removedName], items);
@@ -2592,17 +2688,263 @@ var findOrphanInstalledItems = (removedTargetNames, remainingInstalled, items) =
2592
2688
  )
2593
2689
  ).filter((item) => Boolean(item)).filter((item) => removedDependencyNames.has(item.name));
2594
2690
  };
2691
+ var checkItemFiles = async (name) => {
2692
+ const item = await findItem(name);
2693
+ const config = await loadConfig();
2694
+ if (!item) {
2695
+ console.log(`Component "${name}" no longer exists in the registry.`);
2696
+ return;
2697
+ }
2698
+ const installTarget = resolveItemInstallTarget(config, item);
2699
+ console.log(`File check for ${item.canonicalName}:`);
2700
+ for (const file of item.files) {
2701
+ const fileName = file.split("/").at(-1);
2702
+ if (!fileName) {
2703
+ console.log(`- invalid registry file path: ${file}`);
2704
+ continue;
2705
+ }
2706
+ const targetPath = join(getCwd(), installTarget, fileName);
2707
+ if (!await fileExists(targetPath)) {
2708
+ console.log(`- missing: ${targetPath}`);
2709
+ continue;
2710
+ }
2711
+ const preparedContent = prepareInstalledFileContent(
2712
+ await readFile(getRegistryTemplatePath(file), "utf-8"),
2713
+ item
2714
+ );
2715
+ const targetContent = await readFile(targetPath, "utf-8");
2716
+ if (hashesAreEqual(preparedContent, targetContent)) {
2717
+ console.log(`- identical: ${targetPath}`);
2718
+ continue;
2719
+ }
2720
+ console.log(`- conflict: ${targetPath}`);
2721
+ }
2722
+ };
2723
+ var applyItemOverwrite = async (name, force) => {
2724
+ const item = await findItem(name);
2725
+ const config = await loadConfig();
2726
+ if (!item) {
2727
+ console.log(`Component "${name}" no longer exists in the registry.`);
2728
+ return false;
2729
+ }
2730
+ const installTarget = resolveItemInstallTarget(config, item);
2731
+ let hasConflict = false;
2732
+ console.log(`Applying update for ${item.canonicalName}:`);
2733
+ for (const file of item.files) {
2734
+ const sourcePath = getRegistryTemplatePath(file);
2735
+ const fileName = file.split("/").at(-1);
2736
+ if (!fileName) {
2737
+ console.log(`- invalid registry file path: ${file}`);
2738
+ hasConflict = true;
2739
+ continue;
2740
+ }
2741
+ const targetPath = join(getCwd(), installTarget, fileName);
2742
+ const preparedContent = prepareInstalledFileContent(
2743
+ await readFile(sourcePath, "utf-8"),
2744
+ item
2745
+ );
2746
+ await mkdir(dirname(targetPath), { recursive: true });
2747
+ if (!await fileExists(targetPath)) {
2748
+ await writeFile(targetPath, preparedContent, "utf-8");
2749
+ console.log(`- restored missing file: ${targetPath}`);
2750
+ continue;
2751
+ }
2752
+ const targetContent = await readFile(targetPath, "utf-8");
2753
+ if (hashesAreEqual(preparedContent, targetContent)) {
2754
+ console.log(`- identical: ${targetPath}`);
2755
+ continue;
2756
+ }
2757
+ if (force) {
2758
+ const backupPath = await createBackupFile(targetPath);
2759
+ if (backupPath) {
2760
+ console.log(`- backup created: ${backupPath}`);
2761
+ }
2762
+ await writeFile(targetPath, preparedContent, "utf-8");
2763
+ console.log(`- force updated file: ${targetPath}`);
2764
+ continue;
2765
+ }
2766
+ hasConflict = true;
2767
+ console.log(`- conflict (user modified): ${targetPath}`);
2768
+ }
2769
+ if (hasConflict) {
2770
+ console.log(
2771
+ "Update finished with conflicts. Review conflicted files before retrying."
2772
+ );
2773
+ return false;
2774
+ }
2775
+ console.log(`\u2714 ${item.canonicalName} updated successfully`);
2776
+ return true;
2777
+ };
2778
+ var checkItemUpdate = async (name, dryRun, force, sync = false) => {
2779
+ const item = await findItem(name);
2780
+ if (!item) {
2781
+ console.log(`Component "${name}" no longer exists in the registry.`);
2782
+ return false;
2783
+ }
2784
+ const driftStatus = await getComponentDriftStatus(name);
2785
+ if (driftStatus === "missing") {
2786
+ console.log(`Component "${name}" no longer exists in the registry.`);
2787
+ return false;
2788
+ }
2789
+ const hasDrift = driftStatus === "drift";
2790
+ if (!sync && !hasDrift) {
2791
+ console.log(`${item.canonicalName} is up to date with the registry.`);
2792
+ return false;
2793
+ }
2794
+ if (sync && !hasDrift) {
2795
+ console.log(
2796
+ `${item.canonicalName} template sync (already matches registry)`
2797
+ );
2798
+ } else {
2799
+ console.log(`${item.canonicalName} can be updated from registry templates`);
2800
+ }
2801
+ if (dryRun) {
2802
+ console.log("\nChanged file candidates:");
2803
+ for (const file of item.files) {
2804
+ console.log(`~ ${file}`);
2805
+ }
2806
+ console.log("\nDry run: no files will be changed.");
2807
+ console.log("Update plan:");
2808
+ if (force) {
2809
+ console.log(
2810
+ "- Force mode requested: conflicted files require backup before overwrite"
2811
+ );
2812
+ console.log(
2813
+ "- Dry run: backups would be created before forced overwrites"
2814
+ );
2815
+ }
2816
+ console.log(`- Check installed files for ${item.canonicalName}`);
2817
+ console.log("- Compare existing files with registry templates");
2818
+ console.log("- Report conflicts before writing changes");
2819
+ console.log("- Never overwrite user-modified files silently");
2820
+ await checkItemFiles(name);
2821
+ return false;
2822
+ }
2823
+ return await applyItemOverwrite(name, force);
2824
+ };
2825
+ var resetItem = async (name, dryRun) => {
2826
+ const item = await findItem(name);
2827
+ if (!item) {
2828
+ console.log(`Component "${name}" no longer exists in the registry.`);
2829
+ return false;
2830
+ }
2831
+ const hasDrift = await itemHasTemplateDrift(item);
2832
+ if (!hasDrift) {
2833
+ console.log(`${item.canonicalName} already matches registry templates.`);
2834
+ return false;
2835
+ }
2836
+ if (dryRun) {
2837
+ console.log(`Reset plan for ${item.canonicalName}:`);
2838
+ console.log("- Backups would be created before overwriting changed files");
2839
+ console.log("- Files would be restored from registry templates");
2840
+ for (const file of item.files) {
2841
+ console.log(`~ ${file}`);
2842
+ }
2843
+ console.log("\nDry run: no files will be changed.");
2844
+ await checkItemFiles(name);
2845
+ return false;
2846
+ }
2847
+ return await applyItemOverwrite(name, true);
2848
+ };
2595
2849
 
2596
- // src/commands/uninstall.ts
2597
- var normalizeInstalledKey = (name) => {
2598
- return name.toLowerCase();
2850
+ // src/commands/reset.ts
2851
+ var resolveInstalledKey = async (name, installed) => {
2852
+ const direct = findInstalledKey(installed, name);
2853
+ if (direct) {
2854
+ return direct;
2855
+ }
2856
+ const item = await findItem(name);
2857
+ if (!item) {
2858
+ return void 0;
2859
+ }
2860
+ return findInstalledKey(installed, item.name);
2861
+ };
2862
+ var runReset = async (args2) => {
2863
+ const dryRun = hasFlag(args2, "--dry-run", "-d");
2864
+ const withDeps = hasFlag(args2, "--with-deps", "-w");
2865
+ const noFallback = hasFlag(args2, "--no-fallback");
2866
+ const targetArgs = removeFlagsWithValues(
2867
+ removeFlags(args2, [
2868
+ "--dry-run",
2869
+ "-d",
2870
+ "--with-deps",
2871
+ "-w",
2872
+ "--no-fallback"
2873
+ ]),
2874
+ ["--cwd", "-C"]
2875
+ );
2876
+ const config = await loadConfig();
2877
+ const installed = [...config.installed ?? []];
2878
+ if (!installed.length) {
2879
+ console.log("No components installed.");
2880
+ return;
2881
+ }
2882
+ try {
2883
+ await getRegistryProviderResult({
2884
+ fallback: !noFallback
2885
+ });
2886
+ } catch (error) {
2887
+ console.log("Failed to resolve registry.");
2888
+ console.log(error instanceof Error ? error.message : String(error));
2889
+ process.exitCode = 1;
2890
+ return;
2891
+ }
2892
+ if (!targetArgs.length) {
2893
+ const selected = await promptMultiselect(
2894
+ "Select components to reset",
2895
+ installed.map((name) => ({ title: name, value: name })),
2896
+ { min: 1 }
2897
+ );
2898
+ if (!selected.length) return;
2899
+ targetArgs.push(...selected);
2900
+ }
2901
+ const resetNames = /* @__PURE__ */ new Set();
2902
+ for (const name of targetArgs) {
2903
+ const installedKey = await resolveInstalledKey(name, installed);
2904
+ if (!installedKey) {
2905
+ console.log(`Component "${name}" is not tracked as installed.`);
2906
+ continue;
2907
+ }
2908
+ resetNames.add(installedKey);
2909
+ }
2910
+ if (!resetNames.size) {
2911
+ console.log("No installed components matched the request.");
2912
+ return;
2913
+ }
2914
+ if (withDeps) {
2915
+ const allItems = await getRegistryItems({ fallback: !noFallback });
2916
+ for (const rootName of [...resetNames]) {
2917
+ const closure = computeRegistryClosure([rootName], allItems);
2918
+ for (const dependencyName of closure) {
2919
+ if (isInstalled(installed, dependencyName)) {
2920
+ resetNames.add(dependencyName);
2921
+ }
2922
+ }
2923
+ }
2924
+ }
2925
+ const resetItems = await resolveRegistryItems([...resetNames], {
2926
+ fallback: !noFallback
2927
+ });
2928
+ if (dryRun) {
2929
+ console.log("Dry run: no files will be changed.\n");
2930
+ console.log("Components:");
2931
+ for (const item of resetItems) {
2932
+ console.log(`- ${item.canonicalName}`);
2933
+ }
2934
+ console.log("");
2935
+ }
2936
+ for (const item of resetItems) {
2937
+ await resetItem(item.name, dryRun);
2938
+ console.log("");
2939
+ }
2599
2940
  };
2941
+
2942
+ // src/commands/uninstall.ts
2600
2943
  var resolveInstalledItems = async (installed) => {
2601
- const names = Object.keys(installed);
2602
- if (!names.length) {
2944
+ if (!installed.length) {
2603
2945
  return [];
2604
2946
  }
2605
- return resolveRegistryItems(names);
2947
+ return resolveRegistryItems(installed);
2606
2948
  };
2607
2949
  var collectOrphanedSharedResources = (removedItems, remainingItems) => {
2608
2950
  const removedUtilities = collectUtilities(removedItems);
@@ -2618,14 +2960,6 @@ var collectOrphanedSharedResources = (removedItems, remainingItems) => {
2618
2960
  })
2619
2961
  };
2620
2962
  };
2621
- var removeInstalledKey = (installed, itemName) => {
2622
- const installedKey = Object.keys(installed).find((key) => {
2623
- return normalizeInstalledKey(key) === normalizeInstalledKey(itemName);
2624
- });
2625
- if (installedKey) {
2626
- delete installed[installedKey];
2627
- }
2628
- };
2629
2963
  var runUninstall = async (args2) => {
2630
2964
  const dryRun = hasFlag(args2, "--dry-run", "-d");
2631
2965
  const withDeps = hasFlag(args2, "--with-deps", "-w");
@@ -2642,7 +2976,7 @@ var runUninstall = async (args2) => {
2642
2976
  );
2643
2977
  if (!targetArgs.length) {
2644
2978
  const preConfig = await loadConfig();
2645
- const installedNames = Object.keys(preConfig.installed ?? {});
2979
+ const installedNames = preConfig.installed ?? [];
2646
2980
  if (installedNames.length === 0) {
2647
2981
  console.log("No components installed.");
2648
2982
  return;
@@ -2656,7 +2990,7 @@ var runUninstall = async (args2) => {
2656
2990
  targetArgs.push(...selected);
2657
2991
  }
2658
2992
  const config = await loadConfig();
2659
- const installed = config.installed ?? {};
2993
+ const installed = [...config.installed ?? []];
2660
2994
  const resolvedTargets = [];
2661
2995
  const notTracked = [];
2662
2996
  for (const name of targetArgs) {
@@ -2665,10 +2999,7 @@ var runUninstall = async (args2) => {
2665
2999
  console.log(`Component "${name}" not found in registry.`);
2666
3000
  continue;
2667
3001
  }
2668
- const installedKey = Object.keys(installed).find((key) => {
2669
- return normalizeInstalledKey(key) === normalizeInstalledKey(item.name);
2670
- });
2671
- if (!installedKey) {
3002
+ if (!isInstalled(installed, item.name)) {
2672
3003
  notTracked.push(name);
2673
3004
  console.log(`Component "${name}" is not tracked as installed.`);
2674
3005
  continue;
@@ -2681,10 +3012,11 @@ var runUninstall = async (args2) => {
2681
3012
  }
2682
3013
  return;
2683
3014
  }
2684
- const remainingInstalled = { ...installed };
2685
- for (const item of resolvedTargets) {
2686
- removeInstalledKey(remainingInstalled, item.name);
2687
- }
3015
+ const remainingInstalled = installed.filter((entry) => {
3016
+ return !resolvedTargets.some((item) => {
3017
+ return findInstalledKey([entry], item.name) !== void 0;
3018
+ });
3019
+ });
2688
3020
  const allItems = await getRegistryItems({ fallback: !noFallback });
2689
3021
  const orphanItems = withDeps ? findOrphanInstalledItems(
2690
3022
  resolvedTargets.map((item) => item.name),
@@ -2706,9 +3038,7 @@ var runUninstall = async (args2) => {
2706
3038
  console.log("Dry run: no files will be removed.\n");
2707
3039
  console.log("Components:");
2708
3040
  for (const item of resolvedTargets) {
2709
- console.log(
2710
- `- ${item.canonicalName} v${installed[item.name] ?? "unknown"}`
2711
- );
3041
+ console.log(`- ${item.canonicalName}`);
2712
3042
  }
2713
3043
  if (withDeps && orphanItems.length) {
2714
3044
  console.log("\nOrphan registry items (--with-deps):");
@@ -2724,10 +3054,12 @@ var runUninstall = async (args2) => {
2724
3054
  console.log(`- ${item.canonicalName}`);
2725
3055
  }
2726
3056
  }
2727
- const postOrphanRemaining = { ...remainingInstalled };
2728
- for (const item of withDeps ? orphanItems : []) {
2729
- removeInstalledKey(postOrphanRemaining, item.name);
2730
- }
3057
+ const postOrphanRemaining = remainingInstalled.filter((entry) => {
3058
+ if (!withDeps) {
3059
+ return true;
3060
+ }
3061
+ return !orphanItems.some((item) => isInstalled([entry], item.name));
3062
+ });
2731
3063
  const dryRunOrphans = collectOrphanedSharedResources(
2732
3064
  allRemovalTargets,
2733
3065
  await resolveInstalledItems(postOrphanRemaining)
@@ -2761,11 +3093,11 @@ var runUninstall = async (args2) => {
2761
3093
  }
2762
3094
  console.log("");
2763
3095
  }
2764
- const postUninstallInstalled = { ...installed };
3096
+ let updatedInstalled = [...installed];
2765
3097
  for (const item of successfullyUninstalled) {
2766
- removeInstalledKey(postUninstallInstalled, item.name);
3098
+ updatedInstalled = removeInstalled(updatedInstalled, item.name);
2767
3099
  }
2768
- const remainingItems = await resolveInstalledItems(postUninstallInstalled);
3100
+ const remainingItems = await resolveInstalledItems(updatedInstalled);
2769
3101
  const orphanedResources = collectOrphanedSharedResources(
2770
3102
  successfullyUninstalled,
2771
3103
  remainingItems
@@ -2785,12 +3117,6 @@ var runUninstall = async (args2) => {
2785
3117
  }
2786
3118
  const utilitiesResult = await uninstallUtilities(resolvedUtilities, config);
2787
3119
  const stylesResult = await uninstallStyles(resolvedStyles, config);
2788
- const updatedInstalled = {
2789
- ...installed
2790
- };
2791
- for (const item of successfullyUninstalled) {
2792
- removeInstalledKey(updatedInstalled, item.name);
2793
- }
2794
3120
  await saveConfig({
2795
3121
  ...config,
2796
3122
  installed: updatedInstalled
@@ -2810,172 +3136,18 @@ var runUninstall = async (args2) => {
2810
3136
  }
2811
3137
  };
2812
3138
 
2813
- // src/utils/version.ts
2814
- var compareVersions = (a, b) => {
2815
- const pa = a.split(".").map(Number);
2816
- const pb = b.split(".").map(Number);
2817
- const length = Math.max(pa.length, pb.length);
2818
- for (let i = 0; i < length; i++) {
2819
- const va = pa[i] ?? 0;
2820
- const vb = pb[i] ?? 0;
2821
- if (va > vb) return 1;
2822
- if (va < vb) return -1;
2823
- }
2824
- return 0;
2825
- };
2826
- var isUpdateAvailable = (installed, latest) => {
2827
- return compareVersions(latest, installed) === 1;
2828
- };
2829
-
2830
- // src/install/update-engine.ts
2831
- var checkItemFiles = async (name) => {
2832
- const item = await findItem(name);
2833
- const config = await loadConfig();
2834
- if (!item) {
2835
- console.log(`Component "${name}" no longer exists in the registry.`);
2836
- return;
2837
- }
2838
- const installTarget = resolveItemInstallTarget(config, item);
2839
- console.log(`File check for ${item.canonicalName}:`);
2840
- for (const file of item.files) {
2841
- const fileName = file.split("/").at(-1);
2842
- if (!fileName) {
2843
- console.log(`- invalid registry file path: ${file}`);
2844
- continue;
2845
- }
2846
- const targetPath = join(getCwd(), installTarget, fileName);
2847
- if (!await fileExists(targetPath)) {
2848
- console.log(`- missing: ${targetPath}`);
2849
- continue;
2850
- }
2851
- const preparedContent = prepareInstalledFileContent(
2852
- await readFile(getRegistryTemplatePath(file), "utf-8"),
2853
- item
2854
- );
2855
- const targetContent = await readFile(targetPath, "utf-8");
2856
- if (hashesAreEqual(preparedContent, targetContent)) {
2857
- console.log(`- identical: ${targetPath}`);
2858
- continue;
2859
- }
2860
- console.log(`- conflict: ${targetPath}`);
2861
- }
2862
- };
2863
- var applySafeItemUpdate = async (name, force) => {
2864
- const item = await findItem(name);
2865
- const config = await loadConfig();
2866
- if (!item) {
2867
- console.log(`Component "${name}" no longer exists in the registry.`);
2868
- return false;
2869
- }
2870
- const installTarget = resolveItemInstallTarget(config, item);
2871
- let hasConflict = false;
2872
- console.log(`Applying update for ${item.canonicalName}:`);
2873
- for (const file of item.files) {
2874
- const sourcePath = getRegistryTemplatePath(file);
2875
- const fileName = file.split("/").at(-1);
2876
- if (!fileName) {
2877
- console.log(`- invalid registry file path: ${file}`);
2878
- hasConflict = true;
2879
- continue;
2880
- }
2881
- const targetPath = join(getCwd(), installTarget, fileName);
2882
- const preparedContent = prepareInstalledFileContent(
2883
- await readFile(sourcePath, "utf-8"),
2884
- item
2885
- );
2886
- await mkdir(dirname(targetPath), { recursive: true });
2887
- if (!await fileExists(targetPath)) {
2888
- await writeFile(targetPath, preparedContent, "utf-8");
2889
- console.log(`- restored missing file: ${targetPath}`);
2890
- continue;
2891
- }
2892
- const targetContent = await readFile(targetPath, "utf-8");
2893
- if (hashesAreEqual(preparedContent, targetContent)) {
2894
- console.log(`- identical: ${targetPath}`);
2895
- continue;
2896
- }
2897
- if (force) {
2898
- const backupPath = await createBackupFile(targetPath);
2899
- if (backupPath) {
2900
- console.log(`- backup created: ${backupPath}`);
2901
- }
2902
- await writeFile(targetPath, preparedContent, "utf-8");
2903
- console.log(`- force updated file: ${targetPath}`);
2904
- continue;
2905
- }
2906
- hasConflict = true;
2907
- console.log(`- conflict (user modified): ${targetPath}`);
2908
- }
2909
- if (hasConflict) {
2910
- console.log(
2911
- "Update finished with conflicts. Installed version was not changed."
2912
- );
2913
- return false;
2914
- }
2915
- console.log(
2916
- `\u2714 ${item.canonicalName} updated successfully to v${item.version}`
2917
- );
2918
- return true;
2919
- };
2920
- var checkItemUpdate = async (name, installedVersion, dryRun, force, sync = false) => {
2921
- const item = await findItem(name);
2922
- if (!item) {
2923
- console.log(`Component "${name}" no longer exists in the registry.`);
2924
- return false;
2925
- }
2926
- const versionUpdateAvailable = isUpdateAvailable(
2927
- installedVersion,
2928
- item.version
2929
- );
2930
- if (!sync && !versionUpdateAvailable) {
2931
- console.log(`${item.canonicalName} is up to date (v${installedVersion}).`);
2932
- return false;
2933
- }
2934
- if (sync && !versionUpdateAvailable) {
2935
- console.log(
2936
- `${item.canonicalName} template sync (installed v${installedVersion}, registry v${item.version})`
2937
- );
2938
- } else {
2939
- console.log(
2940
- `${item.canonicalName} can be updated: v${installedVersion} \u2192 v${item.version}`
2941
- );
2942
- }
2943
- if (dryRun) {
2944
- console.log("\nChanged file candidates:");
2945
- for (const file of item.files) {
2946
- console.log(`~ ${file}`);
2947
- }
2948
- console.log("\nDry run: no files will be changed.");
2949
- console.log("Update plan:");
2950
- if (force) {
2951
- console.log(
2952
- "- Force mode requested: conflicted files require backup before overwrite"
2953
- );
2954
- console.log(
2955
- "- Dry run: backups would be created before forced overwrites"
2956
- );
2957
- }
2958
- console.log(`- Check installed files for ${item.canonicalName}`);
2959
- console.log("- Compare existing files with registry templates");
2960
- console.log("- Report conflicts before writing changes");
2961
- console.log("- Never overwrite user-modified files silently");
2962
- await checkItemFiles(name);
2963
- return false;
2964
- }
2965
- return await applySafeItemUpdate(name, force);
2966
- };
2967
-
2968
3139
  // src/commands/update.ts
2969
3140
  var styleUpdateNames = ["theme"];
2970
- var resolveInstalledKey = async (name, installed) => {
2971
- if (installed[name]) {
2972
- return name;
3141
+ var resolveInstalledKey2 = async (name, installed) => {
3142
+ const direct = findInstalledKey(installed, name);
3143
+ if (direct) {
3144
+ return direct;
2973
3145
  }
2974
3146
  const item = await findItem(name);
2975
3147
  if (!item) {
2976
3148
  return void 0;
2977
3149
  }
2978
- return installed[item.name] ? item.name : void 0;
3150
+ return findInstalledKey(installed, item.name);
2979
3151
  };
2980
3152
  var runStylesUpdate = async (config, dryRun) => {
2981
3153
  const styles = resolveRegistryStyles(styleUpdateNames);
@@ -3002,9 +3174,7 @@ Tailwind CSS entrypoint: ${config.tailwind.css}`);
3002
3174
  }
3003
3175
  };
3004
3176
  var runUtilitiesUpdate = async (config, installed, dryRun, force) => {
3005
- const installedItems = (await Promise.all(
3006
- Object.keys(installed).map(async (name) => findItem(name))
3007
- )).filter((item) => Boolean(item));
3177
+ const installedItems = (await Promise.all(installed.map(async (name) => findItem(name)))).filter((item) => Boolean(item));
3008
3178
  const utilityNames = collectUtilities(installedItems);
3009
3179
  if (!utilityNames.length) {
3010
3180
  console.log("No shared utilities are tracked for installed components.");
@@ -3029,26 +3199,18 @@ var runUtilitiesUpdate = async (config, installed, dryRun, force) => {
3029
3199
  );
3030
3200
  }
3031
3201
  };
3032
- var runComponentUpdates = async (config, installed, targetNames, dryRun, force, sync) => {
3033
- let changed = false;
3034
- if (!Object.keys(installed).length) {
3202
+ var runComponentUpdates = async (installed, targetNames, dryRun, force, sync) => {
3203
+ if (!installed.length) {
3035
3204
  console.log("No Lexsys components are currently tracked.");
3036
- return false;
3205
+ return;
3037
3206
  }
3038
3207
  console.log("Checking installed Lexsys components:\n");
3039
3208
  for (const name of targetNames) {
3040
- const version = installed[name];
3041
- if (!version) {
3209
+ if (!isInstalled(installed, name)) {
3042
3210
  continue;
3043
3211
  }
3044
- const didUpdate = await checkItemUpdate(name, version, dryRun, force, sync);
3045
- const item = await findItem(name);
3046
- if (didUpdate && item) {
3047
- installed[name] = item.version;
3048
- changed = true;
3049
- }
3212
+ await checkItemUpdate(name, dryRun, force, sync);
3050
3213
  }
3051
- return changed;
3052
3214
  };
3053
3215
  var runUpdate = async (args2) => {
3054
3216
  const dryRun = hasFlag(args2, "--dry-run", "-d");
@@ -3076,7 +3238,7 @@ var runUpdate = async (args2) => {
3076
3238
  "-a"
3077
3239
  ]);
3078
3240
  const config = await loadConfig();
3079
- const installed = { ...config.installed ?? {} };
3241
+ const installed = [...config.installed ?? []];
3080
3242
  try {
3081
3243
  await getRegistryProviderResult({
3082
3244
  fallback: !noFallback
@@ -3088,19 +3250,18 @@ var runUpdate = async (args2) => {
3088
3250
  return;
3089
3251
  }
3090
3252
  if (!updateAll && !stylesFlag && !utilitiesFlag && targetArgs.length === 0) {
3091
- const installedNames = Object.keys(installed);
3092
- if (installedNames.length === 0) {
3253
+ if (installed.length === 0) {
3093
3254
  console.log(
3094
3255
  "No components installed. Run `lexsys add <component>` first."
3095
3256
  );
3096
3257
  return;
3097
3258
  }
3098
3259
  if (yes) {
3099
- targetArgs.push(...installedNames);
3260
+ targetArgs.push(...installed);
3100
3261
  } else {
3101
3262
  const selected = await promptMultiselect(
3102
3263
  "Select components to update",
3103
- installedNames.map((name) => ({ title: name, value: name })),
3264
+ installed.map((name) => ({ title: name, value: name })),
3104
3265
  { min: 1 }
3105
3266
  );
3106
3267
  if (!selected.length) return;
@@ -3127,42 +3288,18 @@ var runUpdate = async (args2) => {
3127
3288
  if (!shouldUpdateComponents) {
3128
3289
  return;
3129
3290
  }
3130
- let changed = false;
3131
3291
  if (updateAll) {
3132
- changed = await runComponentUpdates(
3133
- config,
3134
- installed,
3135
- Object.keys(installed),
3136
- dryRun,
3137
- force,
3138
- sync
3139
- );
3292
+ await runComponentUpdates(installed, installed, dryRun, force, sync);
3140
3293
  } else {
3141
3294
  for (const name of targetArgs) {
3142
- const installedKey = await resolveInstalledKey(name, installed);
3295
+ const installedKey = await resolveInstalledKey2(name, installed);
3143
3296
  if (!installedKey) {
3144
3297
  console.log(`Component "${name}" is not tracked as installed.`);
3145
3298
  continue;
3146
3299
  }
3147
- const didUpdateOne = await runComponentUpdates(
3148
- config,
3149
- installed,
3150
- [installedKey],
3151
- dryRun,
3152
- force,
3153
- sync
3154
- );
3155
- if (didUpdateOne) {
3156
- changed = true;
3157
- }
3300
+ await runComponentUpdates(installed, [installedKey], dryRun, force, sync);
3158
3301
  }
3159
3302
  }
3160
- if (changed) {
3161
- await saveConfig({
3162
- ...config,
3163
- installed
3164
- });
3165
- }
3166
3303
  };
3167
3304
  var cliDistDir = dirname(fileURLToPath(import.meta.url));
3168
3305
  var packageJsonPath = join(cliDistDir, "..", "package.json");
@@ -3269,6 +3406,14 @@ try {
3269
3406
  });
3270
3407
  process.exit(0);
3271
3408
  }
3409
+ if (command === "reset") {
3410
+ if (hasFlag(args, "--help", "-h")) {
3411
+ runHelpFor("reset");
3412
+ process.exit(0);
3413
+ }
3414
+ await runReset(args);
3415
+ process.exit(0);
3416
+ }
3272
3417
  if (command === "uninstall" || command === "rm") {
3273
3418
  if (hasFlag(args, "--help", "-h")) {
3274
3419
  runHelpFor("uninstall");
@@ -0,0 +1,4 @@
1
+ import type { RegistryItem } from "@dalexto/lexsys-registry";
2
+ export type ComponentDriftStatus = "missing" | "in-sync" | "drift";
3
+ export declare const getComponentDriftStatus: (name: string) => Promise<ComponentDriftStatus>;
4
+ export declare const itemHasTemplateDrift: (item: RegistryItem) => Promise<boolean>;
@@ -1,2 +1,4 @@
1
1
  export declare const checkItemFiles: (name: string) => Promise<void>;
2
- export declare const checkItemUpdate: (name: string, installedVersion: string, dryRun: boolean, force: boolean, sync?: boolean) => Promise<boolean>;
2
+ export declare const applyItemOverwrite: (name: string, force: boolean) => Promise<boolean>;
3
+ export declare const checkItemUpdate: (name: string, dryRun: boolean, force: boolean, sync?: boolean) => Promise<boolean>;
4
+ export declare const resetItem: (name: string, dryRun: boolean) => Promise<boolean>;
@@ -1,3 +1,3 @@
1
1
  import type { RegistryItem } from "@dalexto/lexsys-registry";
2
2
  export declare const computeRegistryClosure: (rootNames: string[], items: RegistryItem[]) => Set<string>;
3
- export declare const findOrphanInstalledItems: (removedTargetNames: string[], remainingInstalled: Record<string, string>, items: RegistryItem[]) => RegistryItem[];
3
+ export declare const findOrphanInstalledItems: (removedTargetNames: string[], remainingInstalled: string[], items: RegistryItem[]) => RegistryItem[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dalexto/lexsys-cli",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "description": "Registry-first CLI that installs Lexsys React UI components into your project",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -32,7 +32,7 @@
32
32
  },
33
33
  "dependencies": {
34
34
  "prompts": "^2.4.2",
35
- "@dalexto/lexsys-registry": "0.0.3"
35
+ "@dalexto/lexsys-registry": "0.0.5"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@types/node": "^25.9.1",
@@ -1,2 +0,0 @@
1
- export declare const compareVersions: (a: string, b: string) => number;
2
- export declare const isUpdateAvailable: (installed: string, latest: string) => boolean;