claudekit-cli 3.25.0 → 3.26.1
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/dist/index.js +250 -77
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6297,7 +6297,7 @@ var require_jsonfile = __commonJS((exports, module) => {
|
|
|
6297
6297
|
return obj;
|
|
6298
6298
|
}
|
|
6299
6299
|
var readFile = universalify.fromPromise(_readFile);
|
|
6300
|
-
function
|
|
6300
|
+
function readFileSync4(file, options = {}) {
|
|
6301
6301
|
if (typeof options === "string") {
|
|
6302
6302
|
options = { encoding: options };
|
|
6303
6303
|
}
|
|
@@ -6329,7 +6329,7 @@ var require_jsonfile = __commonJS((exports, module) => {
|
|
|
6329
6329
|
}
|
|
6330
6330
|
module.exports = {
|
|
6331
6331
|
readFile,
|
|
6332
|
-
readFileSync:
|
|
6332
|
+
readFileSync: readFileSync4,
|
|
6333
6333
|
writeFile,
|
|
6334
6334
|
writeFileSync
|
|
6335
6335
|
};
|
|
@@ -8208,7 +8208,7 @@ var init_opencode_installer = __esm(() => {
|
|
|
8208
8208
|
var PARTIAL_INSTALL_VERSION = "partial", EXIT_CODE_CRITICAL_FAILURE = 1, EXIT_CODE_PARTIAL_SUCCESS = 2;
|
|
8209
8209
|
|
|
8210
8210
|
// src/services/package-installer/install-error-handler.ts
|
|
8211
|
-
import { existsSync as existsSync13, readFileSync as
|
|
8211
|
+
import { existsSync as existsSync13, readFileSync as readFileSync6, unlinkSync as unlinkSync2 } from "node:fs";
|
|
8212
8212
|
import { join as join21 } from "node:path";
|
|
8213
8213
|
function parseNameReason(str) {
|
|
8214
8214
|
const colonIndex = str.indexOf(":");
|
|
@@ -8225,7 +8225,7 @@ function displayInstallErrors(skillsDir) {
|
|
|
8225
8225
|
}
|
|
8226
8226
|
let summary;
|
|
8227
8227
|
try {
|
|
8228
|
-
summary = JSON.parse(
|
|
8228
|
+
summary = JSON.parse(readFileSync6(summaryPath, "utf-8"));
|
|
8229
8229
|
} catch (parseError) {
|
|
8230
8230
|
logger.error("Failed to parse error summary. File may be corrupted.");
|
|
8231
8231
|
logger.debug(`Parse error: ${parseError instanceof Error ? parseError.message : String(parseError)}`);
|
|
@@ -16442,7 +16442,7 @@ var init_update_command_help = __esm(() => {
|
|
|
16442
16442
|
sections: [
|
|
16443
16443
|
{
|
|
16444
16444
|
title: "Note",
|
|
16445
|
-
content: "'ck update' updates the CLI tool only. To update kit content (skills, commands,
|
|
16445
|
+
content: "'ck update' updates the CLI tool only. To update kit content (skills, commands, rules), use 'ck init' for local or 'ck init -g' for global."
|
|
16446
16446
|
}
|
|
16447
16447
|
]
|
|
16448
16448
|
};
|
|
@@ -17682,6 +17682,70 @@ class CheckRunner {
|
|
|
17682
17682
|
import { exec as exec4 } from "node:child_process";
|
|
17683
17683
|
import { promisify as promisify4 } from "node:util";
|
|
17684
17684
|
|
|
17685
|
+
// src/domains/github/gh-cli-utils.ts
|
|
17686
|
+
init_logger();
|
|
17687
|
+
import { readFileSync } from "node:fs";
|
|
17688
|
+
var MIN_GH_CLI_VERSION = "2.20.0";
|
|
17689
|
+
var GH_COMMAND_TIMEOUT_MS = 1e4;
|
|
17690
|
+
function compareVersions(a, b) {
|
|
17691
|
+
const partsA = a.split(".").map(Number);
|
|
17692
|
+
const partsB = b.split(".").map(Number);
|
|
17693
|
+
const maxLen = Math.max(partsA.length, partsB.length);
|
|
17694
|
+
for (let i = 0;i < maxLen; i++) {
|
|
17695
|
+
const numA = partsA[i] ?? 0;
|
|
17696
|
+
const numB = partsB[i] ?? 0;
|
|
17697
|
+
if (numA < numB)
|
|
17698
|
+
return -1;
|
|
17699
|
+
if (numA > numB)
|
|
17700
|
+
return 1;
|
|
17701
|
+
}
|
|
17702
|
+
return 0;
|
|
17703
|
+
}
|
|
17704
|
+
function isWSL() {
|
|
17705
|
+
if (process.platform !== "linux")
|
|
17706
|
+
return false;
|
|
17707
|
+
try {
|
|
17708
|
+
const release = readFileSync("/proc/version", "utf-8").toLowerCase();
|
|
17709
|
+
return release.includes("microsoft") || release.includes("wsl");
|
|
17710
|
+
} catch (error) {
|
|
17711
|
+
logger.debug(`WSL detection skipped: ${error instanceof Error ? error.message : "unknown error"}`);
|
|
17712
|
+
return false;
|
|
17713
|
+
}
|
|
17714
|
+
}
|
|
17715
|
+
function shouldSkipExpensiveOperations() {
|
|
17716
|
+
if (process.env.CK_TEST_HOME) {
|
|
17717
|
+
return false;
|
|
17718
|
+
}
|
|
17719
|
+
return process.env.CI === "true" || process.env.CI_SAFE_MODE === "true";
|
|
17720
|
+
}
|
|
17721
|
+
function getGhUpgradeInstructions(currentVersion) {
|
|
17722
|
+
const platform = process.platform;
|
|
17723
|
+
const wsl = isWSL();
|
|
17724
|
+
const lines = [];
|
|
17725
|
+
lines.push(`✗ GitHub CLI v${currentVersion} is outdated`);
|
|
17726
|
+
lines.push(` Minimum required: v${MIN_GH_CLI_VERSION}`);
|
|
17727
|
+
lines.push("");
|
|
17728
|
+
if (wsl) {
|
|
17729
|
+
lines.push("Upgrade GitHub CLI (WSL/Ubuntu):");
|
|
17730
|
+
lines.push(" curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg");
|
|
17731
|
+
lines.push(' echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null');
|
|
17732
|
+
lines.push(" sudo apt update && sudo apt install gh");
|
|
17733
|
+
} else if (platform === "darwin") {
|
|
17734
|
+
lines.push("Upgrade GitHub CLI:");
|
|
17735
|
+
lines.push(" brew upgrade gh");
|
|
17736
|
+
} else if (platform === "win32") {
|
|
17737
|
+
lines.push("Upgrade GitHub CLI:");
|
|
17738
|
+
lines.push(" winget upgrade GitHub.cli");
|
|
17739
|
+
} else {
|
|
17740
|
+
lines.push("Upgrade GitHub CLI:");
|
|
17741
|
+
lines.push(" sudo apt update && sudo apt upgrade gh");
|
|
17742
|
+
lines.push(" Or visit: https://cli.github.com");
|
|
17743
|
+
}
|
|
17744
|
+
lines.push("");
|
|
17745
|
+
lines.push("After upgrade: gh auth login -h github.com");
|
|
17746
|
+
return lines;
|
|
17747
|
+
}
|
|
17748
|
+
|
|
17685
17749
|
// src/services/package-installer/dependency-checker.ts
|
|
17686
17750
|
import { exec } from "node:child_process";
|
|
17687
17751
|
import { promisify } from "node:util";
|
|
@@ -17697,7 +17761,7 @@ function notFoundError(type, name, hint) {
|
|
|
17697
17761
|
// src/services/package-installer/dependency-checker.ts
|
|
17698
17762
|
init_logger();
|
|
17699
17763
|
var execAsync = promisify(exec);
|
|
17700
|
-
function
|
|
17764
|
+
function shouldSkipExpensiveOperations2() {
|
|
17701
17765
|
if (process.env.CK_TEST_HOME) {
|
|
17702
17766
|
return false;
|
|
17703
17767
|
}
|
|
@@ -17709,9 +17773,9 @@ function getOSInfo() {
|
|
|
17709
17773
|
const isWindows = platform === "win32";
|
|
17710
17774
|
const isMacOS = platform === "darwin";
|
|
17711
17775
|
const isLinux = platform === "linux";
|
|
17712
|
-
const
|
|
17776
|
+
const isWSL2 = isLinux && process.env.WSL_DISTRO_NAME !== undefined;
|
|
17713
17777
|
let details = `${platform}-${arch}`;
|
|
17714
|
-
if (
|
|
17778
|
+
if (isWSL2) {
|
|
17715
17779
|
details += ` (WSL: ${process.env.WSL_DISTRO_NAME})`;
|
|
17716
17780
|
}
|
|
17717
17781
|
return {
|
|
@@ -17720,7 +17784,7 @@ function getOSInfo() {
|
|
|
17720
17784
|
isWindows,
|
|
17721
17785
|
isMacOS,
|
|
17722
17786
|
isLinux,
|
|
17723
|
-
isWSL,
|
|
17787
|
+
isWSL: isWSL2,
|
|
17724
17788
|
details
|
|
17725
17789
|
};
|
|
17726
17790
|
}
|
|
@@ -17791,7 +17855,7 @@ var DEPENDENCIES = {
|
|
|
17791
17855
|
}
|
|
17792
17856
|
};
|
|
17793
17857
|
async function commandExists(command) {
|
|
17794
|
-
if (
|
|
17858
|
+
if (shouldSkipExpensiveOperations2()) {
|
|
17795
17859
|
const supportedCommands = ["node", "python", "python3", "pip", "pip3", "claude"];
|
|
17796
17860
|
return supportedCommands.includes(command);
|
|
17797
17861
|
}
|
|
@@ -17807,7 +17871,7 @@ async function commandExists(command) {
|
|
|
17807
17871
|
}
|
|
17808
17872
|
}
|
|
17809
17873
|
async function getCommandPath(command) {
|
|
17810
|
-
if (
|
|
17874
|
+
if (shouldSkipExpensiveOperations2()) {
|
|
17811
17875
|
const ciPath = getCICommandPath(command);
|
|
17812
17876
|
if (ciPath)
|
|
17813
17877
|
return ciPath;
|
|
@@ -17826,7 +17890,7 @@ async function getCommandPath(command) {
|
|
|
17826
17890
|
}
|
|
17827
17891
|
}
|
|
17828
17892
|
async function getCommandVersion(command, versionFlag, versionRegex) {
|
|
17829
|
-
if (
|
|
17893
|
+
if (shouldSkipExpensiveOperations2()) {
|
|
17830
17894
|
const mockVersions = {
|
|
17831
17895
|
npm: "10.0.0",
|
|
17832
17896
|
node: "20.0.0",
|
|
@@ -17852,7 +17916,7 @@ async function getCommandVersion(command, versionFlag, versionRegex) {
|
|
|
17852
17916
|
return null;
|
|
17853
17917
|
}
|
|
17854
17918
|
}
|
|
17855
|
-
function
|
|
17919
|
+
function compareVersions2(current, required) {
|
|
17856
17920
|
const parseCurrent = current.split(".").map((n) => Number.parseInt(n, 10));
|
|
17857
17921
|
const parseRequired = required.split(".").map((n) => Number.parseInt(n, 10));
|
|
17858
17922
|
for (let i = 0;i < 3; i++) {
|
|
@@ -17876,7 +17940,7 @@ async function checkDependency(config) {
|
|
|
17876
17940
|
let meetsRequirements = true;
|
|
17877
17941
|
let message;
|
|
17878
17942
|
if (config.minVersion && version) {
|
|
17879
|
-
meetsRequirements =
|
|
17943
|
+
meetsRequirements = compareVersions2(version, config.minVersion);
|
|
17880
17944
|
if (!meetsRequirements) {
|
|
17881
17945
|
message = `Version ${version} is below minimum ${config.minVersion}`;
|
|
17882
17946
|
}
|
|
@@ -18135,27 +18199,6 @@ async function installDependency(dependency, method) {
|
|
|
18135
18199
|
// src/domains/health-checks/system-checker.ts
|
|
18136
18200
|
init_logger();
|
|
18137
18201
|
var execAsync4 = promisify4(exec4);
|
|
18138
|
-
var MIN_GH_CLI_VERSION = "2.20.0";
|
|
18139
|
-
function compareVersions2(a, b) {
|
|
18140
|
-
const partsA = a.split(".").map(Number);
|
|
18141
|
-
const partsB = b.split(".").map(Number);
|
|
18142
|
-
const maxLen = Math.max(partsA.length, partsB.length);
|
|
18143
|
-
for (let i = 0;i < maxLen; i++) {
|
|
18144
|
-
const numA = partsA[i] ?? 0;
|
|
18145
|
-
const numB = partsB[i] ?? 0;
|
|
18146
|
-
if (numA < numB)
|
|
18147
|
-
return -1;
|
|
18148
|
-
if (numA > numB)
|
|
18149
|
-
return 1;
|
|
18150
|
-
}
|
|
18151
|
-
return 0;
|
|
18152
|
-
}
|
|
18153
|
-
function shouldSkipExpensiveOperations2() {
|
|
18154
|
-
if (process.env.CK_TEST_HOME) {
|
|
18155
|
-
return false;
|
|
18156
|
-
}
|
|
18157
|
-
return process.env.CI === "true" || process.env.CI_SAFE_MODE === "true";
|
|
18158
|
-
}
|
|
18159
18202
|
|
|
18160
18203
|
class SystemChecker {
|
|
18161
18204
|
group = "system";
|
|
@@ -18170,7 +18213,7 @@ class SystemChecker {
|
|
|
18170
18213
|
logger.verbose(`SystemChecker: Processing ${dep.name}`);
|
|
18171
18214
|
results.push(await this.mapDependencyToCheck(dep));
|
|
18172
18215
|
}
|
|
18173
|
-
if (!
|
|
18216
|
+
if (!shouldSkipExpensiveOperations()) {
|
|
18174
18217
|
logger.verbose("SystemChecker: Checking git");
|
|
18175
18218
|
results.push(await this.checkGit());
|
|
18176
18219
|
logger.verbose("SystemChecker: Checking GitHub CLI");
|
|
@@ -18292,7 +18335,7 @@ class SystemChecker {
|
|
|
18292
18335
|
const { stdout } = await execAsync4("gh --version");
|
|
18293
18336
|
const match = stdout.match(/(\d+\.\d+\.\d+)/);
|
|
18294
18337
|
const version = match?.[1];
|
|
18295
|
-
if (version &&
|
|
18338
|
+
if (version && compareVersions(version, MIN_GH_CLI_VERSION) < 0) {
|
|
18296
18339
|
return {
|
|
18297
18340
|
id: "gh-cli-version",
|
|
18298
18341
|
name: "GitHub CLI",
|
|
@@ -18370,18 +18413,18 @@ class SystemChecker {
|
|
|
18370
18413
|
import { join as join2 } from "node:path";
|
|
18371
18414
|
|
|
18372
18415
|
// src/shared/path-resolver.ts
|
|
18373
|
-
import { existsSync as existsSync2, readFileSync as
|
|
18416
|
+
import { existsSync as existsSync2, readFileSync as readFileSync3 } from "node:fs";
|
|
18374
18417
|
import { homedir, platform } from "node:os";
|
|
18375
18418
|
import { join, normalize } from "node:path";
|
|
18376
|
-
function
|
|
18419
|
+
function isWSL2() {
|
|
18377
18420
|
try {
|
|
18378
|
-
return process.platform === "linux" && existsSync2("/proc/version") &&
|
|
18421
|
+
return process.platform === "linux" && existsSync2("/proc/version") && readFileSync3("/proc/version", "utf8").toLowerCase().includes("microsoft");
|
|
18379
18422
|
} catch {
|
|
18380
18423
|
return false;
|
|
18381
18424
|
}
|
|
18382
18425
|
}
|
|
18383
18426
|
function normalizeWSLPath(p) {
|
|
18384
|
-
if (!
|
|
18427
|
+
if (!isWSL2())
|
|
18385
18428
|
return p;
|
|
18386
18429
|
const windowsMatch = p.match(/^([A-Za-z]):(.*)/);
|
|
18387
18430
|
if (windowsMatch) {
|
|
@@ -18499,7 +18542,7 @@ class PathResolver {
|
|
|
18499
18542
|
}
|
|
18500
18543
|
static buildComponentPath(baseDir, component, global2) {
|
|
18501
18544
|
if (!PathResolver.isValidComponentName(component)) {
|
|
18502
|
-
throw new Error(`Invalid component name: "${component}" contains path traversal patterns. Valid names are simple directory names like "agents", "commands", "
|
|
18545
|
+
throw new Error(`Invalid component name: "${component}" contains path traversal patterns. Valid names are simple directory names like "agents", "commands", "rules", "skills", or "hooks".`);
|
|
18503
18546
|
}
|
|
18504
18547
|
const prefix = PathResolver.getPathPrefix(global2);
|
|
18505
18548
|
if (prefix) {
|
|
@@ -18524,7 +18567,7 @@ class PathResolver {
|
|
|
18524
18567
|
return normalizeWSLPath(p);
|
|
18525
18568
|
}
|
|
18526
18569
|
static isWSL() {
|
|
18527
|
-
return
|
|
18570
|
+
return isWSL2();
|
|
18528
18571
|
}
|
|
18529
18572
|
static isAtHomeDirectory(cwd) {
|
|
18530
18573
|
const currentDir = normalize(cwd || process.cwd());
|
|
@@ -18577,7 +18620,7 @@ async function scanClaudeKitDirectory(directoryPath) {
|
|
|
18577
18620
|
const counts = {
|
|
18578
18621
|
agents: 0,
|
|
18579
18622
|
commands: 0,
|
|
18580
|
-
|
|
18623
|
+
rules: 0,
|
|
18581
18624
|
skills: 0
|
|
18582
18625
|
};
|
|
18583
18626
|
try {
|
|
@@ -18595,10 +18638,14 @@ async function scanClaudeKitDirectory(directoryPath) {
|
|
|
18595
18638
|
const commandFiles = await import_fs_extra.readdir(commandsPath);
|
|
18596
18639
|
counts.commands = commandFiles.filter((file) => file.endsWith(".md")).length;
|
|
18597
18640
|
}
|
|
18598
|
-
if (items.includes("
|
|
18641
|
+
if (items.includes("rules")) {
|
|
18642
|
+
const rulesPath = join2(directoryPath, "rules");
|
|
18643
|
+
const ruleFiles = await import_fs_extra.readdir(rulesPath);
|
|
18644
|
+
counts.rules = ruleFiles.filter((file) => file.endsWith(".md")).length;
|
|
18645
|
+
} else if (items.includes("workflows")) {
|
|
18599
18646
|
const workflowsPath = join2(directoryPath, "workflows");
|
|
18600
18647
|
const workflowFiles = await import_fs_extra.readdir(workflowsPath);
|
|
18601
|
-
counts.
|
|
18648
|
+
counts.rules = workflowFiles.filter((file) => file.endsWith(".md")).length;
|
|
18602
18649
|
}
|
|
18603
18650
|
if (items.includes("skills")) {
|
|
18604
18651
|
const skillsPath = join2(directoryPath, "skills");
|
|
@@ -18639,12 +18686,12 @@ async function getClaudeKitSetup(projectDir = process.cwd()) {
|
|
|
18639
18686
|
global: {
|
|
18640
18687
|
path: "",
|
|
18641
18688
|
metadata: null,
|
|
18642
|
-
components: { agents: 0, commands: 0,
|
|
18689
|
+
components: { agents: 0, commands: 0, rules: 0, skills: 0 }
|
|
18643
18690
|
},
|
|
18644
18691
|
project: {
|
|
18645
18692
|
path: "",
|
|
18646
18693
|
metadata: null,
|
|
18647
|
-
components: { agents: 0, commands: 0,
|
|
18694
|
+
components: { agents: 0, commands: 0, rules: 0, skills: 0 }
|
|
18648
18695
|
}
|
|
18649
18696
|
};
|
|
18650
18697
|
const globalDir = getGlobalInstallDir();
|
|
@@ -19170,7 +19217,7 @@ function checkClaudeMdFile(path, name, id) {
|
|
|
19170
19217
|
}
|
|
19171
19218
|
}
|
|
19172
19219
|
// src/domains/health-checks/checkers/active-plan-checker.ts
|
|
19173
|
-
import { existsSync as existsSync5, readFileSync as
|
|
19220
|
+
import { existsSync as existsSync5, readFileSync as readFileSync4 } from "node:fs";
|
|
19174
19221
|
import { join as join5 } from "node:path";
|
|
19175
19222
|
function checkActivePlan(projectDir) {
|
|
19176
19223
|
const activePlanPath = join5(projectDir, ".claude", "active-plan");
|
|
@@ -19186,7 +19233,7 @@ function checkActivePlan(projectDir) {
|
|
|
19186
19233
|
};
|
|
19187
19234
|
}
|
|
19188
19235
|
try {
|
|
19189
|
-
const targetPath =
|
|
19236
|
+
const targetPath = readFileSync4(activePlanPath, "utf-8").trim();
|
|
19190
19237
|
const fullPath = join5(projectDir, targetPath);
|
|
19191
19238
|
if (!existsSync5(fullPath)) {
|
|
19192
19239
|
return {
|
|
@@ -19267,16 +19314,16 @@ function checkComponentCounts(setup) {
|
|
|
19267
19314
|
const project = setup.project.components;
|
|
19268
19315
|
const totalAgents = global2.agents + project.agents;
|
|
19269
19316
|
const totalCommands = global2.commands + project.commands;
|
|
19270
|
-
const
|
|
19317
|
+
const totalRules = global2.rules + project.rules;
|
|
19271
19318
|
const totalSkills = global2.skills + project.skills;
|
|
19272
|
-
const totalComponents = totalAgents + totalCommands +
|
|
19319
|
+
const totalComponents = totalAgents + totalCommands + totalRules + totalSkills;
|
|
19273
19320
|
return {
|
|
19274
19321
|
id: "ck-component-counts",
|
|
19275
19322
|
name: "ClaudeKit Components",
|
|
19276
19323
|
group: "claudekit",
|
|
19277
19324
|
priority: "standard",
|
|
19278
19325
|
status: totalComponents > 0 ? "info" : "warn",
|
|
19279
|
-
message: totalComponents > 0 ? `${totalAgents} agents, ${totalCommands} commands, ${
|
|
19326
|
+
message: totalComponents > 0 ? `${totalAgents} agents, ${totalCommands} commands, ${totalRules} rules, ${totalSkills} skills` : "No components found",
|
|
19280
19327
|
suggestion: totalComponents === 0 ? "Install ClaudeKit: ck new --kit engineer" : undefined,
|
|
19281
19328
|
autoFixable: false
|
|
19282
19329
|
};
|
|
@@ -19637,7 +19684,7 @@ async function checkProjectConfigCompleteness(setup, projectDir) {
|
|
|
19637
19684
|
};
|
|
19638
19685
|
}
|
|
19639
19686
|
const projectClaudeDir = join11(projectDir, ".claude");
|
|
19640
|
-
const requiredDirs = ["agents", "commands", "
|
|
19687
|
+
const requiredDirs = ["agents", "commands", "skills"];
|
|
19641
19688
|
const missingDirs = [];
|
|
19642
19689
|
for (const dir of requiredDirs) {
|
|
19643
19690
|
const dirPath = join11(projectClaudeDir, dir);
|
|
@@ -19645,9 +19692,14 @@ async function checkProjectConfigCompleteness(setup, projectDir) {
|
|
|
19645
19692
|
missingDirs.push(dir);
|
|
19646
19693
|
}
|
|
19647
19694
|
}
|
|
19695
|
+
const hasRulesOrWorkflows = existsSync10(join11(projectClaudeDir, "rules")) || existsSync10(join11(projectClaudeDir, "workflows"));
|
|
19696
|
+
if (!hasRulesOrWorkflows) {
|
|
19697
|
+
missingDirs.push("rules");
|
|
19698
|
+
}
|
|
19648
19699
|
const files = await readdir3(projectClaudeDir).catch(() => []);
|
|
19649
19700
|
const hasOnlyClaudeMd = files.length === 1 && files.includes("CLAUDE.md");
|
|
19650
|
-
|
|
19701
|
+
const totalRequired = requiredDirs.length + 1;
|
|
19702
|
+
if (hasOnlyClaudeMd || missingDirs.length === totalRequired) {
|
|
19651
19703
|
return {
|
|
19652
19704
|
id: "ck-project-config-complete",
|
|
19653
19705
|
name: "Project Config Completeness",
|
|
@@ -19655,7 +19707,7 @@ async function checkProjectConfigCompleteness(setup, projectDir) {
|
|
|
19655
19707
|
priority: "standard",
|
|
19656
19708
|
status: "fail",
|
|
19657
19709
|
message: "Incomplete configuration",
|
|
19658
|
-
details: "Only CLAUDE.md found - missing agents, commands,
|
|
19710
|
+
details: "Only CLAUDE.md found - missing agents, commands, rules, skills",
|
|
19659
19711
|
suggestion: "Run 'ck init' to install complete ClaudeKit in project",
|
|
19660
19712
|
autoFixable: false
|
|
19661
19713
|
};
|
|
@@ -21547,7 +21599,7 @@ class AutoHealer {
|
|
|
21547
21599
|
}
|
|
21548
21600
|
// src/domains/health-checks/report-generator.ts
|
|
21549
21601
|
import { execSync as execSync4, spawnSync } from "node:child_process";
|
|
21550
|
-
import { readFileSync as
|
|
21602
|
+
import { readFileSync as readFileSync5, unlinkSync, writeFileSync } from "node:fs";
|
|
21551
21603
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
21552
21604
|
import { dirname as dirname2, join as join16 } from "node:path";
|
|
21553
21605
|
import { fileURLToPath } from "node:url";
|
|
@@ -21558,7 +21610,7 @@ function getCliVersion() {
|
|
|
21558
21610
|
try {
|
|
21559
21611
|
const __dirname2 = dirname2(fileURLToPath(import.meta.url));
|
|
21560
21612
|
const pkgPath = join16(__dirname2, "../../../package.json");
|
|
21561
|
-
const pkg = JSON.parse(
|
|
21613
|
+
const pkg = JSON.parse(readFileSync5(pkgPath, "utf-8"));
|
|
21562
21614
|
return pkg.version || "unknown";
|
|
21563
21615
|
} catch (err) {
|
|
21564
21616
|
logger.debug(`Failed to read CLI version: ${err}`);
|
|
@@ -24614,9 +24666,9 @@ async function promptDirectorySelection(global2 = false) {
|
|
|
24614
24666
|
{ key: "agents", label: "Agents", pattern: prefix ? `${prefix}/agents` : "agents" },
|
|
24615
24667
|
{ key: "commands", label: "Commands", pattern: prefix ? `${prefix}/commands` : "commands" },
|
|
24616
24668
|
{
|
|
24617
|
-
key: "
|
|
24618
|
-
label: "
|
|
24619
|
-
pattern: prefix ? `${prefix}/
|
|
24669
|
+
key: "rules",
|
|
24670
|
+
label: "Rules",
|
|
24671
|
+
pattern: prefix ? `${prefix}/rules` : "rules"
|
|
24620
24672
|
},
|
|
24621
24673
|
{ key: "skills", label: "Skills", pattern: prefix ? `${prefix}/skills` : "skills" },
|
|
24622
24674
|
{ key: "hooks", label: "Hooks", pattern: prefix ? `${prefix}/hooks` : "hooks" }
|
|
@@ -34425,7 +34477,7 @@ async function getUninstallManifest(claudeDir, kit) {
|
|
|
34425
34477
|
const installedFiles = detection.metadata.installedFiles || [];
|
|
34426
34478
|
const hasFiles = legacyFiles2.length > 0 || installedFiles.length > 0;
|
|
34427
34479
|
if (!hasFiles) {
|
|
34428
|
-
const legacyDirs2 = ["commands", "agents", "skills", "workflows", "hooks", "scripts"];
|
|
34480
|
+
const legacyDirs2 = ["commands", "agents", "skills", "rules", "workflows", "hooks", "scripts"];
|
|
34429
34481
|
const legacyFileList = ["metadata.json"];
|
|
34430
34482
|
return {
|
|
34431
34483
|
filesToRemove: [...legacyDirs2, ...legacyFileList],
|
|
@@ -34443,7 +34495,7 @@ async function getUninstallManifest(claudeDir, kit) {
|
|
|
34443
34495
|
remainingKits: []
|
|
34444
34496
|
};
|
|
34445
34497
|
}
|
|
34446
|
-
const legacyDirs = ["commands", "agents", "skills", "workflows", "hooks", "scripts"];
|
|
34498
|
+
const legacyDirs = ["commands", "agents", "skills", "rules", "workflows", "hooks", "scripts"];
|
|
34447
34499
|
const legacyFiles = ["metadata.json"];
|
|
34448
34500
|
return {
|
|
34449
34501
|
filesToRemove: [...legacyDirs, ...legacyFiles],
|
|
@@ -40314,11 +40366,110 @@ async function detectAccessibleKits() {
|
|
|
40314
40366
|
return accessible;
|
|
40315
40367
|
}
|
|
40316
40368
|
|
|
40369
|
+
// src/domains/github/preflight-checker.ts
|
|
40370
|
+
init_logger();
|
|
40371
|
+
import { exec as exec7 } from "node:child_process";
|
|
40372
|
+
import { promisify as promisify7 } from "node:util";
|
|
40373
|
+
var execAsync7 = promisify7(exec7);
|
|
40374
|
+
function createSuccessfulPreflightResult() {
|
|
40375
|
+
return {
|
|
40376
|
+
success: true,
|
|
40377
|
+
ghInstalled: true,
|
|
40378
|
+
ghVersion: MIN_GH_CLI_VERSION,
|
|
40379
|
+
ghVersionOk: true,
|
|
40380
|
+
ghAuthenticated: true,
|
|
40381
|
+
errorLines: []
|
|
40382
|
+
};
|
|
40383
|
+
}
|
|
40384
|
+
function isTimeoutError(error) {
|
|
40385
|
+
if (error instanceof Error) {
|
|
40386
|
+
const msg = error.message.toLowerCase();
|
|
40387
|
+
return msg.includes("timeout") || msg.includes("timed out") || msg.includes("etimedout");
|
|
40388
|
+
}
|
|
40389
|
+
return false;
|
|
40390
|
+
}
|
|
40391
|
+
async function runPreflightChecks() {
|
|
40392
|
+
logger.debug("Running GitHub CLI pre-flight checks");
|
|
40393
|
+
if (shouldSkipExpensiveOperations()) {
|
|
40394
|
+
logger.debug("Skipping preflight checks in test/CI environment");
|
|
40395
|
+
return createSuccessfulPreflightResult();
|
|
40396
|
+
}
|
|
40397
|
+
const result = {
|
|
40398
|
+
success: false,
|
|
40399
|
+
ghInstalled: false,
|
|
40400
|
+
ghVersion: null,
|
|
40401
|
+
ghVersionOk: false,
|
|
40402
|
+
ghAuthenticated: false,
|
|
40403
|
+
errorLines: []
|
|
40404
|
+
};
|
|
40405
|
+
try {
|
|
40406
|
+
const { stdout: stdout2 } = await execAsync7("gh --version", { timeout: GH_COMMAND_TIMEOUT_MS });
|
|
40407
|
+
const match2 = stdout2.match(/(\d+\.\d+\.\d+)/);
|
|
40408
|
+
if (!match2) {
|
|
40409
|
+
logger.debug(`GitHub CLI version not detected from output: ${stdout2.trim()}`);
|
|
40410
|
+
result.ghInstalled = true;
|
|
40411
|
+
result.errorLines.push("✗ GitHub CLI installed but version could not be detected");
|
|
40412
|
+
result.errorLines.push(` Output: ${stdout2.trim().slice(0, 100)}`);
|
|
40413
|
+
result.errorLines.push(" Try running: gh --version");
|
|
40414
|
+
return result;
|
|
40415
|
+
}
|
|
40416
|
+
result.ghVersion = match2[1];
|
|
40417
|
+
result.ghInstalled = true;
|
|
40418
|
+
logger.debug(`GitHub CLI detected: v${result.ghVersion}`);
|
|
40419
|
+
} catch (error) {
|
|
40420
|
+
if (isTimeoutError(error)) {
|
|
40421
|
+
logger.debug("GitHub CLI check timed out");
|
|
40422
|
+
result.errorLines.push("✗ GitHub CLI check timed out");
|
|
40423
|
+
result.errorLines.push(" This may indicate a slow system or network issue");
|
|
40424
|
+
result.errorLines.push(" Try running: gh --version");
|
|
40425
|
+
} else {
|
|
40426
|
+
logger.debug(`GitHub CLI not found: ${error instanceof Error ? error.message : "unknown error"}`);
|
|
40427
|
+
result.errorLines.push("✗ GitHub CLI not installed");
|
|
40428
|
+
result.errorLines.push(" Install from: https://cli.github.com");
|
|
40429
|
+
result.errorLines.push("");
|
|
40430
|
+
result.errorLines.push("After install: gh auth login -h github.com");
|
|
40431
|
+
}
|
|
40432
|
+
return result;
|
|
40433
|
+
}
|
|
40434
|
+
if (result.ghVersion) {
|
|
40435
|
+
const comparison = compareVersions(result.ghVersion, MIN_GH_CLI_VERSION);
|
|
40436
|
+
result.ghVersionOk = comparison >= 0;
|
|
40437
|
+
if (!result.ghVersionOk) {
|
|
40438
|
+
logger.debug(`GitHub CLI version ${result.ghVersion} is below minimum ${MIN_GH_CLI_VERSION}`);
|
|
40439
|
+
result.errorLines.push(...getGhUpgradeInstructions(result.ghVersion));
|
|
40440
|
+
return result;
|
|
40441
|
+
}
|
|
40442
|
+
}
|
|
40443
|
+
try {
|
|
40444
|
+
await execAsync7("gh auth status -h github.com", {
|
|
40445
|
+
timeout: GH_COMMAND_TIMEOUT_MS,
|
|
40446
|
+
env: { ...process.env, GH_NO_UPDATE_NOTIFIER: "1" }
|
|
40447
|
+
});
|
|
40448
|
+
result.ghAuthenticated = true;
|
|
40449
|
+
logger.debug("GitHub CLI authenticated for github.com");
|
|
40450
|
+
} catch (error) {
|
|
40451
|
+
if (isTimeoutError(error)) {
|
|
40452
|
+
logger.debug("GitHub CLI auth check timed out");
|
|
40453
|
+
result.errorLines.push("✗ GitHub CLI auth check timed out");
|
|
40454
|
+
result.errorLines.push(" This may indicate a network issue");
|
|
40455
|
+
result.errorLines.push(" Try running: gh auth status -h github.com");
|
|
40456
|
+
} else {
|
|
40457
|
+
logger.debug(`GitHub CLI not authenticated: ${error instanceof Error ? error.message : "unknown error"}`);
|
|
40458
|
+
result.errorLines.push("✗ GitHub CLI not authenticated");
|
|
40459
|
+
result.errorLines.push(" Run: gh auth login -h github.com");
|
|
40460
|
+
}
|
|
40461
|
+
return result;
|
|
40462
|
+
}
|
|
40463
|
+
result.success = true;
|
|
40464
|
+
logger.debug("All GitHub CLI pre-flight checks passed");
|
|
40465
|
+
return result;
|
|
40466
|
+
}
|
|
40467
|
+
|
|
40317
40468
|
// src/domains/installation/fresh-installer.ts
|
|
40318
40469
|
init_logger();
|
|
40319
40470
|
import { join as join65 } from "node:path";
|
|
40320
40471
|
var import_fs_extra29 = __toESM(require_lib(), 1);
|
|
40321
|
-
var CLAUDEKIT_SUBDIRECTORIES = ["commands", "agents", "skills", "
|
|
40472
|
+
var CLAUDEKIT_SUBDIRECTORIES = ["commands", "agents", "skills", "rules", "hooks"];
|
|
40322
40473
|
async function handleFreshInstallation(claudeDir, prompts) {
|
|
40323
40474
|
if (!await import_fs_extra29.pathExists(claudeDir)) {
|
|
40324
40475
|
logger.info(".claude directory does not exist, proceeding with fresh installation");
|
|
@@ -40378,10 +40529,25 @@ async function handleSelection(ctx) {
|
|
|
40378
40529
|
const config = await ConfigManager.get();
|
|
40379
40530
|
let accessibleKits;
|
|
40380
40531
|
if (!ctx.options.useGit && !ctx.options.kitPath && !ctx.options.archive) {
|
|
40532
|
+
const preflight = await runPreflightChecks();
|
|
40533
|
+
if (!preflight.success) {
|
|
40534
|
+
for (const line of preflight.errorLines) {
|
|
40535
|
+
if (line.startsWith("✗")) {
|
|
40536
|
+
logger.error(line);
|
|
40537
|
+
} else {
|
|
40538
|
+
logger.info(line);
|
|
40539
|
+
}
|
|
40540
|
+
}
|
|
40541
|
+
logger.info("");
|
|
40542
|
+
logger.info("Full diagnostics: ck doctor");
|
|
40543
|
+
return { ...ctx, cancelled: true };
|
|
40544
|
+
}
|
|
40381
40545
|
accessibleKits = await detectAccessibleKits();
|
|
40382
40546
|
if (accessibleKits.length === 0) {
|
|
40383
|
-
logger.error("No ClaudeKit access found.");
|
|
40384
|
-
logger.info("
|
|
40547
|
+
logger.error("No ClaudeKit repository access found.");
|
|
40548
|
+
logger.info("Check email for GitHub invitation, or purchase at https://claudekit.cc");
|
|
40549
|
+
logger.info("");
|
|
40550
|
+
logger.info("Full diagnostics: ck doctor");
|
|
40385
40551
|
return { ...ctx, cancelled: true };
|
|
40386
40552
|
}
|
|
40387
40553
|
}
|
|
@@ -42401,9 +42567,9 @@ ${import_picocolors22.default.yellow("User modifications will be permanently del
|
|
|
42401
42567
|
}
|
|
42402
42568
|
}
|
|
42403
42569
|
// src/commands/update-cli.ts
|
|
42404
|
-
import { exec as
|
|
42570
|
+
import { exec as exec8 } from "node:child_process";
|
|
42405
42571
|
import { join as join75 } from "node:path";
|
|
42406
|
-
import { promisify as
|
|
42572
|
+
import { promisify as promisify8 } from "node:util";
|
|
42407
42573
|
|
|
42408
42574
|
// src/domains/github/npm-registry.ts
|
|
42409
42575
|
init_logger();
|
|
@@ -42549,7 +42715,7 @@ var import_fs_extra36 = __toESM(require_lib(), 1);
|
|
|
42549
42715
|
// package.json
|
|
42550
42716
|
var package_default = {
|
|
42551
42717
|
name: "claudekit-cli",
|
|
42552
|
-
version: "3.
|
|
42718
|
+
version: "3.26.1",
|
|
42553
42719
|
description: "CLI tool for bootstrapping and updating ClaudeKit projects",
|
|
42554
42720
|
type: "module",
|
|
42555
42721
|
repository: {
|
|
@@ -42640,7 +42806,7 @@ var package_default = {
|
|
|
42640
42806
|
};
|
|
42641
42807
|
|
|
42642
42808
|
// src/commands/update-cli.ts
|
|
42643
|
-
var
|
|
42809
|
+
var execAsync8 = promisify8(exec8);
|
|
42644
42810
|
|
|
42645
42811
|
class CliUpdateError extends ClaudeKitError {
|
|
42646
42812
|
constructor(message) {
|
|
@@ -42660,6 +42826,11 @@ function buildInitCommand(isGlobal, kit, beta) {
|
|
|
42660
42826
|
parts.push("--beta");
|
|
42661
42827
|
return parts.join(" ");
|
|
42662
42828
|
}
|
|
42829
|
+
function isBetaVersion(version) {
|
|
42830
|
+
if (!version)
|
|
42831
|
+
return false;
|
|
42832
|
+
return /-(beta|alpha|rc)[.\d]/i.test(version);
|
|
42833
|
+
}
|
|
42663
42834
|
function selectKitForUpdate(params) {
|
|
42664
42835
|
const { hasLocal, hasGlobal, localKits, globalKits } = params;
|
|
42665
42836
|
const hasLocalKit = localKits.length > 0 || hasLocal;
|
|
@@ -42723,7 +42894,9 @@ async function promptKitUpdate(beta) {
|
|
|
42723
42894
|
logger.verbose("No ClaudeKit installations detected, skipping kit update prompt");
|
|
42724
42895
|
return;
|
|
42725
42896
|
}
|
|
42726
|
-
const
|
|
42897
|
+
const kitVersion = selection.kit ? selection.isGlobal ? globalMetadata?.kits?.[selection.kit]?.version : localMetadata?.kits?.[selection.kit]?.version : undefined;
|
|
42898
|
+
const isBetaInstalled = isBetaVersion(kitVersion);
|
|
42899
|
+
const initCmd = buildInitCommand(selection.isGlobal, selection.kit, beta || isBetaInstalled);
|
|
42727
42900
|
const promptMessage = selection.promptMessage;
|
|
42728
42901
|
logger.info("");
|
|
42729
42902
|
const shouldUpdate = await se({
|
|
@@ -42737,7 +42910,7 @@ async function promptKitUpdate(beta) {
|
|
|
42737
42910
|
const s = de();
|
|
42738
42911
|
s.start("Updating ClaudeKit content...");
|
|
42739
42912
|
try {
|
|
42740
|
-
await
|
|
42913
|
+
await execAsync8(initCmd, {
|
|
42741
42914
|
timeout: 300000
|
|
42742
42915
|
});
|
|
42743
42916
|
s.stop("Kit content updated");
|
|
@@ -42827,7 +43000,7 @@ Run 'ck update' to install`, "Update Check");
|
|
|
42827
43000
|
logger.info(`Running: ${updateCmd}`);
|
|
42828
43001
|
s.start("Updating CLI...");
|
|
42829
43002
|
try {
|
|
42830
|
-
await
|
|
43003
|
+
await execAsync8(updateCmd, {
|
|
42831
43004
|
timeout: 120000
|
|
42832
43005
|
});
|
|
42833
43006
|
s.stop("Update completed");
|
|
@@ -42845,7 +43018,7 @@ Manual update: ${updateCmd}`);
|
|
|
42845
43018
|
}
|
|
42846
43019
|
s.start("Verifying installation...");
|
|
42847
43020
|
try {
|
|
42848
|
-
const { stdout: stdout2 } = await
|
|
43021
|
+
const { stdout: stdout2 } = await execAsync8("ck --version", { timeout: 5000 });
|
|
42849
43022
|
const newVersionMatch = stdout2.match(/CLI Version:\s*(\S+)/);
|
|
42850
43023
|
const newVersion = newVersionMatch ? newVersionMatch[1] : targetVersion;
|
|
42851
43024
|
s.stop(`Installed version: ${newVersion}`);
|
|
@@ -43020,7 +43193,7 @@ function registerCommands(cli) {
|
|
|
43020
43193
|
}
|
|
43021
43194
|
|
|
43022
43195
|
// src/cli/version-display.ts
|
|
43023
|
-
import { existsSync as existsSync20, readFileSync as
|
|
43196
|
+
import { existsSync as existsSync20, readFileSync as readFileSync7 } from "node:fs";
|
|
43024
43197
|
import { join as join77 } from "node:path";
|
|
43025
43198
|
|
|
43026
43199
|
// src/domains/versioning/checking/version-utils.ts
|
|
@@ -43327,7 +43500,7 @@ async function displayVersion() {
|
|
|
43327
43500
|
const isLocalSameAsGlobal = localMetadataPath === globalMetadataPath;
|
|
43328
43501
|
if (!isLocalSameAsGlobal && existsSync20(localMetadataPath)) {
|
|
43329
43502
|
try {
|
|
43330
|
-
const rawMetadata = JSON.parse(
|
|
43503
|
+
const rawMetadata = JSON.parse(readFileSync7(localMetadataPath, "utf-8"));
|
|
43331
43504
|
const metadata = MetadataSchema.parse(rawMetadata);
|
|
43332
43505
|
const kitsDisplay = formatInstalledKits(metadata);
|
|
43333
43506
|
if (kitsDisplay) {
|
|
@@ -43341,7 +43514,7 @@ async function displayVersion() {
|
|
|
43341
43514
|
}
|
|
43342
43515
|
if (existsSync20(globalMetadataPath)) {
|
|
43343
43516
|
try {
|
|
43344
|
-
const rawMetadata = JSON.parse(
|
|
43517
|
+
const rawMetadata = JSON.parse(readFileSync7(globalMetadataPath, "utf-8"));
|
|
43345
43518
|
const metadata = MetadataSchema.parse(rawMetadata);
|
|
43346
43519
|
const kitsDisplay = formatInstalledKits(metadata);
|
|
43347
43520
|
if (kitsDisplay) {
|