claudekit-cli 3.24.1 → 3.26.0

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.
Files changed (2) hide show
  1. package/dist/index.js +630 -467
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -6297,7 +6297,7 @@ var require_jsonfile = __commonJS((exports, module) => {
6297
6297
  return obj;
6298
6298
  }
6299
6299
  var readFile = universalify.fromPromise(_readFile);
6300
- function readFileSync3(file, options = {}) {
6300
+ function readFileSync4(file, options = {}) {
6301
6301
  if (typeof options === "string") {
6302
6302
  options = { encoding: options };
6303
6303
  }
@@ -6329,7 +6329,7 @@ var require_jsonfile = __commonJS((exports, module) => {
6329
6329
  }
6330
6330
  module.exports = {
6331
6331
  readFile,
6332
- readFileSync: readFileSync3,
6332
+ readFileSync: readFileSync4,
6333
6333
  writeFile,
6334
6334
  writeFileSync
6335
6335
  };
@@ -8208,7 +8208,7 @@ var init_opencode_installer = __esm(() => {
8208
8208
  var PARTIAL_INSTALL_VERSION = "partial", EXIT_CODE_CRITICAL_FAILURE = 1, EXIT_CODE_PARTIAL_SUCCESS = 2;
8209
8209
 
8210
8210
  // src/services/package-installer/install-error-handler.ts
8211
- import { existsSync as existsSync13, readFileSync as readFileSync5, unlinkSync as unlinkSync2 } from "node:fs";
8211
+ import { existsSync as existsSync13, readFileSync as readFileSync6, unlinkSync as unlinkSync2 } from "node:fs";
8212
8212
  import { join as join21 } from "node:path";
8213
8213
  function parseNameReason(str) {
8214
8214
  const colonIndex = str.indexOf(":");
@@ -8225,7 +8225,7 @@ function displayInstallErrors(skillsDir) {
8225
8225
  }
8226
8226
  let summary;
8227
8227
  try {
8228
- summary = JSON.parse(readFileSync5(summaryPath, "utf-8"));
8228
+ summary = JSON.parse(readFileSync6(summaryPath, "utf-8"));
8229
8229
  } catch (parseError) {
8230
8230
  logger.error("Failed to parse error summary. File may be corrupted.");
8231
8231
  logger.debug(`Parse error: ${parseError instanceof Error ? parseError.message : String(parseError)}`);
@@ -16529,22 +16529,22 @@ function padEnd(text, width) {
16529
16529
  const padding = Math.max(0, width - visibleLength);
16530
16530
  return text + " ".repeat(padding);
16531
16531
  }
16532
- var import_picocolors28, NO_COLOR, isColorSupported, identity = (text) => text, colors, defaultTheme;
16532
+ var import_picocolors27, NO_COLOR, isColorSupported, identity = (text) => text, colors, defaultTheme;
16533
16533
  var init_help_colors = __esm(() => {
16534
- import_picocolors28 = __toESM(require_picocolors(), 1);
16534
+ import_picocolors27 = __toESM(require_picocolors(), 1);
16535
16535
  NO_COLOR = process.env.NO_COLOR !== undefined;
16536
16536
  isColorSupported = !NO_COLOR && Boolean(process.stdout.isTTY);
16537
16537
  colors = {
16538
- banner: isColorSupported ? import_picocolors28.default.cyan : identity,
16539
- command: isColorSupported ? import_picocolors28.default.bold : identity,
16540
- heading: isColorSupported ? import_picocolors28.default.yellow : identity,
16541
- flag: isColorSupported ? import_picocolors28.default.green : identity,
16542
- description: isColorSupported ? import_picocolors28.default.gray : identity,
16543
- example: isColorSupported ? import_picocolors28.default.blue : identity,
16544
- warning: isColorSupported ? import_picocolors28.default.yellow : identity,
16545
- error: isColorSupported ? import_picocolors28.default.red : identity,
16546
- muted: isColorSupported ? import_picocolors28.default.dim : identity,
16547
- success: isColorSupported ? import_picocolors28.default.green : identity
16538
+ banner: isColorSupported ? import_picocolors27.default.cyan : identity,
16539
+ command: isColorSupported ? import_picocolors27.default.bold : identity,
16540
+ heading: isColorSupported ? import_picocolors27.default.yellow : identity,
16541
+ flag: isColorSupported ? import_picocolors27.default.green : identity,
16542
+ description: isColorSupported ? import_picocolors27.default.gray : identity,
16543
+ example: isColorSupported ? import_picocolors27.default.blue : identity,
16544
+ warning: isColorSupported ? import_picocolors27.default.yellow : identity,
16545
+ error: isColorSupported ? import_picocolors27.default.red : identity,
16546
+ muted: isColorSupported ? import_picocolors27.default.dim : identity,
16547
+ success: isColorSupported ? import_picocolors27.default.green : identity
16548
16548
  };
16549
16549
  defaultTheme = {
16550
16550
  banner: colors.banner,
@@ -17682,6 +17682,70 @@ class CheckRunner {
17682
17682
  import { exec as exec4 } from "node:child_process";
17683
17683
  import { promisify as promisify4 } from "node:util";
17684
17684
 
17685
+ // src/domains/github/gh-cli-utils.ts
17686
+ init_logger();
17687
+ import { readFileSync } from "node:fs";
17688
+ var MIN_GH_CLI_VERSION = "2.20.0";
17689
+ var GH_COMMAND_TIMEOUT_MS = 1e4;
17690
+ function compareVersions(a, b) {
17691
+ const partsA = a.split(".").map(Number);
17692
+ const partsB = b.split(".").map(Number);
17693
+ const maxLen = Math.max(partsA.length, partsB.length);
17694
+ for (let i = 0;i < maxLen; i++) {
17695
+ const numA = partsA[i] ?? 0;
17696
+ const numB = partsB[i] ?? 0;
17697
+ if (numA < numB)
17698
+ return -1;
17699
+ if (numA > numB)
17700
+ return 1;
17701
+ }
17702
+ return 0;
17703
+ }
17704
+ function isWSL() {
17705
+ if (process.platform !== "linux")
17706
+ return false;
17707
+ try {
17708
+ const release = readFileSync("/proc/version", "utf-8").toLowerCase();
17709
+ return release.includes("microsoft") || release.includes("wsl");
17710
+ } catch (error) {
17711
+ logger.debug(`WSL detection skipped: ${error instanceof Error ? error.message : "unknown error"}`);
17712
+ return false;
17713
+ }
17714
+ }
17715
+ function shouldSkipExpensiveOperations() {
17716
+ if (process.env.CK_TEST_HOME) {
17717
+ return false;
17718
+ }
17719
+ return process.env.CI === "true" || process.env.CI_SAFE_MODE === "true";
17720
+ }
17721
+ function getGhUpgradeInstructions(currentVersion) {
17722
+ const platform = process.platform;
17723
+ const wsl = isWSL();
17724
+ const lines = [];
17725
+ lines.push(`✗ GitHub CLI v${currentVersion} is outdated`);
17726
+ lines.push(` Minimum required: v${MIN_GH_CLI_VERSION}`);
17727
+ lines.push("");
17728
+ if (wsl) {
17729
+ lines.push("Upgrade GitHub CLI (WSL/Ubuntu):");
17730
+ lines.push(" curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg");
17731
+ lines.push(' echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null');
17732
+ lines.push(" sudo apt update && sudo apt install gh");
17733
+ } else if (platform === "darwin") {
17734
+ lines.push("Upgrade GitHub CLI:");
17735
+ lines.push(" brew upgrade gh");
17736
+ } else if (platform === "win32") {
17737
+ lines.push("Upgrade GitHub CLI:");
17738
+ lines.push(" winget upgrade GitHub.cli");
17739
+ } else {
17740
+ lines.push("Upgrade GitHub CLI:");
17741
+ lines.push(" sudo apt update && sudo apt upgrade gh");
17742
+ lines.push(" Or visit: https://cli.github.com");
17743
+ }
17744
+ lines.push("");
17745
+ lines.push("After upgrade: gh auth login -h github.com");
17746
+ return lines;
17747
+ }
17748
+
17685
17749
  // src/services/package-installer/dependency-checker.ts
17686
17750
  import { exec } from "node:child_process";
17687
17751
  import { promisify } from "node:util";
@@ -17697,7 +17761,7 @@ function notFoundError(type, name, hint) {
17697
17761
  // src/services/package-installer/dependency-checker.ts
17698
17762
  init_logger();
17699
17763
  var execAsync = promisify(exec);
17700
- function shouldSkipExpensiveOperations() {
17764
+ function shouldSkipExpensiveOperations2() {
17701
17765
  if (process.env.CK_TEST_HOME) {
17702
17766
  return false;
17703
17767
  }
@@ -17709,9 +17773,9 @@ function getOSInfo() {
17709
17773
  const isWindows = platform === "win32";
17710
17774
  const isMacOS = platform === "darwin";
17711
17775
  const isLinux = platform === "linux";
17712
- const isWSL = isLinux && process.env.WSL_DISTRO_NAME !== undefined;
17776
+ const isWSL2 = isLinux && process.env.WSL_DISTRO_NAME !== undefined;
17713
17777
  let details = `${platform}-${arch}`;
17714
- if (isWSL) {
17778
+ if (isWSL2) {
17715
17779
  details += ` (WSL: ${process.env.WSL_DISTRO_NAME})`;
17716
17780
  }
17717
17781
  return {
@@ -17720,7 +17784,7 @@ function getOSInfo() {
17720
17784
  isWindows,
17721
17785
  isMacOS,
17722
17786
  isLinux,
17723
- isWSL,
17787
+ isWSL: isWSL2,
17724
17788
  details
17725
17789
  };
17726
17790
  }
@@ -17791,7 +17855,7 @@ var DEPENDENCIES = {
17791
17855
  }
17792
17856
  };
17793
17857
  async function commandExists(command) {
17794
- if (shouldSkipExpensiveOperations()) {
17858
+ if (shouldSkipExpensiveOperations2()) {
17795
17859
  const supportedCommands = ["node", "python", "python3", "pip", "pip3", "claude"];
17796
17860
  return supportedCommands.includes(command);
17797
17861
  }
@@ -17807,7 +17871,7 @@ async function commandExists(command) {
17807
17871
  }
17808
17872
  }
17809
17873
  async function getCommandPath(command) {
17810
- if (shouldSkipExpensiveOperations()) {
17874
+ if (shouldSkipExpensiveOperations2()) {
17811
17875
  const ciPath = getCICommandPath(command);
17812
17876
  if (ciPath)
17813
17877
  return ciPath;
@@ -17826,7 +17890,7 @@ async function getCommandPath(command) {
17826
17890
  }
17827
17891
  }
17828
17892
  async function getCommandVersion(command, versionFlag, versionRegex) {
17829
- if (shouldSkipExpensiveOperations()) {
17893
+ if (shouldSkipExpensiveOperations2()) {
17830
17894
  const mockVersions = {
17831
17895
  npm: "10.0.0",
17832
17896
  node: "20.0.0",
@@ -17852,7 +17916,7 @@ async function getCommandVersion(command, versionFlag, versionRegex) {
17852
17916
  return null;
17853
17917
  }
17854
17918
  }
17855
- function compareVersions(current, required) {
17919
+ function compareVersions2(current, required) {
17856
17920
  const parseCurrent = current.split(".").map((n) => Number.parseInt(n, 10));
17857
17921
  const parseRequired = required.split(".").map((n) => Number.parseInt(n, 10));
17858
17922
  for (let i = 0;i < 3; i++) {
@@ -17876,7 +17940,7 @@ async function checkDependency(config) {
17876
17940
  let meetsRequirements = true;
17877
17941
  let message;
17878
17942
  if (config.minVersion && version) {
17879
- meetsRequirements = compareVersions(version, config.minVersion);
17943
+ meetsRequirements = compareVersions2(version, config.minVersion);
17880
17944
  if (!meetsRequirements) {
17881
17945
  message = `Version ${version} is below minimum ${config.minVersion}`;
17882
17946
  }
@@ -18135,27 +18199,6 @@ async function installDependency(dependency, method) {
18135
18199
  // src/domains/health-checks/system-checker.ts
18136
18200
  init_logger();
18137
18201
  var execAsync4 = promisify4(exec4);
18138
- var MIN_GH_CLI_VERSION = "2.20.0";
18139
- function compareVersions2(a, b) {
18140
- const partsA = a.split(".").map(Number);
18141
- const partsB = b.split(".").map(Number);
18142
- const maxLen = Math.max(partsA.length, partsB.length);
18143
- for (let i = 0;i < maxLen; i++) {
18144
- const numA = partsA[i] ?? 0;
18145
- const numB = partsB[i] ?? 0;
18146
- if (numA < numB)
18147
- return -1;
18148
- if (numA > numB)
18149
- return 1;
18150
- }
18151
- return 0;
18152
- }
18153
- function shouldSkipExpensiveOperations2() {
18154
- if (process.env.CK_TEST_HOME) {
18155
- return false;
18156
- }
18157
- return process.env.CI === "true" || process.env.CI_SAFE_MODE === "true";
18158
- }
18159
18202
 
18160
18203
  class SystemChecker {
18161
18204
  group = "system";
@@ -18170,7 +18213,7 @@ class SystemChecker {
18170
18213
  logger.verbose(`SystemChecker: Processing ${dep.name}`);
18171
18214
  results.push(await this.mapDependencyToCheck(dep));
18172
18215
  }
18173
- if (!shouldSkipExpensiveOperations2()) {
18216
+ if (!shouldSkipExpensiveOperations()) {
18174
18217
  logger.verbose("SystemChecker: Checking git");
18175
18218
  results.push(await this.checkGit());
18176
18219
  logger.verbose("SystemChecker: Checking GitHub CLI");
@@ -18292,7 +18335,7 @@ class SystemChecker {
18292
18335
  const { stdout } = await execAsync4("gh --version");
18293
18336
  const match = stdout.match(/(\d+\.\d+\.\d+)/);
18294
18337
  const version = match?.[1];
18295
- if (version && compareVersions2(version, MIN_GH_CLI_VERSION) < 0) {
18338
+ if (version && compareVersions(version, MIN_GH_CLI_VERSION) < 0) {
18296
18339
  return {
18297
18340
  id: "gh-cli-version",
18298
18341
  name: "GitHub CLI",
@@ -18370,18 +18413,18 @@ class SystemChecker {
18370
18413
  import { join as join2 } from "node:path";
18371
18414
 
18372
18415
  // src/shared/path-resolver.ts
18373
- import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
18416
+ import { existsSync as existsSync2, readFileSync as readFileSync3 } from "node:fs";
18374
18417
  import { homedir, platform } from "node:os";
18375
18418
  import { join, normalize } from "node:path";
18376
- function isWSL() {
18419
+ function isWSL2() {
18377
18420
  try {
18378
- return process.platform === "linux" && existsSync2("/proc/version") && readFileSync2("/proc/version", "utf8").toLowerCase().includes("microsoft");
18421
+ return process.platform === "linux" && existsSync2("/proc/version") && readFileSync3("/proc/version", "utf8").toLowerCase().includes("microsoft");
18379
18422
  } catch {
18380
18423
  return false;
18381
18424
  }
18382
18425
  }
18383
18426
  function normalizeWSLPath(p) {
18384
- if (!isWSL())
18427
+ if (!isWSL2())
18385
18428
  return p;
18386
18429
  const windowsMatch = p.match(/^([A-Za-z]):(.*)/);
18387
18430
  if (windowsMatch) {
@@ -18524,7 +18567,7 @@ class PathResolver {
18524
18567
  return normalizeWSLPath(p);
18525
18568
  }
18526
18569
  static isWSL() {
18527
- return isWSL();
18570
+ return isWSL2();
18528
18571
  }
18529
18572
  static isAtHomeDirectory(cwd) {
18530
18573
  const currentDir = normalize(cwd || process.cwd());
@@ -19170,7 +19213,7 @@ function checkClaudeMdFile(path, name, id) {
19170
19213
  }
19171
19214
  }
19172
19215
  // src/domains/health-checks/checkers/active-plan-checker.ts
19173
- import { existsSync as existsSync5, readFileSync as readFileSync3 } from "node:fs";
19216
+ import { existsSync as existsSync5, readFileSync as readFileSync4 } from "node:fs";
19174
19217
  import { join as join5 } from "node:path";
19175
19218
  function checkActivePlan(projectDir) {
19176
19219
  const activePlanPath = join5(projectDir, ".claude", "active-plan");
@@ -19186,7 +19229,7 @@ function checkActivePlan(projectDir) {
19186
19229
  };
19187
19230
  }
19188
19231
  try {
19189
- const targetPath = readFileSync3(activePlanPath, "utf-8").trim();
19232
+ const targetPath = readFileSync4(activePlanPath, "utf-8").trim();
19190
19233
  const fullPath = join5(projectDir, targetPath);
19191
19234
  if (!existsSync5(fullPath)) {
19192
19235
  return {
@@ -21547,7 +21590,7 @@ class AutoHealer {
21547
21590
  }
21548
21591
  // src/domains/health-checks/report-generator.ts
21549
21592
  import { execSync as execSync4, spawnSync } from "node:child_process";
21550
- import { readFileSync as readFileSync4, unlinkSync, writeFileSync } from "node:fs";
21593
+ import { readFileSync as readFileSync5, unlinkSync, writeFileSync } from "node:fs";
21551
21594
  import { tmpdir as tmpdir2 } from "node:os";
21552
21595
  import { dirname as dirname2, join as join16 } from "node:path";
21553
21596
  import { fileURLToPath } from "node:url";
@@ -21558,7 +21601,7 @@ function getCliVersion() {
21558
21601
  try {
21559
21602
  const __dirname2 = dirname2(fileURLToPath(import.meta.url));
21560
21603
  const pkgPath = join16(__dirname2, "../../../package.json");
21561
- const pkg = JSON.parse(readFileSync4(pkgPath, "utf-8"));
21604
+ const pkg = JSON.parse(readFileSync5(pkgPath, "utf-8"));
21562
21605
  return pkg.version || "unknown";
21563
21606
  } catch (err) {
21564
21607
  logger.debug(`Failed to read CLI version: ${err}`);
@@ -37841,12 +37884,12 @@ function buildCommandPatterns() {
37841
37884
  const patterns = [];
37842
37885
  for (const cmd of COMMAND_ROOTS) {
37843
37886
  patterns.push({
37844
- regex: new RegExp(`(?<![\\w:])(\\/)${cmd}(:)`, "g"),
37845
- replacement: "$1ck:$2".replace("$2", `${cmd}:`)
37887
+ regex: new RegExp(`(?:^|(?<=[\\s\`]))(/)(${cmd})(:)(?!/)`, "gm"),
37888
+ replacement: "$1ck:$2$3"
37846
37889
  });
37847
37890
  patterns.push({
37848
- regex: new RegExp(`(?<![\\w:])(\\/)${cmd}(?=[\\s\`"'\\)\\]}>.,;:!?]|$)`, "g"),
37849
- replacement: `$1ck:${cmd}`
37891
+ regex: new RegExp(`(?:^|(?<=[\\s\`]))(/)(${cmd})(?![?/=&:\\w])(?=[\\s\`\\]\\)]|$)`, "gm"),
37892
+ replacement: "$1ck:$2"
37850
37893
  });
37851
37894
  }
37852
37895
  return patterns;
@@ -37856,11 +37899,9 @@ function transformCommandContent(content) {
37856
37899
  let transformed = content;
37857
37900
  const patterns = buildCommandPatterns();
37858
37901
  for (const { regex: regex2, replacement } of patterns) {
37859
- regex2.lastIndex = 0;
37860
37902
  const matches = transformed.match(regex2);
37861
37903
  if (matches) {
37862
37904
  changes += matches.length;
37863
- regex2.lastIndex = 0;
37864
37905
  transformed = transformed.replace(regex2, replacement);
37865
37906
  }
37866
37907
  }
@@ -40316,6 +40357,105 @@ async function detectAccessibleKits() {
40316
40357
  return accessible;
40317
40358
  }
40318
40359
 
40360
+ // src/domains/github/preflight-checker.ts
40361
+ init_logger();
40362
+ import { exec as exec7 } from "node:child_process";
40363
+ import { promisify as promisify7 } from "node:util";
40364
+ var execAsync7 = promisify7(exec7);
40365
+ function createSuccessfulPreflightResult() {
40366
+ return {
40367
+ success: true,
40368
+ ghInstalled: true,
40369
+ ghVersion: MIN_GH_CLI_VERSION,
40370
+ ghVersionOk: true,
40371
+ ghAuthenticated: true,
40372
+ errorLines: []
40373
+ };
40374
+ }
40375
+ function isTimeoutError(error) {
40376
+ if (error instanceof Error) {
40377
+ const msg = error.message.toLowerCase();
40378
+ return msg.includes("timeout") || msg.includes("timed out") || msg.includes("etimedout");
40379
+ }
40380
+ return false;
40381
+ }
40382
+ async function runPreflightChecks() {
40383
+ logger.debug("Running GitHub CLI pre-flight checks");
40384
+ if (shouldSkipExpensiveOperations()) {
40385
+ logger.debug("Skipping preflight checks in test/CI environment");
40386
+ return createSuccessfulPreflightResult();
40387
+ }
40388
+ const result = {
40389
+ success: false,
40390
+ ghInstalled: false,
40391
+ ghVersion: null,
40392
+ ghVersionOk: false,
40393
+ ghAuthenticated: false,
40394
+ errorLines: []
40395
+ };
40396
+ try {
40397
+ const { stdout: stdout2 } = await execAsync7("gh --version", { timeout: GH_COMMAND_TIMEOUT_MS });
40398
+ const match2 = stdout2.match(/(\d+\.\d+\.\d+)/);
40399
+ if (!match2) {
40400
+ logger.debug(`GitHub CLI version not detected from output: ${stdout2.trim()}`);
40401
+ result.ghInstalled = true;
40402
+ result.errorLines.push("✗ GitHub CLI installed but version could not be detected");
40403
+ result.errorLines.push(` Output: ${stdout2.trim().slice(0, 100)}`);
40404
+ result.errorLines.push(" Try running: gh --version");
40405
+ return result;
40406
+ }
40407
+ result.ghVersion = match2[1];
40408
+ result.ghInstalled = true;
40409
+ logger.debug(`GitHub CLI detected: v${result.ghVersion}`);
40410
+ } catch (error) {
40411
+ if (isTimeoutError(error)) {
40412
+ logger.debug("GitHub CLI check timed out");
40413
+ result.errorLines.push("✗ GitHub CLI check timed out");
40414
+ result.errorLines.push(" This may indicate a slow system or network issue");
40415
+ result.errorLines.push(" Try running: gh --version");
40416
+ } else {
40417
+ logger.debug(`GitHub CLI not found: ${error instanceof Error ? error.message : "unknown error"}`);
40418
+ result.errorLines.push("✗ GitHub CLI not installed");
40419
+ result.errorLines.push(" Install from: https://cli.github.com");
40420
+ result.errorLines.push("");
40421
+ result.errorLines.push("After install: gh auth login -h github.com");
40422
+ }
40423
+ return result;
40424
+ }
40425
+ if (result.ghVersion) {
40426
+ const comparison = compareVersions(result.ghVersion, MIN_GH_CLI_VERSION);
40427
+ result.ghVersionOk = comparison >= 0;
40428
+ if (!result.ghVersionOk) {
40429
+ logger.debug(`GitHub CLI version ${result.ghVersion} is below minimum ${MIN_GH_CLI_VERSION}`);
40430
+ result.errorLines.push(...getGhUpgradeInstructions(result.ghVersion));
40431
+ return result;
40432
+ }
40433
+ }
40434
+ try {
40435
+ await execAsync7("gh auth status -h github.com", {
40436
+ timeout: GH_COMMAND_TIMEOUT_MS,
40437
+ env: { ...process.env, GH_NO_UPDATE_NOTIFIER: "1" }
40438
+ });
40439
+ result.ghAuthenticated = true;
40440
+ logger.debug("GitHub CLI authenticated for github.com");
40441
+ } catch (error) {
40442
+ if (isTimeoutError(error)) {
40443
+ logger.debug("GitHub CLI auth check timed out");
40444
+ result.errorLines.push("✗ GitHub CLI auth check timed out");
40445
+ result.errorLines.push(" This may indicate a network issue");
40446
+ result.errorLines.push(" Try running: gh auth status -h github.com");
40447
+ } else {
40448
+ logger.debug(`GitHub CLI not authenticated: ${error instanceof Error ? error.message : "unknown error"}`);
40449
+ result.errorLines.push("✗ GitHub CLI not authenticated");
40450
+ result.errorLines.push(" Run: gh auth login -h github.com");
40451
+ }
40452
+ return result;
40453
+ }
40454
+ result.success = true;
40455
+ logger.debug("All GitHub CLI pre-flight checks passed");
40456
+ return result;
40457
+ }
40458
+
40319
40459
  // src/domains/installation/fresh-installer.ts
40320
40460
  init_logger();
40321
40461
  import { join as join65 } from "node:path";
@@ -40379,11 +40519,26 @@ async function handleSelection(ctx) {
40379
40519
  }
40380
40520
  const config = await ConfigManager.get();
40381
40521
  let accessibleKits;
40382
- if (!ctx.options.useGit) {
40522
+ if (!ctx.options.useGit && !ctx.options.kitPath && !ctx.options.archive) {
40523
+ const preflight = await runPreflightChecks();
40524
+ if (!preflight.success) {
40525
+ for (const line of preflight.errorLines) {
40526
+ if (line.startsWith("✗")) {
40527
+ logger.error(line);
40528
+ } else {
40529
+ logger.info(line);
40530
+ }
40531
+ }
40532
+ logger.info("");
40533
+ logger.info("Full diagnostics: ck doctor");
40534
+ return { ...ctx, cancelled: true };
40535
+ }
40383
40536
  accessibleKits = await detectAccessibleKits();
40384
40537
  if (accessibleKits.length === 0) {
40385
- logger.error("No ClaudeKit access found.");
40386
- logger.info("Purchase at https://claudekit.cc");
40538
+ logger.error("No ClaudeKit repository access found.");
40539
+ logger.info("Check email for GitHub invitation, or purchase at https://claudekit.cc");
40540
+ logger.info("");
40541
+ logger.info("Full diagnostics: ck doctor");
40387
40542
  return { ...ctx, cancelled: true };
40388
40543
  }
40389
40544
  }
@@ -41672,7 +41827,7 @@ async function directorySetup(validOptions, prompts) {
41672
41827
  const isNonInteractive2 = !process.stdin.isTTY || process.env.CI === "true" || process.env.NON_INTERACTIVE === "true";
41673
41828
  const config = await ConfigManager.get();
41674
41829
  let accessibleKits;
41675
- if (!validOptions.useGit) {
41830
+ if (!validOptions.useGit && !validOptions.kitPath && !validOptions.archive) {
41676
41831
  accessibleKits = await detectAccessibleKits();
41677
41832
  if (accessibleKits.length === 0) {
41678
41833
  logger.error("No ClaudeKit access found.");
@@ -41811,6 +41966,22 @@ init_types2();
41811
41966
  // src/commands/new/phases/version-selection.ts
41812
41967
  init_logger();
41813
41968
  async function selectVersion2(kit, options, isNonInteractive2, prompts, github) {
41969
+ if (options.kitPath || options.archive) {
41970
+ const localVersion = options.release || "local";
41971
+ return {
41972
+ release: {
41973
+ id: 0,
41974
+ tag_name: localVersion,
41975
+ name: localVersion,
41976
+ draft: false,
41977
+ prerelease: false,
41978
+ tarball_url: "",
41979
+ zipball_url: "",
41980
+ assets: []
41981
+ },
41982
+ selectedVersion: localVersion
41983
+ };
41984
+ }
41814
41985
  let selectedVersion = options.release;
41815
41986
  if (!selectedVersion && isNonInteractive2) {
41816
41987
  throw new Error("Interactive version selection unavailable in non-interactive mode. " + "Either: (1) use --release <tag> flag, or (2) set CI=false to enable interactive mode");
@@ -42387,9 +42558,9 @@ ${import_picocolors22.default.yellow("User modifications will be permanently del
42387
42558
  }
42388
42559
  }
42389
42560
  // src/commands/update-cli.ts
42390
- import { exec as exec7 } from "node:child_process";
42391
- import { join as join76 } from "node:path";
42392
- import { promisify as promisify7 } from "node:util";
42561
+ import { exec as exec8 } from "node:child_process";
42562
+ import { join as join75 } from "node:path";
42563
+ import { promisify as promisify8 } from "node:util";
42393
42564
 
42394
42565
  // src/domains/github/npm-registry.ts
42395
42566
  init_logger();
@@ -42526,281 +42697,16 @@ class NpmRegistryClient {
42526
42697
  }
42527
42698
  }
42528
42699
 
42529
- // src/domains/versioning/checking/version-utils.ts
42530
- var import_compare_versions3 = __toESM(require_umd(), 1);
42531
- function isUpdateCheckDisabled() {
42532
- return process.env.NO_UPDATE_NOTIFIER === "1" || process.env.NO_UPDATE_NOTIFIER === "true" || !process.stdout.isTTY;
42533
- }
42534
- function normalizeVersion(version) {
42535
- return version.replace(/^v/, "");
42536
- }
42537
- function isNewerVersion(currentVersion, latestVersion) {
42538
- try {
42539
- const current = normalizeVersion(currentVersion);
42540
- const latest = normalizeVersion(latestVersion);
42541
- return import_compare_versions3.compareVersions(latest, current) > 0;
42542
- } catch {
42543
- return false;
42544
- }
42545
- }
42546
- // src/domains/versioning/checking/kit-version-checker.ts
42547
- init_logger();
42548
- init_types2();
42549
-
42550
- // src/domains/versioning/version-cache.ts
42551
- init_logger();
42552
- import { existsSync as existsSync19 } from "node:fs";
42553
- import { mkdir as mkdir22, readFile as readFile25, writeFile as writeFile22 } from "node:fs/promises";
42554
- import { join as join75 } from "node:path";
42555
- class VersionCacheManager {
42556
- static CACHE_FILENAME = "version-check.json";
42557
- static CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000;
42558
- static getCacheFile() {
42559
- const cacheDir = PathResolver.getCacheDir(false);
42560
- return join75(cacheDir, VersionCacheManager.CACHE_FILENAME);
42561
- }
42562
- static async load() {
42563
- const cacheFile = VersionCacheManager.getCacheFile();
42564
- try {
42565
- if (!existsSync19(cacheFile)) {
42566
- logger.debug("Version check cache not found");
42567
- return null;
42568
- }
42569
- const content = await readFile25(cacheFile, "utf-8");
42570
- const cache2 = JSON.parse(content);
42571
- if (!cache2.lastCheck || !cache2.currentVersion || !cache2.latestVersion) {
42572
- logger.debug("Invalid cache structure, ignoring");
42573
- return null;
42574
- }
42575
- logger.debug(`Version check cache loaded: ${JSON.stringify(cache2)}`);
42576
- return cache2;
42577
- } catch (error) {
42578
- logger.debug(`Failed to load version check cache: ${error}`);
42579
- return null;
42580
- }
42581
- }
42582
- static async save(cache2) {
42583
- const cacheFile = VersionCacheManager.getCacheFile();
42584
- const cacheDir = PathResolver.getCacheDir(false);
42585
- try {
42586
- if (!existsSync19(cacheDir)) {
42587
- await mkdir22(cacheDir, { recursive: true, mode: 448 });
42588
- }
42589
- await writeFile22(cacheFile, JSON.stringify(cache2, null, 2), "utf-8");
42590
- logger.debug(`Version check cache saved to ${cacheFile}`);
42591
- } catch (error) {
42592
- logger.debug(`Failed to save version check cache: ${error}`);
42593
- }
42594
- }
42595
- static isCacheValid(cache2) {
42596
- if (!cache2)
42597
- return false;
42598
- const now = Date.now();
42599
- const age = now - cache2.lastCheck;
42600
- const isValid2 = age < VersionCacheManager.CACHE_TTL_MS;
42601
- const ageDays = (age / 1000 / 60 / 60 / 24).toFixed(1);
42602
- logger.debug(`Cache validity check: age=${ageDays} days, valid=${isValid2}`);
42603
- return isValid2;
42604
- }
42605
- static async clear() {
42606
- const cacheFile = VersionCacheManager.getCacheFile();
42607
- try {
42608
- if (existsSync19(cacheFile)) {
42609
- const fs14 = await import("node:fs/promises");
42610
- await fs14.unlink(cacheFile);
42611
- logger.debug("Version check cache cleared");
42612
- }
42613
- } catch (error) {
42614
- logger.debug(`Failed to clear version check cache: ${error}`);
42615
- }
42616
- }
42617
- }
42618
-
42619
- // src/domains/versioning/checking/kit-version-checker.ts
42620
- async function fetchLatestRelease(currentVersion) {
42621
- try {
42622
- const githubClient = new GitHubClient;
42623
- const kit = AVAILABLE_KITS.engineer;
42624
- const timeoutPromise = new Promise((_3, reject) => setTimeout(() => reject(new Error("Timeout")), 5000));
42625
- const releasePromise = githubClient.getLatestRelease(kit);
42626
- const release = await Promise.race([releasePromise, timeoutPromise]);
42627
- const latestVersion = release.tag_name;
42628
- const updateAvailable = isNewerVersion(currentVersion, latestVersion);
42629
- const releaseUrl = `https://github.com/${kit.owner}/${kit.repo}/releases/tag/${latestVersion}`;
42630
- logger.debug(`Fetched latest release: current=${currentVersion}, latest=${latestVersion}, updateAvailable=${updateAvailable}`);
42631
- return {
42632
- currentVersion,
42633
- latestVersion,
42634
- updateAvailable,
42635
- releaseUrl
42636
- };
42637
- } catch (error) {
42638
- logger.debug(`Failed to fetch latest release: ${error}`);
42639
- return null;
42640
- }
42641
- }
42642
-
42643
- class VersionChecker {
42644
- static async check(currentVersion) {
42645
- if (isUpdateCheckDisabled()) {
42646
- logger.debug("Update check disabled by environment");
42647
- return null;
42648
- }
42649
- const cache2 = await VersionCacheManager.load();
42650
- if (cache2 && VersionCacheManager.isCacheValid(cache2) && cache2.currentVersion === currentVersion) {
42651
- logger.debug("Using cached version check result");
42652
- return {
42653
- currentVersion: cache2.currentVersion,
42654
- latestVersion: cache2.latestVersion,
42655
- updateAvailable: cache2.updateAvailable,
42656
- releaseUrl: cache2.latestUrl
42657
- };
42658
- }
42659
- logger.debug("Cache expired or invalid, fetching latest release");
42660
- const result = await fetchLatestRelease(currentVersion);
42661
- if (result) {
42662
- await VersionCacheManager.save({
42663
- lastCheck: Date.now(),
42664
- currentVersion: result.currentVersion,
42665
- latestVersion: result.latestVersion,
42666
- latestUrl: result.releaseUrl,
42667
- updateAvailable: result.updateAvailable
42668
- });
42669
- }
42670
- return result;
42671
- }
42672
- }
42673
- // src/domains/versioning/checking/cli-version-checker.ts
42674
- init_logger();
42675
- var import_compare_versions4 = __toESM(require_umd(), 1);
42676
- var PACKAGE_NAME = "claudekit-cli";
42677
-
42678
- class CliVersionChecker {
42679
- static async check(currentVersion) {
42680
- if (isUpdateCheckDisabled()) {
42681
- logger.debug("CLI update check disabled by environment");
42682
- return null;
42683
- }
42684
- try {
42685
- const latestVersion = await NpmRegistryClient.getLatestVersion(PACKAGE_NAME);
42686
- if (!latestVersion) {
42687
- logger.debug("Failed to fetch latest CLI version from npm");
42688
- return null;
42689
- }
42690
- const current = normalizeVersion(currentVersion);
42691
- const latest = normalizeVersion(latestVersion);
42692
- const updateAvailable = import_compare_versions4.compareVersions(latest, current) > 0;
42693
- logger.debug(`CLI version check: current=${current}, latest=${latest}, updateAvailable=${updateAvailable}`);
42694
- return {
42695
- currentVersion: current,
42696
- latestVersion: latest,
42697
- updateAvailable,
42698
- releaseUrl: `https://www.npmjs.com/package/${PACKAGE_NAME}`
42699
- };
42700
- } catch (error) {
42701
- logger.debug(`CLI version check failed: ${error}`);
42702
- return null;
42703
- }
42704
- }
42705
- }
42706
- // src/domains/versioning/checking/notification-display.ts
42707
- var import_picocolors23 = __toESM(require_picocolors(), 1);
42708
- function createNotificationBox2(borderColor, boxWidth) {
42709
- const contentWidth = boxWidth - 2;
42710
- const topBorder = borderColor(`╭${"─".repeat(contentWidth)}╮`);
42711
- const bottomBorder = borderColor(`╰${"─".repeat(contentWidth)}╯`);
42712
- const emptyLine = borderColor("│") + " ".repeat(contentWidth) + borderColor("│");
42713
- const padLine = (text, visibleLen) => {
42714
- const len = visibleLen ?? text.length;
42715
- const displayText = len > contentWidth ? `${text.slice(0, contentWidth - 3)}...` : text;
42716
- const actualLen = visibleLen ?? displayText.length;
42717
- const totalPadding = contentWidth - actualLen;
42718
- const leftPadding = Math.max(0, Math.floor(totalPadding / 2));
42719
- const rightPadding = Math.max(0, totalPadding - leftPadding);
42720
- return borderColor("│") + " ".repeat(leftPadding) + displayText + " ".repeat(rightPadding) + borderColor("│");
42721
- };
42722
- return { topBorder, bottomBorder, emptyLine, padLine };
42723
- }
42724
- function displayKitNotification(result, options = {}) {
42725
- if (!result.updateAvailable)
42726
- return;
42727
- const { currentVersion, latestVersion } = result;
42728
- const { isGlobal = false } = options;
42729
- const displayCurrent = normalizeVersion(currentVersion);
42730
- const displayLatest = normalizeVersion(latestVersion);
42731
- const boxWidth = 52;
42732
- const { topBorder, bottomBorder, emptyLine, padLine } = createNotificationBox2(import_picocolors23.default.cyan, boxWidth);
42733
- const headerText = import_picocolors23.default.bold(import_picocolors23.default.yellow("⬆ Kit Update Available"));
42734
- const headerLen = "⬆ Kit Update Available".length;
42735
- const versionText = `${import_picocolors23.default.dim(displayCurrent)} ${import_picocolors23.default.white("→")} ${import_picocolors23.default.green(import_picocolors23.default.bold(displayLatest))}`;
42736
- const versionLen = displayCurrent.length + 3 + displayLatest.length;
42737
- const updateCmd = isGlobal ? "ck init -g" : "ck init";
42738
- const commandText = `Run: ${import_picocolors23.default.cyan(import_picocolors23.default.bold(updateCmd))}`;
42739
- const commandLen = `Run: ${updateCmd}`.length;
42740
- console.log("");
42741
- console.log(topBorder);
42742
- console.log(emptyLine);
42743
- console.log(padLine(headerText, headerLen));
42744
- console.log(padLine(versionText, versionLen));
42745
- console.log(emptyLine);
42746
- console.log(padLine(commandText, commandLen));
42747
- console.log(emptyLine);
42748
- console.log(bottomBorder);
42749
- console.log("");
42750
- }
42751
- function displayCliNotification(result) {
42752
- if (!result.updateAvailable)
42753
- return;
42754
- const { currentVersion, latestVersion } = result;
42755
- const boxWidth = 52;
42756
- const { topBorder, bottomBorder, emptyLine, padLine } = createNotificationBox2(import_picocolors23.default.magenta, boxWidth);
42757
- const headerText = import_picocolors23.default.bold(import_picocolors23.default.yellow("⬆ CLI Update Available"));
42758
- const headerLen = "⬆ CLI Update Available".length;
42759
- const versionText = `${import_picocolors23.default.dim(currentVersion)} ${import_picocolors23.default.white("→")} ${import_picocolors23.default.green(import_picocolors23.default.bold(latestVersion))}`;
42760
- const versionLen = currentVersion.length + 3 + latestVersion.length;
42761
- const commandText = `Run: ${import_picocolors23.default.magenta(import_picocolors23.default.bold("ck update"))}`;
42762
- const commandLen = "Run: ck update".length;
42763
- console.log("");
42764
- console.log(topBorder);
42765
- console.log(emptyLine);
42766
- console.log(padLine(headerText, headerLen));
42767
- console.log(padLine(versionText, versionLen));
42768
- console.log(emptyLine);
42769
- console.log(padLine(commandText, commandLen));
42770
- console.log(emptyLine);
42771
- console.log(bottomBorder);
42772
- console.log("");
42773
- }
42774
- // src/domains/versioning/version-checker.ts
42775
- class VersionChecker2 {
42776
- static async check(currentVersion) {
42777
- return VersionChecker.check(currentVersion);
42778
- }
42779
- static displayNotification(result, options = {}) {
42780
- displayKitNotification(result, options);
42781
- }
42782
- }
42783
-
42784
- class CliVersionChecker2 {
42785
- static async check(currentVersion) {
42786
- return CliVersionChecker.check(currentVersion);
42787
- }
42788
- static displayNotification(result) {
42789
- displayCliNotification(result);
42790
- }
42791
- }
42792
-
42793
42700
  // src/commands/update-cli.ts
42794
42701
  init_logger();
42795
42702
  init_types2();
42796
42703
  init_types2();
42797
- var import_compare_versions5 = __toESM(require_umd(), 1);
42704
+ var import_compare_versions3 = __toESM(require_umd(), 1);
42798
42705
  var import_fs_extra36 = __toESM(require_lib(), 1);
42799
- var import_picocolors24 = __toESM(require_picocolors(), 1);
42800
42706
  // package.json
42801
42707
  var package_default = {
42802
42708
  name: "claudekit-cli",
42803
- version: "3.24.1",
42709
+ version: "3.26.0",
42804
42710
  description: "CLI tool for bootstrapping and updating ClaudeKit projects",
42805
42711
  type: "module",
42806
42712
  repository: {
@@ -42891,7 +42797,7 @@ var package_default = {
42891
42797
  };
42892
42798
 
42893
42799
  // src/commands/update-cli.ts
42894
- var execAsync7 = promisify7(exec7);
42800
+ var execAsync8 = promisify8(exec8);
42895
42801
 
42896
42802
  class CliUpdateError extends ClaudeKitError {
42897
42803
  constructor(message) {
@@ -42899,8 +42805,7 @@ class CliUpdateError extends ClaudeKitError {
42899
42805
  this.name = "CliUpdateError";
42900
42806
  }
42901
42807
  }
42902
- var PACKAGE_NAME2 = "claudekit-cli";
42903
- var KIT_UPDATE_REMINDER_HEADER = "Note: 'ck update' only updates the CLI tool itself.";
42808
+ var PACKAGE_NAME = "claudekit-cli";
42904
42809
  function buildInitCommand(isGlobal, kit, beta) {
42905
42810
  const parts = ["ck init"];
42906
42811
  if (isGlobal)
@@ -42912,19 +42817,61 @@ function buildInitCommand(isGlobal, kit, beta) {
42912
42817
  parts.push("--beta");
42913
42818
  return parts.join(" ");
42914
42819
  }
42820
+ function isBetaVersion(version) {
42821
+ if (!version)
42822
+ return false;
42823
+ return /-(beta|alpha|rc)[.\d]/i.test(version);
42824
+ }
42825
+ function selectKitForUpdate(params) {
42826
+ const { hasLocal, hasGlobal, localKits, globalKits } = params;
42827
+ const hasLocalKit = localKits.length > 0 || hasLocal;
42828
+ const hasGlobalKit = globalKits.length > 0 || hasGlobal;
42829
+ if (!hasLocalKit && !hasGlobalKit) {
42830
+ return null;
42831
+ }
42832
+ if (hasGlobalKit && !hasLocalKit) {
42833
+ const kit2 = globalKits[0] || localKits[0];
42834
+ return {
42835
+ isGlobal: true,
42836
+ kit: kit2,
42837
+ promptMessage: `Update global ClaudeKit content${kit2 ? ` (${kit2})` : ""}?`
42838
+ };
42839
+ }
42840
+ if (hasLocalKit && !hasGlobalKit) {
42841
+ const kit2 = localKits[0] || globalKits[0];
42842
+ return {
42843
+ isGlobal: false,
42844
+ kit: kit2,
42845
+ promptMessage: `Update local project ClaudeKit content${kit2 ? ` (${kit2})` : ""}?`
42846
+ };
42847
+ }
42848
+ const kit = globalKits[0] || localKits[0];
42849
+ return {
42850
+ isGlobal: true,
42851
+ kit,
42852
+ promptMessage: `Update global ClaudeKit content${kit ? ` (${kit})` : ""}?`
42853
+ };
42854
+ }
42915
42855
  async function readMetadataFile(claudeDir) {
42916
- const metadataPath = join76(claudeDir, "metadata.json");
42856
+ const metadataPath = join75(claudeDir, "metadata.json");
42917
42857
  try {
42918
42858
  if (!await import_fs_extra36.pathExists(metadataPath)) {
42919
42859
  return null;
42920
42860
  }
42921
42861
  const content = await import_fs_extra36.readFile(metadataPath, "utf-8");
42922
- return JSON.parse(content);
42923
- } catch {
42862
+ const parsed = JSON.parse(content);
42863
+ const validated = MetadataSchema.safeParse(parsed);
42864
+ if (!validated.success) {
42865
+ logger.verbose(`Invalid metadata format: ${validated.error.message}`);
42866
+ return null;
42867
+ }
42868
+ return validated.data;
42869
+ } catch (error) {
42870
+ logger.verbose(`Failed to read metadata: ${error instanceof Error ? error.message : "unknown"}`);
42924
42871
  return null;
42925
42872
  }
42926
42873
  }
42927
- async function displayKitUpdateReminder(beta) {
42874
+ async function promptKitUpdate(beta) {
42928
42875
  try {
42929
42876
  const setup = await getClaudeKitSetup();
42930
42877
  const hasLocal = !!setup.project.metadata;
@@ -42933,93 +42880,43 @@ async function displayKitUpdateReminder(beta) {
42933
42880
  const globalMetadata = hasGlobal ? await readMetadataFile(setup.global.path) : null;
42934
42881
  const localKits = localMetadata ? getInstalledKits(localMetadata) : [];
42935
42882
  const globalKits = globalMetadata ? getInstalledKits(globalMetadata) : [];
42936
- const versionsToCheck = new Set;
42937
- if (localMetadata) {
42938
- for (const kit of localKits) {
42939
- const version = localMetadata.kits?.[kit]?.version || localMetadata.version;
42940
- if (version)
42941
- versionsToCheck.add(version);
42942
- }
42943
- }
42944
- if (globalMetadata) {
42945
- for (const kit of globalKits) {
42946
- const version = globalMetadata.kits?.[kit]?.version || globalMetadata.version;
42947
- if (version)
42948
- versionsToCheck.add(version);
42949
- }
42950
- }
42951
- const versionCheckResults = new Map;
42952
- if (versionsToCheck.size > 0) {
42953
- const checkPromises = [...versionsToCheck].map(async (version) => {
42954
- const result = await VersionChecker2.check(version).catch(() => null);
42955
- return { version, result };
42956
- });
42957
- const results = await Promise.all(checkPromises);
42958
- for (const { version, result } of results) {
42959
- versionCheckResults.set(version, result);
42960
- }
42961
- }
42962
- const commands = [];
42963
- if (localKits.length > 0) {
42964
- for (const kit of localKits) {
42965
- const cmd = buildInitCommand(false, kit, beta);
42966
- const version = localMetadata?.kits?.[kit]?.version || localMetadata?.version;
42967
- commands.push({
42968
- cmd,
42969
- desc: `Update local project (${kit}${version ? `@${version}` : ""})`,
42970
- version
42971
- });
42972
- }
42973
- } else if (hasLocal) {
42974
- commands.push({ cmd: beta ? "ck init --beta" : "ck init", desc: "Update local project" });
42975
- } else {
42976
- commands.push({
42977
- cmd: beta ? "ck init --beta" : "ck init",
42978
- desc: "Initialize in current project"
42979
- });
42883
+ const selection = selectKitForUpdate({ hasLocal, hasGlobal, localKits, globalKits });
42884
+ if (!selection) {
42885
+ logger.verbose("No ClaudeKit installations detected, skipping kit update prompt");
42886
+ return;
42980
42887
  }
42981
- if (globalKits.length > 0) {
42982
- for (const kit of globalKits) {
42983
- const cmd = buildInitCommand(true, kit, beta);
42984
- const version = globalMetadata?.kits?.[kit]?.version || globalMetadata?.version;
42985
- commands.push({
42986
- cmd,
42987
- desc: `Update global ~/.claude (${kit}${version ? `@${version}` : ""})`,
42988
- version
42989
- });
42990
- }
42991
- } else if (hasGlobal) {
42992
- commands.push({
42993
- cmd: beta ? "ck init -g --beta" : "ck init -g",
42994
- desc: "Update global ~/.claude"
42995
- });
42996
- } else {
42997
- commands.push({
42998
- cmd: beta ? "ck init -g --beta" : "ck init -g",
42999
- desc: "Initialize global ~/.claude"
43000
- });
42888
+ const kitVersion = selection.kit ? selection.isGlobal ? globalMetadata?.kits?.[selection.kit]?.version : localMetadata?.kits?.[selection.kit]?.version : undefined;
42889
+ const isBetaInstalled = isBetaVersion(kitVersion);
42890
+ const initCmd = buildInitCommand(selection.isGlobal, selection.kit, beta || isBetaInstalled);
42891
+ const promptMessage = selection.promptMessage;
42892
+ logger.info("");
42893
+ const shouldUpdate = await se({
42894
+ message: promptMessage
42895
+ });
42896
+ if (lD(shouldUpdate) || !shouldUpdate) {
42897
+ log.info("Skipped kit content update");
42898
+ return;
43001
42899
  }
43002
- const maxCmdLen = Math.max(...commands.map((c2) => c2.cmd.length));
43003
- const pad = (cmd) => cmd.padEnd(maxCmdLen);
43004
- const lines = [];
43005
- lines.push(import_picocolors24.default.yellow(KIT_UPDATE_REMINDER_HEADER));
43006
- lines.push("");
43007
- lines.push("To update your ClaudeKit content (skills, commands, workflows):");
43008
- for (const { cmd, desc: desc2, version } of commands) {
43009
- lines.push(` ${import_picocolors24.default.cyan(pad(cmd))} ${desc2}`);
43010
- if (version) {
43011
- const versionCheck = versionCheckResults.get(version);
43012
- if (versionCheck?.updateAvailable) {
43013
- const indent = " ".repeat(maxCmdLen + 4);
43014
- lines.push(`${indent}${import_picocolors24.default.green(`→ ${versionCheck.latestVersion} available!`)}`);
43015
- }
42900
+ logger.info(`Running: ${initCmd}`);
42901
+ const s = de();
42902
+ s.start("Updating ClaudeKit content...");
42903
+ try {
42904
+ await execAsync8(initCmd, {
42905
+ timeout: 300000
42906
+ });
42907
+ s.stop("Kit content updated");
42908
+ } catch (error) {
42909
+ s.stop("Kit update finished");
42910
+ const errorMsg = error instanceof Error ? error.message : "unknown";
42911
+ if (errorMsg.includes("exit code") && !errorMsg.includes("exit code 0")) {
42912
+ logger.warning("Kit content update may have encountered issues");
42913
+ logger.verbose(`Error: ${errorMsg}`);
42914
+ } else {
42915
+ logger.verbose(`Init command completed: ${errorMsg}`);
43016
42916
  }
43017
42917
  }
43018
- logger.info("");
43019
- log.info(lines.join(`
43020
- `));
43021
42918
  } catch (error) {
43022
- logger.verbose(`Failed to display kit update reminder: ${error instanceof Error ? error.message : "unknown error"}`);
42919
+ logger.verbose(`Failed to prompt for kit update: ${error instanceof Error ? error.message : "unknown error"}`);
43023
42920
  }
43024
42921
  }
43025
42922
  async function updateCliCommand(options) {
@@ -43037,7 +42934,7 @@ async function updateCliCommand(options) {
43037
42934
  s.start("Checking for updates...");
43038
42935
  let targetVersion = null;
43039
42936
  if (opts.release && opts.release !== "latest") {
43040
- const exists = await NpmRegistryClient.versionExists(PACKAGE_NAME2, opts.release, opts.registry);
42937
+ const exists = await NpmRegistryClient.versionExists(PACKAGE_NAME, opts.release, opts.registry);
43041
42938
  if (!exists) {
43042
42939
  s.stop("Version not found");
43043
42940
  throw new CliUpdateError(`Version ${opts.release} does not exist on npm registry. Run 'ck versions' to see available versions.`);
@@ -43045,25 +42942,25 @@ async function updateCliCommand(options) {
43045
42942
  targetVersion = opts.release;
43046
42943
  s.stop(`Target version: ${targetVersion}`);
43047
42944
  } else if (opts.beta) {
43048
- targetVersion = await NpmRegistryClient.getBetaVersion(PACKAGE_NAME2, opts.registry);
42945
+ targetVersion = await NpmRegistryClient.getBetaVersion(PACKAGE_NAME, opts.registry);
43049
42946
  if (!targetVersion) {
43050
42947
  s.stop("No beta version available");
43051
42948
  logger.warning("No beta version found. Using latest stable version instead.");
43052
- targetVersion = await NpmRegistryClient.getLatestVersion(PACKAGE_NAME2, opts.registry);
42949
+ targetVersion = await NpmRegistryClient.getLatestVersion(PACKAGE_NAME, opts.registry);
43053
42950
  } else {
43054
42951
  s.stop(`Latest beta version: ${targetVersion}`);
43055
42952
  }
43056
42953
  } else {
43057
- targetVersion = await NpmRegistryClient.getLatestVersion(PACKAGE_NAME2, opts.registry);
42954
+ targetVersion = await NpmRegistryClient.getLatestVersion(PACKAGE_NAME, opts.registry);
43058
42955
  s.stop(`Latest version: ${targetVersion || "unknown"}`);
43059
42956
  }
43060
42957
  if (!targetVersion) {
43061
- throw new CliUpdateError(`Failed to fetch version information from npm registry. Check your internet connection and try again. Manual update: ${PackageManagerDetector.getUpdateCommand(pm, PACKAGE_NAME2)}`);
42958
+ throw new CliUpdateError(`Failed to fetch version information from npm registry. Check your internet connection and try again. Manual update: ${PackageManagerDetector.getUpdateCommand(pm, PACKAGE_NAME)}`);
43062
42959
  }
43063
- const comparison = import_compare_versions5.compareVersions(currentVersion, targetVersion);
42960
+ const comparison = import_compare_versions3.compareVersions(currentVersion, targetVersion);
43064
42961
  if (comparison === 0) {
43065
42962
  outro(`[+] Already on the latest CLI version (${currentVersion})`);
43066
- await displayKitUpdateReminder(opts.beta);
42963
+ await promptKitUpdate(opts.beta);
43067
42964
  return;
43068
42965
  }
43069
42966
  if (comparison > 0 && !opts.release) {
@@ -43077,7 +42974,7 @@ async function updateCliCommand(options) {
43077
42974
  note(`CLI update available: ${currentVersion} -> ${targetVersion}
43078
42975
 
43079
42976
  Run 'ck update' to install`, "Update Check");
43080
- await displayKitUpdateReminder(opts.beta);
42977
+ await promptKitUpdate(opts.beta);
43081
42978
  outro("Check complete");
43082
42979
  return;
43083
42980
  }
@@ -43090,11 +42987,11 @@ Run 'ck update' to install`, "Update Check");
43090
42987
  return;
43091
42988
  }
43092
42989
  }
43093
- const updateCmd = PackageManagerDetector.getUpdateCommand(pm, PACKAGE_NAME2, targetVersion);
42990
+ const updateCmd = PackageManagerDetector.getUpdateCommand(pm, PACKAGE_NAME, targetVersion);
43094
42991
  logger.info(`Running: ${updateCmd}`);
43095
42992
  s.start("Updating CLI...");
43096
42993
  try {
43097
- await execAsync7(updateCmd, {
42994
+ await execAsync8(updateCmd, {
43098
42995
  timeout: 120000
43099
42996
  });
43100
42997
  s.stop("Update completed");
@@ -43112,16 +43009,16 @@ Manual update: ${updateCmd}`);
43112
43009
  }
43113
43010
  s.start("Verifying installation...");
43114
43011
  try {
43115
- const { stdout: stdout2 } = await execAsync7("ck --version", { timeout: 5000 });
43012
+ const { stdout: stdout2 } = await execAsync8("ck --version", { timeout: 5000 });
43116
43013
  const newVersionMatch = stdout2.match(/CLI Version:\s*(\S+)/);
43117
43014
  const newVersion = newVersionMatch ? newVersionMatch[1] : targetVersion;
43118
43015
  s.stop(`Installed version: ${newVersion}`);
43119
43016
  outro(`[+] Successfully updated ClaudeKit CLI to ${newVersion}`);
43120
- await displayKitUpdateReminder(opts.beta);
43017
+ await promptKitUpdate(opts.beta);
43121
43018
  } catch {
43122
43019
  s.stop("Verification completed");
43123
43020
  outro(`[+] Update completed. Please restart your terminal to use CLI ${targetVersion}`);
43124
- await displayKitUpdateReminder(opts.beta);
43021
+ await promptKitUpdate(opts.beta);
43125
43022
  }
43126
43023
  } catch (error) {
43127
43024
  if (error instanceof CliUpdateError) {
@@ -43137,7 +43034,7 @@ Manual update: ${updateCmd}`);
43137
43034
  // src/commands/version.ts
43138
43035
  init_logger();
43139
43036
  init_types2();
43140
- var import_picocolors25 = __toESM(require_picocolors(), 1);
43037
+ var import_picocolors23 = __toESM(require_picocolors(), 1);
43141
43038
  function formatRelativeTime(dateString) {
43142
43039
  if (!dateString)
43143
43040
  return "Unknown";
@@ -43159,30 +43056,30 @@ function formatRelativeTime(dateString) {
43159
43056
  }
43160
43057
  function displayKitReleases(kitName, releases) {
43161
43058
  console.log(`
43162
- ${import_picocolors25.default.bold(import_picocolors25.default.cyan(kitName))} - Available Versions:
43059
+ ${import_picocolors23.default.bold(import_picocolors23.default.cyan(kitName))} - Available Versions:
43163
43060
  `);
43164
43061
  if (releases.length === 0) {
43165
- console.log(import_picocolors25.default.dim(" No releases found"));
43062
+ console.log(import_picocolors23.default.dim(" No releases found"));
43166
43063
  return;
43167
43064
  }
43168
43065
  for (const release of releases) {
43169
- const version = import_picocolors25.default.green(release.tag_name);
43066
+ const version = import_picocolors23.default.green(release.tag_name);
43170
43067
  const name2 = release.name || "No title";
43171
43068
  const publishedAt = formatRelativeTime(release.published_at);
43172
43069
  const assetCount = release.assets.length;
43173
43070
  const badges = [];
43174
43071
  if (release.prerelease)
43175
- badges.push(import_picocolors25.default.yellow("[prerelease]"));
43072
+ badges.push(import_picocolors23.default.yellow("[prerelease]"));
43176
43073
  if (release.draft)
43177
- badges.push(import_picocolors25.default.gray("[draft]"));
43074
+ badges.push(import_picocolors23.default.gray("[draft]"));
43178
43075
  const badgeStr = badges.length > 0 ? ` ${badges.join(" ")}` : "";
43179
43076
  const versionPart = version.padEnd(20);
43180
43077
  const namePart = name2.length > 40 ? `${name2.slice(0, 37)}...` : name2.padEnd(40);
43181
- const timePart = import_picocolors25.default.dim(publishedAt.padEnd(20));
43182
- const assetPart = import_picocolors25.default.dim(`(${assetCount} ${assetCount === 1 ? "asset" : "assets"})`);
43078
+ const timePart = import_picocolors23.default.dim(publishedAt.padEnd(20));
43079
+ const assetPart = import_picocolors23.default.dim(`(${assetCount} ${assetCount === 1 ? "asset" : "assets"})`);
43183
43080
  console.log(` ${versionPart} ${namePart} ${timePart} ${assetPart}${badgeStr}`);
43184
43081
  }
43185
- console.log(import_picocolors25.default.dim(`
43082
+ console.log(import_picocolors23.default.dim(`
43186
43083
  Showing ${releases.length} ${releases.length === 1 ? "release" : "releases"}`));
43187
43084
  }
43188
43085
  async function versionCommand(options) {
@@ -43217,8 +43114,8 @@ async function versionCommand(options) {
43217
43114
  for (const result of results) {
43218
43115
  if (result.error) {
43219
43116
  console.log(`
43220
- ${import_picocolors25.default.bold(import_picocolors25.default.cyan(result.kitConfig.name))} - ${import_picocolors25.default.red("Error")}`);
43221
- console.log(import_picocolors25.default.dim(` ${result.error}`));
43117
+ ${import_picocolors23.default.bold(import_picocolors23.default.cyan(result.kitConfig.name))} - ${import_picocolors23.default.red("Error")}`);
43118
+ console.log(import_picocolors23.default.dim(` ${result.error}`));
43222
43119
  } else {
43223
43120
  displayKitReleases(result.kitConfig.name, result.releases);
43224
43121
  }
@@ -43287,8 +43184,274 @@ function registerCommands(cli) {
43287
43184
  }
43288
43185
 
43289
43186
  // src/cli/version-display.ts
43290
- import { existsSync as existsSync20, readFileSync as readFileSync6 } from "node:fs";
43187
+ import { existsSync as existsSync20, readFileSync as readFileSync7 } from "node:fs";
43291
43188
  import { join as join77 } from "node:path";
43189
+
43190
+ // src/domains/versioning/checking/version-utils.ts
43191
+ var import_compare_versions4 = __toESM(require_umd(), 1);
43192
+ function isUpdateCheckDisabled() {
43193
+ return process.env.NO_UPDATE_NOTIFIER === "1" || process.env.NO_UPDATE_NOTIFIER === "true" || !process.stdout.isTTY;
43194
+ }
43195
+ function normalizeVersion(version) {
43196
+ return version.replace(/^v/, "");
43197
+ }
43198
+ function isNewerVersion(currentVersion, latestVersion) {
43199
+ try {
43200
+ const current = normalizeVersion(currentVersion);
43201
+ const latest = normalizeVersion(latestVersion);
43202
+ return import_compare_versions4.compareVersions(latest, current) > 0;
43203
+ } catch {
43204
+ return false;
43205
+ }
43206
+ }
43207
+ // src/domains/versioning/checking/kit-version-checker.ts
43208
+ init_logger();
43209
+ init_types2();
43210
+
43211
+ // src/domains/versioning/version-cache.ts
43212
+ init_logger();
43213
+ import { existsSync as existsSync19 } from "node:fs";
43214
+ import { mkdir as mkdir22, readFile as readFile26, writeFile as writeFile22 } from "node:fs/promises";
43215
+ import { join as join76 } from "node:path";
43216
+ class VersionCacheManager {
43217
+ static CACHE_FILENAME = "version-check.json";
43218
+ static CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000;
43219
+ static getCacheFile() {
43220
+ const cacheDir = PathResolver.getCacheDir(false);
43221
+ return join76(cacheDir, VersionCacheManager.CACHE_FILENAME);
43222
+ }
43223
+ static async load() {
43224
+ const cacheFile = VersionCacheManager.getCacheFile();
43225
+ try {
43226
+ if (!existsSync19(cacheFile)) {
43227
+ logger.debug("Version check cache not found");
43228
+ return null;
43229
+ }
43230
+ const content = await readFile26(cacheFile, "utf-8");
43231
+ const cache2 = JSON.parse(content);
43232
+ if (!cache2.lastCheck || !cache2.currentVersion || !cache2.latestVersion) {
43233
+ logger.debug("Invalid cache structure, ignoring");
43234
+ return null;
43235
+ }
43236
+ logger.debug(`Version check cache loaded: ${JSON.stringify(cache2)}`);
43237
+ return cache2;
43238
+ } catch (error) {
43239
+ logger.debug(`Failed to load version check cache: ${error}`);
43240
+ return null;
43241
+ }
43242
+ }
43243
+ static async save(cache2) {
43244
+ const cacheFile = VersionCacheManager.getCacheFile();
43245
+ const cacheDir = PathResolver.getCacheDir(false);
43246
+ try {
43247
+ if (!existsSync19(cacheDir)) {
43248
+ await mkdir22(cacheDir, { recursive: true, mode: 448 });
43249
+ }
43250
+ await writeFile22(cacheFile, JSON.stringify(cache2, null, 2), "utf-8");
43251
+ logger.debug(`Version check cache saved to ${cacheFile}`);
43252
+ } catch (error) {
43253
+ logger.debug(`Failed to save version check cache: ${error}`);
43254
+ }
43255
+ }
43256
+ static isCacheValid(cache2) {
43257
+ if (!cache2)
43258
+ return false;
43259
+ const now = Date.now();
43260
+ const age = now - cache2.lastCheck;
43261
+ const isValid2 = age < VersionCacheManager.CACHE_TTL_MS;
43262
+ const ageDays = (age / 1000 / 60 / 60 / 24).toFixed(1);
43263
+ logger.debug(`Cache validity check: age=${ageDays} days, valid=${isValid2}`);
43264
+ return isValid2;
43265
+ }
43266
+ static async clear() {
43267
+ const cacheFile = VersionCacheManager.getCacheFile();
43268
+ try {
43269
+ if (existsSync19(cacheFile)) {
43270
+ const fs14 = await import("node:fs/promises");
43271
+ await fs14.unlink(cacheFile);
43272
+ logger.debug("Version check cache cleared");
43273
+ }
43274
+ } catch (error) {
43275
+ logger.debug(`Failed to clear version check cache: ${error}`);
43276
+ }
43277
+ }
43278
+ }
43279
+
43280
+ // src/domains/versioning/checking/kit-version-checker.ts
43281
+ async function fetchLatestRelease(currentVersion) {
43282
+ try {
43283
+ const githubClient = new GitHubClient;
43284
+ const kit = AVAILABLE_KITS.engineer;
43285
+ const timeoutPromise = new Promise((_3, reject) => setTimeout(() => reject(new Error("Timeout")), 5000));
43286
+ const releasePromise = githubClient.getLatestRelease(kit);
43287
+ const release = await Promise.race([releasePromise, timeoutPromise]);
43288
+ const latestVersion = release.tag_name;
43289
+ const updateAvailable = isNewerVersion(currentVersion, latestVersion);
43290
+ const releaseUrl = `https://github.com/${kit.owner}/${kit.repo}/releases/tag/${latestVersion}`;
43291
+ logger.debug(`Fetched latest release: current=${currentVersion}, latest=${latestVersion}, updateAvailable=${updateAvailable}`);
43292
+ return {
43293
+ currentVersion,
43294
+ latestVersion,
43295
+ updateAvailable,
43296
+ releaseUrl
43297
+ };
43298
+ } catch (error) {
43299
+ logger.debug(`Failed to fetch latest release: ${error}`);
43300
+ return null;
43301
+ }
43302
+ }
43303
+
43304
+ class VersionChecker {
43305
+ static async check(currentVersion) {
43306
+ if (isUpdateCheckDisabled()) {
43307
+ logger.debug("Update check disabled by environment");
43308
+ return null;
43309
+ }
43310
+ const cache2 = await VersionCacheManager.load();
43311
+ if (cache2 && VersionCacheManager.isCacheValid(cache2) && cache2.currentVersion === currentVersion) {
43312
+ logger.debug("Using cached version check result");
43313
+ return {
43314
+ currentVersion: cache2.currentVersion,
43315
+ latestVersion: cache2.latestVersion,
43316
+ updateAvailable: cache2.updateAvailable,
43317
+ releaseUrl: cache2.latestUrl
43318
+ };
43319
+ }
43320
+ logger.debug("Cache expired or invalid, fetching latest release");
43321
+ const result = await fetchLatestRelease(currentVersion);
43322
+ if (result) {
43323
+ await VersionCacheManager.save({
43324
+ lastCheck: Date.now(),
43325
+ currentVersion: result.currentVersion,
43326
+ latestVersion: result.latestVersion,
43327
+ latestUrl: result.releaseUrl,
43328
+ updateAvailable: result.updateAvailable
43329
+ });
43330
+ }
43331
+ return result;
43332
+ }
43333
+ }
43334
+ // src/domains/versioning/checking/cli-version-checker.ts
43335
+ init_logger();
43336
+ var import_compare_versions5 = __toESM(require_umd(), 1);
43337
+ var PACKAGE_NAME2 = "claudekit-cli";
43338
+
43339
+ class CliVersionChecker {
43340
+ static async check(currentVersion) {
43341
+ if (isUpdateCheckDisabled()) {
43342
+ logger.debug("CLI update check disabled by environment");
43343
+ return null;
43344
+ }
43345
+ try {
43346
+ const latestVersion = await NpmRegistryClient.getLatestVersion(PACKAGE_NAME2);
43347
+ if (!latestVersion) {
43348
+ logger.debug("Failed to fetch latest CLI version from npm");
43349
+ return null;
43350
+ }
43351
+ const current = normalizeVersion(currentVersion);
43352
+ const latest = normalizeVersion(latestVersion);
43353
+ const updateAvailable = import_compare_versions5.compareVersions(latest, current) > 0;
43354
+ logger.debug(`CLI version check: current=${current}, latest=${latest}, updateAvailable=${updateAvailable}`);
43355
+ return {
43356
+ currentVersion: current,
43357
+ latestVersion: latest,
43358
+ updateAvailable,
43359
+ releaseUrl: `https://www.npmjs.com/package/${PACKAGE_NAME2}`
43360
+ };
43361
+ } catch (error) {
43362
+ logger.debug(`CLI version check failed: ${error}`);
43363
+ return null;
43364
+ }
43365
+ }
43366
+ }
43367
+ // src/domains/versioning/checking/notification-display.ts
43368
+ var import_picocolors24 = __toESM(require_picocolors(), 1);
43369
+ function createNotificationBox2(borderColor, boxWidth) {
43370
+ const contentWidth = boxWidth - 2;
43371
+ const topBorder = borderColor(`╭${"─".repeat(contentWidth)}╮`);
43372
+ const bottomBorder = borderColor(`╰${"─".repeat(contentWidth)}╯`);
43373
+ const emptyLine = borderColor("│") + " ".repeat(contentWidth) + borderColor("│");
43374
+ const padLine = (text, visibleLen) => {
43375
+ const len = visibleLen ?? text.length;
43376
+ const displayText = len > contentWidth ? `${text.slice(0, contentWidth - 3)}...` : text;
43377
+ const actualLen = visibleLen ?? displayText.length;
43378
+ const totalPadding = contentWidth - actualLen;
43379
+ const leftPadding = Math.max(0, Math.floor(totalPadding / 2));
43380
+ const rightPadding = Math.max(0, totalPadding - leftPadding);
43381
+ return borderColor("│") + " ".repeat(leftPadding) + displayText + " ".repeat(rightPadding) + borderColor("│");
43382
+ };
43383
+ return { topBorder, bottomBorder, emptyLine, padLine };
43384
+ }
43385
+ function displayKitNotification(result, options = {}) {
43386
+ if (!result.updateAvailable)
43387
+ return;
43388
+ const { currentVersion, latestVersion } = result;
43389
+ const { isGlobal = false } = options;
43390
+ const displayCurrent = normalizeVersion(currentVersion);
43391
+ const displayLatest = normalizeVersion(latestVersion);
43392
+ const boxWidth = 52;
43393
+ const { topBorder, bottomBorder, emptyLine, padLine } = createNotificationBox2(import_picocolors24.default.cyan, boxWidth);
43394
+ const headerText = import_picocolors24.default.bold(import_picocolors24.default.yellow("⬆ Kit Update Available"));
43395
+ const headerLen = "⬆ Kit Update Available".length;
43396
+ const versionText = `${import_picocolors24.default.dim(displayCurrent)} ${import_picocolors24.default.white("→")} ${import_picocolors24.default.green(import_picocolors24.default.bold(displayLatest))}`;
43397
+ const versionLen = displayCurrent.length + 3 + displayLatest.length;
43398
+ const updateCmd = isGlobal ? "ck init -g" : "ck init";
43399
+ const commandText = `Run: ${import_picocolors24.default.cyan(import_picocolors24.default.bold(updateCmd))}`;
43400
+ const commandLen = `Run: ${updateCmd}`.length;
43401
+ console.log("");
43402
+ console.log(topBorder);
43403
+ console.log(emptyLine);
43404
+ console.log(padLine(headerText, headerLen));
43405
+ console.log(padLine(versionText, versionLen));
43406
+ console.log(emptyLine);
43407
+ console.log(padLine(commandText, commandLen));
43408
+ console.log(emptyLine);
43409
+ console.log(bottomBorder);
43410
+ console.log("");
43411
+ }
43412
+ function displayCliNotification(result) {
43413
+ if (!result.updateAvailable)
43414
+ return;
43415
+ const { currentVersion, latestVersion } = result;
43416
+ const boxWidth = 52;
43417
+ const { topBorder, bottomBorder, emptyLine, padLine } = createNotificationBox2(import_picocolors24.default.magenta, boxWidth);
43418
+ const headerText = import_picocolors24.default.bold(import_picocolors24.default.yellow("⬆ CLI Update Available"));
43419
+ const headerLen = "⬆ CLI Update Available".length;
43420
+ const versionText = `${import_picocolors24.default.dim(currentVersion)} ${import_picocolors24.default.white("→")} ${import_picocolors24.default.green(import_picocolors24.default.bold(latestVersion))}`;
43421
+ const versionLen = currentVersion.length + 3 + latestVersion.length;
43422
+ const commandText = `Run: ${import_picocolors24.default.magenta(import_picocolors24.default.bold("ck update"))}`;
43423
+ const commandLen = "Run: ck update".length;
43424
+ console.log("");
43425
+ console.log(topBorder);
43426
+ console.log(emptyLine);
43427
+ console.log(padLine(headerText, headerLen));
43428
+ console.log(padLine(versionText, versionLen));
43429
+ console.log(emptyLine);
43430
+ console.log(padLine(commandText, commandLen));
43431
+ console.log(emptyLine);
43432
+ console.log(bottomBorder);
43433
+ console.log("");
43434
+ }
43435
+ // src/domains/versioning/version-checker.ts
43436
+ class VersionChecker2 {
43437
+ static async check(currentVersion) {
43438
+ return VersionChecker.check(currentVersion);
43439
+ }
43440
+ static displayNotification(result, options = {}) {
43441
+ displayKitNotification(result, options);
43442
+ }
43443
+ }
43444
+
43445
+ class CliVersionChecker2 {
43446
+ static async check(currentVersion) {
43447
+ return CliVersionChecker.check(currentVersion);
43448
+ }
43449
+ static displayNotification(result) {
43450
+ displayCliNotification(result);
43451
+ }
43452
+ }
43453
+
43454
+ // src/cli/version-display.ts
43292
43455
  init_logger();
43293
43456
  init_types2();
43294
43457
  var packageVersion = package_default.version;
@@ -43328,7 +43491,7 @@ async function displayVersion() {
43328
43491
  const isLocalSameAsGlobal = localMetadataPath === globalMetadataPath;
43329
43492
  if (!isLocalSameAsGlobal && existsSync20(localMetadataPath)) {
43330
43493
  try {
43331
- const rawMetadata = JSON.parse(readFileSync6(localMetadataPath, "utf-8"));
43494
+ const rawMetadata = JSON.parse(readFileSync7(localMetadataPath, "utf-8"));
43332
43495
  const metadata = MetadataSchema.parse(rawMetadata);
43333
43496
  const kitsDisplay = formatInstalledKits(metadata);
43334
43497
  if (kitsDisplay) {
@@ -43342,7 +43505,7 @@ async function displayVersion() {
43342
43505
  }
43343
43506
  if (existsSync20(globalMetadataPath)) {
43344
43507
  try {
43345
- const rawMetadata = JSON.parse(readFileSync6(globalMetadataPath, "utf-8"));
43508
+ const rawMetadata = JSON.parse(readFileSync7(globalMetadataPath, "utf-8"));
43346
43509
  const metadata = MetadataSchema.parse(rawMetadata);
43347
43510
  const kitsDisplay = formatInstalledKits(metadata);
43348
43511
  if (kitsDisplay) {
@@ -43387,7 +43550,7 @@ function getPackageVersion2() {
43387
43550
 
43388
43551
  // src/shared/logger.ts
43389
43552
  init_output_manager();
43390
- var import_picocolors26 = __toESM(require_picocolors(), 1);
43553
+ var import_picocolors25 = __toESM(require_picocolors(), 1);
43391
43554
  import { createWriteStream as createWriteStream3 } from "node:fs";
43392
43555
 
43393
43556
  class Logger2 {
@@ -43396,23 +43559,23 @@ class Logger2 {
43396
43559
  exitHandlerRegistered = false;
43397
43560
  info(message) {
43398
43561
  const symbols = output.getSymbols();
43399
- console.log(import_picocolors26.default.blue(symbols.info), message);
43562
+ console.log(import_picocolors25.default.blue(symbols.info), message);
43400
43563
  }
43401
43564
  success(message) {
43402
43565
  const symbols = output.getSymbols();
43403
- console.log(import_picocolors26.default.green(symbols.success), message);
43566
+ console.log(import_picocolors25.default.green(symbols.success), message);
43404
43567
  }
43405
43568
  warning(message) {
43406
43569
  const symbols = output.getSymbols();
43407
- console.log(import_picocolors26.default.yellow(symbols.warning), message);
43570
+ console.log(import_picocolors25.default.yellow(symbols.warning), message);
43408
43571
  }
43409
43572
  error(message) {
43410
43573
  const symbols = output.getSymbols();
43411
- console.error(import_picocolors26.default.red(symbols.error), message);
43574
+ console.error(import_picocolors25.default.red(symbols.error), message);
43412
43575
  }
43413
43576
  debug(message) {
43414
43577
  if (process.env.DEBUG) {
43415
- console.log(import_picocolors26.default.gray("[DEBUG]"), message);
43578
+ console.log(import_picocolors25.default.gray("[DEBUG]"), message);
43416
43579
  }
43417
43580
  }
43418
43581
  verbose(message, context) {
@@ -43421,7 +43584,7 @@ class Logger2 {
43421
43584
  const timestamp = this.getTimestamp();
43422
43585
  const sanitizedMessage = this.sanitize(message);
43423
43586
  const formattedContext = context ? this.formatContext(context) : "";
43424
- const logLine = `${timestamp} ${import_picocolors26.default.gray("[VERBOSE]")} ${sanitizedMessage}${formattedContext}`;
43587
+ const logLine = `${timestamp} ${import_picocolors25.default.gray("[VERBOSE]")} ${sanitizedMessage}${formattedContext}`;
43425
43588
  console.error(logLine);
43426
43589
  if (this.logFileStream) {
43427
43590
  const plainLogLine = `${timestamp} [VERBOSE] ${sanitizedMessage}${formattedContext}`;
@@ -43524,7 +43687,7 @@ var logger3 = new Logger2;
43524
43687
 
43525
43688
  // src/shared/output-manager.ts
43526
43689
  init_terminal_utils();
43527
- var import_picocolors27 = __toESM(require_picocolors(), 1);
43690
+ var import_picocolors26 = __toESM(require_picocolors(), 1);
43528
43691
  var SYMBOLS2 = {
43529
43692
  unicode: {
43530
43693
  prompt: "◇",
@@ -43603,7 +43766,7 @@ class OutputManager2 {
43603
43766
  if (this.config.quiet)
43604
43767
  return;
43605
43768
  const symbol = this.getSymbols().success;
43606
- console.log(import_picocolors27.default.green(`${symbol} ${message}`));
43769
+ console.log(import_picocolors26.default.green(`${symbol} ${message}`));
43607
43770
  }
43608
43771
  error(message, data) {
43609
43772
  if (this.config.json) {
@@ -43611,7 +43774,7 @@ class OutputManager2 {
43611
43774
  return;
43612
43775
  }
43613
43776
  const symbol = this.getSymbols().error;
43614
- console.error(import_picocolors27.default.red(`${symbol} ${message}`));
43777
+ console.error(import_picocolors26.default.red(`${symbol} ${message}`));
43615
43778
  }
43616
43779
  warning(message, data) {
43617
43780
  if (this.config.json) {
@@ -43621,7 +43784,7 @@ class OutputManager2 {
43621
43784
  if (this.config.quiet)
43622
43785
  return;
43623
43786
  const symbol = this.getSymbols().warning;
43624
- console.log(import_picocolors27.default.yellow(`${symbol} ${message}`));
43787
+ console.log(import_picocolors26.default.yellow(`${symbol} ${message}`));
43625
43788
  }
43626
43789
  info(message, data) {
43627
43790
  if (this.config.json) {
@@ -43631,7 +43794,7 @@ class OutputManager2 {
43631
43794
  if (this.config.quiet)
43632
43795
  return;
43633
43796
  const symbol = this.getSymbols().info;
43634
- console.log(import_picocolors27.default.blue(`${symbol} ${message}`));
43797
+ console.log(import_picocolors26.default.blue(`${symbol} ${message}`));
43635
43798
  }
43636
43799
  verbose(message, data) {
43637
43800
  if (!this.config.verbose)
@@ -43640,7 +43803,7 @@ class OutputManager2 {
43640
43803
  this.addJsonEntry({ type: "info", message, data });
43641
43804
  return;
43642
43805
  }
43643
- console.log(import_picocolors27.default.dim(` ${message}`));
43806
+ console.log(import_picocolors26.default.dim(` ${message}`));
43644
43807
  }
43645
43808
  indent(message) {
43646
43809
  if (this.config.json)
@@ -43665,7 +43828,7 @@ class OutputManager2 {
43665
43828
  return;
43666
43829
  const symbols = this.getSymbols();
43667
43830
  console.log();
43668
- console.log(import_picocolors27.default.bold(import_picocolors27.default.cyan(`${symbols.line} ${title}`)));
43831
+ console.log(import_picocolors26.default.bold(import_picocolors26.default.cyan(`${symbols.line} ${title}`)));
43669
43832
  }
43670
43833
  addJsonEntry(entry) {
43671
43834
  this.jsonBuffer.push({