claudekit-cli 4.3.1-dev.17 → 4.3.1-dev.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -12622,6 +12622,217 @@ var init_converters = __esm(() => {
12622
12622
  init_skill_md();
12623
12623
  });
12624
12624
 
12625
+ // src/shared/path-resolver.ts
12626
+ import { createHash as createHash3 } from "node:crypto";
12627
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
12628
+ import { homedir as homedir3, platform as platform2 } from "node:os";
12629
+ import { join as join2, normalize, resolve } from "node:path";
12630
+ function getEnvVar(name) {
12631
+ const val = process.env[name];
12632
+ if (!val || val.trim() === "")
12633
+ return;
12634
+ if (val.includes("..")) {
12635
+ console.warn(`Environment variable ${name} contains path traversal: ${val}`);
12636
+ return;
12637
+ }
12638
+ return val;
12639
+ }
12640
+ function isWSL() {
12641
+ try {
12642
+ return process.platform === "linux" && existsSync2("/proc/version") && readFileSync2("/proc/version", "utf8").toLowerCase().includes("microsoft");
12643
+ } catch {
12644
+ return false;
12645
+ }
12646
+ }
12647
+ function normalizeWSLPath(p) {
12648
+ if (!isWSL())
12649
+ return p;
12650
+ const windowsMatch = p.match(/^([A-Za-z]):(.*)/);
12651
+ if (windowsMatch) {
12652
+ const drive = windowsMatch[1].toLowerCase();
12653
+ const rest = windowsMatch[2].replace(/\\/g, "/");
12654
+ return `/mnt/${drive}${rest}`;
12655
+ }
12656
+ return p;
12657
+ }
12658
+
12659
+ class PathResolver {
12660
+ static getTestHomeDir() {
12661
+ return process.env.CK_TEST_HOME;
12662
+ }
12663
+ static isValidComponentName(name) {
12664
+ if (!name || typeof name !== "string") {
12665
+ return false;
12666
+ }
12667
+ const dangerousPatterns = [
12668
+ "..",
12669
+ "~"
12670
+ ];
12671
+ for (const pattern of dangerousPatterns) {
12672
+ if (name.includes(pattern)) {
12673
+ return false;
12674
+ }
12675
+ }
12676
+ const normalized = normalize(name);
12677
+ for (const pattern of dangerousPatterns) {
12678
+ if (normalized.includes(pattern)) {
12679
+ return false;
12680
+ }
12681
+ }
12682
+ if (name.startsWith("/") || normalized.startsWith("/") || /^[a-zA-Z]:/.test(name) || name.startsWith("\\\\") || normalized.startsWith("\\\\")) {
12683
+ return false;
12684
+ }
12685
+ return true;
12686
+ }
12687
+ static getConfigDir(global2 = false) {
12688
+ const testHome = PathResolver.getTestHomeDir();
12689
+ if (testHome) {
12690
+ return global2 ? join2(testHome, ".config", "claude") : join2(testHome, ".claudekit");
12691
+ }
12692
+ if (!global2) {
12693
+ return join2(homedir3(), ".claudekit");
12694
+ }
12695
+ const os = platform2();
12696
+ if (os === "win32") {
12697
+ const localAppData = getEnvVar("LOCALAPPDATA") ?? join2(homedir3(), "AppData", "Local");
12698
+ return join2(localAppData, "claude");
12699
+ }
12700
+ const xdgConfigHome = getEnvVar("XDG_CONFIG_HOME");
12701
+ if (xdgConfigHome) {
12702
+ return join2(xdgConfigHome, "claude");
12703
+ }
12704
+ return join2(homedir3(), ".config", "claude");
12705
+ }
12706
+ static getConfigFile(global2 = false) {
12707
+ return join2(PathResolver.getConfigDir(global2), "config.json");
12708
+ }
12709
+ static getCacheDir(global2 = false) {
12710
+ const testHome = PathResolver.getTestHomeDir();
12711
+ if (testHome) {
12712
+ return global2 ? join2(testHome, ".cache", "claude") : join2(testHome, ".claudekit", "cache");
12713
+ }
12714
+ if (!global2) {
12715
+ return join2(homedir3(), ".claudekit", "cache");
12716
+ }
12717
+ const os = platform2();
12718
+ if (os === "win32") {
12719
+ const localAppData = getEnvVar("LOCALAPPDATA") ?? join2(homedir3(), "AppData", "Local");
12720
+ return join2(localAppData, "claude", "cache");
12721
+ }
12722
+ const xdgCacheHome = getEnvVar("XDG_CACHE_HOME");
12723
+ if (xdgCacheHome) {
12724
+ return join2(xdgCacheHome, "claude");
12725
+ }
12726
+ return join2(homedir3(), ".cache", "claude");
12727
+ }
12728
+ static getGlobalKitDir() {
12729
+ const testHome = PathResolver.getTestHomeDir();
12730
+ if (testHome) {
12731
+ return join2(testHome, ".claude");
12732
+ }
12733
+ const claudeConfigDir = process.env.CLAUDE_CONFIG_DIR;
12734
+ if (claudeConfigDir) {
12735
+ return claudeConfigDir;
12736
+ }
12737
+ return join2(homedir3(), ".claude");
12738
+ }
12739
+ static getClaudeKitDir() {
12740
+ const testHome = PathResolver.getTestHomeDir();
12741
+ if (testHome) {
12742
+ return join2(testHome, ".claudekit");
12743
+ }
12744
+ return join2(homedir3(), ".claudekit");
12745
+ }
12746
+ static getProjectsRegistryPath() {
12747
+ return join2(PathResolver.getClaudeKitDir(), "projects.json");
12748
+ }
12749
+ static getOpenCodeDir(global2, baseDir) {
12750
+ const testHome = PathResolver.getTestHomeDir();
12751
+ if (testHome) {
12752
+ return global2 ? join2(testHome, ".config", "opencode") : join2(baseDir || testHome, ".opencode");
12753
+ }
12754
+ if (!global2) {
12755
+ return join2(baseDir || process.cwd(), ".opencode");
12756
+ }
12757
+ const xdgConfigHome = process.env.XDG_CONFIG_HOME;
12758
+ if (xdgConfigHome) {
12759
+ return join2(xdgConfigHome, "opencode");
12760
+ }
12761
+ return join2(homedir3(), ".config", "opencode");
12762
+ }
12763
+ static getPathPrefix(global2) {
12764
+ return global2 ? "" : ".claude";
12765
+ }
12766
+ static buildSkillsPath(baseDir, global2) {
12767
+ const prefix = PathResolver.getPathPrefix(global2);
12768
+ if (prefix) {
12769
+ return join2(baseDir, prefix, "skills");
12770
+ }
12771
+ return join2(baseDir, "skills");
12772
+ }
12773
+ static buildComponentPath(baseDir, component, global2) {
12774
+ if (!PathResolver.isValidComponentName(component)) {
12775
+ throw new Error(`Invalid component name: "${component}" contains path traversal patterns. Valid names are simple directory names like "agents", "commands", "rules", "skills", or "hooks".`);
12776
+ }
12777
+ const prefix = PathResolver.getPathPrefix(global2);
12778
+ if (prefix) {
12779
+ return join2(baseDir, prefix, component);
12780
+ }
12781
+ return join2(baseDir, component);
12782
+ }
12783
+ static getBackupDir(timestamp) {
12784
+ const testHome = PathResolver.getTestHomeDir();
12785
+ const baseDir = testHome ? join2(testHome, ".claudekit") : join2(homedir3(), ".claudekit");
12786
+ if (timestamp) {
12787
+ return join2(baseDir, "backups", timestamp);
12788
+ }
12789
+ const now = new Date;
12790
+ const dateStr = now.toISOString().replace(/[:.]/g, "-").slice(0, 19);
12791
+ const ms = now.getMilliseconds().toString().padStart(3, "0");
12792
+ const random = Math.random().toString(36).slice(2, 6);
12793
+ const ts = `${dateStr}-${ms}-${random}`;
12794
+ return join2(baseDir, "backups", ts);
12795
+ }
12796
+ static normalizeWSLPath(p) {
12797
+ return normalizeWSLPath(p);
12798
+ }
12799
+ static isWSL() {
12800
+ return isWSL();
12801
+ }
12802
+ static isAtHomeDirectory(cwd2) {
12803
+ const currentDir = normalize(cwd2 || process.cwd());
12804
+ const homeDir = normalize(homedir3());
12805
+ return currentDir === homeDir;
12806
+ }
12807
+ static getLocalClaudeDir(baseDir) {
12808
+ const dir = baseDir || process.cwd();
12809
+ return join2(dir, ".claude");
12810
+ }
12811
+ static isLocalSameAsGlobal(cwd2) {
12812
+ const localPath = normalize(PathResolver.getLocalClaudeDir(cwd2));
12813
+ const globalPath = normalize(PathResolver.getGlobalKitDir());
12814
+ return localPath === globalPath;
12815
+ }
12816
+ static isGlobPattern(pattern) {
12817
+ return pattern.includes("*") || pattern.includes("?") || pattern.includes("{");
12818
+ }
12819
+ static computeProjectHash(projectRoot) {
12820
+ let normalized = resolve(projectRoot).replace(/[/\\]+$/, "");
12821
+ if (process.platform === "darwin" || process.platform === "win32") {
12822
+ normalized = normalized.toLowerCase();
12823
+ }
12824
+ return createHash3("sha256").update(normalized).digest("hex").slice(0, 12);
12825
+ }
12826
+ static getPlansRegistriesDir() {
12827
+ return join2(PathResolver.getGlobalKitDir(), "plans-registries");
12828
+ }
12829
+ static getPlansRegistryPath(projectRoot) {
12830
+ const hash = PathResolver.computeProjectHash(projectRoot);
12831
+ return join2(PathResolver.getPlansRegistriesDir(), `${hash}.json`);
12832
+ }
12833
+ }
12834
+ var init_path_resolver = () => {};
12835
+
12625
12836
  // src/commands/portable/reconcile-types.ts
12626
12837
  function normalizeChecksum(checksum) {
12627
12838
  if (!checksum)
@@ -12686,18 +12897,16 @@ function providerConfigAppliesToType(config, type) {
12686
12897
  var UNKNOWN_CHECKSUM = "unknown";
12687
12898
 
12688
12899
  // src/commands/portable/portable-registry.ts
12689
- import { existsSync as existsSync2 } from "node:fs";
12900
+ import { existsSync as existsSync3 } from "node:fs";
12690
12901
  import { mkdir, readFile as readFile2, rename, unlink, writeFile } from "node:fs/promises";
12691
- import { homedir as homedir3 } from "node:os";
12692
- import { dirname, join as join2, resolve } from "node:path";
12902
+ import { dirname, join as join3, resolve as resolve2 } from "node:path";
12693
12903
  function getPortableRegistryPaths() {
12694
- const home2 = homedir3();
12695
- const claudekitDir = join2(home2, ".claudekit");
12904
+ const claudekitDir = PathResolver.getConfigDir(false);
12696
12905
  return {
12697
- registryPath: join2(claudekitDir, "portable-registry.json"),
12698
- registryLockPath: join2(claudekitDir, "portable-registry.lock"),
12699
- legacyRegistryPath: join2(claudekitDir, "skill-registry.json"),
12700
- migrationLockPath: join2(claudekitDir, ".migration.lock")
12906
+ registryPath: join3(claudekitDir, "portable-registry.json"),
12907
+ registryLockPath: join3(claudekitDir, "portable-registry.lock"),
12908
+ legacyRegistryPath: join3(claudekitDir, "skill-registry.json"),
12909
+ migrationLockPath: join3(claudekitDir, ".migration.lock")
12701
12910
  };
12702
12911
  }
12703
12912
  function isErrnoCode(error, code) {
@@ -12721,12 +12930,12 @@ function getCliVersion() {
12721
12930
  if (process.env.npm_package_version) {
12722
12931
  return process.env.npm_package_version;
12723
12932
  }
12724
- const { readFileSync: readFileSync2 } = __require("node:fs");
12933
+ const { readFileSync: readFileSync3 } = __require("node:fs");
12725
12934
  const { dirname: dn, join: jp } = __require("node:path");
12726
12935
  const { fileURLToPath } = __require("node:url");
12727
12936
  const __dirname2 = dn(fileURLToPath(import.meta.url));
12728
12937
  const pkgPath = jp(__dirname2, "../../../package.json");
12729
- const pkg = JSON.parse(readFileSync2(pkgPath, "utf-8"));
12938
+ const pkg = JSON.parse(readFileSync3(pkgPath, "utf-8"));
12730
12939
  return pkg.version || "unknown";
12731
12940
  } catch {
12732
12941
  return "unknown";
@@ -12762,7 +12971,7 @@ async function migrateRegistryV2ToV3(v2Registry) {
12762
12971
  for (const item of v2Registry.installations) {
12763
12972
  let targetChecksum = UNKNOWN_CHECKSUM;
12764
12973
  try {
12765
- if (existsSync2(item.path)) {
12974
+ if (existsSync3(item.path)) {
12766
12975
  targetChecksum = await computeFileChecksum(item.path);
12767
12976
  }
12768
12977
  } catch (error) {
@@ -12819,7 +13028,7 @@ async function repairStaleRegistryV3(registry) {
12819
13028
  const installations = [];
12820
13029
  for (const item of registry.installations) {
12821
13030
  let targetChecksum = normalizeChecksum(getStringField(item, "targetChecksum")) || UNKNOWN_CHECKSUM;
12822
- if (targetChecksum === UNKNOWN_CHECKSUM && existsSync2(item.path)) {
13031
+ if (targetChecksum === UNKNOWN_CHECKSUM && existsSync3(item.path)) {
12823
13032
  try {
12824
13033
  targetChecksum = await computeFileChecksum(item.path);
12825
13034
  } catch {
@@ -12906,7 +13115,7 @@ async function isMigrationLocked() {
12906
13115
  async function createMigrationLock() {
12907
13116
  const { migrationLockPath } = getPortableRegistryPaths();
12908
13117
  const lockDir = dirname(migrationLockPath);
12909
- if (!existsSync2(lockDir)) {
13118
+ if (!existsSync3(lockDir)) {
12910
13119
  await mkdir(lockDir, { recursive: true });
12911
13120
  }
12912
13121
  await writeFile(migrationLockPath, Date.now().toString(), "utf-8");
@@ -12994,7 +13203,7 @@ async function readPortableRegistryWithinRegistryLock() {
12994
13203
  async function writePortableRegistry(registry) {
12995
13204
  const { registryPath } = getPortableRegistryPaths();
12996
13205
  const dir = dirname(registryPath);
12997
- if (!existsSync2(dir)) {
13206
+ if (!existsSync3(dir)) {
12998
13207
  await mkdir(dir, { recursive: true });
12999
13208
  }
13000
13209
  const normalizedRegistry = normalizePortableRegistryChecksums(registry);
@@ -13012,10 +13221,10 @@ async function writePortableRegistry(registry) {
13012
13221
  async function withRegistryLock(operation) {
13013
13222
  const { registryLockPath } = getPortableRegistryPaths();
13014
13223
  const lockDir = dirname(registryLockPath);
13015
- if (!existsSync2(lockDir)) {
13224
+ if (!existsSync3(lockDir)) {
13016
13225
  await mkdir(lockDir, { recursive: true });
13017
13226
  }
13018
- if (!existsSync2(registryLockPath)) {
13227
+ if (!existsSync3(registryLockPath)) {
13019
13228
  await writeFile(registryLockPath, "", "utf-8");
13020
13229
  }
13021
13230
  const release = await import_proper_lockfile.default.lock(registryLockPath, {
@@ -13057,7 +13266,7 @@ async function addPortableInstallation(item, type, provider, global2, path2, sou
13057
13266
  async function removePortableInstallation(item, type, provider, global2, options2) {
13058
13267
  return withRegistryLock(async () => {
13059
13268
  const registry = await readPortableRegistryWithinRegistryLock();
13060
- const index = registry.installations.findIndex((i) => i.item === item && i.type === type && i.provider === provider && i.global === global2 && (!options2?.path || resolve(i.path) === resolve(options2.path)));
13269
+ const index = registry.installations.findIndex((i) => i.item === item && i.type === type && i.provider === provider && i.global === global2 && (!options2?.path || resolve2(i.path) === resolve2(options2.path)));
13061
13270
  if (index === -1)
13062
13271
  return null;
13063
13272
  const [removed] = registry.installations.splice(index, 1);
@@ -13107,7 +13316,7 @@ async function syncPortableRegistry() {
13107
13316
  const registry = await readPortableRegistryWithinRegistryLock();
13108
13317
  const removed = [];
13109
13318
  registry.installations = registry.installations.filter((i) => {
13110
- if (!existsSync2(i.path)) {
13319
+ if (!existsSync3(i.path)) {
13111
13320
  removed.push(i);
13112
13321
  return false;
13113
13322
  }
@@ -13123,6 +13332,7 @@ var import_proper_lockfile, PortableInstallationSchema, PortableRegistrySchema,
13123
13332
  var init_portable_registry = __esm(() => {
13124
13333
  init_zod();
13125
13334
  init_logger();
13335
+ init_path_resolver();
13126
13336
  init_checksum_utils();
13127
13337
  import_proper_lockfile = __toESM(require_proper_lockfile(), 1);
13128
13338
  PortableInstallationSchema = exports_external.object({
@@ -13181,10 +13391,10 @@ var init_portable_registry = __esm(() => {
13181
13391
  });
13182
13392
 
13183
13393
  // src/commands/portable/codex-toml-installer.ts
13184
- import { existsSync as existsSync3 } from "node:fs";
13394
+ import { existsSync as existsSync4 } from "node:fs";
13185
13395
  import { mkdir as mkdir2, readFile as readFile3, realpath, unlink as unlink2, writeFile as writeFile2 } from "node:fs/promises";
13186
13396
  import { homedir as homedir4 } from "node:os";
13187
- import { basename, dirname as dirname2, isAbsolute, join as join3, relative, resolve as resolve2 } from "node:path";
13397
+ import { basename, dirname as dirname2, isAbsolute, join as join4, relative, resolve as resolve3 } from "node:path";
13188
13398
  function resolveCodexTomlRegistryDeps(deps) {
13189
13399
  return {
13190
13400
  ...defaultCodexTomlRegistryDeps,
@@ -13193,7 +13403,7 @@ function resolveCodexTomlRegistryDeps(deps) {
13193
13403
  }
13194
13404
  async function ensureDir(filePath) {
13195
13405
  const dir = dirname2(filePath);
13196
- if (!existsSync3(dir)) {
13406
+ if (!existsSync4(dir)) {
13197
13407
  await mkdir2(dir, { recursive: true });
13198
13408
  }
13199
13409
  }
@@ -13201,7 +13411,7 @@ function isErrnoCode2(error, code) {
13201
13411
  return typeof error === "object" && error !== null && "code" in error && error.code === code;
13202
13412
  }
13203
13413
  function normalizePathForComparison(path2) {
13204
- const normalized = resolve2(path2);
13414
+ const normalized = resolve3(path2);
13205
13415
  return process.platform === "win32" ? normalized.toLowerCase() : normalized;
13206
13416
  }
13207
13417
  function isPathWithinBoundary(targetPath, boundaryPath) {
@@ -13217,7 +13427,7 @@ async function resolveRealPathSafe(path2) {
13217
13427
  try {
13218
13428
  return await realpath(path2);
13219
13429
  } catch {
13220
- return resolve2(path2);
13430
+ return resolve3(path2);
13221
13431
  }
13222
13432
  }
13223
13433
  async function isCanonicalPathWithinBoundary(targetPath, boundaryPath) {
@@ -13391,10 +13601,10 @@ function mergeConfigTomlWithDiagnostics(existing, managedBlock) {
13391
13601
  };
13392
13602
  }
13393
13603
  function getCodexLockPath(configTomlPath) {
13394
- return join3(dirname2(configTomlPath), `.${basename(configTomlPath)}.ck-codex.lock`);
13604
+ return join4(dirname2(configTomlPath), `.${basename(configTomlPath)}.ck-codex.lock`);
13395
13605
  }
13396
13606
  async function withCodexTargetLock(configTomlPath, operation) {
13397
- const resolvedTargetPath = resolve2(configTomlPath);
13607
+ const resolvedTargetPath = resolve3(configTomlPath);
13398
13608
  await ensureDir(resolvedTargetPath);
13399
13609
  const release = await import_proper_lockfile2.default.lock(dirname2(resolvedTargetPath), {
13400
13610
  realpath: false,
@@ -13473,8 +13683,8 @@ async function installCodexToml(items, provider, portableType, options2, deps) {
13473
13683
  };
13474
13684
  }
13475
13685
  const boundary = options2.global ? homedir4() : process.cwd();
13476
- const agentsDir = resolve2(basePath);
13477
- const configTomlPath = join3(dirname2(agentsDir), "config.toml");
13686
+ const agentsDir = resolve3(basePath);
13687
+ const configTomlPath = join4(dirname2(agentsDir), "config.toml");
13478
13688
  if (!isPathWithinBoundary(agentsDir, boundary)) {
13479
13689
  return {
13480
13690
  provider,
@@ -13568,7 +13778,7 @@ async function installCodexToml(items, provider, portableType, options2, deps) {
13568
13778
  continue;
13569
13779
  }
13570
13780
  seenSlugOwners.set(slug, item.name);
13571
- const agentTomlPath = join3(agentsDir, `${slug}.toml`);
13781
+ const agentTomlPath = join4(agentsDir, `${slug}.toml`);
13572
13782
  if (process.platform === "win32" && agentTomlPath.length > MAX_WINDOWS_PATH_LENGTH) {
13573
13783
  allWarnings.push(`Skipped ${item.name}: target path exceeds ${MAX_WINDOWS_PATH_LENGTH} characters on Windows`);
13574
13784
  continue;
@@ -13695,9 +13905,9 @@ async function cleanupStaleCodexConfigEntries(options2) {
13695
13905
  const basePath = options2.global ? pathConfig.globalPath : pathConfig.projectPath;
13696
13906
  if (!basePath)
13697
13907
  return [];
13698
- const agentsDir = resolve2(basePath);
13699
- const configTomlPath = join3(dirname2(agentsDir), "config.toml");
13700
- if (!existsSync3(configTomlPath))
13908
+ const agentsDir = resolve3(basePath);
13909
+ const configTomlPath = join4(dirname2(agentsDir), "config.toml");
13910
+ if (!existsSync4(configTomlPath))
13701
13911
  return [];
13702
13912
  try {
13703
13913
  return await withCodexTargetLock(configTomlPath, async () => {
@@ -13713,8 +13923,8 @@ async function cleanupStaleCodexConfigEntries(options2) {
13713
13923
  if (managedEntries.size > 0) {
13714
13924
  const validEntries = new Map;
13715
13925
  for (const [slug, entry] of managedEntries) {
13716
- const tomlPath = join3(agentsDir, `${slug}.toml`);
13717
- if (existsSync3(tomlPath)) {
13926
+ const tomlPath = join4(agentsDir, `${slug}.toml`);
13927
+ if (existsSync4(tomlPath)) {
13718
13928
  validEntries.set(slug, entry);
13719
13929
  } else {
13720
13930
  allStaleSlugs.push(slug);
@@ -13744,10 +13954,10 @@ async function cleanupStaleCodexConfigEntries(options2) {
13744
13954
  const unmanagedSlugs = extractUnmanagedAgentSlugs(analysis.unmanagedContent);
13745
13955
  const legacyStaleSlugs = [];
13746
13956
  for (const slug of unmanagedSlugs) {
13747
- const tomlPath = join3(agentsDir, `${slug}.toml`);
13957
+ const tomlPath = join4(agentsDir, `${slug}.toml`);
13748
13958
  if (!isPathWithinBoundary(tomlPath, agentsDir))
13749
13959
  continue;
13750
- if (!existsSync3(tomlPath)) {
13960
+ if (!existsSync4(tomlPath)) {
13751
13961
  legacyStaleSlugs.push(slug);
13752
13962
  }
13753
13963
  }
@@ -13992,13 +14202,13 @@ var init_merge_single_sections = __esm(() => {
13992
14202
  });
13993
14203
 
13994
14204
  // src/commands/portable/portable-installer.ts
13995
- import { existsSync as existsSync4 } from "node:fs";
14205
+ import { existsSync as existsSync5 } from "node:fs";
13996
14206
  import { lstat, mkdir as mkdir3, readFile as readFile4, realpath as realpath2, unlink as unlink3, writeFile as writeFile3 } from "node:fs/promises";
13997
14207
  import { homedir as homedir5 } from "node:os";
13998
- import { basename as basename2, dirname as dirname3, join as join4, relative as relative2, resolve as resolve3, sep } from "node:path";
14208
+ import { basename as basename2, dirname as dirname3, join as join5, relative as relative2, resolve as resolve4, sep } from "node:path";
13999
14209
  function isSamePath(path1, path2) {
14000
14210
  try {
14001
- return resolve3(path1) === resolve3(path2);
14211
+ return resolve4(path1) === resolve4(path2);
14002
14212
  } catch {
14003
14213
  return false;
14004
14214
  }
@@ -14027,8 +14237,8 @@ function isWindowsAbsolutePath(path2) {
14027
14237
  return /^[a-zA-Z]:[\\/]/.test(path2) || /^\\\\/.test(path2);
14028
14238
  }
14029
14239
  function isPathWithinBoundary2(targetPath, boundaryPath) {
14030
- const resolvedTarget = resolve3(targetPath);
14031
- const resolvedBoundary = resolve3(boundaryPath);
14240
+ const resolvedTarget = resolve4(targetPath);
14241
+ const resolvedBoundary = resolve4(boundaryPath);
14032
14242
  return resolvedTarget === resolvedBoundary || resolvedTarget.startsWith(`${resolvedBoundary}${sep}`);
14033
14243
  }
14034
14244
  function validateStrategyTargetPath(targetPath, options2) {
@@ -14054,16 +14264,16 @@ function resolvePerFileOutputFilename(filename, pathConfig) {
14054
14264
  return `${nameWithoutExt.replace(/\//g, "-")}${ext}`;
14055
14265
  }
14056
14266
  function validateResolvedTargetWithinBase(targetPath, basePath, pathConfig) {
14057
- const resolvedTarget = resolve3(targetPath);
14058
- const resolvedBase = pathConfig.writeStrategy === "single-file" ? resolve3(dirname3(basePath)) : resolve3(basePath);
14267
+ const resolvedTarget = resolve4(targetPath);
14268
+ const resolvedBase = pathConfig.writeStrategy === "single-file" ? resolve4(dirname3(basePath)) : resolve4(basePath);
14059
14269
  if (!resolvedTarget.startsWith(`${resolvedBase}${sep}`) && resolvedTarget !== resolvedBase) {
14060
14270
  return "Unsafe path: target escapes base directory";
14061
14271
  }
14062
14272
  return null;
14063
14273
  }
14064
14274
  async function validateNoSymlinkComponents(targetPath, boundaryPath) {
14065
- const resolvedTarget = resolve3(targetPath);
14066
- const resolvedBoundary = resolve3(boundaryPath);
14275
+ const resolvedTarget = resolve4(targetPath);
14276
+ const resolvedBoundary = resolve4(boundaryPath);
14067
14277
  if (!isPathWithinBoundary2(resolvedTarget, resolvedBoundary)) {
14068
14278
  return `Unsafe path: target escapes ${resolvedBoundary}`;
14069
14279
  }
@@ -14071,7 +14281,7 @@ async function validateNoSymlinkComponents(targetPath, boundaryPath) {
14071
14281
  let cursor = resolvedBoundary;
14072
14282
  let deepestExisting = resolvedBoundary;
14073
14283
  for (const segment of segments) {
14074
- cursor = join4(cursor, segment);
14284
+ cursor = join5(cursor, segment);
14075
14285
  try {
14076
14286
  await lstat(cursor);
14077
14287
  deepestExisting = cursor;
@@ -14181,13 +14391,13 @@ function buildPerFileCollisionSkips(items, provider, configDisplayName, basePath
14181
14391
  continue;
14182
14392
  }
14183
14393
  const resolvedFilename = resolvePerFileOutputFilename(result.filename, pathConfig);
14184
- const targetPath = pathConfig.writeStrategy === "single-file" ? basePath : join4(basePath, resolvedFilename);
14394
+ const targetPath = pathConfig.writeStrategy === "single-file" ? basePath : join5(basePath, resolvedFilename);
14185
14395
  if (validateResolvedTargetWithinBase(targetPath, basePath, pathConfig)) {
14186
14396
  continue;
14187
14397
  }
14188
- const first = seenTargets.get(resolve3(targetPath));
14398
+ const first = seenTargets.get(resolve4(targetPath));
14189
14399
  if (!first) {
14190
- seenTargets.set(resolve3(targetPath), { itemName: item.name, targetPath });
14400
+ seenTargets.set(resolve4(targetPath), { itemName: item.name, targetPath });
14191
14401
  continue;
14192
14402
  }
14193
14403
  skipped.set(index, {
@@ -14267,16 +14477,16 @@ async function installPerFileItems(items, provider, portableType, pathConfig, op
14267
14477
  }
14268
14478
  async function ensureDir2(filePath) {
14269
14479
  const dir = dirname3(filePath);
14270
- if (!existsSync4(dir)) {
14480
+ if (!existsSync5(dir)) {
14271
14481
  await mkdir3(dir, { recursive: true });
14272
14482
  }
14273
14483
  }
14274
14484
  function getMergeTargetLockPath(targetPath) {
14275
14485
  const lockName = `.${basename2(targetPath)}.ck-merge.lock`;
14276
- return join4(dirname3(targetPath), lockName);
14486
+ return join5(dirname3(targetPath), lockName);
14277
14487
  }
14278
14488
  async function withMergeTargetLock(targetPath, operation) {
14279
- const resolvedTargetPath = resolve3(targetPath);
14489
+ const resolvedTargetPath = resolve4(targetPath);
14280
14490
  await ensureDir2(resolvedTargetPath);
14281
14491
  const release = await import_proper_lockfile3.default.lock(dirname3(resolvedTargetPath), {
14282
14492
  realpath: false,
@@ -14393,7 +14603,7 @@ async function installPerFile(item, provider, portableType, options2, registryDe
14393
14603
  };
14394
14604
  }
14395
14605
  const resolvedFilename = resolvePerFileOutputFilename(result.filename, pathConfig);
14396
- targetPath = pathConfig.writeStrategy === "single-file" ? basePath : join4(basePath, resolvedFilename);
14606
+ targetPath = pathConfig.writeStrategy === "single-file" ? basePath : join5(basePath, resolvedFilename);
14397
14607
  const targetPathError = validateResolvedTargetWithinBase(targetPath, basePath, pathConfig);
14398
14608
  if (targetPathError) {
14399
14609
  return {
@@ -14520,7 +14730,7 @@ async function installMergeSingle(items, provider, portableType, options2, regis
14520
14730
  error: "Config merge target accepts only one item per install"
14521
14731
  };
14522
14732
  }
14523
- const alreadyExists = existsSync4(targetPath);
14733
+ const alreadyExists = existsSync5(targetPath);
14524
14734
  let existingSections = [];
14525
14735
  let existingPreamble = "";
14526
14736
  const allWarnings = [];
@@ -14723,7 +14933,7 @@ async function installYamlMerge(items, provider, portableType, options2, registr
14723
14933
  }
14724
14934
  let targetSnapshot = null;
14725
14935
  try {
14726
- const alreadyExists = existsSync4(targetPath);
14936
+ const alreadyExists = existsSync5(targetPath);
14727
14937
  let existingModes = new Map;
14728
14938
  if (alreadyExists) {
14729
14939
  try {
@@ -14899,7 +15109,7 @@ async function installJsonMerge(items, provider, portableType, options2, registr
14899
15109
  }
14900
15110
  modes.push(parsedMode.data);
14901
15111
  }
14902
- const modesPath = join4(basePath, "cline_custom_modes.json");
15112
+ const modesPath = join5(basePath, "cline_custom_modes.json");
14903
15113
  failurePath = modesPath;
14904
15114
  const modesSymlinkError = await validateWritableTargetPath(modesPath, options2);
14905
15115
  if (modesSymlinkError) {
@@ -14912,7 +15122,7 @@ async function installJsonMerge(items, provider, portableType, options2, registr
14912
15122
  };
14913
15123
  }
14914
15124
  await ensureDir2(modesPath);
14915
- const alreadyExists = existsSync4(modesPath);
15125
+ const alreadyExists = existsSync5(modesPath);
14916
15126
  if (alreadyExists) {
14917
15127
  try {
14918
15128
  const existingRaw = JSON.parse(await readFile4(modesPath, "utf-8"));
@@ -14948,7 +15158,7 @@ async function installJsonMerge(items, provider, portableType, options2, registr
14948
15158
  await writeFile3(modesPath, modesJson, "utf-8");
14949
15159
  const targetChecksum = computeContentChecksum(modesJson);
14950
15160
  const ownedSections = modes.map((m2) => m2.slug);
14951
- const rulesDir = join4(dirname3(basePath), ".clinerules");
15161
+ const rulesDir = join5(dirname3(basePath), ".clinerules");
14952
15162
  await mkdir3(rulesDir, { recursive: true });
14953
15163
  const capturedRuleSnapshots = new Set;
14954
15164
  for (const item of items) {
@@ -14970,10 +15180,10 @@ async function installJsonMerge(items, provider, portableType, options2, registr
14970
15180
  }
14971
15181
  }
14972
15182
  const filename = `${namespacedName}.md`;
14973
- const rulePath = join4(rulesDir, filename);
15183
+ const rulePath = join5(rulesDir, filename);
14974
15184
  failurePath = rulePath;
14975
- const resolvedRulePath = resolve3(rulePath);
14976
- const resolvedRulesDir = resolve3(rulesDir);
15185
+ const resolvedRulePath = resolve4(rulePath);
15186
+ const resolvedRulesDir = resolve4(rulesDir);
14977
15187
  if (!resolvedRulePath.startsWith(resolvedRulesDir + sep) && resolvedRulePath !== resolvedRulesDir) {
14978
15188
  throw new Error(`Unsafe path: rule target escapes rules directory (${rulePath})`);
14979
15189
  }
@@ -16182,26 +16392,26 @@ var init_types3 = __esm(() => {
16182
16392
  });
16183
16393
 
16184
16394
  // src/shared/kit-layout.ts
16185
- import { existsSync as existsSync5, readFileSync as readFileSync2 } from "node:fs";
16186
- import { join as join5 } from "node:path";
16395
+ import { existsSync as existsSync6, readFileSync as readFileSync3 } from "node:fs";
16396
+ import { join as join6 } from "node:path";
16187
16397
  function uniquePaths(paths) {
16188
16398
  return [...new Set(paths)];
16189
16399
  }
16190
16400
  function findFirstExistingPath(paths) {
16191
16401
  for (const candidate of paths) {
16192
- if (existsSync5(candidate)) {
16402
+ if (existsSync6(candidate)) {
16193
16403
  return candidate;
16194
16404
  }
16195
16405
  }
16196
16406
  return null;
16197
16407
  }
16198
16408
  function resolveKitLayout(projectRoot) {
16199
- const packageJsonPath = join5(projectRoot, "package.json");
16200
- if (!existsSync5(packageJsonPath)) {
16409
+ const packageJsonPath = join6(projectRoot, "package.json");
16410
+ if (!existsSync6(packageJsonPath)) {
16201
16411
  return DEFAULT_KIT_LAYOUT;
16202
16412
  }
16203
16413
  try {
16204
- const parsed = ClaudeKitPackageMetadataSchema.parse(JSON.parse(readFileSync2(packageJsonPath, "utf8")));
16414
+ const parsed = ClaudeKitPackageMetadataSchema.parse(JSON.parse(readFileSync3(packageJsonPath, "utf8")));
16205
16415
  return KitLayoutSchema.parse({
16206
16416
  ...DEFAULT_KIT_LAYOUT,
16207
16417
  ...parsed.claudekit ?? {}
@@ -16213,8 +16423,8 @@ function resolveKitLayout(projectRoot) {
16213
16423
  function getProjectLayoutCandidates(projectRoot, subPath) {
16214
16424
  const layout = resolveKitLayout(projectRoot);
16215
16425
  return uniquePaths([
16216
- join5(projectRoot, layout.sourceDir, subPath),
16217
- join5(projectRoot, DEFAULT_KIT_LAYOUT.sourceDir, subPath)
16426
+ join6(projectRoot, layout.sourceDir, subPath),
16427
+ join6(projectRoot, DEFAULT_KIT_LAYOUT.sourceDir, subPath)
16218
16428
  ]);
16219
16429
  }
16220
16430
  function findExistingProjectLayoutPath(projectRoot, subPath) {
@@ -16223,9 +16433,9 @@ function findExistingProjectLayoutPath(projectRoot, subPath) {
16223
16433
  function getProjectConfigCandidates(projectRoot) {
16224
16434
  const layout = resolveKitLayout(projectRoot);
16225
16435
  return uniquePaths([
16226
- join5(projectRoot, "CLAUDE.md"),
16227
- join5(projectRoot, layout.sourceDir, "CLAUDE.md"),
16228
- join5(projectRoot, DEFAULT_KIT_LAYOUT.sourceDir, "CLAUDE.md")
16436
+ join6(projectRoot, "CLAUDE.md"),
16437
+ join6(projectRoot, layout.sourceDir, "CLAUDE.md"),
16438
+ join6(projectRoot, DEFAULT_KIT_LAYOUT.sourceDir, "CLAUDE.md")
16229
16439
  ]);
16230
16440
  }
16231
16441
  function findExistingProjectConfigPath(projectRoot) {
@@ -16339,9 +16549,9 @@ var init_frontmatter_parser = __esm(() => {
16339
16549
  // src/commands/agents/agents-discovery.ts
16340
16550
  import { readdir } from "node:fs/promises";
16341
16551
  import { homedir as homedir6 } from "node:os";
16342
- import { join as join6 } from "node:path";
16552
+ import { join as join7 } from "node:path";
16343
16553
  function getAgentSourcePath(globalOnly = false) {
16344
- const globalPath = join6(homedir6(), ".claude/agents");
16554
+ const globalPath = join7(homedir6(), ".claude/agents");
16345
16555
  if (globalOnly) {
16346
16556
  return findFirstExistingPath([globalPath]);
16347
16557
  }
@@ -16360,7 +16570,7 @@ async function discoverAgents(sourcePath) {
16360
16570
  for (const entry of entries) {
16361
16571
  if (!entry.isFile() || !entry.name.endsWith(".md"))
16362
16572
  continue;
16363
- const filePath = join6(searchPath, entry.name);
16573
+ const filePath = join7(searchPath, entry.name);
16364
16574
  try {
16365
16575
  const { frontmatter, body } = await parseFrontmatterFile(filePath);
16366
16576
  const name = entry.name.replace(/\.md$/, "");
@@ -19423,217 +19633,6 @@ var init_safe_spinner = __esm(() => {
19423
19633
  };
19424
19634
  });
19425
19635
 
19426
- // src/shared/path-resolver.ts
19427
- import { createHash as createHash3 } from "node:crypto";
19428
- import { existsSync as existsSync8, readFileSync as readFileSync4 } from "node:fs";
19429
- import { homedir as homedir9, platform as platform2 } from "node:os";
19430
- import { join as join11, normalize, resolve as resolve4 } from "node:path";
19431
- function getEnvVar(name) {
19432
- const val = process.env[name];
19433
- if (!val || val.trim() === "")
19434
- return;
19435
- if (val.includes("..")) {
19436
- console.warn(`Environment variable ${name} contains path traversal: ${val}`);
19437
- return;
19438
- }
19439
- return val;
19440
- }
19441
- function isWSL() {
19442
- try {
19443
- return process.platform === "linux" && existsSync8("/proc/version") && readFileSync4("/proc/version", "utf8").toLowerCase().includes("microsoft");
19444
- } catch {
19445
- return false;
19446
- }
19447
- }
19448
- function normalizeWSLPath(p) {
19449
- if (!isWSL())
19450
- return p;
19451
- const windowsMatch = p.match(/^([A-Za-z]):(.*)/);
19452
- if (windowsMatch) {
19453
- const drive = windowsMatch[1].toLowerCase();
19454
- const rest = windowsMatch[2].replace(/\\/g, "/");
19455
- return `/mnt/${drive}${rest}`;
19456
- }
19457
- return p;
19458
- }
19459
-
19460
- class PathResolver {
19461
- static getTestHomeDir() {
19462
- return process.env.CK_TEST_HOME;
19463
- }
19464
- static isValidComponentName(name) {
19465
- if (!name || typeof name !== "string") {
19466
- return false;
19467
- }
19468
- const dangerousPatterns = [
19469
- "..",
19470
- "~"
19471
- ];
19472
- for (const pattern of dangerousPatterns) {
19473
- if (name.includes(pattern)) {
19474
- return false;
19475
- }
19476
- }
19477
- const normalized = normalize(name);
19478
- for (const pattern of dangerousPatterns) {
19479
- if (normalized.includes(pattern)) {
19480
- return false;
19481
- }
19482
- }
19483
- if (name.startsWith("/") || normalized.startsWith("/") || /^[a-zA-Z]:/.test(name) || name.startsWith("\\\\") || normalized.startsWith("\\\\")) {
19484
- return false;
19485
- }
19486
- return true;
19487
- }
19488
- static getConfigDir(global3 = false) {
19489
- const testHome = PathResolver.getTestHomeDir();
19490
- if (testHome) {
19491
- return global3 ? join11(testHome, ".config", "claude") : join11(testHome, ".claudekit");
19492
- }
19493
- if (!global3) {
19494
- return join11(homedir9(), ".claudekit");
19495
- }
19496
- const os2 = platform2();
19497
- if (os2 === "win32") {
19498
- const localAppData = getEnvVar("LOCALAPPDATA") ?? join11(homedir9(), "AppData", "Local");
19499
- return join11(localAppData, "claude");
19500
- }
19501
- const xdgConfigHome = getEnvVar("XDG_CONFIG_HOME");
19502
- if (xdgConfigHome) {
19503
- return join11(xdgConfigHome, "claude");
19504
- }
19505
- return join11(homedir9(), ".config", "claude");
19506
- }
19507
- static getConfigFile(global3 = false) {
19508
- return join11(PathResolver.getConfigDir(global3), "config.json");
19509
- }
19510
- static getCacheDir(global3 = false) {
19511
- const testHome = PathResolver.getTestHomeDir();
19512
- if (testHome) {
19513
- return global3 ? join11(testHome, ".cache", "claude") : join11(testHome, ".claudekit", "cache");
19514
- }
19515
- if (!global3) {
19516
- return join11(homedir9(), ".claudekit", "cache");
19517
- }
19518
- const os2 = platform2();
19519
- if (os2 === "win32") {
19520
- const localAppData = getEnvVar("LOCALAPPDATA") ?? join11(homedir9(), "AppData", "Local");
19521
- return join11(localAppData, "claude", "cache");
19522
- }
19523
- const xdgCacheHome = getEnvVar("XDG_CACHE_HOME");
19524
- if (xdgCacheHome) {
19525
- return join11(xdgCacheHome, "claude");
19526
- }
19527
- return join11(homedir9(), ".cache", "claude");
19528
- }
19529
- static getGlobalKitDir() {
19530
- const testHome = PathResolver.getTestHomeDir();
19531
- if (testHome) {
19532
- return join11(testHome, ".claude");
19533
- }
19534
- const claudeConfigDir = process.env.CLAUDE_CONFIG_DIR;
19535
- if (claudeConfigDir) {
19536
- return claudeConfigDir;
19537
- }
19538
- return join11(homedir9(), ".claude");
19539
- }
19540
- static getClaudeKitDir() {
19541
- const testHome = PathResolver.getTestHomeDir();
19542
- if (testHome) {
19543
- return join11(testHome, ".claudekit");
19544
- }
19545
- return join11(homedir9(), ".claudekit");
19546
- }
19547
- static getProjectsRegistryPath() {
19548
- return join11(PathResolver.getClaudeKitDir(), "projects.json");
19549
- }
19550
- static getOpenCodeDir(global3, baseDir) {
19551
- const testHome = PathResolver.getTestHomeDir();
19552
- if (testHome) {
19553
- return global3 ? join11(testHome, ".config", "opencode") : join11(baseDir || testHome, ".opencode");
19554
- }
19555
- if (!global3) {
19556
- return join11(baseDir || process.cwd(), ".opencode");
19557
- }
19558
- const xdgConfigHome = process.env.XDG_CONFIG_HOME;
19559
- if (xdgConfigHome) {
19560
- return join11(xdgConfigHome, "opencode");
19561
- }
19562
- return join11(homedir9(), ".config", "opencode");
19563
- }
19564
- static getPathPrefix(global3) {
19565
- return global3 ? "" : ".claude";
19566
- }
19567
- static buildSkillsPath(baseDir, global3) {
19568
- const prefix = PathResolver.getPathPrefix(global3);
19569
- if (prefix) {
19570
- return join11(baseDir, prefix, "skills");
19571
- }
19572
- return join11(baseDir, "skills");
19573
- }
19574
- static buildComponentPath(baseDir, component, global3) {
19575
- if (!PathResolver.isValidComponentName(component)) {
19576
- throw new Error(`Invalid component name: "${component}" contains path traversal patterns. Valid names are simple directory names like "agents", "commands", "rules", "skills", or "hooks".`);
19577
- }
19578
- const prefix = PathResolver.getPathPrefix(global3);
19579
- if (prefix) {
19580
- return join11(baseDir, prefix, component);
19581
- }
19582
- return join11(baseDir, component);
19583
- }
19584
- static getBackupDir(timestamp) {
19585
- const testHome = PathResolver.getTestHomeDir();
19586
- const baseDir = testHome ? join11(testHome, ".claudekit") : join11(homedir9(), ".claudekit");
19587
- if (timestamp) {
19588
- return join11(baseDir, "backups", timestamp);
19589
- }
19590
- const now = new Date;
19591
- const dateStr = now.toISOString().replace(/[:.]/g, "-").slice(0, 19);
19592
- const ms = now.getMilliseconds().toString().padStart(3, "0");
19593
- const random = Math.random().toString(36).slice(2, 6);
19594
- const ts = `${dateStr}-${ms}-${random}`;
19595
- return join11(baseDir, "backups", ts);
19596
- }
19597
- static normalizeWSLPath(p) {
19598
- return normalizeWSLPath(p);
19599
- }
19600
- static isWSL() {
19601
- return isWSL();
19602
- }
19603
- static isAtHomeDirectory(cwd2) {
19604
- const currentDir = normalize(cwd2 || process.cwd());
19605
- const homeDir = normalize(homedir9());
19606
- return currentDir === homeDir;
19607
- }
19608
- static getLocalClaudeDir(baseDir) {
19609
- const dir = baseDir || process.cwd();
19610
- return join11(dir, ".claude");
19611
- }
19612
- static isLocalSameAsGlobal(cwd2) {
19613
- const localPath = normalize(PathResolver.getLocalClaudeDir(cwd2));
19614
- const globalPath = normalize(PathResolver.getGlobalKitDir());
19615
- return localPath === globalPath;
19616
- }
19617
- static isGlobPattern(pattern) {
19618
- return pattern.includes("*") || pattern.includes("?") || pattern.includes("{");
19619
- }
19620
- static computeProjectHash(projectRoot) {
19621
- let normalized = resolve4(projectRoot).replace(/[/\\]+$/, "");
19622
- if (process.platform === "darwin" || process.platform === "win32") {
19623
- normalized = normalized.toLowerCase();
19624
- }
19625
- return createHash3("sha256").update(normalized).digest("hex").slice(0, 12);
19626
- }
19627
- static getPlansRegistriesDir() {
19628
- return join11(PathResolver.getGlobalKitDir(), "plans-registries");
19629
- }
19630
- static getPlansRegistryPath(projectRoot) {
19631
- const hash = PathResolver.computeProjectHash(projectRoot);
19632
- return join11(PathResolver.getPlansRegistriesDir(), `${hash}.json`);
19633
- }
19634
- }
19635
- var init_path_resolver = () => {};
19636
-
19637
19636
  // node_modules/universalify/index.js
19638
19637
  var require_universalify = __commonJS((exports) => {
19639
19638
  exports.fromCallback = function(fn) {
@@ -21022,10 +21021,10 @@ var init_safe_prompts = __esm(() => {
21022
21021
 
21023
21022
  // src/commands/commands/commands-discovery.ts
21024
21023
  import { readdir as readdir4 } from "node:fs/promises";
21025
- import { homedir as homedir10 } from "node:os";
21024
+ import { homedir as homedir9 } from "node:os";
21026
21025
  import { join as join16, relative as relative3 } from "node:path";
21027
21026
  function getCommandSourcePath(globalOnly = false) {
21028
- const globalPath = join16(homedir10(), ".claude/commands");
21027
+ const globalPath = join16(homedir9(), ".claude/commands");
21029
21028
  if (globalOnly) {
21030
21029
  return findFirstExistingPath([globalPath]);
21031
21030
  }
@@ -45405,7 +45404,7 @@ __export(exports_ck_config_manager, {
45405
45404
  });
45406
45405
  import { existsSync as existsSync11 } from "node:fs";
45407
45406
  import { mkdir as mkdir7, readFile as readFile8, writeFile as writeFile6 } from "node:fs/promises";
45408
- import { homedir as homedir11 } from "node:os";
45407
+ import { homedir as homedir10 } from "node:os";
45409
45408
  import { join as join19 } from "node:path";
45410
45409
  function getNestedValue(obj, path4) {
45411
45410
  if (!obj || typeof obj !== "object")
@@ -45480,7 +45479,7 @@ function valuesEqual(a3, b3) {
45480
45479
 
45481
45480
  class CkConfigManager {
45482
45481
  static getGlobalConfigDir() {
45483
- return join19(homedir11(), ".claude");
45482
+ return join19(homedir10(), ".claude");
45484
45483
  }
45485
45484
  static getGlobalConfigPath() {
45486
45485
  return join19(CkConfigManager.getGlobalConfigDir(), CK_CONFIG_FILE);
@@ -45739,7 +45738,7 @@ function notFoundError(type, name, hint) {
45739
45738
  }
45740
45739
 
45741
45740
  // src/shared/command-normalizer.ts
45742
- import { homedir as homedir12 } from "node:os";
45741
+ import { homedir as homedir11 } from "node:os";
45743
45742
  import { join as join20 } from "node:path";
45744
45743
  function escapeRegex(value) {
45745
45744
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -45779,7 +45778,7 @@ function resolveClaudePathArg(arg, root) {
45779
45778
  const isWin2 = process.platform === "win32";
45780
45779
  const cmp = (s) => isWin2 ? s.toLowerCase() : s;
45781
45780
  const globalRoots = [
45782
- `${homedir12().replace(/\\/g, "/").replace(/\/+$/, "")}/.claude/`,
45781
+ `${homedir11().replace(/\\/g, "/").replace(/\/+$/, "")}/.claude/`,
45783
45782
  `${PathResolver.getGlobalKitDir().replace(/\\/g, "/").replace(/\/+$/, "")}/`
45784
45783
  ];
45785
45784
  const isUnderGlobal = globalRoots.some((g2) => cmp(absolutePath).startsWith(cmp(g2)));
@@ -45856,7 +45855,7 @@ function repairClaudeNodeCommandPath(cmd, root) {
45856
45855
  const isWin2 = process.platform === "win32";
45857
45856
  const cmp = (s) => isWin2 ? s.toLowerCase() : s;
45858
45857
  const globalRoots = [
45859
- `${homedir12().replace(/\\/g, "/").replace(/\/+$/, "")}/.claude/`,
45858
+ `${homedir11().replace(/\\/g, "/").replace(/\/+$/, "")}/.claude/`,
45860
45859
  `${PathResolver.getGlobalKitDir().replace(/\\/g, "/").replace(/\/+$/, "")}/`
45861
45860
  ];
45862
45861
  const isUnderGlobal = globalRoots.some((g2) => cmp(normalizedAbsPath).startsWith(cmp(g2)));
@@ -45905,7 +45904,7 @@ function normalizeCommand(cmd) {
45905
45904
  return "";
45906
45905
  let normalized = cmd;
45907
45906
  const globalKitDir = PathResolver.getGlobalKitDir().replace(/\\/g, "/").replace(/\/+$/, "");
45908
- const defaultGlobalKitDir = join20(homedir12(), ".claude").replace(/\\/g, "/");
45907
+ const defaultGlobalKitDir = join20(homedir11(), ".claude").replace(/\\/g, "/");
45909
45908
  normalized = normalized.replace(/"/g, "");
45910
45909
  normalized = normalized.replace(/~\//g, "$HOME/");
45911
45910
  normalized = normalized.replace(/\$CLAUDE_PROJECT_DIR/g, "$HOME");
@@ -46103,11 +46102,15 @@ function mergeHookEntries(sourceEntries, destEntries, eventName, result, install
46103
46102
  const isFullyDuplicated = commands.length > 0 && commands.every((cmd) => existingCommands.has(normalizeCommand(cmd)));
46104
46103
  const duplicateCommands = commands.filter((cmd) => existingCommands.has(normalizeCommand(cmd)));
46105
46104
  logDuplicates(duplicateCommands, eventName, result);
46106
- const hasNonRemovedCommands = commands.length === 0 || commands.some((cmd) => !existingCommands.has(normalizeCommand(cmd)) && !wasCommandInstalled(cmd, installedHooks));
46105
+ const newCommands = commands.filter((cmd) => !existingCommands.has(normalizeCommand(cmd)) && !wasCommandInstalled(cmd, installedHooks));
46106
+ const hasNonRemovedCommands = commands.length === 0 || newCommands.length > 0;
46107
46107
  if (!isFullyDuplicated && hasNonRemovedCommands) {
46108
46108
  let filteredEntry = entry;
46109
- if ("hooks" in entry && entry.hooks && userRemovedCommands.length > 0) {
46110
- const filteredHooks = entry.hooks.filter((h2) => !h2.command || !wasCommandInstalled(h2.command, installedHooks));
46109
+ if ("hooks" in entry && entry.hooks && commands.length > 0) {
46110
+ const filteredHooks = entry.hooks.filter((h2) => !h2.command || !existingCommands.has(normalizeCommand(h2.command)) && !wasCommandInstalled(h2.command, installedHooks));
46111
+ if (filteredHooks.length === 0) {
46112
+ continue;
46113
+ }
46111
46114
  filteredEntry = { ...entry, hooks: filteredHooks };
46112
46115
  } else if ("command" in entry && wasCommandInstalled(entry.command, installedHooks)) {
46113
46116
  continue;
@@ -46118,16 +46121,12 @@ function mergeHookEntries(sourceEntries, destEntries, eventName, result, install
46118
46121
  if (sourceMatcher) {
46119
46122
  matcherIndex.set(sourceMatcher, merged.length - 1);
46120
46123
  }
46121
- for (const cmd of commands) {
46124
+ for (const cmd of newCommands) {
46122
46125
  const normalizedCmd = normalizeCommand(cmd);
46123
- if (!existingCommands.has(normalizedCmd) && !wasCommandInstalled(cmd, installedHooks)) {
46124
- existingCommands.add(normalizedCmd);
46125
- result.newlyInstalledHooks.push(cmd);
46126
- if (sourceKit) {
46127
- trackHookOrigin(result, sourceKit, cmd);
46128
- }
46129
- } else if (!existingCommands.has(normalizedCmd)) {
46130
- existingCommands.add(normalizedCmd);
46126
+ existingCommands.add(normalizedCmd);
46127
+ result.newlyInstalledHooks.push(cmd);
46128
+ if (sourceKit) {
46129
+ trackHookOrigin(result, sourceKit, cmd);
46131
46130
  }
46132
46131
  }
46133
46132
  }
@@ -48098,7 +48097,7 @@ var init_chokidar = __esm(() => {
48098
48097
  });
48099
48098
 
48100
48099
  // src/domains/web-server/file-watcher.ts
48101
- import { homedir as homedir13 } from "node:os";
48100
+ import { homedir as homedir12 } from "node:os";
48102
48101
  import { join as join25 } from "node:path";
48103
48102
 
48104
48103
  class FileWatcher {
@@ -48121,9 +48120,9 @@ class FileWatcher {
48121
48120
  }
48122
48121
  getWatchPaths() {
48123
48122
  const paths = [];
48124
- const globalDir = join25(homedir13(), ".claudekit");
48123
+ const globalDir = join25(homedir12(), ".claudekit");
48125
48124
  paths.push(join25(globalDir, "config.json"));
48126
- const globalKitDir = join25(homedir13(), ".claude");
48125
+ const globalKitDir = join25(homedir12(), ".claude");
48127
48126
  paths.push(join25(globalKitDir, ".ck.json"));
48128
48127
  paths.push(join25(globalKitDir, "settings.json"));
48129
48128
  paths.push(join25(globalKitDir, "settings.local.json"));
@@ -48173,8 +48172,8 @@ class FileWatcher {
48173
48172
  return path4.endsWith("config.json") || path4.endsWith(".ck.json") || path4.endsWith("settings.json") || path4.endsWith("settings.local.json");
48174
48173
  }
48175
48174
  getConfigScope(path4) {
48176
- const globalDir = join25(homedir13(), ".claudekit");
48177
- const globalKitDir = join25(homedir13(), ".claude");
48175
+ const globalDir = join25(homedir12(), ".claudekit");
48176
+ const globalKitDir = join25(homedir12(), ".claude");
48178
48177
  return path4.startsWith(globalDir) || path4.startsWith(globalKitDir) ? "global" : "local";
48179
48178
  }
48180
48179
  stop() {
@@ -48665,7 +48664,7 @@ var init_claudekit_data2 = __esm(() => {
48665
48664
  // src/domains/web-server/routes/action-routes.ts
48666
48665
  import { spawn, spawnSync } from "node:child_process";
48667
48666
  import { existsSync as existsSync14 } from "node:fs";
48668
- import { homedir as homedir14 } from "node:os";
48667
+ import { homedir as homedir13 } from "node:os";
48669
48668
  import { join as join27, resolve as resolve12, sep as sep5 } from "node:path";
48670
48669
  function getWindowsPaths(...relativePaths) {
48671
48670
  const roots = [
@@ -48942,7 +48941,7 @@ async function isActionPathAllowed(dirPath, projectId) {
48942
48941
  try {
48943
48942
  const encodedPath = projectId.slice("discovered-".length);
48944
48943
  const discoveredPath = resolve12(Buffer.from(encodedPath, "base64url").toString("utf-8"));
48945
- if (discoveredPath === dirPath && (isPathInsideBase(discoveredPath, process.cwd()) || isPathInsideBase(discoveredPath, homedir14()))) {
48944
+ if (discoveredPath === dirPath && (isPathInsideBase(discoveredPath, process.cwd()) || isPathInsideBase(discoveredPath, homedir13()))) {
48946
48945
  return true;
48947
48946
  }
48948
48947
  } catch {}
@@ -48954,7 +48953,7 @@ async function isActionPathAllowed(dirPath, projectId) {
48954
48953
  if (isPathInsideBase(dirPath, process.cwd())) {
48955
48954
  return true;
48956
48955
  }
48957
- return isPathInsideBase(dirPath, homedir14());
48956
+ return isPathInsideBase(dirPath, homedir13());
48958
48957
  }
48959
48958
  function buildSystemTerminalCommand(dirPath) {
48960
48959
  if (isMacOS()) {
@@ -49293,7 +49292,7 @@ var init_action_routes = __esm(() => {
49293
49292
  projectId: exports_external.string().min(1).max(256).optional()
49294
49293
  }).strict();
49295
49294
  WINDOWS_PATHS = {
49296
- localAppData: process.env.LOCALAPPDATA || join27(homedir14(), "AppData", "Local"),
49295
+ localAppData: process.env.LOCALAPPDATA || join27(homedir13(), "AppData", "Local"),
49297
49296
  programFiles: process.env.ProgramFiles || "C:\\Program Files",
49298
49297
  programFilesX86: process.env["ProgramFiles(x86)"] || "C:\\Program Files (x86)"
49299
49298
  };
@@ -49314,7 +49313,7 @@ var init_action_routes = __esm(() => {
49314
49313
  openMode: "open-directory",
49315
49314
  capabilities: ["open-directory", "run-command"],
49316
49315
  macAppName: "iTerm",
49317
- macAppPaths: ["/Applications/iTerm.app", join27(homedir14(), "Applications", "iTerm.app")]
49316
+ macAppPaths: ["/Applications/iTerm.app", join27(homedir13(), "Applications", "iTerm.app")]
49318
49317
  },
49319
49318
  {
49320
49319
  id: "warp",
@@ -49325,7 +49324,7 @@ var init_action_routes = __esm(() => {
49325
49324
  capabilities: ["open-directory", "uri-scheme"],
49326
49325
  commands: ["warp"],
49327
49326
  macAppName: "Warp",
49328
- macAppPaths: ["/Applications/Warp.app", join27(homedir14(), "Applications", "Warp.app")],
49327
+ macAppPaths: ["/Applications/Warp.app", join27(homedir13(), "Applications", "Warp.app")],
49329
49328
  windowsAppPaths: getWindowsPaths("Warp\\Warp.exe"),
49330
49329
  linuxAppPaths: ["/usr/bin/warp", "/usr/local/bin/warp"]
49331
49330
  },
@@ -49348,7 +49347,7 @@ var init_action_routes = __esm(() => {
49348
49347
  capabilities: ["open-directory"],
49349
49348
  commands: ["wezterm"],
49350
49349
  macAppName: "WezTerm",
49351
- macAppPaths: ["/Applications/WezTerm.app", join27(homedir14(), "Applications", "WezTerm.app")],
49350
+ macAppPaths: ["/Applications/WezTerm.app", join27(homedir13(), "Applications", "WezTerm.app")],
49352
49351
  windowsAppPaths: getWindowsPaths("WezTerm\\wezterm-gui.exe", "WezTerm\\wezterm.exe"),
49353
49352
  linuxAppPaths: ["/usr/bin/wezterm", "/usr/local/bin/wezterm"]
49354
49353
  },
@@ -49361,7 +49360,7 @@ var init_action_routes = __esm(() => {
49361
49360
  capabilities: ["open-directory"],
49362
49361
  commands: ["kitty"],
49363
49362
  macAppName: "kitty",
49364
- macAppPaths: ["/Applications/kitty.app", join27(homedir14(), "Applications", "kitty.app")],
49363
+ macAppPaths: ["/Applications/kitty.app", join27(homedir13(), "Applications", "kitty.app")],
49365
49364
  windowsAppPaths: getWindowsPaths("kitty\\kitty.exe"),
49366
49365
  linuxAppPaths: ["/usr/bin/kitty", "/usr/local/bin/kitty"]
49367
49366
  },
@@ -49374,7 +49373,7 @@ var init_action_routes = __esm(() => {
49374
49373
  capabilities: ["open-directory"],
49375
49374
  commands: ["alacritty"],
49376
49375
  macAppName: "Alacritty",
49377
- macAppPaths: ["/Applications/Alacritty.app", join27(homedir14(), "Applications", "Alacritty.app")],
49376
+ macAppPaths: ["/Applications/Alacritty.app", join27(homedir13(), "Applications", "Alacritty.app")],
49378
49377
  windowsAppPaths: getWindowsPaths("Alacritty\\alacritty.exe"),
49379
49378
  linuxAppPaths: ["/usr/bin/alacritty", "/usr/local/bin/alacritty"]
49380
49379
  },
@@ -49447,7 +49446,7 @@ var init_action_routes = __esm(() => {
49447
49446
  capabilities: ["open-app"],
49448
49447
  commands: ["termius"],
49449
49448
  macAppName: "Termius",
49450
- macAppPaths: ["/Applications/Termius.app", join27(homedir14(), "Applications", "Termius.app")],
49449
+ macAppPaths: ["/Applications/Termius.app", join27(homedir13(), "Applications", "Termius.app")],
49451
49450
  windowsAppPaths: getWindowsPaths("Termius\\Termius.exe"),
49452
49451
  linuxAppPaths: ["/usr/bin/termius"]
49453
49452
  },
@@ -49470,7 +49469,7 @@ var init_action_routes = __esm(() => {
49470
49469
  macAppName: "Visual Studio Code",
49471
49470
  macAppPaths: [
49472
49471
  "/Applications/Visual Studio Code.app",
49473
- join27(homedir14(), "Applications", "Visual Studio Code.app")
49472
+ join27(homedir13(), "Applications", "Visual Studio Code.app")
49474
49473
  ],
49475
49474
  windowsAppPaths: getWindowsPaths("Programs\\Microsoft VS Code\\Code.exe", "Microsoft VS Code\\Code.exe"),
49476
49475
  linuxAppPaths: ["/usr/bin/code", "/snap/bin/code"]
@@ -49484,7 +49483,7 @@ var init_action_routes = __esm(() => {
49484
49483
  capabilities: ["open-directory"],
49485
49484
  commands: ["cursor"],
49486
49485
  macAppName: "Cursor",
49487
- macAppPaths: ["/Applications/Cursor.app", join27(homedir14(), "Applications", "Cursor.app")],
49486
+ macAppPaths: ["/Applications/Cursor.app", join27(homedir13(), "Applications", "Cursor.app")],
49488
49487
  windowsAppPaths: getWindowsPaths("Programs\\Cursor\\Cursor.exe", "Cursor\\Cursor.exe"),
49489
49488
  linuxAppPaths: ["/usr/bin/cursor"]
49490
49489
  },
@@ -49497,7 +49496,7 @@ var init_action_routes = __esm(() => {
49497
49496
  capabilities: ["open-directory"],
49498
49497
  commands: ["windsurf"],
49499
49498
  macAppName: "Windsurf",
49500
- macAppPaths: ["/Applications/Windsurf.app", join27(homedir14(), "Applications", "Windsurf.app")],
49499
+ macAppPaths: ["/Applications/Windsurf.app", join27(homedir13(), "Applications", "Windsurf.app")],
49501
49500
  windowsAppPaths: getWindowsPaths("Programs\\Windsurf\\Windsurf.exe", "Windsurf\\Windsurf.exe"),
49502
49501
  linuxAppPaths: ["/usr/bin/windsurf"]
49503
49502
  },
@@ -49512,11 +49511,11 @@ var init_action_routes = __esm(() => {
49512
49511
  macAppName: "Antigravity",
49513
49512
  macAppPaths: [
49514
49513
  "/Applications/Antigravity.app",
49515
- join27(homedir14(), "Applications", "Antigravity.app")
49514
+ join27(homedir13(), "Applications", "Antigravity.app")
49516
49515
  ],
49517
49516
  windowsAppPaths: getWindowsPaths("Programs\\Antigravity\\Antigravity.exe"),
49518
49517
  linuxAppPaths: ["/usr/bin/antigravity"],
49519
- fallbackDetectionPaths: [join27(homedir14(), ".gemini", "antigravity")]
49518
+ fallbackDetectionPaths: [join27(homedir13(), ".gemini", "antigravity")]
49520
49519
  },
49521
49520
  {
49522
49521
  id: "zed",
@@ -49527,7 +49526,7 @@ var init_action_routes = __esm(() => {
49527
49526
  capabilities: ["open-directory"],
49528
49527
  commands: ["zed"],
49529
49528
  macAppName: "Zed",
49530
- macAppPaths: ["/Applications/Zed.app", join27(homedir14(), "Applications", "Zed.app")],
49529
+ macAppPaths: ["/Applications/Zed.app", join27(homedir13(), "Applications", "Zed.app")],
49531
49530
  windowsAppPaths: getWindowsPaths("Zed\\Zed.exe"),
49532
49531
  linuxAppPaths: ["/usr/bin/zed", "/usr/local/bin/zed"]
49533
49532
  },
@@ -49542,7 +49541,7 @@ var init_action_routes = __esm(() => {
49542
49541
  macAppName: "Sublime Text",
49543
49542
  macAppPaths: [
49544
49543
  "/Applications/Sublime Text.app",
49545
- join27(homedir14(), "Applications", "Sublime Text.app")
49544
+ join27(homedir13(), "Applications", "Sublime Text.app")
49546
49545
  ],
49547
49546
  windowsAppPaths: getWindowsPaths("Sublime Text\\sublime_text.exe"),
49548
49547
  linuxAppPaths: ["/usr/bin/subl", "/snap/bin/subl"]
@@ -49583,7 +49582,7 @@ var init_action_routes = __esm(() => {
49583
49582
 
49584
49583
  // src/domains/web-server/routes/agents-routes.ts
49585
49584
  import { readdir as readdir7 } from "node:fs/promises";
49586
- import { homedir as homedir15 } from "node:os";
49585
+ import { homedir as homedir14 } from "node:os";
49587
49586
  import { isAbsolute as isAbsolute4, join as join28, relative as relative7 } from "node:path";
49588
49587
  function resolveAgentDirs() {
49589
49588
  const dirs = [];
@@ -49628,7 +49627,7 @@ async function scanAgentDir(dirPath, dirLabel) {
49628
49627
  color: frontmatter.color || null,
49629
49628
  skillCount: countSkills(frontmatter.tools),
49630
49629
  dirLabel,
49631
- relativePath: relative7(homedir15(), filePath)
49630
+ relativePath: relative7(homedir14(), filePath)
49632
49631
  });
49633
49632
  } catch {}
49634
49633
  }
@@ -49672,7 +49671,7 @@ function registerAgentsBrowserRoutes(app) {
49672
49671
  color: frontmatter.color || null,
49673
49672
  skillCount: countSkills(frontmatter.tools),
49674
49673
  dirLabel: dir.label,
49675
- relativePath: relative7(homedir15(), filePath),
49674
+ relativePath: relative7(homedir14(), filePath),
49676
49675
  frontmatter,
49677
49676
  body
49678
49677
  };
@@ -49687,7 +49686,7 @@ var home2;
49687
49686
  var init_agents_routes = __esm(() => {
49688
49687
  init_frontmatter_parser();
49689
49688
  init_kit_layout();
49690
- home2 = homedir15();
49689
+ home2 = homedir14();
49691
49690
  });
49692
49691
 
49693
49692
  // src/schemas/ck-config.schema.json
@@ -50524,7 +50523,7 @@ var init_ck_config_routes = __esm(() => {
50524
50523
  // src/domains/web-server/routes/command-routes.ts
50525
50524
  import { existsSync as existsSync16 } from "node:fs";
50526
50525
  import { readFile as readFile12, readdir as readdir8 } from "node:fs/promises";
50527
- import { homedir as homedir16 } from "node:os";
50526
+ import { homedir as homedir15 } from "node:os";
50528
50527
  import { basename as basename9, isAbsolute as isAbsolute5, join as join30, relative as relative8, resolve as resolve13 } from "node:path";
50529
50528
  async function buildCommandTree(dir, baseDir) {
50530
50529
  let dirents;
@@ -50566,7 +50565,7 @@ async function buildCommandTree(dir, baseDir) {
50566
50565
  }
50567
50566
  function registerCommandRoutes(app) {
50568
50567
  app.get("/api/commands", async (_req, res) => {
50569
- const commandsDir = join30(homedir16(), ".claude", "commands");
50568
+ const commandsDir = join30(homedir15(), ".claude", "commands");
50570
50569
  if (!existsSync16(commandsDir)) {
50571
50570
  res.json({ tree: [] });
50572
50571
  return;
@@ -50589,7 +50588,7 @@ function registerCommandRoutes(app) {
50589
50588
  res.status(400).json({ error: "Invalid path" });
50590
50589
  return;
50591
50590
  }
50592
- const commandsDir = join30(homedir16(), ".claude", "commands");
50591
+ const commandsDir = join30(homedir15(), ".claude", "commands");
50593
50592
  const safePath = resolve13(commandsDir, rawPath);
50594
50593
  const rel = relative8(commandsDir, safePath);
50595
50594
  if (rel.startsWith("..") || isAbsolute5(rel)) {
@@ -50663,11 +50662,11 @@ var init_types5 = __esm(() => {
50663
50662
 
50664
50663
  // src/services/claude-data/history-parser.ts
50665
50664
  import { createReadStream, statSync as statSync4 } from "node:fs";
50666
- import { homedir as homedir17 } from "node:os";
50665
+ import { homedir as homedir16 } from "node:os";
50667
50666
  import { join as join31 } from "node:path";
50668
50667
  import { createInterface as createInterface2 } from "node:readline";
50669
50668
  function getHistoryPath() {
50670
- return process.env.CLAUDE_HISTORY_PATH ?? join31(homedir17(), ".claude", "history.jsonl");
50669
+ return process.env.CLAUDE_HISTORY_PATH ?? join31(homedir16(), ".claude", "history.jsonl");
50671
50670
  }
50672
50671
  function emptyResult(parseTimeMs, error) {
50673
50672
  return { projects: [], totalEntries: 0, errorCount: 0, parseTimeMs, error };
@@ -50865,10 +50864,10 @@ var init_session_parser = () => {};
50865
50864
  // src/services/claude-data/skill-scanner.ts
50866
50865
  import { existsSync as existsSync18 } from "node:fs";
50867
50866
  import { readFile as readFile14, readdir as readdir10, stat as stat6 } from "node:fs/promises";
50868
- import { homedir as homedir18 } from "node:os";
50867
+ import { homedir as homedir17 } from "node:os";
50869
50868
  import { join as join33 } from "node:path";
50870
50869
  async function getCkSkillMetadata(scope) {
50871
- const metaPath = scope === "global" ? join33(homedir18(), ".claude", "metadata.json") : join33(process.cwd(), ".claude", "metadata.json");
50870
+ const metaPath = scope === "global" ? join33(homedir17(), ".claude", "metadata.json") : join33(process.cwd(), ".claude", "metadata.json");
50872
50871
  if (!existsSync18(metaPath))
50873
50872
  return null;
50874
50873
  const result = new Map;
@@ -50998,14 +50997,14 @@ async function scanSkills() {
50998
50997
  var import_gray_matter4, skillsDir, SKIP_DIRS2;
50999
50998
  var init_skill_scanner = __esm(() => {
51000
50999
  import_gray_matter4 = __toESM(require_gray_matter(), 1);
51001
- skillsDir = join33(homedir18(), ".claude", "skills");
51000
+ skillsDir = join33(homedir17(), ".claude", "skills");
51002
51001
  SKIP_DIRS2 = [".venv", "scripts", "__pycache__", "node_modules", ".git", "common"];
51003
51002
  });
51004
51003
 
51005
51004
  // src/services/claude-data/settings-reader.ts
51006
51005
  import { existsSync as existsSync19 } from "node:fs";
51007
51006
  import { copyFile as copyFile2, mkdir as mkdir9, readFile as readFile15, rename as rename5, rm as rm4, writeFile as writeFile10 } from "node:fs/promises";
51008
- import { homedir as homedir19 } from "node:os";
51007
+ import { homedir as homedir18 } from "node:os";
51009
51008
  import { join as join34 } from "node:path";
51010
51009
  function getSettingsPath() {
51011
51010
  return join34(claudeDir, settingsFilename);
@@ -51067,7 +51066,7 @@ function countMcpServers(settings) {
51067
51066
  }
51068
51067
  var claudeDir, settingsFilename = "settings.json", settingsBackupDir;
51069
51068
  var init_settings_reader = __esm(() => {
51070
- claudeDir = join34(homedir19(), ".claude");
51069
+ claudeDir = join34(homedir18(), ".claude");
51071
51070
  settingsBackupDir = join34(claudeDir, ".ck-backups", "settings");
51072
51071
  });
51073
51072
 
@@ -51235,7 +51234,7 @@ var init_hook_log_reader = __esm(() => {
51235
51234
  });
51236
51235
 
51237
51236
  // src/services/claude-data/project-scanner.ts
51238
- import { homedir as homedir20 } from "node:os";
51237
+ import { homedir as homedir19 } from "node:os";
51239
51238
  import { basename as basename10, join as join36, normalize as normalize4 } from "node:path";
51240
51239
  function decodePath(encoded) {
51241
51240
  const decoded = encoded.replace(/^-/, "/").replace(/-/g, "/");
@@ -51250,7 +51249,7 @@ function encodePath(path4) {
51250
51249
  }
51251
51250
  var projectsDir;
51252
51251
  var init_project_scanner = __esm(() => {
51253
- projectsDir = join36(homedir20(), ".claude", "projects");
51252
+ projectsDir = join36(homedir19(), ".claude", "projects");
51254
51253
  });
51255
51254
 
51256
51255
  // src/services/claude-data/project-discovery.ts
@@ -51345,10 +51344,10 @@ var init_project_discovery = __esm(() => {
51345
51344
 
51346
51345
  // src/services/claude-data/user-preferences.ts
51347
51346
  import { readFile as readFile16, stat as stat7 } from "node:fs/promises";
51348
- import { homedir as homedir21 } from "node:os";
51347
+ import { homedir as homedir20 } from "node:os";
51349
51348
  import { join as join37 } from "node:path";
51350
51349
  function getPreferencesPath() {
51351
- return join37(homedir21(), ".claude.json");
51350
+ return join37(homedir20(), ".claude.json");
51352
51351
  }
51353
51352
  async function readUserPreferences(filePath) {
51354
51353
  const path4 = filePath ?? getPreferencesPath();
@@ -51439,7 +51438,7 @@ var init_claude_data = __esm(() => {
51439
51438
  // src/domains/web-server/routes/dashboard-routes.ts
51440
51439
  import { existsSync as existsSync20 } from "node:fs";
51441
51440
  import { readFile as readFile17, readdir as readdir11 } from "node:fs/promises";
51442
- import { homedir as homedir22 } from "node:os";
51441
+ import { homedir as homedir21 } from "node:os";
51443
51442
  import { join as join38 } from "node:path";
51444
51443
  async function readAgents() {
51445
51444
  const agentsDir = join38(claudeDir2, "agents");
@@ -51509,7 +51508,7 @@ async function countAllMcpServers() {
51509
51508
  }
51510
51509
  let claudeJsonCount = 0;
51511
51510
  try {
51512
- const claudeJsonPath = join38(homedir22(), ".claude.json");
51511
+ const claudeJsonPath = join38(homedir21(), ".claude.json");
51513
51512
  if (existsSync20(claudeJsonPath)) {
51514
51513
  const content = await readFile17(claudeJsonPath, "utf-8");
51515
51514
  const data = JSON.parse(content);
@@ -51636,7 +51635,7 @@ var claudeDir2;
51636
51635
  var init_dashboard_routes = __esm(() => {
51637
51636
  init_frontmatter_parser();
51638
51637
  init_claude_data();
51639
- claudeDir2 = join38(homedir22(), ".claude");
51638
+ claudeDir2 = join38(homedir21(), ".claude");
51640
51639
  });
51641
51640
 
51642
51641
  // src/domains/web-server/routes/health-routes.ts
@@ -51710,7 +51709,7 @@ var init_hook_log_routes = __esm(() => {
51710
51709
  // src/domains/web-server/routes/mcp-routes.ts
51711
51710
  import { existsSync as existsSync21 } from "node:fs";
51712
51711
  import { readFile as readFile18 } from "node:fs/promises";
51713
- import { homedir as homedir23 } from "node:os";
51712
+ import { homedir as homedir22 } from "node:os";
51714
51713
  import { basename as basename12, join as join39, resolve as resolve14 } from "node:path";
51715
51714
  function parseMcpServers(raw, source, sourceLabel) {
51716
51715
  const entries = [];
@@ -51759,7 +51758,7 @@ function mergeServers(lists) {
51759
51758
  function isSafeProjectPath(projectPath) {
51760
51759
  if (projectPath.includes(".."))
51761
51760
  return false;
51762
- const home3 = homedir23();
51761
+ const home3 = homedir22();
51763
51762
  try {
51764
51763
  const resolved = resolve14(projectPath);
51765
51764
  if (!resolved.startsWith(home3))
@@ -51772,7 +51771,7 @@ function isSafeProjectPath(projectPath) {
51772
51771
  function registerMcpRoutes(app) {
51773
51772
  app.get("/api/mcp-servers", async (_req, res) => {
51774
51773
  try {
51775
- const claudeDir3 = join39(homedir23(), ".claude");
51774
+ const claudeDir3 = join39(homedir22(), ".claude");
51776
51775
  const allLists = [];
51777
51776
  try {
51778
51777
  const settings = await readSettings();
@@ -51782,7 +51781,7 @@ function registerMcpRoutes(app) {
51782
51781
  }
51783
51782
  } catch {}
51784
51783
  try {
51785
- const claudeJsonPath = join39(homedir23(), ".claude.json");
51784
+ const claudeJsonPath = join39(homedir22(), ".claude.json");
51786
51785
  if (existsSync21(claudeJsonPath)) {
51787
51786
  const content = await readFile18(claudeJsonPath, "utf-8");
51788
51787
  const parsed = JSON.parse(content);
@@ -52043,7 +52042,7 @@ var init_skill_directory_installer = __esm(() => {
52043
52042
  // src/commands/portable/config-discovery.ts
52044
52043
  import { existsSync as existsSync23, readFileSync as readFileSync6 } from "node:fs";
52045
52044
  import { cp as cp2, mkdir as mkdir11, readFile as readFile19, readdir as readdir12, stat as stat8 } from "node:fs/promises";
52046
- import { homedir as homedir24 } from "node:os";
52045
+ import { homedir as homedir23 } from "node:os";
52047
52046
  import { basename as basename13, dirname as dirname12, extname as extname3, join as join41, relative as relative9, resolve as resolve16, sep as sep6 } from "node:path";
52048
52047
  async function copyHooksCompanionDirs(sourceDir, targetDir) {
52049
52048
  const result = {
@@ -52126,7 +52125,7 @@ async function copyHooksCompanionDirs(sourceDir, targetDir) {
52126
52125
  function resolveSourceOrigin(sourcePath) {
52127
52126
  if (!sourcePath)
52128
52127
  return "global";
52129
- const home3 = homedir24();
52128
+ const home3 = homedir23();
52130
52129
  const cwd2 = process.cwd();
52131
52130
  if (cwd2 === home3)
52132
52131
  return "global";
@@ -52141,16 +52140,16 @@ function getConfigSourcePath(globalOnly = false) {
52141
52140
  return findExistingProjectConfigPath(process.cwd()) ?? getGlobalConfigSourcePath();
52142
52141
  }
52143
52142
  function getGlobalConfigSourcePath() {
52144
- return join41(homedir24(), ".claude", "CLAUDE.md");
52143
+ return join41(homedir23(), ".claude", "CLAUDE.md");
52145
52144
  }
52146
52145
  function getRulesSourcePath(globalOnly = false) {
52147
- const globalPath = join41(homedir24(), ".claude", "rules");
52146
+ const globalPath = join41(homedir23(), ".claude", "rules");
52148
52147
  if (globalOnly)
52149
52148
  return globalPath;
52150
52149
  return findExistingProjectLayoutPath(process.cwd(), "rules") ?? globalPath;
52151
52150
  }
52152
52151
  function getHooksSourcePath(globalOnly = false) {
52153
- const globalPath = join41(homedir24(), ".claude", "hooks");
52152
+ const globalPath = join41(homedir23(), ".claude", "hooks");
52154
52153
  if (globalOnly)
52155
52154
  return globalPath;
52156
52155
  return findExistingProjectLayoutPath(process.cwd(), "hooks") ?? globalPath;
@@ -54339,7 +54338,7 @@ var init_codex_capabilities = __esm(() => {
54339
54338
  // src/commands/portable/codex-path-safety.ts
54340
54339
  import { existsSync as existsSync24 } from "node:fs";
54341
54340
  import { mkdir as mkdir12, realpath as realpath7 } from "node:fs/promises";
54342
- import { homedir as homedir25 } from "node:os";
54341
+ import { homedir as homedir24 } from "node:os";
54343
54342
  import { dirname as dirname13, join as join42, resolve as resolve17, sep as sep7 } from "node:path";
54344
54343
  function isPathWithinBoundary3(targetPath, boundaryPath) {
54345
54344
  const resolvedTarget = resolve17(targetPath);
@@ -54386,7 +54385,7 @@ async function withCodexTargetLock2(targetFilePath, operation) {
54386
54385
  }
54387
54386
  }
54388
54387
  function getCodexGlobalBoundary() {
54389
- return join42(homedir25(), ".codex");
54388
+ return join42(homedir24(), ".codex");
54390
54389
  }
54391
54390
  var import_proper_lockfile6;
54392
54391
  var init_codex_path_safety = __esm(() => {
@@ -54781,7 +54780,7 @@ var init_codex_hook_wrapper = __esm(() => {
54781
54780
  });
54782
54781
 
54783
54782
  // src/commands/portable/converters/claude-to-codex-hooks.ts
54784
- import { homedir as homedir26 } from "node:os";
54783
+ import { homedir as homedir25 } from "node:os";
54785
54784
  function convertClaudeHooksToCodex(sourceHooks, capabilities, pathRewrite) {
54786
54785
  const result = {};
54787
54786
  for (const [event, groups] of Object.entries(sourceHooks)) {
@@ -54839,7 +54838,7 @@ function rewriteCommandPath(command, pathRewrite) {
54839
54838
  const normalizeSlashes = (s) => s.replace(/\\/g, "/");
54840
54839
  let rewritten = command;
54841
54840
  if (pathRewrite.commandSubstitutions && pathRewrite.commandSubstitutions.size > 0) {
54842
- const home3 = homedir26();
54841
+ const home3 = homedir25();
54843
54842
  const homeForward = normalizeSlashes(home3);
54844
54843
  for (const [originalAbsPath, wrapperAbsPath] of pathRewrite.commandSubstitutions) {
54845
54844
  const originalAbsForward = normalizeSlashes(originalAbsPath);
@@ -54942,7 +54941,7 @@ var init_gemini_hook_event_map = __esm(() => {
54942
54941
  // src/commands/portable/hooks-settings-merger.ts
54943
54942
  import { existsSync as existsSync26 } from "node:fs";
54944
54943
  import { mkdir as mkdir13, readFile as readFile21, rename as rename8, rm as rm6, writeFile as writeFile12 } from "node:fs/promises";
54945
- import { homedir as homedir27 } from "node:os";
54944
+ import { homedir as homedir26 } from "node:os";
54946
54945
  import { basename as basename14, dirname as dirname16, extname as extname4, join as join44, resolve as resolve20 } from "node:path";
54947
54946
  function isCodexWrappableHookPath(filePath) {
54948
54947
  return hookAssetBasename(filePath) !== "node-hook-runner.sh" && CODEX_WRAPPABLE_HOOK_EXTENSIONS.has(extname4(filePath).toLowerCase());
@@ -55025,7 +55024,7 @@ function normalizeDirPattern(value) {
55025
55024
  }
55026
55025
  function homeRelativeDir(value) {
55027
55026
  const normalized = normalizeDirPattern(value);
55028
- const home3 = normalizeDirPattern(homedir27());
55027
+ const home3 = normalizeDirPattern(homedir26());
55029
55028
  return normalized.startsWith(`${home3}/`) ? normalized.slice(home3.length + 1) : normalized;
55030
55029
  }
55031
55030
  function buildHookDirRewritePairs(sourceHooksDir, targetHooksDir) {
@@ -55582,7 +55581,7 @@ async function migrateHooksSettingsForCodex(options2) {
55582
55581
  }
55583
55582
  let featureFlagWritten = false;
55584
55583
  if (capabilities.requiresFeatureFlag) {
55585
- const configTomlPath = isGlobal ? join44(homedir27(), ".codex", "config.toml") : join44(process.cwd(), ".codex", "config.toml");
55584
+ const configTomlPath = isGlobal ? join44(homedir26(), ".codex", "config.toml") : join44(process.cwd(), ".codex", "config.toml");
55586
55585
  const flagResult = await ensureCodexHooksFeatureFlag(configTomlPath, isGlobal);
55587
55586
  featureFlagWritten = flagResult.status === "written" || flagResult.status === "updated";
55588
55587
  }
@@ -56987,10 +56986,10 @@ __export(exports_skills_discovery, {
56987
56986
  discoverSkills: () => discoverSkills
56988
56987
  });
56989
56988
  import { readFile as readFile25, readdir as readdir13, stat as stat9 } from "node:fs/promises";
56990
- import { homedir as homedir28 } from "node:os";
56989
+ import { homedir as homedir27 } from "node:os";
56991
56990
  import { dirname as dirname17, join as join45 } from "node:path";
56992
56991
  function getSkillSourcePath(globalOnly = false) {
56993
- const globalPath = join45(homedir28(), ".claude/skills");
56992
+ const globalPath = join45(homedir27(), ".claude/skills");
56994
56993
  if (globalOnly) {
56995
56994
  return findFirstExistingPath([globalPath]);
56996
56995
  }
@@ -57231,7 +57230,7 @@ var init_migration_result_utils = __esm(() => {
57231
57230
  // src/domains/web-server/routes/migration-routes.ts
57232
57231
  import { existsSync as existsSync30 } from "node:fs";
57233
57232
  import { readFile as readFile26, rm as rm8 } from "node:fs/promises";
57234
- import { homedir as homedir29 } from "node:os";
57233
+ import { homedir as homedir28 } from "node:os";
57235
57234
  import { basename as basename17, join as join46, resolve as resolve23 } from "node:path";
57236
57235
  function resolveRegistryDeps(deps) {
57237
57236
  return {
@@ -57910,7 +57909,7 @@ function registerMigrationRoutes(app, deps) {
57910
57909
  };
57911
57910
  const discovered = await discoverMigrationItems(includeAll);
57912
57911
  const cwd2 = process.cwd();
57913
- const home3 = homedir29();
57912
+ const home3 = homedir28();
57914
57913
  res.status(200).json({
57915
57914
  cwd: cwd2,
57916
57915
  targetPaths: {
@@ -59426,7 +59425,7 @@ function scanPlanDir(dir) {
59426
59425
  var init_plan_scanner = () => {};
59427
59426
 
59428
59427
  // src/domains/plan-parser/plan-scope.ts
59429
- import { homedir as homedir30 } from "node:os";
59428
+ import { homedir as homedir29 } from "node:os";
59430
59429
  import { isAbsolute as isAbsolute8, join as join49, relative as relative12, resolve as resolve25 } from "node:path";
59431
59430
  function resolveConfiguredDir(configuredPath, baseDir) {
59432
59431
  const trimmed = configuredPath?.trim();
@@ -59439,7 +59438,7 @@ function resolveProjectPlansDir(projectRoot, config) {
59439
59438
  return resolveConfiguredDir(config?.paths?.plans, projectRoot);
59440
59439
  }
59441
59440
  function resolveGlobalPlansDir(config) {
59442
- return resolveConfiguredDir(config?.paths?.globalPlans, join49(homedir30(), ".claude"));
59441
+ return resolveConfiguredDir(config?.paths?.globalPlans, join49(homedir29(), ".claude"));
59443
59442
  }
59444
59443
  function resolvePlanDirForScope(scope, projectRoot, config) {
59445
59444
  return scope === "global" ? resolveGlobalPlansDir(config) : resolveProjectPlansDir(projectRoot, config);
@@ -60711,7 +60710,7 @@ var init_p_limit = __esm(() => {
60711
60710
 
60712
60711
  // src/domains/web-server/routes/plan-routes.ts
60713
60712
  import { existsSync as existsSync36, readFileSync as readFileSync12, realpathSync as realpathSync2 } from "node:fs";
60714
- import { homedir as homedir31 } from "node:os";
60713
+ import { homedir as homedir30 } from "node:os";
60715
60714
  import { basename as basename20, dirname as dirname24, join as join54, relative as relative14, resolve as resolve27, sep as sep8 } from "node:path";
60716
60715
  function sanitizeError(err) {
60717
60716
  if (err instanceof Error) {
@@ -60902,7 +60901,7 @@ function withTimeout(promiseFactory, timeoutMs, label) {
60902
60901
  function isCurrentProjectFallbackCandidate(currentPath, globalProjectKey) {
60903
60902
  if (toProjectPathKey(currentPath) === globalProjectKey)
60904
60903
  return false;
60905
- if (toProjectPathKey(currentPath) === toProjectPathKey(homedir31()))
60904
+ if (toProjectPathKey(currentPath) === toProjectPathKey(homedir30()))
60906
60905
  return false;
60907
60906
  return existsSync36(join54(currentPath, ".git")) || existsSync36(CkConfigManager.getProjectConfigPath(currentPath)) || existsSync36(join54(currentPath, "plans"));
60908
60907
  }
@@ -60967,7 +60966,7 @@ function registerPlanRoutes(app) {
60967
60966
  });
60968
60967
  app.get("/api/plan/list-all", async (_req, res) => {
60969
60968
  try {
60970
- const globalProjectKey = toProjectPathKey(join54(homedir31(), ".claude"));
60969
+ const globalProjectKey = toProjectPathKey(join54(homedir30(), ".claude"));
60971
60970
  const seenProjectKeys = new Set;
60972
60971
  const scanTargets = [];
60973
60972
  for (const project of await ProjectsRegistryManager.listProjects()) {
@@ -61214,7 +61213,7 @@ var init_project_plan_data = __esm(() => {
61214
61213
  // src/domains/web-server/routes/project-routes.ts
61215
61214
  import { existsSync as existsSync37 } from "node:fs";
61216
61215
  import { readFile as readFile27 } from "node:fs/promises";
61217
- import { homedir as homedir32 } from "node:os";
61216
+ import { homedir as homedir31 } from "node:os";
61218
61217
  import { basename as basename21, join as join55, resolve as resolve28 } from "node:path";
61219
61218
  function registerProjectRoutes(app) {
61220
61219
  app.get("/api/projects", async (req, res) => {
@@ -61235,7 +61234,7 @@ function registerProjectRoutes(app) {
61235
61234
  for (const discovered of discoveredProjects) {
61236
61235
  if (registeredPaths.has(discovered.path))
61237
61236
  continue;
61238
- if (discovered.path === join55(homedir32(), ".claude"))
61237
+ if (discovered.path === join55(homedir31(), ".claude"))
61239
61238
  continue;
61240
61239
  const projectInfo = await detectAndBuildProjectInfo(discovered.path, `discovered-${discovered.path}`, cachedSettings, cachedSkills, false);
61241
61240
  if (projectInfo) {
@@ -61251,7 +61250,7 @@ function registerProjectRoutes(app) {
61251
61250
  if (cwdProject) {
61252
61251
  projects.push(cwdProject);
61253
61252
  }
61254
- const globalDir = join55(homedir32(), ".claude");
61253
+ const globalDir = join55(homedir31(), ".claude");
61255
61254
  const globalProject = await detectAndBuildProjectInfo(globalDir, "global", undefined, undefined, false);
61256
61255
  if (globalProject) {
61257
61256
  projects.push(globalProject);
@@ -61323,12 +61322,12 @@ function registerProjectRoutes(app) {
61323
61322
  const body = validation.data;
61324
61323
  let projectPath = body.path;
61325
61324
  if (projectPath.startsWith("~/") || projectPath === "~") {
61326
- projectPath = join55(homedir32(), projectPath.slice(1));
61325
+ projectPath = join55(homedir31(), projectPath.slice(1));
61327
61326
  } else if (projectPath.startsWith("~\\")) {
61328
- projectPath = join55(homedir32(), projectPath.slice(1));
61327
+ projectPath = join55(homedir31(), projectPath.slice(1));
61329
61328
  }
61330
61329
  projectPath = resolve28(projectPath);
61331
- const homeDir = homedir32();
61330
+ const homeDir = homedir31();
61332
61331
  if (projectPath.includes("..") || !projectPath.startsWith(homeDir)) {
61333
61332
  res.status(400).json({ error: "Invalid path after expansion" });
61334
61333
  return;
@@ -61385,7 +61384,7 @@ function registerProjectRoutes(app) {
61385
61384
  if (id === "current") {
61386
61385
  projectPath = process.cwd();
61387
61386
  } else if (id === "global") {
61388
- projectPath = join55(homedir32(), ".claude");
61387
+ projectPath = join55(homedir31(), ".claude");
61389
61388
  } else {
61390
61389
  res.status(404).json({ error: "Project not found" });
61391
61390
  return;
@@ -61465,7 +61464,7 @@ async function buildProjectInfoFromRegistry(registered, cachedSettings, cachedSk
61465
61464
  const hasLocalConfig = hasClaudeDir && CkConfigManager.projectConfigExists(registered.path, false);
61466
61465
  const settings = cachedSettings !== undefined ? cachedSettings : await readSettings();
61467
61466
  const skills = cachedSkills !== undefined ? cachedSkills : await scanSkills();
61468
- const settingsPath = join55(homedir32(), ".claude", "settings.json");
61467
+ const settingsPath = join55(homedir31(), ".claude", "settings.json");
61469
61468
  const health = existsSync37(settingsPath) ? "healthy" : "warning";
61470
61469
  const model = getCurrentModel() || settings?.model || "claude-sonnet-4";
61471
61470
  const planData = includePlanData ? await buildProjectPlanData(registered.path, "project") : null;
@@ -61507,7 +61506,7 @@ async function detectAndBuildProjectInfo(path6, id, cachedSettings, cachedSkills
61507
61506
  const hasLocalConfig = CkConfigManager.projectConfigExists(path6, id === "global");
61508
61507
  const settings = cachedSettings !== undefined ? cachedSettings : await readSettings();
61509
61508
  const skills = cachedSkills !== undefined ? cachedSkills : await scanSkills();
61510
- const settingsPath = join55(homedir32(), ".claude", "settings.json");
61509
+ const settingsPath = join55(homedir31(), ".claude", "settings.json");
61511
61510
  const health = existsSync37(settingsPath) ? "healthy" : "warning";
61512
61511
  const model = getCurrentModel() || settings?.model || "claude-sonnet-4";
61513
61512
  const scope = id === "global" ? "global" : "project";
@@ -61555,7 +61554,7 @@ var init_project_routes = __esm(() => {
61555
61554
  // src/domains/web-server/routes/session-routes.ts
61556
61555
  import { existsSync as existsSync38 } from "node:fs";
61557
61556
  import { readFile as readFile28, readdir as readdir14, stat as stat10 } from "node:fs/promises";
61558
- import { homedir as homedir33 } from "node:os";
61557
+ import { homedir as homedir32 } from "node:os";
61559
61558
  import { basename as basename22, join as join56 } from "node:path";
61560
61559
  function toDateStr(d3) {
61561
61560
  const y3 = d3.getFullYear();
@@ -61564,7 +61563,7 @@ function toDateStr(d3) {
61564
61563
  return `${y3}-${m2}-${day}`;
61565
61564
  }
61566
61565
  async function scanActivityMetrics(periodDays) {
61567
- const home3 = homedir33();
61566
+ const home3 = homedir32();
61568
61567
  const projectsDir2 = join56(home3, ".claude", "projects");
61569
61568
  const cutoff = new Date;
61570
61569
  cutoff.setDate(cutoff.getDate() - periodDays);
@@ -61635,7 +61634,7 @@ async function scanActivityMetrics(periodDays) {
61635
61634
  return { totalSessions, projects: projectActivities, dailyCounts };
61636
61635
  }
61637
61636
  async function resolveSessionDir(projectId) {
61638
- const home3 = homedir33();
61637
+ const home3 = homedir32();
61639
61638
  if (projectId.startsWith("discovered-")) {
61640
61639
  try {
61641
61640
  const encodedPathB64 = projectId.slice("discovered-".length);
@@ -61809,7 +61808,7 @@ async function parseSessionDetail(filePath, limit, offset) {
61809
61808
  }
61810
61809
  function registerSessionRoutes(app) {
61811
61810
  app.get("/api/sessions", async (_req, res) => {
61812
- const home3 = homedir33();
61811
+ const home3 = homedir32();
61813
61812
  const projectsDir2 = join56(home3, ".claude", "projects");
61814
61813
  if (!existsSync38(projectsDir2)) {
61815
61814
  res.json({ projects: [] });
@@ -61878,7 +61877,7 @@ function registerSessionRoutes(app) {
61878
61877
  res.status(404).json({ error: "Project not found" });
61879
61878
  return;
61880
61879
  }
61881
- const allowedBase = join56(homedir33(), ".claude", "projects");
61880
+ const allowedBase = join56(homedir32(), ".claude", "projects");
61882
61881
  if (!projectDir.startsWith(allowedBase)) {
61883
61882
  res.status(403).json({ error: "Access denied" });
61884
61883
  return;
@@ -61908,7 +61907,7 @@ function registerSessionRoutes(app) {
61908
61907
  res.status(404).json({ error: "Project not found" });
61909
61908
  return;
61910
61909
  }
61911
- const allowedBase = join56(homedir33(), ".claude", "projects");
61910
+ const allowedBase = join56(homedir32(), ".claude", "projects");
61912
61911
  if (!projectDir.startsWith(allowedBase)) {
61913
61912
  res.status(403).json({ error: "Access denied" });
61914
61913
  return;
@@ -61942,7 +61941,7 @@ var init_session_routes = __esm(() => {
61942
61941
  });
61943
61942
 
61944
61943
  // src/domains/web-server/routes/settings-routes.ts
61945
- import { homedir as homedir34 } from "node:os";
61944
+ import { homedir as homedir33 } from "node:os";
61946
61945
  function registerSettingsRoutes(app) {
61947
61946
  app.get("/api/settings", async (_req, res) => {
61948
61947
  try {
@@ -61998,7 +61997,7 @@ function registerSettingsRoutes(app) {
61998
61997
  res.json({
61999
61998
  success: true,
62000
61999
  path: "~/.claude/settings.json",
62001
- backupPath: saveResult.backupPath ? saveResult.backupPath.replace(homedir34(), "~") : null,
62000
+ backupPath: saveResult.backupPath ? saveResult.backupPath.replace(homedir33(), "~") : null,
62002
62001
  absolutePath: getSettingsPath()
62003
62002
  });
62004
62003
  } catch (error) {
@@ -62032,7 +62031,7 @@ var init_settings_routes = __esm(() => {
62032
62031
 
62033
62032
  // src/domains/skills/skill-catalog-generator.ts
62034
62033
  import { mkdir as mkdir14, readFile as readFile29, readdir as readdir15, rename as rename10, stat as stat11, writeFile as writeFile14 } from "node:fs/promises";
62035
- import { homedir as homedir35 } from "node:os";
62034
+ import { homedir as homedir34 } from "node:os";
62036
62035
  import { dirname as dirname25, join as join57, relative as relative15 } from "node:path";
62037
62036
  async function hasScripts(skillPath) {
62038
62037
  try {
@@ -62175,7 +62174,7 @@ var CATALOG_PATH, CATALOG_VERSION = "1.0.0", SKIP_DIRS4, skillCatalogGenerator;
62175
62174
  var init_skill_catalog_generator = __esm(() => {
62176
62175
  init_skills_discovery();
62177
62176
  init_logger();
62178
- CATALOG_PATH = join57(homedir35(), ".claude", ".skills-catalog.json");
62177
+ CATALOG_PATH = join57(homedir34(), ".claude", ".skills-catalog.json");
62179
62178
  SKIP_DIRS4 = [".venv", "__pycache__", "node_modules", ".git"];
62180
62179
  skillCatalogGenerator = new SkillCatalogGenerator;
62181
62180
  });
@@ -62465,7 +62464,7 @@ var init_skill_browser_routes = __esm(() => {
62465
62464
 
62466
62465
  // src/commands/skills/agents.ts
62467
62466
  import { existsSync as existsSync39, readdirSync as readdirSync6, statSync as statSync8 } from "node:fs";
62468
- import { homedir as homedir37, platform as platform5 } from "node:os";
62467
+ import { homedir as homedir36, platform as platform5 } from "node:os";
62469
62468
  import { join as join59 } from "node:path";
62470
62469
  function hasInstallSignal2(path7) {
62471
62470
  if (!path7 || !existsSync39(path7)) {
@@ -62522,7 +62521,7 @@ function isSkillInstalled(skillName, agent, options2) {
62522
62521
  }
62523
62522
  var home3, OPENCODE_BINARY_NAME2, agents;
62524
62523
  var init_agents = __esm(() => {
62525
- home3 = homedir37();
62524
+ home3 = homedir36();
62526
62525
  OPENCODE_BINARY_NAME2 = platform5() === "win32" ? "opencode.exe" : "opencode";
62527
62526
  agents = {
62528
62527
  "claude-code": {
@@ -62629,7 +62628,7 @@ var init_agents = __esm(() => {
62629
62628
  // src/commands/skills/skills-registry.ts
62630
62629
  import { existsSync as existsSync40 } from "node:fs";
62631
62630
  import { mkdir as mkdir15, readFile as readFile31, writeFile as writeFile15 } from "node:fs/promises";
62632
- import { homedir as homedir38 } from "node:os";
62631
+ import { homedir as homedir37 } from "node:os";
62633
62632
  import { dirname as dirname26, join as join60, sep as sep10 } from "node:path";
62634
62633
  function getCliVersion3() {
62635
62634
  try {
@@ -62741,7 +62740,7 @@ async function syncRegistry() {
62741
62740
  var home4, REGISTRY_PATH, SkillInstallationSchema, SkillRegistrySchema, REGISTRY_PATH_MIGRATIONS;
62742
62741
  var init_skills_registry = __esm(() => {
62743
62742
  init_zod();
62744
- home4 = homedir38();
62743
+ home4 = homedir37();
62745
62744
  REGISTRY_PATH = join60(home4, ".claudekit", "skill-registry.json");
62746
62745
  SkillInstallationSchema = exports_external.object({
62747
62746
  skill: exports_external.string(),
@@ -62773,7 +62772,7 @@ var init_skills_registry = __esm(() => {
62773
62772
  // src/commands/skills/skills-installer.ts
62774
62773
  import { existsSync as existsSync41 } from "node:fs";
62775
62774
  import { cp as cp3, mkdir as mkdir16, rm as rm9, stat as stat12 } from "node:fs/promises";
62776
- import { homedir as homedir39 } from "node:os";
62775
+ import { homedir as homedir38 } from "node:os";
62777
62776
  import { dirname as dirname27, join as join61, resolve as resolve30 } from "node:path";
62778
62777
  function isSamePath2(path1, path22) {
62779
62778
  try {
@@ -62904,7 +62903,7 @@ var init_skills_installer = __esm(() => {
62904
62903
  LEGACY_SKILL_PATHS = {
62905
62904
  "gemini-cli": {
62906
62905
  project: ".gemini/skills",
62907
- global: join61(homedir39(), ".gemini/skills")
62906
+ global: join61(homedir38(), ".gemini/skills")
62908
62907
  }
62909
62908
  };
62910
62909
  });
@@ -63853,7 +63852,7 @@ var package_default;
63853
63852
  var init_package = __esm(() => {
63854
63853
  package_default = {
63855
63854
  name: "claudekit-cli",
63856
- version: "4.3.1-dev.17",
63855
+ version: "4.3.1-dev.18",
63857
63856
  description: "CLI tool for bootstrapping and updating ClaudeKit projects",
63858
63857
  type: "module",
63859
63858
  repository: {
@@ -64335,7 +64334,7 @@ var init_package_manager_runner = __esm(() => {
64335
64334
 
64336
64335
  // src/domains/installation/merger/zombie-wirings-pruner.ts
64337
64336
  import { existsSync as existsSync44, readdirSync as readdirSync7 } from "node:fs";
64338
- import { homedir as homedir40 } from "node:os";
64337
+ import { homedir as homedir39 } from "node:os";
64339
64338
  import { basename as basename23, dirname as dirname28, isAbsolute as isAbsolute10, resolve as resolve32, sep as sep11 } from "node:path";
64340
64339
  function pruneZombieEngineerWirings(settings, hookDir, preserveCommands = new Set) {
64341
64340
  const pruned = [];
@@ -64415,7 +64414,7 @@ function extractHookFilePath(command, hookDir) {
64415
64414
  return null;
64416
64415
  if (/&&|\|\||;|(?<!["|'])\|(?!["|'])/.test(command))
64417
64416
  return null;
64418
- const home5 = homedir40().replace(/\\/g, "/");
64417
+ const home5 = homedir39().replace(/\\/g, "/");
64419
64418
  const hookDirNorm = hookDir.replace(/\\/g, "/");
64420
64419
  function resolveEnvPath(prefix, rest) {
64421
64420
  const normRest = rest.replace(/\\/g, "/");
@@ -64495,7 +64494,7 @@ var init_shared2 = __esm(() => {
64495
64494
  import { spawnSync as spawnSync3 } from "node:child_process";
64496
64495
  import { existsSync as existsSync45, readFileSync as readFileSync13, readdirSync as readdirSync8, statSync as statSync9, writeFileSync as writeFileSync5 } from "node:fs";
64497
64496
  import { readdir as readdir17 } from "node:fs/promises";
64498
- import { homedir as homedir41, tmpdir } from "node:os";
64497
+ import { homedir as homedir40, tmpdir } from "node:os";
64499
64498
  import { join as join64, resolve as resolve33 } from "node:path";
64500
64499
  function resolveDoctorCkExecutable(platformName = process.platform) {
64501
64500
  return platformName === "win32" ? "ck.cmd" : "ck";
@@ -64525,12 +64524,12 @@ function isPathWithin2(filePath, parentDir) {
64525
64524
  }
64526
64525
  function getCanonicalGlobalCommandRoot() {
64527
64526
  const configuredGlobalDir = PathResolver.getGlobalKitDir().replace(/\\/g, "/").replace(/\/+$/, "");
64528
- const defaultGlobalDir = join64(homedir41(), ".claude").replace(/\\/g, "/");
64527
+ const defaultGlobalDir = join64(homedir40(), ".claude").replace(/\\/g, "/");
64529
64528
  return configuredGlobalDir === defaultGlobalDir ? "$HOME" : configuredGlobalDir;
64530
64529
  }
64531
64530
  function getClaudeSettingsFiles(projectDir) {
64532
64531
  const globalClaudeDir = PathResolver.getGlobalKitDir();
64533
- const ccsSettingsDir = join64(process.env.CK_TEST_HOME ?? homedir41(), ".ccs");
64532
+ const ccsSettingsDir = join64(process.env.CK_TEST_HOME ?? homedir40(), ".ccs");
64534
64533
  const candidates = [
64535
64534
  {
64536
64535
  path: resolve33(projectDir, ".claude", "settings.json"),
@@ -65229,7 +65228,7 @@ function extractHookReferencePaths(cmd) {
65229
65228
  }
65230
65229
  function resolveHookScriptPath(scriptPath, projectDir) {
65231
65230
  let resolved = scriptPath.replace(/\\/g, "/");
65232
- const home5 = homedir41();
65231
+ const home5 = homedir40();
65233
65232
  resolved = resolved.replace(/^\$\{?HOME\}?/, home5);
65234
65233
  resolved = resolved.replace(/^\$\{?CLAUDE_PROJECT_DIR\}?/, projectDir);
65235
65234
  resolved = resolved.replace(/^%USERPROFILE%/, home5);
@@ -67444,6 +67443,61 @@ async function readMetadataFile(claudeDir3) {
67444
67443
  return null;
67445
67444
  }
67446
67445
  }
67446
+ function extractCkHookName(command) {
67447
+ if (!command.trim().startsWith("node "))
67448
+ return null;
67449
+ const normalized = command.replace(/\\/g, "/");
67450
+ const match = normalized.match(/\/hooks\/([^/"'\s]+)\.(?:cjs|mjs|js)(?:["'\s]|$)/);
67451
+ return match?.[1] ?? null;
67452
+ }
67453
+ function collectSettingsHookCommands(settings) {
67454
+ const commands = new Set;
67455
+ for (const entries of Object.values(settings.hooks ?? {})) {
67456
+ for (const entry of entries) {
67457
+ if (typeof entry.command === "string") {
67458
+ commands.add(normalizeCommand(entry.command));
67459
+ }
67460
+ for (const hook of entry.hooks ?? []) {
67461
+ if (typeof hook.command === "string") {
67462
+ commands.add(normalizeCommand(hook.command));
67463
+ }
67464
+ }
67465
+ }
67466
+ }
67467
+ return commands;
67468
+ }
67469
+ function getInstalledHookCommands(config, kit) {
67470
+ const kits = Object.entries(config.kits ?? {});
67471
+ if (kits.length === 0)
67472
+ return [];
67473
+ const kitKey = kit?.toLowerCase();
67474
+ const preferred = kitKey ? kits.filter(([name]) => {
67475
+ const normalizedName = name.toLowerCase();
67476
+ return normalizedName === kitKey || normalizedName.includes(kitKey);
67477
+ }) : [];
67478
+ const candidates = preferred.length > 0 ? preferred : kits;
67479
+ return candidates.flatMap(([, entry]) => entry.installedSettings?.hooks ?? []);
67480
+ }
67481
+ async function countMissingCkHookRegistrations(claudeDir3, kit) {
67482
+ const settingsPath = join68(claudeDir3, "settings.json");
67483
+ const configPath = join68(claudeDir3, ".ck.json");
67484
+ if (!existsSync47(settingsPath) || !existsSync47(configPath))
67485
+ return 0;
67486
+ const settings = parseJsonContent(await import_fs_extra8.readFile(settingsPath, "utf-8"));
67487
+ const config = parseJsonContent(await import_fs_extra8.readFile(configPath, "utf-8"));
67488
+ const existingCommands = collectSettingsHookCommands(settings);
67489
+ const disabledHooks = new Set(Object.entries(config.hooks ?? {}).filter(([, enabled]) => enabled === false).map(([name]) => name));
67490
+ let missing = 0;
67491
+ for (const command of getInstalledHookCommands(config, kit)) {
67492
+ const hookName = extractCkHookName(command);
67493
+ if (hookName && disabledHooks.has(hookName))
67494
+ continue;
67495
+ if (!existingCommands.has(normalizeCommand(command))) {
67496
+ missing++;
67497
+ }
67498
+ }
67499
+ return missing;
67500
+ }
67447
67501
  function buildInitCommand(isGlobal, kit, beta, yes, restoreCkHooks) {
67448
67502
  const parts = ["ck init"];
67449
67503
  if (isGlobal)
@@ -67565,6 +67619,27 @@ async function promptKitUpdate(beta, yes, deps) {
67565
67619
  };
67566
67620
  }
67567
67621
  }
67622
+ const selectedClaudeDir = selection.isGlobal ? setup.global.path : setup.project.path;
67623
+ if (selectedClaudeDir) {
67624
+ try {
67625
+ const missingHookDeps = await findMissingHookDepsFn(selectedClaudeDir);
67626
+ if (missingHookDeps.length > 0) {
67627
+ logger.warning(`Detected ${missingHookDeps.length} ${selection.isGlobal ? "global" : "local"} missing hook dependency(ies); reinstalling kit content`);
67628
+ forceKitReinstall = true;
67629
+ }
67630
+ } catch (error) {
67631
+ logger.verbose(`Selected hook dependency self-heal check skipped: ${error instanceof Error ? error.message : "unknown"}`);
67632
+ }
67633
+ try {
67634
+ const missingHookRegistrations = await countMissingCkHookRegistrations(selectedClaudeDir, selection.kit);
67635
+ if (missingHookRegistrations > 0) {
67636
+ logger.warning(`Detected ${missingHookRegistrations} ${selection.isGlobal ? "global" : "local"} missing hook registration(s); reinstalling kit content`);
67637
+ forceKitReinstall = true;
67638
+ }
67639
+ } catch (error) {
67640
+ logger.verbose(`Selected hook registration self-heal check skipped: ${error instanceof Error ? error.message : "unknown"}`);
67641
+ }
67642
+ }
67568
67643
  let kitVersion = selection.kit ? selection.isGlobal ? globalMetadata?.kits?.[selection.kit]?.version : localMetadata?.kits?.[selection.kit]?.version : undefined;
67569
67644
  const isBetaInstalled = isBetaVersion(kitVersion);
67570
67645
  const promptMessage = selection.promptMessage;
@@ -67834,6 +67909,7 @@ var init_post_update_handler = __esm(() => {
67834
67909
  init_metadata_migration();
67835
67910
  init_version_utils();
67836
67911
  init_claudekit_scanner();
67912
+ init_command_normalizer();
67837
67913
  init_logger();
67838
67914
  init_safe_prompts();
67839
67915
  init_types3();
@@ -68239,7 +68315,7 @@ import { spawn as spawn3 } from "node:child_process";
68239
68315
  import { execFile as execFile8 } from "node:child_process";
68240
68316
  import { existsSync as existsSync48 } from "node:fs";
68241
68317
  import { readFile as readFile38 } from "node:fs/promises";
68242
- import { cpus, homedir as homedir42, totalmem } from "node:os";
68318
+ import { cpus, homedir as homedir41, totalmem } from "node:os";
68243
68319
  import { join as join70 } from "node:path";
68244
68320
  function runCommand(cmd, args, fallback2) {
68245
68321
  return new Promise((resolve34) => {
@@ -68405,7 +68481,7 @@ function registerSystemRoutes(app) {
68405
68481
  gitVersion,
68406
68482
  ghVersion,
68407
68483
  shell: process.env.SHELL ?? process.env.ComSpec ?? "unknown",
68408
- homeDir: homedir42(),
68484
+ homeDir: homedir41(),
68409
68485
  cpuCores: cpus().length,
68410
68486
  totalMemoryGb: (totalmem() / 1024 ** 3).toFixed(1)
68411
68487
  };
@@ -74367,10 +74443,10 @@ var init_config_manager2 = __esm(() => {
74367
74443
 
74368
74444
  // src/services/package-installer/gemini-mcp/validation.ts
74369
74445
  import { existsSync as existsSync63, lstatSync, readlinkSync } from "node:fs";
74370
- import { homedir as homedir45 } from "node:os";
74446
+ import { homedir as homedir44 } from "node:os";
74371
74447
  import { join as join93 } from "node:path";
74372
74448
  function getGlobalMcpConfigPath() {
74373
- return join93(homedir45(), ".claude", ".mcp.json");
74449
+ return join93(homedir44(), ".claude", ".mcp.json");
74374
74450
  }
74375
74451
  function getLocalMcpConfigPath(projectDir) {
74376
74452
  return join93(projectDir, ".mcp.json");
@@ -74391,7 +74467,7 @@ function findMcpConfigPath(projectDir) {
74391
74467
  }
74392
74468
  function getGeminiSettingsPath(projectDir, isGlobal) {
74393
74469
  if (isGlobal) {
74394
- return join93(homedir45(), ".gemini", "settings.json");
74470
+ return join93(homedir44(), ".gemini", "settings.json");
74395
74471
  }
74396
74472
  return join93(projectDir, ".gemini", "settings.json");
74397
74473
  }
@@ -77019,7 +77095,7 @@ var init_content_validator = __esm(() => {
77019
77095
  import { createHash as createHash9 } from "node:crypto";
77020
77096
  import { existsSync as existsSync79, mkdirSync as mkdirSync5, readFileSync as readFileSync19, readdirSync as readdirSync13, statSync as statSync14 } from "node:fs";
77021
77097
  import { rename as rename16, writeFile as writeFile40 } from "node:fs/promises";
77022
- import { homedir as homedir55 } from "node:os";
77098
+ import { homedir as homedir54 } from "node:os";
77023
77099
  import { basename as basename34, join as join160 } from "node:path";
77024
77100
  function getCachedContext(repoPath) {
77025
77101
  const cachePath = getCacheFilePath(repoPath);
@@ -77094,7 +77170,7 @@ function getCacheFilePath(repoPath) {
77094
77170
  }
77095
77171
  var CACHE_DIR, CACHE_TTL_MS5;
77096
77172
  var init_context_cache_manager = __esm(() => {
77097
- CACHE_DIR = join160(homedir55(), ".claudekit", "cache");
77173
+ CACHE_DIR = join160(homedir54(), ".claudekit", "cache");
77098
77174
  CACHE_TTL_MS5 = 24 * 60 * 60 * 1000;
77099
77175
  });
77100
77176
 
@@ -77548,10 +77624,10 @@ IMPORTANT: Generate the image and output the path as JSON: {"imagePath": "/path/
77548
77624
  // src/commands/content/phases/photo-generator.ts
77549
77625
  import { execSync as execSync8 } from "node:child_process";
77550
77626
  import { existsSync as existsSync81, mkdirSync as mkdirSync6, readdirSync as readdirSync15 } from "node:fs";
77551
- import { homedir as homedir56 } from "node:os";
77627
+ import { homedir as homedir55 } from "node:os";
77552
77628
  import { join as join162 } from "node:path";
77553
77629
  async function generatePhoto(_content, context, config, platform18, contentId, contentLogger) {
77554
- const mediaDir = join162(config.contentDir.replace(/^~/, homedir56()), "media", String(contentId));
77630
+ const mediaDir = join162(config.contentDir.replace(/^~/, homedir55()), "media", String(contentId));
77555
77631
  if (!existsSync81(mediaDir)) {
77556
77632
  mkdirSync6(mediaDir, { recursive: true });
77557
77633
  }
@@ -77665,7 +77741,7 @@ var init_content_creator = __esm(() => {
77665
77741
 
77666
77742
  // src/commands/content/phases/content-logger.ts
77667
77743
  import { createWriteStream as createWriteStream4, existsSync as existsSync82, mkdirSync as mkdirSync7, statSync as statSync15 } from "node:fs";
77668
- import { homedir as homedir57 } from "node:os";
77744
+ import { homedir as homedir56 } from "node:os";
77669
77745
  import { join as join163 } from "node:path";
77670
77746
 
77671
77747
  class ContentLogger {
@@ -77674,7 +77750,7 @@ class ContentLogger {
77674
77750
  logDir;
77675
77751
  maxBytes;
77676
77752
  constructor(maxBytes = 0) {
77677
- this.logDir = join163(homedir57(), ".claudekit", "logs");
77753
+ this.logDir = join163(homedir56(), ".claudekit", "logs");
77678
77754
  this.maxBytes = maxBytes;
77679
77755
  }
77680
77756
  init() {
@@ -79285,11 +79361,11 @@ var init_setup_wizard = __esm(() => {
79285
79361
 
79286
79362
  // src/commands/content/content-review-commands.ts
79287
79363
  import { existsSync as existsSync86 } from "node:fs";
79288
- import { homedir as homedir58 } from "node:os";
79364
+ import { homedir as homedir57 } from "node:os";
79289
79365
  async function queueContent() {
79290
79366
  const cwd2 = process.cwd();
79291
79367
  const config = await loadContentConfig(cwd2);
79292
- const dbPath = config.dbPath.replace(/^~/, homedir58());
79368
+ const dbPath = config.dbPath.replace(/^~/, homedir57());
79293
79369
  if (!existsSync86(dbPath)) {
79294
79370
  logger.info("No content database found. Run 'ck content setup' first.");
79295
79371
  return;
@@ -79316,7 +79392,7 @@ async function queueContent() {
79316
79392
  async function approveContentCmd(id) {
79317
79393
  const cwd2 = process.cwd();
79318
79394
  const config = await loadContentConfig(cwd2);
79319
- const dbPath = config.dbPath.replace(/^~/, homedir58());
79395
+ const dbPath = config.dbPath.replace(/^~/, homedir57());
79320
79396
  const db = initDatabase(dbPath);
79321
79397
  try {
79322
79398
  approveContent(db, Number.parseInt(id, 10));
@@ -79328,7 +79404,7 @@ async function approveContentCmd(id) {
79328
79404
  async function rejectContentCmd(id, reason) {
79329
79405
  const cwd2 = process.cwd();
79330
79406
  const config = await loadContentConfig(cwd2);
79331
- const dbPath = config.dbPath.replace(/^~/, homedir58());
79407
+ const dbPath = config.dbPath.replace(/^~/, homedir57());
79332
79408
  const db = initDatabase(dbPath);
79333
79409
  try {
79334
79410
  rejectContent(db, Number.parseInt(id, 10), reason);
@@ -79359,7 +79435,7 @@ __export(exports_content_subcommands, {
79359
79435
  approveContentCmd: () => approveContentCmd
79360
79436
  });
79361
79437
  import { existsSync as existsSync87, readFileSync as readFileSync22, unlinkSync as unlinkSync6 } from "node:fs";
79362
- import { homedir as homedir59 } from "node:os";
79438
+ import { homedir as homedir58 } from "node:os";
79363
79439
  import { join as join168 } from "node:path";
79364
79440
  function isDaemonRunning() {
79365
79441
  const lockFile = join168(LOCK_DIR, `${LOCK_NAME2}.lock`);
@@ -79433,7 +79509,7 @@ async function statusContent() {
79433
79509
  } catch {}
79434
79510
  }
79435
79511
  async function logsContent(options2) {
79436
- const logDir = join168(homedir59(), ".claudekit", "logs");
79512
+ const logDir = join168(homedir58(), ".claudekit", "logs");
79437
79513
  const dateStr = new Date().toISOString().slice(0, 10).replace(/-/g, "");
79438
79514
  const logPath = join168(logDir, `content-${dateStr}.log`);
79439
79515
  if (!existsSync87(logPath)) {
@@ -79467,12 +79543,12 @@ var init_content_subcommands = __esm(() => {
79467
79543
  init_setup_wizard();
79468
79544
  init_state_manager();
79469
79545
  init_content_review_commands();
79470
- LOCK_DIR = join168(homedir59(), ".claudekit", "locks");
79546
+ LOCK_DIR = join168(homedir58(), ".claudekit", "locks");
79471
79547
  });
79472
79548
 
79473
79549
  // src/commands/content/content-command.ts
79474
79550
  import { existsSync as existsSync88, mkdirSync as mkdirSync9, unlinkSync as unlinkSync7, writeFileSync as writeFileSync7 } from "node:fs";
79475
- import { homedir as homedir60 } from "node:os";
79551
+ import { homedir as homedir59 } from "node:os";
79476
79552
  import { join as join169 } from "node:path";
79477
79553
  async function contentCommand(options2) {
79478
79554
  const cwd2 = process.cwd();
@@ -79505,7 +79581,7 @@ async function contentCommand(options2) {
79505
79581
  if (!existsSync88(LOCK_DIR2))
79506
79582
  mkdirSync9(LOCK_DIR2, { recursive: true });
79507
79583
  writeFileSync7(LOCK_FILE, String(process.pid), "utf-8");
79508
- const dbPath = config.dbPath.replace(/^~/, homedir60());
79584
+ const dbPath = config.dbPath.replace(/^~/, homedir59());
79509
79585
  const db = initDatabase(dbPath);
79510
79586
  contentLogger.info(`Database initialised at ${dbPath}`);
79511
79587
  const adapters = initializeAdapters(config);
@@ -79651,7 +79727,7 @@ var init_content_command = __esm(() => {
79651
79727
  init_publisher();
79652
79728
  init_review_manager();
79653
79729
  init_state_manager();
79654
- LOCK_DIR2 = join169(homedir60(), ".claudekit", "locks");
79730
+ LOCK_DIR2 = join169(homedir59(), ".claudekit", "locks");
79655
79731
  LOCK_FILE = join169(LOCK_DIR2, "ck-content.lock");
79656
79732
  });
79657
79733
 
@@ -82872,9 +82948,9 @@ var import_picocolors6 = __toESM(require_picocolors(), 1);
82872
82948
  init_fm_to_json();
82873
82949
  init_portable_registry();
82874
82950
  init_provider_registry();
82875
- import { existsSync as existsSync6 } from "node:fs";
82951
+ import { existsSync as existsSync7 } from "node:fs";
82876
82952
  import { readFile as readFile6, rm, writeFile as writeFile4 } from "node:fs/promises";
82877
- import { dirname as dirname4, join as join7 } from "node:path";
82953
+ import { dirname as dirname4, join as join8 } from "node:path";
82878
82954
  function toSlug3(name) {
82879
82955
  return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
82880
82956
  }
@@ -82994,7 +83070,7 @@ async function removeFromJsonMerge(agentName, filePath) {
82994
83070
  const rulesDir = dirname4(filePath);
82995
83071
  const ruleNames = new Set([`${agentName}.md`, `${slug}.md`]);
82996
83072
  for (const ruleName of ruleNames) {
82997
- await rm(join7(rulesDir, ruleName), { force: true });
83073
+ await rm(join8(rulesDir, ruleName), { force: true });
82998
83074
  }
82999
83075
  if (filtered.length === 0) {
83000
83076
  await rm(filePath, { force: true });
@@ -83024,7 +83100,7 @@ async function uninstallAgentFromProvider(agentName, provider, global2) {
83024
83100
  };
83025
83101
  }
83026
83102
  const installation = installations[0];
83027
- const fileExists = existsSync6(installation.path);
83103
+ const fileExists = existsSync7(installation.path);
83028
83104
  try {
83029
83105
  const config = providers[provider];
83030
83106
  const pathConfig = config.agents;
@@ -83113,8 +83189,8 @@ async function forceUninstallAgentFromProvider(agentName, provider, global2) {
83113
83189
  };
83114
83190
  }
83115
83191
  const writeStrategy = pathConfig.writeStrategy;
83116
- const targetPath = writeStrategy === "json-merge" ? join7(basePath, "cline_custom_modes.json") : writeStrategy === "merge-single" || writeStrategy === "yaml-merge" || writeStrategy === "single-file" ? basePath : join7(basePath, `${agentName}${pathConfig.fileExtension}`);
83117
- const fileExists = existsSync6(targetPath);
83192
+ const targetPath = writeStrategy === "json-merge" ? join8(basePath, "cline_custom_modes.json") : writeStrategy === "merge-single" || writeStrategy === "yaml-merge" || writeStrategy === "single-file" ? basePath : join8(basePath, `${agentName}${pathConfig.fileExtension}`);
83193
+ const fileExists = existsSync7(targetPath);
83118
83194
  try {
83119
83195
  if (!fileExists) {
83120
83196
  return {
@@ -83633,7 +83709,7 @@ var import_picocolors8 = __toESM(require_picocolors(), 1);
83633
83709
 
83634
83710
  // src/domains/claudekit-api/index.ts
83635
83711
  import { homedir as homedir7 } from "node:os";
83636
- import { join as join9 } from "node:path";
83712
+ import { join as join10 } from "node:path";
83637
83713
 
83638
83714
  // src/domains/api-key/validator.ts
83639
83715
  var API_BASE_URL = "https://claudekit.cc/api";
@@ -83680,20 +83756,20 @@ function isValidKeyFormat(key) {
83680
83756
  return /^ck_live_[A-Za-z0-9_-]{32}$/.test(key);
83681
83757
  }
83682
83758
  // src/domains/api-key/storage.ts
83683
- import { existsSync as existsSync7, readFileSync as readFileSync3, writeFileSync } from "node:fs";
83684
- import { join as join8 } from "node:path";
83759
+ import { existsSync as existsSync8, readFileSync as readFileSync4, writeFileSync } from "node:fs";
83760
+ import { join as join9 } from "node:path";
83685
83761
  var ENV_FILE = ".env";
83686
83762
  var API_KEY_VAR = "CLAUDEKIT_API_KEY";
83687
83763
  function getEnvFilePath(claudeDir) {
83688
- return join8(claudeDir, ENV_FILE);
83764
+ return join9(claudeDir, ENV_FILE);
83689
83765
  }
83690
83766
  function readExistingApiKey(claudeDir) {
83691
83767
  const envPath = getEnvFilePath(claudeDir);
83692
- if (!existsSync7(envPath)) {
83768
+ if (!existsSync8(envPath)) {
83693
83769
  return null;
83694
83770
  }
83695
83771
  try {
83696
- const content = readFileSync3(envPath, "utf-8");
83772
+ const content = readFileSync4(envPath, "utf-8");
83697
83773
  const match = content.match(new RegExp(`^${API_KEY_VAR}=(.+)$`, "m"));
83698
83774
  return match?.[1]?.trim() ?? null;
83699
83775
  } catch {
@@ -83703,8 +83779,8 @@ function readExistingApiKey(claudeDir) {
83703
83779
  function saveApiKey(claudeDir, apiKey) {
83704
83780
  const envPath = getEnvFilePath(claudeDir);
83705
83781
  let content = "";
83706
- if (existsSync7(envPath)) {
83707
- content = readFileSync3(envPath, "utf-8");
83782
+ if (existsSync8(envPath)) {
83783
+ content = readFileSync4(envPath, "utf-8");
83708
83784
  if (content.includes(`${API_KEY_VAR}=`)) {
83709
83785
  content = content.replace(new RegExp(`^${API_KEY_VAR}=.*$`, "m"), `${API_KEY_VAR}=${apiKey}`);
83710
83786
  } else {
@@ -83860,7 +83936,7 @@ class ClaudekitHttpClient {
83860
83936
  } catch (error) {
83861
83937
  if (error instanceof CkApiError && error.code === "RATE_LIMIT_EXCEEDED" && error.retryAfter) {
83862
83938
  const delayMs = error.retryAfter * 1000;
83863
- await new Promise((resolve4) => setTimeout(resolve4, delayMs));
83939
+ await new Promise((resolve5) => setTimeout(resolve5, delayMs));
83864
83940
  return fn();
83865
83941
  }
83866
83942
  throw error;
@@ -83870,7 +83946,7 @@ class ClaudekitHttpClient {
83870
83946
 
83871
83947
  // src/domains/claudekit-api/index.ts
83872
83948
  function createApiClient(claudeDir) {
83873
- const dir = claudeDir ?? join9(homedir7(), ".claude");
83949
+ const dir = claudeDir ?? join10(homedir7(), ".claude");
83874
83950
  const apiKey = readExistingApiKey(dir);
83875
83951
  if (!apiKey) {
83876
83952
  throw new CkApiError("MISSING_API_KEY", "No API key found. Run `ck api setup` to configure your ClaudeKit API key.", 401);
@@ -84301,13 +84377,13 @@ async function handleApiServices(options2) {
84301
84377
 
84302
84378
  // src/commands/api/subcommands/api-setup-handler.ts
84303
84379
  import { homedir as homedir8 } from "node:os";
84304
- import { join as join10 } from "node:path";
84380
+ import { join as join11 } from "node:path";
84305
84381
  init_logger();
84306
84382
  init_dist2();
84307
84383
  var DASHBOARD_URL = "https://claudekit.cc/api-keys";
84308
84384
  var MAX_ATTEMPTS = 3;
84309
84385
  async function handleApiSetup(options2) {
84310
- const claudeDir = join10(homedir8(), ".claude");
84386
+ const claudeDir = join11(homedir8(), ".claude");
84311
84387
  const existing = readExistingApiKey(claudeDir);
84312
84388
  if (existing && !options2.force) {
84313
84389
  const masked = `${existing.slice(0, 15)}...`;
@@ -88291,7 +88367,7 @@ init_logger();
88291
88367
  init_path_resolver();
88292
88368
  import { existsSync as existsSync58 } from "node:fs";
88293
88369
  import { readFile as readFile42 } from "node:fs/promises";
88294
- import { homedir as homedir43 } from "node:os";
88370
+ import { homedir as homedir42 } from "node:os";
88295
88371
  import { dirname as dirname31, join as join80, normalize as normalize6, resolve as resolve36 } from "node:path";
88296
88372
  async function checkPathRefsValid(projectDir) {
88297
88373
  const globalClaudeMd = join80(PathResolver.getGlobalKitDir(), "CLAUDE.md");
@@ -88324,7 +88400,7 @@ async function checkPathRefsValid(projectDir) {
88324
88400
  };
88325
88401
  }
88326
88402
  const baseDir = dirname31(claudeMdPath);
88327
- const home5 = homedir43();
88403
+ const home5 = homedir42();
88328
88404
  const broken = [];
88329
88405
  for (const ref of refs) {
88330
88406
  let refPath;
@@ -89328,7 +89404,7 @@ import { platform as platform8 } from "node:os";
89328
89404
  init_environment();
89329
89405
  init_path_resolver();
89330
89406
  import { constants as constants3, access as access4, mkdir as mkdir21, readFile as readFile44, unlink as unlink11, writeFile as writeFile21 } from "node:fs/promises";
89331
- import { arch as arch2, homedir as homedir44, platform as platform7 } from "node:os";
89407
+ import { arch as arch2, homedir as homedir43, platform as platform7 } from "node:os";
89332
89408
  import { join as join85, normalize as normalize7 } from "node:path";
89333
89409
  function shouldSkipExpensiveOperations4() {
89334
89410
  return shouldSkipExpensiveOperations();
@@ -89351,7 +89427,7 @@ async function checkPlatformDetect() {
89351
89427
  };
89352
89428
  }
89353
89429
  async function checkHomeDirResolution() {
89354
- const nodeHome = normalize7(homedir44());
89430
+ const nodeHome = normalize7(homedir43());
89355
89431
  const rawEnvHome = getHomeDirectoryFromEnv(platform7());
89356
89432
  const envHome = rawEnvHome ? normalize7(rawEnvHome) : "";
89357
89433
  const match = nodeHome === envHome && envHome !== "";
@@ -103436,7 +103512,7 @@ class FileScanner {
103436
103512
 
103437
103513
  // src/domains/installation/merger/settings-processor.ts
103438
103514
  import { execSync as execSync5 } from "node:child_process";
103439
- import { homedir as homedir46 } from "node:os";
103515
+ import { homedir as homedir45 } from "node:os";
103440
103516
  import { dirname as dirname39, join as join109 } from "node:path";
103441
103517
 
103442
103518
  // src/domains/config/installed-settings-tracker.ts
@@ -104053,7 +104129,7 @@ class SettingsProcessor {
104053
104129
  return false;
104054
104130
  }
104055
104131
  const configuredGlobalDir = PathResolver.getGlobalKitDir().replace(/\\/g, "/").replace(/\/+$/, "");
104056
- const defaultGlobalDir = join109(homedir46(), ".claude").replace(/\\/g, "/");
104132
+ const defaultGlobalDir = join109(homedir45(), ".claude").replace(/\\/g, "/");
104057
104133
  return configuredGlobalDir !== defaultGlobalDir;
104058
104134
  }
104059
104135
  getClaudeCommandRoot() {
@@ -107750,7 +107826,7 @@ async function handleFreshInstallation(claudeDir3, prompts) {
107750
107826
  // src/domains/installation/global-kit-legacy-repair.ts
107751
107827
  var import_fs_extra35 = __toESM(require_lib(), 1);
107752
107828
  import { cp as cp5, mkdir as mkdir35, readdir as readdir42, rename as rename11, rm as rm16, stat as stat22 } from "node:fs/promises";
107753
- import { homedir as homedir47 } from "node:os";
107829
+ import { homedir as homedir46 } from "node:os";
107754
107830
  import { dirname as dirname42, join as join133, normalize as normalize11, resolve as resolve46 } from "node:path";
107755
107831
  var LEGACY_KIT_MARKERS = [
107756
107832
  "metadata.json",
@@ -107785,7 +107861,7 @@ function uniqueNormalizedPaths(paths) {
107785
107861
  }
107786
107862
  return result;
107787
107863
  }
107788
- function getLegacyWindowsGlobalKitDirCandidates(env2 = process.env, homeDir = homedir47()) {
107864
+ function getLegacyWindowsGlobalKitDirCandidates(env2 = process.env, homeDir = homedir46()) {
107789
107865
  const candidates = [];
107790
107866
  const localAppData = safeEnvPath(env2.LOCALAPPDATA);
107791
107867
  const appData = safeEnvPath(env2.APPDATA);
@@ -108918,7 +108994,7 @@ async function transformFolderPaths(extractDir, folders, options2 = {}) {
108918
108994
  // src/services/transformers/global-path-transformer.ts
108919
108995
  init_logger();
108920
108996
  import { readFile as readFile61, readdir as readdir44, writeFile as writeFile35 } from "node:fs/promises";
108921
- import { homedir as homedir48, platform as platform15 } from "node:os";
108997
+ import { homedir as homedir47, platform as platform15 } from "node:os";
108922
108998
  import { extname as extname7, join as join138 } from "node:path";
108923
108999
  var IS_WINDOWS3 = platform15() === "win32";
108924
109000
  var HOME_PREFIX = "$HOME";
@@ -108929,7 +109005,7 @@ function normalizeInstallPath(path17) {
108929
109005
  return path17.replace(/\\/g, "/").replace(/\/+$/, "");
108930
109006
  }
108931
109007
  function getDefaultGlobalClaudeDir() {
108932
- return normalizeInstallPath(join138(homedir48(), ".claude"));
109008
+ return normalizeInstallPath(join138(homedir47(), ".claude"));
108933
109009
  }
108934
109010
  function getCustomGlobalClaudeDir(targetClaudeDir) {
108935
109011
  if (!targetClaudeDir)
@@ -109361,13 +109437,13 @@ init_dist2();
109361
109437
  var import_picocolors30 = __toESM(require_picocolors(), 1);
109362
109438
  import { existsSync as existsSync68 } from "node:fs";
109363
109439
  import { readFile as readFile65, rm as rm18, unlink as unlink14 } from "node:fs/promises";
109364
- import { homedir as homedir53 } from "node:os";
109440
+ import { homedir as homedir52 } from "node:os";
109365
109441
  import { basename as basename30, join as join143, resolve as resolve50 } from "node:path";
109366
109442
  init_logger();
109367
109443
 
109368
109444
  // src/ui/ck-cli-design/tokens.ts
109369
109445
  var import_picocolors27 = __toESM(require_picocolors(), 1);
109370
- import { homedir as homedir49, platform as platform16 } from "node:os";
109446
+ import { homedir as homedir48, platform as platform16 } from "node:os";
109371
109447
  import { resolve as resolve49, win32 as win322 } from "node:path";
109372
109448
  var PANEL_MIN_WIDTH = 60;
109373
109449
  var PANEL_MAX_WIDTH = 72;
@@ -109525,7 +109601,7 @@ function wrapText(value, width) {
109525
109601
  }
109526
109602
  function formatDisplayPath(value) {
109527
109603
  const normalized = value.replace(/\\/g, "/");
109528
- const home5 = homedir49().replace(/\\/g, "/");
109604
+ const home5 = homedir48().replace(/\\/g, "/");
109529
109605
  if (normalized === home5)
109530
109606
  return "~";
109531
109607
  if (normalized.startsWith(`${home5}/`)) {
@@ -109839,13 +109915,13 @@ init_logger();
109839
109915
  init_dist2();
109840
109916
  init_model_taxonomy();
109841
109917
  import { mkdir as mkdir39, readFile as readFile64, writeFile as writeFile37 } from "node:fs/promises";
109842
- import { homedir as homedir52 } from "node:os";
109918
+ import { homedir as homedir51 } from "node:os";
109843
109919
  import { dirname as dirname44, join as join142 } from "node:path";
109844
109920
 
109845
109921
  // src/commands/portable/models-dev-cache.ts
109846
109922
  init_logger();
109847
109923
  import { mkdir as mkdir38, readFile as readFile62, rename as rename14, writeFile as writeFile36 } from "node:fs/promises";
109848
- import { homedir as homedir50 } from "node:os";
109924
+ import { homedir as homedir49 } from "node:os";
109849
109925
  import { join as join140 } from "node:path";
109850
109926
 
109851
109927
  class ModelsDevUnavailableError extends Error {
@@ -109858,7 +109934,7 @@ var MODELS_DEV_URL = "https://models.dev/api.json";
109858
109934
  var CACHE_TTL_MS3 = 24 * 60 * 60 * 1000;
109859
109935
  var FETCH_TIMEOUT_MS = 1e4;
109860
109936
  function defaultCacheDir() {
109861
- return join140(homedir50(), ".config", "claudekit", "cache");
109937
+ return join140(homedir49(), ".config", "claudekit", "cache");
109862
109938
  }
109863
109939
  function cacheFilePath(cacheDir) {
109864
109940
  return join140(cacheDir, "models-dev.json");
@@ -109938,7 +110014,7 @@ async function getModelsDevCatalog(opts = {}) {
109938
110014
  // src/commands/portable/opencode-model-discovery.ts
109939
110015
  init_logger();
109940
110016
  import { readFile as readFile63 } from "node:fs/promises";
109941
- import { homedir as homedir51, platform as platform17 } from "node:os";
110017
+ import { homedir as homedir50, platform as platform17 } from "node:os";
109942
110018
  import { join as join141 } from "node:path";
109943
110019
  function resolveOpenCodeAuthPath(homeDir) {
109944
110020
  if (platform17() === "win32") {
@@ -109984,7 +110060,7 @@ function pickGenericModel(models) {
109984
110060
  return sorted[0] ?? null;
109985
110061
  }
109986
110062
  async function resolveOpenCodeDefaultModel(opts = {}) {
109987
- const home5 = opts.homeDir ?? homedir51();
110063
+ const home5 = opts.homeDir ?? homedir50();
109988
110064
  const authedProviders = await readAuthedProviders(home5);
109989
110065
  if (authedProviders.length === 0) {
109990
110066
  return { ok: false, reason: "no-auth", authedProviders: [] };
@@ -110048,7 +110124,7 @@ function messageForReason(reason) {
110048
110124
  }
110049
110125
  function getOpenCodeConfigPath(options2) {
110050
110126
  if (options2.global) {
110051
- return join142(options2.homeDir ?? homedir52(), ".config", "opencode", "opencode.json");
110127
+ return join142(options2.homeDir ?? homedir51(), ".config", "opencode", "opencode.json");
110052
110128
  }
110053
110129
  return join142(options2.cwd ?? process.cwd(), "opencode.json");
110054
110130
  }
@@ -111055,7 +111131,7 @@ async function processMetadataDeletions(skillSourcePath, installGlobally) {
111055
111131
  }
111056
111132
  if (!sourceMetadata.deletions || sourceMetadata.deletions.length === 0)
111057
111133
  return;
111058
- const claudeDir3 = installGlobally ? join143(homedir53(), ".claude") : join143(process.cwd(), ".claude");
111134
+ const claudeDir3 = installGlobally ? join143(homedir52(), ".claude") : join143(process.cwd(), ".claude");
111059
111135
  if (!existsSync68(claudeDir3))
111060
111136
  return;
111061
111137
  try {
@@ -111184,7 +111260,7 @@ async function migrateCommand(options2) {
111184
111260
  let installGlobally = requestedGlobal;
111185
111261
  if (options2.global === undefined && !options2.yes) {
111186
111262
  const projectTarget = join143(process.cwd(), ".claude");
111187
- const globalTarget = join143(homedir53(), ".claude");
111263
+ const globalTarget = join143(homedir52(), ".claude");
111188
111264
  const scopeChoice = await ie({
111189
111265
  message: "Installation scope",
111190
111266
  options: [
@@ -111257,7 +111333,7 @@ async function migrateCommand(options2) {
111257
111333
  }).join(`
111258
111334
  `));
111259
111335
  if (sourceGlobalOnly) {
111260
- f2.info(import_picocolors30.default.dim(` Scope: global (--global / -g) - reading from ${formatDisplayPath(join143(homedir53(), ".claude"))}`));
111336
+ f2.info(import_picocolors30.default.dim(` Scope: global (--global / -g) - reading from ${formatDisplayPath(join143(homedir52(), ".claude"))}`));
111261
111337
  } else {
111262
111338
  f2.info(import_picocolors30.default.dim(` CWD: ${process.cwd()}`));
111263
111339
  }
@@ -116286,7 +116362,7 @@ async function scanForRepos(parentDir) {
116286
116362
  init_logger();
116287
116363
  import { spawnSync as spawnSync8 } from "node:child_process";
116288
116364
  import { existsSync as existsSync76 } from "node:fs";
116289
- import { homedir as homedir54 } from "node:os";
116365
+ import { homedir as homedir53 } from "node:os";
116290
116366
  import { join as join157 } from "node:path";
116291
116367
  async function validateSetup(cwd2) {
116292
116368
  const workDir = cwd2 ?? process.cwd();
@@ -116318,7 +116394,7 @@ Run this command from a directory with a GitHub remote.`);
116318
116394
  } catch {
116319
116395
  throw new Error(`Failed to parse repository info: ${ghRepo.stdout}`);
116320
116396
  }
116321
- const skillsPath = join157(homedir54(), ".claude", "skills");
116397
+ const skillsPath = join157(homedir53(), ".claude", "skills");
116322
116398
  const skillsAvailable = existsSync76(skillsPath);
116323
116399
  if (!skillsAvailable) {
116324
116400
  logger.warning(`ClaudeKit Engineer skills not found at ${skillsPath}`);