claudekit-cli 2.5.2 → 3.0.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 (3) hide show
  1. package/bin/ck.js +4 -2
  2. package/dist/index.js +354 -515
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -4997,7 +4997,8 @@ var init_types2 = __esm(() => {
4997
4997
  installSkills: exports_external.boolean().default(false),
4998
4998
  prefix: exports_external.boolean().default(false),
4999
4999
  beta: exports_external.boolean().default(false),
5000
- dryRun: exports_external.boolean().default(false)
5000
+ dryRun: exports_external.boolean().default(false),
5001
+ refresh: exports_external.boolean().default(false)
5001
5002
  });
5002
5003
  UpdateCommandOptionsSchema = exports_external.object({
5003
5004
  dir: exports_external.string().default("."),
@@ -5012,7 +5013,8 @@ var init_types2 = __esm(() => {
5012
5013
  beta: exports_external.boolean().default(false),
5013
5014
  dryRun: exports_external.boolean().default(false),
5014
5015
  forceOverwrite: exports_external.boolean().default(false),
5015
- skipSetup: exports_external.boolean().default(false)
5016
+ skipSetup: exports_external.boolean().default(false),
5017
+ refresh: exports_external.boolean().default(false)
5016
5018
  });
5017
5019
  VersionCommandOptionsSchema = exports_external.object({
5018
5020
  kit: KitType.optional(),
@@ -5050,9 +5052,6 @@ var init_types2 = __esm(() => {
5050
5052
  files: exports_external.array(TrackedFileSchema).optional()
5051
5053
  });
5052
5054
  ConfigSchema = exports_external.object({
5053
- github: exports_external.object({
5054
- token: exports_external.string().optional()
5055
- }).optional(),
5056
5055
  defaults: exports_external.object({
5057
5056
  kit: KitType.optional(),
5058
5057
  dir: exports_external.string().optional()
@@ -5423,7 +5422,7 @@ var require_polyfills = __commonJS((exports, module) => {
5423
5422
  var constants = __require("constants");
5424
5423
  var origCwd = process.cwd;
5425
5424
  var cwd = null;
5426
- var platform3 = process.env.GRACEFUL_FS_PLATFORM || process.platform;
5425
+ var platform2 = process.env.GRACEFUL_FS_PLATFORM || process.platform;
5427
5426
  process.cwd = function() {
5428
5427
  if (!cwd)
5429
5428
  cwd = origCwd.call(process);
@@ -5482,7 +5481,7 @@ var require_polyfills = __commonJS((exports, module) => {
5482
5481
  };
5483
5482
  fs.lchownSync = function() {};
5484
5483
  }
5485
- if (platform3 === "win32") {
5484
+ if (platform2 === "win32") {
5486
5485
  fs.rename = typeof fs.rename !== "function" ? fs.rename : function(fs$rename) {
5487
5486
  function rename(from, to, cb) {
5488
5487
  var start = Date.now();
@@ -5922,8 +5921,8 @@ GFS4: `);
5922
5921
  fs2.createReadStream = createReadStream;
5923
5922
  fs2.createWriteStream = createWriteStream2;
5924
5923
  var fs$readFile = fs2.readFile;
5925
- fs2.readFile = readFile3;
5926
- function readFile3(path, options, cb) {
5924
+ fs2.readFile = readFile2;
5925
+ function readFile2(path, options, cb) {
5927
5926
  if (typeof options === "function")
5928
5927
  cb = options, options = null;
5929
5928
  return go$readFile(path, options, cb);
@@ -5939,8 +5938,8 @@ GFS4: `);
5939
5938
  }
5940
5939
  }
5941
5940
  var fs$writeFile = fs2.writeFile;
5942
- fs2.writeFile = writeFile3;
5943
- function writeFile3(path, data, options, cb) {
5941
+ fs2.writeFile = writeFile2;
5942
+ function writeFile2(path, data, options, cb) {
5944
5943
  if (typeof options === "function")
5945
5944
  cb = options, options = null;
5946
5945
  return go$writeFile(path, data, options, cb);
@@ -6860,14 +6859,14 @@ var require_empty = __commonJS((exports, module) => {
6860
6859
  var u = require_universalify().fromPromise;
6861
6860
  var fs = require_fs();
6862
6861
  var path = __require("path");
6863
- var mkdir3 = require_mkdirs();
6862
+ var mkdir2 = require_mkdirs();
6864
6863
  var remove = require_remove();
6865
6864
  var emptyDir = u(async function emptyDir(dir) {
6866
6865
  let items;
6867
6866
  try {
6868
6867
  items = await fs.readdir(dir);
6869
6868
  } catch {
6870
- return mkdir3.mkdirs(dir);
6869
+ return mkdir2.mkdirs(dir);
6871
6870
  }
6872
6871
  return Promise.all(items.map((item) => remove.remove(path.join(dir, item))));
6873
6872
  });
@@ -6876,7 +6875,7 @@ var require_empty = __commonJS((exports, module) => {
6876
6875
  try {
6877
6876
  items = fs.readdirSync(dir);
6878
6877
  } catch {
6879
- return mkdir3.mkdirsSync(dir);
6878
+ return mkdir2.mkdirsSync(dir);
6880
6879
  }
6881
6880
  items.forEach((item) => {
6882
6881
  item = path.join(dir, item);
@@ -6896,7 +6895,7 @@ var require_file = __commonJS((exports, module) => {
6896
6895
  var u = require_universalify().fromPromise;
6897
6896
  var path = __require("path");
6898
6897
  var fs = require_fs();
6899
- var mkdir3 = require_mkdirs();
6898
+ var mkdir2 = require_mkdirs();
6900
6899
  async function createFile(file) {
6901
6900
  let stats;
6902
6901
  try {
@@ -6910,7 +6909,7 @@ var require_file = __commonJS((exports, module) => {
6910
6909
  dirStats = await fs.stat(dir);
6911
6910
  } catch (err) {
6912
6911
  if (err.code === "ENOENT") {
6913
- await mkdir3.mkdirs(dir);
6912
+ await mkdir2.mkdirs(dir);
6914
6913
  await fs.writeFile(file, "");
6915
6914
  return;
6916
6915
  } else {
@@ -6937,7 +6936,7 @@ var require_file = __commonJS((exports, module) => {
6937
6936
  }
6938
6937
  } catch (err) {
6939
6938
  if (err && err.code === "ENOENT")
6940
- mkdir3.mkdirsSync(dir);
6939
+ mkdir2.mkdirsSync(dir);
6941
6940
  else
6942
6941
  throw err;
6943
6942
  }
@@ -6954,7 +6953,7 @@ var require_link = __commonJS((exports, module) => {
6954
6953
  var u = require_universalify().fromPromise;
6955
6954
  var path = __require("path");
6956
6955
  var fs = require_fs();
6957
- var mkdir3 = require_mkdirs();
6956
+ var mkdir2 = require_mkdirs();
6958
6957
  var { pathExists } = require_path_exists();
6959
6958
  var { areIdentical } = require_stat();
6960
6959
  async function createLink(srcpath, dstpath) {
@@ -6974,7 +6973,7 @@ var require_link = __commonJS((exports, module) => {
6974
6973
  const dir = path.dirname(dstpath);
6975
6974
  const dirExists = await pathExists(dir);
6976
6975
  if (!dirExists) {
6977
- await mkdir3.mkdirs(dir);
6976
+ await mkdir2.mkdirs(dir);
6978
6977
  }
6979
6978
  await fs.link(srcpath, dstpath);
6980
6979
  }
@@ -6995,7 +6994,7 @@ var require_link = __commonJS((exports, module) => {
6995
6994
  const dirExists = fs.existsSync(dir);
6996
6995
  if (dirExists)
6997
6996
  return fs.linkSync(srcpath, dstpath);
6998
- mkdir3.mkdirsSync(dir);
6997
+ mkdir2.mkdirsSync(dir);
6999
6998
  return fs.linkSync(srcpath, dstpath);
7000
6999
  }
7001
7000
  module.exports = {
@@ -7235,7 +7234,7 @@ var require_jsonfile = __commonJS((exports, module) => {
7235
7234
  }
7236
7235
  return obj;
7237
7236
  }
7238
- var readFile3 = universalify.fromPromise(_readFile);
7237
+ var readFile2 = universalify.fromPromise(_readFile);
7239
7238
  function readFileSync(file, options = {}) {
7240
7239
  if (typeof options === "string") {
7241
7240
  options = { encoding: options };
@@ -7260,16 +7259,16 @@ var require_jsonfile = __commonJS((exports, module) => {
7260
7259
  const str = stringify(obj, options);
7261
7260
  await universalify.fromCallback(fs.writeFile)(file, str, options);
7262
7261
  }
7263
- var writeFile3 = universalify.fromPromise(_writeFile);
7262
+ var writeFile2 = universalify.fromPromise(_writeFile);
7264
7263
  function writeFileSync(file, obj, options = {}) {
7265
7264
  const fs = options.fs || _fs;
7266
7265
  const str = stringify(obj, options);
7267
7266
  return fs.writeFileSync(file, str, options);
7268
7267
  }
7269
7268
  module.exports = {
7270
- readFile: readFile3,
7269
+ readFile: readFile2,
7271
7270
  readFileSync,
7272
- writeFile: writeFile3,
7271
+ writeFile: writeFile2,
7273
7272
  writeFileSync
7274
7273
  };
7275
7274
  });
@@ -7290,19 +7289,19 @@ var require_output_file = __commonJS((exports, module) => {
7290
7289
  var u = require_universalify().fromPromise;
7291
7290
  var fs = require_fs();
7292
7291
  var path = __require("path");
7293
- var mkdir3 = require_mkdirs();
7292
+ var mkdir2 = require_mkdirs();
7294
7293
  var pathExists = require_path_exists().pathExists;
7295
7294
  async function outputFile(file, data, encoding = "utf-8") {
7296
7295
  const dir = path.dirname(file);
7297
7296
  if (!await pathExists(dir)) {
7298
- await mkdir3.mkdirs(dir);
7297
+ await mkdir2.mkdirs(dir);
7299
7298
  }
7300
7299
  return fs.writeFile(file, data, encoding);
7301
7300
  }
7302
7301
  function outputFileSync(file, ...args) {
7303
7302
  const dir = path.dirname(file);
7304
7303
  if (!fs.existsSync(dir)) {
7305
- mkdir3.mkdirsSync(dir);
7304
+ mkdir2.mkdirsSync(dir);
7306
7305
  }
7307
7306
  fs.writeFileSync(file, ...args);
7308
7307
  }
@@ -11708,6 +11707,10 @@ var init_help_commands = __esm(() => {
11708
11707
  {
11709
11708
  flags: "--beta",
11710
11709
  description: "Show beta versions in selection prompt"
11710
+ },
11711
+ {
11712
+ flags: "--refresh",
11713
+ description: "Bypass release cache to fetch latest versions from GitHub"
11711
11714
  }
11712
11715
  ]
11713
11716
  },
@@ -11789,6 +11792,10 @@ var init_help_commands = __esm(() => {
11789
11792
  {
11790
11793
  flags: "--beta",
11791
11794
  description: "Show beta versions in selection prompt"
11795
+ },
11796
+ {
11797
+ flags: "--refresh",
11798
+ description: "Bypass release cache to fetch latest versions from GitHub"
11792
11799
  }
11793
11800
  ]
11794
11801
  },
@@ -13035,7 +13042,7 @@ var cac = (name = "") => new CAC(name);
13035
13042
  // package.json
13036
13043
  var package_default = {
13037
13044
  name: "claudekit-cli",
13038
- version: "2.5.2",
13045
+ version: "3.0.0",
13039
13046
  description: "CLI tool for bootstrapping and updating ClaudeKit projects",
13040
13047
  type: "module",
13041
13048
  repository: {
@@ -13124,17 +13131,89 @@ init_dist2();
13124
13131
  import { execSync as execSync2 } from "node:child_process";
13125
13132
 
13126
13133
  // src/lib/auth.ts
13127
- init_dist2();
13128
13134
  init_types2();
13135
+ init_logger();
13129
13136
  import { execSync } from "node:child_process";
13130
13137
 
13131
- // src/utils/config.ts
13138
+ class AuthManager {
13139
+ static token = null;
13140
+ static ghCliInstalled = null;
13141
+ static async getToken() {
13142
+ if (AuthManager.token) {
13143
+ return { token: AuthManager.token, method: "gh-cli" };
13144
+ }
13145
+ if (!AuthManager.isGhCliInstalled()) {
13146
+ throw new AuthenticationError(`GitHub CLI is not installed.
13147
+
13148
+ ` + `ClaudeKit requires GitHub CLI for accessing private repositories.
13149
+
13150
+ ` + `To install:
13151
+ ` + ` macOS: brew install gh
13152
+ ` + ` Windows: winget install GitHub.cli
13153
+ ` + ` Linux: sudo apt install gh (or see: gh.io/install)
13154
+
13155
+ ` + "After installing, run: gh auth login");
13156
+ }
13157
+ const token = AuthManager.getFromGhCli();
13158
+ if (token) {
13159
+ AuthManager.token = token;
13160
+ logger.debug("Using GitHub CLI authentication");
13161
+ return { token, method: "gh-cli" };
13162
+ }
13163
+ throw new AuthenticationError(`GitHub CLI is not authenticated.
13164
+
13165
+ ` + `Run: gh auth login
13166
+
13167
+ ` + "Then follow the prompts to authenticate with your GitHub account.");
13168
+ }
13169
+ static isGhCliInstalled() {
13170
+ if (AuthManager.ghCliInstalled !== null) {
13171
+ return AuthManager.ghCliInstalled;
13172
+ }
13173
+ try {
13174
+ execSync("gh --version", {
13175
+ stdio: "ignore",
13176
+ timeout: 5000
13177
+ });
13178
+ AuthManager.ghCliInstalled = true;
13179
+ return true;
13180
+ } catch {
13181
+ AuthManager.ghCliInstalled = false;
13182
+ return false;
13183
+ }
13184
+ }
13185
+ static getFromGhCli() {
13186
+ try {
13187
+ const token = execSync("gh auth token", {
13188
+ encoding: "utf-8",
13189
+ stdio: ["pipe", "pipe", "ignore"],
13190
+ timeout: 5000
13191
+ }).trim();
13192
+ if (token && token.length > 0) {
13193
+ return token;
13194
+ }
13195
+ return null;
13196
+ } catch {
13197
+ return null;
13198
+ }
13199
+ }
13200
+ static async clearToken() {
13201
+ AuthManager.token = null;
13202
+ logger.debug("Cleared cached token");
13203
+ }
13204
+ }
13205
+
13206
+ // src/lib/github.ts
13132
13207
  init_types2();
13133
13208
  init_logger();
13209
+ import { Octokit } from "@octokit/rest";
13210
+
13211
+ // src/lib/release-cache.ts
13212
+ init_zod();
13213
+ init_logger();
13134
13214
  import { existsSync } from "node:fs";
13135
- import { mkdir, readFile, writeFile } from "node:fs/promises";
13136
- import { chmod } from "node:fs/promises";
13137
- import { platform as platform2 } from "node:os";
13215
+ import { mkdir, readFile, unlink, writeFile } from "node:fs/promises";
13216
+ import { join as join2 } from "node:path";
13138
13217
 
13139
13218
  // src/utils/path-resolver.ts
13140
13219
  import { homedir, platform } from "node:os";
@@ -13238,243 +13317,7 @@ class PathResolver {
13238
13317
  }
13239
13318
  }
13240
13319
 
13241
- // src/utils/config.ts
13242
- class ConfigManager {
13243
- static config = null;
13244
- static globalFlag = false;
13245
- static setGlobalFlag(global2) {
13246
- ConfigManager.globalFlag = global2;
13247
- ConfigManager.config = null;
13248
- }
13249
- static getGlobalFlag() {
13250
- return ConfigManager.globalFlag;
13251
- }
13252
- static async load() {
13253
- if (ConfigManager.config) {
13254
- return ConfigManager.config;
13255
- }
13256
- const configFile = PathResolver.getConfigFile(ConfigManager.globalFlag);
13257
- try {
13258
- if (existsSync(configFile)) {
13259
- const content = await readFile(configFile, "utf-8");
13260
- const data = JSON.parse(content);
13261
- ConfigManager.config = ConfigSchema.parse(data);
13262
- logger.debug(`Config loaded from ${configFile}`);
13263
- return ConfigManager.config;
13264
- }
13265
- } catch (error) {
13266
- logger.warning(`Failed to load config: ${error instanceof Error ? error.message : "Unknown error"}`);
13267
- }
13268
- ConfigManager.config = { github: {}, defaults: {} };
13269
- return ConfigManager.config;
13270
- }
13271
- static async save(config) {
13272
- try {
13273
- const validConfig = ConfigSchema.parse(config);
13274
- const configDir = PathResolver.getConfigDir(ConfigManager.globalFlag);
13275
- const configFile = PathResolver.getConfigFile(ConfigManager.globalFlag);
13276
- if (!existsSync(configDir)) {
13277
- await mkdir(configDir, { recursive: true });
13278
- if (platform2() !== "win32") {
13279
- await chmod(configDir, 448);
13280
- }
13281
- }
13282
- await writeFile(configFile, JSON.stringify(validConfig, null, 2), "utf-8");
13283
- if (platform2() !== "win32") {
13284
- await chmod(configFile, 384);
13285
- }
13286
- ConfigManager.config = validConfig;
13287
- logger.debug(`Config saved to ${configFile}`);
13288
- } catch (error) {
13289
- throw new Error(`Failed to save config: ${error instanceof Error ? error.message : "Unknown error"}`);
13290
- }
13291
- }
13292
- static async get() {
13293
- return ConfigManager.load();
13294
- }
13295
- static async set(key, value) {
13296
- const config = await ConfigManager.load();
13297
- const keys = key.split(".");
13298
- let current = config;
13299
- for (let i = 0;i < keys.length - 1; i++) {
13300
- if (!(keys[i] in current)) {
13301
- current[keys[i]] = {};
13302
- }
13303
- current = current[keys[i]];
13304
- }
13305
- current[keys[keys.length - 1]] = value;
13306
- await ConfigManager.save(config);
13307
- }
13308
- static async getToken() {
13309
- const config = await ConfigManager.load();
13310
- return config.github?.token;
13311
- }
13312
- static async setToken(token) {
13313
- await ConfigManager.set("github.token", token);
13314
- }
13315
- }
13316
-
13317
- // src/lib/auth.ts
13318
- init_logger();
13319
- var keytarModule = null;
13320
- async function getKeytar() {
13321
- if (keytarModule)
13322
- return keytarModule;
13323
- try {
13324
- keytarModule = await import("keytar");
13325
- return keytarModule;
13326
- } catch (error) {
13327
- logger.debug(`Keytar not available: ${String(error)}`);
13328
- return null;
13329
- }
13330
- }
13331
- var SERVICE_NAME = "claudekit-cli";
13332
- var ACCOUNT_NAME = "github-token";
13333
-
13334
- class AuthManager {
13335
- static token = null;
13336
- static authMethod = null;
13337
- static async getToken() {
13338
- if (AuthManager.token && AuthManager.authMethod) {
13339
- return { token: AuthManager.token, method: AuthManager.authMethod };
13340
- }
13341
- try {
13342
- const token = await AuthManager.getFromGhCli();
13343
- if (token) {
13344
- AuthManager.token = token;
13345
- AuthManager.authMethod = "gh-cli";
13346
- logger.debug("Using GitHub CLI authentication");
13347
- return { token, method: "gh-cli" };
13348
- }
13349
- } catch (error) {
13350
- logger.debug("GitHub CLI not available");
13351
- }
13352
- const envToken = process.env.GITHUB_TOKEN || process.env.GH_TOKEN;
13353
- if (envToken) {
13354
- AuthManager.token = envToken;
13355
- AuthManager.authMethod = "env-var";
13356
- logger.debug("Using environment variable authentication");
13357
- return { token: envToken, method: "env-var" };
13358
- }
13359
- try {
13360
- const configToken = await ConfigManager.getToken();
13361
- if (configToken) {
13362
- AuthManager.token = configToken;
13363
- AuthManager.authMethod = "env-var";
13364
- logger.debug("Using config file authentication");
13365
- return { token: configToken, method: "env-var" };
13366
- }
13367
- } catch (error) {
13368
- logger.debug("No token in config file");
13369
- }
13370
- try {
13371
- const keytar = await getKeytar();
13372
- if (keytar) {
13373
- const keychainToken = await keytar.getPassword(SERVICE_NAME, ACCOUNT_NAME);
13374
- if (keychainToken) {
13375
- AuthManager.token = keychainToken;
13376
- AuthManager.authMethod = "keychain";
13377
- logger.debug("Using keychain authentication");
13378
- return { token: keychainToken, method: "keychain" };
13379
- }
13380
- } else {
13381
- logger.debug("Keychain not available on this system");
13382
- }
13383
- } catch (error) {
13384
- logger.debug("No token in keychain");
13385
- }
13386
- const promptedToken = await AuthManager.promptForToken();
13387
- AuthManager.token = promptedToken;
13388
- AuthManager.authMethod = "prompt";
13389
- return { token: promptedToken, method: "prompt" };
13390
- }
13391
- static async getFromGhCli() {
13392
- try {
13393
- const token = execSync("gh auth token", {
13394
- encoding: "utf-8",
13395
- stdio: ["pipe", "pipe", "ignore"],
13396
- timeout: 5000
13397
- }).trim();
13398
- if (token && token.length > 0) {
13399
- return token;
13400
- }
13401
- return null;
13402
- } catch {
13403
- return null;
13404
- }
13405
- }
13406
- static async promptForToken() {
13407
- logger.info("");
13408
- logger.info("GitHub authentication required to access private repositories.");
13409
- logger.info("");
13410
- logger.info("\uD83D\uDCA1 Tip: For easier setup, use GitHub CLI instead:");
13411
- logger.info(" gh auth login");
13412
- logger.info("");
13413
- logger.info("Or create a Personal Access Token:");
13414
- logger.info(" https://github.com/settings/tokens/new?scopes=repo&description=ClaudeKit%20CLI");
13415
- logger.info("");
13416
- const token = await re({
13417
- message: "Enter your GitHub Personal Access Token:",
13418
- validate: (value) => {
13419
- if (!value || value.length === 0) {
13420
- return "Token is required";
13421
- }
13422
- if (!value.startsWith("ghp_") && !value.startsWith("github_pat_")) {
13423
- return 'Invalid token format. Token should start with "ghp_" or "github_pat_"';
13424
- }
13425
- return;
13426
- }
13427
- });
13428
- if (lD(token)) {
13429
- logger.info("");
13430
- logger.info("Alternative: Set GITHUB_TOKEN environment variable or use 'gh auth login'");
13431
- throw new AuthenticationError("Authentication cancelled by user");
13432
- }
13433
- const keytar = await getKeytar();
13434
- if (keytar) {
13435
- const save = await se({
13436
- message: "Save token securely in OS keychain?"
13437
- });
13438
- if (save && !lD(save)) {
13439
- try {
13440
- await keytar.setPassword(SERVICE_NAME, ACCOUNT_NAME, token);
13441
- logger.success("Token saved securely in keychain");
13442
- } catch (error) {
13443
- logger.warning("Failed to save token to keychain");
13444
- }
13445
- }
13446
- }
13447
- return token;
13448
- }
13449
- static async clearToken() {
13450
- AuthManager.token = null;
13451
- AuthManager.authMethod = null;
13452
- try {
13453
- const keytar = await getKeytar();
13454
- if (keytar) {
13455
- await keytar.deletePassword(SERVICE_NAME, ACCOUNT_NAME);
13456
- logger.success("Token cleared from keychain");
13457
- }
13458
- } catch (error) {
13459
- logger.warning("Failed to clear token from keychain");
13460
- }
13461
- }
13462
- static isValidTokenFormat(token) {
13463
- return token.startsWith("ghp_") || token.startsWith("github_pat_");
13464
- }
13465
- }
13466
-
13467
- // src/lib/github.ts
13468
- init_types2();
13469
- init_logger();
13470
- import { Octokit } from "@octokit/rest";
13471
-
13472
13320
  // src/lib/release-cache.ts
13473
- init_zod();
13474
- init_logger();
13475
- import { existsSync as existsSync2 } from "node:fs";
13476
- import { mkdir as mkdir2, readFile as readFile2, unlink, writeFile as writeFile2 } from "node:fs/promises";
13477
- import { join as join2 } from "node:path";
13478
13321
  var ReleaseCacheEntrySchema = exports_external.object({
13479
13322
  timestamp: exports_external.number(),
13480
13323
  releases: exports_external.array(exports_external.any())
@@ -13490,11 +13333,11 @@ class ReleaseCache {
13490
13333
  async get(key) {
13491
13334
  const cacheFile = this.getCachePath(key);
13492
13335
  try {
13493
- if (!existsSync2(cacheFile)) {
13336
+ if (!existsSync(cacheFile)) {
13494
13337
  logger.debug(`Release cache not found for key: ${key}`);
13495
13338
  return null;
13496
13339
  }
13497
- const content = await readFile2(cacheFile, "utf-8");
13340
+ const content = await readFile(cacheFile, "utf-8");
13498
13341
  const parsed = JSON.parse(content);
13499
13342
  const cacheEntry = ReleaseCacheEntrySchema.parse(parsed);
13500
13343
  if (this.isExpired(cacheEntry.timestamp)) {
@@ -13515,12 +13358,12 @@ class ReleaseCache {
13515
13358
  async set(key, releases) {
13516
13359
  const cacheFile = this.getCachePath(key);
13517
13360
  try {
13518
- await mkdir2(this.cacheDir, { recursive: true, mode: 448 });
13361
+ await mkdir(this.cacheDir, { recursive: true, mode: 448 });
13519
13362
  const cacheEntry = {
13520
13363
  timestamp: Date.now(),
13521
13364
  releases
13522
13365
  };
13523
- await writeFile2(cacheFile, JSON.stringify(cacheEntry, null, 2), "utf-8");
13366
+ await writeFile(cacheFile, JSON.stringify(cacheEntry, null, 2), "utf-8");
13524
13367
  logger.debug(`Release cache set for key: ${key}, cached ${releases.length} releases`);
13525
13368
  } catch (error) {
13526
13369
  logger.debug(`Failed to set release cache for key ${key}: ${error}`);
@@ -13530,7 +13373,7 @@ class ReleaseCache {
13530
13373
  if (key) {
13531
13374
  const cacheFile = this.getCachePath(key);
13532
13375
  try {
13533
- if (existsSync2(cacheFile)) {
13376
+ if (existsSync(cacheFile)) {
13534
13377
  await unlink(cacheFile);
13535
13378
  logger.debug(`Release cache cleared for key: ${key}`);
13536
13379
  }
@@ -13840,50 +13683,57 @@ class GitHubClient {
13840
13683
  });
13841
13684
  return GitHubReleaseSchema.parse(data);
13842
13685
  } catch (error) {
13843
- if (error?.status === 404) {
13844
- throw new GitHubError(`Cannot access ${kit.name} repository.
13686
+ return this.handleHttpError(error, {
13687
+ kit,
13688
+ operation: "fetch release",
13689
+ verboseFlag: "ck new --verbose"
13690
+ });
13691
+ }
13692
+ }
13693
+ async invalidateAuth() {
13694
+ await AuthManager.clearToken();
13695
+ this.octokit = null;
13696
+ logger.debug("Invalidated cached authentication due to 401 error");
13697
+ }
13698
+ async handleHttpError(error, context) {
13699
+ const { kit, operation, verboseFlag = "ck new --verbose" } = context;
13700
+ if (error?.status === 401) {
13701
+ await this.invalidateAuth();
13702
+ throw new GitHubError(`Authentication failed.
13845
13703
 
13846
- Possible causes:
13847
- • You haven't accepted the GitHub repository invitation
13848
- • Your token lacks the 'repo' scope (needs full private repo access)
13849
- • You're not added as a collaborator yet
13850
- • Repository doesn't exist
13704
+ Your GitHub CLI session may have expired.
13851
13705
 
13852
- Solutions:
13853
- 1. Check email for GitHub invitation and accept it
13854
- 2. Use 'gh auth login' for automatic authentication (recommended)
13855
- 3. Recreate token with 'repo' scope: https://github.com/settings/tokens/new?scopes=repo
13856
- 4. Wait 2-5 minutes after accepting invitation for permissions to sync
13706
+ Solution: Re-authenticate with GitHub CLI
13707
+ gh auth login
13857
13708
 
13858
- Need help? Run with: ck new --verbose`, 404);
13859
- }
13860
- if (error?.status === 401) {
13861
- throw new GitHubError(`Authentication failed - token is invalid or expired.
13709
+ Need help? Run with: ${verboseFlag}`, 401);
13710
+ }
13711
+ if (error?.status === 403) {
13712
+ throw new GitHubError(`Access forbidden.
13862
13713
 
13863
- ` + `Solutions:
13864
- ` + ` 1. Use GitHub CLI (recommended): gh auth login
13865
- ` + ` 2. Create new token: https://github.com/settings/tokens/new?scopes=repo
13866
- ` + ` 3. Verify token format (should start with 'ghp_' or 'github_pat_')
13867
- ` + ` 4. Check token is set: echo $GITHUB_TOKEN
13714
+ Your GitHub CLI session may lack required permissions.
13868
13715
 
13869
- ` + "Need help? Run with: ck new --verbose", 401);
13870
- }
13871
- if (error?.status === 403) {
13872
- throw new GitHubError(`Access forbidden - token lacks required permissions.
13716
+ Solution: Re-authenticate with GitHub CLI
13717
+ gh auth login
13873
13718
 
13874
- ` + `Your token needs the 'repo' scope for private repositories.
13719
+ Need help? Run with: ${verboseFlag}`, 403);
13720
+ }
13721
+ if (error?.status === 404) {
13722
+ throw new GitHubError(`Cannot access ${kit.name} repository.
13875
13723
 
13876
- ` + `Solutions:
13877
- ` + ` 1. Use GitHub CLI (handles scopes automatically): gh auth login
13878
- ` + ` 2. Recreate token with 'repo' scope: https://github.com/settings/tokens/new?scopes=repo
13879
- ` + ` 3. Check existing token scopes: https://github.com/settings/tokens
13724
+ Possible causes:
13725
+ You haven't accepted the GitHub repository invitation
13726
+ You're not added as a collaborator yet
13727
+ Repository doesn't exist
13880
13728
 
13881
- ` + `Common mistake: Using 'public_repo' scope doesn't work for private repos.
13729
+ Solutions:
13730
+ 1. Check email for GitHub invitation and accept it
13731
+ 2. Re-authenticate: gh auth login
13732
+ 3. Wait 2-5 minutes after accepting invitation for permissions to sync
13882
13733
 
13883
- ` + "Need help? Run with: ck new --verbose", 403);
13884
- }
13885
- throw new GitHubError(`Failed to fetch release: ${error?.message || "Unknown error"}`, error?.status);
13734
+ Need help? Run with: ${verboseFlag}`, 404);
13886
13735
  }
13736
+ throw new GitHubError(`Failed to ${operation}: ${error?.message || "Unknown error"}`, error?.status);
13887
13737
  }
13888
13738
  async getReleaseByTag(kit, tag) {
13889
13739
  try {
@@ -13902,40 +13752,19 @@ Need help? Run with: ck new --verbose`, 404);
13902
13752
  Possible causes:
13903
13753
  • Release version doesn't exist (check: ck versions --kit ${kit.name.toLowerCase()})
13904
13754
  • You don't have repository access
13905
- • Your token lacks the 'repo' scope
13906
13755
 
13907
13756
  Solutions:
13908
13757
  1. List available versions: ck versions --kit ${kit.name.toLowerCase()}
13909
13758
  2. Check email for GitHub invitation and accept it
13910
- 3. Use 'gh auth login' for automatic authentication
13911
- 4. Recreate token: https://github.com/settings/tokens/new?scopes=repo
13759
+ 3. Re-authenticate: gh auth login
13912
13760
 
13913
13761
  Need help? Run with: ck new --verbose`, 404);
13914
13762
  }
13915
- if (error?.status === 401) {
13916
- throw new GitHubError(`Authentication failed - token is invalid or expired.
13917
-
13918
- ` + `Solutions:
13919
- ` + ` 1. Use GitHub CLI (recommended): gh auth login
13920
- ` + ` 2. Create new token: https://github.com/settings/tokens/new?scopes=repo
13921
- ` + ` 3. Verify token format (should start with 'ghp_' or 'github_pat_')
13922
- ` + ` 4. Check token is set: echo $GITHUB_TOKEN
13923
-
13924
- ` + "Need help? Run with: ck new --verbose", 401);
13925
- }
13926
- if (error?.status === 403) {
13927
- throw new GitHubError(`Access forbidden - token lacks required permissions.
13928
-
13929
- ` + `Your token needs the 'repo' scope for private repositories.
13930
-
13931
- ` + `Solutions:
13932
- ` + ` 1. Use GitHub CLI (handles scopes automatically): gh auth login
13933
- ` + ` 2. Recreate token with 'repo' scope: https://github.com/settings/tokens/new?scopes=repo
13934
- ` + ` 3. Check existing token scopes: https://github.com/settings/tokens
13935
-
13936
- ` + "Need help? Run with: ck new --verbose", 403);
13937
- }
13938
- throw new GitHubError(`Failed to fetch release: ${error?.message || "Unknown error"}`, error?.status);
13763
+ return this.handleHttpError(error, {
13764
+ kit,
13765
+ operation: "fetch release",
13766
+ verboseFlag: "ck new --verbose"
13767
+ });
13939
13768
  }
13940
13769
  }
13941
13770
  async listReleases(kit, limit = 10) {
@@ -13949,40 +13778,11 @@ Need help? Run with: ck new --verbose`, 404);
13949
13778
  });
13950
13779
  return data.map((release) => GitHubReleaseSchema.parse(release));
13951
13780
  } catch (error) {
13952
- if (error?.status === 401) {
13953
- throw new GitHubError(`Authentication failed - token is invalid or expired.
13954
-
13955
- ` + `Solutions:
13956
- ` + ` 1. Use GitHub CLI (recommended): gh auth login
13957
- ` + ` 2. Create new token: https://github.com/settings/tokens/new?scopes=repo
13958
- ` + ` 3. Verify token format (should start with 'ghp_' or 'github_pat_')
13959
-
13960
- ` + "Need help? Run with: ck versions --verbose", 401);
13961
- }
13962
- if (error?.status === 403) {
13963
- throw new GitHubError(`Access forbidden - token lacks required permissions.
13964
-
13965
- ` + `Your token needs the 'repo' scope for private repositories.
13966
-
13967
- ` + `Solutions:
13968
- ` + ` 1. Use GitHub CLI (handles scopes automatically): gh auth login
13969
- ` + ` 2. Recreate token with 'repo' scope: https://github.com/settings/tokens/new?scopes=repo
13970
-
13971
- ` + "Need help? Run with: ck versions --verbose", 403);
13972
- }
13973
- if (error?.status === 404) {
13974
- throw new GitHubError(`Cannot access ${kit.name} repository.
13975
-
13976
- You may not have been added as a collaborator yet.
13977
-
13978
- Solutions:
13979
- 1. Check email for GitHub invitation and accept it
13980
- 2. Contact support to verify repository access
13981
- 3. Use 'gh auth login' for automatic authentication
13982
-
13983
- Need help? Run with: ck versions --verbose`, 404);
13984
- }
13985
- throw new GitHubError(`Failed to list releases: ${error?.message || "Unknown error"}`, error?.status);
13781
+ return this.handleHttpError(error, {
13782
+ kit,
13783
+ operation: "list releases",
13784
+ verboseFlag: "ck versions --verbose"
13785
+ });
13986
13786
  }
13987
13787
  }
13988
13788
  async checkAccess(kit) {
@@ -13999,51 +13799,31 @@ Need help? Run with: ck versions --verbose`, 404);
13999
13799
 
14000
13800
  Possible causes:
14001
13801
  • You haven't accepted the GitHub repository invitation
14002
- • Your token lacks the 'repo' scope (needs full private repo access)
14003
13802
  • You're not added as a collaborator yet
14004
- Token belongs to a different GitHub account
13803
+ You're logged into a different GitHub account
14005
13804
 
14006
13805
  Solutions:
14007
13806
  1. Check email for GitHub invitation and accept it
14008
- 2. Use 'gh auth login' for automatic authentication (recommended)
14009
- 3. Recreate token with 'repo' scope: https://github.com/settings/tokens/new?scopes=repo
14010
- 4. Verify you're using the correct GitHub account
14011
- 5. Wait 2-5 minutes after accepting invitation for permissions to sync
13807
+ 2. Re-authenticate: gh auth login
13808
+ 3. Verify you're using the correct GitHub account
13809
+ 4. Wait 2-5 minutes after accepting invitation for permissions to sync
14012
13810
 
14013
13811
  Need help? Run with: ck new --verbose`, 404);
14014
13812
  }
14015
- if (error?.status === 403) {
14016
- throw new GitHubError(`Access forbidden - token lacks required permissions.
14017
-
14018
- ` + `Your token needs the 'repo' scope for private repositories.
14019
-
14020
- ` + `Solutions:
14021
- ` + ` 1. Use GitHub CLI (handles scopes automatically): gh auth login
14022
- ` + ` 2. Recreate token with 'repo' scope: https://github.com/settings/tokens/new?scopes=repo
14023
- ` + ` 3. Check existing token scopes: https://github.com/settings/tokens
14024
-
14025
- ` + `Common mistake: Using 'public_repo' scope doesn't work for private repos.
14026
-
14027
- ` + "Need help? Run with: ck new --verbose", 403);
14028
- }
14029
- if (error?.status === 401) {
14030
- throw new GitHubError(`Authentication failed - token is invalid or expired.
14031
-
14032
- ` + `Solutions:
14033
- ` + ` 1. Use GitHub CLI (recommended): gh auth login
14034
- ` + ` 2. Create new token: https://github.com/settings/tokens/new?scopes=repo
14035
- ` + ` 3. Verify token format (should start with 'ghp_' or 'github_pat_')
14036
- ` + ` 4. Check token is set: echo $GITHUB_TOKEN
14037
-
14038
- ` + "Need help? Run with: ck new --verbose", 401);
14039
- }
14040
- throw new GitHubError(`Failed to check repository access: ${error?.message || "Unknown error"}`, error?.status);
13813
+ return this.handleHttpError(error, {
13814
+ kit,
13815
+ operation: "check repository access",
13816
+ verboseFlag: "ck new --verbose"
13817
+ });
14041
13818
  }
14042
13819
  }
14043
13820
  async listReleasesWithCache(kit, options = {}) {
14044
13821
  const { limit = 10, includePrereleases = false, forceRefresh = false } = options;
14045
13822
  const cacheKey = `${kit.repo}-${limit}-${includePrereleases}`;
14046
13823
  try {
13824
+ if (forceRefresh) {
13825
+ logger.debug("Bypassing cache (--refresh flag) - fetching from GitHub API");
13826
+ }
14047
13827
  if (!forceRefresh) {
14048
13828
  const cachedReleases = await this.releaseCache.get(cacheKey);
14049
13829
  if (cachedReleases) {
@@ -14161,18 +13941,18 @@ import { promisify } from "node:util";
14161
13941
  var execAsync = promisify(exec);
14162
13942
  var isCIEnvironment = process.env.CI === "true" || process.env.CI_SAFE_MODE === "true";
14163
13943
  function getOSInfo() {
14164
- const platform3 = process.platform;
13944
+ const platform2 = process.platform;
14165
13945
  const arch = process.arch;
14166
- const isWindows = platform3 === "win32";
14167
- const isMacOS = platform3 === "darwin";
14168
- const isLinux = platform3 === "linux";
13946
+ const isWindows = platform2 === "win32";
13947
+ const isMacOS = platform2 === "darwin";
13948
+ const isLinux = platform2 === "linux";
14169
13949
  const isWSL = isLinux && process.env.WSL_DISTRO_NAME !== undefined;
14170
- let details = `${platform3}-${arch}`;
13950
+ let details = `${platform2}-${arch}`;
14171
13951
  if (isWSL) {
14172
13952
  details += ` (WSL: ${process.env.WSL_DISTRO_NAME})`;
14173
13953
  }
14174
13954
  return {
14175
- platform: platform3,
13955
+ platform: platform2,
14176
13956
  arch,
14177
13957
  isWindows,
14178
13958
  isMacOS,
@@ -14449,68 +14229,40 @@ function checkEnvironmentVariables() {
14449
14229
  const githubToken = process.env.GITHUB_TOKEN;
14450
14230
  const ghToken = process.env.GH_TOKEN;
14451
14231
  if (githubToken || ghToken) {
14452
- const tokenToCheck = githubToken || ghToken;
14453
14232
  const tokenVar = githubToken ? "GITHUB_TOKEN" : "GH_TOKEN";
14454
- if (!tokenToCheck?.startsWith("ghp_") && !tokenToCheck?.startsWith("github_pat_")) {
14455
- return {
14456
- name: "Environment Variables",
14457
- status: "fail",
14458
- message: `${tokenVar} is set but has invalid format`,
14459
- details: "Token should start with 'ghp_' or 'github_pat_'",
14460
- suggestion: "Create new token: https://github.com/settings/tokens/new?scopes=repo"
14461
- };
14462
- }
14463
14233
  return {
14464
14234
  name: "Environment Variables",
14465
- status: "pass",
14466
- message: `${tokenVar} is set and has valid format`,
14467
- details: `Token: ${tokenToCheck.substring(0, 8)}...`
14235
+ status: "info",
14236
+ message: `${tokenVar} is set but PAT authentication is no longer supported`,
14237
+ details: "ClaudeKit now uses GitHub CLI exclusively for authentication",
14238
+ suggestion: "Run: gh auth login"
14468
14239
  };
14469
14240
  }
14470
14241
  return {
14471
14242
  name: "Environment Variables",
14472
14243
  status: "info",
14473
- message: "No GitHub token found in environment variables",
14474
- details: "GITHUB_TOKEN or GH_TOKEN not set",
14475
- suggestion: `Set token:
14476
- ` + ` • Unix/Mac: export GITHUB_TOKEN=ghp_xxx
14477
- ` + " • Windows: [System.Environment]::SetEnvironmentVariable('GITHUB_TOKEN', 'ghp_xxx', 'User')"
14244
+ message: "No GitHub token found in environment variables (expected)",
14245
+ details: "ClaudeKit uses GitHub CLI for authentication"
14478
14246
  };
14479
14247
  }
14480
14248
  async function checkAuthentication() {
14481
14249
  try {
14482
- const { token, method } = await AuthManager.getToken();
14483
- const methodLabels = {
14484
- "gh-cli": "GitHub CLI",
14485
- "env-var": "Environment Variable",
14486
- keychain: "OS Keychain",
14487
- prompt: "User Prompt"
14488
- };
14489
- if (!AuthManager.isValidTokenFormat(token)) {
14490
- return {
14491
- name: "Authentication",
14492
- status: "fail",
14493
- message: "Token has invalid format",
14494
- details: "Token should start with 'ghp_' or 'github_pat_'",
14495
- suggestion: "Create new token: https://github.com/settings/tokens/new?scopes=repo"
14496
- };
14497
- }
14250
+ const { token } = await AuthManager.getToken();
14498
14251
  return {
14499
14252
  name: "Authentication",
14500
14253
  status: "pass",
14501
- message: `Successfully authenticated via ${methodLabels[method]}`,
14254
+ message: "Successfully authenticated via GitHub CLI",
14502
14255
  details: `Token: ${token.substring(0, 8)}...`
14503
14256
  };
14504
14257
  } catch (error) {
14505
14258
  return {
14506
14259
  name: "Authentication",
14507
14260
  status: "fail",
14508
- message: "Failed to obtain authentication token",
14261
+ message: "GitHub CLI authentication required",
14509
14262
  details: error?.message || "Unknown error",
14510
- suggestion: `Options:
14511
- ` + ` 1. Use GitHub CLI: gh auth login
14512
- ` + ` 2. Set GITHUB_TOKEN environment variable
14513
- ` + " 3. Create token: https://github.com/settings/tokens/new?scopes=repo"
14263
+ suggestion: `To authenticate:
14264
+ ` + ` 1. Install GitHub CLI: https://cli.github.com
14265
+ ` + " 2. Run: gh auth login"
14514
14266
  };
14515
14267
  }
14516
14268
  }
@@ -14539,7 +14291,7 @@ async function checkRepositoryAccess(kit) {
14539
14291
  message: `Cannot access ${kitConfig.owner}/${kitConfig.repo}`,
14540
14292
  suggestion: `Solutions:
14541
14293
  ` + ` 1. Check email for GitHub invitation and accept it
14542
- ` + ` 2. Verify token has 'repo' scope (not just 'public_repo')
14294
+ ` + ` 2. Re-authenticate: gh auth login
14543
14295
  ` + ` 3. Wait 2-5 minutes after accepting invitation
14544
14296
  ` + " 4. Contact support if issue persists"
14545
14297
  };
@@ -14550,9 +14302,9 @@ async function checkRepositoryAccess(kit) {
14550
14302
  message: "Failed to check repository access",
14551
14303
  details: error?.message || "Unknown error",
14552
14304
  suggestion: `Possible causes:
14553
- ` + ` • Token lacks 'repo' scope
14554
14305
  ` + ` • You haven't been added as collaborator
14555
- ` + " • Network connectivity issues"
14306
+ ` + ` • Network connectivity issues
14307
+ ` + " • Try: gh auth login"
14556
14308
  };
14557
14309
  }
14558
14310
  }
@@ -14620,7 +14372,7 @@ function checkSystemInfo() {
14620
14372
 
14621
14373
  // src/commands/doctor.ts
14622
14374
  init_dist2();
14623
- import { existsSync as existsSync4 } from "node:fs";
14375
+ import { existsSync as existsSync3 } from "node:fs";
14624
14376
  import { join as join4 } from "node:path";
14625
14377
 
14626
14378
  // src/utils/claudekit-scanner.ts
@@ -14719,16 +14471,16 @@ import { promisify as promisify2 } from "node:util";
14719
14471
  init_logger();
14720
14472
  var execAsync2 = promisify2(exec2);
14721
14473
  async function detectOS() {
14722
- const platform3 = process.platform;
14723
- const info = { platform: platform3 };
14724
- if (platform3 === "darwin") {
14474
+ const platform2 = process.platform;
14475
+ const info = { platform: platform2 };
14476
+ if (platform2 === "darwin") {
14725
14477
  try {
14726
14478
  await execAsync2("which brew");
14727
14479
  info.hasHomebrew = true;
14728
14480
  } catch {
14729
14481
  info.hasHomebrew = false;
14730
14482
  }
14731
- } else if (platform3 === "linux") {
14483
+ } else if (platform2 === "linux") {
14732
14484
  try {
14733
14485
  if (fs.existsSync("/etc/os-release")) {
14734
14486
  const content = fs.readFileSync("/etc/os-release", "utf-8");
@@ -15000,14 +14752,14 @@ function getManualInstructions(dependency, osInfo) {
15000
14752
  init_environment();
15001
14753
  init_logger();
15002
14754
  function checkSkillsInstallation() {
15003
- const platform3 = process.platform;
15004
- const scriptName = platform3 === "win32" ? "install.ps1" : "install.sh";
14755
+ const platform2 = process.platform;
14756
+ const scriptName = platform2 === "win32" ? "install.ps1" : "install.sh";
15005
14757
  const globalSkillsDir = join4(PathResolver.getGlobalKitDir(), "skills");
15006
14758
  const globalScriptPath = join4(globalSkillsDir, scriptName);
15007
- const globalAvailable = existsSync4(globalScriptPath);
14759
+ const globalAvailable = existsSync3(globalScriptPath);
15008
14760
  const projectSkillsDir = join4(process.cwd(), ".claude", "skills");
15009
14761
  const projectScriptPath = join4(projectSkillsDir, scriptName);
15010
- const projectAvailable = existsSync4(projectScriptPath);
14762
+ const projectAvailable = existsSync3(projectScriptPath);
15011
14763
  return {
15012
14764
  global: {
15013
14765
  available: globalAvailable,
@@ -15279,7 +15031,7 @@ import { join as join22, resolve as resolve4 } from "node:path";
15279
15031
  // src/lib/commands-prefix.ts
15280
15032
  init_logger();
15281
15033
  var import_fs_extra3 = __toESM(require_lib(), 1);
15282
- import { lstat, mkdir as mkdir3, readdir as readdir2, stat as stat2 } from "node:fs/promises";
15034
+ import { lstat, mkdir as mkdir2, readdir as readdir2, stat as stat2 } from "node:fs/promises";
15283
15035
  import { join as join6 } from "node:path";
15284
15036
 
15285
15037
  // src/utils/manifest-writer.ts
@@ -15438,8 +15190,11 @@ class OwnershipChecker {
15438
15190
  const hash = createHash("sha256");
15439
15191
  const stream = createReadStream(filePath);
15440
15192
  stream.on("data", (chunk) => hash.update(chunk));
15441
- stream.on("end", () => resolve(hash.digest("hex")));
15193
+ stream.on("end", () => {
15194
+ resolve(hash.digest("hex"));
15195
+ });
15442
15196
  stream.on("error", (err) => {
15197
+ stream.destroy();
15443
15198
  reject(new Error(`Failed to calculate checksum for "${filePath}": ${err.message}`));
15444
15199
  });
15445
15200
  });
@@ -15683,9 +15438,9 @@ class CommandsPrefix {
15683
15438
  }
15684
15439
  await import_fs_extra3.copy(commandsDir, backupDir);
15685
15440
  logger.verbose("Created backup of commands directory");
15686
- await mkdir3(tempDir, { recursive: true });
15441
+ await mkdir2(tempDir, { recursive: true });
15687
15442
  const ckDir = join6(tempDir, "ck");
15688
- await mkdir3(ckDir, { recursive: true });
15443
+ await mkdir2(ckDir, { recursive: true });
15689
15444
  let processedCount = 0;
15690
15445
  for (const entry of entries) {
15691
15446
  const sourcePath = join6(commandsDir, entry);
@@ -15959,7 +15714,7 @@ var import_ignore = __toESM(require_ignore(), 1);
15959
15714
  import { Buffer as Buffer3 } from "node:buffer";
15960
15715
  import { execFile } from "node:child_process";
15961
15716
  import { createWriteStream as createWriteStream2 } from "node:fs";
15962
- import { mkdir as mkdir5 } from "node:fs/promises";
15717
+ import { mkdir as mkdir4 } from "node:fs/promises";
15963
15718
  import { tmpdir } from "node:os";
15964
15719
  import { join as join8, relative as relative2, resolve } from "node:path";
15965
15720
  import { TextDecoder } from "node:util";
@@ -19260,8 +19015,8 @@ class Minipass3 extends EventEmitter4 {
19260
19015
  }
19261
19016
 
19262
19017
  // node_modules/tar/dist/esm/normalize-windows-path.js
19263
- var platform3 = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform;
19264
- var normalizeWindowsPath = platform3 !== "win32" ? (p) => p : (p) => p && p.replace(/\\/g, "/");
19018
+ var platform2 = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform;
19019
+ var normalizeWindowsPath = platform2 !== "win32" ? (p) => p : (p) => p && p.replace(/\\/g, "/");
19265
19020
 
19266
19021
  // node_modules/tar/dist/esm/read-entry.js
19267
19022
  class ReadEntry extends Minipass3 {
@@ -21459,8 +21214,8 @@ import path6 from "node:path";
21459
21214
 
21460
21215
  // node_modules/tar/dist/esm/get-write-flag.js
21461
21216
  import fs6 from "fs";
21462
- var platform4 = process.env.__FAKE_PLATFORM__ || process.platform;
21463
- var isWindows2 = platform4 === "win32";
21217
+ var platform3 = process.env.__FAKE_PLATFORM__ || process.platform;
21218
+ var isWindows2 = platform3 === "win32";
21464
21219
  var { O_CREAT, O_TRUNC, O_WRONLY } = fs6.constants;
21465
21220
  var UV_FS_O_FILEMAP = Number(process.env.__FAKE_FS_O_FILENAME__) || fs6.constants.UV_FS_O_FILEMAP || 0;
21466
21221
  var fMapEnabled = isWindows2 && !!UV_FS_O_FILEMAP;
@@ -21591,7 +21346,7 @@ var checkCwd = (dir, cb) => {
21591
21346
  cb(er);
21592
21347
  });
21593
21348
  };
21594
- var mkdir4 = (dir, opt, cb) => {
21349
+ var mkdir3 = (dir, opt, cb) => {
21595
21350
  dir = normalizeWindowsPath(dir);
21596
21351
  const umask = opt.umask ?? 18;
21597
21352
  const mode = opt.mode | 448;
@@ -21751,8 +21506,8 @@ var normalizeUnicode = (s) => {
21751
21506
  };
21752
21507
 
21753
21508
  // node_modules/tar/dist/esm/path-reservations.js
21754
- var platform5 = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform;
21755
- var isWindows3 = platform5 === "win32";
21509
+ var platform4 = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform;
21510
+ var isWindows3 = platform4 === "win32";
21756
21511
  var getDirs = (path6) => {
21757
21512
  const dirs = path6.split("/").slice(0, -1).reduce((set, path7) => {
21758
21513
  const s = set[set.length - 1];
@@ -21898,8 +21653,8 @@ var DOCHOWN = Symbol("doChown");
21898
21653
  var UID = Symbol("uid");
21899
21654
  var GID = Symbol("gid");
21900
21655
  var CHECKED_CWD = Symbol("checkedCwd");
21901
- var platform6 = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform;
21902
- var isWindows4 = platform6 === "win32";
21656
+ var platform5 = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform;
21657
+ var isWindows4 = platform5 === "win32";
21903
21658
  var DEFAULT_MAX_DEPTH = 1024;
21904
21659
  var unlinkFile = (path7, cb) => {
21905
21660
  if (!isWindows4) {
@@ -22114,7 +21869,7 @@ class Unpack extends Parser {
22114
21869
  }
22115
21870
  }
22116
21871
  [MKDIR](dir, mode, cb) {
22117
- mkdir4(normalizeWindowsPath(dir), {
21872
+ mkdir3(normalizeWindowsPath(dir), {
22118
21873
  uid: this.uid,
22119
21874
  gid: this.gid,
22120
21875
  processUid: this.processUid,
@@ -25931,7 +25686,7 @@ class DownloadManager {
25931
25686
  async downloadAsset(asset, destDir) {
25932
25687
  try {
25933
25688
  const destPath = join8(destDir, asset.name);
25934
- await mkdir5(destDir, { recursive: true });
25689
+ await mkdir4(destDir, { recursive: true });
25935
25690
  logger.info(`Downloading ${asset.name} (${this.formatBytes(asset.size)})...`);
25936
25691
  const progressBar = new import_cli_progress.default.SingleBar({
25937
25692
  format: "Progress |{bar}| {percentage}% | {value}/{total} MB",
@@ -25981,7 +25736,7 @@ class DownloadManager {
25981
25736
  async downloadFile(params) {
25982
25737
  const { url, name: name2, size, destDir, token } = params;
25983
25738
  const destPath = join8(destDir, name2);
25984
- await mkdir5(destDir, { recursive: true });
25739
+ await mkdir4(destDir, { recursive: true });
25985
25740
  logger.info(`Downloading ${name2}${size ? ` (${this.formatBytes(size)})` : ""}...`);
25986
25741
  const headers = {};
25987
25742
  if (token && url.includes("api.github.com")) {
@@ -26045,7 +25800,7 @@ class DownloadManager {
26045
25800
  try {
26046
25801
  this.resetExtractionSize();
26047
25802
  const detectedType = archiveType || this.detectArchiveType(archivePath);
26048
- await mkdir5(destDir, { recursive: true });
25803
+ await mkdir4(destDir, { recursive: true });
26049
25804
  if (detectedType === "tar.gz") {
26050
25805
  await this.extractTarGz(archivePath, destDir);
26051
25806
  } else if (detectedType === "zip") {
@@ -26298,7 +26053,7 @@ class DownloadManager {
26298
26053
  const timestamp = Date.now();
26299
26054
  const primaryTempDir = join8(tmpdir(), `claudekit-${timestamp}`);
26300
26055
  try {
26301
- await mkdir5(primaryTempDir, { recursive: true });
26056
+ await mkdir4(primaryTempDir, { recursive: true });
26302
26057
  logger.debug(`Created temp directory: ${primaryTempDir}`);
26303
26058
  return primaryTempDir;
26304
26059
  } catch (primaryError) {
@@ -26314,7 +26069,7 @@ Solutions:
26314
26069
  }
26315
26070
  const fallbackTempDir = join8(homeDir, ".claudekit", "tmp", `claudekit-${timestamp}`);
26316
26071
  try {
26317
- await mkdir5(fallbackTempDir, { recursive: true });
26072
+ await mkdir4(fallbackTempDir, { recursive: true });
26318
26073
  logger.debug(`Created temp directory (fallback): ${fallbackTempDir}`);
26319
26074
  logger.warning(`Using fallback temp directory: ${fallbackTempDir}
26320
26075
  (OS temp directory was not accessible)`);
@@ -26383,10 +26138,10 @@ async function handleFreshInstallation(claudeDir, prompts) {
26383
26138
 
26384
26139
  // src/lib/global-path-transformer.ts
26385
26140
  init_logger();
26386
- import { readFile as readFile5, readdir as readdir3, writeFile as writeFile4 } from "node:fs/promises";
26387
- import { platform as platform7 } from "node:os";
26141
+ import { readFile as readFile4, readdir as readdir3, writeFile as writeFile3 } from "node:fs/promises";
26142
+ import { platform as platform6 } from "node:os";
26388
26143
  import { extname, join as join10 } from "node:path";
26389
- var IS_WINDOWS = platform7() === "win32";
26144
+ var IS_WINDOWS = platform6() === "win32";
26390
26145
  var HOME_PREFIX = IS_WINDOWS ? "%USERPROFILE%" : "$HOME";
26391
26146
  function getHomeDirPrefix() {
26392
26147
  return HOME_PREFIX;
@@ -26485,10 +26240,10 @@ async function transformPathsForGlobalInstall(directory, options = {}) {
26485
26240
  await processDirectory(fullPath);
26486
26241
  } else if (entry.isFile() && shouldTransformFile(entry.name)) {
26487
26242
  try {
26488
- const content = await readFile5(fullPath, "utf-8");
26243
+ const content = await readFile4(fullPath, "utf-8");
26489
26244
  const { transformed, changes } = transformContent(content);
26490
26245
  if (changes > 0) {
26491
- await writeFile4(fullPath, transformed, "utf-8");
26246
+ await writeFile3(fullPath, transformed, "utf-8");
26492
26247
  filesTransformed++;
26493
26248
  totalChanges += changes;
26494
26249
  if (options.verbose) {
@@ -28523,7 +28278,8 @@ class VersionSelector {
28523
28278
  includePrereleases = false,
28524
28279
  limit = 10,
28525
28280
  defaultValue,
28526
- allowManualEntry = false
28281
+ allowManualEntry = false,
28282
+ forceRefresh = false
28527
28283
  } = options;
28528
28284
  try {
28529
28285
  const loadingSpinner = de();
@@ -28531,7 +28287,7 @@ class VersionSelector {
28531
28287
  const releases = await this.githubClient.listReleasesWithCache(kit, {
28532
28288
  limit: limit * 2,
28533
28289
  includePrereleases,
28534
- forceRefresh: false
28290
+ forceRefresh
28535
28291
  });
28536
28292
  loadingSpinner.stop();
28537
28293
  if (releases.length === 0) {
@@ -28677,12 +28433,12 @@ This could be due to:
28677
28433
  allowManualEntry
28678
28434
  });
28679
28435
  }
28680
- async getLatestVersion(kit, includePrereleases = false) {
28436
+ async getLatestVersion(kit, includePrereleases = false, forceRefresh = false) {
28681
28437
  try {
28682
28438
  const releases = await this.githubClient.listReleasesWithCache(kit, {
28683
28439
  limit: 5,
28684
28440
  includePrereleases,
28685
- forceRefresh: false
28441
+ forceRefresh
28686
28442
  });
28687
28443
  if (releases.length === 0) {
28688
28444
  return null;
@@ -29062,7 +28818,7 @@ init_types2();
29062
28818
  init_logger();
29063
28819
  var import_fs_extra10 = __toESM(require_lib(), 1);
29064
28820
  import { createHash as createHash2 } from "node:crypto";
29065
- import { readFile as readFile9, readdir as readdir6, writeFile as writeFile8 } from "node:fs/promises";
28821
+ import { readFile as readFile8, readdir as readdir6, writeFile as writeFile7 } from "node:fs/promises";
29066
28822
  import { join as join16, relative as relative5 } from "node:path";
29067
28823
 
29068
28824
  class SkillsManifestManager {
@@ -29086,7 +28842,7 @@ class SkillsManifestManager {
29086
28842
  }
29087
28843
  static async writeManifest(skillsDir, manifest) {
29088
28844
  const manifestPath = join16(skillsDir, SkillsManifestManager.MANIFEST_FILENAME);
29089
- await writeFile8(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
28845
+ await writeFile7(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
29090
28846
  logger.debug(`Wrote manifest to: ${manifestPath}`);
29091
28847
  }
29092
28848
  static async readManifest(skillsDir) {
@@ -29096,7 +28852,7 @@ class SkillsManifestManager {
29096
28852
  return null;
29097
28853
  }
29098
28854
  try {
29099
- const content = await readFile9(manifestPath, "utf-8");
28855
+ const content = await readFile8(manifestPath, "utf-8");
29100
28856
  const data = JSON.parse(content);
29101
28857
  const manifest = SkillsManifestSchema.parse(data);
29102
28858
  logger.debug(`Read manifest from: ${manifestPath}`);
@@ -29168,7 +28924,7 @@ class SkillsManifestManager {
29168
28924
  files.sort();
29169
28925
  for (const file of files) {
29170
28926
  const relativePath = relative5(dirPath, file);
29171
- const content = await readFile9(file);
28927
+ const content = await readFile8(file);
29172
28928
  hash.update(relativePath);
29173
28929
  hash.update(content);
29174
28930
  }
@@ -29464,14 +29220,14 @@ class SkillsMigrationDetector {
29464
29220
  init_types2();
29465
29221
  init_logger();
29466
29222
  var import_fs_extra14 = __toESM(require_lib(), 1);
29467
- import { copyFile as copyFile2, mkdir as mkdir7, readdir as readdir10, rm as rm2 } from "node:fs/promises";
29223
+ import { copyFile as copyFile2, mkdir as mkdir6, readdir as readdir10, rm as rm2 } from "node:fs/promises";
29468
29224
  import { join as join20 } from "node:path";
29469
29225
 
29470
29226
  // src/lib/skills-backup-manager.ts
29471
29227
  init_types2();
29472
29228
  init_logger();
29473
29229
  var import_fs_extra12 = __toESM(require_lib(), 1);
29474
- import { copyFile, mkdir as mkdir6, readdir as readdir8, rm, stat as stat4 } from "node:fs/promises";
29230
+ import { copyFile, mkdir as mkdir5, readdir as readdir8, rm, stat as stat4 } from "node:fs/promises";
29475
29231
  import { basename as basename2, join as join18, normalize as normalize2 } from "node:path";
29476
29232
  function validatePath2(path9, paramName) {
29477
29233
  if (!path9 || typeof path9 !== "string") {
@@ -29501,7 +29257,7 @@ class SkillsBackupManager {
29501
29257
  const backupDir = parentDir ? join18(parentDir, backupDirName) : join18(skillsDir, "..", backupDirName);
29502
29258
  logger.info(`Creating backup at: ${backupDir}`);
29503
29259
  try {
29504
- await mkdir6(backupDir, { recursive: true });
29260
+ await mkdir5(backupDir, { recursive: true });
29505
29261
  await SkillsBackupManager.copyDirectory(skillsDir, backupDir);
29506
29262
  logger.success("Backup created successfully");
29507
29263
  return backupDir;
@@ -29523,7 +29279,7 @@ class SkillsBackupManager {
29523
29279
  if (await import_fs_extra12.pathExists(targetDir)) {
29524
29280
  await rm(targetDir, { recursive: true, force: true });
29525
29281
  }
29526
- await mkdir6(targetDir, { recursive: true });
29282
+ await mkdir5(targetDir, { recursive: true });
29527
29283
  await SkillsBackupManager.copyDirectory(backupDir, targetDir);
29528
29284
  logger.success("Backup restored successfully");
29529
29285
  } catch (error2) {
@@ -29583,7 +29339,7 @@ class SkillsBackupManager {
29583
29339
  continue;
29584
29340
  }
29585
29341
  if (entry.isDirectory()) {
29586
- await mkdir6(destPath, { recursive: true });
29342
+ await mkdir5(destPath, { recursive: true });
29587
29343
  await SkillsBackupManager.copyDirectory(sourcePath, destPath);
29588
29344
  } else if (entry.isFile()) {
29589
29345
  await copyFile(sourcePath, destPath);
@@ -29624,7 +29380,7 @@ init_logger();
29624
29380
  var import_fs_extra13 = __toESM(require_lib(), 1);
29625
29381
  import { createHash as createHash3 } from "node:crypto";
29626
29382
  import { createReadStream as createReadStream2 } from "node:fs";
29627
- import { readFile as readFile10, readdir as readdir9 } from "node:fs/promises";
29383
+ import { readFile as readFile9, readdir as readdir9 } from "node:fs/promises";
29628
29384
  import { join as join19, normalize as normalize3, relative as relative6 } from "node:path";
29629
29385
  function validatePath3(path9, paramName) {
29630
29386
  if (!path9 || typeof path9 !== "string") {
@@ -29837,8 +29593,13 @@ class SkillsCustomizationScanner {
29837
29593
  const hash = createHash3("sha256");
29838
29594
  const stream = createReadStream2(filePath);
29839
29595
  stream.on("data", (chunk) => hash.update(chunk));
29840
- stream.on("end", () => resolve2(hash.digest("hex")));
29841
- stream.on("error", (error2) => reject(error2));
29596
+ stream.on("end", () => {
29597
+ resolve2(hash.digest("hex"));
29598
+ });
29599
+ stream.on("error", (error2) => {
29600
+ stream.destroy();
29601
+ reject(error2);
29602
+ });
29842
29603
  });
29843
29604
  }
29844
29605
  static async hashDirectory(dirPath) {
@@ -29847,7 +29608,7 @@ class SkillsCustomizationScanner {
29847
29608
  files.sort();
29848
29609
  for (const file of files) {
29849
29610
  const relativePath = relative6(dirPath, file);
29850
- const content = await readFile10(file);
29611
+ const content = await readFile9(file);
29851
29612
  hash.update(relativePath);
29852
29613
  hash.update(content);
29853
29614
  }
@@ -30110,7 +29871,7 @@ class SkillsMigrator {
30110
29871
  const preserved = [];
30111
29872
  const errors2 = [];
30112
29873
  const tempDir = join20(currentSkillsDir, "..", ".skills-migration-temp");
30113
- await mkdir7(tempDir, { recursive: true });
29874
+ await mkdir6(tempDir, { recursive: true });
30114
29875
  try {
30115
29876
  for (const mapping of mappings) {
30116
29877
  try {
@@ -30132,7 +29893,7 @@ class SkillsMigrator {
30132
29893
  const category = mapping.category;
30133
29894
  const targetPath = category ? join20(tempDir, category, skillName) : join20(tempDir, skillName);
30134
29895
  if (category) {
30135
- await mkdir7(join20(tempDir, category), { recursive: true });
29896
+ await mkdir6(join20(tempDir, category), { recursive: true });
30136
29897
  }
30137
29898
  await SkillsMigrator.copySkillDirectory(currentSkillPath, targetPath);
30138
29899
  migrated.push(skillName);
@@ -30151,7 +29912,7 @@ class SkillsMigrator {
30151
29912
  }
30152
29913
  }
30153
29914
  await rm2(currentSkillsDir, { recursive: true, force: true });
30154
- await mkdir7(currentSkillsDir, { recursive: true });
29915
+ await mkdir6(currentSkillsDir, { recursive: true });
30155
29916
  await SkillsMigrator.copySkillDirectory(tempDir, currentSkillsDir);
30156
29917
  await rm2(tempDir, { recursive: true, force: true });
30157
29918
  return { migrated, preserved, errors: errors2 };
@@ -30163,7 +29924,7 @@ class SkillsMigrator {
30163
29924
  }
30164
29925
  }
30165
29926
  static async copySkillDirectory(sourceDir, destDir) {
30166
- await mkdir7(destDir, { recursive: true });
29927
+ await mkdir6(destDir, { recursive: true });
30167
29928
  const entries = await readdir10(sourceDir, { withFileTypes: true });
30168
29929
  for (const entry of entries) {
30169
29930
  const sourcePath = join20(sourceDir, entry.name);
@@ -30182,6 +29943,83 @@ class SkillsMigrator {
30182
29943
 
30183
29944
  // src/commands/init.ts
30184
29945
  init_types2();
29946
+
29947
+ // src/utils/config.ts
29948
+ init_types2();
29949
+ init_logger();
29950
+ import { existsSync as existsSync4 } from "node:fs";
29951
+ import { mkdir as mkdir7, readFile as readFile10, writeFile as writeFile8 } from "node:fs/promises";
29952
+ import { chmod } from "node:fs/promises";
29953
+ import { platform as platform7 } from "node:os";
29954
+ class ConfigManager {
29955
+ static config = null;
29956
+ static globalFlag = false;
29957
+ static setGlobalFlag(global3) {
29958
+ ConfigManager.globalFlag = global3;
29959
+ ConfigManager.config = null;
29960
+ }
29961
+ static getGlobalFlag() {
29962
+ return ConfigManager.globalFlag;
29963
+ }
29964
+ static async load() {
29965
+ if (ConfigManager.config) {
29966
+ return ConfigManager.config;
29967
+ }
29968
+ const configFile = PathResolver.getConfigFile(ConfigManager.globalFlag);
29969
+ try {
29970
+ if (existsSync4(configFile)) {
29971
+ const content = await readFile10(configFile, "utf-8");
29972
+ const data = JSON.parse(content);
29973
+ ConfigManager.config = ConfigSchema.parse(data);
29974
+ logger.debug(`Config loaded from ${configFile}`);
29975
+ return ConfigManager.config;
29976
+ }
29977
+ } catch (error2) {
29978
+ logger.warning(`Failed to load config: ${error2 instanceof Error ? error2.message : "Unknown error"}`);
29979
+ }
29980
+ ConfigManager.config = { defaults: {} };
29981
+ return ConfigManager.config;
29982
+ }
29983
+ static async save(config) {
29984
+ try {
29985
+ const validConfig = ConfigSchema.parse(config);
29986
+ const configDir = PathResolver.getConfigDir(ConfigManager.globalFlag);
29987
+ const configFile = PathResolver.getConfigFile(ConfigManager.globalFlag);
29988
+ if (!existsSync4(configDir)) {
29989
+ await mkdir7(configDir, { recursive: true });
29990
+ if (platform7() !== "win32") {
29991
+ await chmod(configDir, 448);
29992
+ }
29993
+ }
29994
+ await writeFile8(configFile, JSON.stringify(validConfig, null, 2), "utf-8");
29995
+ if (platform7() !== "win32") {
29996
+ await chmod(configFile, 384);
29997
+ }
29998
+ ConfigManager.config = validConfig;
29999
+ logger.debug(`Config saved to ${configFile}`);
30000
+ } catch (error2) {
30001
+ throw new Error(`Failed to save config: ${error2 instanceof Error ? error2.message : "Unknown error"}`);
30002
+ }
30003
+ }
30004
+ static async get() {
30005
+ return ConfigManager.load();
30006
+ }
30007
+ static async set(key, value) {
30008
+ const config = await ConfigManager.load();
30009
+ const keys = key.split(".");
30010
+ let current = config;
30011
+ for (let i = 0;i < keys.length - 1; i++) {
30012
+ if (!(keys[i] in current)) {
30013
+ current[keys[i]] = {};
30014
+ }
30015
+ current = current[keys[i]];
30016
+ }
30017
+ current[keys[keys.length - 1]] = value;
30018
+ await ConfigManager.save(config);
30019
+ }
30020
+ }
30021
+
30022
+ // src/commands/init.ts
30185
30023
  init_environment();
30186
30024
 
30187
30025
  // src/utils/file-scanner.ts
@@ -30349,7 +30187,8 @@ async function initCommand(options) {
30349
30187
  kit: kitConfig,
30350
30188
  includePrereleases: validOptions.beta,
30351
30189
  limit: 10,
30352
- allowManualEntry: true
30190
+ allowManualEntry: true,
30191
+ forceRefresh: validOptions.refresh
30353
30192
  });
30354
30193
  if (!versionResult) {
30355
30194
  logger.warning("Version selection cancelled by user");
@@ -30661,7 +30500,8 @@ async function newCommand(options) {
30661
30500
  kit: kitConfig,
30662
30501
  includePrereleases: validOptions.beta,
30663
30502
  limit: 10,
30664
- allowManualEntry: true
30503
+ allowManualEntry: true,
30504
+ forceRefresh: validOptions.refresh
30665
30505
  });
30666
30506
  if (!versionResult) {
30667
30507
  logger.warning("Version selection cancelled by user");
@@ -31060,7 +30900,7 @@ import { promisify as promisify5 } from "node:util";
31060
30900
  // package.json
31061
30901
  var package_default2 = {
31062
30902
  name: "claudekit-cli",
31063
- version: "2.5.2",
30903
+ version: "3.0.0",
31064
30904
  description: "CLI tool for bootstrapping and updating ClaudeKit projects",
31065
30905
  type: "module",
31066
30906
  repository: {
@@ -32023,7 +31863,8 @@ var NewCommandOptionsSchema2 = exports_external.object({
32023
31863
  installSkills: exports_external.boolean().default(false),
32024
31864
  prefix: exports_external.boolean().default(false),
32025
31865
  beta: exports_external.boolean().default(false),
32026
- dryRun: exports_external.boolean().default(false)
31866
+ dryRun: exports_external.boolean().default(false),
31867
+ refresh: exports_external.boolean().default(false)
32027
31868
  });
32028
31869
  var UpdateCommandOptionsSchema2 = exports_external.object({
32029
31870
  dir: exports_external.string().default("."),
@@ -32038,7 +31879,8 @@ var UpdateCommandOptionsSchema2 = exports_external.object({
32038
31879
  beta: exports_external.boolean().default(false),
32039
31880
  dryRun: exports_external.boolean().default(false),
32040
31881
  forceOverwrite: exports_external.boolean().default(false),
32041
- skipSetup: exports_external.boolean().default(false)
31882
+ skipSetup: exports_external.boolean().default(false),
31883
+ refresh: exports_external.boolean().default(false)
32042
31884
  });
32043
31885
  var VersionCommandOptionsSchema2 = exports_external.object({
32044
31886
  kit: KitType2.optional(),
@@ -32076,9 +31918,6 @@ var MetadataSchema2 = exports_external.object({
32076
31918
  files: exports_external.array(TrackedFileSchema2).optional()
32077
31919
  });
32078
31920
  var ConfigSchema2 = exports_external.object({
32079
- github: exports_external.object({
32080
- token: exports_external.string().optional()
32081
- }).optional(),
32082
31921
  defaults: exports_external.object({
32083
31922
  kit: KitType2.optional(),
32084
31923
  dir: exports_external.string().optional()
@@ -32412,13 +32251,13 @@ async function displayVersion() {
32412
32251
  var cli = cac("ck");
32413
32252
  cli.option("--verbose", "Enable verbose logging for debugging");
32414
32253
  cli.option("--log-file <path>", "Write logs to file");
32415
- cli.command("new", "Bootstrap a new ClaudeKit project (with interactive version selection)").option("--dir <dir>", "Target directory (default: .)").option("--kit <kit>", "Kit to use (engineer, marketing)").option("-r, --release <version>", "Skip version selection, use specific version (e.g., latest, v1.0.0)").option("--force", "Overwrite existing files without confirmation").option("--exclude <pattern>", "Exclude files matching glob pattern (can be used multiple times)").option("--opencode", "Install OpenCode CLI package (non-interactive mode)").option("--gemini", "Install Google Gemini CLI package (non-interactive mode)").option("--install-skills", "Install skills dependencies (non-interactive mode)").option("--prefix", "Add /ck: prefix to all slash commands by moving them to commands/ck/ subdirectory").option("--beta", "Show beta versions in selection prompt").action(async (options) => {
32254
+ cli.command("new", "Bootstrap a new ClaudeKit project (with interactive version selection)").option("--dir <dir>", "Target directory (default: .)").option("--kit <kit>", "Kit to use (engineer, marketing)").option("-r, --release <version>", "Skip version selection, use specific version (e.g., latest, v1.0.0)").option("--force", "Overwrite existing files without confirmation").option("--exclude <pattern>", "Exclude files matching glob pattern (can be used multiple times)").option("--opencode", "Install OpenCode CLI package (non-interactive mode)").option("--gemini", "Install Google Gemini CLI package (non-interactive mode)").option("--install-skills", "Install skills dependencies (non-interactive mode)").option("--prefix", "Add /ck: prefix to all slash commands by moving them to commands/ck/ subdirectory").option("--beta", "Show beta versions in selection prompt").option("--refresh", "Bypass release cache to fetch latest versions from GitHub").action(async (options) => {
32416
32255
  if (options.exclude && !Array.isArray(options.exclude)) {
32417
32256
  options.exclude = [options.exclude];
32418
32257
  }
32419
32258
  await newCommand(options);
32420
32259
  });
32421
- cli.command("init", "Initialize or update ClaudeKit project (with interactive version selection)").option("--dir <dir>", "Target directory (default: .)").option("--kit <kit>", "Kit to use (engineer, marketing)").option("-r, --release <version>", "Skip version selection, use specific version (e.g., latest, v1.0.0)").option("--exclude <pattern>", "Exclude files matching glob pattern (can be used multiple times)").option("--only <pattern>", "Include only files matching glob pattern (can be used multiple times)").option("-g, --global", "Use platform-specific user configuration directory").option("--fresh", "Completely remove .claude directory before downloading (requires confirmation)").option("--install-skills", "Install skills dependencies (non-interactive mode)").option("--prefix", "Add /ck: prefix to all slash commands by moving them to commands/ck/ subdirectory").option("--beta", "Show beta versions in selection prompt").option("--dry-run", "Preview changes without applying them (requires --prefix)").option("--force-overwrite", "Override ownership protections and delete user-modified files (requires --prefix)").option("--skip-setup", "Skip interactive configuration wizard").action(async (options) => {
32260
+ cli.command("init", "Initialize or update ClaudeKit project (with interactive version selection)").option("--dir <dir>", "Target directory (default: .)").option("--kit <kit>", "Kit to use (engineer, marketing)").option("-r, --release <version>", "Skip version selection, use specific version (e.g., latest, v1.0.0)").option("--exclude <pattern>", "Exclude files matching glob pattern (can be used multiple times)").option("--only <pattern>", "Include only files matching glob pattern (can be used multiple times)").option("-g, --global", "Use platform-specific user configuration directory").option("--fresh", "Completely remove .claude directory before downloading (requires confirmation)").option("--install-skills", "Install skills dependencies (non-interactive mode)").option("--prefix", "Add /ck: prefix to all slash commands by moving them to commands/ck/ subdirectory").option("--beta", "Show beta versions in selection prompt").option("--refresh", "Bypass release cache to fetch latest versions from GitHub").option("--dry-run", "Preview changes without applying them (requires --prefix)").option("--force-overwrite", "Override ownership protections and delete user-modified files (requires --prefix)").option("--skip-setup", "Skip interactive configuration wizard").action(async (options) => {
32422
32261
  if (options.exclude && !Array.isArray(options.exclude)) {
32423
32262
  options.exclude = [options.exclude];
32424
32263
  }