claudekit-cli 4.5.0-dev.6 → 4.5.0-dev.7

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/cli-manifest.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "4.5.0-dev.6",
3
- "generatedAt": "2026-06-27T14:02:00.674Z",
2
+ "version": "4.5.0-dev.7",
3
+ "generatedAt": "2026-06-29T17:20:27.008Z",
4
4
  "commands": {
5
5
  "agents": {
6
6
  "name": "agents",
package/dist/index.js CHANGED
@@ -52475,11 +52475,56 @@ function getRulesSourcePath(globalOnly = false) {
52475
52475
  return globalPath;
52476
52476
  return findExistingProjectLayoutPath(process.cwd(), "rules") ?? globalPath;
52477
52477
  }
52478
+ function isRecord2(value) {
52479
+ return typeof value === "object" && value !== null && !Array.isArray(value);
52480
+ }
52481
+ function isClaudeKitPluginEnabled(settings) {
52482
+ if (!isRecord2(settings))
52483
+ return false;
52484
+ const enabledPlugins = settings.enabledPlugins;
52485
+ if (Array.isArray(enabledPlugins)) {
52486
+ return enabledPlugins.includes("ck@claudekit");
52487
+ }
52488
+ return isRecord2(enabledPlugins) && enabledPlugins["ck@claudekit"] === true;
52489
+ }
52490
+ function readJsonSafe2(filePath) {
52491
+ try {
52492
+ return JSON.parse(readFileSync7(filePath, "utf-8"));
52493
+ } catch {
52494
+ return null;
52495
+ }
52496
+ }
52497
+ function resolveConfiguredClaudeKitPluginSourceSubpath(relativePath) {
52498
+ const claudeDir3 = join42(homedir23(), ".claude");
52499
+ const settings = readJsonSafe2(join42(claudeDir3, "settings.json"));
52500
+ if (!isClaudeKitPluginEnabled(settings) || !isRecord2(settings))
52501
+ return null;
52502
+ const marketplaces = settings.extraKnownMarketplaces;
52503
+ const claudekit = isRecord2(marketplaces) ? marketplaces.claudekit : null;
52504
+ const source = isRecord2(claudekit) ? claudekit.source : null;
52505
+ const sourcePath = isRecord2(source) && typeof source.path === "string" ? source.path : null;
52506
+ if (!sourcePath)
52507
+ return null;
52508
+ const candidates = [join42(sourcePath, ".claude", relativePath), join42(sourcePath, relativePath)];
52509
+ return candidates.find((candidate) => existsSync24(candidate)) ?? null;
52510
+ }
52511
+ function hasAdjacentSettings(sourceDir) {
52512
+ return existsSync24(join42(dirname12(sourceDir), "settings.json"));
52513
+ }
52514
+ function resolveClaudeKitPluginHooksSourcePath() {
52515
+ const candidates = [
52516
+ resolveConfiguredClaudeKitPluginSourceSubpath("hooks"),
52517
+ resolveInstalledPluginCacheSubpath("hooks", join42(homedir23(), ".claude"))
52518
+ ].filter((path4) => typeof path4 === "string");
52519
+ return candidates.find((candidate) => hasAdjacentSettings(candidate)) ?? null;
52520
+ }
52478
52521
  function getHooksSourcePath(globalOnly = false) {
52479
52522
  const globalPath = join42(homedir23(), ".claude", "hooks");
52523
+ const pluginPath = resolveClaudeKitPluginHooksSourcePath();
52524
+ const globalCandidate = pluginPath ?? globalPath;
52480
52525
  if (globalOnly)
52481
- return globalPath;
52482
- return findExistingProjectLayoutPath(process.cwd(), "hooks") ?? globalPath;
52526
+ return globalCandidate;
52527
+ return findExistingProjectLayoutPath(process.cwd(), "hooks") ?? globalCandidate;
52483
52528
  }
52484
52529
  async function discoverConfig(sourcePath) {
52485
52530
  const path4 = sourcePath ?? getConfigSourcePath();
@@ -52725,6 +52770,7 @@ async function discoverPortableFiles(dir, baseDir, options2) {
52725
52770
  }
52726
52771
  var HOOK_EXTENSIONS, SHELL_HOOK_EXTENSIONS, HOOK_ASSET_EXTENSIONS, HOOK_DEPENDENCY_SKIP_SEGMENTS, HOOKS_SKIP_DIR_NAMES, HOOKS_COMPANION_DOTFILES;
52727
52772
  var init_config_discovery = __esm(() => {
52773
+ init_install_mode_detector();
52728
52774
  init_kit_layout();
52729
52775
  init_hook_migration_compatibility();
52730
52776
  HOOK_EXTENSIONS = new Set([".js", ".cjs", ".mjs", ".ts"]);
@@ -55317,13 +55363,25 @@ var init_gemini_hook_event_map = __esm(() => {
55317
55363
  });
55318
55364
 
55319
55365
  // src/commands/portable/hooks-settings-merger.ts
55320
- import { existsSync as existsSync27 } from "node:fs";
55366
+ import { existsSync as existsSync27, readFileSync as readFileSync8 } from "node:fs";
55321
55367
  import { mkdir as mkdir13, readFile as readFile22, rename as rename8, rm as rm6, writeFile as writeFile13 } from "node:fs/promises";
55322
55368
  import { homedir as homedir26 } from "node:os";
55323
- import { basename as basename14, dirname as dirname16, extname as extname4, join as join45, resolve as resolve20 } from "node:path";
55369
+ import { basename as basename14, dirname as dirname16, extname as extname4, isAbsolute as isAbsolute6, join as join45, resolve as resolve20 } from "node:path";
55370
+ function resolveSettingsPath(pathValue, isGlobal) {
55371
+ if (isGlobal || isAbsolute6(pathValue))
55372
+ return pathValue;
55373
+ return join45(process.cwd(), pathValue);
55374
+ }
55324
55375
  function isCodexWrappableHookPath(filePath) {
55325
55376
  return hookAssetBasename(filePath) !== "node-hook-runner.sh" && CODEX_WRAPPABLE_HOOK_EXTENSIONS.has(extname4(filePath).toLowerCase());
55326
55377
  }
55378
+ function collectSourceHookDirs(sourceHooksDirOverride, providerSourceHooksDir) {
55379
+ const dirs = [sourceHooksDirOverride, providerSourceHooksDir].filter((value) => typeof value === "string" && value.length > 0);
55380
+ return Array.from(new Set(dirs));
55381
+ }
55382
+ function rewriteHookPathsFromSourceDirs(hooks, sourceHooksDirs, targetHooksDir) {
55383
+ return sourceHooksDirs.reduce((currentHooks, sourceHooksDir) => rewriteHookPaths(currentHooks, sourceHooksDir, targetHooksDir), hooks);
55384
+ }
55327
55385
  function validateHooksSectionShape(value) {
55328
55386
  if (!value || typeof value !== "object" || Array.isArray(value)) {
55329
55387
  return "hooks must be a non-null object";
@@ -55523,8 +55581,9 @@ function pruneIncompatibleHookRegistrations(hooks, options2) {
55523
55581
  const keptHooks = group.hooks.filter((entry) => {
55524
55582
  const refs = extractHookReferencesFromCommand(entry.command);
55525
55583
  const targetOwned = commandTargetsHookDir(entry.command, targetHooksDir);
55584
+ const foreignCkOwned = commandTargetsForeignCkHookDir(entry.command, targetHooksDir);
55526
55585
  const incompatible = !isCodexSupportedHookEvent(event) || refs.some((ref) => isExcludedHookAsset(ref));
55527
- if (targetOwned && incompatible) {
55586
+ if (foreignCkOwned || targetOwned && incompatible) {
55528
55587
  hooksPruned += 1;
55529
55588
  return false;
55530
55589
  }
@@ -55569,10 +55628,44 @@ function commandTargetsHookDir(command, targetHooksDir) {
55569
55628
  const normalizedDir = targetHooksDir.replace(/\\/g, "/").replace(/\/+$/, "");
55570
55629
  return normalizedCommand.includes(`${normalizedDir}/`) || normalizedCommand.includes("$HOME/.codex/hooks/") || normalizedCommand.includes("~/.codex/hooks/");
55571
55630
  }
55631
+ function commandTargetsForeignCkHookDir(command, targetHooksDir) {
55632
+ const normalizedCommand = command.replace(/\\/g, "/");
55633
+ const normalizedDir = targetHooksDir.replace(/\\/g, "/").replace(/\/+$/, "");
55634
+ const targetTokens = [
55635
+ `${normalizedDir}/`,
55636
+ "$HOME/.codex/hooks/",
55637
+ "~/.codex/hooks/",
55638
+ ".codex/hooks/"
55639
+ ];
55640
+ if (targetTokens.some((token) => normalizedCommand.includes(token)))
55641
+ return false;
55642
+ return normalizedCommand.includes("$HOME/.claude/hooks/") || normalizedCommand.includes("~/.claude/hooks/") || normalizedCommand.includes(".claude/hooks/");
55643
+ }
55572
55644
  function isCkManagedHookPath(absPath) {
55573
55645
  const normalized = absPath.replace(/\\/g, "/");
55574
55646
  return normalized.includes("/.claude/hooks/") || normalized.includes("/.codex/hooks/") || normalized.includes("/.gemini/hooks/");
55575
55647
  }
55648
+ function readCodexWrapperOriginalHookPath(wrapperPath) {
55649
+ try {
55650
+ const content = readFileSync8(wrapperPath, "utf8");
55651
+ const match = content.match(/const\s+ORIGINAL_HOOK\s*=\s*("(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*')/);
55652
+ if (!match)
55653
+ return null;
55654
+ const literal = match[1];
55655
+ if (literal.startsWith('"')) {
55656
+ return JSON.parse(literal);
55657
+ }
55658
+ return literal.slice(1, -1).replace(/\\'/g, "'").replace(/\\\\/g, "\\");
55659
+ } catch {
55660
+ return null;
55661
+ }
55662
+ }
55663
+ function codexWrapperReferencesMissingOriginal(wrapperPath) {
55664
+ const originalPath = readCodexWrapperOriginalHookPath(wrapperPath);
55665
+ if (!originalPath || !isCkManagedHookPath(originalPath))
55666
+ return false;
55667
+ return !existsSync27(originalPath);
55668
+ }
55576
55669
  function extractAbsolutePaths(command) {
55577
55670
  const matches = [];
55578
55671
  const pathPattern = /(?:^|[\s"'(])(\/[^\s"'()]+)/g;
@@ -55593,7 +55686,7 @@ function pruneStaleFileHooks(existing) {
55593
55686
  const ckPaths = paths.filter(isCkManagedHookPath);
55594
55687
  if (ckPaths.length === 0)
55595
55688
  return true;
55596
- return ckPaths.some((p) => existsSync27(p));
55689
+ return ckPaths.some((p) => existsSync27(p) && !codexWrapperReferencesMissingOriginal(p));
55597
55690
  });
55598
55691
  if (survivingHooks.length > 0) {
55599
55692
  prunedGroups.push({ ...group, hooks: survivingHooks });
@@ -55658,7 +55751,7 @@ async function migrateHooksSettings(options2) {
55658
55751
  targetSettingsPath: null
55659
55752
  };
55660
55753
  }
55661
- const sourceSettingsPath = isGlobal ? sourceConfig.settingsJsonPath?.globalPath : sourceConfig.settingsJsonPath?.projectPath;
55754
+ const sourceSettingsPath = options2.sourceSettingsPath ?? (isGlobal ? sourceConfig.settingsJsonPath?.globalPath : sourceConfig.settingsJsonPath?.projectPath);
55662
55755
  const targetSettingsPath = isGlobal ? targetConfig.settingsJsonPath?.globalPath : targetConfig.settingsJsonPath?.projectPath;
55663
55756
  if (!sourceSettingsPath) {
55664
55757
  return {
@@ -55682,7 +55775,7 @@ async function migrateHooksSettings(options2) {
55682
55775
  targetSettingsPath: null
55683
55776
  };
55684
55777
  }
55685
- const resolvedSourcePath = isGlobal ? sourceSettingsPath : join45(process.cwd(), sourceSettingsPath);
55778
+ const resolvedSourcePath = resolveSettingsPath(sourceSettingsPath, isGlobal);
55686
55779
  const resolvedTargetPath = isGlobal ? targetSettingsPath : join45(process.cwd(), targetSettingsPath);
55687
55780
  const sourceHooksResult = await inspectHooksSettings(resolvedSourcePath);
55688
55781
  if (sourceHooksResult.status === "missing-file") {
@@ -55730,14 +55823,15 @@ async function migrateHooksSettings(options2) {
55730
55823
  targetSettingsPath: resolvedTargetPath
55731
55824
  };
55732
55825
  }
55733
- const sourceHooksDir = isGlobal ? sourceConfig.hooks?.globalPath ?? "" : sourceConfig.hooks?.projectPath ?? "";
55826
+ const providerSourceHooksDir = isGlobal ? sourceConfig.hooks?.globalPath ?? "" : sourceConfig.hooks?.projectPath ?? "";
55827
+ const sourceHooksDirs = collectSourceHookDirs(options2.sourceHooksDir, providerSourceHooksDir);
55734
55828
  const targetHooksDir = isGlobal ? targetConfig.hooks?.globalPath ?? "" : targetConfig.hooks?.projectPath ?? "";
55735
55829
  const warnings = [];
55736
55830
  const filtered = filterToInstalledHooks(sourceHooks, installedHookFiles, {
55737
55831
  targetProvider,
55738
55832
  warnings
55739
55833
  });
55740
- const rewritten = rewriteHookPaths(filtered, sourceHooksDir, targetHooksDir);
55834
+ const rewritten = rewriteHookPathsFromSourceDirs(filtered, sourceHooksDirs, targetHooksDir);
55741
55835
  const eventMapped = mapHookEventsForProvider(rewritten, targetProvider);
55742
55836
  let hooksRegistered = 0;
55743
55837
  for (const groups of Object.values(eventMapped)) {
@@ -55815,7 +55909,7 @@ async function migrateHooksSettingsForCodex(options2) {
55815
55909
  };
55816
55910
  }
55817
55911
  const capabilities = await detectCodexCapabilities();
55818
- const sourceSettingsPath = isGlobal ? sourceConfig.settingsJsonPath.globalPath : sourceConfig.settingsJsonPath.projectPath;
55912
+ const sourceSettingsPath = options2.sourceSettingsPath ?? (isGlobal ? sourceConfig.settingsJsonPath.globalPath : sourceConfig.settingsJsonPath.projectPath);
55819
55913
  const targetSettingsPath = isGlobal ? codexConfig.settingsJsonPath?.globalPath ?? null : codexConfig.settingsJsonPath?.projectPath ?? null;
55820
55914
  if (!targetSettingsPath) {
55821
55915
  return {
@@ -55828,7 +55922,7 @@ async function migrateHooksSettingsForCodex(options2) {
55828
55922
  targetSettingsPath: null
55829
55923
  };
55830
55924
  }
55831
- const resolvedSourcePath = isGlobal ? sourceSettingsPath : join45(process.cwd(), sourceSettingsPath);
55925
+ const resolvedSourcePath = resolveSettingsPath(sourceSettingsPath, isGlobal);
55832
55926
  const resolvedTargetPath = isGlobal ? targetSettingsPath : join45(process.cwd(), targetSettingsPath);
55833
55927
  const projectDir = isGlobal ? undefined : process.cwd();
55834
55928
  const sourceHooksResult = await inspectHooksSettings(resolvedSourcePath);
@@ -55875,7 +55969,9 @@ async function migrateHooksSettingsForCodex(options2) {
55875
55969
  warnings
55876
55970
  });
55877
55971
  const targetHooksDir = isGlobal ? codexConfig.hooks?.globalPath ?? "" : codexConfig.hooks?.projectPath ?? "";
55878
- const sourceHooksDir = isGlobal ? sourceConfig.hooks?.globalPath ?? "" : sourceConfig.hooks?.projectPath ?? "";
55972
+ const providerSourceHooksDir = isGlobal ? sourceConfig.hooks?.globalPath ?? "" : sourceConfig.hooks?.projectPath ?? "";
55973
+ const sourceHooksDir = options2.sourceHooksDir ?? providerSourceHooksDir;
55974
+ const sourceHookCommandDirs = collectSourceHookDirs(options2.sourceHooksDir, providerSourceHooksDir);
55879
55975
  const wrapperPaths = [];
55880
55976
  const commandSubstitutions = new Map;
55881
55977
  if (installedHookAbsolutePaths && installedHookAbsolutePaths.length > 0 && targetHooksDir) {
@@ -55891,11 +55987,11 @@ async function migrateHooksSettingsForCodex(options2) {
55891
55987
  addKey(join45(targetHooksDir, base));
55892
55988
  addKey(`./${join45(targetHooksDir, base)}`);
55893
55989
  }
55894
- if (sourceHooksDir) {
55895
- const sourceAbs = join45(resolve20(sourceHooksDir), base);
55990
+ for (const commandSourceHooksDir of sourceHookCommandDirs) {
55991
+ const sourceAbs = join45(resolve20(commandSourceHooksDir), base);
55896
55992
  addKey(sourceAbs);
55897
- addKey(join45(sourceHooksDir, base));
55898
- addKey(`./${join45(sourceHooksDir, base)}`);
55993
+ addKey(join45(commandSourceHooksDir, base));
55994
+ addKey(`./${join45(commandSourceHooksDir, base)}`);
55899
55995
  if (sourceAbs.startsWith("/private/")) {
55900
55996
  addKey(sourceAbs.slice("/private".length));
55901
55997
  } else if (sourceAbs.startsWith("/var/")) {
@@ -55905,7 +56001,8 @@ async function migrateHooksSettingsForCodex(options2) {
55905
56001
  }
55906
56002
  }
55907
56003
  }
55908
- if (!sourceHooksDir) {
56004
+ const pathRewriteSourceDir = providerSourceHooksDir || sourceHooksDir;
56005
+ if (!pathRewriteSourceDir) {
55909
56006
  const convertedNoRewrite = convertClaudeHooksToCodex(filtered, capabilities);
55910
56007
  let hooksRegisteredNoRewrite = 0;
55911
56008
  for (const groups of Object.values(convertedNoRewrite)) {
@@ -55944,7 +56041,7 @@ async function migrateHooksSettingsForCodex(options2) {
55944
56041
  }
55945
56042
  const effectiveTargetDir = targetHooksDir || sourceHooksDir;
55946
56043
  const converted = convertClaudeHooksToCodex(filtered, capabilities, {
55947
- sourceDir: sourceHooksDir,
56044
+ sourceDir: pathRewriteSourceDir,
55948
56045
  targetDir: effectiveTargetDir,
55949
56046
  commandSubstitutions: commandSubstitutions.size > 0 ? commandSubstitutions : undefined,
55950
56047
  projectDir
@@ -56055,7 +56152,7 @@ var init_generated_context_hooks = __esm(() => {
56055
56152
  // src/commands/portable/migrated-hook-settings-cleanup.ts
56056
56153
  import { existsSync as existsSync28, realpathSync } from "node:fs";
56057
56154
  import { readFile as readFile23, rename as rename9, rm as rm7, unlink as unlink7, writeFile as writeFile14 } from "node:fs/promises";
56058
- import { basename as basename16, isAbsolute as isAbsolute6, relative as relative10, resolve as resolve21 } from "node:path";
56155
+ import { basename as basename16, isAbsolute as isAbsolute7, relative as relative10, resolve as resolve21 } from "node:path";
56059
56156
  async function pruneSettingsHooks(settingsPath, hooksDir) {
56060
56157
  const filesToRemove = new Set;
56061
56158
  const warnings = [];
@@ -56138,7 +56235,7 @@ function hookFilesFromCommand(command, hooksDir) {
56138
56235
  const name = basename16(cleaned);
56139
56236
  if (!name || !isGeneratedContextHookName(name))
56140
56237
  continue;
56141
- if (isAbsolute6(cleaned) && isPathWithin(cleaned, hooksDir))
56238
+ if (isAbsolute7(cleaned) && isPathWithin(cleaned, hooksDir))
56142
56239
  files.add(resolve21(cleaned));
56143
56240
  else if (referencesHooksDir(cleaned, hooksDir) || cleaned.includes(".claude/hooks/")) {
56144
56241
  files.add(resolve21(hooksDir, name));
@@ -56153,7 +56250,7 @@ function referencesHooksDir(command, hooksDir) {
56153
56250
  }
56154
56251
  function isPathWithin(filePath, parentDir) {
56155
56252
  const rel = relative10(resolvePathForContainment(parentDir), resolvePathForContainment(filePath));
56156
- return rel === "" || !!rel && !rel.startsWith("..") && !isAbsolute6(rel);
56253
+ return rel === "" || !!rel && !rel.startsWith("..") && !isAbsolute7(rel);
56157
56254
  }
56158
56255
  function resolvePathForContainment(pathValue) {
56159
56256
  try {
@@ -56186,7 +56283,7 @@ __export(exports_migrated_hooks_cleanup, {
56186
56283
  isGeneratedContextHookName: () => isGeneratedContextHookName,
56187
56284
  cleanupMigratedHooksForProviders: () => cleanupMigratedHooksForProviders
56188
56285
  });
56189
- import { isAbsolute as isAbsolute7, resolve as resolve22 } from "node:path";
56286
+ import { isAbsolute as isAbsolute8, resolve as resolve22 } from "node:path";
56190
56287
  async function cleanupMigratedHooksForProviders(providerIds, options2) {
56191
56288
  const uniqueProviders = Array.from(new Set(providerIds));
56192
56289
  const results = [];
@@ -56240,7 +56337,7 @@ async function cleanupMigratedHooksForProvider(provider, options2) {
56240
56337
  function resolveProviderPath(pathValue) {
56241
56338
  if (!pathValue)
56242
56339
  return null;
56243
- return isAbsolute7(pathValue) ? pathValue : resolve22(process.cwd(), pathValue);
56340
+ return isAbsolute8(pathValue) ? pathValue : resolve22(process.cwd(), pathValue);
56244
56341
  }
56245
56342
  var init_migrated_hooks_cleanup = __esm(() => {
56246
56343
  init_generated_context_hooks();
@@ -59296,10 +59393,10 @@ var init_migration_routes = __esm(() => {
59296
59393
  });
59297
59394
 
59298
59395
  // src/domains/plan-parser/plan-metadata.ts
59299
- import { readFileSync as readFileSync8, statSync as statSync7 } from "node:fs";
59396
+ import { readFileSync as readFileSync9, statSync as statSync7 } from "node:fs";
59300
59397
  function readMatter(filePath) {
59301
59398
  try {
59302
- return import_gray_matter6.default(readFileSync8(filePath, "utf8")).data;
59399
+ return import_gray_matter6.default(readFileSync9(filePath, "utf8")).data;
59303
59400
  } catch {
59304
59401
  return {};
59305
59402
  }
@@ -59406,7 +59503,7 @@ var init_plan_metadata = __esm(() => {
59406
59503
  });
59407
59504
 
59408
59505
  // src/domains/plan-parser/plan-table-parser.ts
59409
- import { readFileSync as readFileSync9 } from "node:fs";
59506
+ import { readFileSync as readFileSync10 } from "node:fs";
59410
59507
  import { dirname as dirname18, resolve as resolve24 } from "node:path";
59411
59508
  function normalizeStatus(raw) {
59412
59509
  const s = raw.toLowerCase().trim();
@@ -59771,7 +59868,7 @@ function parsePhasesFromBody(body, dir, options2) {
59771
59868
  return parseFormat6(normalizedBody, dir, options2);
59772
59869
  }
59773
59870
  function parsePlanFile(planFilePath, options2) {
59774
- const content = readFileSync9(planFilePath, "utf8");
59871
+ const content = readFileSync10(planFilePath, "utf8");
59775
59872
  const dir = dirname18(planFilePath);
59776
59873
  const { data: frontmatter, content: body } = import_gray_matter7.default(content, {
59777
59874
  engines: { javascript: { parse: () => ({}) } }
@@ -59919,13 +60016,13 @@ var init_plan_scanner = () => {};
59919
60016
 
59920
60017
  // src/domains/plan-parser/plan-scope.ts
59921
60018
  import { homedir as homedir29 } from "node:os";
59922
- import { isAbsolute as isAbsolute8, join as join50, relative as relative12, resolve as resolve25 } from "node:path";
60019
+ import { isAbsolute as isAbsolute9, join as join50, relative as relative12, resolve as resolve25 } from "node:path";
59923
60020
  function resolveConfiguredDir(configuredPath, baseDir) {
59924
60021
  const trimmed = configuredPath?.trim();
59925
60022
  if (!trimmed) {
59926
60023
  return join50(baseDir, DEFAULT_PLANS_DIRNAME);
59927
60024
  }
59928
- return isAbsolute8(trimmed) ? resolve25(trimmed) : resolve25(baseDir, trimmed);
60025
+ return isAbsolute9(trimmed) ? resolve25(trimmed) : resolve25(baseDir, trimmed);
59929
60026
  }
59930
60027
  function resolveProjectPlansDir(projectRoot, config) {
59931
60028
  return resolveConfiguredDir(config?.paths?.plans, projectRoot);
@@ -59940,7 +60037,7 @@ function isWithinDir(targetPath, baseDir) {
59940
60037
  const resolvedTarget = resolve25(targetPath);
59941
60038
  const resolvedBase = resolve25(baseDir);
59942
60039
  const relativePath = relative12(resolvedBase, resolvedTarget);
59943
- return relativePath === "" || !relativePath.startsWith("..") && relativePath !== ".." && !isAbsolute8(relativePath);
60040
+ return relativePath === "" || !relativePath.startsWith("..") && relativePath !== ".." && !isAbsolute9(relativePath);
59944
60041
  }
59945
60042
  function inferPlanScopeForDir(planDir, config) {
59946
60043
  return isWithinDir(planDir, resolveGlobalPlansDir(config)) ? "global" : "project";
@@ -59949,7 +60046,7 @@ function parsePlanReference(reference, defaultScope) {
59949
60046
  const trimmed = reference.trim();
59950
60047
  const normalizePlanId = (rawPlanId) => {
59951
60048
  const planId = rawPlanId.trim();
59952
- const valid = planId.length > 0 && !isAbsolute8(planId) && !planId.includes("/") && !planId.includes("\\") && PLAN_ID_PATTERN.test(planId);
60049
+ const valid = planId.length > 0 && !isAbsolute9(planId) && !planId.includes("/") && !planId.includes("\\") && PLAN_ID_PATTERN.test(planId);
59953
60050
  return { planId, valid };
59954
60051
  };
59955
60052
  if (trimmed.startsWith(GLOBAL_PLAN_PREFIX)) {
@@ -60067,10 +60164,10 @@ var init_timeline_builder = __esm(() => {
60067
60164
  });
60068
60165
 
60069
60166
  // src/domains/plan-parser/plan-validator.ts
60070
- import { existsSync as existsSync34, readFileSync as readFileSync10 } from "node:fs";
60167
+ import { existsSync as existsSync34, readFileSync as readFileSync11 } from "node:fs";
60071
60168
  import { basename as basename18, dirname as dirname19 } from "node:path";
60072
60169
  function validatePlanFile(filePath, strict = false) {
60073
- const rawContent = readFileSync10(filePath, "utf8");
60170
+ const rawContent = readFileSync11(filePath, "utf8");
60074
60171
  const content = rawContent.replace(/\r\n/g, `
60075
60172
  `);
60076
60173
  const dir = dirname19(filePath);
@@ -60137,7 +60234,7 @@ var init_plan_validator = __esm(() => {
60137
60234
 
60138
60235
  // src/domains/plan-parser/plan-writer.ts
60139
60236
  import { execSync } from "node:child_process";
60140
- import { mkdirSync as mkdirSync2, readFileSync as readFileSync11, writeFileSync as writeFileSync3 } from "node:fs";
60237
+ import { mkdirSync as mkdirSync2, readFileSync as readFileSync12, writeFileSync as writeFileSync3 } from "node:fs";
60141
60238
  import { existsSync as existsSync35 } from "node:fs";
60142
60239
  import { basename as basename19, dirname as dirname20, join as join52 } from "node:path";
60143
60240
  function phaseNameToFilename(id, name) {
@@ -60310,7 +60407,7 @@ function isCanonicalFormat(content) {
60310
60407
  return /^\|\s*phase\s*\|\s*name\s*\|\s*status\s*\|/im.test(content);
60311
60408
  }
60312
60409
  function updatePhaseStatus(planFile, phaseId, newStatus) {
60313
- const raw = readFileSync11(planFile, "utf8").replace(/\r\n/g, `
60410
+ const raw = readFileSync12(planFile, "utf8").replace(/\r\n/g, `
60314
60411
  `);
60315
60412
  if (!isCanonicalFormat(raw)) {
60316
60413
  console.error("[!] plan.md is not in canonical format — skipping status update");
@@ -60372,7 +60469,7 @@ function phaseNameFilenameFromTableRow(body, phaseId, planDir) {
60372
60469
  return null;
60373
60470
  }
60374
60471
  function updatePhaseFileFrontmatter(phaseFile, newStatus) {
60375
- const raw = readFileSync11(phaseFile, "utf8");
60472
+ const raw = readFileSync12(phaseFile, "utf8");
60376
60473
  const { data: frontmatter, content: body } = import_gray_matter9.default(raw, {
60377
60474
  engines: { javascript: { parse: () => ({}) } }
60378
60475
  });
@@ -60380,7 +60477,7 @@ function updatePhaseFileFrontmatter(phaseFile, newStatus) {
60380
60477
  writeFileSync3(phaseFile, import_gray_matter9.default.stringify(body, updated), "utf8");
60381
60478
  }
60382
60479
  function addPhase(planFile, name, afterId) {
60383
- const raw = readFileSync11(planFile, "utf8").replace(/\r\n/g, `
60480
+ const raw = readFileSync12(planFile, "utf8").replace(/\r\n/g, `
60384
60481
  `);
60385
60482
  if (!isCanonicalFormat(raw)) {
60386
60483
  console.error("[!] plan.md is not in canonical format — cannot add phase");
@@ -60725,12 +60822,12 @@ var init_plan_types = __esm(() => {
60725
60822
  import {
60726
60823
  existsSync as existsSync36,
60727
60824
  mkdirSync as mkdirSync3,
60728
- readFileSync as readFileSync12,
60825
+ readFileSync as readFileSync13,
60729
60826
  renameSync,
60730
60827
  unlinkSync,
60731
60828
  writeFileSync as writeFileSync4
60732
60829
  } from "node:fs";
60733
- import { dirname as dirname22, isAbsolute as isAbsolute9, join as join53, parse as parse2, relative as relative13, resolve as resolve26 } from "node:path";
60830
+ import { dirname as dirname22, isAbsolute as isAbsolute10, join as join53, parse as parse2, relative as relative13, resolve as resolve26 } from "node:path";
60734
60831
  function createEmptyRegistry() {
60735
60832
  return {
60736
60833
  version: 1,
@@ -60756,7 +60853,7 @@ function migrateFromProjectLocal(cwd2, globalPath) {
60756
60853
  return;
60757
60854
  }
60758
60855
  try {
60759
- const oldData = JSON.parse(readFileSync12(oldPath, "utf8"));
60856
+ const oldData = JSON.parse(readFileSync13(oldPath, "utf8"));
60760
60857
  if (oldData && typeof oldData === "object" && Array.isArray(oldData.plans)) {
60761
60858
  const migrated = {
60762
60859
  version: 1,
@@ -60785,7 +60882,7 @@ function migrateFromProjectLocal(cwd2, globalPath) {
60785
60882
  }
60786
60883
  }
60787
60884
  function normalizeRegistryDir(cwd2, dir) {
60788
- const absoluteDir = isAbsolute9(dir) ? dir : resolve26(cwd2, dir);
60885
+ const absoluteDir = isAbsolute10(dir) ? dir : resolve26(cwd2, dir);
60789
60886
  const relativeDir = relative13(cwd2, absoluteDir) || dir;
60790
60887
  return relativeDir.replace(/\\/g, "/");
60791
60888
  }
@@ -60807,7 +60904,7 @@ function readRegistry(cwd2 = process.cwd()) {
60807
60904
  return createEmptyRegistry();
60808
60905
  }
60809
60906
  try {
60810
- const parsed = PlansRegistrySchema.safeParse(JSON.parse(readFileSync12(globalPath, "utf8")));
60907
+ const parsed = PlansRegistrySchema.safeParse(JSON.parse(readFileSync13(globalPath, "utf8")));
60811
60908
  return parsed.success ? parsed.data : createEmptyRegistry();
60812
60909
  } catch {
60813
60910
  return createEmptyRegistry();
@@ -60820,7 +60917,7 @@ function writeRegistry(registry, cwd2 = process.cwd()) {
60820
60917
  mkdirSync3(dirname22(globalPath), { recursive: true });
60821
60918
  if (existsSync36(globalPath)) {
60822
60919
  try {
60823
- writeFileSync4(`${globalPath}.bak`, readFileSync12(globalPath));
60920
+ writeFileSync4(`${globalPath}.bak`, readFileSync13(globalPath));
60824
60921
  } catch {}
60825
60922
  }
60826
60923
  const tempPath = `${globalPath}.tmp-${process.pid}-${Date.now()}`;
@@ -61202,7 +61299,7 @@ var init_p_limit = __esm(() => {
61202
61299
  });
61203
61300
 
61204
61301
  // src/domains/web-server/routes/plan-routes.ts
61205
- import { existsSync as existsSync37, readFileSync as readFileSync13, realpathSync as realpathSync2 } from "node:fs";
61302
+ import { existsSync as existsSync37, readFileSync as readFileSync14, realpathSync as realpathSync2 } from "node:fs";
61206
61303
  import { homedir as homedir30 } from "node:os";
61207
61304
  import { basename as basename20, dirname as dirname24, join as join55, relative as relative14, resolve as resolve27, sep as sep8 } from "node:path";
61208
61305
  function sanitizeError(err) {
@@ -61251,7 +61348,7 @@ function getGlobalPlanRoot() {
61251
61348
  if (!existsSync37(configPath)) {
61252
61349
  value = resolveGlobalPlansDir();
61253
61350
  } else {
61254
- const raw = JSON.parse(readFileSync13(configPath, "utf8"));
61351
+ const raw = JSON.parse(readFileSync14(configPath, "utf8"));
61255
61352
  const parsed = CkConfigSchema.parse(normalizeCkConfigInput(raw));
61256
61353
  value = resolveGlobalPlansDir(parsed);
61257
61354
  }
@@ -61581,7 +61678,7 @@ function registerPlanRoutes(app) {
61581
61678
  return;
61582
61679
  }
61583
61680
  try {
61584
- const raw = readFileSync13(file, "utf8");
61681
+ const raw = readFileSync14(file, "utf8");
61585
61682
  const parsed = import_gray_matter10.default(raw);
61586
61683
  res.json({
61587
61684
  file: relative14(process.cwd(), file),
@@ -63153,12 +63250,12 @@ function getCliVersion3() {
63153
63250
  if (process.env.npm_package_version) {
63154
63251
  return process.env.npm_package_version;
63155
63252
  }
63156
- const { readFileSync: readFileSync14 } = __require("node:fs");
63253
+ const { readFileSync: readFileSync15 } = __require("node:fs");
63157
63254
  const { dirname: dirname27, join: joinPath } = __require("node:path");
63158
63255
  const { fileURLToPath: fileURLToPath2 } = __require("node:url");
63159
63256
  const __dirname3 = dirname27(fileURLToPath2(import.meta.url));
63160
63257
  const pkgPath = joinPath(__dirname3, "../../../package.json");
63161
- const pkg = JSON.parse(readFileSync14(pkgPath, "utf-8"));
63258
+ const pkg = JSON.parse(readFileSync15(pkgPath, "utf-8"));
63162
63259
  return pkg.version || "unknown";
63163
63260
  } catch {
63164
63261
  return "unknown";
@@ -64421,7 +64518,7 @@ var package_default;
64421
64518
  var init_package = __esm(() => {
64422
64519
  package_default = {
64423
64520
  name: "claudekit-cli",
64424
- version: "4.5.0-dev.6",
64521
+ version: "4.5.0-dev.7",
64425
64522
  description: "CLI tool for bootstrapping and updating ClaudeKit projects",
64426
64523
  type: "module",
64427
64524
  repository: {
@@ -64923,7 +65020,7 @@ var init_package_manager_runner = __esm(() => {
64923
65020
  // src/domains/installation/merger/zombie-wirings-pruner.ts
64924
65021
  import { existsSync as existsSync45, readdirSync as readdirSync8 } from "node:fs";
64925
65022
  import { homedir as homedir39 } from "node:os";
64926
- import { basename as basename23, dirname as dirname28, isAbsolute as isAbsolute10, resolve as resolve32, sep as sep10 } from "node:path";
65023
+ import { basename as basename23, dirname as dirname28, isAbsolute as isAbsolute11, resolve as resolve32, sep as sep10 } from "node:path";
64927
65024
  function pruneZombieEngineerWirings(settings, hookDir, preserveCommands = new Set) {
64928
65025
  const pruned = [];
64929
65026
  const normalizedPreserveCommands = new Set(Array.from(preserveCommands).map((command) => normalizeCommand(command)));
@@ -65021,7 +65118,7 @@ function extractHookFilePath(command, hookDir) {
65021
65118
  const bashMatch = command.match(/^bash\s+["']([^"']+\.sh)["']/);
65022
65119
  if (bashMatch) {
65023
65120
  const rawPath = bashMatch[1].replace(/\\/g, "/");
65024
- const resolved = isAbsolute10(rawPath) || /^[A-Za-z]:[\\/]/.test(rawPath) ? rawPath : resolve32(hookDir, rawPath);
65121
+ const resolved = isAbsolute11(rawPath) || /^[A-Za-z]:[\\/]/.test(rawPath) ? rawPath : resolve32(hookDir, rawPath);
65025
65122
  return process.platform === "win32" ? resolved.replace(/\//g, sep10) : resolved;
65026
65123
  }
65027
65124
  return null;
@@ -65043,7 +65140,7 @@ function extractHookFilePath(command, hookDir) {
65043
65140
  return process.platform === "win32" ? resolved.replace(/\//g, sep10) : resolved;
65044
65141
  }
65045
65142
  const tildeResolved = rawArg.replace(/^~(?=\/)/, home5);
65046
- if (isAbsolute10(tildeResolved) || /^[A-Za-z]:[\\/]/.test(tildeResolved)) {
65143
+ if (isAbsolute11(tildeResolved) || /^[A-Za-z]:[\\/]/.test(tildeResolved)) {
65047
65144
  return process.platform === "win32" ? tildeResolved.replace(/\//g, sep10) : tildeResolved;
65048
65145
  }
65049
65146
  return resolve32(hookDir, tildeResolved);
@@ -65057,7 +65154,7 @@ function extractHookFilePath(command, hookDir) {
65057
65154
  return process.platform === "win32" ? resolved.replace(/\//g, sep10) : resolved;
65058
65155
  }
65059
65156
  const tildeResolved = rawArg.replace(/^~(?=\/)/, home5);
65060
- if (isAbsolute10(tildeResolved) || /^[A-Za-z]:[\\/]/.test(tildeResolved)) {
65157
+ if (isAbsolute11(tildeResolved) || /^[A-Za-z]:[\\/]/.test(tildeResolved)) {
65061
65158
  return process.platform === "win32" ? tildeResolved.replace(/\//g, sep10) : tildeResolved;
65062
65159
  }
65063
65160
  return resolve32(hookDir, tildeResolved);
@@ -65080,7 +65177,7 @@ var init_shared2 = __esm(() => {
65080
65177
 
65081
65178
  // src/domains/health-checks/checkers/hook-health-checker.ts
65082
65179
  import { spawnSync as spawnSync3 } from "node:child_process";
65083
- import { existsSync as existsSync46, readFileSync as readFileSync14, readdirSync as readdirSync9, statSync as statSync10, writeFileSync as writeFileSync5 } from "node:fs";
65180
+ import { existsSync as existsSync46, readFileSync as readFileSync15, readdirSync as readdirSync9, statSync as statSync10, writeFileSync as writeFileSync5 } from "node:fs";
65084
65181
  import { readdir as readdir17 } from "node:fs/promises";
65085
65182
  import { homedir as homedir40, tmpdir } from "node:os";
65086
65183
  import { dirname as dirname29, join as join65, resolve as resolve33, sep as sep11 } from "node:path";
@@ -65120,7 +65217,7 @@ function readManagedHookNamesForClaudeDir(claudeDir3) {
65120
65217
  if (!existsSync46(manifestPath))
65121
65218
  return new Set;
65122
65219
  try {
65123
- const data = JSON.parse(readFileSync14(manifestPath, "utf-8"));
65220
+ const data = JSON.parse(readFileSync15(manifestPath, "utf-8"));
65124
65221
  if (!Array.isArray(data.managedHooks))
65125
65222
  return new Set;
65126
65223
  return new Set(data.managedHooks.filter((name) => typeof name === "string"));
@@ -65591,7 +65688,7 @@ async function checkHookDeps(projectDir) {
65591
65688
  const filePath = join65(hooksDir, file);
65592
65689
  if (!isPathWithin2(filePath, hooksDir))
65593
65690
  continue;
65594
- const content = readFileSync14(filePath, "utf-8");
65691
+ const content = readFileSync15(filePath, "utf-8");
65595
65692
  for (let match = requireRegex.exec(content);match !== null; match = requireRegex.exec(content)) {
65596
65693
  const depPath = match[1];
65597
65694
  if (depPath.startsWith("node:") || isNodeBuiltin(depPath)) {
@@ -66140,7 +66237,7 @@ async function checkHookConfig(projectDir) {
66140
66237
  };
66141
66238
  }
66142
66239
  try {
66143
- const configContent = readFileSync14(configPath, "utf-8");
66240
+ const configContent = readFileSync15(configPath, "utf-8");
66144
66241
  const config = JSON.parse(configContent);
66145
66242
  if (!config.hooks || typeof config.hooks !== "object") {
66146
66243
  return {
@@ -66276,7 +66373,7 @@ async function checkHookLogs(projectDir) {
66276
66373
  }
66277
66374
  };
66278
66375
  }
66279
- const logContent = readFileSync14(logPath, "utf-8");
66376
+ const logContent = readFileSync15(logPath, "utf-8");
66280
66377
  const lines = logContent.trim().split(`
66281
66378
  `).filter(Boolean);
66282
66379
  const now = Date.now();
@@ -75127,7 +75224,7 @@ var init_npm_package_manager = __esm(() => {
75127
75224
  });
75128
75225
 
75129
75226
  // src/services/package-installer/install-error-handler.ts
75130
- import { existsSync as existsSync62, readFileSync as readFileSync19, unlinkSync as unlinkSync3 } from "node:fs";
75227
+ import { existsSync as existsSync62, readFileSync as readFileSync20, unlinkSync as unlinkSync3 } from "node:fs";
75131
75228
  import { join as join92 } from "node:path";
75132
75229
  function parseNameReason(str2) {
75133
75230
  const colonIndex = str2.indexOf(":");
@@ -75198,7 +75295,7 @@ function displayInstallErrors(skillsDir2) {
75198
75295
  }
75199
75296
  let summary;
75200
75297
  try {
75201
- summary = JSON.parse(readFileSync19(summaryPath, "utf-8"));
75298
+ summary = JSON.parse(readFileSync20(summaryPath, "utf-8"));
75202
75299
  } catch (parseError) {
75203
75300
  logger.error("Failed to parse error summary. File may be corrupted.");
75204
75301
  logger.debug(`Parse error: ${parseError instanceof Error ? parseError.message : String(parseError)}`);
@@ -78326,7 +78423,7 @@ var init_content_validator = __esm(() => {
78326
78423
 
78327
78424
  // src/commands/content/phases/context-cache-manager.ts
78328
78425
  import { createHash as createHash9 } from "node:crypto";
78329
- import { existsSync as existsSync83, mkdirSync as mkdirSync7, readFileSync as readFileSync22, readdirSync as readdirSync14, statSync as statSync15 } from "node:fs";
78426
+ import { existsSync as existsSync83, mkdirSync as mkdirSync7, readFileSync as readFileSync23, readdirSync as readdirSync14, statSync as statSync15 } from "node:fs";
78330
78427
  import { rename as rename16, writeFile as writeFile43 } from "node:fs/promises";
78331
78428
  import { homedir as homedir54 } from "node:os";
78332
78429
  import { basename as basename34, join as join167 } from "node:path";
@@ -78335,7 +78432,7 @@ function getCachedContext(repoPath) {
78335
78432
  if (!existsSync83(cachePath))
78336
78433
  return null;
78337
78434
  try {
78338
- const raw2 = readFileSync22(cachePath, "utf-8");
78435
+ const raw2 = readFileSync23(cachePath, "utf-8");
78339
78436
  const cache5 = JSON.parse(raw2);
78340
78437
  const age = Date.now() - new Date(cache5.createdAt).getTime();
78341
78438
  if (age >= CACHE_TTL_MS5)
@@ -78583,7 +78680,7 @@ function extractContentFromResponse(response) {
78583
78680
 
78584
78681
  // src/commands/content/phases/docs-summarizer.ts
78585
78682
  import { execSync as execSync7 } from "node:child_process";
78586
- import { existsSync as existsSync84, readFileSync as readFileSync23, readdirSync as readdirSync15 } from "node:fs";
78683
+ import { existsSync as existsSync84, readFileSync as readFileSync24, readdirSync as readdirSync15 } from "node:fs";
78587
78684
  import { join as join168 } from "node:path";
78588
78685
  async function summarizeProjectDocs(repoPath, contentLogger) {
78589
78686
  const rawContent = collectRawDocs(repoPath);
@@ -78632,7 +78729,7 @@ function collectRawDocs(repoPath) {
78632
78729
  return "";
78633
78730
  if (totalChars >= MAX_RAW_CONTENT_CHARS)
78634
78731
  return "";
78635
- const content = readFileSync23(filePath, "utf-8");
78732
+ const content = readFileSync24(filePath, "utf-8");
78636
78733
  const capped = content.slice(0, Math.min(maxChars, MAX_RAW_CONTENT_CHARS - totalChars));
78637
78734
  totalChars += capped.length;
78638
78735
  return capped;
@@ -79126,7 +79223,7 @@ var init_sqlite_client = __esm(() => {
79126
79223
 
79127
79224
  // src/commands/content/phases/db-manager.ts
79128
79225
  import { existsSync as existsSync87, mkdirSync as mkdirSync10 } from "node:fs";
79129
- import { dirname as dirname55 } from "node:path";
79226
+ import { dirname as dirname56 } from "node:path";
79130
79227
  function initDatabase(dbPath) {
79131
79228
  ensureParentDir(dbPath);
79132
79229
  const db = openDatabase(dbPath);
@@ -79147,7 +79244,7 @@ function runRetentionCleanup(db, retentionDays = 90) {
79147
79244
  db.prepare("DELETE FROM git_events WHERE processed = 1 AND created_at < ?").run(cutoff);
79148
79245
  }
79149
79246
  function ensureParentDir(dbPath) {
79150
- const dir = dirname55(dbPath);
79247
+ const dir = dirname56(dbPath);
79151
79248
  if (dir && !existsSync87(dir)) {
79152
79249
  mkdirSync10(dir, { recursive: true });
79153
79250
  }
@@ -79313,7 +79410,7 @@ function isNoiseCommit(title, author) {
79313
79410
 
79314
79411
  // src/commands/content/phases/change-detector.ts
79315
79412
  import { execSync as execSync10, spawnSync as spawnSync9 } from "node:child_process";
79316
- import { existsSync as existsSync88, readFileSync as readFileSync24, readdirSync as readdirSync17, statSync as statSync17 } from "node:fs";
79413
+ import { existsSync as existsSync88, readFileSync as readFileSync25, readdirSync as readdirSync17, statSync as statSync17 } from "node:fs";
79317
79414
  import { join as join171 } from "node:path";
79318
79415
  function detectCommits(repo, since) {
79319
79416
  try {
@@ -79440,7 +79537,7 @@ function detectCompletedPlans(repo, since) {
79440
79537
  const stat26 = statSync17(planFile);
79441
79538
  if (stat26.mtimeMs < sinceMs)
79442
79539
  continue;
79443
- const content = readFileSync24(planFile, "utf-8");
79540
+ const content = readFileSync25(planFile, "utf-8");
79444
79541
  const frontmatterMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
79445
79542
  if (!frontmatterMatch)
79446
79543
  continue;
@@ -80205,7 +80302,7 @@ async function loadContentConfig(projectDir) {
80205
80302
  }
80206
80303
  async function saveContentConfig(projectDir, config) {
80207
80304
  const configPath = join173(projectDir, CK_CONFIG_FILE2);
80208
- const json = await readJsonSafe4(configPath);
80305
+ const json = await readJsonSafe5(configPath);
80209
80306
  json.content = { ...json.content, ...config };
80210
80307
  await atomicWrite3(configPath, json);
80211
80308
  }
@@ -80230,14 +80327,14 @@ async function saveContentState(projectDir, state) {
80230
80327
  }
80231
80328
  }
80232
80329
  ContentStateSchema.parse(state);
80233
- const json = await readJsonSafe4(configPath);
80330
+ const json = await readJsonSafe5(configPath);
80234
80331
  if (!json.content || typeof json.content !== "object") {
80235
80332
  json.content = {};
80236
80333
  }
80237
80334
  json.content.state = state;
80238
80335
  await atomicWrite3(configPath, json);
80239
80336
  }
80240
- async function readJsonSafe4(filePath) {
80337
+ async function readJsonSafe5(filePath) {
80241
80338
  try {
80242
80339
  const raw2 = await readFile72(filePath, "utf-8");
80243
80340
  return JSON.parse(raw2);
@@ -80712,7 +80809,7 @@ __export(exports_content_subcommands, {
80712
80809
  logsContent: () => logsContent,
80713
80810
  approveContentCmd: () => approveContentCmd
80714
80811
  });
80715
- import { existsSync as existsSync91, readFileSync as readFileSync25, unlinkSync as unlinkSync6 } from "node:fs";
80812
+ import { existsSync as existsSync91, readFileSync as readFileSync26, unlinkSync as unlinkSync6 } from "node:fs";
80716
80813
  import { homedir as homedir58 } from "node:os";
80717
80814
  import { join as join175 } from "node:path";
80718
80815
  function isDaemonRunning() {
@@ -80720,7 +80817,7 @@ function isDaemonRunning() {
80720
80817
  if (!existsSync91(lockFile))
80721
80818
  return { running: false, pid: null };
80722
80819
  try {
80723
- const pidStr = readFileSync25(lockFile, "utf-8").trim();
80820
+ const pidStr = readFileSync26(lockFile, "utf-8").trim();
80724
80821
  const pid = Number.parseInt(pidStr, 10);
80725
80822
  if (Number.isNaN(pid)) {
80726
80823
  unlinkSync6(lockFile);
@@ -80754,7 +80851,7 @@ async function stopContent() {
80754
80851
  return;
80755
80852
  }
80756
80853
  try {
80757
- const pidStr = readFileSync25(lockFile, "utf-8").trim();
80854
+ const pidStr = readFileSync26(lockFile, "utf-8").trim();
80758
80855
  const pid = Number.parseInt(pidStr, 10);
80759
80856
  if (!Number.isNaN(pid)) {
80760
80857
  process.kill(pid, "SIGTERM");
@@ -80802,7 +80899,7 @@ async function logsContent(options2) {
80802
80899
  process.exit(0);
80803
80900
  });
80804
80901
  } else {
80805
- const content = readFileSync25(logPath, "utf-8");
80902
+ const content = readFileSync26(logPath, "utf-8");
80806
80903
  console.log(content);
80807
80904
  }
80808
80905
  }
@@ -88177,7 +88274,7 @@ import { promisify as promisify14 } from "node:util";
88177
88274
  // src/domains/github/gh-cli-utils.ts
88178
88275
  init_environment();
88179
88276
  init_logger();
88180
- import { readFileSync as readFileSync15 } from "node:fs";
88277
+ import { readFileSync as readFileSync16 } from "node:fs";
88181
88278
  var MIN_GH_CLI_VERSION = "2.20.0";
88182
88279
  var GH_COMMAND_TIMEOUT_MS = 1e4;
88183
88280
  function compareVersions6(a3, b3) {
@@ -88198,7 +88295,7 @@ function isWSL2() {
88198
88295
  if (process.platform !== "linux")
88199
88296
  return false;
88200
88297
  try {
88201
- const release = readFileSync15("/proc/version", "utf-8").toLowerCase();
88298
+ const release = readFileSync16("/proc/version", "utf-8").toLowerCase();
88202
88299
  return release.includes("microsoft") || release.includes("wsl");
88203
88300
  } catch (error) {
88204
88301
  logger.debug(`WSL detection skipped: ${error instanceof Error ? error.message : "unknown error"}`);
@@ -89027,7 +89124,7 @@ function checkClaudeMdFile(path7, name, id) {
89027
89124
  }
89028
89125
  }
89029
89126
  // src/domains/health-checks/checkers/active-plan-checker.ts
89030
- import { existsSync as existsSync53, readFileSync as readFileSync17 } from "node:fs";
89127
+ import { existsSync as existsSync53, readFileSync as readFileSync18 } from "node:fs";
89031
89128
  import { join as join74 } from "node:path";
89032
89129
  function checkActivePlan(projectDir) {
89033
89130
  const activePlanPath = join74(projectDir, ".claude", "active-plan");
@@ -89043,7 +89140,7 @@ function checkActivePlan(projectDir) {
89043
89140
  };
89044
89141
  }
89045
89142
  try {
89046
- const targetPath = readFileSync17(activePlanPath, "utf-8").trim();
89143
+ const targetPath = readFileSync18(activePlanPath, "utf-8").trim();
89047
89144
  const fullPath = join74(projectDir, targetPath);
89048
89145
  if (!existsSync53(fullPath)) {
89049
89146
  return {
@@ -91584,7 +91681,7 @@ class AutoHealer {
91584
91681
  }
91585
91682
  // src/domains/health-checks/report-generator.ts
91586
91683
  import { execSync as execSync4, spawnSync as spawnSync6 } from "node:child_process";
91587
- import { readFileSync as readFileSync18, unlinkSync as unlinkSync2, writeFileSync as writeFileSync6 } from "node:fs";
91684
+ import { readFileSync as readFileSync19, unlinkSync as unlinkSync2, writeFileSync as writeFileSync6 } from "node:fs";
91588
91685
  import { tmpdir as tmpdir3 } from "node:os";
91589
91686
  import { dirname as dirname33, join as join88 } from "node:path";
91590
91687
  import { fileURLToPath as fileURLToPath4 } from "node:url";
@@ -91595,7 +91692,7 @@ function getCliVersion4() {
91595
91692
  try {
91596
91693
  const __dirname4 = dirname33(fileURLToPath4(import.meta.url));
91597
91694
  const pkgPath = join88(__dirname4, "../../../package.json");
91598
- const pkg = JSON.parse(readFileSync18(pkgPath, "utf-8"));
91695
+ const pkg = JSON.parse(readFileSync19(pkgPath, "utf-8"));
91599
91696
  return pkg.version || "unknown";
91600
91697
  } catch (err) {
91601
91698
  logger.debug(`Failed to read CLI version: ${err}`);
@@ -92075,7 +92172,7 @@ init_config_version_checker();
92075
92172
 
92076
92173
  // src/domains/sync/sync-engine.ts
92077
92174
  import { lstat as lstat6, readFile as readFile48, readlink as readlink2, realpath as realpath8, stat as stat14 } from "node:fs/promises";
92078
- import { isAbsolute as isAbsolute11, join as join89, normalize as normalize8, relative as relative18 } from "node:path";
92175
+ import { isAbsolute as isAbsolute12, join as join89, normalize as normalize8, relative as relative18 } from "node:path";
92079
92176
 
92080
92177
  // src/services/file-operations/ownership-checker.ts
92081
92178
  init_metadata_migration();
@@ -93290,10 +93387,10 @@ async function validateSymlinkChain(path8, basePath, maxDepth = MAX_SYMLINK_DEPT
93290
93387
  if (!stats.isSymbolicLink())
93291
93388
  break;
93292
93389
  const target = await readlink2(current);
93293
- const resolvedTarget = isAbsolute11(target) ? target : join89(current, "..", target);
93390
+ const resolvedTarget = isAbsolute12(target) ? target : join89(current, "..", target);
93294
93391
  const normalizedTarget = normalize8(resolvedTarget);
93295
93392
  const rel = relative18(basePath, normalizedTarget);
93296
- if (rel.startsWith("..") || isAbsolute11(rel)) {
93393
+ if (rel.startsWith("..") || isAbsolute12(rel)) {
93297
93394
  throw new Error(`Symlink chain escapes base directory at depth ${depth}: ${path8}`);
93298
93395
  }
93299
93396
  current = normalizedTarget;
@@ -93320,7 +93417,7 @@ async function validateSyncPath(basePath, filePath) {
93320
93417
  throw new Error(`Path too long: ${filePath.slice(0, 50)}...`);
93321
93418
  }
93322
93419
  const normalized = normalize8(filePath);
93323
- if (isAbsolute11(normalized)) {
93420
+ if (isAbsolute12(normalized)) {
93324
93421
  throw new Error(`Absolute paths not allowed: ${filePath}`);
93325
93422
  }
93326
93423
  if (normalized.startsWith("..") || normalized.includes("/../")) {
@@ -93328,7 +93425,7 @@ async function validateSyncPath(basePath, filePath) {
93328
93425
  }
93329
93426
  const fullPath = join89(basePath, normalized);
93330
93427
  const rel = relative18(basePath, fullPath);
93331
- if (rel.startsWith("..") || isAbsolute11(rel)) {
93428
+ if (rel.startsWith("..") || isAbsolute12(rel)) {
93332
93429
  throw new Error(`Path escapes base directory: ${filePath}`);
93333
93430
  }
93334
93431
  await validateSymlinkChain(fullPath, basePath);
@@ -93336,7 +93433,7 @@ async function validateSyncPath(basePath, filePath) {
93336
93433
  const resolvedBase = await realpath8(basePath);
93337
93434
  const resolvedFull = await realpath8(fullPath);
93338
93435
  const resolvedRel = relative18(resolvedBase, resolvedFull);
93339
- if (resolvedRel.startsWith("..") || isAbsolute11(resolvedRel)) {
93436
+ if (resolvedRel.startsWith("..") || isAbsolute12(resolvedRel)) {
93340
93437
  throw new Error(`Symlink escapes base directory: ${filePath}`);
93341
93438
  }
93342
93439
  } catch (error) {
@@ -93346,7 +93443,7 @@ async function validateSyncPath(basePath, filePath) {
93346
93443
  const resolvedBase = await realpath8(basePath);
93347
93444
  const resolvedParent = await realpath8(parentPath);
93348
93445
  const resolvedRel = relative18(resolvedBase, resolvedParent);
93349
- if (resolvedRel.startsWith("..") || isAbsolute11(resolvedRel)) {
93446
+ if (resolvedRel.startsWith("..") || isAbsolute12(resolvedRel)) {
93350
93447
  throw new Error(`Parent symlink escapes base directory: ${filePath}`);
93351
93448
  }
93352
93449
  } catch (parentError) {
@@ -99195,11 +99292,11 @@ var modeFix = (mode, isDir2, portable) => {
99195
99292
 
99196
99293
  // node_modules/tar/dist/esm/strip-absolute-path.js
99197
99294
  import { win32 as win322 } from "node:path";
99198
- var { isAbsolute: isAbsolute12, parse: parse5 } = win322;
99295
+ var { isAbsolute: isAbsolute13, parse: parse5 } = win322;
99199
99296
  var stripAbsolutePath = (path8) => {
99200
99297
  let r2 = "";
99201
99298
  let parsed = parse5(path8);
99202
- while (isAbsolute12(path8) || parsed.root) {
99299
+ while (isAbsolute13(path8) || parsed.root) {
99203
99300
  const root = path8.charAt(0) === "/" && path8.slice(0, 4) !== "//?/" ? "/" : parsed.root;
99204
99301
  path8 = path8.slice(root.length);
99205
99302
  r2 += root;
@@ -109028,12 +109125,12 @@ async function handlePostInstall(ctx) {
109028
109125
  }
109029
109126
  // src/commands/init/phases/plugin-install-handler.ts
109030
109127
  init_codex_plugin_installer();
109031
- import { cpSync as cpSync2, existsSync as existsSync69, mkdirSync as mkdirSync6, readFileSync as readFileSync21, rmSync as rmSync4, writeFileSync as writeFileSync8 } from "node:fs";
109128
+ import { cpSync as cpSync2, existsSync as existsSync69, mkdirSync as mkdirSync6, readFileSync as readFileSync22, rmSync as rmSync4, writeFileSync as writeFileSync8 } from "node:fs";
109032
109129
  import { join as join136 } from "node:path";
109033
109130
 
109034
109131
  // src/domains/installation/plugin/migrate-legacy-to-plugin.ts
109035
109132
  init_install_mode_detector();
109036
- import { cpSync, existsSync as existsSync68, mkdirSync as mkdirSync5, readFileSync as readFileSync20, rmSync as rmSync3, writeFileSync as writeFileSync7 } from "node:fs";
109133
+ import { cpSync, existsSync as existsSync68, mkdirSync as mkdirSync5, readFileSync as readFileSync21, rmSync as rmSync3, writeFileSync as writeFileSync7 } from "node:fs";
109037
109134
  import { dirname as dirname43, join as join135 } from "node:path";
109038
109135
 
109039
109136
  // src/domains/installation/plugin/plugin-installer.ts
@@ -109200,7 +109297,7 @@ function base(action, modeBefore, pluginVerified) {
109200
109297
  }
109201
109298
  var PLUGIN_SUPPLIED_LEGACY_PREFIXES2 = ["agents/", "skills/"];
109202
109299
  function defaultLegacyRemover(claudeDir3, backupDir) {
109203
- const meta = readJsonSafe2(join135(claudeDir3, "metadata.json"));
109300
+ const meta = readJsonSafe3(join135(claudeDir3, "metadata.json"));
109204
109301
  const files = collectTrackedFiles2(meta);
109205
109302
  const removed = [];
109206
109303
  for (const file of files) {
@@ -109224,22 +109321,22 @@ function isPluginSuppliedLegacyPath(pathValue) {
109224
109321
  return PLUGIN_SUPPLIED_LEGACY_PREFIXES2.some((prefix) => normalized.startsWith(prefix));
109225
109322
  }
109226
109323
  function collectTrackedFiles2(meta) {
109227
- if (!isRecord2(meta))
109324
+ if (!isRecord3(meta))
109228
109325
  return [];
109229
109326
  const out = [];
109230
109327
  const push2 = (arr) => {
109231
109328
  if (!Array.isArray(arr))
109232
109329
  return;
109233
109330
  for (const f3 of arr) {
109234
- if (isRecord2(f3) && typeof f3.path === "string") {
109331
+ if (isRecord3(f3) && typeof f3.path === "string") {
109235
109332
  const ownership = f3.ownership === "user" || f3.ownership === "ck-modified" ? f3.ownership : "ck";
109236
109333
  out.push({ path: f3.path, ownership });
109237
109334
  }
109238
109335
  }
109239
109336
  };
109240
- if (isRecord2(meta.kits)) {
109337
+ if (isRecord3(meta.kits)) {
109241
109338
  const engineer = meta.kits[ENGINEER_KIT_KEY];
109242
- if (isRecord2(engineer))
109339
+ if (isRecord3(engineer))
109243
109340
  push2(engineer.files);
109244
109341
  } else {
109245
109342
  push2(meta.files);
@@ -109248,21 +109345,21 @@ function collectTrackedFiles2(meta) {
109248
109345
  }
109249
109346
  function writeReceipt(claudeDir3, receipt) {
109250
109347
  const receiptPath = join135(claudeDir3, ".ck-migration-log.json");
109251
- const existing = readJsonSafe2(receiptPath);
109348
+ const existing = readJsonSafe3(receiptPath);
109252
109349
  const history = Array.isArray(existing) ? existing : [];
109253
109350
  history.push(receipt);
109254
109351
  writeFileSync7(receiptPath, `${JSON.stringify(history, null, 2)}
109255
109352
  `, "utf-8");
109256
109353
  return receiptPath;
109257
109354
  }
109258
- function readJsonSafe2(filePath) {
109355
+ function readJsonSafe3(filePath) {
109259
109356
  try {
109260
- return JSON.parse(readFileSync20(filePath, "utf-8"));
109357
+ return JSON.parse(readFileSync21(filePath, "utf-8"));
109261
109358
  } catch {
109262
109359
  return null;
109263
109360
  }
109264
109361
  }
109265
- function isRecord2(value) {
109362
+ function isRecord3(value) {
109266
109363
  return typeof value === "object" && value !== null && !Array.isArray(value);
109267
109364
  }
109268
109365
 
@@ -109335,7 +109432,7 @@ function ensureCodexPluginManifest(pluginRoot) {
109335
109432
  const manifestPath = join136(pluginRoot, ".codex-plugin", "plugin.json");
109336
109433
  if (existsSync69(manifestPath))
109337
109434
  return;
109338
- const claudeManifest = readJsonSafe3(join136(pluginRoot, ".claude-plugin", "plugin.json"));
109435
+ const claudeManifest = readJsonSafe4(join136(pluginRoot, ".claude-plugin", "plugin.json"));
109339
109436
  const manifest = pruneUndefined({
109340
109437
  name: stringField(claudeManifest, "name") ?? "ck",
109341
109438
  version: stringField(claudeManifest, "version") ?? "0.0.0",
@@ -109360,10 +109457,10 @@ function ensureCodexPluginManifest(pluginRoot) {
109360
109457
  writeFileSync8(manifestPath, `${JSON.stringify(manifest, null, 2)}
109361
109458
  `, "utf-8");
109362
109459
  }
109363
- function readJsonSafe3(filePath) {
109460
+ function readJsonSafe4(filePath) {
109364
109461
  try {
109365
- const parsed = JSON.parse(readFileSync21(filePath, "utf-8"));
109366
- return isRecord3(parsed) ? parsed : null;
109462
+ const parsed = JSON.parse(readFileSync22(filePath, "utf-8"));
109463
+ return isRecord4(parsed) ? parsed : null;
109367
109464
  } catch {
109368
109465
  return null;
109369
109466
  }
@@ -109374,7 +109471,7 @@ function stringField(source, key) {
109374
109471
  }
109375
109472
  function authorField(source) {
109376
109473
  const author = source?.author;
109377
- if (isRecord3(author) && typeof author.name === "string" && author.name.trim() !== "") {
109474
+ if (isRecord4(author) && typeof author.name === "string" && author.name.trim() !== "") {
109378
109475
  return { name: author.name };
109379
109476
  }
109380
109477
  return { name: "ClaudeKit" };
@@ -109382,7 +109479,7 @@ function authorField(source) {
109382
109479
  function pruneUndefined(value) {
109383
109480
  return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== undefined));
109384
109481
  }
109385
- function isRecord3(value) {
109482
+ function isRecord4(value) {
109386
109483
  return typeof value === "object" && value !== null && !Array.isArray(value);
109387
109484
  }
109388
109485
  function logPluginResult(result) {
@@ -111495,7 +111592,7 @@ var import_picocolors30 = __toESM(require_picocolors(), 1);
111495
111592
  import { existsSync as existsSync71 } from "node:fs";
111496
111593
  import { readFile as readFile67, rm as rm18, unlink as unlink14 } from "node:fs/promises";
111497
111594
  import { homedir as homedir52 } from "node:os";
111498
- import { basename as basename30, join as join148, resolve as resolve48 } from "node:path";
111595
+ import { basename as basename30, dirname as dirname49, join as join148, resolve as resolve48 } from "node:path";
111499
111596
  init_logger();
111500
111597
 
111501
111598
  // src/ui/ck-cli-design/next-steps-footer.ts
@@ -113011,6 +113108,24 @@ function createSkippedPathMigrationCleanupResult2(action) {
113011
113108
  skipReason: "Legacy path cleanup skipped because no successful replacement write was recorded"
113012
113109
  };
113013
113110
  }
113111
+ function resolveHookTargetPath(item, provider, global3) {
113112
+ const pathConfig = providers[provider].hooks;
113113
+ if (!pathConfig)
113114
+ return null;
113115
+ const basePath = global3 ? pathConfig.globalPath : pathConfig.projectPath;
113116
+ if (!basePath)
113117
+ return null;
113118
+ const converted = convertItem(item, pathConfig.format, provider, { global: global3 });
113119
+ if (converted.error)
113120
+ return null;
113121
+ const targetPath = pathConfig.writeStrategy === "single-file" ? basePath : join148(basePath, converted.filename);
113122
+ const resolvedTarget = resolve48(targetPath).replace(/\\/g, "/");
113123
+ const resolvedBase = resolve48(basePath).replace(/\\/g, "/").replace(/\/+$/, "");
113124
+ if (resolvedTarget !== resolvedBase && !resolvedTarget.startsWith(`${resolvedBase}/`)) {
113125
+ return null;
113126
+ }
113127
+ return targetPath;
113128
+ }
113014
113129
  async function processMetadataDeletions(skillSourcePath, installGlobally) {
113015
113130
  if (!skillSourcePath)
113016
113131
  return;
@@ -113418,23 +113533,31 @@ async function migrateCommand(options2) {
113418
113533
  }
113419
113534
  const progressSink = createMigrateProgressSink(writeTasks.length + plannedDeleteActions.length);
113420
113535
  const writtenPaths = new Set;
113536
+ const recordHookTargetForSettings = (provider, global3, targetPath) => {
113537
+ if (targetPath.length === 0 || !existsSync71(targetPath))
113538
+ return;
113539
+ const resolvedPath = resolve48(targetPath);
113540
+ const entry = successfulHookFiles.get(provider) ?? {
113541
+ files: [],
113542
+ global: global3
113543
+ };
113544
+ const hookFile = basename30(targetPath);
113545
+ if (!entry.files.includes(hookFile))
113546
+ entry.files.push(hookFile);
113547
+ successfulHookFiles.set(provider, entry);
113548
+ const absExisting = successfulHookAbsPaths.get(provider) ?? [];
113549
+ if (!absExisting.includes(resolvedPath)) {
113550
+ absExisting.push(resolvedPath);
113551
+ successfulHookAbsPaths.set(provider, absExisting);
113552
+ }
113553
+ };
113421
113554
  const recordSuccessfulWrites = (task, taskResults) => {
113422
- for (const result of taskResults.filter((entry) => entry.success && !entry.skipped)) {
113423
- if (result.path.length > 0) {
113555
+ for (const result of taskResults.filter((entry) => entry.success)) {
113556
+ if (!result.skipped && result.path.length > 0) {
113424
113557
  writtenPaths.add(resolve48(result.path));
113425
113558
  }
113426
113559
  if (task.type === "hooks") {
113427
- const existing = successfulHookFiles.get(task.provider) ?? {
113428
- files: [],
113429
- global: task.global
113430
- };
113431
- existing.files.push(basename30(result.path));
113432
- successfulHookFiles.set(task.provider, existing);
113433
- if (result.path.length > 0) {
113434
- const absExisting = successfulHookAbsPaths.get(task.provider) ?? [];
113435
- absExisting.push(resolve48(result.path));
113436
- successfulHookAbsPaths.set(task.provider, absExisting);
113437
- }
113560
+ recordHookTargetForSettings(task.provider, task.global, result.path);
113438
113561
  }
113439
113562
  }
113440
113563
  };
@@ -113469,6 +113592,18 @@ async function migrateCommand(options2) {
113469
113592
  recordSuccessfulWrites(task, taskResults);
113470
113593
  progressSink.tick(progressLabelForType(task.type));
113471
113594
  }
113595
+ if (hooksSource && effectiveHookItems.length > 0) {
113596
+ for (const provider of selectedProviders) {
113597
+ if (!getProvidersSupporting("hooks").includes(provider))
113598
+ continue;
113599
+ const global3 = resolvePortableTypeGlobal(provider, "hooks", installGlobally);
113600
+ for (const item of effectiveHookItems) {
113601
+ const targetPath = resolveHookTargetPath(item, provider, global3);
113602
+ if (targetPath)
113603
+ recordHookTargetForSettings(provider, global3, targetPath);
113604
+ }
113605
+ }
113606
+ }
113472
113607
  if (selectedProviders.includes("opencode")) {
113473
113608
  try {
113474
113609
  const result = await ensureOpenCodeModel({
@@ -113518,12 +113653,15 @@ async function migrateCommand(options2) {
113518
113653
  for (const [hooksProvider, entry] of successfulHookFiles) {
113519
113654
  if (entry.files.length === 0)
113520
113655
  continue;
113656
+ const sourceSettingsPath = hooksSource ? join148(dirname49(hooksSource), "settings.json") : undefined;
113521
113657
  const mergeResult = await migrateHooksSettings({
113522
113658
  sourceProvider: "claude-code",
113523
113659
  targetProvider: hooksProvider,
113524
113660
  installedHookFiles: entry.files,
113525
113661
  installedHookAbsolutePaths: successfulHookAbsPaths.get(hooksProvider),
113526
- global: entry.global
113662
+ global: entry.global,
113663
+ sourceSettingsPath,
113664
+ sourceHooksDir: hooksSource ?? undefined
113527
113665
  });
113528
113666
  appendMigrationWarningMessages(postProgressWarnings, mergeResult.warnings);
113529
113667
  if (mergeResult.success && mergeResult.hooksRegistered > 0) {
@@ -114170,7 +114308,7 @@ Please use only one download method.`);
114170
114308
  // src/commands/plan/plan-command.ts
114171
114309
  init_output_manager();
114172
114310
  import { existsSync as existsSync74, statSync as statSync13 } from "node:fs";
114173
- import { dirname as dirname52, isAbsolute as isAbsolute14, join as join153, parse as parse7, resolve as resolve53 } from "node:path";
114311
+ import { dirname as dirname53, isAbsolute as isAbsolute15, join as join153, parse as parse7, resolve as resolve53 } from "node:path";
114174
114312
 
114175
114313
  // src/commands/plan/plan-read-handlers.ts
114176
114314
  init_config();
@@ -114180,18 +114318,18 @@ init_logger();
114180
114318
  init_output_manager();
114181
114319
  var import_picocolors32 = __toESM(require_picocolors(), 1);
114182
114320
  import { existsSync as existsSync73, statSync as statSync12 } from "node:fs";
114183
- import { basename as basename31, dirname as dirname50, join as join152, relative as relative32, resolve as resolve51 } from "node:path";
114321
+ import { basename as basename31, dirname as dirname51, join as join152, relative as relative32, resolve as resolve51 } from "node:path";
114184
114322
 
114185
114323
  // src/commands/plan/plan-dependencies.ts
114186
114324
  init_config();
114187
114325
  init_plan_parser();
114188
114326
  init_plans_registry();
114189
114327
  import { existsSync as existsSync72 } from "node:fs";
114190
- import { dirname as dirname49, join as join151 } from "node:path";
114328
+ import { dirname as dirname50, join as join151 } from "node:path";
114191
114329
  async function resolvePlanDependencies(references, currentPlanFile, options2 = {}) {
114192
114330
  if (references.length === 0)
114193
114331
  return [];
114194
- const currentPlanDir = dirname49(currentPlanFile);
114332
+ const currentPlanDir = dirname50(currentPlanFile);
114195
114333
  const projectRoot = findProjectRoot(currentPlanDir);
114196
114334
  const config = options2.preloadedConfig ?? (await CkConfigManager.loadFull(projectRoot)).config;
114197
114335
  const defaultScope = inferPlanScopeForDir(currentPlanDir, config);
@@ -114238,14 +114376,14 @@ init_config();
114238
114376
  init_plan_parser();
114239
114377
  init_plan_scope();
114240
114378
  init_plans_registry();
114241
- import { isAbsolute as isAbsolute13, resolve as resolve50 } from "node:path";
114379
+ import { isAbsolute as isAbsolute14, resolve as resolve50 } from "node:path";
114242
114380
  async function getGlobalPlansDirFromCwd() {
114243
114381
  const projectRoot = findProjectRoot(process.cwd());
114244
114382
  const { config } = await CkConfigManager.loadFull(projectRoot);
114245
114383
  return resolveGlobalPlansDir(config);
114246
114384
  }
114247
114385
  function resolveTargetFromBase(target, baseDir) {
114248
- const resolvedTarget = isAbsolute13(target) ? resolve50(target) : resolve50(baseDir, target);
114386
+ const resolvedTarget = isAbsolute14(target) ? resolve50(target) : resolve50(baseDir, target);
114249
114387
  return isWithinDir(resolvedTarget, baseDir) ? resolvedTarget : null;
114250
114388
  }
114251
114389
 
@@ -114278,7 +114416,7 @@ async function handleParse(target, options2) {
114278
114416
  console.log(JSON.stringify({ file: relative32(process.cwd(), planFile), frontmatter, phases }, null, 2));
114279
114417
  return;
114280
114418
  }
114281
- const title = typeof frontmatter.title === "string" ? frontmatter.title : basename31(dirname50(planFile));
114419
+ const title = typeof frontmatter.title === "string" ? frontmatter.title : basename31(dirname51(planFile));
114282
114420
  console.log();
114283
114421
  console.log(import_picocolors32.default.bold(` Plan: ${title}`));
114284
114422
  console.log(` File: ${planFile}`);
@@ -114389,7 +114527,7 @@ async function handleStatus(target, options2) {
114389
114527
  const blockedBy2 = await resolvePlanDependencies(s.blockedBy, pf, { preloadedConfig });
114390
114528
  const blocks2 = await resolvePlanDependencies(s.blocks, pf, { preloadedConfig });
114391
114529
  const bar = progressBar(s.completed, s.totalPhases);
114392
- const title2 = s.title ?? basename31(dirname50(pf));
114530
+ const title2 = s.title ?? basename31(dirname51(pf));
114393
114531
  console.log(` ${import_picocolors32.default.bold(title2)}`);
114394
114532
  console.log(` ${bar}`);
114395
114533
  if (s.inProgress > 0)
@@ -114408,7 +114546,7 @@ async function handleStatus(target, options2) {
114408
114546
  }
114409
114547
  console.log();
114410
114548
  } catch {
114411
- console.log(` [X] Failed to read: ${basename31(dirname50(pf))}`);
114549
+ console.log(` [X] Failed to read: ${basename31(dirname51(pf))}`);
114412
114550
  console.log();
114413
114551
  }
114414
114552
  }
@@ -114435,7 +114573,7 @@ async function handleStatus(target, options2) {
114435
114573
  console.log(JSON.stringify({ ...summary, dependencyStatus: { blockedBy, blocks } }, null, 2));
114436
114574
  return;
114437
114575
  }
114438
- const title = summary.title ?? basename31(dirname50(planFile));
114576
+ const title = summary.title ?? basename31(dirname51(planFile));
114439
114577
  console.log();
114440
114578
  console.log(import_picocolors32.default.bold(` ${title}`));
114441
114579
  if (summary.status)
@@ -114498,7 +114636,7 @@ async function handleKanban(target, options2) {
114498
114636
  process.exitCode = 1;
114499
114637
  return;
114500
114638
  }
114501
- const route = `/plans?dir=${encodeURIComponent(dirname50(dirname50(planFile)))}&view=kanban`;
114639
+ const route = `/plans?dir=${encodeURIComponent(dirname51(dirname51(planFile)))}&view=kanban`;
114502
114640
  const url = `http://localhost:${server.port}${route}`;
114503
114641
  console.log();
114504
114642
  console.log(import_picocolors32.default.bold(" ClaudeKit Dashboard — Plans"));
@@ -114533,7 +114671,7 @@ init_plan_parser();
114533
114671
  init_plans_registry();
114534
114672
  init_output_manager();
114535
114673
  var import_picocolors33 = __toESM(require_picocolors(), 1);
114536
- import { basename as basename32, dirname as dirname51, relative as relative33, resolve as resolve52 } from "node:path";
114674
+ import { basename as basename32, dirname as dirname52, relative as relative33, resolve as resolve52 } from "node:path";
114537
114675
  function quoteReadTarget(filePath) {
114538
114676
  return `"${filePath.replace(/\\/g, "/").replace(/"/g, "\\\"")}"`;
114539
114677
  }
@@ -114647,7 +114785,7 @@ async function handleCheck(target, options2) {
114647
114785
  process.exitCode = 1;
114648
114786
  return;
114649
114787
  }
114650
- const planDir = dirname51(planFile);
114788
+ const planDir = dirname52(planFile);
114651
114789
  let planStatus = "pending";
114652
114790
  try {
114653
114791
  const projectRoot = findProjectRoot(planDir);
@@ -114696,7 +114834,7 @@ async function handleUncheck(target, options2) {
114696
114834
  process.exitCode = 1;
114697
114835
  return;
114698
114836
  }
114699
- const planDir = dirname51(planFile);
114837
+ const planDir = dirname52(planFile);
114700
114838
  try {
114701
114839
  const projectRoot = findProjectRoot(planDir);
114702
114840
  const summary = buildPlanSummary(planFile);
@@ -114735,7 +114873,7 @@ async function handleAddPhase(target, options2) {
114735
114873
  try {
114736
114874
  const result = addPhase(planFile, target, options2.after);
114737
114875
  try {
114738
- const planDir = dirname51(planFile);
114876
+ const planDir = dirname52(planFile);
114739
114877
  const projectRoot = findProjectRoot(planDir);
114740
114878
  updateRegistryAddPhase({
114741
114879
  planDir,
@@ -114763,7 +114901,7 @@ function resolveTargetPath(target, baseDir) {
114763
114901
  if (!baseDir) {
114764
114902
  return resolve53(target);
114765
114903
  }
114766
- if (isAbsolute14(target)) {
114904
+ if (isAbsolute15(target)) {
114767
114905
  return resolve53(target);
114768
114906
  }
114769
114907
  const cwdCandidate = resolve53(target);
@@ -114789,7 +114927,7 @@ function resolvePlanFile(target, baseDir) {
114789
114927
  const candidate = join153(dir, "plan.md");
114790
114928
  if (existsSync74(candidate))
114791
114929
  return candidate;
114792
- dir = dirname52(dir);
114930
+ dir = dirname53(dir);
114793
114931
  }
114794
114932
  }
114795
114933
  return null;
@@ -116100,7 +116238,7 @@ var import_fs_extra44 = __toESM(require_lib(), 1);
116100
116238
  // src/commands/uninstall/analysis-handler.ts
116101
116239
  init_metadata_migration();
116102
116240
  import { readdirSync as readdirSync12, rmSync as rmSync7 } from "node:fs";
116103
- import { dirname as dirname53, join as join157 } from "node:path";
116241
+ import { dirname as dirname54, join as join157 } from "node:path";
116104
116242
  init_logger();
116105
116243
  init_safe_prompts();
116106
116244
  var import_fs_extra42 = __toESM(require_lib(), 1);
@@ -116122,7 +116260,7 @@ function classifyFileByOwnership(ownership, forceOverwrite, deleteReason) {
116122
116260
  }
116123
116261
  async function cleanupEmptyDirectories3(filePath, installationRoot) {
116124
116262
  let cleaned = 0;
116125
- let currentDir = dirname53(filePath);
116263
+ let currentDir = dirname54(filePath);
116126
116264
  while (currentDir !== installationRoot && currentDir.startsWith(installationRoot)) {
116127
116265
  try {
116128
116266
  const entries = readdirSync12(currentDir);
@@ -116130,7 +116268,7 @@ async function cleanupEmptyDirectories3(filePath, installationRoot) {
116130
116268
  rmSync7(currentDir, { recursive: true });
116131
116269
  cleaned++;
116132
116270
  logger.debug(`Removed empty directory: ${currentDir}`);
116133
- currentDir = dirname53(currentDir);
116271
+ currentDir = dirname54(currentDir);
116134
116272
  } else {
116135
116273
  break;
116136
116274
  }
@@ -118258,7 +118396,7 @@ init_file_io();
118258
118396
  init_logger();
118259
118397
  import { existsSync as existsSync78 } from "node:fs";
118260
118398
  import { mkdir as mkdir41, readFile as readFile71 } from "node:fs/promises";
118261
- import { dirname as dirname54 } from "node:path";
118399
+ import { dirname as dirname55 } from "node:path";
118262
118400
  var PROCESSED_ISSUES_CAP = 500;
118263
118401
  async function readCkJson(projectDir) {
118264
118402
  const configPath = CkConfigManager.getProjectConfigPath(projectDir);
@@ -118288,7 +118426,7 @@ async function loadWatchState(projectDir) {
118288
118426
  }
118289
118427
  async function saveWatchState(projectDir, state) {
118290
118428
  const configPath = CkConfigManager.getProjectConfigPath(projectDir);
118291
- const configDir = dirname54(configPath);
118429
+ const configDir = dirname55(configPath);
118292
118430
  if (!existsSync78(configDir)) {
118293
118431
  await mkdir41(configDir, { recursive: true });
118294
118432
  }
@@ -118962,7 +119100,7 @@ function registerCommands(cli) {
118962
119100
  // src/cli/version-display.ts
118963
119101
  init_package();
118964
119102
  init_config_version_checker();
118965
- import { existsSync as existsSync94, readFileSync as readFileSync26 } from "node:fs";
119103
+ import { existsSync as existsSync94, readFileSync as readFileSync27 } from "node:fs";
118966
119104
  import { join as join178 } from "node:path";
118967
119105
 
118968
119106
  // src/domains/versioning/version-checker.ts
@@ -119302,7 +119440,7 @@ async function displayVersion() {
119302
119440
  const isLocalSameAsGlobal = localMetadataPath === globalMetadataPath;
119303
119441
  if (!isLocalSameAsGlobal && existsSync94(localMetadataPath)) {
119304
119442
  try {
119305
- const rawMetadata = JSON.parse(readFileSync26(localMetadataPath, "utf-8"));
119443
+ const rawMetadata = JSON.parse(readFileSync27(localMetadataPath, "utf-8"));
119306
119444
  const metadata = MetadataSchema.parse(rawMetadata);
119307
119445
  const kitsDisplay = formatInstalledKits(metadata);
119308
119446
  if (kitsDisplay) {
@@ -119316,7 +119454,7 @@ async function displayVersion() {
119316
119454
  }
119317
119455
  if (existsSync94(globalMetadataPath)) {
119318
119456
  try {
119319
- const rawMetadata = JSON.parse(readFileSync26(globalMetadataPath, "utf-8"));
119457
+ const rawMetadata = JSON.parse(readFileSync27(globalMetadataPath, "utf-8"));
119320
119458
  const metadata = MetadataSchema.parse(rawMetadata);
119321
119459
  const kitsDisplay = formatInstalledKits(metadata);
119322
119460
  if (kitsDisplay) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudekit-cli",
3
- "version": "4.5.0-dev.6",
3
+ "version": "4.5.0-dev.7",
4
4
  "description": "CLI tool for bootstrapping and updating ClaudeKit projects",
5
5
  "type": "module",
6
6
  "repository": {