claudekit-cli 3.42.2-dev.5 → 3.42.2-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": "3.42.2-dev.5",
3
- "generatedAt": "2026-04-30T19:53:41.311Z",
2
+ "version": "3.42.2-dev.7",
3
+ "generatedAt": "2026-05-04T15:29:19.209Z",
4
4
  "commands": {
5
5
  "agents": {
6
6
  "name": "agents",
package/dist/index.js CHANGED
@@ -43804,6 +43804,26 @@ function repairClaudeNodeCommandPath(cmd, root) {
43804
43804
  const command = formatCanonicalClaudeCommand(nodePrefix, root, relativePath, suffix);
43805
43805
  return { command, changed: command !== cmd, issue: "invalid-format" };
43806
43806
  }
43807
+ const absoluteMatch = cmd.match(/^(node\s+)"((?:[A-Za-z]:[/\\]|\/)[^"]*?[/\\]\.claude[/\\][^"]+)"(.*)$/) ?? cmd.match(/^(node\s+)((?:[A-Za-z]:[\\/]|\/)[^\s"]*?[\\/]\.claude[\\/][^\s"]+)(.*)$/);
43808
+ if (absoluteMatch) {
43809
+ const [, nodePrefix, absolutePath, suffix] = absoluteMatch;
43810
+ const normalizedAbsPath = absolutePath.replace(/\\/g, "/");
43811
+ const dotClaudeIdx = normalizedAbsPath.indexOf("/.claude/");
43812
+ if (dotClaudeIdx === -1) {
43813
+ return { command: cmd, changed: false, issue: null };
43814
+ }
43815
+ const isWin2 = process.platform === "win32";
43816
+ const cmp = (s) => isWin2 ? s.toLowerCase() : s;
43817
+ const globalRoots = [
43818
+ `${homedir11().replace(/\\/g, "/").replace(/\/+$/, "")}/.claude/`,
43819
+ `${PathResolver.getGlobalKitDir().replace(/\\/g, "/").replace(/\/+$/, "")}/`
43820
+ ];
43821
+ const isUnderGlobal = globalRoots.some((g2) => cmp(normalizedAbsPath).startsWith(cmp(g2)));
43822
+ const resolvedRoot = isUnderGlobal ? "$HOME" : root;
43823
+ const relativePath = normalizedAbsPath.slice(dotClaudeIdx + 1);
43824
+ const command = formatCanonicalClaudeCommand(nodePrefix, resolvedRoot, relativePath, suffix);
43825
+ return { command, changed: command !== cmd, issue: "invalid-format" };
43826
+ }
43807
43827
  return { command: cmd, changed: false, issue: null };
43808
43828
  }
43809
43829
  function normalizeCommand(cmd) {
@@ -62369,7 +62389,7 @@ var package_default;
62369
62389
  var init_package = __esm(() => {
62370
62390
  package_default = {
62371
62391
  name: "claudekit-cli",
62372
- version: "3.42.2-dev.5",
62392
+ version: "3.42.2-dev.7",
62373
62393
  description: "CLI tool for bootstrapping and updating ClaudeKit projects",
62374
62394
  type: "module",
62375
62395
  repository: {
@@ -86203,6 +86223,20 @@ import { join as join86, resolve as resolve31 } from "node:path";
86203
86223
  var HOOK_CHECK_TIMEOUT_MS = 5000;
86204
86224
  var PYTHON_CHECK_TIMEOUT_MS = 3000;
86205
86225
  var MAX_LOG_FILE_SIZE_BYTES = 10 * 1024 * 1024;
86226
+
86227
+ class FixerDidNotConvergeError extends Error {
86228
+ unresolved;
86229
+ constructor(unresolved) {
86230
+ const lines = unresolved.map((f3) => ` ${f3.label} :: ${f3.eventName} :: ${f3.command}`).join(`
86231
+ `);
86232
+ super(`ck doctor --fix: fixer did not converge — ${unresolved.length} stale hook command path(s) remain after repair:
86233
+ ${lines}
86234
+
86235
+ This is a bug. Please open an issue at https://github.com/mrgoonie/claudekit-cli`);
86236
+ this.name = "FixerDidNotConvergeError";
86237
+ this.unresolved = unresolved;
86238
+ }
86239
+ }
86206
86240
  function getHooksDir(projectDir) {
86207
86241
  const projectHooksDir = resolve31(projectDir, ".claude", "hooks");
86208
86242
  const globalHooksDir = resolve31(PathResolver.getGlobalKitDir(), "hooks");
@@ -86296,13 +86330,18 @@ async function repairHookCommandsInSettingsFile(settingsFile) {
86296
86330
  if (!settings?.hooks) {
86297
86331
  return 0;
86298
86332
  }
86333
+ const findings = collectHookCommandFindings(settings, settingsFile);
86334
+ if (findings.length === 0) {
86335
+ return 0;
86336
+ }
86337
+ const repairMap = new Map(findings.map((f3) => [f3.command, f3.expected]));
86299
86338
  let repaired = 0;
86300
86339
  for (const entries of Object.values(settings.hooks)) {
86301
86340
  for (const entry of entries) {
86302
86341
  if ("command" in entry && typeof entry.command === "string") {
86303
- const repair = repairClaudeNodeCommandPath(entry.command, settingsFile.root);
86304
- if (repair.changed) {
86305
- entry.command = repair.command;
86342
+ const fixed = repairMap.get(entry.command);
86343
+ if (fixed !== undefined) {
86344
+ entry.command = fixed;
86306
86345
  repaired++;
86307
86346
  }
86308
86347
  }
@@ -86313,9 +86352,9 @@ async function repairHookCommandsInSettingsFile(settingsFile) {
86313
86352
  if (!hook.command) {
86314
86353
  continue;
86315
86354
  }
86316
- const repair = repairClaudeNodeCommandPath(hook.command, settingsFile.root);
86317
- if (repair.changed) {
86318
- hook.command = repair.command;
86355
+ const fixed = repairMap.get(hook.command);
86356
+ if (fixed !== undefined) {
86357
+ hook.command = fixed;
86319
86358
  repaired++;
86320
86359
  }
86321
86360
  }
@@ -86324,6 +86363,10 @@ async function repairHookCommandsInSettingsFile(settingsFile) {
86324
86363
  if (repaired > 0) {
86325
86364
  await SettingsMerger.writeSettingsFile(settingsFile.path, settings);
86326
86365
  }
86366
+ const remaining = collectHookCommandFindings(settings, settingsFile);
86367
+ if (remaining.length > 0) {
86368
+ throw new FixerDidNotConvergeError(remaining);
86369
+ }
86327
86370
  return repaired;
86328
86371
  }
86329
86372
  async function checkHookSyntax(projectDir) {
@@ -104868,24 +104911,63 @@ import { mkdir as mkdir34 } from "node:fs/promises";
104868
104911
  import { join as join135, resolve as resolve38 } from "node:path";
104869
104912
 
104870
104913
  // src/domains/github/kit-access-checker.ts
104914
+ init_error2();
104871
104915
  init_logger();
104872
104916
  init_safe_spinner();
104873
104917
  init_types3();
104918
+ init_types3();
104874
104919
  init_github_client();
104920
+ function toGitHubError(error) {
104921
+ if (error instanceof GitHubError) {
104922
+ return error;
104923
+ }
104924
+ const classified = classifyGitHubError(error, "check repository access");
104925
+ const actions = suggestActions(classified.category);
104926
+ const formattedActions = formatActions(actions);
104927
+ const messageParts = [classified.message];
104928
+ if (classified.details) {
104929
+ messageParts.push(`
104930
+ ${classified.details}`);
104931
+ }
104932
+ if (formattedActions) {
104933
+ messageParts.push(`
104934
+ Solutions:${formattedActions}`);
104935
+ }
104936
+ messageParts.push(`
104937
+ Need help? Run with: ck new --verbose`);
104938
+ return new GitHubError(messageParts.join(`
104939
+ `), classified.httpStatus);
104940
+ }
104875
104941
  async function detectAccessibleKits() {
104876
104942
  const spinner = createSpinner("Checking kit access...").start();
104877
104943
  const github = new GitHubClient;
104878
- const results = await Promise.all(Object.entries(AVAILABLE_KITS).map(async ([type, config]) => {
104879
- try {
104880
- await github.checkAccess(config);
104881
- logger.debug(`Access confirmed: ${type}`);
104882
- return type;
104883
- } catch {
104884
- logger.debug(`No access to ${type}`);
104885
- return null;
104886
- }
104944
+ const settled = await Promise.allSettled(Object.entries(AVAILABLE_KITS).map(async ([type, config]) => {
104945
+ await github.checkAccess(config);
104946
+ logger.debug(`Access confirmed: ${type}`);
104947
+ return type;
104887
104948
  }));
104888
- const accessible = results.filter((kit) => kit !== null);
104949
+ const accessible = [];
104950
+ const fatalErrors = [];
104951
+ for (const result of settled) {
104952
+ if (result.status === "fulfilled") {
104953
+ accessible.push(result.value);
104954
+ } else {
104955
+ const err = result.reason;
104956
+ const status = err?.statusCode ?? err?.status;
104957
+ if (status === 404) {
104958
+ logger.debug("No access to kit (404)");
104959
+ } else {
104960
+ fatalErrors.push(toGitHubError(err));
104961
+ }
104962
+ }
104963
+ }
104964
+ if (fatalErrors.length > 0) {
104965
+ spinner.fail("Kit access check failed");
104966
+ for (const extra of fatalErrors.slice(1)) {
104967
+ logger.debug(`Additional kit access error (suppressed): ${extra.message}`);
104968
+ }
104969
+ throw fatalErrors[0];
104970
+ }
104889
104971
  if (accessible.length === 0) {
104890
104972
  spinner.fail("No kit access found");
104891
104973
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudekit-cli",
3
- "version": "3.42.2-dev.5",
3
+ "version": "3.42.2-dev.7",
4
4
  "description": "CLI tool for bootstrapping and updating ClaudeKit projects",
5
5
  "type": "module",
6
6
  "repository": {