claudekit-cli 3.5.1 → 3.6.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/dist/index.js +353 -138
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7411,7 +7411,7 @@ var require_umd = __commonJS((exports, module) => {
|
|
|
7411
7411
|
}
|
|
7412
7412
|
return 0;
|
|
7413
7413
|
};
|
|
7414
|
-
const
|
|
7414
|
+
const compareVersions3 = (v1, v2) => {
|
|
7415
7415
|
const n1 = validateAndParse(v1);
|
|
7416
7416
|
const n2 = validateAndParse(v2);
|
|
7417
7417
|
const p1 = n1.pop();
|
|
@@ -7428,7 +7428,7 @@ var require_umd = __commonJS((exports, module) => {
|
|
|
7428
7428
|
};
|
|
7429
7429
|
const compare = (v1, v2, operator) => {
|
|
7430
7430
|
assertValidOperator(operator);
|
|
7431
|
-
const res =
|
|
7431
|
+
const res = compareVersions3(v1, v2);
|
|
7432
7432
|
return operatorResMap[operator].includes(res);
|
|
7433
7433
|
};
|
|
7434
7434
|
const operatorResMap = {
|
|
@@ -7485,7 +7485,7 @@ var require_umd = __commonJS((exports, module) => {
|
|
|
7485
7485
|
const validate = (version) => typeof version === "string" && /^[v\d]/.test(version) && semver.test(version);
|
|
7486
7486
|
const validateStrict = (version) => typeof version === "string" && /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/.test(version);
|
|
7487
7487
|
exports2.compare = compare;
|
|
7488
|
-
exports2.compareVersions =
|
|
7488
|
+
exports2.compareVersions = compareVersions3;
|
|
7489
7489
|
exports2.satisfies = satisfies;
|
|
7490
7490
|
exports2.validate = validate;
|
|
7491
7491
|
exports2.validateStrict = validateStrict;
|
|
@@ -12725,6 +12725,116 @@ var require_emoji_regex2 = __commonJS((exports, module) => {
|
|
|
12725
12725
|
};
|
|
12726
12726
|
});
|
|
12727
12727
|
|
|
12728
|
+
// src/utils/install-error-handler.ts
|
|
12729
|
+
import { existsSync as existsSync5, readFileSync as readFileSync4, unlinkSync as unlinkSync2 } from "node:fs";
|
|
12730
|
+
import { join as join17 } from "node:path";
|
|
12731
|
+
function parseNameReason(str) {
|
|
12732
|
+
const colonIndex = str.indexOf(":");
|
|
12733
|
+
if (colonIndex === -1) {
|
|
12734
|
+
return [str.trim(), undefined];
|
|
12735
|
+
}
|
|
12736
|
+
return [str.slice(0, colonIndex).trim(), str.slice(colonIndex + 1).trim()];
|
|
12737
|
+
}
|
|
12738
|
+
function displayInstallErrors(skillsDir) {
|
|
12739
|
+
const summaryPath = join17(skillsDir, ".install-error-summary.json");
|
|
12740
|
+
if (!existsSync5(summaryPath)) {
|
|
12741
|
+
logger.error("Skills installation failed. Run with --verbose for details.");
|
|
12742
|
+
return;
|
|
12743
|
+
}
|
|
12744
|
+
let summary;
|
|
12745
|
+
try {
|
|
12746
|
+
summary = JSON.parse(readFileSync4(summaryPath, "utf-8"));
|
|
12747
|
+
} catch (parseError) {
|
|
12748
|
+
logger.error("Failed to parse error summary. File may be corrupted.");
|
|
12749
|
+
logger.debug(`Parse error: ${parseError instanceof Error ? parseError.message : String(parseError)}`);
|
|
12750
|
+
return;
|
|
12751
|
+
}
|
|
12752
|
+
try {
|
|
12753
|
+
if (summary.critical_failures.length > 0) {
|
|
12754
|
+
logger.error("");
|
|
12755
|
+
logger.error("━━━ Critical Failures ━━━");
|
|
12756
|
+
for (const failure of summary.critical_failures) {
|
|
12757
|
+
const [name2, reason] = parseNameReason(failure);
|
|
12758
|
+
logger.error(` ✗ ${name2}`);
|
|
12759
|
+
if (reason)
|
|
12760
|
+
logger.error(` Reason: ${reason}`);
|
|
12761
|
+
}
|
|
12762
|
+
logger.error("");
|
|
12763
|
+
logger.error("These must be fixed before skills can work.");
|
|
12764
|
+
}
|
|
12765
|
+
if (summary.optional_failures.length > 0) {
|
|
12766
|
+
logger.warning("");
|
|
12767
|
+
logger.warning("━━━ Optional Package Failures ━━━");
|
|
12768
|
+
for (const failure of summary.optional_failures) {
|
|
12769
|
+
const [name2, reason] = parseNameReason(failure);
|
|
12770
|
+
logger.warning(` ! ${name2}`);
|
|
12771
|
+
if (reason)
|
|
12772
|
+
logger.info(` Reason: ${reason}`);
|
|
12773
|
+
}
|
|
12774
|
+
}
|
|
12775
|
+
if (summary.skipped.length > 0) {
|
|
12776
|
+
logger.info("");
|
|
12777
|
+
logger.info("━━━ Skipped (No sudo) ━━━");
|
|
12778
|
+
for (const skipped of summary.skipped) {
|
|
12779
|
+
const [name2] = parseNameReason(skipped);
|
|
12780
|
+
logger.info(` ~ ${name2}`);
|
|
12781
|
+
}
|
|
12782
|
+
}
|
|
12783
|
+
logger.info("");
|
|
12784
|
+
logger.info("━━━ How to Fix ━━━");
|
|
12785
|
+
logger.info("");
|
|
12786
|
+
if (summary.optional_failures.some((f3) => f3.includes("no wheel") || f3.includes("build tools") || f3.includes("build failed")) && summary.remediation.build_tools) {
|
|
12787
|
+
logger.info("Install build tools (one-time):");
|
|
12788
|
+
logger.info(` ${summary.remediation.build_tools}`);
|
|
12789
|
+
logger.info("");
|
|
12790
|
+
}
|
|
12791
|
+
if (summary.skipped.length > 0 && summary.remediation.sudo_packages) {
|
|
12792
|
+
logger.info("Install system packages:");
|
|
12793
|
+
logger.info(` ${summary.remediation.sudo_packages}`);
|
|
12794
|
+
logger.info("");
|
|
12795
|
+
}
|
|
12796
|
+
if (summary.optional_failures.length > 0 && summary.remediation.pip_retry) {
|
|
12797
|
+
logger.info("Then retry failed packages manually:");
|
|
12798
|
+
logger.info(` ${summary.remediation.pip_retry}`);
|
|
12799
|
+
}
|
|
12800
|
+
try {
|
|
12801
|
+
unlinkSync2(summaryPath);
|
|
12802
|
+
} catch (cleanupError) {
|
|
12803
|
+
if (cleanupError.code !== "ENOENT") {
|
|
12804
|
+
logger.debug(`Failed to cleanup summary file: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`);
|
|
12805
|
+
}
|
|
12806
|
+
}
|
|
12807
|
+
} catch (displayError) {
|
|
12808
|
+
logger.error("Failed to display error summary.");
|
|
12809
|
+
logger.debug(`Display error: ${displayError instanceof Error ? displayError.message : String(displayError)}`);
|
|
12810
|
+
}
|
|
12811
|
+
}
|
|
12812
|
+
async function checkNeedsSudoPackages() {
|
|
12813
|
+
if (process.platform !== "linux") {
|
|
12814
|
+
return false;
|
|
12815
|
+
}
|
|
12816
|
+
const { exec: exec5 } = await import("node:child_process");
|
|
12817
|
+
const { promisify: promisify5 } = await import("node:util");
|
|
12818
|
+
const execAsync5 = promisify5(exec5);
|
|
12819
|
+
try {
|
|
12820
|
+
await Promise.all([
|
|
12821
|
+
execAsync5("which ffmpeg", { timeout: WHICH_COMMAND_TIMEOUT_MS }),
|
|
12822
|
+
execAsync5("which convert", { timeout: WHICH_COMMAND_TIMEOUT_MS })
|
|
12823
|
+
]);
|
|
12824
|
+
return false;
|
|
12825
|
+
} catch {
|
|
12826
|
+
return true;
|
|
12827
|
+
}
|
|
12828
|
+
}
|
|
12829
|
+
function hasInstallState(skillsDir) {
|
|
12830
|
+
const stateFilePath = join17(skillsDir, ".install-state.json");
|
|
12831
|
+
return existsSync5(stateFilePath);
|
|
12832
|
+
}
|
|
12833
|
+
var WHICH_COMMAND_TIMEOUT_MS = 5000;
|
|
12834
|
+
var init_install_error_handler = __esm(() => {
|
|
12835
|
+
init_logger();
|
|
12836
|
+
});
|
|
12837
|
+
|
|
12728
12838
|
// src/utils/package-installer.ts
|
|
12729
12839
|
var exports_package_installer = {};
|
|
12730
12840
|
__export(exports_package_installer, {
|
|
@@ -12741,7 +12851,7 @@ __export(exports_package_installer, {
|
|
|
12741
12851
|
getPackageVersion: () => getPackageVersion
|
|
12742
12852
|
});
|
|
12743
12853
|
import { exec as exec5, execFile as execFile2, spawn } from "node:child_process";
|
|
12744
|
-
import { resolve as resolve2 } from "node:path";
|
|
12854
|
+
import { join as join18, resolve as resolve2 } from "node:path";
|
|
12745
12855
|
import { promisify as promisify5 } from "node:util";
|
|
12746
12856
|
function executeInteractiveScript(command, args, options) {
|
|
12747
12857
|
return new Promise((resolve3, reject) => {
|
|
@@ -12935,9 +13045,8 @@ async function installOpenCode() {
|
|
|
12935
13045
|
try {
|
|
12936
13046
|
logger.info(`Installing ${displayName}...`);
|
|
12937
13047
|
const { unlink: unlink2 } = await import("node:fs/promises");
|
|
12938
|
-
const { join: join17 } = await import("node:path");
|
|
12939
13048
|
const { tmpdir: tmpdir3 } = await import("node:os");
|
|
12940
|
-
const tempScriptPath =
|
|
13049
|
+
const tempScriptPath = join18(tmpdir3(), "opencode-install.sh");
|
|
12941
13050
|
try {
|
|
12942
13051
|
logger.info("Downloading OpenCode installation script...");
|
|
12943
13052
|
await execFileAsync("curl", ["-fsSL", "https://opencode.ai/install", "-o", tempScriptPath], {
|
|
@@ -13047,13 +13156,12 @@ async function installSkillsDependencies(skillsDir) {
|
|
|
13047
13156
|
};
|
|
13048
13157
|
}
|
|
13049
13158
|
try {
|
|
13050
|
-
const { existsSync:
|
|
13159
|
+
const { existsSync: existsSync6 } = await import("node:fs");
|
|
13051
13160
|
const { readFile: readFile9 } = await import("node:fs/promises");
|
|
13052
|
-
const { join: join17 } = await import("node:path");
|
|
13053
13161
|
const clack = await Promise.resolve().then(() => (init_dist2(), exports_dist));
|
|
13054
13162
|
const platform8 = process.platform;
|
|
13055
13163
|
const scriptName = platform8 === "win32" ? "install.ps1" : "install.sh";
|
|
13056
|
-
const scriptPath =
|
|
13164
|
+
const scriptPath = join18(skillsDir, scriptName);
|
|
13057
13165
|
try {
|
|
13058
13166
|
validateScriptPath(skillsDir, scriptPath);
|
|
13059
13167
|
} catch (error) {
|
|
@@ -13065,11 +13173,11 @@ async function installSkillsDependencies(skillsDir) {
|
|
|
13065
13173
|
error: `Path validation failed: ${errorMessage}`
|
|
13066
13174
|
};
|
|
13067
13175
|
}
|
|
13068
|
-
if (!
|
|
13176
|
+
if (!existsSync6(scriptPath)) {
|
|
13069
13177
|
logger.warning(`Skills installation script not found: ${scriptPath}`);
|
|
13070
13178
|
logger.info("");
|
|
13071
13179
|
logger.info("\uD83D\uDCD6 Manual Installation Instructions:");
|
|
13072
|
-
logger.info(` See: ${
|
|
13180
|
+
logger.info(` See: ${join18(skillsDir, "INSTALLATION.md")}`);
|
|
13073
13181
|
logger.info("");
|
|
13074
13182
|
logger.info("Quick start:");
|
|
13075
13183
|
logger.info(" cd .claude/skills/ai-multimodal/scripts");
|
|
@@ -13113,7 +13221,7 @@ async function installSkillsDependencies(skillsDir) {
|
|
|
13113
13221
|
logger.info(` ${platform8 === "win32" ? `powershell -File "${scriptPath}"` : `bash ${scriptPath}`}`);
|
|
13114
13222
|
logger.info("");
|
|
13115
13223
|
logger.info("Or see complete guide:");
|
|
13116
|
-
logger.info(` ${
|
|
13224
|
+
logger.info(` ${join18(skillsDir, "INSTALLATION.md")}`);
|
|
13117
13225
|
return {
|
|
13118
13226
|
success: false,
|
|
13119
13227
|
package: displayName,
|
|
@@ -13122,6 +13230,47 @@ async function installSkillsDependencies(skillsDir) {
|
|
|
13122
13230
|
}
|
|
13123
13231
|
logger.info(`Installing ${displayName}...`);
|
|
13124
13232
|
logger.info(`Running: ${scriptPath}`);
|
|
13233
|
+
const scriptArgs = ["--yes"];
|
|
13234
|
+
if (hasInstallState(skillsDir)) {
|
|
13235
|
+
if (isNonInteractive()) {
|
|
13236
|
+
logger.info("Resuming previous installation (non-interactive mode)...");
|
|
13237
|
+
scriptArgs.push("--resume");
|
|
13238
|
+
} else {
|
|
13239
|
+
const shouldResume = await clack.confirm({
|
|
13240
|
+
message: "Previous installation was interrupted. Resume?",
|
|
13241
|
+
initialValue: true
|
|
13242
|
+
});
|
|
13243
|
+
if (!clack.isCancel(shouldResume) && shouldResume) {
|
|
13244
|
+
scriptArgs.push("--resume");
|
|
13245
|
+
logger.info("Resuming previous installation...");
|
|
13246
|
+
}
|
|
13247
|
+
}
|
|
13248
|
+
}
|
|
13249
|
+
if (platform8 === "linux") {
|
|
13250
|
+
const needsSudo = await checkNeedsSudoPackages();
|
|
13251
|
+
if (needsSudo) {
|
|
13252
|
+
if (isNonInteractive()) {
|
|
13253
|
+
logger.info("Skipping system packages in non-interactive mode.");
|
|
13254
|
+
logger.info("Install manually: sudo apt-get install -y ffmpeg imagemagick");
|
|
13255
|
+
} else {
|
|
13256
|
+
logger.info("");
|
|
13257
|
+
logger.info("System packages (requires sudo):");
|
|
13258
|
+
logger.info(" • ffmpeg - Video/audio processing");
|
|
13259
|
+
logger.info(" • imagemagick - Image editing & conversion");
|
|
13260
|
+
logger.info("");
|
|
13261
|
+
const shouldInstallSudo = await clack.confirm({
|
|
13262
|
+
message: "Install these packages? (requires sudo password)",
|
|
13263
|
+
initialValue: true
|
|
13264
|
+
});
|
|
13265
|
+
if (!clack.isCancel(shouldInstallSudo) && shouldInstallSudo) {
|
|
13266
|
+
scriptArgs.push("--with-sudo");
|
|
13267
|
+
} else {
|
|
13268
|
+
logger.info("Skipping system packages. Install manually later:");
|
|
13269
|
+
logger.info(" sudo apt-get install -y ffmpeg imagemagick");
|
|
13270
|
+
}
|
|
13271
|
+
}
|
|
13272
|
+
}
|
|
13273
|
+
}
|
|
13125
13274
|
const scriptEnv = {
|
|
13126
13275
|
...process.env,
|
|
13127
13276
|
NON_INTERACTIVE: "1"
|
|
@@ -13137,7 +13286,7 @@ async function installSkillsDependencies(skillsDir) {
|
|
|
13137
13286
|
env: scriptEnv
|
|
13138
13287
|
});
|
|
13139
13288
|
} else {
|
|
13140
|
-
await executeInteractiveScript("bash", [scriptPath,
|
|
13289
|
+
await executeInteractiveScript("bash", [scriptPath, ...scriptArgs], {
|
|
13141
13290
|
timeout: 600000,
|
|
13142
13291
|
cwd: skillsDir,
|
|
13143
13292
|
env: scriptEnv
|
|
@@ -13150,13 +13299,34 @@ async function installSkillsDependencies(skillsDir) {
|
|
|
13150
13299
|
};
|
|
13151
13300
|
} catch (error) {
|
|
13152
13301
|
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
13153
|
-
|
|
13302
|
+
const exitCodeMatch = errorMessage.match(/exited with code (\d+)/);
|
|
13303
|
+
const exitCode = exitCodeMatch ? Number.parseInt(exitCodeMatch[1], 10) : 1;
|
|
13304
|
+
if (exitCode === EXIT_CODE_PARTIAL_SUCCESS) {
|
|
13305
|
+
displayInstallErrors(skillsDir);
|
|
13306
|
+
logger.info("");
|
|
13307
|
+
logger.success("Core functionality is available despite some package failures.");
|
|
13308
|
+
return {
|
|
13309
|
+
success: true,
|
|
13310
|
+
package: displayName,
|
|
13311
|
+
version: PARTIAL_INSTALL_VERSION
|
|
13312
|
+
};
|
|
13313
|
+
}
|
|
13314
|
+
if (exitCode === EXIT_CODE_CRITICAL_FAILURE) {
|
|
13315
|
+
displayInstallErrors(skillsDir);
|
|
13316
|
+
logger.error("");
|
|
13317
|
+
logger.error("Skills installation failed. See above for details.");
|
|
13318
|
+
return {
|
|
13319
|
+
success: false,
|
|
13320
|
+
package: displayName,
|
|
13321
|
+
error: "Critical dependencies missing"
|
|
13322
|
+
};
|
|
13323
|
+
}
|
|
13324
|
+
logger.error(`Unexpected error: ${errorMessage}`);
|
|
13154
13325
|
logger.info("");
|
|
13155
13326
|
logger.info("\uD83D\uDCD6 Manual Installation Instructions:");
|
|
13156
13327
|
logger.info("");
|
|
13157
13328
|
logger.info("See complete guide:");
|
|
13158
|
-
|
|
13159
|
-
logger.info(` cat ${join17(skillsDir, "INSTALLATION.md")}`);
|
|
13329
|
+
logger.info(` cat ${join18(skillsDir, "INSTALLATION.md")}`);
|
|
13160
13330
|
logger.info("");
|
|
13161
13331
|
logger.info("Quick start:");
|
|
13162
13332
|
logger.info(" cd .claude/skills/ai-multimodal/scripts");
|
|
@@ -13177,19 +13347,24 @@ async function handleSkillsInstallation(skillsDir) {
|
|
|
13177
13347
|
try {
|
|
13178
13348
|
const skillsResult = await installSkillsDependencies(skillsDir);
|
|
13179
13349
|
if (skillsResult.success) {
|
|
13180
|
-
|
|
13350
|
+
if (skillsResult.version === PARTIAL_INSTALL_VERSION) {
|
|
13351
|
+
logger.success("Skills core dependencies installed (some optional packages skipped)");
|
|
13352
|
+
} else {
|
|
13353
|
+
logger.success("Skills dependencies installed successfully");
|
|
13354
|
+
}
|
|
13181
13355
|
} else {
|
|
13182
|
-
logger.warning(`Skills installation
|
|
13183
|
-
logger.info(
|
|
13356
|
+
logger.warning(`Skills installation incomplete: ${skillsResult.error || "Unknown error"}`);
|
|
13357
|
+
logger.info("You can install skills dependencies manually. See INSTALLATION.md");
|
|
13184
13358
|
}
|
|
13185
|
-
} catch
|
|
13186
|
-
logger.warning(
|
|
13359
|
+
} catch {
|
|
13360
|
+
logger.warning("Skills installation failed");
|
|
13187
13361
|
logger.info("You can install skills dependencies manually later");
|
|
13188
13362
|
}
|
|
13189
13363
|
}
|
|
13190
|
-
var execAsync5, execFileAsync, NPM_PACKAGE_REGEX;
|
|
13364
|
+
var execAsync5, execFileAsync, PARTIAL_INSTALL_VERSION = "partial", EXIT_CODE_CRITICAL_FAILURE = 1, EXIT_CODE_PARTIAL_SUCCESS = 2, NPM_PACKAGE_REGEX;
|
|
13191
13365
|
var init_package_installer = __esm(() => {
|
|
13192
13366
|
init_environment();
|
|
13367
|
+
init_install_error_handler();
|
|
13193
13368
|
init_logger();
|
|
13194
13369
|
execAsync5 = promisify5(exec5);
|
|
13195
13370
|
execFileAsync = promisify5(execFile2);
|
|
@@ -14144,8 +14319,8 @@ var init_help_interceptor = __esm(() => {
|
|
|
14144
14319
|
});
|
|
14145
14320
|
|
|
14146
14321
|
// src/index.ts
|
|
14147
|
-
import { existsSync as
|
|
14148
|
-
import { join as
|
|
14322
|
+
import { existsSync as existsSync8, readFileSync as readFileSync5 } from "fs";
|
|
14323
|
+
import { join as join33 } from "path";
|
|
14149
14324
|
|
|
14150
14325
|
// node_modules/cac/dist/index.mjs
|
|
14151
14326
|
import { EventEmitter } from "events";
|
|
@@ -14750,7 +14925,7 @@ var cac = (name = "") => new CAC(name);
|
|
|
14750
14925
|
// package.json
|
|
14751
14926
|
var package_default = {
|
|
14752
14927
|
name: "claudekit-cli",
|
|
14753
|
-
version: "3.
|
|
14928
|
+
version: "3.6.0",
|
|
14754
14929
|
description: "CLI tool for bootstrapping and updating ClaudeKit projects",
|
|
14755
14930
|
type: "module",
|
|
14756
14931
|
repository: {
|
|
@@ -15408,6 +15583,21 @@ async function installDependency(dependency, method) {
|
|
|
15408
15583
|
// src/lib/health-checks/system-checker.ts
|
|
15409
15584
|
init_logger();
|
|
15410
15585
|
var execAsync3 = promisify3(exec3);
|
|
15586
|
+
var MIN_GH_CLI_VERSION = "2.20.0";
|
|
15587
|
+
function compareVersions2(a3, b3) {
|
|
15588
|
+
const partsA = a3.split(".").map(Number);
|
|
15589
|
+
const partsB = b3.split(".").map(Number);
|
|
15590
|
+
const maxLen = Math.max(partsA.length, partsB.length);
|
|
15591
|
+
for (let i = 0;i < maxLen; i++) {
|
|
15592
|
+
const numA = partsA[i] ?? 0;
|
|
15593
|
+
const numB = partsB[i] ?? 0;
|
|
15594
|
+
if (numA < numB)
|
|
15595
|
+
return -1;
|
|
15596
|
+
if (numA > numB)
|
|
15597
|
+
return 1;
|
|
15598
|
+
}
|
|
15599
|
+
return 0;
|
|
15600
|
+
}
|
|
15411
15601
|
|
|
15412
15602
|
class SystemChecker {
|
|
15413
15603
|
group = "system";
|
|
@@ -15527,12 +15717,25 @@ class SystemChecker {
|
|
|
15527
15717
|
try {
|
|
15528
15718
|
const { stdout } = await execAsync3("gh --version");
|
|
15529
15719
|
const match = stdout.match(/(\d+\.\d+\.\d+)/);
|
|
15720
|
+
const version = match?.[1];
|
|
15721
|
+
if (version && compareVersions2(version, MIN_GH_CLI_VERSION) < 0) {
|
|
15722
|
+
return {
|
|
15723
|
+
id: "gh-cli-version",
|
|
15724
|
+
name: "GitHub CLI",
|
|
15725
|
+
group: "system",
|
|
15726
|
+
status: "warn",
|
|
15727
|
+
message: `v${version} (outdated)`,
|
|
15728
|
+
details: `Minimum required: v${MIN_GH_CLI_VERSION}`,
|
|
15729
|
+
suggestion: this.getGhUpgradeInstructions(),
|
|
15730
|
+
autoFixable: false
|
|
15731
|
+
};
|
|
15732
|
+
}
|
|
15530
15733
|
return {
|
|
15531
15734
|
id: "gh-cli-version",
|
|
15532
15735
|
name: "GitHub CLI",
|
|
15533
15736
|
group: "system",
|
|
15534
15737
|
status: "pass",
|
|
15535
|
-
message:
|
|
15738
|
+
message: version ? `v${version}` : "Installed",
|
|
15536
15739
|
autoFixable: true,
|
|
15537
15740
|
fix: undefined
|
|
15538
15741
|
};
|
|
@@ -15549,6 +15752,13 @@ class SystemChecker {
|
|
|
15549
15752
|
};
|
|
15550
15753
|
}
|
|
15551
15754
|
}
|
|
15755
|
+
getGhUpgradeInstructions() {
|
|
15756
|
+
return `Upgrade GitHub CLI to v${MIN_GH_CLI_VERSION}+:
|
|
15757
|
+
macOS: brew upgrade gh
|
|
15758
|
+
Windows: winget upgrade GitHub.cli
|
|
15759
|
+
Linux: sudo apt update && sudo apt upgrade gh
|
|
15760
|
+
Or visit: https://cli.github.com`;
|
|
15761
|
+
}
|
|
15552
15762
|
createGhCliFix() {
|
|
15553
15763
|
return {
|
|
15554
15764
|
id: "install-gh-cli",
|
|
@@ -17722,7 +17932,7 @@ async function doctorCommand(options = {}) {
|
|
|
17722
17932
|
|
|
17723
17933
|
// src/commands/init.ts
|
|
17724
17934
|
var import_fs_extra17 = __toESM(require_lib(), 1);
|
|
17725
|
-
import { join as
|
|
17935
|
+
import { join as join28, resolve as resolve4 } from "node:path";
|
|
17726
17936
|
|
|
17727
17937
|
// src/lib/commands-prefix.ts
|
|
17728
17938
|
init_logger();
|
|
@@ -28977,7 +29187,7 @@ class FileMerger {
|
|
|
28977
29187
|
const isWindows5 = process.platform === "win32";
|
|
28978
29188
|
let processedContent = content;
|
|
28979
29189
|
if (this.isGlobal) {
|
|
28980
|
-
const homeVar = isWindows5 ? "%USERPROFILE%" : "$HOME";
|
|
29190
|
+
const homeVar = isWindows5 ? '"%USERPROFILE%"' : '"$HOME"';
|
|
28981
29191
|
processedContent = this.transformClaudePaths(content, homeVar);
|
|
28982
29192
|
if (processedContent !== content) {
|
|
28983
29193
|
logger.debug(`Transformed .claude/ paths to ${homeVar}/.claude/ in settings.json for global installation`);
|
|
@@ -28996,12 +29206,17 @@ class FileMerger {
|
|
|
28996
29206
|
}
|
|
28997
29207
|
}
|
|
28998
29208
|
transformClaudePaths(content, prefix) {
|
|
29209
|
+
if (/\.claude\/[^\s"']*[;`$&|><]/.test(content)) {
|
|
29210
|
+
logger.warning("Potentially unsafe characters detected in .claude/ paths");
|
|
29211
|
+
throw new Error("Settings file contains potentially unsafe path characters");
|
|
29212
|
+
}
|
|
28999
29213
|
let transformed = content;
|
|
29000
29214
|
const jsonSafePrefix = prefix.includes('"') ? prefix.replace(/"/g, "\\\"") : prefix;
|
|
29215
|
+
const rawPrefix = prefix.replace(/"/g, "");
|
|
29001
29216
|
transformed = transformed.replace(/(node\s+)(?:\.\/)?\.claude\//g, `$1${jsonSafePrefix}/.claude/`);
|
|
29002
|
-
if (
|
|
29003
|
-
transformed = transformed.replace(/\$CLAUDE_PROJECT_DIR/g,
|
|
29004
|
-
transformed = transformed.replace(/%CLAUDE_PROJECT_DIR%/g,
|
|
29217
|
+
if (rawPrefix.includes("HOME") || rawPrefix.includes("USERPROFILE")) {
|
|
29218
|
+
transformed = transformed.replace(/\$CLAUDE_PROJECT_DIR/g, rawPrefix);
|
|
29219
|
+
transformed = transformed.replace(/%CLAUDE_PROJECT_DIR%/g, rawPrefix);
|
|
29005
29220
|
}
|
|
29006
29221
|
return transformed;
|
|
29007
29222
|
}
|
|
@@ -29870,11 +30085,11 @@ class PromptsManager {
|
|
|
29870
30085
|
init_dist2();
|
|
29871
30086
|
init_logger();
|
|
29872
30087
|
var import_fs_extra10 = __toESM(require_lib(), 1);
|
|
29873
|
-
import { join as
|
|
30088
|
+
import { join as join20 } from "node:path";
|
|
29874
30089
|
|
|
29875
30090
|
// src/lib/config-generator.ts
|
|
29876
30091
|
var import_fs_extra9 = __toESM(require_lib(), 1);
|
|
29877
|
-
import { join as
|
|
30092
|
+
import { join as join19 } from "node:path";
|
|
29878
30093
|
async function generateEnvFile(targetDir, values) {
|
|
29879
30094
|
const lines = [
|
|
29880
30095
|
"# Generated by ClaudeKit CLI setup wizard",
|
|
@@ -29886,7 +30101,7 @@ async function generateEnvFile(targetDir, values) {
|
|
|
29886
30101
|
lines.push(`${key}=${value}`);
|
|
29887
30102
|
}
|
|
29888
30103
|
}
|
|
29889
|
-
const envPath =
|
|
30104
|
+
const envPath = join19(targetDir, ".env");
|
|
29890
30105
|
await import_fs_extra9.writeFile(envPath, `${lines.join(`
|
|
29891
30106
|
`)}
|
|
29892
30107
|
`, { mode: 384 });
|
|
@@ -29957,7 +30172,7 @@ async function parseEnvFile(path9) {
|
|
|
29957
30172
|
}
|
|
29958
30173
|
}
|
|
29959
30174
|
async function checkGlobalConfig() {
|
|
29960
|
-
const globalEnvPath =
|
|
30175
|
+
const globalEnvPath = join20(PathResolver.getGlobalKitDir(), ".env");
|
|
29961
30176
|
if (!await import_fs_extra10.pathExists(globalEnvPath))
|
|
29962
30177
|
return false;
|
|
29963
30178
|
const env2 = await parseEnvFile(globalEnvPath);
|
|
@@ -29973,7 +30188,7 @@ async function runSetupWizard(options) {
|
|
|
29973
30188
|
let globalEnv = {};
|
|
29974
30189
|
const hasGlobalConfig = !isGlobal && await checkGlobalConfig();
|
|
29975
30190
|
if (!isGlobal) {
|
|
29976
|
-
const globalEnvPath =
|
|
30191
|
+
const globalEnvPath = join20(PathResolver.getGlobalKitDir(), ".env");
|
|
29977
30192
|
if (await import_fs_extra10.pathExists(globalEnvPath)) {
|
|
29978
30193
|
globalEnv = await parseEnvFile(globalEnvPath);
|
|
29979
30194
|
}
|
|
@@ -30026,7 +30241,7 @@ async function runSetupWizard(options) {
|
|
|
30026
30241
|
}
|
|
30027
30242
|
}
|
|
30028
30243
|
await generateEnvFile(targetDir, values);
|
|
30029
|
-
f2.success(`Configuration saved to ${
|
|
30244
|
+
f2.success(`Configuration saved to ${join20(targetDir, ".env")}`);
|
|
30030
30245
|
return true;
|
|
30031
30246
|
}
|
|
30032
30247
|
|
|
@@ -30034,7 +30249,7 @@ async function runSetupWizard(options) {
|
|
|
30034
30249
|
init_logger();
|
|
30035
30250
|
var import_fs_extra12 = __toESM(require_lib(), 1);
|
|
30036
30251
|
import { readdir as readdir8 } from "node:fs/promises";
|
|
30037
|
-
import { join as
|
|
30252
|
+
import { join as join22 } from "node:path";
|
|
30038
30253
|
|
|
30039
30254
|
// src/lib/skills-manifest.ts
|
|
30040
30255
|
init_types2();
|
|
@@ -30042,7 +30257,7 @@ init_logger();
|
|
|
30042
30257
|
var import_fs_extra11 = __toESM(require_lib(), 1);
|
|
30043
30258
|
import { createHash as createHash2 } from "node:crypto";
|
|
30044
30259
|
import { readFile as readFile10, readdir as readdir7, writeFile as writeFile9 } from "node:fs/promises";
|
|
30045
|
-
import { join as
|
|
30260
|
+
import { join as join21, relative as relative6 } from "node:path";
|
|
30046
30261
|
|
|
30047
30262
|
class SkillsManifestManager {
|
|
30048
30263
|
static MANIFEST_FILENAME = ".skills-manifest.json";
|
|
@@ -30064,12 +30279,12 @@ class SkillsManifestManager {
|
|
|
30064
30279
|
return manifest;
|
|
30065
30280
|
}
|
|
30066
30281
|
static async writeManifest(skillsDir, manifest) {
|
|
30067
|
-
const manifestPath =
|
|
30282
|
+
const manifestPath = join21(skillsDir, SkillsManifestManager.MANIFEST_FILENAME);
|
|
30068
30283
|
await writeFile9(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
30069
30284
|
logger.debug(`Wrote manifest to: ${manifestPath}`);
|
|
30070
30285
|
}
|
|
30071
30286
|
static async readManifest(skillsDir) {
|
|
30072
|
-
const manifestPath =
|
|
30287
|
+
const manifestPath = join21(skillsDir, SkillsManifestManager.MANIFEST_FILENAME);
|
|
30073
30288
|
if (!await import_fs_extra11.pathExists(manifestPath)) {
|
|
30074
30289
|
logger.debug(`No manifest found at: ${manifestPath}`);
|
|
30075
30290
|
return null;
|
|
@@ -30092,7 +30307,7 @@ class SkillsManifestManager {
|
|
|
30092
30307
|
return "flat";
|
|
30093
30308
|
}
|
|
30094
30309
|
for (const dir of dirs.slice(0, 3)) {
|
|
30095
|
-
const dirPath =
|
|
30310
|
+
const dirPath = join21(skillsDir, dir.name);
|
|
30096
30311
|
const subEntries = await readdir7(dirPath, { withFileTypes: true });
|
|
30097
30312
|
const hasSubdirs = subEntries.some((entry) => entry.isDirectory());
|
|
30098
30313
|
if (hasSubdirs) {
|
|
@@ -30111,7 +30326,7 @@ class SkillsManifestManager {
|
|
|
30111
30326
|
const entries = await readdir7(skillsDir, { withFileTypes: true });
|
|
30112
30327
|
for (const entry of entries) {
|
|
30113
30328
|
if (entry.isDirectory() && entry.name !== "node_modules" && !entry.name.startsWith(".")) {
|
|
30114
|
-
const skillPath =
|
|
30329
|
+
const skillPath = join21(skillsDir, entry.name);
|
|
30115
30330
|
const hash = await SkillsManifestManager.hashDirectory(skillPath);
|
|
30116
30331
|
skills.push({
|
|
30117
30332
|
name: entry.name,
|
|
@@ -30123,11 +30338,11 @@ class SkillsManifestManager {
|
|
|
30123
30338
|
const categories = await readdir7(skillsDir, { withFileTypes: true });
|
|
30124
30339
|
for (const category of categories) {
|
|
30125
30340
|
if (category.isDirectory() && category.name !== "node_modules" && !category.name.startsWith(".")) {
|
|
30126
|
-
const categoryPath =
|
|
30341
|
+
const categoryPath = join21(skillsDir, category.name);
|
|
30127
30342
|
const skillEntries = await readdir7(categoryPath, { withFileTypes: true });
|
|
30128
30343
|
for (const skillEntry of skillEntries) {
|
|
30129
30344
|
if (skillEntry.isDirectory() && !skillEntry.name.startsWith(".")) {
|
|
30130
|
-
const skillPath =
|
|
30345
|
+
const skillPath = join21(categoryPath, skillEntry.name);
|
|
30131
30346
|
const hash = await SkillsManifestManager.hashDirectory(skillPath);
|
|
30132
30347
|
skills.push({
|
|
30133
30348
|
name: skillEntry.name,
|
|
@@ -30157,7 +30372,7 @@ class SkillsManifestManager {
|
|
|
30157
30372
|
const files = [];
|
|
30158
30373
|
const entries = await readdir7(dirPath, { withFileTypes: true });
|
|
30159
30374
|
for (const entry of entries) {
|
|
30160
|
-
const fullPath =
|
|
30375
|
+
const fullPath = join21(dirPath, entry.name);
|
|
30161
30376
|
if (entry.name.startsWith(".") || entry.name === "node_modules") {
|
|
30162
30377
|
continue;
|
|
30163
30378
|
}
|
|
@@ -30400,12 +30615,12 @@ class SkillsMigrationDetector {
|
|
|
30400
30615
|
let totalSkillLikeCount = 0;
|
|
30401
30616
|
const allSkills = [];
|
|
30402
30617
|
for (const dir of dirs) {
|
|
30403
|
-
const dirPath =
|
|
30618
|
+
const dirPath = join22(skillsDir, dir.name);
|
|
30404
30619
|
const subEntries = await readdir8(dirPath, { withFileTypes: true });
|
|
30405
30620
|
const subdirs = subEntries.filter((entry) => entry.isDirectory() && !entry.name.startsWith("."));
|
|
30406
30621
|
if (subdirs.length > 0) {
|
|
30407
30622
|
for (const subdir of subdirs.slice(0, 3)) {
|
|
30408
|
-
const subdirPath =
|
|
30623
|
+
const subdirPath = join22(dirPath, subdir.name);
|
|
30409
30624
|
const subdirFiles = await readdir8(subdirPath, { withFileTypes: true });
|
|
30410
30625
|
const hasSkillMarker = subdirFiles.some((file) => file.isFile() && (file.name === "skill.md" || file.name === "README.md" || file.name === "readme.md" || file.name === "config.json" || file.name === "package.json"));
|
|
30411
30626
|
if (hasSkillMarker) {
|
|
@@ -30444,14 +30659,14 @@ init_types2();
|
|
|
30444
30659
|
init_logger();
|
|
30445
30660
|
var import_fs_extra15 = __toESM(require_lib(), 1);
|
|
30446
30661
|
import { copyFile as copyFile2, mkdir as mkdir7, readdir as readdir11, rm as rm2 } from "node:fs/promises";
|
|
30447
|
-
import { join as
|
|
30662
|
+
import { join as join25 } from "node:path";
|
|
30448
30663
|
|
|
30449
30664
|
// src/lib/skills-backup-manager.ts
|
|
30450
30665
|
init_types2();
|
|
30451
30666
|
init_logger();
|
|
30452
30667
|
var import_fs_extra13 = __toESM(require_lib(), 1);
|
|
30453
30668
|
import { copyFile, mkdir as mkdir6, readdir as readdir9, rm, stat as stat4 } from "node:fs/promises";
|
|
30454
|
-
import { basename as basename2, join as
|
|
30669
|
+
import { basename as basename2, join as join23, normalize as normalize2 } from "node:path";
|
|
30455
30670
|
function validatePath2(path9, paramName) {
|
|
30456
30671
|
if (!path9 || typeof path9 !== "string") {
|
|
30457
30672
|
throw new SkillsMigrationError(`${paramName} must be a non-empty string`);
|
|
@@ -30477,7 +30692,7 @@ class SkillsBackupManager {
|
|
|
30477
30692
|
const timestamp = Date.now();
|
|
30478
30693
|
const randomSuffix = Math.random().toString(36).substring(2, 8);
|
|
30479
30694
|
const backupDirName = `${SkillsBackupManager.BACKUP_PREFIX}${timestamp}-${randomSuffix}`;
|
|
30480
|
-
const backupDir = parentDir ?
|
|
30695
|
+
const backupDir = parentDir ? join23(parentDir, backupDirName) : join23(skillsDir, "..", backupDirName);
|
|
30481
30696
|
logger.info(`Creating backup at: ${backupDir}`);
|
|
30482
30697
|
try {
|
|
30483
30698
|
await mkdir6(backupDir, { recursive: true });
|
|
@@ -30528,7 +30743,7 @@ class SkillsBackupManager {
|
|
|
30528
30743
|
}
|
|
30529
30744
|
try {
|
|
30530
30745
|
const entries = await readdir9(parentDir, { withFileTypes: true });
|
|
30531
|
-
const backups = entries.filter((entry) => entry.isDirectory() && entry.name.startsWith(SkillsBackupManager.BACKUP_PREFIX)).map((entry) =>
|
|
30746
|
+
const backups = entries.filter((entry) => entry.isDirectory() && entry.name.startsWith(SkillsBackupManager.BACKUP_PREFIX)).map((entry) => join23(parentDir, entry.name));
|
|
30532
30747
|
backups.sort().reverse();
|
|
30533
30748
|
return backups;
|
|
30534
30749
|
} catch (error) {
|
|
@@ -30556,8 +30771,8 @@ class SkillsBackupManager {
|
|
|
30556
30771
|
static async copyDirectory(sourceDir, destDir) {
|
|
30557
30772
|
const entries = await readdir9(sourceDir, { withFileTypes: true });
|
|
30558
30773
|
for (const entry of entries) {
|
|
30559
|
-
const sourcePath =
|
|
30560
|
-
const destPath =
|
|
30774
|
+
const sourcePath = join23(sourceDir, entry.name);
|
|
30775
|
+
const destPath = join23(destDir, entry.name);
|
|
30561
30776
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.isSymbolicLink()) {
|
|
30562
30777
|
continue;
|
|
30563
30778
|
}
|
|
@@ -30573,7 +30788,7 @@ class SkillsBackupManager {
|
|
|
30573
30788
|
let size = 0;
|
|
30574
30789
|
const entries = await readdir9(dirPath, { withFileTypes: true });
|
|
30575
30790
|
for (const entry of entries) {
|
|
30576
|
-
const fullPath =
|
|
30791
|
+
const fullPath = join23(dirPath, entry.name);
|
|
30577
30792
|
if (entry.isSymbolicLink()) {
|
|
30578
30793
|
continue;
|
|
30579
30794
|
}
|
|
@@ -30604,7 +30819,7 @@ var import_fs_extra14 = __toESM(require_lib(), 1);
|
|
|
30604
30819
|
import { createHash as createHash3 } from "node:crypto";
|
|
30605
30820
|
import { createReadStream as createReadStream2 } from "node:fs";
|
|
30606
30821
|
import { readFile as readFile11, readdir as readdir10 } from "node:fs/promises";
|
|
30607
|
-
import { join as
|
|
30822
|
+
import { join as join24, normalize as normalize3, relative as relative7 } from "node:path";
|
|
30608
30823
|
function validatePath3(path9, paramName) {
|
|
30609
30824
|
if (!path9 || typeof path9 !== "string") {
|
|
30610
30825
|
throw new SkillsMigrationError(`${paramName} must be a non-empty string`);
|
|
@@ -30751,13 +30966,13 @@ class SkillsCustomizationScanner {
|
|
|
30751
30966
|
if (dirs.length === 0) {
|
|
30752
30967
|
return ["flat", []];
|
|
30753
30968
|
}
|
|
30754
|
-
const firstDirPath =
|
|
30969
|
+
const firstDirPath = join24(skillsDir, dirs[0].name);
|
|
30755
30970
|
const subEntries = await readdir10(firstDirPath, { withFileTypes: true });
|
|
30756
30971
|
const subdirs = subEntries.filter((entry) => entry.isDirectory() && !entry.name.startsWith("."));
|
|
30757
30972
|
if (subdirs.length > 0) {
|
|
30758
30973
|
let skillLikeCount = 0;
|
|
30759
30974
|
for (const subdir of subdirs.slice(0, 3)) {
|
|
30760
|
-
const subdirPath =
|
|
30975
|
+
const subdirPath = join24(firstDirPath, subdir.name);
|
|
30761
30976
|
const subdirFiles = await readdir10(subdirPath, { withFileTypes: true });
|
|
30762
30977
|
const hasSkillMarker = subdirFiles.some((file) => file.isFile() && (file.name === "skill.md" || file.name === "README.md" || file.name === "readme.md" || file.name === "config.json" || file.name === "package.json"));
|
|
30763
30978
|
if (hasSkillMarker) {
|
|
@@ -30767,7 +30982,7 @@ class SkillsCustomizationScanner {
|
|
|
30767
30982
|
if (skillLikeCount > 0) {
|
|
30768
30983
|
const skills = [];
|
|
30769
30984
|
for (const dir of dirs) {
|
|
30770
|
-
const categoryPath =
|
|
30985
|
+
const categoryPath = join24(skillsDir, dir.name);
|
|
30771
30986
|
const skillDirs = await readdir10(categoryPath, { withFileTypes: true });
|
|
30772
30987
|
skills.push(...skillDirs.filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name));
|
|
30773
30988
|
}
|
|
@@ -30777,7 +30992,7 @@ class SkillsCustomizationScanner {
|
|
|
30777
30992
|
return ["flat", dirs.map((dir) => dir.name)];
|
|
30778
30993
|
}
|
|
30779
30994
|
static async findSkillPath(skillsDir, skillName) {
|
|
30780
|
-
const flatPath =
|
|
30995
|
+
const flatPath = join24(skillsDir, skillName);
|
|
30781
30996
|
if (await import_fs_extra14.pathExists(flatPath)) {
|
|
30782
30997
|
return { path: flatPath, category: undefined };
|
|
30783
30998
|
}
|
|
@@ -30786,8 +31001,8 @@ class SkillsCustomizationScanner {
|
|
|
30786
31001
|
if (!entry.isDirectory() || entry.name.startsWith(".") || entry.name === "node_modules") {
|
|
30787
31002
|
continue;
|
|
30788
31003
|
}
|
|
30789
|
-
const categoryPath =
|
|
30790
|
-
const skillPath =
|
|
31004
|
+
const categoryPath = join24(skillsDir, entry.name);
|
|
31005
|
+
const skillPath = join24(categoryPath, skillName);
|
|
30791
31006
|
if (await import_fs_extra14.pathExists(skillPath)) {
|
|
30792
31007
|
return { path: skillPath, category: entry.name };
|
|
30793
31008
|
}
|
|
@@ -30798,7 +31013,7 @@ class SkillsCustomizationScanner {
|
|
|
30798
31013
|
const files = [];
|
|
30799
31014
|
const entries = await readdir10(dirPath, { withFileTypes: true });
|
|
30800
31015
|
for (const entry of entries) {
|
|
30801
|
-
const fullPath =
|
|
31016
|
+
const fullPath = join24(dirPath, entry.name);
|
|
30802
31017
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.isSymbolicLink()) {
|
|
30803
31018
|
continue;
|
|
30804
31019
|
}
|
|
@@ -31041,7 +31256,7 @@ class SkillsMigrator {
|
|
|
31041
31256
|
}
|
|
31042
31257
|
}
|
|
31043
31258
|
if (options.backup && !options.dryRun) {
|
|
31044
|
-
const claudeDir =
|
|
31259
|
+
const claudeDir = join25(currentSkillsDir, "..");
|
|
31045
31260
|
result.backupPath = await SkillsBackupManager.createBackup(currentSkillsDir, claudeDir);
|
|
31046
31261
|
logger.success(`Backup created at: ${result.backupPath}`);
|
|
31047
31262
|
}
|
|
@@ -31093,7 +31308,7 @@ class SkillsMigrator {
|
|
|
31093
31308
|
const migrated = [];
|
|
31094
31309
|
const preserved = [];
|
|
31095
31310
|
const errors2 = [];
|
|
31096
|
-
const tempDir =
|
|
31311
|
+
const tempDir = join25(currentSkillsDir, "..", ".skills-migration-temp");
|
|
31097
31312
|
await mkdir7(tempDir, { recursive: true });
|
|
31098
31313
|
try {
|
|
31099
31314
|
for (const mapping of mappings) {
|
|
@@ -31114,9 +31329,9 @@ class SkillsMigrator {
|
|
|
31114
31329
|
}
|
|
31115
31330
|
}
|
|
31116
31331
|
const category = mapping.category;
|
|
31117
|
-
const targetPath = category ?
|
|
31332
|
+
const targetPath = category ? join25(tempDir, category, skillName) : join25(tempDir, skillName);
|
|
31118
31333
|
if (category) {
|
|
31119
|
-
await mkdir7(
|
|
31334
|
+
await mkdir7(join25(tempDir, category), { recursive: true });
|
|
31120
31335
|
}
|
|
31121
31336
|
await SkillsMigrator.copySkillDirectory(currentSkillPath, targetPath);
|
|
31122
31337
|
migrated.push(skillName);
|
|
@@ -31150,8 +31365,8 @@ class SkillsMigrator {
|
|
|
31150
31365
|
await mkdir7(destDir, { recursive: true });
|
|
31151
31366
|
const entries = await readdir11(sourceDir, { withFileTypes: true });
|
|
31152
31367
|
for (const entry of entries) {
|
|
31153
|
-
const sourcePath =
|
|
31154
|
-
const destPath =
|
|
31368
|
+
const sourcePath = join25(sourceDir, entry.name);
|
|
31369
|
+
const destPath = join25(destDir, entry.name);
|
|
31155
31370
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.isSymbolicLink()) {
|
|
31156
31371
|
continue;
|
|
31157
31372
|
}
|
|
@@ -31170,18 +31385,18 @@ init_types2();
|
|
|
31170
31385
|
// src/utils/config.ts
|
|
31171
31386
|
init_types2();
|
|
31172
31387
|
init_logger();
|
|
31173
|
-
import { existsSync as
|
|
31388
|
+
import { existsSync as existsSync6 } from "node:fs";
|
|
31174
31389
|
import { mkdir as mkdir8, readFile as readFile12, rename as rename2, rm as rm3, writeFile as writeFile10 } from "node:fs/promises";
|
|
31175
31390
|
import { chmod as chmod2 } from "node:fs/promises";
|
|
31176
31391
|
import { platform as platform8 } from "node:os";
|
|
31177
|
-
import { join as
|
|
31392
|
+
import { join as join26 } from "node:path";
|
|
31178
31393
|
var PROJECT_CONFIG_FILE = ".ck.json";
|
|
31179
31394
|
|
|
31180
31395
|
class ConfigManager {
|
|
31181
31396
|
static config = null;
|
|
31182
31397
|
static globalFlag = false;
|
|
31183
31398
|
static getProjectConfigDir(projectDir, global3) {
|
|
31184
|
-
return global3 ? projectDir :
|
|
31399
|
+
return global3 ? projectDir : join26(projectDir, ".claude");
|
|
31185
31400
|
}
|
|
31186
31401
|
static setGlobalFlag(global3) {
|
|
31187
31402
|
ConfigManager.globalFlag = global3;
|
|
@@ -31196,7 +31411,7 @@ class ConfigManager {
|
|
|
31196
31411
|
}
|
|
31197
31412
|
const configFile = PathResolver.getConfigFile(ConfigManager.globalFlag);
|
|
31198
31413
|
try {
|
|
31199
|
-
if (
|
|
31414
|
+
if (existsSync6(configFile)) {
|
|
31200
31415
|
const content = await readFile12(configFile, "utf-8");
|
|
31201
31416
|
const data = JSON.parse(content);
|
|
31202
31417
|
ConfigManager.config = ConfigSchema.parse(data);
|
|
@@ -31214,7 +31429,7 @@ class ConfigManager {
|
|
|
31214
31429
|
const validConfig = ConfigSchema.parse(config);
|
|
31215
31430
|
const configDir = PathResolver.getConfigDir(ConfigManager.globalFlag);
|
|
31216
31431
|
const configFile = PathResolver.getConfigFile(ConfigManager.globalFlag);
|
|
31217
|
-
if (!
|
|
31432
|
+
if (!existsSync6(configDir)) {
|
|
31218
31433
|
await mkdir8(configDir, { recursive: true });
|
|
31219
31434
|
if (platform8() !== "win32") {
|
|
31220
31435
|
await chmod2(configDir, 448);
|
|
@@ -31248,9 +31463,9 @@ class ConfigManager {
|
|
|
31248
31463
|
}
|
|
31249
31464
|
static async loadProjectConfig(projectDir, global3 = false) {
|
|
31250
31465
|
const configDir = ConfigManager.getProjectConfigDir(projectDir, global3);
|
|
31251
|
-
const configPath =
|
|
31466
|
+
const configPath = join26(configDir, PROJECT_CONFIG_FILE);
|
|
31252
31467
|
try {
|
|
31253
|
-
if (
|
|
31468
|
+
if (existsSync6(configPath)) {
|
|
31254
31469
|
const content = await readFile12(configPath, "utf-8");
|
|
31255
31470
|
const data = JSON.parse(content);
|
|
31256
31471
|
const folders = FoldersConfigSchema.parse(data.paths || data);
|
|
@@ -31264,9 +31479,9 @@ class ConfigManager {
|
|
|
31264
31479
|
}
|
|
31265
31480
|
static async saveProjectConfig(projectDir, folders, global3 = false) {
|
|
31266
31481
|
const configDir = ConfigManager.getProjectConfigDir(projectDir, global3);
|
|
31267
|
-
const configPath =
|
|
31482
|
+
const configPath = join26(configDir, PROJECT_CONFIG_FILE);
|
|
31268
31483
|
try {
|
|
31269
|
-
if (!
|
|
31484
|
+
if (!existsSync6(configDir)) {
|
|
31270
31485
|
await mkdir8(configDir, { recursive: true });
|
|
31271
31486
|
}
|
|
31272
31487
|
const validFolders = FoldersConfigSchema.parse(folders);
|
|
@@ -31296,21 +31511,21 @@ class ConfigManager {
|
|
|
31296
31511
|
}
|
|
31297
31512
|
static projectConfigExists(projectDir, global3 = false) {
|
|
31298
31513
|
const configDir = ConfigManager.getProjectConfigDir(projectDir, global3);
|
|
31299
|
-
return
|
|
31514
|
+
return existsSync6(join26(configDir, PROJECT_CONFIG_FILE));
|
|
31300
31515
|
}
|
|
31301
31516
|
static async migrateNestedConfig(globalDir) {
|
|
31302
|
-
const correctPath =
|
|
31303
|
-
const incorrectPath =
|
|
31304
|
-
if (
|
|
31517
|
+
const correctPath = join26(globalDir, PROJECT_CONFIG_FILE);
|
|
31518
|
+
const incorrectPath = join26(globalDir, ".claude", PROJECT_CONFIG_FILE);
|
|
31519
|
+
if (existsSync6(correctPath)) {
|
|
31305
31520
|
logger.debug("Config already exists at correct location, skipping migration");
|
|
31306
31521
|
return false;
|
|
31307
31522
|
}
|
|
31308
|
-
if (
|
|
31523
|
+
if (existsSync6(incorrectPath)) {
|
|
31309
31524
|
try {
|
|
31310
31525
|
logger.info("Migrating .ck.json from nested location to correct location...");
|
|
31311
31526
|
await rename2(incorrectPath, correctPath);
|
|
31312
31527
|
logger.success(`Migrated ${PROJECT_CONFIG_FILE} to ${correctPath}`);
|
|
31313
|
-
const nestedClaudeDir =
|
|
31528
|
+
const nestedClaudeDir = join26(globalDir, ".claude");
|
|
31314
31529
|
try {
|
|
31315
31530
|
await rm3(nestedClaudeDir, { recursive: false });
|
|
31316
31531
|
logger.debug("Removed empty nested .claude directory");
|
|
@@ -31333,7 +31548,7 @@ init_environment();
|
|
|
31333
31548
|
// src/utils/file-scanner.ts
|
|
31334
31549
|
init_logger();
|
|
31335
31550
|
var import_fs_extra16 = __toESM(require_lib(), 1);
|
|
31336
|
-
import { join as
|
|
31551
|
+
import { join as join27, relative as relative8, resolve as resolve3 } from "node:path";
|
|
31337
31552
|
var SKIP_DIRS = [
|
|
31338
31553
|
"node_modules",
|
|
31339
31554
|
".venv",
|
|
@@ -31360,7 +31575,7 @@ class FileScanner {
|
|
|
31360
31575
|
logger.debug(`Skipping directory: ${entry}`);
|
|
31361
31576
|
continue;
|
|
31362
31577
|
}
|
|
31363
|
-
const fullPath =
|
|
31578
|
+
const fullPath = join27(dirPath, entry);
|
|
31364
31579
|
if (!FileScanner.isSafePath(basePath, fullPath)) {
|
|
31365
31580
|
logger.warning(`Skipping potentially unsafe path: ${entry}`);
|
|
31366
31581
|
continue;
|
|
@@ -31395,8 +31610,8 @@ class FileScanner {
|
|
|
31395
31610
|
return files;
|
|
31396
31611
|
}
|
|
31397
31612
|
static async findCustomFiles(destDir, sourceDir, subPath) {
|
|
31398
|
-
const destSubDir =
|
|
31399
|
-
const sourceSubDir =
|
|
31613
|
+
const destSubDir = join27(destDir, subPath);
|
|
31614
|
+
const sourceSubDir = join27(sourceDir, subPath);
|
|
31400
31615
|
const destFiles = await FileScanner.getFiles(destSubDir, destDir);
|
|
31401
31616
|
const sourceFiles = await FileScanner.getFiles(sourceSubDir, sourceDir);
|
|
31402
31617
|
const sourceFileSet = new Set(sourceFiles);
|
|
@@ -31437,7 +31652,7 @@ async function initCommand(options) {
|
|
|
31437
31652
|
logger.info("Running in non-interactive mode (--yes flag)");
|
|
31438
31653
|
}
|
|
31439
31654
|
if (validOptions.global) {
|
|
31440
|
-
const localSettingsPath =
|
|
31655
|
+
const localSettingsPath = join28(process.cwd(), ".claude", "settings.json");
|
|
31441
31656
|
if (await import_fs_extra17.pathExists(localSettingsPath)) {
|
|
31442
31657
|
if (isNonInteractive2) {
|
|
31443
31658
|
logger.warning("Local .claude/settings.json detected. Local settings take precedence over global.");
|
|
@@ -31449,7 +31664,7 @@ async function initCommand(options) {
|
|
|
31449
31664
|
return;
|
|
31450
31665
|
}
|
|
31451
31666
|
if (choice === "remove") {
|
|
31452
|
-
const localClaudeDir =
|
|
31667
|
+
const localClaudeDir = join28(process.cwd(), ".claude");
|
|
31453
31668
|
try {
|
|
31454
31669
|
await import_fs_extra17.remove(localClaudeDir);
|
|
31455
31670
|
logger.success("Removed local .claude/ directory");
|
|
@@ -31508,7 +31723,7 @@ async function initCommand(options) {
|
|
|
31508
31723
|
}
|
|
31509
31724
|
if (validOptions.fresh) {
|
|
31510
31725
|
const prefix = PathResolver.getPathPrefix(validOptions.global);
|
|
31511
|
-
const claudeDir2 = prefix ?
|
|
31726
|
+
const claudeDir2 = prefix ? join28(resolvedDir, prefix) : resolvedDir;
|
|
31512
31727
|
const canProceed = await handleFreshInstallation(claudeDir2, prompts);
|
|
31513
31728
|
if (!canProceed) {
|
|
31514
31729
|
return;
|
|
@@ -31645,7 +31860,7 @@ async function initCommand(options) {
|
|
|
31645
31860
|
}
|
|
31646
31861
|
}
|
|
31647
31862
|
if (!validOptions.fresh) {
|
|
31648
|
-
const newSkillsDir =
|
|
31863
|
+
const newSkillsDir = join28(extractDir, ".claude", "skills");
|
|
31649
31864
|
const currentSkillsDir = PathResolver.buildSkillsPath(resolvedDir, validOptions.global);
|
|
31650
31865
|
if (await import_fs_extra17.pathExists(newSkillsDir) && await import_fs_extra17.pathExists(currentSkillsDir)) {
|
|
31651
31866
|
logger.info("Checking for skills directory migration...");
|
|
@@ -31670,7 +31885,7 @@ async function initCommand(options) {
|
|
|
31670
31885
|
let customClaudeFiles = [];
|
|
31671
31886
|
if (!validOptions.fresh) {
|
|
31672
31887
|
logger.info("Scanning for custom .claude files...");
|
|
31673
|
-
const scanSourceDir = validOptions.global ?
|
|
31888
|
+
const scanSourceDir = validOptions.global ? join28(extractDir, ".claude") : extractDir;
|
|
31674
31889
|
const scanTargetSubdir = validOptions.global ? "" : ".claude";
|
|
31675
31890
|
customClaudeFiles = await FileScanner.findCustomFiles(resolvedDir, scanSourceDir, scanTargetSubdir);
|
|
31676
31891
|
} else {
|
|
@@ -31699,7 +31914,7 @@ async function initCommand(options) {
|
|
|
31699
31914
|
merger.addIgnorePatterns(validOptions.exclude);
|
|
31700
31915
|
}
|
|
31701
31916
|
merger.setGlobalFlag(validOptions.global);
|
|
31702
|
-
const claudeDir = validOptions.global ? resolvedDir :
|
|
31917
|
+
const claudeDir = validOptions.global ? resolvedDir : join28(resolvedDir, ".claude");
|
|
31703
31918
|
const releaseManifest = await ReleaseManifestLoader.load(extractDir);
|
|
31704
31919
|
if (!validOptions.fresh && await import_fs_extra17.pathExists(claudeDir)) {
|
|
31705
31920
|
const legacyDetection = await LegacyMigration.detectLegacy(claudeDir);
|
|
@@ -31721,7 +31936,7 @@ async function initCommand(options) {
|
|
|
31721
31936
|
return;
|
|
31722
31937
|
}
|
|
31723
31938
|
}
|
|
31724
|
-
const sourceDir = validOptions.global ?
|
|
31939
|
+
const sourceDir = validOptions.global ? join28(extractDir, ".claude") : extractDir;
|
|
31725
31940
|
await merger.merge(sourceDir, resolvedDir, false);
|
|
31726
31941
|
const manifestWriter = new ManifestWriter;
|
|
31727
31942
|
const installedFiles = merger.getAllInstalledFiles();
|
|
@@ -31730,7 +31945,7 @@ async function initCommand(options) {
|
|
|
31730
31945
|
if (!validOptions.global && !installedPath.startsWith(".claude/"))
|
|
31731
31946
|
continue;
|
|
31732
31947
|
const relativePath = validOptions.global ? installedPath : installedPath.replace(/^\.claude\//, "");
|
|
31733
|
-
const filePath =
|
|
31948
|
+
const filePath = join28(claudeDir, relativePath);
|
|
31734
31949
|
const manifestEntry = releaseManifest ? ReleaseManifestLoader.findFile(releaseManifest, installedPath) : null;
|
|
31735
31950
|
const ownership = manifestEntry ? "ck" : "user";
|
|
31736
31951
|
filesToTrack.push({
|
|
@@ -31751,8 +31966,8 @@ async function initCommand(options) {
|
|
|
31751
31966
|
trackingSpinner.succeed(`Tracked ${trackResult.success} files`);
|
|
31752
31967
|
await manifestWriter.writeManifest(claudeDir, kitConfig.name, release.tag_name, validOptions.global ? "global" : "local");
|
|
31753
31968
|
if (validOptions.global) {
|
|
31754
|
-
const claudeMdSource =
|
|
31755
|
-
const claudeMdDest =
|
|
31969
|
+
const claudeMdSource = join28(extractDir, "CLAUDE.md");
|
|
31970
|
+
const claudeMdDest = join28(resolvedDir, "CLAUDE.md");
|
|
31756
31971
|
if (await import_fs_extra17.pathExists(claudeMdSource)) {
|
|
31757
31972
|
if (!await import_fs_extra17.pathExists(claudeMdDest)) {
|
|
31758
31973
|
await import_fs_extra17.copy(claudeMdSource, claudeMdDest);
|
|
@@ -31772,7 +31987,7 @@ async function initCommand(options) {
|
|
|
31772
31987
|
await handleSkillsInstallation2(skillsDir);
|
|
31773
31988
|
}
|
|
31774
31989
|
if (!validOptions.skipSetup && !isNonInteractive2) {
|
|
31775
|
-
const envPath =
|
|
31990
|
+
const envPath = join28(claudeDir, ".env");
|
|
31776
31991
|
if (!await import_fs_extra17.pathExists(envPath)) {
|
|
31777
31992
|
const shouldSetup = await prompts.confirm("Set up API keys now? (Gemini API key for ai-multimodal skill, optional webhooks)");
|
|
31778
31993
|
if (shouldSetup) {
|
|
@@ -31804,7 +32019,7 @@ Protected files (.env, etc.) were not modified.`;
|
|
|
31804
32019
|
|
|
31805
32020
|
// src/commands/new.ts
|
|
31806
32021
|
var import_fs_extra18 = __toESM(require_lib(), 1);
|
|
31807
|
-
import { join as
|
|
32022
|
+
import { join as join29, resolve as resolve5 } from "node:path";
|
|
31808
32023
|
init_types2();
|
|
31809
32024
|
init_environment();
|
|
31810
32025
|
init_logger();
|
|
@@ -31975,7 +32190,7 @@ async function newCommand(options) {
|
|
|
31975
32190
|
await CommandsPrefix.cleanupCommandsDirectory(resolvedDir, false);
|
|
31976
32191
|
}
|
|
31977
32192
|
await merger.merge(extractDir, resolvedDir, true);
|
|
31978
|
-
const claudeDir =
|
|
32193
|
+
const claudeDir = join29(resolvedDir, ".claude");
|
|
31979
32194
|
const manifestWriter = new ManifestWriter;
|
|
31980
32195
|
const releaseManifest = await ReleaseManifestLoader.load(extractDir);
|
|
31981
32196
|
const installedFiles = merger.getAllInstalledFiles();
|
|
@@ -31984,7 +32199,7 @@ async function newCommand(options) {
|
|
|
31984
32199
|
if (!installedPath.startsWith(".claude/"))
|
|
31985
32200
|
continue;
|
|
31986
32201
|
const relativePath = installedPath.replace(/^\.claude\//, "");
|
|
31987
|
-
const filePath =
|
|
32202
|
+
const filePath = join29(claudeDir, relativePath);
|
|
31988
32203
|
const manifestEntry = releaseManifest ? ReleaseManifestLoader.findFile(releaseManifest, installedPath) : null;
|
|
31989
32204
|
const ownership = manifestEntry ? "ck" : "user";
|
|
31990
32205
|
filesToTrack.push({
|
|
@@ -32040,7 +32255,7 @@ init_dist2();
|
|
|
32040
32255
|
var import_fs_extra19 = __toESM(require_lib(), 1);
|
|
32041
32256
|
var import_picocolors10 = __toESM(require_picocolors(), 1);
|
|
32042
32257
|
import { readdirSync, rmSync } from "node:fs";
|
|
32043
|
-
import { dirname as dirname4, join as
|
|
32258
|
+
import { dirname as dirname4, join as join30 } from "node:path";
|
|
32044
32259
|
init_types2();
|
|
32045
32260
|
init_logger();
|
|
32046
32261
|
async function detectInstallations() {
|
|
@@ -32131,7 +32346,7 @@ async function analyzeInstallation(installation, forceOverwrite) {
|
|
|
32131
32346
|
return result;
|
|
32132
32347
|
}
|
|
32133
32348
|
for (const trackedFile of metadata.files) {
|
|
32134
|
-
const filePath =
|
|
32349
|
+
const filePath = join30(installation.path, trackedFile.path);
|
|
32135
32350
|
const ownershipResult = await OwnershipChecker.checkOwnership(filePath, metadata, installation.path);
|
|
32136
32351
|
if (!ownershipResult.exists)
|
|
32137
32352
|
continue;
|
|
@@ -32189,7 +32404,7 @@ async function removeInstallations(installations, options) {
|
|
|
32189
32404
|
let removedCount = 0;
|
|
32190
32405
|
let cleanedDirs = 0;
|
|
32191
32406
|
for (const item of analysis.toDelete) {
|
|
32192
|
-
const filePath =
|
|
32407
|
+
const filePath = join30(installation.path, item.path);
|
|
32193
32408
|
if (await import_fs_extra19.pathExists(filePath)) {
|
|
32194
32409
|
await import_fs_extra19.remove(filePath);
|
|
32195
32410
|
removedCount++;
|
|
@@ -32291,7 +32506,7 @@ import { promisify as promisify6 } from "node:util";
|
|
|
32291
32506
|
// package.json
|
|
32292
32507
|
var package_default2 = {
|
|
32293
32508
|
name: "claudekit-cli",
|
|
32294
|
-
version: "3.
|
|
32509
|
+
version: "3.6.0",
|
|
32295
32510
|
description: "CLI tool for bootstrapping and updating ClaudeKit projects",
|
|
32296
32511
|
type: "module",
|
|
32297
32512
|
repository: {
|
|
@@ -32736,20 +32951,20 @@ var import_picocolors12 = __toESM(require_picocolors(), 1);
|
|
|
32736
32951
|
|
|
32737
32952
|
// src/lib/version-cache.ts
|
|
32738
32953
|
init_logger();
|
|
32739
|
-
import { existsSync as
|
|
32954
|
+
import { existsSync as existsSync7 } from "node:fs";
|
|
32740
32955
|
import { mkdir as mkdir9, readFile as readFile13, writeFile as writeFile11 } from "node:fs/promises";
|
|
32741
|
-
import { join as
|
|
32956
|
+
import { join as join31 } from "node:path";
|
|
32742
32957
|
class VersionCacheManager {
|
|
32743
32958
|
static CACHE_FILENAME = "version-check.json";
|
|
32744
32959
|
static CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000;
|
|
32745
32960
|
static getCacheFile() {
|
|
32746
32961
|
const cacheDir = PathResolver.getCacheDir(false);
|
|
32747
|
-
return
|
|
32962
|
+
return join31(cacheDir, VersionCacheManager.CACHE_FILENAME);
|
|
32748
32963
|
}
|
|
32749
32964
|
static async load() {
|
|
32750
32965
|
const cacheFile = VersionCacheManager.getCacheFile();
|
|
32751
32966
|
try {
|
|
32752
|
-
if (!
|
|
32967
|
+
if (!existsSync7(cacheFile)) {
|
|
32753
32968
|
logger.debug("Version check cache not found");
|
|
32754
32969
|
return null;
|
|
32755
32970
|
}
|
|
@@ -32770,7 +32985,7 @@ class VersionCacheManager {
|
|
|
32770
32985
|
const cacheFile = VersionCacheManager.getCacheFile();
|
|
32771
32986
|
const cacheDir = PathResolver.getCacheDir(false);
|
|
32772
32987
|
try {
|
|
32773
|
-
if (!
|
|
32988
|
+
if (!existsSync7(cacheDir)) {
|
|
32774
32989
|
await mkdir9(cacheDir, { recursive: true, mode: 448 });
|
|
32775
32990
|
}
|
|
32776
32991
|
await writeFile11(cacheFile, JSON.stringify(cache2, null, 2), "utf-8");
|
|
@@ -32792,7 +33007,7 @@ class VersionCacheManager {
|
|
|
32792
33007
|
static async clear() {
|
|
32793
33008
|
const cacheFile = VersionCacheManager.getCacheFile();
|
|
32794
33009
|
try {
|
|
32795
|
-
if (
|
|
33010
|
+
if (existsSync7(cacheFile)) {
|
|
32796
33011
|
const fs12 = await import("node:fs/promises");
|
|
32797
33012
|
await fs12.unlink(cacheFile);
|
|
32798
33013
|
logger.debug("Version check cache cleared");
|
|
@@ -33220,7 +33435,7 @@ var logger2 = new Logger2;
|
|
|
33220
33435
|
|
|
33221
33436
|
// src/utils/path-resolver.ts
|
|
33222
33437
|
import { homedir as homedir2, platform as platform9 } from "node:os";
|
|
33223
|
-
import { join as
|
|
33438
|
+
import { join as join32, normalize as normalize4 } from "node:path";
|
|
33224
33439
|
|
|
33225
33440
|
class PathResolver2 {
|
|
33226
33441
|
static getTestHomeDir() {
|
|
@@ -33253,50 +33468,50 @@ class PathResolver2 {
|
|
|
33253
33468
|
static getConfigDir(global3 = false) {
|
|
33254
33469
|
const testHome = PathResolver2.getTestHomeDir();
|
|
33255
33470
|
if (testHome) {
|
|
33256
|
-
return global3 ?
|
|
33471
|
+
return global3 ? join32(testHome, ".config", "claude") : join32(testHome, ".claudekit");
|
|
33257
33472
|
}
|
|
33258
33473
|
if (!global3) {
|
|
33259
|
-
return
|
|
33474
|
+
return join32(homedir2(), ".claudekit");
|
|
33260
33475
|
}
|
|
33261
33476
|
const os2 = platform9();
|
|
33262
33477
|
if (os2 === "win32") {
|
|
33263
|
-
const localAppData = process.env.LOCALAPPDATA ||
|
|
33264
|
-
return
|
|
33478
|
+
const localAppData = process.env.LOCALAPPDATA || join32(homedir2(), "AppData", "Local");
|
|
33479
|
+
return join32(localAppData, "claude");
|
|
33265
33480
|
}
|
|
33266
33481
|
const xdgConfigHome = process.env.XDG_CONFIG_HOME;
|
|
33267
33482
|
if (xdgConfigHome) {
|
|
33268
|
-
return
|
|
33483
|
+
return join32(xdgConfigHome, "claude");
|
|
33269
33484
|
}
|
|
33270
|
-
return
|
|
33485
|
+
return join32(homedir2(), ".config", "claude");
|
|
33271
33486
|
}
|
|
33272
33487
|
static getConfigFile(global3 = false) {
|
|
33273
|
-
return
|
|
33488
|
+
return join32(PathResolver2.getConfigDir(global3), "config.json");
|
|
33274
33489
|
}
|
|
33275
33490
|
static getCacheDir(global3 = false) {
|
|
33276
33491
|
const testHome = PathResolver2.getTestHomeDir();
|
|
33277
33492
|
if (testHome) {
|
|
33278
|
-
return global3 ?
|
|
33493
|
+
return global3 ? join32(testHome, ".cache", "claude") : join32(testHome, ".claudekit", "cache");
|
|
33279
33494
|
}
|
|
33280
33495
|
if (!global3) {
|
|
33281
|
-
return
|
|
33496
|
+
return join32(homedir2(), ".claudekit", "cache");
|
|
33282
33497
|
}
|
|
33283
33498
|
const os2 = platform9();
|
|
33284
33499
|
if (os2 === "win32") {
|
|
33285
|
-
const localAppData = process.env.LOCALAPPDATA ||
|
|
33286
|
-
return
|
|
33500
|
+
const localAppData = process.env.LOCALAPPDATA || join32(homedir2(), "AppData", "Local");
|
|
33501
|
+
return join32(localAppData, "claude", "cache");
|
|
33287
33502
|
}
|
|
33288
33503
|
const xdgCacheHome = process.env.XDG_CACHE_HOME;
|
|
33289
33504
|
if (xdgCacheHome) {
|
|
33290
|
-
return
|
|
33505
|
+
return join32(xdgCacheHome, "claude");
|
|
33291
33506
|
}
|
|
33292
|
-
return
|
|
33507
|
+
return join32(homedir2(), ".cache", "claude");
|
|
33293
33508
|
}
|
|
33294
33509
|
static getGlobalKitDir() {
|
|
33295
33510
|
const testHome = PathResolver2.getTestHomeDir();
|
|
33296
33511
|
if (testHome) {
|
|
33297
|
-
return
|
|
33512
|
+
return join32(testHome, ".claude");
|
|
33298
33513
|
}
|
|
33299
|
-
return
|
|
33514
|
+
return join32(homedir2(), ".claude");
|
|
33300
33515
|
}
|
|
33301
33516
|
static getPathPrefix(global3) {
|
|
33302
33517
|
return global3 ? "" : ".claude";
|
|
@@ -33304,9 +33519,9 @@ class PathResolver2 {
|
|
|
33304
33519
|
static buildSkillsPath(baseDir, global3) {
|
|
33305
33520
|
const prefix = PathResolver2.getPathPrefix(global3);
|
|
33306
33521
|
if (prefix) {
|
|
33307
|
-
return
|
|
33522
|
+
return join32(baseDir, prefix, "skills");
|
|
33308
33523
|
}
|
|
33309
|
-
return
|
|
33524
|
+
return join32(baseDir, "skills");
|
|
33310
33525
|
}
|
|
33311
33526
|
static buildComponentPath(baseDir, component, global3) {
|
|
33312
33527
|
if (!PathResolver2.isPathSafe(component)) {
|
|
@@ -33314,9 +33529,9 @@ class PathResolver2 {
|
|
|
33314
33529
|
}
|
|
33315
33530
|
const prefix = PathResolver2.getPathPrefix(global3);
|
|
33316
33531
|
if (prefix) {
|
|
33317
|
-
return
|
|
33532
|
+
return join32(baseDir, prefix, component);
|
|
33318
33533
|
}
|
|
33319
|
-
return
|
|
33534
|
+
return join32(baseDir, component);
|
|
33320
33535
|
}
|
|
33321
33536
|
}
|
|
33322
33537
|
|
|
@@ -33334,13 +33549,13 @@ async function displayVersion() {
|
|
|
33334
33549
|
let localKitVersion = null;
|
|
33335
33550
|
let isGlobalOnlyKit = false;
|
|
33336
33551
|
const globalKitDir = PathResolver2.getGlobalKitDir();
|
|
33337
|
-
const globalMetadataPath =
|
|
33552
|
+
const globalMetadataPath = join33(globalKitDir, "metadata.json");
|
|
33338
33553
|
const prefix = PathResolver2.getPathPrefix(false);
|
|
33339
|
-
const localMetadataPath = prefix ?
|
|
33554
|
+
const localMetadataPath = prefix ? join33(process.cwd(), prefix, "metadata.json") : join33(process.cwd(), "metadata.json");
|
|
33340
33555
|
const isLocalSameAsGlobal = localMetadataPath === globalMetadataPath;
|
|
33341
|
-
if (!isLocalSameAsGlobal &&
|
|
33556
|
+
if (!isLocalSameAsGlobal && existsSync8(localMetadataPath)) {
|
|
33342
33557
|
try {
|
|
33343
|
-
const rawMetadata = JSON.parse(
|
|
33558
|
+
const rawMetadata = JSON.parse(readFileSync5(localMetadataPath, "utf-8"));
|
|
33344
33559
|
const metadata = MetadataSchema2.parse(rawMetadata);
|
|
33345
33560
|
if (metadata.version) {
|
|
33346
33561
|
const kitName = metadata.name || "ClaudeKit";
|
|
@@ -33352,9 +33567,9 @@ async function displayVersion() {
|
|
|
33352
33567
|
logger2.verbose("Failed to parse local metadata.json", { error });
|
|
33353
33568
|
}
|
|
33354
33569
|
}
|
|
33355
|
-
if (
|
|
33570
|
+
if (existsSync8(globalMetadataPath)) {
|
|
33356
33571
|
try {
|
|
33357
|
-
const rawMetadata = JSON.parse(
|
|
33572
|
+
const rawMetadata = JSON.parse(readFileSync5(globalMetadataPath, "utf-8"));
|
|
33358
33573
|
const metadata = MetadataSchema2.parse(rawMetadata);
|
|
33359
33574
|
if (metadata.version) {
|
|
33360
33575
|
const kitName = metadata.name || "ClaudeKit";
|