claudekit-cli 3.30.0-dev.1 → 3.30.0-dev.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +558 -383
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -18149,7 +18149,7 @@ function getPagerArgs(pagerCmd) {
18149
18149
  return [];
18150
18150
  }
18151
18151
  async function trySystemPager(content) {
18152
- return new Promise((resolve11) => {
18152
+ return new Promise((resolve12) => {
18153
18153
  const pagerCmd = process.env.PAGER || "less";
18154
18154
  const pagerArgs = getPagerArgs(pagerCmd);
18155
18155
  try {
@@ -18159,20 +18159,20 @@ async function trySystemPager(content) {
18159
18159
  });
18160
18160
  const timeout = setTimeout(() => {
18161
18161
  pager.kill();
18162
- resolve11(false);
18162
+ resolve12(false);
18163
18163
  }, 30000);
18164
18164
  pager.stdin.write(content);
18165
18165
  pager.stdin.end();
18166
18166
  pager.on("close", (code2) => {
18167
18167
  clearTimeout(timeout);
18168
- resolve11(code2 === 0);
18168
+ resolve12(code2 === 0);
18169
18169
  });
18170
18170
  pager.on("error", () => {
18171
18171
  clearTimeout(timeout);
18172
- resolve11(false);
18172
+ resolve12(false);
18173
18173
  });
18174
18174
  } catch {
18175
- resolve11(false);
18175
+ resolve12(false);
18176
18176
  }
18177
18177
  });
18178
18178
  }
@@ -18199,16 +18199,16 @@ async function basicPager(content) {
18199
18199
  break;
18200
18200
  }
18201
18201
  const remaining = lines.length - currentLine;
18202
- await new Promise((resolve11) => {
18202
+ await new Promise((resolve12) => {
18203
18203
  rl.question(`-- More (${remaining} lines) [Enter/q] --`, (answer) => {
18204
18204
  if (answer.toLowerCase() === "q") {
18205
18205
  rl.close();
18206
18206
  process.exitCode = 0;
18207
- resolve11();
18207
+ resolve12();
18208
18208
  return;
18209
18209
  }
18210
18210
  process.stdout.write("\x1B[1A\x1B[2K");
18211
- resolve11();
18211
+ resolve12();
18212
18212
  });
18213
18213
  });
18214
18214
  }
@@ -35225,22 +35225,11 @@ async function handleDownload(ctx) {
35225
35225
  };
35226
35226
  }
35227
35227
  // src/commands/init/phases/merge-handler.ts
35228
- import { join as join53 } from "node:path";
35229
-
35230
- // src/domains/installation/file-merger.ts
35231
- init_logger();
35232
- init_types2();
35233
- init_dist2();
35234
-
35235
- // src/domains/installation/merger/copy-executor.ts
35236
- init_logger();
35237
- init_types2();
35238
- var import_fs_extra10 = __toESM(require_lib(), 1);
35239
- var import_ignore3 = __toESM(require_ignore(), 1);
35240
- import { dirname as dirname8, join as join43, relative as relative6 } from "node:path";
35228
+ import { join as join54 } from "node:path";
35241
35229
 
35242
- // src/domains/installation/selective-merger.ts
35243
- import { stat as stat6 } from "node:fs/promises";
35230
+ // src/domains/installation/deletion-handler.ts
35231
+ import { existsSync as existsSync17, lstatSync as lstatSync2, readdirSync, rmSync as rmSync2, rmdirSync, unlinkSync as unlinkSync3 } from "node:fs";
35232
+ import { dirname as dirname6, join as join40, resolve as resolve6 } from "node:path";
35244
35233
 
35245
35234
  // src/services/file-operations/manifest/manifest-reader.ts
35246
35235
  import { join as join39 } from "node:path";
@@ -35389,7 +35378,172 @@ async function getUninstallManifest(claudeDir, kit) {
35389
35378
  };
35390
35379
  }
35391
35380
 
35381
+ // src/domains/installation/deletion-handler.ts
35382
+ init_logger();
35383
+ var import_fs_extra7 = __toESM(require_lib(), 1);
35384
+ function findFileInMetadata(metadata, path10) {
35385
+ if (!metadata)
35386
+ return null;
35387
+ if (metadata.kits) {
35388
+ for (const kitMeta of Object.values(metadata.kits)) {
35389
+ if (kitMeta?.files) {
35390
+ const found = kitMeta.files.find((f3) => f3.path === path10);
35391
+ if (found)
35392
+ return found;
35393
+ }
35394
+ }
35395
+ }
35396
+ if (metadata.files) {
35397
+ const found = metadata.files.find((f3) => f3.path === path10);
35398
+ if (found)
35399
+ return found;
35400
+ }
35401
+ return null;
35402
+ }
35403
+ function shouldDeletePath(path10, metadata) {
35404
+ const tracked = findFileInMetadata(metadata, path10);
35405
+ if (!tracked)
35406
+ return true;
35407
+ return tracked.ownership !== "user";
35408
+ }
35409
+ var MAX_CLEANUP_ITERATIONS = 50;
35410
+ function cleanupEmptyDirectories(filePath, claudeDir) {
35411
+ const normalizedClaudeDir = resolve6(claudeDir);
35412
+ let currentDir = resolve6(dirname6(filePath));
35413
+ let iterations = 0;
35414
+ while (currentDir !== normalizedClaudeDir && currentDir.startsWith(normalizedClaudeDir) && iterations < MAX_CLEANUP_ITERATIONS) {
35415
+ iterations++;
35416
+ try {
35417
+ const entries = readdirSync(currentDir);
35418
+ if (entries.length === 0) {
35419
+ rmdirSync(currentDir);
35420
+ logger.debug(`Removed empty directory: ${currentDir}`);
35421
+ currentDir = resolve6(dirname6(currentDir));
35422
+ } else {
35423
+ break;
35424
+ }
35425
+ } catch {
35426
+ break;
35427
+ }
35428
+ }
35429
+ }
35430
+ function deletePath(fullPath, claudeDir) {
35431
+ const normalizedPath = resolve6(fullPath);
35432
+ const normalizedClaudeDir = resolve6(claudeDir);
35433
+ if (!normalizedPath.startsWith(`${normalizedClaudeDir}/`) && normalizedPath !== normalizedClaudeDir) {
35434
+ throw new Error(`Path traversal detected: ${fullPath}`);
35435
+ }
35436
+ try {
35437
+ const stat6 = lstatSync2(fullPath);
35438
+ if (stat6.isDirectory()) {
35439
+ rmSync2(fullPath, { recursive: true, force: true });
35440
+ } else {
35441
+ unlinkSync3(fullPath);
35442
+ cleanupEmptyDirectories(fullPath, claudeDir);
35443
+ }
35444
+ } catch (error) {
35445
+ throw new Error(`Failed to delete ${fullPath}: ${error instanceof Error ? error.message : String(error)}`);
35446
+ }
35447
+ }
35448
+ async function updateMetadataAfterDeletion(claudeDir, deletedPaths) {
35449
+ const metadataPath = join40(claudeDir, "metadata.json");
35450
+ if (!await import_fs_extra7.pathExists(metadataPath)) {
35451
+ return;
35452
+ }
35453
+ let content;
35454
+ try {
35455
+ content = await import_fs_extra7.readFile(metadataPath, "utf-8");
35456
+ } catch {
35457
+ logger.debug("Failed to read metadata.json for cleanup");
35458
+ return;
35459
+ }
35460
+ let metadata;
35461
+ try {
35462
+ metadata = JSON.parse(content);
35463
+ } catch {
35464
+ logger.debug("Failed to parse metadata.json for cleanup");
35465
+ return;
35466
+ }
35467
+ const deletedSet = new Set(deletedPaths);
35468
+ const isDeletedOrInDeletedDir = (path10) => {
35469
+ if (deletedSet.has(path10))
35470
+ return true;
35471
+ for (const deleted of deletedPaths) {
35472
+ if (path10.startsWith(`${deleted}/`))
35473
+ return true;
35474
+ }
35475
+ return false;
35476
+ };
35477
+ if (metadata.kits) {
35478
+ for (const kitName of Object.keys(metadata.kits)) {
35479
+ const kit = metadata.kits[kitName];
35480
+ if (kit?.files) {
35481
+ kit.files = kit.files.filter((f3) => !isDeletedOrInDeletedDir(f3.path));
35482
+ }
35483
+ }
35484
+ }
35485
+ if (metadata.files) {
35486
+ metadata.files = metadata.files.filter((f3) => !isDeletedOrInDeletedDir(f3.path));
35487
+ }
35488
+ try {
35489
+ await import_fs_extra7.writeFile(metadataPath, JSON.stringify(metadata, null, 2));
35490
+ logger.debug(`Updated metadata.json, removed ${deletedPaths.length} entries`);
35491
+ } catch {
35492
+ logger.debug("Failed to write updated metadata.json");
35493
+ }
35494
+ }
35495
+ async function handleDeletions(sourceMetadata, claudeDir) {
35496
+ const deletions = sourceMetadata.deletions || [];
35497
+ if (deletions.length === 0) {
35498
+ return { deletedPaths: [], preservedPaths: [], errors: [] };
35499
+ }
35500
+ const userMetadata = await readManifest(claudeDir);
35501
+ const result = { deletedPaths: [], preservedPaths: [], errors: [] };
35502
+ for (const path10 of deletions) {
35503
+ const fullPath = join40(claudeDir, path10);
35504
+ const normalizedPath = resolve6(fullPath);
35505
+ const normalizedClaudeDir = resolve6(claudeDir);
35506
+ if (!normalizedPath.startsWith(`${normalizedClaudeDir}/`)) {
35507
+ logger.warning(`Skipping invalid path: ${path10}`);
35508
+ result.errors.push(path10);
35509
+ continue;
35510
+ }
35511
+ if (!shouldDeletePath(path10, userMetadata)) {
35512
+ result.preservedPaths.push(path10);
35513
+ logger.verbose(`Preserved user file: ${path10}`);
35514
+ continue;
35515
+ }
35516
+ if (existsSync17(fullPath)) {
35517
+ try {
35518
+ deletePath(fullPath, claudeDir);
35519
+ result.deletedPaths.push(path10);
35520
+ logger.verbose(`Deleted: ${path10}`);
35521
+ } catch (error) {
35522
+ result.errors.push(path10);
35523
+ logger.debug(`Failed to delete ${path10}: ${error}`);
35524
+ }
35525
+ }
35526
+ }
35527
+ if (result.deletedPaths.length > 0) {
35528
+ await updateMetadataAfterDeletion(claudeDir, result.deletedPaths);
35529
+ }
35530
+ return result;
35531
+ }
35532
+
35533
+ // src/domains/installation/file-merger.ts
35534
+ init_logger();
35535
+ init_types2();
35536
+ init_dist2();
35537
+
35538
+ // src/domains/installation/merger/copy-executor.ts
35539
+ init_logger();
35540
+ init_types2();
35541
+ var import_fs_extra11 = __toESM(require_lib(), 1);
35542
+ var import_ignore3 = __toESM(require_ignore(), 1);
35543
+ import { dirname as dirname9, join as join44, relative as relative6 } from "node:path";
35544
+
35392
35545
  // src/domains/installation/selective-merger.ts
35546
+ import { stat as stat6 } from "node:fs/promises";
35393
35547
  init_logger();
35394
35548
  var import_semver = __toESM(require_semver2(), 1);
35395
35549
 
@@ -35562,10 +35716,10 @@ class SelectiveMerger {
35562
35716
 
35563
35717
  // src/domains/installation/merger/file-scanner.ts
35564
35718
  init_logger();
35565
- var import_fs_extra7 = __toESM(require_lib(), 1);
35719
+ var import_fs_extra8 = __toESM(require_lib(), 1);
35566
35720
  var import_ignore2 = __toESM(require_ignore(), 1);
35567
35721
  import { relative as relative5 } from "node:path";
35568
- import { join as join40 } from "node:path";
35722
+ import { join as join41 } from "node:path";
35569
35723
 
35570
35724
  // node_modules/@isaacs/balanced-match/dist/esm/index.js
35571
35725
  var balanced = (a3, b3, str) => {
@@ -37019,12 +37173,12 @@ class FileScanner {
37019
37173
  }
37020
37174
  async getFiles(dir, baseDir = dir) {
37021
37175
  const files = [];
37022
- const entries = await import_fs_extra7.readdir(dir, { encoding: "utf8" });
37176
+ const entries = await import_fs_extra8.readdir(dir, { encoding: "utf8" });
37023
37177
  for (const entry of entries) {
37024
- const fullPath = join40(dir, entry);
37178
+ const fullPath = join41(dir, entry);
37025
37179
  const relativePath = relative5(baseDir, fullPath);
37026
37180
  const normalizedRelativePath = relativePath.replace(/\\/g, "/");
37027
- const stats = await import_fs_extra7.lstat(fullPath);
37181
+ const stats = await import_fs_extra8.lstat(fullPath);
37028
37182
  if (stats.isSymbolicLink()) {
37029
37183
  logger.warning(`Skipping symbolic link: ${normalizedRelativePath}`);
37030
37184
  continue;
@@ -37055,9 +37209,9 @@ class FileScanner {
37055
37209
  }
37056
37210
 
37057
37211
  // src/domains/config/installed-settings-tracker.ts
37058
- import { existsSync as existsSync17 } from "node:fs";
37059
- import { mkdir as mkdir15, readFile as readFile13, writeFile as writeFile10 } from "node:fs/promises";
37060
- import { dirname as dirname6, join as join41 } from "node:path";
37212
+ import { existsSync as existsSync18 } from "node:fs";
37213
+ import { mkdir as mkdir15, readFile as readFile14, writeFile as writeFile11 } from "node:fs/promises";
37214
+ import { dirname as dirname7, join as join42 } from "node:path";
37061
37215
 
37062
37216
  // src/shared/index.ts
37063
37217
  init_logger();
@@ -37097,17 +37251,17 @@ class InstalledSettingsTracker {
37097
37251
  }
37098
37252
  getCkJsonPath() {
37099
37253
  if (this.isGlobal) {
37100
- return join41(this.projectDir, CK_JSON_FILE);
37254
+ return join42(this.projectDir, CK_JSON_FILE);
37101
37255
  }
37102
- return join41(this.projectDir, ".claude", CK_JSON_FILE);
37256
+ return join42(this.projectDir, ".claude", CK_JSON_FILE);
37103
37257
  }
37104
37258
  async loadInstalledSettings() {
37105
37259
  const ckJsonPath = this.getCkJsonPath();
37106
- if (!existsSync17(ckJsonPath)) {
37260
+ if (!existsSync18(ckJsonPath)) {
37107
37261
  return { hooks: [], mcpServers: [] };
37108
37262
  }
37109
37263
  try {
37110
- const content = await readFile13(ckJsonPath, "utf-8");
37264
+ const content = await readFile14(ckJsonPath, "utf-8");
37111
37265
  const data = JSON.parse(content);
37112
37266
  const installed = data.kits?.[this.kitName]?.installedSettings;
37113
37267
  if (installed) {
@@ -37123,8 +37277,8 @@ class InstalledSettingsTracker {
37123
37277
  const ckJsonPath = this.getCkJsonPath();
37124
37278
  try {
37125
37279
  let data = {};
37126
- if (existsSync17(ckJsonPath)) {
37127
- const content = await readFile13(ckJsonPath, "utf-8");
37280
+ if (existsSync18(ckJsonPath)) {
37281
+ const content = await readFile14(ckJsonPath, "utf-8");
37128
37282
  data = JSON.parse(content);
37129
37283
  }
37130
37284
  if (!data.kits) {
@@ -37134,8 +37288,8 @@ class InstalledSettingsTracker {
37134
37288
  data.kits[this.kitName] = {};
37135
37289
  }
37136
37290
  data.kits[this.kitName].installedSettings = settings;
37137
- await mkdir15(dirname6(ckJsonPath), { recursive: true });
37138
- await writeFile10(ckJsonPath, JSON.stringify(data, null, 2), "utf-8");
37291
+ await mkdir15(dirname7(ckJsonPath), { recursive: true });
37292
+ await writeFile11(ckJsonPath, JSON.stringify(data, null, 2), "utf-8");
37139
37293
  logger.debug(`Saved installed settings to ${ckJsonPath}`);
37140
37294
  } catch (error) {
37141
37295
  logger.warning(`Failed to save installed settings: ${error instanceof Error ? error.message : "Unknown error"}`);
@@ -37556,18 +37710,18 @@ function mergeSettings(source, destination, options) {
37556
37710
  }
37557
37711
  // src/domains/config/merger/file-io.ts
37558
37712
  init_logger();
37559
- var import_fs_extra8 = __toESM(require_lib(), 1);
37713
+ var import_fs_extra9 = __toESM(require_lib(), 1);
37560
37714
  import { randomUUID } from "node:crypto";
37561
- import { dirname as dirname7, join as join42 } from "node:path";
37715
+ import { dirname as dirname8, join as join43 } from "node:path";
37562
37716
  function stripBOM(content) {
37563
37717
  return content.charCodeAt(0) === 65279 ? content.slice(1) : content;
37564
37718
  }
37565
37719
  async function readSettingsFile(filePath) {
37566
37720
  try {
37567
- if (!await import_fs_extra8.pathExists(filePath)) {
37721
+ if (!await import_fs_extra9.pathExists(filePath)) {
37568
37722
  return null;
37569
37723
  }
37570
- const rawContent = await import_fs_extra8.readFile(filePath, "utf-8");
37724
+ const rawContent = await import_fs_extra9.readFile(filePath, "utf-8");
37571
37725
  const content = stripBOM(rawContent);
37572
37726
  const parsed = JSON.parse(content);
37573
37727
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
@@ -37581,15 +37735,15 @@ async function readSettingsFile(filePath) {
37581
37735
  }
37582
37736
  }
37583
37737
  async function atomicWriteFile(filePath, content) {
37584
- const dir = dirname7(filePath);
37585
- const tempPath = join42(dir, `.settings-${randomUUID()}.tmp`);
37738
+ const dir = dirname8(filePath);
37739
+ const tempPath = join43(dir, `.settings-${randomUUID()}.tmp`);
37586
37740
  try {
37587
- await import_fs_extra8.writeFile(tempPath, content, "utf-8");
37588
- await import_fs_extra8.rename(tempPath, filePath);
37741
+ await import_fs_extra9.writeFile(tempPath, content, "utf-8");
37742
+ await import_fs_extra9.rename(tempPath, filePath);
37589
37743
  } catch (error) {
37590
37744
  try {
37591
- if (await import_fs_extra8.pathExists(tempPath)) {
37592
- await import_fs_extra8.unlink(tempPath);
37745
+ if (await import_fs_extra9.pathExists(tempPath)) {
37746
+ await import_fs_extra9.unlink(tempPath);
37593
37747
  }
37594
37748
  } catch {}
37595
37749
  throw error;
@@ -37618,7 +37772,7 @@ class SettingsMerger {
37618
37772
  // src/domains/installation/merger/settings-processor.ts
37619
37773
  init_environment();
37620
37774
  init_logger();
37621
- var import_fs_extra9 = __toESM(require_lib(), 1);
37775
+ var import_fs_extra10 = __toESM(require_lib(), 1);
37622
37776
 
37623
37777
  class SettingsProcessor {
37624
37778
  isGlobal = false;
@@ -37651,7 +37805,7 @@ class SettingsProcessor {
37651
37805
  }
37652
37806
  async processSettingsJson(sourceFile, destFile) {
37653
37807
  try {
37654
- const sourceContent = await import_fs_extra9.readFile(sourceFile, "utf-8");
37808
+ const sourceContent = await import_fs_extra10.readFile(sourceFile, "utf-8");
37655
37809
  let transformedSource = sourceContent;
37656
37810
  if (this.isGlobal) {
37657
37811
  const homeVar = isWindows() ? '"%USERPROFILE%"' : '"$HOME"';
@@ -37666,12 +37820,12 @@ class SettingsProcessor {
37666
37820
  logger.debug(`Transformed .claude/ paths to ${projectDirVar}/.claude/ in settings.json for local installation`);
37667
37821
  }
37668
37822
  }
37669
- const destExists = await import_fs_extra9.pathExists(destFile);
37823
+ const destExists = await import_fs_extra10.pathExists(destFile);
37670
37824
  if (destExists && !this.forceOverwriteSettings) {
37671
37825
  await this.selectiveMergeSettings(transformedSource, destFile);
37672
37826
  } else {
37673
37827
  const formattedContent = this.formatJsonContent(transformedSource);
37674
- await import_fs_extra9.writeFile(destFile, formattedContent, "utf-8");
37828
+ await import_fs_extra10.writeFile(destFile, formattedContent, "utf-8");
37675
37829
  try {
37676
37830
  const parsedSettings = JSON.parse(formattedContent);
37677
37831
  if (this.forceOverwriteSettings && destExists) {
@@ -37685,7 +37839,7 @@ class SettingsProcessor {
37685
37839
  }
37686
37840
  } catch (error) {
37687
37841
  logger.error(`Failed to process settings.json: ${error}`);
37688
- await import_fs_extra9.copy(sourceFile, destFile, { overwrite: true });
37842
+ await import_fs_extra10.copy(sourceFile, destFile, { overwrite: true });
37689
37843
  }
37690
37844
  }
37691
37845
  async selectiveMergeSettings(transformedSourceContent, destFile) {
@@ -37695,7 +37849,7 @@ class SettingsProcessor {
37695
37849
  } catch {
37696
37850
  logger.warning("Failed to parse source settings.json, falling back to overwrite");
37697
37851
  const formattedContent = this.formatJsonContent(transformedSourceContent);
37698
- await import_fs_extra9.writeFile(destFile, formattedContent, "utf-8");
37852
+ await import_fs_extra10.writeFile(destFile, formattedContent, "utf-8");
37699
37853
  return;
37700
37854
  }
37701
37855
  let destSettings;
@@ -37781,7 +37935,7 @@ class SettingsProcessor {
37781
37935
  }
37782
37936
  async readAndNormalizeGlobalSettings(destFile) {
37783
37937
  try {
37784
- const content = await import_fs_extra9.readFile(destFile, "utf-8");
37938
+ const content = await import_fs_extra10.readFile(destFile, "utf-8");
37785
37939
  if (!content.trim())
37786
37940
  return null;
37787
37941
  const homeVar = isWindows() ? "%USERPROFILE%" : "$HOME";
@@ -37892,8 +38046,8 @@ class CopyExecutor {
37892
38046
  for (const file of files) {
37893
38047
  const relativePath = relative6(sourceDir, file);
37894
38048
  const normalizedRelativePath = relativePath.replace(/\\/g, "/");
37895
- const destPath = join43(destDir, relativePath);
37896
- if (await import_fs_extra10.pathExists(destPath)) {
38049
+ const destPath = join44(destDir, relativePath);
38050
+ if (await import_fs_extra11.pathExists(destPath)) {
37897
38051
  if (this.fileScanner.shouldNeverCopy(normalizedRelativePath)) {
37898
38052
  logger.debug(`Security-sensitive file exists but won't be overwritten: ${normalizedRelativePath}`);
37899
38053
  continue;
@@ -37914,14 +38068,14 @@ class CopyExecutor {
37914
38068
  for (const file of files) {
37915
38069
  const relativePath = relative6(sourceDir, file);
37916
38070
  const normalizedRelativePath = relativePath.replace(/\\/g, "/");
37917
- const destPath = join43(destDir, relativePath);
38071
+ const destPath = join44(destDir, relativePath);
37918
38072
  if (this.fileScanner.shouldNeverCopy(normalizedRelativePath)) {
37919
38073
  logger.debug(`Skipping security-sensitive file: ${normalizedRelativePath}`);
37920
38074
  skippedCount++;
37921
38075
  continue;
37922
38076
  }
37923
38077
  if (this.userConfigChecker.ignores(normalizedRelativePath)) {
37924
- const fileExists = await import_fs_extra10.pathExists(destPath);
38078
+ const fileExists = await import_fs_extra11.pathExists(destPath);
37925
38079
  if (fileExists) {
37926
38080
  logger.debug(`Preserving user config: ${normalizedRelativePath}`);
37927
38081
  skippedCount++;
@@ -37952,7 +38106,7 @@ class CopyExecutor {
37952
38106
  continue;
37953
38107
  }
37954
38108
  }
37955
- await withRetry2(() => import_fs_extra10.copy(file, destPath, { overwrite: true }));
38109
+ await withRetry2(() => import_fs_extra11.copy(file, destPath, { overwrite: true }));
37956
38110
  this.trackInstalledFile(normalizedRelativePath);
37957
38111
  copiedCount++;
37958
38112
  }
@@ -37991,10 +38145,10 @@ class CopyExecutor {
37991
38145
  }
37992
38146
  trackInstalledFile(relativePath) {
37993
38147
  this.installedFiles.add(relativePath);
37994
- let dir = dirname8(relativePath);
38148
+ let dir = dirname9(relativePath);
37995
38149
  while (dir && dir !== "." && dir !== "/") {
37996
38150
  this.installedDirectories.add(`${dir}/`);
37997
- dir = dirname8(dir);
38151
+ dir = dirname9(dir);
37998
38152
  }
37999
38153
  }
38000
38154
  }
@@ -38084,15 +38238,15 @@ class FileMerger {
38084
38238
 
38085
38239
  // src/domains/migration/legacy-migration.ts
38086
38240
  import { readdir as readdir9, stat as stat7 } from "node:fs/promises";
38087
- import { join as join47, relative as relative7 } from "node:path";
38241
+ import { join as join48, relative as relative7 } from "node:path";
38088
38242
  // src/services/file-operations/manifest/manifest-tracker.ts
38089
- import { join as join46 } from "node:path";
38243
+ import { join as join47 } from "node:path";
38090
38244
 
38091
38245
  // src/domains/migration/release-manifest.ts
38092
38246
  init_logger();
38093
38247
  init_zod();
38094
- var import_fs_extra11 = __toESM(require_lib(), 1);
38095
- import { join as join44 } from "node:path";
38248
+ var import_fs_extra12 = __toESM(require_lib(), 1);
38249
+ import { join as join45 } from "node:path";
38096
38250
  var ReleaseManifestFileSchema = exports_external.object({
38097
38251
  path: exports_external.string(),
38098
38252
  checksum: exports_external.string().regex(/^[a-f0-9]{64}$/),
@@ -38107,9 +38261,9 @@ var ReleaseManifestSchema = exports_external.object({
38107
38261
 
38108
38262
  class ReleaseManifestLoader {
38109
38263
  static async load(extractDir) {
38110
- const manifestPath = join44(extractDir, "release-manifest.json");
38264
+ const manifestPath = join45(extractDir, "release-manifest.json");
38111
38265
  try {
38112
- const content = await import_fs_extra11.readFile(manifestPath, "utf-8");
38266
+ const content = await import_fs_extra12.readFile(manifestPath, "utf-8");
38113
38267
  const parsed = JSON.parse(content);
38114
38268
  return ReleaseManifestSchema.parse(parsed);
38115
38269
  } catch (error) {
@@ -38127,15 +38281,15 @@ init_environment();
38127
38281
  init_logger();
38128
38282
 
38129
38283
  // src/services/file-operations/manifest/manifest-updater.ts
38130
- import { join as join45 } from "node:path";
38284
+ import { join as join46 } from "node:path";
38131
38285
  init_logger();
38132
38286
  init_types2();
38133
- var import_fs_extra12 = __toESM(require_lib(), 1);
38287
+ var import_fs_extra13 = __toESM(require_lib(), 1);
38134
38288
  var import_proper_lockfile2 = __toESM(require_proper_lockfile(), 1);
38135
38289
  async function writeManifest(claudeDir, kitName, version, scope, kitType, trackedFiles, userConfigFiles) {
38136
- const metadataPath = join45(claudeDir, "metadata.json");
38290
+ const metadataPath = join46(claudeDir, "metadata.json");
38137
38291
  const kit = kitType || (/\bmarketing\b/i.test(kitName) ? "marketing" : "engineer");
38138
- await import_fs_extra12.ensureFile(metadataPath);
38292
+ await import_fs_extra13.ensureFile(metadataPath);
38139
38293
  let release = null;
38140
38294
  try {
38141
38295
  release = await import_proper_lockfile2.lock(metadataPath, {
@@ -38148,9 +38302,9 @@ async function writeManifest(claudeDir, kitName, version, scope, kitType, tracke
38148
38302
  logger.warning(`Metadata migration warning: ${migrationResult.error}`);
38149
38303
  }
38150
38304
  let existingMetadata = { kits: {} };
38151
- if (await import_fs_extra12.pathExists(metadataPath)) {
38305
+ if (await import_fs_extra13.pathExists(metadataPath)) {
38152
38306
  try {
38153
- const content = await import_fs_extra12.readFile(metadataPath, "utf-8");
38307
+ const content = await import_fs_extra13.readFile(metadataPath, "utf-8");
38154
38308
  const parsed = JSON.parse(content);
38155
38309
  if (parsed && typeof parsed === "object" && Object.keys(parsed).length > 0) {
38156
38310
  existingMetadata = parsed;
@@ -38179,7 +38333,7 @@ async function writeManifest(claudeDir, kitName, version, scope, kitType, tracke
38179
38333
  userConfigFiles: [...USER_CONFIG_PATTERNS, ...userConfigFiles]
38180
38334
  };
38181
38335
  const validated = MetadataSchema.parse(metadata);
38182
- await import_fs_extra12.writeFile(metadataPath, JSON.stringify(validated, null, 2), "utf-8");
38336
+ await import_fs_extra13.writeFile(metadataPath, JSON.stringify(validated, null, 2), "utf-8");
38183
38337
  logger.debug(`Wrote manifest for kit "${kit}" with ${trackedFiles.length} tracked files`);
38184
38338
  } finally {
38185
38339
  if (release) {
@@ -38189,8 +38343,8 @@ async function writeManifest(claudeDir, kitName, version, scope, kitType, tracke
38189
38343
  }
38190
38344
  }
38191
38345
  async function removeKitFromManifest(claudeDir, kit) {
38192
- const metadataPath = join45(claudeDir, "metadata.json");
38193
- if (!await import_fs_extra12.pathExists(metadataPath))
38346
+ const metadataPath = join46(claudeDir, "metadata.json");
38347
+ if (!await import_fs_extra13.pathExists(metadataPath))
38194
38348
  return false;
38195
38349
  let release = null;
38196
38350
  try {
@@ -38211,7 +38365,7 @@ async function removeKitFromManifest(claudeDir, kit) {
38211
38365
  ...metadata,
38212
38366
  kits: remainingKits
38213
38367
  };
38214
- await import_fs_extra12.writeFile(metadataPath, JSON.stringify(updated, null, 2), "utf-8");
38368
+ await import_fs_extra13.writeFile(metadataPath, JSON.stringify(updated, null, 2), "utf-8");
38215
38369
  logger.debug(`Removed kit "${kit}" from metadata, ${Object.keys(remainingKits).length} kit(s) remaining`);
38216
38370
  return true;
38217
38371
  } finally {
@@ -38319,7 +38473,7 @@ function buildFileTrackingList(options) {
38319
38473
  if (!isGlobal && !installedPath.startsWith(".claude/"))
38320
38474
  continue;
38321
38475
  const relativePath = isGlobal ? installedPath : installedPath.replace(/^\.claude\//, "");
38322
- const filePath = join46(claudeDir, relativePath);
38476
+ const filePath = join47(claudeDir, relativePath);
38323
38477
  const manifestEntry = releaseManifest ? ReleaseManifestLoader.findFile(releaseManifest, installedPath) : null;
38324
38478
  const ownership = manifestEntry ? "ck" : "user";
38325
38479
  filesToTrack.push({
@@ -38392,7 +38546,7 @@ class ManifestWriter {
38392
38546
 
38393
38547
  // src/domains/migration/legacy-migration.ts
38394
38548
  init_logger();
38395
- var import_fs_extra13 = __toESM(require_lib(), 1);
38549
+ var import_fs_extra14 = __toESM(require_lib(), 1);
38396
38550
  class LegacyMigration {
38397
38551
  static async detectLegacy(claudeDir) {
38398
38552
  const metadata = await ManifestWriter.readManifest(claudeDir);
@@ -38425,7 +38579,7 @@ class LegacyMigration {
38425
38579
  continue;
38426
38580
  if (SKIP_DIRS_ALL.includes(entry))
38427
38581
  continue;
38428
- const fullPath = join47(dir, entry);
38582
+ const fullPath = join48(dir, entry);
38429
38583
  let stats;
38430
38584
  try {
38431
38585
  stats = await stat7(fullPath);
@@ -38527,7 +38681,7 @@ User-created files (sample):`);
38527
38681
  ];
38528
38682
  if (filesToChecksum.length > 0) {
38529
38683
  const checksumResults = await mapWithLimit(filesToChecksum, async ({ relativePath, ownership }) => {
38530
- const fullPath = join47(claudeDir, relativePath);
38684
+ const fullPath = join48(claudeDir, relativePath);
38531
38685
  const checksum = await OwnershipChecker.calculateChecksum(fullPath);
38532
38686
  return { relativePath, checksum, ownership };
38533
38687
  });
@@ -38548,8 +38702,8 @@ User-created files (sample):`);
38548
38702
  installedAt: new Date().toISOString(),
38549
38703
  files: trackedFiles
38550
38704
  };
38551
- const metadataPath = join47(claudeDir, "metadata.json");
38552
- await import_fs_extra13.writeFile(metadataPath, JSON.stringify(updatedMetadata, null, 2));
38705
+ const metadataPath = join48(claudeDir, "metadata.json");
38706
+ await import_fs_extra14.writeFile(metadataPath, JSON.stringify(updatedMetadata, null, 2));
38553
38707
  logger.success(`Migration complete: tracked ${trackedFiles.length} files`);
38554
38708
  return true;
38555
38709
  }
@@ -38651,32 +38805,32 @@ function buildConflictSummary(fileConflicts, hookConflicts, mcpConflicts) {
38651
38805
  }
38652
38806
 
38653
38807
  // src/services/file-operations/file-scanner.ts
38654
- import { join as join48, relative as relative8, resolve as resolve6 } from "node:path";
38808
+ import { join as join49, relative as relative8, resolve as resolve7 } from "node:path";
38655
38809
  init_logger();
38656
- var import_fs_extra14 = __toESM(require_lib(), 1);
38810
+ var import_fs_extra15 = __toESM(require_lib(), 1);
38657
38811
 
38658
38812
  class FileScanner2 {
38659
38813
  static async getFiles(dirPath, relativeTo) {
38660
38814
  const basePath = relativeTo || dirPath;
38661
38815
  const files = [];
38662
- if (!await import_fs_extra14.pathExists(dirPath)) {
38816
+ if (!await import_fs_extra15.pathExists(dirPath)) {
38663
38817
  return files;
38664
38818
  }
38665
38819
  try {
38666
- const entries = await import_fs_extra14.readdir(dirPath, { encoding: "utf8" });
38820
+ const entries = await import_fs_extra15.readdir(dirPath, { encoding: "utf8" });
38667
38821
  for (const entry of entries) {
38668
38822
  if (SKIP_DIRS_ALL.includes(entry)) {
38669
38823
  logger.debug(`Skipping directory: ${entry}`);
38670
38824
  continue;
38671
38825
  }
38672
- const fullPath = join48(dirPath, entry);
38826
+ const fullPath = join49(dirPath, entry);
38673
38827
  if (!FileScanner2.isSafePath(basePath, fullPath)) {
38674
38828
  logger.warning(`Skipping potentially unsafe path: ${entry}`);
38675
38829
  continue;
38676
38830
  }
38677
38831
  let stats;
38678
38832
  try {
38679
- stats = await import_fs_extra14.lstat(fullPath);
38833
+ stats = await import_fs_extra15.lstat(fullPath);
38680
38834
  } catch (error) {
38681
38835
  if (error instanceof Error && "code" in error && (error.code === "EACCES" || error.code === "EPERM")) {
38682
38836
  logger.warning(`Skipping inaccessible path: ${entry}`);
@@ -38704,8 +38858,8 @@ class FileScanner2 {
38704
38858
  return files;
38705
38859
  }
38706
38860
  static async findCustomFiles(destDir, sourceDir, subPath) {
38707
- const destSubDir = join48(destDir, subPath);
38708
- const sourceSubDir = join48(sourceDir, subPath);
38861
+ const destSubDir = join49(destDir, subPath);
38862
+ const sourceSubDir = join49(sourceDir, subPath);
38709
38863
  logger.debug(`findCustomFiles - destDir: ${destDir}`);
38710
38864
  logger.debug(`findCustomFiles - sourceDir: ${sourceDir}`);
38711
38865
  logger.debug(`findCustomFiles - subPath: "${subPath}"`);
@@ -38715,7 +38869,7 @@ class FileScanner2 {
38715
38869
  const sourceFiles = await FileScanner2.getFiles(sourceSubDir, sourceDir);
38716
38870
  logger.debug(`findCustomFiles - destFiles count: ${destFiles.length}`);
38717
38871
  logger.debug(`findCustomFiles - sourceFiles count: ${sourceFiles.length}`);
38718
- const sourceExists = await import_fs_extra14.pathExists(sourceSubDir);
38872
+ const sourceExists = await import_fs_extra15.pathExists(sourceSubDir);
38719
38873
  if (sourceExists && sourceFiles.length === 0 && destFiles.length > 100) {
38720
38874
  logger.warning(`Source directory exists but is empty while destination has ${destFiles.length} files. This may indicate an extraction issue. Skipping custom file detection.`);
38721
38875
  return [];
@@ -38733,8 +38887,8 @@ class FileScanner2 {
38733
38887
  return customFiles;
38734
38888
  }
38735
38889
  static isSafePath(basePath, targetPath) {
38736
- const resolvedBase = resolve6(basePath);
38737
- const resolvedTarget = resolve6(targetPath);
38890
+ const resolvedBase = resolve7(basePath);
38891
+ const resolvedTarget = resolve7(targetPath);
38738
38892
  return resolvedTarget.startsWith(resolvedBase);
38739
38893
  }
38740
38894
  static toPosixPath(path11) {
@@ -38744,14 +38898,14 @@ class FileScanner2 {
38744
38898
 
38745
38899
  // src/services/transformers/commands-prefix/prefix-applier.ts
38746
38900
  init_logger();
38747
- var import_fs_extra15 = __toESM(require_lib(), 1);
38901
+ var import_fs_extra16 = __toESM(require_lib(), 1);
38748
38902
  import { lstat as lstat5, mkdir as mkdir16, readdir as readdir12, stat as stat8 } from "node:fs/promises";
38749
- import { join as join50 } from "node:path";
38903
+ import { join as join51 } from "node:path";
38750
38904
 
38751
38905
  // src/services/transformers/commands-prefix/content-transformer.ts
38752
38906
  init_logger();
38753
- import { readFile as readFile18, readdir as readdir11, writeFile as writeFile15 } from "node:fs/promises";
38754
- import { join as join49 } from "node:path";
38907
+ import { readFile as readFile19, readdir as readdir11, writeFile as writeFile16 } from "node:fs/promises";
38908
+ import { join as join50 } from "node:path";
38755
38909
  var TRANSFORMABLE_EXTENSIONS = new Set([
38756
38910
  ".md",
38757
38911
  ".txt",
@@ -38819,7 +38973,7 @@ async function transformCommandReferences(directory, options = {}) {
38819
38973
  async function processDirectory(dir) {
38820
38974
  const entries = await readdir11(dir, { withFileTypes: true });
38821
38975
  for (const entry of entries) {
38822
- const fullPath = join49(dir, entry.name);
38976
+ const fullPath = join50(dir, entry.name);
38823
38977
  if (entry.isDirectory()) {
38824
38978
  if (entry.name === "node_modules" || entry.name.startsWith(".") && entry.name !== ".claude") {
38825
38979
  continue;
@@ -38827,13 +38981,13 @@ async function transformCommandReferences(directory, options = {}) {
38827
38981
  await processDirectory(fullPath);
38828
38982
  } else if (entry.isFile() && shouldTransformFile(entry.name)) {
38829
38983
  try {
38830
- const content = await readFile18(fullPath, "utf-8");
38984
+ const content = await readFile19(fullPath, "utf-8");
38831
38985
  const { transformed, changes } = transformCommandContent(content);
38832
38986
  if (changes > 0) {
38833
38987
  if (options.dryRun) {
38834
38988
  logger.debug(`[dry-run] Would transform ${changes} command ref(s) in ${fullPath}`);
38835
38989
  } else {
38836
- await writeFile15(fullPath, transformed, "utf-8");
38990
+ await writeFile16(fullPath, transformed, "utf-8");
38837
38991
  if (options.verbose) {
38838
38992
  logger.verbose(`Transformed ${changes} command ref(s) in ${fullPath}`);
38839
38993
  }
@@ -38894,14 +39048,14 @@ function shouldApplyPrefix(options) {
38894
39048
  // src/services/transformers/commands-prefix/prefix-applier.ts
38895
39049
  async function applyPrefix(extractDir) {
38896
39050
  validatePath(extractDir, "extractDir");
38897
- const commandsDir = join50(extractDir, ".claude", "commands");
38898
- if (!await import_fs_extra15.pathExists(commandsDir)) {
39051
+ const commandsDir = join51(extractDir, ".claude", "commands");
39052
+ if (!await import_fs_extra16.pathExists(commandsDir)) {
38899
39053
  logger.verbose("No commands directory found, skipping prefix application");
38900
39054
  return;
38901
39055
  }
38902
39056
  logger.info("Applying /ck: prefix to slash commands...");
38903
- const backupDir = join50(extractDir, ".commands-backup");
38904
- const tempDir = join50(extractDir, ".commands-prefix-temp");
39057
+ const backupDir = join51(extractDir, ".commands-backup");
39058
+ const tempDir = join51(extractDir, ".commands-prefix-temp");
38905
39059
  try {
38906
39060
  const entries = await readdir12(commandsDir);
38907
39061
  if (entries.length === 0) {
@@ -38909,28 +39063,28 @@ async function applyPrefix(extractDir) {
38909
39063
  return;
38910
39064
  }
38911
39065
  if (entries.length === 1 && entries[0] === "ck") {
38912
- const ckDir2 = join50(commandsDir, "ck");
39066
+ const ckDir2 = join51(commandsDir, "ck");
38913
39067
  const ckStat = await stat8(ckDir2);
38914
39068
  if (ckStat.isDirectory()) {
38915
39069
  logger.verbose("Commands already have /ck: prefix, skipping");
38916
39070
  return;
38917
39071
  }
38918
39072
  }
38919
- await import_fs_extra15.copy(commandsDir, backupDir);
39073
+ await import_fs_extra16.copy(commandsDir, backupDir);
38920
39074
  logger.verbose("Created backup of commands directory");
38921
39075
  await mkdir16(tempDir, { recursive: true });
38922
- const ckDir = join50(tempDir, "ck");
39076
+ const ckDir = join51(tempDir, "ck");
38923
39077
  await mkdir16(ckDir, { recursive: true });
38924
39078
  let processedCount = 0;
38925
39079
  for (const entry of entries) {
38926
- const sourcePath = join50(commandsDir, entry);
39080
+ const sourcePath = join51(commandsDir, entry);
38927
39081
  const stats = await lstat5(sourcePath);
38928
39082
  if (stats.isSymbolicLink()) {
38929
39083
  logger.warning(`Skipping symlink for security: ${entry}`);
38930
39084
  continue;
38931
39085
  }
38932
- const destPath = join50(ckDir, entry);
38933
- await import_fs_extra15.copy(sourcePath, destPath, {
39086
+ const destPath = join51(ckDir, entry);
39087
+ await import_fs_extra16.copy(sourcePath, destPath, {
38934
39088
  overwrite: false,
38935
39089
  errorOnExist: true
38936
39090
  });
@@ -38939,15 +39093,15 @@ async function applyPrefix(extractDir) {
38939
39093
  }
38940
39094
  if (processedCount === 0) {
38941
39095
  logger.warning("No files to move (all were symlinks or invalid)");
38942
- await import_fs_extra15.remove(backupDir);
38943
- await import_fs_extra15.remove(tempDir);
39096
+ await import_fs_extra16.remove(backupDir);
39097
+ await import_fs_extra16.remove(tempDir);
38944
39098
  return;
38945
39099
  }
38946
- await import_fs_extra15.remove(commandsDir);
38947
- await import_fs_extra15.move(tempDir, commandsDir);
38948
- await import_fs_extra15.remove(backupDir);
39100
+ await import_fs_extra16.remove(commandsDir);
39101
+ await import_fs_extra16.move(tempDir, commandsDir);
39102
+ await import_fs_extra16.remove(backupDir);
38949
39103
  logger.success("Successfully reorganized commands to /ck: prefix");
38950
- const claudeDir = join50(extractDir, ".claude");
39104
+ const claudeDir = join51(extractDir, ".claude");
38951
39105
  logger.info("Transforming command references in file contents...");
38952
39106
  const transformResult = await transformCommandReferences(claudeDir, {
38953
39107
  verbose: logger.isVerbose()
@@ -38958,46 +39112,46 @@ async function applyPrefix(extractDir) {
38958
39112
  logger.verbose("No command references needed transformation");
38959
39113
  }
38960
39114
  } catch (error) {
38961
- if (await import_fs_extra15.pathExists(backupDir)) {
39115
+ if (await import_fs_extra16.pathExists(backupDir)) {
38962
39116
  try {
38963
- await import_fs_extra15.remove(commandsDir).catch(() => {});
38964
- await import_fs_extra15.move(backupDir, commandsDir);
39117
+ await import_fs_extra16.remove(commandsDir).catch(() => {});
39118
+ await import_fs_extra16.move(backupDir, commandsDir);
38965
39119
  logger.info("Restored original commands directory from backup");
38966
39120
  } catch (rollbackError) {
38967
39121
  logger.error(`Rollback failed: ${rollbackError}`);
38968
39122
  }
38969
39123
  }
38970
- if (await import_fs_extra15.pathExists(tempDir)) {
38971
- await import_fs_extra15.remove(tempDir).catch(() => {});
39124
+ if (await import_fs_extra16.pathExists(tempDir)) {
39125
+ await import_fs_extra16.remove(tempDir).catch(() => {});
38972
39126
  }
38973
39127
  logger.error("Failed to apply /ck: prefix to commands");
38974
39128
  throw error;
38975
39129
  } finally {
38976
- if (await import_fs_extra15.pathExists(backupDir)) {
38977
- await import_fs_extra15.remove(backupDir).catch(() => {});
39130
+ if (await import_fs_extra16.pathExists(backupDir)) {
39131
+ await import_fs_extra16.remove(backupDir).catch(() => {});
38978
39132
  }
38979
- if (await import_fs_extra15.pathExists(tempDir)) {
38980
- await import_fs_extra15.remove(tempDir).catch(() => {});
39133
+ if (await import_fs_extra16.pathExists(tempDir)) {
39134
+ await import_fs_extra16.remove(tempDir).catch(() => {});
38981
39135
  }
38982
39136
  }
38983
39137
  }
38984
39138
 
38985
39139
  // src/services/transformers/commands-prefix/prefix-cleaner.ts
38986
39140
  import { lstat as lstat7, readdir as readdir14 } from "node:fs/promises";
38987
- import { join as join52 } from "node:path";
39141
+ import { join as join53 } from "node:path";
38988
39142
  init_logger();
38989
- var import_fs_extra17 = __toESM(require_lib(), 1);
39143
+ var import_fs_extra18 = __toESM(require_lib(), 1);
38990
39144
 
38991
39145
  // src/services/transformers/commands-prefix/file-processor.ts
38992
39146
  import { lstat as lstat6, readdir as readdir13 } from "node:fs/promises";
38993
- import { join as join51 } from "node:path";
39147
+ import { join as join52 } from "node:path";
38994
39148
  init_logger();
38995
- var import_fs_extra16 = __toESM(require_lib(), 1);
39149
+ var import_fs_extra17 = __toESM(require_lib(), 1);
38996
39150
  async function scanDirectoryFiles(dir) {
38997
39151
  const files = [];
38998
39152
  const entries = await readdir13(dir);
38999
39153
  for (const entry of entries) {
39000
- const fullPath = join51(dir, entry);
39154
+ const fullPath = join52(dir, entry);
39001
39155
  const stats = await lstat6(fullPath);
39002
39156
  if (stats.isSymbolicLink()) {
39003
39157
  continue;
@@ -39020,7 +39174,7 @@ async function processFileOwnership(file, relativePath, metadata, claudeDir, opt
39020
39174
  action: "delete"
39021
39175
  });
39022
39176
  if (!dryRun) {
39023
- await import_fs_extra16.remove(file);
39177
+ await import_fs_extra17.remove(file);
39024
39178
  logger.verbose(`Deleted CK file: ${relativePath}`);
39025
39179
  }
39026
39180
  accumulator.deletedCount++;
@@ -39035,7 +39189,7 @@ async function processFileOwnership(file, relativePath, metadata, claudeDir, opt
39035
39189
  reason: "force overwrite"
39036
39190
  });
39037
39191
  if (!dryRun) {
39038
- await import_fs_extra16.remove(file);
39192
+ await import_fs_extra17.remove(file);
39039
39193
  logger.verbose(`Force-deleted modified file: ${relativePath}`);
39040
39194
  }
39041
39195
  accumulator.deletedCount++;
@@ -39059,7 +39213,7 @@ async function processFileOwnership(file, relativePath, metadata, claudeDir, opt
39059
39213
  reason: "force overwrite"
39060
39214
  });
39061
39215
  if (!dryRun) {
39062
- await import_fs_extra16.remove(file);
39216
+ await import_fs_extra17.remove(file);
39063
39217
  logger.verbose(`Force-deleted user file: ${relativePath}`);
39064
39218
  }
39065
39219
  accumulator.deletedCount++;
@@ -39105,8 +39259,8 @@ function logCleanupSummary(deletedCount, preservedCount, dryRun, results) {
39105
39259
  async function cleanupCommandsDirectory(targetDir, isGlobal, options = {}) {
39106
39260
  const { dryRun = false } = options;
39107
39261
  validatePath(targetDir, "targetDir");
39108
- const claudeDir = isGlobal ? targetDir : join52(targetDir, ".claude");
39109
- const commandsDir = join52(claudeDir, "commands");
39262
+ const claudeDir = isGlobal ? targetDir : join53(targetDir, ".claude");
39263
+ const commandsDir = join53(claudeDir, "commands");
39110
39264
  const accumulator = {
39111
39265
  results: [],
39112
39266
  deletedCount: 0,
@@ -39118,7 +39272,7 @@ async function cleanupCommandsDirectory(targetDir, isGlobal, options = {}) {
39118
39272
  preservedCount: 0,
39119
39273
  wasDryRun: dryRun
39120
39274
  };
39121
- if (!await import_fs_extra17.pathExists(commandsDir)) {
39275
+ if (!await import_fs_extra18.pathExists(commandsDir)) {
39122
39276
  logger.verbose(`Commands directory does not exist: ${commandsDir}`);
39123
39277
  return result;
39124
39278
  }
@@ -39140,7 +39294,7 @@ async function cleanupCommandsDirectory(targetDir, isGlobal, options = {}) {
39140
39294
  return result;
39141
39295
  }
39142
39296
  for (const entry of entries) {
39143
- const entryPath = join52(commandsDir, entry);
39297
+ const entryPath = join53(commandsDir, entry);
39144
39298
  const stats = await lstat7(entryPath);
39145
39299
  if (stats.isSymbolicLink()) {
39146
39300
  addSymlinkSkip(entry, accumulator);
@@ -39169,7 +39323,7 @@ async function processDirectory(entryPath, entry, claudeDir, metadata, options,
39169
39323
  }
39170
39324
  }
39171
39325
  if (canDeleteDir && !dryRun) {
39172
- await import_fs_extra17.remove(entryPath);
39326
+ await import_fs_extra18.remove(entryPath);
39173
39327
  logger.verbose(`Removed directory: ${entry}`);
39174
39328
  }
39175
39329
  }
@@ -39184,7 +39338,7 @@ class CommandsPrefix {
39184
39338
  // src/commands/init/phases/merge-handler.ts
39185
39339
  init_logger();
39186
39340
  init_output_manager();
39187
- var import_fs_extra18 = __toESM(require_lib(), 1);
39341
+ var import_fs_extra19 = __toESM(require_lib(), 1);
39188
39342
  async function handleMerge(ctx) {
39189
39343
  if (ctx.cancelled || !ctx.extractDir || !ctx.resolvedDir || !ctx.claudeDir || !ctx.kit || !ctx.kitType) {
39190
39344
  return ctx;
@@ -39193,7 +39347,7 @@ async function handleMerge(ctx) {
39193
39347
  let customClaudeFiles = [];
39194
39348
  if (!ctx.options.fresh) {
39195
39349
  logger.info("Scanning for custom .claude files...");
39196
- const scanSourceDir = ctx.options.global ? join53(ctx.extractDir, ".claude") : ctx.extractDir;
39350
+ const scanSourceDir = ctx.options.global ? join54(ctx.extractDir, ".claude") : ctx.extractDir;
39197
39351
  const scanTargetSubdir = ctx.options.global ? "" : ".claude";
39198
39352
  customClaudeFiles = await FileScanner2.findCustomFiles(ctx.resolvedDir, scanSourceDir, scanTargetSubdir);
39199
39353
  } else {
@@ -39237,7 +39391,7 @@ async function handleMerge(ctx) {
39237
39391
  if (releaseManifest) {
39238
39392
  merger.setManifest(releaseManifest);
39239
39393
  }
39240
- if (!ctx.options.fresh && await import_fs_extra18.pathExists(ctx.claudeDir)) {
39394
+ if (!ctx.options.fresh && await import_fs_extra19.pathExists(ctx.claudeDir)) {
39241
39395
  const legacyDetection = await LegacyMigration.detectLegacy(ctx.claudeDir);
39242
39396
  if (legacyDetection.isLegacy && releaseManifest) {
39243
39397
  logger.info("Legacy installation detected - migrating to ownership tracking...");
@@ -39257,13 +39411,34 @@ async function handleMerge(ctx) {
39257
39411
  return { ...ctx, cancelled: true };
39258
39412
  }
39259
39413
  }
39260
- const sourceDir = ctx.options.global ? join53(ctx.extractDir, ".claude") : ctx.extractDir;
39414
+ const sourceDir = ctx.options.global ? join54(ctx.extractDir, ".claude") : ctx.extractDir;
39261
39415
  await merger.merge(sourceDir, ctx.resolvedDir, ctx.isNonInteractive);
39262
39416
  const fileConflicts = merger.getFileConflicts();
39263
39417
  if (fileConflicts.length > 0 && !ctx.isNonInteractive) {
39264
39418
  const summary = buildConflictSummary(fileConflicts, [], []);
39265
39419
  displayConflictSummary(summary);
39266
39420
  }
39421
+ try {
39422
+ const sourceMetadataPath = join54(sourceDir, "metadata.json");
39423
+ if (await import_fs_extra19.pathExists(sourceMetadataPath)) {
39424
+ const metadataContent = await import_fs_extra19.readFile(sourceMetadataPath, "utf-8");
39425
+ const sourceMetadata = JSON.parse(metadataContent);
39426
+ if (sourceMetadata.deletions && sourceMetadata.deletions.length > 0) {
39427
+ const deletionResult = await handleDeletions(sourceMetadata, ctx.claudeDir);
39428
+ if (deletionResult.deletedPaths.length > 0) {
39429
+ logger.info(`Removed ${deletionResult.deletedPaths.length} deprecated file(s)`);
39430
+ for (const path11 of deletionResult.deletedPaths) {
39431
+ logger.verbose(` - ${path11}`);
39432
+ }
39433
+ }
39434
+ if (deletionResult.preservedPaths.length > 0) {
39435
+ logger.verbose(`Preserved ${deletionResult.preservedPaths.length} user-owned file(s)`);
39436
+ }
39437
+ }
39438
+ }
39439
+ } catch (error) {
39440
+ logger.debug(`Cleanup of deprecated files failed: ${error}`);
39441
+ }
39267
39442
  const installedFiles = merger.getAllInstalledFiles();
39268
39443
  const filesToTrack = buildFileTrackingList({
39269
39444
  installedFiles,
@@ -39286,11 +39461,11 @@ async function handleMerge(ctx) {
39286
39461
  };
39287
39462
  }
39288
39463
  // src/commands/init/phases/migration-handler.ts
39289
- import { join as join61 } from "node:path";
39464
+ import { join as join62 } from "node:path";
39290
39465
 
39291
39466
  // src/domains/skills/skills-detector.ts
39292
39467
  init_logger();
39293
- var import_fs_extra21 = __toESM(require_lib(), 1);
39468
+ var import_fs_extra22 = __toESM(require_lib(), 1);
39294
39469
 
39295
39470
  // src/domains/skills/detection/config-detector.ts
39296
39471
  init_logger();
@@ -39298,17 +39473,17 @@ init_logger();
39298
39473
  // src/domains/skills/skills-manifest.ts
39299
39474
  init_logger();
39300
39475
  import { createHash as createHash2 } from "node:crypto";
39301
- import { readFile as readFile19, readdir as readdir15, writeFile as writeFile16 } from "node:fs/promises";
39302
- import { join as join54, relative as relative9 } from "node:path";
39476
+ import { readFile as readFile21, readdir as readdir15, writeFile as writeFile17 } from "node:fs/promises";
39477
+ import { join as join55, relative as relative9 } from "node:path";
39303
39478
  init_types2();
39304
- var import_fs_extra19 = __toESM(require_lib(), 1);
39479
+ var import_fs_extra20 = __toESM(require_lib(), 1);
39305
39480
 
39306
39481
  class SkillsManifestManager {
39307
39482
  static MANIFEST_FILENAME = ".skills-manifest.json";
39308
39483
  static MANIFEST_VERSION = "1.0.0";
39309
39484
  static async generateManifest(skillsDir) {
39310
39485
  logger.debug(`Generating manifest for: ${skillsDir}`);
39311
- if (!await import_fs_extra19.pathExists(skillsDir)) {
39486
+ if (!await import_fs_extra20.pathExists(skillsDir)) {
39312
39487
  throw new SkillsMigrationError(`Skills directory does not exist: ${skillsDir}`);
39313
39488
  }
39314
39489
  const structure = await SkillsManifestManager.detectStructure(skillsDir);
@@ -39323,18 +39498,18 @@ class SkillsManifestManager {
39323
39498
  return manifest;
39324
39499
  }
39325
39500
  static async writeManifest(skillsDir, manifest) {
39326
- const manifestPath = join54(skillsDir, SkillsManifestManager.MANIFEST_FILENAME);
39327
- await writeFile16(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
39501
+ const manifestPath = join55(skillsDir, SkillsManifestManager.MANIFEST_FILENAME);
39502
+ await writeFile17(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
39328
39503
  logger.debug(`Wrote manifest to: ${manifestPath}`);
39329
39504
  }
39330
39505
  static async readManifest(skillsDir) {
39331
- const manifestPath = join54(skillsDir, SkillsManifestManager.MANIFEST_FILENAME);
39332
- if (!await import_fs_extra19.pathExists(manifestPath)) {
39506
+ const manifestPath = join55(skillsDir, SkillsManifestManager.MANIFEST_FILENAME);
39507
+ if (!await import_fs_extra20.pathExists(manifestPath)) {
39333
39508
  logger.debug(`No manifest found at: ${manifestPath}`);
39334
39509
  return null;
39335
39510
  }
39336
39511
  try {
39337
- const content = await readFile19(manifestPath, "utf-8");
39512
+ const content = await readFile21(manifestPath, "utf-8");
39338
39513
  const data = JSON.parse(content);
39339
39514
  const manifest = SkillsManifestSchema.parse(data);
39340
39515
  logger.debug(`Read manifest from: ${manifestPath}`);
@@ -39351,7 +39526,7 @@ class SkillsManifestManager {
39351
39526
  return "flat";
39352
39527
  }
39353
39528
  for (const dir of dirs.slice(0, 3)) {
39354
- const dirPath = join54(skillsDir, dir.name);
39529
+ const dirPath = join55(skillsDir, dir.name);
39355
39530
  const subEntries = await readdir15(dirPath, { withFileTypes: true });
39356
39531
  const hasSubdirs = subEntries.some((entry) => entry.isDirectory());
39357
39532
  if (hasSubdirs) {
@@ -39370,7 +39545,7 @@ class SkillsManifestManager {
39370
39545
  const entries = await readdir15(skillsDir, { withFileTypes: true });
39371
39546
  for (const entry of entries) {
39372
39547
  if (entry.isDirectory() && !BUILD_ARTIFACT_DIRS.includes(entry.name) && !entry.name.startsWith(".")) {
39373
- const skillPath = join54(skillsDir, entry.name);
39548
+ const skillPath = join55(skillsDir, entry.name);
39374
39549
  const hash = await SkillsManifestManager.hashDirectory(skillPath);
39375
39550
  skills.push({
39376
39551
  name: entry.name,
@@ -39382,11 +39557,11 @@ class SkillsManifestManager {
39382
39557
  const categories = await readdir15(skillsDir, { withFileTypes: true });
39383
39558
  for (const category of categories) {
39384
39559
  if (category.isDirectory() && !BUILD_ARTIFACT_DIRS.includes(category.name) && !category.name.startsWith(".")) {
39385
- const categoryPath = join54(skillsDir, category.name);
39560
+ const categoryPath = join55(skillsDir, category.name);
39386
39561
  const skillEntries = await readdir15(categoryPath, { withFileTypes: true });
39387
39562
  for (const skillEntry of skillEntries) {
39388
39563
  if (skillEntry.isDirectory() && !skillEntry.name.startsWith(".")) {
39389
- const skillPath = join54(categoryPath, skillEntry.name);
39564
+ const skillPath = join55(categoryPath, skillEntry.name);
39390
39565
  const hash = await SkillsManifestManager.hashDirectory(skillPath);
39391
39566
  skills.push({
39392
39567
  name: skillEntry.name,
@@ -39406,7 +39581,7 @@ class SkillsManifestManager {
39406
39581
  files.sort();
39407
39582
  for (const file of files) {
39408
39583
  const relativePath = relative9(dirPath, file);
39409
- const content = await readFile19(file);
39584
+ const content = await readFile21(file);
39410
39585
  hash.update(relativePath);
39411
39586
  hash.update(content);
39412
39587
  }
@@ -39416,7 +39591,7 @@ class SkillsManifestManager {
39416
39591
  const files = [];
39417
39592
  const entries = await readdir15(dirPath, { withFileTypes: true });
39418
39593
  for (const entry of entries) {
39419
- const fullPath = join54(dirPath, entry.name);
39594
+ const fullPath = join55(dirPath, entry.name);
39420
39595
  if (entry.name.startsWith(".") || BUILD_ARTIFACT_DIRS.includes(entry.name)) {
39421
39596
  continue;
39422
39597
  }
@@ -39536,11 +39711,11 @@ function getPathMapping(skillName, oldBasePath, newBasePath) {
39536
39711
  }
39537
39712
 
39538
39713
  // src/domains/skills/detection/script-detector.ts
39539
- var import_fs_extra20 = __toESM(require_lib(), 1);
39714
+ var import_fs_extra21 = __toESM(require_lib(), 1);
39540
39715
  import { readdir as readdir16 } from "node:fs/promises";
39541
- import { join as join55 } from "node:path";
39716
+ import { join as join56 } from "node:path";
39542
39717
  async function scanDirectory(skillsDir) {
39543
- if (!await import_fs_extra20.pathExists(skillsDir)) {
39718
+ if (!await import_fs_extra21.pathExists(skillsDir)) {
39544
39719
  return ["flat", []];
39545
39720
  }
39546
39721
  const entries = await readdir16(skillsDir, { withFileTypes: true });
@@ -39551,12 +39726,12 @@ async function scanDirectory(skillsDir) {
39551
39726
  let totalSkillLikeCount = 0;
39552
39727
  const allSkills = [];
39553
39728
  for (const dir of dirs) {
39554
- const dirPath = join55(skillsDir, dir.name);
39729
+ const dirPath = join56(skillsDir, dir.name);
39555
39730
  const subEntries = await readdir16(dirPath, { withFileTypes: true });
39556
39731
  const subdirs = subEntries.filter((entry) => entry.isDirectory() && !entry.name.startsWith("."));
39557
39732
  if (subdirs.length > 0) {
39558
39733
  for (const subdir of subdirs.slice(0, 3)) {
39559
- const subdirPath = join55(dirPath, subdir.name);
39734
+ const subdirPath = join56(dirPath, subdir.name);
39560
39735
  const subdirFiles = await readdir16(subdirPath, { withFileTypes: true });
39561
39736
  const hasSkillMarker = subdirFiles.some((file) => file.isFile() && (file.name === "skill.md" || file.name === "README.md" || file.name === "readme.md" || file.name === "config.json" || file.name === "package.json"));
39562
39737
  if (hasSkillMarker) {
@@ -39678,8 +39853,8 @@ async function detectViaManifest(oldSkillsDir, currentSkillsDir) {
39678
39853
  class SkillsMigrationDetector {
39679
39854
  static async detectMigration(oldSkillsDir, currentSkillsDir) {
39680
39855
  logger.debug("Detecting skills migration need...");
39681
- const oldExists = await import_fs_extra21.pathExists(oldSkillsDir);
39682
- const currentExists = await import_fs_extra21.pathExists(currentSkillsDir);
39856
+ const oldExists = await import_fs_extra22.pathExists(oldSkillsDir);
39857
+ const currentExists = await import_fs_extra22.pathExists(currentSkillsDir);
39683
39858
  if (!oldExists && !currentExists) {
39684
39859
  logger.debug("No skills directories found, migration not needed");
39685
39860
  return {
@@ -39713,13 +39888,13 @@ class SkillsMigrationDetector {
39713
39888
  // src/domains/skills/skills-migrator.ts
39714
39889
  init_logger();
39715
39890
  init_types2();
39716
- import { join as join60 } from "node:path";
39891
+ import { join as join61 } from "node:path";
39717
39892
 
39718
39893
  // src/domains/skills/migrator/migration-executor.ts
39719
39894
  init_logger();
39720
39895
  import { copyFile as copyFile4, mkdir as mkdir17, readdir as readdir17, rm as rm3 } from "node:fs/promises";
39721
- import { join as join56 } from "node:path";
39722
- var import_fs_extra22 = __toESM(require_lib(), 1);
39896
+ import { join as join57 } from "node:path";
39897
+ var import_fs_extra23 = __toESM(require_lib(), 1);
39723
39898
 
39724
39899
  // src/domains/skills/skills-migration-prompts.ts
39725
39900
  init_environment();
@@ -39883,8 +40058,8 @@ async function copySkillDirectory(sourceDir, destDir) {
39883
40058
  await mkdir17(destDir, { recursive: true });
39884
40059
  const entries = await readdir17(sourceDir, { withFileTypes: true });
39885
40060
  for (const entry of entries) {
39886
- const sourcePath = join56(sourceDir, entry.name);
39887
- const destPath = join56(destDir, entry.name);
40061
+ const sourcePath = join57(sourceDir, entry.name);
40062
+ const destPath = join57(destDir, entry.name);
39888
40063
  if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.isSymbolicLink()) {
39889
40064
  continue;
39890
40065
  }
@@ -39899,14 +40074,14 @@ async function executeInternal(mappings, customizations, currentSkillsDir, inter
39899
40074
  const migrated = [];
39900
40075
  const preserved = [];
39901
40076
  const errors2 = [];
39902
- const tempDir = join56(currentSkillsDir, "..", ".skills-migration-temp");
40077
+ const tempDir = join57(currentSkillsDir, "..", ".skills-migration-temp");
39903
40078
  await mkdir17(tempDir, { recursive: true });
39904
40079
  try {
39905
40080
  for (const mapping of mappings) {
39906
40081
  try {
39907
40082
  const skillName = mapping.skillName;
39908
40083
  const currentSkillPath = mapping.oldPath;
39909
- if (!await import_fs_extra22.pathExists(currentSkillPath)) {
40084
+ if (!await import_fs_extra23.pathExists(currentSkillPath)) {
39910
40085
  logger.warning(`Skill not found, skipping: ${skillName}`);
39911
40086
  continue;
39912
40087
  }
@@ -39920,9 +40095,9 @@ async function executeInternal(mappings, customizations, currentSkillsDir, inter
39920
40095
  }
39921
40096
  }
39922
40097
  const category = mapping.category;
39923
- const targetPath = category ? join56(tempDir, category, skillName) : join56(tempDir, skillName);
40098
+ const targetPath = category ? join57(tempDir, category, skillName) : join57(tempDir, skillName);
39924
40099
  if (category) {
39925
- await mkdir17(join56(tempDir, category), { recursive: true });
40100
+ await mkdir17(join57(tempDir, category), { recursive: true });
39926
40101
  }
39927
40102
  await copySkillDirectory(currentSkillPath, targetPath);
39928
40103
  migrated.push(skillName);
@@ -39987,9 +40162,9 @@ function validateMigrationPath(path11, paramName) {
39987
40162
  // src/domains/skills/skills-backup-manager.ts
39988
40163
  init_logger();
39989
40164
  init_types2();
39990
- var import_fs_extra23 = __toESM(require_lib(), 1);
40165
+ var import_fs_extra24 = __toESM(require_lib(), 1);
39991
40166
  import { copyFile as copyFile5, mkdir as mkdir18, readdir as readdir18, rm as rm4, stat as stat9 } from "node:fs/promises";
39992
- import { basename as basename2, join as join57, normalize as normalize6 } from "node:path";
40167
+ import { basename as basename2, join as join58, normalize as normalize6 } from "node:path";
39993
40168
  function validatePath2(path11, paramName) {
39994
40169
  if (!path11 || typeof path11 !== "string") {
39995
40170
  throw new SkillsMigrationError(`${paramName} must be a non-empty string`);
@@ -40009,13 +40184,13 @@ class SkillsBackupManager {
40009
40184
  if (parentDir) {
40010
40185
  validatePath2(parentDir, "parentDir");
40011
40186
  }
40012
- if (!await import_fs_extra23.pathExists(skillsDir)) {
40187
+ if (!await import_fs_extra24.pathExists(skillsDir)) {
40013
40188
  throw new SkillsMigrationError(`Cannot create backup: Skills directory does not exist: ${skillsDir}`);
40014
40189
  }
40015
40190
  const timestamp = Date.now();
40016
40191
  const randomSuffix = Math.random().toString(36).substring(2, 8);
40017
40192
  const backupDirName = `${SkillsBackupManager.BACKUP_PREFIX}${timestamp}-${randomSuffix}`;
40018
- const backupDir = parentDir ? join57(parentDir, backupDirName) : join57(skillsDir, "..", backupDirName);
40193
+ const backupDir = parentDir ? join58(parentDir, backupDirName) : join58(skillsDir, "..", backupDirName);
40019
40194
  logger.info(`Creating backup at: ${backupDir}`);
40020
40195
  try {
40021
40196
  await mkdir18(backupDir, { recursive: true });
@@ -40032,12 +40207,12 @@ class SkillsBackupManager {
40032
40207
  static async restoreBackup(backupDir, targetDir) {
40033
40208
  validatePath2(backupDir, "backupDir");
40034
40209
  validatePath2(targetDir, "targetDir");
40035
- if (!await import_fs_extra23.pathExists(backupDir)) {
40210
+ if (!await import_fs_extra24.pathExists(backupDir)) {
40036
40211
  throw new SkillsMigrationError(`Cannot restore: Backup directory does not exist: ${backupDir}`);
40037
40212
  }
40038
40213
  logger.info(`Restoring from backup: ${backupDir}`);
40039
40214
  try {
40040
- if (await import_fs_extra23.pathExists(targetDir)) {
40215
+ if (await import_fs_extra24.pathExists(targetDir)) {
40041
40216
  await rm4(targetDir, { recursive: true, force: true });
40042
40217
  }
40043
40218
  await mkdir18(targetDir, { recursive: true });
@@ -40048,7 +40223,7 @@ class SkillsBackupManager {
40048
40223
  }
40049
40224
  }
40050
40225
  static async deleteBackup(backupDir) {
40051
- if (!await import_fs_extra23.pathExists(backupDir)) {
40226
+ if (!await import_fs_extra24.pathExists(backupDir)) {
40052
40227
  logger.warning(`Backup directory does not exist: ${backupDir}`);
40053
40228
  return;
40054
40229
  }
@@ -40061,12 +40236,12 @@ class SkillsBackupManager {
40061
40236
  }
40062
40237
  }
40063
40238
  static async listBackups(parentDir) {
40064
- if (!await import_fs_extra23.pathExists(parentDir)) {
40239
+ if (!await import_fs_extra24.pathExists(parentDir)) {
40065
40240
  return [];
40066
40241
  }
40067
40242
  try {
40068
40243
  const entries = await readdir18(parentDir, { withFileTypes: true });
40069
- const backups = entries.filter((entry) => entry.isDirectory() && entry.name.startsWith(SkillsBackupManager.BACKUP_PREFIX)).map((entry) => join57(parentDir, entry.name));
40244
+ const backups = entries.filter((entry) => entry.isDirectory() && entry.name.startsWith(SkillsBackupManager.BACKUP_PREFIX)).map((entry) => join58(parentDir, entry.name));
40070
40245
  backups.sort().reverse();
40071
40246
  return backups;
40072
40247
  } catch (error) {
@@ -40086,7 +40261,7 @@ class SkillsBackupManager {
40086
40261
  }
40087
40262
  }
40088
40263
  static async getBackupSize(backupDir) {
40089
- if (!await import_fs_extra23.pathExists(backupDir)) {
40264
+ if (!await import_fs_extra24.pathExists(backupDir)) {
40090
40265
  return 0;
40091
40266
  }
40092
40267
  return await SkillsBackupManager.getDirectorySize(backupDir);
@@ -40094,8 +40269,8 @@ class SkillsBackupManager {
40094
40269
  static async copyDirectory(sourceDir, destDir) {
40095
40270
  const entries = await readdir18(sourceDir, { withFileTypes: true });
40096
40271
  for (const entry of entries) {
40097
- const sourcePath = join57(sourceDir, entry.name);
40098
- const destPath = join57(destDir, entry.name);
40272
+ const sourcePath = join58(sourceDir, entry.name);
40273
+ const destPath = join58(destDir, entry.name);
40099
40274
  if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.isSymbolicLink()) {
40100
40275
  continue;
40101
40276
  }
@@ -40111,7 +40286,7 @@ class SkillsBackupManager {
40111
40286
  let size = 0;
40112
40287
  const entries = await readdir18(dirPath, { withFileTypes: true });
40113
40288
  for (const entry of entries) {
40114
- const fullPath = join57(dirPath, entry.name);
40289
+ const fullPath = join58(dirPath, entry.name);
40115
40290
  if (entry.isSymbolicLink()) {
40116
40291
  continue;
40117
40292
  }
@@ -40139,19 +40314,19 @@ class SkillsBackupManager {
40139
40314
  init_logger();
40140
40315
 
40141
40316
  // src/domains/skills/customization/comparison-engine.ts
40142
- var import_fs_extra24 = __toESM(require_lib(), 1);
40317
+ var import_fs_extra25 = __toESM(require_lib(), 1);
40143
40318
  import { relative as relative11 } from "node:path";
40144
40319
 
40145
40320
  // src/domains/skills/customization/hash-calculator.ts
40146
40321
  import { createHash as createHash3 } from "node:crypto";
40147
40322
  import { createReadStream as createReadStream2 } from "node:fs";
40148
- import { readFile as readFile20, readdir as readdir19 } from "node:fs/promises";
40149
- import { join as join58, relative as relative10 } from "node:path";
40323
+ import { readFile as readFile22, readdir as readdir19 } from "node:fs/promises";
40324
+ import { join as join59, relative as relative10 } from "node:path";
40150
40325
  async function getAllFiles(dirPath) {
40151
40326
  const files = [];
40152
40327
  const entries = await readdir19(dirPath, { withFileTypes: true });
40153
40328
  for (const entry of entries) {
40154
- const fullPath = join58(dirPath, entry.name);
40329
+ const fullPath = join59(dirPath, entry.name);
40155
40330
  if (entry.name.startsWith(".") || BUILD_ARTIFACT_DIRS.includes(entry.name) || entry.isSymbolicLink()) {
40156
40331
  continue;
40157
40332
  }
@@ -40165,12 +40340,12 @@ async function getAllFiles(dirPath) {
40165
40340
  return files;
40166
40341
  }
40167
40342
  async function hashFile(filePath) {
40168
- return new Promise((resolve7, reject) => {
40343
+ return new Promise((resolve8, reject) => {
40169
40344
  const hash = createHash3("sha256");
40170
40345
  const stream = createReadStream2(filePath);
40171
40346
  stream.on("data", (chunk) => hash.update(chunk));
40172
40347
  stream.on("end", () => {
40173
- resolve7(hash.digest("hex"));
40348
+ resolve8(hash.digest("hex"));
40174
40349
  });
40175
40350
  stream.on("error", (error) => {
40176
40351
  stream.destroy();
@@ -40184,7 +40359,7 @@ async function hashDirectory(dirPath) {
40184
40359
  files.sort();
40185
40360
  for (const file of files) {
40186
40361
  const relativePath = relative10(dirPath, file);
40187
- const content = await readFile20(file);
40362
+ const content = await readFile22(file);
40188
40363
  hash.update(relativePath);
40189
40364
  hash.update(content);
40190
40365
  }
@@ -40234,7 +40409,7 @@ async function compareDirectories(dir1, dir2) {
40234
40409
  async function detectFileChanges(currentSkillPath, baselineSkillPath) {
40235
40410
  const changes = [];
40236
40411
  const currentFiles = await getAllFiles(currentSkillPath);
40237
- const baselineFiles = await import_fs_extra24.pathExists(baselineSkillPath) ? await getAllFiles(baselineSkillPath) : [];
40412
+ const baselineFiles = await import_fs_extra25.pathExists(baselineSkillPath) ? await getAllFiles(baselineSkillPath) : [];
40238
40413
  const currentFileMap = new Map(await Promise.all(currentFiles.map(async (f3) => {
40239
40414
  const relPath = relative11(currentSkillPath, f3);
40240
40415
  const hash = await hashFile(f3);
@@ -40276,9 +40451,9 @@ async function detectFileChanges(currentSkillPath, baselineSkillPath) {
40276
40451
 
40277
40452
  // src/domains/skills/customization/scan-reporter.ts
40278
40453
  init_types2();
40279
- var import_fs_extra25 = __toESM(require_lib(), 1);
40454
+ var import_fs_extra26 = __toESM(require_lib(), 1);
40280
40455
  import { readdir as readdir20 } from "node:fs/promises";
40281
- import { join as join59, normalize as normalize7 } from "node:path";
40456
+ import { join as join60, normalize as normalize7 } from "node:path";
40282
40457
  function validatePath3(path11, paramName) {
40283
40458
  if (!path11 || typeof path11 !== "string") {
40284
40459
  throw new SkillsMigrationError(`${paramName} must be a non-empty string`);
@@ -40291,7 +40466,7 @@ function validatePath3(path11, paramName) {
40291
40466
  }
40292
40467
  }
40293
40468
  async function scanSkillsDirectory(skillsDir) {
40294
- if (!await import_fs_extra25.pathExists(skillsDir)) {
40469
+ if (!await import_fs_extra26.pathExists(skillsDir)) {
40295
40470
  return ["flat", []];
40296
40471
  }
40297
40472
  const entries = await readdir20(skillsDir, { withFileTypes: true });
@@ -40299,13 +40474,13 @@ async function scanSkillsDirectory(skillsDir) {
40299
40474
  if (dirs.length === 0) {
40300
40475
  return ["flat", []];
40301
40476
  }
40302
- const firstDirPath = join59(skillsDir, dirs[0].name);
40477
+ const firstDirPath = join60(skillsDir, dirs[0].name);
40303
40478
  const subEntries = await readdir20(firstDirPath, { withFileTypes: true });
40304
40479
  const subdirs = subEntries.filter((entry) => entry.isDirectory() && !entry.name.startsWith("."));
40305
40480
  if (subdirs.length > 0) {
40306
40481
  let skillLikeCount = 0;
40307
40482
  for (const subdir of subdirs.slice(0, 3)) {
40308
- const subdirPath = join59(firstDirPath, subdir.name);
40483
+ const subdirPath = join60(firstDirPath, subdir.name);
40309
40484
  const subdirFiles = await readdir20(subdirPath, { withFileTypes: true });
40310
40485
  const hasSkillMarker = subdirFiles.some((file) => file.isFile() && (file.name === "skill.md" || file.name === "README.md" || file.name === "readme.md" || file.name === "config.json" || file.name === "package.json"));
40311
40486
  if (hasSkillMarker) {
@@ -40315,7 +40490,7 @@ async function scanSkillsDirectory(skillsDir) {
40315
40490
  if (skillLikeCount > 0) {
40316
40491
  const skills = [];
40317
40492
  for (const dir of dirs) {
40318
- const categoryPath = join59(skillsDir, dir.name);
40493
+ const categoryPath = join60(skillsDir, dir.name);
40319
40494
  const skillDirs = await readdir20(categoryPath, { withFileTypes: true });
40320
40495
  skills.push(...skillDirs.filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name));
40321
40496
  }
@@ -40325,8 +40500,8 @@ async function scanSkillsDirectory(skillsDir) {
40325
40500
  return ["flat", dirs.map((dir) => dir.name)];
40326
40501
  }
40327
40502
  async function findSkillPath(skillsDir, skillName) {
40328
- const flatPath = join59(skillsDir, skillName);
40329
- if (await import_fs_extra25.pathExists(flatPath)) {
40503
+ const flatPath = join60(skillsDir, skillName);
40504
+ if (await import_fs_extra26.pathExists(flatPath)) {
40330
40505
  return { path: flatPath, category: undefined };
40331
40506
  }
40332
40507
  const entries = await readdir20(skillsDir, { withFileTypes: true });
@@ -40334,9 +40509,9 @@ async function findSkillPath(skillsDir, skillName) {
40334
40509
  if (!entry.isDirectory() || entry.name.startsWith(".") || entry.name === "node_modules") {
40335
40510
  continue;
40336
40511
  }
40337
- const categoryPath = join59(skillsDir, entry.name);
40338
- const skillPath = join59(categoryPath, skillName);
40339
- if (await import_fs_extra25.pathExists(skillPath)) {
40512
+ const categoryPath = join60(skillsDir, entry.name);
40513
+ const skillPath = join60(categoryPath, skillName);
40514
+ if (await import_fs_extra26.pathExists(skillPath)) {
40340
40515
  return { path: skillPath, category: entry.name };
40341
40516
  }
40342
40517
  }
@@ -40429,7 +40604,7 @@ class SkillsMigrator {
40429
40604
  }
40430
40605
  }
40431
40606
  if (options.backup && !options.dryRun) {
40432
- const claudeDir = join60(currentSkillsDir, "..");
40607
+ const claudeDir = join61(currentSkillsDir, "..");
40433
40608
  result.backupPath = await SkillsBackupManager.createBackup(currentSkillsDir, claudeDir);
40434
40609
  logger.success(`Backup created at: ${result.backupPath}`);
40435
40610
  }
@@ -40482,7 +40657,7 @@ class SkillsMigrator {
40482
40657
  // src/commands/init/phases/migration-handler.ts
40483
40658
  init_logger();
40484
40659
  init_path_resolver();
40485
- var import_fs_extra26 = __toESM(require_lib(), 1);
40660
+ var import_fs_extra27 = __toESM(require_lib(), 1);
40486
40661
  async function handleMigration(ctx) {
40487
40662
  if (ctx.cancelled || !ctx.extractDir || !ctx.resolvedDir)
40488
40663
  return ctx;
@@ -40490,9 +40665,9 @@ async function handleMigration(ctx) {
40490
40665
  logger.debug("Skipping skills migration (fresh installation)");
40491
40666
  return ctx;
40492
40667
  }
40493
- const newSkillsDir = join61(ctx.extractDir, ".claude", "skills");
40668
+ const newSkillsDir = join62(ctx.extractDir, ".claude", "skills");
40494
40669
  const currentSkillsDir = PathResolver.buildSkillsPath(ctx.resolvedDir, ctx.options.global);
40495
- if (!await import_fs_extra26.pathExists(newSkillsDir) || !await import_fs_extra26.pathExists(currentSkillsDir)) {
40670
+ if (!await import_fs_extra27.pathExists(newSkillsDir) || !await import_fs_extra27.pathExists(currentSkillsDir)) {
40496
40671
  return ctx;
40497
40672
  }
40498
40673
  logger.info("Checking for skills directory migration...");
@@ -40514,13 +40689,13 @@ async function handleMigration(ctx) {
40514
40689
  }
40515
40690
  // src/commands/init/phases/opencode-handler.ts
40516
40691
  import { cp, readdir as readdir22, rm as rm5 } from "node:fs/promises";
40517
- import { join as join63 } from "node:path";
40692
+ import { join as join64 } from "node:path";
40518
40693
 
40519
40694
  // src/services/transformers/opencode-path-transformer.ts
40520
40695
  init_logger();
40521
- import { readFile as readFile21, readdir as readdir21, writeFile as writeFile17 } from "node:fs/promises";
40696
+ import { readFile as readFile23, readdir as readdir21, writeFile as writeFile18 } from "node:fs/promises";
40522
40697
  import { platform as platform10 } from "node:os";
40523
- import { extname as extname2, join as join62 } from "node:path";
40698
+ import { extname as extname2, join as join63 } from "node:path";
40524
40699
  var IS_WINDOWS3 = platform10() === "win32";
40525
40700
  function getOpenCodeGlobalPath() {
40526
40701
  return "$HOME/.config/opencode/";
@@ -40581,7 +40756,7 @@ async function transformPathsForGlobalOpenCode(directory, options = {}) {
40581
40756
  async function processDirectory2(dir) {
40582
40757
  const entries = await readdir21(dir, { withFileTypes: true });
40583
40758
  for (const entry of entries) {
40584
- const fullPath = join62(dir, entry.name);
40759
+ const fullPath = join63(dir, entry.name);
40585
40760
  if (entry.isDirectory()) {
40586
40761
  if (entry.name === "node_modules" || entry.name.startsWith(".")) {
40587
40762
  continue;
@@ -40589,10 +40764,10 @@ async function transformPathsForGlobalOpenCode(directory, options = {}) {
40589
40764
  await processDirectory2(fullPath);
40590
40765
  } else if (entry.isFile() && shouldTransformFile2(entry.name)) {
40591
40766
  try {
40592
- const content = await readFile21(fullPath, "utf-8");
40767
+ const content = await readFile23(fullPath, "utf-8");
40593
40768
  const { transformed, changes } = transformOpenCodeContent(content);
40594
40769
  if (changes > 0) {
40595
- await writeFile17(fullPath, transformed, "utf-8");
40770
+ await writeFile18(fullPath, transformed, "utf-8");
40596
40771
  filesTransformed++;
40597
40772
  totalChanges += changes;
40598
40773
  if (options.verbose) {
@@ -40615,13 +40790,13 @@ async function transformPathsForGlobalOpenCode(directory, options = {}) {
40615
40790
  // src/commands/init/phases/opencode-handler.ts
40616
40791
  init_logger();
40617
40792
  init_path_resolver();
40618
- var import_fs_extra27 = __toESM(require_lib(), 1);
40793
+ var import_fs_extra28 = __toESM(require_lib(), 1);
40619
40794
  async function handleOpenCode(ctx) {
40620
40795
  if (ctx.cancelled || !ctx.extractDir || !ctx.resolvedDir) {
40621
40796
  return ctx;
40622
40797
  }
40623
- const openCodeSource = join63(ctx.extractDir, ".opencode");
40624
- if (!await import_fs_extra27.pathExists(openCodeSource)) {
40798
+ const openCodeSource = join64(ctx.extractDir, ".opencode");
40799
+ if (!await import_fs_extra28.pathExists(openCodeSource)) {
40625
40800
  logger.debug("No .opencode directory in archive, skipping");
40626
40801
  return ctx;
40627
40802
  }
@@ -40635,12 +40810,12 @@ async function handleOpenCode(ctx) {
40635
40810
  if (transformResult.totalChanges > 0) {
40636
40811
  logger.success(`Transformed ${transformResult.totalChanges} OpenCode path(s) in ${transformResult.filesTransformed} file(s)`);
40637
40812
  }
40638
- await import_fs_extra27.ensureDir(targetDir);
40813
+ await import_fs_extra28.ensureDir(targetDir);
40639
40814
  const entries = await readdir22(openCodeSource, { withFileTypes: true });
40640
40815
  for (const entry of entries) {
40641
- const sourcePath = join63(openCodeSource, entry.name);
40642
- const targetPath = join63(targetDir, entry.name);
40643
- if (await import_fs_extra27.pathExists(targetPath)) {
40816
+ const sourcePath = join64(openCodeSource, entry.name);
40817
+ const targetPath = join64(targetDir, entry.name);
40818
+ if (await import_fs_extra28.pathExists(targetPath)) {
40644
40819
  if (!ctx.options.forceOverwrite) {
40645
40820
  logger.verbose(`Skipping existing: ${entry.name}`);
40646
40821
  continue;
@@ -40660,18 +40835,18 @@ async function handleOpenCode(ctx) {
40660
40835
  init_logger();
40661
40836
  init_path_resolver();
40662
40837
  init_types2();
40663
- import { existsSync as existsSync18 } from "node:fs";
40664
- import { mkdir as mkdir19, readFile as readFile22, rename as rename2, rm as rm6, writeFile as writeFile18 } from "node:fs/promises";
40838
+ import { existsSync as existsSync19 } from "node:fs";
40839
+ import { mkdir as mkdir19, readFile as readFile24, rename as rename2, rm as rm6, writeFile as writeFile19 } from "node:fs/promises";
40665
40840
  import { chmod as chmod2 } from "node:fs/promises";
40666
40841
  import { platform as platform11 } from "node:os";
40667
- import { join as join64 } from "node:path";
40842
+ import { join as join65 } from "node:path";
40668
40843
  var PROJECT_CONFIG_FILE = ".ck.json";
40669
40844
 
40670
40845
  class ConfigManager {
40671
40846
  static config = null;
40672
40847
  static globalFlag = false;
40673
40848
  static getProjectConfigDir(projectDir, global3) {
40674
- return global3 ? projectDir : join64(projectDir, ".claude");
40849
+ return global3 ? projectDir : join65(projectDir, ".claude");
40675
40850
  }
40676
40851
  static setGlobalFlag(global3) {
40677
40852
  ConfigManager.globalFlag = global3;
@@ -40686,8 +40861,8 @@ class ConfigManager {
40686
40861
  }
40687
40862
  const configFile = PathResolver.getConfigFile(ConfigManager.globalFlag);
40688
40863
  try {
40689
- if (existsSync18(configFile)) {
40690
- const content = await readFile22(configFile, "utf-8");
40864
+ if (existsSync19(configFile)) {
40865
+ const content = await readFile24(configFile, "utf-8");
40691
40866
  const data = JSON.parse(content);
40692
40867
  ConfigManager.config = ConfigSchema.parse(data);
40693
40868
  logger.debug(`Config loaded from ${configFile}`);
@@ -40704,13 +40879,13 @@ class ConfigManager {
40704
40879
  const validConfig = ConfigSchema.parse(config);
40705
40880
  const configDir = PathResolver.getConfigDir(ConfigManager.globalFlag);
40706
40881
  const configFile = PathResolver.getConfigFile(ConfigManager.globalFlag);
40707
- if (!existsSync18(configDir)) {
40882
+ if (!existsSync19(configDir)) {
40708
40883
  await mkdir19(configDir, { recursive: true });
40709
40884
  if (platform11() !== "win32") {
40710
40885
  await chmod2(configDir, 448);
40711
40886
  }
40712
40887
  }
40713
- await writeFile18(configFile, JSON.stringify(validConfig, null, 2), "utf-8");
40888
+ await writeFile19(configFile, JSON.stringify(validConfig, null, 2), "utf-8");
40714
40889
  if (platform11() !== "win32") {
40715
40890
  await chmod2(configFile, 384);
40716
40891
  }
@@ -40738,10 +40913,10 @@ class ConfigManager {
40738
40913
  }
40739
40914
  static async loadProjectConfig(projectDir, global3 = false) {
40740
40915
  const configDir = ConfigManager.getProjectConfigDir(projectDir, global3);
40741
- const configPath = join64(configDir, PROJECT_CONFIG_FILE);
40916
+ const configPath = join65(configDir, PROJECT_CONFIG_FILE);
40742
40917
  try {
40743
- if (existsSync18(configPath)) {
40744
- const content = await readFile22(configPath, "utf-8");
40918
+ if (existsSync19(configPath)) {
40919
+ const content = await readFile24(configPath, "utf-8");
40745
40920
  const data = JSON.parse(content);
40746
40921
  const folders = FoldersConfigSchema.parse(data.paths || data);
40747
40922
  logger.debug(`Project config loaded from ${configPath}`);
@@ -40754,15 +40929,15 @@ class ConfigManager {
40754
40929
  }
40755
40930
  static async saveProjectConfig(projectDir, folders, global3 = false) {
40756
40931
  const configDir = ConfigManager.getProjectConfigDir(projectDir, global3);
40757
- const configPath = join64(configDir, PROJECT_CONFIG_FILE);
40932
+ const configPath = join65(configDir, PROJECT_CONFIG_FILE);
40758
40933
  try {
40759
- if (!existsSync18(configDir)) {
40934
+ if (!existsSync19(configDir)) {
40760
40935
  await mkdir19(configDir, { recursive: true });
40761
40936
  }
40762
40937
  let existingConfig = {};
40763
- if (existsSync18(configPath)) {
40938
+ if (existsSync19(configPath)) {
40764
40939
  try {
40765
- const content = await readFile22(configPath, "utf-8");
40940
+ const content = await readFile24(configPath, "utf-8");
40766
40941
  existingConfig = JSON.parse(content);
40767
40942
  } catch (error) {
40768
40943
  logger.debug(`Could not parse existing config, starting fresh: ${error instanceof Error ? error.message : "Unknown error"}`);
@@ -40777,7 +40952,7 @@ class ConfigManager {
40777
40952
  ...validFolders
40778
40953
  }
40779
40954
  };
40780
- await writeFile18(configPath, JSON.stringify(mergedConfig, null, 2), "utf-8");
40955
+ await writeFile19(configPath, JSON.stringify(mergedConfig, null, 2), "utf-8");
40781
40956
  logger.debug(`Project config saved to ${configPath}`);
40782
40957
  } catch (error) {
40783
40958
  throw new Error(`Failed to save project config: ${error instanceof Error ? error.message : "Unknown error"}`);
@@ -40803,21 +40978,21 @@ class ConfigManager {
40803
40978
  }
40804
40979
  static projectConfigExists(projectDir, global3 = false) {
40805
40980
  const configDir = ConfigManager.getProjectConfigDir(projectDir, global3);
40806
- return existsSync18(join64(configDir, PROJECT_CONFIG_FILE));
40981
+ return existsSync19(join65(configDir, PROJECT_CONFIG_FILE));
40807
40982
  }
40808
40983
  static async migrateNestedConfig(globalDir) {
40809
- const correctPath = join64(globalDir, PROJECT_CONFIG_FILE);
40810
- const incorrectPath = join64(globalDir, ".claude", PROJECT_CONFIG_FILE);
40811
- if (existsSync18(correctPath)) {
40984
+ const correctPath = join65(globalDir, PROJECT_CONFIG_FILE);
40985
+ const incorrectPath = join65(globalDir, ".claude", PROJECT_CONFIG_FILE);
40986
+ if (existsSync19(correctPath)) {
40812
40987
  logger.debug("Config already exists at correct location, skipping migration");
40813
40988
  return false;
40814
40989
  }
40815
- if (existsSync18(incorrectPath)) {
40990
+ if (existsSync19(incorrectPath)) {
40816
40991
  try {
40817
40992
  logger.info("Migrating .ck.json from nested location to correct location...");
40818
40993
  await rename2(incorrectPath, correctPath);
40819
40994
  logger.success(`Migrated ${PROJECT_CONFIG_FILE} to ${correctPath}`);
40820
- const nestedClaudeDir = join64(globalDir, ".claude");
40995
+ const nestedClaudeDir = join65(globalDir, ".claude");
40821
40996
  try {
40822
40997
  await rm6(nestedClaudeDir, { recursive: false });
40823
40998
  logger.debug("Removed empty nested .claude directory");
@@ -40908,20 +41083,20 @@ Please use only one download method.`);
40908
41083
  };
40909
41084
  }
40910
41085
  // src/commands/init/phases/post-install-handler.ts
40911
- import { join as join65 } from "node:path";
41086
+ import { join as join66 } from "node:path";
40912
41087
  init_logger();
40913
41088
  init_path_resolver();
40914
- var import_fs_extra28 = __toESM(require_lib(), 1);
41089
+ var import_fs_extra29 = __toESM(require_lib(), 1);
40915
41090
  async function handlePostInstall(ctx) {
40916
41091
  if (ctx.cancelled || !ctx.extractDir || !ctx.resolvedDir || !ctx.claudeDir) {
40917
41092
  return ctx;
40918
41093
  }
40919
41094
  if (ctx.options.global) {
40920
- const claudeMdSource = join65(ctx.extractDir, "CLAUDE.md");
40921
- const claudeMdDest = join65(ctx.resolvedDir, "CLAUDE.md");
40922
- if (await import_fs_extra28.pathExists(claudeMdSource)) {
40923
- if (!await import_fs_extra28.pathExists(claudeMdDest)) {
40924
- await import_fs_extra28.copy(claudeMdSource, claudeMdDest);
41095
+ const claudeMdSource = join66(ctx.extractDir, "CLAUDE.md");
41096
+ const claudeMdDest = join66(ctx.resolvedDir, "CLAUDE.md");
41097
+ if (await import_fs_extra29.pathExists(claudeMdSource)) {
41098
+ if (!await import_fs_extra29.pathExists(claudeMdDest)) {
41099
+ await import_fs_extra29.copy(claudeMdSource, claudeMdDest);
40925
41100
  logger.success("Copied CLAUDE.md to global directory");
40926
41101
  } else {
40927
41102
  logger.debug("CLAUDE.md already exists in global directory (preserved)");
@@ -40966,7 +41141,7 @@ async function handlePostInstall(ctx) {
40966
41141
  }
40967
41142
  if (!ctx.options.skipSetup) {
40968
41143
  await promptSetupWizardIfNeeded({
40969
- envPath: join65(ctx.claudeDir, ".env"),
41144
+ envPath: join66(ctx.claudeDir, ".env"),
40970
41145
  claudeDir: ctx.claudeDir,
40971
41146
  isGlobal: ctx.options.global,
40972
41147
  isNonInteractive: ctx.isNonInteractive,
@@ -40980,7 +41155,7 @@ async function handlePostInstall(ctx) {
40980
41155
  }
40981
41156
  // src/commands/init/phases/selection-handler.ts
40982
41157
  import { mkdir as mkdir20 } from "node:fs/promises";
40983
- import { join as join67, resolve as resolve8 } from "node:path";
41158
+ import { join as join68, resolve as resolve9 } from "node:path";
40984
41159
  init_github_client();
40985
41160
 
40986
41161
  // src/domains/github/kit-access-checker.ts
@@ -41109,10 +41284,10 @@ async function runPreflightChecks() {
41109
41284
  }
41110
41285
 
41111
41286
  // src/domains/installation/fresh-installer.ts
41112
- import { existsSync as existsSync19, readdirSync, rmSync as rmSync2, rmdirSync, unlinkSync as unlinkSync3 } from "node:fs";
41113
- import { dirname as dirname9, join as join66, resolve as resolve7 } from "node:path";
41287
+ import { existsSync as existsSync20, readdirSync as readdirSync2, rmSync as rmSync3, rmdirSync as rmdirSync2, unlinkSync as unlinkSync4 } from "node:fs";
41288
+ import { dirname as dirname10, join as join67, resolve as resolve8 } from "node:path";
41114
41289
  init_logger();
41115
- var import_fs_extra29 = __toESM(require_lib(), 1);
41290
+ var import_fs_extra30 = __toESM(require_lib(), 1);
41116
41291
  var CLAUDEKIT_SUBDIRECTORIES = ["commands", "agents", "skills", "rules", "hooks"];
41117
41292
  async function analyzeFreshInstallation(claudeDir) {
41118
41293
  const metadata = await readManifest(claudeDir);
@@ -41156,16 +41331,16 @@ async function analyzeFreshInstallation(claudeDir) {
41156
41331
  hasMetadata: true
41157
41332
  };
41158
41333
  }
41159
- function cleanupEmptyDirectories(filePath, claudeDir) {
41160
- const normalizedClaudeDir = resolve7(claudeDir);
41161
- let currentDir = resolve7(dirname9(filePath));
41334
+ function cleanupEmptyDirectories2(filePath, claudeDir) {
41335
+ const normalizedClaudeDir = resolve8(claudeDir);
41336
+ let currentDir = resolve8(dirname10(filePath));
41162
41337
  while (currentDir !== normalizedClaudeDir && currentDir.startsWith(normalizedClaudeDir)) {
41163
41338
  try {
41164
- const entries = readdirSync(currentDir);
41339
+ const entries = readdirSync2(currentDir);
41165
41340
  if (entries.length === 0) {
41166
- rmdirSync(currentDir);
41341
+ rmdirSync2(currentDir);
41167
41342
  logger.debug(`Removed empty directory: ${currentDir}`);
41168
- currentDir = resolve7(dirname9(currentDir));
41343
+ currentDir = resolve8(dirname10(currentDir));
41169
41344
  } else {
41170
41345
  break;
41171
41346
  }
@@ -41182,13 +41357,13 @@ async function removeFilesByOwnership(claudeDir, analysis, includeModified) {
41182
41357
  const filesToRemove = includeModified ? [...analysis.ckFiles, ...analysis.ckModifiedFiles] : analysis.ckFiles;
41183
41358
  const filesToPreserve = includeModified ? analysis.userFiles : [...analysis.ckModifiedFiles, ...analysis.userFiles];
41184
41359
  for (const file of filesToRemove) {
41185
- const fullPath = join66(claudeDir, file.path);
41360
+ const fullPath = join67(claudeDir, file.path);
41186
41361
  try {
41187
- if (existsSync19(fullPath)) {
41188
- unlinkSync3(fullPath);
41362
+ if (existsSync20(fullPath)) {
41363
+ unlinkSync4(fullPath);
41189
41364
  removedFiles.push(file.path);
41190
41365
  logger.debug(`Removed: ${file.path}`);
41191
- cleanupEmptyDirectories(fullPath, claudeDir);
41366
+ cleanupEmptyDirectories2(fullPath, claudeDir);
41192
41367
  }
41193
41368
  } catch (error) {
41194
41369
  logger.debug(`Failed to remove ${file.path}: ${error}`);
@@ -41207,13 +41382,13 @@ async function removeFilesByOwnership(claudeDir, analysis, includeModified) {
41207
41382
  };
41208
41383
  }
41209
41384
  async function updateMetadataAfterFresh(claudeDir, removedFiles) {
41210
- const metadataPath = join66(claudeDir, "metadata.json");
41211
- if (!await import_fs_extra29.pathExists(metadataPath)) {
41385
+ const metadataPath = join67(claudeDir, "metadata.json");
41386
+ if (!await import_fs_extra30.pathExists(metadataPath)) {
41212
41387
  return;
41213
41388
  }
41214
41389
  let content;
41215
41390
  try {
41216
- content = await import_fs_extra29.readFile(metadataPath, "utf-8");
41391
+ content = await import_fs_extra30.readFile(metadataPath, "utf-8");
41217
41392
  } catch (readError) {
41218
41393
  logger.warning(`Failed to read metadata.json: ${readError instanceof Error ? readError.message : String(readError)}`);
41219
41394
  return;
@@ -41239,7 +41414,7 @@ async function updateMetadataAfterFresh(claudeDir, removedFiles) {
41239
41414
  metadata.files = metadata.files.filter((f3) => !removedSet.has(f3.path));
41240
41415
  }
41241
41416
  try {
41242
- await import_fs_extra29.writeFile(metadataPath, JSON.stringify(metadata, null, 2));
41417
+ await import_fs_extra30.writeFile(metadataPath, JSON.stringify(metadata, null, 2));
41243
41418
  logger.debug(`Updated metadata.json, removed ${removedFiles.length} file entries`);
41244
41419
  } catch (writeError) {
41245
41420
  logger.warning(`Failed to write metadata.json: ${writeError instanceof Error ? writeError.message : String(writeError)}`);
@@ -41250,17 +41425,17 @@ async function removeSubdirectoriesFallback(claudeDir) {
41250
41425
  const removedFiles = [];
41251
41426
  let removedDirCount = 0;
41252
41427
  for (const subdir of CLAUDEKIT_SUBDIRECTORIES) {
41253
- const subdirPath = join66(claudeDir, subdir);
41254
- if (await import_fs_extra29.pathExists(subdirPath)) {
41255
- rmSync2(subdirPath, { recursive: true, force: true });
41428
+ const subdirPath = join67(claudeDir, subdir);
41429
+ if (await import_fs_extra30.pathExists(subdirPath)) {
41430
+ rmSync3(subdirPath, { recursive: true, force: true });
41256
41431
  removedDirCount++;
41257
41432
  removedFiles.push(`${subdir}/ (entire directory)`);
41258
41433
  logger.debug(`Removed subdirectory: ${subdir}/`);
41259
41434
  }
41260
41435
  }
41261
- const metadataPath = join66(claudeDir, "metadata.json");
41262
- if (await import_fs_extra29.pathExists(metadataPath)) {
41263
- unlinkSync3(metadataPath);
41436
+ const metadataPath = join67(claudeDir, "metadata.json");
41437
+ if (await import_fs_extra30.pathExists(metadataPath)) {
41438
+ unlinkSync4(metadataPath);
41264
41439
  removedFiles.push("metadata.json");
41265
41440
  }
41266
41441
  return {
@@ -41272,7 +41447,7 @@ async function removeSubdirectoriesFallback(claudeDir) {
41272
41447
  };
41273
41448
  }
41274
41449
  async function handleFreshInstallation(claudeDir, prompts) {
41275
- if (!await import_fs_extra29.pathExists(claudeDir)) {
41450
+ if (!await import_fs_extra30.pathExists(claudeDir)) {
41276
41451
  logger.info(".claude directory does not exist, proceeding with fresh installation");
41277
41452
  return true;
41278
41453
  }
@@ -41306,7 +41481,7 @@ async function handleFreshInstallation(claudeDir, prompts) {
41306
41481
  init_logger();
41307
41482
  init_path_resolver();
41308
41483
  init_types2();
41309
- var import_fs_extra30 = __toESM(require_lib(), 1);
41484
+ var import_fs_extra31 = __toESM(require_lib(), 1);
41310
41485
 
41311
41486
  // src/commands/init/types.ts
41312
41487
  function isSyncContext(ctx) {
@@ -41475,7 +41650,7 @@ async function handleSelection(ctx) {
41475
41650
  }
41476
41651
  }
41477
41652
  }
41478
- const resolvedDir = resolve8(targetDir);
41653
+ const resolvedDir = resolve9(targetDir);
41479
41654
  logger.info(`Target directory: ${resolvedDir}`);
41480
41655
  if (!ctx.options.global && PathResolver.isLocalSameAsGlobal(resolvedDir)) {
41481
41656
  logger.warning("You're at HOME directory. Installing here modifies your GLOBAL ClaudeKit.");
@@ -41497,7 +41672,7 @@ async function handleSelection(ctx) {
41497
41672
  return { ...ctx, cancelled: true };
41498
41673
  }
41499
41674
  }
41500
- if (!await import_fs_extra30.pathExists(resolvedDir)) {
41675
+ if (!await import_fs_extra31.pathExists(resolvedDir)) {
41501
41676
  if (ctx.options.global) {
41502
41677
  await mkdir20(resolvedDir, { recursive: true });
41503
41678
  logger.info(`Created global directory: ${resolvedDir}`);
@@ -41509,7 +41684,7 @@ async function handleSelection(ctx) {
41509
41684
  }
41510
41685
  if (!ctx.options.fresh) {
41511
41686
  const prefix = PathResolver.getPathPrefix(ctx.options.global);
41512
- const claudeDir = prefix ? join67(resolvedDir, prefix) : resolvedDir;
41687
+ const claudeDir = prefix ? join68(resolvedDir, prefix) : resolvedDir;
41513
41688
  try {
41514
41689
  const existingMetadata = await readManifest(claudeDir);
41515
41690
  if (existingMetadata?.kits) {
@@ -41541,7 +41716,7 @@ async function handleSelection(ctx) {
41541
41716
  }
41542
41717
  if (ctx.options.fresh) {
41543
41718
  const prefix = PathResolver.getPathPrefix(ctx.options.global);
41544
- const claudeDir = prefix ? join67(resolvedDir, prefix) : resolvedDir;
41719
+ const claudeDir = prefix ? join68(resolvedDir, prefix) : resolvedDir;
41545
41720
  const canProceed = await handleFreshInstallation(claudeDir, ctx.prompts);
41546
41721
  if (!canProceed) {
41547
41722
  return { ...ctx, cancelled: true };
@@ -41560,7 +41735,7 @@ async function handleSelection(ctx) {
41560
41735
  logger.info("Fetching available versions...");
41561
41736
  let currentVersion = null;
41562
41737
  try {
41563
- const metadataPath = ctx.options.global ? join67(PathResolver.getGlobalKitDir(), "metadata.json") : join67(resolvedDir, ".claude", "metadata.json");
41738
+ const metadataPath = ctx.options.global ? join68(PathResolver.getGlobalKitDir(), "metadata.json") : join68(resolvedDir, ".claude", "metadata.json");
41564
41739
  const metadata = await readClaudeKitMetadata(metadataPath);
41565
41740
  currentVersion = metadata?.version || null;
41566
41741
  if (currentVersion) {
@@ -41634,25 +41809,25 @@ async function handleSelection(ctx) {
41634
41809
  };
41635
41810
  }
41636
41811
  // src/commands/init/phases/sync-handler.ts
41637
- import { copyFile as copyFile6, mkdir as mkdir21, open, rename as rename3, stat as stat10, unlink as unlink7, writeFile as writeFile20 } from "node:fs/promises";
41638
- import { dirname as dirname10, join as join68, resolve as resolve9 } from "node:path";
41812
+ import { copyFile as copyFile6, mkdir as mkdir21, open, rename as rename3, stat as stat10, unlink as unlink7, writeFile as writeFile21 } from "node:fs/promises";
41813
+ import { dirname as dirname11, join as join69, resolve as resolve10 } from "node:path";
41639
41814
  init_logger();
41640
41815
  init_path_resolver();
41641
- var import_fs_extra31 = __toESM(require_lib(), 1);
41816
+ var import_fs_extra32 = __toESM(require_lib(), 1);
41642
41817
  var import_picocolors19 = __toESM(require_picocolors(), 1);
41643
41818
  async function handleSync(ctx) {
41644
41819
  if (!ctx.options.sync) {
41645
41820
  return ctx;
41646
41821
  }
41647
- const resolvedDir = ctx.options.global ? PathResolver.getGlobalKitDir() : resolve9(ctx.options.dir || ".");
41648
- const claudeDir = ctx.options.global ? resolvedDir : join68(resolvedDir, ".claude");
41649
- if (!await import_fs_extra31.pathExists(claudeDir)) {
41822
+ const resolvedDir = ctx.options.global ? PathResolver.getGlobalKitDir() : resolve10(ctx.options.dir || ".");
41823
+ const claudeDir = ctx.options.global ? resolvedDir : join69(resolvedDir, ".claude");
41824
+ if (!await import_fs_extra32.pathExists(claudeDir)) {
41650
41825
  logger.error("Cannot sync: no .claude directory found");
41651
41826
  ctx.prompts.note("Run 'ck init' without --sync to install first.", "No Installation Found");
41652
41827
  return { ...ctx, cancelled: true };
41653
41828
  }
41654
- const metadataPath = join68(claudeDir, "metadata.json");
41655
- if (!await import_fs_extra31.pathExists(metadataPath)) {
41829
+ const metadataPath = join69(claudeDir, "metadata.json");
41830
+ if (!await import_fs_extra32.pathExists(metadataPath)) {
41656
41831
  logger.error("Cannot sync: no metadata.json found");
41657
41832
  ctx.prompts.note(`Your installation may be from an older version.
41658
41833
  Run 'ck init' to update.`, "Legacy Installation");
@@ -41751,10 +41926,10 @@ function getLockTimeout() {
41751
41926
  var STALE_LOCK_THRESHOLD_MS = 5 * 60 * 1000;
41752
41927
  async function acquireSyncLock(global3) {
41753
41928
  const cacheDir = PathResolver.getCacheDir(global3);
41754
- const lockPath = join68(cacheDir, ".sync-lock");
41929
+ const lockPath = join69(cacheDir, ".sync-lock");
41755
41930
  const startTime = Date.now();
41756
41931
  const lockTimeout = getLockTimeout();
41757
- await mkdir21(dirname10(lockPath), { recursive: true });
41932
+ await mkdir21(dirname11(lockPath), { recursive: true });
41758
41933
  while (Date.now() - startTime < lockTimeout) {
41759
41934
  try {
41760
41935
  const handle = await open(lockPath, "wx");
@@ -41778,7 +41953,7 @@ async function acquireSyncLock(global3) {
41778
41953
  }
41779
41954
  logger.debug(`Lock stat failed: ${statError}`);
41780
41955
  }
41781
- await new Promise((resolve10) => setTimeout(resolve10, 100));
41956
+ await new Promise((resolve11) => setTimeout(resolve11, 100));
41782
41957
  continue;
41783
41958
  }
41784
41959
  throw err;
@@ -41797,7 +41972,7 @@ async function executeSyncMerge(ctx) {
41797
41972
  const releaseLock = await acquireSyncLock(ctx.options.global);
41798
41973
  try {
41799
41974
  const trackedFiles = ctx.syncTrackedFiles;
41800
- const upstreamDir = ctx.options.global ? join68(ctx.extractDir, ".claude") : ctx.extractDir;
41975
+ const upstreamDir = ctx.options.global ? join69(ctx.extractDir, ".claude") : ctx.extractDir;
41801
41976
  logger.info("Analyzing file changes...");
41802
41977
  const plan = await SyncEngine.createSyncPlan(trackedFiles, ctx.claudeDir, upstreamDir);
41803
41978
  displaySyncPlan(plan);
@@ -41816,7 +41991,7 @@ async function executeSyncMerge(ctx) {
41816
41991
  try {
41817
41992
  const sourcePath = await validateSyncPath(upstreamDir, file.path);
41818
41993
  const targetPath = await validateSyncPath(ctx.claudeDir, file.path);
41819
- const targetDir = join68(targetPath, "..");
41994
+ const targetDir = join69(targetPath, "..");
41820
41995
  try {
41821
41996
  await mkdir21(targetDir, { recursive: true });
41822
41997
  } catch (mkdirError) {
@@ -41897,7 +42072,7 @@ async function executeSyncMerge(ctx) {
41897
42072
  try {
41898
42073
  const tempPath = `${currentPath}.tmp.${Date.now()}`;
41899
42074
  try {
41900
- await writeFile20(tempPath, result.result, "utf-8");
42075
+ await writeFile21(tempPath, result.result, "utf-8");
41901
42076
  await rename3(tempPath, currentPath);
41902
42077
  } catch (atomicError) {
41903
42078
  await unlink7(tempPath).catch(() => {});
@@ -41985,9 +42160,9 @@ async function createBackup(claudeDir, files, backupDir) {
41985
42160
  for (const file of files) {
41986
42161
  try {
41987
42162
  const sourcePath = await validateSyncPath(claudeDir, file.path);
41988
- if (await import_fs_extra31.pathExists(sourcePath)) {
42163
+ if (await import_fs_extra32.pathExists(sourcePath)) {
41989
42164
  const targetPath = await validateSyncPath(backupDir, file.path);
41990
- const targetDir = join68(targetPath, "..");
42165
+ const targetDir = join69(targetPath, "..");
41991
42166
  await mkdir21(targetDir, { recursive: true });
41992
42167
  await copyFile6(sourcePath, targetPath);
41993
42168
  }
@@ -42001,7 +42176,7 @@ async function createBackup(claudeDir, files, backupDir) {
42001
42176
  }
42002
42177
  }
42003
42178
  // src/commands/init/phases/transform-handler.ts
42004
- import { join as join72 } from "node:path";
42179
+ import { join as join73 } from "node:path";
42005
42180
 
42006
42181
  // src/services/transformers/folder-path-transformer.ts
42007
42182
  init_logger();
@@ -42010,40 +42185,40 @@ init_types2();
42010
42185
  // src/services/transformers/folder-transform/folder-renamer.ts
42011
42186
  init_logger();
42012
42187
  init_types2();
42013
- var import_fs_extra32 = __toESM(require_lib(), 1);
42188
+ var import_fs_extra33 = __toESM(require_lib(), 1);
42014
42189
  import { rename as rename4, rm as rm7 } from "node:fs/promises";
42015
- import { join as join69, relative as relative12 } from "node:path";
42190
+ import { join as join70, relative as relative12 } from "node:path";
42016
42191
  async function collectDirsToRename(extractDir, folders) {
42017
42192
  const dirsToRename = [];
42018
42193
  if (folders.docs !== DEFAULT_FOLDERS.docs) {
42019
- const docsPath = join69(extractDir, DEFAULT_FOLDERS.docs);
42020
- if (await import_fs_extra32.pathExists(docsPath)) {
42194
+ const docsPath = join70(extractDir, DEFAULT_FOLDERS.docs);
42195
+ if (await import_fs_extra33.pathExists(docsPath)) {
42021
42196
  dirsToRename.push({
42022
42197
  from: docsPath,
42023
- to: join69(extractDir, folders.docs)
42198
+ to: join70(extractDir, folders.docs)
42024
42199
  });
42025
42200
  }
42026
- const claudeDocsPath = join69(extractDir, ".claude", DEFAULT_FOLDERS.docs);
42027
- if (await import_fs_extra32.pathExists(claudeDocsPath)) {
42201
+ const claudeDocsPath = join70(extractDir, ".claude", DEFAULT_FOLDERS.docs);
42202
+ if (await import_fs_extra33.pathExists(claudeDocsPath)) {
42028
42203
  dirsToRename.push({
42029
42204
  from: claudeDocsPath,
42030
- to: join69(extractDir, ".claude", folders.docs)
42205
+ to: join70(extractDir, ".claude", folders.docs)
42031
42206
  });
42032
42207
  }
42033
42208
  }
42034
42209
  if (folders.plans !== DEFAULT_FOLDERS.plans) {
42035
- const plansPath = join69(extractDir, DEFAULT_FOLDERS.plans);
42036
- if (await import_fs_extra32.pathExists(plansPath)) {
42210
+ const plansPath = join70(extractDir, DEFAULT_FOLDERS.plans);
42211
+ if (await import_fs_extra33.pathExists(plansPath)) {
42037
42212
  dirsToRename.push({
42038
42213
  from: plansPath,
42039
- to: join69(extractDir, folders.plans)
42214
+ to: join70(extractDir, folders.plans)
42040
42215
  });
42041
42216
  }
42042
- const claudePlansPath = join69(extractDir, ".claude", DEFAULT_FOLDERS.plans);
42043
- if (await import_fs_extra32.pathExists(claudePlansPath)) {
42217
+ const claudePlansPath = join70(extractDir, ".claude", DEFAULT_FOLDERS.plans);
42218
+ if (await import_fs_extra33.pathExists(claudePlansPath)) {
42044
42219
  dirsToRename.push({
42045
42220
  from: claudePlansPath,
42046
- to: join69(extractDir, ".claude", folders.plans)
42221
+ to: join70(extractDir, ".claude", folders.plans)
42047
42222
  });
42048
42223
  }
42049
42224
  }
@@ -42055,7 +42230,7 @@ async function moveAcrossDevices(src, dest) {
42055
42230
  } catch (e2) {
42056
42231
  if (e2.code === "EXDEV") {
42057
42232
  logger.debug(`Cross-device move detected, using copy+delete: ${src} -> ${dest}`);
42058
- await import_fs_extra32.copy(src, dest, { overwrite: true });
42233
+ await import_fs_extra33.copy(src, dest, { overwrite: true });
42059
42234
  await rm7(src, { recursive: true, force: true });
42060
42235
  } else {
42061
42236
  throw e2;
@@ -42083,8 +42258,8 @@ async function renameFolders(dirsToRename, extractDir, options) {
42083
42258
  // src/services/transformers/folder-transform/path-replacer.ts
42084
42259
  init_logger();
42085
42260
  init_types2();
42086
- import { readFile as readFile24, readdir as readdir23, writeFile as writeFile21 } from "node:fs/promises";
42087
- import { join as join70, relative as relative13 } from "node:path";
42261
+ import { readFile as readFile26, readdir as readdir23, writeFile as writeFile22 } from "node:fs/promises";
42262
+ import { join as join71, relative as relative13 } from "node:path";
42088
42263
  var TRANSFORMABLE_FILE_PATTERNS = [
42089
42264
  ".md",
42090
42265
  ".txt",
@@ -42137,7 +42312,7 @@ async function transformFileContents(dir, compiledReplacements, options) {
42137
42312
  let replacementsCount = 0;
42138
42313
  const entries = await readdir23(dir, { withFileTypes: true });
42139
42314
  for (const entry of entries) {
42140
- const fullPath = join70(dir, entry.name);
42315
+ const fullPath = join71(dir, entry.name);
42141
42316
  if (entry.isDirectory()) {
42142
42317
  if (entry.name === "node_modules" || entry.name === ".git") {
42143
42318
  continue;
@@ -42150,7 +42325,7 @@ async function transformFileContents(dir, compiledReplacements, options) {
42150
42325
  if (!shouldTransform)
42151
42326
  continue;
42152
42327
  try {
42153
- const content = await readFile24(fullPath, "utf-8");
42328
+ const content = await readFile26(fullPath, "utf-8");
42154
42329
  let newContent = content;
42155
42330
  let changeCount = 0;
42156
42331
  for (const { regex: regex2, replacement } of compiledReplacements) {
@@ -42166,7 +42341,7 @@ async function transformFileContents(dir, compiledReplacements, options) {
42166
42341
  if (options.dryRun) {
42167
42342
  logger.debug(`[dry-run] Would update ${relative13(dir, fullPath)}: ${changeCount} replacement(s)`);
42168
42343
  } else {
42169
- await writeFile21(fullPath, newContent, "utf-8");
42344
+ await writeFile22(fullPath, newContent, "utf-8");
42170
42345
  logger.debug(`Updated ${relative13(dir, fullPath)}: ${changeCount} replacement(s)`);
42171
42346
  }
42172
42347
  filesChanged++;
@@ -42272,9 +42447,9 @@ async function transformFolderPaths(extractDir, folders, options = {}) {
42272
42447
 
42273
42448
  // src/services/transformers/global-path-transformer.ts
42274
42449
  init_logger();
42275
- import { readFile as readFile25, readdir as readdir24, writeFile as writeFile22 } from "node:fs/promises";
42450
+ import { readFile as readFile27, readdir as readdir24, writeFile as writeFile23 } from "node:fs/promises";
42276
42451
  import { platform as platform12 } from "node:os";
42277
- import { extname as extname3, join as join71 } from "node:path";
42452
+ import { extname as extname3, join as join72 } from "node:path";
42278
42453
  var IS_WINDOWS4 = platform12() === "win32";
42279
42454
  var HOME_PREFIX = IS_WINDOWS4 ? "%USERPROFILE%" : "$HOME";
42280
42455
  function getHomeDirPrefix() {
@@ -42384,7 +42559,7 @@ async function transformPathsForGlobalInstall(directory, options = {}) {
42384
42559
  async function processDirectory2(dir) {
42385
42560
  const entries = await readdir24(dir, { withFileTypes: true });
42386
42561
  for (const entry of entries) {
42387
- const fullPath = join71(dir, entry.name);
42562
+ const fullPath = join72(dir, entry.name);
42388
42563
  if (entry.isDirectory()) {
42389
42564
  if (entry.name === "node_modules" || entry.name.startsWith(".") && entry.name !== ".claude") {
42390
42565
  continue;
@@ -42392,10 +42567,10 @@ async function transformPathsForGlobalInstall(directory, options = {}) {
42392
42567
  await processDirectory2(fullPath);
42393
42568
  } else if (entry.isFile() && shouldTransformFile3(entry.name)) {
42394
42569
  try {
42395
- const content = await readFile25(fullPath, "utf-8");
42570
+ const content = await readFile27(fullPath, "utf-8");
42396
42571
  const { transformed, changes } = transformContent(content);
42397
42572
  if (changes > 0) {
42398
- await writeFile22(fullPath, transformed, "utf-8");
42573
+ await writeFile23(fullPath, transformed, "utf-8");
42399
42574
  filesTransformed++;
42400
42575
  totalChanges += changes;
42401
42576
  if (options.verbose) {
@@ -42460,7 +42635,7 @@ async function handleTransforms(ctx) {
42460
42635
  logger.debug(ctx.options.global ? "Saved folder configuration to ~/.claude/.ck.json" : "Saved folder configuration to .claude/.ck.json");
42461
42636
  }
42462
42637
  }
42463
- const claudeDir = ctx.options.global ? ctx.resolvedDir : join72(ctx.resolvedDir, ".claude");
42638
+ const claudeDir = ctx.options.global ? ctx.resolvedDir : join73(ctx.resolvedDir, ".claude");
42464
42639
  return {
42465
42640
  ...ctx,
42466
42641
  foldersConfig,
@@ -42650,11 +42825,11 @@ init_types2();
42650
42825
  var import_picocolors20 = __toESM(require_picocolors(), 1);
42651
42826
 
42652
42827
  // src/commands/new/phases/directory-setup.ts
42653
- import { resolve as resolve10 } from "node:path";
42828
+ import { resolve as resolve11 } from "node:path";
42654
42829
  init_logger();
42655
42830
  init_path_resolver();
42656
42831
  init_types2();
42657
- var import_fs_extra33 = __toESM(require_lib(), 1);
42832
+ var import_fs_extra34 = __toESM(require_lib(), 1);
42658
42833
  async function directorySetup(validOptions, prompts) {
42659
42834
  const isNonInteractive2 = !process.stdin.isTTY || process.env.CI === "true" || process.env.NON_INTERACTIVE === "true";
42660
42835
  const config = await ConfigManager.get();
@@ -42735,7 +42910,7 @@ async function directorySetup(validOptions, prompts) {
42735
42910
  targetDir = await prompts.getDirectory(targetDir);
42736
42911
  }
42737
42912
  }
42738
- const resolvedDir = resolve10(targetDir);
42913
+ const resolvedDir = resolve11(targetDir);
42739
42914
  logger.info(`Target directory: ${resolvedDir}`);
42740
42915
  if (PathResolver.isLocalSameAsGlobal(resolvedDir)) {
42741
42916
  logger.warning("You're creating a project at HOME directory.");
@@ -42753,8 +42928,8 @@ async function directorySetup(validOptions, prompts) {
42753
42928
  return null;
42754
42929
  }
42755
42930
  }
42756
- if (await import_fs_extra33.pathExists(resolvedDir)) {
42757
- const files = await import_fs_extra33.readdir(resolvedDir);
42931
+ if (await import_fs_extra34.pathExists(resolvedDir)) {
42932
+ const files = await import_fs_extra34.readdir(resolvedDir);
42758
42933
  const isEmpty = files.length === 0;
42759
42934
  if (!isEmpty) {
42760
42935
  if (isNonInteractive2) {
@@ -42790,7 +42965,7 @@ async function handleDirectorySetup(ctx) {
42790
42965
  };
42791
42966
  }
42792
42967
  // src/commands/new/phases/project-creation.ts
42793
- import { join as join73 } from "node:path";
42968
+ import { join as join74 } from "node:path";
42794
42969
  init_github_client();
42795
42970
  init_logger();
42796
42971
  init_output_manager();
@@ -42917,7 +43092,7 @@ async function projectCreation(kit, resolvedDir, validOptions, isNonInteractive2
42917
43092
  output.section("Installing");
42918
43093
  logger.verbose("Installation target", { directory: resolvedDir });
42919
43094
  const merger = new FileMerger;
42920
- const claudeDir = join73(resolvedDir, ".claude");
43095
+ const claudeDir = join74(resolvedDir, ".claude");
42921
43096
  merger.setMultiKitContext(claudeDir, kit);
42922
43097
  if (validOptions.exclude && validOptions.exclude.length > 0) {
42923
43098
  merger.addIgnorePatterns(validOptions.exclude);
@@ -42963,7 +43138,7 @@ async function handleProjectCreation(ctx) {
42963
43138
  };
42964
43139
  }
42965
43140
  // src/commands/new/phases/post-setup.ts
42966
- import { join as join74 } from "node:path";
43141
+ import { join as join75 } from "node:path";
42967
43142
  init_package_installer();
42968
43143
  init_logger();
42969
43144
  init_path_resolver();
@@ -42995,9 +43170,9 @@ async function postSetup(resolvedDir, validOptions, isNonInteractive2, prompts)
42995
43170
  withSudo: validOptions.withSudo
42996
43171
  });
42997
43172
  }
42998
- const claudeDir = join74(resolvedDir, ".claude");
43173
+ const claudeDir = join75(resolvedDir, ".claude");
42999
43174
  await promptSetupWizardIfNeeded({
43000
- envPath: join74(claudeDir, ".env"),
43175
+ envPath: join75(claudeDir, ".env"),
43001
43176
  claudeDir,
43002
43177
  isGlobal: false,
43003
43178
  isNonInteractive: isNonInteractive2,
@@ -43066,7 +43241,7 @@ var import_picocolors22 = __toESM(require_picocolors(), 1);
43066
43241
 
43067
43242
  // src/commands/uninstall/installation-detector.ts
43068
43243
  init_path_resolver();
43069
- var import_fs_extra34 = __toESM(require_lib(), 1);
43244
+ var import_fs_extra35 = __toESM(require_lib(), 1);
43070
43245
  async function detectInstallations() {
43071
43246
  const installations = [];
43072
43247
  const setup = await getClaudeKitSetup(process.cwd());
@@ -43075,28 +43250,28 @@ async function detectInstallations() {
43075
43250
  installations.push({
43076
43251
  type: "local",
43077
43252
  path: setup.project.path,
43078
- exists: await import_fs_extra34.pathExists(setup.project.path)
43253
+ exists: await import_fs_extra35.pathExists(setup.project.path)
43079
43254
  });
43080
43255
  }
43081
43256
  if (setup.global.path && setup.global.metadata) {
43082
43257
  installations.push({
43083
43258
  type: "global",
43084
43259
  path: setup.global.path,
43085
- exists: await import_fs_extra34.pathExists(setup.global.path)
43260
+ exists: await import_fs_extra35.pathExists(setup.global.path)
43086
43261
  });
43087
43262
  }
43088
43263
  return installations.filter((i) => i.exists);
43089
43264
  }
43090
43265
 
43091
43266
  // src/commands/uninstall/removal-handler.ts
43092
- import { readdirSync as readdirSync3, rmSync as rmSync4 } from "node:fs";
43093
- import { join as join76 } from "node:path";
43267
+ import { readdirSync as readdirSync4, rmSync as rmSync5 } from "node:fs";
43268
+ import { join as join77 } from "node:path";
43094
43269
  init_logger();
43095
- var import_fs_extra35 = __toESM(require_lib(), 1);
43270
+ var import_fs_extra36 = __toESM(require_lib(), 1);
43096
43271
 
43097
43272
  // src/commands/uninstall/analysis-handler.ts
43098
- import { readdirSync as readdirSync2, rmSync as rmSync3 } from "node:fs";
43099
- import { dirname as dirname11, join as join75 } from "node:path";
43273
+ import { readdirSync as readdirSync3, rmSync as rmSync4 } from "node:fs";
43274
+ import { dirname as dirname12, join as join76 } from "node:path";
43100
43275
  init_logger();
43101
43276
  var import_picocolors21 = __toESM(require_picocolors(), 1);
43102
43277
  function classifyFileByOwnership(ownership, forceOverwrite, deleteReason) {
@@ -43111,17 +43286,17 @@ function classifyFileByOwnership(ownership, forceOverwrite, deleteReason) {
43111
43286
  }
43112
43287
  return { action: "preserve", reason: "user-created" };
43113
43288
  }
43114
- async function cleanupEmptyDirectories2(filePath, installationRoot) {
43289
+ async function cleanupEmptyDirectories3(filePath, installationRoot) {
43115
43290
  let cleaned = 0;
43116
- let currentDir = dirname11(filePath);
43291
+ let currentDir = dirname12(filePath);
43117
43292
  while (currentDir !== installationRoot && currentDir.startsWith(installationRoot)) {
43118
43293
  try {
43119
- const entries = readdirSync2(currentDir);
43294
+ const entries = readdirSync3(currentDir);
43120
43295
  if (entries.length === 0) {
43121
- rmSync3(currentDir, { recursive: true });
43296
+ rmSync4(currentDir, { recursive: true });
43122
43297
  cleaned++;
43123
43298
  logger.debug(`Removed empty directory: ${currentDir}`);
43124
- currentDir = dirname11(currentDir);
43299
+ currentDir = dirname12(currentDir);
43125
43300
  } else {
43126
43301
  break;
43127
43302
  }
@@ -43143,7 +43318,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
43143
43318
  if (uninstallManifest.isMultiKit && kit && metadata?.kits?.[kit]) {
43144
43319
  const kitFiles = metadata.kits[kit].files || [];
43145
43320
  for (const trackedFile of kitFiles) {
43146
- const filePath = join75(installation.path, trackedFile.path);
43321
+ const filePath = join76(installation.path, trackedFile.path);
43147
43322
  if (uninstallManifest.filesToPreserve.includes(trackedFile.path)) {
43148
43323
  result.toPreserve.push({ path: trackedFile.path, reason: "shared with other kit" });
43149
43324
  continue;
@@ -43173,7 +43348,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
43173
43348
  return result;
43174
43349
  }
43175
43350
  for (const trackedFile of allTrackedFiles) {
43176
- const filePath = join75(installation.path, trackedFile.path);
43351
+ const filePath = join76(installation.path, trackedFile.path);
43177
43352
  const ownershipResult = await OwnershipChecker.checkOwnership(filePath, metadata, installation.path);
43178
43353
  if (!ownershipResult.exists)
43179
43354
  continue;
@@ -43233,21 +43408,21 @@ async function removeInstallations(installations, options) {
43233
43408
  let removedCount = 0;
43234
43409
  let cleanedDirs = 0;
43235
43410
  for (const item of analysis.toDelete) {
43236
- const filePath = join76(installation.path, item.path);
43237
- if (await import_fs_extra35.pathExists(filePath)) {
43238
- await import_fs_extra35.remove(filePath);
43411
+ const filePath = join77(installation.path, item.path);
43412
+ if (await import_fs_extra36.pathExists(filePath)) {
43413
+ await import_fs_extra36.remove(filePath);
43239
43414
  removedCount++;
43240
43415
  logger.debug(`Removed: ${item.path}`);
43241
- cleanedDirs += await cleanupEmptyDirectories2(filePath, installation.path);
43416
+ cleanedDirs += await cleanupEmptyDirectories3(filePath, installation.path);
43242
43417
  }
43243
43418
  }
43244
43419
  if (options.kit && analysis.remainingKits.length > 0) {
43245
43420
  await ManifestWriter.removeKitFromManifest(installation.path, options.kit);
43246
43421
  }
43247
43422
  try {
43248
- const remaining = readdirSync3(installation.path);
43423
+ const remaining = readdirSync4(installation.path);
43249
43424
  if (remaining.length === 0) {
43250
- rmSync4(installation.path, { recursive: true });
43425
+ rmSync5(installation.path, { recursive: true });
43251
43426
  logger.debug(`Removed empty installation directory: ${installation.path}`);
43252
43427
  }
43253
43428
  } catch {}
@@ -43404,7 +43579,7 @@ ${import_picocolors22.default.yellow("User modifications will be permanently del
43404
43579
  }
43405
43580
  // src/commands/update-cli.ts
43406
43581
  import { exec as exec8 } from "node:child_process";
43407
- import { join as join77 } from "node:path";
43582
+ import { join as join78 } from "node:path";
43408
43583
  import { promisify as promisify8 } from "node:util";
43409
43584
 
43410
43585
  // src/domains/github/npm-registry.ts
@@ -43547,11 +43722,11 @@ init_logger();
43547
43722
  init_types2();
43548
43723
  init_types2();
43549
43724
  var import_compare_versions3 = __toESM(require_umd(), 1);
43550
- var import_fs_extra36 = __toESM(require_lib(), 1);
43725
+ var import_fs_extra37 = __toESM(require_lib(), 1);
43551
43726
  // package.json
43552
43727
  var package_default = {
43553
43728
  name: "claudekit-cli",
43554
- version: "3.30.0-dev.1",
43729
+ version: "3.30.0-dev.2",
43555
43730
  description: "CLI tool for bootstrapping and updating ClaudeKit projects",
43556
43731
  type: "module",
43557
43732
  repository: {
@@ -43698,12 +43873,12 @@ function selectKitForUpdate(params) {
43698
43873
  };
43699
43874
  }
43700
43875
  async function readMetadataFile(claudeDir) {
43701
- const metadataPath = join77(claudeDir, "metadata.json");
43876
+ const metadataPath = join78(claudeDir, "metadata.json");
43702
43877
  try {
43703
- if (!await import_fs_extra36.pathExists(metadataPath)) {
43878
+ if (!await import_fs_extra37.pathExists(metadataPath)) {
43704
43879
  return null;
43705
43880
  }
43706
- const content = await import_fs_extra36.readFile(metadataPath, "utf-8");
43881
+ const content = await import_fs_extra37.readFile(metadataPath, "utf-8");
43707
43882
  const parsed = JSON.parse(content);
43708
43883
  const validated = MetadataSchema.safeParse(parsed);
43709
43884
  if (!validated.success) {
@@ -44030,8 +44205,8 @@ function registerCommands(cli) {
44030
44205
  }
44031
44206
 
44032
44207
  // src/cli/version-display.ts
44033
- import { existsSync as existsSync21, readFileSync as readFileSync7 } from "node:fs";
44034
- import { join as join79 } from "node:path";
44208
+ import { existsSync as existsSync22, readFileSync as readFileSync7 } from "node:fs";
44209
+ import { join as join80 } from "node:path";
44035
44210
 
44036
44211
  // src/domains/versioning/checking/version-utils.ts
44037
44212
  var import_compare_versions4 = __toESM(require_umd(), 1);
@@ -44058,25 +44233,25 @@ init_types2();
44058
44233
  // src/domains/versioning/version-cache.ts
44059
44234
  init_logger();
44060
44235
  init_path_resolver();
44061
- import { existsSync as existsSync20 } from "node:fs";
44062
- import { mkdir as mkdir22, readFile as readFile27, writeFile as writeFile23 } from "node:fs/promises";
44063
- import { join as join78 } from "node:path";
44236
+ import { existsSync as existsSync21 } from "node:fs";
44237
+ import { mkdir as mkdir22, readFile as readFile29, writeFile as writeFile24 } from "node:fs/promises";
44238
+ import { join as join79 } from "node:path";
44064
44239
 
44065
44240
  class VersionCacheManager {
44066
44241
  static CACHE_FILENAME = "version-check.json";
44067
44242
  static CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000;
44068
44243
  static getCacheFile() {
44069
44244
  const cacheDir = PathResolver.getCacheDir(false);
44070
- return join78(cacheDir, VersionCacheManager.CACHE_FILENAME);
44245
+ return join79(cacheDir, VersionCacheManager.CACHE_FILENAME);
44071
44246
  }
44072
44247
  static async load() {
44073
44248
  const cacheFile = VersionCacheManager.getCacheFile();
44074
44249
  try {
44075
- if (!existsSync20(cacheFile)) {
44250
+ if (!existsSync21(cacheFile)) {
44076
44251
  logger.debug("Version check cache not found");
44077
44252
  return null;
44078
44253
  }
44079
- const content = await readFile27(cacheFile, "utf-8");
44254
+ const content = await readFile29(cacheFile, "utf-8");
44080
44255
  const cache2 = JSON.parse(content);
44081
44256
  if (!cache2.lastCheck || !cache2.currentVersion || !cache2.latestVersion) {
44082
44257
  logger.debug("Invalid cache structure, ignoring");
@@ -44093,10 +44268,10 @@ class VersionCacheManager {
44093
44268
  const cacheFile = VersionCacheManager.getCacheFile();
44094
44269
  const cacheDir = PathResolver.getCacheDir(false);
44095
44270
  try {
44096
- if (!existsSync20(cacheDir)) {
44271
+ if (!existsSync21(cacheDir)) {
44097
44272
  await mkdir22(cacheDir, { recursive: true, mode: 448 });
44098
44273
  }
44099
- await writeFile23(cacheFile, JSON.stringify(cache2, null, 2), "utf-8");
44274
+ await writeFile24(cacheFile, JSON.stringify(cache2, null, 2), "utf-8");
44100
44275
  logger.debug(`Version check cache saved to ${cacheFile}`);
44101
44276
  } catch (error) {
44102
44277
  logger.debug(`Failed to save version check cache: ${error}`);
@@ -44115,7 +44290,7 @@ class VersionCacheManager {
44115
44290
  static async clear() {
44116
44291
  const cacheFile = VersionCacheManager.getCacheFile();
44117
44292
  try {
44118
- if (existsSync20(cacheFile)) {
44293
+ if (existsSync21(cacheFile)) {
44119
44294
  const fs14 = await import("node:fs/promises");
44120
44295
  await fs14.unlink(cacheFile);
44121
44296
  logger.debug("Version check cache cleared");
@@ -44335,11 +44510,11 @@ async function displayVersion() {
44335
44510
  let localKitVersion = null;
44336
44511
  let isGlobalOnlyKit = false;
44337
44512
  const globalKitDir = PathResolver.getGlobalKitDir();
44338
- const globalMetadataPath = join79(globalKitDir, "metadata.json");
44513
+ const globalMetadataPath = join80(globalKitDir, "metadata.json");
44339
44514
  const prefix = PathResolver.getPathPrefix(false);
44340
- const localMetadataPath = prefix ? join79(process.cwd(), prefix, "metadata.json") : join79(process.cwd(), "metadata.json");
44515
+ const localMetadataPath = prefix ? join80(process.cwd(), prefix, "metadata.json") : join80(process.cwd(), "metadata.json");
44341
44516
  const isLocalSameAsGlobal = localMetadataPath === globalMetadataPath;
44342
- if (!isLocalSameAsGlobal && existsSync21(localMetadataPath)) {
44517
+ if (!isLocalSameAsGlobal && existsSync22(localMetadataPath)) {
44343
44518
  try {
44344
44519
  const rawMetadata = JSON.parse(readFileSync7(localMetadataPath, "utf-8"));
44345
44520
  const metadata = MetadataSchema.parse(rawMetadata);
@@ -44353,7 +44528,7 @@ async function displayVersion() {
44353
44528
  logger.verbose("Failed to parse local metadata.json", { error });
44354
44529
  }
44355
44530
  }
44356
- if (existsSync21(globalMetadataPath)) {
44531
+ if (existsSync22(globalMetadataPath)) {
44357
44532
  try {
44358
44533
  const rawMetadata = JSON.parse(readFileSync7(globalMetadataPath, "utf-8"));
44359
44534
  const metadata = MetadataSchema.parse(rawMetadata);