claudekit-cli 3.41.4-dev.52 → 3.41.4-dev.53

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": "3.41.4-dev.52",
3
- "generatedAt": "2026-04-24T21:12:39.210Z",
2
+ "version": "3.41.4-dev.53",
3
+ "generatedAt": "2026-04-24T21:32:46.232Z",
4
4
  "commands": {
5
5
  "agents": {
6
6
  "name": "agents",
package/dist/index.js CHANGED
@@ -53854,7 +53854,7 @@ var init_gemini_hook_event_map = __esm(() => {
53854
53854
  import { existsSync as existsSync25 } from "node:fs";
53855
53855
  import { mkdir as mkdir11, readFile as readFile21, rename as rename7, rm as rm5, writeFile as writeFile12 } from "node:fs/promises";
53856
53856
  import { homedir as homedir27 } from "node:os";
53857
- import { basename as basename11, dirname as dirname12, isAbsolute as isAbsolute5, join as join39, resolve as resolve15 } from "node:path";
53857
+ import { basename as basename11, dirname as dirname12, join as join39, resolve as resolve15 } from "node:path";
53858
53858
  function validateHooksSectionShape(value) {
53859
53859
  if (!value || typeof value !== "object" || Array.isArray(value)) {
53860
53860
  return "hooks must be a non-null object";
@@ -54017,33 +54017,31 @@ async function mergeHooksIntoSettings(targetSettingsPath, newHooks) {
54017
54017
  }
54018
54018
  return { backupPath };
54019
54019
  }
54020
- function extractLeadingAbsolutePath(command) {
54021
- const trimmed = command.trim();
54022
- if (trimmed.length === 0)
54023
- return null;
54024
- const firstToken = trimmed.split(/\s+/)[0];
54025
- if (!firstToken)
54026
- return null;
54027
- if (!isAbsolute5(firstToken))
54028
- return null;
54029
- return firstToken;
54030
- }
54031
54020
  function isCkManagedHookPath(absPath) {
54032
54021
  const normalized = absPath.replace(/\\/g, "/");
54033
54022
  return normalized.includes("/.claude/hooks/") || normalized.includes("/.codex/hooks/") || normalized.includes("/.gemini/hooks/");
54034
54023
  }
54024
+ function extractAbsolutePaths(command) {
54025
+ const matches = [];
54026
+ const pathPattern = /(?:^|[\s"'(])(\/[^\s"'()]+)/g;
54027
+ let match = pathPattern.exec(command);
54028
+ while (match !== null) {
54029
+ matches.push(match[1]);
54030
+ match = pathPattern.exec(command);
54031
+ }
54032
+ return matches;
54033
+ }
54035
54034
  function pruneStaleFileHooks(existing) {
54036
54035
  const result = {};
54037
54036
  for (const [event, groups] of Object.entries(existing)) {
54038
54037
  const prunedGroups = [];
54039
54038
  for (const group of groups) {
54040
54039
  const survivingHooks = group.hooks.filter((h2) => {
54041
- const path3 = extractLeadingAbsolutePath(h2.command);
54042
- if (path3 === null)
54043
- return true;
54044
- if (!isCkManagedHookPath(path3))
54040
+ const paths = extractAbsolutePaths(h2.command);
54041
+ const ckPaths = paths.filter(isCkManagedHookPath);
54042
+ if (ckPaths.length === 0)
54045
54043
  return true;
54046
- return existsSync25(path3);
54044
+ return ckPaths.some((p) => existsSync25(p));
54047
54045
  });
54048
54046
  if (survivingHooks.length > 0) {
54049
54047
  prunedGroups.push({ ...group, hooks: survivingHooks });
@@ -57820,13 +57818,13 @@ var init_plan_scanner = () => {};
57820
57818
 
57821
57819
  // src/domains/plan-parser/plan-scope.ts
57822
57820
  import { homedir as homedir30 } from "node:os";
57823
- import { isAbsolute as isAbsolute6, join as join44, relative as relative9, resolve as resolve18 } from "node:path";
57821
+ import { isAbsolute as isAbsolute5, join as join44, relative as relative9, resolve as resolve18 } from "node:path";
57824
57822
  function resolveConfiguredDir(configuredPath, baseDir) {
57825
57823
  const trimmed = configuredPath?.trim();
57826
57824
  if (!trimmed) {
57827
57825
  return join44(baseDir, DEFAULT_PLANS_DIRNAME);
57828
57826
  }
57829
- return isAbsolute6(trimmed) ? resolve18(trimmed) : resolve18(baseDir, trimmed);
57827
+ return isAbsolute5(trimmed) ? resolve18(trimmed) : resolve18(baseDir, trimmed);
57830
57828
  }
57831
57829
  function resolveProjectPlansDir(projectRoot, config) {
57832
57830
  return resolveConfiguredDir(config?.paths?.plans, projectRoot);
@@ -57841,7 +57839,7 @@ function isWithinDir(targetPath, baseDir) {
57841
57839
  const resolvedTarget = resolve18(targetPath);
57842
57840
  const resolvedBase = resolve18(baseDir);
57843
57841
  const relativePath = relative9(resolvedBase, resolvedTarget);
57844
- return relativePath === "" || !relativePath.startsWith("..") && relativePath !== ".." && !isAbsolute6(relativePath);
57842
+ return relativePath === "" || !relativePath.startsWith("..") && relativePath !== ".." && !isAbsolute5(relativePath);
57845
57843
  }
57846
57844
  function inferPlanScopeForDir(planDir, config) {
57847
57845
  return isWithinDir(planDir, resolveGlobalPlansDir(config)) ? "global" : "project";
@@ -57850,7 +57848,7 @@ function parsePlanReference(reference, defaultScope) {
57850
57848
  const trimmed = reference.trim();
57851
57849
  const normalizePlanId = (rawPlanId) => {
57852
57850
  const planId = rawPlanId.trim();
57853
- const valid = planId.length > 0 && !isAbsolute6(planId) && !planId.includes("/") && !planId.includes("\\") && PLAN_ID_PATTERN.test(planId);
57851
+ const valid = planId.length > 0 && !isAbsolute5(planId) && !planId.includes("/") && !planId.includes("\\") && PLAN_ID_PATTERN.test(planId);
57854
57852
  return { planId, valid };
57855
57853
  };
57856
57854
  if (trimmed.startsWith(GLOBAL_PLAN_PREFIX)) {
@@ -58631,7 +58629,7 @@ import {
58631
58629
  unlinkSync,
58632
58630
  writeFileSync as writeFileSync4
58633
58631
  } from "node:fs";
58634
- import { dirname as dirname18, isAbsolute as isAbsolute7, join as join47, parse as parse2, relative as relative10, resolve as resolve19 } from "node:path";
58632
+ import { dirname as dirname18, isAbsolute as isAbsolute6, join as join47, parse as parse2, relative as relative10, resolve as resolve19 } from "node:path";
58635
58633
  function createEmptyRegistry() {
58636
58634
  return {
58637
58635
  version: 1,
@@ -58686,7 +58684,7 @@ function migrateFromProjectLocal(cwd2, globalPath) {
58686
58684
  }
58687
58685
  }
58688
58686
  function normalizeRegistryDir(cwd2, dir) {
58689
- const absoluteDir = isAbsolute7(dir) ? dir : resolve19(cwd2, dir);
58687
+ const absoluteDir = isAbsolute6(dir) ? dir : resolve19(cwd2, dir);
58690
58688
  const relativeDir = relative10(cwd2, absoluteDir) || dir;
58691
58689
  return relativeDir.replace(/\\/g, "/");
58692
58690
  }
@@ -62246,7 +62244,7 @@ var package_default;
62246
62244
  var init_package = __esm(() => {
62247
62245
  package_default = {
62248
62246
  name: "claudekit-cli",
62249
- version: "3.41.4-dev.52",
62247
+ version: "3.41.4-dev.53",
62250
62248
  description: "CLI tool for bootstrapping and updating ClaudeKit projects",
62251
62249
  type: "module",
62252
62250
  repository: {
@@ -82474,11 +82472,11 @@ init_path_resolver();
82474
82472
  init_zod();
82475
82473
  var import_fs_extra9 = __toESM(require_lib3(), 1);
82476
82474
  import { mkdir as mkdir19, readdir as readdir17, readlink, rename as rename10, symlink } from "node:fs/promises";
82477
- import { basename as basename21, dirname as dirname28, isAbsolute as isAbsolute8, join as join71, normalize as normalize4, resolve as resolve27, sep as sep8 } from "node:path";
82475
+ import { basename as basename21, dirname as dirname28, isAbsolute as isAbsolute7, join as join71, normalize as normalize4, resolve as resolve27, sep as sep8 } from "node:path";
82478
82476
  var SNAPSHOT_DIR = "snapshot";
82479
82477
  var MANIFEST_FILE = "manifest.json";
82480
82478
  function normalizeRelativePath(rootDir, inputPath) {
82481
- if (!inputPath || isAbsolute8(inputPath)) {
82479
+ if (!inputPath || isAbsolute7(inputPath)) {
82482
82480
  throw new Error(`Unsafe backup path: ${inputPath}`);
82483
82481
  }
82484
82482
  const normalized = normalize4(inputPath).replaceAll("\\", "/");
@@ -82738,7 +82736,7 @@ async function loadDestructiveOperationBackup(backupDir) {
82738
82736
  const resolvedBackupDir = await assertManagedBackupDir(backupDir);
82739
82737
  const manifestPath = join71(resolvedBackupDir, MANIFEST_FILE);
82740
82738
  const manifest = destructiveOperationBackupManifestSchema.parse(await import_fs_extra9.readJson(manifestPath));
82741
- if (!isAbsolute8(manifest.sourceRoot)) {
82739
+ if (!isAbsolute7(manifest.sourceRoot)) {
82742
82740
  throw new Error(`Backup manifest source root must be absolute: ${manifest.sourceRoot}`);
82743
82741
  }
82744
82742
  const resolvedSourceRoot = resolve27(manifest.sourceRoot);
@@ -88594,7 +88592,7 @@ init_config_version_checker();
88594
88592
 
88595
88593
  // src/domains/sync/sync-engine.ts
88596
88594
  import { lstat as lstat4, readFile as readFile43, readlink as readlink2, realpath as realpath6, stat as stat15 } from "node:fs/promises";
88597
- import { isAbsolute as isAbsolute9, join as join91, normalize as normalize8, relative as relative15 } from "node:path";
88595
+ import { isAbsolute as isAbsolute8, join as join91, normalize as normalize8, relative as relative15 } from "node:path";
88598
88596
 
88599
88597
  // src/services/file-operations/ownership-checker.ts
88600
88598
  init_metadata_migration();
@@ -89816,10 +89814,10 @@ async function validateSymlinkChain(path7, basePath, maxDepth = MAX_SYMLINK_DEPT
89816
89814
  if (!stats.isSymbolicLink())
89817
89815
  break;
89818
89816
  const target = await readlink2(current);
89819
- const resolvedTarget = isAbsolute9(target) ? target : join91(current, "..", target);
89817
+ const resolvedTarget = isAbsolute8(target) ? target : join91(current, "..", target);
89820
89818
  const normalizedTarget = normalize8(resolvedTarget);
89821
89819
  const rel = relative15(basePath, normalizedTarget);
89822
- if (rel.startsWith("..") || isAbsolute9(rel)) {
89820
+ if (rel.startsWith("..") || isAbsolute8(rel)) {
89823
89821
  throw new Error(`Symlink chain escapes base directory at depth ${depth}: ${path7}`);
89824
89822
  }
89825
89823
  current = normalizedTarget;
@@ -89846,7 +89844,7 @@ async function validateSyncPath(basePath, filePath) {
89846
89844
  throw new Error(`Path too long: ${filePath.slice(0, 50)}...`);
89847
89845
  }
89848
89846
  const normalized = normalize8(filePath);
89849
- if (isAbsolute9(normalized)) {
89847
+ if (isAbsolute8(normalized)) {
89850
89848
  throw new Error(`Absolute paths not allowed: ${filePath}`);
89851
89849
  }
89852
89850
  if (normalized.startsWith("..") || normalized.includes("/../")) {
@@ -89854,7 +89852,7 @@ async function validateSyncPath(basePath, filePath) {
89854
89852
  }
89855
89853
  const fullPath = join91(basePath, normalized);
89856
89854
  const rel = relative15(basePath, fullPath);
89857
- if (rel.startsWith("..") || isAbsolute9(rel)) {
89855
+ if (rel.startsWith("..") || isAbsolute8(rel)) {
89858
89856
  throw new Error(`Path escapes base directory: ${filePath}`);
89859
89857
  }
89860
89858
  await validateSymlinkChain(fullPath, basePath);
@@ -89862,7 +89860,7 @@ async function validateSyncPath(basePath, filePath) {
89862
89860
  const resolvedBase = await realpath6(basePath);
89863
89861
  const resolvedFull = await realpath6(fullPath);
89864
89862
  const resolvedRel = relative15(resolvedBase, resolvedFull);
89865
- if (resolvedRel.startsWith("..") || isAbsolute9(resolvedRel)) {
89863
+ if (resolvedRel.startsWith("..") || isAbsolute8(resolvedRel)) {
89866
89864
  throw new Error(`Symlink escapes base directory: ${filePath}`);
89867
89865
  }
89868
89866
  } catch (error) {
@@ -89872,7 +89870,7 @@ async function validateSyncPath(basePath, filePath) {
89872
89870
  const resolvedBase = await realpath6(basePath);
89873
89871
  const resolvedParent = await realpath6(parentPath);
89874
89872
  const resolvedRel = relative15(resolvedBase, resolvedParent);
89875
- if (resolvedRel.startsWith("..") || isAbsolute9(resolvedRel)) {
89873
+ if (resolvedRel.startsWith("..") || isAbsolute8(resolvedRel)) {
89876
89874
  throw new Error(`Parent symlink escapes base directory: ${filePath}`);
89877
89875
  }
89878
89876
  } catch (parentError) {
@@ -95320,11 +95318,11 @@ var modeFix = (mode, isDir, portable) => {
95320
95318
 
95321
95319
  // node_modules/tar/dist/esm/strip-absolute-path.js
95322
95320
  import { win32 as win322 } from "node:path";
95323
- var { isAbsolute: isAbsolute10, parse: parse5 } = win322;
95321
+ var { isAbsolute: isAbsolute9, parse: parse5 } = win322;
95324
95322
  var stripAbsolutePath = (path7) => {
95325
95323
  let r2 = "";
95326
95324
  let parsed = parse5(path7);
95327
- while (isAbsolute10(path7) || parsed.root) {
95325
+ while (isAbsolute9(path7) || parsed.root) {
95328
95326
  const root = path7.charAt(0) === "/" && path7.slice(0, 4) !== "//?/" ? "/" : parsed.root;
95329
95327
  path7 = path7.slice(root.length);
95330
95328
  r2 += root;
@@ -108965,7 +108963,7 @@ Please use only one download method.`);
108965
108963
  // src/commands/plan/plan-command.ts
108966
108964
  init_output_manager();
108967
108965
  import { existsSync as existsSync67, statSync as statSync12 } from "node:fs";
108968
- import { dirname as dirname46, isAbsolute as isAbsolute12, join as join147, parse as parse7, resolve as resolve46 } from "node:path";
108966
+ import { dirname as dirname46, isAbsolute as isAbsolute11, join as join147, parse as parse7, resolve as resolve46 } from "node:path";
108969
108967
 
108970
108968
  // src/commands/plan/plan-read-handlers.ts
108971
108969
  init_config();
@@ -109033,14 +109031,14 @@ init_config();
109033
109031
  init_plan_parser();
109034
109032
  init_plan_scope();
109035
109033
  init_plans_registry();
109036
- import { isAbsolute as isAbsolute11, resolve as resolve43 } from "node:path";
109034
+ import { isAbsolute as isAbsolute10, resolve as resolve43 } from "node:path";
109037
109035
  async function getGlobalPlansDirFromCwd() {
109038
109036
  const projectRoot = findProjectRoot(process.cwd());
109039
109037
  const { config } = await CkConfigManager.loadFull(projectRoot);
109040
109038
  return resolveGlobalPlansDir(config);
109041
109039
  }
109042
109040
  function resolveTargetFromBase(target, baseDir) {
109043
- const resolvedTarget = isAbsolute11(target) ? resolve43(target) : resolve43(baseDir, target);
109041
+ const resolvedTarget = isAbsolute10(target) ? resolve43(target) : resolve43(baseDir, target);
109044
109042
  return isWithinDir(resolvedTarget, baseDir) ? resolvedTarget : null;
109045
109043
  }
109046
109044
 
@@ -109544,7 +109542,7 @@ function resolveTargetPath(target, baseDir) {
109544
109542
  if (!baseDir) {
109545
109543
  return resolve46(target);
109546
109544
  }
109547
- if (isAbsolute12(target)) {
109545
+ if (isAbsolute11(target)) {
109548
109546
  return resolve46(target);
109549
109547
  }
109550
109548
  const cwdCandidate = resolve46(target);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudekit-cli",
3
- "version": "3.41.4-dev.52",
3
+ "version": "3.41.4-dev.53",
4
4
  "description": "CLI tool for bootstrapping and updating ClaudeKit projects",
5
5
  "type": "module",
6
6
  "repository": {