claudekit-cli 3.5.2 → 3.6.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 +333 -136
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -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.1",
|
|
14754
14929
|
description: "CLI tool for bootstrapping and updating ClaudeKit projects",
|
|
14755
14930
|
type: "module",
|
|
14756
14931
|
repository: {
|
|
@@ -16459,6 +16634,7 @@ Note: Do NOT use 'Paste an authentication token' - use web browser login.`);
|
|
|
16459
16634
|
if (token && token.length > 0) {
|
|
16460
16635
|
return token;
|
|
16461
16636
|
}
|
|
16637
|
+
logger.debug("gh auth token returned empty result");
|
|
16462
16638
|
return null;
|
|
16463
16639
|
} catch (error) {
|
|
16464
16640
|
if (error?.stderr) {
|
|
@@ -17757,7 +17933,7 @@ async function doctorCommand(options = {}) {
|
|
|
17757
17933
|
|
|
17758
17934
|
// src/commands/init.ts
|
|
17759
17935
|
var import_fs_extra17 = __toESM(require_lib(), 1);
|
|
17760
|
-
import { join as
|
|
17936
|
+
import { join as join28, resolve as resolve4 } from "node:path";
|
|
17761
17937
|
|
|
17762
17938
|
// src/lib/commands-prefix.ts
|
|
17763
17939
|
init_logger();
|
|
@@ -29012,7 +29188,7 @@ class FileMerger {
|
|
|
29012
29188
|
const isWindows5 = process.platform === "win32";
|
|
29013
29189
|
let processedContent = content;
|
|
29014
29190
|
if (this.isGlobal) {
|
|
29015
|
-
const homeVar = isWindows5 ? "%USERPROFILE%" : "$HOME";
|
|
29191
|
+
const homeVar = isWindows5 ? '"%USERPROFILE%"' : '"$HOME"';
|
|
29016
29192
|
processedContent = this.transformClaudePaths(content, homeVar);
|
|
29017
29193
|
if (processedContent !== content) {
|
|
29018
29194
|
logger.debug(`Transformed .claude/ paths to ${homeVar}/.claude/ in settings.json for global installation`);
|
|
@@ -29031,12 +29207,17 @@ class FileMerger {
|
|
|
29031
29207
|
}
|
|
29032
29208
|
}
|
|
29033
29209
|
transformClaudePaths(content, prefix) {
|
|
29210
|
+
if (/\.claude\/[^\s"']*[;`$&|><]/.test(content)) {
|
|
29211
|
+
logger.warning("Potentially unsafe characters detected in .claude/ paths");
|
|
29212
|
+
throw new Error("Settings file contains potentially unsafe path characters");
|
|
29213
|
+
}
|
|
29034
29214
|
let transformed = content;
|
|
29035
29215
|
const jsonSafePrefix = prefix.includes('"') ? prefix.replace(/"/g, "\\\"") : prefix;
|
|
29216
|
+
const rawPrefix = prefix.replace(/"/g, "");
|
|
29036
29217
|
transformed = transformed.replace(/(node\s+)(?:\.\/)?\.claude\//g, `$1${jsonSafePrefix}/.claude/`);
|
|
29037
|
-
if (
|
|
29038
|
-
transformed = transformed.replace(/\$CLAUDE_PROJECT_DIR/g,
|
|
29039
|
-
transformed = transformed.replace(/%CLAUDE_PROJECT_DIR%/g,
|
|
29218
|
+
if (rawPrefix.includes("HOME") || rawPrefix.includes("USERPROFILE")) {
|
|
29219
|
+
transformed = transformed.replace(/\$CLAUDE_PROJECT_DIR/g, rawPrefix);
|
|
29220
|
+
transformed = transformed.replace(/%CLAUDE_PROJECT_DIR%/g, rawPrefix);
|
|
29040
29221
|
}
|
|
29041
29222
|
return transformed;
|
|
29042
29223
|
}
|
|
@@ -29905,11 +30086,11 @@ class PromptsManager {
|
|
|
29905
30086
|
init_dist2();
|
|
29906
30087
|
init_logger();
|
|
29907
30088
|
var import_fs_extra10 = __toESM(require_lib(), 1);
|
|
29908
|
-
import { join as
|
|
30089
|
+
import { join as join20 } from "node:path";
|
|
29909
30090
|
|
|
29910
30091
|
// src/lib/config-generator.ts
|
|
29911
30092
|
var import_fs_extra9 = __toESM(require_lib(), 1);
|
|
29912
|
-
import { join as
|
|
30093
|
+
import { join as join19 } from "node:path";
|
|
29913
30094
|
async function generateEnvFile(targetDir, values) {
|
|
29914
30095
|
const lines = [
|
|
29915
30096
|
"# Generated by ClaudeKit CLI setup wizard",
|
|
@@ -29921,7 +30102,7 @@ async function generateEnvFile(targetDir, values) {
|
|
|
29921
30102
|
lines.push(`${key}=${value}`);
|
|
29922
30103
|
}
|
|
29923
30104
|
}
|
|
29924
|
-
const envPath =
|
|
30105
|
+
const envPath = join19(targetDir, ".env");
|
|
29925
30106
|
await import_fs_extra9.writeFile(envPath, `${lines.join(`
|
|
29926
30107
|
`)}
|
|
29927
30108
|
`, { mode: 384 });
|
|
@@ -29992,7 +30173,7 @@ async function parseEnvFile(path9) {
|
|
|
29992
30173
|
}
|
|
29993
30174
|
}
|
|
29994
30175
|
async function checkGlobalConfig() {
|
|
29995
|
-
const globalEnvPath =
|
|
30176
|
+
const globalEnvPath = join20(PathResolver.getGlobalKitDir(), ".env");
|
|
29996
30177
|
if (!await import_fs_extra10.pathExists(globalEnvPath))
|
|
29997
30178
|
return false;
|
|
29998
30179
|
const env2 = await parseEnvFile(globalEnvPath);
|
|
@@ -30008,7 +30189,7 @@ async function runSetupWizard(options) {
|
|
|
30008
30189
|
let globalEnv = {};
|
|
30009
30190
|
const hasGlobalConfig = !isGlobal && await checkGlobalConfig();
|
|
30010
30191
|
if (!isGlobal) {
|
|
30011
|
-
const globalEnvPath =
|
|
30192
|
+
const globalEnvPath = join20(PathResolver.getGlobalKitDir(), ".env");
|
|
30012
30193
|
if (await import_fs_extra10.pathExists(globalEnvPath)) {
|
|
30013
30194
|
globalEnv = await parseEnvFile(globalEnvPath);
|
|
30014
30195
|
}
|
|
@@ -30061,7 +30242,7 @@ async function runSetupWizard(options) {
|
|
|
30061
30242
|
}
|
|
30062
30243
|
}
|
|
30063
30244
|
await generateEnvFile(targetDir, values);
|
|
30064
|
-
f2.success(`Configuration saved to ${
|
|
30245
|
+
f2.success(`Configuration saved to ${join20(targetDir, ".env")}`);
|
|
30065
30246
|
return true;
|
|
30066
30247
|
}
|
|
30067
30248
|
|
|
@@ -30069,7 +30250,7 @@ async function runSetupWizard(options) {
|
|
|
30069
30250
|
init_logger();
|
|
30070
30251
|
var import_fs_extra12 = __toESM(require_lib(), 1);
|
|
30071
30252
|
import { readdir as readdir8 } from "node:fs/promises";
|
|
30072
|
-
import { join as
|
|
30253
|
+
import { join as join22 } from "node:path";
|
|
30073
30254
|
|
|
30074
30255
|
// src/lib/skills-manifest.ts
|
|
30075
30256
|
init_types2();
|
|
@@ -30077,7 +30258,7 @@ init_logger();
|
|
|
30077
30258
|
var import_fs_extra11 = __toESM(require_lib(), 1);
|
|
30078
30259
|
import { createHash as createHash2 } from "node:crypto";
|
|
30079
30260
|
import { readFile as readFile10, readdir as readdir7, writeFile as writeFile9 } from "node:fs/promises";
|
|
30080
|
-
import { join as
|
|
30261
|
+
import { join as join21, relative as relative6 } from "node:path";
|
|
30081
30262
|
|
|
30082
30263
|
class SkillsManifestManager {
|
|
30083
30264
|
static MANIFEST_FILENAME = ".skills-manifest.json";
|
|
@@ -30099,12 +30280,12 @@ class SkillsManifestManager {
|
|
|
30099
30280
|
return manifest;
|
|
30100
30281
|
}
|
|
30101
30282
|
static async writeManifest(skillsDir, manifest) {
|
|
30102
|
-
const manifestPath =
|
|
30283
|
+
const manifestPath = join21(skillsDir, SkillsManifestManager.MANIFEST_FILENAME);
|
|
30103
30284
|
await writeFile9(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
30104
30285
|
logger.debug(`Wrote manifest to: ${manifestPath}`);
|
|
30105
30286
|
}
|
|
30106
30287
|
static async readManifest(skillsDir) {
|
|
30107
|
-
const manifestPath =
|
|
30288
|
+
const manifestPath = join21(skillsDir, SkillsManifestManager.MANIFEST_FILENAME);
|
|
30108
30289
|
if (!await import_fs_extra11.pathExists(manifestPath)) {
|
|
30109
30290
|
logger.debug(`No manifest found at: ${manifestPath}`);
|
|
30110
30291
|
return null;
|
|
@@ -30127,7 +30308,7 @@ class SkillsManifestManager {
|
|
|
30127
30308
|
return "flat";
|
|
30128
30309
|
}
|
|
30129
30310
|
for (const dir of dirs.slice(0, 3)) {
|
|
30130
|
-
const dirPath =
|
|
30311
|
+
const dirPath = join21(skillsDir, dir.name);
|
|
30131
30312
|
const subEntries = await readdir7(dirPath, { withFileTypes: true });
|
|
30132
30313
|
const hasSubdirs = subEntries.some((entry) => entry.isDirectory());
|
|
30133
30314
|
if (hasSubdirs) {
|
|
@@ -30146,7 +30327,7 @@ class SkillsManifestManager {
|
|
|
30146
30327
|
const entries = await readdir7(skillsDir, { withFileTypes: true });
|
|
30147
30328
|
for (const entry of entries) {
|
|
30148
30329
|
if (entry.isDirectory() && entry.name !== "node_modules" && !entry.name.startsWith(".")) {
|
|
30149
|
-
const skillPath =
|
|
30330
|
+
const skillPath = join21(skillsDir, entry.name);
|
|
30150
30331
|
const hash = await SkillsManifestManager.hashDirectory(skillPath);
|
|
30151
30332
|
skills.push({
|
|
30152
30333
|
name: entry.name,
|
|
@@ -30158,11 +30339,11 @@ class SkillsManifestManager {
|
|
|
30158
30339
|
const categories = await readdir7(skillsDir, { withFileTypes: true });
|
|
30159
30340
|
for (const category of categories) {
|
|
30160
30341
|
if (category.isDirectory() && category.name !== "node_modules" && !category.name.startsWith(".")) {
|
|
30161
|
-
const categoryPath =
|
|
30342
|
+
const categoryPath = join21(skillsDir, category.name);
|
|
30162
30343
|
const skillEntries = await readdir7(categoryPath, { withFileTypes: true });
|
|
30163
30344
|
for (const skillEntry of skillEntries) {
|
|
30164
30345
|
if (skillEntry.isDirectory() && !skillEntry.name.startsWith(".")) {
|
|
30165
|
-
const skillPath =
|
|
30346
|
+
const skillPath = join21(categoryPath, skillEntry.name);
|
|
30166
30347
|
const hash = await SkillsManifestManager.hashDirectory(skillPath);
|
|
30167
30348
|
skills.push({
|
|
30168
30349
|
name: skillEntry.name,
|
|
@@ -30192,7 +30373,7 @@ class SkillsManifestManager {
|
|
|
30192
30373
|
const files = [];
|
|
30193
30374
|
const entries = await readdir7(dirPath, { withFileTypes: true });
|
|
30194
30375
|
for (const entry of entries) {
|
|
30195
|
-
const fullPath =
|
|
30376
|
+
const fullPath = join21(dirPath, entry.name);
|
|
30196
30377
|
if (entry.name.startsWith(".") || entry.name === "node_modules") {
|
|
30197
30378
|
continue;
|
|
30198
30379
|
}
|
|
@@ -30435,12 +30616,12 @@ class SkillsMigrationDetector {
|
|
|
30435
30616
|
let totalSkillLikeCount = 0;
|
|
30436
30617
|
const allSkills = [];
|
|
30437
30618
|
for (const dir of dirs) {
|
|
30438
|
-
const dirPath =
|
|
30619
|
+
const dirPath = join22(skillsDir, dir.name);
|
|
30439
30620
|
const subEntries = await readdir8(dirPath, { withFileTypes: true });
|
|
30440
30621
|
const subdirs = subEntries.filter((entry) => entry.isDirectory() && !entry.name.startsWith("."));
|
|
30441
30622
|
if (subdirs.length > 0) {
|
|
30442
30623
|
for (const subdir of subdirs.slice(0, 3)) {
|
|
30443
|
-
const subdirPath =
|
|
30624
|
+
const subdirPath = join22(dirPath, subdir.name);
|
|
30444
30625
|
const subdirFiles = await readdir8(subdirPath, { withFileTypes: true });
|
|
30445
30626
|
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"));
|
|
30446
30627
|
if (hasSkillMarker) {
|
|
@@ -30479,14 +30660,14 @@ init_types2();
|
|
|
30479
30660
|
init_logger();
|
|
30480
30661
|
var import_fs_extra15 = __toESM(require_lib(), 1);
|
|
30481
30662
|
import { copyFile as copyFile2, mkdir as mkdir7, readdir as readdir11, rm as rm2 } from "node:fs/promises";
|
|
30482
|
-
import { join as
|
|
30663
|
+
import { join as join25 } from "node:path";
|
|
30483
30664
|
|
|
30484
30665
|
// src/lib/skills-backup-manager.ts
|
|
30485
30666
|
init_types2();
|
|
30486
30667
|
init_logger();
|
|
30487
30668
|
var import_fs_extra13 = __toESM(require_lib(), 1);
|
|
30488
30669
|
import { copyFile, mkdir as mkdir6, readdir as readdir9, rm, stat as stat4 } from "node:fs/promises";
|
|
30489
|
-
import { basename as basename2, join as
|
|
30670
|
+
import { basename as basename2, join as join23, normalize as normalize2 } from "node:path";
|
|
30490
30671
|
function validatePath2(path9, paramName) {
|
|
30491
30672
|
if (!path9 || typeof path9 !== "string") {
|
|
30492
30673
|
throw new SkillsMigrationError(`${paramName} must be a non-empty string`);
|
|
@@ -30512,7 +30693,7 @@ class SkillsBackupManager {
|
|
|
30512
30693
|
const timestamp = Date.now();
|
|
30513
30694
|
const randomSuffix = Math.random().toString(36).substring(2, 8);
|
|
30514
30695
|
const backupDirName = `${SkillsBackupManager.BACKUP_PREFIX}${timestamp}-${randomSuffix}`;
|
|
30515
|
-
const backupDir = parentDir ?
|
|
30696
|
+
const backupDir = parentDir ? join23(parentDir, backupDirName) : join23(skillsDir, "..", backupDirName);
|
|
30516
30697
|
logger.info(`Creating backup at: ${backupDir}`);
|
|
30517
30698
|
try {
|
|
30518
30699
|
await mkdir6(backupDir, { recursive: true });
|
|
@@ -30563,7 +30744,7 @@ class SkillsBackupManager {
|
|
|
30563
30744
|
}
|
|
30564
30745
|
try {
|
|
30565
30746
|
const entries = await readdir9(parentDir, { withFileTypes: true });
|
|
30566
|
-
const backups = entries.filter((entry) => entry.isDirectory() && entry.name.startsWith(SkillsBackupManager.BACKUP_PREFIX)).map((entry) =>
|
|
30747
|
+
const backups = entries.filter((entry) => entry.isDirectory() && entry.name.startsWith(SkillsBackupManager.BACKUP_PREFIX)).map((entry) => join23(parentDir, entry.name));
|
|
30567
30748
|
backups.sort().reverse();
|
|
30568
30749
|
return backups;
|
|
30569
30750
|
} catch (error) {
|
|
@@ -30591,8 +30772,8 @@ class SkillsBackupManager {
|
|
|
30591
30772
|
static async copyDirectory(sourceDir, destDir) {
|
|
30592
30773
|
const entries = await readdir9(sourceDir, { withFileTypes: true });
|
|
30593
30774
|
for (const entry of entries) {
|
|
30594
|
-
const sourcePath =
|
|
30595
|
-
const destPath =
|
|
30775
|
+
const sourcePath = join23(sourceDir, entry.name);
|
|
30776
|
+
const destPath = join23(destDir, entry.name);
|
|
30596
30777
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.isSymbolicLink()) {
|
|
30597
30778
|
continue;
|
|
30598
30779
|
}
|
|
@@ -30608,7 +30789,7 @@ class SkillsBackupManager {
|
|
|
30608
30789
|
let size = 0;
|
|
30609
30790
|
const entries = await readdir9(dirPath, { withFileTypes: true });
|
|
30610
30791
|
for (const entry of entries) {
|
|
30611
|
-
const fullPath =
|
|
30792
|
+
const fullPath = join23(dirPath, entry.name);
|
|
30612
30793
|
if (entry.isSymbolicLink()) {
|
|
30613
30794
|
continue;
|
|
30614
30795
|
}
|
|
@@ -30639,7 +30820,7 @@ var import_fs_extra14 = __toESM(require_lib(), 1);
|
|
|
30639
30820
|
import { createHash as createHash3 } from "node:crypto";
|
|
30640
30821
|
import { createReadStream as createReadStream2 } from "node:fs";
|
|
30641
30822
|
import { readFile as readFile11, readdir as readdir10 } from "node:fs/promises";
|
|
30642
|
-
import { join as
|
|
30823
|
+
import { join as join24, normalize as normalize3, relative as relative7 } from "node:path";
|
|
30643
30824
|
function validatePath3(path9, paramName) {
|
|
30644
30825
|
if (!path9 || typeof path9 !== "string") {
|
|
30645
30826
|
throw new SkillsMigrationError(`${paramName} must be a non-empty string`);
|
|
@@ -30786,13 +30967,13 @@ class SkillsCustomizationScanner {
|
|
|
30786
30967
|
if (dirs.length === 0) {
|
|
30787
30968
|
return ["flat", []];
|
|
30788
30969
|
}
|
|
30789
|
-
const firstDirPath =
|
|
30970
|
+
const firstDirPath = join24(skillsDir, dirs[0].name);
|
|
30790
30971
|
const subEntries = await readdir10(firstDirPath, { withFileTypes: true });
|
|
30791
30972
|
const subdirs = subEntries.filter((entry) => entry.isDirectory() && !entry.name.startsWith("."));
|
|
30792
30973
|
if (subdirs.length > 0) {
|
|
30793
30974
|
let skillLikeCount = 0;
|
|
30794
30975
|
for (const subdir of subdirs.slice(0, 3)) {
|
|
30795
|
-
const subdirPath =
|
|
30976
|
+
const subdirPath = join24(firstDirPath, subdir.name);
|
|
30796
30977
|
const subdirFiles = await readdir10(subdirPath, { withFileTypes: true });
|
|
30797
30978
|
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"));
|
|
30798
30979
|
if (hasSkillMarker) {
|
|
@@ -30802,7 +30983,7 @@ class SkillsCustomizationScanner {
|
|
|
30802
30983
|
if (skillLikeCount > 0) {
|
|
30803
30984
|
const skills = [];
|
|
30804
30985
|
for (const dir of dirs) {
|
|
30805
|
-
const categoryPath =
|
|
30986
|
+
const categoryPath = join24(skillsDir, dir.name);
|
|
30806
30987
|
const skillDirs = await readdir10(categoryPath, { withFileTypes: true });
|
|
30807
30988
|
skills.push(...skillDirs.filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name));
|
|
30808
30989
|
}
|
|
@@ -30812,7 +30993,7 @@ class SkillsCustomizationScanner {
|
|
|
30812
30993
|
return ["flat", dirs.map((dir) => dir.name)];
|
|
30813
30994
|
}
|
|
30814
30995
|
static async findSkillPath(skillsDir, skillName) {
|
|
30815
|
-
const flatPath =
|
|
30996
|
+
const flatPath = join24(skillsDir, skillName);
|
|
30816
30997
|
if (await import_fs_extra14.pathExists(flatPath)) {
|
|
30817
30998
|
return { path: flatPath, category: undefined };
|
|
30818
30999
|
}
|
|
@@ -30821,8 +31002,8 @@ class SkillsCustomizationScanner {
|
|
|
30821
31002
|
if (!entry.isDirectory() || entry.name.startsWith(".") || entry.name === "node_modules") {
|
|
30822
31003
|
continue;
|
|
30823
31004
|
}
|
|
30824
|
-
const categoryPath =
|
|
30825
|
-
const skillPath =
|
|
31005
|
+
const categoryPath = join24(skillsDir, entry.name);
|
|
31006
|
+
const skillPath = join24(categoryPath, skillName);
|
|
30826
31007
|
if (await import_fs_extra14.pathExists(skillPath)) {
|
|
30827
31008
|
return { path: skillPath, category: entry.name };
|
|
30828
31009
|
}
|
|
@@ -30833,7 +31014,7 @@ class SkillsCustomizationScanner {
|
|
|
30833
31014
|
const files = [];
|
|
30834
31015
|
const entries = await readdir10(dirPath, { withFileTypes: true });
|
|
30835
31016
|
for (const entry of entries) {
|
|
30836
|
-
const fullPath =
|
|
31017
|
+
const fullPath = join24(dirPath, entry.name);
|
|
30837
31018
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.isSymbolicLink()) {
|
|
30838
31019
|
continue;
|
|
30839
31020
|
}
|
|
@@ -31076,7 +31257,7 @@ class SkillsMigrator {
|
|
|
31076
31257
|
}
|
|
31077
31258
|
}
|
|
31078
31259
|
if (options.backup && !options.dryRun) {
|
|
31079
|
-
const claudeDir =
|
|
31260
|
+
const claudeDir = join25(currentSkillsDir, "..");
|
|
31080
31261
|
result.backupPath = await SkillsBackupManager.createBackup(currentSkillsDir, claudeDir);
|
|
31081
31262
|
logger.success(`Backup created at: ${result.backupPath}`);
|
|
31082
31263
|
}
|
|
@@ -31128,7 +31309,7 @@ class SkillsMigrator {
|
|
|
31128
31309
|
const migrated = [];
|
|
31129
31310
|
const preserved = [];
|
|
31130
31311
|
const errors2 = [];
|
|
31131
|
-
const tempDir =
|
|
31312
|
+
const tempDir = join25(currentSkillsDir, "..", ".skills-migration-temp");
|
|
31132
31313
|
await mkdir7(tempDir, { recursive: true });
|
|
31133
31314
|
try {
|
|
31134
31315
|
for (const mapping of mappings) {
|
|
@@ -31149,9 +31330,9 @@ class SkillsMigrator {
|
|
|
31149
31330
|
}
|
|
31150
31331
|
}
|
|
31151
31332
|
const category = mapping.category;
|
|
31152
|
-
const targetPath = category ?
|
|
31333
|
+
const targetPath = category ? join25(tempDir, category, skillName) : join25(tempDir, skillName);
|
|
31153
31334
|
if (category) {
|
|
31154
|
-
await mkdir7(
|
|
31335
|
+
await mkdir7(join25(tempDir, category), { recursive: true });
|
|
31155
31336
|
}
|
|
31156
31337
|
await SkillsMigrator.copySkillDirectory(currentSkillPath, targetPath);
|
|
31157
31338
|
migrated.push(skillName);
|
|
@@ -31185,8 +31366,8 @@ class SkillsMigrator {
|
|
|
31185
31366
|
await mkdir7(destDir, { recursive: true });
|
|
31186
31367
|
const entries = await readdir11(sourceDir, { withFileTypes: true });
|
|
31187
31368
|
for (const entry of entries) {
|
|
31188
|
-
const sourcePath =
|
|
31189
|
-
const destPath =
|
|
31369
|
+
const sourcePath = join25(sourceDir, entry.name);
|
|
31370
|
+
const destPath = join25(destDir, entry.name);
|
|
31190
31371
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.isSymbolicLink()) {
|
|
31191
31372
|
continue;
|
|
31192
31373
|
}
|
|
@@ -31205,18 +31386,18 @@ init_types2();
|
|
|
31205
31386
|
// src/utils/config.ts
|
|
31206
31387
|
init_types2();
|
|
31207
31388
|
init_logger();
|
|
31208
|
-
import { existsSync as
|
|
31389
|
+
import { existsSync as existsSync6 } from "node:fs";
|
|
31209
31390
|
import { mkdir as mkdir8, readFile as readFile12, rename as rename2, rm as rm3, writeFile as writeFile10 } from "node:fs/promises";
|
|
31210
31391
|
import { chmod as chmod2 } from "node:fs/promises";
|
|
31211
31392
|
import { platform as platform8 } from "node:os";
|
|
31212
|
-
import { join as
|
|
31393
|
+
import { join as join26 } from "node:path";
|
|
31213
31394
|
var PROJECT_CONFIG_FILE = ".ck.json";
|
|
31214
31395
|
|
|
31215
31396
|
class ConfigManager {
|
|
31216
31397
|
static config = null;
|
|
31217
31398
|
static globalFlag = false;
|
|
31218
31399
|
static getProjectConfigDir(projectDir, global3) {
|
|
31219
|
-
return global3 ? projectDir :
|
|
31400
|
+
return global3 ? projectDir : join26(projectDir, ".claude");
|
|
31220
31401
|
}
|
|
31221
31402
|
static setGlobalFlag(global3) {
|
|
31222
31403
|
ConfigManager.globalFlag = global3;
|
|
@@ -31231,7 +31412,7 @@ class ConfigManager {
|
|
|
31231
31412
|
}
|
|
31232
31413
|
const configFile = PathResolver.getConfigFile(ConfigManager.globalFlag);
|
|
31233
31414
|
try {
|
|
31234
|
-
if (
|
|
31415
|
+
if (existsSync6(configFile)) {
|
|
31235
31416
|
const content = await readFile12(configFile, "utf-8");
|
|
31236
31417
|
const data = JSON.parse(content);
|
|
31237
31418
|
ConfigManager.config = ConfigSchema.parse(data);
|
|
@@ -31249,7 +31430,7 @@ class ConfigManager {
|
|
|
31249
31430
|
const validConfig = ConfigSchema.parse(config);
|
|
31250
31431
|
const configDir = PathResolver.getConfigDir(ConfigManager.globalFlag);
|
|
31251
31432
|
const configFile = PathResolver.getConfigFile(ConfigManager.globalFlag);
|
|
31252
|
-
if (!
|
|
31433
|
+
if (!existsSync6(configDir)) {
|
|
31253
31434
|
await mkdir8(configDir, { recursive: true });
|
|
31254
31435
|
if (platform8() !== "win32") {
|
|
31255
31436
|
await chmod2(configDir, 448);
|
|
@@ -31283,9 +31464,9 @@ class ConfigManager {
|
|
|
31283
31464
|
}
|
|
31284
31465
|
static async loadProjectConfig(projectDir, global3 = false) {
|
|
31285
31466
|
const configDir = ConfigManager.getProjectConfigDir(projectDir, global3);
|
|
31286
|
-
const configPath =
|
|
31467
|
+
const configPath = join26(configDir, PROJECT_CONFIG_FILE);
|
|
31287
31468
|
try {
|
|
31288
|
-
if (
|
|
31469
|
+
if (existsSync6(configPath)) {
|
|
31289
31470
|
const content = await readFile12(configPath, "utf-8");
|
|
31290
31471
|
const data = JSON.parse(content);
|
|
31291
31472
|
const folders = FoldersConfigSchema.parse(data.paths || data);
|
|
@@ -31299,9 +31480,9 @@ class ConfigManager {
|
|
|
31299
31480
|
}
|
|
31300
31481
|
static async saveProjectConfig(projectDir, folders, global3 = false) {
|
|
31301
31482
|
const configDir = ConfigManager.getProjectConfigDir(projectDir, global3);
|
|
31302
|
-
const configPath =
|
|
31483
|
+
const configPath = join26(configDir, PROJECT_CONFIG_FILE);
|
|
31303
31484
|
try {
|
|
31304
|
-
if (!
|
|
31485
|
+
if (!existsSync6(configDir)) {
|
|
31305
31486
|
await mkdir8(configDir, { recursive: true });
|
|
31306
31487
|
}
|
|
31307
31488
|
const validFolders = FoldersConfigSchema.parse(folders);
|
|
@@ -31331,21 +31512,21 @@ class ConfigManager {
|
|
|
31331
31512
|
}
|
|
31332
31513
|
static projectConfigExists(projectDir, global3 = false) {
|
|
31333
31514
|
const configDir = ConfigManager.getProjectConfigDir(projectDir, global3);
|
|
31334
|
-
return
|
|
31515
|
+
return existsSync6(join26(configDir, PROJECT_CONFIG_FILE));
|
|
31335
31516
|
}
|
|
31336
31517
|
static async migrateNestedConfig(globalDir) {
|
|
31337
|
-
const correctPath =
|
|
31338
|
-
const incorrectPath =
|
|
31339
|
-
if (
|
|
31518
|
+
const correctPath = join26(globalDir, PROJECT_CONFIG_FILE);
|
|
31519
|
+
const incorrectPath = join26(globalDir, ".claude", PROJECT_CONFIG_FILE);
|
|
31520
|
+
if (existsSync6(correctPath)) {
|
|
31340
31521
|
logger.debug("Config already exists at correct location, skipping migration");
|
|
31341
31522
|
return false;
|
|
31342
31523
|
}
|
|
31343
|
-
if (
|
|
31524
|
+
if (existsSync6(incorrectPath)) {
|
|
31344
31525
|
try {
|
|
31345
31526
|
logger.info("Migrating .ck.json from nested location to correct location...");
|
|
31346
31527
|
await rename2(incorrectPath, correctPath);
|
|
31347
31528
|
logger.success(`Migrated ${PROJECT_CONFIG_FILE} to ${correctPath}`);
|
|
31348
|
-
const nestedClaudeDir =
|
|
31529
|
+
const nestedClaudeDir = join26(globalDir, ".claude");
|
|
31349
31530
|
try {
|
|
31350
31531
|
await rm3(nestedClaudeDir, { recursive: false });
|
|
31351
31532
|
logger.debug("Removed empty nested .claude directory");
|
|
@@ -31368,7 +31549,7 @@ init_environment();
|
|
|
31368
31549
|
// src/utils/file-scanner.ts
|
|
31369
31550
|
init_logger();
|
|
31370
31551
|
var import_fs_extra16 = __toESM(require_lib(), 1);
|
|
31371
|
-
import { join as
|
|
31552
|
+
import { join as join27, relative as relative8, resolve as resolve3 } from "node:path";
|
|
31372
31553
|
var SKIP_DIRS = [
|
|
31373
31554
|
"node_modules",
|
|
31374
31555
|
".venv",
|
|
@@ -31395,7 +31576,7 @@ class FileScanner {
|
|
|
31395
31576
|
logger.debug(`Skipping directory: ${entry}`);
|
|
31396
31577
|
continue;
|
|
31397
31578
|
}
|
|
31398
|
-
const fullPath =
|
|
31579
|
+
const fullPath = join27(dirPath, entry);
|
|
31399
31580
|
if (!FileScanner.isSafePath(basePath, fullPath)) {
|
|
31400
31581
|
logger.warning(`Skipping potentially unsafe path: ${entry}`);
|
|
31401
31582
|
continue;
|
|
@@ -31430,14 +31611,27 @@ class FileScanner {
|
|
|
31430
31611
|
return files;
|
|
31431
31612
|
}
|
|
31432
31613
|
static async findCustomFiles(destDir, sourceDir, subPath) {
|
|
31433
|
-
const destSubDir =
|
|
31434
|
-
const sourceSubDir =
|
|
31614
|
+
const destSubDir = join27(destDir, subPath);
|
|
31615
|
+
const sourceSubDir = join27(sourceDir, subPath);
|
|
31616
|
+
logger.debug(`findCustomFiles - destDir: ${destDir}`);
|
|
31617
|
+
logger.debug(`findCustomFiles - sourceDir: ${sourceDir}`);
|
|
31618
|
+
logger.debug(`findCustomFiles - subPath: "${subPath}"`);
|
|
31619
|
+
logger.debug(`findCustomFiles - destSubDir: ${destSubDir}`);
|
|
31620
|
+
logger.debug(`findCustomFiles - sourceSubDir: ${sourceSubDir}`);
|
|
31435
31621
|
const destFiles = await FileScanner.getFiles(destSubDir, destDir);
|
|
31436
31622
|
const sourceFiles = await FileScanner.getFiles(sourceSubDir, sourceDir);
|
|
31623
|
+
logger.debug(`findCustomFiles - destFiles count: ${destFiles.length}`);
|
|
31624
|
+
logger.debug(`findCustomFiles - sourceFiles count: ${sourceFiles.length}`);
|
|
31625
|
+
const sourceExists = await import_fs_extra16.pathExists(sourceSubDir);
|
|
31626
|
+
if (sourceExists && sourceFiles.length === 0 && destFiles.length > 100) {
|
|
31627
|
+
logger.warning(`Source directory exists but is empty while destination has ${destFiles.length} files. This may indicate an extraction issue. Skipping custom file detection.`);
|
|
31628
|
+
return [];
|
|
31629
|
+
}
|
|
31437
31630
|
const sourceFileSet = new Set(sourceFiles);
|
|
31438
31631
|
const customFiles = destFiles.filter((file) => !sourceFileSet.has(file));
|
|
31439
31632
|
if (customFiles.length > 0) {
|
|
31440
|
-
|
|
31633
|
+
const displayPath = subPath || destSubDir;
|
|
31634
|
+
logger.info(`Found ${customFiles.length} custom file(s) in ${displayPath}`);
|
|
31441
31635
|
customFiles.slice(0, 5).forEach((file) => logger.debug(` - ${file}`));
|
|
31442
31636
|
if (customFiles.length > 5) {
|
|
31443
31637
|
logger.debug(` ... and ${customFiles.length - 5} more`);
|
|
@@ -31472,8 +31666,11 @@ async function initCommand(options) {
|
|
|
31472
31666
|
logger.info("Running in non-interactive mode (--yes flag)");
|
|
31473
31667
|
}
|
|
31474
31668
|
if (validOptions.global) {
|
|
31475
|
-
const
|
|
31476
|
-
|
|
31669
|
+
const globalKitDir = PathResolver.getGlobalKitDir();
|
|
31670
|
+
const cwdResolved = resolve4(process.cwd());
|
|
31671
|
+
const isInGlobalDir = cwdResolved === globalKitDir || cwdResolved === resolve4(globalKitDir, "..");
|
|
31672
|
+
const localSettingsPath = join28(process.cwd(), ".claude", "settings.json");
|
|
31673
|
+
if (!isInGlobalDir && await import_fs_extra17.pathExists(localSettingsPath)) {
|
|
31477
31674
|
if (isNonInteractive2) {
|
|
31478
31675
|
logger.warning("Local .claude/settings.json detected. Local settings take precedence over global.");
|
|
31479
31676
|
logger.warning("Consider removing local installation: rm -rf .claude");
|
|
@@ -31484,7 +31681,7 @@ async function initCommand(options) {
|
|
|
31484
31681
|
return;
|
|
31485
31682
|
}
|
|
31486
31683
|
if (choice === "remove") {
|
|
31487
|
-
const localClaudeDir =
|
|
31684
|
+
const localClaudeDir = join28(process.cwd(), ".claude");
|
|
31488
31685
|
try {
|
|
31489
31686
|
await import_fs_extra17.remove(localClaudeDir);
|
|
31490
31687
|
logger.success("Removed local .claude/ directory");
|
|
@@ -31543,7 +31740,7 @@ async function initCommand(options) {
|
|
|
31543
31740
|
}
|
|
31544
31741
|
if (validOptions.fresh) {
|
|
31545
31742
|
const prefix = PathResolver.getPathPrefix(validOptions.global);
|
|
31546
|
-
const claudeDir2 = prefix ?
|
|
31743
|
+
const claudeDir2 = prefix ? join28(resolvedDir, prefix) : resolvedDir;
|
|
31547
31744
|
const canProceed = await handleFreshInstallation(claudeDir2, prompts);
|
|
31548
31745
|
if (!canProceed) {
|
|
31549
31746
|
return;
|
|
@@ -31680,7 +31877,7 @@ async function initCommand(options) {
|
|
|
31680
31877
|
}
|
|
31681
31878
|
}
|
|
31682
31879
|
if (!validOptions.fresh) {
|
|
31683
|
-
const newSkillsDir =
|
|
31880
|
+
const newSkillsDir = join28(extractDir, ".claude", "skills");
|
|
31684
31881
|
const currentSkillsDir = PathResolver.buildSkillsPath(resolvedDir, validOptions.global);
|
|
31685
31882
|
if (await import_fs_extra17.pathExists(newSkillsDir) && await import_fs_extra17.pathExists(currentSkillsDir)) {
|
|
31686
31883
|
logger.info("Checking for skills directory migration...");
|
|
@@ -31705,7 +31902,7 @@ async function initCommand(options) {
|
|
|
31705
31902
|
let customClaudeFiles = [];
|
|
31706
31903
|
if (!validOptions.fresh) {
|
|
31707
31904
|
logger.info("Scanning for custom .claude files...");
|
|
31708
|
-
const scanSourceDir = validOptions.global ?
|
|
31905
|
+
const scanSourceDir = validOptions.global ? join28(extractDir, ".claude") : extractDir;
|
|
31709
31906
|
const scanTargetSubdir = validOptions.global ? "" : ".claude";
|
|
31710
31907
|
customClaudeFiles = await FileScanner.findCustomFiles(resolvedDir, scanSourceDir, scanTargetSubdir);
|
|
31711
31908
|
} else {
|
|
@@ -31734,7 +31931,7 @@ async function initCommand(options) {
|
|
|
31734
31931
|
merger.addIgnorePatterns(validOptions.exclude);
|
|
31735
31932
|
}
|
|
31736
31933
|
merger.setGlobalFlag(validOptions.global);
|
|
31737
|
-
const claudeDir = validOptions.global ? resolvedDir :
|
|
31934
|
+
const claudeDir = validOptions.global ? resolvedDir : join28(resolvedDir, ".claude");
|
|
31738
31935
|
const releaseManifest = await ReleaseManifestLoader.load(extractDir);
|
|
31739
31936
|
if (!validOptions.fresh && await import_fs_extra17.pathExists(claudeDir)) {
|
|
31740
31937
|
const legacyDetection = await LegacyMigration.detectLegacy(claudeDir);
|
|
@@ -31756,7 +31953,7 @@ async function initCommand(options) {
|
|
|
31756
31953
|
return;
|
|
31757
31954
|
}
|
|
31758
31955
|
}
|
|
31759
|
-
const sourceDir = validOptions.global ?
|
|
31956
|
+
const sourceDir = validOptions.global ? join28(extractDir, ".claude") : extractDir;
|
|
31760
31957
|
await merger.merge(sourceDir, resolvedDir, false);
|
|
31761
31958
|
const manifestWriter = new ManifestWriter;
|
|
31762
31959
|
const installedFiles = merger.getAllInstalledFiles();
|
|
@@ -31765,7 +31962,7 @@ async function initCommand(options) {
|
|
|
31765
31962
|
if (!validOptions.global && !installedPath.startsWith(".claude/"))
|
|
31766
31963
|
continue;
|
|
31767
31964
|
const relativePath = validOptions.global ? installedPath : installedPath.replace(/^\.claude\//, "");
|
|
31768
|
-
const filePath =
|
|
31965
|
+
const filePath = join28(claudeDir, relativePath);
|
|
31769
31966
|
const manifestEntry = releaseManifest ? ReleaseManifestLoader.findFile(releaseManifest, installedPath) : null;
|
|
31770
31967
|
const ownership = manifestEntry ? "ck" : "user";
|
|
31771
31968
|
filesToTrack.push({
|
|
@@ -31786,8 +31983,8 @@ async function initCommand(options) {
|
|
|
31786
31983
|
trackingSpinner.succeed(`Tracked ${trackResult.success} files`);
|
|
31787
31984
|
await manifestWriter.writeManifest(claudeDir, kitConfig.name, release.tag_name, validOptions.global ? "global" : "local");
|
|
31788
31985
|
if (validOptions.global) {
|
|
31789
|
-
const claudeMdSource =
|
|
31790
|
-
const claudeMdDest =
|
|
31986
|
+
const claudeMdSource = join28(extractDir, "CLAUDE.md");
|
|
31987
|
+
const claudeMdDest = join28(resolvedDir, "CLAUDE.md");
|
|
31791
31988
|
if (await import_fs_extra17.pathExists(claudeMdSource)) {
|
|
31792
31989
|
if (!await import_fs_extra17.pathExists(claudeMdDest)) {
|
|
31793
31990
|
await import_fs_extra17.copy(claudeMdSource, claudeMdDest);
|
|
@@ -31807,7 +32004,7 @@ async function initCommand(options) {
|
|
|
31807
32004
|
await handleSkillsInstallation2(skillsDir);
|
|
31808
32005
|
}
|
|
31809
32006
|
if (!validOptions.skipSetup && !isNonInteractive2) {
|
|
31810
|
-
const envPath =
|
|
32007
|
+
const envPath = join28(claudeDir, ".env");
|
|
31811
32008
|
if (!await import_fs_extra17.pathExists(envPath)) {
|
|
31812
32009
|
const shouldSetup = await prompts.confirm("Set up API keys now? (Gemini API key for ai-multimodal skill, optional webhooks)");
|
|
31813
32010
|
if (shouldSetup) {
|
|
@@ -31839,7 +32036,7 @@ Protected files (.env, etc.) were not modified.`;
|
|
|
31839
32036
|
|
|
31840
32037
|
// src/commands/new.ts
|
|
31841
32038
|
var import_fs_extra18 = __toESM(require_lib(), 1);
|
|
31842
|
-
import { join as
|
|
32039
|
+
import { join as join29, resolve as resolve5 } from "node:path";
|
|
31843
32040
|
init_types2();
|
|
31844
32041
|
init_environment();
|
|
31845
32042
|
init_logger();
|
|
@@ -32010,7 +32207,7 @@ async function newCommand(options) {
|
|
|
32010
32207
|
await CommandsPrefix.cleanupCommandsDirectory(resolvedDir, false);
|
|
32011
32208
|
}
|
|
32012
32209
|
await merger.merge(extractDir, resolvedDir, true);
|
|
32013
|
-
const claudeDir =
|
|
32210
|
+
const claudeDir = join29(resolvedDir, ".claude");
|
|
32014
32211
|
const manifestWriter = new ManifestWriter;
|
|
32015
32212
|
const releaseManifest = await ReleaseManifestLoader.load(extractDir);
|
|
32016
32213
|
const installedFiles = merger.getAllInstalledFiles();
|
|
@@ -32019,7 +32216,7 @@ async function newCommand(options) {
|
|
|
32019
32216
|
if (!installedPath.startsWith(".claude/"))
|
|
32020
32217
|
continue;
|
|
32021
32218
|
const relativePath = installedPath.replace(/^\.claude\//, "");
|
|
32022
|
-
const filePath =
|
|
32219
|
+
const filePath = join29(claudeDir, relativePath);
|
|
32023
32220
|
const manifestEntry = releaseManifest ? ReleaseManifestLoader.findFile(releaseManifest, installedPath) : null;
|
|
32024
32221
|
const ownership = manifestEntry ? "ck" : "user";
|
|
32025
32222
|
filesToTrack.push({
|
|
@@ -32075,7 +32272,7 @@ init_dist2();
|
|
|
32075
32272
|
var import_fs_extra19 = __toESM(require_lib(), 1);
|
|
32076
32273
|
var import_picocolors10 = __toESM(require_picocolors(), 1);
|
|
32077
32274
|
import { readdirSync, rmSync } from "node:fs";
|
|
32078
|
-
import { dirname as dirname4, join as
|
|
32275
|
+
import { dirname as dirname4, join as join30 } from "node:path";
|
|
32079
32276
|
init_types2();
|
|
32080
32277
|
init_logger();
|
|
32081
32278
|
async function detectInstallations() {
|
|
@@ -32166,7 +32363,7 @@ async function analyzeInstallation(installation, forceOverwrite) {
|
|
|
32166
32363
|
return result;
|
|
32167
32364
|
}
|
|
32168
32365
|
for (const trackedFile of metadata.files) {
|
|
32169
|
-
const filePath =
|
|
32366
|
+
const filePath = join30(installation.path, trackedFile.path);
|
|
32170
32367
|
const ownershipResult = await OwnershipChecker.checkOwnership(filePath, metadata, installation.path);
|
|
32171
32368
|
if (!ownershipResult.exists)
|
|
32172
32369
|
continue;
|
|
@@ -32224,7 +32421,7 @@ async function removeInstallations(installations, options) {
|
|
|
32224
32421
|
let removedCount = 0;
|
|
32225
32422
|
let cleanedDirs = 0;
|
|
32226
32423
|
for (const item of analysis.toDelete) {
|
|
32227
|
-
const filePath =
|
|
32424
|
+
const filePath = join30(installation.path, item.path);
|
|
32228
32425
|
if (await import_fs_extra19.pathExists(filePath)) {
|
|
32229
32426
|
await import_fs_extra19.remove(filePath);
|
|
32230
32427
|
removedCount++;
|
|
@@ -32326,7 +32523,7 @@ import { promisify as promisify6 } from "node:util";
|
|
|
32326
32523
|
// package.json
|
|
32327
32524
|
var package_default2 = {
|
|
32328
32525
|
name: "claudekit-cli",
|
|
32329
|
-
version: "3.
|
|
32526
|
+
version: "3.6.1",
|
|
32330
32527
|
description: "CLI tool for bootstrapping and updating ClaudeKit projects",
|
|
32331
32528
|
type: "module",
|
|
32332
32529
|
repository: {
|
|
@@ -32771,20 +32968,20 @@ var import_picocolors12 = __toESM(require_picocolors(), 1);
|
|
|
32771
32968
|
|
|
32772
32969
|
// src/lib/version-cache.ts
|
|
32773
32970
|
init_logger();
|
|
32774
|
-
import { existsSync as
|
|
32971
|
+
import { existsSync as existsSync7 } from "node:fs";
|
|
32775
32972
|
import { mkdir as mkdir9, readFile as readFile13, writeFile as writeFile11 } from "node:fs/promises";
|
|
32776
|
-
import { join as
|
|
32973
|
+
import { join as join31 } from "node:path";
|
|
32777
32974
|
class VersionCacheManager {
|
|
32778
32975
|
static CACHE_FILENAME = "version-check.json";
|
|
32779
32976
|
static CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000;
|
|
32780
32977
|
static getCacheFile() {
|
|
32781
32978
|
const cacheDir = PathResolver.getCacheDir(false);
|
|
32782
|
-
return
|
|
32979
|
+
return join31(cacheDir, VersionCacheManager.CACHE_FILENAME);
|
|
32783
32980
|
}
|
|
32784
32981
|
static async load() {
|
|
32785
32982
|
const cacheFile = VersionCacheManager.getCacheFile();
|
|
32786
32983
|
try {
|
|
32787
|
-
if (!
|
|
32984
|
+
if (!existsSync7(cacheFile)) {
|
|
32788
32985
|
logger.debug("Version check cache not found");
|
|
32789
32986
|
return null;
|
|
32790
32987
|
}
|
|
@@ -32805,7 +33002,7 @@ class VersionCacheManager {
|
|
|
32805
33002
|
const cacheFile = VersionCacheManager.getCacheFile();
|
|
32806
33003
|
const cacheDir = PathResolver.getCacheDir(false);
|
|
32807
33004
|
try {
|
|
32808
|
-
if (!
|
|
33005
|
+
if (!existsSync7(cacheDir)) {
|
|
32809
33006
|
await mkdir9(cacheDir, { recursive: true, mode: 448 });
|
|
32810
33007
|
}
|
|
32811
33008
|
await writeFile11(cacheFile, JSON.stringify(cache2, null, 2), "utf-8");
|
|
@@ -32827,7 +33024,7 @@ class VersionCacheManager {
|
|
|
32827
33024
|
static async clear() {
|
|
32828
33025
|
const cacheFile = VersionCacheManager.getCacheFile();
|
|
32829
33026
|
try {
|
|
32830
|
-
if (
|
|
33027
|
+
if (existsSync7(cacheFile)) {
|
|
32831
33028
|
const fs12 = await import("node:fs/promises");
|
|
32832
33029
|
await fs12.unlink(cacheFile);
|
|
32833
33030
|
logger.debug("Version check cache cleared");
|
|
@@ -33255,7 +33452,7 @@ var logger2 = new Logger2;
|
|
|
33255
33452
|
|
|
33256
33453
|
// src/utils/path-resolver.ts
|
|
33257
33454
|
import { homedir as homedir2, platform as platform9 } from "node:os";
|
|
33258
|
-
import { join as
|
|
33455
|
+
import { join as join32, normalize as normalize4 } from "node:path";
|
|
33259
33456
|
|
|
33260
33457
|
class PathResolver2 {
|
|
33261
33458
|
static getTestHomeDir() {
|
|
@@ -33288,50 +33485,50 @@ class PathResolver2 {
|
|
|
33288
33485
|
static getConfigDir(global3 = false) {
|
|
33289
33486
|
const testHome = PathResolver2.getTestHomeDir();
|
|
33290
33487
|
if (testHome) {
|
|
33291
|
-
return global3 ?
|
|
33488
|
+
return global3 ? join32(testHome, ".config", "claude") : join32(testHome, ".claudekit");
|
|
33292
33489
|
}
|
|
33293
33490
|
if (!global3) {
|
|
33294
|
-
return
|
|
33491
|
+
return join32(homedir2(), ".claudekit");
|
|
33295
33492
|
}
|
|
33296
33493
|
const os2 = platform9();
|
|
33297
33494
|
if (os2 === "win32") {
|
|
33298
|
-
const localAppData = process.env.LOCALAPPDATA ||
|
|
33299
|
-
return
|
|
33495
|
+
const localAppData = process.env.LOCALAPPDATA || join32(homedir2(), "AppData", "Local");
|
|
33496
|
+
return join32(localAppData, "claude");
|
|
33300
33497
|
}
|
|
33301
33498
|
const xdgConfigHome = process.env.XDG_CONFIG_HOME;
|
|
33302
33499
|
if (xdgConfigHome) {
|
|
33303
|
-
return
|
|
33500
|
+
return join32(xdgConfigHome, "claude");
|
|
33304
33501
|
}
|
|
33305
|
-
return
|
|
33502
|
+
return join32(homedir2(), ".config", "claude");
|
|
33306
33503
|
}
|
|
33307
33504
|
static getConfigFile(global3 = false) {
|
|
33308
|
-
return
|
|
33505
|
+
return join32(PathResolver2.getConfigDir(global3), "config.json");
|
|
33309
33506
|
}
|
|
33310
33507
|
static getCacheDir(global3 = false) {
|
|
33311
33508
|
const testHome = PathResolver2.getTestHomeDir();
|
|
33312
33509
|
if (testHome) {
|
|
33313
|
-
return global3 ?
|
|
33510
|
+
return global3 ? join32(testHome, ".cache", "claude") : join32(testHome, ".claudekit", "cache");
|
|
33314
33511
|
}
|
|
33315
33512
|
if (!global3) {
|
|
33316
|
-
return
|
|
33513
|
+
return join32(homedir2(), ".claudekit", "cache");
|
|
33317
33514
|
}
|
|
33318
33515
|
const os2 = platform9();
|
|
33319
33516
|
if (os2 === "win32") {
|
|
33320
|
-
const localAppData = process.env.LOCALAPPDATA ||
|
|
33321
|
-
return
|
|
33517
|
+
const localAppData = process.env.LOCALAPPDATA || join32(homedir2(), "AppData", "Local");
|
|
33518
|
+
return join32(localAppData, "claude", "cache");
|
|
33322
33519
|
}
|
|
33323
33520
|
const xdgCacheHome = process.env.XDG_CACHE_HOME;
|
|
33324
33521
|
if (xdgCacheHome) {
|
|
33325
|
-
return
|
|
33522
|
+
return join32(xdgCacheHome, "claude");
|
|
33326
33523
|
}
|
|
33327
|
-
return
|
|
33524
|
+
return join32(homedir2(), ".cache", "claude");
|
|
33328
33525
|
}
|
|
33329
33526
|
static getGlobalKitDir() {
|
|
33330
33527
|
const testHome = PathResolver2.getTestHomeDir();
|
|
33331
33528
|
if (testHome) {
|
|
33332
|
-
return
|
|
33529
|
+
return join32(testHome, ".claude");
|
|
33333
33530
|
}
|
|
33334
|
-
return
|
|
33531
|
+
return join32(homedir2(), ".claude");
|
|
33335
33532
|
}
|
|
33336
33533
|
static getPathPrefix(global3) {
|
|
33337
33534
|
return global3 ? "" : ".claude";
|
|
@@ -33339,9 +33536,9 @@ class PathResolver2 {
|
|
|
33339
33536
|
static buildSkillsPath(baseDir, global3) {
|
|
33340
33537
|
const prefix = PathResolver2.getPathPrefix(global3);
|
|
33341
33538
|
if (prefix) {
|
|
33342
|
-
return
|
|
33539
|
+
return join32(baseDir, prefix, "skills");
|
|
33343
33540
|
}
|
|
33344
|
-
return
|
|
33541
|
+
return join32(baseDir, "skills");
|
|
33345
33542
|
}
|
|
33346
33543
|
static buildComponentPath(baseDir, component, global3) {
|
|
33347
33544
|
if (!PathResolver2.isPathSafe(component)) {
|
|
@@ -33349,9 +33546,9 @@ class PathResolver2 {
|
|
|
33349
33546
|
}
|
|
33350
33547
|
const prefix = PathResolver2.getPathPrefix(global3);
|
|
33351
33548
|
if (prefix) {
|
|
33352
|
-
return
|
|
33549
|
+
return join32(baseDir, prefix, component);
|
|
33353
33550
|
}
|
|
33354
|
-
return
|
|
33551
|
+
return join32(baseDir, component);
|
|
33355
33552
|
}
|
|
33356
33553
|
}
|
|
33357
33554
|
|
|
@@ -33369,13 +33566,13 @@ async function displayVersion() {
|
|
|
33369
33566
|
let localKitVersion = null;
|
|
33370
33567
|
let isGlobalOnlyKit = false;
|
|
33371
33568
|
const globalKitDir = PathResolver2.getGlobalKitDir();
|
|
33372
|
-
const globalMetadataPath =
|
|
33569
|
+
const globalMetadataPath = join33(globalKitDir, "metadata.json");
|
|
33373
33570
|
const prefix = PathResolver2.getPathPrefix(false);
|
|
33374
|
-
const localMetadataPath = prefix ?
|
|
33571
|
+
const localMetadataPath = prefix ? join33(process.cwd(), prefix, "metadata.json") : join33(process.cwd(), "metadata.json");
|
|
33375
33572
|
const isLocalSameAsGlobal = localMetadataPath === globalMetadataPath;
|
|
33376
|
-
if (!isLocalSameAsGlobal &&
|
|
33573
|
+
if (!isLocalSameAsGlobal && existsSync8(localMetadataPath)) {
|
|
33377
33574
|
try {
|
|
33378
|
-
const rawMetadata = JSON.parse(
|
|
33575
|
+
const rawMetadata = JSON.parse(readFileSync5(localMetadataPath, "utf-8"));
|
|
33379
33576
|
const metadata = MetadataSchema2.parse(rawMetadata);
|
|
33380
33577
|
if (metadata.version) {
|
|
33381
33578
|
const kitName = metadata.name || "ClaudeKit";
|
|
@@ -33387,9 +33584,9 @@ async function displayVersion() {
|
|
|
33387
33584
|
logger2.verbose("Failed to parse local metadata.json", { error });
|
|
33388
33585
|
}
|
|
33389
33586
|
}
|
|
33390
|
-
if (
|
|
33587
|
+
if (existsSync8(globalMetadataPath)) {
|
|
33391
33588
|
try {
|
|
33392
|
-
const rawMetadata = JSON.parse(
|
|
33589
|
+
const rawMetadata = JSON.parse(readFileSync5(globalMetadataPath, "utf-8"));
|
|
33393
33590
|
const metadata = MetadataSchema2.parse(rawMetadata);
|
|
33394
33591
|
if (metadata.version) {
|
|
33395
33592
|
const kitName = metadata.name || "ClaudeKit";
|