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.
- package/bin/ck.js +4 -2
- package/dist/index.js +354 -515
- 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
|
|
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 (
|
|
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 =
|
|
5926
|
-
function
|
|
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 =
|
|
5943
|
-
function
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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:
|
|
7269
|
+
readFile: readFile2,
|
|
7271
7270
|
readFileSync,
|
|
7272
|
-
writeFile:
|
|
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
|
|
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
|
|
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
|
-
|
|
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: "
|
|
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
|
-
|
|
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 {
|
|
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 (!
|
|
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
|
|
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
|
|
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
|
|
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 (
|
|
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
|
-
|
|
13844
|
-
|
|
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
|
-
|
|
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
|
-
|
|
13853
|
-
|
|
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:
|
|
13859
|
-
|
|
13860
|
-
|
|
13861
|
-
|
|
13709
|
+
Need help? Run with: ${verboseFlag}`, 401);
|
|
13710
|
+
}
|
|
13711
|
+
if (error?.status === 403) {
|
|
13712
|
+
throw new GitHubError(`Access forbidden.
|
|
13862
13713
|
|
|
13863
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
13877
|
-
|
|
13878
|
-
|
|
13879
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
13916
|
-
|
|
13917
|
-
|
|
13918
|
-
|
|
13919
|
-
|
|
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
|
-
|
|
13953
|
-
|
|
13954
|
-
|
|
13955
|
-
|
|
13956
|
-
|
|
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
|
-
•
|
|
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.
|
|
14009
|
-
3.
|
|
14010
|
-
4.
|
|
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
|
-
|
|
14016
|
-
|
|
14017
|
-
|
|
14018
|
-
|
|
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
|
|
13944
|
+
const platform2 = process.platform;
|
|
14165
13945
|
const arch = process.arch;
|
|
14166
|
-
const isWindows =
|
|
14167
|
-
const isMacOS =
|
|
14168
|
-
const isLinux =
|
|
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 = `${
|
|
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:
|
|
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: "
|
|
14466
|
-
message: `${tokenVar} is set
|
|
14467
|
-
details:
|
|
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: "
|
|
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
|
|
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:
|
|
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: "
|
|
14261
|
+
message: "GitHub CLI authentication required",
|
|
14509
14262
|
details: error?.message || "Unknown error",
|
|
14510
|
-
suggestion: `
|
|
14511
|
-
` + ` 1.
|
|
14512
|
-
` +
|
|
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.
|
|
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
|
-
` +
|
|
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
|
|
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
|
|
14723
|
-
const info = { platform:
|
|
14724
|
-
if (
|
|
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 (
|
|
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
|
|
15004
|
-
const scriptName =
|
|
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 =
|
|
14759
|
+
const globalAvailable = existsSync3(globalScriptPath);
|
|
15008
14760
|
const projectSkillsDir = join4(process.cwd(), ".claude", "skills");
|
|
15009
14761
|
const projectScriptPath = join4(projectSkillsDir, scriptName);
|
|
15010
|
-
const projectAvailable =
|
|
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
|
|
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", () =>
|
|
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
|
|
15441
|
+
await mkdir2(tempDir, { recursive: true });
|
|
15687
15442
|
const ckDir = join6(tempDir, "ck");
|
|
15688
|
-
await
|
|
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
|
|
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
|
|
19264
|
-
var normalizeWindowsPath =
|
|
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
|
|
21463
|
-
var isWindows2 =
|
|
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
|
|
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
|
|
21755
|
-
var isWindows3 =
|
|
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
|
|
21902
|
-
var isWindows4 =
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
26387
|
-
import { platform as
|
|
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 =
|
|
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
|
|
26243
|
+
const content = await readFile4(fullPath, "utf-8");
|
|
26489
26244
|
const { transformed, changes } = transformContent(content);
|
|
26490
26245
|
if (changes > 0) {
|
|
26491
|
-
await
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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", () =>
|
|
29841
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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: "
|
|
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
|
}
|