claudekit-cli 3.34.1-dev.5 → 3.35.0-dev.1

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 +1191 -389
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -45277,7 +45277,7 @@ var package_default;
45277
45277
  var init_package = __esm(() => {
45278
45278
  package_default = {
45279
45279
  name: "claudekit-cli",
45280
- version: "3.34.1-dev.5",
45280
+ version: "3.35.0-dev.1",
45281
45281
  description: "CLI tool for bootstrapping and updating ClaudeKit projects",
45282
45282
  type: "module",
45283
45283
  repository: {
@@ -50617,7 +50617,7 @@ __export(exports_github_api_checker, {
50617
50617
  checkRepositoryAccess: () => checkRepositoryAccess,
50618
50618
  checkRateLimit: () => checkRateLimit
50619
50619
  });
50620
- import { spawnSync } from "node:child_process";
50620
+ import { spawnSync as spawnSync2 } from "node:child_process";
50621
50621
  async function checkRateLimit() {
50622
50622
  if (false) {}
50623
50623
  const apiEndpoint = "api.github.com/rate_limit";
@@ -50712,7 +50712,7 @@ async function checkTokenScopes() {
50712
50712
  if (false) {}
50713
50713
  const checkCommand = "gh auth status -h github.com";
50714
50714
  try {
50715
- const result = spawnSync("gh", ["auth", "status", "-h", "github.com"], {
50715
+ const result = spawnSync2("gh", ["auth", "status", "-h", "github.com"], {
50716
50716
  encoding: "utf8",
50717
50717
  timeout: COMMAND_TIMEOUT_MS
50718
50718
  });
@@ -52280,7 +52280,7 @@ var require_picomatch2 = __commonJS((exports, module) => {
52280
52280
  import { exec as exec7, execFile as execFile7, spawn as spawn3 } from "node:child_process";
52281
52281
  import { promisify as promisify13 } from "node:util";
52282
52282
  function executeInteractiveScript(command, args, options2) {
52283
- return new Promise((resolve8, reject) => {
52283
+ return new Promise((resolve9, reject) => {
52284
52284
  const child = spawn3(command, args, {
52285
52285
  stdio: ["ignore", "inherit", "inherit"],
52286
52286
  cwd: options2?.cwd,
@@ -52301,7 +52301,7 @@ function executeInteractiveScript(command, args, options2) {
52301
52301
  } else if (code !== 0) {
52302
52302
  reject(new Error(`Command exited with code ${code}`));
52303
52303
  } else {
52304
- resolve8();
52304
+ resolve9();
52305
52305
  }
52306
52306
  });
52307
52307
  child.on("error", (error) => {
@@ -52322,7 +52322,7 @@ var init_process_executor = __esm(() => {
52322
52322
  });
52323
52323
 
52324
52324
  // src/services/package-installer/validators.ts
52325
- import { resolve as resolve8 } from "node:path";
52325
+ import { resolve as resolve9 } from "node:path";
52326
52326
  function validatePackageName(packageName) {
52327
52327
  if (!packageName || typeof packageName !== "string") {
52328
52328
  throw new Error("Package name must be a non-empty string");
@@ -52335,8 +52335,8 @@ function validatePackageName(packageName) {
52335
52335
  }
52336
52336
  }
52337
52337
  function validateScriptPath(skillsDir2, scriptPath) {
52338
- const skillsDirResolved = resolve8(skillsDir2);
52339
- const scriptPathResolved = resolve8(scriptPath);
52338
+ const skillsDirResolved = resolve9(skillsDir2);
52339
+ const scriptPathResolved = resolve9(scriptPath);
52340
52340
  const skillsDirNormalized = isWindows() ? skillsDirResolved.toLowerCase() : skillsDirResolved;
52341
52341
  const scriptPathNormalized = isWindows() ? scriptPathResolved.toLowerCase() : scriptPathResolved;
52342
52342
  if (!scriptPathNormalized.startsWith(skillsDirNormalized)) {
@@ -52500,7 +52500,7 @@ var init_gemini_installer = __esm(() => {
52500
52500
  });
52501
52501
 
52502
52502
  // src/services/package-installer/opencode-installer.ts
52503
- import { join as join47 } from "node:path";
52503
+ import { join as join48 } from "node:path";
52504
52504
  async function isOpenCodeInstalled() {
52505
52505
  try {
52506
52506
  await execAsync7("opencode --version", { timeout: 5000 });
@@ -52522,8 +52522,8 @@ async function installOpenCode() {
52522
52522
  try {
52523
52523
  logger.info(`Installing ${displayName}...`);
52524
52524
  const { unlink: unlink8 } = await import("node:fs/promises");
52525
- const { tmpdir: tmpdir3 } = await import("node:os");
52526
- const tempScriptPath = join47(tmpdir3(), "opencode-install.sh");
52525
+ const { tmpdir: tmpdir4 } = await import("node:os");
52526
+ const tempScriptPath = join48(tmpdir4(), "opencode-install.sh");
52527
52527
  try {
52528
52528
  logger.info("Downloading OpenCode installation script...");
52529
52529
  await execFileAsync5("curl", ["-fsSL", "https://opencode.ai/install", "-o", tempScriptPath], {
@@ -52574,8 +52574,8 @@ var init_opencode_installer = __esm(() => {
52574
52574
  var PARTIAL_INSTALL_VERSION = "partial", EXIT_CODE_CRITICAL_FAILURE = 1, EXIT_CODE_PARTIAL_SUCCESS = 2;
52575
52575
 
52576
52576
  // src/services/package-installer/install-error-handler.ts
52577
- import { existsSync as existsSync31, readFileSync as readFileSync7, unlinkSync as unlinkSync2 } from "node:fs";
52578
- import { join as join48 } from "node:path";
52577
+ import { existsSync as existsSync32, readFileSync as readFileSync8, unlinkSync as unlinkSync2 } from "node:fs";
52578
+ import { join as join49 } from "node:path";
52579
52579
  function parseNameReason(str2) {
52580
52580
  const colonIndex = str2.indexOf(":");
52581
52581
  if (colonIndex === -1) {
@@ -52584,14 +52584,14 @@ function parseNameReason(str2) {
52584
52584
  return [str2.slice(0, colonIndex).trim(), str2.slice(colonIndex + 1).trim()];
52585
52585
  }
52586
52586
  function displayInstallErrors(skillsDir2) {
52587
- const summaryPath = join48(skillsDir2, ".install-error-summary.json");
52588
- if (!existsSync31(summaryPath)) {
52587
+ const summaryPath = join49(skillsDir2, ".install-error-summary.json");
52588
+ if (!existsSync32(summaryPath)) {
52589
52589
  logger.error("Skills installation failed. Run with --verbose for details.");
52590
52590
  return;
52591
52591
  }
52592
52592
  let summary;
52593
52593
  try {
52594
- summary = JSON.parse(readFileSync7(summaryPath, "utf-8"));
52594
+ summary = JSON.parse(readFileSync8(summaryPath, "utf-8"));
52595
52595
  } catch (parseError) {
52596
52596
  logger.error("Failed to parse error summary. File may be corrupted.");
52597
52597
  logger.debug(`Parse error: ${parseError instanceof Error ? parseError.message : String(parseError)}`);
@@ -52675,8 +52675,8 @@ async function checkNeedsSudoPackages() {
52675
52675
  }
52676
52676
  }
52677
52677
  function hasInstallState(skillsDir2) {
52678
- const stateFilePath = join48(skillsDir2, ".install-state.json");
52679
- return existsSync31(stateFilePath);
52678
+ const stateFilePath = join49(skillsDir2, ".install-state.json");
52679
+ return existsSync32(stateFilePath);
52680
52680
  }
52681
52681
  var WHICH_COMMAND_TIMEOUT_MS = 5000;
52682
52682
  var init_install_error_handler = __esm(() => {
@@ -52684,7 +52684,7 @@ var init_install_error_handler = __esm(() => {
52684
52684
  });
52685
52685
 
52686
52686
  // src/services/package-installer/skills-installer.ts
52687
- import { join as join49 } from "node:path";
52687
+ import { join as join50 } from "node:path";
52688
52688
  async function installSkillsDependencies(skillsDir2, options2 = {}) {
52689
52689
  const { skipConfirm = false, withSudo = false } = options2;
52690
52690
  const displayName = "Skills Dependencies";
@@ -52706,11 +52706,11 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
52706
52706
  };
52707
52707
  }
52708
52708
  try {
52709
- const { existsSync: existsSync32 } = await import("node:fs");
52709
+ const { existsSync: existsSync33 } = await import("node:fs");
52710
52710
  const clack = await Promise.resolve().then(() => (init_dist2(), exports_dist));
52711
52711
  const platform7 = process.platform;
52712
52712
  const scriptName = platform7 === "win32" ? "install.ps1" : "install.sh";
52713
- const scriptPath = join49(skillsDir2, scriptName);
52713
+ const scriptPath = join50(skillsDir2, scriptName);
52714
52714
  try {
52715
52715
  validateScriptPath(skillsDir2, scriptPath);
52716
52716
  } catch (error) {
@@ -52722,11 +52722,11 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
52722
52722
  error: `Path validation failed: ${errorMessage}`
52723
52723
  };
52724
52724
  }
52725
- if (!existsSync32(scriptPath)) {
52725
+ if (!existsSync33(scriptPath)) {
52726
52726
  logger.warning(`Skills installation script not found: ${scriptPath}`);
52727
52727
  logger.info("");
52728
52728
  logger.info("\uD83D\uDCD6 Manual Installation Instructions:");
52729
- logger.info(` See: ${join49(skillsDir2, "INSTALLATION.md")}`);
52729
+ logger.info(` See: ${join50(skillsDir2, "INSTALLATION.md")}`);
52730
52730
  logger.info("");
52731
52731
  logger.info("Quick start:");
52732
52732
  logger.info(" cd .claude/skills/ai-multimodal/scripts");
@@ -52773,7 +52773,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
52773
52773
  logger.info(` ${platform7 === "win32" ? `powershell -File "${scriptPath}"` : `bash ${scriptPath}`}`);
52774
52774
  logger.info("");
52775
52775
  logger.info("Or see complete guide:");
52776
- logger.info(` ${join49(skillsDir2, "INSTALLATION.md")}`);
52776
+ logger.info(` ${join50(skillsDir2, "INSTALLATION.md")}`);
52777
52777
  return {
52778
52778
  success: false,
52779
52779
  package: displayName,
@@ -52894,7 +52894,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
52894
52894
  logger.info("\uD83D\uDCD6 Manual Installation Instructions:");
52895
52895
  logger.info("");
52896
52896
  logger.info("See complete guide:");
52897
- logger.info(` cat ${join49(skillsDir2, "INSTALLATION.md")}`);
52897
+ logger.info(` cat ${join50(skillsDir2, "INSTALLATION.md")}`);
52898
52898
  logger.info("");
52899
52899
  logger.info("Quick start:");
52900
52900
  logger.info(" cd .claude/skills/ai-multimodal/scripts");
@@ -52938,9 +52938,9 @@ var init_skills_installer2 = __esm(() => {
52938
52938
  });
52939
52939
 
52940
52940
  // src/services/package-installer/gemini-mcp/config-manager.ts
52941
- import { existsSync as existsSync32 } from "node:fs";
52941
+ import { existsSync as existsSync33 } from "node:fs";
52942
52942
  import { mkdir as mkdir12, readFile as readFile26, writeFile as writeFile15 } from "node:fs/promises";
52943
- import { dirname as dirname11, join as join50 } from "node:path";
52943
+ import { dirname as dirname11, join as join51 } from "node:path";
52944
52944
  async function readJsonFile(filePath) {
52945
52945
  try {
52946
52946
  const content = await readFile26(filePath, "utf-8");
@@ -52952,11 +52952,11 @@ async function readJsonFile(filePath) {
52952
52952
  }
52953
52953
  }
52954
52954
  async function addGeminiToGitignore(projectDir) {
52955
- const gitignorePath = join50(projectDir, ".gitignore");
52955
+ const gitignorePath = join51(projectDir, ".gitignore");
52956
52956
  const geminiPattern = ".gemini/";
52957
52957
  try {
52958
52958
  let content = "";
52959
- if (existsSync32(gitignorePath)) {
52959
+ if (existsSync33(gitignorePath)) {
52960
52960
  content = await readFile26(gitignorePath, "utf-8");
52961
52961
  const lines = content.split(`
52962
52962
  `).map((line) => line.trim()).filter((line) => !line.startsWith("#"));
@@ -52981,7 +52981,7 @@ ${geminiPattern}
52981
52981
  }
52982
52982
  async function createNewSettingsWithMerge(geminiSettingsPath, mcpConfigPath) {
52983
52983
  const linkDir = dirname11(geminiSettingsPath);
52984
- if (!existsSync32(linkDir)) {
52984
+ if (!existsSync33(linkDir)) {
52985
52985
  await mkdir12(linkDir, { recursive: true });
52986
52986
  logger.debug(`Created directory: ${linkDir}`);
52987
52987
  }
@@ -53042,23 +53042,23 @@ var init_config_manager2 = __esm(() => {
53042
53042
  });
53043
53043
 
53044
53044
  // src/services/package-installer/gemini-mcp/validation.ts
53045
- import { existsSync as existsSync33, lstatSync, readlinkSync } from "node:fs";
53045
+ import { existsSync as existsSync34, lstatSync, readlinkSync } from "node:fs";
53046
53046
  import { homedir as homedir17 } from "node:os";
53047
- import { join as join51 } from "node:path";
53047
+ import { join as join52 } from "node:path";
53048
53048
  function getGlobalMcpConfigPath() {
53049
- return join51(homedir17(), ".claude", ".mcp.json");
53049
+ return join52(homedir17(), ".claude", ".mcp.json");
53050
53050
  }
53051
53051
  function getLocalMcpConfigPath(projectDir) {
53052
- return join51(projectDir, ".mcp.json");
53052
+ return join52(projectDir, ".mcp.json");
53053
53053
  }
53054
53054
  function findMcpConfigPath(projectDir) {
53055
53055
  const localPath = getLocalMcpConfigPath(projectDir);
53056
- if (existsSync33(localPath)) {
53056
+ if (existsSync34(localPath)) {
53057
53057
  logger.debug(`Found local MCP config: ${localPath}`);
53058
53058
  return localPath;
53059
53059
  }
53060
53060
  const globalPath = getGlobalMcpConfigPath();
53061
- if (existsSync33(globalPath)) {
53061
+ if (existsSync34(globalPath)) {
53062
53062
  logger.debug(`Found global MCP config: ${globalPath}`);
53063
53063
  return globalPath;
53064
53064
  }
@@ -53067,13 +53067,13 @@ function findMcpConfigPath(projectDir) {
53067
53067
  }
53068
53068
  function getGeminiSettingsPath(projectDir, isGlobal) {
53069
53069
  if (isGlobal) {
53070
- return join51(homedir17(), ".gemini", "settings.json");
53070
+ return join52(homedir17(), ".gemini", "settings.json");
53071
53071
  }
53072
- return join51(projectDir, ".gemini", "settings.json");
53072
+ return join52(projectDir, ".gemini", "settings.json");
53073
53073
  }
53074
53074
  function checkExistingGeminiConfig(projectDir, isGlobal = false) {
53075
53075
  const geminiSettingsPath = getGeminiSettingsPath(projectDir, isGlobal);
53076
- if (!existsSync33(geminiSettingsPath)) {
53076
+ if (!existsSync34(geminiSettingsPath)) {
53077
53077
  return { exists: false, isSymlink: false, settingsPath: geminiSettingsPath };
53078
53078
  }
53079
53079
  try {
@@ -53097,12 +53097,12 @@ var init_validation = __esm(() => {
53097
53097
  });
53098
53098
 
53099
53099
  // src/services/package-installer/gemini-mcp/linker-core.ts
53100
- import { existsSync as existsSync34 } from "node:fs";
53100
+ import { existsSync as existsSync35 } from "node:fs";
53101
53101
  import { mkdir as mkdir13, symlink as symlink2 } from "node:fs/promises";
53102
- import { dirname as dirname12, join as join52 } from "node:path";
53102
+ import { dirname as dirname12, join as join53 } from "node:path";
53103
53103
  async function createSymlink(targetPath, linkPath, projectDir, isGlobal) {
53104
53104
  const linkDir = dirname12(linkPath);
53105
- if (!existsSync34(linkDir)) {
53105
+ if (!existsSync35(linkDir)) {
53106
53106
  await mkdir13(linkDir, { recursive: true });
53107
53107
  logger.debug(`Created directory: ${linkDir}`);
53108
53108
  }
@@ -53110,7 +53110,7 @@ async function createSymlink(targetPath, linkPath, projectDir, isGlobal) {
53110
53110
  if (isGlobal) {
53111
53111
  symlinkTarget = getGlobalMcpConfigPath();
53112
53112
  } else {
53113
- const localMcpPath = join52(projectDir, ".mcp.json");
53113
+ const localMcpPath = join53(projectDir, ".mcp.json");
53114
53114
  const isLocalConfig = targetPath === localMcpPath;
53115
53115
  symlinkTarget = isLocalConfig ? "../.mcp.json" : targetPath;
53116
53116
  }
@@ -53143,10 +53143,10 @@ __export(exports_gemini_mcp_linker, {
53143
53143
  checkExistingGeminiConfig: () => checkExistingGeminiConfig,
53144
53144
  addGeminiToGitignore: () => addGeminiToGitignore
53145
53145
  });
53146
- import { resolve as resolve9 } from "node:path";
53146
+ import { resolve as resolve10 } from "node:path";
53147
53147
  async function linkGeminiMcpConfig(projectDir, options2 = {}) {
53148
53148
  const { skipGitignore = false, isGlobal = false } = options2;
53149
- const resolvedProjectDir = resolve9(projectDir);
53149
+ const resolvedProjectDir = resolve10(projectDir);
53150
53150
  const geminiSettingsPath = getGeminiSettingsPath(resolvedProjectDir, isGlobal);
53151
53151
  const mcpConfigPath = findMcpConfigPath(resolvedProjectDir);
53152
53152
  if (!mcpConfigPath) {
@@ -53944,12 +53944,12 @@ var require_adapter = __commonJS((exports, module) => {
53944
53944
  return newFs;
53945
53945
  }
53946
53946
  function toPromise(method) {
53947
- return (...args) => new Promise((resolve10, reject) => {
53947
+ return (...args) => new Promise((resolve11, reject) => {
53948
53948
  args.push((err, result) => {
53949
53949
  if (err) {
53950
53950
  reject(err);
53951
53951
  } else {
53952
- resolve10(result);
53952
+ resolve11(result);
53953
53953
  }
53954
53954
  });
53955
53955
  method(...args);
@@ -54519,7 +54519,7 @@ var require_get_stream = __commonJS((exports, module) => {
54519
54519
  };
54520
54520
  const { maxBuffer } = options2;
54521
54521
  let stream;
54522
- await new Promise((resolve11, reject) => {
54522
+ await new Promise((resolve12, reject) => {
54523
54523
  const rejectPromise = (error) => {
54524
54524
  if (error && stream.getBufferedLength() <= BufferConstants.MAX_LENGTH) {
54525
54525
  error.bufferedData = stream.getBufferedValue();
@@ -54531,7 +54531,7 @@ var require_get_stream = __commonJS((exports, module) => {
54531
54531
  rejectPromise(error);
54532
54532
  return;
54533
54533
  }
54534
- resolve11();
54534
+ resolve12();
54535
54535
  });
54536
54536
  stream.on("data", () => {
54537
54537
  if (stream.getBufferedLength() > maxBuffer) {
@@ -55892,7 +55892,7 @@ var require_extract_zip = __commonJS((exports, module) => {
55892
55892
  debug("opening", this.zipPath, "with opts", this.opts);
55893
55893
  this.zipfile = await openZip(this.zipPath, { lazyEntries: true });
55894
55894
  this.canceled = false;
55895
- return new Promise((resolve11, reject) => {
55895
+ return new Promise((resolve12, reject) => {
55896
55896
  this.zipfile.on("error", (err) => {
55897
55897
  this.canceled = true;
55898
55898
  reject(err);
@@ -55901,7 +55901,7 @@ var require_extract_zip = __commonJS((exports, module) => {
55901
55901
  this.zipfile.on("close", () => {
55902
55902
  if (!this.canceled) {
55903
55903
  debug("zip extraction complete");
55904
- resolve11();
55904
+ resolve12();
55905
55905
  }
55906
55906
  });
55907
55907
  this.zipfile.on("entry", async (entry) => {
@@ -58609,7 +58609,7 @@ function getPagerArgs(pagerCmd) {
58609
58609
  return [];
58610
58610
  }
58611
58611
  async function trySystemPager(content) {
58612
- return new Promise((resolve20) => {
58612
+ return new Promise((resolve21) => {
58613
58613
  const pagerCmd = process.env.PAGER || "less";
58614
58614
  const pagerArgs = getPagerArgs(pagerCmd);
58615
58615
  try {
@@ -58619,20 +58619,20 @@ async function trySystemPager(content) {
58619
58619
  });
58620
58620
  const timeout2 = setTimeout(() => {
58621
58621
  pager.kill();
58622
- resolve20(false);
58622
+ resolve21(false);
58623
58623
  }, 30000);
58624
58624
  pager.stdin.write(content);
58625
58625
  pager.stdin.end();
58626
58626
  pager.on("close", (code2) => {
58627
58627
  clearTimeout(timeout2);
58628
- resolve20(code2 === 0);
58628
+ resolve21(code2 === 0);
58629
58629
  });
58630
58630
  pager.on("error", () => {
58631
58631
  clearTimeout(timeout2);
58632
- resolve20(false);
58632
+ resolve21(false);
58633
58633
  });
58634
58634
  } catch {
58635
- resolve20(false);
58635
+ resolve21(false);
58636
58636
  }
58637
58637
  });
58638
58638
  }
@@ -58659,16 +58659,16 @@ async function basicPager(content) {
58659
58659
  break;
58660
58660
  }
58661
58661
  const remaining = lines.length - currentLine;
58662
- await new Promise((resolve20) => {
58662
+ await new Promise((resolve21) => {
58663
58663
  rl.question(`-- More (${remaining} lines) [Enter/q] --`, (answer) => {
58664
58664
  if (answer.toLowerCase() === "q") {
58665
58665
  rl.close();
58666
58666
  process.exitCode = 0;
58667
- resolve20();
58667
+ resolve21();
58668
58668
  return;
58669
58669
  }
58670
58670
  process.stdout.write("\x1B[1A\x1B[2K");
58671
- resolve20();
58671
+ resolve21();
58672
58672
  });
58673
58673
  });
58674
58674
  }
@@ -61616,6 +61616,794 @@ async function checkEnvKeys(setup) {
61616
61616
  }
61617
61617
  return results;
61618
61618
  }
61619
+ // src/domains/health-checks/checkers/hook-health-checker.ts
61620
+ init_logger();
61621
+ init_path_resolver();
61622
+ import { spawnSync } from "node:child_process";
61623
+ import { existsSync as existsSync30, readFileSync as readFileSync6, statSync as statSync5, writeFileSync } from "node:fs";
61624
+ import { readdir as readdir9 } from "node:fs/promises";
61625
+ import { tmpdir } from "node:os";
61626
+ import { join as join41, resolve as resolve8 } from "node:path";
61627
+ var HOOK_CHECK_TIMEOUT_MS = 5000;
61628
+ var PYTHON_CHECK_TIMEOUT_MS = 3000;
61629
+ var MAX_LOG_FILE_SIZE_BYTES = 10 * 1024 * 1024;
61630
+ function getHooksDir(projectDir) {
61631
+ const projectHooksDir = resolve8(projectDir, ".claude", "hooks");
61632
+ const globalHooksDir = resolve8(PathResolver.getGlobalKitDir(), "hooks");
61633
+ if (existsSync30(projectHooksDir))
61634
+ return projectHooksDir;
61635
+ if (existsSync30(globalHooksDir))
61636
+ return globalHooksDir;
61637
+ return null;
61638
+ }
61639
+ function isPathWithin(filePath, parentDir) {
61640
+ return resolve8(filePath).startsWith(resolve8(parentDir));
61641
+ }
61642
+ async function checkHookSyntax(projectDir) {
61643
+ const hooksDir = getHooksDir(projectDir);
61644
+ if (!hooksDir) {
61645
+ return {
61646
+ id: "hook-syntax",
61647
+ name: "Hook Syntax",
61648
+ group: "claudekit",
61649
+ priority: "critical",
61650
+ status: "info",
61651
+ message: "No hooks directory",
61652
+ autoFixable: false
61653
+ };
61654
+ }
61655
+ try {
61656
+ const files = await readdir9(hooksDir);
61657
+ const cjsFiles = files.filter((f3) => f3.endsWith(".cjs"));
61658
+ if (cjsFiles.length === 0) {
61659
+ return {
61660
+ id: "hook-syntax",
61661
+ name: "Hook Syntax",
61662
+ group: "claudekit",
61663
+ priority: "critical",
61664
+ status: "info",
61665
+ message: "No .cjs hooks found",
61666
+ autoFixable: false
61667
+ };
61668
+ }
61669
+ const errors2 = [];
61670
+ for (const file of cjsFiles) {
61671
+ const filePath = join41(hooksDir, file);
61672
+ if (!isPathWithin(filePath, hooksDir))
61673
+ continue;
61674
+ const result = spawnSync("node", ["--check", filePath], {
61675
+ timeout: HOOK_CHECK_TIMEOUT_MS,
61676
+ encoding: "utf-8"
61677
+ });
61678
+ if (result.status !== 0) {
61679
+ errors2.push(`${file}: ${result.stderr?.trim() || "syntax error"}`);
61680
+ }
61681
+ }
61682
+ if (errors2.length > 0) {
61683
+ return {
61684
+ id: "hook-syntax",
61685
+ name: "Hook Syntax",
61686
+ group: "claudekit",
61687
+ priority: "critical",
61688
+ status: "fail",
61689
+ message: `${errors2.length} hook(s) with syntax errors`,
61690
+ details: errors2.join(`
61691
+ `),
61692
+ suggestion: "Run: ck init",
61693
+ autoFixable: true,
61694
+ fix: {
61695
+ id: "fix-hook-syntax",
61696
+ description: "Reinstall hooks via ck init",
61697
+ execute: async () => ({
61698
+ success: false,
61699
+ message: "Manual fix required: run 'ck init'"
61700
+ })
61701
+ }
61702
+ };
61703
+ }
61704
+ return {
61705
+ id: "hook-syntax",
61706
+ name: "Hook Syntax",
61707
+ group: "claudekit",
61708
+ priority: "critical",
61709
+ status: "pass",
61710
+ message: `${cjsFiles.length} hook(s) valid`,
61711
+ autoFixable: false
61712
+ };
61713
+ } catch (error) {
61714
+ logger.debug(`Hook syntax check failed: ${error}`);
61715
+ return {
61716
+ id: "hook-syntax",
61717
+ name: "Hook Syntax",
61718
+ group: "claudekit",
61719
+ priority: "critical",
61720
+ status: "fail",
61721
+ message: "Failed to check hook syntax",
61722
+ details: error instanceof Error ? error.message : String(error),
61723
+ autoFixable: false
61724
+ };
61725
+ }
61726
+ }
61727
+ async function checkHookDeps(projectDir) {
61728
+ const hooksDir = getHooksDir(projectDir);
61729
+ if (!hooksDir) {
61730
+ return {
61731
+ id: "hook-deps",
61732
+ name: "Hook Dependencies",
61733
+ group: "claudekit",
61734
+ priority: "critical",
61735
+ status: "info",
61736
+ message: "No hooks directory",
61737
+ autoFixable: false
61738
+ };
61739
+ }
61740
+ try {
61741
+ const files = await readdir9(hooksDir);
61742
+ const cjsFiles = files.filter((f3) => f3.endsWith(".cjs"));
61743
+ if (cjsFiles.length === 0) {
61744
+ return {
61745
+ id: "hook-deps",
61746
+ name: "Hook Dependencies",
61747
+ group: "claudekit",
61748
+ priority: "critical",
61749
+ status: "info",
61750
+ message: "No .cjs hooks found",
61751
+ autoFixable: false
61752
+ };
61753
+ }
61754
+ const missingDeps = [];
61755
+ const requireRegex = /require\(['"]([^'"]+)['"]\)/g;
61756
+ for (const file of cjsFiles) {
61757
+ const filePath = join41(hooksDir, file);
61758
+ if (!isPathWithin(filePath, hooksDir))
61759
+ continue;
61760
+ const content = readFileSync6(filePath, "utf-8");
61761
+ for (let match = requireRegex.exec(content);match !== null; match = requireRegex.exec(content)) {
61762
+ const depPath = match[1];
61763
+ if (depPath.startsWith("node:") || isNodeBuiltin(depPath)) {
61764
+ continue;
61765
+ }
61766
+ if (depPath.startsWith(".")) {
61767
+ const resolvedPath = join41(hooksDir, depPath);
61768
+ const extensions = [".js", ".cjs", ".mjs", ".json"];
61769
+ const indexFiles = ["index.js", "index.cjs", "index.mjs"];
61770
+ const exists = existsSync30(resolvedPath) || extensions.some((ext) => existsSync30(resolvedPath + ext)) || indexFiles.some((idx) => existsSync30(join41(resolvedPath, idx)));
61771
+ if (!exists) {
61772
+ missingDeps.push(`${file}: ${depPath}`);
61773
+ }
61774
+ }
61775
+ }
61776
+ }
61777
+ if (missingDeps.length > 0) {
61778
+ return {
61779
+ id: "hook-deps",
61780
+ name: "Hook Dependencies",
61781
+ group: "claudekit",
61782
+ priority: "critical",
61783
+ status: "fail",
61784
+ message: `${missingDeps.length} missing dependency(ies)`,
61785
+ details: missingDeps.join(`
61786
+ `),
61787
+ suggestion: "Run: ck init",
61788
+ autoFixable: true,
61789
+ fix: {
61790
+ id: "fix-hook-deps",
61791
+ description: "Reinstall hooks via ck init",
61792
+ execute: async () => ({
61793
+ success: false,
61794
+ message: "Manual fix required: run 'ck init'"
61795
+ })
61796
+ }
61797
+ };
61798
+ }
61799
+ return {
61800
+ id: "hook-deps",
61801
+ name: "Hook Dependencies",
61802
+ group: "claudekit",
61803
+ priority: "critical",
61804
+ status: "pass",
61805
+ message: "All dependencies resolved",
61806
+ autoFixable: false
61807
+ };
61808
+ } catch (error) {
61809
+ logger.debug(`Hook deps check failed: ${error}`);
61810
+ return {
61811
+ id: "hook-deps",
61812
+ name: "Hook Dependencies",
61813
+ group: "claudekit",
61814
+ priority: "critical",
61815
+ status: "fail",
61816
+ message: "Failed to check dependencies",
61817
+ details: error instanceof Error ? error.message : String(error),
61818
+ autoFixable: false
61819
+ };
61820
+ }
61821
+ }
61822
+ function isNodeBuiltin(mod) {
61823
+ try {
61824
+ const { builtinModules } = __require("node:module");
61825
+ return builtinModules.includes(mod);
61826
+ } catch {
61827
+ const builtins = [
61828
+ "fs",
61829
+ "path",
61830
+ "os",
61831
+ "child_process",
61832
+ "util",
61833
+ "stream",
61834
+ "events",
61835
+ "crypto",
61836
+ "http",
61837
+ "https",
61838
+ "net",
61839
+ "dns",
61840
+ "url",
61841
+ "querystring",
61842
+ "readline",
61843
+ "process",
61844
+ "buffer",
61845
+ "console",
61846
+ "timers",
61847
+ "assert",
61848
+ "zlib",
61849
+ "worker_threads",
61850
+ "perf_hooks",
61851
+ "v8",
61852
+ "vm",
61853
+ "tls"
61854
+ ];
61855
+ return builtins.includes(mod);
61856
+ }
61857
+ }
61858
+ async function checkHookRuntime(projectDir) {
61859
+ const hooksDir = getHooksDir(projectDir);
61860
+ if (!hooksDir) {
61861
+ return {
61862
+ id: "hook-runtime",
61863
+ name: "Hook Runtime",
61864
+ group: "claudekit",
61865
+ priority: "standard",
61866
+ status: "info",
61867
+ message: "No hooks directory",
61868
+ autoFixable: false
61869
+ };
61870
+ }
61871
+ try {
61872
+ const files = await readdir9(hooksDir);
61873
+ const cjsFiles = files.filter((f3) => f3.endsWith(".cjs"));
61874
+ if (cjsFiles.length === 0) {
61875
+ return {
61876
+ id: "hook-runtime",
61877
+ name: "Hook Runtime",
61878
+ group: "claudekit",
61879
+ priority: "standard",
61880
+ status: "info",
61881
+ message: "No .cjs hooks found",
61882
+ autoFixable: false
61883
+ };
61884
+ }
61885
+ const syntheticPayload = JSON.stringify({
61886
+ tool_name: "Read",
61887
+ tool_input: { file_path: join41(tmpdir(), "ck-doctor-test.txt") }
61888
+ });
61889
+ const failures = [];
61890
+ for (const file of cjsFiles) {
61891
+ const filePath = join41(hooksDir, file);
61892
+ if (!isPathWithin(filePath, hooksDir))
61893
+ continue;
61894
+ const result = spawnSync("node", [filePath], {
61895
+ input: syntheticPayload,
61896
+ timeout: HOOK_CHECK_TIMEOUT_MS,
61897
+ encoding: "utf-8"
61898
+ });
61899
+ if (result.status !== null && result.status !== 0 && result.status !== 2) {
61900
+ const error = result.error?.message || result.stderr?.trim() || `exit code ${result.status}`;
61901
+ failures.push(`${file}: ${error}`);
61902
+ } else if (result.status === null && result.error) {
61903
+ const error = result.error.message || "failed to execute";
61904
+ failures.push(`${file}: ${error}`);
61905
+ }
61906
+ }
61907
+ if (failures.length > 0) {
61908
+ return {
61909
+ id: "hook-runtime",
61910
+ name: "Hook Runtime",
61911
+ group: "claudekit",
61912
+ priority: "standard",
61913
+ status: "fail",
61914
+ message: `${failures.length} hook(s) failed dry-run`,
61915
+ details: failures.join(`
61916
+ `),
61917
+ suggestion: "Run: ck init",
61918
+ autoFixable: true,
61919
+ fix: {
61920
+ id: "fix-hook-runtime",
61921
+ description: "Reinstall hooks via ck init",
61922
+ execute: async () => ({
61923
+ success: false,
61924
+ message: "Manual fix required: run 'ck init'"
61925
+ })
61926
+ }
61927
+ };
61928
+ }
61929
+ return {
61930
+ id: "hook-runtime",
61931
+ name: "Hook Runtime",
61932
+ group: "claudekit",
61933
+ priority: "standard",
61934
+ status: "pass",
61935
+ message: `${cjsFiles.length} hook(s) passed dry-run`,
61936
+ autoFixable: false
61937
+ };
61938
+ } catch (error) {
61939
+ logger.debug(`Hook runtime check failed: ${error}`);
61940
+ return {
61941
+ id: "hook-runtime",
61942
+ name: "Hook Runtime",
61943
+ group: "claudekit",
61944
+ priority: "standard",
61945
+ status: "fail",
61946
+ message: "Failed to check hook runtime",
61947
+ details: error instanceof Error ? error.message : String(error),
61948
+ autoFixable: false
61949
+ };
61950
+ }
61951
+ }
61952
+ async function checkHookConfig(projectDir) {
61953
+ const projectConfigPath = join41(projectDir, ".claude", ".ck.json");
61954
+ const globalConfigPath = join41(PathResolver.getGlobalKitDir(), ".ck.json");
61955
+ const configPath = existsSync30(projectConfigPath) ? projectConfigPath : existsSync30(globalConfigPath) ? globalConfigPath : null;
61956
+ if (!configPath) {
61957
+ return {
61958
+ id: "hook-config",
61959
+ name: "Hook Config",
61960
+ group: "claudekit",
61961
+ priority: "standard",
61962
+ status: "info",
61963
+ message: "No .ck.json config",
61964
+ autoFixable: false
61965
+ };
61966
+ }
61967
+ const hooksDir = getHooksDir(projectDir);
61968
+ if (!hooksDir) {
61969
+ return {
61970
+ id: "hook-config",
61971
+ name: "Hook Config",
61972
+ group: "claudekit",
61973
+ priority: "standard",
61974
+ status: "info",
61975
+ message: "No hooks directory",
61976
+ autoFixable: false
61977
+ };
61978
+ }
61979
+ try {
61980
+ const configContent = readFileSync6(configPath, "utf-8");
61981
+ const config = JSON.parse(configContent);
61982
+ if (!config.hooks || typeof config.hooks !== "object") {
61983
+ return {
61984
+ id: "hook-config",
61985
+ name: "Hook Config",
61986
+ group: "claudekit",
61987
+ priority: "standard",
61988
+ status: "pass",
61989
+ message: "No hooks configured",
61990
+ autoFixable: false
61991
+ };
61992
+ }
61993
+ const files = await readdir9(hooksDir);
61994
+ const hookBaseNames = new Set(files.filter((f3) => HOOK_EXTENSIONS.some((ext) => f3.endsWith(ext))).map((f3) => {
61995
+ for (const ext of HOOK_EXTENSIONS) {
61996
+ if (f3.endsWith(ext))
61997
+ return f3.slice(0, -ext.length);
61998
+ }
61999
+ return f3;
62000
+ }));
62001
+ const orphanedEntries = [];
62002
+ for (const hookName of Object.keys(config.hooks)) {
62003
+ if (!hookBaseNames.has(hookName)) {
62004
+ orphanedEntries.push(hookName);
62005
+ }
62006
+ }
62007
+ if (orphanedEntries.length > 0) {
62008
+ return {
62009
+ id: "hook-config",
62010
+ name: "Hook Config",
62011
+ group: "claudekit",
62012
+ priority: "standard",
62013
+ status: "warn",
62014
+ message: `${orphanedEntries.length} orphaned config entry(ies)`,
62015
+ details: orphanedEntries.join(", "),
62016
+ suggestion: "Remove orphaned entries from .ck.json",
62017
+ autoFixable: true,
62018
+ fix: {
62019
+ id: "fix-hook-config",
62020
+ description: "Remove orphaned entries from .ck.json",
62021
+ execute: async () => {
62022
+ try {
62023
+ for (const entry of orphanedEntries) {
62024
+ delete config.hooks[entry];
62025
+ }
62026
+ const updatedConfig = JSON.stringify(config, null, 2);
62027
+ writeFileSync(configPath, updatedConfig, "utf-8");
62028
+ return {
62029
+ success: true,
62030
+ message: `Removed ${orphanedEntries.length} orphaned entry(ies)`
62031
+ };
62032
+ } catch (err) {
62033
+ return {
62034
+ success: false,
62035
+ message: `Failed to update .ck.json: ${err}`
62036
+ };
62037
+ }
62038
+ }
62039
+ }
62040
+ };
62041
+ }
62042
+ return {
62043
+ id: "hook-config",
62044
+ name: "Hook Config",
62045
+ group: "claudekit",
62046
+ priority: "standard",
62047
+ status: "pass",
62048
+ message: "All config entries valid",
62049
+ autoFixable: false
62050
+ };
62051
+ } catch (error) {
62052
+ logger.debug(`Hook config check failed: ${error}`);
62053
+ return {
62054
+ id: "hook-config",
62055
+ name: "Hook Config",
62056
+ group: "claudekit",
62057
+ priority: "standard",
62058
+ status: "fail",
62059
+ message: "Failed to validate config",
62060
+ details: error instanceof Error ? error.message : String(error),
62061
+ autoFixable: false
62062
+ };
62063
+ }
62064
+ }
62065
+ async function checkHookLogs(projectDir) {
62066
+ const hooksDir = getHooksDir(projectDir);
62067
+ if (!hooksDir) {
62068
+ return {
62069
+ id: "hook-logs",
62070
+ name: "Hook Crash Logs",
62071
+ group: "claudekit",
62072
+ priority: "standard",
62073
+ status: "info",
62074
+ message: "No hooks directory",
62075
+ autoFixable: false
62076
+ };
62077
+ }
62078
+ const logPath = join41(hooksDir, ".logs", "hook-log.jsonl");
62079
+ if (!existsSync30(logPath)) {
62080
+ return {
62081
+ id: "hook-logs",
62082
+ name: "Hook Crash Logs",
62083
+ group: "claudekit",
62084
+ priority: "standard",
62085
+ status: "pass",
62086
+ message: "No crash logs",
62087
+ autoFixable: false
62088
+ };
62089
+ }
62090
+ try {
62091
+ const logStats = statSync5(logPath);
62092
+ if (logStats.size > MAX_LOG_FILE_SIZE_BYTES) {
62093
+ return {
62094
+ id: "hook-logs",
62095
+ name: "Hook Crash Logs",
62096
+ group: "claudekit",
62097
+ priority: "standard",
62098
+ status: "warn",
62099
+ message: `Log file too large (${Math.round(logStats.size / 1024 / 1024)}MB)`,
62100
+ suggestion: "Delete .claude/hooks/.logs/hook-log.jsonl and run: ck init",
62101
+ autoFixable: true,
62102
+ fix: {
62103
+ id: "fix-hook-logs",
62104
+ description: "Clear oversized log file",
62105
+ execute: async () => {
62106
+ try {
62107
+ writeFileSync(logPath, "", "utf-8");
62108
+ return { success: true, message: "Cleared oversized log file" };
62109
+ } catch (err) {
62110
+ return { success: false, message: `Failed to clear log: ${err}` };
62111
+ }
62112
+ }
62113
+ }
62114
+ };
62115
+ }
62116
+ const logContent = readFileSync6(logPath, "utf-8");
62117
+ const lines = logContent.trim().split(`
62118
+ `).filter(Boolean);
62119
+ const now = Date.now();
62120
+ const oneDayAgo = now - 24 * 60 * 60 * 1000;
62121
+ const crashes = [];
62122
+ for (const line of lines) {
62123
+ try {
62124
+ const entry = JSON.parse(line);
62125
+ const timestamp = new Date(entry.ts || entry.timestamp).getTime();
62126
+ if (timestamp >= oneDayAgo && entry.status === "crash") {
62127
+ crashes.push({
62128
+ hook: entry.hook || "unknown",
62129
+ error: entry.error || "unknown error"
62130
+ });
62131
+ }
62132
+ } catch {}
62133
+ }
62134
+ if (crashes.length === 0) {
62135
+ return {
62136
+ id: "hook-logs",
62137
+ name: "Hook Crash Logs",
62138
+ group: "claudekit",
62139
+ priority: "standard",
62140
+ status: "pass",
62141
+ message: "No crashes in last 24h",
62142
+ autoFixable: false
62143
+ };
62144
+ }
62145
+ if (crashes.length <= 5) {
62146
+ const hookList = crashes.map((c2) => `${c2.hook}: ${c2.error}`).join(`
62147
+ `);
62148
+ return {
62149
+ id: "hook-logs",
62150
+ name: "Hook Crash Logs",
62151
+ group: "claudekit",
62152
+ priority: "standard",
62153
+ status: "warn",
62154
+ message: `${crashes.length} crash(es) in last 24h`,
62155
+ details: hookList,
62156
+ suggestion: "Run: ck init",
62157
+ autoFixable: true,
62158
+ fix: {
62159
+ id: "fix-hook-logs",
62160
+ description: "Clear log file",
62161
+ execute: async () => {
62162
+ try {
62163
+ writeFileSync(logPath, "", "utf-8");
62164
+ return {
62165
+ success: true,
62166
+ message: "Cleared crash log file"
62167
+ };
62168
+ } catch (err) {
62169
+ return {
62170
+ success: false,
62171
+ message: `Failed to clear log: ${err}`
62172
+ };
62173
+ }
62174
+ }
62175
+ }
62176
+ };
62177
+ }
62178
+ const hookCounts = crashes.reduce((acc, c2) => {
62179
+ acc[c2.hook] = (acc[c2.hook] || 0) + 1;
62180
+ return acc;
62181
+ }, {});
62182
+ const topCrashers = Object.entries(hookCounts).sort((a3, b3) => b3[1] - a3[1]).slice(0, 5).map(([hook, count]) => `${hook} (${count}x)`).join(", ");
62183
+ return {
62184
+ id: "hook-logs",
62185
+ name: "Hook Crash Logs",
62186
+ group: "claudekit",
62187
+ priority: "standard",
62188
+ status: "fail",
62189
+ message: `${crashes.length} crashes in last 24h`,
62190
+ details: `Most frequent: ${topCrashers}`,
62191
+ suggestion: "Run: ck init",
62192
+ autoFixable: true,
62193
+ fix: {
62194
+ id: "fix-hook-logs",
62195
+ description: "Clear log file and suggest reinstall",
62196
+ execute: async () => {
62197
+ try {
62198
+ writeFileSync(logPath, "", "utf-8");
62199
+ return {
62200
+ success: true,
62201
+ message: "Cleared crash log. Run 'ck init' to reinstall hooks."
62202
+ };
62203
+ } catch (err) {
62204
+ return {
62205
+ success: false,
62206
+ message: `Failed to clear log: ${err}`
62207
+ };
62208
+ }
62209
+ }
62210
+ }
62211
+ };
62212
+ } catch (error) {
62213
+ logger.debug(`Hook logs check failed: ${error}`);
62214
+ return {
62215
+ id: "hook-logs",
62216
+ name: "Hook Crash Logs",
62217
+ group: "claudekit",
62218
+ priority: "standard",
62219
+ status: "fail",
62220
+ message: "Failed to check crash logs",
62221
+ details: error instanceof Error ? error.message : String(error),
62222
+ autoFixable: false
62223
+ };
62224
+ }
62225
+ }
62226
+ async function checkCliVersion() {
62227
+ try {
62228
+ const versionResult = spawnSync("ck", ["-V"], {
62229
+ timeout: HOOK_CHECK_TIMEOUT_MS,
62230
+ encoding: "utf-8"
62231
+ });
62232
+ let installedVersion = "unknown";
62233
+ if (versionResult.status === 0 && versionResult.stdout) {
62234
+ installedVersion = versionResult.stdout.trim();
62235
+ }
62236
+ if (installedVersion === "unknown") {
62237
+ return {
62238
+ id: "cli-version",
62239
+ name: "CLI Version",
62240
+ group: "claudekit",
62241
+ priority: "critical",
62242
+ status: "warn",
62243
+ message: "Cannot determine installed version",
62244
+ autoFixable: false
62245
+ };
62246
+ }
62247
+ const npmResult = spawnSync("npm", ["view", "claudekit-cli", "version"], {
62248
+ timeout: HOOK_CHECK_TIMEOUT_MS,
62249
+ encoding: "utf-8"
62250
+ });
62251
+ if (npmResult.status !== 0) {
62252
+ return {
62253
+ id: "cli-version",
62254
+ name: "CLI Version",
62255
+ group: "claudekit",
62256
+ priority: "critical",
62257
+ status: "warn",
62258
+ message: `v${installedVersion} (unable to check for updates)`,
62259
+ autoFixable: false
62260
+ };
62261
+ }
62262
+ const latestVersion = npmResult.stdout?.trim() || installedVersion;
62263
+ const parseVersion = (v2) => v2.replace(/-.*$/, "").split(".").map(Number);
62264
+ const [installedMajor, installedMinor] = parseVersion(installedVersion);
62265
+ const [latestMajor, latestMinor] = parseVersion(latestVersion);
62266
+ if (installedMajor < latestMajor) {
62267
+ return {
62268
+ id: "cli-version",
62269
+ name: "CLI Version",
62270
+ group: "claudekit",
62271
+ priority: "critical",
62272
+ status: "fail",
62273
+ message: `v${installedVersion} (latest: v${latestVersion})`,
62274
+ details: "Major version behind",
62275
+ suggestion: "Run: ck update",
62276
+ autoFixable: true,
62277
+ fix: {
62278
+ id: "fix-cli-version",
62279
+ description: "Update CLI to latest version",
62280
+ execute: async () => ({
62281
+ success: false,
62282
+ message: "Manual fix required: run 'ck update'"
62283
+ })
62284
+ }
62285
+ };
62286
+ }
62287
+ if (installedMajor === latestMajor && installedMinor < latestMinor) {
62288
+ return {
62289
+ id: "cli-version",
62290
+ name: "CLI Version",
62291
+ group: "claudekit",
62292
+ priority: "critical",
62293
+ status: "warn",
62294
+ message: `v${installedVersion} (latest: v${latestVersion})`,
62295
+ details: "Minor version behind",
62296
+ suggestion: "Run: ck update",
62297
+ autoFixable: true,
62298
+ fix: {
62299
+ id: "fix-cli-version",
62300
+ description: "Update CLI to latest version",
62301
+ execute: async () => ({
62302
+ success: false,
62303
+ message: "Manual fix required: run 'ck update'"
62304
+ })
62305
+ }
62306
+ };
62307
+ }
62308
+ return {
62309
+ id: "cli-version",
62310
+ name: "CLI Version",
62311
+ group: "claudekit",
62312
+ priority: "critical",
62313
+ status: "pass",
62314
+ message: `v${installedVersion} (up to date)`,
62315
+ autoFixable: false
62316
+ };
62317
+ } catch (error) {
62318
+ logger.debug(`CLI version check failed: ${error}`);
62319
+ return {
62320
+ id: "cli-version",
62321
+ name: "CLI Version",
62322
+ group: "claudekit",
62323
+ priority: "critical",
62324
+ status: "warn",
62325
+ message: "Failed to check version",
62326
+ details: error instanceof Error ? error.message : String(error),
62327
+ autoFixable: false
62328
+ };
62329
+ }
62330
+ }
62331
+ async function checkPythonVenv(projectDir) {
62332
+ const isWindows3 = process.platform === "win32";
62333
+ const venvBin = isWindows3 ? join41("Scripts", "python.exe") : join41("bin", "python3");
62334
+ const projectVenvPath = join41(projectDir, ".claude", "skills", ".venv", venvBin);
62335
+ const globalVenvPath = join41(PathResolver.getGlobalKitDir(), "skills", ".venv", venvBin);
62336
+ const venvPath = existsSync30(projectVenvPath) ? projectVenvPath : existsSync30(globalVenvPath) ? globalVenvPath : null;
62337
+ if (!venvPath) {
62338
+ return {
62339
+ id: "python-venv",
62340
+ name: "Python Venv",
62341
+ group: "claudekit",
62342
+ priority: "standard",
62343
+ status: "warn",
62344
+ message: "Virtual environment not found",
62345
+ suggestion: "Delete .venv and run install.sh",
62346
+ autoFixable: true,
62347
+ fix: {
62348
+ id: "fix-python-venv",
62349
+ description: "Delete .venv and suggest reinstall",
62350
+ execute: async () => ({
62351
+ success: false,
62352
+ message: "Manual fix required: delete .venv and run install.sh"
62353
+ })
62354
+ }
62355
+ };
62356
+ }
62357
+ try {
62358
+ const result = spawnSync(venvPath, ["--version"], {
62359
+ timeout: PYTHON_CHECK_TIMEOUT_MS,
62360
+ encoding: "utf-8"
62361
+ });
62362
+ if (result.status !== 0) {
62363
+ return {
62364
+ id: "python-venv",
62365
+ name: "Python Venv",
62366
+ group: "claudekit",
62367
+ priority: "standard",
62368
+ status: "fail",
62369
+ message: "Python venv exists but broken",
62370
+ details: result.stderr?.trim() || "Failed to run python3 --version",
62371
+ suggestion: "Delete .venv and run install.sh",
62372
+ autoFixable: true,
62373
+ fix: {
62374
+ id: "fix-python-venv",
62375
+ description: "Delete .venv",
62376
+ execute: async () => ({
62377
+ success: false,
62378
+ message: "Manual fix required: delete .venv and run install.sh"
62379
+ })
62380
+ }
62381
+ };
62382
+ }
62383
+ const version = result.stdout?.trim() || "unknown";
62384
+ return {
62385
+ id: "python-venv",
62386
+ name: "Python Venv",
62387
+ group: "claudekit",
62388
+ priority: "standard",
62389
+ status: "pass",
62390
+ message: version,
62391
+ autoFixable: false
62392
+ };
62393
+ } catch (error) {
62394
+ logger.debug(`Python venv check failed: ${error}`);
62395
+ return {
62396
+ id: "python-venv",
62397
+ name: "Python Venv",
62398
+ group: "claudekit",
62399
+ priority: "standard",
62400
+ status: "fail",
62401
+ message: "Failed to check venv",
62402
+ details: error instanceof Error ? error.message : String(error),
62403
+ autoFixable: false
62404
+ };
62405
+ }
62406
+ }
61619
62407
  // src/domains/health-checks/claudekit-checker.ts
61620
62408
  class ClaudekitChecker {
61621
62409
  group = "claudekit";
@@ -61630,6 +62418,8 @@ class ClaudekitChecker {
61630
62418
  const setup = await getClaudeKitSetup(this.projectDir);
61631
62419
  logger.verbose("ClaudekitChecker: Setup scan complete");
61632
62420
  const results = [];
62421
+ logger.verbose("ClaudekitChecker: Checking CLI version");
62422
+ results.push(await checkCliVersion());
61633
62423
  logger.verbose("ClaudekitChecker: Checking CLI install method");
61634
62424
  results.push(await checkCliInstallMethod());
61635
62425
  logger.verbose("ClaudekitChecker: Checking global install");
@@ -61652,6 +62442,18 @@ class ClaudekitChecker {
61652
62442
  results.push(await checkGlobalDirWritable());
61653
62443
  logger.verbose("ClaudekitChecker: Checking hooks directory");
61654
62444
  results.push(await checkHooksExist(this.projectDir));
62445
+ logger.verbose("ClaudekitChecker: Checking hook syntax");
62446
+ results.push(await checkHookSyntax(this.projectDir));
62447
+ logger.verbose("ClaudekitChecker: Checking hook dependencies");
62448
+ results.push(await checkHookDeps(this.projectDir));
62449
+ logger.verbose("ClaudekitChecker: Checking hook runtime");
62450
+ results.push(await checkHookRuntime(this.projectDir));
62451
+ logger.verbose("ClaudekitChecker: Checking hook config");
62452
+ results.push(await checkHookConfig(this.projectDir));
62453
+ logger.verbose("ClaudekitChecker: Checking hook crash logs");
62454
+ results.push(await checkHookLogs(this.projectDir));
62455
+ logger.verbose("ClaudekitChecker: Checking Python venv");
62456
+ results.push(await checkPythonVenv(this.projectDir));
61655
62457
  logger.verbose("ClaudekitChecker: Checking settings.json validity");
61656
62458
  results.push(await checkSettingsValid(this.projectDir));
61657
62459
  logger.verbose("ClaudekitChecker: Checking path references");
@@ -61664,7 +62466,7 @@ class ClaudekitChecker {
61664
62466
  }
61665
62467
  // src/domains/health-checks/auth-checker.ts
61666
62468
  init_github_auth();
61667
- import { spawnSync as spawnSync2 } from "node:child_process";
62469
+ import { spawnSync as spawnSync3 } from "node:child_process";
61668
62470
 
61669
62471
  // src/domains/installation/git-clone-manager.ts
61670
62472
  init_logger();
@@ -61931,7 +62733,7 @@ class AuthChecker {
61931
62733
  if (false) {}
61932
62734
  try {
61933
62735
  logger.verbose("AuthChecker: Running 'gh auth status -h github.com' command");
61934
- const result = spawnSync2("gh", ["auth", "status", "-h", "github.com"], {
62736
+ const result = spawnSync3("gh", ["auth", "status", "-h", "github.com"], {
61935
62737
  encoding: "utf8",
61936
62738
  timeout: COMMAND_TIMEOUT_MS2
61937
62739
  });
@@ -62010,7 +62812,7 @@ import { platform as platform6 } from "node:os";
62010
62812
  init_path_resolver();
62011
62813
  import { constants as constants3, access as access3, mkdir as mkdir9, readFile as readFile23, unlink as unlink5, writeFile as writeFile12 } from "node:fs/promises";
62012
62814
  import { arch as arch2, homedir as homedir16, platform as platform5 } from "node:os";
62013
- import { join as join42, normalize as normalize6 } from "node:path";
62815
+ import { join as join43, normalize as normalize6 } from "node:path";
62014
62816
  var IS_WINDOWS = platform5() === "win32";
62015
62817
  function shouldSkipExpensiveOperations4() {
62016
62818
  if (process.env.CK_TEST_HOME) {
@@ -62104,7 +62906,7 @@ async function checkGlobalDirAccess() {
62104
62906
  autoFixable: false
62105
62907
  };
62106
62908
  }
62107
- const testFile = join42(globalDir, ".ck-doctor-access-test");
62909
+ const testFile = join43(globalDir, ".ck-doctor-access-test");
62108
62910
  try {
62109
62911
  await mkdir9(globalDir, { recursive: true });
62110
62912
  await writeFile12(testFile, "test", "utf-8");
@@ -62182,7 +62984,7 @@ async function checkWSLBoundary() {
62182
62984
  // src/domains/health-checks/platform/windows-checker.ts
62183
62985
  init_path_resolver();
62184
62986
  import { mkdir as mkdir10, symlink, unlink as unlink6, writeFile as writeFile13 } from "node:fs/promises";
62185
- import { join as join43 } from "node:path";
62987
+ import { join as join44 } from "node:path";
62186
62988
  async function checkLongPathSupport() {
62187
62989
  if (shouldSkipExpensiveOperations4()) {
62188
62990
  return {
@@ -62234,8 +63036,8 @@ async function checkSymlinkSupport() {
62234
63036
  };
62235
63037
  }
62236
63038
  const testDir = PathResolver.getGlobalKitDir();
62237
- const target = join43(testDir, ".ck-symlink-test-target");
62238
- const link = join43(testDir, ".ck-symlink-test-link");
63039
+ const target = join44(testDir, ".ck-symlink-test-target");
63040
+ const link = join44(testDir, ".ck-symlink-test-link");
62239
63041
  try {
62240
63042
  await mkdir10(testDir, { recursive: true });
62241
63043
  await writeFile13(target, "test", "utf-8");
@@ -62518,10 +63320,10 @@ class AutoHealer {
62518
63320
  }
62519
63321
  }
62520
63322
  // src/domains/health-checks/report-generator.ts
62521
- import { execSync as execSync3, spawnSync as spawnSync3 } from "node:child_process";
62522
- import { readFileSync as readFileSync6, unlinkSync, writeFileSync } from "node:fs";
62523
- import { tmpdir as tmpdir2 } from "node:os";
62524
- import { dirname as dirname10, join as join44 } from "node:path";
63323
+ import { execSync as execSync3, spawnSync as spawnSync4 } from "node:child_process";
63324
+ import { readFileSync as readFileSync7, unlinkSync, writeFileSync as writeFileSync2 } from "node:fs";
63325
+ import { tmpdir as tmpdir3 } from "node:os";
63326
+ import { dirname as dirname10, join as join45 } from "node:path";
62525
63327
  import { fileURLToPath as fileURLToPath3 } from "node:url";
62526
63328
  init_environment();
62527
63329
  init_logger();
@@ -62529,8 +63331,8 @@ init_dist2();
62529
63331
  function getCliVersion2() {
62530
63332
  try {
62531
63333
  const __dirname4 = dirname10(fileURLToPath3(import.meta.url));
62532
- const pkgPath = join44(__dirname4, "../../../package.json");
62533
- const pkg = JSON.parse(readFileSync6(pkgPath, "utf-8"));
63334
+ const pkgPath = join45(__dirname4, "../../../package.json");
63335
+ const pkg = JSON.parse(readFileSync7(pkgPath, "utf-8"));
62534
63336
  return pkg.version || "unknown";
62535
63337
  } catch (err) {
62536
63338
  logger.debug(`Failed to read CLI version: ${err}`);
@@ -62668,10 +63470,10 @@ class ReportGenerator {
62668
63470
  return null;
62669
63471
  }
62670
63472
  }
62671
- const tmpFile = join44(tmpdir2(), `ck-report-${Date.now()}.txt`);
62672
- writeFileSync(tmpFile, report);
63473
+ const tmpFile = join45(tmpdir3(), `ck-report-${Date.now()}.txt`);
63474
+ writeFileSync2(tmpFile, report);
62673
63475
  try {
62674
- const result = spawnSync3("gh", ["gist", "create", tmpFile, "--desc", "ClaudeKit Diagnostic Report"], {
63476
+ const result = spawnSync4("gh", ["gist", "create", tmpFile, "--desc", "ClaudeKit Diagnostic Report"], {
62675
63477
  encoding: "utf-8"
62676
63478
  });
62677
63479
  if (result.status !== 0) {
@@ -62993,7 +63795,7 @@ init_logger();
62993
63795
  init_path_resolver();
62994
63796
  var import_compare_versions5 = __toESM(require_umd(), 1);
62995
63797
  import { mkdir as mkdir11, readFile as readFile24, unlink as unlink7, writeFile as writeFile14 } from "node:fs/promises";
62996
- import { join as join45 } from "node:path";
63798
+ import { join as join46 } from "node:path";
62997
63799
  var CACHE_TTL_HOURS = 24;
62998
63800
  var DEFAULT_CACHE_TTL_MS = CACHE_TTL_HOURS * 60 * 60 * 1000;
62999
63801
  var MIN_CACHE_TTL_MS = 60 * 1000;
@@ -63030,7 +63832,7 @@ var KIT_REPOS = {
63030
63832
  class ConfigVersionChecker {
63031
63833
  static getCacheFilePath(kitType, global3) {
63032
63834
  const cacheDir = PathResolver.getCacheDir(global3);
63033
- return join45(cacheDir, `${kitType}-${CACHE_FILENAME}`);
63835
+ return join46(cacheDir, `${kitType}-${CACHE_FILENAME}`);
63034
63836
  }
63035
63837
  static async loadCache(kitType, global3) {
63036
63838
  try {
@@ -63117,7 +63919,7 @@ class ConfigVersionChecker {
63117
63919
  return null;
63118
63920
  }
63119
63921
  const delay = baseBackoff * 2 ** attempt;
63120
- await new Promise((resolve8) => setTimeout(resolve8, delay));
63922
+ await new Promise((resolve9) => setTimeout(resolve9, delay));
63121
63923
  }
63122
63924
  }
63123
63925
  return null;
@@ -63193,7 +63995,7 @@ class ConfigVersionChecker {
63193
63995
  }
63194
63996
  // src/domains/sync/sync-engine.ts
63195
63997
  import { lstat as lstat3, readFile as readFile25, readlink, realpath as realpath2, stat as stat9 } from "node:fs/promises";
63196
- import { isAbsolute as isAbsolute2, join as join46, normalize as normalize7, relative as relative4 } from "node:path";
63998
+ import { isAbsolute as isAbsolute2, join as join47, normalize as normalize7, relative as relative4 } from "node:path";
63197
63999
 
63198
64000
  // src/services/file-operations/ownership-checker.ts
63199
64001
  init_metadata_migration();
@@ -63284,24 +64086,24 @@ function pLimit(concurrency) {
63284
64086
  activeCount--;
63285
64087
  resumeNext();
63286
64088
  };
63287
- const run = async (function_, resolve8, arguments_) => {
64089
+ const run = async (function_, resolve9, arguments_) => {
63288
64090
  const result = (async () => function_(...arguments_))();
63289
- resolve8(result);
64091
+ resolve9(result);
63290
64092
  try {
63291
64093
  await result;
63292
64094
  } catch {}
63293
64095
  next();
63294
64096
  };
63295
- const enqueue = (function_, resolve8, arguments_) => {
64097
+ const enqueue = (function_, resolve9, arguments_) => {
63296
64098
  new Promise((internalResolve) => {
63297
64099
  queue.enqueue(internalResolve);
63298
- }).then(run.bind(undefined, function_, resolve8, arguments_));
64100
+ }).then(run.bind(undefined, function_, resolve9, arguments_));
63299
64101
  if (activeCount < concurrency) {
63300
64102
  resumeNext();
63301
64103
  }
63302
64104
  };
63303
- const generator = (function_, ...arguments_) => new Promise((resolve8) => {
63304
- enqueue(function_, resolve8, arguments_);
64105
+ const generator = (function_, ...arguments_) => new Promise((resolve9) => {
64106
+ enqueue(function_, resolve9, arguments_);
63305
64107
  });
63306
64108
  Object.defineProperties(generator, {
63307
64109
  activeCount: {
@@ -63352,12 +64154,12 @@ async function mapWithLimit(items, fn, concurrency = DEFAULT_CONCURRENCY) {
63352
64154
  // src/services/file-operations/ownership-checker.ts
63353
64155
  class OwnershipChecker {
63354
64156
  static async calculateChecksum(filePath) {
63355
- return new Promise((resolve8, reject) => {
64157
+ return new Promise((resolve9, reject) => {
63356
64158
  const hash = createHash("sha256");
63357
64159
  const stream = createReadStream2(filePath);
63358
64160
  stream.on("data", (chunk) => hash.update(chunk));
63359
64161
  stream.on("end", () => {
63360
- resolve8(hash.digest("hex"));
64162
+ resolve9(hash.digest("hex"));
63361
64163
  });
63362
64164
  stream.on("error", (err) => {
63363
64165
  stream.destroy();
@@ -64481,7 +65283,7 @@ async function validateSymlinkChain(path3, basePath, maxDepth = MAX_SYMLINK_DEPT
64481
65283
  if (!stats.isSymbolicLink())
64482
65284
  break;
64483
65285
  const target = await readlink(current);
64484
- const resolvedTarget = isAbsolute2(target) ? target : join46(current, "..", target);
65286
+ const resolvedTarget = isAbsolute2(target) ? target : join47(current, "..", target);
64485
65287
  const normalizedTarget = normalize7(resolvedTarget);
64486
65288
  const rel = relative4(basePath, normalizedTarget);
64487
65289
  if (rel.startsWith("..") || isAbsolute2(rel)) {
@@ -64517,7 +65319,7 @@ async function validateSyncPath(basePath, filePath) {
64517
65319
  if (normalized.startsWith("..") || normalized.includes("/../")) {
64518
65320
  throw new Error(`Path traversal not allowed: ${filePath}`);
64519
65321
  }
64520
- const fullPath = join46(basePath, normalized);
65322
+ const fullPath = join47(basePath, normalized);
64521
65323
  const rel = relative4(basePath, fullPath);
64522
65324
  if (rel.startsWith("..") || isAbsolute2(rel)) {
64523
65325
  throw new Error(`Path escapes base directory: ${filePath}`);
@@ -64532,7 +65334,7 @@ async function validateSyncPath(basePath, filePath) {
64532
65334
  }
64533
65335
  } catch (error) {
64534
65336
  if (error.code === "ENOENT") {
64535
- const parentPath = join46(fullPath, "..");
65337
+ const parentPath = join47(fullPath, "..");
64536
65338
  try {
64537
65339
  const resolvedBase = await realpath2(basePath);
64538
65340
  const resolvedParent = await realpath2(parentPath);
@@ -65714,7 +66516,7 @@ init_logger();
65714
66516
  var import_proper_lockfile = __toESM(require_proper_lockfile(), 1);
65715
66517
  import { mkdir as mkdir14 } from "node:fs/promises";
65716
66518
  import os5 from "node:os";
65717
- import { join as join53 } from "node:path";
66519
+ import { join as join54 } from "node:path";
65718
66520
  var LOCK_CONFIG = {
65719
66521
  stale: 60000,
65720
66522
  retries: 0
@@ -65722,12 +66524,12 @@ var LOCK_CONFIG = {
65722
66524
  var activeLocks = new Set;
65723
66525
  var cleanupRegistered = false;
65724
66526
  function getLocksDir() {
65725
- return join53(os5.homedir(), ".claudekit", "locks");
66527
+ return join54(os5.homedir(), ".claudekit", "locks");
65726
66528
  }
65727
66529
  function cleanupLocks() {
65728
66530
  for (const name of activeLocks) {
65729
66531
  try {
65730
- const lockPath = join53(getLocksDir(), `${name}.lock`);
66532
+ const lockPath = join54(getLocksDir(), `${name}.lock`);
65731
66533
  import_proper_lockfile.default.unlockSync(lockPath, { realpath: false });
65732
66534
  } catch {
65733
66535
  try {
@@ -65750,7 +66552,7 @@ async function ensureLocksDir() {
65750
66552
  async function withProcessLock(lockName, fn) {
65751
66553
  registerCleanupHandlers();
65752
66554
  await ensureLocksDir();
65753
- const lockPath = join53(getLocksDir(), `${lockName}.lock`);
66555
+ const lockPath = join54(getLocksDir(), `${lockName}.lock`);
65754
66556
  let release;
65755
66557
  try {
65756
66558
  release = await import_proper_lockfile.default.lock(lockPath, { ...LOCK_CONFIG, realpath: false });
@@ -65781,7 +66583,7 @@ init_logger();
65781
66583
  init_logger();
65782
66584
  init_path_resolver();
65783
66585
  var import_fs_extra7 = __toESM(require_lib3(), 1);
65784
- import { join as join54 } from "node:path";
66586
+ import { join as join55 } from "node:path";
65785
66587
  async function handleConflicts(ctx) {
65786
66588
  if (ctx.cancelled)
65787
66589
  return ctx;
@@ -65790,7 +66592,7 @@ async function handleConflicts(ctx) {
65790
66592
  if (PathResolver.isLocalSameAsGlobal()) {
65791
66593
  return ctx;
65792
66594
  }
65793
- const localSettingsPath = join54(process.cwd(), ".claude", "settings.json");
66595
+ const localSettingsPath = join55(process.cwd(), ".claude", "settings.json");
65794
66596
  if (!await import_fs_extra7.pathExists(localSettingsPath)) {
65795
66597
  return ctx;
65796
66598
  }
@@ -65805,7 +66607,7 @@ async function handleConflicts(ctx) {
65805
66607
  return { ...ctx, cancelled: true };
65806
66608
  }
65807
66609
  if (choice === "remove") {
65808
- const localClaudeDir = join54(process.cwd(), ".claude");
66610
+ const localClaudeDir = join55(process.cwd(), ".claude");
65809
66611
  try {
65810
66612
  await import_fs_extra7.remove(localClaudeDir);
65811
66613
  logger.success("Removed local .claude/ directory");
@@ -65901,8 +66703,8 @@ init_environment();
65901
66703
  init_logger();
65902
66704
  init_safe_spinner();
65903
66705
  import { mkdir as mkdir20, stat as stat12 } from "node:fs/promises";
65904
- import { tmpdir as tmpdir3 } from "node:os";
65905
- import { join as join61 } from "node:path";
66706
+ import { tmpdir as tmpdir4 } from "node:os";
66707
+ import { join as join62 } from "node:path";
65906
66708
 
65907
66709
  // src/shared/temp-cleanup.ts
65908
66710
  init_logger();
@@ -65921,7 +66723,7 @@ init_logger();
65921
66723
  init_output_manager();
65922
66724
  import { createWriteStream as createWriteStream2, rmSync } from "node:fs";
65923
66725
  import { mkdir as mkdir15 } from "node:fs/promises";
65924
- import { join as join55 } from "node:path";
66726
+ import { join as join56 } from "node:path";
65925
66727
 
65926
66728
  // src/shared/progress-bar.ts
65927
66729
  init_output_manager();
@@ -66086,10 +66888,10 @@ init_types2();
66086
66888
  // src/domains/installation/utils/path-security.ts
66087
66889
  init_types2();
66088
66890
  import { lstatSync as lstatSync2, realpathSync as realpathSync2 } from "node:fs";
66089
- import { relative as relative5, resolve as resolve10 } from "node:path";
66891
+ import { relative as relative5, resolve as resolve11 } from "node:path";
66090
66892
  var MAX_EXTRACTION_SIZE = 500 * 1024 * 1024;
66091
66893
  function isPathSafe(basePath, targetPath) {
66092
- const resolvedBase = resolve10(basePath);
66894
+ const resolvedBase = resolve11(basePath);
66093
66895
  try {
66094
66896
  const stat10 = lstatSync2(targetPath);
66095
66897
  if (stat10.isSymbolicLink()) {
@@ -66099,7 +66901,7 @@ function isPathSafe(basePath, targetPath) {
66099
66901
  }
66100
66902
  }
66101
66903
  } catch {}
66102
- const resolvedTarget = resolve10(targetPath);
66904
+ const resolvedTarget = resolve11(targetPath);
66103
66905
  const relativePath = relative5(resolvedBase, resolvedTarget);
66104
66906
  return !relativePath.startsWith("..") && !relativePath.startsWith("/") && resolvedTarget.startsWith(resolvedBase);
66105
66907
  }
@@ -66131,7 +66933,7 @@ var MAX_DOWNLOAD_SIZE = 500 * 1024 * 1024;
66131
66933
  class FileDownloader {
66132
66934
  async downloadAsset(asset, destDir) {
66133
66935
  try {
66134
- const destPath = join55(destDir, asset.name);
66936
+ const destPath = join56(destDir, asset.name);
66135
66937
  await mkdir15(destDir, { recursive: true });
66136
66938
  output.info(`Downloading ${asset.name} (${formatBytes(asset.size)})...`);
66137
66939
  logger.verbose("Download details", {
@@ -66187,7 +66989,7 @@ class FileDownloader {
66187
66989
  }
66188
66990
  if (downloadedSize !== totalSize) {
66189
66991
  fileStream.end();
66190
- await new Promise((resolve11) => fileStream.once("close", resolve11));
66992
+ await new Promise((resolve12) => fileStream.once("close", resolve12));
66191
66993
  try {
66192
66994
  rmSync(destPath, { force: true });
66193
66995
  } catch (cleanupError) {
@@ -66201,7 +67003,7 @@ class FileDownloader {
66201
67003
  return destPath;
66202
67004
  } catch (error) {
66203
67005
  fileStream.end();
66204
- await new Promise((resolve11) => fileStream.once("close", resolve11));
67006
+ await new Promise((resolve12) => fileStream.once("close", resolve12));
66205
67007
  try {
66206
67008
  rmSync(destPath, { force: true });
66207
67009
  } catch (cleanupError) {
@@ -66216,7 +67018,7 @@ class FileDownloader {
66216
67018
  }
66217
67019
  async downloadFile(params) {
66218
67020
  const { url, name, size, destDir, token } = params;
66219
- const destPath = join55(destDir, name);
67021
+ const destPath = join56(destDir, name);
66220
67022
  await mkdir15(destDir, { recursive: true });
66221
67023
  output.info(`Downloading ${name}${size ? ` (${formatBytes(size)})` : ""}...`);
66222
67024
  const headers = {};
@@ -66267,7 +67069,7 @@ class FileDownloader {
66267
67069
  const expectedSize = Number(response.headers.get("content-length"));
66268
67070
  if (expectedSize > 0 && downloadedSize !== expectedSize) {
66269
67071
  fileStream.end();
66270
- await new Promise((resolve11) => fileStream.once("close", resolve11));
67072
+ await new Promise((resolve12) => fileStream.once("close", resolve12));
66271
67073
  try {
66272
67074
  rmSync(destPath, { force: true });
66273
67075
  } catch (cleanupError) {
@@ -66285,7 +67087,7 @@ class FileDownloader {
66285
67087
  return destPath;
66286
67088
  } catch (error) {
66287
67089
  fileStream.end();
66288
- await new Promise((resolve11) => fileStream.once("close", resolve11));
67090
+ await new Promise((resolve12) => fileStream.once("close", resolve12));
66289
67091
  try {
66290
67092
  rmSync(destPath, { force: true });
66291
67093
  } catch (cleanupError) {
@@ -66301,11 +67103,11 @@ class FileDownloader {
66301
67103
  init_logger();
66302
67104
  init_types2();
66303
67105
  import { constants as constants4 } from "node:fs";
66304
- import { access as access4, readdir as readdir9 } from "node:fs/promises";
66305
- import { join as join56 } from "node:path";
67106
+ import { access as access4, readdir as readdir10 } from "node:fs/promises";
67107
+ import { join as join57 } from "node:path";
66306
67108
  async function validateExtraction(extractDir) {
66307
67109
  try {
66308
- const entries = await readdir9(extractDir, { encoding: "utf8" });
67110
+ const entries = await readdir10(extractDir, { encoding: "utf8" });
66309
67111
  logger.debug(`Extracted files: ${entries.join(", ")}`);
66310
67112
  if (entries.length === 0) {
66311
67113
  throw new ExtractionError("Extraction resulted in no files");
@@ -66314,7 +67116,7 @@ async function validateExtraction(extractDir) {
66314
67116
  const missingPaths = [];
66315
67117
  for (const path3 of criticalPaths) {
66316
67118
  try {
66317
- await access4(join56(extractDir, path3), constants4.F_OK);
67119
+ await access4(join57(extractDir, path3), constants4.F_OK);
66318
67120
  logger.debug(`Found: ${path3}`);
66319
67121
  } catch {
66320
67122
  logger.warning(`Expected path not found: ${path3}`);
@@ -66335,8 +67137,8 @@ async function validateExtraction(extractDir) {
66335
67137
 
66336
67138
  // src/domains/installation/extraction/tar-extractor.ts
66337
67139
  init_logger();
66338
- import { copyFile as copyFile3, mkdir as mkdir18, readdir as readdir11, rm as rm3, stat as stat10 } from "node:fs/promises";
66339
- import { join as join59 } from "node:path";
67140
+ import { copyFile as copyFile3, mkdir as mkdir18, readdir as readdir12, rm as rm3, stat as stat10 } from "node:fs/promises";
67141
+ import { join as join60 } from "node:path";
66340
67142
 
66341
67143
  // node_modules/@isaacs/fs-minipass/dist/esm/index.js
66342
67144
  import EE from "events";
@@ -66884,10 +67686,10 @@ class Minipass extends EventEmitter3 {
66884
67686
  return this[ENCODING] ? buf.join("") : Buffer.concat(buf, buf.dataLength);
66885
67687
  }
66886
67688
  async promise() {
66887
- return new Promise((resolve11, reject) => {
67689
+ return new Promise((resolve12, reject) => {
66888
67690
  this.on(DESTROYED, () => reject(new Error("stream destroyed")));
66889
67691
  this.on("error", (er) => reject(er));
66890
- this.on("end", () => resolve11());
67692
+ this.on("end", () => resolve12());
66891
67693
  });
66892
67694
  }
66893
67695
  [Symbol.asyncIterator]() {
@@ -66906,7 +67708,7 @@ class Minipass extends EventEmitter3 {
66906
67708
  return Promise.resolve({ done: false, value: res });
66907
67709
  if (this[EOF])
66908
67710
  return stop();
66909
- let resolve11;
67711
+ let resolve12;
66910
67712
  let reject;
66911
67713
  const onerr = (er) => {
66912
67714
  this.off("data", ondata);
@@ -66920,19 +67722,19 @@ class Minipass extends EventEmitter3 {
66920
67722
  this.off("end", onend);
66921
67723
  this.off(DESTROYED, ondestroy);
66922
67724
  this.pause();
66923
- resolve11({ value, done: !!this[EOF] });
67725
+ resolve12({ value, done: !!this[EOF] });
66924
67726
  };
66925
67727
  const onend = () => {
66926
67728
  this.off("error", onerr);
66927
67729
  this.off("data", ondata);
66928
67730
  this.off(DESTROYED, ondestroy);
66929
67731
  stop();
66930
- resolve11({ done: true, value: undefined });
67732
+ resolve12({ done: true, value: undefined });
66931
67733
  };
66932
67734
  const ondestroy = () => onerr(new Error("stream destroyed"));
66933
67735
  return new Promise((res2, rej) => {
66934
67736
  reject = rej;
66935
- resolve11 = res2;
67737
+ resolve12 = res2;
66936
67738
  this.once(DESTROYED, ondestroy);
66937
67739
  this.once("error", onerr);
66938
67740
  this.once("end", onend);
@@ -68038,10 +68840,10 @@ class Minipass2 extends EventEmitter4 {
68038
68840
  return this[ENCODING2] ? buf.join("") : Buffer.concat(buf, buf.dataLength);
68039
68841
  }
68040
68842
  async promise() {
68041
- return new Promise((resolve11, reject) => {
68843
+ return new Promise((resolve12, reject) => {
68042
68844
  this.on(DESTROYED2, () => reject(new Error("stream destroyed")));
68043
68845
  this.on("error", (er) => reject(er));
68044
- this.on("end", () => resolve11());
68846
+ this.on("end", () => resolve12());
68045
68847
  });
68046
68848
  }
68047
68849
  [Symbol.asyncIterator]() {
@@ -68060,7 +68862,7 @@ class Minipass2 extends EventEmitter4 {
68060
68862
  return Promise.resolve({ done: false, value: res });
68061
68863
  if (this[EOF2])
68062
68864
  return stop();
68063
- let resolve11;
68865
+ let resolve12;
68064
68866
  let reject;
68065
68867
  const onerr = (er) => {
68066
68868
  this.off("data", ondata);
@@ -68074,19 +68876,19 @@ class Minipass2 extends EventEmitter4 {
68074
68876
  this.off("end", onend);
68075
68877
  this.off(DESTROYED2, ondestroy);
68076
68878
  this.pause();
68077
- resolve11({ value, done: !!this[EOF2] });
68879
+ resolve12({ value, done: !!this[EOF2] });
68078
68880
  };
68079
68881
  const onend = () => {
68080
68882
  this.off("error", onerr);
68081
68883
  this.off("data", ondata);
68082
68884
  this.off(DESTROYED2, ondestroy);
68083
68885
  stop();
68084
- resolve11({ done: true, value: undefined });
68886
+ resolve12({ done: true, value: undefined });
68085
68887
  };
68086
68888
  const ondestroy = () => onerr(new Error("stream destroyed"));
68087
68889
  return new Promise((res2, rej) => {
68088
68890
  reject = rej;
68089
- resolve11 = res2;
68891
+ resolve12 = res2;
68090
68892
  this.once(DESTROYED2, ondestroy);
68091
68893
  this.once("error", onerr);
68092
68894
  this.once("end", onend);
@@ -69514,10 +70316,10 @@ class Minipass3 extends EventEmitter5 {
69514
70316
  return this[ENCODING3] ? buf.join("") : Buffer.concat(buf, buf.dataLength);
69515
70317
  }
69516
70318
  async promise() {
69517
- return new Promise((resolve11, reject) => {
70319
+ return new Promise((resolve12, reject) => {
69518
70320
  this.on(DESTROYED3, () => reject(new Error("stream destroyed")));
69519
70321
  this.on("error", (er) => reject(er));
69520
- this.on("end", () => resolve11());
70322
+ this.on("end", () => resolve12());
69521
70323
  });
69522
70324
  }
69523
70325
  [Symbol.asyncIterator]() {
@@ -69536,7 +70338,7 @@ class Minipass3 extends EventEmitter5 {
69536
70338
  return Promise.resolve({ done: false, value: res });
69537
70339
  if (this[EOF3])
69538
70340
  return stop();
69539
- let resolve11;
70341
+ let resolve12;
69540
70342
  let reject;
69541
70343
  const onerr = (er) => {
69542
70344
  this.off("data", ondata);
@@ -69550,19 +70352,19 @@ class Minipass3 extends EventEmitter5 {
69550
70352
  this.off("end", onend);
69551
70353
  this.off(DESTROYED3, ondestroy);
69552
70354
  this.pause();
69553
- resolve11({ value, done: !!this[EOF3] });
70355
+ resolve12({ value, done: !!this[EOF3] });
69554
70356
  };
69555
70357
  const onend = () => {
69556
70358
  this.off("error", onerr);
69557
70359
  this.off("data", ondata);
69558
70360
  this.off(DESTROYED3, ondestroy);
69559
70361
  stop();
69560
- resolve11({ done: true, value: undefined });
70362
+ resolve12({ done: true, value: undefined });
69561
70363
  };
69562
70364
  const ondestroy = () => onerr(new Error("stream destroyed"));
69563
70365
  return new Promise((res2, rej) => {
69564
70366
  reject = rej;
69565
- resolve11 = res2;
70367
+ resolve12 = res2;
69566
70368
  this.once(DESTROYED3, ondestroy);
69567
70369
  this.once("error", onerr);
69568
70370
  this.once("end", onend);
@@ -70333,9 +71135,9 @@ var listFile = (opt, _files) => {
70333
71135
  const parse4 = new Parser(opt);
70334
71136
  const readSize = opt.maxReadSize || 16 * 1024 * 1024;
70335
71137
  const file = opt.file;
70336
- const p = new Promise((resolve11, reject) => {
71138
+ const p = new Promise((resolve12, reject) => {
70337
71139
  parse4.on("error", reject);
70338
- parse4.on("end", resolve11);
71140
+ parse4.on("end", resolve12);
70339
71141
  fs9.stat(file, (er, stat10) => {
70340
71142
  if (er) {
70341
71143
  reject(er);
@@ -72098,7 +72900,7 @@ var mkdirSync = (dir, opt) => {
72098
72900
  };
72099
72901
 
72100
72902
  // node_modules/tar/dist/esm/path-reservations.js
72101
- import { join as join57 } from "node:path";
72903
+ import { join as join58 } from "node:path";
72102
72904
 
72103
72905
  // node_modules/tar/dist/esm/normalize-unicode.js
72104
72906
  var normalizeCache = Object.create(null);
@@ -72131,7 +72933,7 @@ var getDirs = (path8) => {
72131
72933
  const dirs = path8.split("/").slice(0, -1).reduce((set, path9) => {
72132
72934
  const s = set[set.length - 1];
72133
72935
  if (s !== undefined) {
72134
- path9 = join57(s, path9);
72936
+ path9 = join58(s, path9);
72135
72937
  }
72136
72938
  set.push(path9 || "/");
72137
72939
  return set;
@@ -72145,7 +72947,7 @@ class PathReservations {
72145
72947
  #running = new Set;
72146
72948
  reserve(paths, fn) {
72147
72949
  paths = isWindows4 ? ["win32 parallelization disabled"] : paths.map((p) => {
72148
- return stripTrailingSlashes(join57(normalizeUnicode(p))).toLowerCase();
72950
+ return stripTrailingSlashes(join58(normalizeUnicode(p))).toLowerCase();
72149
72951
  });
72150
72952
  const dirs = new Set(paths.map((path8) => getDirs(path8)).reduce((a3, b3) => a3.concat(b3)));
72151
72953
  this.#reservations.set(fn, { dirs, paths });
@@ -72915,9 +73717,9 @@ var extractFile = (opt, _3) => {
72915
73717
  const u = new Unpack(opt);
72916
73718
  const readSize = opt.maxReadSize || 16 * 1024 * 1024;
72917
73719
  const file = opt.file;
72918
- const p = new Promise((resolve11, reject) => {
73720
+ const p = new Promise((resolve12, reject) => {
72919
73721
  u.on("error", reject);
72920
- u.on("close", resolve11);
73722
+ u.on("close", resolve12);
72921
73723
  fs16.stat(file, (er, stat10) => {
72922
73724
  if (er) {
72923
73725
  reject(er);
@@ -73050,7 +73852,7 @@ var replaceAsync = (opt, files) => {
73050
73852
  };
73051
73853
  fs17.read(fd, headBuf, 0, 512, position, onread);
73052
73854
  };
73053
- const promise = new Promise((resolve11, reject) => {
73855
+ const promise = new Promise((resolve12, reject) => {
73054
73856
  p.on("error", reject);
73055
73857
  let flag = "r+";
73056
73858
  const onopen = (er, fd) => {
@@ -73075,7 +73877,7 @@ var replaceAsync = (opt, files) => {
73075
73877
  });
73076
73878
  p.pipe(stream);
73077
73879
  stream.on("error", reject);
73078
- stream.on("close", resolve11);
73880
+ stream.on("close", resolve12);
73079
73881
  addFilesAsync2(p, files);
73080
73882
  });
73081
73883
  });
@@ -73204,8 +74006,8 @@ function decodeFilePath(path10) {
73204
74006
  // src/domains/installation/utils/file-utils.ts
73205
74007
  init_logger();
73206
74008
  init_types2();
73207
- import { copyFile as copyFile2, lstat as lstat4, mkdir as mkdir17, readdir as readdir10 } from "node:fs/promises";
73208
- import { join as join58, relative as relative6 } from "node:path";
74009
+ import { copyFile as copyFile2, lstat as lstat4, mkdir as mkdir17, readdir as readdir11 } from "node:fs/promises";
74010
+ import { join as join59, relative as relative6 } from "node:path";
73209
74011
  async function withRetry(fn, retries = 3) {
73210
74012
  for (let i = 0;i < retries; i++) {
73211
74013
  try {
@@ -73225,10 +74027,10 @@ var isRetryable = (e2) => {
73225
74027
  var delay = (ms) => new Promise((r2) => setTimeout(r2, ms));
73226
74028
  async function moveDirectoryContents(sourceDir, destDir, shouldExclude, sizeTracker) {
73227
74029
  await mkdir17(destDir, { recursive: true });
73228
- const entries = await readdir10(sourceDir, { encoding: "utf8" });
74030
+ const entries = await readdir11(sourceDir, { encoding: "utf8" });
73229
74031
  for (const entry of entries) {
73230
- const sourcePath = join58(sourceDir, entry);
73231
- const destPath = join58(destDir, entry);
74032
+ const sourcePath = join59(sourceDir, entry);
74033
+ const destPath = join59(destDir, entry);
73232
74034
  const relativePath = relative6(sourceDir, sourcePath);
73233
74035
  if (!isPathSafe(destDir, destPath)) {
73234
74036
  logger.warning(`Skipping unsafe path: ${relativePath}`);
@@ -73253,10 +74055,10 @@ async function moveDirectoryContents(sourceDir, destDir, shouldExclude, sizeTrac
73253
74055
  }
73254
74056
  async function copyDirectory(sourceDir, destDir, shouldExclude, sizeTracker) {
73255
74057
  await mkdir17(destDir, { recursive: true });
73256
- const entries = await readdir10(sourceDir, { encoding: "utf8" });
74058
+ const entries = await readdir11(sourceDir, { encoding: "utf8" });
73257
74059
  for (const entry of entries) {
73258
- const sourcePath = join58(sourceDir, entry);
73259
- const destPath = join58(destDir, entry);
74060
+ const sourcePath = join59(sourceDir, entry);
74061
+ const destPath = join59(destDir, entry);
73260
74062
  const relativePath = relative6(sourceDir, sourcePath);
73261
74063
  if (!isPathSafe(destDir, destPath)) {
73262
74064
  logger.warning(`Skipping unsafe path: ${relativePath}`);
@@ -73300,14 +74102,14 @@ class TarExtractor {
73300
74102
  }
73301
74103
  });
73302
74104
  logger.debug(`Extracted TAR.GZ to temp: ${tempExtractDir}`);
73303
- const entries = await readdir11(tempExtractDir, { encoding: "utf8" });
74105
+ const entries = await readdir12(tempExtractDir, { encoding: "utf8" });
73304
74106
  logger.debug(`Root entries: ${entries.join(", ")}`);
73305
74107
  if (entries.length === 1) {
73306
74108
  const rootEntry = entries[0];
73307
- const rootPath = join59(tempExtractDir, rootEntry);
74109
+ const rootPath = join60(tempExtractDir, rootEntry);
73308
74110
  const rootStat = await stat10(rootPath);
73309
74111
  if (rootStat.isDirectory()) {
73310
- const rootContents = await readdir11(rootPath, { encoding: "utf8" });
74112
+ const rootContents = await readdir12(rootPath, { encoding: "utf8" });
73311
74113
  logger.debug(`Root directory '${rootEntry}' contains: ${rootContents.join(", ")}`);
73312
74114
  const isWrapper = isWrapperDirectory(rootEntry);
73313
74115
  logger.debug(`Is wrapper directory: ${isWrapper}`);
@@ -73320,7 +74122,7 @@ class TarExtractor {
73320
74122
  }
73321
74123
  } else {
73322
74124
  await mkdir18(destDir, { recursive: true });
73323
- await copyFile3(rootPath, join59(destDir, rootEntry));
74125
+ await copyFile3(rootPath, join60(destDir, rootEntry));
73324
74126
  }
73325
74127
  } else {
73326
74128
  logger.debug("Multiple root entries - moving all");
@@ -73342,27 +74144,27 @@ init_environment();
73342
74144
  init_logger();
73343
74145
  var import_extract_zip = __toESM(require_extract_zip(), 1);
73344
74146
  import { execFile as execFile8 } from "node:child_process";
73345
- import { copyFile as copyFile4, mkdir as mkdir19, readdir as readdir12, rm as rm4, stat as stat11 } from "node:fs/promises";
73346
- import { join as join60 } from "node:path";
74147
+ import { copyFile as copyFile4, mkdir as mkdir19, readdir as readdir13, rm as rm4, stat as stat11 } from "node:fs/promises";
74148
+ import { join as join61 } from "node:path";
73347
74149
  class ZipExtractor {
73348
74150
  async tryNativeUnzip(archivePath, destDir) {
73349
74151
  if (!isMacOS()) {
73350
74152
  return false;
73351
74153
  }
73352
- return new Promise((resolve11) => {
74154
+ return new Promise((resolve12) => {
73353
74155
  mkdir19(destDir, { recursive: true }).then(() => {
73354
74156
  execFile8("unzip", ["-o", "-q", archivePath, "-d", destDir], (error, _stdout, stderr) => {
73355
74157
  if (error) {
73356
74158
  logger.debug(`Native unzip failed: ${stderr || error.message}`);
73357
- resolve11(false);
74159
+ resolve12(false);
73358
74160
  return;
73359
74161
  }
73360
74162
  logger.debug("Native unzip succeeded");
73361
- resolve11(true);
74163
+ resolve12(true);
73362
74164
  });
73363
74165
  }).catch((err) => {
73364
74166
  logger.debug(`Failed to create directory for native unzip: ${err.message}`);
73365
- resolve11(false);
74167
+ resolve12(false);
73366
74168
  });
73367
74169
  });
73368
74170
  }
@@ -73387,14 +74189,14 @@ class ZipExtractor {
73387
74189
  logger.verbose(`Extracted ${extractedCount} files`);
73388
74190
  }
73389
74191
  logger.debug(`Extracted ZIP to temp: ${tempExtractDir}`);
73390
- const entries = await readdir12(tempExtractDir, { encoding: "utf8" });
74192
+ const entries = await readdir13(tempExtractDir, { encoding: "utf8" });
73391
74193
  logger.debug(`Root entries: ${entries.join(", ")}`);
73392
74194
  if (entries.length === 1) {
73393
74195
  const rootEntry = entries[0];
73394
- const rootPath = join60(tempExtractDir, rootEntry);
74196
+ const rootPath = join61(tempExtractDir, rootEntry);
73395
74197
  const rootStat = await stat11(rootPath);
73396
74198
  if (rootStat.isDirectory()) {
73397
- const rootContents = await readdir12(rootPath, { encoding: "utf8" });
74199
+ const rootContents = await readdir13(rootPath, { encoding: "utf8" });
73398
74200
  logger.debug(`Root directory '${rootEntry}' contains: ${rootContents.join(", ")}`);
73399
74201
  const isWrapper = isWrapperDirectory(rootEntry);
73400
74202
  logger.debug(`Is wrapper directory: ${isWrapper}`);
@@ -73407,7 +74209,7 @@ class ZipExtractor {
73407
74209
  }
73408
74210
  } else {
73409
74211
  await mkdir19(destDir, { recursive: true });
73410
- await copyFile4(rootPath, join60(destDir, rootEntry));
74212
+ await copyFile4(rootPath, join61(destDir, rootEntry));
73411
74213
  }
73412
74214
  } else {
73413
74215
  logger.debug("Multiple root entries - moving all");
@@ -73506,7 +74308,7 @@ class DownloadManager {
73506
74308
  async createTempDir() {
73507
74309
  const timestamp = Date.now();
73508
74310
  const counter = DownloadManager.tempDirCounter++;
73509
- const primaryTempDir = join61(tmpdir3(), `claudekit-${timestamp}-${counter}`);
74311
+ const primaryTempDir = join62(tmpdir4(), `claudekit-${timestamp}-${counter}`);
73510
74312
  try {
73511
74313
  await mkdir20(primaryTempDir, { recursive: true });
73512
74314
  logger.debug(`Created temp directory: ${primaryTempDir}`);
@@ -73523,7 +74325,7 @@ Solutions:
73523
74325
  2. Set HOME environment variable
73524
74326
  3. Try running from a different directory`);
73525
74327
  }
73526
- const fallbackTempDir = join61(homeDir, ".claudekit", "tmp", `claudekit-${timestamp}-${counter}`);
74328
+ const fallbackTempDir = join62(homeDir, ".claudekit", "tmp", `claudekit-${timestamp}-${counter}`);
73527
74329
  try {
73528
74330
  await mkdir20(fallbackTempDir, { recursive: true });
73529
74331
  logger.debug(`Created temp directory (fallback): ${fallbackTempDir}`);
@@ -73872,20 +74674,20 @@ async function handleDownload(ctx) {
73872
74674
  };
73873
74675
  }
73874
74676
  // src/commands/init/phases/merge-handler.ts
73875
- import { join as join77 } from "node:path";
74677
+ import { join as join78 } from "node:path";
73876
74678
 
73877
74679
  // src/domains/installation/deletion-handler.ts
73878
- import { existsSync as existsSync35, lstatSync as lstatSync3, readdirSync as readdirSync2, rmSync as rmSync2, rmdirSync, unlinkSync as unlinkSync3 } from "node:fs";
73879
- import { dirname as dirname14, join as join64, relative as relative7, resolve as resolve12, sep as sep2 } from "node:path";
74680
+ import { existsSync as existsSync36, lstatSync as lstatSync3, readdirSync as readdirSync2, rmSync as rmSync2, rmdirSync, unlinkSync as unlinkSync3 } from "node:fs";
74681
+ import { dirname as dirname14, join as join65, relative as relative7, resolve as resolve13, sep as sep2 } from "node:path";
73880
74682
 
73881
74683
  // src/services/file-operations/manifest/manifest-reader.ts
73882
74684
  init_metadata_migration();
73883
74685
  init_logger();
73884
74686
  init_types2();
73885
74687
  var import_fs_extra8 = __toESM(require_lib3(), 1);
73886
- import { join as join63 } from "node:path";
74688
+ import { join as join64 } from "node:path";
73887
74689
  async function readManifest(claudeDir2) {
73888
- const metadataPath = join63(claudeDir2, "metadata.json");
74690
+ const metadataPath = join64(claudeDir2, "metadata.json");
73889
74691
  if (!await import_fs_extra8.pathExists(metadataPath)) {
73890
74692
  return null;
73891
74693
  }
@@ -74058,12 +74860,12 @@ function shouldDeletePath(path11, metadata) {
74058
74860
  }
74059
74861
  function collectFilesRecursively(dir, baseDir) {
74060
74862
  const results = [];
74061
- if (!existsSync35(dir))
74863
+ if (!existsSync36(dir))
74062
74864
  return results;
74063
74865
  try {
74064
74866
  const entries = readdirSync2(dir, { withFileTypes: true });
74065
74867
  for (const entry of entries) {
74066
- const fullPath = join64(dir, entry.name);
74868
+ const fullPath = join65(dir, entry.name);
74067
74869
  const relativePath = relative7(baseDir, fullPath);
74068
74870
  if (entry.isDirectory()) {
74069
74871
  results.push(...collectFilesRecursively(fullPath, baseDir));
@@ -74093,8 +74895,8 @@ function expandGlobPatterns(patterns, claudeDir2) {
74093
74895
  }
74094
74896
  var MAX_CLEANUP_ITERATIONS = 50;
74095
74897
  function cleanupEmptyDirectories(filePath, claudeDir2) {
74096
- const normalizedClaudeDir = resolve12(claudeDir2);
74097
- let currentDir = resolve12(dirname14(filePath));
74898
+ const normalizedClaudeDir = resolve13(claudeDir2);
74899
+ let currentDir = resolve13(dirname14(filePath));
74098
74900
  let iterations = 0;
74099
74901
  while (currentDir !== normalizedClaudeDir && currentDir.startsWith(normalizedClaudeDir) && iterations < MAX_CLEANUP_ITERATIONS) {
74100
74902
  iterations++;
@@ -74103,7 +74905,7 @@ function cleanupEmptyDirectories(filePath, claudeDir2) {
74103
74905
  if (entries.length === 0) {
74104
74906
  rmdirSync(currentDir);
74105
74907
  logger.debug(`Removed empty directory: ${currentDir}`);
74106
- currentDir = resolve12(dirname14(currentDir));
74908
+ currentDir = resolve13(dirname14(currentDir));
74107
74909
  } else {
74108
74910
  break;
74109
74911
  }
@@ -74113,8 +74915,8 @@ function cleanupEmptyDirectories(filePath, claudeDir2) {
74113
74915
  }
74114
74916
  }
74115
74917
  function deletePath(fullPath, claudeDir2) {
74116
- const normalizedPath = resolve12(fullPath);
74117
- const normalizedClaudeDir = resolve12(claudeDir2);
74918
+ const normalizedPath = resolve13(fullPath);
74919
+ const normalizedClaudeDir = resolve13(claudeDir2);
74118
74920
  if (!normalizedPath.startsWith(`${normalizedClaudeDir}${sep2}`) && normalizedPath !== normalizedClaudeDir) {
74119
74921
  throw new Error(`Path traversal detected: ${fullPath}`);
74120
74922
  }
@@ -74131,7 +74933,7 @@ function deletePath(fullPath, claudeDir2) {
74131
74933
  }
74132
74934
  }
74133
74935
  async function updateMetadataAfterDeletion(claudeDir2, deletedPaths) {
74134
- const metadataPath = join64(claudeDir2, "metadata.json");
74936
+ const metadataPath = join65(claudeDir2, "metadata.json");
74135
74937
  if (!await import_fs_extra9.pathExists(metadataPath)) {
74136
74938
  return;
74137
74939
  }
@@ -74186,9 +74988,9 @@ async function handleDeletions(sourceMetadata, claudeDir2) {
74186
74988
  const userMetadata = await readManifest(claudeDir2);
74187
74989
  const result = { deletedPaths: [], preservedPaths: [], errors: [] };
74188
74990
  for (const path11 of deletions) {
74189
- const fullPath = join64(claudeDir2, path11);
74190
- const normalizedPath = resolve12(fullPath);
74191
- const normalizedClaudeDir = resolve12(claudeDir2);
74991
+ const fullPath = join65(claudeDir2, path11);
74992
+ const normalizedPath = resolve13(fullPath);
74993
+ const normalizedClaudeDir = resolve13(claudeDir2);
74192
74994
  if (!normalizedPath.startsWith(`${normalizedClaudeDir}${sep2}`)) {
74193
74995
  logger.warning(`Skipping invalid path: ${path11}`);
74194
74996
  result.errors.push(path11);
@@ -74199,7 +75001,7 @@ async function handleDeletions(sourceMetadata, claudeDir2) {
74199
75001
  logger.verbose(`Preserved user file: ${path11}`);
74200
75002
  continue;
74201
75003
  }
74202
- if (existsSync35(fullPath)) {
75004
+ if (existsSync36(fullPath)) {
74203
75005
  try {
74204
75006
  deletePath(fullPath, claudeDir2);
74205
75007
  result.deletedPaths.push(path11);
@@ -74226,7 +75028,7 @@ init_logger();
74226
75028
  init_types2();
74227
75029
  var import_fs_extra12 = __toESM(require_lib3(), 1);
74228
75030
  var import_ignore3 = __toESM(require_ignore(), 1);
74229
- import { dirname as dirname16, join as join67, relative as relative9 } from "node:path";
75031
+ import { dirname as dirname16, join as join68, relative as relative9 } from "node:path";
74230
75032
 
74231
75033
  // src/domains/installation/selective-merger.ts
74232
75034
  import { stat as stat13 } from "node:fs/promises";
@@ -74405,7 +75207,7 @@ init_logger();
74405
75207
  var import_fs_extra10 = __toESM(require_lib3(), 1);
74406
75208
  var import_ignore2 = __toESM(require_ignore(), 1);
74407
75209
  import { relative as relative8 } from "node:path";
74408
- import { join as join65 } from "node:path";
75210
+ import { join as join66 } from "node:path";
74409
75211
 
74410
75212
  // node_modules/@isaacs/balanced-match/dist/esm/index.js
74411
75213
  var balanced = (a3, b3, str2) => {
@@ -75861,7 +76663,7 @@ class FileScanner {
75861
76663
  const files = [];
75862
76664
  const entries = await import_fs_extra10.readdir(dir, { encoding: "utf8" });
75863
76665
  for (const entry of entries) {
75864
- const fullPath = join65(dir, entry);
76666
+ const fullPath = join66(dir, entry);
75865
76667
  const relativePath = relative8(baseDir, fullPath);
75866
76668
  const normalizedRelativePath = relativePath.replace(/\\/g, "/");
75867
76669
  const stats = await import_fs_extra10.lstat(fullPath);
@@ -75899,9 +76701,9 @@ import { execSync as execSync4 } from "node:child_process";
75899
76701
 
75900
76702
  // src/domains/config/installed-settings-tracker.ts
75901
76703
  init_shared();
75902
- import { existsSync as existsSync36 } from "node:fs";
76704
+ import { existsSync as existsSync37 } from "node:fs";
75903
76705
  import { mkdir as mkdir21, readFile as readFile29, writeFile as writeFile17 } from "node:fs/promises";
75904
- import { dirname as dirname15, join as join66 } from "node:path";
76706
+ import { dirname as dirname15, join as join67 } from "node:path";
75905
76707
  var CK_JSON_FILE = ".ck.json";
75906
76708
 
75907
76709
  class InstalledSettingsTracker {
@@ -75915,13 +76717,13 @@ class InstalledSettingsTracker {
75915
76717
  }
75916
76718
  getCkJsonPath() {
75917
76719
  if (this.isGlobal) {
75918
- return join66(this.projectDir, CK_JSON_FILE);
76720
+ return join67(this.projectDir, CK_JSON_FILE);
75919
76721
  }
75920
- return join66(this.projectDir, ".claude", CK_JSON_FILE);
76722
+ return join67(this.projectDir, ".claude", CK_JSON_FILE);
75921
76723
  }
75922
76724
  async loadInstalledSettings() {
75923
76725
  const ckJsonPath = this.getCkJsonPath();
75924
- if (!existsSync36(ckJsonPath)) {
76726
+ if (!existsSync37(ckJsonPath)) {
75925
76727
  return { hooks: [], mcpServers: [] };
75926
76728
  }
75927
76729
  try {
@@ -75941,7 +76743,7 @@ class InstalledSettingsTracker {
75941
76743
  const ckJsonPath = this.getCkJsonPath();
75942
76744
  try {
75943
76745
  let data = {};
75944
- if (existsSync36(ckJsonPath)) {
76746
+ if (existsSync37(ckJsonPath)) {
75945
76747
  const content = await readFile29(ckJsonPath, "utf-8");
75946
76748
  data = JSON.parse(content);
75947
76749
  }
@@ -76348,7 +77150,7 @@ class CopyExecutor {
76348
77150
  for (const file of files) {
76349
77151
  const relativePath = relative9(sourceDir, file);
76350
77152
  const normalizedRelativePath = relativePath.replace(/\\/g, "/");
76351
- const destPath = join67(destDir, relativePath);
77153
+ const destPath = join68(destDir, relativePath);
76352
77154
  if (await import_fs_extra12.pathExists(destPath)) {
76353
77155
  if (this.fileScanner.shouldNeverCopy(normalizedRelativePath)) {
76354
77156
  logger.debug(`Security-sensitive file exists but won't be overwritten: ${normalizedRelativePath}`);
@@ -76370,7 +77172,7 @@ class CopyExecutor {
76370
77172
  for (const file of files) {
76371
77173
  const relativePath = relative9(sourceDir, file);
76372
77174
  const normalizedRelativePath = relativePath.replace(/\\/g, "/");
76373
- const destPath = join67(destDir, relativePath);
77175
+ const destPath = join68(destDir, relativePath);
76374
77176
  if (this.fileScanner.shouldNeverCopy(normalizedRelativePath)) {
76375
77177
  logger.debug(`Skipping security-sensitive file: ${normalizedRelativePath}`);
76376
77178
  skippedCount++;
@@ -76539,16 +77341,16 @@ class FileMerger {
76539
77341
  }
76540
77342
 
76541
77343
  // src/domains/migration/legacy-migration.ts
76542
- import { readdir as readdir14, stat as stat14 } from "node:fs/promises";
76543
- import { join as join71, relative as relative10 } from "node:path";
77344
+ import { readdir as readdir15, stat as stat14 } from "node:fs/promises";
77345
+ import { join as join72, relative as relative10 } from "node:path";
76544
77346
  // src/services/file-operations/manifest/manifest-tracker.ts
76545
- import { join as join70 } from "node:path";
77347
+ import { join as join71 } from "node:path";
76546
77348
 
76547
77349
  // src/domains/migration/release-manifest.ts
76548
77350
  init_logger();
76549
77351
  init_zod();
76550
77352
  var import_fs_extra13 = __toESM(require_lib3(), 1);
76551
- import { join as join68 } from "node:path";
77353
+ import { join as join69 } from "node:path";
76552
77354
  var ReleaseManifestFileSchema = exports_external.object({
76553
77355
  path: exports_external.string(),
76554
77356
  checksum: exports_external.string().regex(/^[a-f0-9]{64}$/),
@@ -76563,7 +77365,7 @@ var ReleaseManifestSchema = exports_external.object({
76563
77365
 
76564
77366
  class ReleaseManifestLoader {
76565
77367
  static async load(extractDir) {
76566
- const manifestPath = join68(extractDir, "release-manifest.json");
77368
+ const manifestPath = join69(extractDir, "release-manifest.json");
76567
77369
  try {
76568
77370
  const content = await import_fs_extra13.readFile(manifestPath, "utf-8");
76569
77371
  const parsed = JSON.parse(content);
@@ -76589,9 +77391,9 @@ init_logger();
76589
77391
  init_types2();
76590
77392
  var import_fs_extra14 = __toESM(require_lib3(), 1);
76591
77393
  var import_proper_lockfile2 = __toESM(require_proper_lockfile(), 1);
76592
- import { join as join69 } from "node:path";
77394
+ import { join as join70 } from "node:path";
76593
77395
  async function writeManifest(claudeDir2, kitName, version, scope, kitType, trackedFiles, userConfigFiles) {
76594
- const metadataPath = join69(claudeDir2, "metadata.json");
77396
+ const metadataPath = join70(claudeDir2, "metadata.json");
76595
77397
  const kit = kitType || (/\bmarketing\b/i.test(kitName) ? "marketing" : "engineer");
76596
77398
  await import_fs_extra14.ensureFile(metadataPath);
76597
77399
  let release = null;
@@ -76647,7 +77449,7 @@ async function writeManifest(claudeDir2, kitName, version, scope, kitType, track
76647
77449
  }
76648
77450
  }
76649
77451
  async function removeKitFromManifest(claudeDir2, kit) {
76650
- const metadataPath = join69(claudeDir2, "metadata.json");
77452
+ const metadataPath = join70(claudeDir2, "metadata.json");
76651
77453
  if (!await import_fs_extra14.pathExists(metadataPath))
76652
77454
  return false;
76653
77455
  let release = null;
@@ -76777,7 +77579,7 @@ function buildFileTrackingList(options2) {
76777
77579
  if (!isGlobal && !installedPath.startsWith(".claude/"))
76778
77580
  continue;
76779
77581
  const relativePath = isGlobal ? installedPath : installedPath.replace(/^\.claude\//, "");
76780
- const filePath = join70(claudeDir2, relativePath);
77582
+ const filePath = join71(claudeDir2, relativePath);
76781
77583
  const manifestEntry = releaseManifest ? ReleaseManifestLoader.findFile(releaseManifest, installedPath) : null;
76782
77584
  const ownership = manifestEntry ? "ck" : "user";
76783
77585
  filesToTrack.push({
@@ -76867,7 +77669,7 @@ class LegacyMigration {
76867
77669
  const files = [];
76868
77670
  let entries;
76869
77671
  try {
76870
- entries = await readdir14(dir);
77672
+ entries = await readdir15(dir);
76871
77673
  } catch (err) {
76872
77674
  const error = err;
76873
77675
  if (error.code === "ENOENT") {
@@ -76884,7 +77686,7 @@ class LegacyMigration {
76884
77686
  continue;
76885
77687
  if (SKIP_DIRS_ALL.includes(entry))
76886
77688
  continue;
76887
- const fullPath = join71(dir, entry);
77689
+ const fullPath = join72(dir, entry);
76888
77690
  let stats;
76889
77691
  try {
76890
77692
  stats = await stat14(fullPath);
@@ -76986,7 +77788,7 @@ User-created files (sample):`);
76986
77788
  ];
76987
77789
  if (filesToChecksum.length > 0) {
76988
77790
  const checksumResults = await mapWithLimit(filesToChecksum, async ({ relativePath, ownership }) => {
76989
- const fullPath = join71(claudeDir2, relativePath);
77791
+ const fullPath = join72(claudeDir2, relativePath);
76990
77792
  const checksum = await OwnershipChecker.calculateChecksum(fullPath);
76991
77793
  return { relativePath, checksum, ownership };
76992
77794
  });
@@ -77007,7 +77809,7 @@ User-created files (sample):`);
77007
77809
  installedAt: new Date().toISOString(),
77008
77810
  files: trackedFiles
77009
77811
  };
77010
- const metadataPath = join71(claudeDir2, "metadata.json");
77812
+ const metadataPath = join72(claudeDir2, "metadata.json");
77011
77813
  await import_fs_extra15.writeFile(metadataPath, JSON.stringify(updatedMetadata, null, 2));
77012
77814
  logger.success(`Migration complete: tracked ${trackedFiles.length} files`);
77013
77815
  return true;
@@ -77113,7 +77915,7 @@ function buildConflictSummary(fileConflicts, hookConflicts, mcpConflicts) {
77113
77915
  init_logger();
77114
77916
  init_skip_directories();
77115
77917
  var import_fs_extra16 = __toESM(require_lib3(), 1);
77116
- import { join as join72, relative as relative11, resolve as resolve13 } from "node:path";
77918
+ import { join as join73, relative as relative11, resolve as resolve14 } from "node:path";
77117
77919
 
77118
77920
  class FileScanner2 {
77119
77921
  static async getFiles(dirPath, relativeTo) {
@@ -77129,7 +77931,7 @@ class FileScanner2 {
77129
77931
  logger.debug(`Skipping directory: ${entry}`);
77130
77932
  continue;
77131
77933
  }
77132
- const fullPath = join72(dirPath, entry);
77934
+ const fullPath = join73(dirPath, entry);
77133
77935
  if (!FileScanner2.isSafePath(basePath, fullPath)) {
77134
77936
  logger.warning(`Skipping potentially unsafe path: ${entry}`);
77135
77937
  continue;
@@ -77164,8 +77966,8 @@ class FileScanner2 {
77164
77966
  return files;
77165
77967
  }
77166
77968
  static async findCustomFiles(destDir, sourceDir, subPath) {
77167
- const destSubDir = join72(destDir, subPath);
77168
- const sourceSubDir = join72(sourceDir, subPath);
77969
+ const destSubDir = join73(destDir, subPath);
77970
+ const sourceSubDir = join73(sourceDir, subPath);
77169
77971
  logger.debug(`findCustomFiles - destDir: ${destDir}`);
77170
77972
  logger.debug(`findCustomFiles - sourceDir: ${sourceDir}`);
77171
77973
  logger.debug(`findCustomFiles - subPath: "${subPath}"`);
@@ -77193,8 +77995,8 @@ class FileScanner2 {
77193
77995
  return customFiles;
77194
77996
  }
77195
77997
  static isSafePath(basePath, targetPath) {
77196
- const resolvedBase = resolve13(basePath);
77197
- const resolvedTarget = resolve13(targetPath);
77998
+ const resolvedBase = resolve14(basePath);
77999
+ const resolvedTarget = resolve14(targetPath);
77198
78000
  return resolvedTarget.startsWith(resolvedBase);
77199
78001
  }
77200
78002
  static toPosixPath(path12) {
@@ -77205,13 +78007,13 @@ class FileScanner2 {
77205
78007
  // src/services/transformers/commands-prefix/prefix-applier.ts
77206
78008
  init_logger();
77207
78009
  var import_fs_extra17 = __toESM(require_lib3(), 1);
77208
- import { lstat as lstat7, mkdir as mkdir22, readdir as readdir17, stat as stat15 } from "node:fs/promises";
77209
- import { join as join74 } from "node:path";
78010
+ import { lstat as lstat7, mkdir as mkdir22, readdir as readdir18, stat as stat15 } from "node:fs/promises";
78011
+ import { join as join75 } from "node:path";
77210
78012
 
77211
78013
  // src/services/transformers/commands-prefix/content-transformer.ts
77212
78014
  init_logger();
77213
- import { readFile as readFile33, readdir as readdir16, writeFile as writeFile21 } from "node:fs/promises";
77214
- import { join as join73 } from "node:path";
78015
+ import { readFile as readFile33, readdir as readdir17, writeFile as writeFile21 } from "node:fs/promises";
78016
+ import { join as join74 } from "node:path";
77215
78017
  var TRANSFORMABLE_EXTENSIONS = new Set([
77216
78018
  ".md",
77217
78019
  ".txt",
@@ -77270,9 +78072,9 @@ async function transformCommandReferences(directory, options2 = {}) {
77270
78072
  let filesTransformed = 0;
77271
78073
  let totalReplacements = 0;
77272
78074
  async function processDirectory(dir) {
77273
- const entries = await readdir16(dir, { withFileTypes: true });
78075
+ const entries = await readdir17(dir, { withFileTypes: true });
77274
78076
  for (const entry of entries) {
77275
- const fullPath = join73(dir, entry.name);
78077
+ const fullPath = join74(dir, entry.name);
77276
78078
  if (entry.isDirectory()) {
77277
78079
  if (entry.name === "node_modules" || entry.name.startsWith(".") && entry.name !== ".claude") {
77278
78080
  continue;
@@ -77347,22 +78149,22 @@ function shouldApplyPrefix(options2) {
77347
78149
  // src/services/transformers/commands-prefix/prefix-applier.ts
77348
78150
  async function applyPrefix(extractDir) {
77349
78151
  validatePath(extractDir, "extractDir");
77350
- const commandsDir = join74(extractDir, ".claude", "commands");
78152
+ const commandsDir = join75(extractDir, ".claude", "commands");
77351
78153
  if (!await import_fs_extra17.pathExists(commandsDir)) {
77352
78154
  logger.verbose("No commands directory found, skipping prefix application");
77353
78155
  return;
77354
78156
  }
77355
78157
  logger.info("Applying /ck: prefix to slash commands...");
77356
- const backupDir = join74(extractDir, ".commands-backup");
77357
- const tempDir = join74(extractDir, ".commands-prefix-temp");
78158
+ const backupDir = join75(extractDir, ".commands-backup");
78159
+ const tempDir = join75(extractDir, ".commands-prefix-temp");
77358
78160
  try {
77359
- const entries = await readdir17(commandsDir);
78161
+ const entries = await readdir18(commandsDir);
77360
78162
  if (entries.length === 0) {
77361
78163
  logger.verbose("Commands directory is empty, skipping prefix application");
77362
78164
  return;
77363
78165
  }
77364
78166
  if (entries.length === 1 && entries[0] === "ck") {
77365
- const ckDir2 = join74(commandsDir, "ck");
78167
+ const ckDir2 = join75(commandsDir, "ck");
77366
78168
  const ckStat = await stat15(ckDir2);
77367
78169
  if (ckStat.isDirectory()) {
77368
78170
  logger.verbose("Commands already have /ck: prefix, skipping");
@@ -77372,17 +78174,17 @@ async function applyPrefix(extractDir) {
77372
78174
  await import_fs_extra17.copy(commandsDir, backupDir);
77373
78175
  logger.verbose("Created backup of commands directory");
77374
78176
  await mkdir22(tempDir, { recursive: true });
77375
- const ckDir = join74(tempDir, "ck");
78177
+ const ckDir = join75(tempDir, "ck");
77376
78178
  await mkdir22(ckDir, { recursive: true });
77377
78179
  let processedCount = 0;
77378
78180
  for (const entry of entries) {
77379
- const sourcePath = join74(commandsDir, entry);
78181
+ const sourcePath = join75(commandsDir, entry);
77380
78182
  const stats = await lstat7(sourcePath);
77381
78183
  if (stats.isSymbolicLink()) {
77382
78184
  logger.warning(`Skipping symlink for security: ${entry}`);
77383
78185
  continue;
77384
78186
  }
77385
- const destPath = join74(ckDir, entry);
78187
+ const destPath = join75(ckDir, entry);
77386
78188
  await import_fs_extra17.copy(sourcePath, destPath, {
77387
78189
  overwrite: false,
77388
78190
  errorOnExist: true
@@ -77400,7 +78202,7 @@ async function applyPrefix(extractDir) {
77400
78202
  await import_fs_extra17.move(tempDir, commandsDir);
77401
78203
  await import_fs_extra17.remove(backupDir);
77402
78204
  logger.success("Successfully reorganized commands to /ck: prefix");
77403
- const claudeDir2 = join74(extractDir, ".claude");
78205
+ const claudeDir2 = join75(extractDir, ".claude");
77404
78206
  logger.info("Transforming command references in file contents...");
77405
78207
  const transformResult = await transformCommandReferences(claudeDir2, {
77406
78208
  verbose: logger.isVerbose()
@@ -77437,21 +78239,21 @@ async function applyPrefix(extractDir) {
77437
78239
 
77438
78240
  // src/services/transformers/commands-prefix/prefix-cleaner.ts
77439
78241
  init_metadata_migration();
77440
- import { lstat as lstat9, readdir as readdir19 } from "node:fs/promises";
77441
- import { join as join76 } from "node:path";
78242
+ import { lstat as lstat9, readdir as readdir20 } from "node:fs/promises";
78243
+ import { join as join77 } from "node:path";
77442
78244
  init_logger();
77443
78245
  var import_fs_extra19 = __toESM(require_lib3(), 1);
77444
78246
 
77445
78247
  // src/services/transformers/commands-prefix/file-processor.ts
77446
- import { lstat as lstat8, readdir as readdir18 } from "node:fs/promises";
77447
- import { join as join75 } from "node:path";
78248
+ import { lstat as lstat8, readdir as readdir19 } from "node:fs/promises";
78249
+ import { join as join76 } from "node:path";
77448
78250
  init_logger();
77449
78251
  var import_fs_extra18 = __toESM(require_lib3(), 1);
77450
78252
  async function scanDirectoryFiles(dir) {
77451
78253
  const files = [];
77452
- const entries = await readdir18(dir);
78254
+ const entries = await readdir19(dir);
77453
78255
  for (const entry of entries) {
77454
- const fullPath = join75(dir, entry);
78256
+ const fullPath = join76(dir, entry);
77455
78257
  const stats = await lstat8(fullPath);
77456
78258
  if (stats.isSymbolicLink()) {
77457
78259
  continue;
@@ -77579,8 +78381,8 @@ function isDifferentKitDirectory(dirName, currentKit) {
77579
78381
  async function cleanupCommandsDirectory(targetDir, isGlobal, options2 = {}) {
77580
78382
  const { dryRun = false } = options2;
77581
78383
  validatePath(targetDir, "targetDir");
77582
- const claudeDir2 = isGlobal ? targetDir : join76(targetDir, ".claude");
77583
- const commandsDir = join76(claudeDir2, "commands");
78384
+ const claudeDir2 = isGlobal ? targetDir : join77(targetDir, ".claude");
78385
+ const commandsDir = join77(claudeDir2, "commands");
77584
78386
  const accumulator = {
77585
78387
  results: [],
77586
78388
  deletedCount: 0,
@@ -77615,14 +78417,14 @@ async function cleanupCommandsDirectory(targetDir, isGlobal, options2 = {}) {
77615
78417
  if (options2.kitType) {
77616
78418
  logger.verbose(`Kit-aware cleanup: only cleaning files owned by '${options2.kitType}'`);
77617
78419
  }
77618
- const entries = await readdir19(commandsDir);
78420
+ const entries = await readdir20(commandsDir);
77619
78421
  if (entries.length === 0) {
77620
78422
  logger.verbose("Commands directory is empty");
77621
78423
  return result;
77622
78424
  }
77623
78425
  const metadataForChecks = options2.kitType ? createKitSpecificMetadata(metadata, options2.kitType) : metadata;
77624
78426
  for (const entry of entries) {
77625
- const entryPath = join76(commandsDir, entry);
78427
+ const entryPath = join77(commandsDir, entry);
77626
78428
  const stats = await lstat9(entryPath);
77627
78429
  if (stats.isSymbolicLink()) {
77628
78430
  addSymlinkSkip(entry, accumulator);
@@ -77679,7 +78481,7 @@ async function handleMerge(ctx) {
77679
78481
  let customClaudeFiles = [];
77680
78482
  if (!ctx.options.fresh) {
77681
78483
  logger.info("Scanning for custom .claude files...");
77682
- const scanSourceDir = ctx.options.global ? join77(ctx.extractDir, ".claude") : ctx.extractDir;
78484
+ const scanSourceDir = ctx.options.global ? join78(ctx.extractDir, ".claude") : ctx.extractDir;
77683
78485
  const scanTargetSubdir = ctx.options.global ? "" : ".claude";
77684
78486
  customClaudeFiles = await FileScanner2.findCustomFiles(ctx.resolvedDir, scanSourceDir, scanTargetSubdir);
77685
78487
  } else {
@@ -77744,7 +78546,7 @@ async function handleMerge(ctx) {
77744
78546
  return { ...ctx, cancelled: true };
77745
78547
  }
77746
78548
  }
77747
- const sourceDir = ctx.options.global ? join77(ctx.extractDir, ".claude") : ctx.extractDir;
78549
+ const sourceDir = ctx.options.global ? join78(ctx.extractDir, ".claude") : ctx.extractDir;
77748
78550
  await merger.merge(sourceDir, ctx.resolvedDir, ctx.isNonInteractive);
77749
78551
  const fileConflicts = merger.getFileConflicts();
77750
78552
  if (fileConflicts.length > 0 && !ctx.isNonInteractive) {
@@ -77752,7 +78554,7 @@ async function handleMerge(ctx) {
77752
78554
  displayConflictSummary(summary);
77753
78555
  }
77754
78556
  try {
77755
- const sourceMetadataPath = ctx.options.global ? join77(sourceDir, "metadata.json") : join77(sourceDir, ".claude", "metadata.json");
78557
+ const sourceMetadataPath = ctx.options.global ? join78(sourceDir, "metadata.json") : join78(sourceDir, ".claude", "metadata.json");
77756
78558
  if (await import_fs_extra20.pathExists(sourceMetadataPath)) {
77757
78559
  const metadataContent = await import_fs_extra20.readFile(sourceMetadataPath, "utf-8");
77758
78560
  const sourceMetadata = JSON.parse(metadataContent);
@@ -77796,7 +78598,7 @@ async function handleMerge(ctx) {
77796
78598
  };
77797
78599
  }
77798
78600
  // src/commands/init/phases/migration-handler.ts
77799
- import { join as join85 } from "node:path";
78601
+ import { join as join86 } from "node:path";
77800
78602
 
77801
78603
  // src/domains/skills/skills-detector.ts
77802
78604
  init_logger();
@@ -77811,8 +78613,8 @@ init_skip_directories();
77811
78613
  init_types2();
77812
78614
  var import_fs_extra21 = __toESM(require_lib3(), 1);
77813
78615
  import { createHash as createHash2 } from "node:crypto";
77814
- import { readFile as readFile35, readdir as readdir20, writeFile as writeFile22 } from "node:fs/promises";
77815
- import { join as join78, relative as relative12 } from "node:path";
78616
+ import { readFile as readFile35, readdir as readdir21, writeFile as writeFile22 } from "node:fs/promises";
78617
+ import { join as join79, relative as relative12 } from "node:path";
77816
78618
 
77817
78619
  class SkillsManifestManager {
77818
78620
  static MANIFEST_FILENAME = ".skills-manifest.json";
@@ -77834,12 +78636,12 @@ class SkillsManifestManager {
77834
78636
  return manifest;
77835
78637
  }
77836
78638
  static async writeManifest(skillsDir2, manifest) {
77837
- const manifestPath = join78(skillsDir2, SkillsManifestManager.MANIFEST_FILENAME);
78639
+ const manifestPath = join79(skillsDir2, SkillsManifestManager.MANIFEST_FILENAME);
77838
78640
  await writeFile22(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
77839
78641
  logger.debug(`Wrote manifest to: ${manifestPath}`);
77840
78642
  }
77841
78643
  static async readManifest(skillsDir2) {
77842
- const manifestPath = join78(skillsDir2, SkillsManifestManager.MANIFEST_FILENAME);
78644
+ const manifestPath = join79(skillsDir2, SkillsManifestManager.MANIFEST_FILENAME);
77843
78645
  if (!await import_fs_extra21.pathExists(manifestPath)) {
77844
78646
  logger.debug(`No manifest found at: ${manifestPath}`);
77845
78647
  return null;
@@ -77856,14 +78658,14 @@ class SkillsManifestManager {
77856
78658
  }
77857
78659
  }
77858
78660
  static async detectStructure(skillsDir2) {
77859
- const entries = await readdir20(skillsDir2, { withFileTypes: true });
78661
+ const entries = await readdir21(skillsDir2, { withFileTypes: true });
77860
78662
  const dirs = entries.filter((entry) => entry.isDirectory() && !BUILD_ARTIFACT_DIRS.includes(entry.name) && !entry.name.startsWith("."));
77861
78663
  if (dirs.length === 0) {
77862
78664
  return "flat";
77863
78665
  }
77864
78666
  for (const dir of dirs.slice(0, 3)) {
77865
- const dirPath = join78(skillsDir2, dir.name);
77866
- const subEntries = await readdir20(dirPath, { withFileTypes: true });
78667
+ const dirPath = join79(skillsDir2, dir.name);
78668
+ const subEntries = await readdir21(dirPath, { withFileTypes: true });
77867
78669
  const hasSubdirs = subEntries.some((entry) => entry.isDirectory());
77868
78670
  if (hasSubdirs) {
77869
78671
  return "categorized";
@@ -77878,10 +78680,10 @@ class SkillsManifestManager {
77878
78680
  static async scanSkills(skillsDir2, structure) {
77879
78681
  const skills = [];
77880
78682
  if (structure === "flat") {
77881
- const entries = await readdir20(skillsDir2, { withFileTypes: true });
78683
+ const entries = await readdir21(skillsDir2, { withFileTypes: true });
77882
78684
  for (const entry of entries) {
77883
78685
  if (entry.isDirectory() && !BUILD_ARTIFACT_DIRS.includes(entry.name) && !entry.name.startsWith(".")) {
77884
- const skillPath = join78(skillsDir2, entry.name);
78686
+ const skillPath = join79(skillsDir2, entry.name);
77885
78687
  const hash = await SkillsManifestManager.hashDirectory(skillPath);
77886
78688
  skills.push({
77887
78689
  name: entry.name,
@@ -77890,14 +78692,14 @@ class SkillsManifestManager {
77890
78692
  }
77891
78693
  }
77892
78694
  } else {
77893
- const categories = await readdir20(skillsDir2, { withFileTypes: true });
78695
+ const categories = await readdir21(skillsDir2, { withFileTypes: true });
77894
78696
  for (const category of categories) {
77895
78697
  if (category.isDirectory() && !BUILD_ARTIFACT_DIRS.includes(category.name) && !category.name.startsWith(".")) {
77896
- const categoryPath = join78(skillsDir2, category.name);
77897
- const skillEntries = await readdir20(categoryPath, { withFileTypes: true });
78698
+ const categoryPath = join79(skillsDir2, category.name);
78699
+ const skillEntries = await readdir21(categoryPath, { withFileTypes: true });
77898
78700
  for (const skillEntry of skillEntries) {
77899
78701
  if (skillEntry.isDirectory() && !skillEntry.name.startsWith(".")) {
77900
- const skillPath = join78(categoryPath, skillEntry.name);
78702
+ const skillPath = join79(categoryPath, skillEntry.name);
77901
78703
  const hash = await SkillsManifestManager.hashDirectory(skillPath);
77902
78704
  skills.push({
77903
78705
  name: skillEntry.name,
@@ -77925,9 +78727,9 @@ class SkillsManifestManager {
77925
78727
  }
77926
78728
  static async getAllFiles(dirPath) {
77927
78729
  const files = [];
77928
- const entries = await readdir20(dirPath, { withFileTypes: true });
78730
+ const entries = await readdir21(dirPath, { withFileTypes: true });
77929
78731
  for (const entry of entries) {
77930
- const fullPath = join78(dirPath, entry.name);
78732
+ const fullPath = join79(dirPath, entry.name);
77931
78733
  if (entry.name.startsWith(".") || BUILD_ARTIFACT_DIRS.includes(entry.name)) {
77932
78734
  continue;
77933
78735
  }
@@ -78048,13 +78850,13 @@ function getPathMapping(skillName, oldBasePath, newBasePath) {
78048
78850
 
78049
78851
  // src/domains/skills/detection/script-detector.ts
78050
78852
  var import_fs_extra22 = __toESM(require_lib3(), 1);
78051
- import { readdir as readdir21 } from "node:fs/promises";
78052
- import { join as join79 } from "node:path";
78853
+ import { readdir as readdir22 } from "node:fs/promises";
78854
+ import { join as join80 } from "node:path";
78053
78855
  async function scanDirectory(skillsDir2) {
78054
78856
  if (!await import_fs_extra22.pathExists(skillsDir2)) {
78055
78857
  return ["flat", []];
78056
78858
  }
78057
- const entries = await readdir21(skillsDir2, { withFileTypes: true });
78859
+ const entries = await readdir22(skillsDir2, { withFileTypes: true });
78058
78860
  const dirs = entries.filter((entry) => entry.isDirectory() && entry.name !== "node_modules" && !entry.name.startsWith("."));
78059
78861
  if (dirs.length === 0) {
78060
78862
  return ["flat", []];
@@ -78062,13 +78864,13 @@ async function scanDirectory(skillsDir2) {
78062
78864
  let totalSkillLikeCount = 0;
78063
78865
  const allSkills = [];
78064
78866
  for (const dir of dirs) {
78065
- const dirPath = join79(skillsDir2, dir.name);
78066
- const subEntries = await readdir21(dirPath, { withFileTypes: true });
78867
+ const dirPath = join80(skillsDir2, dir.name);
78868
+ const subEntries = await readdir22(dirPath, { withFileTypes: true });
78067
78869
  const subdirs = subEntries.filter((entry) => entry.isDirectory() && !entry.name.startsWith("."));
78068
78870
  if (subdirs.length > 0) {
78069
78871
  for (const subdir of subdirs.slice(0, 3)) {
78070
- const subdirPath = join79(dirPath, subdir.name);
78071
- const subdirFiles = await readdir21(subdirPath, { withFileTypes: true });
78872
+ const subdirPath = join80(dirPath, subdir.name);
78873
+ const subdirFiles = await readdir22(subdirPath, { withFileTypes: true });
78072
78874
  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"));
78073
78875
  if (hasSkillMarker) {
78074
78876
  totalSkillLikeCount++;
@@ -78224,12 +79026,12 @@ class SkillsMigrationDetector {
78224
79026
  // src/domains/skills/skills-migrator.ts
78225
79027
  init_logger();
78226
79028
  init_types2();
78227
- import { join as join84 } from "node:path";
79029
+ import { join as join85 } from "node:path";
78228
79030
 
78229
79031
  // src/domains/skills/migrator/migration-executor.ts
78230
79032
  init_logger();
78231
- import { copyFile as copyFile5, mkdir as mkdir23, readdir as readdir22, rm as rm5 } from "node:fs/promises";
78232
- import { join as join80 } from "node:path";
79033
+ import { copyFile as copyFile5, mkdir as mkdir23, readdir as readdir23, rm as rm5 } from "node:fs/promises";
79034
+ import { join as join81 } from "node:path";
78233
79035
  var import_fs_extra24 = __toESM(require_lib3(), 1);
78234
79036
 
78235
79037
  // src/domains/skills/skills-migration-prompts.ts
@@ -78392,10 +79194,10 @@ Detected changes:`;
78392
79194
  // src/domains/skills/migrator/migration-executor.ts
78393
79195
  async function copySkillDirectory(sourceDir, destDir) {
78394
79196
  await mkdir23(destDir, { recursive: true });
78395
- const entries = await readdir22(sourceDir, { withFileTypes: true });
79197
+ const entries = await readdir23(sourceDir, { withFileTypes: true });
78396
79198
  for (const entry of entries) {
78397
- const sourcePath = join80(sourceDir, entry.name);
78398
- const destPath = join80(destDir, entry.name);
79199
+ const sourcePath = join81(sourceDir, entry.name);
79200
+ const destPath = join81(destDir, entry.name);
78399
79201
  if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.isSymbolicLink()) {
78400
79202
  continue;
78401
79203
  }
@@ -78410,7 +79212,7 @@ async function executeInternal(mappings, customizations, currentSkillsDir, inter
78410
79212
  const migrated = [];
78411
79213
  const preserved = [];
78412
79214
  const errors2 = [];
78413
- const tempDir = join80(currentSkillsDir, "..", ".skills-migration-temp");
79215
+ const tempDir = join81(currentSkillsDir, "..", ".skills-migration-temp");
78414
79216
  await mkdir23(tempDir, { recursive: true });
78415
79217
  try {
78416
79218
  for (const mapping of mappings) {
@@ -78431,9 +79233,9 @@ async function executeInternal(mappings, customizations, currentSkillsDir, inter
78431
79233
  }
78432
79234
  }
78433
79235
  const category = mapping.category;
78434
- const targetPath = category ? join80(tempDir, category, skillName) : join80(tempDir, skillName);
79236
+ const targetPath = category ? join81(tempDir, category, skillName) : join81(tempDir, skillName);
78435
79237
  if (category) {
78436
- await mkdir23(join80(tempDir, category), { recursive: true });
79238
+ await mkdir23(join81(tempDir, category), { recursive: true });
78437
79239
  }
78438
79240
  await copySkillDirectory(currentSkillPath, targetPath);
78439
79241
  migrated.push(skillName);
@@ -78499,8 +79301,8 @@ function validateMigrationPath(path12, paramName) {
78499
79301
  init_logger();
78500
79302
  init_types2();
78501
79303
  var import_fs_extra25 = __toESM(require_lib3(), 1);
78502
- import { copyFile as copyFile6, mkdir as mkdir24, readdir as readdir23, rm as rm6, stat as stat16 } from "node:fs/promises";
78503
- import { basename as basename8, join as join81, normalize as normalize8 } from "node:path";
79304
+ import { copyFile as copyFile6, mkdir as mkdir24, readdir as readdir24, rm as rm6, stat as stat16 } from "node:fs/promises";
79305
+ import { basename as basename8, join as join82, normalize as normalize8 } from "node:path";
78504
79306
  function validatePath2(path12, paramName) {
78505
79307
  if (!path12 || typeof path12 !== "string") {
78506
79308
  throw new SkillsMigrationError(`${paramName} must be a non-empty string`);
@@ -78526,7 +79328,7 @@ class SkillsBackupManager {
78526
79328
  const timestamp = Date.now();
78527
79329
  const randomSuffix = Math.random().toString(36).substring(2, 8);
78528
79330
  const backupDirName = `${SkillsBackupManager.BACKUP_PREFIX}${timestamp}-${randomSuffix}`;
78529
- const backupDir = parentDir ? join81(parentDir, backupDirName) : join81(skillsDir2, "..", backupDirName);
79331
+ const backupDir = parentDir ? join82(parentDir, backupDirName) : join82(skillsDir2, "..", backupDirName);
78530
79332
  logger.info(`Creating backup at: ${backupDir}`);
78531
79333
  try {
78532
79334
  await mkdir24(backupDir, { recursive: true });
@@ -78576,8 +79378,8 @@ class SkillsBackupManager {
78576
79378
  return [];
78577
79379
  }
78578
79380
  try {
78579
- const entries = await readdir23(parentDir, { withFileTypes: true });
78580
- const backups = entries.filter((entry) => entry.isDirectory() && entry.name.startsWith(SkillsBackupManager.BACKUP_PREFIX)).map((entry) => join81(parentDir, entry.name));
79381
+ const entries = await readdir24(parentDir, { withFileTypes: true });
79382
+ const backups = entries.filter((entry) => entry.isDirectory() && entry.name.startsWith(SkillsBackupManager.BACKUP_PREFIX)).map((entry) => join82(parentDir, entry.name));
78581
79383
  backups.sort().reverse();
78582
79384
  return backups;
78583
79385
  } catch (error) {
@@ -78603,10 +79405,10 @@ class SkillsBackupManager {
78603
79405
  return await SkillsBackupManager.getDirectorySize(backupDir);
78604
79406
  }
78605
79407
  static async copyDirectory(sourceDir, destDir) {
78606
- const entries = await readdir23(sourceDir, { withFileTypes: true });
79408
+ const entries = await readdir24(sourceDir, { withFileTypes: true });
78607
79409
  for (const entry of entries) {
78608
- const sourcePath = join81(sourceDir, entry.name);
78609
- const destPath = join81(destDir, entry.name);
79410
+ const sourcePath = join82(sourceDir, entry.name);
79411
+ const destPath = join82(destDir, entry.name);
78610
79412
  if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.isSymbolicLink()) {
78611
79413
  continue;
78612
79414
  }
@@ -78620,9 +79422,9 @@ class SkillsBackupManager {
78620
79422
  }
78621
79423
  static async getDirectorySize(dirPath) {
78622
79424
  let size = 0;
78623
- const entries = await readdir23(dirPath, { withFileTypes: true });
79425
+ const entries = await readdir24(dirPath, { withFileTypes: true });
78624
79426
  for (const entry of entries) {
78625
- const fullPath = join81(dirPath, entry.name);
79427
+ const fullPath = join82(dirPath, entry.name);
78626
79428
  if (entry.isSymbolicLink()) {
78627
79429
  continue;
78628
79430
  }
@@ -78657,13 +79459,13 @@ import { relative as relative14 } from "node:path";
78657
79459
  init_skip_directories();
78658
79460
  import { createHash as createHash3 } from "node:crypto";
78659
79461
  import { createReadStream as createReadStream3 } from "node:fs";
78660
- import { readFile as readFile36, readdir as readdir24 } from "node:fs/promises";
78661
- import { join as join82, relative as relative13 } from "node:path";
79462
+ import { readFile as readFile36, readdir as readdir25 } from "node:fs/promises";
79463
+ import { join as join83, relative as relative13 } from "node:path";
78662
79464
  async function getAllFiles(dirPath) {
78663
79465
  const files = [];
78664
- const entries = await readdir24(dirPath, { withFileTypes: true });
79466
+ const entries = await readdir25(dirPath, { withFileTypes: true });
78665
79467
  for (const entry of entries) {
78666
- const fullPath = join82(dirPath, entry.name);
79468
+ const fullPath = join83(dirPath, entry.name);
78667
79469
  if (entry.name.startsWith(".") || BUILD_ARTIFACT_DIRS.includes(entry.name) || entry.isSymbolicLink()) {
78668
79470
  continue;
78669
79471
  }
@@ -78677,12 +79479,12 @@ async function getAllFiles(dirPath) {
78677
79479
  return files;
78678
79480
  }
78679
79481
  async function hashFile(filePath) {
78680
- return new Promise((resolve14, reject) => {
79482
+ return new Promise((resolve15, reject) => {
78681
79483
  const hash = createHash3("sha256");
78682
79484
  const stream = createReadStream3(filePath);
78683
79485
  stream.on("data", (chunk) => hash.update(chunk));
78684
79486
  stream.on("end", () => {
78685
- resolve14(hash.digest("hex"));
79487
+ resolve15(hash.digest("hex"));
78686
79488
  });
78687
79489
  stream.on("error", (error) => {
78688
79490
  stream.destroy();
@@ -78789,8 +79591,8 @@ async function detectFileChanges(currentSkillPath, baselineSkillPath) {
78789
79591
  // src/domains/skills/customization/scan-reporter.ts
78790
79592
  init_types2();
78791
79593
  var import_fs_extra27 = __toESM(require_lib3(), 1);
78792
- import { readdir as readdir25 } from "node:fs/promises";
78793
- import { join as join83, normalize as normalize9 } from "node:path";
79594
+ import { readdir as readdir26 } from "node:fs/promises";
79595
+ import { join as join84, normalize as normalize9 } from "node:path";
78794
79596
  function validatePath3(path12, paramName) {
78795
79597
  if (!path12 || typeof path12 !== "string") {
78796
79598
  throw new SkillsMigrationError(`${paramName} must be a non-empty string`);
@@ -78806,19 +79608,19 @@ async function scanSkillsDirectory(skillsDir2) {
78806
79608
  if (!await import_fs_extra27.pathExists(skillsDir2)) {
78807
79609
  return ["flat", []];
78808
79610
  }
78809
- const entries = await readdir25(skillsDir2, { withFileTypes: true });
79611
+ const entries = await readdir26(skillsDir2, { withFileTypes: true });
78810
79612
  const dirs = entries.filter((entry) => entry.isDirectory() && entry.name !== "node_modules" && !entry.name.startsWith("."));
78811
79613
  if (dirs.length === 0) {
78812
79614
  return ["flat", []];
78813
79615
  }
78814
- const firstDirPath = join83(skillsDir2, dirs[0].name);
78815
- const subEntries = await readdir25(firstDirPath, { withFileTypes: true });
79616
+ const firstDirPath = join84(skillsDir2, dirs[0].name);
79617
+ const subEntries = await readdir26(firstDirPath, { withFileTypes: true });
78816
79618
  const subdirs = subEntries.filter((entry) => entry.isDirectory() && !entry.name.startsWith("."));
78817
79619
  if (subdirs.length > 0) {
78818
79620
  let skillLikeCount = 0;
78819
79621
  for (const subdir of subdirs.slice(0, 3)) {
78820
- const subdirPath = join83(firstDirPath, subdir.name);
78821
- const subdirFiles = await readdir25(subdirPath, { withFileTypes: true });
79622
+ const subdirPath = join84(firstDirPath, subdir.name);
79623
+ const subdirFiles = await readdir26(subdirPath, { withFileTypes: true });
78822
79624
  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"));
78823
79625
  if (hasSkillMarker) {
78824
79626
  skillLikeCount++;
@@ -78827,8 +79629,8 @@ async function scanSkillsDirectory(skillsDir2) {
78827
79629
  if (skillLikeCount > 0) {
78828
79630
  const skills = [];
78829
79631
  for (const dir of dirs) {
78830
- const categoryPath = join83(skillsDir2, dir.name);
78831
- const skillDirs = await readdir25(categoryPath, { withFileTypes: true });
79632
+ const categoryPath = join84(skillsDir2, dir.name);
79633
+ const skillDirs = await readdir26(categoryPath, { withFileTypes: true });
78832
79634
  skills.push(...skillDirs.filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name));
78833
79635
  }
78834
79636
  return ["categorized", skills];
@@ -78837,17 +79639,17 @@ async function scanSkillsDirectory(skillsDir2) {
78837
79639
  return ["flat", dirs.map((dir) => dir.name)];
78838
79640
  }
78839
79641
  async function findSkillPath(skillsDir2, skillName) {
78840
- const flatPath = join83(skillsDir2, skillName);
79642
+ const flatPath = join84(skillsDir2, skillName);
78841
79643
  if (await import_fs_extra27.pathExists(flatPath)) {
78842
79644
  return { path: flatPath, category: undefined };
78843
79645
  }
78844
- const entries = await readdir25(skillsDir2, { withFileTypes: true });
79646
+ const entries = await readdir26(skillsDir2, { withFileTypes: true });
78845
79647
  for (const entry of entries) {
78846
79648
  if (!entry.isDirectory() || entry.name.startsWith(".") || entry.name === "node_modules") {
78847
79649
  continue;
78848
79650
  }
78849
- const categoryPath = join83(skillsDir2, entry.name);
78850
- const skillPath = join83(categoryPath, skillName);
79651
+ const categoryPath = join84(skillsDir2, entry.name);
79652
+ const skillPath = join84(categoryPath, skillName);
78851
79653
  if (await import_fs_extra27.pathExists(skillPath)) {
78852
79654
  return { path: skillPath, category: entry.name };
78853
79655
  }
@@ -78941,7 +79743,7 @@ class SkillsMigrator {
78941
79743
  }
78942
79744
  }
78943
79745
  if (options2.backup && !options2.dryRun) {
78944
- const claudeDir2 = join84(currentSkillsDir, "..");
79746
+ const claudeDir2 = join85(currentSkillsDir, "..");
78945
79747
  result.backupPath = await SkillsBackupManager.createBackup(currentSkillsDir, claudeDir2);
78946
79748
  logger.success(`Backup created at: ${result.backupPath}`);
78947
79749
  }
@@ -79002,7 +79804,7 @@ async function handleMigration(ctx) {
79002
79804
  logger.debug("Skipping skills migration (fresh installation)");
79003
79805
  return ctx;
79004
79806
  }
79005
- const newSkillsDir = join85(ctx.extractDir, ".claude", "skills");
79807
+ const newSkillsDir = join86(ctx.extractDir, ".claude", "skills");
79006
79808
  const currentSkillsDir = PathResolver.buildSkillsPath(ctx.resolvedDir, ctx.options.global);
79007
79809
  if (!await import_fs_extra28.pathExists(newSkillsDir) || !await import_fs_extra28.pathExists(currentSkillsDir)) {
79008
79810
  return ctx;
@@ -79025,14 +79827,14 @@ async function handleMigration(ctx) {
79025
79827
  return ctx;
79026
79828
  }
79027
79829
  // src/commands/init/phases/opencode-handler.ts
79028
- import { cp as cp2, readdir as readdir27, rm as rm7 } from "node:fs/promises";
79029
- import { join as join87 } from "node:path";
79830
+ import { cp as cp2, readdir as readdir28, rm as rm7 } from "node:fs/promises";
79831
+ import { join as join88 } from "node:path";
79030
79832
 
79031
79833
  // src/services/transformers/opencode-path-transformer.ts
79032
79834
  init_logger();
79033
- import { readFile as readFile37, readdir as readdir26, writeFile as writeFile23 } from "node:fs/promises";
79835
+ import { readFile as readFile37, readdir as readdir27, writeFile as writeFile23 } from "node:fs/promises";
79034
79836
  import { platform as platform12 } from "node:os";
79035
- import { extname as extname3, join as join86 } from "node:path";
79837
+ import { extname as extname3, join as join87 } from "node:path";
79036
79838
  var IS_WINDOWS3 = platform12() === "win32";
79037
79839
  function getOpenCodeGlobalPath() {
79038
79840
  return "$HOME/.config/opencode/";
@@ -79091,9 +79893,9 @@ async function transformPathsForGlobalOpenCode(directory, options2 = {}) {
79091
79893
  let totalChanges = 0;
79092
79894
  let filesSkipped = 0;
79093
79895
  async function processDirectory2(dir) {
79094
- const entries = await readdir26(dir, { withFileTypes: true });
79896
+ const entries = await readdir27(dir, { withFileTypes: true });
79095
79897
  for (const entry of entries) {
79096
- const fullPath = join86(dir, entry.name);
79898
+ const fullPath = join87(dir, entry.name);
79097
79899
  if (entry.isDirectory()) {
79098
79900
  if (entry.name === "node_modules" || entry.name.startsWith(".")) {
79099
79901
  continue;
@@ -79132,7 +79934,7 @@ async function handleOpenCode(ctx) {
79132
79934
  if (ctx.cancelled || !ctx.extractDir || !ctx.resolvedDir) {
79133
79935
  return ctx;
79134
79936
  }
79135
- const openCodeSource = join87(ctx.extractDir, ".opencode");
79937
+ const openCodeSource = join88(ctx.extractDir, ".opencode");
79136
79938
  if (!await import_fs_extra29.pathExists(openCodeSource)) {
79137
79939
  logger.debug("No .opencode directory in archive, skipping");
79138
79940
  return ctx;
@@ -79148,10 +79950,10 @@ async function handleOpenCode(ctx) {
79148
79950
  logger.success(`Transformed ${transformResult.totalChanges} OpenCode path(s) in ${transformResult.filesTransformed} file(s)`);
79149
79951
  }
79150
79952
  await import_fs_extra29.ensureDir(targetDir);
79151
- const entries = await readdir27(openCodeSource, { withFileTypes: true });
79953
+ const entries = await readdir28(openCodeSource, { withFileTypes: true });
79152
79954
  for (const entry of entries) {
79153
- const sourcePath = join87(openCodeSource, entry.name);
79154
- const targetPath = join87(targetDir, entry.name);
79955
+ const sourcePath = join88(openCodeSource, entry.name);
79956
+ const targetPath = join88(targetDir, entry.name);
79155
79957
  if (await import_fs_extra29.pathExists(targetPath)) {
79156
79958
  if (!ctx.options.forceOverwrite) {
79157
79959
  logger.verbose(`Skipping existing: ${entry.name}`);
@@ -79244,7 +80046,7 @@ Please use only one download method.`);
79244
80046
  }
79245
80047
  // src/commands/init/phases/post-install-handler.ts
79246
80048
  init_projects_registry();
79247
- import { join as join88 } from "node:path";
80049
+ import { join as join89 } from "node:path";
79248
80050
  init_logger();
79249
80051
  init_path_resolver();
79250
80052
  var import_fs_extra30 = __toESM(require_lib3(), 1);
@@ -79253,8 +80055,8 @@ async function handlePostInstall(ctx) {
79253
80055
  return ctx;
79254
80056
  }
79255
80057
  if (ctx.options.global) {
79256
- const claudeMdSource = join88(ctx.extractDir, "CLAUDE.md");
79257
- const claudeMdDest = join88(ctx.resolvedDir, "CLAUDE.md");
80058
+ const claudeMdSource = join89(ctx.extractDir, "CLAUDE.md");
80059
+ const claudeMdDest = join89(ctx.resolvedDir, "CLAUDE.md");
79258
80060
  if (await import_fs_extra30.pathExists(claudeMdSource)) {
79259
80061
  if (!await import_fs_extra30.pathExists(claudeMdDest)) {
79260
80062
  await import_fs_extra30.copy(claudeMdSource, claudeMdDest);
@@ -79302,7 +80104,7 @@ async function handlePostInstall(ctx) {
79302
80104
  }
79303
80105
  if (!ctx.options.skipSetup) {
79304
80106
  await promptSetupWizardIfNeeded({
79305
- envPath: join88(ctx.claudeDir, ".env"),
80107
+ envPath: join89(ctx.claudeDir, ".env"),
79306
80108
  claudeDir: ctx.claudeDir,
79307
80109
  isGlobal: ctx.options.global,
79308
80110
  isNonInteractive: ctx.isNonInteractive,
@@ -79326,7 +80128,7 @@ async function handlePostInstall(ctx) {
79326
80128
  init_config_manager();
79327
80129
  init_github_client();
79328
80130
  import { mkdir as mkdir25 } from "node:fs/promises";
79329
- import { join as join90, resolve as resolve15 } from "node:path";
80131
+ import { join as join91, resolve as resolve16 } from "node:path";
79330
80132
 
79331
80133
  // src/domains/github/kit-access-checker.ts
79332
80134
  init_logger();
@@ -79456,8 +80258,8 @@ async function runPreflightChecks() {
79456
80258
 
79457
80259
  // src/domains/installation/fresh-installer.ts
79458
80260
  init_metadata_migration();
79459
- import { existsSync as existsSync37, readdirSync as readdirSync3, rmSync as rmSync3, rmdirSync as rmdirSync2, unlinkSync as unlinkSync4 } from "node:fs";
79460
- import { dirname as dirname17, join as join89, resolve as resolve14 } from "node:path";
80261
+ import { existsSync as existsSync38, readdirSync as readdirSync3, rmSync as rmSync3, rmdirSync as rmdirSync2, unlinkSync as unlinkSync4 } from "node:fs";
80262
+ import { dirname as dirname17, join as join90, resolve as resolve15 } from "node:path";
79461
80263
  init_logger();
79462
80264
  init_safe_spinner();
79463
80265
  var import_fs_extra31 = __toESM(require_lib3(), 1);
@@ -79505,15 +80307,15 @@ async function analyzeFreshInstallation(claudeDir2) {
79505
80307
  };
79506
80308
  }
79507
80309
  function cleanupEmptyDirectories2(filePath, claudeDir2) {
79508
- const normalizedClaudeDir = resolve14(claudeDir2);
79509
- let currentDir = resolve14(dirname17(filePath));
80310
+ const normalizedClaudeDir = resolve15(claudeDir2);
80311
+ let currentDir = resolve15(dirname17(filePath));
79510
80312
  while (currentDir !== normalizedClaudeDir && currentDir.startsWith(normalizedClaudeDir)) {
79511
80313
  try {
79512
80314
  const entries = readdirSync3(currentDir);
79513
80315
  if (entries.length === 0) {
79514
80316
  rmdirSync2(currentDir);
79515
80317
  logger.debug(`Removed empty directory: ${currentDir}`);
79516
- currentDir = resolve14(dirname17(currentDir));
80318
+ currentDir = resolve15(dirname17(currentDir));
79517
80319
  } else {
79518
80320
  break;
79519
80321
  }
@@ -79530,9 +80332,9 @@ async function removeFilesByOwnership(claudeDir2, analysis, includeModified) {
79530
80332
  const filesToRemove = includeModified ? [...analysis.ckFiles, ...analysis.ckModifiedFiles] : analysis.ckFiles;
79531
80333
  const filesToPreserve = includeModified ? analysis.userFiles : [...analysis.ckModifiedFiles, ...analysis.userFiles];
79532
80334
  for (const file of filesToRemove) {
79533
- const fullPath = join89(claudeDir2, file.path);
80335
+ const fullPath = join90(claudeDir2, file.path);
79534
80336
  try {
79535
- if (existsSync37(fullPath)) {
80337
+ if (existsSync38(fullPath)) {
79536
80338
  unlinkSync4(fullPath);
79537
80339
  removedFiles.push(file.path);
79538
80340
  logger.debug(`Removed: ${file.path}`);
@@ -79555,7 +80357,7 @@ async function removeFilesByOwnership(claudeDir2, analysis, includeModified) {
79555
80357
  };
79556
80358
  }
79557
80359
  async function updateMetadataAfterFresh(claudeDir2, removedFiles) {
79558
- const metadataPath = join89(claudeDir2, "metadata.json");
80360
+ const metadataPath = join90(claudeDir2, "metadata.json");
79559
80361
  if (!await import_fs_extra31.pathExists(metadataPath)) {
79560
80362
  return;
79561
80363
  }
@@ -79598,7 +80400,7 @@ async function removeSubdirectoriesFallback(claudeDir2) {
79598
80400
  const removedFiles = [];
79599
80401
  let removedDirCount = 0;
79600
80402
  for (const subdir of CLAUDEKIT_SUBDIRECTORIES) {
79601
- const subdirPath = join89(claudeDir2, subdir);
80403
+ const subdirPath = join90(claudeDir2, subdir);
79602
80404
  if (await import_fs_extra31.pathExists(subdirPath)) {
79603
80405
  rmSync3(subdirPath, { recursive: true, force: true });
79604
80406
  removedDirCount++;
@@ -79606,7 +80408,7 @@ async function removeSubdirectoriesFallback(claudeDir2) {
79606
80408
  logger.debug(`Removed subdirectory: ${subdir}/`);
79607
80409
  }
79608
80410
  }
79609
- const metadataPath = join89(claudeDir2, "metadata.json");
80411
+ const metadataPath = join90(claudeDir2, "metadata.json");
79610
80412
  if (await import_fs_extra31.pathExists(metadataPath)) {
79611
80413
  unlinkSync4(metadataPath);
79612
80414
  removedFiles.push("metadata.json");
@@ -79824,7 +80626,7 @@ async function handleSelection(ctx) {
79824
80626
  }
79825
80627
  }
79826
80628
  }
79827
- const resolvedDir = resolve15(targetDir);
80629
+ const resolvedDir = resolve16(targetDir);
79828
80630
  logger.info(`Target directory: ${resolvedDir}`);
79829
80631
  if (!ctx.options.global && PathResolver.isLocalSameAsGlobal(resolvedDir)) {
79830
80632
  logger.warning("You're at HOME directory. Installing here modifies your GLOBAL ClaudeKit.");
@@ -79858,7 +80660,7 @@ async function handleSelection(ctx) {
79858
80660
  }
79859
80661
  if (!ctx.options.fresh) {
79860
80662
  const prefix = PathResolver.getPathPrefix(ctx.options.global);
79861
- const claudeDir2 = prefix ? join90(resolvedDir, prefix) : resolvedDir;
80663
+ const claudeDir2 = prefix ? join91(resolvedDir, prefix) : resolvedDir;
79862
80664
  try {
79863
80665
  const existingMetadata = await readManifest(claudeDir2);
79864
80666
  if (existingMetadata?.kits) {
@@ -79890,7 +80692,7 @@ async function handleSelection(ctx) {
79890
80692
  }
79891
80693
  if (ctx.options.fresh) {
79892
80694
  const prefix = PathResolver.getPathPrefix(ctx.options.global);
79893
- const claudeDir2 = prefix ? join90(resolvedDir, prefix) : resolvedDir;
80695
+ const claudeDir2 = prefix ? join91(resolvedDir, prefix) : resolvedDir;
79894
80696
  const canProceed = await handleFreshInstallation(claudeDir2, ctx.prompts);
79895
80697
  if (!canProceed) {
79896
80698
  return { ...ctx, cancelled: true };
@@ -79909,7 +80711,7 @@ async function handleSelection(ctx) {
79909
80711
  logger.info("Fetching available versions...");
79910
80712
  let currentVersion = null;
79911
80713
  try {
79912
- const metadataPath = ctx.options.global ? join90(PathResolver.getGlobalKitDir(), "metadata.json") : join90(resolvedDir, ".claude", "metadata.json");
80714
+ const metadataPath = ctx.options.global ? join91(PathResolver.getGlobalKitDir(), "metadata.json") : join91(resolvedDir, ".claude", "metadata.json");
79913
80715
  const metadata = await readClaudeKitMetadata(metadataPath);
79914
80716
  currentVersion = metadata?.version || null;
79915
80717
  if (currentVersion) {
@@ -79984,7 +80786,7 @@ async function handleSelection(ctx) {
79984
80786
  }
79985
80787
  // src/commands/init/phases/sync-handler.ts
79986
80788
  import { copyFile as copyFile7, mkdir as mkdir26, open as open4, readFile as readFile39, rename as rename3, stat as stat17, unlink as unlink8, writeFile as writeFile25 } from "node:fs/promises";
79987
- import { dirname as dirname18, join as join91, resolve as resolve16 } from "node:path";
80789
+ import { dirname as dirname18, join as join92, resolve as resolve17 } from "node:path";
79988
80790
  init_logger();
79989
80791
  init_path_resolver();
79990
80792
  var import_fs_extra33 = __toESM(require_lib3(), 1);
@@ -79993,14 +80795,14 @@ async function handleSync(ctx) {
79993
80795
  if (!ctx.options.sync) {
79994
80796
  return ctx;
79995
80797
  }
79996
- const resolvedDir = ctx.options.global ? PathResolver.getGlobalKitDir() : resolve16(ctx.options.dir || ".");
79997
- const claudeDir2 = ctx.options.global ? resolvedDir : join91(resolvedDir, ".claude");
80798
+ const resolvedDir = ctx.options.global ? PathResolver.getGlobalKitDir() : resolve17(ctx.options.dir || ".");
80799
+ const claudeDir2 = ctx.options.global ? resolvedDir : join92(resolvedDir, ".claude");
79998
80800
  if (!await import_fs_extra33.pathExists(claudeDir2)) {
79999
80801
  logger.error("Cannot sync: no .claude directory found");
80000
80802
  ctx.prompts.note("Run 'ck init' without --sync to install first.", "No Installation Found");
80001
80803
  return { ...ctx, cancelled: true };
80002
80804
  }
80003
- const metadataPath = join91(claudeDir2, "metadata.json");
80805
+ const metadataPath = join92(claudeDir2, "metadata.json");
80004
80806
  if (!await import_fs_extra33.pathExists(metadataPath)) {
80005
80807
  logger.error("Cannot sync: no metadata.json found");
80006
80808
  ctx.prompts.note(`Your installation may be from an older version.
@@ -80100,7 +80902,7 @@ function getLockTimeout() {
80100
80902
  var STALE_LOCK_THRESHOLD_MS = 5 * 60 * 1000;
80101
80903
  async function acquireSyncLock(global3) {
80102
80904
  const cacheDir = PathResolver.getCacheDir(global3);
80103
- const lockPath = join91(cacheDir, ".sync-lock");
80905
+ const lockPath = join92(cacheDir, ".sync-lock");
80104
80906
  const startTime = Date.now();
80105
80907
  const lockTimeout = getLockTimeout();
80106
80908
  await mkdir26(dirname18(lockPath), { recursive: true });
@@ -80127,7 +80929,7 @@ async function acquireSyncLock(global3) {
80127
80929
  }
80128
80930
  logger.debug(`Lock stat failed: ${statError}`);
80129
80931
  }
80130
- await new Promise((resolve17) => setTimeout(resolve17, 100));
80932
+ await new Promise((resolve18) => setTimeout(resolve18, 100));
80131
80933
  continue;
80132
80934
  }
80133
80935
  throw err;
@@ -80146,10 +80948,10 @@ async function executeSyncMerge(ctx) {
80146
80948
  const releaseLock = await acquireSyncLock(ctx.options.global);
80147
80949
  try {
80148
80950
  const trackedFiles = ctx.syncTrackedFiles;
80149
- const upstreamDir = ctx.options.global ? join91(ctx.extractDir, ".claude") : ctx.extractDir;
80951
+ const upstreamDir = ctx.options.global ? join92(ctx.extractDir, ".claude") : ctx.extractDir;
80150
80952
  let deletions = [];
80151
80953
  try {
80152
- const sourceMetadataPath = join91(upstreamDir, "metadata.json");
80954
+ const sourceMetadataPath = join92(upstreamDir, "metadata.json");
80153
80955
  if (await import_fs_extra33.pathExists(sourceMetadataPath)) {
80154
80956
  const content = await readFile39(sourceMetadataPath, "utf-8");
80155
80957
  const sourceMetadata = JSON.parse(content);
@@ -80181,7 +80983,7 @@ async function executeSyncMerge(ctx) {
80181
80983
  try {
80182
80984
  const sourcePath = await validateSyncPath(upstreamDir, file.path);
80183
80985
  const targetPath = await validateSyncPath(ctx.claudeDir, file.path);
80184
- const targetDir = join91(targetPath, "..");
80986
+ const targetDir = join92(targetPath, "..");
80185
80987
  try {
80186
80988
  await mkdir26(targetDir, { recursive: true });
80187
80989
  } catch (mkdirError) {
@@ -80352,7 +81154,7 @@ async function createBackup(claudeDir2, files, backupDir) {
80352
81154
  const sourcePath = await validateSyncPath(claudeDir2, file.path);
80353
81155
  if (await import_fs_extra33.pathExists(sourcePath)) {
80354
81156
  const targetPath = await validateSyncPath(backupDir, file.path);
80355
- const targetDir = join91(targetPath, "..");
81157
+ const targetDir = join92(targetPath, "..");
80356
81158
  await mkdir26(targetDir, { recursive: true });
80357
81159
  await copyFile7(sourcePath, targetPath);
80358
81160
  }
@@ -80367,7 +81169,7 @@ async function createBackup(claudeDir2, files, backupDir) {
80367
81169
  }
80368
81170
  // src/commands/init/phases/transform-handler.ts
80369
81171
  init_config_manager();
80370
- import { join as join95 } from "node:path";
81172
+ import { join as join96 } from "node:path";
80371
81173
 
80372
81174
  // src/services/transformers/folder-path-transformer.ts
80373
81175
  init_logger();
@@ -80378,38 +81180,38 @@ init_logger();
80378
81180
  init_types2();
80379
81181
  var import_fs_extra34 = __toESM(require_lib3(), 1);
80380
81182
  import { rename as rename4, rm as rm8 } from "node:fs/promises";
80381
- import { join as join92, relative as relative15 } from "node:path";
81183
+ import { join as join93, relative as relative15 } from "node:path";
80382
81184
  async function collectDirsToRename(extractDir, folders) {
80383
81185
  const dirsToRename = [];
80384
81186
  if (folders.docs !== DEFAULT_FOLDERS.docs) {
80385
- const docsPath = join92(extractDir, DEFAULT_FOLDERS.docs);
81187
+ const docsPath = join93(extractDir, DEFAULT_FOLDERS.docs);
80386
81188
  if (await import_fs_extra34.pathExists(docsPath)) {
80387
81189
  dirsToRename.push({
80388
81190
  from: docsPath,
80389
- to: join92(extractDir, folders.docs)
81191
+ to: join93(extractDir, folders.docs)
80390
81192
  });
80391
81193
  }
80392
- const claudeDocsPath = join92(extractDir, ".claude", DEFAULT_FOLDERS.docs);
81194
+ const claudeDocsPath = join93(extractDir, ".claude", DEFAULT_FOLDERS.docs);
80393
81195
  if (await import_fs_extra34.pathExists(claudeDocsPath)) {
80394
81196
  dirsToRename.push({
80395
81197
  from: claudeDocsPath,
80396
- to: join92(extractDir, ".claude", folders.docs)
81198
+ to: join93(extractDir, ".claude", folders.docs)
80397
81199
  });
80398
81200
  }
80399
81201
  }
80400
81202
  if (folders.plans !== DEFAULT_FOLDERS.plans) {
80401
- const plansPath = join92(extractDir, DEFAULT_FOLDERS.plans);
81203
+ const plansPath = join93(extractDir, DEFAULT_FOLDERS.plans);
80402
81204
  if (await import_fs_extra34.pathExists(plansPath)) {
80403
81205
  dirsToRename.push({
80404
81206
  from: plansPath,
80405
- to: join92(extractDir, folders.plans)
81207
+ to: join93(extractDir, folders.plans)
80406
81208
  });
80407
81209
  }
80408
- const claudePlansPath = join92(extractDir, ".claude", DEFAULT_FOLDERS.plans);
81210
+ const claudePlansPath = join93(extractDir, ".claude", DEFAULT_FOLDERS.plans);
80409
81211
  if (await import_fs_extra34.pathExists(claudePlansPath)) {
80410
81212
  dirsToRename.push({
80411
81213
  from: claudePlansPath,
80412
- to: join92(extractDir, ".claude", folders.plans)
81214
+ to: join93(extractDir, ".claude", folders.plans)
80413
81215
  });
80414
81216
  }
80415
81217
  }
@@ -80449,8 +81251,8 @@ async function renameFolders(dirsToRename, extractDir, options2) {
80449
81251
  // src/services/transformers/folder-transform/path-replacer.ts
80450
81252
  init_logger();
80451
81253
  init_types2();
80452
- import { readFile as readFile40, readdir as readdir28, writeFile as writeFile26 } from "node:fs/promises";
80453
- import { join as join93, relative as relative16 } from "node:path";
81254
+ import { readFile as readFile40, readdir as readdir29, writeFile as writeFile26 } from "node:fs/promises";
81255
+ import { join as join94, relative as relative16 } from "node:path";
80454
81256
  var TRANSFORMABLE_FILE_PATTERNS = [
80455
81257
  ".md",
80456
81258
  ".txt",
@@ -80501,9 +81303,9 @@ function compileReplacements(replacements) {
80501
81303
  async function transformFileContents(dir, compiledReplacements, options2) {
80502
81304
  let filesChanged = 0;
80503
81305
  let replacementsCount = 0;
80504
- const entries = await readdir28(dir, { withFileTypes: true });
81306
+ const entries = await readdir29(dir, { withFileTypes: true });
80505
81307
  for (const entry of entries) {
80506
- const fullPath = join93(dir, entry.name);
81308
+ const fullPath = join94(dir, entry.name);
80507
81309
  if (entry.isDirectory()) {
80508
81310
  if (entry.name === "node_modules" || entry.name === ".git") {
80509
81311
  continue;
@@ -80638,9 +81440,9 @@ async function transformFolderPaths(extractDir, folders, options2 = {}) {
80638
81440
 
80639
81441
  // src/services/transformers/global-path-transformer.ts
80640
81442
  init_logger();
80641
- import { readFile as readFile41, readdir as readdir29, writeFile as writeFile27 } from "node:fs/promises";
81443
+ import { readFile as readFile41, readdir as readdir30, writeFile as writeFile27 } from "node:fs/promises";
80642
81444
  import { platform as platform13 } from "node:os";
80643
- import { extname as extname4, join as join94 } from "node:path";
81445
+ import { extname as extname4, join as join95 } from "node:path";
80644
81446
  var IS_WINDOWS4 = platform13() === "win32";
80645
81447
  var HOME_PREFIX = IS_WINDOWS4 ? "%USERPROFILE%" : "$HOME";
80646
81448
  function getHomeDirPrefix() {
@@ -80748,9 +81550,9 @@ async function transformPathsForGlobalInstall(directory, options2 = {}) {
80748
81550
  let filesSkipped = 0;
80749
81551
  const skippedFiles = [];
80750
81552
  async function processDirectory2(dir) {
80751
- const entries = await readdir29(dir, { withFileTypes: true });
81553
+ const entries = await readdir30(dir, { withFileTypes: true });
80752
81554
  for (const entry of entries) {
80753
- const fullPath = join94(dir, entry.name);
81555
+ const fullPath = join95(dir, entry.name);
80754
81556
  if (entry.isDirectory()) {
80755
81557
  if (entry.name === "node_modules" || entry.name.startsWith(".") && entry.name !== ".claude") {
80756
81558
  continue;
@@ -80826,7 +81628,7 @@ async function handleTransforms(ctx) {
80826
81628
  logger.debug(ctx.options.global ? "Saved folder configuration to ~/.claude/.ck.json" : "Saved folder configuration to .claude/.ck.json");
80827
81629
  }
80828
81630
  }
80829
- const claudeDir2 = ctx.options.global ? ctx.resolvedDir : join95(ctx.resolvedDir, ".claude");
81631
+ const claudeDir2 = ctx.options.global ? ctx.resolvedDir : join96(ctx.resolvedDir, ".claude");
80830
81632
  return {
80831
81633
  ...ctx,
80832
81634
  foldersConfig,
@@ -81019,7 +81821,7 @@ var import_picocolors22 = __toESM(require_picocolors(), 1);
81019
81821
 
81020
81822
  // src/commands/new/phases/directory-setup.ts
81021
81823
  init_config_manager();
81022
- import { resolve as resolve17 } from "node:path";
81824
+ import { resolve as resolve18 } from "node:path";
81023
81825
  init_logger();
81024
81826
  init_path_resolver();
81025
81827
  init_types2();
@@ -81104,7 +81906,7 @@ async function directorySetup(validOptions, prompts) {
81104
81906
  targetDir = await prompts.getDirectory(targetDir);
81105
81907
  }
81106
81908
  }
81107
- const resolvedDir = resolve17(targetDir);
81909
+ const resolvedDir = resolve18(targetDir);
81108
81910
  logger.info(`Target directory: ${resolvedDir}`);
81109
81911
  if (PathResolver.isLocalSameAsGlobal(resolvedDir)) {
81110
81912
  logger.warning("You're creating a project at HOME directory.");
@@ -81161,7 +81963,7 @@ async function handleDirectorySetup(ctx) {
81161
81963
  // src/commands/new/phases/project-creation.ts
81162
81964
  init_config_manager();
81163
81965
  init_github_client();
81164
- import { join as join96 } from "node:path";
81966
+ import { join as join97 } from "node:path";
81165
81967
  init_logger();
81166
81968
  init_output_manager();
81167
81969
  init_types2();
@@ -81287,7 +82089,7 @@ async function projectCreation(kit, resolvedDir, validOptions, isNonInteractive2
81287
82089
  output.section("Installing");
81288
82090
  logger.verbose("Installation target", { directory: resolvedDir });
81289
82091
  const merger = new FileMerger;
81290
- const claudeDir2 = join96(resolvedDir, ".claude");
82092
+ const claudeDir2 = join97(resolvedDir, ".claude");
81291
82093
  merger.setMultiKitContext(claudeDir2, kit);
81292
82094
  if (validOptions.exclude && validOptions.exclude.length > 0) {
81293
82095
  merger.addIgnorePatterns(validOptions.exclude);
@@ -81334,7 +82136,7 @@ async function handleProjectCreation(ctx) {
81334
82136
  }
81335
82137
  // src/commands/new/phases/post-setup.ts
81336
82138
  init_projects_registry();
81337
- import { join as join97 } from "node:path";
82139
+ import { join as join98 } from "node:path";
81338
82140
  init_package_installer();
81339
82141
  init_logger();
81340
82142
  init_path_resolver();
@@ -81366,9 +82168,9 @@ async function postSetup(resolvedDir, validOptions, isNonInteractive2, prompts)
81366
82168
  withSudo: validOptions.withSudo
81367
82169
  });
81368
82170
  }
81369
- const claudeDir2 = join97(resolvedDir, ".claude");
82171
+ const claudeDir2 = join98(resolvedDir, ".claude");
81370
82172
  await promptSetupWizardIfNeeded({
81371
- envPath: join97(claudeDir2, ".env"),
82173
+ envPath: join98(claudeDir2, ".env"),
81372
82174
  claudeDir: claudeDir2,
81373
82175
  isGlobal: false,
81374
82176
  isNonInteractive: isNonInteractive2,
@@ -81440,13 +82242,13 @@ init_claudekit_data2();
81440
82242
  init_logger();
81441
82243
  init_safe_prompts();
81442
82244
  var import_picocolors23 = __toESM(require_picocolors(), 1);
81443
- import { existsSync as existsSync38 } from "node:fs";
81444
- import { resolve as resolve18 } from "node:path";
82245
+ import { existsSync as existsSync39 } from "node:fs";
82246
+ import { resolve as resolve19 } from "node:path";
81445
82247
  async function handleAdd(projectPath, options2) {
81446
82248
  logger.debug(`Adding project: ${projectPath}, options: ${JSON.stringify(options2)}`);
81447
82249
  intro("Add Project");
81448
- const absolutePath = resolve18(projectPath);
81449
- if (!existsSync38(absolutePath)) {
82250
+ const absolutePath = resolve19(projectPath);
82251
+ if (!existsSync39(absolutePath)) {
81450
82252
  log.error(`Path does not exist: ${absolutePath}`);
81451
82253
  process.exitCode = 1;
81452
82254
  return;
@@ -82374,7 +83176,7 @@ async function detectInstallations() {
82374
83176
 
82375
83177
  // src/commands/uninstall/removal-handler.ts
82376
83178
  import { readdirSync as readdirSync5, rmSync as rmSync5 } from "node:fs";
82377
- import { join as join99, resolve as resolve19, sep as sep4 } from "node:path";
83179
+ import { join as join100, resolve as resolve20, sep as sep4 } from "node:path";
82378
83180
  init_logger();
82379
83181
  init_safe_prompts();
82380
83182
  init_safe_spinner();
@@ -82383,7 +83185,7 @@ var import_fs_extra37 = __toESM(require_lib3(), 1);
82383
83185
  // src/commands/uninstall/analysis-handler.ts
82384
83186
  init_metadata_migration();
82385
83187
  import { readdirSync as readdirSync4, rmSync as rmSync4 } from "node:fs";
82386
- import { dirname as dirname19, join as join98 } from "node:path";
83188
+ import { dirname as dirname19, join as join99 } from "node:path";
82387
83189
  init_logger();
82388
83190
  init_safe_prompts();
82389
83191
  var import_picocolors27 = __toESM(require_picocolors(), 1);
@@ -82431,7 +83233,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
82431
83233
  if (uninstallManifest.isMultiKit && kit && metadata?.kits?.[kit]) {
82432
83234
  const kitFiles = metadata.kits[kit].files || [];
82433
83235
  for (const trackedFile of kitFiles) {
82434
- const filePath = join98(installation.path, trackedFile.path);
83236
+ const filePath = join99(installation.path, trackedFile.path);
82435
83237
  if (uninstallManifest.filesToPreserve.includes(trackedFile.path)) {
82436
83238
  result.toPreserve.push({ path: trackedFile.path, reason: "shared with other kit" });
82437
83239
  continue;
@@ -82461,7 +83263,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
82461
83263
  return result;
82462
83264
  }
82463
83265
  for (const trackedFile of allTrackedFiles) {
82464
- const filePath = join98(installation.path, trackedFile.path);
83266
+ const filePath = join99(installation.path, trackedFile.path);
82465
83267
  const ownershipResult = await OwnershipChecker.checkOwnership(filePath, metadata, installation.path);
82466
83268
  if (!ownershipResult.exists)
82467
83269
  continue;
@@ -82515,8 +83317,8 @@ async function isDirectory(filePath) {
82515
83317
  }
82516
83318
  async function isPathSafeToRemove(filePath, baseDir) {
82517
83319
  try {
82518
- const resolvedPath = resolve19(filePath);
82519
- const resolvedBase = resolve19(baseDir);
83320
+ const resolvedPath = resolve20(filePath);
83321
+ const resolvedBase = resolve20(baseDir);
82520
83322
  if (!resolvedPath.startsWith(resolvedBase + sep4) && resolvedPath !== resolvedBase) {
82521
83323
  logger.debug(`Path outside installation directory: ${filePath}`);
82522
83324
  return false;
@@ -82524,7 +83326,7 @@ async function isPathSafeToRemove(filePath, baseDir) {
82524
83326
  const stats = await import_fs_extra37.lstat(filePath);
82525
83327
  if (stats.isSymbolicLink()) {
82526
83328
  const realPath = await import_fs_extra37.realpath(filePath);
82527
- const resolvedReal = resolve19(realPath);
83329
+ const resolvedReal = resolve20(realPath);
82528
83330
  if (!resolvedReal.startsWith(resolvedBase + sep4) && resolvedReal !== resolvedBase) {
82529
83331
  logger.debug(`Symlink points outside installation directory: ${filePath} -> ${realPath}`);
82530
83332
  return false;
@@ -82558,7 +83360,7 @@ async function removeInstallations(installations, options2) {
82558
83360
  let removedCount = 0;
82559
83361
  let cleanedDirs = 0;
82560
83362
  for (const item of analysis.toDelete) {
82561
- const filePath = join99(installation.path, item.path);
83363
+ const filePath = join100(installation.path, item.path);
82562
83364
  if (!await import_fs_extra37.pathExists(filePath))
82563
83365
  continue;
82564
83366
  if (!await isPathSafeToRemove(filePath, installation.path)) {
@@ -82932,8 +83734,8 @@ init_version_checker();
82932
83734
  init_logger();
82933
83735
  init_path_resolver();
82934
83736
  init_types2();
82935
- import { existsSync as existsSync39, readFileSync as readFileSync8 } from "node:fs";
82936
- import { join as join100 } from "node:path";
83737
+ import { existsSync as existsSync40, readFileSync as readFileSync9 } from "node:fs";
83738
+ import { join as join101 } from "node:path";
82937
83739
  var packageVersion = package_default.version;
82938
83740
  function formatInstalledKits(metadata) {
82939
83741
  if (!metadata.kits || Object.keys(metadata.kits).length === 0) {
@@ -82965,13 +83767,13 @@ async function displayVersion() {
82965
83767
  let localKitVersion = null;
82966
83768
  let isGlobalOnlyKit = false;
82967
83769
  const globalKitDir = PathResolver.getGlobalKitDir();
82968
- const globalMetadataPath = join100(globalKitDir, "metadata.json");
83770
+ const globalMetadataPath = join101(globalKitDir, "metadata.json");
82969
83771
  const prefix = PathResolver.getPathPrefix(false);
82970
- const localMetadataPath = prefix ? join100(process.cwd(), prefix, "metadata.json") : join100(process.cwd(), "metadata.json");
83772
+ const localMetadataPath = prefix ? join101(process.cwd(), prefix, "metadata.json") : join101(process.cwd(), "metadata.json");
82971
83773
  const isLocalSameAsGlobal = localMetadataPath === globalMetadataPath;
82972
- if (!isLocalSameAsGlobal && existsSync39(localMetadataPath)) {
83774
+ if (!isLocalSameAsGlobal && existsSync40(localMetadataPath)) {
82973
83775
  try {
82974
- const rawMetadata = JSON.parse(readFileSync8(localMetadataPath, "utf-8"));
83776
+ const rawMetadata = JSON.parse(readFileSync9(localMetadataPath, "utf-8"));
82975
83777
  const metadata = MetadataSchema.parse(rawMetadata);
82976
83778
  const kitsDisplay = formatInstalledKits(metadata);
82977
83779
  if (kitsDisplay) {
@@ -82983,9 +83785,9 @@ async function displayVersion() {
82983
83785
  logger.verbose("Failed to parse local metadata.json", { error });
82984
83786
  }
82985
83787
  }
82986
- if (existsSync39(globalMetadataPath)) {
83788
+ if (existsSync40(globalMetadataPath)) {
82987
83789
  try {
82988
- const rawMetadata = JSON.parse(readFileSync8(globalMetadataPath, "utf-8"));
83790
+ const rawMetadata = JSON.parse(readFileSync9(globalMetadataPath, "utf-8"));
82989
83791
  const metadata = MetadataSchema.parse(rawMetadata);
82990
83792
  const kitsDisplay = formatInstalledKits(metadata);
82991
83793
  if (kitsDisplay) {