claudekit-cli 4.3.1-dev.1 → 4.3.1-dev.3

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
@@ -12564,6 +12564,16 @@ import { existsSync as existsSync2 } from "node:fs";
12564
12564
  import { mkdir, readFile as readFile2, rename, unlink, writeFile } from "node:fs/promises";
12565
12565
  import { homedir as homedir3 } from "node:os";
12566
12566
  import { dirname, join as join2, resolve } from "node:path";
12567
+ function getPortableRegistryPaths() {
12568
+ const home2 = homedir3();
12569
+ const claudekitDir = join2(home2, ".claudekit");
12570
+ return {
12571
+ registryPath: join2(claudekitDir, "portable-registry.json"),
12572
+ registryLockPath: join2(claudekitDir, "portable-registry.lock"),
12573
+ legacyRegistryPath: join2(claudekitDir, "skill-registry.json"),
12574
+ migrationLockPath: join2(claudekitDir, ".migration.lock")
12575
+ };
12576
+ }
12567
12577
  function isErrnoCode(error, code) {
12568
12578
  return typeof error === "object" && error !== null && "code" in error && error.code === code;
12569
12579
  }
@@ -12597,8 +12607,9 @@ function getCliVersion() {
12597
12607
  }
12598
12608
  }
12599
12609
  async function migrateLegacyRegistry() {
12610
+ const { legacyRegistryPath } = getPortableRegistryPaths();
12600
12611
  try {
12601
- const content = await readFile2(LEGACY_REGISTRY_PATH, "utf-8");
12612
+ const content = await readFile2(legacyRegistryPath, "utf-8");
12602
12613
  const data = JSON.parse(content);
12603
12614
  const legacy = LegacyRegistrySchema.parse(data);
12604
12615
  const installations = legacy.installations.map((i) => ({
@@ -12707,9 +12718,10 @@ async function repairStaleRegistryV3(registry) {
12707
12718
  }
12708
12719
  async function persistCurrentStaleRegistryV3Repair(preparedRepair) {
12709
12720
  return withRegistryLock(async () => {
12721
+ const { registryPath } = getPortableRegistryPaths();
12710
12722
  let content;
12711
12723
  try {
12712
- content = await readFile2(REGISTRY_PATH, "utf-8");
12724
+ content = await readFile2(registryPath, "utf-8");
12713
12725
  } catch (error) {
12714
12726
  if (isErrnoCode(error, "ENOENT")) {
12715
12727
  return readPortableRegistryInternal({ persistStaleV3Repair: false });
@@ -12741,8 +12753,9 @@ async function persistCurrentStaleRegistryV3Repair(preparedRepair) {
12741
12753
  });
12742
12754
  }
12743
12755
  async function isMigrationLocked() {
12756
+ const { migrationLockPath } = getPortableRegistryPaths();
12744
12757
  try {
12745
- const lockContent = await readFile2(MIGRATION_LOCK_PATH, "utf-8");
12758
+ const lockContent = await readFile2(migrationLockPath, "utf-8");
12746
12759
  const lockTime = Number.parseInt(lockContent, 10);
12747
12760
  if (Number.isNaN(lockTime)) {
12748
12761
  logger.verbose("Migration lock timestamp is invalid, treating lock as active");
@@ -12754,7 +12767,7 @@ async function isMigrationLocked() {
12754
12767
  return true;
12755
12768
  }
12756
12769
  logger.verbose("Removing stale migration lock");
12757
- await unlink(MIGRATION_LOCK_PATH);
12770
+ await unlink(migrationLockPath);
12758
12771
  return false;
12759
12772
  } catch (error) {
12760
12773
  if (isErrnoCode(error, "ENOENT")) {
@@ -12765,23 +12778,26 @@ async function isMigrationLocked() {
12765
12778
  }
12766
12779
  }
12767
12780
  async function createMigrationLock() {
12768
- const lockDir = dirname(MIGRATION_LOCK_PATH);
12781
+ const { migrationLockPath } = getPortableRegistryPaths();
12782
+ const lockDir = dirname(migrationLockPath);
12769
12783
  if (!existsSync2(lockDir)) {
12770
12784
  await mkdir(lockDir, { recursive: true });
12771
12785
  }
12772
- await writeFile(MIGRATION_LOCK_PATH, Date.now().toString(), "utf-8");
12786
+ await writeFile(migrationLockPath, Date.now().toString(), "utf-8");
12773
12787
  }
12774
12788
  async function removeMigrationLock() {
12789
+ const { migrationLockPath } = getPortableRegistryPaths();
12775
12790
  try {
12776
- await unlink(MIGRATION_LOCK_PATH);
12791
+ await unlink(migrationLockPath);
12777
12792
  } catch {}
12778
12793
  }
12779
12794
  async function readPortableRegistry() {
12780
12795
  return readPortableRegistryInternal({ persistStaleV3Repair: true });
12781
12796
  }
12782
12797
  async function readPortableRegistryInternal(options2) {
12798
+ const { registryPath } = getPortableRegistryPaths();
12783
12799
  try {
12784
- const content = await readFile2(REGISTRY_PATH, "utf-8");
12800
+ const content = await readFile2(registryPath, "utf-8");
12785
12801
  let data;
12786
12802
  try {
12787
12803
  data = JSON.parse(content);
@@ -12850,15 +12866,16 @@ async function readPortableRegistryWithinRegistryLock() {
12850
12866
  return readPortableRegistryInternal({ persistStaleV3Repair: false });
12851
12867
  }
12852
12868
  async function writePortableRegistry(registry) {
12853
- const dir = dirname(REGISTRY_PATH);
12869
+ const { registryPath } = getPortableRegistryPaths();
12870
+ const dir = dirname(registryPath);
12854
12871
  if (!existsSync2(dir)) {
12855
12872
  await mkdir(dir, { recursive: true });
12856
12873
  }
12857
12874
  const normalizedRegistry = normalizePortableRegistryChecksums(registry);
12858
- const tempPath = `${REGISTRY_PATH}.tmp-${process.pid}-${Date.now()}`;
12875
+ const tempPath = `${registryPath}.tmp-${process.pid}-${Date.now()}`;
12859
12876
  try {
12860
12877
  await writeFile(tempPath, JSON.stringify(normalizedRegistry, null, 2), "utf-8");
12861
- await rename(tempPath, REGISTRY_PATH);
12878
+ await rename(tempPath, registryPath);
12862
12879
  } catch (error) {
12863
12880
  try {
12864
12881
  await unlink(tempPath);
@@ -12867,14 +12884,15 @@ async function writePortableRegistry(registry) {
12867
12884
  }
12868
12885
  }
12869
12886
  async function withRegistryLock(operation) {
12870
- const lockDir = dirname(REGISTRY_LOCK_PATH);
12887
+ const { registryLockPath } = getPortableRegistryPaths();
12888
+ const lockDir = dirname(registryLockPath);
12871
12889
  if (!existsSync2(lockDir)) {
12872
12890
  await mkdir(lockDir, { recursive: true });
12873
12891
  }
12874
- if (!existsSync2(REGISTRY_LOCK_PATH)) {
12875
- await writeFile(REGISTRY_LOCK_PATH, "", "utf-8");
12892
+ if (!existsSync2(registryLockPath)) {
12893
+ await writeFile(registryLockPath, "", "utf-8");
12876
12894
  }
12877
- const release = await import_proper_lockfile.default.lock(REGISTRY_LOCK_PATH, {
12895
+ const release = await import_proper_lockfile.default.lock(registryLockPath, {
12878
12896
  realpath: false,
12879
12897
  retries: {
12880
12898
  retries: 5,
@@ -12975,17 +12993,12 @@ async function syncPortableRegistry() {
12975
12993
  return { removed };
12976
12994
  });
12977
12995
  }
12978
- var import_proper_lockfile, home2, REGISTRY_PATH, REGISTRY_LOCK_PATH, LEGACY_REGISTRY_PATH, MIGRATION_LOCK_PATH, PortableInstallationSchema, PortableRegistrySchema, PortableInstallationSchemaV3, PortableRegistrySchemaV3, RepairablePortableRegistrySchemaV3, LegacyInstallationSchema, LegacyRegistrySchema;
12996
+ var import_proper_lockfile, PortableInstallationSchema, PortableRegistrySchema, PortableInstallationSchemaV3, PortableRegistrySchemaV3, RepairablePortableRegistrySchemaV3, LegacyInstallationSchema, LegacyRegistrySchema;
12979
12997
  var init_portable_registry = __esm(() => {
12980
12998
  init_zod();
12981
12999
  init_logger();
12982
13000
  init_checksum_utils();
12983
13001
  import_proper_lockfile = __toESM(require_proper_lockfile(), 1);
12984
- home2 = homedir3();
12985
- REGISTRY_PATH = join2(home2, ".claudekit", "portable-registry.json");
12986
- REGISTRY_LOCK_PATH = join2(home2, ".claudekit", "portable-registry.lock");
12987
- LEGACY_REGISTRY_PATH = join2(home2, ".claudekit", "skill-registry.json");
12988
- MIGRATION_LOCK_PATH = join2(home2, ".claudekit", ".migration.lock");
12989
13002
  PortableInstallationSchema = exports_external.object({
12990
13003
  item: exports_external.string(),
12991
13004
  type: exports_external.enum(["agent", "command", "skill", "config", "rules", "hooks"]),
@@ -13046,6 +13059,12 @@ import { existsSync as existsSync3 } from "node:fs";
13046
13059
  import { mkdir as mkdir2, readFile as readFile3, realpath, unlink as unlink2, writeFile as writeFile2 } from "node:fs/promises";
13047
13060
  import { homedir as homedir4 } from "node:os";
13048
13061
  import { basename, dirname as dirname2, isAbsolute, join as join3, relative, resolve as resolve2 } from "node:path";
13062
+ function resolveCodexTomlRegistryDeps(deps) {
13063
+ return {
13064
+ ...defaultCodexTomlRegistryDeps,
13065
+ ...deps
13066
+ };
13067
+ }
13049
13068
  async function ensureDir(filePath) {
13050
13069
  const dir = dirname2(filePath);
13051
13070
  if (!existsSync3(dir)) {
@@ -13299,12 +13318,13 @@ async function restoreFileSnapshots(snapshots) {
13299
13318
  await restoreFileSnapshot(snapshots[index]);
13300
13319
  }
13301
13320
  }
13302
- async function rollbackRegistryEntries(entries, portableType, provider, global2) {
13321
+ async function rollbackRegistryEntries(entries, portableType, provider, global2, registryDeps) {
13303
13322
  for (let index = entries.length - 1;index >= 0; index -= 1) {
13304
- await removePortableInstallation(entries[index].itemName, portableType, provider, global2);
13323
+ await registryDeps.removePortableInstallation(entries[index].itemName, portableType, provider, global2);
13305
13324
  }
13306
13325
  }
13307
- async function installCodexToml(items, provider, portableType, options2) {
13326
+ async function installCodexToml(items, provider, portableType, options2, deps) {
13327
+ const registryDeps = resolveCodexTomlRegistryDeps(deps);
13308
13328
  const config = providers[provider];
13309
13329
  const pathConfig = config.agents;
13310
13330
  if (!pathConfig) {
@@ -13487,7 +13507,7 @@ async function installCodexToml(items, provider, portableType, options2) {
13487
13507
  }
13488
13508
  await writeFile2(configTomlPath, mergeResult.content, "utf-8");
13489
13509
  for (const install of pendingInstalls) {
13490
- await addPortableInstallation(install.itemName, portableType, provider, options2.global, install.agentTomlPath, install.sourcePath, {
13510
+ await registryDeps.addPortableInstallation(install.itemName, portableType, provider, options2.global, install.agentTomlPath, install.sourcePath, {
13491
13511
  sourceChecksum: install.sourceChecksum,
13492
13512
  targetChecksum: install.targetChecksum,
13493
13513
  ownedSections: [install.slug],
@@ -13506,7 +13526,7 @@ async function installCodexToml(items, provider, portableType, options2) {
13506
13526
  let message = error instanceof Error ? error.message : "Unknown error";
13507
13527
  if (addedRegistryEntries.length > 0) {
13508
13528
  try {
13509
- await rollbackRegistryEntries(addedRegistryEntries, portableType, provider, options2.global);
13529
+ await rollbackRegistryEntries(addedRegistryEntries, portableType, provider, options2.global, registryDeps);
13510
13530
  } catch (rollbackRegistryError) {
13511
13531
  const rollbackMessage = rollbackRegistryError instanceof Error ? rollbackRegistryError.message : "Unknown registry rollback error";
13512
13532
  message = `${message}; registry rollback failed: ${rollbackMessage}`;
@@ -13632,7 +13652,7 @@ async function cleanupStaleCodexConfigEntries(options2) {
13632
13652
  return [];
13633
13653
  }
13634
13654
  }
13635
- var import_proper_lockfile2, SENTINEL_START = "# --- ck-managed-agents-start ---", SENTINEL_END = "# --- ck-managed-agents-end ---", MAX_WINDOWS_PATH_LENGTH = 240;
13655
+ var import_proper_lockfile2, SENTINEL_START = "# --- ck-managed-agents-start ---", SENTINEL_END = "# --- ck-managed-agents-end ---", MAX_WINDOWS_PATH_LENGTH = 240, defaultCodexTomlRegistryDeps;
13636
13656
  var init_codex_toml_installer = __esm(() => {
13637
13657
  init_logger();
13638
13658
  init_checksum_utils();
@@ -13641,6 +13661,10 @@ var init_codex_toml_installer = __esm(() => {
13641
13661
  init_portable_registry();
13642
13662
  init_provider_registry();
13643
13663
  import_proper_lockfile2 = __toESM(require_proper_lockfile(), 1);
13664
+ defaultCodexTomlRegistryDeps = {
13665
+ addPortableInstallation,
13666
+ removePortableInstallation
13667
+ };
13644
13668
  });
13645
13669
 
13646
13670
  // src/commands/portable/merge-single-sections.ts
@@ -13888,6 +13912,12 @@ function validateStrategyTargetPath(targetPath, options2) {
13888
13912
  }
13889
13913
  return null;
13890
13914
  }
13915
+ function resolvePortableInstallerRegistryDeps(deps) {
13916
+ return {
13917
+ ...defaultPortableInstallerRegistryDeps,
13918
+ ...deps
13919
+ };
13920
+ }
13891
13921
  function resolvePerFileOutputFilename(filename, pathConfig) {
13892
13922
  if (pathConfig.nestedCommands !== false || !filename.includes("/")) {
13893
13923
  return filename;
@@ -14049,7 +14079,7 @@ function buildPerFileCollisionSkips(items, provider, configDisplayName, basePath
14049
14079
  }
14050
14080
  return skipped;
14051
14081
  }
14052
- async function installPerFileItems(items, provider, portableType, pathConfig, options2) {
14082
+ async function installPerFileItems(items, provider, portableType, pathConfig, options2, registryDeps) {
14053
14083
  const config = providers[provider];
14054
14084
  const results = [];
14055
14085
  let aggregateChars = 0;
@@ -14101,7 +14131,7 @@ async function installPerFileItems(items, provider, portableType, pathConfig, op
14101
14131
  continue;
14102
14132
  }
14103
14133
  }
14104
- const result = await installPerFile(item, provider, portableType, options2);
14134
+ const result = await installPerFile(item, provider, portableType, options2, registryDeps);
14105
14135
  if (totalCharLimit && result.success && !result.skipped) {
14106
14136
  aggregateChars += itemSize;
14107
14137
  }
@@ -14189,7 +14219,7 @@ function parseYamlModesFile(content) {
14189
14219
  }
14190
14220
  return modes;
14191
14221
  }
14192
- async function installPerFile(item, provider, portableType, options2) {
14222
+ async function installPerFile(item, provider, portableType, options2, registryDeps) {
14193
14223
  const config = providers[provider];
14194
14224
  const typeKey = getProviderPathKeyForPortableType(portableType);
14195
14225
  const pathConfig = config[typeKey];
@@ -14274,7 +14304,7 @@ async function installPerFile(item, provider, portableType, options2) {
14274
14304
  await writeFile3(targetPath, result.content, "utf-8");
14275
14305
  const sourceChecksum = computeContentChecksum(result.content);
14276
14306
  const targetChecksum = sourceChecksum;
14277
- await addPortableInstallation(item.name, portableType, provider, options2.global, targetPath, item.sourcePath, {
14307
+ await registryDeps.addPortableInstallation(item.name, portableType, provider, options2.global, targetPath, item.sourcePath, {
14278
14308
  sourceChecksum,
14279
14309
  targetChecksum,
14280
14310
  installSource: "kit"
@@ -14307,7 +14337,7 @@ async function installPerFile(item, provider, portableType, options2) {
14307
14337
  };
14308
14338
  }
14309
14339
  }
14310
- async function installMergeSingle(items, provider, portableType, options2) {
14340
+ async function installMergeSingle(items, provider, portableType, options2, registryDeps) {
14311
14341
  const config = providers[provider];
14312
14342
  const typeKey = getProviderPathKeyForPortableType(portableType);
14313
14343
  const pathConfig = config[typeKey];
@@ -14479,7 +14509,7 @@ ${sections.join(`
14479
14509
  const sectionContent = newOwnedSections.get(sectionKey) || "";
14480
14510
  const sourceChecksum = newSourceChecksums.get(sectionKey) ?? computeContentChecksum(item.body);
14481
14511
  const targetChecksum = computeContentChecksum(sectionContent);
14482
- await addPortableInstallation(item.name, portableType, provider, options2.global, targetPath, item.sourcePath, {
14512
+ await registryDeps.addPortableInstallation(item.name, portableType, provider, options2.global, targetPath, item.sourcePath, {
14483
14513
  sourceChecksum,
14484
14514
  targetChecksum,
14485
14515
  ownedSections: [sectionKey],
@@ -14522,7 +14552,7 @@ ${sections.join(`
14522
14552
  };
14523
14553
  }
14524
14554
  }
14525
- async function installYamlMerge(items, provider, portableType, options2) {
14555
+ async function installYamlMerge(items, provider, portableType, options2, registryDeps) {
14526
14556
  const config = providers[provider];
14527
14557
  const typeKey = getProviderPathKeyForPortableType(portableType);
14528
14558
  const pathConfig = config[typeKey];
@@ -14628,7 +14658,7 @@ async function installYamlMerge(items, provider, portableType, options2) {
14628
14658
  for (const item of items) {
14629
14659
  const result = convertItem(item, pathConfig.format, provider, { global: options2.global });
14630
14660
  const sourceChecksum = computeContentChecksum(result.content);
14631
- await addPortableInstallation(item.name, portableType, provider, options2.global, targetPath, item.sourcePath, {
14661
+ await registryDeps.addPortableInstallation(item.name, portableType, provider, options2.global, targetPath, item.sourcePath, {
14632
14662
  sourceChecksum,
14633
14663
  targetChecksum,
14634
14664
  ownedSections,
@@ -14660,7 +14690,7 @@ async function installYamlMerge(items, provider, portableType, options2) {
14660
14690
  };
14661
14691
  }
14662
14692
  }
14663
- async function installJsonMerge(items, provider, portableType, options2) {
14693
+ async function installJsonMerge(items, provider, portableType, options2, registryDeps) {
14664
14694
  const config = providers[provider];
14665
14695
  const typeKey = getProviderPathKeyForPortableType(portableType);
14666
14696
  const pathConfig = config[typeKey];
@@ -14838,7 +14868,7 @@ ${item.body}
14838
14868
  for (const item of items) {
14839
14869
  const result = convertItem(item, pathConfig.format, provider, { global: options2.global });
14840
14870
  const sourceChecksum = computeContentChecksum(result.content);
14841
- await addPortableInstallation(item.name, portableType, provider, options2.global, modesPath, item.sourcePath, {
14871
+ await registryDeps.addPortableInstallation(item.name, portableType, provider, options2.global, modesPath, item.sourcePath, {
14842
14872
  sourceChecksum,
14843
14873
  targetChecksum,
14844
14874
  ownedSections,
@@ -14870,7 +14900,8 @@ ${item.body}
14870
14900
  };
14871
14901
  }
14872
14902
  }
14873
- async function installPortableItem(items, provider, portableType, options2) {
14903
+ async function installPortableItem(items, provider, portableType, options2, deps) {
14904
+ const registryDeps = resolvePortableInstallerRegistryDeps(deps);
14874
14905
  const config = providers[provider];
14875
14906
  const typeKey = getProviderPathKeyForPortableType(portableType);
14876
14907
  const pathConfig = config[typeKey];
@@ -14885,17 +14916,17 @@ async function installPortableItem(items, provider, portableType, options2) {
14885
14916
  }
14886
14917
  switch (pathConfig.writeStrategy) {
14887
14918
  case "merge-single":
14888
- return installMergeSingle(items, provider, portableType, options2);
14919
+ return installMergeSingle(items, provider, portableType, options2, registryDeps);
14889
14920
  case "yaml-merge":
14890
- return installYamlMerge(items, provider, portableType, options2);
14921
+ return installYamlMerge(items, provider, portableType, options2, registryDeps);
14891
14922
  case "json-merge":
14892
- return installJsonMerge(items, provider, portableType, options2);
14923
+ return installJsonMerge(items, provider, portableType, options2, registryDeps);
14893
14924
  case "codex-toml":
14894
- return installCodexToml(items, provider, portableType, options2);
14925
+ return installCodexToml(items, provider, portableType, options2, registryDeps);
14895
14926
  case "single-file":
14896
- return installPerFile(items[0], provider, portableType, options2);
14927
+ return installPerFile(items[0], provider, portableType, options2, registryDeps);
14897
14928
  case "codex-hooks":
14898
- return installPerFile(items[0], provider, portableType, options2);
14929
+ return installPerFile(items[0], provider, portableType, options2, registryDeps);
14899
14930
  case "per-file": {
14900
14931
  const results = [];
14901
14932
  let aggregateChars = 0;
@@ -14943,7 +14974,7 @@ async function installPortableItem(items, provider, portableType, options2) {
14943
14974
  continue;
14944
14975
  }
14945
14976
  }
14946
- const result = await installPerFile(item, provider, portableType, options2);
14977
+ const result = await installPerFile(item, provider, portableType, options2, registryDeps);
14947
14978
  if (totalCharLimit && result.success && !result.skipped) {
14948
14979
  aggregateChars += itemSize;
14949
14980
  }
@@ -14979,7 +15010,8 @@ async function installPortableItem(items, provider, portableType, options2) {
14979
15010
  }
14980
15011
  }
14981
15012
  }
14982
- async function installPortableItems(items, targetProviders, portableType, options2) {
15013
+ async function installPortableItems(items, targetProviders, portableType, options2, deps) {
15014
+ const registryDeps = resolvePortableInstallerRegistryDeps(deps);
14983
15015
  const uniqueProviders = Array.from(new Set(targetProviders));
14984
15016
  const results = [];
14985
15017
  for (const provider of uniqueProviders) {
@@ -14988,14 +15020,14 @@ async function installPortableItems(items, targetProviders, portableType, option
14988
15020
  const pathConfig = config[typeKey];
14989
15021
  const providerOptions = { ...options2 };
14990
15022
  if (pathConfig?.writeStrategy === "per-file") {
14991
- results.push(...await installPerFileItems(items, provider, portableType, pathConfig, providerOptions));
15023
+ results.push(...await installPerFileItems(items, provider, portableType, pathConfig, providerOptions, registryDeps));
14992
15024
  continue;
14993
15025
  }
14994
- results.push(await installPortableItem(items, provider, portableType, providerOptions));
15026
+ results.push(await installPortableItem(items, provider, portableType, providerOptions, registryDeps));
14995
15027
  }
14996
15028
  return results;
14997
15029
  }
14998
- var import_proper_lockfile3, ClineCustomModeSchema, ClineCustomModesFileSchema;
15030
+ var import_proper_lockfile3, ClineCustomModeSchema, ClineCustomModesFileSchema, defaultPortableInstallerRegistryDeps;
14999
15031
  var init_portable_installer = __esm(() => {
15000
15032
  init_zod();
15001
15033
  init_checksum_utils();
@@ -15018,6 +15050,9 @@ var init_portable_installer = __esm(() => {
15018
15050
  ClineCustomModesFileSchema = exports_external.object({
15019
15051
  customModes: exports_external.array(ClineCustomModeSchema).optional()
15020
15052
  });
15053
+ defaultPortableInstallerRegistryDeps = {
15054
+ addPortableInstallation
15055
+ };
15021
15056
  });
15022
15057
 
15023
15058
  // src/commands/portable/types.ts
@@ -49406,7 +49441,7 @@ function resolveAgentDirs() {
49406
49441
  dirs.push({ path: candidate, label: rel });
49407
49442
  }
49408
49443
  }
49409
- const globalPath = join28(home3, ".claude", "agents");
49444
+ const globalPath = join28(home2, ".claude", "agents");
49410
49445
  dirs.push({ path: globalPath, label: "~/.claude/agents" });
49411
49446
  const seen = new Set;
49412
49447
  return dirs.filter(({ path: path3 }) => {
@@ -49495,11 +49530,11 @@ function registerAgentsBrowserRoutes(app) {
49495
49530
  res.status(404).json({ error: "Agent not found" });
49496
49531
  });
49497
49532
  }
49498
- var home3;
49533
+ var home2;
49499
49534
  var init_agents_routes = __esm(() => {
49500
49535
  init_frontmatter_parser();
49501
49536
  init_kit_layout();
49502
- home3 = homedir15();
49537
+ home2 = homedir15();
49503
49538
  });
49504
49539
 
49505
49540
  // src/schemas/ck-config.schema.json
@@ -51551,10 +51586,10 @@ function mergeServers(lists) {
51551
51586
  function isSafeProjectPath(projectPath) {
51552
51587
  if (projectPath.includes(".."))
51553
51588
  return false;
51554
- const home4 = homedir23();
51589
+ const home3 = homedir23();
51555
51590
  try {
51556
51591
  const resolved = resolve14(projectPath);
51557
- if (!resolved.startsWith(home4))
51592
+ if (!resolved.startsWith(home3))
51558
51593
  return false;
51559
51594
  return existsSync21(resolved);
51560
51595
  } catch {
@@ -51918,9 +51953,9 @@ async function copyHooksCompanionDirs(sourceDir, targetDir) {
51918
51953
  function resolveSourceOrigin(sourcePath) {
51919
51954
  if (!sourcePath)
51920
51955
  return "global";
51921
- const home4 = homedir24();
51956
+ const home3 = homedir24();
51922
51957
  const cwd2 = process.cwd();
51923
- if (cwd2 === home4)
51958
+ if (cwd2 === home3)
51924
51959
  return "global";
51925
51960
  const cwdPrefix = cwd2.endsWith(sep6) ? cwd2 : `${cwd2}${sep6}`;
51926
51961
  if (sourcePath === cwd2 || sourcePath.startsWith(cwdPrefix))
@@ -53856,22 +53891,29 @@ async function detectCodexCapabilities() {
53856
53891
  if (process.env.CK_CODEX_COMPAT === "strict") {
53857
53892
  return CODEX_CAPABILITY_TABLE[CODEX_CAPABILITY_TABLE.length - 1];
53858
53893
  }
53859
- try {
53860
- const { stdout } = await execFileAsync5("codex", ["--version"], {
53861
- timeout: 5000,
53862
- encoding: "utf8"
53863
- });
53864
- const raw = stdout.trim();
53894
+ const binaryCandidates = process.platform === "win32" ? ["codex.exe", "codex"] : ["codex"];
53895
+ let rawStdout = null;
53896
+ for (const bin of binaryCandidates) {
53897
+ try {
53898
+ const { stdout } = await execFileAsync5(bin, ["--version"], {
53899
+ timeout: 5000,
53900
+ encoding: "utf8"
53901
+ });
53902
+ rawStdout = stdout;
53903
+ break;
53904
+ } catch {}
53905
+ }
53906
+ if (rawStdout !== null) {
53907
+ const raw = rawStdout.trim();
53865
53908
  const version = raw.replace(/^(codex\s+)?v?/i, "").trim();
53866
53909
  const match = findCapabilitiesForVersion(version);
53867
53910
  if (match)
53868
53911
  return match;
53869
53912
  logger.warning(`[!] Codex version ${version} not found in ck capability table; using most-restrictive baseline. Set CK_CODEX_COMPAT=optimistic to use newest known capabilities instead.`);
53870
53913
  return process.env.CK_CODEX_COMPAT === "optimistic" ? CODEX_CAPABILITY_TABLE[0] : FALLBACK_CAPABILITIES;
53871
- } catch {
53872
- logger.warning("[!] Could not detect Codex version; using most-restrictive capability baseline. Set CK_CODEX_COMPAT=optimistic to use newest known capabilities instead.");
53873
- return process.env.CK_CODEX_COMPAT === "optimistic" ? CODEX_CAPABILITY_TABLE[0] : FALLBACK_CAPABILITIES;
53874
53914
  }
53915
+ logger.warning("[!] Could not detect Codex version; using most-restrictive capability baseline. Set CK_CODEX_COMPAT=optimistic to use newest known capabilities instead.");
53916
+ return process.env.CK_CODEX_COMPAT === "optimistic" ? CODEX_CAPABILITY_TABLE[0] : FALLBACK_CAPABILITIES;
53875
53917
  }
53876
53918
  function findCapabilitiesForVersion(version) {
53877
53919
  const exact = CODEX_CAPABILITY_TABLE.find((entry) => entry.version === version);
@@ -54234,11 +54276,12 @@ function buildWrapperScript(originalPath, capabilities, hookTimeoutMs) {
54234
54276
  const escapedOriginalPath = JSON.stringify(originalPath);
54235
54277
  const scrubRulesJson = JSON.stringify(scrubRules);
54236
54278
  const effectiveTimeout = hookTimeoutMs ?? 30000;
54237
- return `#!/usr/bin/env node
54238
- // AUTO-GENERATED by claudekit ck migrate — DO NOT EDIT
54279
+ return `// AUTO-GENERATED by claudekit ck migrate — DO NOT EDIT
54239
54280
  // Codex hook compatibility wrapper for:
54240
54281
  // ${originalPath}
54241
54282
  //
54283
+ // INVOCATION: always call as \`node "<this-file>"\` — no shebang (Windows portability).
54284
+ // The hooks.json command field must prefix this wrapper with \`node\`.
54242
54285
  // This wrapper spawns the original hook, sanitizes its JSON output
54243
54286
  // to remove fields that Codex does not support, then re-emits to stdout.
54244
54287
  // To regenerate: run \`ck migrate\` again.
@@ -54450,25 +54493,46 @@ function scrubHookEntry(entry, event, capabilities, pathRewrite) {
54450
54493
  }
54451
54494
  function rewriteCommandPath(command, pathRewrite) {
54452
54495
  if (pathRewrite.commandSubstitutions && pathRewrite.commandSubstitutions.size > 0) {
54453
- const home4 = homedir26();
54496
+ const home3 = homedir26();
54497
+ const homeForward = home3.replace(/\\/g, "/");
54498
+ const normalizeSlashesStr = (s) => s.replace(/\\/g, "/");
54454
54499
  for (const [originalAbsPath, wrapperAbsPath] of pathRewrite.commandSubstitutions) {
54455
- const candidates = new Set([
54456
- originalAbsPath,
54457
- originalAbsPath.replace(home4, "$HOME"),
54458
- originalAbsPath.replace(home4, "~")
54459
- ]);
54500
+ const originalAbsForward = normalizeSlashesStr(originalAbsPath);
54501
+ let relFromHome = null;
54502
+ if (originalAbsForward.startsWith(`${homeForward}/`)) {
54503
+ relFromHome = originalAbsForward.slice(homeForward.length + 1);
54504
+ } else if (originalAbsForward === homeForward) {
54505
+ relFromHome = "";
54506
+ }
54507
+ const candidates = [
54508
+ originalAbsForward,
54509
+ originalAbsPath
54510
+ ];
54511
+ if (relFromHome !== null && relFromHome !== "") {
54512
+ candidates.push(`$HOME/${relFromHome}`);
54513
+ candidates.push(`~/${relFromHome}`);
54514
+ candidates.push(`%USERPROFILE%/${relFromHome}`);
54515
+ candidates.push(`\${HOME}/${relFromHome}`);
54516
+ }
54517
+ const commandNorm = normalizeSlashesStr(command);
54460
54518
  for (const candidate of candidates) {
54461
- if (command.includes(candidate)) {
54462
- return command.replaceAll(candidate, wrapperAbsPath);
54519
+ const candidateNorm = normalizeSlashesStr(candidate);
54520
+ if (commandNorm.includes(candidateNorm)) {
54521
+ const wrapperForward = normalizeSlashesStr(wrapperAbsPath);
54522
+ return commandNorm.replaceAll(candidateNorm, wrapperForward);
54463
54523
  }
54464
54524
  }
54465
54525
  }
54466
54526
  }
54467
- const src = pathRewrite.sourceDir.endsWith("/") ? pathRewrite.sourceDir : `${pathRewrite.sourceDir}/`;
54468
- const tgt = pathRewrite.targetDir.endsWith("/") ? pathRewrite.targetDir : `${pathRewrite.targetDir}/`;
54527
+ const normalizeSlashes = (s) => s.replace(/\\/g, "/");
54528
+ const src = normalizeSlashes(pathRewrite.sourceDir.endsWith("/") || pathRewrite.sourceDir.endsWith("\\") ? pathRewrite.sourceDir : `${pathRewrite.sourceDir}/`);
54529
+ const tgt = normalizeSlashes(pathRewrite.targetDir.endsWith("/") || pathRewrite.targetDir.endsWith("\\") ? pathRewrite.targetDir : `${pathRewrite.targetDir}/`);
54469
54530
  if (src === tgt)
54470
54531
  return command;
54471
- return command.replaceAll(src, tgt);
54532
+ const normalizedCommand = normalizeSlashes(command);
54533
+ if (!normalizedCommand.includes(src))
54534
+ return command;
54535
+ return normalizedCommand.replaceAll(src, tgt);
54472
54536
  }
54473
54537
  var init_claude_to_codex_hooks = () => {};
54474
54538
 
@@ -54897,17 +54961,6 @@ async function migrateHooksSettingsForCodex(options2) {
54897
54961
  installedHookAbsolutePaths,
54898
54962
  global: isGlobal
54899
54963
  } = options2;
54900
- if (process.platform === "win32") {
54901
- return {
54902
- status: "skipped-windows",
54903
- success: true,
54904
- backupPath: null,
54905
- hooksRegistered: 0,
54906
- message: "[!] Codex hook installation skipped: Codex CLI hooks are temporarily disabled on Windows.",
54907
- sourceSettingsPath: null,
54908
- targetSettingsPath: null
54909
- };
54910
- }
54911
54964
  if (installedHookFiles.length === 0) {
54912
54965
  return {
54913
54966
  status: "no-installed-files",
@@ -55432,14 +55485,15 @@ var init_portable_manifest = __esm(() => {
55432
55485
  function shouldBackfillRegistry(action) {
55433
55486
  return action.action === "skip" && action.backfillRegistry === true && typeof action.targetPath === "string" && action.targetPath.length > 0 && typeof action.sourceChecksum === "string" && !isUnknownChecksum(action.sourceChecksum) && typeof action.currentTargetChecksum === "string" && !isUnknownChecksum(action.currentTargetChecksum);
55434
55487
  }
55435
- async function backfillRegistryChecksums(actions, registry) {
55488
+ async function backfillRegistryChecksums(actions, registry, deps) {
55489
+ const addInstallation = deps?.addPortableInstallation ?? addPortableInstallation;
55436
55490
  for (const action of actions) {
55437
55491
  if (!shouldBackfillRegistry(action))
55438
55492
  continue;
55439
55493
  const registryEntry = registry.installations.find((entry) => entry.item === action.item && entry.type === action.type && entry.provider === action.provider && entry.global === action.global);
55440
55494
  if (!registryEntry)
55441
55495
  continue;
55442
- await addPortableInstallation(action.item, action.type, action.provider, action.global, action.targetPath, registryEntry.sourcePath, {
55496
+ await addInstallation(action.item, action.type, action.provider, action.global, action.targetPath, registryEntry.sourcePath, {
55443
55497
  sourceChecksum: action.sourceChecksum,
55444
55498
  targetChecksum: action.currentTargetChecksum,
55445
55499
  ownedSections: registryEntry.ownedSections,
@@ -56728,6 +56782,12 @@ import { existsSync as existsSync30 } from "node:fs";
56728
56782
  import { readFile as readFile26, rm as rm8 } from "node:fs/promises";
56729
56783
  import { homedir as homedir29 } from "node:os";
56730
56784
  import { basename as basename17, join as join46, resolve as resolve23 } from "node:path";
56785
+ function resolveRegistryDeps(deps) {
56786
+ return {
56787
+ ...defaultRegistryDeps,
56788
+ ...deps?.registry
56789
+ };
56790
+ }
56731
56791
  function isDisallowedControlCode(codePoint) {
56732
56792
  return codePoint >= 0 && codePoint <= 8 || codePoint >= 11 && codePoint <= 31 || codePoint >= 127 && codePoint <= 159;
56733
56793
  }
@@ -56962,7 +57022,7 @@ async function executePlanDeleteAction(action, options2) {
56962
57022
  if (!shouldPreserveTarget && action.targetPath && existsSync30(action.targetPath)) {
56963
57023
  await rm8(action.targetPath, { recursive: true, force: true });
56964
57024
  }
56965
- await removePortableInstallation(action.item, action.type, action.provider, action.global, action.targetPath ? { path: action.targetPath } : undefined);
57025
+ await (options2?.removePortableInstallation ?? removePortableInstallation)(action.item, action.type, action.provider, action.global, action.targetPath ? { path: action.targetPath } : undefined);
56966
57026
  return {
56967
57027
  provider: action.provider,
56968
57028
  providerDisplayName: providers[action.provider]?.displayName || action.provider,
@@ -57333,7 +57393,8 @@ function getCapabilities(provider) {
57333
57393
  hooks: config.hooks !== null
57334
57394
  };
57335
57395
  }
57336
- function registerMigrationRoutes(app) {
57396
+ function registerMigrationRoutes(app, deps) {
57397
+ const registryDeps = resolveRegistryDeps(deps);
57337
57398
  app.get("/api/migrate/providers", async (_req, res) => {
57338
57399
  try {
57339
57400
  const detected = new Set(await detectInstalledProviders());
@@ -57367,12 +57428,12 @@ function registerMigrationRoutes(app) {
57367
57428
  };
57368
57429
  const discovered = await discoverMigrationItems(includeAll);
57369
57430
  const cwd2 = process.cwd();
57370
- const home4 = homedir29();
57431
+ const home3 = homedir29();
57371
57432
  res.status(200).json({
57372
57433
  cwd: cwd2,
57373
57434
  targetPaths: {
57374
57435
  project: join46(cwd2, ".claude"),
57375
- global: join46(home4, ".claude")
57436
+ global: join46(home3, ".claude")
57376
57437
  },
57377
57438
  sourcePaths: discovered.sourcePaths,
57378
57439
  sourceOrigins: {
@@ -57541,7 +57602,7 @@ function registerMigrationRoutes(app) {
57541
57602
  warnReadFailure("hook", hook.name, error);
57542
57603
  }
57543
57604
  }
57544
- const registry = await readPortableRegistry();
57605
+ const registry = await registryDeps.readPortableRegistry();
57545
57606
  const targetStates = await buildTargetStates(registry.installations, {
57546
57607
  onReadFailure: (entryPath, error) => warnReadFailure("registry-target", entryPath, error)
57547
57608
  });
@@ -57650,7 +57711,7 @@ function registerMigrationRoutes(app) {
57650
57711
  }
57651
57712
  const configSource = sourceParsed.value;
57652
57713
  const discovered = await discoverMigrationItems(include, configSource);
57653
- const registry = await readPortableRegistry();
57714
+ const registry = await registryDeps.readPortableRegistry();
57654
57715
  const candidates = [];
57655
57716
  if (include.agents) {
57656
57717
  addCandidates(discovered.agents.map((a3) => ({
@@ -57903,15 +57964,18 @@ function registerMigrationRoutes(app) {
57903
57964
  const writtenPaths = new Set(allResults.filter((r2) => r2.success && !r2.skipped && r2.path.length > 0).map((r2) => resolve23(r2.path)));
57904
57965
  for (const deleteAction of deleteActions) {
57905
57966
  const deleteResult = await executePlanDeleteAction(deleteAction, {
57906
- preservePaths: writtenPaths
57967
+ preservePaths: writtenPaths,
57968
+ removePortableInstallation: registryDeps.removePortableInstallation
57907
57969
  });
57908
57970
  deleteResult.portableType = deleteAction.type;
57909
57971
  deleteResult.itemName = deleteAction.item;
57910
57972
  allResults.push(deleteResult);
57911
57973
  }
57912
57974
  try {
57913
- const registry = await readPortableRegistry();
57914
- await backfillRegistryChecksums(plan.actions, registry);
57975
+ const registry = await registryDeps.readPortableRegistry();
57976
+ await backfillRegistryChecksums(plan.actions, registry, {
57977
+ addPortableInstallation: registryDeps.addPortableInstallation
57978
+ });
57915
57979
  } catch {}
57916
57980
  for (const provider of allPlanProviders) {
57917
57981
  if (providers[provider]?.agents?.writeStrategy !== "codex-toml")
@@ -57928,7 +57992,7 @@ function registerMigrationRoutes(app) {
57928
57992
  });
57929
57993
  if (staleSlugs.length > 0) {
57930
57994
  const staleSlugSet = new Set(staleSlugs.map((s) => `${s}.toml`));
57931
- await removeInstallationsByFilter((i) => i.type === "agent" && i.provider === provider && i.global === scope && staleSlugSet.has(basename17(i.path)));
57995
+ await registryDeps.removeInstallationsByFilter((i) => i.type === "agent" && i.provider === provider && i.global === scope && staleSlugSet.has(basename17(i.path)));
57932
57996
  }
57933
57997
  }
57934
57998
  }
@@ -57939,7 +58003,7 @@ function registerMigrationRoutes(app) {
57939
58003
  const kitRoot = (agentSrc ? resolve23(agentSrc, "..") : null) ?? (cmdSrc ? resolve23(cmdSrc, "..") : null) ?? (skillSrc ? resolve23(skillSrc, "..") : null) ?? null;
57940
58004
  const manifest = kitRoot ? await loadPortableManifest(kitRoot) : null;
57941
58005
  if (manifest?.cliVersion) {
57942
- await updateAppliedManifestVersion(manifest.cliVersion);
58006
+ await registryDeps.updateAppliedManifestVersion(manifest.cliVersion);
57943
58007
  }
57944
58008
  } catch {}
57945
58009
  const responseResults2 = [...allResults, ...hookRegistrationResults2];
@@ -58141,7 +58205,7 @@ function registerMigrationRoutes(app) {
58141
58205
  }
58142
58206
  });
58143
58207
  }
58144
- var MIGRATION_TYPES, MAX_PROVIDER_COUNT = 20, MAX_PLAN_ACTIONS = 5000, ALLOWED_CONFIG_SOURCE_KEYS, CONFLICT_RESOLUTION_SCHEMA, RECONCILE_ACTION_SCHEMA, RECONCILE_BANNER_SCHEMA, RECONCILE_PLAN_SCHEMA, PLAN_EXECUTE_PAYLOAD_SCHEMA, PLURAL_TO_SINGULAR, shellHookWarningShown = false;
58208
+ var defaultRegistryDeps, MIGRATION_TYPES, MAX_PROVIDER_COUNT = 20, MAX_PLAN_ACTIONS = 5000, ALLOWED_CONFIG_SOURCE_KEYS, CONFLICT_RESOLUTION_SCHEMA, RECONCILE_ACTION_SCHEMA, RECONCILE_BANNER_SCHEMA, RECONCILE_PLAN_SCHEMA, PLAN_EXECUTE_PAYLOAD_SCHEMA, PLURAL_TO_SINGULAR, shellHookWarningShown = false;
58145
58209
  var init_migration_routes = __esm(() => {
58146
58210
  init_agents_discovery();
58147
58211
  init_commands_discovery();
@@ -58163,6 +58227,13 @@ var init_migration_routes = __esm(() => {
58163
58227
  init_logger();
58164
58228
  init_zod();
58165
58229
  init_migration_result_utils();
58230
+ defaultRegistryDeps = {
58231
+ addPortableInstallation,
58232
+ readPortableRegistry,
58233
+ removeInstallationsByFilter,
58234
+ removePortableInstallation,
58235
+ updateAppliedManifestVersion
58236
+ };
58166
58237
  MIGRATION_TYPES = [
58167
58238
  "agents",
58168
58239
  "commands",
@@ -60998,8 +61069,8 @@ function toDateStr(d3) {
60998
61069
  return `${y3}-${m2}-${day}`;
60999
61070
  }
61000
61071
  async function scanActivityMetrics(periodDays) {
61001
- const home4 = homedir33();
61002
- const projectsDir2 = join56(home4, ".claude", "projects");
61072
+ const home3 = homedir33();
61073
+ const projectsDir2 = join56(home3, ".claude", "projects");
61003
61074
  const cutoff = new Date;
61004
61075
  cutoff.setDate(cutoff.getDate() - periodDays);
61005
61076
  const dailyMap = new Map;
@@ -61069,29 +61140,29 @@ async function scanActivityMetrics(periodDays) {
61069
61140
  return { totalSessions, projects: projectActivities, dailyCounts };
61070
61141
  }
61071
61142
  async function resolveSessionDir(projectId) {
61072
- const home4 = homedir33();
61143
+ const home3 = homedir33();
61073
61144
  if (projectId.startsWith("discovered-")) {
61074
61145
  try {
61075
61146
  const encodedPathB64 = projectId.slice("discovered-".length);
61076
61147
  const projectPath = Buffer.from(encodedPathB64, "base64url").toString("utf-8");
61077
61148
  const claudeEncoded = encodePath(projectPath);
61078
- return join56(home4, ".claude", "projects", claudeEncoded);
61149
+ return join56(home3, ".claude", "projects", claudeEncoded);
61079
61150
  } catch {
61080
61151
  return null;
61081
61152
  }
61082
61153
  }
61083
61154
  if (projectId === "current") {
61084
61155
  const cwdEncoded = encodePath(process.cwd());
61085
- return join56(home4, ".claude", "projects", cwdEncoded);
61156
+ return join56(home3, ".claude", "projects", cwdEncoded);
61086
61157
  }
61087
61158
  if (projectId === "global") {
61088
- const globalEncoded = encodePath(join56(home4, ".claude"));
61089
- return join56(home4, ".claude", "projects", globalEncoded);
61159
+ const globalEncoded = encodePath(join56(home3, ".claude"));
61160
+ return join56(home3, ".claude", "projects", globalEncoded);
61090
61161
  }
61091
61162
  const registered = await ProjectsRegistryManager.getProject(projectId);
61092
61163
  if (registered) {
61093
61164
  const claudeEncoded = encodePath(registered.path);
61094
- return join56(home4, ".claude", "projects", claudeEncoded);
61165
+ return join56(home3, ".claude", "projects", claudeEncoded);
61095
61166
  }
61096
61167
  return null;
61097
61168
  }
@@ -61243,8 +61314,8 @@ async function parseSessionDetail(filePath, limit, offset) {
61243
61314
  }
61244
61315
  function registerSessionRoutes(app) {
61245
61316
  app.get("/api/sessions", async (_req, res) => {
61246
- const home4 = homedir33();
61247
- const projectsDir2 = join56(home4, ".claude", "projects");
61317
+ const home3 = homedir33();
61318
+ const projectsDir2 = join56(home3, ".claude", "projects");
61248
61319
  if (!existsSync38(projectsDir2)) {
61249
61320
  res.json({ projects: [] });
61250
61321
  return;
@@ -61927,10 +61998,10 @@ function hasOpenCodeInstallSignal2() {
61927
61998
  join59(process.cwd(), "opencode.jsonc"),
61928
61999
  join59(process.cwd(), ".opencode/agents"),
61929
62000
  join59(process.cwd(), ".opencode/commands"),
61930
- join59(home4, ".config/opencode/AGENTS.md"),
61931
- join59(home4, ".config/opencode/agents"),
61932
- join59(home4, ".config/opencode/commands"),
61933
- join59(home4, ".opencode", "bin", OPENCODE_BINARY_NAME2)
62001
+ join59(home3, ".config/opencode/AGENTS.md"),
62002
+ join59(home3, ".config/opencode/agents"),
62003
+ join59(home3, ".config/opencode/commands"),
62004
+ join59(home3, ".opencode", "bin", OPENCODE_BINARY_NAME2)
61934
62005
  ]);
61935
62006
  }
61936
62007
  async function detectInstalledAgents() {
@@ -61954,108 +62025,108 @@ function isSkillInstalled(skillName, agent, options2) {
61954
62025
  const installPath = getInstallPath(skillName, agent, options2);
61955
62026
  return existsSync39(installPath);
61956
62027
  }
61957
- var home4, OPENCODE_BINARY_NAME2, agents;
62028
+ var home3, OPENCODE_BINARY_NAME2, agents;
61958
62029
  var init_agents = __esm(() => {
61959
- home4 = homedir37();
62030
+ home3 = homedir37();
61960
62031
  OPENCODE_BINARY_NAME2 = platform5() === "win32" ? "opencode.exe" : "opencode";
61961
62032
  agents = {
61962
62033
  "claude-code": {
61963
62034
  name: "claude-code",
61964
62035
  displayName: "Claude Code",
61965
62036
  projectPath: ".claude/skills",
61966
- globalPath: join59(home4, ".claude/skills"),
61967
- detect: async () => existsSync39(join59(home4, ".claude"))
62037
+ globalPath: join59(home3, ".claude/skills"),
62038
+ detect: async () => existsSync39(join59(home3, ".claude"))
61968
62039
  },
61969
62040
  cursor: {
61970
62041
  name: "cursor",
61971
62042
  displayName: "Cursor",
61972
62043
  projectPath: ".cursor/skills",
61973
- globalPath: join59(home4, ".cursor/skills"),
61974
- detect: async () => existsSync39(join59(home4, ".cursor"))
62044
+ globalPath: join59(home3, ".cursor/skills"),
62045
+ detect: async () => existsSync39(join59(home3, ".cursor"))
61975
62046
  },
61976
62047
  codex: {
61977
62048
  name: "codex",
61978
62049
  displayName: "Codex",
61979
62050
  projectPath: ".codex/skills",
61980
- globalPath: join59(home4, ".codex/skills"),
61981
- detect: async () => existsSync39(join59(home4, ".codex"))
62051
+ globalPath: join59(home3, ".codex/skills"),
62052
+ detect: async () => existsSync39(join59(home3, ".codex"))
61982
62053
  },
61983
62054
  opencode: {
61984
62055
  name: "opencode",
61985
62056
  displayName: "OpenCode",
61986
62057
  projectPath: ".claude/skills",
61987
- globalPath: join59(home4, ".claude/skills"),
62058
+ globalPath: join59(home3, ".claude/skills"),
61988
62059
  detect: async () => hasOpenCodeInstallSignal2()
61989
62060
  },
61990
62061
  goose: {
61991
62062
  name: "goose",
61992
62063
  displayName: "Goose",
61993
62064
  projectPath: ".goose/skills",
61994
- globalPath: join59(home4, ".config/goose/skills"),
61995
- detect: async () => existsSync39(join59(home4, ".config/goose"))
62065
+ globalPath: join59(home3, ".config/goose/skills"),
62066
+ detect: async () => existsSync39(join59(home3, ".config/goose"))
61996
62067
  },
61997
62068
  "gemini-cli": {
61998
62069
  name: "gemini-cli",
61999
62070
  displayName: "Gemini CLI",
62000
62071
  projectPath: ".agents/skills",
62001
- globalPath: join59(home4, ".agents/skills"),
62002
- detect: async () => existsSync39(join59(home4, ".gemini"))
62072
+ globalPath: join59(home3, ".agents/skills"),
62073
+ detect: async () => existsSync39(join59(home3, ".gemini"))
62003
62074
  },
62004
62075
  antigravity: {
62005
62076
  name: "antigravity",
62006
62077
  displayName: "Antigravity",
62007
62078
  projectPath: ".agent/skills",
62008
- globalPath: join59(home4, ".gemini/antigravity/skills"),
62009
- detect: async () => existsSync39(join59(process.cwd(), ".agent")) || existsSync39(join59(home4, ".gemini/antigravity"))
62079
+ globalPath: join59(home3, ".gemini/antigravity/skills"),
62080
+ detect: async () => existsSync39(join59(process.cwd(), ".agent")) || existsSync39(join59(home3, ".gemini/antigravity"))
62010
62081
  },
62011
62082
  "github-copilot": {
62012
62083
  name: "github-copilot",
62013
62084
  displayName: "GitHub Copilot",
62014
62085
  projectPath: ".github/skills",
62015
- globalPath: join59(home4, ".copilot/skills"),
62016
- detect: async () => existsSync39(join59(home4, ".copilot"))
62086
+ globalPath: join59(home3, ".copilot/skills"),
62087
+ detect: async () => existsSync39(join59(home3, ".copilot"))
62017
62088
  },
62018
62089
  amp: {
62019
62090
  name: "amp",
62020
62091
  displayName: "Amp",
62021
62092
  projectPath: ".agents/skills",
62022
- globalPath: join59(home4, ".config/agents/skills"),
62023
- detect: async () => existsSync39(join59(home4, ".config/amp"))
62093
+ globalPath: join59(home3, ".config/agents/skills"),
62094
+ detect: async () => existsSync39(join59(home3, ".config/amp"))
62024
62095
  },
62025
62096
  kilo: {
62026
62097
  name: "kilo",
62027
62098
  displayName: "Kilo Code",
62028
62099
  projectPath: ".kilocode/skills",
62029
- globalPath: join59(home4, ".kilocode/skills"),
62030
- detect: async () => existsSync39(join59(home4, ".kilocode"))
62100
+ globalPath: join59(home3, ".kilocode/skills"),
62101
+ detect: async () => existsSync39(join59(home3, ".kilocode"))
62031
62102
  },
62032
62103
  roo: {
62033
62104
  name: "roo",
62034
62105
  displayName: "Roo Code",
62035
62106
  projectPath: ".roo/skills",
62036
- globalPath: join59(home4, ".roo/skills"),
62037
- detect: async () => existsSync39(join59(home4, ".roo"))
62107
+ globalPath: join59(home3, ".roo/skills"),
62108
+ detect: async () => existsSync39(join59(home3, ".roo"))
62038
62109
  },
62039
62110
  windsurf: {
62040
62111
  name: "windsurf",
62041
62112
  displayName: "Windsurf",
62042
62113
  projectPath: ".windsurf/skills",
62043
- globalPath: join59(home4, ".codeium/windsurf/skills"),
62044
- detect: async () => existsSync39(join59(home4, ".codeium/windsurf"))
62114
+ globalPath: join59(home3, ".codeium/windsurf/skills"),
62115
+ detect: async () => existsSync39(join59(home3, ".codeium/windsurf"))
62045
62116
  },
62046
62117
  cline: {
62047
62118
  name: "cline",
62048
62119
  displayName: "Cline",
62049
62120
  projectPath: ".cline/skills",
62050
- globalPath: join59(home4, ".cline/skills"),
62051
- detect: async () => existsSync39(join59(home4, ".cline"))
62121
+ globalPath: join59(home3, ".cline/skills"),
62122
+ detect: async () => existsSync39(join59(home3, ".cline"))
62052
62123
  },
62053
62124
  openhands: {
62054
62125
  name: "openhands",
62055
62126
  displayName: "OpenHands",
62056
62127
  projectPath: ".openhands/skills",
62057
- globalPath: join59(home4, ".openhands/skills"),
62058
- detect: async () => existsSync39(join59(home4, ".openhands"))
62128
+ globalPath: join59(home3, ".openhands/skills"),
62129
+ detect: async () => existsSync39(join59(home3, ".openhands"))
62059
62130
  }
62060
62131
  };
62061
62132
  });
@@ -62096,15 +62167,15 @@ function migrateRegistryPaths(registry) {
62096
62167
  }
62097
62168
  async function readRegistry2() {
62098
62169
  try {
62099
- if (!existsSync40(REGISTRY_PATH2)) {
62170
+ if (!existsSync40(REGISTRY_PATH)) {
62100
62171
  return { version: "1.0", installations: [] };
62101
62172
  }
62102
- const content = await readFile31(REGISTRY_PATH2, "utf-8");
62173
+ const content = await readFile31(REGISTRY_PATH, "utf-8");
62103
62174
  const data = JSON.parse(content);
62104
62175
  const registry = SkillRegistrySchema.parse(data);
62105
62176
  if (migrateRegistryPaths(registry)) {
62106
62177
  try {
62107
- await writeFile15(REGISTRY_PATH2, JSON.stringify(registry, null, 2), "utf-8");
62178
+ await writeFile15(REGISTRY_PATH, JSON.stringify(registry, null, 2), "utf-8");
62108
62179
  } catch {}
62109
62180
  }
62110
62181
  return registry;
@@ -62116,11 +62187,11 @@ async function readRegistry2() {
62116
62187
  }
62117
62188
  }
62118
62189
  async function writeRegistry2(registry) {
62119
- const dir = dirname25(REGISTRY_PATH2);
62190
+ const dir = dirname25(REGISTRY_PATH);
62120
62191
  if (!existsSync40(dir)) {
62121
62192
  await mkdir15(dir, { recursive: true });
62122
62193
  }
62123
- await writeFile15(REGISTRY_PATH2, JSON.stringify(registry, null, 2), "utf-8");
62194
+ await writeFile15(REGISTRY_PATH, JSON.stringify(registry, null, 2), "utf-8");
62124
62195
  }
62125
62196
  async function addInstallation(skill, agent, global3, path6, sourcePath) {
62126
62197
  const registry = await readRegistry2();
@@ -62172,11 +62243,11 @@ async function syncRegistry() {
62172
62243
  }
62173
62244
  return { removed };
62174
62245
  }
62175
- var home5, REGISTRY_PATH2, SkillInstallationSchema, SkillRegistrySchema, REGISTRY_PATH_MIGRATIONS;
62246
+ var home4, REGISTRY_PATH, SkillInstallationSchema, SkillRegistrySchema, REGISTRY_PATH_MIGRATIONS;
62176
62247
  var init_skills_registry = __esm(() => {
62177
62248
  init_zod();
62178
- home5 = homedir38();
62179
- REGISTRY_PATH2 = join60(home5, ".claudekit", "skill-registry.json");
62249
+ home4 = homedir38();
62250
+ REGISTRY_PATH = join60(home4, ".claudekit", "skill-registry.json");
62180
62251
  SkillInstallationSchema = exports_external.object({
62181
62252
  skill: exports_external.string(),
62182
62253
  agent: exports_external.string(),
@@ -63287,7 +63358,7 @@ var package_default;
63287
63358
  var init_package = __esm(() => {
63288
63359
  package_default = {
63289
63360
  name: "claudekit-cli",
63290
- version: "4.3.1-dev.1",
63361
+ version: "4.3.1-dev.3",
63291
63362
  description: "CLI tool for bootstrapping and updating ClaudeKit projects",
63292
63363
  type: "module",
63293
63364
  repository: {
@@ -65804,12 +65875,12 @@ function extractHookReferencePaths(cmd) {
65804
65875
  }
65805
65876
  function resolveHookScriptPath(scriptPath, projectDir) {
65806
65877
  let resolved = scriptPath.replace(/\\/g, "/");
65807
- const home6 = homedir40();
65808
- resolved = resolved.replace(/^\$\{?HOME\}?/, home6);
65878
+ const home5 = homedir40();
65879
+ resolved = resolved.replace(/^\$\{?HOME\}?/, home5);
65809
65880
  resolved = resolved.replace(/^\$\{?CLAUDE_PROJECT_DIR\}?/, projectDir);
65810
- resolved = resolved.replace(/^%USERPROFILE%/, home6);
65881
+ resolved = resolved.replace(/^%USERPROFILE%/, home5);
65811
65882
  resolved = resolved.replace(/^%CLAUDE_PROJECT_DIR%/, projectDir);
65812
- resolved = resolved.replace(/^~\//, `${home6}/`);
65883
+ resolved = resolved.replace(/^~\//, `${home5}/`);
65813
65884
  if (resolved.startsWith(".claude/") || resolved === ".claude") {
65814
65885
  resolved = join67(projectDir, resolved);
65815
65886
  }
@@ -75826,7 +75897,7 @@ __export(exports_worktree_manager, {
75826
75897
  createWorktree: () => createWorktree,
75827
75898
  cleanupAllWorktrees: () => cleanupAllWorktrees
75828
75899
  });
75829
- import { existsSync as existsSync71 } from "node:fs";
75900
+ import { existsSync as existsSync72 } from "node:fs";
75830
75901
  import { readFile as readFile67, writeFile as writeFile38 } from "node:fs/promises";
75831
75902
  import { join as join153 } from "node:path";
75832
75903
  async function createWorktree(projectDir, issueNumber, baseBranch) {
@@ -75892,7 +75963,7 @@ async function cleanupAllWorktrees(projectDir) {
75892
75963
  async function ensureGitignore(projectDir) {
75893
75964
  const gitignorePath = join153(projectDir, ".gitignore");
75894
75965
  try {
75895
- const content = existsSync71(gitignorePath) ? await readFile67(gitignorePath, "utf-8") : "";
75966
+ const content = existsSync72(gitignorePath) ? await readFile67(gitignorePath, "utf-8") : "";
75896
75967
  if (!content.includes(".worktrees")) {
75897
75968
  const newContent = content.endsWith(`
75898
75969
  `) ? `${content}.worktrees/
@@ -75994,13 +76065,13 @@ var init_content_validator = __esm(() => {
75994
76065
 
75995
76066
  // src/commands/content/phases/context-cache-manager.ts
75996
76067
  import { createHash as createHash9 } from "node:crypto";
75997
- import { existsSync as existsSync77, mkdirSync as mkdirSync5, readFileSync as readFileSync18, readdirSync as readdirSync11, statSync as statSync14 } from "node:fs";
76068
+ import { existsSync as existsSync78, mkdirSync as mkdirSync5, readFileSync as readFileSync18, readdirSync as readdirSync12, statSync as statSync14 } from "node:fs";
75998
76069
  import { rename as rename16, writeFile as writeFile40 } from "node:fs/promises";
75999
- import { homedir as homedir54 } from "node:os";
76000
- import { basename as basename33, join as join160 } from "node:path";
76070
+ import { homedir as homedir55 } from "node:os";
76071
+ import { basename as basename34, join as join160 } from "node:path";
76001
76072
  function getCachedContext(repoPath) {
76002
76073
  const cachePath = getCacheFilePath(repoPath);
76003
- if (!existsSync77(cachePath))
76074
+ if (!existsSync78(cachePath))
76004
76075
  return null;
76005
76076
  try {
76006
76077
  const raw2 = readFileSync18(cachePath, "utf-8");
@@ -76017,7 +76088,7 @@ function getCachedContext(repoPath) {
76017
76088
  }
76018
76089
  }
76019
76090
  async function saveCachedContext(repoPath, cache5) {
76020
- if (!existsSync77(CACHE_DIR)) {
76091
+ if (!existsSync78(CACHE_DIR)) {
76021
76092
  mkdirSync5(CACHE_DIR, { recursive: true });
76022
76093
  }
76023
76094
  const cachePath = getCacheFilePath(repoPath);
@@ -76041,9 +76112,9 @@ function computeSourceHash(repoPath) {
76041
76112
  function getDocSourcePaths(repoPath) {
76042
76113
  const paths = [];
76043
76114
  const docsDir = join160(repoPath, "docs");
76044
- if (existsSync77(docsDir)) {
76115
+ if (existsSync78(docsDir)) {
76045
76116
  try {
76046
- const files = readdirSync11(docsDir);
76117
+ const files = readdirSync12(docsDir);
76047
76118
  for (const f3 of files) {
76048
76119
  if (f3.endsWith(".md"))
76049
76120
  paths.push(join160(docsDir, f3));
@@ -76051,12 +76122,12 @@ function getDocSourcePaths(repoPath) {
76051
76122
  } catch {}
76052
76123
  }
76053
76124
  const readme = join160(repoPath, "README.md");
76054
- if (existsSync77(readme))
76125
+ if (existsSync78(readme))
76055
76126
  paths.push(readme);
76056
76127
  const stylesDir = join160(repoPath, "assets", "writing-styles");
76057
- if (existsSync77(stylesDir)) {
76128
+ if (existsSync78(stylesDir)) {
76058
76129
  try {
76059
- const files = readdirSync11(stylesDir);
76130
+ const files = readdirSync12(stylesDir);
76060
76131
  for (const f3 of files) {
76061
76132
  paths.push(join160(stylesDir, f3));
76062
76133
  }
@@ -76065,13 +76136,13 @@ function getDocSourcePaths(repoPath) {
76065
76136
  return paths.sort();
76066
76137
  }
76067
76138
  function getCacheFilePath(repoPath) {
76068
- const repoName = basename33(repoPath).replace(/[^a-zA-Z0-9_-]/g, "_");
76139
+ const repoName = basename34(repoPath).replace(/[^a-zA-Z0-9_-]/g, "_");
76069
76140
  const pathHash = createHash9("sha256").update(repoPath).digest("hex").slice(0, 8);
76070
76141
  return join160(CACHE_DIR, `${repoName}-${pathHash}-context-cache.json`);
76071
76142
  }
76072
76143
  var CACHE_DIR, CACHE_TTL_MS5;
76073
76144
  var init_context_cache_manager = __esm(() => {
76074
- CACHE_DIR = join160(homedir54(), ".claudekit", "cache");
76145
+ CACHE_DIR = join160(homedir55(), ".claudekit", "cache");
76075
76146
  CACHE_TTL_MS5 = 24 * 60 * 60 * 1000;
76076
76147
  });
76077
76148
 
@@ -76251,7 +76322,7 @@ function extractContentFromResponse(response) {
76251
76322
 
76252
76323
  // src/commands/content/phases/docs-summarizer.ts
76253
76324
  import { execSync as execSync7 } from "node:child_process";
76254
- import { existsSync as existsSync78, readFileSync as readFileSync19, readdirSync as readdirSync12 } from "node:fs";
76325
+ import { existsSync as existsSync79, readFileSync as readFileSync19, readdirSync as readdirSync13 } from "node:fs";
76255
76326
  import { join as join161 } from "node:path";
76256
76327
  async function summarizeProjectDocs(repoPath, contentLogger) {
76257
76328
  const rawContent = collectRawDocs(repoPath);
@@ -76296,7 +76367,7 @@ async function summarizeProjectDocs(repoPath, contentLogger) {
76296
76367
  function collectRawDocs(repoPath) {
76297
76368
  let totalChars = 0;
76298
76369
  const readCapped = (filePath, maxChars) => {
76299
- if (!existsSync78(filePath))
76370
+ if (!existsSync79(filePath))
76300
76371
  return "";
76301
76372
  if (totalChars >= MAX_RAW_CONTENT_CHARS)
76302
76373
  return "";
@@ -76307,9 +76378,9 @@ function collectRawDocs(repoPath) {
76307
76378
  };
76308
76379
  const docsContent = [];
76309
76380
  const docsDir = join161(repoPath, "docs");
76310
- if (existsSync78(docsDir)) {
76381
+ if (existsSync79(docsDir)) {
76311
76382
  try {
76312
- const files = readdirSync12(docsDir).filter((f3) => f3.endsWith(".md")).sort();
76383
+ const files = readdirSync13(docsDir).filter((f3) => f3.endsWith(".md")).sort();
76313
76384
  for (const f3 of files) {
76314
76385
  const content = readCapped(join161(docsDir, f3), 5000);
76315
76386
  if (content) {
@@ -76331,9 +76402,9 @@ ${content}`);
76331
76402
  }
76332
76403
  let styles3 = "";
76333
76404
  const stylesDir = join161(repoPath, "assets", "writing-styles");
76334
- if (existsSync78(stylesDir)) {
76405
+ if (existsSync79(stylesDir)) {
76335
76406
  try {
76336
- const files = readdirSync12(stylesDir).slice(0, 3);
76407
+ const files = readdirSync13(stylesDir).slice(0, 3);
76337
76408
  styles3 = files.map((f3) => readCapped(join161(stylesDir, f3), 1000)).filter(Boolean).join(`
76338
76409
 
76339
76410
  `);
@@ -76524,12 +76595,12 @@ IMPORTANT: Generate the image and output the path as JSON: {"imagePath": "/path/
76524
76595
 
76525
76596
  // src/commands/content/phases/photo-generator.ts
76526
76597
  import { execSync as execSync8 } from "node:child_process";
76527
- import { existsSync as existsSync79, mkdirSync as mkdirSync6, readdirSync as readdirSync13 } from "node:fs";
76528
- import { homedir as homedir55 } from "node:os";
76598
+ import { existsSync as existsSync80, mkdirSync as mkdirSync6, readdirSync as readdirSync14 } from "node:fs";
76599
+ import { homedir as homedir56 } from "node:os";
76529
76600
  import { join as join162 } from "node:path";
76530
76601
  async function generatePhoto(_content, context, config, platform18, contentId, contentLogger) {
76531
- const mediaDir = join162(config.contentDir.replace(/^~/, homedir55()), "media", String(contentId));
76532
- if (!existsSync79(mediaDir)) {
76602
+ const mediaDir = join162(config.contentDir.replace(/^~/, homedir56()), "media", String(contentId));
76603
+ if (!existsSync80(mediaDir)) {
76533
76604
  mkdirSync6(mediaDir, { recursive: true });
76534
76605
  }
76535
76606
  const prompt = buildPhotoPrompt(context, platform18);
@@ -76545,11 +76616,11 @@ async function generatePhoto(_content, context, config, platform18, contentId, c
76545
76616
  const parsed = parseClaudeJsonOutput(result);
76546
76617
  if (parsed && typeof parsed === "object" && "imagePath" in parsed) {
76547
76618
  const imagePath = String(parsed.imagePath);
76548
- if (existsSync79(imagePath)) {
76619
+ if (existsSync80(imagePath)) {
76549
76620
  return { path: imagePath, ...dimensions, format: "png" };
76550
76621
  }
76551
76622
  }
76552
- const files = readdirSync13(mediaDir);
76623
+ const files = readdirSync14(mediaDir);
76553
76624
  const imageFile = files.find((f3) => /\.(png|jpg|jpeg|webp)$/i.test(f3));
76554
76625
  if (imageFile) {
76555
76626
  const ext2 = imageFile.split(".").pop() ?? "png";
@@ -76641,8 +76712,8 @@ var init_content_creator = __esm(() => {
76641
76712
  });
76642
76713
 
76643
76714
  // src/commands/content/phases/content-logger.ts
76644
- import { createWriteStream as createWriteStream4, existsSync as existsSync80, mkdirSync as mkdirSync7, statSync as statSync15 } from "node:fs";
76645
- import { homedir as homedir56 } from "node:os";
76715
+ import { createWriteStream as createWriteStream4, existsSync as existsSync81, mkdirSync as mkdirSync7, statSync as statSync15 } from "node:fs";
76716
+ import { homedir as homedir57 } from "node:os";
76646
76717
  import { join as join163 } from "node:path";
76647
76718
 
76648
76719
  class ContentLogger {
@@ -76651,11 +76722,11 @@ class ContentLogger {
76651
76722
  logDir;
76652
76723
  maxBytes;
76653
76724
  constructor(maxBytes = 0) {
76654
- this.logDir = join163(homedir56(), ".claudekit", "logs");
76725
+ this.logDir = join163(homedir57(), ".claudekit", "logs");
76655
76726
  this.maxBytes = maxBytes;
76656
76727
  }
76657
76728
  init() {
76658
- if (!existsSync80(this.logDir)) {
76729
+ if (!existsSync81(this.logDir)) {
76659
76730
  mkdirSync7(this.logDir, { recursive: true });
76660
76731
  }
76661
76732
  this.rotateIfNeeded();
@@ -76748,8 +76819,8 @@ function openDatabase(dbPath) {
76748
76819
  var init_sqlite_client = () => {};
76749
76820
 
76750
76821
  // src/commands/content/phases/db-manager.ts
76751
- import { existsSync as existsSync81, mkdirSync as mkdirSync8 } from "node:fs";
76752
- import { dirname as dirname49 } from "node:path";
76822
+ import { existsSync as existsSync82, mkdirSync as mkdirSync8 } from "node:fs";
76823
+ import { dirname as dirname50 } from "node:path";
76753
76824
  function initDatabase(dbPath) {
76754
76825
  ensureParentDir(dbPath);
76755
76826
  const db = openDatabase(dbPath);
@@ -76770,8 +76841,8 @@ function runRetentionCleanup(db, retentionDays = 90) {
76770
76841
  db.prepare("DELETE FROM git_events WHERE processed = 1 AND created_at < ?").run(cutoff);
76771
76842
  }
76772
76843
  function ensureParentDir(dbPath) {
76773
- const dir = dirname49(dbPath);
76774
- if (dir && !existsSync81(dir)) {
76844
+ const dir = dirname50(dbPath);
76845
+ if (dir && !existsSync82(dir)) {
76775
76846
  mkdirSync8(dir, { recursive: true });
76776
76847
  }
76777
76848
  }
@@ -76936,7 +77007,7 @@ function isNoiseCommit(title, author) {
76936
77007
 
76937
77008
  // src/commands/content/phases/change-detector.ts
76938
77009
  import { execSync as execSync10, spawnSync as spawnSync9 } from "node:child_process";
76939
- import { existsSync as existsSync82, readFileSync as readFileSync20, readdirSync as readdirSync14, statSync as statSync16 } from "node:fs";
77010
+ import { existsSync as existsSync83, readFileSync as readFileSync20, readdirSync as readdirSync15, statSync as statSync16 } from "node:fs";
76940
77011
  import { join as join164 } from "node:path";
76941
77012
  function detectCommits(repo, since) {
76942
77013
  try {
@@ -77047,17 +77118,17 @@ function detectTags(repo, since) {
77047
77118
  }
77048
77119
  function detectCompletedPlans(repo, since) {
77049
77120
  const plansDir = join164(repo.path, "plans");
77050
- if (!existsSync82(plansDir))
77121
+ if (!existsSync83(plansDir))
77051
77122
  return [];
77052
77123
  const sinceMs = new Date(since).getTime();
77053
77124
  const events = [];
77054
77125
  try {
77055
- const entries = readdirSync14(plansDir, { withFileTypes: true });
77126
+ const entries = readdirSync15(plansDir, { withFileTypes: true });
77056
77127
  for (const entry of entries) {
77057
77128
  if (!entry.isDirectory())
77058
77129
  continue;
77059
77130
  const planFile = join164(plansDir, entry.name, "plan.md");
77060
- if (!existsSync82(planFile))
77131
+ if (!existsSync83(planFile))
77061
77132
  continue;
77062
77133
  try {
77063
77134
  const stat26 = statSync16(planFile);
@@ -77133,7 +77204,7 @@ function classifyCommit(event) {
77133
77204
 
77134
77205
  // src/commands/content/phases/repo-discoverer.ts
77135
77206
  import { execSync as execSync11 } from "node:child_process";
77136
- import { readdirSync as readdirSync15 } from "node:fs";
77207
+ import { readdirSync as readdirSync16 } from "node:fs";
77137
77208
  import { join as join165 } from "node:path";
77138
77209
  function discoverRepos2(cwd2) {
77139
77210
  const repos = [];
@@ -77143,7 +77214,7 @@ function discoverRepos2(cwd2) {
77143
77214
  repos.push(info);
77144
77215
  }
77145
77216
  try {
77146
- const entries = readdirSync15(cwd2, { withFileTypes: true });
77217
+ const entries = readdirSync16(cwd2, { withFileTypes: true });
77147
77218
  for (const entry of entries) {
77148
77219
  if (!entry.isDirectory() || entry.name.startsWith("."))
77149
77220
  continue;
@@ -78125,7 +78196,7 @@ var init_platform_setup_x = __esm(() => {
78125
78196
  });
78126
78197
 
78127
78198
  // src/commands/content/phases/setup-wizard.ts
78128
- import { existsSync as existsSync83 } from "node:fs";
78199
+ import { existsSync as existsSync84 } from "node:fs";
78129
78200
  import { join as join167 } from "node:path";
78130
78201
  async function runSetupWizard2(cwd2, contentLogger) {
78131
78202
  console.log();
@@ -78194,8 +78265,8 @@ async function showRepoSummary(cwd2) {
78194
78265
  function detectBrandAssets(cwd2, contentLogger) {
78195
78266
  const repos = discoverRepos2(cwd2);
78196
78267
  for (const repo of repos) {
78197
- const hasGuidelines = existsSync83(join167(repo.path, "docs", "brand-guidelines.md"));
78198
- const hasStyles = existsSync83(join167(repo.path, "assets", "writing-styles"));
78268
+ const hasGuidelines = existsSync84(join167(repo.path, "docs", "brand-guidelines.md"));
78269
+ const hasStyles = existsSync84(join167(repo.path, "assets", "writing-styles"));
78199
78270
  if (!hasGuidelines) {
78200
78271
  f2.warning(`${repo.name}: No docs/brand-guidelines.md — content will use generic tone.`);
78201
78272
  contentLogger.warn(`${repo.name}: missing docs/brand-guidelines.md`);
@@ -78261,13 +78332,13 @@ var init_setup_wizard = __esm(() => {
78261
78332
  });
78262
78333
 
78263
78334
  // src/commands/content/content-review-commands.ts
78264
- import { existsSync as existsSync84 } from "node:fs";
78265
- import { homedir as homedir57 } from "node:os";
78335
+ import { existsSync as existsSync85 } from "node:fs";
78336
+ import { homedir as homedir58 } from "node:os";
78266
78337
  async function queueContent() {
78267
78338
  const cwd2 = process.cwd();
78268
78339
  const config = await loadContentConfig(cwd2);
78269
- const dbPath = config.dbPath.replace(/^~/, homedir57());
78270
- if (!existsSync84(dbPath)) {
78340
+ const dbPath = config.dbPath.replace(/^~/, homedir58());
78341
+ if (!existsSync85(dbPath)) {
78271
78342
  logger.info("No content database found. Run 'ck content setup' first.");
78272
78343
  return;
78273
78344
  }
@@ -78293,7 +78364,7 @@ async function queueContent() {
78293
78364
  async function approveContentCmd(id) {
78294
78365
  const cwd2 = process.cwd();
78295
78366
  const config = await loadContentConfig(cwd2);
78296
- const dbPath = config.dbPath.replace(/^~/, homedir57());
78367
+ const dbPath = config.dbPath.replace(/^~/, homedir58());
78297
78368
  const db = initDatabase(dbPath);
78298
78369
  try {
78299
78370
  approveContent(db, Number.parseInt(id, 10));
@@ -78305,7 +78376,7 @@ async function approveContentCmd(id) {
78305
78376
  async function rejectContentCmd(id, reason) {
78306
78377
  const cwd2 = process.cwd();
78307
78378
  const config = await loadContentConfig(cwd2);
78308
- const dbPath = config.dbPath.replace(/^~/, homedir57());
78379
+ const dbPath = config.dbPath.replace(/^~/, homedir58());
78309
78380
  const db = initDatabase(dbPath);
78310
78381
  try {
78311
78382
  rejectContent(db, Number.parseInt(id, 10), reason);
@@ -78335,12 +78406,12 @@ __export(exports_content_subcommands, {
78335
78406
  logsContent: () => logsContent,
78336
78407
  approveContentCmd: () => approveContentCmd
78337
78408
  });
78338
- import { existsSync as existsSync85, readFileSync as readFileSync21, unlinkSync as unlinkSync6 } from "node:fs";
78339
- import { homedir as homedir58 } from "node:os";
78409
+ import { existsSync as existsSync86, readFileSync as readFileSync21, unlinkSync as unlinkSync6 } from "node:fs";
78410
+ import { homedir as homedir59 } from "node:os";
78340
78411
  import { join as join168 } from "node:path";
78341
78412
  function isDaemonRunning() {
78342
78413
  const lockFile = join168(LOCK_DIR, `${LOCK_NAME2}.lock`);
78343
- if (!existsSync85(lockFile))
78414
+ if (!existsSync86(lockFile))
78344
78415
  return { running: false, pid: null };
78345
78416
  try {
78346
78417
  const pidStr = readFileSync21(lockFile, "utf-8").trim();
@@ -78372,7 +78443,7 @@ async function startContent(options2) {
78372
78443
  }
78373
78444
  async function stopContent() {
78374
78445
  const lockFile = join168(LOCK_DIR, `${LOCK_NAME2}.lock`);
78375
- if (!existsSync85(lockFile)) {
78446
+ if (!existsSync86(lockFile)) {
78376
78447
  logger.info("Content daemon is not running.");
78377
78448
  return;
78378
78449
  }
@@ -78410,10 +78481,10 @@ async function statusContent() {
78410
78481
  } catch {}
78411
78482
  }
78412
78483
  async function logsContent(options2) {
78413
- const logDir = join168(homedir58(), ".claudekit", "logs");
78484
+ const logDir = join168(homedir59(), ".claudekit", "logs");
78414
78485
  const dateStr = new Date().toISOString().slice(0, 10).replace(/-/g, "");
78415
78486
  const logPath = join168(logDir, `content-${dateStr}.log`);
78416
- if (!existsSync85(logPath)) {
78487
+ if (!existsSync86(logPath)) {
78417
78488
  logger.info("No content logs found for today.");
78418
78489
  return;
78419
78490
  }
@@ -78444,12 +78515,12 @@ var init_content_subcommands = __esm(() => {
78444
78515
  init_setup_wizard();
78445
78516
  init_state_manager();
78446
78517
  init_content_review_commands();
78447
- LOCK_DIR = join168(homedir58(), ".claudekit", "locks");
78518
+ LOCK_DIR = join168(homedir59(), ".claudekit", "locks");
78448
78519
  });
78449
78520
 
78450
78521
  // src/commands/content/content-command.ts
78451
- import { existsSync as existsSync86, mkdirSync as mkdirSync9, unlinkSync as unlinkSync7, writeFileSync as writeFileSync7 } from "node:fs";
78452
- import { homedir as homedir59 } from "node:os";
78522
+ import { existsSync as existsSync87, mkdirSync as mkdirSync9, unlinkSync as unlinkSync7, writeFileSync as writeFileSync7 } from "node:fs";
78523
+ import { homedir as homedir60 } from "node:os";
78453
78524
  import { join as join169 } from "node:path";
78454
78525
  async function contentCommand(options2) {
78455
78526
  const cwd2 = process.cwd();
@@ -78479,10 +78550,10 @@ async function contentCommand(options2) {
78479
78550
  }
78480
78551
  contentLogger.info("Setup complete. Starting daemon...");
78481
78552
  }
78482
- if (!existsSync86(LOCK_DIR2))
78553
+ if (!existsSync87(LOCK_DIR2))
78483
78554
  mkdirSync9(LOCK_DIR2, { recursive: true });
78484
78555
  writeFileSync7(LOCK_FILE, String(process.pid), "utf-8");
78485
- const dbPath = config.dbPath.replace(/^~/, homedir59());
78556
+ const dbPath = config.dbPath.replace(/^~/, homedir60());
78486
78557
  const db = initDatabase(dbPath);
78487
78558
  contentLogger.info(`Database initialised at ${dbPath}`);
78488
78559
  const adapters = initializeAdapters(config);
@@ -78628,7 +78699,7 @@ var init_content_command = __esm(() => {
78628
78699
  init_publisher();
78629
78700
  init_review_manager();
78630
78701
  init_state_manager();
78631
- LOCK_DIR2 = join169(homedir59(), ".claudekit", "locks");
78702
+ LOCK_DIR2 = join169(homedir60(), ".claudekit", "locks");
78632
78703
  LOCK_FILE = join169(LOCK_DIR2, "ck-content.lock");
78633
78704
  });
78634
78705
 
@@ -80168,6 +80239,12 @@ var init_plan_command_help = __esm(() => {
80168
80239
  title: "Scope Options",
80169
80240
  options: [{ flags: "-g, --global", description: "Create plan in global plans scope" }]
80170
80241
  }
80242
+ ],
80243
+ sections: [
80244
+ {
80245
+ title: "Agent Editing Reminder",
80246
+ content: "After creating a plan, Claude Code agents should read `plan.md` and every generated `phase-*.md` before editing. The files already exist; Write/Edit without Read can be rejected after wasting tokens."
80247
+ }
80171
80248
  ]
80172
80249
  },
80173
80250
  {
@@ -84596,6 +84673,16 @@ init_provider_registry();
84596
84673
  import { existsSync as existsSync9 } from "node:fs";
84597
84674
  import { lstat as lstat3, rm as rm2 } from "node:fs/promises";
84598
84675
  import { basename as basename5, dirname as dirname6, join as join17, relative as relative4, resolve as resolve8, sep as sep4 } from "node:path";
84676
+ var defaultCommandRegistryDeps = {
84677
+ readPortableRegistry,
84678
+ removePortableInstallation
84679
+ };
84680
+ function resolveCommandRegistryDeps(deps) {
84681
+ return {
84682
+ ...defaultCommandRegistryDeps,
84683
+ ...deps
84684
+ };
84685
+ }
84599
84686
  function isPathWithinBase(targetPath, basePath) {
84600
84687
  const resolvedTarget = resolve8(targetPath);
84601
84688
  const resolvedBase = resolve8(basePath);
@@ -84727,8 +84814,9 @@ async function removeCommandTarget(targetPath, provider, basePath) {
84727
84814
  }
84728
84815
  await rm2(targetPath, { recursive: true, force: true });
84729
84816
  }
84730
- async function uninstallCommandFromProvider(commandName, provider, global3) {
84731
- const registry = await readPortableRegistry();
84817
+ async function uninstallCommandFromProvider(commandName, provider, global3, deps) {
84818
+ const registryDeps = resolveCommandRegistryDeps(deps);
84819
+ const registry = await registryDeps.readPortableRegistry();
84732
84820
  const installations = findPortableInstallations(registry, commandName, "command", provider, global3);
84733
84821
  if (installations.length === 0) {
84734
84822
  return {
@@ -84749,7 +84837,7 @@ async function uninstallCommandFromProvider(commandName, provider, global3) {
84749
84837
  if (fileExists) {
84750
84838
  await removeCommandTarget(installation.path, provider, basePath);
84751
84839
  }
84752
- await removePortableInstallation(commandName, "command", provider, global3);
84840
+ await registryDeps.removePortableInstallation(commandName, "command", provider, global3);
84753
84841
  return {
84754
84842
  item: commandName,
84755
84843
  provider,
@@ -84771,7 +84859,8 @@ async function uninstallCommandFromProvider(commandName, provider, global3) {
84771
84859
  };
84772
84860
  }
84773
84861
  }
84774
- async function forceUninstallCommandFromProvider(commandName, provider, global3) {
84862
+ async function forceUninstallCommandFromProvider(commandName, provider, global3, deps) {
84863
+ const registryDeps = resolveCommandRegistryDeps(deps);
84775
84864
  const config = providers[provider];
84776
84865
  const pathConfig = config.commands;
84777
84866
  if (!pathConfig) {
@@ -84841,7 +84930,7 @@ async function forceUninstallCommandFromProvider(commandName, provider, global3)
84841
84930
  }
84842
84931
  try {
84843
84932
  await removeCommandTarget(targetPath, provider, basePath);
84844
- await removePortableInstallation(commandName, "command", provider, global3);
84933
+ await registryDeps.removePortableInstallation(commandName, "command", provider, global3);
84845
84934
  return {
84846
84935
  item: commandName,
84847
84936
  provider,
@@ -84862,8 +84951,9 @@ async function forceUninstallCommandFromProvider(commandName, provider, global3)
84862
84951
  };
84863
84952
  }
84864
84953
  }
84865
- async function getInstalledCommands(provider, global3) {
84866
- const registry = await readPortableRegistry();
84954
+ async function getInstalledCommands(provider, global3, deps) {
84955
+ const registryDeps = resolveCommandRegistryDeps(deps);
84956
+ const registry = await registryDeps.readPortableRegistry();
84867
84957
  return registry.installations.filter((i) => {
84868
84958
  if (i.type !== "command")
84869
84959
  return false;
@@ -84876,9 +84966,20 @@ async function getInstalledCommands(provider, global3) {
84876
84966
  }
84877
84967
 
84878
84968
  // src/commands/commands/commands-command.ts
84879
- async function listCommands(showInstalled) {
84969
+ var defaultCommandsRegistryDeps = {
84970
+ readPortableRegistry,
84971
+ removePortableInstallation,
84972
+ syncPortableRegistry
84973
+ };
84974
+ function resolveCommandsRegistryDeps(options2) {
84975
+ return {
84976
+ ...defaultCommandsRegistryDeps,
84977
+ ...options2?.registry
84978
+ };
84979
+ }
84980
+ async function listCommands(showInstalled, registryDeps) {
84880
84981
  if (showInstalled) {
84881
- const installations = await getInstalledCommands();
84982
+ const installations = await getInstalledCommands(undefined, undefined, registryDeps);
84882
84983
  if (installations.length === 0) {
84883
84984
  f2.warn("No commands installed via ck commands.");
84884
84985
  return;
@@ -84930,9 +85031,9 @@ async function listCommands(showInstalled) {
84930
85031
  console.log(import_picocolors13.default.dim(` Source: ${sourcePath}`));
84931
85032
  console.log();
84932
85033
  }
84933
- async function handleUninstall2(options2) {
85034
+ async function handleUninstall2(options2, registryDeps) {
84934
85035
  if (!options2.name) {
84935
- const installations = await getInstalledCommands();
85036
+ const installations = await getInstalledCommands(undefined, undefined, registryDeps);
84936
85037
  if (installations.length === 0) {
84937
85038
  f2.warn("No commands installed via ck commands.");
84938
85039
  return;
@@ -84964,7 +85065,7 @@ async function handleUninstall2(options2) {
84964
85065
  const spinner2 = de();
84965
85066
  spinner2.start("Uninstalling...");
84966
85067
  for (const inst of toUninstall) {
84967
- await uninstallCommandFromProvider(inst.item, inst.provider, inst.global);
85068
+ await uninstallCommandFromProvider(inst.item, inst.provider, inst.global, registryDeps);
84968
85069
  }
84969
85070
  spinner2.stop("Uninstall complete");
84970
85071
  f2.success(`Removed ${toUninstall.length} command(s)`);
@@ -84990,7 +85091,7 @@ async function handleUninstall2(options2) {
84990
85091
  const spinner2 = de();
84991
85092
  spinner2.start("Force uninstalling...");
84992
85093
  const targets = options2.agent;
84993
- const results = await Promise.all(targets.map((provider) => forceUninstallCommandFromProvider(trimmedName, provider, options2.global ?? false)));
85094
+ const results = await Promise.all(targets.map((provider) => forceUninstallCommandFromProvider(trimmedName, provider, options2.global ?? false, registryDeps)));
84994
85095
  const successCount2 = results.filter((result) => result.success).length;
84995
85096
  spinner2.stop("Force uninstall complete");
84996
85097
  for (const result of results) {
@@ -85005,7 +85106,7 @@ async function handleUninstall2(options2) {
85005
85106
  }
85006
85107
  return true;
85007
85108
  };
85008
- const registry = await readPortableRegistry();
85109
+ const registry = await registryDeps.readPortableRegistry();
85009
85110
  const matches = registry.installations.filter((i) => i.type === "command" && i.item.toLowerCase() === trimmedName.toLowerCase());
85010
85111
  if (matches.length === 0) {
85011
85112
  if (options2.force) {
@@ -85048,7 +85149,7 @@ async function handleUninstall2(options2) {
85048
85149
  spinner.start("Uninstalling...");
85049
85150
  let successCount = 0;
85050
85151
  for (const inst of toRemove) {
85051
- const result = await uninstallCommandFromProvider(inst.item, inst.provider, inst.global);
85152
+ const result = await uninstallCommandFromProvider(inst.item, inst.provider, inst.global, registryDeps);
85052
85153
  if (result.success)
85053
85154
  successCount++;
85054
85155
  }
@@ -85059,11 +85160,12 @@ async function commandsCommand(options2) {
85059
85160
  console.log();
85060
85161
  oe(import_picocolors13.default.bgCyan(import_picocolors13.default.black(" ck commands ")));
85061
85162
  try {
85163
+ const registryDeps = resolveCommandsRegistryDeps(options2);
85062
85164
  const validOptions = PortableCommandOptionsSchema.parse(options2);
85063
85165
  if (validOptions.sync) {
85064
85166
  const spinner2 = de();
85065
85167
  spinner2.start("Syncing registry...");
85066
- const { removed } = await syncPortableRegistry();
85168
+ const { removed } = await registryDeps.syncPortableRegistry();
85067
85169
  spinner2.stop("Sync complete");
85068
85170
  if (removed.length > 0) {
85069
85171
  const cmdRemoved = removed.filter((r2) => r2.type === "command");
@@ -85075,12 +85177,12 @@ async function commandsCommand(options2) {
85075
85177
  return;
85076
85178
  }
85077
85179
  if (validOptions.uninstall) {
85078
- await handleUninstall2(validOptions);
85180
+ await handleUninstall2(validOptions, registryDeps);
85079
85181
  $e(import_picocolors13.default.green("Done!"));
85080
85182
  return;
85081
85183
  }
85082
85184
  if (validOptions.list) {
85083
- await listCommands(validOptions.installed ?? false);
85185
+ await listCommands(validOptions.installed ?? false, registryDeps);
85084
85186
  $e(import_picocolors13.default.dim("Use --name <command> to install a specific command"));
85085
85187
  return;
85086
85188
  }
@@ -87266,16 +87368,16 @@ async function checkPathRefsValid(projectDir) {
87266
87368
  };
87267
87369
  }
87268
87370
  const baseDir = dirname28(claudeMdPath);
87269
- const home6 = homedir42();
87371
+ const home5 = homedir42();
87270
87372
  const broken = [];
87271
87373
  for (const ref of refs) {
87272
87374
  let refPath;
87273
87375
  if (ref.startsWith("$HOME") || ref.startsWith("${HOME}") || ref.startsWith("%USERPROFILE%")) {
87274
- refPath = normalize6(ref.replace(/^\$\{?HOME\}?/, home6).replace("%USERPROFILE%", home6));
87376
+ refPath = normalize6(ref.replace(/^\$\{?HOME\}?/, home5).replace("%USERPROFILE%", home5));
87275
87377
  } else if (ref.startsWith("$CLAUDE_PROJECT_DIR") || ref.startsWith("${CLAUDE_PROJECT_DIR}") || ref.startsWith("%CLAUDE_PROJECT_DIR%")) {
87276
87378
  refPath = normalize6(ref.replace(/^\$\{?CLAUDE_PROJECT_DIR\}?/, projectDir).replace("%CLAUDE_PROJECT_DIR%", projectDir));
87277
87379
  } else if (ref.startsWith("~")) {
87278
- refPath = normalize6(ref.replace(/^~/, home6));
87380
+ refPath = normalize6(ref.replace(/^~/, home5));
87279
87381
  } else if (ref.startsWith("/")) {
87280
87382
  refPath = normalize6(ref);
87281
87383
  } else if (/^[A-Za-z]:/.test(ref)) {
@@ -87284,7 +87386,7 @@ async function checkPathRefsValid(projectDir) {
87284
87386
  refPath = resolve35(baseDir, ref);
87285
87387
  }
87286
87388
  const normalizedPath = normalize6(refPath);
87287
- const isWithinHome = normalizedPath.startsWith(home6);
87389
+ const isWithinHome = normalizedPath.startsWith(home5);
87288
87390
  const isWithinBase2 = normalizedPath.startsWith(normalize6(baseDir));
87289
87391
  const isAbsoluteAllowed = ref.startsWith("/") || /^[A-Za-z]:/.test(ref);
87290
87392
  if (!isWithinHome && !isWithinBase2 && !isAbsoluteAllowed) {
@@ -89271,8 +89373,8 @@ class ReportGenerator {
89271
89373
  };
89272
89374
  }
89273
89375
  scrubPath(path7) {
89274
- const home6 = process.env.HOME || process.env.USERPROFILE || "";
89275
- return home6 ? path7.replace(home6, "~") : path7;
89376
+ const home5 = process.env.HOME || process.env.USERPROFILE || "";
89377
+ return home5 ? path7.replace(home5, "~") : path7;
89276
89378
  }
89277
89379
  getStatusIcon(status) {
89278
89380
  switch (status) {
@@ -89386,8 +89488,8 @@ class DoctorUIRenderer {
89386
89488
  }
89387
89489
  }
89388
89490
  shortenPath(path7) {
89389
- const home6 = process.env.HOME || process.env.USERPROFILE || "";
89390
- let shortened = home6 ? path7.replace(home6, "~") : path7;
89491
+ const home5 = process.env.HOME || process.env.USERPROFILE || "";
89492
+ let shortened = home5 ? path7.replace(home5, "~") : path7;
89391
89493
  const maxLen = 50;
89392
89494
  if (shortened.length > maxLen) {
89393
89495
  const start = shortened.slice(0, 20);
@@ -100668,7 +100770,7 @@ init_logger();
100668
100770
  init_types3();
100669
100771
  var import_fs_extra15 = __toESM(require_lib(), 1);
100670
100772
  var import_ignore3 = __toESM(require_ignore(), 1);
100671
- import { dirname as dirname37, join as join110, relative as relative23 } from "node:path";
100773
+ import { dirname as dirname38, join as join110, relative as relative23 } from "node:path";
100672
100774
 
100673
100775
  // src/domains/installation/selective-merger.ts
100674
100776
  import { stat as stat18 } from "node:fs/promises";
@@ -102338,8 +102440,8 @@ class FileScanner {
102338
102440
 
102339
102441
  // src/domains/installation/merger/settings-processor.ts
102340
102442
  import { execSync as execSync5 } from "node:child_process";
102341
- import { homedir as homedir45 } from "node:os";
102342
- import { dirname as dirname36, join as join109 } from "node:path";
102443
+ import { homedir as homedir46 } from "node:os";
102444
+ import { dirname as dirname37, join as join109 } from "node:path";
102343
102445
 
102344
102446
  // src/domains/config/installed-settings-tracker.ts
102345
102447
  init_shared();
@@ -102436,6 +102538,136 @@ class InstalledSettingsTracker {
102436
102538
 
102437
102539
  // src/domains/installation/merger/settings-processor.ts
102438
102540
  init_settings_merger();
102541
+
102542
+ // src/domains/installation/merger/zombie-wirings-pruner.ts
102543
+ import { existsSync as existsSync65, readdirSync as readdirSync8 } from "node:fs";
102544
+ import { homedir as homedir45 } from "node:os";
102545
+ import { basename as basename26, dirname as dirname36, isAbsolute as isAbsolute12, resolve as resolve41, sep as sep13 } from "node:path";
102546
+ function pruneZombieEngineerWirings(settings, hookDir) {
102547
+ const pruned = [];
102548
+ if (!existsSync65(hookDir)) {
102549
+ return { settings, pruned };
102550
+ }
102551
+ const hookFiles = readdirSync8(hookDir);
102552
+ const hasHookFiles = hookFiles.some((f3) => f3.endsWith(".cjs") || f3.endsWith(".sh"));
102553
+ if (!hasHookFiles) {
102554
+ return { settings, pruned };
102555
+ }
102556
+ if (!settings.hooks) {
102557
+ return { settings, pruned };
102558
+ }
102559
+ const eventKeysToDelete = [];
102560
+ const events = settings.hooks;
102561
+ for (const eventName of Object.keys(events)) {
102562
+ const groups = events[eventName];
102563
+ const keptGroups = [];
102564
+ for (const group of groups) {
102565
+ if (!("hooks" in group) || !Array.isArray(group.hooks)) {
102566
+ const entry = group;
102567
+ if (shouldPruneEntry(entry, hookDir, pruned)) {
102568
+ continue;
102569
+ }
102570
+ keptGroups.push(group);
102571
+ continue;
102572
+ }
102573
+ const keptHooks = group.hooks.filter((h2) => {
102574
+ return !shouldPruneEntry(h2, hookDir, pruned);
102575
+ });
102576
+ if (keptHooks.length > 0) {
102577
+ keptGroups.push({ ...group, hooks: keptHooks });
102578
+ }
102579
+ }
102580
+ if (keptGroups.length > 0) {
102581
+ events[eventName] = keptGroups;
102582
+ } else {
102583
+ eventKeysToDelete.push(eventName);
102584
+ }
102585
+ }
102586
+ for (const key of eventKeysToDelete) {
102587
+ delete events[key];
102588
+ }
102589
+ return { settings, pruned };
102590
+ }
102591
+ function shouldPruneEntry(entry, hookDir, pruned) {
102592
+ if (entry._origin !== "engineer")
102593
+ return false;
102594
+ const filePath = extractHookFilePath(entry.command, hookDir);
102595
+ if (!filePath)
102596
+ return false;
102597
+ if (existsSync65(filePath))
102598
+ return false;
102599
+ pruned.push(basename26(filePath));
102600
+ return true;
102601
+ }
102602
+ function extractHookFilePath(command, hookDir) {
102603
+ if (!command)
102604
+ return null;
102605
+ if (/&&|\|\||;|(?<!["|'])\|(?!["|'])/.test(command))
102606
+ return null;
102607
+ const home5 = homedir45().replace(/\\/g, "/");
102608
+ const hookDirNorm = hookDir.replace(/\\/g, "/");
102609
+ function resolveEnvPath(prefix, rest) {
102610
+ const normRest = rest.replace(/\\/g, "/");
102611
+ let resolved;
102612
+ if (prefix === "$HOME" || prefix === "${HOME}" || prefix === "%USERPROFILE%") {
102613
+ resolved = `${home5}/${normRest}`;
102614
+ } else if (prefix === "$CLAUDE_PROJECT_DIR" || prefix === "%CLAUDE_PROJECT_DIR%") {
102615
+ const projectRoot = dirname36(dirname36(hookDirNorm));
102616
+ resolved = `${projectRoot}/${normRest}`;
102617
+ } else {
102618
+ resolved = `${prefix}/${normRest}`;
102619
+ }
102620
+ return resolved;
102621
+ }
102622
+ if (/^bash\s/.test(command)) {
102623
+ const bashMatch = command.match(/^bash\s+["']([^"']+\.sh)["']/);
102624
+ if (bashMatch) {
102625
+ const rawPath = bashMatch[1].replace(/\\/g, "/");
102626
+ const resolved = isAbsolute12(rawPath) || /^[A-Za-z]:[\\/]/.test(rawPath) ? rawPath : resolve41(hookDir, rawPath);
102627
+ return process.platform === "win32" ? resolved.replace(/\//g, sep13) : resolved;
102628
+ }
102629
+ return null;
102630
+ }
102631
+ if (!/(?:^|\s)node\s/.test(command))
102632
+ return null;
102633
+ const varOnlyQuoted = command.match(/(?:^|\s)node\s+["'](\$\w+|\$\{\w+\}|%\w+%)["'][/\\](\.claude[/\\]\S+)/);
102634
+ if (varOnlyQuoted) {
102635
+ const [, envVar, rest] = varOnlyQuoted;
102636
+ const resolved = resolveEnvPath(envVar, rest);
102637
+ return process.platform === "win32" ? resolved.replace(/\//g, sep13) : resolved;
102638
+ }
102639
+ const quotedMatch = command.match(/(?:^|\s)node\s+["']([^"']+)["']/);
102640
+ if (quotedMatch) {
102641
+ const rawArg = quotedMatch[1].trim().replace(/\\/g, "/");
102642
+ const envPrefixMatch = rawArg.match(/^(\$HOME|\$\{HOME\}|%USERPROFILE%|\$CLAUDE_PROJECT_DIR|%CLAUDE_PROJECT_DIR%)[/\\](.*)/);
102643
+ if (envPrefixMatch) {
102644
+ const resolved = resolveEnvPath(envPrefixMatch[1], envPrefixMatch[2]);
102645
+ return process.platform === "win32" ? resolved.replace(/\//g, sep13) : resolved;
102646
+ }
102647
+ const tildeResolved = rawArg.replace(/^~(?=\/)/, home5);
102648
+ if (isAbsolute12(tildeResolved) || /^[A-Za-z]:[\\/]/.test(tildeResolved)) {
102649
+ return process.platform === "win32" ? tildeResolved.replace(/\//g, sep13) : tildeResolved;
102650
+ }
102651
+ return resolve41(hookDir, tildeResolved);
102652
+ }
102653
+ const unquotedMatch = command.match(/(?:^|\s)node\s+(\S+\.(?:cjs|sh|mjs|js))/);
102654
+ if (unquotedMatch) {
102655
+ const rawArg = unquotedMatch[1].replace(/\\/g, "/");
102656
+ const envPrefixMatch = rawArg.match(/^(\$HOME|\$\{HOME\}|%USERPROFILE%|\$CLAUDE_PROJECT_DIR|%CLAUDE_PROJECT_DIR%)[/\\](.*)/);
102657
+ if (envPrefixMatch) {
102658
+ const resolved = resolveEnvPath(envPrefixMatch[1], envPrefixMatch[2]);
102659
+ return process.platform === "win32" ? resolved.replace(/\//g, sep13) : resolved;
102660
+ }
102661
+ const tildeResolved = rawArg.replace(/^~(?=\/)/, home5);
102662
+ if (isAbsolute12(tildeResolved) || /^[A-Za-z]:[\\/]/.test(tildeResolved)) {
102663
+ return process.platform === "win32" ? tildeResolved.replace(/\//g, sep13) : tildeResolved;
102664
+ }
102665
+ return resolve41(hookDir, tildeResolved);
102666
+ }
102667
+ return null;
102668
+ }
102669
+
102670
+ // src/domains/installation/merger/settings-processor.ts
102439
102671
  init_command_normalizer();
102440
102672
  init_logger();
102441
102673
  init_path_resolver();
@@ -102452,6 +102684,7 @@ class SettingsProcessor {
102452
102684
  installingKit;
102453
102685
  cachedVersion = undefined;
102454
102686
  deletionPatterns = [];
102687
+ zombiePrunerHookDir = null;
102455
102688
  setGlobalFlag(isGlobal) {
102456
102689
  this.isGlobal = isGlobal;
102457
102690
  }
@@ -102472,6 +102705,9 @@ class SettingsProcessor {
102472
102705
  setDeletions(deletions) {
102473
102706
  this.deletionPatterns = deletions;
102474
102707
  }
102708
+ setZombiePrunerHookDir(hookDir) {
102709
+ this.zombiePrunerHookDir = hookDir;
102710
+ }
102475
102711
  initTracker() {
102476
102712
  if (this.projectDir) {
102477
102713
  this.tracker = new InstalledSettingsTracker(this.projectDir, this.isGlobal, this.kitName);
@@ -102582,6 +102818,12 @@ class SettingsProcessor {
102582
102818
  if (hooksPruned > 0) {
102583
102819
  logger.info(`Pruned ${hooksPruned} stale hook(s) referencing deleted files`);
102584
102820
  }
102821
+ if (this.zombiePrunerHookDir) {
102822
+ const { pruned: zombiePruned } = pruneZombieEngineerWirings(mergeResult.merged, this.zombiePrunerHookDir);
102823
+ if (zombiePruned.length > 0) {
102824
+ logger.info(`Pruned ${zombiePruned.length} zombie hook entries: ${zombiePruned.join(", ")}`);
102825
+ }
102826
+ }
102585
102827
  await SettingsMerger.writeSettingsFile(destFile, mergeResult.merged);
102586
102828
  logger.success("Merged settings.json (user customizations preserved)");
102587
102829
  await this.injectTeamHooksIfSupported(destFile, mergeResult.merged);
@@ -102827,7 +103069,7 @@ class SettingsProcessor {
102827
103069
  return false;
102828
103070
  }
102829
103071
  const configuredGlobalDir = PathResolver.getGlobalKitDir().replace(/\\/g, "/").replace(/\/+$/, "");
102830
- const defaultGlobalDir = join109(homedir45(), ".claude").replace(/\\/g, "/");
103072
+ const defaultGlobalDir = join109(homedir46(), ".claude").replace(/\\/g, "/");
102831
103073
  return configuredGlobalDir !== defaultGlobalDir;
102832
103074
  }
102833
103075
  getClaudeCommandRoot() {
@@ -102847,7 +103089,7 @@ class SettingsProcessor {
102847
103089
  return true;
102848
103090
  }
102849
103091
  async repairSiblingSettingsLocal(destFile) {
102850
- const settingsLocalPath = join109(dirname36(destFile), "settings.local.json");
103092
+ const settingsLocalPath = join109(dirname37(destFile), "settings.local.json");
102851
103093
  if (settingsLocalPath === destFile || !await import_fs_extra14.pathExists(settingsLocalPath)) {
102852
103094
  return;
102853
103095
  }
@@ -102987,6 +103229,9 @@ class CopyExecutor {
102987
103229
  setKitName(kit) {
102988
103230
  this.settingsProcessor.setKitName(kit);
102989
103231
  }
103232
+ setZombiePrunerHookDir(hookDir) {
103233
+ this.settingsProcessor.setZombiePrunerHookDir(hookDir);
103234
+ }
102990
103235
  setManifest(manifest) {
102991
103236
  this.selectiveMerger = manifest ? new SelectiveMerger(manifest) : null;
102992
103237
  if (manifest && this.selectiveMerger?.hasManifest()) {
@@ -103107,10 +103352,10 @@ class CopyExecutor {
103107
103352
  }
103108
103353
  trackInstalledFile(relativePath) {
103109
103354
  this.installedFiles.add(relativePath);
103110
- let dir = dirname37(relativePath);
103355
+ let dir = dirname38(relativePath);
103111
103356
  while (dir && dir !== "." && dir !== "/") {
103112
103357
  this.installedDirectories.add(`${dir}/`);
103113
- dir = dirname37(dir);
103358
+ dir = dirname38(dir);
103114
103359
  }
103115
103360
  }
103116
103361
  }
@@ -103156,6 +103401,9 @@ class FileMerger {
103156
103401
  setDeletions(deletions) {
103157
103402
  this.copyExecutor.setDeletions(deletions);
103158
103403
  }
103404
+ setZombiePrunerHookDir(hookDir) {
103405
+ this.copyExecutor.setZombiePrunerHookDir(hookDir);
103406
+ }
103159
103407
  setManifest(manifest) {
103160
103408
  this.copyExecutor.setManifest(manifest);
103161
103409
  }
@@ -103867,7 +104115,7 @@ function buildConflictSummary(fileConflicts, hookConflicts, mcpConflicts) {
103867
104115
  init_logger();
103868
104116
  init_skip_directories();
103869
104117
  var import_fs_extra19 = __toESM(require_lib(), 1);
103870
- import { join as join115, relative as relative25, resolve as resolve41 } from "node:path";
104118
+ import { join as join115, relative as relative25, resolve as resolve43 } from "node:path";
103871
104119
 
103872
104120
  class FileScanner2 {
103873
104121
  static async getFiles(dirPath, relativeTo) {
@@ -103947,8 +104195,8 @@ class FileScanner2 {
103947
104195
  return customFiles;
103948
104196
  }
103949
104197
  static isSafePath(basePath, targetPath) {
103950
- const resolvedBase = resolve41(basePath);
103951
- const resolvedTarget = resolve41(targetPath);
104198
+ const resolvedBase = resolve43(basePath);
104199
+ const resolvedTarget = resolve43(targetPath);
103952
104200
  return resolvedTarget.startsWith(resolvedBase);
103953
104201
  }
103954
104202
  static toPosixPath(path16) {
@@ -104469,6 +104717,7 @@ async function handleMerge(ctx) {
104469
104717
  merger.setForceOverwriteSettings(ctx.options.forceOverwriteSettings);
104470
104718
  merger.setProjectDir(ctx.resolvedDir);
104471
104719
  merger.setKitName(ctx.kit.name);
104720
+ merger.setZombiePrunerHookDir(join120(ctx.claudeDir, "hooks"));
104472
104721
  if (ctx.kitType) {
104473
104722
  merger.setMultiKitContext(ctx.claudeDir, ctx.kitType);
104474
104723
  }
@@ -105259,7 +105508,7 @@ init_logger();
105259
105508
  init_types3();
105260
105509
  var import_fs_extra28 = __toESM(require_lib(), 1);
105261
105510
  import { copyFile as copyFile7, mkdir as mkdir34, readdir as readdir36, rm as rm14, stat as stat21 } from "node:fs/promises";
105262
- import { basename as basename26, join as join124, normalize as normalize9 } from "node:path";
105511
+ import { basename as basename27, join as join124, normalize as normalize9 } from "node:path";
105263
105512
  function validatePath2(path16, paramName) {
105264
105513
  if (!path16 || typeof path16 !== "string") {
105265
105514
  throw new SkillsMigrationError(`${paramName} must be a non-empty string`);
@@ -105395,7 +105644,7 @@ class SkillsBackupManager {
105395
105644
  return size;
105396
105645
  }
105397
105646
  static extractBackupTimestamp(backupPath) {
105398
- const dirName = basename26(backupPath);
105647
+ const dirName = basename27(backupPath);
105399
105648
  if (!dirName.startsWith(SkillsBackupManager.BACKUP_PREFIX)) {
105400
105649
  return null;
105401
105650
  }
@@ -105436,12 +105685,12 @@ async function getAllFiles(dirPath) {
105436
105685
  return files;
105437
105686
  }
105438
105687
  async function hashFile(filePath) {
105439
- return new Promise((resolve43, reject) => {
105688
+ return new Promise((resolve44, reject) => {
105440
105689
  const hash = createHash8("sha256");
105441
105690
  const stream = createReadStream2(filePath);
105442
105691
  stream.on("data", (chunk) => hash.update(chunk));
105443
105692
  stream.on("end", () => {
105444
- resolve43(hash.digest("hex"));
105693
+ resolve44(hash.digest("hex"));
105445
105694
  });
105446
105695
  stream.on("error", (error) => {
105447
105696
  stream.destroy();
@@ -106090,7 +106339,7 @@ async function handlePostInstall(ctx) {
106090
106339
  init_config_manager();
106091
106340
  init_github_client();
106092
106341
  import { mkdir as mkdir36 } from "node:fs/promises";
106093
- import { join as join134, resolve as resolve46 } from "node:path";
106342
+ import { join as join134, resolve as resolve47 } from "node:path";
106094
106343
 
106095
106344
  // src/domains/github/kit-access-checker.ts
106096
106345
  init_error2();
@@ -106259,8 +106508,8 @@ async function runPreflightChecks() {
106259
106508
 
106260
106509
  // src/domains/installation/fresh-installer.ts
106261
106510
  init_metadata_migration();
106262
- import { existsSync as existsSync65, readdirSync as readdirSync8, rmSync as rmSync3, rmdirSync as rmdirSync2, unlinkSync as unlinkSync5 } from "node:fs";
106263
- import { basename as basename27, dirname as dirname38, join as join132, resolve as resolve43 } from "node:path";
106511
+ import { existsSync as existsSync66, readdirSync as readdirSync9, rmSync as rmSync3, rmdirSync as rmdirSync2, unlinkSync as unlinkSync5 } from "node:fs";
106512
+ import { basename as basename28, dirname as dirname39, join as join132, resolve as resolve45 } from "node:path";
106264
106513
  init_logger();
106265
106514
  init_safe_spinner();
106266
106515
  var import_fs_extra34 = __toESM(require_lib(), 1);
@@ -106312,15 +106561,15 @@ async function analyzeFreshInstallation(claudeDir3) {
106312
106561
  };
106313
106562
  }
106314
106563
  function cleanupEmptyDirectories2(filePath, claudeDir3) {
106315
- const normalizedClaudeDir = resolve43(claudeDir3);
106316
- let currentDir = resolve43(dirname38(filePath));
106564
+ const normalizedClaudeDir = resolve45(claudeDir3);
106565
+ let currentDir = resolve45(dirname39(filePath));
106317
106566
  while (currentDir !== normalizedClaudeDir && currentDir.startsWith(normalizedClaudeDir)) {
106318
106567
  try {
106319
- const entries = readdirSync8(currentDir);
106568
+ const entries = readdirSync9(currentDir);
106320
106569
  if (entries.length === 0) {
106321
106570
  rmdirSync2(currentDir);
106322
106571
  logger.debug(`Removed empty directory: ${currentDir}`);
106323
- currentDir = resolve43(dirname38(currentDir));
106572
+ currentDir = resolve45(dirname39(currentDir));
106324
106573
  } else {
106325
106574
  break;
106326
106575
  }
@@ -106343,7 +106592,7 @@ async function removeFilesByOwnership(claudeDir3, analysis, includeModified) {
106343
106592
  }
106344
106593
  for (const file of filesToRemove) {
106345
106594
  const fullPath = join132(claudeDir3, file.path);
106346
- if (!existsSync65(fullPath)) {
106595
+ if (!existsSync66(fullPath)) {
106347
106596
  continue;
106348
106597
  }
106349
106598
  try {
@@ -106401,8 +106650,8 @@ function getFreshBackupTargets(claudeDir3, analysis, includeModified) {
106401
106650
  mutatePaths: filesToRemove.length > 0 ? ["metadata.json"] : []
106402
106651
  };
106403
106652
  }
106404
- const deletePaths = CLAUDEKIT_SUBDIRECTORIES.filter((subdir) => existsSync65(join132(claudeDir3, subdir)));
106405
- if (existsSync65(join132(claudeDir3, "metadata.json"))) {
106653
+ const deletePaths = CLAUDEKIT_SUBDIRECTORIES.filter((subdir) => existsSync66(join132(claudeDir3, subdir)));
106654
+ if (existsSync66(join132(claudeDir3, "metadata.json"))) {
106406
106655
  deletePaths.push("metadata.json");
106407
106656
  }
106408
106657
  return {
@@ -106471,7 +106720,7 @@ async function handleFreshInstallation(claudeDir3, prompts) {
106471
106720
  mutatePaths: backupTargets.mutatePaths,
106472
106721
  scope: "claude"
106473
106722
  });
106474
- await cleanupOldDestructiveOperationBackups(undefined, basename27(backup.backupDir));
106723
+ await cleanupOldDestructiveOperationBackups(undefined, basename28(backup.backupDir));
106475
106724
  backupSpinner.succeed(`Recovery backup saved to ${backup.backupDir}`);
106476
106725
  } catch (error) {
106477
106726
  backupSpinner.fail("Failed to create recovery backup");
@@ -106509,8 +106758,8 @@ async function handleFreshInstallation(claudeDir3, prompts) {
106509
106758
  // src/domains/installation/global-kit-legacy-repair.ts
106510
106759
  var import_fs_extra35 = __toESM(require_lib(), 1);
106511
106760
  import { cp as cp5, mkdir as mkdir35, readdir as readdir41, rename as rename11, rm as rm16, stat as stat22 } from "node:fs/promises";
106512
- import { homedir as homedir46 } from "node:os";
106513
- import { dirname as dirname39, join as join133, normalize as normalize11, resolve as resolve45 } from "node:path";
106761
+ import { homedir as homedir47 } from "node:os";
106762
+ import { dirname as dirname40, join as join133, normalize as normalize11, resolve as resolve46 } from "node:path";
106514
106763
  var LEGACY_KIT_MARKERS = [
106515
106764
  "metadata.json",
106516
106765
  ".ck.json",
@@ -106536,7 +106785,7 @@ function uniqueNormalizedPaths(paths) {
106536
106785
  const seen = new Set;
106537
106786
  const result = [];
106538
106787
  for (const path16 of paths) {
106539
- const normalized = normalize11(resolve45(path16));
106788
+ const normalized = normalize11(resolve46(path16));
106540
106789
  if (seen.has(normalized))
106541
106790
  continue;
106542
106791
  seen.add(normalized);
@@ -106544,7 +106793,7 @@ function uniqueNormalizedPaths(paths) {
106544
106793
  }
106545
106794
  return result;
106546
106795
  }
106547
- function getLegacyWindowsGlobalKitDirCandidates(env2 = process.env, homeDir = homedir46()) {
106796
+ function getLegacyWindowsGlobalKitDirCandidates(env2 = process.env, homeDir = homedir47()) {
106548
106797
  const candidates = [];
106549
106798
  const localAppData = safeEnvPath(env2.LOCALAPPDATA);
106550
106799
  const appData = safeEnvPath(env2.APPDATA);
@@ -106601,8 +106850,8 @@ async function repairLegacyWindowsGlobalKitDir(options2) {
106601
106850
  if (safeEnvPath(env2.CLAUDE_CONFIG_DIR)) {
106602
106851
  return { status: "skipped", reason: "custom-global-dir", candidateDirs: [] };
106603
106852
  }
106604
- const targetDir = normalize11(resolve45(options2.targetDir));
106605
- const candidateDirs = getLegacyWindowsGlobalKitDirCandidates(env2, options2.homeDir).filter((candidate) => normalize11(resolve45(candidate)) !== targetDir);
106853
+ const targetDir = normalize11(resolve46(options2.targetDir));
106854
+ const candidateDirs = getLegacyWindowsGlobalKitDirCandidates(env2, options2.homeDir).filter((candidate) => normalize11(resolve46(candidate)) !== targetDir);
106606
106855
  const legacyDirs = [];
106607
106856
  for (const candidate of candidateDirs) {
106608
106857
  if (await hasKitMarkers(candidate)) {
@@ -106623,7 +106872,7 @@ async function repairLegacyWindowsGlobalKitDir(options2) {
106623
106872
  if (targetExists) {
106624
106873
  await rm16(targetDir, { recursive: true, force: true });
106625
106874
  }
106626
- await mkdir35(dirname39(targetDir), { recursive: true });
106875
+ await mkdir35(dirname40(targetDir), { recursive: true });
106627
106876
  await moveDirectory(legacyDir, targetDir);
106628
106877
  return { status: "repaired", reason: "repaired", legacyDir, candidateDirs };
106629
106878
  }
@@ -106825,7 +107074,7 @@ async function handleSelection(ctx) {
106825
107074
  }
106826
107075
  }
106827
107076
  }
106828
- const resolvedDir = resolve46(targetDir);
107077
+ const resolvedDir = resolve47(targetDir);
106829
107078
  if (ctx.options.global) {
106830
107079
  try {
106831
107080
  const repairResult = await repairLegacyWindowsGlobalKitDir({ targetDir: resolvedDir });
@@ -107022,7 +107271,7 @@ async function handleSelection(ctx) {
107022
107271
  }
107023
107272
  // src/commands/init/phases/sync-handler.ts
107024
107273
  import { copyFile as copyFile8, mkdir as mkdir37, open as open5, readFile as readFile59, rename as rename12, stat as stat23, unlink as unlink13, writeFile as writeFile33 } from "node:fs/promises";
107025
- import { dirname as dirname40, join as join135, resolve as resolve47 } from "node:path";
107274
+ import { dirname as dirname41, join as join135, resolve as resolve48 } from "node:path";
107026
107275
  init_logger();
107027
107276
  init_path_resolver();
107028
107277
  var import_fs_extra37 = __toESM(require_lib(), 1);
@@ -107031,7 +107280,7 @@ async function handleSync(ctx) {
107031
107280
  if (!ctx.options.sync) {
107032
107281
  return ctx;
107033
107282
  }
107034
- const resolvedDir = ctx.options.global ? PathResolver.getGlobalKitDir() : resolve47(ctx.options.dir || ".");
107283
+ const resolvedDir = ctx.options.global ? PathResolver.getGlobalKitDir() : resolve48(ctx.options.dir || ".");
107035
107284
  const claudeDir3 = ctx.options.global ? resolvedDir : join135(resolvedDir, ".claude");
107036
107285
  if (!await import_fs_extra37.pathExists(claudeDir3)) {
107037
107286
  logger.error("Cannot sync: no .claude directory found");
@@ -107141,7 +107390,7 @@ async function acquireSyncLock(global3) {
107141
107390
  const lockPath = join135(cacheDir, ".sync-lock");
107142
107391
  const startTime = Date.now();
107143
107392
  const lockTimeout = getLockTimeout();
107144
- await mkdir37(dirname40(lockPath), { recursive: true });
107393
+ await mkdir37(dirname41(lockPath), { recursive: true });
107145
107394
  while (Date.now() - startTime < lockTimeout) {
107146
107395
  try {
107147
107396
  const handle = await open5(lockPath, "wx");
@@ -107677,7 +107926,7 @@ async function transformFolderPaths(extractDir, folders, options2 = {}) {
107677
107926
  // src/services/transformers/global-path-transformer.ts
107678
107927
  init_logger();
107679
107928
  import { readFile as readFile61, readdir as readdir43, writeFile as writeFile35 } from "node:fs/promises";
107680
- import { homedir as homedir47, platform as platform15 } from "node:os";
107929
+ import { homedir as homedir48, platform as platform15 } from "node:os";
107681
107930
  import { extname as extname6, join as join138 } from "node:path";
107682
107931
  var IS_WINDOWS3 = platform15() === "win32";
107683
107932
  var HOME_PREFIX = "$HOME";
@@ -107688,7 +107937,7 @@ function normalizeInstallPath(path16) {
107688
107937
  return path16.replace(/\\/g, "/").replace(/\/+$/, "");
107689
107938
  }
107690
107939
  function getDefaultGlobalClaudeDir() {
107691
- return normalizeInstallPath(join138(homedir47(), ".claude"));
107940
+ return normalizeInstallPath(join138(homedir48(), ".claude"));
107692
107941
  }
107693
107942
  function getCustomGlobalClaudeDir(targetClaudeDir) {
107694
107943
  if (!targetClaudeDir)
@@ -107808,8 +108057,8 @@ function transformContent(content, options2 = {}) {
107808
108057
  }
107809
108058
  function shouldTransformFile3(filename) {
107810
108059
  const ext2 = extname6(filename).toLowerCase();
107811
- const basename28 = filename.split("/").pop() || filename;
107812
- return TRANSFORMABLE_EXTENSIONS3.has(ext2) || ALWAYS_TRANSFORM_FILES.has(basename28);
108060
+ const basename29 = filename.split("/").pop() || filename;
108061
+ return TRANSFORMABLE_EXTENSIONS3.has(ext2) || ALWAYS_TRANSFORM_FILES.has(basename29);
107813
108062
  }
107814
108063
  async function transformPathsForGlobalInstall(directory, options2 = {}) {
107815
108064
  let filesTransformed = 0;
@@ -108087,16 +108336,16 @@ async function initCommand(options2) {
108087
108336
  // src/commands/migrate/migrate-command.ts
108088
108337
  init_dist2();
108089
108338
  var import_picocolors30 = __toESM(require_picocolors(), 1);
108090
- import { existsSync as existsSync66 } from "node:fs";
108339
+ import { existsSync as existsSync67 } from "node:fs";
108091
108340
  import { readFile as readFile65, rm as rm18, unlink as unlink14 } from "node:fs/promises";
108092
- import { homedir as homedir52 } from "node:os";
108093
- import { basename as basename29, join as join143, resolve as resolve49 } from "node:path";
108341
+ import { homedir as homedir53 } from "node:os";
108342
+ import { basename as basename30, join as join143, resolve as resolve50 } from "node:path";
108094
108343
  init_logger();
108095
108344
 
108096
108345
  // src/ui/ck-cli-design/tokens.ts
108097
108346
  var import_picocolors27 = __toESM(require_picocolors(), 1);
108098
- import { homedir as homedir48, platform as platform16 } from "node:os";
108099
- import { resolve as resolve48, win32 as win322 } from "node:path";
108347
+ import { homedir as homedir49, platform as platform16 } from "node:os";
108348
+ import { resolve as resolve49, win32 as win322 } from "node:path";
108100
108349
  var PANEL_MIN_WIDTH = 60;
108101
108350
  var PANEL_MAX_WIDTH = 72;
108102
108351
  var DEFAULT_WIDTH = PANEL_MAX_WIDTH;
@@ -108253,11 +108502,11 @@ function wrapText(value, width) {
108253
108502
  }
108254
108503
  function formatDisplayPath(value) {
108255
108504
  const normalized = value.replace(/\\/g, "/");
108256
- const home6 = homedir48().replace(/\\/g, "/");
108257
- if (normalized === home6)
108505
+ const home5 = homedir49().replace(/\\/g, "/");
108506
+ if (normalized === home5)
108258
108507
  return "~";
108259
- if (normalized.startsWith(`${home6}/`)) {
108260
- return normalized.replace(home6, "~");
108508
+ if (normalized.startsWith(`${home5}/`)) {
108509
+ return normalized.replace(home5, "~");
108261
108510
  }
108262
108511
  return normalized;
108263
108512
  }
@@ -108266,7 +108515,7 @@ function formatCdHint(value, currentPlatform = platform16()) {
108266
108515
  const absolutePath2 = win322.resolve(value);
108267
108516
  return `cd /d "${absolutePath2}"`;
108268
108517
  }
108269
- const absolutePath = resolve48(value);
108518
+ const absolutePath = resolve49(value);
108270
108519
  const displayPath = formatDisplayPath(absolutePath);
108271
108520
  if (displayPath.includes(" ")) {
108272
108521
  return `cd "${displayPath}"`;
@@ -108567,13 +108816,13 @@ init_logger();
108567
108816
  init_dist2();
108568
108817
  init_model_taxonomy();
108569
108818
  import { mkdir as mkdir39, readFile as readFile64, writeFile as writeFile37 } from "node:fs/promises";
108570
- import { homedir as homedir51 } from "node:os";
108571
- import { dirname as dirname41, join as join142 } from "node:path";
108819
+ import { homedir as homedir52 } from "node:os";
108820
+ import { dirname as dirname42, join as join142 } from "node:path";
108572
108821
 
108573
108822
  // src/commands/portable/models-dev-cache.ts
108574
108823
  init_logger();
108575
108824
  import { mkdir as mkdir38, readFile as readFile62, rename as rename14, writeFile as writeFile36 } from "node:fs/promises";
108576
- import { homedir as homedir49 } from "node:os";
108825
+ import { homedir as homedir50 } from "node:os";
108577
108826
  import { join as join140 } from "node:path";
108578
108827
 
108579
108828
  class ModelsDevUnavailableError extends Error {
@@ -108586,7 +108835,7 @@ var MODELS_DEV_URL = "https://models.dev/api.json";
108586
108835
  var CACHE_TTL_MS3 = 24 * 60 * 60 * 1000;
108587
108836
  var FETCH_TIMEOUT_MS = 1e4;
108588
108837
  function defaultCacheDir() {
108589
- return join140(homedir49(), ".config", "claudekit", "cache");
108838
+ return join140(homedir50(), ".config", "claudekit", "cache");
108590
108839
  }
108591
108840
  function cacheFilePath(cacheDir) {
108592
108841
  return join140(cacheDir, "models-dev.json");
@@ -108666,7 +108915,7 @@ async function getModelsDevCatalog(opts = {}) {
108666
108915
  // src/commands/portable/opencode-model-discovery.ts
108667
108916
  init_logger();
108668
108917
  import { readFile as readFile63 } from "node:fs/promises";
108669
- import { homedir as homedir50, platform as platform17 } from "node:os";
108918
+ import { homedir as homedir51, platform as platform17 } from "node:os";
108670
108919
  import { join as join141 } from "node:path";
108671
108920
  function resolveOpenCodeAuthPath(homeDir) {
108672
108921
  if (platform17() === "win32") {
@@ -108712,8 +108961,8 @@ function pickGenericModel(models) {
108712
108961
  return sorted[0] ?? null;
108713
108962
  }
108714
108963
  async function resolveOpenCodeDefaultModel(opts = {}) {
108715
- const home6 = opts.homeDir ?? homedir50();
108716
- const authedProviders = await readAuthedProviders(home6);
108964
+ const home5 = opts.homeDir ?? homedir51();
108965
+ const authedProviders = await readAuthedProviders(home5);
108717
108966
  if (authedProviders.length === 0) {
108718
108967
  return { ok: false, reason: "no-auth", authedProviders: [] };
108719
108968
  }
@@ -108776,7 +109025,7 @@ function messageForReason(reason) {
108776
109025
  }
108777
109026
  function getOpenCodeConfigPath(options2) {
108778
109027
  if (options2.global) {
108779
- return join142(options2.homeDir ?? homedir51(), ".config", "opencode", "opencode.json");
109028
+ return join142(options2.homeDir ?? homedir52(), ".config", "opencode", "opencode.json");
108780
109029
  }
108781
109030
  return join142(options2.cwd ?? process.cwd(), "opencode.json");
108782
109031
  }
@@ -108921,7 +109170,7 @@ async function ensureOpenCodeModel(options2) {
108921
109170
  }
108922
109171
  const chosenModel2 = response2.action === "custom" ? response2.value : suggestion2.model;
108923
109172
  const next2 = { ...existing, model: chosenModel2 };
108924
- await mkdir39(dirname41(configPath), { recursive: true });
109173
+ await mkdir39(dirname42(configPath), { recursive: true });
108925
109174
  await writeFile37(configPath, `${JSON.stringify(next2, null, 2)}
108926
109175
  `, "utf-8");
108927
109176
  return { path: configPath, action: "added", model: chosenModel2, reason: suggestion2.reason };
@@ -108932,7 +109181,7 @@ async function ensureOpenCodeModel(options2) {
108932
109181
  throw new OpenCodeAuthRequiredError(suggestion.failure);
108933
109182
  }
108934
109183
  const next2 = { ...existing ?? {}, model: suggestion.model };
108935
- await mkdir39(dirname41(configPath), { recursive: true });
109184
+ await mkdir39(dirname42(configPath), { recursive: true });
108936
109185
  await writeFile37(configPath, `${JSON.stringify(next2, null, 2)}
108937
109186
  `, "utf-8");
108938
109187
  return {
@@ -108954,7 +109203,7 @@ async function ensureOpenCodeModel(options2) {
108954
109203
  }
108955
109204
  const chosenModel = response.action === "custom" ? response.value : suggestion.ok ? suggestion.model : "";
108956
109205
  const next = { ...existing ?? {}, model: chosenModel };
108957
- await mkdir39(dirname41(configPath), { recursive: true });
109206
+ await mkdir39(dirname42(configPath), { recursive: true });
108958
109207
  await writeFile37(configPath, `${JSON.stringify(next, null, 2)}
108959
109208
  `, "utf-8");
108960
109209
  return {
@@ -108967,7 +109216,7 @@ async function ensureOpenCodeModel(options2) {
108967
109216
 
108968
109217
  // src/commands/portable/plan-display.ts
108969
109218
  var import_picocolors28 = __toESM(require_picocolors(), 1);
108970
- import { basename as basename28, dirname as dirname42, extname as extname7 } from "node:path";
109219
+ import { basename as basename29, dirname as dirname43, extname as extname7 } from "node:path";
108971
109220
  var DEFAULT_MAX_PLAN_GROUP_ITEMS = 20;
108972
109221
  var TYPE_ORDER = [
108973
109222
  "agent",
@@ -109193,21 +109442,21 @@ function collectPlannedWhereLines(plan) {
109193
109442
  return destinations.map((destination) => `${formatDisplayPath(destination)} -> ${formatCdHint(resolveCdTarget(destination))}`);
109194
109443
  }
109195
109444
  function resolveCdTarget(destination) {
109196
- return extname7(destination).length > 0 ? dirname42(destination) : destination;
109445
+ return extname7(destination).length > 0 ? dirname43(destination) : destination;
109197
109446
  }
109198
109447
  function normalizeWhereDestination(path16, portableType) {
109199
109448
  if (portableType === "agent" || portableType === "command" || portableType === "skill") {
109200
- return dirname42(path16);
109449
+ return dirname43(path16);
109201
109450
  }
109202
109451
  if (portableType === "hooks") {
109203
- return dirname42(path16);
109452
+ return dirname43(path16);
109204
109453
  }
109205
109454
  if (portableType === "rules") {
109206
- const fileName = basename28(path16).toLowerCase();
109455
+ const fileName = basename29(path16).toLowerCase();
109207
109456
  if (fileName === "agents.md" || fileName === "gemini.md" || fileName === ".goosehints" || fileName === "custom_modes.yaml" || fileName === "custom_modes.yml") {
109208
109457
  return path16;
109209
109458
  }
109210
- return dirname42(path16);
109459
+ return dirname43(path16);
109211
109460
  }
109212
109461
  return path16;
109213
109462
  }
@@ -109728,9 +109977,9 @@ function shouldExecuteAction2(action) {
109728
109977
  }
109729
109978
  async function executeDeleteAction(action, options2) {
109730
109979
  const preservePaths = options2?.preservePaths ?? new Set;
109731
- const shouldPreserveTarget = action.targetPath.length > 0 && preservePaths.has(resolve49(action.targetPath));
109980
+ const shouldPreserveTarget = action.targetPath.length > 0 && preservePaths.has(resolve50(action.targetPath));
109732
109981
  try {
109733
- if (!shouldPreserveTarget && action.targetPath && existsSync66(action.targetPath)) {
109982
+ if (!shouldPreserveTarget && action.targetPath && existsSync67(action.targetPath)) {
109734
109983
  await rm18(action.targetPath, { recursive: true, force: true });
109735
109984
  }
109736
109985
  await removePortableInstallation(action.item, action.type, action.provider, action.global, action.targetPath ? { path: action.targetPath } : undefined);
@@ -109761,8 +110010,8 @@ async function executeDeleteAction(action, options2) {
109761
110010
  async function processMetadataDeletions(skillSourcePath, installGlobally) {
109762
110011
  if (!skillSourcePath)
109763
110012
  return;
109764
- const sourceMetadataPath = join143(resolve49(skillSourcePath, ".."), "metadata.json");
109765
- if (!existsSync66(sourceMetadataPath))
110013
+ const sourceMetadataPath = join143(resolve50(skillSourcePath, ".."), "metadata.json");
110014
+ if (!existsSync67(sourceMetadataPath))
109766
110015
  return;
109767
110016
  let sourceMetadata;
109768
110017
  try {
@@ -109774,8 +110023,8 @@ async function processMetadataDeletions(skillSourcePath, installGlobally) {
109774
110023
  }
109775
110024
  if (!sourceMetadata.deletions || sourceMetadata.deletions.length === 0)
109776
110025
  return;
109777
- const claudeDir3 = installGlobally ? join143(homedir52(), ".claude") : join143(process.cwd(), ".claude");
109778
- if (!existsSync66(claudeDir3))
110026
+ const claudeDir3 = installGlobally ? join143(homedir53(), ".claude") : join143(process.cwd(), ".claude");
110027
+ if (!existsSync67(claudeDir3))
109779
110028
  return;
109780
110029
  try {
109781
110030
  const result = await handleDeletions(sourceMetadata, claudeDir3, inferKitTypeFromSourceMetadata(sourceMetadata));
@@ -109903,7 +110152,7 @@ async function migrateCommand(options2) {
109903
110152
  let installGlobally = requestedGlobal;
109904
110153
  if (options2.global === undefined && !options2.yes) {
109905
110154
  const projectTarget = join143(process.cwd(), ".claude");
109906
- const globalTarget = join143(homedir52(), ".claude");
110155
+ const globalTarget = join143(homedir53(), ".claude");
109907
110156
  const scopeChoice = await ie({
109908
110157
  message: "Installation scope",
109909
110158
  options: [
@@ -109976,7 +110225,7 @@ async function migrateCommand(options2) {
109976
110225
  }).join(`
109977
110226
  `));
109978
110227
  if (sourceGlobalOnly) {
109979
- f2.info(import_picocolors30.default.dim(` Scope: global (--global / -g) - reading from ${formatDisplayPath(join143(homedir52(), ".claude"))}`));
110228
+ f2.info(import_picocolors30.default.dim(` Scope: global (--global / -g) - reading from ${formatDisplayPath(join143(homedir53(), ".claude"))}`));
109980
110229
  } else {
109981
110230
  f2.info(import_picocolors30.default.dim(` CWD: ${process.cwd()}`));
109982
110231
  }
@@ -110067,7 +110316,7 @@ async function migrateCommand(options2) {
110067
110316
  const interactive = process.stdout.isTTY && !options2.yes;
110068
110317
  const conflictActions = plan.actions.filter((a3) => a3.action === "conflict");
110069
110318
  for (const action of conflictActions) {
110070
- if (!action.diff && action.targetPath && existsSync66(action.targetPath)) {
110319
+ if (!action.diff && action.targetPath && existsSync67(action.targetPath)) {
110071
110320
  try {
110072
110321
  const targetContent = await readFile65(action.targetPath, "utf-8");
110073
110322
  const sourceItem = effectiveAgents.find((a3) => a3.name === action.item) || effectiveCommands.find((c2) => c2.name === action.item) || (effectiveConfigItem?.name === action.item ? effectiveConfigItem : null) || effectiveRuleItems.find((r2) => r2.name === action.item) || effectiveHookItems.find((h2) => h2.name === action.item);
@@ -110182,18 +110431,18 @@ async function migrateCommand(options2) {
110182
110431
  const recordSuccessfulWrites = (task, taskResults) => {
110183
110432
  for (const result of taskResults.filter((entry) => entry.success && !entry.skipped)) {
110184
110433
  if (result.path.length > 0) {
110185
- writtenPaths.add(resolve49(result.path));
110434
+ writtenPaths.add(resolve50(result.path));
110186
110435
  }
110187
110436
  if (task.type === "hooks") {
110188
110437
  const existing = successfulHookFiles.get(task.provider) ?? {
110189
110438
  files: [],
110190
110439
  global: task.global
110191
110440
  };
110192
- existing.files.push(basename29(result.path));
110441
+ existing.files.push(basename30(result.path));
110193
110442
  successfulHookFiles.set(task.provider, existing);
110194
110443
  if (result.path.length > 0) {
110195
110444
  const absExisting = successfulHookAbsPaths.get(task.provider) ?? [];
110196
- absExisting.push(resolve49(result.path));
110445
+ absExisting.push(resolve50(result.path));
110197
110446
  successfulHookAbsPaths.set(task.provider, absExisting);
110198
110447
  }
110199
110448
  }
@@ -110327,7 +110576,7 @@ async function migrateCommand(options2) {
110327
110576
  });
110328
110577
  if (staleSlugs.length > 0) {
110329
110578
  const staleSlugSet = new Set(staleSlugs.map((s) => `${s}.toml`));
110330
- const removed = await removeInstallationsByFilter((i) => i.type === "agent" && i.provider === provider && i.global === scope2 && staleSlugSet.has(basename29(i.path)));
110579
+ const removed = await removeInstallationsByFilter((i) => i.type === "agent" && i.provider === provider && i.global === scope2 && staleSlugSet.has(basename30(i.path)));
110331
110580
  for (const entry of removed) {
110332
110581
  logger.verbose(`[migrate] Cleaned stale registry entry: ${entry.item} (${provider})`);
110333
110582
  }
@@ -110335,7 +110584,7 @@ async function migrateCommand(options2) {
110335
110584
  }
110336
110585
  }
110337
110586
  try {
110338
- const kitRoot = (agentSource ? resolve49(agentSource, "..") : null) ?? (commandSource ? resolve49(commandSource, "..") : null) ?? (skillSource ? resolve49(skillSource, "..") : null) ?? null;
110587
+ const kitRoot = (agentSource ? resolve50(agentSource, "..") : null) ?? (commandSource ? resolve50(commandSource, "..") : null) ?? (skillSource ? resolve50(skillSource, "..") : null) ?? null;
110339
110588
  const manifest = kitRoot ? await loadPortableManifest(kitRoot) : null;
110340
110589
  if (manifest?.cliVersion) {
110341
110590
  await updateAppliedManifestVersion(manifest.cliVersion);
@@ -110383,7 +110632,7 @@ async function migrateCommand(options2) {
110383
110632
  async function rollbackResults(results) {
110384
110633
  const rolledBackPaths = new Set;
110385
110634
  for (const result of results) {
110386
- if (!result.path || !existsSync66(result.path))
110635
+ if (!result.path || !existsSync67(result.path))
110387
110636
  continue;
110388
110637
  try {
110389
110638
  if (result.overwritten)
@@ -110532,7 +110781,7 @@ var import_picocolors31 = __toESM(require_picocolors(), 1);
110532
110781
 
110533
110782
  // src/commands/new/phases/directory-setup.ts
110534
110783
  init_config_manager();
110535
- import { resolve as resolve50 } from "node:path";
110784
+ import { resolve as resolve51 } from "node:path";
110536
110785
  init_logger();
110537
110786
  init_path_resolver();
110538
110787
  init_types3();
@@ -110617,7 +110866,7 @@ async function directorySetup(validOptions, prompts) {
110617
110866
  targetDir = await prompts.getDirectory(targetDir);
110618
110867
  }
110619
110868
  }
110620
- const resolvedDir = resolve50(targetDir);
110869
+ const resolvedDir = resolve51(targetDir);
110621
110870
  logger.info(`Target directory: ${resolvedDir}`);
110622
110871
  if (PathResolver.isLocalSameAsGlobal(resolvedDir)) {
110623
110872
  logger.warning("You're creating a project at HOME directory.");
@@ -110950,8 +111199,8 @@ Please use only one download method.`);
110950
111199
  }
110951
111200
  // src/commands/plan/plan-command.ts
110952
111201
  init_output_manager();
110953
- import { existsSync as existsSync69, statSync as statSync12 } from "node:fs";
110954
- import { dirname as dirname46, isAbsolute as isAbsolute13, join as join148, parse as parse7, resolve as resolve54 } from "node:path";
111202
+ import { existsSync as existsSync70, statSync as statSync12 } from "node:fs";
111203
+ import { dirname as dirname47, isAbsolute as isAbsolute14, join as join148, parse as parse7, resolve as resolve55 } from "node:path";
110955
111204
 
110956
111205
  // src/commands/plan/plan-read-handlers.ts
110957
111206
  init_config();
@@ -110960,19 +111209,19 @@ init_plans_registry();
110960
111209
  init_logger();
110961
111210
  init_output_manager();
110962
111211
  var import_picocolors32 = __toESM(require_picocolors(), 1);
110963
- import { existsSync as existsSync68, statSync as statSync11 } from "node:fs";
110964
- import { basename as basename30, dirname as dirname44, join as join147, relative as relative31, resolve as resolve52 } from "node:path";
111212
+ import { existsSync as existsSync69, statSync as statSync11 } from "node:fs";
111213
+ import { basename as basename31, dirname as dirname45, join as join147, relative as relative31, resolve as resolve53 } from "node:path";
110965
111214
 
110966
111215
  // src/commands/plan/plan-dependencies.ts
110967
111216
  init_config();
110968
111217
  init_plan_parser();
110969
111218
  init_plans_registry();
110970
- import { existsSync as existsSync67 } from "node:fs";
110971
- import { dirname as dirname43, join as join146 } from "node:path";
111219
+ import { existsSync as existsSync68 } from "node:fs";
111220
+ import { dirname as dirname44, join as join146 } from "node:path";
110972
111221
  async function resolvePlanDependencies(references, currentPlanFile, options2 = {}) {
110973
111222
  if (references.length === 0)
110974
111223
  return [];
110975
- const currentPlanDir = dirname43(currentPlanFile);
111224
+ const currentPlanDir = dirname44(currentPlanFile);
110976
111225
  const projectRoot = findProjectRoot(currentPlanDir);
110977
111226
  const config = options2.preloadedConfig ?? (await CkConfigManager.loadFull(projectRoot)).config;
110978
111227
  const defaultScope = inferPlanScopeForDir(currentPlanDir, config);
@@ -110990,7 +111239,7 @@ async function resolvePlanDependencies(references, currentPlanFile, options2 = {
110990
111239
  const scopeRoot = resolvePlanDirForScope(scope, projectRoot, config);
110991
111240
  const planFile = join146(scopeRoot, planId, "plan.md");
110992
111241
  const isSelfReference = planFile === currentPlanFile;
110993
- if (!existsSync67(planFile)) {
111242
+ if (!existsSync68(planFile)) {
110994
111243
  return {
110995
111244
  reference,
110996
111245
  scope,
@@ -111019,14 +111268,14 @@ init_config();
111019
111268
  init_plan_parser();
111020
111269
  init_plan_scope();
111021
111270
  init_plans_registry();
111022
- import { isAbsolute as isAbsolute12, resolve as resolve51 } from "node:path";
111271
+ import { isAbsolute as isAbsolute13, resolve as resolve52 } from "node:path";
111023
111272
  async function getGlobalPlansDirFromCwd() {
111024
111273
  const projectRoot = findProjectRoot(process.cwd());
111025
111274
  const { config } = await CkConfigManager.loadFull(projectRoot);
111026
111275
  return resolveGlobalPlansDir(config);
111027
111276
  }
111028
111277
  function resolveTargetFromBase(target, baseDir) {
111029
- const resolvedTarget = isAbsolute12(target) ? resolve51(target) : resolve51(baseDir, target);
111278
+ const resolvedTarget = isAbsolute13(target) ? resolve52(target) : resolve52(baseDir, target);
111030
111279
  return isWithinDir(resolvedTarget, baseDir) ? resolvedTarget : null;
111031
111280
  }
111032
111281
 
@@ -111059,7 +111308,7 @@ async function handleParse(target, options2) {
111059
111308
  console.log(JSON.stringify({ file: relative31(process.cwd(), planFile), frontmatter, phases }, null, 2));
111060
111309
  return;
111061
111310
  }
111062
- const title = typeof frontmatter.title === "string" ? frontmatter.title : basename30(dirname44(planFile));
111311
+ const title = typeof frontmatter.title === "string" ? frontmatter.title : basename31(dirname45(planFile));
111063
111312
  console.log();
111064
111313
  console.log(import_picocolors32.default.bold(` Plan: ${title}`));
111065
111314
  console.log(` File: ${planFile}`);
@@ -111129,8 +111378,8 @@ async function handleStatus(target, options2) {
111129
111378
  return;
111130
111379
  }
111131
111380
  const effectiveTarget = !resolvedTarget && globalBaseDir ? globalBaseDir : resolvedTarget;
111132
- const t = effectiveTarget ? resolve52(effectiveTarget) : null;
111133
- const plansDir = t && existsSync68(t) && statSync11(t).isDirectory() && !existsSync68(join147(t, "plan.md")) ? t : null;
111381
+ const t = effectiveTarget ? resolve53(effectiveTarget) : null;
111382
+ const plansDir = t && existsSync69(t) && statSync11(t).isDirectory() && !existsSync69(join147(t, "plan.md")) ? t : null;
111134
111383
  if (plansDir) {
111135
111384
  const planFiles = scanPlanDir(plansDir);
111136
111385
  if (planFiles.length === 0) {
@@ -111170,7 +111419,7 @@ async function handleStatus(target, options2) {
111170
111419
  const blockedBy2 = await resolvePlanDependencies(s.blockedBy, pf, { preloadedConfig });
111171
111420
  const blocks2 = await resolvePlanDependencies(s.blocks, pf, { preloadedConfig });
111172
111421
  const bar = progressBar(s.completed, s.totalPhases);
111173
- const title2 = s.title ?? basename30(dirname44(pf));
111422
+ const title2 = s.title ?? basename31(dirname45(pf));
111174
111423
  console.log(` ${import_picocolors32.default.bold(title2)}`);
111175
111424
  console.log(` ${bar}`);
111176
111425
  if (s.inProgress > 0)
@@ -111189,7 +111438,7 @@ async function handleStatus(target, options2) {
111189
111438
  }
111190
111439
  console.log();
111191
111440
  } catch {
111192
- console.log(` [X] Failed to read: ${basename30(dirname44(pf))}`);
111441
+ console.log(` [X] Failed to read: ${basename31(dirname45(pf))}`);
111193
111442
  console.log();
111194
111443
  }
111195
111444
  }
@@ -111216,7 +111465,7 @@ async function handleStatus(target, options2) {
111216
111465
  console.log(JSON.stringify({ ...summary, dependencyStatus: { blockedBy, blocks } }, null, 2));
111217
111466
  return;
111218
111467
  }
111219
- const title = summary.title ?? basename30(dirname44(planFile));
111468
+ const title = summary.title ?? basename31(dirname45(planFile));
111220
111469
  console.log();
111221
111470
  console.log(import_picocolors32.default.bold(` ${title}`));
111222
111471
  if (summary.status)
@@ -111279,7 +111528,7 @@ async function handleKanban(target, options2) {
111279
111528
  process.exitCode = 1;
111280
111529
  return;
111281
111530
  }
111282
- const route = `/plans?dir=${encodeURIComponent(dirname44(dirname44(planFile)))}&view=kanban`;
111531
+ const route = `/plans?dir=${encodeURIComponent(dirname45(dirname45(planFile)))}&view=kanban`;
111283
111532
  const url = `http://localhost:${server.port}${route}`;
111284
111533
  console.log();
111285
111534
  console.log(import_picocolors32.default.bold(" ClaudeKit Dashboard — Plans"));
@@ -111314,7 +111563,18 @@ init_plan_parser();
111314
111563
  init_plans_registry();
111315
111564
  init_output_manager();
111316
111565
  var import_picocolors33 = __toESM(require_picocolors(), 1);
111317
- import { basename as basename31, dirname as dirname45, relative as relative32, resolve as resolve53 } from "node:path";
111566
+ import { basename as basename32, dirname as dirname46, relative as relative32, resolve as resolve54 } from "node:path";
111567
+ function quoteReadTarget(filePath) {
111568
+ return `"${filePath.replace(/\\/g, "/").replace(/"/g, "\\\"")}"`;
111569
+ }
111570
+ function buildPlanCreateReadReminder(planFile, phaseFiles, cwd2 = process.cwd()) {
111571
+ const files = [planFile, ...phaseFiles].map((file) => quoteReadTarget(relative32(cwd2, file)));
111572
+ return [
111573
+ " [i] Claude Code agents: read plan.md and every phase-*.md before editing.",
111574
+ " These files already exist; Write/Edit without Read may be rejected after wasting tokens.",
111575
+ ` cat ${files.join(" ")}`
111576
+ ];
111577
+ }
111318
111578
  async function handleCreate(target, options2) {
111319
111579
  if (!options2.title) {
111320
111580
  output.error("[X] --title is required for create");
@@ -111346,13 +111606,13 @@ async function handleCreate(target, options2) {
111346
111606
  return;
111347
111607
  }
111348
111608
  const globalBaseDir = options2.global ? await getGlobalPlansDirFromCwd() : undefined;
111349
- const resolvedDir = globalBaseDir ? resolveTargetFromBase(dir, globalBaseDir) : resolve53(dir);
111609
+ const resolvedDir = globalBaseDir ? resolveTargetFromBase(dir, globalBaseDir) : resolve54(dir);
111350
111610
  if (globalBaseDir && !resolvedDir) {
111351
111611
  output.error("[X] Target directory must stay within the configured global plans root");
111352
111612
  process.exitCode = 1;
111353
111613
  return;
111354
111614
  }
111355
- const safeResolvedDir = resolvedDir ?? resolve53(dir);
111615
+ const safeResolvedDir = resolvedDir ?? resolve54(dir);
111356
111616
  const result = scaffoldPlan({
111357
111617
  title: options2.title,
111358
111618
  phases: phaseNames.map((name2) => ({ name: name2 })),
@@ -111390,7 +111650,10 @@ async function handleCreate(target, options2) {
111390
111650
  console.log(` Directory: ${safeResolvedDir}`);
111391
111651
  console.log(` Phases: ${result.phaseFiles.length}`);
111392
111652
  for (const f3 of result.phaseFiles) {
111393
- console.log(` [ ] ${basename31(f3)}`);
111653
+ console.log(` [ ] ${basename32(f3)}`);
111654
+ }
111655
+ for (const line of buildPlanCreateReadReminder(result.planFile, result.phaseFiles)) {
111656
+ console.log(line);
111394
111657
  }
111395
111658
  console.log();
111396
111659
  }
@@ -111414,7 +111677,7 @@ async function handleCheck(target, options2) {
111414
111677
  process.exitCode = 1;
111415
111678
  return;
111416
111679
  }
111417
- const planDir = dirname45(planFile);
111680
+ const planDir = dirname46(planFile);
111418
111681
  let planStatus = "pending";
111419
111682
  try {
111420
111683
  const projectRoot = findProjectRoot(planDir);
@@ -111463,7 +111726,7 @@ async function handleUncheck(target, options2) {
111463
111726
  process.exitCode = 1;
111464
111727
  return;
111465
111728
  }
111466
- const planDir = dirname45(planFile);
111729
+ const planDir = dirname46(planFile);
111467
111730
  try {
111468
111731
  const projectRoot = findProjectRoot(planDir);
111469
111732
  const summary = buildPlanSummary(planFile);
@@ -111502,7 +111765,7 @@ async function handleAddPhase(target, options2) {
111502
111765
  try {
111503
111766
  const result = addPhase(planFile, target, options2.after);
111504
111767
  try {
111505
- const planDir = dirname45(planFile);
111768
+ const planDir = dirname46(planFile);
111506
111769
  const projectRoot = findProjectRoot(planDir);
111507
111770
  updateRegistryAddPhase({
111508
111771
  planDir,
@@ -111528,25 +111791,25 @@ async function handleAddPhase(target, options2) {
111528
111791
  // src/commands/plan/plan-command.ts
111529
111792
  function resolveTargetPath(target, baseDir) {
111530
111793
  if (!baseDir) {
111531
- return resolve54(target);
111794
+ return resolve55(target);
111532
111795
  }
111533
- if (isAbsolute13(target)) {
111534
- return resolve54(target);
111796
+ if (isAbsolute14(target)) {
111797
+ return resolve55(target);
111535
111798
  }
111536
- const cwdCandidate = resolve54(target);
111537
- if (existsSync69(cwdCandidate)) {
111799
+ const cwdCandidate = resolve55(target);
111800
+ if (existsSync70(cwdCandidate)) {
111538
111801
  return cwdCandidate;
111539
111802
  }
111540
- return resolve54(baseDir, target);
111803
+ return resolve55(baseDir, target);
111541
111804
  }
111542
111805
  function resolvePlanFile(target, baseDir) {
111543
- const t = target ? resolveTargetPath(target, baseDir) : baseDir ? resolve54(baseDir) : process.cwd();
111544
- if (existsSync69(t)) {
111806
+ const t = target ? resolveTargetPath(target, baseDir) : baseDir ? resolve55(baseDir) : process.cwd();
111807
+ if (existsSync70(t)) {
111545
111808
  const stat24 = statSync12(t);
111546
111809
  if (stat24.isFile())
111547
111810
  return t;
111548
111811
  const candidate = join148(t, "plan.md");
111549
- if (existsSync69(candidate))
111812
+ if (existsSync70(candidate))
111550
111813
  return candidate;
111551
111814
  }
111552
111815
  if (!target && !baseDir) {
@@ -111554,9 +111817,9 @@ function resolvePlanFile(target, baseDir) {
111554
111817
  const root = parse7(dir).root;
111555
111818
  while (dir !== root) {
111556
111819
  const candidate = join148(dir, "plan.md");
111557
- if (existsSync69(candidate))
111820
+ if (existsSync70(candidate))
111558
111821
  return candidate;
111559
- dir = dirname46(dir);
111822
+ dir = dirname47(dir);
111560
111823
  }
111561
111824
  }
111562
111825
  return null;
@@ -111604,7 +111867,7 @@ async function planCommand(action, target, options2) {
111604
111867
  let resolvedTarget = target;
111605
111868
  if (resolvedAction && !knownActions.has(resolvedAction)) {
111606
111869
  const looksLikePath = resolvedAction.includes("/") || resolvedAction.includes("\\") || resolvedAction.endsWith(".md") || resolvedAction === "." || resolvedAction === "..";
111607
- const existsOnDisk = !looksLikePath && existsSync69(resolve54(resolvedAction));
111870
+ const existsOnDisk = !looksLikePath && existsSync70(resolve55(resolvedAction));
111608
111871
  if (looksLikePath || existsOnDisk) {
111609
111872
  resolvedTarget = resolvedAction;
111610
111873
  resolvedAction = undefined;
@@ -111646,13 +111909,13 @@ init_claudekit_data2();
111646
111909
  init_logger();
111647
111910
  init_safe_prompts();
111648
111911
  var import_picocolors34 = __toESM(require_picocolors(), 1);
111649
- import { existsSync as existsSync70 } from "node:fs";
111650
- import { resolve as resolve55 } from "node:path";
111912
+ import { existsSync as existsSync71 } from "node:fs";
111913
+ import { resolve as resolve56 } from "node:path";
111651
111914
  async function handleAdd(projectPath, options2) {
111652
111915
  logger.debug(`Adding project: ${projectPath}, options: ${JSON.stringify(options2)}`);
111653
111916
  intro("Add Project");
111654
- const absolutePath = resolve55(projectPath);
111655
- if (!existsSync70(absolutePath)) {
111917
+ const absolutePath = resolve56(projectPath);
111918
+ if (!existsSync71(absolutePath)) {
111656
111919
  log.error(`Path does not exist: ${absolutePath}`);
111657
111920
  process.exitCode = 1;
111658
111921
  return;
@@ -112075,7 +112338,7 @@ import { readFile as readFile66 } from "node:fs/promises";
112075
112338
  import { join as join150 } from "node:path";
112076
112339
 
112077
112340
  // src/commands/skills/installed-skills-inventory.ts
112078
- import { join as join149, resolve as resolve56 } from "node:path";
112341
+ import { join as join149, resolve as resolve57 } from "node:path";
112079
112342
  init_path_resolver();
112080
112343
  var SCOPE_SORT_ORDER = {
112081
112344
  project: 0,
@@ -112083,8 +112346,8 @@ var SCOPE_SORT_ORDER = {
112083
112346
  };
112084
112347
  async function getActiveClaudeSkillInstallations(options2 = {}) {
112085
112348
  const projectDir = options2.projectDir ?? process.cwd();
112086
- const globalDir = resolve56(options2.globalDir ?? PathResolver.getGlobalKitDir());
112087
- const projectClaudeDir = resolve56(projectDir, ".claude");
112349
+ const globalDir = resolve57(options2.globalDir ?? PathResolver.getGlobalKitDir());
112350
+ const projectClaudeDir = resolve57(projectDir, ".claude");
112088
112351
  const projectScopeAliasesGlobal = projectClaudeDir === globalDir;
112089
112352
  const [projectSkills, globalSkills] = await Promise.all([
112090
112353
  projectScopeAliasesGlobal ? Promise.resolve([]) : scanSkills2(join149(projectClaudeDir, "skills")),
@@ -112830,8 +113093,8 @@ async function detectInstallations() {
112830
113093
  }
112831
113094
 
112832
113095
  // src/commands/uninstall/removal-handler.ts
112833
- import { readdirSync as readdirSync10, rmSync as rmSync5 } from "node:fs";
112834
- import { basename as basename32, join as join152, resolve as resolve57, sep as sep13 } from "node:path";
113096
+ import { readdirSync as readdirSync11, rmSync as rmSync5 } from "node:fs";
113097
+ import { basename as basename33, join as join152, resolve as resolve58, sep as sep14 } from "node:path";
112835
113098
  init_logger();
112836
113099
  init_safe_prompts();
112837
113100
  init_safe_spinner();
@@ -112839,8 +113102,8 @@ var import_fs_extra42 = __toESM(require_lib(), 1);
112839
113102
 
112840
113103
  // src/commands/uninstall/analysis-handler.ts
112841
113104
  init_metadata_migration();
112842
- import { readdirSync as readdirSync9, rmSync as rmSync4 } from "node:fs";
112843
- import { dirname as dirname47, join as join151 } from "node:path";
113105
+ import { readdirSync as readdirSync10, rmSync as rmSync4 } from "node:fs";
113106
+ import { dirname as dirname48, join as join151 } from "node:path";
112844
113107
  init_logger();
112845
113108
  init_safe_prompts();
112846
113109
  var import_fs_extra41 = __toESM(require_lib(), 1);
@@ -112862,15 +113125,15 @@ function classifyFileByOwnership(ownership, forceOverwrite, deleteReason) {
112862
113125
  }
112863
113126
  async function cleanupEmptyDirectories3(filePath, installationRoot) {
112864
113127
  let cleaned = 0;
112865
- let currentDir = dirname47(filePath);
113128
+ let currentDir = dirname48(filePath);
112866
113129
  while (currentDir !== installationRoot && currentDir.startsWith(installationRoot)) {
112867
113130
  try {
112868
- const entries = readdirSync9(currentDir);
113131
+ const entries = readdirSync10(currentDir);
112869
113132
  if (entries.length === 0) {
112870
113133
  rmSync4(currentDir, { recursive: true });
112871
113134
  cleaned++;
112872
113135
  logger.debug(`Removed empty directory: ${currentDir}`);
112873
- currentDir = dirname47(currentDir);
113136
+ currentDir = dirname48(currentDir);
112874
113137
  } else {
112875
113138
  break;
112876
113139
  }
@@ -113015,17 +113278,17 @@ async function restoreUninstallBackup(backup) {
113015
113278
  }
113016
113279
  async function isPathSafeToRemove(filePath, baseDir) {
113017
113280
  try {
113018
- const resolvedPath = resolve57(filePath);
113019
- const resolvedBase = resolve57(baseDir);
113020
- if (!resolvedPath.startsWith(resolvedBase + sep13) && resolvedPath !== resolvedBase) {
113281
+ const resolvedPath = resolve58(filePath);
113282
+ const resolvedBase = resolve58(baseDir);
113283
+ if (!resolvedPath.startsWith(resolvedBase + sep14) && resolvedPath !== resolvedBase) {
113021
113284
  logger.debug(`Path outside installation directory: ${filePath}`);
113022
113285
  return false;
113023
113286
  }
113024
113287
  const stats = await import_fs_extra42.lstat(filePath);
113025
113288
  if (stats.isSymbolicLink()) {
113026
113289
  const realPath = await import_fs_extra42.realpath(filePath);
113027
- const resolvedReal = resolve57(realPath);
113028
- if (!resolvedReal.startsWith(resolvedBase + sep13) && resolvedReal !== resolvedBase) {
113290
+ const resolvedReal = resolve58(realPath);
113291
+ if (!resolvedReal.startsWith(resolvedBase + sep14) && resolvedReal !== resolvedBase) {
113029
113292
  logger.debug(`Symlink points outside installation directory: ${filePath} -> ${realPath}`);
113030
113293
  return false;
113031
113294
  }
@@ -113070,7 +113333,7 @@ async function removeInstallations(installations, options2) {
113070
113333
  scope: installation.type,
113071
113334
  kit: options2.kit
113072
113335
  });
113073
- await cleanupOldDestructiveOperationBackups(undefined, basename32(backup.backupDir));
113336
+ await cleanupOldDestructiveOperationBackups(undefined, basename33(backup.backupDir));
113074
113337
  backupSpinner.succeed(`Recovery backup saved to ${backup.backupDir}`);
113075
113338
  } catch (error) {
113076
113339
  backupSpinner.fail("Failed to create recovery backup");
@@ -113109,7 +113372,7 @@ async function removeInstallations(installations, options2) {
113109
113372
  }
113110
113373
  }
113111
113374
  try {
113112
- const remaining = readdirSync10(installation.path);
113375
+ const remaining = readdirSync11(installation.path);
113113
113376
  if (remaining.length === 0) {
113114
113377
  rmSync5(installation.path, { recursive: true });
113115
113378
  logger.debug(`Removed empty installation directory: ${installation.path}`);
@@ -113491,7 +113754,7 @@ ${import_picocolors40.default.bold(import_picocolors40.default.cyan(result.kitCo
113491
113754
 
113492
113755
  // src/commands/watch/watch-command.ts
113493
113756
  init_logger();
113494
- import { existsSync as existsSync76 } from "node:fs";
113757
+ import { existsSync as existsSync77 } from "node:fs";
113495
113758
  import { rm as rm19 } from "node:fs/promises";
113496
113759
  import { join as join159 } from "node:path";
113497
113760
  var import_picocolors41 = __toESM(require_picocolors(), 1);
@@ -114790,14 +115053,14 @@ function cleanExpiredIssues(state, ttlDays) {
114790
115053
  init_ck_config_manager();
114791
115054
  init_file_io();
114792
115055
  init_logger();
114793
- import { existsSync as existsSync72 } from "node:fs";
115056
+ import { existsSync as existsSync73 } from "node:fs";
114794
115057
  import { mkdir as mkdir41, readFile as readFile68 } from "node:fs/promises";
114795
- import { dirname as dirname48 } from "node:path";
115058
+ import { dirname as dirname49 } from "node:path";
114796
115059
  var PROCESSED_ISSUES_CAP = 500;
114797
115060
  async function readCkJson(projectDir) {
114798
115061
  const configPath = CkConfigManager.getProjectConfigPath(projectDir);
114799
115062
  try {
114800
- if (!existsSync72(configPath))
115063
+ if (!existsSync73(configPath))
114801
115064
  return {};
114802
115065
  const content = await readFile68(configPath, "utf-8");
114803
115066
  return JSON.parse(content);
@@ -114822,8 +115085,8 @@ async function loadWatchState(projectDir) {
114822
115085
  }
114823
115086
  async function saveWatchState(projectDir, state) {
114824
115087
  const configPath = CkConfigManager.getProjectConfigPath(projectDir);
114825
- const configDir = dirname48(configPath);
114826
- if (!existsSync72(configDir)) {
115088
+ const configDir = dirname49(configPath);
115089
+ if (!existsSync73(configDir)) {
114827
115090
  await mkdir41(configDir, { recursive: true });
114828
115091
  }
114829
115092
  const raw2 = await readCkJson(projectDir);
@@ -114950,7 +115213,7 @@ async function processImplementationQueue(state, config, setup, options2, watchL
114950
115213
  // src/commands/watch/phases/repo-scanner.ts
114951
115214
  init_logger();
114952
115215
  import { spawnSync as spawnSync7 } from "node:child_process";
114953
- import { existsSync as existsSync73 } from "node:fs";
115216
+ import { existsSync as existsSync74 } from "node:fs";
114954
115217
  import { readdir as readdir46, stat as stat25 } from "node:fs/promises";
114955
115218
  import { join as join156 } from "node:path";
114956
115219
  async function scanForRepos(parentDir) {
@@ -114964,7 +115227,7 @@ async function scanForRepos(parentDir) {
114964
115227
  if (!entryStat.isDirectory())
114965
115228
  continue;
114966
115229
  const gitDir = join156(fullPath, ".git");
114967
- if (!existsSync73(gitDir))
115230
+ if (!existsSync74(gitDir))
114968
115231
  continue;
114969
115232
  const result = spawnSync7("gh", ["repo", "view", "--json", "owner,name"], {
114970
115233
  encoding: "utf-8",
@@ -114988,8 +115251,8 @@ async function scanForRepos(parentDir) {
114988
115251
  // src/commands/watch/phases/setup-validator.ts
114989
115252
  init_logger();
114990
115253
  import { spawnSync as spawnSync8 } from "node:child_process";
114991
- import { existsSync as existsSync74 } from "node:fs";
114992
- import { homedir as homedir53 } from "node:os";
115254
+ import { existsSync as existsSync75 } from "node:fs";
115255
+ import { homedir as homedir54 } from "node:os";
114993
115256
  import { join as join157 } from "node:path";
114994
115257
  async function validateSetup(cwd2) {
114995
115258
  const workDir = cwd2 ?? process.cwd();
@@ -115021,8 +115284,8 @@ Run this command from a directory with a GitHub remote.`);
115021
115284
  } catch {
115022
115285
  throw new Error(`Failed to parse repository info: ${ghRepo.stdout}`);
115023
115286
  }
115024
- const skillsPath = join157(homedir53(), ".claude", "skills");
115025
- const skillsAvailable = existsSync74(skillsPath);
115287
+ const skillsPath = join157(homedir54(), ".claude", "skills");
115288
+ const skillsAvailable = existsSync75(skillsPath);
115026
115289
  if (!skillsAvailable) {
115027
115290
  logger.warning(`ClaudeKit Engineer skills not found at ${skillsPath}`);
115028
115291
  }
@@ -115038,7 +115301,7 @@ Run this command from a directory with a GitHub remote.`);
115038
115301
  init_logger();
115039
115302
  init_path_resolver();
115040
115303
  import { createWriteStream as createWriteStream3, statSync as statSync13 } from "node:fs";
115041
- import { existsSync as existsSync75 } from "node:fs";
115304
+ import { existsSync as existsSync76 } from "node:fs";
115042
115305
  import { mkdir as mkdir42, rename as rename15 } from "node:fs/promises";
115043
115306
  import { join as join158 } from "node:path";
115044
115307
 
@@ -115053,7 +115316,7 @@ class WatchLogger {
115053
115316
  }
115054
115317
  async init() {
115055
115318
  try {
115056
- if (!existsSync75(this.logDir)) {
115319
+ if (!existsSync76(this.logDir)) {
115057
115320
  await mkdir42(this.logDir, { recursive: true });
115058
115321
  }
115059
115322
  const dateStr = formatDate(new Date);
@@ -115239,7 +115502,7 @@ async function watchCommand(options2) {
115239
115502
  }
115240
115503
  async function discoverRepos(options2, watchLog) {
115241
115504
  const cwd2 = process.cwd();
115242
- const isGitRepo = existsSync76(join159(cwd2, ".git"));
115505
+ const isGitRepo = existsSync77(join159(cwd2, ".git"));
115243
115506
  if (options2.force) {
115244
115507
  await forceRemoveLock(watchLog);
115245
115508
  }
@@ -115496,7 +115759,7 @@ function registerCommands(cli) {
115496
115759
  // src/cli/version-display.ts
115497
115760
  init_package();
115498
115761
  init_config_version_checker();
115499
- import { existsSync as existsSync88, readFileSync as readFileSync22 } from "node:fs";
115762
+ import { existsSync as existsSync89, readFileSync as readFileSync22 } from "node:fs";
115500
115763
  import { join as join171 } from "node:path";
115501
115764
 
115502
115765
  // src/domains/versioning/version-checker.ts
@@ -115510,7 +115773,7 @@ init_types3();
115510
115773
  // src/domains/versioning/version-cache.ts
115511
115774
  init_logger();
115512
115775
  init_path_resolver();
115513
- import { existsSync as existsSync87 } from "node:fs";
115776
+ import { existsSync as existsSync88 } from "node:fs";
115514
115777
  import { mkdir as mkdir43, readFile as readFile70, writeFile as writeFile42 } from "node:fs/promises";
115515
115778
  import { join as join170 } from "node:path";
115516
115779
 
@@ -115524,7 +115787,7 @@ class VersionCacheManager {
115524
115787
  static async load() {
115525
115788
  const cacheFile = VersionCacheManager.getCacheFile();
115526
115789
  try {
115527
- if (!existsSync87(cacheFile)) {
115790
+ if (!existsSync88(cacheFile)) {
115528
115791
  logger.debug("Version check cache not found");
115529
115792
  return null;
115530
115793
  }
@@ -115545,7 +115808,7 @@ class VersionCacheManager {
115545
115808
  const cacheFile = VersionCacheManager.getCacheFile();
115546
115809
  const cacheDir = PathResolver.getCacheDir(false);
115547
115810
  try {
115548
- if (!existsSync87(cacheDir)) {
115811
+ if (!existsSync88(cacheDir)) {
115549
115812
  await mkdir43(cacheDir, { recursive: true, mode: 448 });
115550
115813
  }
115551
115814
  await writeFile42(cacheFile, JSON.stringify(cache5, null, 2), "utf-8");
@@ -115567,7 +115830,7 @@ class VersionCacheManager {
115567
115830
  static async clear() {
115568
115831
  const cacheFile = VersionCacheManager.getCacheFile();
115569
115832
  try {
115570
- if (existsSync87(cacheFile)) {
115833
+ if (existsSync88(cacheFile)) {
115571
115834
  const fs20 = await import("node:fs/promises");
115572
115835
  await fs20.unlink(cacheFile);
115573
115836
  logger.debug("Version check cache cleared");
@@ -115834,7 +116097,7 @@ async function displayVersion() {
115834
116097
  const prefix = PathResolver.getPathPrefix(false);
115835
116098
  const localMetadataPath = prefix ? join171(process.cwd(), prefix, "metadata.json") : join171(process.cwd(), "metadata.json");
115836
116099
  const isLocalSameAsGlobal = localMetadataPath === globalMetadataPath;
115837
- if (!isLocalSameAsGlobal && existsSync88(localMetadataPath)) {
116100
+ if (!isLocalSameAsGlobal && existsSync89(localMetadataPath)) {
115838
116101
  try {
115839
116102
  const rawMetadata = JSON.parse(readFileSync22(localMetadataPath, "utf-8"));
115840
116103
  const metadata = MetadataSchema.parse(rawMetadata);
@@ -115848,7 +116111,7 @@ async function displayVersion() {
115848
116111
  logger.verbose("Failed to parse local metadata.json", { error });
115849
116112
  }
115850
116113
  }
115851
- if (existsSync88(globalMetadataPath)) {
116114
+ if (existsSync89(globalMetadataPath)) {
115852
116115
  try {
115853
116116
  const rawMetadata = JSON.parse(readFileSync22(globalMetadataPath, "utf-8"));
115854
116117
  const metadata = MetadataSchema.parse(rawMetadata);