claudekit-cli 3.36.0-dev.12 → 3.36.0-dev.14

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 +662 -445
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -48304,11 +48304,38 @@ var init_skill_directory_installer = __esm(() => {
48304
48304
  import { existsSync as existsSync17 } from "node:fs";
48305
48305
  import { readFile as readFile12, readdir as readdir5 } from "node:fs/promises";
48306
48306
  import { homedir as homedir13 } from "node:os";
48307
- import { extname as extname3, join as join21, relative as relative5 } from "node:path";
48307
+ import { extname as extname3, join as join21, relative as relative5, sep as sep3 } from "node:path";
48308
+ function resolveSourceOrigin(sourcePath) {
48309
+ if (!sourcePath)
48310
+ return "global";
48311
+ const home5 = homedir13();
48312
+ const cwd2 = process.cwd();
48313
+ if (cwd2 === home5)
48314
+ return "global";
48315
+ const cwdPrefix = cwd2.endsWith(sep3) ? cwd2 : `${cwd2}${sep3}`;
48316
+ if (sourcePath === cwd2 || sourcePath.startsWith(cwdPrefix))
48317
+ return "project";
48318
+ return "global";
48319
+ }
48308
48320
  function getConfigSourcePath() {
48321
+ const projectPath = join21(process.cwd(), "CLAUDE.md");
48322
+ if (existsSync17(projectPath)) {
48323
+ return projectPath;
48324
+ }
48325
+ const projectDotClaudePath = join21(process.cwd(), ".claude", "CLAUDE.md");
48326
+ if (existsSync17(projectDotClaudePath)) {
48327
+ return projectDotClaudePath;
48328
+ }
48329
+ return getGlobalConfigSourcePath();
48330
+ }
48331
+ function getGlobalConfigSourcePath() {
48309
48332
  return join21(homedir13(), ".claude", "CLAUDE.md");
48310
48333
  }
48311
48334
  function getRulesSourcePath() {
48335
+ const projectPath = join21(process.cwd(), ".claude", "rules");
48336
+ if (existsSync17(projectPath)) {
48337
+ return projectPath;
48338
+ }
48312
48339
  return join21(homedir13(), ".claude", "rules");
48313
48340
  }
48314
48341
  function getHooksSourcePath() {
@@ -50720,12 +50747,31 @@ function determineAction(source, providerConfig, input, targetStateIndex, delete
50720
50747
  const registeredSourceChecksum = normalizeChecksum(registryEntry.sourceChecksum);
50721
50748
  const registeredTargetChecksum = normalizeChecksum(registryEntry.targetChecksum);
50722
50749
  if (isUnknownChecksum(registeredSourceChecksum)) {
50750
+ const targetState2 = lookupTargetState(targetStateIndex, registryEntry.path);
50751
+ const currentTargetChecksum = normalizeChecksum(targetState2?.currentChecksum);
50752
+ if (currentTargetChecksum === convertedChecksum) {
50753
+ return {
50754
+ ...common,
50755
+ action: "skip",
50756
+ reason: "Target up-to-date after registry upgrade — checksums will be backfilled",
50757
+ sourceChecksum: convertedChecksum,
50758
+ currentTargetChecksum
50759
+ };
50760
+ }
50761
+ if (!targetState2 || !targetState2.exists) {
50762
+ return {
50763
+ ...common,
50764
+ action: "install",
50765
+ reason: "Target deleted — reinstalling after registry upgrade",
50766
+ sourceChecksum: convertedChecksum
50767
+ };
50768
+ }
50723
50769
  return {
50724
50770
  ...common,
50725
- action: "skip",
50726
- reason: "First run after registry upgrade — populating checksums (no writes)",
50771
+ action: "update",
50772
+ reason: "Healing stale target after registry upgrade",
50727
50773
  sourceChecksum: convertedChecksum,
50728
- currentTargetChecksum: registeredTargetChecksum
50774
+ currentTargetChecksum
50729
50775
  };
50730
50776
  }
50731
50777
  const sourceChanged = convertedChecksum !== registeredSourceChecksum;
@@ -51102,7 +51148,8 @@ var init_migration_result_utils = __esm(() => {
51102
51148
  // src/domains/web-server/routes/migration-routes.ts
51103
51149
  import { existsSync as existsSync21 } from "node:fs";
51104
51150
  import { readFile as readFile15, rm as rm5 } from "node:fs/promises";
51105
- import { basename as basename7, resolve as resolve8 } from "node:path";
51151
+ import { homedir as homedir15 } from "node:os";
51152
+ import { basename as basename7, join as join24, resolve as resolve8 } from "node:path";
51106
51153
  function isDisallowedControlCode(codePoint) {
51107
51154
  return codePoint >= 0 && codePoint <= 8 || codePoint >= 11 && codePoint <= 31 || codePoint >= 127 && codePoint <= 159;
51108
51155
  }
@@ -51253,7 +51300,7 @@ function parseConfigSource(input) {
51253
51300
  return { ok: true, value: undefined };
51254
51301
  }
51255
51302
  const projectSourcePath = resolve8(process.cwd(), "CLAUDE.md");
51256
- const globalSourcePath = resolve8(getConfigSourcePath());
51303
+ const globalSourcePath = resolve8(getGlobalConfigSourcePath());
51257
51304
  const sourceMap = {
51258
51305
  default: undefined,
51259
51306
  global: globalSourcePath,
@@ -51548,12 +51595,14 @@ async function discoverMigrationItems(include, configSource) {
51548
51595
  const commandsSource = include.commands ? getCommandSourcePath() : null;
51549
51596
  const skillsSource = include.skills ? getSkillSourcePath() : null;
51550
51597
  const hooksSource = include.hooks ? getHooksSourcePath() : null;
51598
+ const configSourcePath = include.config ? configSource ?? getConfigSourcePath() : null;
51599
+ const rulesSourcePath = include.rules ? getRulesSourcePath() : null;
51551
51600
  const [agents, commands, skills, configItem, ruleItems, hookItems] = await Promise.all([
51552
51601
  agentsSource ? discoverAgents(agentsSource) : Promise.resolve([]),
51553
51602
  commandsSource ? discoverCommands(commandsSource) : Promise.resolve([]),
51554
51603
  skillsSource ? discoverSkills(skillsSource) : Promise.resolve([]),
51555
- include.config ? discoverConfig(configSource) : Promise.resolve(null),
51556
- include.rules ? discoverRules() : Promise.resolve([]),
51604
+ configSourcePath ? discoverConfig(configSourcePath) : Promise.resolve(null),
51605
+ rulesSourcePath ? discoverRules(rulesSourcePath) : Promise.resolve([]),
51557
51606
  hooksSource ? discoverHooks(hooksSource).then(({ items, skippedShellHooks }) => {
51558
51607
  if (skippedShellHooks.length > 0) {
51559
51608
  console.warn(`[migrate] Skipping ${skippedShellHooks.length} shell hook(s) not supported for migration (node-runnable only): ${skippedShellHooks.join(", ")}`);
@@ -51572,7 +51621,9 @@ async function discoverMigrationItems(include, configSource) {
51572
51621
  agents: agentsSource,
51573
51622
  commands: commandsSource,
51574
51623
  skills: skillsSource,
51575
- hooks: hooksSource
51624
+ hooks: hooksSource,
51625
+ config: configSourcePath,
51626
+ rules: rulesSourcePath
51576
51627
  }
51577
51628
  };
51578
51629
  }
@@ -51620,8 +51671,23 @@ function registerMigrationRoutes(app) {
51620
51671
  hooks: true
51621
51672
  };
51622
51673
  const discovered = await discoverMigrationItems(includeAll);
51674
+ const cwd2 = process.cwd();
51675
+ const home6 = homedir15();
51623
51676
  res.status(200).json({
51677
+ cwd: cwd2,
51678
+ targetPaths: {
51679
+ project: join24(cwd2, ".claude"),
51680
+ global: join24(home6, ".claude")
51681
+ },
51624
51682
  sourcePaths: discovered.sourcePaths,
51683
+ sourceOrigins: {
51684
+ agents: discovered.sourcePaths.agents ? resolveSourceOrigin(discovered.sourcePaths.agents) : null,
51685
+ commands: discovered.sourcePaths.commands ? resolveSourceOrigin(discovered.sourcePaths.commands) : null,
51686
+ skills: discovered.sourcePaths.skills ? resolveSourceOrigin(discovered.sourcePaths.skills) : null,
51687
+ config: discovered.sourcePaths.config ? resolveSourceOrigin(discovered.sourcePaths.config) : null,
51688
+ rules: discovered.sourcePaths.rules ? resolveSourceOrigin(discovered.sourcePaths.rules) : null,
51689
+ hooks: discovered.sourcePaths.hooks ? resolveSourceOrigin(discovered.sourcePaths.hooks) : null
51690
+ },
51625
51691
  counts: {
51626
51692
  agents: discovered.agents.length,
51627
51693
  commands: discovered.commands.length,
@@ -52644,12 +52710,12 @@ var init_plan_table_parser = __esm(() => {
52644
52710
 
52645
52711
  // src/domains/plan-parser/plan-scanner.ts
52646
52712
  import { existsSync as existsSync22, readdirSync as readdirSync3 } from "node:fs";
52647
- import { join as join24 } from "node:path";
52713
+ import { join as join25 } from "node:path";
52648
52714
  function scanPlanDir(dir) {
52649
52715
  if (!existsSync22(dir))
52650
52716
  return [];
52651
52717
  try {
52652
- return readdirSync3(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join24(dir, entry.name, "plan.md")).filter(existsSync22);
52718
+ return readdirSync3(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join25(dir, entry.name, "plan.md")).filter(existsSync22);
52653
52719
  } catch {
52654
52720
  return [];
52655
52721
  }
@@ -52724,7 +52790,7 @@ var init_plan_validator = __esm(() => {
52724
52790
  // src/domains/plan-parser/plan-writer.ts
52725
52791
  import { mkdirSync as mkdirSync2, readFileSync as readFileSync6, writeFileSync as writeFileSync2 } from "node:fs";
52726
52792
  import { existsSync as existsSync24 } from "node:fs";
52727
- import { basename as basename9, dirname as dirname13, join as join25 } from "node:path";
52793
+ import { basename as basename9, dirname as dirname13, join as join26 } from "node:path";
52728
52794
  function phaseNameToFilename(id, name) {
52729
52795
  const numMatch = /^(\d+)([a-z]*)$/i.exec(id);
52730
52796
  const num = numMatch ? numMatch[1] : id;
@@ -52832,12 +52898,12 @@ function scaffoldPlan(options2) {
52832
52898
  mkdirSync2(dir, { recursive: true });
52833
52899
  const resolvedPhases = resolvePhaseIds(options2.phases);
52834
52900
  const optionsWithResolved = { ...options2, phases: resolvedPhases };
52835
- const planFile = join25(dir, "plan.md");
52901
+ const planFile = join26(dir, "plan.md");
52836
52902
  writeFileSync2(planFile, generatePlanMd(optionsWithResolved), "utf8");
52837
52903
  const phaseFiles = [];
52838
52904
  for (const phase of resolvedPhases) {
52839
52905
  const filename = phaseNameToFilename(phase.id, phase.name);
52840
- const phaseFile = join25(dir, filename);
52906
+ const phaseFile = join26(dir, filename);
52841
52907
  writeFileSync2(phaseFile, generatePhaseTemplate(phase), "utf8");
52842
52908
  phaseFiles.push(phaseFile);
52843
52909
  }
@@ -52917,7 +52983,7 @@ function phaseNameFilenameFromTableRow(body, phaseId, planDir) {
52917
52983
  continue;
52918
52984
  const linkMatch = /\[([^\]]+)\]\(\.\/([^)]+)\)/.exec(row);
52919
52985
  if (linkMatch)
52920
- return join25(planDir, linkMatch[2]);
52986
+ return join26(planDir, linkMatch[2]);
52921
52987
  }
52922
52988
  return null;
52923
52989
  }
@@ -52998,7 +53064,7 @@ function addPhase(planFile, name, afterId) {
52998
53064
  `);
52999
53065
  }
53000
53066
  writeFileSync2(planFile, import_gray_matter7.default.stringify(updatedBody, frontmatter), "utf8");
53001
- const phaseFilePath = join25(planDir, filename);
53067
+ const phaseFilePath = join26(planDir, filename);
53002
53068
  writeFileSync2(phaseFilePath, generatePhaseTemplate({ id: phaseId, name }), "utf8");
53003
53069
  return { phaseId, phaseFile: phaseFilePath };
53004
53070
  }
@@ -53037,11 +53103,11 @@ var init_plan_parser = __esm(() => {
53037
53103
 
53038
53104
  // src/domains/web-server/routes/plan-routes.ts
53039
53105
  import { existsSync as existsSync25, realpathSync } from "node:fs";
53040
- import { basename as basename10, dirname as dirname15, relative as relative6, resolve as resolve10, sep as sep3 } from "node:path";
53106
+ import { basename as basename10, dirname as dirname15, relative as relative6, resolve as resolve10, sep as sep4 } from "node:path";
53041
53107
  function isWithinCwd(filePath) {
53042
53108
  const cwd2 = process.cwd();
53043
53109
  const resolved = resolve10(filePath);
53044
- const cwdPrefix = cwd2.endsWith(sep3) ? cwd2 : `${cwd2}${sep3}`;
53110
+ const cwdPrefix = cwd2.endsWith(sep4) ? cwd2 : `${cwd2}${sep4}`;
53045
53111
  if (!resolved.startsWith(cwdPrefix) && resolved !== cwd2)
53046
53112
  return false;
53047
53113
  if (existsSync25(resolved)) {
@@ -53188,11 +53254,11 @@ var init_types5 = __esm(() => {
53188
53254
 
53189
53255
  // src/services/claude-data/history-parser.ts
53190
53256
  import { createReadStream, statSync as statSync4 } from "node:fs";
53191
- import { homedir as homedir15 } from "node:os";
53192
- import { join as join26 } from "node:path";
53257
+ import { homedir as homedir16 } from "node:os";
53258
+ import { join as join27 } from "node:path";
53193
53259
  import { createInterface as createInterface2 } from "node:readline";
53194
53260
  function getHistoryPath() {
53195
- return process.env.CLAUDE_HISTORY_PATH ?? join26(homedir15(), ".claude", "history.jsonl");
53261
+ return process.env.CLAUDE_HISTORY_PATH ?? join27(homedir16(), ".claude", "history.jsonl");
53196
53262
  }
53197
53263
  function emptyResult(parseTimeMs, error) {
53198
53264
  return { projects: [], totalEntries: 0, errorCount: 0, parseTimeMs, error };
@@ -53276,7 +53342,7 @@ var init_history_parser = __esm(() => {
53276
53342
  // src/services/claude-data/session-parser.ts
53277
53343
  import { existsSync as existsSync26 } from "node:fs";
53278
53344
  import { readFile as readFile16, readdir as readdir7, stat as stat5 } from "node:fs/promises";
53279
- import { join as join27 } from "node:path";
53345
+ import { join as join28 } from "node:path";
53280
53346
  function formatTimestamp(date) {
53281
53347
  const now = new Date;
53282
53348
  const isToday = date.toDateString() === now.toDateString();
@@ -53373,7 +53439,7 @@ async function getProjectSessions(projectDir, limit = 10) {
53373
53439
  const files = await readdir7(projectDir);
53374
53440
  const jsonlFiles = files.filter((f3) => f3.endsWith(".jsonl"));
53375
53441
  const fileStats = await Promise.all(jsonlFiles.map(async (file) => {
53376
- const filePath = join27(projectDir, file);
53442
+ const filePath = join28(projectDir, file);
53377
53443
  const fileStat = await stat5(filePath).catch(() => null);
53378
53444
  return { file, filePath, mtime: fileStat?.mtime || new Date(0) };
53379
53445
  }));
@@ -53390,10 +53456,10 @@ var init_session_parser = () => {};
53390
53456
  // src/services/claude-data/skill-scanner.ts
53391
53457
  import { existsSync as existsSync27 } from "node:fs";
53392
53458
  import { readFile as readFile17, readdir as readdir8 } from "node:fs/promises";
53393
- import { homedir as homedir16 } from "node:os";
53394
- import { join as join28 } from "node:path";
53459
+ import { homedir as homedir17 } from "node:os";
53460
+ import { join as join29 } from "node:path";
53395
53461
  async function getCkSkillMetadata(scope) {
53396
- const metaPath = scope === "global" ? join28(homedir16(), ".claude", "metadata.json") : join28(process.cwd(), ".claude", "metadata.json");
53462
+ const metaPath = scope === "global" ? join29(homedir17(), ".claude", "metadata.json") : join29(process.cwd(), ".claude", "metadata.json");
53397
53463
  if (!existsSync27(metaPath))
53398
53464
  return null;
53399
53465
  const result = new Map;
@@ -53429,7 +53495,7 @@ async function getCkSkillMetadata(scope) {
53429
53495
  return result.size > 0 ? result : null;
53430
53496
  }
53431
53497
  async function getSkillMetadata(skillPath) {
53432
- const skillMdPath = join28(skillPath, "SKILL.md");
53498
+ const skillMdPath = join29(skillPath, "SKILL.md");
53433
53499
  if (!existsSync27(skillMdPath))
53434
53500
  return null;
53435
53501
  try {
@@ -53478,8 +53544,8 @@ async function scanSkills() {
53478
53544
  continue;
53479
53545
  if (ckMeta && !ckMeta.has(entry))
53480
53546
  continue;
53481
- const entryPath = join28(skillsDir, entry);
53482
- const skillMdPath = join28(entryPath, "SKILL.md");
53547
+ const entryPath = join29(skillsDir, entry);
53548
+ const skillMdPath = join29(entryPath, "SKILL.md");
53483
53549
  if (!existsSync27(skillMdPath))
53484
53550
  continue;
53485
53551
  const frontmatter = await getSkillMetadata(entryPath);
@@ -53524,17 +53590,17 @@ async function scanSkills() {
53524
53590
  var import_gray_matter8, skillsDir, SKIP_DIRS3;
53525
53591
  var init_skill_scanner = __esm(() => {
53526
53592
  import_gray_matter8 = __toESM(require_gray_matter(), 1);
53527
- skillsDir = join28(homedir16(), ".claude", "skills");
53593
+ skillsDir = join29(homedir17(), ".claude", "skills");
53528
53594
  SKIP_DIRS3 = [".venv", "scripts", "__pycache__", "node_modules", ".git", "common"];
53529
53595
  });
53530
53596
 
53531
53597
  // src/services/claude-data/settings-reader.ts
53532
53598
  import { existsSync as existsSync28 } from "node:fs";
53533
53599
  import { copyFile as copyFile2, mkdir as mkdir8, readFile as readFile18, rename as rename5, rm as rm6, writeFile as writeFile10 } from "node:fs/promises";
53534
- import { homedir as homedir17 } from "node:os";
53535
- import { join as join29 } from "node:path";
53600
+ import { homedir as homedir18 } from "node:os";
53601
+ import { join as join30 } from "node:path";
53536
53602
  function getSettingsPath() {
53537
- return join29(claudeDir, settingsFilename);
53603
+ return join30(claudeDir, settingsFilename);
53538
53604
  }
53539
53605
  async function readSettings() {
53540
53606
  const settingsPath = getSettingsPath();
@@ -53556,7 +53622,7 @@ async function backupAndSaveSettings(settings) {
53556
53622
  let backupPath = null;
53557
53623
  if (existsSync28(settingsPath)) {
53558
53624
  await mkdir8(settingsBackupDir, { recursive: true });
53559
- backupPath = join29(settingsBackupDir, `${getBackupTimestamp()}-${settingsFilename}`);
53625
+ backupPath = join30(settingsBackupDir, `${getBackupTimestamp()}-${settingsFilename}`);
53560
53626
  await copyFile2(settingsPath, backupPath);
53561
53627
  }
53562
53628
  const tempPath = `${settingsPath}.tmp-${Date.now()}`;
@@ -53593,19 +53659,19 @@ function countMcpServers(settings) {
53593
53659
  }
53594
53660
  var claudeDir, settingsFilename = "settings.json", settingsBackupDir;
53595
53661
  var init_settings_reader = __esm(() => {
53596
- claudeDir = join29(homedir17(), ".claude");
53597
- settingsBackupDir = join29(claudeDir, ".ck-backups", "settings");
53662
+ claudeDir = join30(homedir18(), ".claude");
53663
+ settingsBackupDir = join30(claudeDir, ".ck-backups", "settings");
53598
53664
  });
53599
53665
 
53600
53666
  // src/services/claude-data/project-scanner.ts
53601
- import { homedir as homedir18 } from "node:os";
53602
- import { basename as basename11, join as join30, normalize as normalize3 } from "node:path";
53667
+ import { homedir as homedir19 } from "node:os";
53668
+ import { basename as basename11, join as join31, normalize as normalize3 } from "node:path";
53603
53669
  function encodePath(path4) {
53604
53670
  return path4.replace(/\//g, "-").replace(/^-/, "-");
53605
53671
  }
53606
53672
  var projectsDir;
53607
53673
  var init_project_scanner = __esm(() => {
53608
- projectsDir = join30(homedir18(), ".claude", "projects");
53674
+ projectsDir = join31(homedir19(), ".claude", "projects");
53609
53675
  });
53610
53676
 
53611
53677
  // src/services/claude-data/project-discovery.ts
@@ -53700,10 +53766,10 @@ var init_project_discovery = __esm(() => {
53700
53766
 
53701
53767
  // src/services/claude-data/user-preferences.ts
53702
53768
  import { readFile as readFile19, stat as stat6 } from "node:fs/promises";
53703
- import { homedir as homedir19 } from "node:os";
53704
- import { join as join31 } from "node:path";
53769
+ import { homedir as homedir20 } from "node:os";
53770
+ import { join as join32 } from "node:path";
53705
53771
  function getPreferencesPath() {
53706
- return join31(homedir19(), ".claude.json");
53772
+ return join32(homedir20(), ".claude.json");
53707
53773
  }
53708
53774
  async function readUserPreferences(filePath) {
53709
53775
  const path4 = filePath ?? getPreferencesPath();
@@ -53793,8 +53859,8 @@ var init_claude_data = __esm(() => {
53793
53859
  // src/domains/web-server/routes/project-routes.ts
53794
53860
  import { existsSync as existsSync29 } from "node:fs";
53795
53861
  import { readFile as readFile20 } from "node:fs/promises";
53796
- import { homedir as homedir20 } from "node:os";
53797
- import { basename as basename13, join as join32, resolve as resolve11 } from "node:path";
53862
+ import { homedir as homedir21 } from "node:os";
53863
+ import { basename as basename13, join as join33, resolve as resolve11 } from "node:path";
53798
53864
  function registerProjectRoutes(app) {
53799
53865
  app.get("/api/projects", async (req, res) => {
53800
53866
  try {
@@ -53813,7 +53879,7 @@ function registerProjectRoutes(app) {
53813
53879
  for (const discovered of discoveredProjects) {
53814
53880
  if (registeredPaths.has(discovered.path))
53815
53881
  continue;
53816
- if (discovered.path === join32(homedir20(), ".claude"))
53882
+ if (discovered.path === join33(homedir21(), ".claude"))
53817
53883
  continue;
53818
53884
  const projectInfo = await detectAndBuildProjectInfo(discovered.path, `discovered-${discovered.path}`);
53819
53885
  if (projectInfo) {
@@ -53829,7 +53895,7 @@ function registerProjectRoutes(app) {
53829
53895
  if (cwdProject) {
53830
53896
  projects.push(cwdProject);
53831
53897
  }
53832
- const globalDir = join32(homedir20(), ".claude");
53898
+ const globalDir = join33(homedir21(), ".claude");
53833
53899
  const globalProject = await detectAndBuildProjectInfo(globalDir, "global");
53834
53900
  if (globalProject) {
53835
53901
  projects.push(globalProject);
@@ -53901,12 +53967,12 @@ function registerProjectRoutes(app) {
53901
53967
  const body = validation.data;
53902
53968
  let projectPath = body.path;
53903
53969
  if (projectPath.startsWith("~/") || projectPath === "~") {
53904
- projectPath = join32(homedir20(), projectPath.slice(1));
53970
+ projectPath = join33(homedir21(), projectPath.slice(1));
53905
53971
  } else if (projectPath.startsWith("~\\")) {
53906
- projectPath = join32(homedir20(), projectPath.slice(1));
53972
+ projectPath = join33(homedir21(), projectPath.slice(1));
53907
53973
  }
53908
53974
  projectPath = resolve11(projectPath);
53909
- const homeDir = homedir20();
53975
+ const homeDir = homedir21();
53910
53976
  if (projectPath.includes("..") || !projectPath.startsWith(homeDir)) {
53911
53977
  res.status(400).json({ error: "Invalid path after expansion" });
53912
53978
  return;
@@ -53963,7 +54029,7 @@ function registerProjectRoutes(app) {
53963
54029
  if (id === "current") {
53964
54030
  projectPath = process.cwd();
53965
54031
  } else if (id === "global") {
53966
- projectPath = join32(homedir20(), ".claude");
54032
+ projectPath = join33(homedir21(), ".claude");
53967
54033
  } else {
53968
54034
  res.status(404).json({ error: "Project not found" });
53969
54035
  return;
@@ -54025,8 +54091,8 @@ function registerProjectRoutes(app) {
54025
54091
  });
54026
54092
  }
54027
54093
  async function buildProjectInfoFromRegistry(registered) {
54028
- const claudeDir2 = join32(registered.path, ".claude");
54029
- const metadataPath = join32(claudeDir2, "metadata.json");
54094
+ const claudeDir2 = join33(registered.path, ".claude");
54095
+ const metadataPath = join33(claudeDir2, "metadata.json");
54030
54096
  if (!existsSync29(registered.path)) {
54031
54097
  return null;
54032
54098
  }
@@ -54043,7 +54109,7 @@ async function buildProjectInfoFromRegistry(registered) {
54043
54109
  const hasLocalConfig = hasClaudeDir && CkConfigManager.projectConfigExists(registered.path, false);
54044
54110
  const settings = await readSettings();
54045
54111
  const skills = await scanSkills();
54046
- const settingsPath = join32(homedir20(), ".claude", "settings.json");
54112
+ const settingsPath = join33(homedir21(), ".claude", "settings.json");
54047
54113
  const health = existsSync29(settingsPath) ? "healthy" : "warning";
54048
54114
  const model = getCurrentModel() || settings?.model || "claude-sonnet-4";
54049
54115
  return {
@@ -54066,8 +54132,8 @@ async function buildProjectInfoFromRegistry(registered) {
54066
54132
  };
54067
54133
  }
54068
54134
  async function detectAndBuildProjectInfo(path4, id) {
54069
- const claudeDir2 = id === "global" ? path4 : join32(path4, ".claude");
54070
- const metadataPath = join32(claudeDir2, "metadata.json");
54135
+ const claudeDir2 = id === "global" ? path4 : join33(path4, ".claude");
54136
+ const metadataPath = join33(claudeDir2, "metadata.json");
54071
54137
  if (!existsSync29(metadataPath)) {
54072
54138
  if (!existsSync29(claudeDir2)) {
54073
54139
  return null;
@@ -54085,7 +54151,7 @@ async function detectAndBuildProjectInfo(path4, id) {
54085
54151
  const hasLocalConfig = CkConfigManager.projectConfigExists(path4, id === "global");
54086
54152
  const settings = await readSettings();
54087
54153
  const skills = await scanSkills();
54088
- const settingsPath = join32(homedir20(), ".claude", "settings.json");
54154
+ const settingsPath = join33(homedir21(), ".claude", "settings.json");
54089
54155
  const health = existsSync29(settingsPath) ? "healthy" : "warning";
54090
54156
  const model = getCurrentModel() || settings?.model || "claude-sonnet-4";
54091
54157
  return {
@@ -54126,32 +54192,32 @@ var init_project_routes = __esm(() => {
54126
54192
  });
54127
54193
 
54128
54194
  // src/domains/web-server/routes/session-routes.ts
54129
- import { homedir as homedir21 } from "node:os";
54130
- import { join as join33 } from "node:path";
54195
+ import { homedir as homedir22 } from "node:os";
54196
+ import { join as join34 } from "node:path";
54131
54197
  async function resolveSessionDir(projectId) {
54132
- const home6 = homedir21();
54198
+ const home6 = homedir22();
54133
54199
  if (projectId.startsWith("discovered-")) {
54134
54200
  try {
54135
54201
  const encodedPathB64 = projectId.slice("discovered-".length);
54136
54202
  const projectPath = Buffer.from(encodedPathB64, "base64url").toString("utf-8");
54137
54203
  const claudeEncoded = encodePath(projectPath);
54138
- return join33(home6, ".claude", "projects", claudeEncoded);
54204
+ return join34(home6, ".claude", "projects", claudeEncoded);
54139
54205
  } catch {
54140
54206
  return null;
54141
54207
  }
54142
54208
  }
54143
54209
  if (projectId === "current") {
54144
54210
  const cwdEncoded = encodePath(process.cwd());
54145
- return join33(home6, ".claude", "projects", cwdEncoded);
54211
+ return join34(home6, ".claude", "projects", cwdEncoded);
54146
54212
  }
54147
54213
  if (projectId === "global") {
54148
- const globalEncoded = encodePath(join33(home6, ".claude"));
54149
- return join33(home6, ".claude", "projects", globalEncoded);
54214
+ const globalEncoded = encodePath(join34(home6, ".claude"));
54215
+ return join34(home6, ".claude", "projects", globalEncoded);
54150
54216
  }
54151
54217
  const registered = await ProjectsRegistryManager.getProject(projectId);
54152
54218
  if (registered) {
54153
54219
  const claudeEncoded = encodePath(registered.path);
54154
- return join33(home6, ".claude", "projects", claudeEncoded);
54220
+ return join34(home6, ".claude", "projects", claudeEncoded);
54155
54221
  }
54156
54222
  return null;
54157
54223
  }
@@ -54168,7 +54234,7 @@ function registerSessionRoutes(app) {
54168
54234
  res.status(404).json({ error: "Project not found" });
54169
54235
  return;
54170
54236
  }
54171
- const allowedBase = join33(homedir21(), ".claude", "projects");
54237
+ const allowedBase = join34(homedir22(), ".claude", "projects");
54172
54238
  if (!projectDir.startsWith(allowedBase)) {
54173
54239
  res.status(403).json({ error: "Access denied" });
54174
54240
  return;
@@ -54190,7 +54256,7 @@ var init_session_routes = __esm(() => {
54190
54256
  });
54191
54257
 
54192
54258
  // src/domains/web-server/routes/settings-routes.ts
54193
- import { homedir as homedir22 } from "node:os";
54259
+ import { homedir as homedir23 } from "node:os";
54194
54260
  function registerSettingsRoutes(app) {
54195
54261
  app.get("/api/settings", async (_req, res) => {
54196
54262
  try {
@@ -54246,7 +54312,7 @@ function registerSettingsRoutes(app) {
54246
54312
  res.json({
54247
54313
  success: true,
54248
54314
  path: "~/.claude/settings.json",
54249
- backupPath: saveResult.backupPath ? saveResult.backupPath.replace(homedir22(), "~") : null,
54315
+ backupPath: saveResult.backupPath ? saveResult.backupPath.replace(homedir23(), "~") : null,
54250
54316
  absolutePath: getSettingsPath()
54251
54317
  });
54252
54318
  } catch (error) {
@@ -54280,8 +54346,8 @@ var init_settings_routes = __esm(() => {
54280
54346
 
54281
54347
  // src/commands/skills/agents.ts
54282
54348
  import { existsSync as existsSync30 } from "node:fs";
54283
- import { homedir as homedir23 } from "node:os";
54284
- import { join as join34 } from "node:path";
54349
+ import { homedir as homedir24 } from "node:os";
54350
+ import { join as join35 } from "node:path";
54285
54351
  async function detectInstalledAgents() {
54286
54352
  const installed = [];
54287
54353
  for (const [type, config] of Object.entries(agents)) {
@@ -54297,7 +54363,7 @@ function getAgentConfig(type) {
54297
54363
  function getInstallPath(skillName, agent, options2) {
54298
54364
  const config = agents[agent];
54299
54365
  const basePath = options2.global ? config.globalPath : config.projectPath;
54300
- return join34(basePath, skillName);
54366
+ return join35(basePath, skillName);
54301
54367
  }
54302
54368
  function isSkillInstalled(skillName, agent, options2) {
54303
54369
  const installPath = getInstallPath(skillName, agent, options2);
@@ -54305,105 +54371,105 @@ function isSkillInstalled(skillName, agent, options2) {
54305
54371
  }
54306
54372
  var home6, agents;
54307
54373
  var init_agents = __esm(() => {
54308
- home6 = homedir23();
54374
+ home6 = homedir24();
54309
54375
  agents = {
54310
54376
  "claude-code": {
54311
54377
  name: "claude-code",
54312
54378
  displayName: "Claude Code",
54313
54379
  projectPath: ".claude/skills",
54314
- globalPath: join34(home6, ".claude/skills"),
54315
- detect: async () => existsSync30(join34(home6, ".claude"))
54380
+ globalPath: join35(home6, ".claude/skills"),
54381
+ detect: async () => existsSync30(join35(home6, ".claude"))
54316
54382
  },
54317
54383
  cursor: {
54318
54384
  name: "cursor",
54319
54385
  displayName: "Cursor",
54320
54386
  projectPath: ".cursor/skills",
54321
- globalPath: join34(home6, ".cursor/skills"),
54322
- detect: async () => existsSync30(join34(home6, ".cursor"))
54387
+ globalPath: join35(home6, ".cursor/skills"),
54388
+ detect: async () => existsSync30(join35(home6, ".cursor"))
54323
54389
  },
54324
54390
  codex: {
54325
54391
  name: "codex",
54326
54392
  displayName: "Codex",
54327
54393
  projectPath: ".codex/skills",
54328
- globalPath: join34(home6, ".codex/skills"),
54329
- detect: async () => existsSync30(join34(home6, ".codex"))
54394
+ globalPath: join35(home6, ".codex/skills"),
54395
+ detect: async () => existsSync30(join35(home6, ".codex"))
54330
54396
  },
54331
54397
  opencode: {
54332
54398
  name: "opencode",
54333
54399
  displayName: "OpenCode",
54334
54400
  projectPath: ".opencode/skills",
54335
- globalPath: join34(home6, ".config/opencode/skills"),
54336
- detect: async () => existsSync30(join34(home6, ".config/opencode"))
54401
+ globalPath: join35(home6, ".config/opencode/skills"),
54402
+ detect: async () => existsSync30(join35(home6, ".config/opencode"))
54337
54403
  },
54338
54404
  goose: {
54339
54405
  name: "goose",
54340
54406
  displayName: "Goose",
54341
54407
  projectPath: ".goose/skills",
54342
- globalPath: join34(home6, ".config/goose/skills"),
54343
- detect: async () => existsSync30(join34(home6, ".config/goose"))
54408
+ globalPath: join35(home6, ".config/goose/skills"),
54409
+ detect: async () => existsSync30(join35(home6, ".config/goose"))
54344
54410
  },
54345
54411
  "gemini-cli": {
54346
54412
  name: "gemini-cli",
54347
54413
  displayName: "Gemini CLI",
54348
54414
  projectPath: ".gemini/skills",
54349
- globalPath: join34(home6, ".gemini/skills"),
54350
- detect: async () => existsSync30(join34(home6, ".gemini"))
54415
+ globalPath: join35(home6, ".gemini/skills"),
54416
+ detect: async () => existsSync30(join35(home6, ".gemini"))
54351
54417
  },
54352
54418
  antigravity: {
54353
54419
  name: "antigravity",
54354
54420
  displayName: "Antigravity",
54355
54421
  projectPath: ".agent/skills",
54356
- globalPath: join34(home6, ".gemini/antigravity/skills"),
54357
- detect: async () => existsSync30(join34(process.cwd(), ".agent")) || existsSync30(join34(home6, ".gemini/antigravity"))
54422
+ globalPath: join35(home6, ".gemini/antigravity/skills"),
54423
+ detect: async () => existsSync30(join35(process.cwd(), ".agent")) || existsSync30(join35(home6, ".gemini/antigravity"))
54358
54424
  },
54359
54425
  "github-copilot": {
54360
54426
  name: "github-copilot",
54361
54427
  displayName: "GitHub Copilot",
54362
54428
  projectPath: ".github/skills",
54363
- globalPath: join34(home6, ".copilot/skills"),
54364
- detect: async () => existsSync30(join34(home6, ".copilot"))
54429
+ globalPath: join35(home6, ".copilot/skills"),
54430
+ detect: async () => existsSync30(join35(home6, ".copilot"))
54365
54431
  },
54366
54432
  amp: {
54367
54433
  name: "amp",
54368
54434
  displayName: "Amp",
54369
54435
  projectPath: ".agents/skills",
54370
- globalPath: join34(home6, ".config/agents/skills"),
54371
- detect: async () => existsSync30(join34(home6, ".config/amp"))
54436
+ globalPath: join35(home6, ".config/agents/skills"),
54437
+ detect: async () => existsSync30(join35(home6, ".config/amp"))
54372
54438
  },
54373
54439
  kilo: {
54374
54440
  name: "kilo",
54375
54441
  displayName: "Kilo Code",
54376
54442
  projectPath: ".kilocode/skills",
54377
- globalPath: join34(home6, ".kilocode/skills"),
54378
- detect: async () => existsSync30(join34(home6, ".kilocode"))
54443
+ globalPath: join35(home6, ".kilocode/skills"),
54444
+ detect: async () => existsSync30(join35(home6, ".kilocode"))
54379
54445
  },
54380
54446
  roo: {
54381
54447
  name: "roo",
54382
54448
  displayName: "Roo Code",
54383
54449
  projectPath: ".roo/skills",
54384
- globalPath: join34(home6, ".roo/skills"),
54385
- detect: async () => existsSync30(join34(home6, ".roo"))
54450
+ globalPath: join35(home6, ".roo/skills"),
54451
+ detect: async () => existsSync30(join35(home6, ".roo"))
54386
54452
  },
54387
54453
  windsurf: {
54388
54454
  name: "windsurf",
54389
54455
  displayName: "Windsurf",
54390
54456
  projectPath: ".windsurf/skills",
54391
- globalPath: join34(home6, ".codeium/windsurf/skills"),
54392
- detect: async () => existsSync30(join34(home6, ".codeium/windsurf"))
54457
+ globalPath: join35(home6, ".codeium/windsurf/skills"),
54458
+ detect: async () => existsSync30(join35(home6, ".codeium/windsurf"))
54393
54459
  },
54394
54460
  cline: {
54395
54461
  name: "cline",
54396
54462
  displayName: "Cline",
54397
54463
  projectPath: ".cline/skills",
54398
- globalPath: join34(home6, ".cline/skills"),
54399
- detect: async () => existsSync30(join34(home6, ".cline"))
54464
+ globalPath: join35(home6, ".cline/skills"),
54465
+ detect: async () => existsSync30(join35(home6, ".cline"))
54400
54466
  },
54401
54467
  openhands: {
54402
54468
  name: "openhands",
54403
54469
  displayName: "OpenHands",
54404
54470
  projectPath: ".openhands/skills",
54405
- globalPath: join34(home6, ".openhands/skills"),
54406
- detect: async () => existsSync30(join34(home6, ".openhands"))
54471
+ globalPath: join35(home6, ".openhands/skills"),
54472
+ detect: async () => existsSync30(join35(home6, ".openhands"))
54407
54473
  }
54408
54474
  };
54409
54475
  });
@@ -54411,8 +54477,8 @@ var init_agents = __esm(() => {
54411
54477
  // src/commands/skills/skills-registry.ts
54412
54478
  import { existsSync as existsSync31 } from "node:fs";
54413
54479
  import { mkdir as mkdir9, readFile as readFile21, writeFile as writeFile11 } from "node:fs/promises";
54414
- import { homedir as homedir24 } from "node:os";
54415
- import { dirname as dirname16, join as join35 } from "node:path";
54480
+ import { homedir as homedir25 } from "node:os";
54481
+ import { dirname as dirname16, join as join36 } from "node:path";
54416
54482
  function getCliVersion3() {
54417
54483
  try {
54418
54484
  if (process.env.npm_package_version) {
@@ -54504,8 +54570,8 @@ async function syncRegistry() {
54504
54570
  var home7, REGISTRY_PATH2, SkillInstallationSchema, SkillRegistrySchema;
54505
54571
  var init_skills_registry = __esm(() => {
54506
54572
  init_zod();
54507
- home7 = homedir24();
54508
- REGISTRY_PATH2 = join35(home7, ".claudekit", "skill-registry.json");
54573
+ home7 = homedir25();
54574
+ REGISTRY_PATH2 = join36(home7, ".claudekit", "skill-registry.json");
54509
54575
  SkillInstallationSchema = exports_external.object({
54510
54576
  skill: exports_external.string(),
54511
54577
  agent: exports_external.string(),
@@ -54628,7 +54694,7 @@ var init_skills_installer = __esm(() => {
54628
54694
  // src/commands/skills/skills-uninstaller.ts
54629
54695
  import { existsSync as existsSync33 } from "node:fs";
54630
54696
  import { rm as rm7 } from "node:fs/promises";
54631
- import { join as join36 } from "node:path";
54697
+ import { join as join37 } from "node:path";
54632
54698
  async function uninstallSkillFromAgent(skill, agent, global3) {
54633
54699
  const agentConfig = agents[agent];
54634
54700
  const registry = await readRegistry();
@@ -54676,7 +54742,7 @@ async function uninstallSkillFromAgent(skill, agent, global3) {
54676
54742
  async function forceUninstallSkill(skill, agent, global3) {
54677
54743
  const agentConfig = agents[agent];
54678
54744
  const basePath = global3 ? agentConfig.globalPath : agentConfig.projectPath;
54679
- const path4 = join36(basePath, skill);
54745
+ const path4 = join37(basePath, skill);
54680
54746
  if (!existsSync33(path4)) {
54681
54747
  return {
54682
54748
  skill,
@@ -55220,7 +55286,7 @@ var init_pnpm_detector = __esm(() => {
55220
55286
  import { existsSync as existsSync34, realpathSync as realpathSync2 } from "node:fs";
55221
55287
  import { chmod as chmod2, mkdir as mkdir11, readFile as readFile22, writeFile as writeFile12 } from "node:fs/promises";
55222
55288
  import { platform as platform4 } from "node:os";
55223
- import { join as join37 } from "node:path";
55289
+ import { join as join38 } from "node:path";
55224
55290
  function detectFromBinaryPath() {
55225
55291
  const normalizePath2 = (pathValue) => pathValue.replace(/\\/g, "/").toLowerCase();
55226
55292
  const detectFromNormalizedPath = (normalized) => {
@@ -55297,7 +55363,7 @@ function detectFromEnv() {
55297
55363
  }
55298
55364
  async function readCachedPm() {
55299
55365
  try {
55300
- const cacheFile = join37(PathResolver.getConfigDir(false), CACHE_FILE);
55366
+ const cacheFile = join38(PathResolver.getConfigDir(false), CACHE_FILE);
55301
55367
  if (!existsSync34(cacheFile)) {
55302
55368
  return null;
55303
55369
  }
@@ -55328,7 +55394,7 @@ async function saveCachedPm(pm, getVersion) {
55328
55394
  return;
55329
55395
  try {
55330
55396
  const configDir = PathResolver.getConfigDir(false);
55331
- const cacheFile = join37(configDir, CACHE_FILE);
55397
+ const cacheFile = join38(configDir, CACHE_FILE);
55332
55398
  if (!existsSync34(configDir)) {
55333
55399
  await mkdir11(configDir, { recursive: true });
55334
55400
  if (platform4() !== "win32") {
@@ -55391,7 +55457,7 @@ async function findOwningPm() {
55391
55457
  async function clearCache() {
55392
55458
  try {
55393
55459
  const { unlink: unlink6 } = await import("node:fs/promises");
55394
- const cacheFile = join37(PathResolver.getConfigDir(false), CACHE_FILE);
55460
+ const cacheFile = join38(PathResolver.getConfigDir(false), CACHE_FILE);
55395
55461
  if (existsSync34(cacheFile)) {
55396
55462
  await unlink6(cacheFile);
55397
55463
  logger.debug("Package manager cache cleared");
@@ -55548,9 +55614,9 @@ var init_package_manager_detector = __esm(() => {
55548
55614
  });
55549
55615
 
55550
55616
  // src/domains/migration/metadata-migration.ts
55551
- import { join as join38 } from "node:path";
55617
+ import { join as join39 } from "node:path";
55552
55618
  async function detectMetadataFormat(claudeDir2) {
55553
- const metadataPath = join38(claudeDir2, "metadata.json");
55619
+ const metadataPath = join39(claudeDir2, "metadata.json");
55554
55620
  if (!await import_fs_extra3.pathExists(metadataPath)) {
55555
55621
  return { format: "none", metadata: null, detectedKit: null };
55556
55622
  }
@@ -55602,7 +55668,7 @@ async function migrateToMultiKit(claudeDir2) {
55602
55668
  toFormat: "multi-kit"
55603
55669
  };
55604
55670
  }
55605
- const metadataPath = join38(claudeDir2, "metadata.json");
55671
+ const metadataPath = join39(claudeDir2, "metadata.json");
55606
55672
  const legacy = detection.metadata;
55607
55673
  if (!legacy) {
55608
55674
  return {
@@ -55714,7 +55780,7 @@ var init_metadata_migration = __esm(() => {
55714
55780
  });
55715
55781
 
55716
55782
  // src/services/file-operations/claudekit-scanner.ts
55717
- import { join as join39 } from "node:path";
55783
+ import { join as join40 } from "node:path";
55718
55784
  async function scanClaudeKitDirectory(directoryPath) {
55719
55785
  const counts = {
55720
55786
  agents: 0,
@@ -55728,33 +55794,33 @@ async function scanClaudeKitDirectory(directoryPath) {
55728
55794
  }
55729
55795
  const items = await import_fs_extra4.readdir(directoryPath);
55730
55796
  if (items.includes("agents")) {
55731
- const agentsPath = join39(directoryPath, "agents");
55797
+ const agentsPath = join40(directoryPath, "agents");
55732
55798
  const agentFiles = await import_fs_extra4.readdir(agentsPath);
55733
55799
  counts.agents = agentFiles.filter((file) => file.endsWith(".md")).length;
55734
55800
  }
55735
55801
  if (items.includes("commands")) {
55736
- const commandsPath = join39(directoryPath, "commands");
55802
+ const commandsPath = join40(directoryPath, "commands");
55737
55803
  const commandFiles = await import_fs_extra4.readdir(commandsPath);
55738
55804
  counts.commands = commandFiles.filter((file) => file.endsWith(".md")).length;
55739
55805
  }
55740
55806
  if (items.includes("rules")) {
55741
- const rulesPath = join39(directoryPath, "rules");
55807
+ const rulesPath = join40(directoryPath, "rules");
55742
55808
  const ruleFiles = await import_fs_extra4.readdir(rulesPath);
55743
55809
  counts.rules = ruleFiles.filter((file) => file.endsWith(".md")).length;
55744
55810
  } else if (items.includes("workflows")) {
55745
- const workflowsPath = join39(directoryPath, "workflows");
55811
+ const workflowsPath = join40(directoryPath, "workflows");
55746
55812
  const workflowFiles = await import_fs_extra4.readdir(workflowsPath);
55747
55813
  counts.rules = workflowFiles.filter((file) => file.endsWith(".md")).length;
55748
55814
  }
55749
55815
  if (items.includes("skills")) {
55750
- const skillsPath = join39(directoryPath, "skills");
55816
+ const skillsPath = join40(directoryPath, "skills");
55751
55817
  const skillItems = await import_fs_extra4.readdir(skillsPath);
55752
55818
  let skillCount = 0;
55753
55819
  for (const item of skillItems) {
55754
55820
  if (SKIP_DIRS_CLAUDE_INTERNAL.includes(item)) {
55755
55821
  continue;
55756
55822
  }
55757
- const itemPath = join39(skillsPath, item);
55823
+ const itemPath = join40(skillsPath, item);
55758
55824
  const stat8 = await import_fs_extra4.readdir(itemPath).catch(() => null);
55759
55825
  if (stat8?.includes("SKILL.md")) {
55760
55826
  skillCount++;
@@ -55796,14 +55862,14 @@ async function getClaudeKitSetup(projectDir = process.cwd()) {
55796
55862
  const globalDir = getGlobalInstallDir();
55797
55863
  if (await import_fs_extra4.pathExists(globalDir)) {
55798
55864
  setup.global.path = globalDir;
55799
- setup.global.metadata = await readClaudeKitMetadata(join39(globalDir, "metadata.json"));
55865
+ setup.global.metadata = await readClaudeKitMetadata(join40(globalDir, "metadata.json"));
55800
55866
  setup.global.components = await scanClaudeKitDirectory(globalDir);
55801
55867
  }
55802
- const projectClaudeDir = join39(projectDir, ".claude");
55868
+ const projectClaudeDir = join40(projectDir, ".claude");
55803
55869
  const isLocalSameAsGlobal = projectClaudeDir === globalDir;
55804
55870
  if (!isLocalSameAsGlobal && await import_fs_extra4.pathExists(projectClaudeDir)) {
55805
55871
  setup.project.path = projectClaudeDir;
55806
- setup.project.metadata = await readClaudeKitMetadata(join39(projectClaudeDir, "metadata.json"));
55872
+ setup.project.metadata = await readClaudeKitMetadata(join40(projectClaudeDir, "metadata.json"));
55807
55873
  setup.project.components = await scanClaudeKitDirectory(projectClaudeDir);
55808
55874
  }
55809
55875
  return setup;
@@ -55942,7 +56008,7 @@ var package_default;
55942
56008
  var init_package = __esm(() => {
55943
56009
  package_default = {
55944
56010
  name: "claudekit-cli",
55945
- version: "3.36.0-dev.12",
56011
+ version: "3.36.0-dev.14",
55946
56012
  description: "CLI tool for bootstrapping and updating ClaudeKit projects",
55947
56013
  type: "module",
55948
56014
  repository: {
@@ -56051,7 +56117,7 @@ var init_package = __esm(() => {
56051
56117
 
56052
56118
  // src/commands/update-cli.ts
56053
56119
  import { exec as exec2 } from "node:child_process";
56054
- import { join as join40 } from "node:path";
56120
+ import { join as join41 } from "node:path";
56055
56121
  import { promisify as promisify8 } from "node:util";
56056
56122
  function getDefaultUpdateCliCommandDeps() {
56057
56123
  return {
@@ -56130,7 +56196,7 @@ function selectKitForUpdate(params) {
56130
56196
  };
56131
56197
  }
56132
56198
  async function readMetadataFile(claudeDir2) {
56133
- const metadataPath = join40(claudeDir2, "metadata.json");
56199
+ const metadataPath = join41(claudeDir2, "metadata.json");
56134
56200
  try {
56135
56201
  if (!await import_fs_extra5.pathExists(metadataPath)) {
56136
56202
  return null;
@@ -56148,9 +56214,10 @@ async function readMetadataFile(claudeDir2) {
56148
56214
  return null;
56149
56215
  }
56150
56216
  }
56151
- async function promptKitUpdate(beta, yes) {
56217
+ async function promptKitUpdate(beta, yes, deps) {
56152
56218
  try {
56153
- const setup = await getClaudeKitSetup();
56219
+ const execFn = deps?.execAsyncFn ?? execAsync2;
56220
+ const setup = await (deps?.getSetupFn ?? getClaudeKitSetup)();
56154
56221
  const hasLocal = !!setup.project.metadata;
56155
56222
  const hasGlobal = !!setup.global.metadata;
56156
56223
  const localMetadata = hasLocal ? await readMetadataFile(setup.project.path) : null;
@@ -56166,6 +56233,9 @@ async function promptKitUpdate(beta, yes) {
56166
56233
  const isBetaInstalled = isBetaVersion(kitVersion);
56167
56234
  const initCmd = buildInitCommand(selection.isGlobal, selection.kit, beta || isBetaInstalled);
56168
56235
  const promptMessage = selection.promptMessage;
56236
+ if (selection.kit && kitVersion) {
56237
+ logger.info(`Current kit version: ${selection.kit}@${kitVersion}`);
56238
+ }
56169
56239
  if (!yes) {
56170
56240
  logger.info("");
56171
56241
  const shouldUpdate = await se({
@@ -56179,13 +56249,25 @@ async function promptKitUpdate(beta, yes) {
56179
56249
  logger.verbose("Auto-proceeding with kit update (--yes flag)");
56180
56250
  }
56181
56251
  logger.info(`Running: ${initCmd}`);
56182
- const s = de();
56252
+ const s = (deps?.spinnerFn ?? de)();
56183
56253
  s.start("Updating ClaudeKit content...");
56184
56254
  try {
56185
- await execAsync2(initCmd, {
56255
+ await execFn(initCmd, {
56186
56256
  timeout: 300000
56187
56257
  });
56188
- s.stop("Kit content updated");
56258
+ let newKitVersion;
56259
+ try {
56260
+ const claudeDir2 = selection.isGlobal ? setup.global.path : setup.project.path;
56261
+ const updatedMetadata = await readMetadataFile(claudeDir2);
56262
+ newKitVersion = selection.kit ? updatedMetadata?.kits?.[selection.kit]?.version : undefined;
56263
+ } catch {}
56264
+ if (selection.kit && kitVersion && newKitVersion && kitVersion !== newKitVersion) {
56265
+ s.stop(`Kit updated: ${selection.kit}@${kitVersion} -> ${newKitVersion}`);
56266
+ } else if (selection.kit && newKitVersion) {
56267
+ s.stop(`Kit content updated (${selection.kit}@${newKitVersion})`);
56268
+ } else {
56269
+ s.stop("Kit content updated");
56270
+ }
56189
56271
  } catch (error) {
56190
56272
  s.stop("Kit update finished");
56191
56273
  const errorMsg = error instanceof Error ? error.message : "unknown";
@@ -56838,7 +56920,7 @@ var init_error_handler2 = __esm(() => {
56838
56920
  // src/domains/versioning/release-cache.ts
56839
56921
  import { existsSync as existsSync35 } from "node:fs";
56840
56922
  import { mkdir as mkdir12, readFile as readFile26, unlink as unlink6, writeFile as writeFile14 } from "node:fs/promises";
56841
- import { join as join41 } from "node:path";
56923
+ import { join as join42 } from "node:path";
56842
56924
  var ReleaseCacheEntrySchema, ReleaseCache;
56843
56925
  var init_release_cache = __esm(() => {
56844
56926
  init_logger();
@@ -56853,7 +56935,7 @@ var init_release_cache = __esm(() => {
56853
56935
  static CACHE_TTL_SECONDS = Number(process.env.CK_CACHE_TTL) || 3600;
56854
56936
  cacheDir;
56855
56937
  constructor() {
56856
- this.cacheDir = join41(PathResolver.getCacheDir(false), ReleaseCache.CACHE_DIR);
56938
+ this.cacheDir = join42(PathResolver.getCacheDir(false), ReleaseCache.CACHE_DIR);
56857
56939
  }
56858
56940
  async get(key) {
56859
56941
  const cacheFile = this.getCachePath(key);
@@ -56911,7 +56993,7 @@ var init_release_cache = __esm(() => {
56911
56993
  const files = await readdir10(this.cacheDir);
56912
56994
  for (const file of files) {
56913
56995
  if (file.endsWith(".json")) {
56914
- await unlink6(join41(this.cacheDir, file));
56996
+ await unlink6(join42(this.cacheDir, file));
56915
56997
  }
56916
56998
  }
56917
56999
  logger.debug("All release cache cleared");
@@ -56922,7 +57004,7 @@ var init_release_cache = __esm(() => {
56922
57004
  }
56923
57005
  getCachePath(key) {
56924
57006
  const safeKey = key.replace(/[^a-zA-Z0-9_-]/g, "_");
56925
- return join41(this.cacheDir, `${safeKey}.json`);
57007
+ return join42(this.cacheDir, `${safeKey}.json`);
56926
57008
  }
56927
57009
  isExpired(timestamp) {
56928
57010
  const now = Date.now();
@@ -57600,7 +57682,7 @@ var init_version_utils = __esm(() => {
57600
57682
  // src/domains/versioning/version-cache.ts
57601
57683
  import { existsSync as existsSync36 } from "node:fs";
57602
57684
  import { mkdir as mkdir13, readFile as readFile27, writeFile as writeFile15 } from "node:fs/promises";
57603
- import { join as join42 } from "node:path";
57685
+ import { join as join43 } from "node:path";
57604
57686
  var VersionCacheManager;
57605
57687
  var init_version_cache = __esm(() => {
57606
57688
  init_logger();
@@ -57610,7 +57692,7 @@ var init_version_cache = __esm(() => {
57610
57692
  static CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000;
57611
57693
  static getCacheFile() {
57612
57694
  const cacheDir = PathResolver.getCacheDir(false);
57613
- return join42(cacheDir, VersionCacheManager.CACHE_FILENAME);
57695
+ return join43(cacheDir, VersionCacheManager.CACHE_FILENAME);
57614
57696
  }
57615
57697
  static async load() {
57616
57698
  const cacheFile = VersionCacheManager.getCacheFile();
@@ -57879,7 +57961,7 @@ var init_version_checker = __esm(() => {
57879
57961
  import { spawn as spawn2 } from "node:child_process";
57880
57962
  import { existsSync as existsSync37 } from "node:fs";
57881
57963
  import { readFile as readFile28 } from "node:fs/promises";
57882
- import { join as join43 } from "node:path";
57964
+ import { join as join44 } from "node:path";
57883
57965
  function hasCliUpdate(currentVersion, latestVersion) {
57884
57966
  if (!latestVersion) {
57885
57967
  return false;
@@ -58122,7 +58204,7 @@ async function getPackageJson() {
58122
58204
  }
58123
58205
  async function getKitMetadata2(kitName) {
58124
58206
  try {
58125
- const metadataPath = join43(PathResolver.getGlobalKitDir(), "metadata.json");
58207
+ const metadataPath = join44(PathResolver.getGlobalKitDir(), "metadata.json");
58126
58208
  if (!existsSync37(metadataPath))
58127
58209
  return null;
58128
58210
  const content = await readFile28(metadataPath, "utf-8");
@@ -58267,7 +58349,7 @@ var init_routes = __esm(() => {
58267
58349
 
58268
58350
  // src/domains/web-server/static-server.ts
58269
58351
  import { existsSync as existsSync38 } from "node:fs";
58270
- import { dirname as dirname18, extname as extname4, join as join44 } from "node:path";
58352
+ import { dirname as dirname18, extname as extname4, join as join45 } from "node:path";
58271
58353
  import { fileURLToPath as fileURLToPath2 } from "node:url";
58272
58354
  function tryServeFromEmbedded(app) {
58273
58355
  if (typeof globalThis.Bun === "undefined" || !globalThis.Bun.embeddedFiles?.length) {
@@ -58328,12 +58410,12 @@ function tryServeFromEmbedded(app) {
58328
58410
  }
58329
58411
  function resolveUiDistPath() {
58330
58412
  const candidates = [
58331
- join44(__dirname3, "ui"),
58332
- join44(process.cwd(), "dist", "ui"),
58333
- join44(process.cwd(), "src", "ui", "dist")
58413
+ join45(__dirname3, "ui"),
58414
+ join45(process.cwd(), "dist", "ui"),
58415
+ join45(process.cwd(), "src", "ui", "dist")
58334
58416
  ];
58335
58417
  for (const path4 of candidates) {
58336
- if (existsSync38(join44(path4, "index.html"))) {
58418
+ if (existsSync38(join45(path4, "index.html"))) {
58337
58419
  return path4;
58338
58420
  }
58339
58421
  }
@@ -58376,7 +58458,7 @@ function serveStatic(app) {
58376
58458
  if (req.path.startsWith("/assets/") || req.path.match(/\.(js|css|ico|png|jpg|svg|woff2?)$/)) {
58377
58459
  return next();
58378
58460
  }
58379
- res.sendFile(join44(uiDistPath, "index.html"), { dotfiles: "allow" });
58461
+ res.sendFile(join45(uiDistPath, "index.html"), { dotfiles: "allow" });
58380
58462
  });
58381
58463
  logger.debug(`Serving static files from ${uiDistPath}`);
58382
58464
  }
@@ -63376,7 +63458,7 @@ var init_gemini_installer = __esm(() => {
63376
63458
  });
63377
63459
 
63378
63460
  // src/services/package-installer/opencode-installer.ts
63379
- import { join as join62 } from "node:path";
63461
+ import { join as join63 } from "node:path";
63380
63462
  async function isOpenCodeInstalled() {
63381
63463
  try {
63382
63464
  await execAsync7("opencode --version", { timeout: 5000 });
@@ -63399,7 +63481,7 @@ async function installOpenCode() {
63399
63481
  logger.info(`Installing ${displayName}...`);
63400
63482
  const { unlink: unlink11 } = await import("node:fs/promises");
63401
63483
  const { tmpdir: tmpdir4 } = await import("node:os");
63402
- const tempScriptPath = join62(tmpdir4(), "opencode-install.sh");
63484
+ const tempScriptPath = join63(tmpdir4(), "opencode-install.sh");
63403
63485
  try {
63404
63486
  logger.info("Downloading OpenCode installation script...");
63405
63487
  await execFileAsync5("curl", ["-fsSL", "https://opencode.ai/install", "-o", tempScriptPath], {
@@ -63451,7 +63533,7 @@ var PARTIAL_INSTALL_VERSION = "partial", EXIT_CODE_CRITICAL_FAILURE = 1, EXIT_CO
63451
63533
 
63452
63534
  // src/services/package-installer/install-error-handler.ts
63453
63535
  import { existsSync as existsSync49, readFileSync as readFileSync12, unlinkSync as unlinkSync2 } from "node:fs";
63454
- import { join as join63 } from "node:path";
63536
+ import { join as join64 } from "node:path";
63455
63537
  function parseNameReason(str2) {
63456
63538
  const colonIndex = str2.indexOf(":");
63457
63539
  if (colonIndex === -1) {
@@ -63460,7 +63542,7 @@ function parseNameReason(str2) {
63460
63542
  return [str2.slice(0, colonIndex).trim(), str2.slice(colonIndex + 1).trim()];
63461
63543
  }
63462
63544
  function displayInstallErrors(skillsDir2) {
63463
- const summaryPath = join63(skillsDir2, ".install-error-summary.json");
63545
+ const summaryPath = join64(skillsDir2, ".install-error-summary.json");
63464
63546
  if (!existsSync49(summaryPath)) {
63465
63547
  logger.error("Skills installation failed. Run with --verbose for details.");
63466
63548
  return;
@@ -63551,7 +63633,7 @@ async function checkNeedsSudoPackages() {
63551
63633
  }
63552
63634
  }
63553
63635
  function hasInstallState(skillsDir2) {
63554
- const stateFilePath = join63(skillsDir2, ".install-state.json");
63636
+ const stateFilePath = join64(skillsDir2, ".install-state.json");
63555
63637
  return existsSync49(stateFilePath);
63556
63638
  }
63557
63639
  var WHICH_COMMAND_TIMEOUT_MS = 5000;
@@ -63560,7 +63642,7 @@ var init_install_error_handler = __esm(() => {
63560
63642
  });
63561
63643
 
63562
63644
  // src/services/package-installer/skills-installer.ts
63563
- import { join as join64 } from "node:path";
63645
+ import { join as join65 } from "node:path";
63564
63646
  async function installSkillsDependencies(skillsDir2, options2 = {}) {
63565
63647
  const { skipConfirm = false, withSudo = false } = options2;
63566
63648
  const displayName = "Skills Dependencies";
@@ -63586,7 +63668,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
63586
63668
  const clack = await Promise.resolve().then(() => (init_dist2(), exports_dist));
63587
63669
  const platform7 = process.platform;
63588
63670
  const scriptName = platform7 === "win32" ? "install.ps1" : "install.sh";
63589
- const scriptPath = join64(skillsDir2, scriptName);
63671
+ const scriptPath = join65(skillsDir2, scriptName);
63590
63672
  try {
63591
63673
  validateScriptPath(skillsDir2, scriptPath);
63592
63674
  } catch (error) {
@@ -63602,7 +63684,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
63602
63684
  logger.warning(`Skills installation script not found: ${scriptPath}`);
63603
63685
  logger.info("");
63604
63686
  logger.info("\uD83D\uDCD6 Manual Installation Instructions:");
63605
- logger.info(` See: ${join64(skillsDir2, "INSTALLATION.md")}`);
63687
+ logger.info(` See: ${join65(skillsDir2, "INSTALLATION.md")}`);
63606
63688
  logger.info("");
63607
63689
  logger.info("Quick start:");
63608
63690
  logger.info(" cd .claude/skills/ai-multimodal/scripts");
@@ -63649,7 +63731,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
63649
63731
  logger.info(` ${platform7 === "win32" ? `powershell -File "${scriptPath}"` : `bash ${scriptPath}`}`);
63650
63732
  logger.info("");
63651
63733
  logger.info("Or see complete guide:");
63652
- logger.info(` ${join64(skillsDir2, "INSTALLATION.md")}`);
63734
+ logger.info(` ${join65(skillsDir2, "INSTALLATION.md")}`);
63653
63735
  return {
63654
63736
  success: false,
63655
63737
  package: displayName,
@@ -63770,7 +63852,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
63770
63852
  logger.info("\uD83D\uDCD6 Manual Installation Instructions:");
63771
63853
  logger.info("");
63772
63854
  logger.info("See complete guide:");
63773
- logger.info(` cat ${join64(skillsDir2, "INSTALLATION.md")}`);
63855
+ logger.info(` cat ${join65(skillsDir2, "INSTALLATION.md")}`);
63774
63856
  logger.info("");
63775
63857
  logger.info("Quick start:");
63776
63858
  logger.info(" cd .claude/skills/ai-multimodal/scripts");
@@ -63816,7 +63898,7 @@ var init_skills_installer2 = __esm(() => {
63816
63898
  // src/services/package-installer/gemini-mcp/config-manager.ts
63817
63899
  import { existsSync as existsSync50 } from "node:fs";
63818
63900
  import { mkdir as mkdir17, readFile as readFile35, writeFile as writeFile20 } from "node:fs/promises";
63819
- import { dirname as dirname21, join as join65 } from "node:path";
63901
+ import { dirname as dirname21, join as join66 } from "node:path";
63820
63902
  async function readJsonFile(filePath) {
63821
63903
  try {
63822
63904
  const content = await readFile35(filePath, "utf-8");
@@ -63828,7 +63910,7 @@ async function readJsonFile(filePath) {
63828
63910
  }
63829
63911
  }
63830
63912
  async function addGeminiToGitignore(projectDir) {
63831
- const gitignorePath = join65(projectDir, ".gitignore");
63913
+ const gitignorePath = join66(projectDir, ".gitignore");
63832
63914
  const geminiPattern = ".gemini/";
63833
63915
  try {
63834
63916
  let content = "";
@@ -63919,13 +64001,13 @@ var init_config_manager2 = __esm(() => {
63919
64001
 
63920
64002
  // src/services/package-installer/gemini-mcp/validation.ts
63921
64003
  import { existsSync as existsSync51, lstatSync, readlinkSync } from "node:fs";
63922
- import { homedir as homedir27 } from "node:os";
63923
- import { join as join66 } from "node:path";
64004
+ import { homedir as homedir28 } from "node:os";
64005
+ import { join as join67 } from "node:path";
63924
64006
  function getGlobalMcpConfigPath() {
63925
- return join66(homedir27(), ".claude", ".mcp.json");
64007
+ return join67(homedir28(), ".claude", ".mcp.json");
63926
64008
  }
63927
64009
  function getLocalMcpConfigPath(projectDir) {
63928
- return join66(projectDir, ".mcp.json");
64010
+ return join67(projectDir, ".mcp.json");
63929
64011
  }
63930
64012
  function findMcpConfigPath(projectDir) {
63931
64013
  const localPath = getLocalMcpConfigPath(projectDir);
@@ -63943,9 +64025,9 @@ function findMcpConfigPath(projectDir) {
63943
64025
  }
63944
64026
  function getGeminiSettingsPath(projectDir, isGlobal) {
63945
64027
  if (isGlobal) {
63946
- return join66(homedir27(), ".gemini", "settings.json");
64028
+ return join67(homedir28(), ".gemini", "settings.json");
63947
64029
  }
63948
- return join66(projectDir, ".gemini", "settings.json");
64030
+ return join67(projectDir, ".gemini", "settings.json");
63949
64031
  }
63950
64032
  function checkExistingGeminiConfig(projectDir, isGlobal = false) {
63951
64033
  const geminiSettingsPath = getGeminiSettingsPath(projectDir, isGlobal);
@@ -63975,7 +64057,7 @@ var init_validation = __esm(() => {
63975
64057
  // src/services/package-installer/gemini-mcp/linker-core.ts
63976
64058
  import { existsSync as existsSync52 } from "node:fs";
63977
64059
  import { mkdir as mkdir18, symlink as symlink2 } from "node:fs/promises";
63978
- import { dirname as dirname22, join as join67 } from "node:path";
64060
+ import { dirname as dirname22, join as join68 } from "node:path";
63979
64061
  async function createSymlink(targetPath, linkPath, projectDir, isGlobal) {
63980
64062
  const linkDir = dirname22(linkPath);
63981
64063
  if (!existsSync52(linkDir)) {
@@ -63986,7 +64068,7 @@ async function createSymlink(targetPath, linkPath, projectDir, isGlobal) {
63986
64068
  if (isGlobal) {
63987
64069
  symlinkTarget = getGlobalMcpConfigPath();
63988
64070
  } else {
63989
- const localMcpPath = join67(projectDir, ".mcp.json");
64071
+ const localMcpPath = join68(projectDir, ".mcp.json");
63990
64072
  const isLocalConfig = targetPath === localMcpPath;
63991
64073
  symlinkTarget = isLocalConfig ? "../.mcp.json" : targetPath;
63992
64074
  }
@@ -70887,14 +70969,14 @@ async function checkCliInstallMethod() {
70887
70969
  }
70888
70970
  // src/domains/health-checks/checkers/claude-md-checker.ts
70889
70971
  import { existsSync as existsSync40, statSync as statSync5 } from "node:fs";
70890
- import { join as join45 } from "node:path";
70972
+ import { join as join46 } from "node:path";
70891
70973
  function checkClaudeMd(setup, projectDir) {
70892
70974
  const results = [];
70893
70975
  if (setup.global.path) {
70894
- const globalClaudeMd = join45(setup.global.path, "CLAUDE.md");
70976
+ const globalClaudeMd = join46(setup.global.path, "CLAUDE.md");
70895
70977
  results.push(checkClaudeMdFile(globalClaudeMd, "Global CLAUDE.md", "ck-global-claude-md"));
70896
70978
  }
70897
- const projectClaudeMd = join45(projectDir, ".claude", "CLAUDE.md");
70979
+ const projectClaudeMd = join46(projectDir, ".claude", "CLAUDE.md");
70898
70980
  results.push(checkClaudeMdFile(projectClaudeMd, "Project CLAUDE.md", "ck-project-claude-md"));
70899
70981
  return results;
70900
70982
  }
@@ -70953,9 +71035,9 @@ function checkClaudeMdFile(path4, name, id) {
70953
71035
  }
70954
71036
  // src/domains/health-checks/checkers/active-plan-checker.ts
70955
71037
  import { existsSync as existsSync41, readFileSync as readFileSync9 } from "node:fs";
70956
- import { join as join46 } from "node:path";
71038
+ import { join as join47 } from "node:path";
70957
71039
  function checkActivePlan(projectDir) {
70958
- const activePlanPath = join46(projectDir, ".claude", "active-plan");
71040
+ const activePlanPath = join47(projectDir, ".claude", "active-plan");
70959
71041
  if (!existsSync41(activePlanPath)) {
70960
71042
  return {
70961
71043
  id: "ck-active-plan",
@@ -70969,7 +71051,7 @@ function checkActivePlan(projectDir) {
70969
71051
  }
70970
71052
  try {
70971
71053
  const targetPath = readFileSync9(activePlanPath, "utf-8").trim();
70972
- const fullPath = join46(projectDir, targetPath);
71054
+ const fullPath = join47(projectDir, targetPath);
70973
71055
  if (!existsSync41(fullPath)) {
70974
71056
  return {
70975
71057
  id: "ck-active-plan",
@@ -71007,13 +71089,13 @@ function checkActivePlan(projectDir) {
71007
71089
  }
71008
71090
  // src/domains/health-checks/checkers/skills-checker.ts
71009
71091
  import { existsSync as existsSync42 } from "node:fs";
71010
- import { join as join47 } from "node:path";
71092
+ import { join as join48 } from "node:path";
71011
71093
  function checkSkillsScripts(setup) {
71012
71094
  const results = [];
71013
71095
  const platform5 = process.platform;
71014
71096
  const scriptName = platform5 === "win32" ? "install.ps1" : "install.sh";
71015
71097
  if (setup.global.path) {
71016
- const globalScriptPath = join47(setup.global.path, "skills", scriptName);
71098
+ const globalScriptPath = join48(setup.global.path, "skills", scriptName);
71017
71099
  const hasGlobalScript = existsSync42(globalScriptPath);
71018
71100
  results.push({
71019
71101
  id: "ck-global-skills-script",
@@ -71028,7 +71110,7 @@ function checkSkillsScripts(setup) {
71028
71110
  });
71029
71111
  }
71030
71112
  if (setup.project.metadata) {
71031
- const projectScriptPath = join47(setup.project.path, "skills", scriptName);
71113
+ const projectScriptPath = join48(setup.project.path, "skills", scriptName);
71032
71114
  const hasProjectScript = existsSync42(projectScriptPath);
71033
71115
  results.push({
71034
71116
  id: "ck-project-skills-script",
@@ -71067,7 +71149,7 @@ function checkComponentCounts(setup) {
71067
71149
  init_logger();
71068
71150
  init_path_resolver();
71069
71151
  import { constants as constants2, access as access2, unlink as unlink7, writeFile as writeFile16 } from "node:fs/promises";
71070
- import { join as join48 } from "node:path";
71152
+ import { join as join49 } from "node:path";
71071
71153
 
71072
71154
  // src/domains/health-checks/checkers/shared.ts
71073
71155
  init_environment();
@@ -71133,7 +71215,7 @@ async function checkGlobalDirWritable() {
71133
71215
  }
71134
71216
  const timestamp = Date.now();
71135
71217
  const random = Math.random().toString(36).substring(2);
71136
- const testFile = join48(globalDir, `.ck-write-test-${timestamp}-${random}`);
71218
+ const testFile = join49(globalDir, `.ck-write-test-${timestamp}-${random}`);
71137
71219
  try {
71138
71220
  await writeFile16(testFile, "test", { encoding: "utf-8", flag: "wx" });
71139
71221
  } catch (error) {
@@ -71169,7 +71251,7 @@ async function checkGlobalDirWritable() {
71169
71251
  init_path_resolver();
71170
71252
  import { existsSync as existsSync43 } from "node:fs";
71171
71253
  import { readdir as readdir10 } from "node:fs/promises";
71172
- import { join as join49 } from "node:path";
71254
+ import { join as join50 } from "node:path";
71173
71255
 
71174
71256
  // src/domains/health-checks/utils/path-normalizer.ts
71175
71257
  import { normalize as normalize4 } from "node:path";
@@ -71181,8 +71263,8 @@ function normalizePath2(filePath) {
71181
71263
 
71182
71264
  // src/domains/health-checks/checkers/hooks-checker.ts
71183
71265
  async function checkHooksExist(projectDir) {
71184
- const globalHooksDir = join49(PathResolver.getGlobalKitDir(), "hooks");
71185
- const projectHooksDir = join49(projectDir, ".claude", "hooks");
71266
+ const globalHooksDir = join50(PathResolver.getGlobalKitDir(), "hooks");
71267
+ const projectHooksDir = join50(projectDir, ".claude", "hooks");
71186
71268
  const globalExists = existsSync43(globalHooksDir);
71187
71269
  const projectExists = existsSync43(projectHooksDir);
71188
71270
  let hookCount = 0;
@@ -71191,7 +71273,7 @@ async function checkHooksExist(projectDir) {
71191
71273
  const files = await readdir10(globalHooksDir, { withFileTypes: false });
71192
71274
  const hooks = files.filter((f3) => HOOK_EXTENSIONS2.some((ext) => f3.endsWith(ext)));
71193
71275
  hooks.forEach((hook) => {
71194
- const fullPath = join49(globalHooksDir, hook);
71276
+ const fullPath = join50(globalHooksDir, hook);
71195
71277
  checkedFiles.add(normalizePath2(fullPath));
71196
71278
  });
71197
71279
  }
@@ -71201,7 +71283,7 @@ async function checkHooksExist(projectDir) {
71201
71283
  const files = await readdir10(projectHooksDir, { withFileTypes: false });
71202
71284
  const hooks = files.filter((f3) => HOOK_EXTENSIONS2.some((ext) => f3.endsWith(ext)));
71203
71285
  hooks.forEach((hook) => {
71204
- const fullPath = join49(projectHooksDir, hook);
71286
+ const fullPath = join50(projectHooksDir, hook);
71205
71287
  checkedFiles.add(normalizePath2(fullPath));
71206
71288
  });
71207
71289
  }
@@ -71233,10 +71315,10 @@ init_logger();
71233
71315
  init_path_resolver();
71234
71316
  import { existsSync as existsSync44 } from "node:fs";
71235
71317
  import { readFile as readFile29 } from "node:fs/promises";
71236
- import { join as join50 } from "node:path";
71318
+ import { join as join51 } from "node:path";
71237
71319
  async function checkSettingsValid(projectDir) {
71238
- const globalSettings = join50(PathResolver.getGlobalKitDir(), "settings.json");
71239
- const projectSettings = join50(projectDir, ".claude", "settings.json");
71320
+ const globalSettings = join51(PathResolver.getGlobalKitDir(), "settings.json");
71321
+ const projectSettings = join51(projectDir, ".claude", "settings.json");
71240
71322
  const settingsPath = existsSync44(globalSettings) ? globalSettings : existsSync44(projectSettings) ? projectSettings : null;
71241
71323
  if (!settingsPath) {
71242
71324
  return {
@@ -71308,11 +71390,11 @@ init_logger();
71308
71390
  init_path_resolver();
71309
71391
  import { existsSync as existsSync45 } from "node:fs";
71310
71392
  import { readFile as readFile30 } from "node:fs/promises";
71311
- import { homedir as homedir25 } from "node:os";
71312
- import { dirname as dirname19, join as join51, normalize as normalize5, resolve as resolve13 } from "node:path";
71393
+ import { homedir as homedir26 } from "node:os";
71394
+ import { dirname as dirname19, join as join52, normalize as normalize5, resolve as resolve13 } from "node:path";
71313
71395
  async function checkPathRefsValid(projectDir) {
71314
- const globalClaudeMd = join51(PathResolver.getGlobalKitDir(), "CLAUDE.md");
71315
- const projectClaudeMd = join51(projectDir, ".claude", "CLAUDE.md");
71396
+ const globalClaudeMd = join52(PathResolver.getGlobalKitDir(), "CLAUDE.md");
71397
+ const projectClaudeMd = join52(projectDir, ".claude", "CLAUDE.md");
71316
71398
  const claudeMdPath = existsSync45(globalClaudeMd) ? globalClaudeMd : existsSync45(projectClaudeMd) ? projectClaudeMd : null;
71317
71399
  if (!claudeMdPath) {
71318
71400
  return {
@@ -71341,7 +71423,7 @@ async function checkPathRefsValid(projectDir) {
71341
71423
  };
71342
71424
  }
71343
71425
  const baseDir = dirname19(claudeMdPath);
71344
- const home8 = homedir25();
71426
+ const home8 = homedir26();
71345
71427
  const broken = [];
71346
71428
  for (const ref of refs) {
71347
71429
  let refPath;
@@ -71407,7 +71489,7 @@ async function checkPathRefsValid(projectDir) {
71407
71489
  // src/domains/health-checks/checkers/config-completeness-checker.ts
71408
71490
  import { existsSync as existsSync46 } from "node:fs";
71409
71491
  import { readdir as readdir11 } from "node:fs/promises";
71410
- import { join as join52 } from "node:path";
71492
+ import { join as join53 } from "node:path";
71411
71493
  async function checkProjectConfigCompleteness(setup, projectDir) {
71412
71494
  if (setup.project.path === setup.global.path) {
71413
71495
  return {
@@ -71420,16 +71502,16 @@ async function checkProjectConfigCompleteness(setup, projectDir) {
71420
71502
  autoFixable: false
71421
71503
  };
71422
71504
  }
71423
- const projectClaudeDir = join52(projectDir, ".claude");
71505
+ const projectClaudeDir = join53(projectDir, ".claude");
71424
71506
  const requiredDirs = ["agents", "commands", "skills"];
71425
71507
  const missingDirs = [];
71426
71508
  for (const dir of requiredDirs) {
71427
- const dirPath = join52(projectClaudeDir, dir);
71509
+ const dirPath = join53(projectClaudeDir, dir);
71428
71510
  if (!existsSync46(dirPath)) {
71429
71511
  missingDirs.push(dir);
71430
71512
  }
71431
71513
  }
71432
- const hasRulesOrWorkflows = existsSync46(join52(projectClaudeDir, "rules")) || existsSync46(join52(projectClaudeDir, "workflows"));
71514
+ const hasRulesOrWorkflows = existsSync46(join53(projectClaudeDir, "rules")) || existsSync46(join53(projectClaudeDir, "workflows"));
71433
71515
  if (!hasRulesOrWorkflows) {
71434
71516
  missingDirs.push("rules");
71435
71517
  }
@@ -71474,7 +71556,7 @@ async function checkProjectConfigCompleteness(setup, projectDir) {
71474
71556
  };
71475
71557
  }
71476
71558
  // src/domains/health-checks/checkers/env-keys-checker.ts
71477
- import { join as join54 } from "node:path";
71559
+ import { join as join55 } from "node:path";
71478
71560
 
71479
71561
  // src/domains/installation/setup-wizard.ts
71480
71562
  init_config_generator();
@@ -71483,7 +71565,7 @@ init_logger();
71483
71565
  init_path_resolver();
71484
71566
  init_dist2();
71485
71567
  var import_fs_extra6 = __toESM(require_lib3(), 1);
71486
- import { join as join53 } from "node:path";
71568
+ import { join as join54 } from "node:path";
71487
71569
  var REQUIRED_ENV_KEYS = [
71488
71570
  { key: "GEMINI_API_KEY", label: "Gemini API Key" }
71489
71571
  ];
@@ -71560,7 +71642,7 @@ async function parseEnvFile(path4) {
71560
71642
  }
71561
71643
  }
71562
71644
  async function checkGlobalConfig() {
71563
- const globalEnvPath = join53(PathResolver.getGlobalKitDir(), ".env");
71645
+ const globalEnvPath = join54(PathResolver.getGlobalKitDir(), ".env");
71564
71646
  if (!await import_fs_extra6.pathExists(globalEnvPath))
71565
71647
  return false;
71566
71648
  const env2 = await parseEnvFile(globalEnvPath);
@@ -71576,7 +71658,7 @@ async function runSetupWizard(options2) {
71576
71658
  let globalEnv = {};
71577
71659
  const hasGlobalConfig = !isGlobal && await checkGlobalConfig();
71578
71660
  if (!isGlobal) {
71579
- const globalEnvPath = join53(PathResolver.getGlobalKitDir(), ".env");
71661
+ const globalEnvPath = join54(PathResolver.getGlobalKitDir(), ".env");
71580
71662
  if (await import_fs_extra6.pathExists(globalEnvPath)) {
71581
71663
  globalEnv = await parseEnvFile(globalEnvPath);
71582
71664
  }
@@ -71639,7 +71721,7 @@ async function runSetupWizard(options2) {
71639
71721
  }
71640
71722
  }
71641
71723
  await generateEnvFile(targetDir, values);
71642
- f2.success(`Configuration saved to ${join53(targetDir, ".env")}`);
71724
+ f2.success(`Configuration saved to ${join54(targetDir, ".env")}`);
71643
71725
  return true;
71644
71726
  }
71645
71727
  async function promptForAdditionalGeminiKeys(primaryKey) {
@@ -71714,7 +71796,7 @@ Optional: DISCORD_WEBHOOK_URL, TELEGRAM_BOT_TOKEN`, "Configuration skipped");
71714
71796
  async function checkEnvKeys(setup) {
71715
71797
  const results = [];
71716
71798
  if (setup.global.path) {
71717
- const globalEnvPath = join54(setup.global.path, ".env");
71799
+ const globalEnvPath = join55(setup.global.path, ".env");
71718
71800
  const globalCheck = await checkRequiredKeysExist(globalEnvPath);
71719
71801
  if (!globalCheck.allPresent) {
71720
71802
  const missingKeys = globalCheck.missing.map((m2) => m2.label).join(", ");
@@ -71743,7 +71825,7 @@ async function checkEnvKeys(setup) {
71743
71825
  }
71744
71826
  }
71745
71827
  if (setup.project.metadata) {
71746
- const projectEnvPath = join54(setup.project.path, ".env");
71828
+ const projectEnvPath = join55(setup.project.path, ".env");
71747
71829
  const projectCheck = await checkRequiredKeysExist(projectEnvPath);
71748
71830
  if (!projectCheck.allPresent) {
71749
71831
  const missingKeys = projectCheck.missing.map((m2) => m2.label).join(", ");
@@ -71781,7 +71863,7 @@ import { spawnSync as spawnSync2 } from "node:child_process";
71781
71863
  import { existsSync as existsSync47, readFileSync as readFileSync10, statSync as statSync6, writeFileSync as writeFileSync3 } from "node:fs";
71782
71864
  import { readdir as readdir12 } from "node:fs/promises";
71783
71865
  import { tmpdir } from "node:os";
71784
- import { join as join55, resolve as resolve14 } from "node:path";
71866
+ import { join as join56, resolve as resolve14 } from "node:path";
71785
71867
  var HOOK_CHECK_TIMEOUT_MS = 5000;
71786
71868
  var PYTHON_CHECK_TIMEOUT_MS = 3000;
71787
71869
  var MAX_LOG_FILE_SIZE_BYTES = 10 * 1024 * 1024;
@@ -71826,7 +71908,7 @@ async function checkHookSyntax(projectDir) {
71826
71908
  }
71827
71909
  const errors2 = [];
71828
71910
  for (const file of cjsFiles) {
71829
- const filePath = join55(hooksDir, file);
71911
+ const filePath = join56(hooksDir, file);
71830
71912
  if (!isPathWithin(filePath, hooksDir))
71831
71913
  continue;
71832
71914
  const result = spawnSync2("node", ["--check", filePath], {
@@ -71912,7 +71994,7 @@ async function checkHookDeps(projectDir) {
71912
71994
  const missingDeps = [];
71913
71995
  const requireRegex = /require\(['"]([^'"]+)['"]\)/g;
71914
71996
  for (const file of cjsFiles) {
71915
- const filePath = join55(hooksDir, file);
71997
+ const filePath = join56(hooksDir, file);
71916
71998
  if (!isPathWithin(filePath, hooksDir))
71917
71999
  continue;
71918
72000
  const content = readFileSync10(filePath, "utf-8");
@@ -71922,10 +72004,10 @@ async function checkHookDeps(projectDir) {
71922
72004
  continue;
71923
72005
  }
71924
72006
  if (depPath.startsWith(".")) {
71925
- const resolvedPath = join55(hooksDir, depPath);
72007
+ const resolvedPath = join56(hooksDir, depPath);
71926
72008
  const extensions = [".js", ".cjs", ".mjs", ".json"];
71927
72009
  const indexFiles = ["index.js", "index.cjs", "index.mjs"];
71928
- const exists = existsSync47(resolvedPath) || extensions.some((ext) => existsSync47(resolvedPath + ext)) || indexFiles.some((idx) => existsSync47(join55(resolvedPath, idx)));
72010
+ const exists = existsSync47(resolvedPath) || extensions.some((ext) => existsSync47(resolvedPath + ext)) || indexFiles.some((idx) => existsSync47(join56(resolvedPath, idx)));
71929
72011
  if (!exists) {
71930
72012
  missingDeps.push(`${file}: ${depPath}`);
71931
72013
  }
@@ -72042,11 +72124,11 @@ async function checkHookRuntime(projectDir) {
72042
72124
  }
72043
72125
  const syntheticPayload = JSON.stringify({
72044
72126
  tool_name: "Read",
72045
- tool_input: { file_path: join55(tmpdir(), "ck-doctor-test.txt") }
72127
+ tool_input: { file_path: join56(tmpdir(), "ck-doctor-test.txt") }
72046
72128
  });
72047
72129
  const failures = [];
72048
72130
  for (const file of cjsFiles) {
72049
- const filePath = join55(hooksDir, file);
72131
+ const filePath = join56(hooksDir, file);
72050
72132
  if (!isPathWithin(filePath, hooksDir))
72051
72133
  continue;
72052
72134
  const result = spawnSync2("node", [filePath], {
@@ -72108,8 +72190,8 @@ async function checkHookRuntime(projectDir) {
72108
72190
  }
72109
72191
  }
72110
72192
  async function checkHookConfig(projectDir) {
72111
- const projectConfigPath = join55(projectDir, ".claude", ".ck.json");
72112
- const globalConfigPath = join55(PathResolver.getGlobalKitDir(), ".ck.json");
72193
+ const projectConfigPath = join56(projectDir, ".claude", ".ck.json");
72194
+ const globalConfigPath = join56(PathResolver.getGlobalKitDir(), ".ck.json");
72113
72195
  const configPath = existsSync47(projectConfigPath) ? projectConfigPath : existsSync47(globalConfigPath) ? globalConfigPath : null;
72114
72196
  if (!configPath) {
72115
72197
  return {
@@ -72233,7 +72315,7 @@ async function checkHookLogs(projectDir) {
72233
72315
  autoFixable: false
72234
72316
  };
72235
72317
  }
72236
- const logPath = join55(hooksDir, ".logs", "hook-log.jsonl");
72318
+ const logPath = join56(hooksDir, ".logs", "hook-log.jsonl");
72237
72319
  if (!existsSync47(logPath)) {
72238
72320
  return {
72239
72321
  id: "hook-logs",
@@ -72488,9 +72570,9 @@ async function checkCliVersion() {
72488
72570
  }
72489
72571
  async function checkPythonVenv(projectDir) {
72490
72572
  const isWindows3 = process.platform === "win32";
72491
- const venvBin = isWindows3 ? join55("Scripts", "python.exe") : join55("bin", "python3");
72492
- const projectVenvPath = join55(projectDir, ".claude", "skills", ".venv", venvBin);
72493
- const globalVenvPath = join55(PathResolver.getGlobalKitDir(), "skills", ".venv", venvBin);
72573
+ const venvBin = isWindows3 ? join56("Scripts", "python.exe") : join56("bin", "python3");
72574
+ const projectVenvPath = join56(projectDir, ".claude", "skills", ".venv", venvBin);
72575
+ const globalVenvPath = join56(PathResolver.getGlobalKitDir(), "skills", ".venv", venvBin);
72494
72576
  const venvPath = existsSync47(projectVenvPath) ? projectVenvPath : existsSync47(globalVenvPath) ? globalVenvPath : null;
72495
72577
  if (!venvPath) {
72496
72578
  return {
@@ -72970,8 +73052,8 @@ import { platform as platform6 } from "node:os";
72970
73052
  init_environment();
72971
73053
  init_path_resolver();
72972
73054
  import { constants as constants3, access as access3, mkdir as mkdir14, readFile as readFile32, unlink as unlink8, writeFile as writeFile17 } from "node:fs/promises";
72973
- import { arch as arch2, homedir as homedir26, platform as platform5 } from "node:os";
72974
- import { join as join57, normalize as normalize6 } from "node:path";
73055
+ import { arch as arch2, homedir as homedir27, platform as platform5 } from "node:os";
73056
+ import { join as join58, normalize as normalize6 } from "node:path";
72975
73057
  function shouldSkipExpensiveOperations4() {
72976
73058
  return shouldSkipExpensiveOperations();
72977
73059
  }
@@ -72993,7 +73075,7 @@ async function checkPlatformDetect() {
72993
73075
  };
72994
73076
  }
72995
73077
  async function checkHomeDirResolution() {
72996
- const nodeHome = normalize6(homedir26());
73078
+ const nodeHome = normalize6(homedir27());
72997
73079
  const rawEnvHome = getHomeDirectoryFromEnv(platform5());
72998
73080
  const envHome = rawEnvHome ? normalize6(rawEnvHome) : "";
72999
73081
  const match = nodeHome === envHome && envHome !== "";
@@ -73062,7 +73144,7 @@ async function checkGlobalDirAccess() {
73062
73144
  autoFixable: false
73063
73145
  };
73064
73146
  }
73065
- const testFile = join57(globalDir, ".ck-doctor-access-test");
73147
+ const testFile = join58(globalDir, ".ck-doctor-access-test");
73066
73148
  try {
73067
73149
  await mkdir14(globalDir, { recursive: true });
73068
73150
  await writeFile17(testFile, "test", "utf-8");
@@ -73140,7 +73222,7 @@ async function checkWSLBoundary() {
73140
73222
  // src/domains/health-checks/platform/windows-checker.ts
73141
73223
  init_path_resolver();
73142
73224
  import { mkdir as mkdir15, symlink, unlink as unlink9, writeFile as writeFile18 } from "node:fs/promises";
73143
- import { join as join58 } from "node:path";
73225
+ import { join as join59 } from "node:path";
73144
73226
  async function checkLongPathSupport() {
73145
73227
  if (shouldSkipExpensiveOperations4()) {
73146
73228
  return {
@@ -73192,8 +73274,8 @@ async function checkSymlinkSupport() {
73192
73274
  };
73193
73275
  }
73194
73276
  const testDir = PathResolver.getGlobalKitDir();
73195
- const target = join58(testDir, ".ck-symlink-test-target");
73196
- const link = join58(testDir, ".ck-symlink-test-link");
73277
+ const target = join59(testDir, ".ck-symlink-test-target");
73278
+ const link = join59(testDir, ".ck-symlink-test-link");
73197
73279
  try {
73198
73280
  await mkdir15(testDir, { recursive: true });
73199
73281
  await writeFile18(target, "test", "utf-8");
@@ -73487,7 +73569,7 @@ class AutoHealer {
73487
73569
  import { execSync as execSync3, spawnSync as spawnSync5 } from "node:child_process";
73488
73570
  import { readFileSync as readFileSync11, unlinkSync, writeFileSync as writeFileSync4 } from "node:fs";
73489
73571
  import { tmpdir as tmpdir3 } from "node:os";
73490
- import { dirname as dirname20, join as join59 } from "node:path";
73572
+ import { dirname as dirname20, join as join60 } from "node:path";
73491
73573
  import { fileURLToPath as fileURLToPath4 } from "node:url";
73492
73574
  init_environment();
73493
73575
  init_logger();
@@ -73495,7 +73577,7 @@ init_dist2();
73495
73577
  function getCliVersion4() {
73496
73578
  try {
73497
73579
  const __dirname4 = dirname20(fileURLToPath4(import.meta.url));
73498
- const pkgPath = join59(__dirname4, "../../../package.json");
73580
+ const pkgPath = join60(__dirname4, "../../../package.json");
73499
73581
  const pkg = JSON.parse(readFileSync11(pkgPath, "utf-8"));
73500
73582
  return pkg.version || "unknown";
73501
73583
  } catch (err) {
@@ -73634,7 +73716,7 @@ class ReportGenerator {
73634
73716
  return null;
73635
73717
  }
73636
73718
  }
73637
- const tmpFile = join59(tmpdir3(), `ck-report-${Date.now()}.txt`);
73719
+ const tmpFile = join60(tmpdir3(), `ck-report-${Date.now()}.txt`);
73638
73720
  writeFileSync4(tmpFile, report);
73639
73721
  try {
73640
73722
  const result = spawnSync5("gh", ["gist", "create", tmpFile, "--desc", "ClaudeKit Diagnostic Report"], {
@@ -73960,7 +74042,7 @@ init_logger();
73960
74042
  init_path_resolver();
73961
74043
  var import_compare_versions6 = __toESM(require_umd(), 1);
73962
74044
  import { mkdir as mkdir16, readFile as readFile33, unlink as unlink10, writeFile as writeFile19 } from "node:fs/promises";
73963
- import { join as join60 } from "node:path";
74045
+ import { join as join61 } from "node:path";
73964
74046
  var CACHE_TTL_HOURS = 24;
73965
74047
  var DEFAULT_CACHE_TTL_MS = CACHE_TTL_HOURS * 60 * 60 * 1000;
73966
74048
  var MIN_CACHE_TTL_MS = 60 * 1000;
@@ -73997,7 +74079,7 @@ var KIT_REPOS = {
73997
74079
  class ConfigVersionChecker {
73998
74080
  static getCacheFilePath(kitType, global3) {
73999
74081
  const cacheDir = PathResolver.getCacheDir(global3);
74000
- return join60(cacheDir, `${kitType}-${CACHE_FILENAME}`);
74082
+ return join61(cacheDir, `${kitType}-${CACHE_FILENAME}`);
74001
74083
  }
74002
74084
  static async loadCache(kitType, global3) {
74003
74085
  try {
@@ -74160,7 +74242,7 @@ class ConfigVersionChecker {
74160
74242
  }
74161
74243
  // src/domains/sync/sync-engine.ts
74162
74244
  import { lstat as lstat3, readFile as readFile34, readlink, realpath as realpath3, stat as stat9 } from "node:fs/promises";
74163
- import { isAbsolute as isAbsolute3, join as join61, normalize as normalize7, relative as relative8 } from "node:path";
74245
+ import { isAbsolute as isAbsolute3, join as join62, normalize as normalize7, relative as relative8 } from "node:path";
74164
74246
 
74165
74247
  // src/services/file-operations/ownership-checker.ts
74166
74248
  init_metadata_migration();
@@ -75521,7 +75603,7 @@ async function validateSymlinkChain(path5, basePath, maxDepth = MAX_SYMLINK_DEPT
75521
75603
  if (!stats.isSymbolicLink())
75522
75604
  break;
75523
75605
  const target = await readlink(current);
75524
- const resolvedTarget = isAbsolute3(target) ? target : join61(current, "..", target);
75606
+ const resolvedTarget = isAbsolute3(target) ? target : join62(current, "..", target);
75525
75607
  const normalizedTarget = normalize7(resolvedTarget);
75526
75608
  const rel = relative8(basePath, normalizedTarget);
75527
75609
  if (rel.startsWith("..") || isAbsolute3(rel)) {
@@ -75557,7 +75639,7 @@ async function validateSyncPath(basePath, filePath) {
75557
75639
  if (normalized.startsWith("..") || normalized.includes("/../")) {
75558
75640
  throw new Error(`Path traversal not allowed: ${filePath}`);
75559
75641
  }
75560
- const fullPath = join61(basePath, normalized);
75642
+ const fullPath = join62(basePath, normalized);
75561
75643
  const rel = relative8(basePath, fullPath);
75562
75644
  if (rel.startsWith("..") || isAbsolute3(rel)) {
75563
75645
  throw new Error(`Path escapes base directory: ${filePath}`);
@@ -75572,7 +75654,7 @@ async function validateSyncPath(basePath, filePath) {
75572
75654
  }
75573
75655
  } catch (error) {
75574
75656
  if (error.code === "ENOENT") {
75575
- const parentPath = join61(fullPath, "..");
75657
+ const parentPath = join62(fullPath, "..");
75576
75658
  try {
75577
75659
  const resolvedBase = await realpath3(basePath);
75578
75660
  const resolvedParent = await realpath3(parentPath);
@@ -76754,7 +76836,7 @@ init_logger();
76754
76836
  var import_proper_lockfile4 = __toESM(require_proper_lockfile(), 1);
76755
76837
  import { mkdir as mkdir19 } from "node:fs/promises";
76756
76838
  import os5 from "node:os";
76757
- import { join as join68 } from "node:path";
76839
+ import { join as join69 } from "node:path";
76758
76840
  var LOCK_CONFIG = {
76759
76841
  stale: 60000,
76760
76842
  retries: 0
@@ -76762,12 +76844,12 @@ var LOCK_CONFIG = {
76762
76844
  var activeLocks = new Set;
76763
76845
  var cleanupRegistered = false;
76764
76846
  function getLocksDir() {
76765
- return join68(os5.homedir(), ".claudekit", "locks");
76847
+ return join69(os5.homedir(), ".claudekit", "locks");
76766
76848
  }
76767
76849
  function cleanupLocks() {
76768
76850
  for (const name of activeLocks) {
76769
76851
  try {
76770
- const lockPath = join68(getLocksDir(), `${name}.lock`);
76852
+ const lockPath = join69(getLocksDir(), `${name}.lock`);
76771
76853
  import_proper_lockfile4.default.unlockSync(lockPath, { realpath: false });
76772
76854
  } catch {
76773
76855
  try {
@@ -76790,7 +76872,7 @@ async function ensureLocksDir() {
76790
76872
  async function withProcessLock(lockName, fn) {
76791
76873
  registerCleanupHandlers();
76792
76874
  await ensureLocksDir();
76793
- const lockPath = join68(getLocksDir(), `${lockName}.lock`);
76875
+ const lockPath = join69(getLocksDir(), `${lockName}.lock`);
76794
76876
  let release;
76795
76877
  try {
76796
76878
  release = await import_proper_lockfile4.default.lock(lockPath, { ...LOCK_CONFIG, realpath: false });
@@ -76821,7 +76903,7 @@ init_logger();
76821
76903
  init_logger();
76822
76904
  init_path_resolver();
76823
76905
  var import_fs_extra7 = __toESM(require_lib3(), 1);
76824
- import { join as join69 } from "node:path";
76906
+ import { join as join70 } from "node:path";
76825
76907
  async function handleConflicts(ctx) {
76826
76908
  if (ctx.cancelled)
76827
76909
  return ctx;
@@ -76830,7 +76912,7 @@ async function handleConflicts(ctx) {
76830
76912
  if (PathResolver.isLocalSameAsGlobal()) {
76831
76913
  return ctx;
76832
76914
  }
76833
- const localSettingsPath = join69(process.cwd(), ".claude", "settings.json");
76915
+ const localSettingsPath = join70(process.cwd(), ".claude", "settings.json");
76834
76916
  if (!await import_fs_extra7.pathExists(localSettingsPath)) {
76835
76917
  return ctx;
76836
76918
  }
@@ -76845,7 +76927,7 @@ async function handleConflicts(ctx) {
76845
76927
  return { ...ctx, cancelled: true };
76846
76928
  }
76847
76929
  if (choice === "remove") {
76848
- const localClaudeDir = join69(process.cwd(), ".claude");
76930
+ const localClaudeDir = join70(process.cwd(), ".claude");
76849
76931
  try {
76850
76932
  await import_fs_extra7.remove(localClaudeDir);
76851
76933
  logger.success("Removed local .claude/ directory");
@@ -76942,7 +77024,7 @@ init_logger();
76942
77024
  init_safe_spinner();
76943
77025
  import { mkdir as mkdir25, stat as stat12 } from "node:fs/promises";
76944
77026
  import { tmpdir as tmpdir4 } from "node:os";
76945
- import { join as join76 } from "node:path";
77027
+ import { join as join77 } from "node:path";
76946
77028
 
76947
77029
  // src/shared/temp-cleanup.ts
76948
77030
  init_logger();
@@ -76961,7 +77043,7 @@ init_logger();
76961
77043
  init_output_manager();
76962
77044
  import { createWriteStream as createWriteStream2, rmSync as rmSync2 } from "node:fs";
76963
77045
  import { mkdir as mkdir20 } from "node:fs/promises";
76964
- import { join as join70 } from "node:path";
77046
+ import { join as join71 } from "node:path";
76965
77047
 
76966
77048
  // src/shared/progress-bar.ts
76967
77049
  init_output_manager();
@@ -77171,7 +77253,7 @@ var MAX_DOWNLOAD_SIZE = 500 * 1024 * 1024;
77171
77253
  class FileDownloader {
77172
77254
  async downloadAsset(asset, destDir) {
77173
77255
  try {
77174
- const destPath = join70(destDir, asset.name);
77256
+ const destPath = join71(destDir, asset.name);
77175
77257
  await mkdir20(destDir, { recursive: true });
77176
77258
  output.info(`Downloading ${asset.name} (${formatBytes(asset.size)})...`);
77177
77259
  logger.verbose("Download details", {
@@ -77256,7 +77338,7 @@ class FileDownloader {
77256
77338
  }
77257
77339
  async downloadFile(params) {
77258
77340
  const { url, name, size, destDir, token } = params;
77259
- const destPath = join70(destDir, name);
77341
+ const destPath = join71(destDir, name);
77260
77342
  await mkdir20(destDir, { recursive: true });
77261
77343
  output.info(`Downloading ${name}${size ? ` (${formatBytes(size)})` : ""}...`);
77262
77344
  const headers = {};
@@ -77342,7 +77424,7 @@ init_logger();
77342
77424
  init_types3();
77343
77425
  import { constants as constants4 } from "node:fs";
77344
77426
  import { access as access4, readdir as readdir13 } from "node:fs/promises";
77345
- import { join as join71 } from "node:path";
77427
+ import { join as join72 } from "node:path";
77346
77428
  async function validateExtraction(extractDir) {
77347
77429
  try {
77348
77430
  const entries = await readdir13(extractDir, { encoding: "utf8" });
@@ -77354,7 +77436,7 @@ async function validateExtraction(extractDir) {
77354
77436
  const missingPaths = [];
77355
77437
  for (const path5 of criticalPaths) {
77356
77438
  try {
77357
- await access4(join71(extractDir, path5), constants4.F_OK);
77439
+ await access4(join72(extractDir, path5), constants4.F_OK);
77358
77440
  logger.debug(`Found: ${path5}`);
77359
77441
  } catch {
77360
77442
  logger.warning(`Expected path not found: ${path5}`);
@@ -77376,7 +77458,7 @@ async function validateExtraction(extractDir) {
77376
77458
  // src/domains/installation/extraction/tar-extractor.ts
77377
77459
  init_logger();
77378
77460
  import { copyFile as copyFile4, mkdir as mkdir23, readdir as readdir15, rm as rm8, stat as stat10 } from "node:fs/promises";
77379
- import { join as join74 } from "node:path";
77461
+ import { join as join75 } from "node:path";
77380
77462
 
77381
77463
  // node_modules/@isaacs/fs-minipass/dist/esm/index.js
77382
77464
  import EE from "events";
@@ -83138,7 +83220,7 @@ var mkdirSync3 = (dir, opt) => {
83138
83220
  };
83139
83221
 
83140
83222
  // node_modules/tar/dist/esm/path-reservations.js
83141
- import { join as join72 } from "node:path";
83223
+ import { join as join73 } from "node:path";
83142
83224
 
83143
83225
  // node_modules/tar/dist/esm/normalize-unicode.js
83144
83226
  var normalizeCache = Object.create(null);
@@ -83171,7 +83253,7 @@ var getDirs = (path10) => {
83171
83253
  const dirs = path10.split("/").slice(0, -1).reduce((set, path11) => {
83172
83254
  const s = set[set.length - 1];
83173
83255
  if (s !== undefined) {
83174
- path11 = join72(s, path11);
83256
+ path11 = join73(s, path11);
83175
83257
  }
83176
83258
  set.push(path11 || "/");
83177
83259
  return set;
@@ -83185,7 +83267,7 @@ class PathReservations {
83185
83267
  #running = new Set;
83186
83268
  reserve(paths, fn) {
83187
83269
  paths = isWindows4 ? ["win32 parallelization disabled"] : paths.map((p) => {
83188
- return stripTrailingSlashes(join72(normalizeUnicode(p))).toLowerCase();
83270
+ return stripTrailingSlashes(join73(normalizeUnicode(p))).toLowerCase();
83189
83271
  });
83190
83272
  const dirs = new Set(paths.map((path10) => getDirs(path10)).reduce((a3, b3) => a3.concat(b3)));
83191
83273
  this.#reservations.set(fn, { dirs, paths });
@@ -84245,7 +84327,7 @@ function decodeFilePath(path12) {
84245
84327
  init_logger();
84246
84328
  init_types3();
84247
84329
  import { copyFile as copyFile3, lstat as lstat4, mkdir as mkdir22, readdir as readdir14 } from "node:fs/promises";
84248
- import { join as join73, relative as relative10 } from "node:path";
84330
+ import { join as join74, relative as relative10 } from "node:path";
84249
84331
  async function withRetry(fn, retries = 3) {
84250
84332
  for (let i = 0;i < retries; i++) {
84251
84333
  try {
@@ -84267,8 +84349,8 @@ async function moveDirectoryContents(sourceDir, destDir, shouldExclude, sizeTrac
84267
84349
  await mkdir22(destDir, { recursive: true });
84268
84350
  const entries = await readdir14(sourceDir, { encoding: "utf8" });
84269
84351
  for (const entry of entries) {
84270
- const sourcePath = join73(sourceDir, entry);
84271
- const destPath = join73(destDir, entry);
84352
+ const sourcePath = join74(sourceDir, entry);
84353
+ const destPath = join74(destDir, entry);
84272
84354
  const relativePath = relative10(sourceDir, sourcePath);
84273
84355
  if (!isPathSafe(destDir, destPath)) {
84274
84356
  logger.warning(`Skipping unsafe path: ${relativePath}`);
@@ -84295,8 +84377,8 @@ async function copyDirectory(sourceDir, destDir, shouldExclude, sizeTracker) {
84295
84377
  await mkdir22(destDir, { recursive: true });
84296
84378
  const entries = await readdir14(sourceDir, { encoding: "utf8" });
84297
84379
  for (const entry of entries) {
84298
- const sourcePath = join73(sourceDir, entry);
84299
- const destPath = join73(destDir, entry);
84380
+ const sourcePath = join74(sourceDir, entry);
84381
+ const destPath = join74(destDir, entry);
84300
84382
  const relativePath = relative10(sourceDir, sourcePath);
84301
84383
  if (!isPathSafe(destDir, destPath)) {
84302
84384
  logger.warning(`Skipping unsafe path: ${relativePath}`);
@@ -84344,7 +84426,7 @@ class TarExtractor {
84344
84426
  logger.debug(`Root entries: ${entries.join(", ")}`);
84345
84427
  if (entries.length === 1) {
84346
84428
  const rootEntry = entries[0];
84347
- const rootPath = join74(tempExtractDir, rootEntry);
84429
+ const rootPath = join75(tempExtractDir, rootEntry);
84348
84430
  const rootStat = await stat10(rootPath);
84349
84431
  if (rootStat.isDirectory()) {
84350
84432
  const rootContents = await readdir15(rootPath, { encoding: "utf8" });
@@ -84360,7 +84442,7 @@ class TarExtractor {
84360
84442
  }
84361
84443
  } else {
84362
84444
  await mkdir23(destDir, { recursive: true });
84363
- await copyFile4(rootPath, join74(destDir, rootEntry));
84445
+ await copyFile4(rootPath, join75(destDir, rootEntry));
84364
84446
  }
84365
84447
  } else {
84366
84448
  logger.debug("Multiple root entries - moving all");
@@ -84383,7 +84465,7 @@ init_logger();
84383
84465
  var import_extract_zip = __toESM(require_extract_zip(), 1);
84384
84466
  import { execFile as execFile8 } from "node:child_process";
84385
84467
  import { copyFile as copyFile5, mkdir as mkdir24, readdir as readdir16, rm as rm9, stat as stat11 } from "node:fs/promises";
84386
- import { join as join75 } from "node:path";
84468
+ import { join as join76 } from "node:path";
84387
84469
  class ZipExtractor {
84388
84470
  async tryNativeUnzip(archivePath, destDir) {
84389
84471
  if (!isMacOS()) {
@@ -84431,7 +84513,7 @@ class ZipExtractor {
84431
84513
  logger.debug(`Root entries: ${entries.join(", ")}`);
84432
84514
  if (entries.length === 1) {
84433
84515
  const rootEntry = entries[0];
84434
- const rootPath = join75(tempExtractDir, rootEntry);
84516
+ const rootPath = join76(tempExtractDir, rootEntry);
84435
84517
  const rootStat = await stat11(rootPath);
84436
84518
  if (rootStat.isDirectory()) {
84437
84519
  const rootContents = await readdir16(rootPath, { encoding: "utf8" });
@@ -84447,7 +84529,7 @@ class ZipExtractor {
84447
84529
  }
84448
84530
  } else {
84449
84531
  await mkdir24(destDir, { recursive: true });
84450
- await copyFile5(rootPath, join75(destDir, rootEntry));
84532
+ await copyFile5(rootPath, join76(destDir, rootEntry));
84451
84533
  }
84452
84534
  } else {
84453
84535
  logger.debug("Multiple root entries - moving all");
@@ -84546,7 +84628,7 @@ class DownloadManager {
84546
84628
  async createTempDir() {
84547
84629
  const timestamp = Date.now();
84548
84630
  const counter = DownloadManager.tempDirCounter++;
84549
- const primaryTempDir = join76(tmpdir4(), `claudekit-${timestamp}-${counter}`);
84631
+ const primaryTempDir = join77(tmpdir4(), `claudekit-${timestamp}-${counter}`);
84550
84632
  try {
84551
84633
  await mkdir25(primaryTempDir, { recursive: true });
84552
84634
  logger.debug(`Created temp directory: ${primaryTempDir}`);
@@ -84563,7 +84645,7 @@ Solutions:
84563
84645
  2. Set HOME environment variable
84564
84646
  3. Try running from a different directory`);
84565
84647
  }
84566
- const fallbackTempDir = join76(homeDir, ".claudekit", "tmp", `claudekit-${timestamp}-${counter}`);
84648
+ const fallbackTempDir = join77(homeDir, ".claudekit", "tmp", `claudekit-${timestamp}-${counter}`);
84567
84649
  try {
84568
84650
  await mkdir25(fallbackTempDir, { recursive: true });
84569
84651
  logger.debug(`Created temp directory (fallback): ${fallbackTempDir}`);
@@ -84912,20 +84994,20 @@ async function handleDownload(ctx) {
84912
84994
  };
84913
84995
  }
84914
84996
  // src/commands/init/phases/merge-handler.ts
84915
- import { join as join92 } from "node:path";
84997
+ import { join as join93 } from "node:path";
84916
84998
 
84917
84999
  // src/domains/installation/deletion-handler.ts
84918
85000
  import { existsSync as existsSync53, lstatSync as lstatSync3, readdirSync as readdirSync4, rmSync as rmSync3, rmdirSync, unlinkSync as unlinkSync3 } from "node:fs";
84919
- import { dirname as dirname24, join as join79, relative as relative11, resolve as resolve19, sep as sep4 } from "node:path";
85001
+ import { dirname as dirname24, join as join80, relative as relative11, resolve as resolve19, sep as sep5 } from "node:path";
84920
85002
 
84921
85003
  // src/services/file-operations/manifest/manifest-reader.ts
84922
85004
  init_metadata_migration();
84923
85005
  init_logger();
84924
85006
  init_types3();
84925
85007
  var import_fs_extra8 = __toESM(require_lib3(), 1);
84926
- import { join as join78 } from "node:path";
85008
+ import { join as join79 } from "node:path";
84927
85009
  async function readManifest(claudeDir2) {
84928
- const metadataPath = join78(claudeDir2, "metadata.json");
85010
+ const metadataPath = join79(claudeDir2, "metadata.json");
84929
85011
  if (!await import_fs_extra8.pathExists(metadataPath)) {
84930
85012
  return null;
84931
85013
  }
@@ -85103,7 +85185,7 @@ function collectFilesRecursively(dir, baseDir) {
85103
85185
  try {
85104
85186
  const entries = readdirSync4(dir, { withFileTypes: true });
85105
85187
  for (const entry of entries) {
85106
- const fullPath = join79(dir, entry.name);
85188
+ const fullPath = join80(dir, entry.name);
85107
85189
  const relativePath = relative11(baseDir, fullPath);
85108
85190
  if (entry.isDirectory()) {
85109
85191
  results.push(...collectFilesRecursively(fullPath, baseDir));
@@ -85155,7 +85237,7 @@ function cleanupEmptyDirectories(filePath, claudeDir2) {
85155
85237
  function deletePath(fullPath, claudeDir2) {
85156
85238
  const normalizedPath = resolve19(fullPath);
85157
85239
  const normalizedClaudeDir = resolve19(claudeDir2);
85158
- if (!normalizedPath.startsWith(`${normalizedClaudeDir}${sep4}`) && normalizedPath !== normalizedClaudeDir) {
85240
+ if (!normalizedPath.startsWith(`${normalizedClaudeDir}${sep5}`) && normalizedPath !== normalizedClaudeDir) {
85159
85241
  throw new Error(`Path traversal detected: ${fullPath}`);
85160
85242
  }
85161
85243
  try {
@@ -85171,7 +85253,7 @@ function deletePath(fullPath, claudeDir2) {
85171
85253
  }
85172
85254
  }
85173
85255
  async function updateMetadataAfterDeletion(claudeDir2, deletedPaths) {
85174
- const metadataPath = join79(claudeDir2, "metadata.json");
85256
+ const metadataPath = join80(claudeDir2, "metadata.json");
85175
85257
  if (!await import_fs_extra9.pathExists(metadataPath)) {
85176
85258
  return;
85177
85259
  }
@@ -85226,10 +85308,10 @@ async function handleDeletions(sourceMetadata, claudeDir2) {
85226
85308
  const userMetadata = await readManifest(claudeDir2);
85227
85309
  const result = { deletedPaths: [], preservedPaths: [], errors: [] };
85228
85310
  for (const path13 of deletions) {
85229
- const fullPath = join79(claudeDir2, path13);
85311
+ const fullPath = join80(claudeDir2, path13);
85230
85312
  const normalizedPath = resolve19(fullPath);
85231
85313
  const normalizedClaudeDir = resolve19(claudeDir2);
85232
- if (!normalizedPath.startsWith(`${normalizedClaudeDir}${sep4}`)) {
85314
+ if (!normalizedPath.startsWith(`${normalizedClaudeDir}${sep5}`)) {
85233
85315
  logger.warning(`Skipping invalid path: ${path13}`);
85234
85316
  result.errors.push(path13);
85235
85317
  continue;
@@ -85266,7 +85348,7 @@ init_logger();
85266
85348
  init_types3();
85267
85349
  var import_fs_extra12 = __toESM(require_lib3(), 1);
85268
85350
  var import_ignore3 = __toESM(require_ignore(), 1);
85269
- import { dirname as dirname26, join as join82, relative as relative13 } from "node:path";
85351
+ import { dirname as dirname26, join as join83, relative as relative13 } from "node:path";
85270
85352
 
85271
85353
  // src/domains/installation/selective-merger.ts
85272
85354
  import { stat as stat13 } from "node:fs/promises";
@@ -85445,7 +85527,7 @@ init_logger();
85445
85527
  var import_fs_extra10 = __toESM(require_lib3(), 1);
85446
85528
  var import_ignore2 = __toESM(require_ignore(), 1);
85447
85529
  import { relative as relative12 } from "node:path";
85448
- import { join as join80 } from "node:path";
85530
+ import { join as join81 } from "node:path";
85449
85531
 
85450
85532
  // node_modules/@isaacs/balanced-match/dist/esm/index.js
85451
85533
  var balanced = (a3, b3, str2) => {
@@ -86252,8 +86334,8 @@ var path13 = {
86252
86334
  win32: { sep: "\\" },
86253
86335
  posix: { sep: "/" }
86254
86336
  };
86255
- var sep5 = defaultPlatform === "win32" ? path13.win32.sep : path13.posix.sep;
86256
- minimatch.sep = sep5;
86337
+ var sep6 = defaultPlatform === "win32" ? path13.win32.sep : path13.posix.sep;
86338
+ minimatch.sep = sep6;
86257
86339
  var GLOBSTAR = Symbol("globstar **");
86258
86340
  minimatch.GLOBSTAR = GLOBSTAR;
86259
86341
  var qmark2 = "[^/]";
@@ -86901,7 +86983,7 @@ class FileScanner {
86901
86983
  const files = [];
86902
86984
  const entries = await import_fs_extra10.readdir(dir, { encoding: "utf8" });
86903
86985
  for (const entry of entries) {
86904
- const fullPath = join80(dir, entry);
86986
+ const fullPath = join81(dir, entry);
86905
86987
  const relativePath = relative12(baseDir, fullPath);
86906
86988
  const normalizedRelativePath = relativePath.replace(/\\/g, "/");
86907
86989
  const stats = await import_fs_extra10.lstat(fullPath);
@@ -86941,7 +87023,7 @@ import { execSync as execSync4 } from "node:child_process";
86941
87023
  init_shared();
86942
87024
  import { existsSync as existsSync54 } from "node:fs";
86943
87025
  import { mkdir as mkdir26, readFile as readFile38, writeFile as writeFile22 } from "node:fs/promises";
86944
- import { dirname as dirname25, join as join81 } from "node:path";
87026
+ import { dirname as dirname25, join as join82 } from "node:path";
86945
87027
  var CK_JSON_FILE = ".ck.json";
86946
87028
 
86947
87029
  class InstalledSettingsTracker {
@@ -86955,9 +87037,9 @@ class InstalledSettingsTracker {
86955
87037
  }
86956
87038
  getCkJsonPath() {
86957
87039
  if (this.isGlobal) {
86958
- return join81(this.projectDir, CK_JSON_FILE);
87040
+ return join82(this.projectDir, CK_JSON_FILE);
86959
87041
  }
86960
- return join81(this.projectDir, ".claude", CK_JSON_FILE);
87042
+ return join82(this.projectDir, ".claude", CK_JSON_FILE);
86961
87043
  }
86962
87044
  async loadInstalledSettings() {
86963
87045
  const ckJsonPath = this.getCkJsonPath();
@@ -87045,6 +87127,7 @@ class SettingsProcessor {
87045
87127
  tracker = null;
87046
87128
  installingKit;
87047
87129
  cachedVersion = undefined;
87130
+ deletionPatterns = [];
87048
87131
  setGlobalFlag(isGlobal) {
87049
87132
  this.isGlobal = isGlobal;
87050
87133
  }
@@ -87062,6 +87145,9 @@ class SettingsProcessor {
87062
87145
  setInstallingKit(kit) {
87063
87146
  this.installingKit = kit;
87064
87147
  }
87148
+ setDeletions(deletions) {
87149
+ this.deletionPatterns = deletions;
87150
+ }
87065
87151
  initTracker() {
87066
87152
  if (this.projectDir) {
87067
87153
  this.tracker = new InstalledSettingsTracker(this.projectDir, this.isGlobal, this.kitName);
@@ -87171,6 +87257,10 @@ class SettingsProcessor {
87171
87257
  if (pathsFixed) {
87172
87258
  logger.info("Fixed hook command paths to canonical quoted format");
87173
87259
  }
87260
+ const hooksPruned = this.pruneDeletedHooks(mergeResult.merged);
87261
+ if (hooksPruned > 0) {
87262
+ logger.info(`Pruned ${hooksPruned} stale hook(s) referencing deleted files`);
87263
+ }
87174
87264
  await SettingsMerger.writeSettingsFile(destFile, mergeResult.merged);
87175
87265
  logger.success("Merged settings.json (user customizations preserved)");
87176
87266
  await this.injectTeamHooksIfSupported(destFile, mergeResult.merged);
@@ -87215,6 +87305,59 @@ class SettingsProcessor {
87215
87305
  }
87216
87306
  }
87217
87307
  }
87308
+ pruneDeletedHooks(settings) {
87309
+ if (this.deletionPatterns.length === 0 || !settings.hooks)
87310
+ return 0;
87311
+ const hookDeletions = new Set(this.deletionPatterns.filter((p) => p.startsWith("hooks/")));
87312
+ if (hookDeletions.size === 0)
87313
+ return 0;
87314
+ let pruned = 0;
87315
+ const eventKeysToDelete = [];
87316
+ for (const [eventName, entries] of Object.entries(settings.hooks)) {
87317
+ const filteredEntries = [];
87318
+ for (const entry of entries) {
87319
+ if ("hooks" in entry && entry.hooks) {
87320
+ const remainingHooks = entry.hooks.filter((h2) => {
87321
+ const relativePath = this.extractHookRelativePath(h2.command);
87322
+ if (relativePath && hookDeletions.has(relativePath)) {
87323
+ logger.info(`Pruned stale hook: ${h2.command.slice(0, 80)}`);
87324
+ pruned++;
87325
+ return false;
87326
+ }
87327
+ return true;
87328
+ });
87329
+ if (remainingHooks.length > 0) {
87330
+ filteredEntries.push({ ...entry, hooks: remainingHooks });
87331
+ }
87332
+ } else if ("command" in entry) {
87333
+ const relativePath = this.extractHookRelativePath(entry.command);
87334
+ if (relativePath && hookDeletions.has(relativePath)) {
87335
+ logger.info(`Pruned stale hook: ${entry.command.slice(0, 80)}`);
87336
+ pruned++;
87337
+ } else {
87338
+ filteredEntries.push(entry);
87339
+ }
87340
+ } else {
87341
+ filteredEntries.push(entry);
87342
+ }
87343
+ }
87344
+ if (filteredEntries.length > 0) {
87345
+ settings.hooks[eventName] = filteredEntries;
87346
+ } else {
87347
+ eventKeysToDelete.push(eventName);
87348
+ }
87349
+ }
87350
+ for (const key of eventKeysToDelete) {
87351
+ delete settings.hooks[key];
87352
+ }
87353
+ return pruned;
87354
+ }
87355
+ extractHookRelativePath(command) {
87356
+ if (!command)
87357
+ return null;
87358
+ const match2 = command.match(/\.claude[/\\]([\w.\-/\\]+)/);
87359
+ return match2 ? match2[1].replace(/\\/g, "/") : null;
87360
+ }
87218
87361
  async trackInstalledSettings(settings) {
87219
87362
  if (!this.tracker)
87220
87363
  return;
@@ -87483,6 +87626,9 @@ class CopyExecutor {
87483
87626
  setForceOverwriteSettings(force) {
87484
87627
  this.settingsProcessor.setForceOverwriteSettings(force);
87485
87628
  }
87629
+ setDeletions(deletions) {
87630
+ this.settingsProcessor.setDeletions(deletions);
87631
+ }
87486
87632
  setProjectDir(dir) {
87487
87633
  this.settingsProcessor.setProjectDir(dir);
87488
87634
  }
@@ -87510,7 +87656,7 @@ class CopyExecutor {
87510
87656
  for (const file of files) {
87511
87657
  const relativePath = relative13(sourceDir, file);
87512
87658
  const normalizedRelativePath = relativePath.replace(/\\/g, "/");
87513
- const destPath = join82(destDir, relativePath);
87659
+ const destPath = join83(destDir, relativePath);
87514
87660
  if (await import_fs_extra12.pathExists(destPath)) {
87515
87661
  if (this.fileScanner.shouldNeverCopy(normalizedRelativePath)) {
87516
87662
  logger.debug(`Security-sensitive file exists but won't be overwritten: ${normalizedRelativePath}`);
@@ -87532,7 +87678,7 @@ class CopyExecutor {
87532
87678
  for (const file of files) {
87533
87679
  const relativePath = relative13(sourceDir, file);
87534
87680
  const normalizedRelativePath = relativePath.replace(/\\/g, "/");
87535
- const destPath = join82(destDir, relativePath);
87681
+ const destPath = join83(destDir, relativePath);
87536
87682
  if (this.fileScanner.shouldNeverCopy(normalizedRelativePath)) {
87537
87683
  logger.debug(`Skipping security-sensitive file: ${normalizedRelativePath}`);
87538
87684
  skippedCount++;
@@ -87655,6 +87801,9 @@ class FileMerger {
87655
87801
  setKitName(kit) {
87656
87802
  this.copyExecutor.setKitName(kit);
87657
87803
  }
87804
+ setDeletions(deletions) {
87805
+ this.copyExecutor.setDeletions(deletions);
87806
+ }
87658
87807
  setManifest(manifest) {
87659
87808
  this.copyExecutor.setManifest(manifest);
87660
87809
  }
@@ -87702,15 +87851,15 @@ class FileMerger {
87702
87851
 
87703
87852
  // src/domains/migration/legacy-migration.ts
87704
87853
  import { readdir as readdir18, stat as stat14 } from "node:fs/promises";
87705
- import { join as join86, relative as relative14 } from "node:path";
87854
+ import { join as join87, relative as relative14 } from "node:path";
87706
87855
  // src/services/file-operations/manifest/manifest-tracker.ts
87707
- import { join as join85 } from "node:path";
87856
+ import { join as join86 } from "node:path";
87708
87857
 
87709
87858
  // src/domains/migration/release-manifest.ts
87710
87859
  init_logger();
87711
87860
  init_zod();
87712
87861
  var import_fs_extra13 = __toESM(require_lib3(), 1);
87713
- import { join as join83 } from "node:path";
87862
+ import { join as join84 } from "node:path";
87714
87863
  var ReleaseManifestFileSchema = exports_external.object({
87715
87864
  path: exports_external.string(),
87716
87865
  checksum: exports_external.string().regex(/^[a-f0-9]{64}$/),
@@ -87725,7 +87874,7 @@ var ReleaseManifestSchema = exports_external.object({
87725
87874
 
87726
87875
  class ReleaseManifestLoader {
87727
87876
  static async load(extractDir) {
87728
- const manifestPath = join83(extractDir, "release-manifest.json");
87877
+ const manifestPath = join84(extractDir, "release-manifest.json");
87729
87878
  try {
87730
87879
  const content = await import_fs_extra13.readFile(manifestPath, "utf-8");
87731
87880
  const parsed = JSON.parse(content);
@@ -87751,9 +87900,9 @@ init_logger();
87751
87900
  init_types3();
87752
87901
  var import_fs_extra14 = __toESM(require_lib3(), 1);
87753
87902
  var import_proper_lockfile5 = __toESM(require_proper_lockfile(), 1);
87754
- import { join as join84 } from "node:path";
87903
+ import { join as join85 } from "node:path";
87755
87904
  async function writeManifest(claudeDir2, kitName, version, scope, kitType, trackedFiles, userConfigFiles) {
87756
- const metadataPath = join84(claudeDir2, "metadata.json");
87905
+ const metadataPath = join85(claudeDir2, "metadata.json");
87757
87906
  const kit = kitType || (/\bmarketing\b/i.test(kitName) ? "marketing" : "engineer");
87758
87907
  await import_fs_extra14.ensureFile(metadataPath);
87759
87908
  let release = null;
@@ -87809,7 +87958,7 @@ async function writeManifest(claudeDir2, kitName, version, scope, kitType, track
87809
87958
  }
87810
87959
  }
87811
87960
  async function removeKitFromManifest(claudeDir2, kit) {
87812
- const metadataPath = join84(claudeDir2, "metadata.json");
87961
+ const metadataPath = join85(claudeDir2, "metadata.json");
87813
87962
  if (!await import_fs_extra14.pathExists(metadataPath))
87814
87963
  return false;
87815
87964
  let release = null;
@@ -87939,7 +88088,7 @@ function buildFileTrackingList(options2) {
87939
88088
  if (!isGlobal && !installedPath.startsWith(".claude/"))
87940
88089
  continue;
87941
88090
  const relativePath = isGlobal ? installedPath : installedPath.replace(/^\.claude\//, "");
87942
- const filePath = join85(claudeDir2, relativePath);
88091
+ const filePath = join86(claudeDir2, relativePath);
87943
88092
  const manifestEntry = releaseManifest ? ReleaseManifestLoader.findFile(releaseManifest, installedPath) : null;
87944
88093
  const ownership = manifestEntry ? "ck" : "user";
87945
88094
  filesToTrack.push({
@@ -88046,7 +88195,7 @@ class LegacyMigration {
88046
88195
  continue;
88047
88196
  if (SKIP_DIRS_ALL.includes(entry))
88048
88197
  continue;
88049
- const fullPath = join86(dir, entry);
88198
+ const fullPath = join87(dir, entry);
88050
88199
  let stats;
88051
88200
  try {
88052
88201
  stats = await stat14(fullPath);
@@ -88148,7 +88297,7 @@ User-created files (sample):`);
88148
88297
  ];
88149
88298
  if (filesToChecksum.length > 0) {
88150
88299
  const checksumResults = await mapWithLimit(filesToChecksum, async ({ relativePath, ownership }) => {
88151
- const fullPath = join86(claudeDir2, relativePath);
88300
+ const fullPath = join87(claudeDir2, relativePath);
88152
88301
  const checksum = await OwnershipChecker.calculateChecksum(fullPath);
88153
88302
  return { relativePath, checksum, ownership };
88154
88303
  });
@@ -88169,7 +88318,7 @@ User-created files (sample):`);
88169
88318
  installedAt: new Date().toISOString(),
88170
88319
  files: trackedFiles
88171
88320
  };
88172
- const metadataPath = join86(claudeDir2, "metadata.json");
88321
+ const metadataPath = join87(claudeDir2, "metadata.json");
88173
88322
  await import_fs_extra15.writeFile(metadataPath, JSON.stringify(updatedMetadata, null, 2));
88174
88323
  logger.success(`Migration complete: tracked ${trackedFiles.length} files`);
88175
88324
  return true;
@@ -88275,7 +88424,7 @@ function buildConflictSummary(fileConflicts, hookConflicts, mcpConflicts) {
88275
88424
  init_logger();
88276
88425
  init_skip_directories();
88277
88426
  var import_fs_extra16 = __toESM(require_lib3(), 1);
88278
- import { join as join87, relative as relative15, resolve as resolve20 } from "node:path";
88427
+ import { join as join88, relative as relative15, resolve as resolve20 } from "node:path";
88279
88428
 
88280
88429
  class FileScanner2 {
88281
88430
  static async getFiles(dirPath, relativeTo) {
@@ -88291,7 +88440,7 @@ class FileScanner2 {
88291
88440
  logger.debug(`Skipping directory: ${entry}`);
88292
88441
  continue;
88293
88442
  }
88294
- const fullPath = join87(dirPath, entry);
88443
+ const fullPath = join88(dirPath, entry);
88295
88444
  if (!FileScanner2.isSafePath(basePath, fullPath)) {
88296
88445
  logger.warning(`Skipping potentially unsafe path: ${entry}`);
88297
88446
  continue;
@@ -88326,8 +88475,8 @@ class FileScanner2 {
88326
88475
  return files;
88327
88476
  }
88328
88477
  static async findCustomFiles(destDir, sourceDir, subPath) {
88329
- const destSubDir = join87(destDir, subPath);
88330
- const sourceSubDir = join87(sourceDir, subPath);
88478
+ const destSubDir = join88(destDir, subPath);
88479
+ const sourceSubDir = join88(sourceDir, subPath);
88331
88480
  logger.debug(`findCustomFiles - destDir: ${destDir}`);
88332
88481
  logger.debug(`findCustomFiles - sourceDir: ${sourceDir}`);
88333
88482
  logger.debug(`findCustomFiles - subPath: "${subPath}"`);
@@ -88368,12 +88517,12 @@ class FileScanner2 {
88368
88517
  init_logger();
88369
88518
  var import_fs_extra17 = __toESM(require_lib3(), 1);
88370
88519
  import { lstat as lstat7, mkdir as mkdir27, readdir as readdir21, stat as stat15 } from "node:fs/promises";
88371
- import { join as join89 } from "node:path";
88520
+ import { join as join90 } from "node:path";
88372
88521
 
88373
88522
  // src/services/transformers/commands-prefix/content-transformer.ts
88374
88523
  init_logger();
88375
88524
  import { readFile as readFile42, readdir as readdir20, writeFile as writeFile26 } from "node:fs/promises";
88376
- import { join as join88 } from "node:path";
88525
+ import { join as join89 } from "node:path";
88377
88526
  var TRANSFORMABLE_EXTENSIONS = new Set([
88378
88527
  ".md",
88379
88528
  ".txt",
@@ -88434,7 +88583,7 @@ async function transformCommandReferences(directory, options2 = {}) {
88434
88583
  async function processDirectory(dir) {
88435
88584
  const entries = await readdir20(dir, { withFileTypes: true });
88436
88585
  for (const entry of entries) {
88437
- const fullPath = join88(dir, entry.name);
88586
+ const fullPath = join89(dir, entry.name);
88438
88587
  if (entry.isDirectory()) {
88439
88588
  if (entry.name === "node_modules" || entry.name.startsWith(".") && entry.name !== ".claude") {
88440
88589
  continue;
@@ -88509,14 +88658,14 @@ function shouldApplyPrefix(options2) {
88509
88658
  // src/services/transformers/commands-prefix/prefix-applier.ts
88510
88659
  async function applyPrefix(extractDir) {
88511
88660
  validatePath(extractDir, "extractDir");
88512
- const commandsDir = join89(extractDir, ".claude", "commands");
88661
+ const commandsDir = join90(extractDir, ".claude", "commands");
88513
88662
  if (!await import_fs_extra17.pathExists(commandsDir)) {
88514
88663
  logger.verbose("No commands directory found, skipping prefix application");
88515
88664
  return;
88516
88665
  }
88517
88666
  logger.info("Applying /ck: prefix to slash commands...");
88518
- const backupDir = join89(extractDir, ".commands-backup");
88519
- const tempDir = join89(extractDir, ".commands-prefix-temp");
88667
+ const backupDir = join90(extractDir, ".commands-backup");
88668
+ const tempDir = join90(extractDir, ".commands-prefix-temp");
88520
88669
  try {
88521
88670
  const entries = await readdir21(commandsDir);
88522
88671
  if (entries.length === 0) {
@@ -88524,7 +88673,7 @@ async function applyPrefix(extractDir) {
88524
88673
  return;
88525
88674
  }
88526
88675
  if (entries.length === 1 && entries[0] === "ck") {
88527
- const ckDir2 = join89(commandsDir, "ck");
88676
+ const ckDir2 = join90(commandsDir, "ck");
88528
88677
  const ckStat = await stat15(ckDir2);
88529
88678
  if (ckStat.isDirectory()) {
88530
88679
  logger.verbose("Commands already have /ck: prefix, skipping");
@@ -88534,17 +88683,17 @@ async function applyPrefix(extractDir) {
88534
88683
  await import_fs_extra17.copy(commandsDir, backupDir);
88535
88684
  logger.verbose("Created backup of commands directory");
88536
88685
  await mkdir27(tempDir, { recursive: true });
88537
- const ckDir = join89(tempDir, "ck");
88686
+ const ckDir = join90(tempDir, "ck");
88538
88687
  await mkdir27(ckDir, { recursive: true });
88539
88688
  let processedCount = 0;
88540
88689
  for (const entry of entries) {
88541
- const sourcePath = join89(commandsDir, entry);
88690
+ const sourcePath = join90(commandsDir, entry);
88542
88691
  const stats = await lstat7(sourcePath);
88543
88692
  if (stats.isSymbolicLink()) {
88544
88693
  logger.warning(`Skipping symlink for security: ${entry}`);
88545
88694
  continue;
88546
88695
  }
88547
- const destPath = join89(ckDir, entry);
88696
+ const destPath = join90(ckDir, entry);
88548
88697
  await import_fs_extra17.copy(sourcePath, destPath, {
88549
88698
  overwrite: false,
88550
88699
  errorOnExist: true
@@ -88562,7 +88711,7 @@ async function applyPrefix(extractDir) {
88562
88711
  await import_fs_extra17.move(tempDir, commandsDir);
88563
88712
  await import_fs_extra17.remove(backupDir);
88564
88713
  logger.success("Successfully reorganized commands to /ck: prefix");
88565
- const claudeDir2 = join89(extractDir, ".claude");
88714
+ const claudeDir2 = join90(extractDir, ".claude");
88566
88715
  logger.info("Transforming command references in file contents...");
88567
88716
  const transformResult = await transformCommandReferences(claudeDir2, {
88568
88717
  verbose: logger.isVerbose()
@@ -88600,20 +88749,20 @@ async function applyPrefix(extractDir) {
88600
88749
  // src/services/transformers/commands-prefix/prefix-cleaner.ts
88601
88750
  init_metadata_migration();
88602
88751
  import { lstat as lstat9, readdir as readdir23 } from "node:fs/promises";
88603
- import { join as join91 } from "node:path";
88752
+ import { join as join92 } from "node:path";
88604
88753
  init_logger();
88605
88754
  var import_fs_extra19 = __toESM(require_lib3(), 1);
88606
88755
 
88607
88756
  // src/services/transformers/commands-prefix/file-processor.ts
88608
88757
  import { lstat as lstat8, readdir as readdir22 } from "node:fs/promises";
88609
- import { join as join90 } from "node:path";
88758
+ import { join as join91 } from "node:path";
88610
88759
  init_logger();
88611
88760
  var import_fs_extra18 = __toESM(require_lib3(), 1);
88612
88761
  async function scanDirectoryFiles(dir) {
88613
88762
  const files = [];
88614
88763
  const entries = await readdir22(dir);
88615
88764
  for (const entry of entries) {
88616
- const fullPath = join90(dir, entry);
88765
+ const fullPath = join91(dir, entry);
88617
88766
  const stats = await lstat8(fullPath);
88618
88767
  if (stats.isSymbolicLink()) {
88619
88768
  continue;
@@ -88741,8 +88890,8 @@ function isDifferentKitDirectory(dirName, currentKit) {
88741
88890
  async function cleanupCommandsDirectory(targetDir, isGlobal, options2 = {}) {
88742
88891
  const { dryRun = false } = options2;
88743
88892
  validatePath(targetDir, "targetDir");
88744
- const claudeDir2 = isGlobal ? targetDir : join91(targetDir, ".claude");
88745
- const commandsDir = join91(claudeDir2, "commands");
88893
+ const claudeDir2 = isGlobal ? targetDir : join92(targetDir, ".claude");
88894
+ const commandsDir = join92(claudeDir2, "commands");
88746
88895
  const accumulator = {
88747
88896
  results: [],
88748
88897
  deletedCount: 0,
@@ -88784,7 +88933,7 @@ async function cleanupCommandsDirectory(targetDir, isGlobal, options2 = {}) {
88784
88933
  }
88785
88934
  const metadataForChecks = options2.kitType ? createKitSpecificMetadata(metadata, options2.kitType) : metadata;
88786
88935
  for (const entry of entries) {
88787
- const entryPath = join91(commandsDir, entry);
88936
+ const entryPath = join92(commandsDir, entry);
88788
88937
  const stats = await lstat9(entryPath);
88789
88938
  if (stats.isSymbolicLink()) {
88790
88939
  addSymlinkSkip(entry, accumulator);
@@ -88841,7 +88990,7 @@ async function handleMerge(ctx) {
88841
88990
  let customClaudeFiles = [];
88842
88991
  if (!ctx.options.fresh) {
88843
88992
  logger.info("Scanning for custom .claude files...");
88844
- const scanSourceDir = ctx.options.global ? join92(ctx.extractDir, ".claude") : ctx.extractDir;
88993
+ const scanSourceDir = ctx.options.global ? join93(ctx.extractDir, ".claude") : ctx.extractDir;
88845
88994
  const scanTargetSubdir = ctx.options.global ? "" : ".claude";
88846
88995
  customClaudeFiles = await FileScanner2.findCustomFiles(ctx.resolvedDir, scanSourceDir, scanTargetSubdir);
88847
88996
  } else {
@@ -88906,7 +89055,20 @@ async function handleMerge(ctx) {
88906
89055
  return { ...ctx, cancelled: true };
88907
89056
  }
88908
89057
  }
88909
- const sourceDir = ctx.options.global ? join92(ctx.extractDir, ".claude") : ctx.extractDir;
89058
+ const sourceDir = ctx.options.global ? join93(ctx.extractDir, ".claude") : ctx.extractDir;
89059
+ const sourceMetadataPath = ctx.options.global ? join93(sourceDir, "metadata.json") : join93(sourceDir, ".claude", "metadata.json");
89060
+ let sourceMetadata = null;
89061
+ try {
89062
+ if (await import_fs_extra20.pathExists(sourceMetadataPath)) {
89063
+ const metadataContent = await import_fs_extra20.readFile(sourceMetadataPath, "utf-8");
89064
+ sourceMetadata = JSON.parse(metadataContent);
89065
+ }
89066
+ } catch (error) {
89067
+ logger.debug(`Failed to load source metadata: ${error}`);
89068
+ }
89069
+ if (sourceMetadata?.deletions && sourceMetadata.deletions.length > 0) {
89070
+ merger.setDeletions(sourceMetadata.deletions);
89071
+ }
88910
89072
  await merger.merge(sourceDir, ctx.resolvedDir, ctx.isNonInteractive);
88911
89073
  const fileConflicts = merger.getFileConflicts();
88912
89074
  if (fileConflicts.length > 0 && !ctx.isNonInteractive) {
@@ -88914,24 +89076,17 @@ async function handleMerge(ctx) {
88914
89076
  displayConflictSummary(summary);
88915
89077
  }
88916
89078
  try {
88917
- const sourceMetadataPath = ctx.options.global ? join92(sourceDir, "metadata.json") : join92(sourceDir, ".claude", "metadata.json");
88918
- if (await import_fs_extra20.pathExists(sourceMetadataPath)) {
88919
- const metadataContent = await import_fs_extra20.readFile(sourceMetadataPath, "utf-8");
88920
- const sourceMetadata = JSON.parse(metadataContent);
88921
- if (sourceMetadata.deletions && sourceMetadata.deletions.length > 0) {
88922
- const deletionResult = await handleDeletions(sourceMetadata, ctx.claudeDir);
88923
- if (deletionResult.deletedPaths.length > 0) {
88924
- logger.info(`Removed ${deletionResult.deletedPaths.length} deprecated file(s)`);
88925
- for (const path14 of deletionResult.deletedPaths) {
88926
- logger.verbose(` - ${path14}`);
88927
- }
88928
- }
88929
- if (deletionResult.preservedPaths.length > 0) {
88930
- logger.verbose(`Preserved ${deletionResult.preservedPaths.length} user-owned file(s)`);
89079
+ if (sourceMetadata?.deletions && sourceMetadata.deletions.length > 0) {
89080
+ const deletionResult = await handleDeletions(sourceMetadata, ctx.claudeDir);
89081
+ if (deletionResult.deletedPaths.length > 0) {
89082
+ logger.info(`Removed ${deletionResult.deletedPaths.length} deprecated file(s)`);
89083
+ for (const path14 of deletionResult.deletedPaths) {
89084
+ logger.verbose(` - ${path14}`);
88931
89085
  }
88932
89086
  }
88933
- } else {
88934
- logger.debug(`No source metadata found at ${sourceMetadataPath}, skipping deletions`);
89087
+ if (deletionResult.preservedPaths.length > 0) {
89088
+ logger.verbose(`Preserved ${deletionResult.preservedPaths.length} user-owned file(s)`);
89089
+ }
88935
89090
  }
88936
89091
  } catch (error) {
88937
89092
  logger.debug(`Cleanup of deprecated files failed: ${error}`);
@@ -88958,7 +89113,7 @@ async function handleMerge(ctx) {
88958
89113
  };
88959
89114
  }
88960
89115
  // src/commands/init/phases/migration-handler.ts
88961
- import { join as join100 } from "node:path";
89116
+ import { join as join101 } from "node:path";
88962
89117
 
88963
89118
  // src/domains/skills/skills-detector.ts
88964
89119
  init_logger();
@@ -88974,7 +89129,7 @@ init_types3();
88974
89129
  var import_fs_extra21 = __toESM(require_lib3(), 1);
88975
89130
  import { createHash as createHash4 } from "node:crypto";
88976
89131
  import { readFile as readFile44, readdir as readdir24, writeFile as writeFile27 } from "node:fs/promises";
88977
- import { join as join93, relative as relative16 } from "node:path";
89132
+ import { join as join94, relative as relative16 } from "node:path";
88978
89133
 
88979
89134
  class SkillsManifestManager {
88980
89135
  static MANIFEST_FILENAME = ".skills-manifest.json";
@@ -88996,12 +89151,12 @@ class SkillsManifestManager {
88996
89151
  return manifest;
88997
89152
  }
88998
89153
  static async writeManifest(skillsDir2, manifest) {
88999
- const manifestPath = join93(skillsDir2, SkillsManifestManager.MANIFEST_FILENAME);
89154
+ const manifestPath = join94(skillsDir2, SkillsManifestManager.MANIFEST_FILENAME);
89000
89155
  await writeFile27(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
89001
89156
  logger.debug(`Wrote manifest to: ${manifestPath}`);
89002
89157
  }
89003
89158
  static async readManifest(skillsDir2) {
89004
- const manifestPath = join93(skillsDir2, SkillsManifestManager.MANIFEST_FILENAME);
89159
+ const manifestPath = join94(skillsDir2, SkillsManifestManager.MANIFEST_FILENAME);
89005
89160
  if (!await import_fs_extra21.pathExists(manifestPath)) {
89006
89161
  logger.debug(`No manifest found at: ${manifestPath}`);
89007
89162
  return null;
@@ -89024,7 +89179,7 @@ class SkillsManifestManager {
89024
89179
  return "flat";
89025
89180
  }
89026
89181
  for (const dir of dirs.slice(0, 3)) {
89027
- const dirPath = join93(skillsDir2, dir.name);
89182
+ const dirPath = join94(skillsDir2, dir.name);
89028
89183
  const subEntries = await readdir24(dirPath, { withFileTypes: true });
89029
89184
  const hasSubdirs = subEntries.some((entry) => entry.isDirectory());
89030
89185
  if (hasSubdirs) {
@@ -89043,7 +89198,7 @@ class SkillsManifestManager {
89043
89198
  const entries = await readdir24(skillsDir2, { withFileTypes: true });
89044
89199
  for (const entry of entries) {
89045
89200
  if (entry.isDirectory() && !BUILD_ARTIFACT_DIRS.includes(entry.name) && !entry.name.startsWith(".")) {
89046
- const skillPath = join93(skillsDir2, entry.name);
89201
+ const skillPath = join94(skillsDir2, entry.name);
89047
89202
  const hash = await SkillsManifestManager.hashDirectory(skillPath);
89048
89203
  skills.push({
89049
89204
  name: entry.name,
@@ -89055,11 +89210,11 @@ class SkillsManifestManager {
89055
89210
  const categories = await readdir24(skillsDir2, { withFileTypes: true });
89056
89211
  for (const category of categories) {
89057
89212
  if (category.isDirectory() && !BUILD_ARTIFACT_DIRS.includes(category.name) && !category.name.startsWith(".")) {
89058
- const categoryPath = join93(skillsDir2, category.name);
89213
+ const categoryPath = join94(skillsDir2, category.name);
89059
89214
  const skillEntries = await readdir24(categoryPath, { withFileTypes: true });
89060
89215
  for (const skillEntry of skillEntries) {
89061
89216
  if (skillEntry.isDirectory() && !skillEntry.name.startsWith(".")) {
89062
- const skillPath = join93(categoryPath, skillEntry.name);
89217
+ const skillPath = join94(categoryPath, skillEntry.name);
89063
89218
  const hash = await SkillsManifestManager.hashDirectory(skillPath);
89064
89219
  skills.push({
89065
89220
  name: skillEntry.name,
@@ -89089,7 +89244,7 @@ class SkillsManifestManager {
89089
89244
  const files = [];
89090
89245
  const entries = await readdir24(dirPath, { withFileTypes: true });
89091
89246
  for (const entry of entries) {
89092
- const fullPath = join93(dirPath, entry.name);
89247
+ const fullPath = join94(dirPath, entry.name);
89093
89248
  if (entry.name.startsWith(".") || BUILD_ARTIFACT_DIRS.includes(entry.name)) {
89094
89249
  continue;
89095
89250
  }
@@ -89211,7 +89366,7 @@ function getPathMapping(skillName, oldBasePath, newBasePath) {
89211
89366
  // src/domains/skills/detection/script-detector.ts
89212
89367
  var import_fs_extra22 = __toESM(require_lib3(), 1);
89213
89368
  import { readdir as readdir25 } from "node:fs/promises";
89214
- import { join as join94 } from "node:path";
89369
+ import { join as join95 } from "node:path";
89215
89370
  async function scanDirectory(skillsDir2) {
89216
89371
  if (!await import_fs_extra22.pathExists(skillsDir2)) {
89217
89372
  return ["flat", []];
@@ -89224,12 +89379,12 @@ async function scanDirectory(skillsDir2) {
89224
89379
  let totalSkillLikeCount = 0;
89225
89380
  const allSkills = [];
89226
89381
  for (const dir of dirs) {
89227
- const dirPath = join94(skillsDir2, dir.name);
89382
+ const dirPath = join95(skillsDir2, dir.name);
89228
89383
  const subEntries = await readdir25(dirPath, { withFileTypes: true });
89229
89384
  const subdirs = subEntries.filter((entry) => entry.isDirectory() && !entry.name.startsWith("."));
89230
89385
  if (subdirs.length > 0) {
89231
89386
  for (const subdir of subdirs.slice(0, 3)) {
89232
- const subdirPath = join94(dirPath, subdir.name);
89387
+ const subdirPath = join95(dirPath, subdir.name);
89233
89388
  const subdirFiles = await readdir25(subdirPath, { withFileTypes: true });
89234
89389
  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"));
89235
89390
  if (hasSkillMarker) {
@@ -89386,12 +89541,12 @@ class SkillsMigrationDetector {
89386
89541
  // src/domains/skills/skills-migrator.ts
89387
89542
  init_logger();
89388
89543
  init_types3();
89389
- import { join as join99 } from "node:path";
89544
+ import { join as join100 } from "node:path";
89390
89545
 
89391
89546
  // src/domains/skills/migrator/migration-executor.ts
89392
89547
  init_logger();
89393
89548
  import { copyFile as copyFile6, mkdir as mkdir28, readdir as readdir26, rm as rm10 } from "node:fs/promises";
89394
- import { join as join95 } from "node:path";
89549
+ import { join as join96 } from "node:path";
89395
89550
  var import_fs_extra24 = __toESM(require_lib3(), 1);
89396
89551
 
89397
89552
  // src/domains/skills/skills-migration-prompts.ts
@@ -89556,8 +89711,8 @@ async function copySkillDirectory(sourceDir, destDir) {
89556
89711
  await mkdir28(destDir, { recursive: true });
89557
89712
  const entries = await readdir26(sourceDir, { withFileTypes: true });
89558
89713
  for (const entry of entries) {
89559
- const sourcePath = join95(sourceDir, entry.name);
89560
- const destPath = join95(destDir, entry.name);
89714
+ const sourcePath = join96(sourceDir, entry.name);
89715
+ const destPath = join96(destDir, entry.name);
89561
89716
  if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.isSymbolicLink()) {
89562
89717
  continue;
89563
89718
  }
@@ -89572,7 +89727,7 @@ async function executeInternal(mappings, customizations, currentSkillsDir, inter
89572
89727
  const migrated = [];
89573
89728
  const preserved = [];
89574
89729
  const errors2 = [];
89575
- const tempDir = join95(currentSkillsDir, "..", ".skills-migration-temp");
89730
+ const tempDir = join96(currentSkillsDir, "..", ".skills-migration-temp");
89576
89731
  await mkdir28(tempDir, { recursive: true });
89577
89732
  try {
89578
89733
  for (const mapping of mappings) {
@@ -89593,9 +89748,9 @@ async function executeInternal(mappings, customizations, currentSkillsDir, inter
89593
89748
  }
89594
89749
  }
89595
89750
  const category = mapping.category;
89596
- const targetPath = category ? join95(tempDir, category, skillName) : join95(tempDir, skillName);
89751
+ const targetPath = category ? join96(tempDir, category, skillName) : join96(tempDir, skillName);
89597
89752
  if (category) {
89598
- await mkdir28(join95(tempDir, category), { recursive: true });
89753
+ await mkdir28(join96(tempDir, category), { recursive: true });
89599
89754
  }
89600
89755
  await copySkillDirectory(currentSkillPath, targetPath);
89601
89756
  migrated.push(skillName);
@@ -89662,7 +89817,7 @@ init_logger();
89662
89817
  init_types3();
89663
89818
  var import_fs_extra25 = __toESM(require_lib3(), 1);
89664
89819
  import { copyFile as copyFile7, mkdir as mkdir29, readdir as readdir27, rm as rm11, stat as stat16 } from "node:fs/promises";
89665
- import { basename as basename15, join as join96, normalize as normalize8 } from "node:path";
89820
+ import { basename as basename15, join as join97, normalize as normalize8 } from "node:path";
89666
89821
  function validatePath2(path14, paramName) {
89667
89822
  if (!path14 || typeof path14 !== "string") {
89668
89823
  throw new SkillsMigrationError(`${paramName} must be a non-empty string`);
@@ -89688,7 +89843,7 @@ class SkillsBackupManager {
89688
89843
  const timestamp = Date.now();
89689
89844
  const randomSuffix = Math.random().toString(36).substring(2, 8);
89690
89845
  const backupDirName = `${SkillsBackupManager.BACKUP_PREFIX}${timestamp}-${randomSuffix}`;
89691
- const backupDir = parentDir ? join96(parentDir, backupDirName) : join96(skillsDir2, "..", backupDirName);
89846
+ const backupDir = parentDir ? join97(parentDir, backupDirName) : join97(skillsDir2, "..", backupDirName);
89692
89847
  logger.info(`Creating backup at: ${backupDir}`);
89693
89848
  try {
89694
89849
  await mkdir29(backupDir, { recursive: true });
@@ -89739,7 +89894,7 @@ class SkillsBackupManager {
89739
89894
  }
89740
89895
  try {
89741
89896
  const entries = await readdir27(parentDir, { withFileTypes: true });
89742
- const backups = entries.filter((entry) => entry.isDirectory() && entry.name.startsWith(SkillsBackupManager.BACKUP_PREFIX)).map((entry) => join96(parentDir, entry.name));
89897
+ const backups = entries.filter((entry) => entry.isDirectory() && entry.name.startsWith(SkillsBackupManager.BACKUP_PREFIX)).map((entry) => join97(parentDir, entry.name));
89743
89898
  backups.sort().reverse();
89744
89899
  return backups;
89745
89900
  } catch (error) {
@@ -89767,8 +89922,8 @@ class SkillsBackupManager {
89767
89922
  static async copyDirectory(sourceDir, destDir) {
89768
89923
  const entries = await readdir27(sourceDir, { withFileTypes: true });
89769
89924
  for (const entry of entries) {
89770
- const sourcePath = join96(sourceDir, entry.name);
89771
- const destPath = join96(destDir, entry.name);
89925
+ const sourcePath = join97(sourceDir, entry.name);
89926
+ const destPath = join97(destDir, entry.name);
89772
89927
  if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.isSymbolicLink()) {
89773
89928
  continue;
89774
89929
  }
@@ -89784,7 +89939,7 @@ class SkillsBackupManager {
89784
89939
  let size = 0;
89785
89940
  const entries = await readdir27(dirPath, { withFileTypes: true });
89786
89941
  for (const entry of entries) {
89787
- const fullPath = join96(dirPath, entry.name);
89942
+ const fullPath = join97(dirPath, entry.name);
89788
89943
  if (entry.isSymbolicLink()) {
89789
89944
  continue;
89790
89945
  }
@@ -89820,12 +89975,12 @@ init_skip_directories();
89820
89975
  import { createHash as createHash5 } from "node:crypto";
89821
89976
  import { createReadStream as createReadStream3 } from "node:fs";
89822
89977
  import { readFile as readFile45, readdir as readdir28 } from "node:fs/promises";
89823
- import { join as join97, relative as relative17 } from "node:path";
89978
+ import { join as join98, relative as relative17 } from "node:path";
89824
89979
  async function getAllFiles(dirPath) {
89825
89980
  const files = [];
89826
89981
  const entries = await readdir28(dirPath, { withFileTypes: true });
89827
89982
  for (const entry of entries) {
89828
- const fullPath = join97(dirPath, entry.name);
89983
+ const fullPath = join98(dirPath, entry.name);
89829
89984
  if (entry.name.startsWith(".") || BUILD_ARTIFACT_DIRS.includes(entry.name) || entry.isSymbolicLink()) {
89830
89985
  continue;
89831
89986
  }
@@ -89952,7 +90107,7 @@ async function detectFileChanges(currentSkillPath, baselineSkillPath) {
89952
90107
  init_types3();
89953
90108
  var import_fs_extra27 = __toESM(require_lib3(), 1);
89954
90109
  import { readdir as readdir29 } from "node:fs/promises";
89955
- import { join as join98, normalize as normalize9 } from "node:path";
90110
+ import { join as join99, normalize as normalize9 } from "node:path";
89956
90111
  function validatePath3(path14, paramName) {
89957
90112
  if (!path14 || typeof path14 !== "string") {
89958
90113
  throw new SkillsMigrationError(`${paramName} must be a non-empty string`);
@@ -89973,13 +90128,13 @@ async function scanSkillsDirectory(skillsDir2) {
89973
90128
  if (dirs.length === 0) {
89974
90129
  return ["flat", []];
89975
90130
  }
89976
- const firstDirPath = join98(skillsDir2, dirs[0].name);
90131
+ const firstDirPath = join99(skillsDir2, dirs[0].name);
89977
90132
  const subEntries = await readdir29(firstDirPath, { withFileTypes: true });
89978
90133
  const subdirs = subEntries.filter((entry) => entry.isDirectory() && !entry.name.startsWith("."));
89979
90134
  if (subdirs.length > 0) {
89980
90135
  let skillLikeCount = 0;
89981
90136
  for (const subdir of subdirs.slice(0, 3)) {
89982
- const subdirPath = join98(firstDirPath, subdir.name);
90137
+ const subdirPath = join99(firstDirPath, subdir.name);
89983
90138
  const subdirFiles = await readdir29(subdirPath, { withFileTypes: true });
89984
90139
  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"));
89985
90140
  if (hasSkillMarker) {
@@ -89989,7 +90144,7 @@ async function scanSkillsDirectory(skillsDir2) {
89989
90144
  if (skillLikeCount > 0) {
89990
90145
  const skills = [];
89991
90146
  for (const dir of dirs) {
89992
- const categoryPath = join98(skillsDir2, dir.name);
90147
+ const categoryPath = join99(skillsDir2, dir.name);
89993
90148
  const skillDirs = await readdir29(categoryPath, { withFileTypes: true });
89994
90149
  skills.push(...skillDirs.filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name));
89995
90150
  }
@@ -89999,7 +90154,7 @@ async function scanSkillsDirectory(skillsDir2) {
89999
90154
  return ["flat", dirs.map((dir) => dir.name)];
90000
90155
  }
90001
90156
  async function findSkillPath(skillsDir2, skillName) {
90002
- const flatPath = join98(skillsDir2, skillName);
90157
+ const flatPath = join99(skillsDir2, skillName);
90003
90158
  if (await import_fs_extra27.pathExists(flatPath)) {
90004
90159
  return { path: flatPath, category: undefined };
90005
90160
  }
@@ -90008,8 +90163,8 @@ async function findSkillPath(skillsDir2, skillName) {
90008
90163
  if (!entry.isDirectory() || entry.name.startsWith(".") || entry.name === "node_modules") {
90009
90164
  continue;
90010
90165
  }
90011
- const categoryPath = join98(skillsDir2, entry.name);
90012
- const skillPath = join98(categoryPath, skillName);
90166
+ const categoryPath = join99(skillsDir2, entry.name);
90167
+ const skillPath = join99(categoryPath, skillName);
90013
90168
  if (await import_fs_extra27.pathExists(skillPath)) {
90014
90169
  return { path: skillPath, category: entry.name };
90015
90170
  }
@@ -90103,7 +90258,7 @@ class SkillsMigrator {
90103
90258
  }
90104
90259
  }
90105
90260
  if (options2.backup && !options2.dryRun) {
90106
- const claudeDir2 = join99(currentSkillsDir, "..");
90261
+ const claudeDir2 = join100(currentSkillsDir, "..");
90107
90262
  result.backupPath = await SkillsBackupManager.createBackup(currentSkillsDir, claudeDir2);
90108
90263
  logger.success(`Backup created at: ${result.backupPath}`);
90109
90264
  }
@@ -90164,7 +90319,7 @@ async function handleMigration(ctx) {
90164
90319
  logger.debug("Skipping skills migration (fresh installation)");
90165
90320
  return ctx;
90166
90321
  }
90167
- const newSkillsDir = join100(ctx.extractDir, ".claude", "skills");
90322
+ const newSkillsDir = join101(ctx.extractDir, ".claude", "skills");
90168
90323
  const currentSkillsDir = PathResolver.buildSkillsPath(ctx.resolvedDir, ctx.options.global);
90169
90324
  if (!await import_fs_extra28.pathExists(newSkillsDir) || !await import_fs_extra28.pathExists(currentSkillsDir)) {
90170
90325
  return ctx;
@@ -90188,13 +90343,13 @@ async function handleMigration(ctx) {
90188
90343
  }
90189
90344
  // src/commands/init/phases/opencode-handler.ts
90190
90345
  import { cp as cp3, readdir as readdir31, rm as rm12 } from "node:fs/promises";
90191
- import { join as join102 } from "node:path";
90346
+ import { join as join103 } from "node:path";
90192
90347
 
90193
90348
  // src/services/transformers/opencode-path-transformer.ts
90194
90349
  init_logger();
90195
90350
  import { readFile as readFile46, readdir as readdir30, writeFile as writeFile28 } from "node:fs/promises";
90196
90351
  import { platform as platform12 } from "node:os";
90197
- import { extname as extname6, join as join101 } from "node:path";
90352
+ import { extname as extname6, join as join102 } from "node:path";
90198
90353
  var IS_WINDOWS2 = platform12() === "win32";
90199
90354
  function getOpenCodeGlobalPath() {
90200
90355
  return "$HOME/.config/opencode/";
@@ -90255,7 +90410,7 @@ async function transformPathsForGlobalOpenCode(directory, options2 = {}) {
90255
90410
  async function processDirectory2(dir) {
90256
90411
  const entries = await readdir30(dir, { withFileTypes: true });
90257
90412
  for (const entry of entries) {
90258
- const fullPath = join101(dir, entry.name);
90413
+ const fullPath = join102(dir, entry.name);
90259
90414
  if (entry.isDirectory()) {
90260
90415
  if (entry.name === "node_modules" || entry.name.startsWith(".")) {
90261
90416
  continue;
@@ -90294,7 +90449,7 @@ async function handleOpenCode(ctx) {
90294
90449
  if (ctx.cancelled || !ctx.extractDir || !ctx.resolvedDir) {
90295
90450
  return ctx;
90296
90451
  }
90297
- const openCodeSource = join102(ctx.extractDir, ".opencode");
90452
+ const openCodeSource = join103(ctx.extractDir, ".opencode");
90298
90453
  if (!await import_fs_extra29.pathExists(openCodeSource)) {
90299
90454
  logger.debug("No .opencode directory in archive, skipping");
90300
90455
  return ctx;
@@ -90312,8 +90467,8 @@ async function handleOpenCode(ctx) {
90312
90467
  await import_fs_extra29.ensureDir(targetDir);
90313
90468
  const entries = await readdir31(openCodeSource, { withFileTypes: true });
90314
90469
  for (const entry of entries) {
90315
- const sourcePath = join102(openCodeSource, entry.name);
90316
- const targetPath = join102(targetDir, entry.name);
90470
+ const sourcePath = join103(openCodeSource, entry.name);
90471
+ const targetPath = join103(targetDir, entry.name);
90317
90472
  if (await import_fs_extra29.pathExists(targetPath)) {
90318
90473
  if (!ctx.options.forceOverwrite) {
90319
90474
  logger.verbose(`Skipping existing: ${entry.name}`);
@@ -90410,7 +90565,7 @@ Please use only one download method.`);
90410
90565
  }
90411
90566
  // src/commands/init/phases/post-install-handler.ts
90412
90567
  init_projects_registry();
90413
- import { join as join103 } from "node:path";
90568
+ import { join as join104 } from "node:path";
90414
90569
  init_logger();
90415
90570
  init_path_resolver();
90416
90571
  var import_fs_extra30 = __toESM(require_lib3(), 1);
@@ -90419,8 +90574,8 @@ async function handlePostInstall(ctx) {
90419
90574
  return ctx;
90420
90575
  }
90421
90576
  if (ctx.options.global) {
90422
- const claudeMdSource = join103(ctx.extractDir, "CLAUDE.md");
90423
- const claudeMdDest = join103(ctx.resolvedDir, "CLAUDE.md");
90577
+ const claudeMdSource = join104(ctx.extractDir, "CLAUDE.md");
90578
+ const claudeMdDest = join104(ctx.resolvedDir, "CLAUDE.md");
90424
90579
  if (await import_fs_extra30.pathExists(claudeMdSource)) {
90425
90580
  if (ctx.options.fresh || !await import_fs_extra30.pathExists(claudeMdDest)) {
90426
90581
  await import_fs_extra30.copy(claudeMdSource, claudeMdDest);
@@ -90468,7 +90623,7 @@ async function handlePostInstall(ctx) {
90468
90623
  }
90469
90624
  if (!ctx.options.skipSetup) {
90470
90625
  await promptSetupWizardIfNeeded({
90471
- envPath: join103(ctx.claudeDir, ".env"),
90626
+ envPath: join104(ctx.claudeDir, ".env"),
90472
90627
  claudeDir: ctx.claudeDir,
90473
90628
  isGlobal: ctx.options.global,
90474
90629
  isNonInteractive: ctx.isNonInteractive,
@@ -90492,7 +90647,7 @@ async function handlePostInstall(ctx) {
90492
90647
  init_config_manager();
90493
90648
  init_github_client();
90494
90649
  import { mkdir as mkdir30 } from "node:fs/promises";
90495
- import { join as join105, resolve as resolve22 } from "node:path";
90650
+ import { join as join106, resolve as resolve22 } from "node:path";
90496
90651
 
90497
90652
  // src/domains/github/kit-access-checker.ts
90498
90653
  init_logger();
@@ -90623,7 +90778,7 @@ async function runPreflightChecks() {
90623
90778
  // src/domains/installation/fresh-installer.ts
90624
90779
  init_metadata_migration();
90625
90780
  import { existsSync as existsSync55, readdirSync as readdirSync5, rmSync as rmSync4, rmdirSync as rmdirSync2, unlinkSync as unlinkSync4 } from "node:fs";
90626
- import { dirname as dirname27, join as join104, resolve as resolve21 } from "node:path";
90781
+ import { dirname as dirname27, join as join105, resolve as resolve21 } from "node:path";
90627
90782
  init_logger();
90628
90783
  init_safe_spinner();
90629
90784
  var import_fs_extra31 = __toESM(require_lib3(), 1);
@@ -90696,7 +90851,7 @@ async function removeFilesByOwnership(claudeDir2, analysis, includeModified) {
90696
90851
  const filesToRemove = includeModified ? [...analysis.ckFiles, ...analysis.ckModifiedFiles] : analysis.ckFiles;
90697
90852
  const filesToPreserve = includeModified ? analysis.userFiles : [...analysis.ckModifiedFiles, ...analysis.userFiles];
90698
90853
  for (const file of filesToRemove) {
90699
- const fullPath = join104(claudeDir2, file.path);
90854
+ const fullPath = join105(claudeDir2, file.path);
90700
90855
  try {
90701
90856
  if (existsSync55(fullPath)) {
90702
90857
  unlinkSync4(fullPath);
@@ -90721,7 +90876,7 @@ async function removeFilesByOwnership(claudeDir2, analysis, includeModified) {
90721
90876
  };
90722
90877
  }
90723
90878
  async function updateMetadataAfterFresh(claudeDir2, removedFiles) {
90724
- const metadataPath = join104(claudeDir2, "metadata.json");
90879
+ const metadataPath = join105(claudeDir2, "metadata.json");
90725
90880
  if (!await import_fs_extra31.pathExists(metadataPath)) {
90726
90881
  return;
90727
90882
  }
@@ -90764,7 +90919,7 @@ async function removeSubdirectoriesFallback(claudeDir2) {
90764
90919
  const removedFiles = [];
90765
90920
  let removedDirCount = 0;
90766
90921
  for (const subdir of CLAUDEKIT_SUBDIRECTORIES) {
90767
- const subdirPath = join104(claudeDir2, subdir);
90922
+ const subdirPath = join105(claudeDir2, subdir);
90768
90923
  if (await import_fs_extra31.pathExists(subdirPath)) {
90769
90924
  rmSync4(subdirPath, { recursive: true, force: true });
90770
90925
  removedDirCount++;
@@ -90772,7 +90927,7 @@ async function removeSubdirectoriesFallback(claudeDir2) {
90772
90927
  logger.debug(`Removed subdirectory: ${subdir}/`);
90773
90928
  }
90774
90929
  }
90775
- const metadataPath = join104(claudeDir2, "metadata.json");
90930
+ const metadataPath = join105(claudeDir2, "metadata.json");
90776
90931
  if (await import_fs_extra31.pathExists(metadataPath)) {
90777
90932
  unlinkSync4(metadataPath);
90778
90933
  removedFiles.push("metadata.json");
@@ -91024,7 +91179,7 @@ async function handleSelection(ctx) {
91024
91179
  }
91025
91180
  if (!ctx.options.fresh) {
91026
91181
  const prefix = PathResolver.getPathPrefix(ctx.options.global);
91027
- const claudeDir2 = prefix ? join105(resolvedDir, prefix) : resolvedDir;
91182
+ const claudeDir2 = prefix ? join106(resolvedDir, prefix) : resolvedDir;
91028
91183
  try {
91029
91184
  const existingMetadata = await readManifest(claudeDir2);
91030
91185
  if (existingMetadata?.kits) {
@@ -91056,7 +91211,7 @@ async function handleSelection(ctx) {
91056
91211
  }
91057
91212
  if (ctx.options.fresh) {
91058
91213
  const prefix = PathResolver.getPathPrefix(ctx.options.global);
91059
- const claudeDir2 = prefix ? join105(resolvedDir, prefix) : resolvedDir;
91214
+ const claudeDir2 = prefix ? join106(resolvedDir, prefix) : resolvedDir;
91060
91215
  const canProceed = await handleFreshInstallation(claudeDir2, ctx.prompts);
91061
91216
  if (!canProceed) {
91062
91217
  return { ...ctx, cancelled: true };
@@ -91075,7 +91230,7 @@ async function handleSelection(ctx) {
91075
91230
  logger.info("Fetching available versions...");
91076
91231
  let currentVersion = null;
91077
91232
  try {
91078
- const metadataPath = ctx.options.global ? join105(PathResolver.getGlobalKitDir(), "metadata.json") : join105(resolvedDir, ".claude", "metadata.json");
91233
+ const metadataPath = ctx.options.global ? join106(PathResolver.getGlobalKitDir(), "metadata.json") : join106(resolvedDir, ".claude", "metadata.json");
91079
91234
  const metadata = await readClaudeKitMetadata(metadataPath);
91080
91235
  currentVersion = metadata?.version || null;
91081
91236
  if (currentVersion) {
@@ -91150,7 +91305,7 @@ async function handleSelection(ctx) {
91150
91305
  }
91151
91306
  // src/commands/init/phases/sync-handler.ts
91152
91307
  import { copyFile as copyFile8, mkdir as mkdir31, open as open4, readFile as readFile48, rename as rename6, stat as stat17, unlink as unlink11, writeFile as writeFile30 } from "node:fs/promises";
91153
- import { dirname as dirname28, join as join106, resolve as resolve23 } from "node:path";
91308
+ import { dirname as dirname28, join as join107, resolve as resolve23 } from "node:path";
91154
91309
  init_logger();
91155
91310
  init_path_resolver();
91156
91311
  var import_fs_extra33 = __toESM(require_lib3(), 1);
@@ -91160,13 +91315,13 @@ async function handleSync(ctx) {
91160
91315
  return ctx;
91161
91316
  }
91162
91317
  const resolvedDir = ctx.options.global ? PathResolver.getGlobalKitDir() : resolve23(ctx.options.dir || ".");
91163
- const claudeDir2 = ctx.options.global ? resolvedDir : join106(resolvedDir, ".claude");
91318
+ const claudeDir2 = ctx.options.global ? resolvedDir : join107(resolvedDir, ".claude");
91164
91319
  if (!await import_fs_extra33.pathExists(claudeDir2)) {
91165
91320
  logger.error("Cannot sync: no .claude directory found");
91166
91321
  ctx.prompts.note("Run 'ck init' without --sync to install first.", "No Installation Found");
91167
91322
  return { ...ctx, cancelled: true };
91168
91323
  }
91169
- const metadataPath = join106(claudeDir2, "metadata.json");
91324
+ const metadataPath = join107(claudeDir2, "metadata.json");
91170
91325
  if (!await import_fs_extra33.pathExists(metadataPath)) {
91171
91326
  logger.error("Cannot sync: no metadata.json found");
91172
91327
  ctx.prompts.note(`Your installation may be from an older version.
@@ -91266,7 +91421,7 @@ function getLockTimeout() {
91266
91421
  var STALE_LOCK_THRESHOLD_MS = 5 * 60 * 1000;
91267
91422
  async function acquireSyncLock(global3) {
91268
91423
  const cacheDir = PathResolver.getCacheDir(global3);
91269
- const lockPath = join106(cacheDir, ".sync-lock");
91424
+ const lockPath = join107(cacheDir, ".sync-lock");
91270
91425
  const startTime = Date.now();
91271
91426
  const lockTimeout = getLockTimeout();
91272
91427
  await mkdir31(dirname28(lockPath), { recursive: true });
@@ -91312,10 +91467,10 @@ async function executeSyncMerge(ctx) {
91312
91467
  const releaseLock = await acquireSyncLock(ctx.options.global);
91313
91468
  try {
91314
91469
  const trackedFiles = ctx.syncTrackedFiles;
91315
- const upstreamDir = ctx.options.global ? join106(ctx.extractDir, ".claude") : ctx.extractDir;
91470
+ const upstreamDir = ctx.options.global ? join107(ctx.extractDir, ".claude") : ctx.extractDir;
91316
91471
  let deletions = [];
91317
91472
  try {
91318
- const sourceMetadataPath = join106(upstreamDir, "metadata.json");
91473
+ const sourceMetadataPath = join107(upstreamDir, "metadata.json");
91319
91474
  if (await import_fs_extra33.pathExists(sourceMetadataPath)) {
91320
91475
  const content = await readFile48(sourceMetadataPath, "utf-8");
91321
91476
  const sourceMetadata = JSON.parse(content);
@@ -91347,7 +91502,7 @@ async function executeSyncMerge(ctx) {
91347
91502
  try {
91348
91503
  const sourcePath = await validateSyncPath(upstreamDir, file.path);
91349
91504
  const targetPath = await validateSyncPath(ctx.claudeDir, file.path);
91350
- const targetDir = join106(targetPath, "..");
91505
+ const targetDir = join107(targetPath, "..");
91351
91506
  try {
91352
91507
  await mkdir31(targetDir, { recursive: true });
91353
91508
  } catch (mkdirError) {
@@ -91518,7 +91673,7 @@ async function createBackup(claudeDir2, files, backupDir) {
91518
91673
  const sourcePath = await validateSyncPath(claudeDir2, file.path);
91519
91674
  if (await import_fs_extra33.pathExists(sourcePath)) {
91520
91675
  const targetPath = await validateSyncPath(backupDir, file.path);
91521
- const targetDir = join106(targetPath, "..");
91676
+ const targetDir = join107(targetPath, "..");
91522
91677
  await mkdir31(targetDir, { recursive: true });
91523
91678
  await copyFile8(sourcePath, targetPath);
91524
91679
  }
@@ -91533,7 +91688,7 @@ async function createBackup(claudeDir2, files, backupDir) {
91533
91688
  }
91534
91689
  // src/commands/init/phases/transform-handler.ts
91535
91690
  init_config_manager();
91536
- import { join as join110 } from "node:path";
91691
+ import { join as join111 } from "node:path";
91537
91692
 
91538
91693
  // src/services/transformers/folder-path-transformer.ts
91539
91694
  init_logger();
@@ -91544,38 +91699,38 @@ init_logger();
91544
91699
  init_types3();
91545
91700
  var import_fs_extra34 = __toESM(require_lib3(), 1);
91546
91701
  import { rename as rename7, rm as rm13 } from "node:fs/promises";
91547
- import { join as join107, relative as relative19 } from "node:path";
91702
+ import { join as join108, relative as relative19 } from "node:path";
91548
91703
  async function collectDirsToRename(extractDir, folders) {
91549
91704
  const dirsToRename = [];
91550
91705
  if (folders.docs !== DEFAULT_FOLDERS.docs) {
91551
- const docsPath = join107(extractDir, DEFAULT_FOLDERS.docs);
91706
+ const docsPath = join108(extractDir, DEFAULT_FOLDERS.docs);
91552
91707
  if (await import_fs_extra34.pathExists(docsPath)) {
91553
91708
  dirsToRename.push({
91554
91709
  from: docsPath,
91555
- to: join107(extractDir, folders.docs)
91710
+ to: join108(extractDir, folders.docs)
91556
91711
  });
91557
91712
  }
91558
- const claudeDocsPath = join107(extractDir, ".claude", DEFAULT_FOLDERS.docs);
91713
+ const claudeDocsPath = join108(extractDir, ".claude", DEFAULT_FOLDERS.docs);
91559
91714
  if (await import_fs_extra34.pathExists(claudeDocsPath)) {
91560
91715
  dirsToRename.push({
91561
91716
  from: claudeDocsPath,
91562
- to: join107(extractDir, ".claude", folders.docs)
91717
+ to: join108(extractDir, ".claude", folders.docs)
91563
91718
  });
91564
91719
  }
91565
91720
  }
91566
91721
  if (folders.plans !== DEFAULT_FOLDERS.plans) {
91567
- const plansPath = join107(extractDir, DEFAULT_FOLDERS.plans);
91722
+ const plansPath = join108(extractDir, DEFAULT_FOLDERS.plans);
91568
91723
  if (await import_fs_extra34.pathExists(plansPath)) {
91569
91724
  dirsToRename.push({
91570
91725
  from: plansPath,
91571
- to: join107(extractDir, folders.plans)
91726
+ to: join108(extractDir, folders.plans)
91572
91727
  });
91573
91728
  }
91574
- const claudePlansPath = join107(extractDir, ".claude", DEFAULT_FOLDERS.plans);
91729
+ const claudePlansPath = join108(extractDir, ".claude", DEFAULT_FOLDERS.plans);
91575
91730
  if (await import_fs_extra34.pathExists(claudePlansPath)) {
91576
91731
  dirsToRename.push({
91577
91732
  from: claudePlansPath,
91578
- to: join107(extractDir, ".claude", folders.plans)
91733
+ to: join108(extractDir, ".claude", folders.plans)
91579
91734
  });
91580
91735
  }
91581
91736
  }
@@ -91616,7 +91771,7 @@ async function renameFolders(dirsToRename, extractDir, options2) {
91616
91771
  init_logger();
91617
91772
  init_types3();
91618
91773
  import { readFile as readFile49, readdir as readdir32, writeFile as writeFile31 } from "node:fs/promises";
91619
- import { join as join108, relative as relative20 } from "node:path";
91774
+ import { join as join109, relative as relative20 } from "node:path";
91620
91775
  var TRANSFORMABLE_FILE_PATTERNS = [
91621
91776
  ".md",
91622
91777
  ".txt",
@@ -91669,7 +91824,7 @@ async function transformFileContents(dir, compiledReplacements, options2) {
91669
91824
  let replacementsCount = 0;
91670
91825
  const entries = await readdir32(dir, { withFileTypes: true });
91671
91826
  for (const entry of entries) {
91672
- const fullPath = join108(dir, entry.name);
91827
+ const fullPath = join109(dir, entry.name);
91673
91828
  if (entry.isDirectory()) {
91674
91829
  if (entry.name === "node_modules" || entry.name === ".git") {
91675
91830
  continue;
@@ -91806,7 +91961,7 @@ async function transformFolderPaths(extractDir, folders, options2 = {}) {
91806
91961
  init_logger();
91807
91962
  import { readFile as readFile50, readdir as readdir33, writeFile as writeFile32 } from "node:fs/promises";
91808
91963
  import { platform as platform13 } from "node:os";
91809
- import { extname as extname7, join as join109 } from "node:path";
91964
+ import { extname as extname7, join as join110 } from "node:path";
91810
91965
  var IS_WINDOWS3 = platform13() === "win32";
91811
91966
  var HOME_PREFIX = IS_WINDOWS3 ? "%USERPROFILE%" : "$HOME";
91812
91967
  function getHomeDirPrefix() {
@@ -91916,7 +92071,7 @@ async function transformPathsForGlobalInstall(directory, options2 = {}) {
91916
92071
  async function processDirectory2(dir) {
91917
92072
  const entries = await readdir33(dir, { withFileTypes: true });
91918
92073
  for (const entry of entries) {
91919
- const fullPath = join109(dir, entry.name);
92074
+ const fullPath = join110(dir, entry.name);
91920
92075
  if (entry.isDirectory()) {
91921
92076
  if (entry.name === "node_modules" || entry.name.startsWith(".") && entry.name !== ".claude") {
91922
92077
  continue;
@@ -91992,7 +92147,7 @@ async function handleTransforms(ctx) {
91992
92147
  logger.debug(ctx.options.global ? "Saved folder configuration to ~/.claude/.ck.json" : "Saved folder configuration to .claude/.ck.json");
91993
92148
  }
91994
92149
  }
91995
- const claudeDir2 = ctx.options.global ? ctx.resolvedDir : join110(ctx.resolvedDir, ".claude");
92150
+ const claudeDir2 = ctx.options.global ? ctx.resolvedDir : join111(ctx.resolvedDir, ".claude");
91996
92151
  return {
91997
92152
  ...ctx,
91998
92153
  foldersConfig,
@@ -92179,15 +92334,16 @@ async function initCommand(options2) {
92179
92334
  }
92180
92335
  // src/commands/migrate/migrate-command.ts
92181
92336
  init_dist2();
92337
+ var import_picocolors25 = __toESM(require_picocolors(), 1);
92338
+ import { existsSync as existsSync56 } from "node:fs";
92339
+ import { readFile as readFile51, rm as rm14, unlink as unlink12 } from "node:fs/promises";
92340
+ import { homedir as homedir29 } from "node:os";
92341
+ import { basename as basename16, join as join112, resolve as resolve24 } from "node:path";
92182
92342
  init_logger();
92183
92343
  init_agents_discovery();
92184
92344
  init_commands_discovery();
92185
92345
  init_checksum_utils();
92186
92346
  init_config_discovery();
92187
- var import_picocolors25 = __toESM(require_picocolors(), 1);
92188
- import { existsSync as existsSync56 } from "node:fs";
92189
- import { readFile as readFile51, rm as rm14, unlink as unlink12 } from "node:fs/promises";
92190
- import { basename as basename16, resolve as resolve24 } from "node:path";
92191
92347
 
92192
92348
  // src/commands/portable/conflict-resolver.ts
92193
92349
  init_dist2();
@@ -92600,6 +92756,34 @@ async function executeDeleteAction(action, options2) {
92600
92756
  };
92601
92757
  }
92602
92758
  }
92759
+ async function processMetadataDeletions(skillSourcePath, installGlobally) {
92760
+ if (!skillSourcePath)
92761
+ return;
92762
+ const sourceMetadataPath = join112(resolve24(skillSourcePath, ".."), "metadata.json");
92763
+ if (!existsSync56(sourceMetadataPath))
92764
+ return;
92765
+ let sourceMetadata;
92766
+ try {
92767
+ const content = await readFile51(sourceMetadataPath, "utf-8");
92768
+ sourceMetadata = JSON.parse(content);
92769
+ } catch (error) {
92770
+ logger.debug(`[migrate] Failed to parse source metadata.json: ${error}`);
92771
+ return;
92772
+ }
92773
+ if (!sourceMetadata.deletions || sourceMetadata.deletions.length === 0)
92774
+ return;
92775
+ const claudeDir2 = installGlobally ? join112(homedir29(), ".claude") : join112(process.cwd(), ".claude");
92776
+ if (!existsSync56(claudeDir2))
92777
+ return;
92778
+ try {
92779
+ const result = await handleDeletions(sourceMetadata, claudeDir2);
92780
+ if (result.deletedPaths.length > 0) {
92781
+ logger.verbose(`[migrate] Cleaned up ${result.deletedPaths.length} deprecated path(s): ${result.deletedPaths.join(", ")}`);
92782
+ }
92783
+ } catch (error) {
92784
+ logger.warning(`[migrate] Deletion cleanup failed: ${error}`);
92785
+ }
92786
+ }
92603
92787
  async function migrateCommand(options2) {
92604
92788
  console.log();
92605
92789
  oe(import_picocolors25.default.bgMagenta(import_picocolors25.default.black(" ck migrate ")));
@@ -92611,11 +92795,12 @@ async function migrateCommand(options2) {
92611
92795
  const commandSource = scope.commands ? getCommandSourcePath() : null;
92612
92796
  const skillSource = scope.skills ? getSkillSourcePath() : null;
92613
92797
  const hooksSource = scope.hooks ? getHooksSourcePath() : null;
92798
+ const rulesSourcePath = scope.rules ? getRulesSourcePath() : null;
92614
92799
  const agents2 = agentSource ? await discoverAgents(agentSource) : [];
92615
92800
  const commands = commandSource ? await discoverCommands(commandSource) : [];
92616
92801
  const skills = skillSource ? await discoverSkills(skillSource) : [];
92617
92802
  const configItem = scope.config ? await discoverConfig(options2.source) : null;
92618
- const ruleItems = scope.rules ? await discoverRules() : [];
92803
+ const ruleItems = rulesSourcePath ? await discoverRules(rulesSourcePath) : [];
92619
92804
  const { items: hookItems, skippedShellHooks } = hooksSource ? await discoverHooks(hooksSource) : { items: [], skippedShellHooks: [] };
92620
92805
  if (skippedShellHooks.length > 0) {
92621
92806
  logger.warning(`[migrate] Skipping ${skippedShellHooks.length} shell hook(s) not supported for migration (node-runnable only): ${skippedShellHooks.join(", ")}`);
@@ -92624,23 +92809,36 @@ async function migrateCommand(options2) {
92624
92809
  const hasItems = agents2.length > 0 || commands.length > 0 || skills.length > 0 || configItem !== null || ruleItems.length > 0 || hookItems.length > 0;
92625
92810
  if (!hasItems) {
92626
92811
  f2.error("Nothing to migrate.");
92627
- f2.info(import_picocolors25.default.dim("Check ~/.claude/agents/, ~/.claude/commands/, ~/.claude/skills/, ~/.claude/rules/, ~/.claude/hooks/, and ~/.claude/CLAUDE.md"));
92812
+ f2.info(import_picocolors25.default.dim("Check .claude/agents/, .claude/commands/, .claude/skills/, .claude/rules/, .claude/hooks/, and CLAUDE.md (project or ~/.claude/)"));
92628
92813
  $e(import_picocolors25.default.red("Nothing to migrate"));
92629
92814
  return;
92630
92815
  }
92816
+ f2.info(import_picocolors25.default.dim(` CWD: ${process.cwd()}`));
92631
92817
  const parts = [];
92632
- if (agents2.length > 0)
92633
- parts.push(`${agents2.length} agent(s)`);
92634
- if (commands.length > 0)
92635
- parts.push(`${commands.length} command(s)`);
92636
- if (skills.length > 0)
92637
- parts.push(`${skills.length} skill(s)`);
92638
- if (configItem)
92639
- parts.push("config");
92640
- if (ruleItems.length > 0)
92641
- parts.push(`${ruleItems.length} rule(s)`);
92642
- if (hookItems.length > 0)
92643
- parts.push(`${hookItems.length} hook(s)`);
92818
+ if (agents2.length > 0) {
92819
+ const origin = resolveSourceOrigin(agentSource);
92820
+ parts.push(`${agents2.length} agent(s) ${import_picocolors25.default.dim(`<- ${origin}`)}`);
92821
+ }
92822
+ if (commands.length > 0) {
92823
+ const origin = resolveSourceOrigin(commandSource);
92824
+ parts.push(`${commands.length} command(s) ${import_picocolors25.default.dim(`<- ${origin}`)}`);
92825
+ }
92826
+ if (skills.length > 0) {
92827
+ const origin = resolveSourceOrigin(skillSource);
92828
+ parts.push(`${skills.length} skill(s) ${import_picocolors25.default.dim(`<- ${origin}`)}`);
92829
+ }
92830
+ if (configItem) {
92831
+ const origin = resolveSourceOrigin(configItem.sourcePath);
92832
+ parts.push(`config ${import_picocolors25.default.dim(`<- ${origin}`)}`);
92833
+ }
92834
+ if (ruleItems.length > 0) {
92835
+ const origin = resolveSourceOrigin(rulesSourcePath);
92836
+ parts.push(`${ruleItems.length} rule(s) ${import_picocolors25.default.dim(`<- ${origin}`)}`);
92837
+ }
92838
+ if (hookItems.length > 0) {
92839
+ const origin = resolveSourceOrigin(hooksSource);
92840
+ parts.push(`${hookItems.length} hook(s) ${import_picocolors25.default.dim(`<- ${origin}`)}`);
92841
+ }
92644
92842
  f2.info(`Found: ${parts.join(", ")}`);
92645
92843
  const detectedProviders = await detectInstalledProviders();
92646
92844
  let selectedProviders;
@@ -92722,18 +92920,20 @@ async function migrateCommand(options2) {
92722
92920
  selectedProviders = Array.from(new Set(selectedProviders));
92723
92921
  let installGlobally = options2.global ?? false;
92724
92922
  if (options2.global === undefined && !options2.yes) {
92923
+ const projectTarget = join112(process.cwd(), ".claude");
92924
+ const globalTarget = join112(homedir29(), ".claude");
92725
92925
  const scopeChoice = await ie({
92726
92926
  message: "Installation scope",
92727
92927
  options: [
92728
92928
  {
92729
92929
  value: false,
92730
92930
  label: "Project",
92731
- hint: "Install in current directory"
92931
+ hint: `-> ${projectTarget}`
92732
92932
  },
92733
92933
  {
92734
92934
  value: true,
92735
92935
  label: "Global",
92736
- hint: "Install in home directory"
92936
+ hint: `-> ${globalTarget}`
92737
92937
  }
92738
92938
  ]
92739
92939
  });
@@ -92773,7 +92973,8 @@ async function migrateCommand(options2) {
92773
92973
  }
92774
92974
  const providerNames = selectedProviders.map((prov) => import_picocolors25.default.cyan(providers[prov].displayName)).join(", ");
92775
92975
  f2.message(` Providers: ${providerNames}`);
92776
- f2.message(` Scope: ${installGlobally ? "Global" : "Project"}`);
92976
+ const targetDir = installGlobally ? join112(homedir29(), ".claude") : join112(process.cwd(), ".claude");
92977
+ f2.message(` Scope: ${installGlobally ? "Global" : "Project"} ${import_picocolors25.default.dim(`-> ${targetDir}`)}`);
92777
92978
  const cmdProviders = getProvidersSupporting("commands");
92778
92979
  const unsupportedCmd = selectedProviders.filter((pv) => !cmdProviders.includes(pv));
92779
92980
  if (commands.length > 0 && unsupportedCmd.length > 0) {
@@ -92942,12 +93143,28 @@ async function migrateCommand(options2) {
92942
93143
  allResults.push(...await installSkillDirectories(skills, skillProviders, installOpts));
92943
93144
  }
92944
93145
  }
93146
+ await processMetadataDeletions(skillSource, installGlobally);
92945
93147
  const writtenPaths = new Set(allResults.filter((result) => result.success && !result.skipped && result.path.length > 0).map((result) => resolve24(result.path)));
92946
93148
  for (const deleteAction of plannedDeleteActions) {
92947
93149
  allResults.push(await executeDeleteAction(deleteAction, {
92948
93150
  preservePaths: writtenPaths
92949
93151
  }));
92950
93152
  }
93153
+ const skipActionsToPopulate = plan.actions.filter((a3) => a3.action === "skip" && a3.sourceChecksum && !isUnknownChecksum(a3.sourceChecksum) && a3.targetPath);
93154
+ for (const action of skipActionsToPopulate) {
93155
+ const registryEntry = registry.installations.find((i) => i.item === action.item && i.type === action.type && i.provider === action.provider && i.global === action.global);
93156
+ if (registryEntry && isUnknownChecksum(registryEntry.sourceChecksum)) {
93157
+ try {
93158
+ await addPortableInstallation(action.item, action.type, action.provider, action.global, action.targetPath, registryEntry.sourcePath, {
93159
+ sourceChecksum: action.sourceChecksum,
93160
+ targetChecksum: action.currentTargetChecksum,
93161
+ installSource: registryEntry.installSource === "manual" ? "manual" : "kit"
93162
+ });
93163
+ } catch {
93164
+ logger.debug(`Failed to populate checksums for ${action.item} — will retry on next run`);
93165
+ }
93166
+ }
93167
+ }
92951
93168
  installSpinner.stop("Migrate complete");
92952
93169
  displayMigrationSummary(plan, allResults, { color: useColor });
92953
93170
  const failed = allResults.filter((r2) => !r2.success);
@@ -93260,7 +93477,7 @@ async function handleDirectorySetup(ctx) {
93260
93477
  // src/commands/new/phases/project-creation.ts
93261
93478
  init_config_manager();
93262
93479
  init_github_client();
93263
- import { join as join111 } from "node:path";
93480
+ import { join as join113 } from "node:path";
93264
93481
  init_logger();
93265
93482
  init_output_manager();
93266
93483
  init_types3();
@@ -93386,7 +93603,7 @@ async function projectCreation(kit, resolvedDir, validOptions, isNonInteractive2
93386
93603
  output.section("Installing");
93387
93604
  logger.verbose("Installation target", { directory: resolvedDir });
93388
93605
  const merger = new FileMerger;
93389
- const claudeDir2 = join111(resolvedDir, ".claude");
93606
+ const claudeDir2 = join113(resolvedDir, ".claude");
93390
93607
  merger.setMultiKitContext(claudeDir2, kit);
93391
93608
  if (validOptions.exclude && validOptions.exclude.length > 0) {
93392
93609
  merger.addIgnorePatterns(validOptions.exclude);
@@ -93433,7 +93650,7 @@ async function handleProjectCreation(ctx) {
93433
93650
  }
93434
93651
  // src/commands/new/phases/post-setup.ts
93435
93652
  init_projects_registry();
93436
- import { join as join112 } from "node:path";
93653
+ import { join as join114 } from "node:path";
93437
93654
  init_package_installer();
93438
93655
  init_logger();
93439
93656
  init_path_resolver();
@@ -93465,9 +93682,9 @@ async function postSetup(resolvedDir, validOptions, isNonInteractive2, prompts)
93465
93682
  withSudo: validOptions.withSudo
93466
93683
  });
93467
93684
  }
93468
- const claudeDir2 = join112(resolvedDir, ".claude");
93685
+ const claudeDir2 = join114(resolvedDir, ".claude");
93469
93686
  await promptSetupWizardIfNeeded({
93470
- envPath: join112(claudeDir2, ".env"),
93687
+ envPath: join114(claudeDir2, ".env"),
93471
93688
  claudeDir: claudeDir2,
93472
93689
  isGlobal: false,
93473
93690
  isNonInteractive: isNonInteractive2,
@@ -93537,7 +93754,7 @@ Please use only one download method.`);
93537
93754
  // src/commands/plan/plan-command.ts
93538
93755
  init_output_manager();
93539
93756
  import { existsSync as existsSync58, statSync as statSync8 } from "node:fs";
93540
- import { dirname as dirname30, join as join114, parse as parse6, resolve as resolve28 } from "node:path";
93757
+ import { dirname as dirname30, join as join116, parse as parse6, resolve as resolve28 } from "node:path";
93541
93758
 
93542
93759
  // src/commands/plan/plan-read-handlers.ts
93543
93760
  init_plan_parser();
@@ -93545,7 +93762,7 @@ init_logger();
93545
93762
  init_output_manager();
93546
93763
  var import_picocolors27 = __toESM(require_picocolors(), 1);
93547
93764
  import { existsSync as existsSync57, statSync as statSync7 } from "node:fs";
93548
- import { basename as basename17, dirname as dirname29, join as join113, relative as relative21, resolve as resolve26 } from "node:path";
93765
+ import { basename as basename17, dirname as dirname29, join as join115, relative as relative21, resolve as resolve26 } from "node:path";
93549
93766
  async function handleParse(target, options2) {
93550
93767
  const planFile = resolvePlanFile(target);
93551
93768
  if (!planFile) {
@@ -93621,7 +93838,7 @@ async function handleValidate(target, options2) {
93621
93838
  }
93622
93839
  async function handleStatus(target, options2) {
93623
93840
  const t = target ? resolve26(target) : null;
93624
- const plansDir = t && existsSync57(t) && statSync7(t).isDirectory() && !existsSync57(join113(t, "plan.md")) ? t : null;
93841
+ const plansDir = t && existsSync57(t) && statSync7(t).isDirectory() && !existsSync57(join115(t, "plan.md")) ? t : null;
93625
93842
  if (plansDir) {
93626
93843
  const planFiles = scanPlanDir(plansDir);
93627
93844
  if (planFiles.length === 0) {
@@ -93893,7 +94110,7 @@ function resolvePlanFile(target) {
93893
94110
  const stat18 = statSync8(t);
93894
94111
  if (stat18.isFile())
93895
94112
  return t;
93896
- const candidate = join114(t, "plan.md");
94113
+ const candidate = join116(t, "plan.md");
93897
94114
  if (existsSync58(candidate))
93898
94115
  return candidate;
93899
94116
  }
@@ -93901,7 +94118,7 @@ function resolvePlanFile(target) {
93901
94118
  let dir = process.cwd();
93902
94119
  const root = parse6(dir).root;
93903
94120
  while (dir !== root) {
93904
- const candidate = join114(dir, "plan.md");
94121
+ const candidate = join116(dir, "plan.md");
93905
94122
  if (existsSync58(candidate))
93906
94123
  return candidate;
93907
94124
  dir = dirname30(dir);
@@ -94928,7 +95145,7 @@ async function detectInstallations() {
94928
95145
 
94929
95146
  // src/commands/uninstall/removal-handler.ts
94930
95147
  import { readdirSync as readdirSync7, rmSync as rmSync6 } from "node:fs";
94931
- import { join as join116, resolve as resolve30, sep as sep6 } from "node:path";
95148
+ import { join as join118, resolve as resolve30, sep as sep7 } from "node:path";
94932
95149
  init_logger();
94933
95150
  init_safe_prompts();
94934
95151
  init_safe_spinner();
@@ -94937,7 +95154,7 @@ var import_fs_extra37 = __toESM(require_lib3(), 1);
94937
95154
  // src/commands/uninstall/analysis-handler.ts
94938
95155
  init_metadata_migration();
94939
95156
  import { readdirSync as readdirSync6, rmSync as rmSync5 } from "node:fs";
94940
- import { dirname as dirname31, join as join115 } from "node:path";
95157
+ import { dirname as dirname31, join as join117 } from "node:path";
94941
95158
  init_logger();
94942
95159
  init_safe_prompts();
94943
95160
  var import_picocolors33 = __toESM(require_picocolors(), 1);
@@ -94985,7 +95202,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
94985
95202
  if (uninstallManifest.isMultiKit && kit && metadata?.kits?.[kit]) {
94986
95203
  const kitFiles = metadata.kits[kit].files || [];
94987
95204
  for (const trackedFile of kitFiles) {
94988
- const filePath = join115(installation.path, trackedFile.path);
95205
+ const filePath = join117(installation.path, trackedFile.path);
94989
95206
  if (uninstallManifest.filesToPreserve.includes(trackedFile.path)) {
94990
95207
  result.toPreserve.push({ path: trackedFile.path, reason: "shared with other kit" });
94991
95208
  continue;
@@ -95015,7 +95232,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
95015
95232
  return result;
95016
95233
  }
95017
95234
  for (const trackedFile of allTrackedFiles) {
95018
- const filePath = join115(installation.path, trackedFile.path);
95235
+ const filePath = join117(installation.path, trackedFile.path);
95019
95236
  const ownershipResult = await OwnershipChecker.checkOwnership(filePath, metadata, installation.path);
95020
95237
  if (!ownershipResult.exists)
95021
95238
  continue;
@@ -95071,7 +95288,7 @@ async function isPathSafeToRemove(filePath, baseDir) {
95071
95288
  try {
95072
95289
  const resolvedPath = resolve30(filePath);
95073
95290
  const resolvedBase = resolve30(baseDir);
95074
- if (!resolvedPath.startsWith(resolvedBase + sep6) && resolvedPath !== resolvedBase) {
95291
+ if (!resolvedPath.startsWith(resolvedBase + sep7) && resolvedPath !== resolvedBase) {
95075
95292
  logger.debug(`Path outside installation directory: ${filePath}`);
95076
95293
  return false;
95077
95294
  }
@@ -95079,7 +95296,7 @@ async function isPathSafeToRemove(filePath, baseDir) {
95079
95296
  if (stats.isSymbolicLink()) {
95080
95297
  const realPath = await import_fs_extra37.realpath(filePath);
95081
95298
  const resolvedReal = resolve30(realPath);
95082
- if (!resolvedReal.startsWith(resolvedBase + sep6) && resolvedReal !== resolvedBase) {
95299
+ if (!resolvedReal.startsWith(resolvedBase + sep7) && resolvedReal !== resolvedBase) {
95083
95300
  logger.debug(`Symlink points outside installation directory: ${filePath} -> ${realPath}`);
95084
95301
  return false;
95085
95302
  }
@@ -95112,7 +95329,7 @@ async function removeInstallations(installations, options2) {
95112
95329
  let removedCount = 0;
95113
95330
  let cleanedDirs = 0;
95114
95331
  for (const item of analysis.toDelete) {
95115
- const filePath = join116(installation.path, item.path);
95332
+ const filePath = join118(installation.path, item.path);
95116
95333
  if (!await import_fs_extra37.pathExists(filePath))
95117
95334
  continue;
95118
95335
  if (!await isPathSafeToRemove(filePath, installation.path)) {
@@ -95508,7 +95725,7 @@ init_logger();
95508
95725
  init_path_resolver();
95509
95726
  init_types3();
95510
95727
  import { existsSync as existsSync60, readFileSync as readFileSync13 } from "node:fs";
95511
- import { join as join117 } from "node:path";
95728
+ import { join as join119 } from "node:path";
95512
95729
  var packageVersion = package_default.version;
95513
95730
  function formatInstalledKits(metadata) {
95514
95731
  if (!metadata.kits || Object.keys(metadata.kits).length === 0) {
@@ -95540,9 +95757,9 @@ async function displayVersion() {
95540
95757
  let localKitVersion = null;
95541
95758
  let isGlobalOnlyKit = false;
95542
95759
  const globalKitDir = PathResolver.getGlobalKitDir();
95543
- const globalMetadataPath = join117(globalKitDir, "metadata.json");
95760
+ const globalMetadataPath = join119(globalKitDir, "metadata.json");
95544
95761
  const prefix = PathResolver.getPathPrefix(false);
95545
- const localMetadataPath = prefix ? join117(process.cwd(), prefix, "metadata.json") : join117(process.cwd(), "metadata.json");
95762
+ const localMetadataPath = prefix ? join119(process.cwd(), prefix, "metadata.json") : join119(process.cwd(), "metadata.json");
95546
95763
  const isLocalSameAsGlobal = localMetadataPath === globalMetadataPath;
95547
95764
  if (!isLocalSameAsGlobal && existsSync60(localMetadataPath)) {
95548
95765
  try {