claudekit-cli 4.2.2 → 4.2.3-dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cli-manifest.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "4.2.2",
3
- "generatedAt": "2026-05-12T17:36:03.454Z",
2
+ "version": "4.2.3-dev.1",
3
+ "generatedAt": "2026-05-12T22:38:53.023Z",
4
4
  "commands": {
5
5
  "agents": {
6
6
  "name": "agents",
package/dist/index.js CHANGED
@@ -51663,8 +51663,27 @@ var init_migrate_provider_scopes = __esm(() => {
51663
51663
 
51664
51664
  // src/commands/migrate/skill-directory-installer.ts
51665
51665
  import { existsSync as existsSync22 } from "node:fs";
51666
- import { cp, mkdir as mkdir10, rename as rename6, rm as rm5 } from "node:fs/promises";
51667
- import { join as join40, resolve as resolve15 } from "node:path";
51666
+ import { cp, mkdir as mkdir10, realpath as realpath5, rename as rename6, rm as rm5 } from "node:fs/promises";
51667
+ import { dirname as dirname11, join as join40, resolve as resolve15 } from "node:path";
51668
+ async function canonicalize(path3) {
51669
+ try {
51670
+ return await realpath5(path3);
51671
+ } catch {
51672
+ const parent = dirname11(path3);
51673
+ if (parent === path3) {
51674
+ return resolve15(path3);
51675
+ }
51676
+ try {
51677
+ const canonicalParent = await realpath5(parent);
51678
+ const absPath = resolve15(path3);
51679
+ const absParent = resolve15(parent);
51680
+ const basename13 = absPath.slice(absParent.length + 1) || "";
51681
+ return join40(canonicalParent, basename13);
51682
+ } catch {
51683
+ return resolve15(path3);
51684
+ }
51685
+ }
51686
+ }
51668
51687
  async function installSkillDirectories(skills, targetProviders, options2) {
51669
51688
  const results = [];
51670
51689
  for (const provider of targetProviders) {
@@ -51691,9 +51710,28 @@ async function installSkillDirectories(skills, targetProviders, options2) {
51691
51710
  });
51692
51711
  continue;
51693
51712
  }
51713
+ const sourceRoot = skills.length > 0 ? dirname11(skills[0].path) : null;
51714
+ const canonicalBase = existsSync22(basePath) ? await canonicalize(basePath) : null;
51715
+ const canonicalSourceRoot = sourceRoot ? await canonicalize(sourceRoot) : null;
51716
+ const basePathIsSymlinkedToSource = canonicalBase !== null && canonicalSourceRoot !== null && canonicalBase === canonicalSourceRoot && resolve15(basePath) !== resolve15(sourceRoot ?? "");
51717
+ if (basePathIsSymlinkedToSource) {
51718
+ for (const skill of skills) {
51719
+ results.push({
51720
+ provider,
51721
+ providerDisplayName: config.displayName,
51722
+ success: true,
51723
+ path: join40(basePath, skill.name),
51724
+ skipped: true,
51725
+ skipReason: `Skills directory ${basePath} is symlinked to source (${canonicalBase}); already in place`
51726
+ });
51727
+ }
51728
+ continue;
51729
+ }
51694
51730
  for (const skill of skills) {
51695
51731
  const targetDir = join40(basePath, skill.name);
51696
- if (resolve15(skill.path) === resolve15(targetDir)) {
51732
+ const canonicalSource = await canonicalize(skill.path);
51733
+ const canonicalTarget = await canonicalize(targetDir);
51734
+ if (canonicalSource === canonicalTarget) {
51697
51735
  results.push({
51698
51736
  provider,
51699
51737
  providerDisplayName: config.displayName,
@@ -53885,9 +53923,9 @@ var init_codex_capabilities = __esm(() => {
53885
53923
 
53886
53924
  // src/commands/portable/codex-path-safety.ts
53887
53925
  import { existsSync as existsSync24 } from "node:fs";
53888
- import { mkdir as mkdir12, realpath as realpath5 } from "node:fs/promises";
53926
+ import { mkdir as mkdir12, realpath as realpath6 } from "node:fs/promises";
53889
53927
  import { homedir as homedir25 } from "node:os";
53890
- import { dirname as dirname11, join as join42, resolve as resolve17, sep as sep7 } from "node:path";
53928
+ import { dirname as dirname12, join as join42, resolve as resolve17, sep as sep7 } from "node:path";
53891
53929
  function isPathWithinBoundary3(targetPath, boundaryPath) {
53892
53930
  const resolvedTarget = resolve17(targetPath);
53893
53931
  const resolvedBoundary = resolve17(boundaryPath);
@@ -53895,7 +53933,7 @@ function isPathWithinBoundary3(targetPath, boundaryPath) {
53895
53933
  }
53896
53934
  async function resolveRealPathSafe2(path3) {
53897
53935
  try {
53898
- return await realpath5(path3);
53936
+ return await realpath6(path3);
53899
53937
  } catch {
53900
53938
  return resolve17(path3);
53901
53939
  }
@@ -53906,11 +53944,11 @@ async function isCanonicalPathWithinBoundary2(targetPath, boundaryPath) {
53906
53944
  return isPathWithinBoundary3(canonicalTarget, canonicalBoundary);
53907
53945
  }
53908
53946
  function getCodexLockPath2(targetFilePath) {
53909
- return join42(dirname11(resolve17(targetFilePath)), ".config.toml.ck-codex.lock");
53947
+ return join42(dirname12(resolve17(targetFilePath)), ".config.toml.ck-codex.lock");
53910
53948
  }
53911
53949
  async function withCodexTargetLock2(targetFilePath, operation) {
53912
53950
  const resolvedTargetPath = resolve17(targetFilePath);
53913
- const dir = dirname11(resolvedTargetPath);
53951
+ const dir = dirname12(resolvedTargetPath);
53914
53952
  if (!existsSync24(dir)) {
53915
53953
  await mkdir12(dir, { recursive: true });
53916
53954
  }
@@ -53943,10 +53981,10 @@ var init_codex_path_safety = __esm(() => {
53943
53981
  // src/commands/portable/codex-features-flag.ts
53944
53982
  import { existsSync as existsSync25 } from "node:fs";
53945
53983
  import { readFile as readFile20, rename as rename7, unlink as unlink6, writeFile as writeFile11 } from "node:fs/promises";
53946
- import { dirname as dirname12, resolve as resolve18 } from "node:path";
53984
+ import { dirname as dirname13, resolve as resolve18 } from "node:path";
53947
53985
  async function ensureCodexHooksFeatureFlag(configTomlPath, isGlobal = false) {
53948
- const boundary = isGlobal ? getCodexGlobalBoundary() : dirname12(resolve18(configTomlPath));
53949
- if (!await isCanonicalPathWithinBoundary2(dirname12(resolve18(configTomlPath)), boundary)) {
53986
+ const boundary = isGlobal ? getCodexGlobalBoundary() : dirname13(resolve18(configTomlPath));
53987
+ if (!await isCanonicalPathWithinBoundary2(dirname13(resolve18(configTomlPath)), boundary)) {
53950
53988
  return {
53951
53989
  status: "failed",
53952
53990
  configPath: configTomlPath,
@@ -54112,7 +54150,7 @@ ${SENTINEL_END2}`;
54112
54150
  // src/commands/portable/codex-hook-wrapper.ts
54113
54151
  import { createHash as createHash5 } from "node:crypto";
54114
54152
  import { mkdirSync, writeFileSync as writeFileSync2 } from "node:fs";
54115
- import { dirname as dirname13, join as join43, resolve as resolve19 } from "node:path";
54153
+ import { dirname as dirname14, join as join43, resolve as resolve19 } from "node:path";
54116
54154
  function wrapperFilename(originalPath) {
54117
54155
  const abs = resolve19(originalPath);
54118
54156
  const hash = createHash5("sha256").update(abs).digest("hex").slice(0, 8);
@@ -54135,7 +54173,7 @@ function generateCodexHookWrappers(originalPaths, wrapperDir, capabilities, time
54135
54173
  continue;
54136
54174
  }
54137
54175
  try {
54138
- mkdirSync(dirname13(wrapperPath), { recursive: true });
54176
+ mkdirSync(dirname14(wrapperPath), { recursive: true });
54139
54177
  const resolvedPath = resolve19(originalPath);
54140
54178
  const hookTimeoutMs = timeoutsByPath?.[resolvedPath] ?? timeoutsByPath?.[originalPath];
54141
54179
  const content = buildWrapperScript(originalPath, capabilities, hookTimeoutMs);
@@ -54455,7 +54493,7 @@ var init_gemini_hook_event_map = __esm(() => {
54455
54493
  import { existsSync as existsSync26 } from "node:fs";
54456
54494
  import { mkdir as mkdir13, readFile as readFile21, rename as rename8, rm as rm6, writeFile as writeFile12 } from "node:fs/promises";
54457
54495
  import { homedir as homedir27 } from "node:os";
54458
- import { basename as basename14, dirname as dirname14, join as join44, resolve as resolve20 } from "node:path";
54496
+ import { basename as basename14, dirname as dirname15, join as join44, resolve as resolve20 } from "node:path";
54459
54497
  function validateHooksSectionShape(value) {
54460
54498
  if (!value || typeof value !== "object" || Array.isArray(value)) {
54461
54499
  return "hooks must be a non-null object";
@@ -54606,7 +54644,7 @@ async function mergeHooksIntoSettings(targetSettingsPath, newHooks) {
54606
54644
  const pruned = pruneStaleFileHooks(existingHooks);
54607
54645
  const merged = deduplicateMerge(pruned, newHooks);
54608
54646
  existingSettings.hooks = merged;
54609
- const dir = dirname14(targetSettingsPath);
54647
+ const dir = dirname15(targetSettingsPath);
54610
54648
  await mkdir13(dir, { recursive: true });
54611
54649
  const tempPath = `${targetSettingsPath}.tmp`;
54612
54650
  try {
@@ -56193,7 +56231,7 @@ __export(exports_skills_discovery, {
56193
56231
  });
56194
56232
  import { readFile as readFile24, readdir as readdir13, stat as stat9 } from "node:fs/promises";
56195
56233
  import { homedir as homedir28 } from "node:os";
56196
- import { dirname as dirname15, join as join45 } from "node:path";
56234
+ import { dirname as dirname16, join as join45 } from "node:path";
56197
56235
  function getSkillSourcePath(globalOnly = false) {
56198
56236
  const globalPath = join45(homedir28(), ".claude/skills");
56199
56237
  if (globalOnly) {
@@ -56220,7 +56258,7 @@ async function parseSkillMd(skillMdPath) {
56220
56258
  try {
56221
56259
  const content = await readFile24(skillMdPath, "utf-8");
56222
56260
  const { data } = import_gray_matter5.default(content, { engines: { javascript: { parse: () => ({}) } } });
56223
- const skillDir = dirname15(skillMdPath);
56261
+ const skillDir = dirname16(skillMdPath);
56224
56262
  const dirName = skillDir.split(/[/\\]/).pop() || "";
56225
56263
  if (!dirName) {
56226
56264
  logger.verbose(`Skipping ${skillMdPath}: cannot determine skill directory`);
@@ -58024,7 +58062,7 @@ var init_plan_metadata = __esm(() => {
58024
58062
 
58025
58063
  // src/domains/plan-parser/plan-table-parser.ts
58026
58064
  import { readFileSync as readFileSync7 } from "node:fs";
58027
- import { dirname as dirname16, resolve as resolve22 } from "node:path";
58065
+ import { dirname as dirname17, resolve as resolve22 } from "node:path";
58028
58066
  function normalizeStatus(raw) {
58029
58067
  const s = raw.toLowerCase().trim();
58030
58068
  if (s.includes("complete") || s.includes("done") || s.includes("✓") || s.includes("✅")) {
@@ -58284,7 +58322,7 @@ function parseFormat4(content, planFilePath, options2) {
58284
58322
  const hasCheck = /[✅✓]/.test(line);
58285
58323
  current = { name, status: hasCheck ? "completed" : "pending" };
58286
58324
  } else if (fileMatch && current) {
58287
- const planDir = dirname16(planFilePath);
58325
+ const planDir = dirname17(planFilePath);
58288
58326
  current.file = resolve22(planDir, fileMatch[1].trim());
58289
58327
  } else if (statusMatch && current) {
58290
58328
  current.status = normalizeStatus(statusMatch[2]);
@@ -58389,7 +58427,7 @@ function parsePhasesFromBody(body, dir, options2) {
58389
58427
  }
58390
58428
  function parsePlanFile(planFilePath, options2) {
58391
58429
  const content = readFileSync7(planFilePath, "utf8");
58392
- const dir = dirname16(planFilePath);
58430
+ const dir = dirname17(planFilePath);
58393
58431
  const { data: frontmatter, content: body } = import_gray_matter7.default(content, {
58394
58432
  engines: { javascript: { parse: () => ({}) } }
58395
58433
  });
@@ -58685,12 +58723,12 @@ var init_timeline_builder = __esm(() => {
58685
58723
 
58686
58724
  // src/domains/plan-parser/plan-validator.ts
58687
58725
  import { existsSync as existsSync32, readFileSync as readFileSync8 } from "node:fs";
58688
- import { basename as basename16, dirname as dirname17 } from "node:path";
58726
+ import { basename as basename16, dirname as dirname18 } from "node:path";
58689
58727
  function validatePlanFile(filePath, strict = false) {
58690
58728
  const rawContent = readFileSync8(filePath, "utf8");
58691
58729
  const content = rawContent.replace(/\r\n/g, `
58692
58730
  `);
58693
- const dir = dirname17(filePath);
58731
+ const dir = dirname18(filePath);
58694
58732
  const issues = [];
58695
58733
  const lines = content.split(`
58696
58734
  `);
@@ -58756,7 +58794,7 @@ var init_plan_validator = __esm(() => {
58756
58794
  import { execSync } from "node:child_process";
58757
58795
  import { mkdirSync as mkdirSync2, readFileSync as readFileSync9, writeFileSync as writeFileSync3 } from "node:fs";
58758
58796
  import { existsSync as existsSync33 } from "node:fs";
58759
- import { basename as basename17, dirname as dirname18, join as join51 } from "node:path";
58797
+ import { basename as basename17, dirname as dirname19, join as join51 } from "node:path";
58760
58798
  function phaseNameToFilename(id, name) {
58761
58799
  const numMatch = /^(\d+)([a-z]*)$/i.exec(id);
58762
58800
  const num = numMatch ? numMatch[1] : id;
@@ -58970,7 +59008,7 @@ function updatePhaseStatus(planFile, phaseId, newStatus) {
58970
59008
  const updatedFrontmatter = { ...frontmatter, status: planStatus };
58971
59009
  const updatedContent = import_gray_matter9.default.stringify(updatedBody, updatedFrontmatter);
58972
59010
  writeFileSync3(planFile, updatedContent, "utf8");
58973
- const planDir = dirname18(planFile);
59011
+ const planDir = dirname19(planFile);
58974
59012
  const phaseFilename = phaseNameFilenameFromTableRow(updatedBody, phaseId, planDir);
58975
59013
  if (phaseFilename && existsSync33(phaseFilename)) {
58976
59014
  updatePhaseFileFrontmatter(phaseFilename, newStatus);
@@ -59006,7 +59044,7 @@ function addPhase(planFile, name, afterId) {
59006
59044
  const { data: frontmatter, content: body } = import_gray_matter9.default(raw, {
59007
59045
  engines: { javascript: { parse: () => ({}) } }
59008
59046
  });
59009
- const planDir = dirname18(planFile);
59047
+ const planDir = dirname19(planFile);
59010
59048
  const existingIds = [];
59011
59049
  for (const match of body.matchAll(/^\|\s*(\d+[a-z]?)\s*\|/gim)) {
59012
59050
  existingIds.push(match[1].toLowerCase());
@@ -59079,7 +59117,7 @@ var init_plan_writer = __esm(() => {
59079
59117
  });
59080
59118
 
59081
59119
  // src/domains/plan-parser/index.ts
59082
- import { dirname as dirname19 } from "node:path";
59120
+ import { dirname as dirname20 } from "node:path";
59083
59121
  function buildPlanSummary(planFile) {
59084
59122
  const { frontmatter, phases } = parsePlanFile(planFile);
59085
59123
  const completed = phases.filter((p) => p.status === "completed").length;
@@ -59087,7 +59125,7 @@ function buildPlanSummary(planFile) {
59087
59125
  const pending = phases.filter((p) => p.status === "pending").length;
59088
59126
  const metadata = readPlanMetadata(planFile, { total: phases.length, completed, inProgress });
59089
59127
  return {
59090
- planDir: dirname19(planFile),
59128
+ planDir: dirname20(planFile),
59091
59129
  planFile,
59092
59130
  title: metadata.title ?? (typeof frontmatter.title === "string" ? frontmatter.title : undefined),
59093
59131
  description: metadata.description ?? (typeof frontmatter.description === "string" ? frontmatter.description : undefined),
@@ -59347,7 +59385,7 @@ import {
59347
59385
  unlinkSync,
59348
59386
  writeFileSync as writeFileSync4
59349
59387
  } from "node:fs";
59350
- import { dirname as dirname20, isAbsolute as isAbsolute7, join as join52, parse as parse2, relative as relative12, resolve as resolve24 } from "node:path";
59388
+ import { dirname as dirname21, isAbsolute as isAbsolute7, join as join52, parse as parse2, relative as relative12, resolve as resolve24 } from "node:path";
59351
59389
  function createEmptyRegistry() {
59352
59390
  return {
59353
59391
  version: 1,
@@ -59413,7 +59451,7 @@ function findProjectRoot(startDir) {
59413
59451
  if (existsSync34(join52(dir, ".claude")) || existsSync34(join52(dir, ".git"))) {
59414
59452
  return dir;
59415
59453
  }
59416
- dir = dirname20(dir);
59454
+ dir = dirname21(dir);
59417
59455
  }
59418
59456
  return startDir;
59419
59457
  }
@@ -59434,7 +59472,7 @@ function writeRegistry(registry, cwd2 = process.cwd()) {
59434
59472
  const globalPath = PathResolver.getPlansRegistryPath(cwd2);
59435
59473
  const toWrite = { ...registry, projectRoot: cwd2 };
59436
59474
  const validated = PlansRegistrySchema.parse(toWrite);
59437
- mkdirSync3(dirname20(globalPath), { recursive: true });
59475
+ mkdirSync3(dirname21(globalPath), { recursive: true });
59438
59476
  if (existsSync34(globalPath)) {
59439
59477
  try {
59440
59478
  writeFileSync4(`${globalPath}.bak`, readFileSync10(globalPath));
@@ -59544,7 +59582,7 @@ var init_plans_registry = __esm(() => {
59544
59582
  });
59545
59583
 
59546
59584
  // src/domains/plan-actions/action-executor.ts
59547
- import { dirname as dirname21, join as join53 } from "node:path";
59585
+ import { dirname as dirname22, join as join53 } from "node:path";
59548
59586
  function getPlanFile(planDir) {
59549
59587
  return join53(planDir, "plan.md");
59550
59588
  }
@@ -59558,7 +59596,7 @@ function assertPhaseId(phaseId) {
59558
59596
  function syncDashboardTracking(planFile) {
59559
59597
  const summary = buildPlanSummary(planFile);
59560
59598
  try {
59561
- const planDir = dirname21(planFile);
59599
+ const planDir = dirname22(planFile);
59562
59600
  const projectRoot = findProjectRoot(planDir);
59563
59601
  updateRegistryPhaseStatus({
59564
59602
  planDir,
@@ -59821,7 +59859,7 @@ var init_p_limit = __esm(() => {
59821
59859
  // src/domains/web-server/routes/plan-routes.ts
59822
59860
  import { existsSync as existsSync35, readFileSync as readFileSync11, realpathSync } from "node:fs";
59823
59861
  import { homedir as homedir31 } from "node:os";
59824
- import { basename as basename18, dirname as dirname22, join as join54, relative as relative13, resolve as resolve25, sep as sep8 } from "node:path";
59862
+ import { basename as basename18, dirname as dirname23, join as join54, relative as relative13, resolve as resolve25, sep as sep8 } from "node:path";
59825
59863
  function sanitizeError(err) {
59826
59864
  if (err instanceof Error) {
59827
59865
  if (/^(ENOENT|EACCES|EPERM|EISDIR)/.test(err.message))
@@ -59972,8 +60010,8 @@ function createDiscoveredProjectId(projectPath) {
59972
60010
  function toProjectPlanListItem(summary, plansDir) {
59973
60011
  return {
59974
60012
  file: relative13(plansDir, summary.planFile),
59975
- name: basename18(dirname22(summary.planFile)),
59976
- slug: basename18(dirname22(summary.planFile)),
60013
+ name: basename18(dirname23(summary.planFile)),
60014
+ slug: basename18(dirname23(summary.planFile)),
59977
60015
  summary: {
59978
60016
  ...summary,
59979
60017
  planDir: relative13(plansDir, summary.planDir),
@@ -60055,8 +60093,8 @@ function registerPlanRoutes(app) {
60055
60093
  const summaries = buildPlanSummaries(entries.slice(offset, offset + limit));
60056
60094
  const plans = summaries.map((summary) => ({
60057
60095
  file: relative13(process.cwd(), summary.planFile),
60058
- name: basename18(dirname22(summary.planFile)),
60059
- slug: basename18(dirname22(summary.planFile)),
60096
+ name: basename18(dirname23(summary.planFile)),
60097
+ slug: basename18(dirname23(summary.planFile)),
60060
60098
  summary: {
60061
60099
  ...summary,
60062
60100
  planDir: relative13(process.cwd(), summary.planDir),
@@ -61142,7 +61180,7 @@ var init_settings_routes = __esm(() => {
61142
61180
  // src/domains/skills/skill-catalog-generator.ts
61143
61181
  import { mkdir as mkdir14, readFile as readFile28, readdir as readdir15, rename as rename9, stat as stat11, writeFile as writeFile13 } from "node:fs/promises";
61144
61182
  import { homedir as homedir35 } from "node:os";
61145
- import { dirname as dirname23, join as join57, relative as relative14 } from "node:path";
61183
+ import { dirname as dirname24, join as join57, relative as relative14 } from "node:path";
61146
61184
  async function hasScripts(skillPath) {
61147
61185
  try {
61148
61186
  const entries = await readdir15(skillPath, { withFileTypes: true });
@@ -61208,7 +61246,7 @@ class SkillCatalogGenerator {
61208
61246
  };
61209
61247
  }
61210
61248
  async write(catalog) {
61211
- await mkdir14(dirname23(CATALOG_PATH), { recursive: true });
61249
+ await mkdir14(dirname24(CATALOG_PATH), { recursive: true });
61212
61250
  const tmpPath = `${CATALOG_PATH}.tmp`;
61213
61251
  const json = JSON.stringify(catalog, null, 2);
61214
61252
  await writeFile13(tmpPath, json, "utf-8");
@@ -61739,16 +61777,16 @@ var init_agents = __esm(() => {
61739
61777
  import { existsSync as existsSync39 } from "node:fs";
61740
61778
  import { mkdir as mkdir15, readFile as readFile30, writeFile as writeFile14 } from "node:fs/promises";
61741
61779
  import { homedir as homedir38 } from "node:os";
61742
- import { dirname as dirname24, join as join60, sep as sep10 } from "node:path";
61780
+ import { dirname as dirname25, join as join60, sep as sep10 } from "node:path";
61743
61781
  function getCliVersion3() {
61744
61782
  try {
61745
61783
  if (process.env.npm_package_version) {
61746
61784
  return process.env.npm_package_version;
61747
61785
  }
61748
61786
  const { readFileSync: readFileSync12 } = __require("node:fs");
61749
- const { dirname: dirname25, join: joinPath } = __require("node:path");
61787
+ const { dirname: dirname26, join: joinPath } = __require("node:path");
61750
61788
  const { fileURLToPath: fileURLToPath2 } = __require("node:url");
61751
- const __dirname3 = dirname25(fileURLToPath2(import.meta.url));
61789
+ const __dirname3 = dirname26(fileURLToPath2(import.meta.url));
61752
61790
  const pkgPath = joinPath(__dirname3, "../../../package.json");
61753
61791
  const pkg = JSON.parse(readFileSync12(pkgPath, "utf-8"));
61754
61792
  return pkg.version || "unknown";
@@ -61791,7 +61829,7 @@ async function readRegistry2() {
61791
61829
  }
61792
61830
  }
61793
61831
  async function writeRegistry2(registry) {
61794
- const dir = dirname24(REGISTRY_PATH2);
61832
+ const dir = dirname25(REGISTRY_PATH2);
61795
61833
  if (!existsSync39(dir)) {
61796
61834
  await mkdir15(dir, { recursive: true });
61797
61835
  }
@@ -61883,7 +61921,7 @@ var init_skills_registry = __esm(() => {
61883
61921
  import { existsSync as existsSync40 } from "node:fs";
61884
61922
  import { cp as cp3, mkdir as mkdir16, rm as rm8, stat as stat12 } from "node:fs/promises";
61885
61923
  import { homedir as homedir39 } from "node:os";
61886
- import { dirname as dirname25, join as join61, resolve as resolve28 } from "node:path";
61924
+ import { dirname as dirname26, join as join61, resolve as resolve28 } from "node:path";
61887
61925
  function isSamePath2(path1, path22) {
61888
61926
  try {
61889
61927
  return resolve28(path1) === resolve28(path22);
@@ -61952,7 +61990,7 @@ async function installSkillForAgent(skill, agent, options2) {
61952
61990
  try {
61953
61991
  await cleanupLegacySkillPath(skill.name, agent, options2.global);
61954
61992
  } catch {}
61955
- const parentDir = dirname25(targetPath);
61993
+ const parentDir = dirname26(targetPath);
61956
61994
  if (!existsSync40(parentDir)) {
61957
61995
  await mkdir16(parentDir, { recursive: true });
61958
61996
  }
@@ -62962,7 +63000,7 @@ var package_default;
62962
63000
  var init_package = __esm(() => {
62963
63001
  package_default = {
62964
63002
  name: "claudekit-cli",
62965
- version: "4.2.2",
63003
+ version: "4.2.3-dev.1",
62966
63004
  description: "CLI tool for bootstrapping and updating ClaudeKit projects",
62967
63005
  type: "module",
62968
63006
  repository: {
@@ -66042,7 +66080,7 @@ var init_routes = __esm(() => {
66042
66080
 
66043
66081
  // src/domains/web-server/static-server.ts
66044
66082
  import { existsSync as existsSync45 } from "node:fs";
66045
- import { basename as basename21, dirname as dirname26, join as join70, resolve as resolve30 } from "node:path";
66083
+ import { basename as basename21, dirname as dirname27, join as join70, resolve as resolve30 } from "node:path";
66046
66084
  import { fileURLToPath as fileURLToPath2 } from "node:url";
66047
66085
  function addRuntimeUiCandidate(candidates, runtimePath) {
66048
66086
  if (!runtimePath) {
@@ -66052,7 +66090,7 @@ function addRuntimeUiCandidate(candidates, runtimePath) {
66052
66090
  if (!looksLikePath) {
66053
66091
  return;
66054
66092
  }
66055
- const entryDir = dirname26(resolve30(runtimePath));
66093
+ const entryDir = dirname27(resolve30(runtimePath));
66056
66094
  if (basename21(entryDir) === "dist") {
66057
66095
  candidates.add(join70(entryDir, "ui"));
66058
66096
  }
@@ -66113,7 +66151,7 @@ var import_express, __dirname3;
66113
66151
  var init_static_server = __esm(() => {
66114
66152
  init_logger();
66115
66153
  import_express = __toESM(require_express2(), 1);
66116
- __dirname3 = dirname26(fileURLToPath2(import.meta.url));
66154
+ __dirname3 = dirname27(fileURLToPath2(import.meta.url));
66117
66155
  });
66118
66156
 
66119
66157
  // node_modules/ws/lib/constants.js
@@ -71599,7 +71637,7 @@ var init_skills_installer2 = __esm(() => {
71599
71637
  // src/services/package-installer/gemini-mcp/config-manager.ts
71600
71638
  import { existsSync as existsSync59 } from "node:fs";
71601
71639
  import { mkdir as mkdir23, readFile as readFile46, writeFile as writeFile22 } from "node:fs/promises";
71602
- import { dirname as dirname29, join as join92 } from "node:path";
71640
+ import { dirname as dirname30, join as join92 } from "node:path";
71603
71641
  async function readJsonFile(filePath) {
71604
71642
  try {
71605
71643
  const content = await readFile46(filePath, "utf-8");
@@ -71639,7 +71677,7 @@ ${geminiPattern}
71639
71677
  }
71640
71678
  }
71641
71679
  async function createNewSettingsWithMerge(geminiSettingsPath, mcpConfigPath) {
71642
- const linkDir = dirname29(geminiSettingsPath);
71680
+ const linkDir = dirname30(geminiSettingsPath);
71643
71681
  if (!existsSync59(linkDir)) {
71644
71682
  await mkdir23(linkDir, { recursive: true });
71645
71683
  logger.debug(`Created directory: ${linkDir}`);
@@ -71758,9 +71796,9 @@ var init_validation = __esm(() => {
71758
71796
  // src/services/package-installer/gemini-mcp/linker-core.ts
71759
71797
  import { existsSync as existsSync61 } from "node:fs";
71760
71798
  import { mkdir as mkdir24, symlink as symlink3 } from "node:fs/promises";
71761
- import { dirname as dirname30, join as join94 } from "node:path";
71799
+ import { dirname as dirname31, join as join94 } from "node:path";
71762
71800
  async function createSymlink(targetPath, linkPath, projectDir, isGlobal) {
71763
- const linkDir = dirname30(linkPath);
71801
+ const linkDir = dirname31(linkPath);
71764
71802
  if (!existsSync61(linkDir)) {
71765
71803
  await mkdir24(linkDir, { recursive: true });
71766
71804
  logger.debug(`Created directory: ${linkDir}`);
@@ -74078,76 +74116,6 @@ var init_ownership_display = __esm(() => {
74078
74116
  import_picocolors25 = __toESM(require_picocolors(), 1);
74079
74117
  });
74080
74118
 
74081
- // src/ui/node_modules/picocolors/picocolors.js
74082
- var require_picocolors2 = __commonJS((exports, module) => {
74083
- var p = process || {};
74084
- var argv = p.argv || [];
74085
- var env2 = p.env || {};
74086
- var isColorSupported = !(!!env2.NO_COLOR || argv.includes("--no-color")) && (!!env2.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env2.TERM !== "dumb" || !!env2.CI);
74087
- var formatter = (open6, close, replace3 = open6) => (input) => {
74088
- let string = "" + input, index = string.indexOf(close, open6.length);
74089
- return ~index ? open6 + replaceClose(string, close, replace3, index) + close : open6 + string + close;
74090
- };
74091
- var replaceClose = (string, close, replace3, index) => {
74092
- let result = "", cursor = 0;
74093
- do {
74094
- result += string.substring(cursor, index) + replace3;
74095
- cursor = index + close.length;
74096
- index = string.indexOf(close, cursor);
74097
- } while (~index);
74098
- return result + string.substring(cursor);
74099
- };
74100
- var createColors = (enabled = isColorSupported) => {
74101
- let f3 = enabled ? formatter : () => String;
74102
- return {
74103
- isColorSupported: enabled,
74104
- reset: f3("\x1B[0m", "\x1B[0m"),
74105
- bold: f3("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
74106
- dim: f3("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
74107
- italic: f3("\x1B[3m", "\x1B[23m"),
74108
- underline: f3("\x1B[4m", "\x1B[24m"),
74109
- inverse: f3("\x1B[7m", "\x1B[27m"),
74110
- hidden: f3("\x1B[8m", "\x1B[28m"),
74111
- strikethrough: f3("\x1B[9m", "\x1B[29m"),
74112
- black: f3("\x1B[30m", "\x1B[39m"),
74113
- red: f3("\x1B[31m", "\x1B[39m"),
74114
- green: f3("\x1B[32m", "\x1B[39m"),
74115
- yellow: f3("\x1B[33m", "\x1B[39m"),
74116
- blue: f3("\x1B[34m", "\x1B[39m"),
74117
- magenta: f3("\x1B[35m", "\x1B[39m"),
74118
- cyan: f3("\x1B[36m", "\x1B[39m"),
74119
- white: f3("\x1B[37m", "\x1B[39m"),
74120
- gray: f3("\x1B[90m", "\x1B[39m"),
74121
- bgBlack: f3("\x1B[40m", "\x1B[49m"),
74122
- bgRed: f3("\x1B[41m", "\x1B[49m"),
74123
- bgGreen: f3("\x1B[42m", "\x1B[49m"),
74124
- bgYellow: f3("\x1B[43m", "\x1B[49m"),
74125
- bgBlue: f3("\x1B[44m", "\x1B[49m"),
74126
- bgMagenta: f3("\x1B[45m", "\x1B[49m"),
74127
- bgCyan: f3("\x1B[46m", "\x1B[49m"),
74128
- bgWhite: f3("\x1B[47m", "\x1B[49m"),
74129
- blackBright: f3("\x1B[90m", "\x1B[39m"),
74130
- redBright: f3("\x1B[91m", "\x1B[39m"),
74131
- greenBright: f3("\x1B[92m", "\x1B[39m"),
74132
- yellowBright: f3("\x1B[93m", "\x1B[39m"),
74133
- blueBright: f3("\x1B[94m", "\x1B[39m"),
74134
- magentaBright: f3("\x1B[95m", "\x1B[39m"),
74135
- cyanBright: f3("\x1B[96m", "\x1B[39m"),
74136
- whiteBright: f3("\x1B[97m", "\x1B[39m"),
74137
- bgBlackBright: f3("\x1B[100m", "\x1B[49m"),
74138
- bgRedBright: f3("\x1B[101m", "\x1B[49m"),
74139
- bgGreenBright: f3("\x1B[102m", "\x1B[49m"),
74140
- bgYellowBright: f3("\x1B[103m", "\x1B[49m"),
74141
- bgBlueBright: f3("\x1B[104m", "\x1B[49m"),
74142
- bgMagentaBright: f3("\x1B[105m", "\x1B[49m"),
74143
- bgCyanBright: f3("\x1B[106m", "\x1B[49m"),
74144
- bgWhiteBright: f3("\x1B[107m", "\x1B[49m")
74145
- };
74146
- };
74147
- module.exports = createColors();
74148
- module.exports.createColors = createColors;
74149
- });
74150
-
74151
74119
  // src/commands/watch/phases/implementation-git-helpers.ts
74152
74120
  import { spawn as spawn5 } from "node:child_process";
74153
74121
  async function getCurrentBranch2(cwd2) {
@@ -75177,7 +75145,7 @@ var init_sqlite_client = () => {};
75177
75145
 
75178
75146
  // src/commands/content/phases/db-manager.ts
75179
75147
  import { existsSync as existsSync80, mkdirSync as mkdirSync8 } from "node:fs";
75180
- import { dirname as dirname47 } from "node:path";
75148
+ import { dirname as dirname48 } from "node:path";
75181
75149
  function initDatabase(dbPath) {
75182
75150
  ensureParentDir(dbPath);
75183
75151
  const db = openDatabase(dbPath);
@@ -75198,7 +75166,7 @@ function runRetentionCleanup(db, retentionDays = 90) {
75198
75166
  db.prepare("DELETE FROM git_events WHERE processed = 1 AND created_at < ?").run(cutoff);
75199
75167
  }
75200
75168
  function ensureParentDir(dbPath) {
75201
- const dir = dirname47(dbPath);
75169
+ const dir = dirname48(dbPath);
75202
75170
  if (dir && !existsSync80(dir)) {
75203
75171
  mkdirSync8(dir, { recursive: true });
75204
75172
  }
@@ -85262,12 +85230,13 @@ async function applyBudgetDefaults(settingsPath, projectClaudeDir, requiredFract
85262
85230
  var ENGINEER_SKILL_COUNT_THRESHOLD = 20;
85263
85231
  async function checkSkillBudget(setup, projectDir) {
85264
85232
  const projectClaudeDir = resolve31(projectDir, ".claude");
85265
- const globalClaudeDir = PathResolver.getGlobalKitDir();
85233
+ const globalClaudeDir = resolve31(PathResolver.getGlobalKitDir());
85234
+ const projectScopeAliasesGlobal = projectClaudeDir === globalClaudeDir;
85266
85235
  const [projectSkills, globalSkills] = await Promise.all([
85267
- scanSkills2(join75(projectClaudeDir, "skills")),
85236
+ projectScopeAliasesGlobal ? Promise.resolve([]) : scanSkills2(join75(projectClaudeDir, "skills")),
85268
85237
  scanSkills2(join75(globalClaudeDir, "skills"))
85269
85238
  ]);
85270
- if (!isEngineerLikeProject(setup, projectSkills))
85239
+ if (!isEngineerLikeProject(setup, [...projectSkills, ...globalSkills]))
85271
85240
  return [];
85272
85241
  const settingsPath = join75(projectClaudeDir, "settings.json");
85273
85242
  const settings = await readProjectSettings(settingsPath);
@@ -85288,7 +85257,10 @@ function isEngineerLikeProject(setup, projectSkills) {
85288
85257
  const metadataText = [
85289
85258
  setup.project.metadata?.name,
85290
85259
  setup.project.metadata?.description,
85291
- setup.project.metadata?.repository?.url
85260
+ setup.project.metadata?.repository?.url,
85261
+ setup.global.metadata?.name,
85262
+ setup.global.metadata?.description,
85263
+ setup.global.metadata?.repository?.url
85292
85264
  ].filter(Boolean).join(" ").toLowerCase();
85293
85265
  return metadataText.includes("engineer") || projectSkills.length >= ENGINEER_SKILL_COUNT_THRESHOLD;
85294
85266
  }
@@ -85665,7 +85637,7 @@ init_path_resolver();
85665
85637
  import { existsSync as existsSync54 } from "node:fs";
85666
85638
  import { readFile as readFile41 } from "node:fs/promises";
85667
85639
  import { homedir as homedir41 } from "node:os";
85668
- import { dirname as dirname27, join as join79, normalize as normalize6, resolve as resolve32 } from "node:path";
85640
+ import { dirname as dirname28, join as join79, normalize as normalize6, resolve as resolve32 } from "node:path";
85669
85641
  async function checkPathRefsValid(projectDir) {
85670
85642
  const globalClaudeMd = join79(PathResolver.getGlobalKitDir(), "CLAUDE.md");
85671
85643
  const projectClaudeMd = join79(projectDir, ".claude", "CLAUDE.md");
@@ -85696,7 +85668,7 @@ async function checkPathRefsValid(projectDir) {
85696
85668
  autoFixable: false
85697
85669
  };
85698
85670
  }
85699
- const baseDir = dirname27(claudeMdPath);
85671
+ const baseDir = dirname28(claudeMdPath);
85700
85672
  const home6 = homedir41();
85701
85673
  const broken = [];
85702
85674
  for (const ref of refs) {
@@ -88719,14 +88691,14 @@ class AutoHealer {
88719
88691
  import { execSync as execSync4, spawnSync as spawnSync6 } from "node:child_process";
88720
88692
  import { readFileSync as readFileSync16, unlinkSync as unlinkSync2, writeFileSync as writeFileSync6 } from "node:fs";
88721
88693
  import { tmpdir as tmpdir3 } from "node:os";
88722
- import { dirname as dirname28, join as join87 } from "node:path";
88694
+ import { dirname as dirname29, join as join87 } from "node:path";
88723
88695
  import { fileURLToPath as fileURLToPath4 } from "node:url";
88724
88696
  init_environment();
88725
88697
  init_logger();
88726
88698
  init_dist2();
88727
88699
  function getCliVersion4() {
88728
88700
  try {
88729
- const __dirname4 = dirname28(fileURLToPath4(import.meta.url));
88701
+ const __dirname4 = dirname29(fileURLToPath4(import.meta.url));
88730
88702
  const pkgPath = join87(__dirname4, "../../../package.json");
88731
88703
  const pkg = JSON.parse(readFileSync16(pkgPath, "utf-8"));
88732
88704
  return pkg.version || "unknown";
@@ -89191,7 +89163,7 @@ init_github_client();
89191
89163
  init_config_version_checker();
89192
89164
 
89193
89165
  // src/domains/sync/sync-engine.ts
89194
- import { lstat as lstat6, readFile as readFile45, readlink as readlink2, realpath as realpath6, stat as stat14 } from "node:fs/promises";
89166
+ import { lstat as lstat6, readFile as readFile45, readlink as readlink2, realpath as realpath7, stat as stat14 } from "node:fs/promises";
89195
89167
  import { isAbsolute as isAbsolute8, join as join88, normalize as normalize8, relative as relative17 } from "node:path";
89196
89168
 
89197
89169
  // src/services/file-operations/ownership-checker.ts
@@ -89819,14 +89791,14 @@ class JsonDiff extends Diff {
89819
89791
  }
89820
89792
  castInput(value, options2) {
89821
89793
  const { undefinedReplacement, stringifyReplacer = (k2, v2) => typeof v2 === "undefined" ? undefinedReplacement : v2 } = options2;
89822
- return typeof value === "string" ? value : JSON.stringify(canonicalize(value, null, null, stringifyReplacer), null, " ");
89794
+ return typeof value === "string" ? value : JSON.stringify(canonicalize2(value, null, null, stringifyReplacer), null, " ");
89823
89795
  }
89824
89796
  equals(left, right, options2) {
89825
89797
  return super.equals(left.replace(/,([\r\n])/g, "$1"), right.replace(/,([\r\n])/g, "$1"), options2);
89826
89798
  }
89827
89799
  }
89828
89800
  var jsonDiff = new JsonDiff;
89829
- function canonicalize(obj, stack, replacementStack, replacer, key) {
89801
+ function canonicalize2(obj, stack, replacementStack, replacer, key) {
89830
89802
  stack = stack || [];
89831
89803
  replacementStack = replacementStack || [];
89832
89804
  if (replacer) {
@@ -89844,7 +89816,7 @@ function canonicalize(obj, stack, replacementStack, replacer, key) {
89844
89816
  canonicalizedObj = new Array(obj.length);
89845
89817
  replacementStack.push(canonicalizedObj);
89846
89818
  for (i = 0;i < obj.length; i += 1) {
89847
- canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack, replacer, String(i));
89819
+ canonicalizedObj[i] = canonicalize2(obj[i], stack, replacementStack, replacer, String(i));
89848
89820
  }
89849
89821
  stack.pop();
89850
89822
  replacementStack.pop();
@@ -89867,7 +89839,7 @@ function canonicalize(obj, stack, replacementStack, replacer, key) {
89867
89839
  sortedKeys.sort();
89868
89840
  for (i = 0;i < sortedKeys.length; i += 1) {
89869
89841
  key2 = sortedKeys[i];
89870
- canonicalizedObj[key2] = canonicalize(obj[key2], stack, replacementStack, replacer, key2);
89842
+ canonicalizedObj[key2] = canonicalize2(obj[key2], stack, replacementStack, replacer, key2);
89871
89843
  }
89872
89844
  stack.pop();
89873
89845
  replacementStack.pop();
@@ -90450,8 +90422,8 @@ async function validateSyncPath(basePath, filePath) {
90450
90422
  }
90451
90423
  await validateSymlinkChain(fullPath, basePath);
90452
90424
  try {
90453
- const resolvedBase = await realpath6(basePath);
90454
- const resolvedFull = await realpath6(fullPath);
90425
+ const resolvedBase = await realpath7(basePath);
90426
+ const resolvedFull = await realpath7(fullPath);
90455
90427
  const resolvedRel = relative17(resolvedBase, resolvedFull);
90456
90428
  if (resolvedRel.startsWith("..") || isAbsolute8(resolvedRel)) {
90457
90429
  throw new Error(`Symlink escapes base directory: ${filePath}`);
@@ -90460,8 +90432,8 @@ async function validateSyncPath(basePath, filePath) {
90460
90432
  if (error.code === "ENOENT") {
90461
90433
  const parentPath = join88(fullPath, "..");
90462
90434
  try {
90463
- const resolvedBase = await realpath6(basePath);
90464
- const resolvedParent = await realpath6(parentPath);
90435
+ const resolvedBase = await realpath7(basePath);
90436
+ const resolvedParent = await realpath7(parentPath);
90465
90437
  const resolvedRel = relative17(resolvedBase, resolvedParent);
90466
90438
  if (resolvedRel.startsWith("..") || isAbsolute8(resolvedRel)) {
90467
90439
  throw new Error(`Parent symlink escapes base directory: ${filePath}`);
@@ -93294,7 +93266,7 @@ import path9 from "node:path";
93294
93266
 
93295
93267
  // node_modules/tar/dist/esm/list.js
93296
93268
  import fs10 from "node:fs";
93297
- import { dirname as dirname31, parse as parse4 } from "path";
93269
+ import { dirname as dirname32, parse as parse4 } from "path";
93298
93270
 
93299
93271
  // node_modules/tar/dist/esm/options.js
93300
93272
  var argmap = new Map([
@@ -96194,7 +96166,7 @@ var filesFilter = (opt, files) => {
96194
96166
  if (m2 !== undefined) {
96195
96167
  ret = m2;
96196
96168
  } else {
96197
- ret = mapHas(dirname31(file), root);
96169
+ ret = mapHas(dirname32(file), root);
96198
96170
  }
96199
96171
  }
96200
96172
  map.set(file, ret);
@@ -99937,7 +99909,7 @@ import { join as join120 } from "node:path";
99937
99909
 
99938
99910
  // src/domains/installation/deletion-handler.ts
99939
99911
  import { existsSync as existsSync62, lstatSync as lstatSync3, readdirSync as readdirSync7, rmSync as rmSync2, rmdirSync, unlinkSync as unlinkSync4 } from "node:fs";
99940
- import { dirname as dirname33, join as join106, relative as relative20, resolve as resolve38, sep as sep11 } from "node:path";
99912
+ import { dirname as dirname34, join as join106, relative as relative20, resolve as resolve38, sep as sep11 } from "node:path";
99941
99913
 
99942
99914
  // src/services/file-operations/manifest/manifest-reader.ts
99943
99915
  init_metadata_migration();
@@ -100163,7 +100135,7 @@ function expandGlobPatterns(patterns, claudeDir3) {
100163
100135
  var MAX_CLEANUP_ITERATIONS = 50;
100164
100136
  function cleanupEmptyDirectories(filePath, claudeDir3) {
100165
100137
  const normalizedClaudeDir = resolve38(claudeDir3);
100166
- let currentDir = resolve38(dirname33(filePath));
100138
+ let currentDir = resolve38(dirname34(filePath));
100167
100139
  let iterations = 0;
100168
100140
  while (currentDir !== normalizedClaudeDir && currentDir.startsWith(normalizedClaudeDir) && iterations < MAX_CLEANUP_ITERATIONS) {
100169
100141
  iterations++;
@@ -100172,7 +100144,7 @@ function cleanupEmptyDirectories(filePath, claudeDir3) {
100172
100144
  if (entries.length === 0) {
100173
100145
  rmdirSync(currentDir);
100174
100146
  logger.debug(`Removed empty directory: ${currentDir}`);
100175
- currentDir = resolve38(dirname33(currentDir));
100147
+ currentDir = resolve38(dirname34(currentDir));
100176
100148
  } else {
100177
100149
  break;
100178
100150
  }
@@ -100295,7 +100267,7 @@ init_logger();
100295
100267
  init_types3();
100296
100268
  var import_fs_extra15 = __toESM(require_lib(), 1);
100297
100269
  var import_ignore3 = __toESM(require_ignore(), 1);
100298
- import { dirname as dirname36, join as join110, relative as relative22 } from "node:path";
100270
+ import { dirname as dirname37, join as join110, relative as relative22 } from "node:path";
100299
100271
 
100300
100272
  // src/domains/installation/selective-merger.ts
100301
100273
  import { stat as stat18 } from "node:fs/promises";
@@ -101966,13 +101938,13 @@ class FileScanner {
101966
101938
  // src/domains/installation/merger/settings-processor.ts
101967
101939
  import { execSync as execSync5 } from "node:child_process";
101968
101940
  import { homedir as homedir45 } from "node:os";
101969
- import { dirname as dirname35, join as join109 } from "node:path";
101941
+ import { dirname as dirname36, join as join109 } from "node:path";
101970
101942
 
101971
101943
  // src/domains/config/installed-settings-tracker.ts
101972
101944
  init_shared();
101973
101945
  import { existsSync as existsSync63 } from "node:fs";
101974
101946
  import { mkdir as mkdir31, readFile as readFile49, writeFile as writeFile24 } from "node:fs/promises";
101975
- import { dirname as dirname34, join as join108 } from "node:path";
101947
+ import { dirname as dirname35, join as join108 } from "node:path";
101976
101948
  var CK_JSON_FILE = ".ck.json";
101977
101949
 
101978
101950
  class InstalledSettingsTracker {
@@ -102023,7 +101995,7 @@ class InstalledSettingsTracker {
102023
101995
  data.kits[this.kitName] = {};
102024
101996
  }
102025
101997
  data.kits[this.kitName].installedSettings = settings;
102026
- await mkdir31(dirname34(ckJsonPath), { recursive: true });
101998
+ await mkdir31(dirname35(ckJsonPath), { recursive: true });
102027
101999
  await writeFile24(ckJsonPath, JSON.stringify(data, null, 2), "utf-8");
102028
102000
  logger.debug(`Saved installed settings to ${ckJsonPath}`);
102029
102001
  } catch (error) {
@@ -102126,7 +102098,7 @@ class SettingsProcessor {
102126
102098
  } else {
102127
102099
  try {
102128
102100
  const parsedSettings = JSON.parse(transformedSource);
102129
- this.fixHookCommandPaths(parsedSettings);
102101
+ this.logHookCommandRepair(this.fixHookCommandPaths(parsedSettings), "fresh install");
102130
102102
  await SettingsMerger.writeSettingsFile(destFile, parsedSettings);
102131
102103
  try {
102132
102104
  if (this.forceOverwriteSettings && destExists) {
@@ -102204,10 +102176,7 @@ class SettingsProcessor {
102204
102176
  }
102205
102177
  await this.tracker.saveInstalledSettings(installedSettings);
102206
102178
  }
102207
- const pathsFixed = this.fixHookCommandPaths(mergeResult.merged);
102208
- if (pathsFixed) {
102209
- logger.info("Fixed hook command paths to canonical quoted format");
102210
- }
102179
+ this.logHookCommandRepair(this.fixHookCommandPaths(mergeResult.merged), "merged settings");
102211
102180
  const hooksPruned = this.pruneDeletedHooks(mergeResult.merged);
102212
102181
  if (hooksPruned > 0) {
102213
102182
  logger.info(`Pruned ${hooksPruned} stale hook(s) referencing deleted files`);
@@ -102351,7 +102320,7 @@ class SettingsProcessor {
102351
102320
  if (!content.trim())
102352
102321
  return null;
102353
102322
  const parsedSettings = JSON.parse(content);
102354
- this.fixHookCommandPaths(parsedSettings);
102323
+ this.logHookCommandRepair(this.fixHookCommandPaths(parsedSettings), "existing global settings");
102355
102324
  return parsedSettings;
102356
102325
  } catch {
102357
102326
  return null;
@@ -102374,8 +102343,14 @@ class SettingsProcessor {
102374
102343
  }
102375
102344
  return transformed;
102376
102345
  }
102346
+ logHookCommandRepair(count, context) {
102347
+ if (count <= 0)
102348
+ return;
102349
+ const suffix = context ? ` (${context})` : "";
102350
+ logger.info(`Repaired ${count} hook command path(s) to canonical quoted format${suffix} — protects against shells word-splitting on usernames with spaces`);
102351
+ }
102377
102352
  fixHookCommandPaths(settings) {
102378
- let fixed = false;
102353
+ let fixed = 0;
102379
102354
  if (settings.hooks) {
102380
102355
  for (const entries of Object.values(settings.hooks)) {
102381
102356
  for (const entry of entries) {
@@ -102383,7 +102358,7 @@ class SettingsProcessor {
102383
102358
  const result = this.fixSingleCommandPath(entry.command);
102384
102359
  if (result !== entry.command) {
102385
102360
  entry.command = result;
102386
- fixed = true;
102361
+ fixed++;
102387
102362
  }
102388
102363
  }
102389
102364
  if ("hooks" in entry && entry.hooks) {
@@ -102392,7 +102367,7 @@ class SettingsProcessor {
102392
102367
  const result = this.fixSingleCommandPath(hook.command);
102393
102368
  if (result !== hook.command) {
102394
102369
  hook.command = result;
102395
- fixed = true;
102370
+ fixed++;
102396
102371
  }
102397
102372
  }
102398
102373
  }
@@ -102405,7 +102380,7 @@ class SettingsProcessor {
102405
102380
  const result = this.fixSingleCommandPath(statusLine.command);
102406
102381
  if (result !== statusLine.command) {
102407
102382
  statusLine.command = result;
102408
- fixed = true;
102383
+ fixed++;
102409
102384
  }
102410
102385
  }
102411
102386
  return fixed;
@@ -102463,20 +102438,19 @@ class SettingsProcessor {
102463
102438
  return false;
102464
102439
  }
102465
102440
  const pathsFixed = this.fixHookCommandPaths(settings);
102466
- if (!pathsFixed) {
102441
+ if (pathsFixed === 0) {
102467
102442
  return false;
102468
102443
  }
102444
+ this.logHookCommandRepair(pathsFixed, filePath);
102469
102445
  await SettingsMerger.writeSettingsFile(filePath, settings);
102470
102446
  return true;
102471
102447
  }
102472
102448
  async repairSiblingSettingsLocal(destFile) {
102473
- const settingsLocalPath = join109(dirname35(destFile), "settings.local.json");
102449
+ const settingsLocalPath = join109(dirname36(destFile), "settings.local.json");
102474
102450
  if (settingsLocalPath === destFile || !await import_fs_extra14.pathExists(settingsLocalPath)) {
102475
102451
  return;
102476
102452
  }
102477
- if (await this.repairSettingsFile(settingsLocalPath)) {
102478
- logger.info(`Repaired stale .claude command paths in ${settingsLocalPath}`);
102479
- }
102453
+ await this.repairSettingsFile(settingsLocalPath);
102480
102454
  }
102481
102455
  detectClaudeCodeVersion() {
102482
102456
  if (this.cachedVersion !== undefined)
@@ -102732,10 +102706,10 @@ class CopyExecutor {
102732
102706
  }
102733
102707
  trackInstalledFile(relativePath) {
102734
102708
  this.installedFiles.add(relativePath);
102735
- let dir = dirname36(relativePath);
102709
+ let dir = dirname37(relativePath);
102736
102710
  while (dir && dir !== "." && dir !== "/") {
102737
102711
  this.installedDirectories.add(`${dir}/`);
102738
- dir = dirname36(dir);
102712
+ dir = dirname37(dir);
102739
102713
  }
102740
102714
  }
102741
102715
  }
@@ -105885,7 +105859,7 @@ async function runPreflightChecks() {
105885
105859
  // src/domains/installation/fresh-installer.ts
105886
105860
  init_metadata_migration();
105887
105861
  import { existsSync as existsSync64, readdirSync as readdirSync8, rmSync as rmSync3, rmdirSync as rmdirSync2, unlinkSync as unlinkSync5 } from "node:fs";
105888
- import { basename as basename25, dirname as dirname37, join as join132, resolve as resolve40 } from "node:path";
105862
+ import { basename as basename25, dirname as dirname38, join as join132, resolve as resolve40 } from "node:path";
105889
105863
  init_logger();
105890
105864
  init_safe_spinner();
105891
105865
  var import_fs_extra34 = __toESM(require_lib(), 1);
@@ -105938,14 +105912,14 @@ async function analyzeFreshInstallation(claudeDir3) {
105938
105912
  }
105939
105913
  function cleanupEmptyDirectories2(filePath, claudeDir3) {
105940
105914
  const normalizedClaudeDir = resolve40(claudeDir3);
105941
- let currentDir = resolve40(dirname37(filePath));
105915
+ let currentDir = resolve40(dirname38(filePath));
105942
105916
  while (currentDir !== normalizedClaudeDir && currentDir.startsWith(normalizedClaudeDir)) {
105943
105917
  try {
105944
105918
  const entries = readdirSync8(currentDir);
105945
105919
  if (entries.length === 0) {
105946
105920
  rmdirSync2(currentDir);
105947
105921
  logger.debug(`Removed empty directory: ${currentDir}`);
105948
- currentDir = resolve40(dirname37(currentDir));
105922
+ currentDir = resolve40(dirname38(currentDir));
105949
105923
  } else {
105950
105924
  break;
105951
105925
  }
@@ -106512,7 +106486,7 @@ async function handleSelection(ctx) {
106512
106486
  }
106513
106487
  // src/commands/init/phases/sync-handler.ts
106514
106488
  import { copyFile as copyFile8, mkdir as mkdir36, open as open5, readFile as readFile58, rename as rename10, stat as stat22, unlink as unlink12, writeFile as writeFile32 } from "node:fs/promises";
106515
- import { dirname as dirname38, join as join134, resolve as resolve43 } from "node:path";
106489
+ import { dirname as dirname39, join as join134, resolve as resolve43 } from "node:path";
106516
106490
  init_logger();
106517
106491
  init_path_resolver();
106518
106492
  var import_fs_extra36 = __toESM(require_lib(), 1);
@@ -106631,7 +106605,7 @@ async function acquireSyncLock(global3) {
106631
106605
  const lockPath = join134(cacheDir, ".sync-lock");
106632
106606
  const startTime = Date.now();
106633
106607
  const lockTimeout = getLockTimeout();
106634
- await mkdir36(dirname38(lockPath), { recursive: true });
106608
+ await mkdir36(dirname39(lockPath), { recursive: true });
106635
106609
  while (Date.now() - startTime < lockTimeout) {
106636
106610
  try {
106637
106611
  const handle = await open5(lockPath, "wx");
@@ -107584,7 +107558,7 @@ import { basename as basename27, join as join142, resolve as resolve46 } from "n
107584
107558
  init_logger();
107585
107559
 
107586
107560
  // src/ui/ck-cli-design/tokens.ts
107587
- var import_picocolors27 = __toESM(require_picocolors2(), 1);
107561
+ var import_picocolors27 = __toESM(require_picocolors(), 1);
107588
107562
  import { homedir as homedir47, platform as platform16 } from "node:os";
107589
107563
  import { resolve as resolve45, win32 as win322 } from "node:path";
107590
107564
  var PANEL_MIN_WIDTH = 60;
@@ -108057,7 +108031,7 @@ init_dist2();
108057
108031
  init_model_taxonomy();
108058
108032
  import { mkdir as mkdir38, readFile as readFile63, writeFile as writeFile36 } from "node:fs/promises";
108059
108033
  import { homedir as homedir50 } from "node:os";
108060
- import { dirname as dirname39, join as join141 } from "node:path";
108034
+ import { dirname as dirname40, join as join141 } from "node:path";
108061
108035
 
108062
108036
  // src/commands/portable/models-dev-cache.ts
108063
108037
  init_logger();
@@ -108410,7 +108384,7 @@ async function ensureOpenCodeModel(options2) {
108410
108384
  }
108411
108385
  const chosenModel2 = response2.action === "custom" ? response2.value : suggestion2.model;
108412
108386
  const next2 = { ...existing, model: chosenModel2 };
108413
- await mkdir38(dirname39(configPath), { recursive: true });
108387
+ await mkdir38(dirname40(configPath), { recursive: true });
108414
108388
  await writeFile36(configPath, `${JSON.stringify(next2, null, 2)}
108415
108389
  `, "utf-8");
108416
108390
  return { path: configPath, action: "added", model: chosenModel2, reason: suggestion2.reason };
@@ -108421,7 +108395,7 @@ async function ensureOpenCodeModel(options2) {
108421
108395
  throw new OpenCodeAuthRequiredError(suggestion.failure);
108422
108396
  }
108423
108397
  const next2 = { ...existing ?? {}, model: suggestion.model };
108424
- await mkdir38(dirname39(configPath), { recursive: true });
108398
+ await mkdir38(dirname40(configPath), { recursive: true });
108425
108399
  await writeFile36(configPath, `${JSON.stringify(next2, null, 2)}
108426
108400
  `, "utf-8");
108427
108401
  return {
@@ -108443,7 +108417,7 @@ async function ensureOpenCodeModel(options2) {
108443
108417
  }
108444
108418
  const chosenModel = response.action === "custom" ? response.value : suggestion.ok ? suggestion.model : "";
108445
108419
  const next = { ...existing ?? {}, model: chosenModel };
108446
- await mkdir38(dirname39(configPath), { recursive: true });
108420
+ await mkdir38(dirname40(configPath), { recursive: true });
108447
108421
  await writeFile36(configPath, `${JSON.stringify(next, null, 2)}
108448
108422
  `, "utf-8");
108449
108423
  return {
@@ -108456,7 +108430,7 @@ async function ensureOpenCodeModel(options2) {
108456
108430
 
108457
108431
  // src/commands/portable/plan-display.ts
108458
108432
  var import_picocolors28 = __toESM(require_picocolors(), 1);
108459
- import { basename as basename26, dirname as dirname40, extname as extname7 } from "node:path";
108433
+ import { basename as basename26, dirname as dirname41, extname as extname7 } from "node:path";
108460
108434
  var DEFAULT_MAX_PLAN_GROUP_ITEMS = 20;
108461
108435
  var TYPE_ORDER = [
108462
108436
  "agent",
@@ -108682,21 +108656,21 @@ function collectPlannedWhereLines(plan) {
108682
108656
  return destinations.map((destination) => `${formatDisplayPath(destination)} -> ${formatCdHint(resolveCdTarget(destination))}`);
108683
108657
  }
108684
108658
  function resolveCdTarget(destination) {
108685
- return extname7(destination).length > 0 ? dirname40(destination) : destination;
108659
+ return extname7(destination).length > 0 ? dirname41(destination) : destination;
108686
108660
  }
108687
108661
  function normalizeWhereDestination(path16, portableType) {
108688
108662
  if (portableType === "agent" || portableType === "command" || portableType === "skill") {
108689
- return dirname40(path16);
108663
+ return dirname41(path16);
108690
108664
  }
108691
108665
  if (portableType === "hooks") {
108692
- return dirname40(path16);
108666
+ return dirname41(path16);
108693
108667
  }
108694
108668
  if (portableType === "rules") {
108695
108669
  const fileName = basename26(path16).toLowerCase();
108696
108670
  if (fileName === "agents.md" || fileName === "gemini.md" || fileName === ".goosehints" || fileName === "custom_modes.yaml" || fileName === "custom_modes.yml") {
108697
108671
  return path16;
108698
108672
  }
108699
- return dirname40(path16);
108673
+ return dirname41(path16);
108700
108674
  }
108701
108675
  return path16;
108702
108676
  }
@@ -110414,7 +110388,7 @@ Please use only one download method.`);
110414
110388
  // src/commands/plan/plan-command.ts
110415
110389
  init_output_manager();
110416
110390
  import { existsSync as existsSync68, statSync as statSync12 } from "node:fs";
110417
- import { dirname as dirname44, isAbsolute as isAbsolute11, join as join147, parse as parse7, resolve as resolve51 } from "node:path";
110391
+ import { dirname as dirname45, isAbsolute as isAbsolute11, join as join147, parse as parse7, resolve as resolve51 } from "node:path";
110418
110392
 
110419
110393
  // src/commands/plan/plan-read-handlers.ts
110420
110394
  init_config();
@@ -110424,18 +110398,18 @@ init_logger();
110424
110398
  init_output_manager();
110425
110399
  var import_picocolors32 = __toESM(require_picocolors(), 1);
110426
110400
  import { existsSync as existsSync67, statSync as statSync11 } from "node:fs";
110427
- import { basename as basename28, dirname as dirname42, join as join146, relative as relative30, resolve as resolve49 } from "node:path";
110401
+ import { basename as basename28, dirname as dirname43, join as join146, relative as relative30, resolve as resolve49 } from "node:path";
110428
110402
 
110429
110403
  // src/commands/plan/plan-dependencies.ts
110430
110404
  init_config();
110431
110405
  init_plan_parser();
110432
110406
  init_plans_registry();
110433
110407
  import { existsSync as existsSync66 } from "node:fs";
110434
- import { dirname as dirname41, join as join145 } from "node:path";
110408
+ import { dirname as dirname42, join as join145 } from "node:path";
110435
110409
  async function resolvePlanDependencies(references, currentPlanFile, options2 = {}) {
110436
110410
  if (references.length === 0)
110437
110411
  return [];
110438
- const currentPlanDir = dirname41(currentPlanFile);
110412
+ const currentPlanDir = dirname42(currentPlanFile);
110439
110413
  const projectRoot = findProjectRoot(currentPlanDir);
110440
110414
  const config = options2.preloadedConfig ?? (await CkConfigManager.loadFull(projectRoot)).config;
110441
110415
  const defaultScope = inferPlanScopeForDir(currentPlanDir, config);
@@ -110522,7 +110496,7 @@ async function handleParse(target, options2) {
110522
110496
  console.log(JSON.stringify({ file: relative30(process.cwd(), planFile), frontmatter, phases }, null, 2));
110523
110497
  return;
110524
110498
  }
110525
- const title = typeof frontmatter.title === "string" ? frontmatter.title : basename28(dirname42(planFile));
110499
+ const title = typeof frontmatter.title === "string" ? frontmatter.title : basename28(dirname43(planFile));
110526
110500
  console.log();
110527
110501
  console.log(import_picocolors32.default.bold(` Plan: ${title}`));
110528
110502
  console.log(` File: ${planFile}`);
@@ -110633,7 +110607,7 @@ async function handleStatus(target, options2) {
110633
110607
  const blockedBy2 = await resolvePlanDependencies(s.blockedBy, pf, { preloadedConfig });
110634
110608
  const blocks2 = await resolvePlanDependencies(s.blocks, pf, { preloadedConfig });
110635
110609
  const bar = progressBar(s.completed, s.totalPhases);
110636
- const title2 = s.title ?? basename28(dirname42(pf));
110610
+ const title2 = s.title ?? basename28(dirname43(pf));
110637
110611
  console.log(` ${import_picocolors32.default.bold(title2)}`);
110638
110612
  console.log(` ${bar}`);
110639
110613
  if (s.inProgress > 0)
@@ -110652,7 +110626,7 @@ async function handleStatus(target, options2) {
110652
110626
  }
110653
110627
  console.log();
110654
110628
  } catch {
110655
- console.log(` [X] Failed to read: ${basename28(dirname42(pf))}`);
110629
+ console.log(` [X] Failed to read: ${basename28(dirname43(pf))}`);
110656
110630
  console.log();
110657
110631
  }
110658
110632
  }
@@ -110679,7 +110653,7 @@ async function handleStatus(target, options2) {
110679
110653
  console.log(JSON.stringify({ ...summary, dependencyStatus: { blockedBy, blocks } }, null, 2));
110680
110654
  return;
110681
110655
  }
110682
- const title = summary.title ?? basename28(dirname42(planFile));
110656
+ const title = summary.title ?? basename28(dirname43(planFile));
110683
110657
  console.log();
110684
110658
  console.log(import_picocolors32.default.bold(` ${title}`));
110685
110659
  if (summary.status)
@@ -110742,7 +110716,7 @@ async function handleKanban(target, options2) {
110742
110716
  process.exitCode = 1;
110743
110717
  return;
110744
110718
  }
110745
- const route = `/plans?dir=${encodeURIComponent(dirname42(dirname42(planFile)))}&view=kanban`;
110719
+ const route = `/plans?dir=${encodeURIComponent(dirname43(dirname43(planFile)))}&view=kanban`;
110746
110720
  const url = `http://localhost:${server.port}${route}`;
110747
110721
  console.log();
110748
110722
  console.log(import_picocolors32.default.bold(" ClaudeKit Dashboard — Plans"));
@@ -110777,7 +110751,7 @@ init_plan_parser();
110777
110751
  init_plans_registry();
110778
110752
  init_output_manager();
110779
110753
  var import_picocolors33 = __toESM(require_picocolors(), 1);
110780
- import { basename as basename29, dirname as dirname43, relative as relative31, resolve as resolve50 } from "node:path";
110754
+ import { basename as basename29, dirname as dirname44, relative as relative31, resolve as resolve50 } from "node:path";
110781
110755
  async function handleCreate(target, options2) {
110782
110756
  if (!options2.title) {
110783
110757
  output.error("[X] --title is required for create");
@@ -110877,7 +110851,7 @@ async function handleCheck(target, options2) {
110877
110851
  process.exitCode = 1;
110878
110852
  return;
110879
110853
  }
110880
- const planDir = dirname43(planFile);
110854
+ const planDir = dirname44(planFile);
110881
110855
  let planStatus = "pending";
110882
110856
  try {
110883
110857
  const projectRoot = findProjectRoot(planDir);
@@ -110926,7 +110900,7 @@ async function handleUncheck(target, options2) {
110926
110900
  process.exitCode = 1;
110927
110901
  return;
110928
110902
  }
110929
- const planDir = dirname43(planFile);
110903
+ const planDir = dirname44(planFile);
110930
110904
  try {
110931
110905
  const projectRoot = findProjectRoot(planDir);
110932
110906
  const summary = buildPlanSummary(planFile);
@@ -110965,7 +110939,7 @@ async function handleAddPhase(target, options2) {
110965
110939
  try {
110966
110940
  const result = addPhase(planFile, target, options2.after);
110967
110941
  try {
110968
- const planDir = dirname43(planFile);
110942
+ const planDir = dirname44(planFile);
110969
110943
  const projectRoot = findProjectRoot(planDir);
110970
110944
  updateRegistryAddPhase({
110971
110945
  planDir,
@@ -111019,7 +110993,7 @@ function resolvePlanFile(target, baseDir) {
111019
110993
  const candidate = join147(dir, "plan.md");
111020
110994
  if (existsSync68(candidate))
111021
110995
  return candidate;
111022
- dir = dirname44(dir);
110996
+ dir = dirname45(dir);
111023
110997
  }
111024
110998
  }
111025
110999
  return null;
@@ -111538,7 +111512,7 @@ import { readFile as readFile65 } from "node:fs/promises";
111538
111512
  import { join as join149 } from "node:path";
111539
111513
 
111540
111514
  // src/commands/skills/installed-skills-inventory.ts
111541
- import { join as join148 } from "node:path";
111515
+ import { join as join148, resolve as resolve53 } from "node:path";
111542
111516
  init_path_resolver();
111543
111517
  var SCOPE_SORT_ORDER = {
111544
111518
  project: 0,
@@ -111546,9 +111520,11 @@ var SCOPE_SORT_ORDER = {
111546
111520
  };
111547
111521
  async function getActiveClaudeSkillInstallations(options2 = {}) {
111548
111522
  const projectDir = options2.projectDir ?? process.cwd();
111549
- const globalDir = options2.globalDir ?? PathResolver.getGlobalKitDir();
111523
+ const globalDir = resolve53(options2.globalDir ?? PathResolver.getGlobalKitDir());
111524
+ const projectClaudeDir = resolve53(projectDir, ".claude");
111525
+ const projectScopeAliasesGlobal = projectClaudeDir === globalDir;
111550
111526
  const [projectSkills, globalSkills] = await Promise.all([
111551
- scanSkills2(join148(projectDir, ".claude", "skills")),
111527
+ projectScopeAliasesGlobal ? Promise.resolve([]) : scanSkills2(join148(projectClaudeDir, "skills")),
111552
111528
  scanSkills2(join148(globalDir, "skills"))
111553
111529
  ]);
111554
111530
  const projectIds = new Set(projectSkills.map((skill) => skill.id));
@@ -112292,7 +112268,7 @@ async function detectInstallations() {
112292
112268
 
112293
112269
  // src/commands/uninstall/removal-handler.ts
112294
112270
  import { readdirSync as readdirSync10, rmSync as rmSync5 } from "node:fs";
112295
- import { basename as basename30, join as join151, resolve as resolve53, sep as sep13 } from "node:path";
112271
+ import { basename as basename30, join as join151, resolve as resolve54, sep as sep13 } from "node:path";
112296
112272
  init_logger();
112297
112273
  init_safe_prompts();
112298
112274
  init_safe_spinner();
@@ -112301,7 +112277,7 @@ var import_fs_extra41 = __toESM(require_lib(), 1);
112301
112277
  // src/commands/uninstall/analysis-handler.ts
112302
112278
  init_metadata_migration();
112303
112279
  import { readdirSync as readdirSync9, rmSync as rmSync4 } from "node:fs";
112304
- import { dirname as dirname45, join as join150 } from "node:path";
112280
+ import { dirname as dirname46, join as join150 } from "node:path";
112305
112281
  init_logger();
112306
112282
  init_safe_prompts();
112307
112283
  var import_fs_extra40 = __toESM(require_lib(), 1);
@@ -112323,7 +112299,7 @@ function classifyFileByOwnership(ownership, forceOverwrite, deleteReason) {
112323
112299
  }
112324
112300
  async function cleanupEmptyDirectories3(filePath, installationRoot) {
112325
112301
  let cleaned = 0;
112326
- let currentDir = dirname45(filePath);
112302
+ let currentDir = dirname46(filePath);
112327
112303
  while (currentDir !== installationRoot && currentDir.startsWith(installationRoot)) {
112328
112304
  try {
112329
112305
  const entries = readdirSync9(currentDir);
@@ -112331,7 +112307,7 @@ async function cleanupEmptyDirectories3(filePath, installationRoot) {
112331
112307
  rmSync4(currentDir, { recursive: true });
112332
112308
  cleaned++;
112333
112309
  logger.debug(`Removed empty directory: ${currentDir}`);
112334
- currentDir = dirname45(currentDir);
112310
+ currentDir = dirname46(currentDir);
112335
112311
  } else {
112336
112312
  break;
112337
112313
  }
@@ -112476,8 +112452,8 @@ async function restoreUninstallBackup(backup) {
112476
112452
  }
112477
112453
  async function isPathSafeToRemove(filePath, baseDir) {
112478
112454
  try {
112479
- const resolvedPath = resolve53(filePath);
112480
- const resolvedBase = resolve53(baseDir);
112455
+ const resolvedPath = resolve54(filePath);
112456
+ const resolvedBase = resolve54(baseDir);
112481
112457
  if (!resolvedPath.startsWith(resolvedBase + sep13) && resolvedPath !== resolvedBase) {
112482
112458
  logger.debug(`Path outside installation directory: ${filePath}`);
112483
112459
  return false;
@@ -112485,7 +112461,7 @@ async function isPathSafeToRemove(filePath, baseDir) {
112485
112461
  const stats = await import_fs_extra41.lstat(filePath);
112486
112462
  if (stats.isSymbolicLink()) {
112487
112463
  const realPath = await import_fs_extra41.realpath(filePath);
112488
- const resolvedReal = resolve53(realPath);
112464
+ const resolvedReal = resolve54(realPath);
112489
112465
  if (!resolvedReal.startsWith(resolvedBase + sep13) && resolvedReal !== resolvedBase) {
112490
112466
  logger.debug(`Symlink points outside installation directory: ${filePath} -> ${realPath}`);
112491
112467
  return false;
@@ -114253,7 +114229,7 @@ init_file_io();
114253
114229
  init_logger();
114254
114230
  import { existsSync as existsSync71 } from "node:fs";
114255
114231
  import { mkdir as mkdir40, readFile as readFile67 } from "node:fs/promises";
114256
- import { dirname as dirname46 } from "node:path";
114232
+ import { dirname as dirname47 } from "node:path";
114257
114233
  var PROCESSED_ISSUES_CAP = 500;
114258
114234
  async function readCkJson(projectDir) {
114259
114235
  const configPath = CkConfigManager.getProjectConfigPath(projectDir);
@@ -114283,7 +114259,7 @@ async function loadWatchState(projectDir) {
114283
114259
  }
114284
114260
  async function saveWatchState(projectDir, state) {
114285
114261
  const configPath = CkConfigManager.getProjectConfigPath(projectDir);
114286
- const configDir = dirname46(configPath);
114262
+ const configDir = dirname47(configPath);
114287
114263
  if (!existsSync71(configDir)) {
114288
114264
  await mkdir40(configDir, { recursive: true });
114289
114265
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudekit-cli",
3
- "version": "4.2.2",
3
+ "version": "4.2.3-dev.1",
4
4
  "description": "CLI tool for bootstrapping and updating ClaudeKit projects",
5
5
  "type": "module",
6
6
  "repository": {