claudekit-cli 4.5.0-dev.4 → 4.5.0-dev.6
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/cli-manifest.json +2 -2
- package/dist/index.js +869 -577
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -64421,7 +64421,7 @@ var package_default;
|
|
|
64421
64421
|
var init_package = __esm(() => {
|
|
64422
64422
|
package_default = {
|
|
64423
64423
|
name: "claudekit-cli",
|
|
64424
|
-
version: "4.5.0-dev.
|
|
64424
|
+
version: "4.5.0-dev.6",
|
|
64425
64425
|
description: "CLI tool for bootstrapping and updating ClaudeKit projects",
|
|
64426
64426
|
type: "module",
|
|
64427
64427
|
repository: {
|
|
@@ -65083,7 +65083,7 @@ import { spawnSync as spawnSync3 } from "node:child_process";
|
|
|
65083
65083
|
import { existsSync as existsSync46, readFileSync as readFileSync14, readdirSync as readdirSync9, statSync as statSync10, writeFileSync as writeFileSync5 } from "node:fs";
|
|
65084
65084
|
import { readdir as readdir17 } from "node:fs/promises";
|
|
65085
65085
|
import { homedir as homedir40, tmpdir } from "node:os";
|
|
65086
|
-
import { dirname as dirname29, join as join65, resolve as resolve33 } from "node:path";
|
|
65086
|
+
import { dirname as dirname29, join as join65, resolve as resolve33, sep as sep11 } from "node:path";
|
|
65087
65087
|
function resolveDoctorCkExecutable(platformName = process.platform) {
|
|
65088
65088
|
return platformName === "win32" ? "ck.cmd" : "ck";
|
|
65089
65089
|
}
|
|
@@ -66085,6 +66085,21 @@ async function countMissingHookFileReferences(projectDir = process.cwd()) {
|
|
|
66085
66085
|
}
|
|
66086
66086
|
return count;
|
|
66087
66087
|
}
|
|
66088
|
+
async function countMissingHookFileReferencesForClaudeDir(claudeDir3, projectRoot = dirname29(claudeDir3)) {
|
|
66089
|
+
const hooksDirPrefix = `${resolve33(claudeDir3, "hooks")}${sep11}`;
|
|
66090
|
+
let count = 0;
|
|
66091
|
+
for (const fileName of ["settings.json", "settings.local.json"]) {
|
|
66092
|
+
const filePath = resolve33(claudeDir3, fileName);
|
|
66093
|
+
if (!existsSync46(filePath))
|
|
66094
|
+
continue;
|
|
66095
|
+
const settings = await SettingsMerger.readSettingsFile(filePath);
|
|
66096
|
+
if (!settings)
|
|
66097
|
+
continue;
|
|
66098
|
+
const descriptor = { path: filePath, label: fileName, root: "$HOME" };
|
|
66099
|
+
count += collectMissingHookReferences(settings, descriptor, projectRoot).filter((finding) => finding.resolvedPath.startsWith(hooksDirPrefix)).length;
|
|
66100
|
+
}
|
|
66101
|
+
return count;
|
|
66102
|
+
}
|
|
66088
66103
|
async function repairMissingHookFileReferences(projectDir = process.cwd()) {
|
|
66089
66104
|
const result = await checkHookFileReferences(projectDir);
|
|
66090
66105
|
if (result.status !== "fail" || !result.fix) {
|
|
@@ -74769,6 +74784,164 @@ var init_process_executor = __esm(() => {
|
|
|
74769
74784
|
execFileAsync7 = promisify15(execFile10);
|
|
74770
74785
|
});
|
|
74771
74786
|
|
|
74787
|
+
// src/services/package-installer/agy-installer.ts
|
|
74788
|
+
import { join as join90 } from "node:path";
|
|
74789
|
+
async function isAgyInstalled() {
|
|
74790
|
+
try {
|
|
74791
|
+
await execAsync7("agy --version", { timeout: 1e4 });
|
|
74792
|
+
return true;
|
|
74793
|
+
} catch {
|
|
74794
|
+
return false;
|
|
74795
|
+
}
|
|
74796
|
+
}
|
|
74797
|
+
async function installAgyUnix() {
|
|
74798
|
+
const { unlink: unlink13 } = await import("node:fs/promises");
|
|
74799
|
+
const { tmpdir: tmpdir4 } = await import("node:os");
|
|
74800
|
+
const tempScriptPath = join90(tmpdir4(), "agy-install.sh");
|
|
74801
|
+
try {
|
|
74802
|
+
logger.info("Downloading Antigravity CLI installation script...");
|
|
74803
|
+
await execFileAsync7("curl", ["-fsSL", AGY_INSTALL_SH_URL, "-o", tempScriptPath], {
|
|
74804
|
+
timeout: 30000
|
|
74805
|
+
});
|
|
74806
|
+
await execFileAsync7("chmod", ["+x", tempScriptPath], { timeout: 5000 });
|
|
74807
|
+
logger.info("Executing Antigravity CLI installation script...");
|
|
74808
|
+
await execFileAsync7("bash", [tempScriptPath], {
|
|
74809
|
+
timeout: 120000
|
|
74810
|
+
});
|
|
74811
|
+
} finally {
|
|
74812
|
+
try {
|
|
74813
|
+
await unlink13(tempScriptPath);
|
|
74814
|
+
} catch {}
|
|
74815
|
+
}
|
|
74816
|
+
}
|
|
74817
|
+
async function installAgyWindows() {
|
|
74818
|
+
logger.info("Executing Antigravity CLI installation script (PowerShell)...");
|
|
74819
|
+
await execFileAsync7("powershell.exe", ["-NoLogo", "-ExecutionPolicy", "Bypass", "-Command", `irm ${AGY_INSTALL_PS1_URL} | iex`], { timeout: 120000 });
|
|
74820
|
+
}
|
|
74821
|
+
async function installAgy() {
|
|
74822
|
+
const displayName = AGY_DISPLAY_NAME;
|
|
74823
|
+
if (isCIEnvironment()) {
|
|
74824
|
+
logger.info("CI environment detected: skipping Antigravity CLI installation");
|
|
74825
|
+
return {
|
|
74826
|
+
success: false,
|
|
74827
|
+
package: displayName,
|
|
74828
|
+
error: "Installation skipped in CI environment",
|
|
74829
|
+
skipped: true
|
|
74830
|
+
};
|
|
74831
|
+
}
|
|
74832
|
+
try {
|
|
74833
|
+
logger.info(`Installing ${displayName}...`);
|
|
74834
|
+
if (isWindows()) {
|
|
74835
|
+
await installAgyWindows();
|
|
74836
|
+
} else {
|
|
74837
|
+
await installAgyUnix();
|
|
74838
|
+
}
|
|
74839
|
+
const installed = await isAgyInstalled();
|
|
74840
|
+
if (installed) {
|
|
74841
|
+
logger.success(`${displayName} installed successfully`);
|
|
74842
|
+
return {
|
|
74843
|
+
success: true,
|
|
74844
|
+
package: displayName
|
|
74845
|
+
};
|
|
74846
|
+
}
|
|
74847
|
+
const pathHint = isWindows() ? "%LOCALAPPDATA%\\agy\\bin" : "~/.local/bin";
|
|
74848
|
+
logger.warning(`${displayName} installed, but 'agy' is not on your PATH yet. Restart your shell or add "${pathHint}" to PATH.`);
|
|
74849
|
+
return {
|
|
74850
|
+
success: false,
|
|
74851
|
+
package: displayName,
|
|
74852
|
+
error: `Installed but 'agy' not found on PATH. Restart your shell or add "${pathHint}" to PATH.`
|
|
74853
|
+
};
|
|
74854
|
+
} catch (error) {
|
|
74855
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
74856
|
+
logger.error(`Failed to install ${displayName}: ${errorMessage}`);
|
|
74857
|
+
return {
|
|
74858
|
+
success: false,
|
|
74859
|
+
package: displayName,
|
|
74860
|
+
error: errorMessage
|
|
74861
|
+
};
|
|
74862
|
+
}
|
|
74863
|
+
}
|
|
74864
|
+
var AGY_DISPLAY_NAME = "Antigravity CLI (agy)", AGY_INSTALL_SH_URL = "https://antigravity.google/cli/install.sh", AGY_INSTALL_PS1_URL = "https://antigravity.google/cli/install.ps1";
|
|
74865
|
+
var init_agy_installer = __esm(() => {
|
|
74866
|
+
init_environment();
|
|
74867
|
+
init_logger();
|
|
74868
|
+
init_process_executor();
|
|
74869
|
+
});
|
|
74870
|
+
|
|
74871
|
+
// src/services/package-installer/opencode-installer.ts
|
|
74872
|
+
import { join as join91 } from "node:path";
|
|
74873
|
+
async function isOpenCodeInstalled() {
|
|
74874
|
+
try {
|
|
74875
|
+
await execAsync7("opencode --version", { timeout: 5000 });
|
|
74876
|
+
return true;
|
|
74877
|
+
} catch {
|
|
74878
|
+
return false;
|
|
74879
|
+
}
|
|
74880
|
+
}
|
|
74881
|
+
async function installOpenCode() {
|
|
74882
|
+
const displayName = "OpenCode CLI";
|
|
74883
|
+
if (isCIEnvironment()) {
|
|
74884
|
+
logger.info("CI environment detected: skipping OpenCode installation");
|
|
74885
|
+
return {
|
|
74886
|
+
success: false,
|
|
74887
|
+
package: displayName,
|
|
74888
|
+
error: "Installation skipped in CI environment"
|
|
74889
|
+
};
|
|
74890
|
+
}
|
|
74891
|
+
try {
|
|
74892
|
+
logger.info(`Installing ${displayName}...`);
|
|
74893
|
+
const { unlink: unlink13 } = await import("node:fs/promises");
|
|
74894
|
+
const { tmpdir: tmpdir4 } = await import("node:os");
|
|
74895
|
+
const tempScriptPath = join91(tmpdir4(), "opencode-install.sh");
|
|
74896
|
+
try {
|
|
74897
|
+
logger.info("Downloading OpenCode installation script...");
|
|
74898
|
+
await execFileAsync7("curl", ["-fsSL", "https://opencode.ai/install", "-o", tempScriptPath], {
|
|
74899
|
+
timeout: 30000
|
|
74900
|
+
});
|
|
74901
|
+
await execFileAsync7("chmod", ["+x", tempScriptPath], {
|
|
74902
|
+
timeout: 5000
|
|
74903
|
+
});
|
|
74904
|
+
logger.info("Executing OpenCode installation script...");
|
|
74905
|
+
await execFileAsync7("bash", [tempScriptPath], {
|
|
74906
|
+
timeout: 120000
|
|
74907
|
+
});
|
|
74908
|
+
} finally {
|
|
74909
|
+
try {
|
|
74910
|
+
await unlink13(tempScriptPath);
|
|
74911
|
+
} catch {}
|
|
74912
|
+
}
|
|
74913
|
+
const installed = await isOpenCodeInstalled();
|
|
74914
|
+
if (installed) {
|
|
74915
|
+
logger.success(`${displayName} installed successfully`);
|
|
74916
|
+
return {
|
|
74917
|
+
success: true,
|
|
74918
|
+
package: displayName
|
|
74919
|
+
};
|
|
74920
|
+
}
|
|
74921
|
+
return {
|
|
74922
|
+
success: false,
|
|
74923
|
+
package: displayName,
|
|
74924
|
+
error: "Installation completed but opencode command not found in PATH"
|
|
74925
|
+
};
|
|
74926
|
+
} catch (error) {
|
|
74927
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
74928
|
+
logger.error(`Failed to install ${displayName}: ${errorMessage}`);
|
|
74929
|
+
return {
|
|
74930
|
+
success: false,
|
|
74931
|
+
package: displayName,
|
|
74932
|
+
error: errorMessage
|
|
74933
|
+
};
|
|
74934
|
+
}
|
|
74935
|
+
}
|
|
74936
|
+
var init_opencode_installer = __esm(() => {
|
|
74937
|
+
init_environment();
|
|
74938
|
+
init_logger();
|
|
74939
|
+
init_process_executor();
|
|
74940
|
+
});
|
|
74941
|
+
|
|
74942
|
+
// src/services/package-installer/types.ts
|
|
74943
|
+
var PARTIAL_INSTALL_VERSION = "partial", EXIT_CODE_CRITICAL_FAILURE = 1, EXIT_CODE_PARTIAL_SUCCESS = 2;
|
|
74944
|
+
|
|
74772
74945
|
// src/services/package-installer/validators.ts
|
|
74773
74946
|
import { resolve as resolve38 } from "node:path";
|
|
74774
74947
|
function validatePackageName(packageName) {
|
|
@@ -74953,100 +75126,9 @@ var init_npm_package_manager = __esm(() => {
|
|
|
74953
75126
|
init_validators();
|
|
74954
75127
|
});
|
|
74955
75128
|
|
|
74956
|
-
// src/services/package-installer/gemini-installer.ts
|
|
74957
|
-
async function isGeminiInstalled() {
|
|
74958
|
-
try {
|
|
74959
|
-
await execAsync7("gemini --version", { timeout: 1e4 });
|
|
74960
|
-
return true;
|
|
74961
|
-
} catch {
|
|
74962
|
-
return false;
|
|
74963
|
-
}
|
|
74964
|
-
}
|
|
74965
|
-
async function installGemini() {
|
|
74966
|
-
return installPackageGlobally("@google/gemini-cli", "Google Gemini CLI");
|
|
74967
|
-
}
|
|
74968
|
-
var init_gemini_installer = __esm(() => {
|
|
74969
|
-
init_npm_package_manager();
|
|
74970
|
-
init_process_executor();
|
|
74971
|
-
});
|
|
74972
|
-
|
|
74973
|
-
// src/services/package-installer/opencode-installer.ts
|
|
74974
|
-
import { join as join90 } from "node:path";
|
|
74975
|
-
async function isOpenCodeInstalled() {
|
|
74976
|
-
try {
|
|
74977
|
-
await execAsync7("opencode --version", { timeout: 5000 });
|
|
74978
|
-
return true;
|
|
74979
|
-
} catch {
|
|
74980
|
-
return false;
|
|
74981
|
-
}
|
|
74982
|
-
}
|
|
74983
|
-
async function installOpenCode() {
|
|
74984
|
-
const displayName = "OpenCode CLI";
|
|
74985
|
-
if (isCIEnvironment()) {
|
|
74986
|
-
logger.info("CI environment detected: skipping OpenCode installation");
|
|
74987
|
-
return {
|
|
74988
|
-
success: false,
|
|
74989
|
-
package: displayName,
|
|
74990
|
-
error: "Installation skipped in CI environment"
|
|
74991
|
-
};
|
|
74992
|
-
}
|
|
74993
|
-
try {
|
|
74994
|
-
logger.info(`Installing ${displayName}...`);
|
|
74995
|
-
const { unlink: unlink13 } = await import("node:fs/promises");
|
|
74996
|
-
const { tmpdir: tmpdir4 } = await import("node:os");
|
|
74997
|
-
const tempScriptPath = join90(tmpdir4(), "opencode-install.sh");
|
|
74998
|
-
try {
|
|
74999
|
-
logger.info("Downloading OpenCode installation script...");
|
|
75000
|
-
await execFileAsync7("curl", ["-fsSL", "https://opencode.ai/install", "-o", tempScriptPath], {
|
|
75001
|
-
timeout: 30000
|
|
75002
|
-
});
|
|
75003
|
-
await execFileAsync7("chmod", ["+x", tempScriptPath], {
|
|
75004
|
-
timeout: 5000
|
|
75005
|
-
});
|
|
75006
|
-
logger.info("Executing OpenCode installation script...");
|
|
75007
|
-
await execFileAsync7("bash", [tempScriptPath], {
|
|
75008
|
-
timeout: 120000
|
|
75009
|
-
});
|
|
75010
|
-
} finally {
|
|
75011
|
-
try {
|
|
75012
|
-
await unlink13(tempScriptPath);
|
|
75013
|
-
} catch {}
|
|
75014
|
-
}
|
|
75015
|
-
const installed = await isOpenCodeInstalled();
|
|
75016
|
-
if (installed) {
|
|
75017
|
-
logger.success(`${displayName} installed successfully`);
|
|
75018
|
-
return {
|
|
75019
|
-
success: true,
|
|
75020
|
-
package: displayName
|
|
75021
|
-
};
|
|
75022
|
-
}
|
|
75023
|
-
return {
|
|
75024
|
-
success: false,
|
|
75025
|
-
package: displayName,
|
|
75026
|
-
error: "Installation completed but opencode command not found in PATH"
|
|
75027
|
-
};
|
|
75028
|
-
} catch (error) {
|
|
75029
|
-
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
75030
|
-
logger.error(`Failed to install ${displayName}: ${errorMessage}`);
|
|
75031
|
-
return {
|
|
75032
|
-
success: false,
|
|
75033
|
-
package: displayName,
|
|
75034
|
-
error: errorMessage
|
|
75035
|
-
};
|
|
75036
|
-
}
|
|
75037
|
-
}
|
|
75038
|
-
var init_opencode_installer = __esm(() => {
|
|
75039
|
-
init_environment();
|
|
75040
|
-
init_logger();
|
|
75041
|
-
init_process_executor();
|
|
75042
|
-
});
|
|
75043
|
-
|
|
75044
|
-
// src/services/package-installer/types.ts
|
|
75045
|
-
var PARTIAL_INSTALL_VERSION = "partial", EXIT_CODE_CRITICAL_FAILURE = 1, EXIT_CODE_PARTIAL_SUCCESS = 2;
|
|
75046
|
-
|
|
75047
75129
|
// src/services/package-installer/install-error-handler.ts
|
|
75048
75130
|
import { existsSync as existsSync62, readFileSync as readFileSync19, unlinkSync as unlinkSync3 } from "node:fs";
|
|
75049
|
-
import { join as
|
|
75131
|
+
import { join as join92 } from "node:path";
|
|
75050
75132
|
function parseNameReason(str2) {
|
|
75051
75133
|
const colonIndex = str2.indexOf(":");
|
|
75052
75134
|
if (colonIndex === -1) {
|
|
@@ -75109,7 +75191,7 @@ function getSystemPackageCommands(summary, systemFailures) {
|
|
|
75109
75191
|
return summary.remediation.sudo_packages ? [summary.remediation.sudo_packages] : [];
|
|
75110
75192
|
}
|
|
75111
75193
|
function displayInstallErrors(skillsDir2) {
|
|
75112
|
-
const summaryPath =
|
|
75194
|
+
const summaryPath = join92(skillsDir2, ".install-error-summary.json");
|
|
75113
75195
|
if (!existsSync62(summaryPath)) {
|
|
75114
75196
|
logger.error("Skills installation failed. Run with --verbose for details.");
|
|
75115
75197
|
return;
|
|
@@ -75208,7 +75290,7 @@ async function checkNeedsSudoPackages() {
|
|
|
75208
75290
|
}
|
|
75209
75291
|
}
|
|
75210
75292
|
function hasInstallState(skillsDir2) {
|
|
75211
|
-
const stateFilePath =
|
|
75293
|
+
const stateFilePath = join92(skillsDir2, ".install-state.json");
|
|
75212
75294
|
return existsSync62(stateFilePath);
|
|
75213
75295
|
}
|
|
75214
75296
|
var WHICH_COMMAND_TIMEOUT_MS = 5000, WINDOWS_SYSTEM_PACKAGES, SYSTEM_TOOL_KEYS, WINDOWS_RSVG_COMMANDS;
|
|
@@ -75226,7 +75308,7 @@ var init_install_error_handler = __esm(() => {
|
|
|
75226
75308
|
});
|
|
75227
75309
|
|
|
75228
75310
|
// src/services/package-installer/skills-installer.ts
|
|
75229
|
-
import { join as
|
|
75311
|
+
import { join as join93 } from "node:path";
|
|
75230
75312
|
async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
75231
75313
|
const { skipConfirm = false, withSudo = false } = options2;
|
|
75232
75314
|
const displayName = "Skills Dependencies";
|
|
@@ -75252,7 +75334,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
75252
75334
|
const clack = await Promise.resolve().then(() => (init_dist2(), exports_dist));
|
|
75253
75335
|
const platform10 = process.platform;
|
|
75254
75336
|
const scriptName = platform10 === "win32" ? "install.ps1" : "install.sh";
|
|
75255
|
-
const scriptPath =
|
|
75337
|
+
const scriptPath = join93(skillsDir2, scriptName);
|
|
75256
75338
|
try {
|
|
75257
75339
|
validateScriptPath(skillsDir2, scriptPath);
|
|
75258
75340
|
} catch (error) {
|
|
@@ -75268,7 +75350,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
75268
75350
|
logger.warning(`Skills installation script not found: ${scriptPath}`);
|
|
75269
75351
|
logger.info("");
|
|
75270
75352
|
logger.info("\uD83D\uDCD6 Manual Installation Instructions:");
|
|
75271
|
-
logger.info(` See: ${
|
|
75353
|
+
logger.info(` See: ${join93(skillsDir2, "INSTALLATION.md")}`);
|
|
75272
75354
|
logger.info("");
|
|
75273
75355
|
logger.info("Quick start:");
|
|
75274
75356
|
logger.info(" cd .claude/skills/ai-multimodal/scripts");
|
|
@@ -75315,7 +75397,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
75315
75397
|
logger.info(` ${platform10 === "win32" ? `powershell -File "${scriptPath}"` : `bash ${scriptPath}`}`);
|
|
75316
75398
|
logger.info("");
|
|
75317
75399
|
logger.info("Or see complete guide:");
|
|
75318
|
-
logger.info(` ${
|
|
75400
|
+
logger.info(` ${join93(skillsDir2, "INSTALLATION.md")}`);
|
|
75319
75401
|
return {
|
|
75320
75402
|
success: false,
|
|
75321
75403
|
package: displayName,
|
|
@@ -75436,7 +75518,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
75436
75518
|
logger.info("\uD83D\uDCD6 Manual Installation Instructions:");
|
|
75437
75519
|
logger.info("");
|
|
75438
75520
|
logger.info("See complete guide:");
|
|
75439
|
-
logger.info(` cat ${
|
|
75521
|
+
logger.info(` cat ${join93(skillsDir2, "INSTALLATION.md")}`);
|
|
75440
75522
|
logger.info("");
|
|
75441
75523
|
logger.info("Quick start:");
|
|
75442
75524
|
logger.info(" cd .claude/skills/ai-multimodal/scripts");
|
|
@@ -75479,10 +75561,10 @@ var init_skills_installer2 = __esm(() => {
|
|
|
75479
75561
|
init_validators();
|
|
75480
75562
|
});
|
|
75481
75563
|
|
|
75482
|
-
// src/services/package-installer/
|
|
75564
|
+
// src/services/package-installer/agy-mcp/config-manager.ts
|
|
75483
75565
|
import { existsSync as existsSync63 } from "node:fs";
|
|
75484
75566
|
import { mkdir as mkdir23, readFile as readFile49, writeFile as writeFile25 } from "node:fs/promises";
|
|
75485
|
-
import { dirname as dirname34, join as
|
|
75567
|
+
import { dirname as dirname34, join as join94 } from "node:path";
|
|
75486
75568
|
async function readJsonFile(filePath) {
|
|
75487
75569
|
try {
|
|
75488
75570
|
const content = await readFile49(filePath, "utf-8");
|
|
@@ -75493,36 +75575,39 @@ async function readJsonFile(filePath) {
|
|
|
75493
75575
|
return null;
|
|
75494
75576
|
}
|
|
75495
75577
|
}
|
|
75496
|
-
async function
|
|
75497
|
-
const gitignorePath =
|
|
75498
|
-
const geminiPattern = ".gemini/";
|
|
75578
|
+
async function addAgyToGitignore(projectDir) {
|
|
75579
|
+
const gitignorePath = join94(projectDir, ".gitignore");
|
|
75499
75580
|
try {
|
|
75500
75581
|
let content = "";
|
|
75501
75582
|
if (existsSync63(gitignorePath)) {
|
|
75502
75583
|
content = await readFile49(gitignorePath, "utf-8");
|
|
75503
75584
|
const lines = content.split(`
|
|
75504
75585
|
`).map((line) => line.trim()).filter((line) => !line.startsWith("#"));
|
|
75505
|
-
const
|
|
75506
|
-
|
|
75507
|
-
|
|
75586
|
+
const agyPatterns = [
|
|
75587
|
+
".agents/mcp_config.json",
|
|
75588
|
+
"/.agents/mcp_config.json",
|
|
75589
|
+
".agents/mcp_config.json/"
|
|
75590
|
+
];
|
|
75591
|
+
if (lines.some((line) => agyPatterns.includes(line))) {
|
|
75592
|
+
logger.debug(".agents/mcp_config.json already in .gitignore");
|
|
75508
75593
|
return;
|
|
75509
75594
|
}
|
|
75510
75595
|
}
|
|
75511
75596
|
const newLine = content.endsWith(`
|
|
75512
75597
|
`) || content === "" ? "" : `
|
|
75513
75598
|
`;
|
|
75514
|
-
const comment = "#
|
|
75599
|
+
const comment = "# Antigravity CLI MCP config (symlinked to your Claude MCP config)";
|
|
75515
75600
|
await writeFile25(gitignorePath, `${content}${newLine}${comment}
|
|
75516
|
-
${
|
|
75601
|
+
${AGY_GITIGNORE_PATTERN}
|
|
75517
75602
|
`, "utf-8");
|
|
75518
|
-
logger.debug(`Added ${
|
|
75603
|
+
logger.debug(`Added ${AGY_GITIGNORE_PATTERN} to .gitignore`);
|
|
75519
75604
|
} catch (error) {
|
|
75520
75605
|
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
75521
75606
|
logger.warning(`Failed to update .gitignore: ${errorMessage}`);
|
|
75522
75607
|
}
|
|
75523
75608
|
}
|
|
75524
|
-
async function createNewSettingsWithMerge(
|
|
75525
|
-
const linkDir = dirname34(
|
|
75609
|
+
async function createNewSettingsWithMerge(agyConfigPath, mcpConfigPath) {
|
|
75610
|
+
const linkDir = dirname34(agyConfigPath);
|
|
75526
75611
|
if (!existsSync63(linkDir)) {
|
|
75527
75612
|
await mkdir23(linkDir, { recursive: true });
|
|
75528
75613
|
logger.debug(`Created directory: ${linkDir}`);
|
|
@@ -75537,8 +75622,8 @@ async function createNewSettingsWithMerge(geminiSettingsPath, mcpConfigPath) {
|
|
|
75537
75622
|
}
|
|
75538
75623
|
const newSettings = { mcpServers };
|
|
75539
75624
|
try {
|
|
75540
|
-
await writeFile25(
|
|
75541
|
-
logger.debug(`Created new
|
|
75625
|
+
await writeFile25(agyConfigPath, JSON.stringify(newSettings, null, 2), "utf-8");
|
|
75626
|
+
logger.debug(`Created new agy mcp_config.json with mcpServers: ${agyConfigPath}`);
|
|
75542
75627
|
return { success: true, method: "merge", targetPath: mcpConfigPath };
|
|
75543
75628
|
} catch (error) {
|
|
75544
75629
|
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
@@ -75549,10 +75634,14 @@ async function createNewSettingsWithMerge(geminiSettingsPath, mcpConfigPath) {
|
|
|
75549
75634
|
};
|
|
75550
75635
|
}
|
|
75551
75636
|
}
|
|
75552
|
-
async function
|
|
75553
|
-
const
|
|
75554
|
-
if (!
|
|
75555
|
-
return {
|
|
75637
|
+
async function mergeAgySettings(agyConfigPath, mcpConfigPath) {
|
|
75638
|
+
const agyConfig = await readJsonFile(agyConfigPath);
|
|
75639
|
+
if (!agyConfig) {
|
|
75640
|
+
return {
|
|
75641
|
+
success: false,
|
|
75642
|
+
method: "merge",
|
|
75643
|
+
error: "Failed to read existing agy mcp_config.json"
|
|
75644
|
+
};
|
|
75556
75645
|
}
|
|
75557
75646
|
const mcpConfig = await readJsonFile(mcpConfigPath);
|
|
75558
75647
|
if (!mcpConfig) {
|
|
@@ -75563,12 +75652,12 @@ async function mergeGeminiSettings(geminiSettingsPath, mcpConfigPath) {
|
|
|
75563
75652
|
return { success: false, method: "merge", error: "MCP config has no valid mcpServers object" };
|
|
75564
75653
|
}
|
|
75565
75654
|
const mergedSettings = {
|
|
75566
|
-
...
|
|
75655
|
+
...agyConfig,
|
|
75567
75656
|
mcpServers
|
|
75568
75657
|
};
|
|
75569
75658
|
try {
|
|
75570
|
-
await writeFile25(
|
|
75571
|
-
logger.debug(`Merged mcpServers into: ${
|
|
75659
|
+
await writeFile25(agyConfigPath, JSON.stringify(mergedSettings, null, 2), "utf-8");
|
|
75660
|
+
logger.debug(`Merged mcpServers into: ${agyConfigPath}`);
|
|
75572
75661
|
return { success: true, method: "merge", targetPath: mcpConfigPath };
|
|
75573
75662
|
} catch (error) {
|
|
75574
75663
|
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
@@ -75579,19 +75668,20 @@ async function mergeGeminiSettings(geminiSettingsPath, mcpConfigPath) {
|
|
|
75579
75668
|
};
|
|
75580
75669
|
}
|
|
75581
75670
|
}
|
|
75671
|
+
var AGY_GITIGNORE_PATTERN = ".agents/mcp_config.json";
|
|
75582
75672
|
var init_config_manager2 = __esm(() => {
|
|
75583
75673
|
init_logger();
|
|
75584
75674
|
});
|
|
75585
75675
|
|
|
75586
|
-
// src/services/package-installer/
|
|
75676
|
+
// src/services/package-installer/agy-mcp/validation.ts
|
|
75587
75677
|
import { existsSync as existsSync64, lstatSync, readlinkSync } from "node:fs";
|
|
75588
75678
|
import { homedir as homedir45 } from "node:os";
|
|
75589
|
-
import { join as
|
|
75679
|
+
import { join as join95 } from "node:path";
|
|
75590
75680
|
function getGlobalMcpConfigPath() {
|
|
75591
|
-
return
|
|
75681
|
+
return join95(homedir45(), ".claude", ".mcp.json");
|
|
75592
75682
|
}
|
|
75593
75683
|
function getLocalMcpConfigPath(projectDir) {
|
|
75594
|
-
return
|
|
75684
|
+
return join95(projectDir, ".mcp.json");
|
|
75595
75685
|
}
|
|
75596
75686
|
function findMcpConfigPath(projectDir) {
|
|
75597
75687
|
const localPath = getLocalMcpConfigPath(projectDir);
|
|
@@ -75607,41 +75697,41 @@ function findMcpConfigPath(projectDir) {
|
|
|
75607
75697
|
logger.debug("No MCP config found (local or global)");
|
|
75608
75698
|
return null;
|
|
75609
75699
|
}
|
|
75610
|
-
function
|
|
75700
|
+
function getAgyMcpConfigPath(projectDir, isGlobal) {
|
|
75611
75701
|
if (isGlobal) {
|
|
75612
|
-
return
|
|
75702
|
+
return join95(homedir45(), ".gemini", "config", "mcp_config.json");
|
|
75613
75703
|
}
|
|
75614
|
-
return
|
|
75704
|
+
return join95(projectDir, ".agents", "mcp_config.json");
|
|
75615
75705
|
}
|
|
75616
|
-
function
|
|
75617
|
-
const
|
|
75618
|
-
if (!existsSync64(
|
|
75619
|
-
return { exists: false, isSymlink: false, settingsPath:
|
|
75706
|
+
function checkExistingAgyConfig(projectDir, isGlobal = false) {
|
|
75707
|
+
const agyConfigPath = getAgyMcpConfigPath(projectDir, isGlobal);
|
|
75708
|
+
if (!existsSync64(agyConfigPath)) {
|
|
75709
|
+
return { exists: false, isSymlink: false, settingsPath: agyConfigPath };
|
|
75620
75710
|
}
|
|
75621
75711
|
try {
|
|
75622
|
-
const stats = lstatSync(
|
|
75712
|
+
const stats = lstatSync(agyConfigPath);
|
|
75623
75713
|
if (stats.isSymbolicLink()) {
|
|
75624
|
-
const target = readlinkSync(
|
|
75714
|
+
const target = readlinkSync(agyConfigPath);
|
|
75625
75715
|
return {
|
|
75626
75716
|
exists: true,
|
|
75627
75717
|
isSymlink: true,
|
|
75628
75718
|
currentTarget: target,
|
|
75629
|
-
settingsPath:
|
|
75719
|
+
settingsPath: agyConfigPath
|
|
75630
75720
|
};
|
|
75631
75721
|
}
|
|
75632
|
-
return { exists: true, isSymlink: false, settingsPath:
|
|
75722
|
+
return { exists: true, isSymlink: false, settingsPath: agyConfigPath };
|
|
75633
75723
|
} catch {
|
|
75634
|
-
return { exists: true, isSymlink: false, settingsPath:
|
|
75724
|
+
return { exists: true, isSymlink: false, settingsPath: agyConfigPath };
|
|
75635
75725
|
}
|
|
75636
75726
|
}
|
|
75637
75727
|
var init_validation = __esm(() => {
|
|
75638
75728
|
init_logger();
|
|
75639
75729
|
});
|
|
75640
75730
|
|
|
75641
|
-
// src/services/package-installer/
|
|
75731
|
+
// src/services/package-installer/agy-mcp/linker-core.ts
|
|
75642
75732
|
import { existsSync as existsSync65 } from "node:fs";
|
|
75643
75733
|
import { mkdir as mkdir24, symlink as symlink3 } from "node:fs/promises";
|
|
75644
|
-
import { dirname as dirname35, join as
|
|
75734
|
+
import { dirname as dirname35, join as join96 } from "node:path";
|
|
75645
75735
|
async function createSymlink(targetPath, linkPath, projectDir, isGlobal) {
|
|
75646
75736
|
const linkDir = dirname35(linkPath);
|
|
75647
75737
|
if (!existsSync65(linkDir)) {
|
|
@@ -75652,14 +75742,14 @@ async function createSymlink(targetPath, linkPath, projectDir, isGlobal) {
|
|
|
75652
75742
|
if (isGlobal) {
|
|
75653
75743
|
symlinkTarget = getGlobalMcpConfigPath();
|
|
75654
75744
|
} else {
|
|
75655
|
-
const localMcpPath =
|
|
75745
|
+
const localMcpPath = join96(projectDir, ".mcp.json");
|
|
75656
75746
|
const isLocalConfig = targetPath === localMcpPath;
|
|
75657
75747
|
symlinkTarget = isLocalConfig ? "../.mcp.json" : targetPath;
|
|
75658
75748
|
}
|
|
75659
75749
|
try {
|
|
75660
75750
|
await symlink3(symlinkTarget, linkPath, isWindows() ? "file" : undefined);
|
|
75661
75751
|
logger.debug(`Created symlink: ${linkPath} → ${symlinkTarget}`);
|
|
75662
|
-
return { success: true, method: "symlink", targetPath,
|
|
75752
|
+
return { success: true, method: "symlink", targetPath, agyConfigPath: linkPath };
|
|
75663
75753
|
} catch (error) {
|
|
75664
75754
|
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
75665
75755
|
return {
|
|
@@ -75675,21 +75765,21 @@ var init_linker_core = __esm(() => {
|
|
|
75675
75765
|
init_validation();
|
|
75676
75766
|
});
|
|
75677
75767
|
|
|
75678
|
-
// src/services/package-installer/
|
|
75679
|
-
var
|
|
75680
|
-
__export(
|
|
75681
|
-
|
|
75682
|
-
|
|
75683
|
-
|
|
75768
|
+
// src/services/package-installer/agy-mcp-linker.ts
|
|
75769
|
+
var exports_agy_mcp_linker = {};
|
|
75770
|
+
__export(exports_agy_mcp_linker, {
|
|
75771
|
+
processAgyMcpLinking: () => processAgyMcpLinking,
|
|
75772
|
+
linkAgyMcpConfig: () => linkAgyMcpConfig,
|
|
75773
|
+
getAgyMcpConfigPath: () => getAgyMcpConfigPath,
|
|
75684
75774
|
findMcpConfigPath: () => findMcpConfigPath,
|
|
75685
|
-
|
|
75686
|
-
|
|
75775
|
+
checkExistingAgyConfig: () => checkExistingAgyConfig,
|
|
75776
|
+
addAgyToGitignore: () => addAgyToGitignore
|
|
75687
75777
|
});
|
|
75688
75778
|
import { resolve as resolve39 } from "node:path";
|
|
75689
|
-
async function
|
|
75779
|
+
async function linkAgyMcpConfig(projectDir, options2 = {}) {
|
|
75690
75780
|
const { skipGitignore = false, isGlobal = false } = options2;
|
|
75691
75781
|
const resolvedProjectDir = resolve39(projectDir);
|
|
75692
|
-
const
|
|
75782
|
+
const agyConfigPath = getAgyMcpConfigPath(resolvedProjectDir, isGlobal);
|
|
75693
75783
|
const mcpConfigPath = findMcpConfigPath(resolvedProjectDir);
|
|
75694
75784
|
if (!mcpConfigPath) {
|
|
75695
75785
|
return {
|
|
@@ -75698,50 +75788,50 @@ async function linkGeminiMcpConfig(projectDir, options2 = {}) {
|
|
|
75698
75788
|
error: "No MCP config found. Create .mcp.json or ~/.claude/.mcp.json first."
|
|
75699
75789
|
};
|
|
75700
75790
|
}
|
|
75701
|
-
const existing =
|
|
75791
|
+
const existing = checkExistingAgyConfig(resolvedProjectDir, isGlobal);
|
|
75702
75792
|
let result;
|
|
75703
75793
|
if (!existing.exists) {
|
|
75704
|
-
result = await createSymlink(mcpConfigPath,
|
|
75794
|
+
result = await createSymlink(mcpConfigPath, agyConfigPath, resolvedProjectDir, isGlobal);
|
|
75705
75795
|
if (!result.success && process.platform === "win32") {
|
|
75706
75796
|
logger.debug("Symlink failed on Windows, falling back to merge");
|
|
75707
|
-
result = await createNewSettingsWithMerge(
|
|
75797
|
+
result = await createNewSettingsWithMerge(agyConfigPath, mcpConfigPath);
|
|
75708
75798
|
}
|
|
75709
75799
|
} else if (existing.isSymlink) {
|
|
75710
75800
|
result = {
|
|
75711
75801
|
success: true,
|
|
75712
75802
|
method: "skipped",
|
|
75713
75803
|
targetPath: existing.currentTarget,
|
|
75714
|
-
|
|
75804
|
+
agyConfigPath
|
|
75715
75805
|
};
|
|
75716
75806
|
} else {
|
|
75717
|
-
result = await
|
|
75807
|
+
result = await mergeAgySettings(agyConfigPath, mcpConfigPath);
|
|
75718
75808
|
}
|
|
75719
75809
|
if (result.success && !skipGitignore && !isGlobal) {
|
|
75720
|
-
await
|
|
75810
|
+
await addAgyToGitignore(resolvedProjectDir);
|
|
75721
75811
|
}
|
|
75722
75812
|
return result;
|
|
75723
75813
|
}
|
|
75724
|
-
async function
|
|
75725
|
-
logger.info("Setting up
|
|
75726
|
-
const result = await
|
|
75727
|
-
const
|
|
75814
|
+
async function processAgyMcpLinking(projectDir, options2 = {}) {
|
|
75815
|
+
logger.info("Setting up Antigravity (agy) CLI MCP integration...");
|
|
75816
|
+
const result = await linkAgyMcpConfig(projectDir, options2);
|
|
75817
|
+
const configPath = result.agyConfigPath || (options2.isGlobal ? "~/.gemini/config/mcp_config.json" : ".agents/mcp_config.json");
|
|
75728
75818
|
if (result.success) {
|
|
75729
75819
|
if (result.method === "symlink") {
|
|
75730
|
-
logger.success(`
|
|
75820
|
+
logger.success(`agy MCP linked: ${configPath} → ${result.targetPath}`);
|
|
75731
75821
|
logger.info("MCP servers will auto-sync with your Claude config.");
|
|
75732
75822
|
} else if (result.method === "merge") {
|
|
75733
|
-
logger.success("
|
|
75823
|
+
logger.success("agy MCP config updated (merged mcpServers, preserved your settings)");
|
|
75734
75824
|
logger.info("Note: Run 'ck init' again to sync MCP config changes.");
|
|
75735
75825
|
} else {
|
|
75736
|
-
logger.info("
|
|
75826
|
+
logger.info("agy MCP config already configured.");
|
|
75737
75827
|
}
|
|
75738
75828
|
} else {
|
|
75739
|
-
logger.warning(`
|
|
75740
|
-
const cmd = options2.isGlobal ? "mkdir -p ~/.gemini && ln -sf ~/.claude/.mcp.json ~/.gemini/
|
|
75829
|
+
logger.warning(`agy MCP setup incomplete: ${result.error}`);
|
|
75830
|
+
const cmd = options2.isGlobal ? "mkdir -p ~/.gemini/config && ln -sf ~/.claude/.mcp.json ~/.gemini/config/mcp_config.json" : "mkdir -p .agents && ln -sf ../.mcp.json .agents/mcp_config.json";
|
|
75741
75831
|
logger.info(`Manual setup: ${cmd}`);
|
|
75742
75832
|
}
|
|
75743
75833
|
}
|
|
75744
|
-
var
|
|
75834
|
+
var init_agy_mcp_linker = __esm(() => {
|
|
75745
75835
|
init_logger();
|
|
75746
75836
|
init_config_manager2();
|
|
75747
75837
|
init_linker_core();
|
|
@@ -75758,11 +75848,11 @@ __export(exports_package_installer, {
|
|
|
75758
75848
|
processPackageInstallations: () => processPackageInstallations,
|
|
75759
75849
|
isPackageInstalled: () => isPackageInstalled,
|
|
75760
75850
|
isOpenCodeInstalled: () => isOpenCodeInstalled,
|
|
75761
|
-
|
|
75851
|
+
isAgyInstalled: () => isAgyInstalled,
|
|
75762
75852
|
installSkillsDependencies: () => installSkillsDependencies,
|
|
75763
75853
|
installPackageGlobally: () => installPackageGlobally,
|
|
75764
75854
|
installOpenCode: () => installOpenCode,
|
|
75765
|
-
|
|
75855
|
+
installAgy: () => installAgy,
|
|
75766
75856
|
handleSkillsInstallation: () => handleSkillsInstallation,
|
|
75767
75857
|
getPackageVersion: () => getPackageVersion,
|
|
75768
75858
|
getNpmCommand: () => getNpmCommand,
|
|
@@ -75771,9 +75861,10 @@ __export(exports_package_installer, {
|
|
|
75771
75861
|
execAsync: () => execAsync7,
|
|
75772
75862
|
PARTIAL_INSTALL_VERSION: () => PARTIAL_INSTALL_VERSION,
|
|
75773
75863
|
EXIT_CODE_PARTIAL_SUCCESS: () => EXIT_CODE_PARTIAL_SUCCESS,
|
|
75774
|
-
EXIT_CODE_CRITICAL_FAILURE: () => EXIT_CODE_CRITICAL_FAILURE
|
|
75864
|
+
EXIT_CODE_CRITICAL_FAILURE: () => EXIT_CODE_CRITICAL_FAILURE,
|
|
75865
|
+
AGY_DISPLAY_NAME: () => AGY_DISPLAY_NAME
|
|
75775
75866
|
});
|
|
75776
|
-
async function processPackageInstallations(shouldInstallOpenCode,
|
|
75867
|
+
async function processPackageInstallations(shouldInstallOpenCode, shouldInstallAgy, projectDir) {
|
|
75777
75868
|
const results = {};
|
|
75778
75869
|
if (shouldInstallOpenCode) {
|
|
75779
75870
|
if (isTestEnvironment()) {
|
|
@@ -75795,28 +75886,28 @@ async function processPackageInstallations(shouldInstallOpenCode, shouldInstallG
|
|
|
75795
75886
|
}
|
|
75796
75887
|
}
|
|
75797
75888
|
}
|
|
75798
|
-
if (
|
|
75889
|
+
if (shouldInstallAgy) {
|
|
75799
75890
|
if (isTestEnvironment()) {
|
|
75800
|
-
results.
|
|
75891
|
+
results.agy = {
|
|
75801
75892
|
success: true,
|
|
75802
|
-
package:
|
|
75893
|
+
package: AGY_DISPLAY_NAME,
|
|
75803
75894
|
skipped: true
|
|
75804
75895
|
};
|
|
75805
75896
|
} else {
|
|
75806
|
-
const alreadyInstalled = await
|
|
75897
|
+
const alreadyInstalled = await isAgyInstalled();
|
|
75807
75898
|
if (alreadyInstalled) {
|
|
75808
|
-
logger.info(
|
|
75809
|
-
results.
|
|
75899
|
+
logger.info(`${AGY_DISPLAY_NAME} already installed`);
|
|
75900
|
+
results.agy = {
|
|
75810
75901
|
success: true,
|
|
75811
|
-
package:
|
|
75902
|
+
package: AGY_DISPLAY_NAME
|
|
75812
75903
|
};
|
|
75813
75904
|
} else {
|
|
75814
|
-
results.
|
|
75905
|
+
results.agy = await installAgy();
|
|
75815
75906
|
}
|
|
75816
|
-
const
|
|
75817
|
-
if (projectDir &&
|
|
75818
|
-
const {
|
|
75819
|
-
await
|
|
75907
|
+
const agyAvailable = alreadyInstalled || results.agy?.success;
|
|
75908
|
+
if (projectDir && agyAvailable) {
|
|
75909
|
+
const { processAgyMcpLinking: processAgyMcpLinking2 } = await Promise.resolve().then(() => (init_agy_mcp_linker(), exports_agy_mcp_linker));
|
|
75910
|
+
await processAgyMcpLinking2(projectDir);
|
|
75820
75911
|
}
|
|
75821
75912
|
}
|
|
75822
75913
|
}
|
|
@@ -75825,13 +75916,13 @@ async function processPackageInstallations(shouldInstallOpenCode, shouldInstallG
|
|
|
75825
75916
|
var init_package_installer = __esm(() => {
|
|
75826
75917
|
init_environment();
|
|
75827
75918
|
init_logger();
|
|
75828
|
-
|
|
75919
|
+
init_agy_installer();
|
|
75829
75920
|
init_opencode_installer();
|
|
75830
75921
|
init_validators();
|
|
75831
75922
|
init_process_executor();
|
|
75832
75923
|
init_npm_package_manager();
|
|
75833
75924
|
init_opencode_installer();
|
|
75834
|
-
|
|
75925
|
+
init_agy_installer();
|
|
75835
75926
|
init_skills_installer2();
|
|
75836
75927
|
});
|
|
75837
75928
|
|
|
@@ -78068,10 +78159,10 @@ __export(exports_worktree_manager, {
|
|
|
78068
78159
|
cleanupAllWorktrees: () => cleanupAllWorktrees
|
|
78069
78160
|
});
|
|
78070
78161
|
import { existsSync as existsSync77 } from "node:fs";
|
|
78071
|
-
import { readFile as
|
|
78072
|
-
import { join as
|
|
78162
|
+
import { readFile as readFile70, writeFile as writeFile41 } from "node:fs/promises";
|
|
78163
|
+
import { join as join160 } from "node:path";
|
|
78073
78164
|
async function createWorktree(projectDir, issueNumber, baseBranch) {
|
|
78074
|
-
const worktreePath =
|
|
78165
|
+
const worktreePath = join160(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
|
|
78075
78166
|
const branchName = `ck-watch/issue-${issueNumber}`;
|
|
78076
78167
|
await spawnAndCollect("git", ["fetch", "origin", baseBranch], projectDir).catch(() => {
|
|
78077
78168
|
logger.warning(`[worktree] Could not fetch origin/${baseBranch}, using local`);
|
|
@@ -78089,7 +78180,7 @@ async function createWorktree(projectDir, issueNumber, baseBranch) {
|
|
|
78089
78180
|
return worktreePath;
|
|
78090
78181
|
}
|
|
78091
78182
|
async function removeWorktree(projectDir, issueNumber) {
|
|
78092
|
-
const worktreePath =
|
|
78183
|
+
const worktreePath = join160(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
|
|
78093
78184
|
const branchName = `ck-watch/issue-${issueNumber}`;
|
|
78094
78185
|
try {
|
|
78095
78186
|
await spawnAndCollect("git", ["worktree", "remove", worktreePath, "--force"], projectDir);
|
|
@@ -78103,7 +78194,7 @@ async function listActiveWorktrees(projectDir) {
|
|
|
78103
78194
|
try {
|
|
78104
78195
|
const output2 = await spawnAndCollect("git", ["worktree", "list", "--porcelain"], projectDir);
|
|
78105
78196
|
const issueNumbers = [];
|
|
78106
|
-
const worktreePrefix =
|
|
78197
|
+
const worktreePrefix = join160(projectDir, WORKTREE_DIR, "issue-").replace(/\\/g, "/");
|
|
78107
78198
|
for (const line of output2.split(`
|
|
78108
78199
|
`)) {
|
|
78109
78200
|
if (line.startsWith("worktree ")) {
|
|
@@ -78131,16 +78222,16 @@ async function cleanupAllWorktrees(projectDir) {
|
|
|
78131
78222
|
await spawnAndCollect("git", ["worktree", "prune"], projectDir).catch(() => {});
|
|
78132
78223
|
}
|
|
78133
78224
|
async function ensureGitignore(projectDir) {
|
|
78134
|
-
const gitignorePath =
|
|
78225
|
+
const gitignorePath = join160(projectDir, ".gitignore");
|
|
78135
78226
|
try {
|
|
78136
|
-
const content = existsSync77(gitignorePath) ? await
|
|
78227
|
+
const content = existsSync77(gitignorePath) ? await readFile70(gitignorePath, "utf-8") : "";
|
|
78137
78228
|
if (!content.includes(".worktrees")) {
|
|
78138
78229
|
const newContent = content.endsWith(`
|
|
78139
78230
|
`) ? `${content}.worktrees/
|
|
78140
78231
|
` : `${content}
|
|
78141
78232
|
.worktrees/
|
|
78142
78233
|
`;
|
|
78143
|
-
await
|
|
78234
|
+
await writeFile41(gitignorePath, newContent, "utf-8");
|
|
78144
78235
|
logger.info("[worktree] Added .worktrees/ to .gitignore");
|
|
78145
78236
|
}
|
|
78146
78237
|
} catch (err) {
|
|
@@ -78236,9 +78327,9 @@ var init_content_validator = __esm(() => {
|
|
|
78236
78327
|
// src/commands/content/phases/context-cache-manager.ts
|
|
78237
78328
|
import { createHash as createHash9 } from "node:crypto";
|
|
78238
78329
|
import { existsSync as existsSync83, mkdirSync as mkdirSync7, readFileSync as readFileSync22, readdirSync as readdirSync14, statSync as statSync15 } from "node:fs";
|
|
78239
|
-
import { rename as rename16, writeFile as
|
|
78330
|
+
import { rename as rename16, writeFile as writeFile43 } from "node:fs/promises";
|
|
78240
78331
|
import { homedir as homedir54 } from "node:os";
|
|
78241
|
-
import { basename as basename34, join as
|
|
78332
|
+
import { basename as basename34, join as join167 } from "node:path";
|
|
78242
78333
|
function getCachedContext(repoPath) {
|
|
78243
78334
|
const cachePath = getCacheFilePath(repoPath);
|
|
78244
78335
|
if (!existsSync83(cachePath))
|
|
@@ -78263,7 +78354,7 @@ async function saveCachedContext(repoPath, cache5) {
|
|
|
78263
78354
|
}
|
|
78264
78355
|
const cachePath = getCacheFilePath(repoPath);
|
|
78265
78356
|
const tmpPath = `${cachePath}.tmp`;
|
|
78266
|
-
await
|
|
78357
|
+
await writeFile43(tmpPath, JSON.stringify(cache5, null, 2), "utf-8");
|
|
78267
78358
|
await rename16(tmpPath, cachePath);
|
|
78268
78359
|
}
|
|
78269
78360
|
function computeSourceHash(repoPath) {
|
|
@@ -78281,25 +78372,25 @@ function computeSourceHash(repoPath) {
|
|
|
78281
78372
|
}
|
|
78282
78373
|
function getDocSourcePaths(repoPath) {
|
|
78283
78374
|
const paths = [];
|
|
78284
|
-
const docsDir =
|
|
78375
|
+
const docsDir = join167(repoPath, "docs");
|
|
78285
78376
|
if (existsSync83(docsDir)) {
|
|
78286
78377
|
try {
|
|
78287
78378
|
const files = readdirSync14(docsDir);
|
|
78288
78379
|
for (const f3 of files) {
|
|
78289
78380
|
if (f3.endsWith(".md"))
|
|
78290
|
-
paths.push(
|
|
78381
|
+
paths.push(join167(docsDir, f3));
|
|
78291
78382
|
}
|
|
78292
78383
|
} catch {}
|
|
78293
78384
|
}
|
|
78294
|
-
const readme =
|
|
78385
|
+
const readme = join167(repoPath, "README.md");
|
|
78295
78386
|
if (existsSync83(readme))
|
|
78296
78387
|
paths.push(readme);
|
|
78297
|
-
const stylesDir =
|
|
78388
|
+
const stylesDir = join167(repoPath, "assets", "writing-styles");
|
|
78298
78389
|
if (existsSync83(stylesDir)) {
|
|
78299
78390
|
try {
|
|
78300
78391
|
const files = readdirSync14(stylesDir);
|
|
78301
78392
|
for (const f3 of files) {
|
|
78302
|
-
paths.push(
|
|
78393
|
+
paths.push(join167(stylesDir, f3));
|
|
78303
78394
|
}
|
|
78304
78395
|
} catch {}
|
|
78305
78396
|
}
|
|
@@ -78308,11 +78399,11 @@ function getDocSourcePaths(repoPath) {
|
|
|
78308
78399
|
function getCacheFilePath(repoPath) {
|
|
78309
78400
|
const repoName = basename34(repoPath).replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
78310
78401
|
const pathHash = createHash9("sha256").update(repoPath).digest("hex").slice(0, 8);
|
|
78311
|
-
return
|
|
78402
|
+
return join167(CACHE_DIR, `${repoName}-${pathHash}-context-cache.json`);
|
|
78312
78403
|
}
|
|
78313
78404
|
var CACHE_DIR, CACHE_TTL_MS5;
|
|
78314
78405
|
var init_context_cache_manager = __esm(() => {
|
|
78315
|
-
CACHE_DIR =
|
|
78406
|
+
CACHE_DIR = join167(homedir54(), ".claudekit", "cache");
|
|
78316
78407
|
CACHE_TTL_MS5 = 24 * 60 * 60 * 1000;
|
|
78317
78408
|
});
|
|
78318
78409
|
|
|
@@ -78493,7 +78584,7 @@ function extractContentFromResponse(response) {
|
|
|
78493
78584
|
// src/commands/content/phases/docs-summarizer.ts
|
|
78494
78585
|
import { execSync as execSync7 } from "node:child_process";
|
|
78495
78586
|
import { existsSync as existsSync84, readFileSync as readFileSync23, readdirSync as readdirSync15 } from "node:fs";
|
|
78496
|
-
import { join as
|
|
78587
|
+
import { join as join168 } from "node:path";
|
|
78497
78588
|
async function summarizeProjectDocs(repoPath, contentLogger) {
|
|
78498
78589
|
const rawContent = collectRawDocs(repoPath);
|
|
78499
78590
|
if (rawContent.total.length < 200) {
|
|
@@ -78547,12 +78638,12 @@ function collectRawDocs(repoPath) {
|
|
|
78547
78638
|
return capped;
|
|
78548
78639
|
};
|
|
78549
78640
|
const docsContent = [];
|
|
78550
|
-
const docsDir =
|
|
78641
|
+
const docsDir = join168(repoPath, "docs");
|
|
78551
78642
|
if (existsSync84(docsDir)) {
|
|
78552
78643
|
try {
|
|
78553
78644
|
const files = readdirSync15(docsDir).filter((f3) => f3.endsWith(".md")).sort();
|
|
78554
78645
|
for (const f3 of files) {
|
|
78555
|
-
const content = readCapped(
|
|
78646
|
+
const content = readCapped(join168(docsDir, f3), 5000);
|
|
78556
78647
|
if (content) {
|
|
78557
78648
|
docsContent.push(`### ${f3}
|
|
78558
78649
|
${content}`);
|
|
@@ -78566,21 +78657,21 @@ ${content}`);
|
|
|
78566
78657
|
let brand = "";
|
|
78567
78658
|
const brandCandidates = ["docs/brand-guidelines.md", "docs/design-guidelines.md"];
|
|
78568
78659
|
for (const p of brandCandidates) {
|
|
78569
|
-
brand = readCapped(
|
|
78660
|
+
brand = readCapped(join168(repoPath, p), 3000);
|
|
78570
78661
|
if (brand)
|
|
78571
78662
|
break;
|
|
78572
78663
|
}
|
|
78573
78664
|
let styles3 = "";
|
|
78574
|
-
const stylesDir =
|
|
78665
|
+
const stylesDir = join168(repoPath, "assets", "writing-styles");
|
|
78575
78666
|
if (existsSync84(stylesDir)) {
|
|
78576
78667
|
try {
|
|
78577
78668
|
const files = readdirSync15(stylesDir).slice(0, 3);
|
|
78578
|
-
styles3 = files.map((f3) => readCapped(
|
|
78669
|
+
styles3 = files.map((f3) => readCapped(join168(stylesDir, f3), 1000)).filter(Boolean).join(`
|
|
78579
78670
|
|
|
78580
78671
|
`);
|
|
78581
78672
|
} catch {}
|
|
78582
78673
|
}
|
|
78583
|
-
const readme = readCapped(
|
|
78674
|
+
const readme = readCapped(join168(repoPath, "README.md"), 3000);
|
|
78584
78675
|
const total = [docs, brand, styles3, readme].join(`
|
|
78585
78676
|
`);
|
|
78586
78677
|
return { docs, brand, styles: styles3, readme, total };
|
|
@@ -78767,9 +78858,9 @@ IMPORTANT: Generate the image and output the path as JSON: {"imagePath": "/path/
|
|
|
78767
78858
|
import { execSync as execSync8 } from "node:child_process";
|
|
78768
78859
|
import { existsSync as existsSync85, mkdirSync as mkdirSync8, readdirSync as readdirSync16 } from "node:fs";
|
|
78769
78860
|
import { homedir as homedir55 } from "node:os";
|
|
78770
|
-
import { join as
|
|
78861
|
+
import { join as join169 } from "node:path";
|
|
78771
78862
|
async function generatePhoto(_content, context, config, platform18, contentId, contentLogger) {
|
|
78772
|
-
const mediaDir =
|
|
78863
|
+
const mediaDir = join169(config.contentDir.replace(/^~/, homedir55()), "media", String(contentId));
|
|
78773
78864
|
if (!existsSync85(mediaDir)) {
|
|
78774
78865
|
mkdirSync8(mediaDir, { recursive: true });
|
|
78775
78866
|
}
|
|
@@ -78794,7 +78885,7 @@ async function generatePhoto(_content, context, config, platform18, contentId, c
|
|
|
78794
78885
|
const imageFile = files.find((f3) => /\.(png|jpg|jpeg|webp)$/i.test(f3));
|
|
78795
78886
|
if (imageFile) {
|
|
78796
78887
|
const ext2 = imageFile.split(".").pop() ?? "png";
|
|
78797
|
-
return { path:
|
|
78888
|
+
return { path: join169(mediaDir, imageFile), ...dimensions, format: ext2 };
|
|
78798
78889
|
}
|
|
78799
78890
|
contentLogger.warn(`Photo generation produced no image for content ${contentId}`);
|
|
78800
78891
|
return null;
|
|
@@ -78884,7 +78975,7 @@ var init_content_creator = __esm(() => {
|
|
|
78884
78975
|
// src/commands/content/phases/content-logger.ts
|
|
78885
78976
|
import { createWriteStream as createWriteStream4, existsSync as existsSync86, mkdirSync as mkdirSync9, statSync as statSync16 } from "node:fs";
|
|
78886
78977
|
import { homedir as homedir56 } from "node:os";
|
|
78887
|
-
import { join as
|
|
78978
|
+
import { join as join170 } from "node:path";
|
|
78888
78979
|
|
|
78889
78980
|
class ContentLogger {
|
|
78890
78981
|
stream = null;
|
|
@@ -78892,7 +78983,7 @@ class ContentLogger {
|
|
|
78892
78983
|
logDir;
|
|
78893
78984
|
maxBytes;
|
|
78894
78985
|
constructor(maxBytes = 0) {
|
|
78895
|
-
this.logDir =
|
|
78986
|
+
this.logDir = join170(homedir56(), ".claudekit", "logs");
|
|
78896
78987
|
this.maxBytes = maxBytes;
|
|
78897
78988
|
}
|
|
78898
78989
|
init() {
|
|
@@ -78924,7 +79015,7 @@ class ContentLogger {
|
|
|
78924
79015
|
}
|
|
78925
79016
|
}
|
|
78926
79017
|
getLogPath() {
|
|
78927
|
-
return
|
|
79018
|
+
return join170(this.logDir, `content-${this.getDateStr()}.log`);
|
|
78928
79019
|
}
|
|
78929
79020
|
write(level, message) {
|
|
78930
79021
|
this.rotateIfNeeded();
|
|
@@ -78941,18 +79032,18 @@ class ContentLogger {
|
|
|
78941
79032
|
if (dateStr !== this.currentDate) {
|
|
78942
79033
|
this.close();
|
|
78943
79034
|
this.currentDate = dateStr;
|
|
78944
|
-
const logPath =
|
|
79035
|
+
const logPath = join170(this.logDir, `content-${dateStr}.log`);
|
|
78945
79036
|
this.stream = createWriteStream4(logPath, { flags: "a", mode: 384 });
|
|
78946
79037
|
return;
|
|
78947
79038
|
}
|
|
78948
79039
|
if (this.maxBytes > 0 && this.stream) {
|
|
78949
|
-
const logPath =
|
|
79040
|
+
const logPath = join170(this.logDir, `content-${this.currentDate}.log`);
|
|
78950
79041
|
try {
|
|
78951
79042
|
const stat26 = statSync16(logPath);
|
|
78952
79043
|
if (stat26.size >= this.maxBytes) {
|
|
78953
79044
|
this.close();
|
|
78954
79045
|
const suffix = Date.now();
|
|
78955
|
-
const rotatedPath =
|
|
79046
|
+
const rotatedPath = join170(this.logDir, `content-${this.currentDate}-${suffix}.log`);
|
|
78956
79047
|
import("node:fs/promises").then(({ rename: rename17 }) => rename17(logPath, rotatedPath).catch(() => {}));
|
|
78957
79048
|
this.stream = createWriteStream4(logPath, { flags: "w", mode: 384 });
|
|
78958
79049
|
}
|
|
@@ -79223,7 +79314,7 @@ function isNoiseCommit(title, author) {
|
|
|
79223
79314
|
// src/commands/content/phases/change-detector.ts
|
|
79224
79315
|
import { execSync as execSync10, spawnSync as spawnSync9 } from "node:child_process";
|
|
79225
79316
|
import { existsSync as existsSync88, readFileSync as readFileSync24, readdirSync as readdirSync17, statSync as statSync17 } from "node:fs";
|
|
79226
|
-
import { join as
|
|
79317
|
+
import { join as join171 } from "node:path";
|
|
79227
79318
|
function detectCommits(repo, since) {
|
|
79228
79319
|
try {
|
|
79229
79320
|
const fetchUrl = sshToHttps(repo.remoteUrl);
|
|
@@ -79332,7 +79423,7 @@ function detectTags(repo, since) {
|
|
|
79332
79423
|
}
|
|
79333
79424
|
}
|
|
79334
79425
|
function detectCompletedPlans(repo, since) {
|
|
79335
|
-
const plansDir =
|
|
79426
|
+
const plansDir = join171(repo.path, "plans");
|
|
79336
79427
|
if (!existsSync88(plansDir))
|
|
79337
79428
|
return [];
|
|
79338
79429
|
const sinceMs = new Date(since).getTime();
|
|
@@ -79342,7 +79433,7 @@ function detectCompletedPlans(repo, since) {
|
|
|
79342
79433
|
for (const entry of entries) {
|
|
79343
79434
|
if (!entry.isDirectory())
|
|
79344
79435
|
continue;
|
|
79345
|
-
const planFile =
|
|
79436
|
+
const planFile = join171(plansDir, entry.name, "plan.md");
|
|
79346
79437
|
if (!existsSync88(planFile))
|
|
79347
79438
|
continue;
|
|
79348
79439
|
try {
|
|
@@ -79420,7 +79511,7 @@ function classifyCommit(event) {
|
|
|
79420
79511
|
// src/commands/content/phases/repo-discoverer.ts
|
|
79421
79512
|
import { execSync as execSync11 } from "node:child_process";
|
|
79422
79513
|
import { readdirSync as readdirSync18 } from "node:fs";
|
|
79423
|
-
import { join as
|
|
79514
|
+
import { join as join172 } from "node:path";
|
|
79424
79515
|
function discoverRepos2(cwd2) {
|
|
79425
79516
|
const repos = [];
|
|
79426
79517
|
if (isGitRepoRoot(cwd2)) {
|
|
@@ -79433,7 +79524,7 @@ function discoverRepos2(cwd2) {
|
|
|
79433
79524
|
for (const entry of entries) {
|
|
79434
79525
|
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
79435
79526
|
continue;
|
|
79436
|
-
const dirPath =
|
|
79527
|
+
const dirPath = join172(cwd2, entry.name);
|
|
79437
79528
|
if (isGitRepoRoot(dirPath)) {
|
|
79438
79529
|
const info = getRepoInfo(dirPath);
|
|
79439
79530
|
if (info)
|
|
@@ -80100,12 +80191,12 @@ var init_types6 = __esm(() => {
|
|
|
80100
80191
|
});
|
|
80101
80192
|
|
|
80102
80193
|
// src/commands/content/phases/state-manager.ts
|
|
80103
|
-
import { readFile as
|
|
80104
|
-
import { join as
|
|
80194
|
+
import { readFile as readFile72, rename as rename17, writeFile as writeFile44 } from "node:fs/promises";
|
|
80195
|
+
import { join as join173 } from "node:path";
|
|
80105
80196
|
async function loadContentConfig(projectDir) {
|
|
80106
|
-
const configPath =
|
|
80197
|
+
const configPath = join173(projectDir, CK_CONFIG_FILE2);
|
|
80107
80198
|
try {
|
|
80108
|
-
const raw2 = await
|
|
80199
|
+
const raw2 = await readFile72(configPath, "utf-8");
|
|
80109
80200
|
const json = JSON.parse(raw2);
|
|
80110
80201
|
return ContentConfigSchema.parse(json.content ?? {});
|
|
80111
80202
|
} catch {
|
|
@@ -80113,15 +80204,15 @@ async function loadContentConfig(projectDir) {
|
|
|
80113
80204
|
}
|
|
80114
80205
|
}
|
|
80115
80206
|
async function saveContentConfig(projectDir, config) {
|
|
80116
|
-
const configPath =
|
|
80207
|
+
const configPath = join173(projectDir, CK_CONFIG_FILE2);
|
|
80117
80208
|
const json = await readJsonSafe4(configPath);
|
|
80118
80209
|
json.content = { ...json.content, ...config };
|
|
80119
80210
|
await atomicWrite3(configPath, json);
|
|
80120
80211
|
}
|
|
80121
80212
|
async function loadContentState(projectDir) {
|
|
80122
|
-
const configPath =
|
|
80213
|
+
const configPath = join173(projectDir, CK_CONFIG_FILE2);
|
|
80123
80214
|
try {
|
|
80124
|
-
const raw2 = await
|
|
80215
|
+
const raw2 = await readFile72(configPath, "utf-8");
|
|
80125
80216
|
const json = JSON.parse(raw2);
|
|
80126
80217
|
const contentBlock = json.content ?? {};
|
|
80127
80218
|
return ContentStateSchema.parse(contentBlock.state ?? {});
|
|
@@ -80130,7 +80221,7 @@ async function loadContentState(projectDir) {
|
|
|
80130
80221
|
}
|
|
80131
80222
|
}
|
|
80132
80223
|
async function saveContentState(projectDir, state) {
|
|
80133
|
-
const configPath =
|
|
80224
|
+
const configPath = join173(projectDir, CK_CONFIG_FILE2);
|
|
80134
80225
|
const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().slice(0, 10);
|
|
80135
80226
|
for (const key of Object.keys(state.dailyPostCounts)) {
|
|
80136
80227
|
const dateStr = key.slice(-10);
|
|
@@ -80148,7 +80239,7 @@ async function saveContentState(projectDir, state) {
|
|
|
80148
80239
|
}
|
|
80149
80240
|
async function readJsonSafe4(filePath) {
|
|
80150
80241
|
try {
|
|
80151
|
-
const raw2 = await
|
|
80242
|
+
const raw2 = await readFile72(filePath, "utf-8");
|
|
80152
80243
|
return JSON.parse(raw2);
|
|
80153
80244
|
} catch {
|
|
80154
80245
|
return {};
|
|
@@ -80156,7 +80247,7 @@ async function readJsonSafe4(filePath) {
|
|
|
80156
80247
|
}
|
|
80157
80248
|
async function atomicWrite3(filePath, data) {
|
|
80158
80249
|
const tmpPath = `${filePath}.tmp`;
|
|
80159
|
-
await
|
|
80250
|
+
await writeFile44(tmpPath, JSON.stringify(data, null, 2), "utf-8");
|
|
80160
80251
|
await rename17(tmpPath, filePath);
|
|
80161
80252
|
}
|
|
80162
80253
|
var CK_CONFIG_FILE2 = ".ck.json";
|
|
@@ -80412,7 +80503,7 @@ var init_platform_setup_x = __esm(() => {
|
|
|
80412
80503
|
|
|
80413
80504
|
// src/commands/content/phases/setup-wizard.ts
|
|
80414
80505
|
import { existsSync as existsSync89 } from "node:fs";
|
|
80415
|
-
import { join as
|
|
80506
|
+
import { join as join174 } from "node:path";
|
|
80416
80507
|
async function runSetupWizard2(cwd2, contentLogger) {
|
|
80417
80508
|
console.log();
|
|
80418
80509
|
oe(import_picocolors43.default.bgCyan(import_picocolors43.default.white(" CK Content — Multi-Channel Content Engine ")));
|
|
@@ -80480,8 +80571,8 @@ async function showRepoSummary(cwd2) {
|
|
|
80480
80571
|
function detectBrandAssets(cwd2, contentLogger) {
|
|
80481
80572
|
const repos = discoverRepos2(cwd2);
|
|
80482
80573
|
for (const repo of repos) {
|
|
80483
|
-
const hasGuidelines = existsSync89(
|
|
80484
|
-
const hasStyles = existsSync89(
|
|
80574
|
+
const hasGuidelines = existsSync89(join174(repo.path, "docs", "brand-guidelines.md"));
|
|
80575
|
+
const hasStyles = existsSync89(join174(repo.path, "assets", "writing-styles"));
|
|
80485
80576
|
if (!hasGuidelines) {
|
|
80486
80577
|
f2.warning(`${repo.name}: No docs/brand-guidelines.md — content will use generic tone.`);
|
|
80487
80578
|
contentLogger.warn(`${repo.name}: missing docs/brand-guidelines.md`);
|
|
@@ -80623,9 +80714,9 @@ __export(exports_content_subcommands, {
|
|
|
80623
80714
|
});
|
|
80624
80715
|
import { existsSync as existsSync91, readFileSync as readFileSync25, unlinkSync as unlinkSync6 } from "node:fs";
|
|
80625
80716
|
import { homedir as homedir58 } from "node:os";
|
|
80626
|
-
import { join as
|
|
80717
|
+
import { join as join175 } from "node:path";
|
|
80627
80718
|
function isDaemonRunning() {
|
|
80628
|
-
const lockFile =
|
|
80719
|
+
const lockFile = join175(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
80629
80720
|
if (!existsSync91(lockFile))
|
|
80630
80721
|
return { running: false, pid: null };
|
|
80631
80722
|
try {
|
|
@@ -80657,7 +80748,7 @@ async function startContent(options2) {
|
|
|
80657
80748
|
await contentCommand(options2);
|
|
80658
80749
|
}
|
|
80659
80750
|
async function stopContent() {
|
|
80660
|
-
const lockFile =
|
|
80751
|
+
const lockFile = join175(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
80661
80752
|
if (!existsSync91(lockFile)) {
|
|
80662
80753
|
logger.info("Content daemon is not running.");
|
|
80663
80754
|
return;
|
|
@@ -80696,9 +80787,9 @@ async function statusContent() {
|
|
|
80696
80787
|
} catch {}
|
|
80697
80788
|
}
|
|
80698
80789
|
async function logsContent(options2) {
|
|
80699
|
-
const logDir =
|
|
80790
|
+
const logDir = join175(homedir58(), ".claudekit", "logs");
|
|
80700
80791
|
const dateStr = new Date().toISOString().slice(0, 10).replace(/-/g, "");
|
|
80701
|
-
const logPath =
|
|
80792
|
+
const logPath = join175(logDir, `content-${dateStr}.log`);
|
|
80702
80793
|
if (!existsSync91(logPath)) {
|
|
80703
80794
|
logger.info("No content logs found for today.");
|
|
80704
80795
|
return;
|
|
@@ -80730,13 +80821,13 @@ var init_content_subcommands = __esm(() => {
|
|
|
80730
80821
|
init_setup_wizard();
|
|
80731
80822
|
init_state_manager();
|
|
80732
80823
|
init_content_review_commands();
|
|
80733
|
-
LOCK_DIR =
|
|
80824
|
+
LOCK_DIR = join175(homedir58(), ".claudekit", "locks");
|
|
80734
80825
|
});
|
|
80735
80826
|
|
|
80736
80827
|
// src/commands/content/content-command.ts
|
|
80737
80828
|
import { existsSync as existsSync92, mkdirSync as mkdirSync11, unlinkSync as unlinkSync7, writeFileSync as writeFileSync9 } from "node:fs";
|
|
80738
80829
|
import { homedir as homedir59 } from "node:os";
|
|
80739
|
-
import { join as
|
|
80830
|
+
import { join as join176 } from "node:path";
|
|
80740
80831
|
async function contentCommand(options2) {
|
|
80741
80832
|
const cwd2 = process.cwd();
|
|
80742
80833
|
const contentLogger = new ContentLogger;
|
|
@@ -80914,8 +81005,8 @@ var init_content_command = __esm(() => {
|
|
|
80914
81005
|
init_publisher();
|
|
80915
81006
|
init_review_manager();
|
|
80916
81007
|
init_state_manager();
|
|
80917
|
-
LOCK_DIR2 =
|
|
80918
|
-
LOCK_FILE =
|
|
81008
|
+
LOCK_DIR2 = join176(homedir59(), ".claudekit", "locks");
|
|
81009
|
+
LOCK_FILE = join176(LOCK_DIR2, "ck-content.lock");
|
|
80919
81010
|
});
|
|
80920
81011
|
|
|
80921
81012
|
// src/commands/content/index.ts
|
|
@@ -94159,7 +94250,7 @@ async function getLatestVersion(kit, includePrereleases = false) {
|
|
|
94159
94250
|
init_logger();
|
|
94160
94251
|
init_path_resolver();
|
|
94161
94252
|
init_safe_prompts();
|
|
94162
|
-
import { join as
|
|
94253
|
+
import { join as join97 } from "node:path";
|
|
94163
94254
|
async function promptUpdateMode() {
|
|
94164
94255
|
const updateEverything = await se({
|
|
94165
94256
|
message: "Do you want to update everything?"
|
|
@@ -94201,7 +94292,7 @@ async function promptDirectorySelection(global3 = false) {
|
|
|
94201
94292
|
return selectedCategories;
|
|
94202
94293
|
}
|
|
94203
94294
|
async function promptFreshConfirmation(targetPath, analysis) {
|
|
94204
|
-
const backupRoot =
|
|
94295
|
+
const backupRoot = join97(PathResolver.getConfigDir(false), "backups");
|
|
94205
94296
|
logger.warning("[!] Fresh installation will remove ClaudeKit files:");
|
|
94206
94297
|
logger.info(`Path: ${targetPath}`);
|
|
94207
94298
|
logger.info(`Recovery backup: ${backupRoot}`);
|
|
@@ -94371,12 +94462,12 @@ class PromptsManager {
|
|
|
94371
94462
|
}
|
|
94372
94463
|
async promptPackageInstallations() {
|
|
94373
94464
|
log.step("Optional Package Installations");
|
|
94374
|
-
const [openCodeInstalled,
|
|
94465
|
+
const [openCodeInstalled, agyInstalled] = await Promise.all([
|
|
94375
94466
|
isOpenCodeInstalled(),
|
|
94376
|
-
|
|
94467
|
+
isAgyInstalled()
|
|
94377
94468
|
]);
|
|
94378
94469
|
let installOpenCode2 = false;
|
|
94379
|
-
let
|
|
94470
|
+
let installAgy2 = false;
|
|
94380
94471
|
if (openCodeInstalled) {
|
|
94381
94472
|
logger.success("OpenCode CLI is already installed");
|
|
94382
94473
|
} else {
|
|
@@ -94388,20 +94479,20 @@ class PromptsManager {
|
|
|
94388
94479
|
}
|
|
94389
94480
|
installOpenCode2 = shouldInstallOpenCode;
|
|
94390
94481
|
}
|
|
94391
|
-
if (
|
|
94392
|
-
logger.success("
|
|
94482
|
+
if (agyInstalled) {
|
|
94483
|
+
logger.success("Antigravity CLI (agy) is already installed");
|
|
94393
94484
|
} else {
|
|
94394
|
-
const
|
|
94395
|
-
message: "Install
|
|
94485
|
+
const shouldInstallAgy = await se({
|
|
94486
|
+
message: "Install Antigravity CLI (agy) for AI-powered assistance? (Optional additional AI capabilities)"
|
|
94396
94487
|
});
|
|
94397
|
-
if (lD(
|
|
94488
|
+
if (lD(shouldInstallAgy)) {
|
|
94398
94489
|
throw new Error("Package installation cancelled");
|
|
94399
94490
|
}
|
|
94400
|
-
|
|
94491
|
+
installAgy2 = shouldInstallAgy;
|
|
94401
94492
|
}
|
|
94402
94493
|
return {
|
|
94403
94494
|
installOpenCode: installOpenCode2,
|
|
94404
|
-
|
|
94495
|
+
installAgy: installAgy2
|
|
94405
94496
|
};
|
|
94406
94497
|
}
|
|
94407
94498
|
async promptSkillsInstallation() {
|
|
@@ -94417,11 +94508,11 @@ class PromptsManager {
|
|
|
94417
94508
|
failedInstalls.push(`${results.opencode.package}: ${results.opencode.error || "Installation failed"}`);
|
|
94418
94509
|
}
|
|
94419
94510
|
}
|
|
94420
|
-
if (results.
|
|
94421
|
-
if (results.
|
|
94422
|
-
successfulInstalls.push(`${results.
|
|
94511
|
+
if (results.agy) {
|
|
94512
|
+
if (results.agy.success) {
|
|
94513
|
+
successfulInstalls.push(`${results.agy.package}${results.agy.version ? ` v${results.agy.version}` : ""}`);
|
|
94423
94514
|
} else {
|
|
94424
|
-
failedInstalls.push(`${results.
|
|
94515
|
+
failedInstalls.push(`${results.agy.package}: ${results.agy.error || "Installation failed"}`);
|
|
94425
94516
|
}
|
|
94426
94517
|
}
|
|
94427
94518
|
if (successfulInstalls.length > 0) {
|
|
@@ -94429,7 +94520,7 @@ class PromptsManager {
|
|
|
94429
94520
|
}
|
|
94430
94521
|
if (failedInstalls.length > 0) {
|
|
94431
94522
|
logger.warning(`Failed to install: ${failedInstalls.join(", ")}`);
|
|
94432
|
-
logger.info("You can install these manually later
|
|
94523
|
+
logger.info("You can install these manually later from each tool's official install guide.");
|
|
94433
94524
|
}
|
|
94434
94525
|
}
|
|
94435
94526
|
async promptFreshConfirmation(targetPath, analysis) {
|
|
@@ -94478,7 +94569,7 @@ init_logger();
|
|
|
94478
94569
|
init_logger();
|
|
94479
94570
|
init_path_resolver();
|
|
94480
94571
|
var import_fs_extra10 = __toESM(require_lib(), 1);
|
|
94481
|
-
import { join as
|
|
94572
|
+
import { join as join98 } from "node:path";
|
|
94482
94573
|
async function handleConflicts(ctx) {
|
|
94483
94574
|
if (ctx.cancelled)
|
|
94484
94575
|
return ctx;
|
|
@@ -94487,7 +94578,7 @@ async function handleConflicts(ctx) {
|
|
|
94487
94578
|
if (PathResolver.isLocalSameAsGlobal()) {
|
|
94488
94579
|
return ctx;
|
|
94489
94580
|
}
|
|
94490
|
-
const localSettingsPath =
|
|
94581
|
+
const localSettingsPath = join98(process.cwd(), ".claude", "settings.json");
|
|
94491
94582
|
if (!await import_fs_extra10.pathExists(localSettingsPath)) {
|
|
94492
94583
|
return ctx;
|
|
94493
94584
|
}
|
|
@@ -94502,7 +94593,7 @@ async function handleConflicts(ctx) {
|
|
|
94502
94593
|
return { ...ctx, cancelled: true };
|
|
94503
94594
|
}
|
|
94504
94595
|
if (choice === "remove") {
|
|
94505
|
-
const localClaudeDir =
|
|
94596
|
+
const localClaudeDir = join98(process.cwd(), ".claude");
|
|
94506
94597
|
try {
|
|
94507
94598
|
await import_fs_extra10.remove(localClaudeDir);
|
|
94508
94599
|
logger.success("Removed local .claude/ directory");
|
|
@@ -94599,7 +94690,7 @@ init_logger();
|
|
|
94599
94690
|
init_safe_spinner();
|
|
94600
94691
|
import { mkdir as mkdir30, stat as stat17 } from "node:fs/promises";
|
|
94601
94692
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
94602
|
-
import { join as
|
|
94693
|
+
import { join as join105 } from "node:path";
|
|
94603
94694
|
|
|
94604
94695
|
// src/shared/temp-cleanup.ts
|
|
94605
94696
|
init_logger();
|
|
@@ -94618,7 +94709,7 @@ init_logger();
|
|
|
94618
94709
|
init_output_manager();
|
|
94619
94710
|
import { createWriteStream as createWriteStream2, rmSync } from "node:fs";
|
|
94620
94711
|
import { mkdir as mkdir25 } from "node:fs/promises";
|
|
94621
|
-
import { join as
|
|
94712
|
+
import { join as join99 } from "node:path";
|
|
94622
94713
|
|
|
94623
94714
|
// src/shared/progress-bar.ts
|
|
94624
94715
|
init_output_manager();
|
|
@@ -94828,7 +94919,7 @@ var MAX_DOWNLOAD_SIZE = 500 * 1024 * 1024;
|
|
|
94828
94919
|
class FileDownloader {
|
|
94829
94920
|
async downloadAsset(asset, destDir) {
|
|
94830
94921
|
try {
|
|
94831
|
-
const destPath =
|
|
94922
|
+
const destPath = join99(destDir, asset.name);
|
|
94832
94923
|
await mkdir25(destDir, { recursive: true });
|
|
94833
94924
|
output.info(`Downloading ${asset.name} (${formatBytes2(asset.size)})...`);
|
|
94834
94925
|
logger.verbose("Download details", {
|
|
@@ -94913,7 +95004,7 @@ class FileDownloader {
|
|
|
94913
95004
|
}
|
|
94914
95005
|
async downloadFile(params) {
|
|
94915
95006
|
const { url, name, size, destDir, token } = params;
|
|
94916
|
-
const destPath =
|
|
95007
|
+
const destPath = join99(destDir, name);
|
|
94917
95008
|
await mkdir25(destDir, { recursive: true });
|
|
94918
95009
|
output.info(`Downloading ${name}${size ? ` (${formatBytes2(size)})` : ""}...`);
|
|
94919
95010
|
const headers = {};
|
|
@@ -94999,7 +95090,7 @@ init_logger();
|
|
|
94999
95090
|
init_types3();
|
|
95000
95091
|
import { constants as constants4 } from "node:fs";
|
|
95001
95092
|
import { access as access5, readdir as readdir23 } from "node:fs/promises";
|
|
95002
|
-
import { join as
|
|
95093
|
+
import { join as join100 } from "node:path";
|
|
95003
95094
|
async function pathExists11(path8) {
|
|
95004
95095
|
try {
|
|
95005
95096
|
await access5(path8, constants4.F_OK);
|
|
@@ -95018,7 +95109,7 @@ async function validateExtraction(extractDir) {
|
|
|
95018
95109
|
const criticalPaths = [".claude"];
|
|
95019
95110
|
const missingPaths = [];
|
|
95020
95111
|
for (const path8 of criticalPaths) {
|
|
95021
|
-
if (await pathExists11(
|
|
95112
|
+
if (await pathExists11(join100(extractDir, path8))) {
|
|
95022
95113
|
logger.debug(`Found: ${path8}`);
|
|
95023
95114
|
continue;
|
|
95024
95115
|
}
|
|
@@ -95028,7 +95119,7 @@ async function validateExtraction(extractDir) {
|
|
|
95028
95119
|
const guidancePaths = ["CLAUDE.md", ".claude/CLAUDE.md", ".claude/rules/CLAUDE.md"];
|
|
95029
95120
|
let guidancePath = null;
|
|
95030
95121
|
for (const path8 of guidancePaths) {
|
|
95031
|
-
if (await pathExists11(
|
|
95122
|
+
if (await pathExists11(join100(extractDir, path8))) {
|
|
95032
95123
|
guidancePath = path8;
|
|
95033
95124
|
break;
|
|
95034
95125
|
}
|
|
@@ -95053,7 +95144,7 @@ async function validateExtraction(extractDir) {
|
|
|
95053
95144
|
// src/domains/installation/extraction/tar-extractor.ts
|
|
95054
95145
|
init_logger();
|
|
95055
95146
|
import { copyFile as copyFile4, mkdir as mkdir28, readdir as readdir25, rm as rm11, stat as stat15 } from "node:fs/promises";
|
|
95056
|
-
import { join as
|
|
95147
|
+
import { join as join103 } from "node:path";
|
|
95057
95148
|
|
|
95058
95149
|
// node_modules/@isaacs/fs-minipass/dist/esm/index.js
|
|
95059
95150
|
import EE from "events";
|
|
@@ -100815,7 +100906,7 @@ var mkdirSync4 = (dir, opt) => {
|
|
|
100815
100906
|
};
|
|
100816
100907
|
|
|
100817
100908
|
// node_modules/tar/dist/esm/path-reservations.js
|
|
100818
|
-
import { join as
|
|
100909
|
+
import { join as join101 } from "node:path";
|
|
100819
100910
|
|
|
100820
100911
|
// node_modules/tar/dist/esm/normalize-unicode.js
|
|
100821
100912
|
var normalizeCache = Object.create(null);
|
|
@@ -100848,7 +100939,7 @@ var getDirs = (path13) => {
|
|
|
100848
100939
|
const dirs = path13.split("/").slice(0, -1).reduce((set, path14) => {
|
|
100849
100940
|
const s = set[set.length - 1];
|
|
100850
100941
|
if (s !== undefined) {
|
|
100851
|
-
path14 =
|
|
100942
|
+
path14 = join101(s, path14);
|
|
100852
100943
|
}
|
|
100853
100944
|
set.push(path14 || "/");
|
|
100854
100945
|
return set;
|
|
@@ -100862,7 +100953,7 @@ class PathReservations {
|
|
|
100862
100953
|
#running = new Set;
|
|
100863
100954
|
reserve(paths, fn) {
|
|
100864
100955
|
paths = isWindows4 ? ["win32 parallelization disabled"] : paths.map((p) => {
|
|
100865
|
-
return stripTrailingSlashes(
|
|
100956
|
+
return stripTrailingSlashes(join101(normalizeUnicode(p))).toLowerCase();
|
|
100866
100957
|
});
|
|
100867
100958
|
const dirs = new Set(paths.map((path13) => getDirs(path13)).reduce((a3, b3) => a3.concat(b3)));
|
|
100868
100959
|
this.#reservations.set(fn, { dirs, paths });
|
|
@@ -101922,7 +102013,7 @@ function decodeFilePath(path15) {
|
|
|
101922
102013
|
init_logger();
|
|
101923
102014
|
init_types3();
|
|
101924
102015
|
import { copyFile as copyFile3, lstat as lstat7, mkdir as mkdir27, readdir as readdir24 } from "node:fs/promises";
|
|
101925
|
-
import { join as
|
|
102016
|
+
import { join as join102, relative as relative20 } from "node:path";
|
|
101926
102017
|
async function withRetry(fn, retries = 3) {
|
|
101927
102018
|
for (let i = 0;i < retries; i++) {
|
|
101928
102019
|
try {
|
|
@@ -101944,8 +102035,8 @@ async function moveDirectoryContents(sourceDir, destDir, shouldExclude, sizeTrac
|
|
|
101944
102035
|
await mkdir27(destDir, { recursive: true });
|
|
101945
102036
|
const entries = await readdir24(sourceDir, { encoding: "utf8" });
|
|
101946
102037
|
for (const entry of entries) {
|
|
101947
|
-
const sourcePath =
|
|
101948
|
-
const destPath =
|
|
102038
|
+
const sourcePath = join102(sourceDir, entry);
|
|
102039
|
+
const destPath = join102(destDir, entry);
|
|
101949
102040
|
const relativePath = relative20(sourceDir, sourcePath);
|
|
101950
102041
|
if (!isPathSafe(destDir, destPath)) {
|
|
101951
102042
|
logger.warning(`Skipping unsafe path: ${relativePath}`);
|
|
@@ -101972,8 +102063,8 @@ async function copyDirectory(sourceDir, destDir, shouldExclude, sizeTracker) {
|
|
|
101972
102063
|
await mkdir27(destDir, { recursive: true });
|
|
101973
102064
|
const entries = await readdir24(sourceDir, { encoding: "utf8" });
|
|
101974
102065
|
for (const entry of entries) {
|
|
101975
|
-
const sourcePath =
|
|
101976
|
-
const destPath =
|
|
102066
|
+
const sourcePath = join102(sourceDir, entry);
|
|
102067
|
+
const destPath = join102(destDir, entry);
|
|
101977
102068
|
const relativePath = relative20(sourceDir, sourcePath);
|
|
101978
102069
|
if (!isPathSafe(destDir, destPath)) {
|
|
101979
102070
|
logger.warning(`Skipping unsafe path: ${relativePath}`);
|
|
@@ -102021,7 +102112,7 @@ class TarExtractor {
|
|
|
102021
102112
|
logger.debug(`Root entries: ${entries.join(", ")}`);
|
|
102022
102113
|
if (entries.length === 1) {
|
|
102023
102114
|
const rootEntry = entries[0];
|
|
102024
|
-
const rootPath =
|
|
102115
|
+
const rootPath = join103(tempExtractDir, rootEntry);
|
|
102025
102116
|
const rootStat = await stat15(rootPath);
|
|
102026
102117
|
if (rootStat.isDirectory()) {
|
|
102027
102118
|
const rootContents = await readdir25(rootPath, { encoding: "utf8" });
|
|
@@ -102037,7 +102128,7 @@ class TarExtractor {
|
|
|
102037
102128
|
}
|
|
102038
102129
|
} else {
|
|
102039
102130
|
await mkdir28(destDir, { recursive: true });
|
|
102040
|
-
await copyFile4(rootPath,
|
|
102131
|
+
await copyFile4(rootPath, join103(destDir, rootEntry));
|
|
102041
102132
|
}
|
|
102042
102133
|
} else {
|
|
102043
102134
|
logger.debug("Multiple root entries - moving all");
|
|
@@ -102059,7 +102150,7 @@ init_logger();
|
|
|
102059
102150
|
var import_extract_zip = __toESM(require_extract_zip(), 1);
|
|
102060
102151
|
import { execFile as execFile11 } from "node:child_process";
|
|
102061
102152
|
import { copyFile as copyFile5, mkdir as mkdir29, readdir as readdir26, rm as rm12, stat as stat16 } from "node:fs/promises";
|
|
102062
|
-
import { join as
|
|
102153
|
+
import { join as join104 } from "node:path";
|
|
102063
102154
|
import { promisify as promisify16 } from "node:util";
|
|
102064
102155
|
|
|
102065
102156
|
// src/domains/installation/extraction/native-zip-commands.ts
|
|
@@ -102151,7 +102242,7 @@ class ZipExtractor {
|
|
|
102151
102242
|
logger.debug(`Root entries: ${entries.join(", ")}`);
|
|
102152
102243
|
if (entries.length === 1) {
|
|
102153
102244
|
const rootEntry = entries[0];
|
|
102154
|
-
const rootPath =
|
|
102245
|
+
const rootPath = join104(tempExtractDir, rootEntry);
|
|
102155
102246
|
const rootStat = await stat16(rootPath);
|
|
102156
102247
|
if (rootStat.isDirectory()) {
|
|
102157
102248
|
const rootContents = await readdir26(rootPath, { encoding: "utf8" });
|
|
@@ -102167,7 +102258,7 @@ class ZipExtractor {
|
|
|
102167
102258
|
}
|
|
102168
102259
|
} else {
|
|
102169
102260
|
await mkdir29(destDir, { recursive: true });
|
|
102170
|
-
await copyFile5(rootPath,
|
|
102261
|
+
await copyFile5(rootPath, join104(destDir, rootEntry));
|
|
102171
102262
|
}
|
|
102172
102263
|
} else {
|
|
102173
102264
|
logger.debug("Multiple root entries - moving all");
|
|
@@ -102268,7 +102359,7 @@ class DownloadManager {
|
|
|
102268
102359
|
async createTempDir() {
|
|
102269
102360
|
const timestamp = Date.now();
|
|
102270
102361
|
const counter = DownloadManager.tempDirCounter++;
|
|
102271
|
-
const primaryTempDir =
|
|
102362
|
+
const primaryTempDir = join105(tmpdir4(), `claudekit-${timestamp}-${counter}`);
|
|
102272
102363
|
try {
|
|
102273
102364
|
await mkdir30(primaryTempDir, { recursive: true });
|
|
102274
102365
|
logger.debug(`Created temp directory: ${primaryTempDir}`);
|
|
@@ -102285,7 +102376,7 @@ Solutions:
|
|
|
102285
102376
|
2. Set HOME environment variable
|
|
102286
102377
|
3. Try running from a different directory`);
|
|
102287
102378
|
}
|
|
102288
|
-
const fallbackTempDir =
|
|
102379
|
+
const fallbackTempDir = join105(homeDir, ".claudekit", "tmp", `claudekit-${timestamp}-${counter}`);
|
|
102289
102380
|
try {
|
|
102290
102381
|
await mkdir30(fallbackTempDir, { recursive: true });
|
|
102291
102382
|
logger.debug(`Created temp directory (fallback): ${fallbackTempDir}`);
|
|
@@ -102745,20 +102836,20 @@ async function handleDownload(ctx) {
|
|
|
102745
102836
|
};
|
|
102746
102837
|
}
|
|
102747
102838
|
// src/commands/init/phases/merge-handler.ts
|
|
102748
|
-
import { join as
|
|
102839
|
+
import { join as join123 } from "node:path";
|
|
102749
102840
|
|
|
102750
102841
|
// src/domains/installation/deletion-handler.ts
|
|
102751
102842
|
import { existsSync as existsSync66, lstatSync as lstatSync3, readdirSync as readdirSync10, rmSync as rmSync2, rmdirSync, unlinkSync as unlinkSync4 } from "node:fs";
|
|
102752
|
-
import { dirname as dirname38, join as
|
|
102843
|
+
import { dirname as dirname38, join as join108, relative as relative21, resolve as resolve42, sep as sep12 } from "node:path";
|
|
102753
102844
|
|
|
102754
102845
|
// src/services/file-operations/manifest/manifest-reader.ts
|
|
102755
102846
|
init_metadata_migration();
|
|
102756
102847
|
init_logger();
|
|
102757
102848
|
init_types3();
|
|
102758
102849
|
var import_fs_extra11 = __toESM(require_lib(), 1);
|
|
102759
|
-
import { join as
|
|
102850
|
+
import { join as join107 } from "node:path";
|
|
102760
102851
|
async function readManifest(claudeDir3) {
|
|
102761
|
-
const metadataPath =
|
|
102852
|
+
const metadataPath = join107(claudeDir3, "metadata.json");
|
|
102762
102853
|
if (!await import_fs_extra11.pathExists(metadataPath)) {
|
|
102763
102854
|
return null;
|
|
102764
102855
|
}
|
|
@@ -102944,7 +103035,7 @@ function collectFilesRecursively(dir, baseDir) {
|
|
|
102944
103035
|
try {
|
|
102945
103036
|
const entries = readdirSync10(dir, { withFileTypes: true });
|
|
102946
103037
|
for (const entry of entries) {
|
|
102947
|
-
const fullPath =
|
|
103038
|
+
const fullPath = join108(dir, entry.name);
|
|
102948
103039
|
const relativePath = relative21(baseDir, fullPath);
|
|
102949
103040
|
if (entry.isDirectory()) {
|
|
102950
103041
|
results.push(...collectFilesRecursively(fullPath, baseDir));
|
|
@@ -102996,7 +103087,7 @@ function cleanupEmptyDirectories(filePath, claudeDir3) {
|
|
|
102996
103087
|
function deletePath(fullPath, claudeDir3) {
|
|
102997
103088
|
const normalizedPath = resolve42(fullPath);
|
|
102998
103089
|
const normalizedClaudeDir = resolve42(claudeDir3);
|
|
102999
|
-
if (!normalizedPath.startsWith(`${normalizedClaudeDir}${
|
|
103090
|
+
if (!normalizedPath.startsWith(`${normalizedClaudeDir}${sep12}`) && normalizedPath !== normalizedClaudeDir) {
|
|
103000
103091
|
throw new Error(`Path traversal detected: ${fullPath}`);
|
|
103001
103092
|
}
|
|
103002
103093
|
try {
|
|
@@ -103012,7 +103103,7 @@ function deletePath(fullPath, claudeDir3) {
|
|
|
103012
103103
|
}
|
|
103013
103104
|
}
|
|
103014
103105
|
async function updateMetadataAfterDeletion(claudeDir3, deletedPaths) {
|
|
103015
|
-
const metadataPath =
|
|
103106
|
+
const metadataPath = join108(claudeDir3, "metadata.json");
|
|
103016
103107
|
if (!await import_fs_extra12.pathExists(metadataPath)) {
|
|
103017
103108
|
return;
|
|
103018
103109
|
}
|
|
@@ -103067,10 +103158,10 @@ async function handleDeletions(sourceMetadata, claudeDir3, kitType) {
|
|
|
103067
103158
|
const userMetadata = await readManifest(claudeDir3);
|
|
103068
103159
|
const result = { deletedPaths: [], preservedPaths: [], errors: [] };
|
|
103069
103160
|
for (const path16 of deletions) {
|
|
103070
|
-
const fullPath =
|
|
103161
|
+
const fullPath = join108(claudeDir3, path16);
|
|
103071
103162
|
const normalizedPath = resolve42(fullPath);
|
|
103072
103163
|
const normalizedClaudeDir = resolve42(claudeDir3);
|
|
103073
|
-
if (!normalizedPath.startsWith(`${normalizedClaudeDir}${
|
|
103164
|
+
if (!normalizedPath.startsWith(`${normalizedClaudeDir}${sep12}`)) {
|
|
103074
103165
|
logger.warning(`Skipping invalid path: ${path16}`);
|
|
103075
103166
|
result.errors.push(path16);
|
|
103076
103167
|
continue;
|
|
@@ -103107,7 +103198,7 @@ init_logger();
|
|
|
103107
103198
|
init_types3();
|
|
103108
103199
|
var import_fs_extra16 = __toESM(require_lib(), 1);
|
|
103109
103200
|
var import_ignore3 = __toESM(require_ignore(), 1);
|
|
103110
|
-
import { dirname as dirname42, join as
|
|
103201
|
+
import { dirname as dirname42, join as join113, relative as relative24 } from "node:path";
|
|
103111
103202
|
|
|
103112
103203
|
// src/domains/installation/selective-merger.ts
|
|
103113
103204
|
import { stat as stat18 } from "node:fs/promises";
|
|
@@ -103283,7 +103374,7 @@ class SelectiveMerger {
|
|
|
103283
103374
|
|
|
103284
103375
|
// src/domains/installation/merger/deleted-skill-preservation.ts
|
|
103285
103376
|
init_metadata_migration();
|
|
103286
|
-
import { dirname as dirname39, join as
|
|
103377
|
+
import { dirname as dirname39, join as join109, relative as relative22 } from "node:path";
|
|
103287
103378
|
var import_fs_extra13 = __toESM(require_lib(), 1);
|
|
103288
103379
|
async function findIgnoredSkillDirectories({
|
|
103289
103380
|
files,
|
|
@@ -103311,7 +103402,7 @@ async function findIgnoredSkillDirectories({
|
|
|
103311
103402
|
return root ? [root] : [];
|
|
103312
103403
|
}));
|
|
103313
103404
|
for (const [metadataRoot, sourceRoot] of sourceSkillRoots) {
|
|
103314
|
-
const destSkillRoot =
|
|
103405
|
+
const destSkillRoot = join109(destDir, ...sourceRoot.split("/"));
|
|
103315
103406
|
const skillExists = await import_fs_extra13.pathExists(destSkillRoot);
|
|
103316
103407
|
if (existingIgnoredRoots.has(metadataRoot) || !skillExists && previouslyTrackedRoots.has(metadataRoot)) {
|
|
103317
103408
|
ignoredSkillDirectories.add(metadataRoot);
|
|
@@ -103361,7 +103452,7 @@ init_logger();
|
|
|
103361
103452
|
var import_fs_extra14 = __toESM(require_lib(), 1);
|
|
103362
103453
|
var import_ignore2 = __toESM(require_ignore(), 1);
|
|
103363
103454
|
import { relative as relative23 } from "node:path";
|
|
103364
|
-
import { join as
|
|
103455
|
+
import { join as join110 } from "node:path";
|
|
103365
103456
|
|
|
103366
103457
|
// node_modules/@isaacs/balanced-match/dist/esm/index.js
|
|
103367
103458
|
var balanced = (a3, b3, str2) => {
|
|
@@ -104168,8 +104259,8 @@ var path16 = {
|
|
|
104168
104259
|
win32: { sep: "\\" },
|
|
104169
104260
|
posix: { sep: "/" }
|
|
104170
104261
|
};
|
|
104171
|
-
var
|
|
104172
|
-
minimatch.sep =
|
|
104262
|
+
var sep13 = defaultPlatform === "win32" ? path16.win32.sep : path16.posix.sep;
|
|
104263
|
+
minimatch.sep = sep13;
|
|
104173
104264
|
var GLOBSTAR = Symbol("globstar **");
|
|
104174
104265
|
minimatch.GLOBSTAR = GLOBSTAR;
|
|
104175
104266
|
var qmark2 = "[^/]";
|
|
@@ -104817,7 +104908,7 @@ class FileScanner {
|
|
|
104817
104908
|
const files = [];
|
|
104818
104909
|
const entries = await import_fs_extra14.readdir(dir, { encoding: "utf8" });
|
|
104819
104910
|
for (const entry of entries) {
|
|
104820
|
-
const fullPath =
|
|
104911
|
+
const fullPath = join110(dir, entry);
|
|
104821
104912
|
const relativePath = relative23(baseDir, fullPath);
|
|
104822
104913
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
104823
104914
|
const stats = await import_fs_extra14.lstat(fullPath);
|
|
@@ -104853,13 +104944,13 @@ class FileScanner {
|
|
|
104853
104944
|
// src/domains/installation/merger/settings-processor.ts
|
|
104854
104945
|
import { execSync as execSync5 } from "node:child_process";
|
|
104855
104946
|
import { homedir as homedir46 } from "node:os";
|
|
104856
|
-
import { dirname as dirname41, join as
|
|
104947
|
+
import { dirname as dirname41, join as join112 } from "node:path";
|
|
104857
104948
|
|
|
104858
104949
|
// src/domains/config/installed-settings-tracker.ts
|
|
104859
104950
|
init_shared();
|
|
104860
104951
|
import { existsSync as existsSync67 } from "node:fs";
|
|
104861
104952
|
import { mkdir as mkdir31, readFile as readFile52, writeFile as writeFile27 } from "node:fs/promises";
|
|
104862
|
-
import { dirname as dirname40, join as
|
|
104953
|
+
import { dirname as dirname40, join as join111 } from "node:path";
|
|
104863
104954
|
var CK_JSON_FILE = ".ck.json";
|
|
104864
104955
|
|
|
104865
104956
|
class InstalledSettingsTracker {
|
|
@@ -104873,9 +104964,9 @@ class InstalledSettingsTracker {
|
|
|
104873
104964
|
}
|
|
104874
104965
|
getCkJsonPath() {
|
|
104875
104966
|
if (this.isGlobal) {
|
|
104876
|
-
return
|
|
104967
|
+
return join111(this.projectDir, CK_JSON_FILE);
|
|
104877
104968
|
}
|
|
104878
|
-
return
|
|
104969
|
+
return join111(this.projectDir, ".claude", CK_JSON_FILE);
|
|
104879
104970
|
}
|
|
104880
104971
|
async loadInstalledSettings() {
|
|
104881
104972
|
const ckJsonPath = this.getCkJsonPath();
|
|
@@ -105143,10 +105234,10 @@ class SettingsProcessor {
|
|
|
105143
105234
|
};
|
|
105144
105235
|
try {
|
|
105145
105236
|
if (this.isGlobal) {
|
|
105146
|
-
await addFromConfig(
|
|
105237
|
+
await addFromConfig(join112(this.projectDir, ".ck.json"));
|
|
105147
105238
|
} else {
|
|
105148
|
-
await addFromConfig(
|
|
105149
|
-
await addFromConfig(
|
|
105239
|
+
await addFromConfig(join112(PathResolver.getGlobalKitDir(), ".ck.json"));
|
|
105240
|
+
await addFromConfig(join112(this.projectDir, ".claude", ".ck.json"));
|
|
105150
105241
|
}
|
|
105151
105242
|
} catch (error) {
|
|
105152
105243
|
logger.debug(`Failed to load .ck.json hook preferences: ${error instanceof Error ? error.message : "unknown"}`);
|
|
@@ -105533,7 +105624,7 @@ class SettingsProcessor {
|
|
|
105533
105624
|
return false;
|
|
105534
105625
|
}
|
|
105535
105626
|
const configuredGlobalDir = PathResolver.getGlobalKitDir().replace(/\\/g, "/").replace(/\/+$/, "");
|
|
105536
|
-
const defaultGlobalDir =
|
|
105627
|
+
const defaultGlobalDir = join112(homedir46(), ".claude").replace(/\\/g, "/");
|
|
105537
105628
|
return configuredGlobalDir !== defaultGlobalDir;
|
|
105538
105629
|
}
|
|
105539
105630
|
getClaudeCommandRoot() {
|
|
@@ -105553,7 +105644,7 @@ class SettingsProcessor {
|
|
|
105553
105644
|
return true;
|
|
105554
105645
|
}
|
|
105555
105646
|
async repairSiblingSettingsLocal(destFile) {
|
|
105556
|
-
const settingsLocalPath =
|
|
105647
|
+
const settingsLocalPath = join112(dirname41(destFile), "settings.local.json");
|
|
105557
105648
|
if (settingsLocalPath === destFile || !await import_fs_extra15.pathExists(settingsLocalPath)) {
|
|
105558
105649
|
return;
|
|
105559
105650
|
}
|
|
@@ -105650,7 +105741,7 @@ class SettingsProcessor {
|
|
|
105650
105741
|
}
|
|
105651
105742
|
}
|
|
105652
105743
|
async dynamicTeamHookHandlerExists(destFile, handler) {
|
|
105653
|
-
return import_fs_extra15.pathExists(
|
|
105744
|
+
return import_fs_extra15.pathExists(join112(dirname41(destFile), "hooks", handler));
|
|
105654
105745
|
}
|
|
105655
105746
|
removeDynamicTeamHookRegistrations(settings) {
|
|
105656
105747
|
let removed = 0;
|
|
@@ -105791,7 +105882,7 @@ class CopyExecutor {
|
|
|
105791
105882
|
for (const file of files) {
|
|
105792
105883
|
const relativePath = relative24(sourceDir, file);
|
|
105793
105884
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
105794
|
-
const destPath =
|
|
105885
|
+
const destPath = join113(destDir, relativePath);
|
|
105795
105886
|
if (await import_fs_extra16.pathExists(destPath)) {
|
|
105796
105887
|
if (this.fileScanner.shouldNeverCopy(normalizedRelativePath)) {
|
|
105797
105888
|
logger.debug(`Security-sensitive file exists but won't be overwritten: ${normalizedRelativePath}`);
|
|
@@ -105815,7 +105906,7 @@ class CopyExecutor {
|
|
|
105815
105906
|
for (const file of files) {
|
|
105816
105907
|
const relativePath = relative24(sourceDir, file);
|
|
105817
105908
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
105818
|
-
const destPath =
|
|
105909
|
+
const destPath = join113(destDir, relativePath);
|
|
105819
105910
|
if (this.fileScanner.shouldNeverCopy(normalizedRelativePath)) {
|
|
105820
105911
|
logger.debug(`Skipping security-sensitive file: ${normalizedRelativePath}`);
|
|
105821
105912
|
skippedCount++;
|
|
@@ -106027,15 +106118,15 @@ class FileMerger {
|
|
|
106027
106118
|
|
|
106028
106119
|
// src/domains/migration/legacy-migration.ts
|
|
106029
106120
|
import { readdir as readdir28, stat as stat19 } from "node:fs/promises";
|
|
106030
|
-
import { join as
|
|
106121
|
+
import { join as join117, relative as relative25 } from "node:path";
|
|
106031
106122
|
// src/services/file-operations/manifest/manifest-tracker.ts
|
|
106032
|
-
import { join as
|
|
106123
|
+
import { join as join116 } from "node:path";
|
|
106033
106124
|
|
|
106034
106125
|
// src/domains/migration/release-manifest.ts
|
|
106035
106126
|
init_logger();
|
|
106036
106127
|
init_zod();
|
|
106037
106128
|
var import_fs_extra17 = __toESM(require_lib(), 1);
|
|
106038
|
-
import { join as
|
|
106129
|
+
import { join as join114 } from "node:path";
|
|
106039
106130
|
var ReleaseManifestFileSchema = exports_external.object({
|
|
106040
106131
|
path: exports_external.string(),
|
|
106041
106132
|
checksum: exports_external.string().regex(/^[a-f0-9]{64}$/),
|
|
@@ -106050,7 +106141,7 @@ var ReleaseManifestSchema = exports_external.object({
|
|
|
106050
106141
|
|
|
106051
106142
|
class ReleaseManifestLoader {
|
|
106052
106143
|
static async load(extractDir) {
|
|
106053
|
-
const manifestPath =
|
|
106144
|
+
const manifestPath = join114(extractDir, "release-manifest.json");
|
|
106054
106145
|
try {
|
|
106055
106146
|
const content = await import_fs_extra17.readFile(manifestPath, "utf-8");
|
|
106056
106147
|
const parsed = JSON.parse(content);
|
|
@@ -106073,12 +106164,12 @@ init_p_limit();
|
|
|
106073
106164
|
|
|
106074
106165
|
// src/services/file-operations/manifest/manifest-updater.ts
|
|
106075
106166
|
init_metadata_migration();
|
|
106076
|
-
import { join as
|
|
106167
|
+
import { join as join115 } from "node:path";
|
|
106077
106168
|
init_logger();
|
|
106078
106169
|
init_types3();
|
|
106079
106170
|
var import_fs_extra18 = __toESM(require_lib(), 1);
|
|
106080
106171
|
async function writeManifest(claudeDir3, kitName, version, scope, kitType, trackedFiles, userConfigFiles, ignoredSkills = []) {
|
|
106081
|
-
const metadataPath =
|
|
106172
|
+
const metadataPath = join115(claudeDir3, "metadata.json");
|
|
106082
106173
|
const kit = kitType || (/\bmarketing\b/i.test(kitName) ? "marketing" : "engineer");
|
|
106083
106174
|
await import_fs_extra18.ensureFile(metadataPath);
|
|
106084
106175
|
let release = null;
|
|
@@ -106150,7 +106241,7 @@ function uniqueNormalizedSkillRoots(paths) {
|
|
|
106150
106241
|
}))).sort();
|
|
106151
106242
|
}
|
|
106152
106243
|
async function removeKitFromManifest(claudeDir3, kit, options2) {
|
|
106153
|
-
const metadataPath =
|
|
106244
|
+
const metadataPath = join115(claudeDir3, "metadata.json");
|
|
106154
106245
|
if (!await import_fs_extra18.pathExists(metadataPath))
|
|
106155
106246
|
return false;
|
|
106156
106247
|
let release = null;
|
|
@@ -106182,7 +106273,7 @@ async function removeKitFromManifest(claudeDir3, kit, options2) {
|
|
|
106182
106273
|
}
|
|
106183
106274
|
}
|
|
106184
106275
|
async function retainTrackedFilesInManifest(claudeDir3, retainedPaths, options2) {
|
|
106185
|
-
const metadataPath =
|
|
106276
|
+
const metadataPath = join115(claudeDir3, "metadata.json");
|
|
106186
106277
|
if (!await import_fs_extra18.pathExists(metadataPath))
|
|
106187
106278
|
return false;
|
|
106188
106279
|
const normalizedPaths = new Set(retainedPaths.map((path17) => path17.replace(/\\/g, "/")));
|
|
@@ -106363,7 +106454,7 @@ function buildFileTrackingList(options2) {
|
|
|
106363
106454
|
if (!isGlobal && !installedPath.startsWith(".claude/"))
|
|
106364
106455
|
continue;
|
|
106365
106456
|
const relativePath = isGlobal ? installedPath : installedPath.replace(/^\.claude\//, "");
|
|
106366
|
-
const filePath =
|
|
106457
|
+
const filePath = join116(claudeDir3, relativePath);
|
|
106367
106458
|
const manifestEntry = releaseManifest ? ReleaseManifestLoader.findFile(releaseManifest, installedPath) : null;
|
|
106368
106459
|
const ownership = manifestEntry ? "ck" : "user";
|
|
106369
106460
|
filesToTrack.push({
|
|
@@ -106474,7 +106565,7 @@ class LegacyMigration {
|
|
|
106474
106565
|
continue;
|
|
106475
106566
|
if (SKIP_DIRS_ALL.includes(entry))
|
|
106476
106567
|
continue;
|
|
106477
|
-
const fullPath =
|
|
106568
|
+
const fullPath = join117(dir, entry);
|
|
106478
106569
|
let stats;
|
|
106479
106570
|
try {
|
|
106480
106571
|
stats = await stat19(fullPath);
|
|
@@ -106584,7 +106675,7 @@ User-created files (sample):`);
|
|
|
106584
106675
|
];
|
|
106585
106676
|
if (filesToChecksum.length > 0) {
|
|
106586
106677
|
const checksumResults = await mapWithLimit(filesToChecksum, async ({ relativePath, ownership }) => {
|
|
106587
|
-
const fullPath =
|
|
106678
|
+
const fullPath = join117(claudeDir3, relativePath);
|
|
106588
106679
|
const checksum = await OwnershipChecker.calculateChecksum(fullPath);
|
|
106589
106680
|
return { relativePath, checksum, ownership };
|
|
106590
106681
|
}, getOptimalConcurrency());
|
|
@@ -106605,7 +106696,7 @@ User-created files (sample):`);
|
|
|
106605
106696
|
installedAt: new Date().toISOString(),
|
|
106606
106697
|
files: trackedFiles
|
|
106607
106698
|
};
|
|
106608
|
-
const metadataPath =
|
|
106699
|
+
const metadataPath = join117(claudeDir3, "metadata.json");
|
|
106609
106700
|
await import_fs_extra19.writeFile(metadataPath, JSON.stringify(updatedMetadata, null, 2));
|
|
106610
106701
|
logger.success(`Migration complete: tracked ${trackedFiles.length} files`);
|
|
106611
106702
|
return true;
|
|
@@ -106711,7 +106802,7 @@ function buildConflictSummary(fileConflicts, hookConflicts, mcpConflicts) {
|
|
|
106711
106802
|
init_logger();
|
|
106712
106803
|
init_skip_directories();
|
|
106713
106804
|
var import_fs_extra20 = __toESM(require_lib(), 1);
|
|
106714
|
-
import { join as
|
|
106805
|
+
import { join as join118, relative as relative26, resolve as resolve43 } from "node:path";
|
|
106715
106806
|
|
|
106716
106807
|
class FileScanner2 {
|
|
106717
106808
|
static async getFiles(dirPath, relativeTo) {
|
|
@@ -106727,7 +106818,7 @@ class FileScanner2 {
|
|
|
106727
106818
|
logger.debug(`Skipping directory: ${entry}`);
|
|
106728
106819
|
continue;
|
|
106729
106820
|
}
|
|
106730
|
-
const fullPath =
|
|
106821
|
+
const fullPath = join118(dirPath, entry);
|
|
106731
106822
|
if (!FileScanner2.isSafePath(basePath, fullPath)) {
|
|
106732
106823
|
logger.warning(`Skipping potentially unsafe path: ${entry}`);
|
|
106733
106824
|
continue;
|
|
@@ -106762,8 +106853,8 @@ class FileScanner2 {
|
|
|
106762
106853
|
return files;
|
|
106763
106854
|
}
|
|
106764
106855
|
static async findCustomFiles(destDir, sourceDir, subPath) {
|
|
106765
|
-
const destSubDir =
|
|
106766
|
-
const sourceSubDir =
|
|
106856
|
+
const destSubDir = join118(destDir, subPath);
|
|
106857
|
+
const sourceSubDir = join118(sourceDir, subPath);
|
|
106767
106858
|
logger.debug(`findCustomFiles - destDir: ${destDir}`);
|
|
106768
106859
|
logger.debug(`findCustomFiles - sourceDir: ${sourceDir}`);
|
|
106769
106860
|
logger.debug(`findCustomFiles - subPath: "${subPath}"`);
|
|
@@ -106804,12 +106895,12 @@ class FileScanner2 {
|
|
|
106804
106895
|
init_logger();
|
|
106805
106896
|
var import_fs_extra21 = __toESM(require_lib(), 1);
|
|
106806
106897
|
import { lstat as lstat10, mkdir as mkdir32, readdir as readdir31, stat as stat20 } from "node:fs/promises";
|
|
106807
|
-
import { join as
|
|
106898
|
+
import { join as join120 } from "node:path";
|
|
106808
106899
|
|
|
106809
106900
|
// src/services/transformers/commands-prefix/content-transformer.ts
|
|
106810
106901
|
init_logger();
|
|
106811
106902
|
import { readFile as readFile56, readdir as readdir30, writeFile as writeFile31 } from "node:fs/promises";
|
|
106812
|
-
import { join as
|
|
106903
|
+
import { join as join119 } from "node:path";
|
|
106813
106904
|
var TRANSFORMABLE_EXTENSIONS = new Set([
|
|
106814
106905
|
".md",
|
|
106815
106906
|
".txt",
|
|
@@ -106869,7 +106960,7 @@ async function transformCommandReferences(directory, options2 = {}) {
|
|
|
106869
106960
|
async function processDirectory(dir) {
|
|
106870
106961
|
const entries = await readdir30(dir, { withFileTypes: true });
|
|
106871
106962
|
for (const entry of entries) {
|
|
106872
|
-
const fullPath =
|
|
106963
|
+
const fullPath = join119(dir, entry.name);
|
|
106873
106964
|
if (entry.isDirectory()) {
|
|
106874
106965
|
if (entry.name === "node_modules" || entry.name.startsWith(".") && entry.name !== ".claude") {
|
|
106875
106966
|
continue;
|
|
@@ -106944,14 +107035,14 @@ function shouldApplyPrefix(options2) {
|
|
|
106944
107035
|
// src/services/transformers/commands-prefix/prefix-applier.ts
|
|
106945
107036
|
async function applyPrefix(extractDir) {
|
|
106946
107037
|
validatePath(extractDir, "extractDir");
|
|
106947
|
-
const commandsDir =
|
|
107038
|
+
const commandsDir = join120(extractDir, ".claude", "commands");
|
|
106948
107039
|
if (!await import_fs_extra21.pathExists(commandsDir)) {
|
|
106949
107040
|
logger.verbose("No commands directory found, skipping prefix application");
|
|
106950
107041
|
return;
|
|
106951
107042
|
}
|
|
106952
107043
|
logger.info("Applying /ck: prefix to slash commands...");
|
|
106953
|
-
const backupDir =
|
|
106954
|
-
const tempDir =
|
|
107044
|
+
const backupDir = join120(extractDir, ".commands-backup");
|
|
107045
|
+
const tempDir = join120(extractDir, ".commands-prefix-temp");
|
|
106955
107046
|
try {
|
|
106956
107047
|
const entries = await readdir31(commandsDir);
|
|
106957
107048
|
if (entries.length === 0) {
|
|
@@ -106959,7 +107050,7 @@ async function applyPrefix(extractDir) {
|
|
|
106959
107050
|
return;
|
|
106960
107051
|
}
|
|
106961
107052
|
if (entries.length === 1 && entries[0] === "ck") {
|
|
106962
|
-
const ckDir2 =
|
|
107053
|
+
const ckDir2 = join120(commandsDir, "ck");
|
|
106963
107054
|
const ckStat = await stat20(ckDir2);
|
|
106964
107055
|
if (ckStat.isDirectory()) {
|
|
106965
107056
|
logger.verbose("Commands already have /ck: prefix, skipping");
|
|
@@ -106969,17 +107060,17 @@ async function applyPrefix(extractDir) {
|
|
|
106969
107060
|
await import_fs_extra21.copy(commandsDir, backupDir);
|
|
106970
107061
|
logger.verbose("Created backup of commands directory");
|
|
106971
107062
|
await mkdir32(tempDir, { recursive: true });
|
|
106972
|
-
const ckDir =
|
|
107063
|
+
const ckDir = join120(tempDir, "ck");
|
|
106973
107064
|
await mkdir32(ckDir, { recursive: true });
|
|
106974
107065
|
let processedCount = 0;
|
|
106975
107066
|
for (const entry of entries) {
|
|
106976
|
-
const sourcePath =
|
|
107067
|
+
const sourcePath = join120(commandsDir, entry);
|
|
106977
107068
|
const stats = await lstat10(sourcePath);
|
|
106978
107069
|
if (stats.isSymbolicLink()) {
|
|
106979
107070
|
logger.warning(`Skipping symlink for security: ${entry}`);
|
|
106980
107071
|
continue;
|
|
106981
107072
|
}
|
|
106982
|
-
const destPath =
|
|
107073
|
+
const destPath = join120(ckDir, entry);
|
|
106983
107074
|
await import_fs_extra21.copy(sourcePath, destPath, {
|
|
106984
107075
|
overwrite: false,
|
|
106985
107076
|
errorOnExist: true
|
|
@@ -106997,7 +107088,7 @@ async function applyPrefix(extractDir) {
|
|
|
106997
107088
|
await import_fs_extra21.move(tempDir, commandsDir);
|
|
106998
107089
|
await import_fs_extra21.remove(backupDir);
|
|
106999
107090
|
logger.success("Successfully reorganized commands to /ck: prefix");
|
|
107000
|
-
const claudeDir3 =
|
|
107091
|
+
const claudeDir3 = join120(extractDir, ".claude");
|
|
107001
107092
|
logger.info("Transforming command references in file contents...");
|
|
107002
107093
|
const transformResult = await transformCommandReferences(claudeDir3, {
|
|
107003
107094
|
verbose: logger.isVerbose()
|
|
@@ -107035,20 +107126,20 @@ async function applyPrefix(extractDir) {
|
|
|
107035
107126
|
// src/services/transformers/commands-prefix/prefix-cleaner.ts
|
|
107036
107127
|
init_metadata_migration();
|
|
107037
107128
|
import { lstat as lstat12, readdir as readdir33 } from "node:fs/promises";
|
|
107038
|
-
import { join as
|
|
107129
|
+
import { join as join122 } from "node:path";
|
|
107039
107130
|
init_logger();
|
|
107040
107131
|
var import_fs_extra23 = __toESM(require_lib(), 1);
|
|
107041
107132
|
|
|
107042
107133
|
// src/services/transformers/commands-prefix/file-processor.ts
|
|
107043
107134
|
import { lstat as lstat11, readdir as readdir32 } from "node:fs/promises";
|
|
107044
|
-
import { join as
|
|
107135
|
+
import { join as join121 } from "node:path";
|
|
107045
107136
|
init_logger();
|
|
107046
107137
|
var import_fs_extra22 = __toESM(require_lib(), 1);
|
|
107047
107138
|
async function scanDirectoryFiles(dir) {
|
|
107048
107139
|
const files = [];
|
|
107049
107140
|
const entries = await readdir32(dir);
|
|
107050
107141
|
for (const entry of entries) {
|
|
107051
|
-
const fullPath =
|
|
107142
|
+
const fullPath = join121(dir, entry);
|
|
107052
107143
|
const stats = await lstat11(fullPath);
|
|
107053
107144
|
if (stats.isSymbolicLink()) {
|
|
107054
107145
|
continue;
|
|
@@ -107176,8 +107267,8 @@ function isDifferentKitDirectory(dirName, currentKit) {
|
|
|
107176
107267
|
async function cleanupCommandsDirectory(targetDir, isGlobal, options2 = {}) {
|
|
107177
107268
|
const { dryRun = false } = options2;
|
|
107178
107269
|
validatePath(targetDir, "targetDir");
|
|
107179
|
-
const claudeDir3 = isGlobal ? targetDir :
|
|
107180
|
-
const commandsDir =
|
|
107270
|
+
const claudeDir3 = isGlobal ? targetDir : join122(targetDir, ".claude");
|
|
107271
|
+
const commandsDir = join122(claudeDir3, "commands");
|
|
107181
107272
|
const accumulator = {
|
|
107182
107273
|
results: [],
|
|
107183
107274
|
deletedCount: 0,
|
|
@@ -107219,7 +107310,7 @@ async function cleanupCommandsDirectory(targetDir, isGlobal, options2 = {}) {
|
|
|
107219
107310
|
}
|
|
107220
107311
|
const metadataForChecks = options2.kitType ? createKitSpecificMetadata(metadata, options2.kitType) : metadata;
|
|
107221
107312
|
for (const entry of entries) {
|
|
107222
|
-
const entryPath =
|
|
107313
|
+
const entryPath = join122(commandsDir, entry);
|
|
107223
107314
|
const stats = await lstat12(entryPath);
|
|
107224
107315
|
if (stats.isSymbolicLink()) {
|
|
107225
107316
|
addSymlinkSkip(entry, accumulator);
|
|
@@ -107276,7 +107367,7 @@ async function handleMerge(ctx) {
|
|
|
107276
107367
|
let customClaudeFiles = [];
|
|
107277
107368
|
if (!ctx.options.fresh) {
|
|
107278
107369
|
logger.info("Scanning for custom .claude files...");
|
|
107279
|
-
const scanSourceDir = ctx.options.global ?
|
|
107370
|
+
const scanSourceDir = ctx.options.global ? join123(ctx.extractDir, ".claude") : ctx.extractDir;
|
|
107280
107371
|
const scanTargetSubdir = ctx.options.global ? "" : ".claude";
|
|
107281
107372
|
customClaudeFiles = await FileScanner2.findCustomFiles(ctx.resolvedDir, scanSourceDir, scanTargetSubdir);
|
|
107282
107373
|
} else {
|
|
@@ -107315,7 +107406,7 @@ async function handleMerge(ctx) {
|
|
|
107315
107406
|
merger.setRestoreCkHooks(ctx.options.restoreCkHooks);
|
|
107316
107407
|
merger.setProjectDir(ctx.resolvedDir);
|
|
107317
107408
|
merger.setKitName(ctx.kit.name);
|
|
107318
|
-
merger.setZombiePrunerHookDir(
|
|
107409
|
+
merger.setZombiePrunerHookDir(join123(ctx.claudeDir, "hooks"));
|
|
107319
107410
|
if (ctx.kitType) {
|
|
107320
107411
|
merger.setMultiKitContext(ctx.claudeDir, ctx.kitType);
|
|
107321
107412
|
}
|
|
@@ -107344,8 +107435,8 @@ async function handleMerge(ctx) {
|
|
|
107344
107435
|
return { ...ctx, cancelled: true };
|
|
107345
107436
|
}
|
|
107346
107437
|
}
|
|
107347
|
-
const sourceDir = ctx.options.global ?
|
|
107348
|
-
const sourceMetadataPath = ctx.options.global ?
|
|
107438
|
+
const sourceDir = ctx.options.global ? join123(ctx.extractDir, ".claude") : ctx.extractDir;
|
|
107439
|
+
const sourceMetadataPath = ctx.options.global ? join123(sourceDir, "metadata.json") : join123(sourceDir, ".claude", "metadata.json");
|
|
107349
107440
|
let sourceMetadata = null;
|
|
107350
107441
|
try {
|
|
107351
107442
|
if (await import_fs_extra24.pathExists(sourceMetadataPath)) {
|
|
@@ -107403,7 +107494,7 @@ async function handleMerge(ctx) {
|
|
|
107403
107494
|
};
|
|
107404
107495
|
}
|
|
107405
107496
|
// src/commands/init/phases/migration-handler.ts
|
|
107406
|
-
import { join as
|
|
107497
|
+
import { join as join131 } from "node:path";
|
|
107407
107498
|
|
|
107408
107499
|
// src/domains/skills/skills-detector.ts
|
|
107409
107500
|
init_logger();
|
|
@@ -107419,7 +107510,7 @@ init_types3();
|
|
|
107419
107510
|
var import_fs_extra25 = __toESM(require_lib(), 1);
|
|
107420
107511
|
import { createHash as createHash7 } from "node:crypto";
|
|
107421
107512
|
import { readFile as readFile58, readdir as readdir34, writeFile as writeFile32 } from "node:fs/promises";
|
|
107422
|
-
import { join as
|
|
107513
|
+
import { join as join124, relative as relative27 } from "node:path";
|
|
107423
107514
|
|
|
107424
107515
|
class SkillsManifestManager {
|
|
107425
107516
|
static MANIFEST_FILENAME = ".skills-manifest.json";
|
|
@@ -107441,12 +107532,12 @@ class SkillsManifestManager {
|
|
|
107441
107532
|
return manifest;
|
|
107442
107533
|
}
|
|
107443
107534
|
static async writeManifest(skillsDir2, manifest) {
|
|
107444
|
-
const manifestPath =
|
|
107535
|
+
const manifestPath = join124(skillsDir2, SkillsManifestManager.MANIFEST_FILENAME);
|
|
107445
107536
|
await writeFile32(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
107446
107537
|
logger.debug(`Wrote manifest to: ${manifestPath}`);
|
|
107447
107538
|
}
|
|
107448
107539
|
static async readManifest(skillsDir2) {
|
|
107449
|
-
const manifestPath =
|
|
107540
|
+
const manifestPath = join124(skillsDir2, SkillsManifestManager.MANIFEST_FILENAME);
|
|
107450
107541
|
if (!await import_fs_extra25.pathExists(manifestPath)) {
|
|
107451
107542
|
logger.debug(`No manifest found at: ${manifestPath}`);
|
|
107452
107543
|
return null;
|
|
@@ -107469,7 +107560,7 @@ class SkillsManifestManager {
|
|
|
107469
107560
|
return "flat";
|
|
107470
107561
|
}
|
|
107471
107562
|
for (const dir of dirs.slice(0, 3)) {
|
|
107472
|
-
const dirPath =
|
|
107563
|
+
const dirPath = join124(skillsDir2, dir.name);
|
|
107473
107564
|
const subEntries = await readdir34(dirPath, { withFileTypes: true });
|
|
107474
107565
|
const hasSubdirs = subEntries.some((entry) => entry.isDirectory());
|
|
107475
107566
|
if (hasSubdirs) {
|
|
@@ -107488,7 +107579,7 @@ class SkillsManifestManager {
|
|
|
107488
107579
|
const entries = await readdir34(skillsDir2, { withFileTypes: true });
|
|
107489
107580
|
for (const entry of entries) {
|
|
107490
107581
|
if (entry.isDirectory() && !BUILD_ARTIFACT_DIRS.includes(entry.name) && !entry.name.startsWith(".")) {
|
|
107491
|
-
const skillPath =
|
|
107582
|
+
const skillPath = join124(skillsDir2, entry.name);
|
|
107492
107583
|
const hash = await SkillsManifestManager.hashDirectory(skillPath);
|
|
107493
107584
|
skills.push({
|
|
107494
107585
|
name: entry.name,
|
|
@@ -107500,11 +107591,11 @@ class SkillsManifestManager {
|
|
|
107500
107591
|
const categories = await readdir34(skillsDir2, { withFileTypes: true });
|
|
107501
107592
|
for (const category of categories) {
|
|
107502
107593
|
if (category.isDirectory() && !BUILD_ARTIFACT_DIRS.includes(category.name) && !category.name.startsWith(".")) {
|
|
107503
|
-
const categoryPath =
|
|
107594
|
+
const categoryPath = join124(skillsDir2, category.name);
|
|
107504
107595
|
const skillEntries = await readdir34(categoryPath, { withFileTypes: true });
|
|
107505
107596
|
for (const skillEntry of skillEntries) {
|
|
107506
107597
|
if (skillEntry.isDirectory() && !skillEntry.name.startsWith(".")) {
|
|
107507
|
-
const skillPath =
|
|
107598
|
+
const skillPath = join124(categoryPath, skillEntry.name);
|
|
107508
107599
|
const hash = await SkillsManifestManager.hashDirectory(skillPath);
|
|
107509
107600
|
skills.push({
|
|
107510
107601
|
name: skillEntry.name,
|
|
@@ -107534,7 +107625,7 @@ class SkillsManifestManager {
|
|
|
107534
107625
|
const files = [];
|
|
107535
107626
|
const entries = await readdir34(dirPath, { withFileTypes: true });
|
|
107536
107627
|
for (const entry of entries) {
|
|
107537
|
-
const fullPath =
|
|
107628
|
+
const fullPath = join124(dirPath, entry.name);
|
|
107538
107629
|
if (entry.name.startsWith(".") || BUILD_ARTIFACT_DIRS.includes(entry.name)) {
|
|
107539
107630
|
continue;
|
|
107540
107631
|
}
|
|
@@ -107656,7 +107747,7 @@ function getPathMapping(skillName, oldBasePath, newBasePath) {
|
|
|
107656
107747
|
// src/domains/skills/detection/script-detector.ts
|
|
107657
107748
|
var import_fs_extra26 = __toESM(require_lib(), 1);
|
|
107658
107749
|
import { readdir as readdir35 } from "node:fs/promises";
|
|
107659
|
-
import { join as
|
|
107750
|
+
import { join as join125 } from "node:path";
|
|
107660
107751
|
async function scanDirectory(skillsDir2) {
|
|
107661
107752
|
if (!await import_fs_extra26.pathExists(skillsDir2)) {
|
|
107662
107753
|
return ["flat", []];
|
|
@@ -107669,12 +107760,12 @@ async function scanDirectory(skillsDir2) {
|
|
|
107669
107760
|
let totalSkillLikeCount = 0;
|
|
107670
107761
|
const allSkills = [];
|
|
107671
107762
|
for (const dir of dirs) {
|
|
107672
|
-
const dirPath =
|
|
107763
|
+
const dirPath = join125(skillsDir2, dir.name);
|
|
107673
107764
|
const subEntries = await readdir35(dirPath, { withFileTypes: true });
|
|
107674
107765
|
const subdirs = subEntries.filter((entry) => entry.isDirectory() && !entry.name.startsWith("."));
|
|
107675
107766
|
if (subdirs.length > 0) {
|
|
107676
107767
|
for (const subdir of subdirs.slice(0, 3)) {
|
|
107677
|
-
const subdirPath =
|
|
107768
|
+
const subdirPath = join125(dirPath, subdir.name);
|
|
107678
107769
|
const subdirFiles = await readdir35(subdirPath, { withFileTypes: true });
|
|
107679
107770
|
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"));
|
|
107680
107771
|
if (hasSkillMarker) {
|
|
@@ -107831,12 +107922,12 @@ class SkillsMigrationDetector {
|
|
|
107831
107922
|
// src/domains/skills/skills-migrator.ts
|
|
107832
107923
|
init_logger();
|
|
107833
107924
|
init_types3();
|
|
107834
|
-
import { join as
|
|
107925
|
+
import { join as join130 } from "node:path";
|
|
107835
107926
|
|
|
107836
107927
|
// src/domains/skills/migrator/migration-executor.ts
|
|
107837
107928
|
init_logger();
|
|
107838
107929
|
import { copyFile as copyFile6, mkdir as mkdir33, readdir as readdir36, rm as rm13 } from "node:fs/promises";
|
|
107839
|
-
import { join as
|
|
107930
|
+
import { join as join126 } from "node:path";
|
|
107840
107931
|
var import_fs_extra28 = __toESM(require_lib(), 1);
|
|
107841
107932
|
|
|
107842
107933
|
// src/domains/skills/skills-migration-prompts.ts
|
|
@@ -108001,8 +108092,8 @@ async function copySkillDirectory(sourceDir, destDir) {
|
|
|
108001
108092
|
await mkdir33(destDir, { recursive: true });
|
|
108002
108093
|
const entries = await readdir36(sourceDir, { withFileTypes: true });
|
|
108003
108094
|
for (const entry of entries) {
|
|
108004
|
-
const sourcePath =
|
|
108005
|
-
const destPath =
|
|
108095
|
+
const sourcePath = join126(sourceDir, entry.name);
|
|
108096
|
+
const destPath = join126(destDir, entry.name);
|
|
108006
108097
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.isSymbolicLink()) {
|
|
108007
108098
|
continue;
|
|
108008
108099
|
}
|
|
@@ -108017,7 +108108,7 @@ async function executeInternal(mappings, customizations, currentSkillsDir, inter
|
|
|
108017
108108
|
const migrated = [];
|
|
108018
108109
|
const preserved = [];
|
|
108019
108110
|
const errors2 = [];
|
|
108020
|
-
const tempDir =
|
|
108111
|
+
const tempDir = join126(currentSkillsDir, "..", ".skills-migration-temp");
|
|
108021
108112
|
await mkdir33(tempDir, { recursive: true });
|
|
108022
108113
|
try {
|
|
108023
108114
|
for (const mapping of mappings) {
|
|
@@ -108038,9 +108129,9 @@ async function executeInternal(mappings, customizations, currentSkillsDir, inter
|
|
|
108038
108129
|
}
|
|
108039
108130
|
}
|
|
108040
108131
|
const category = mapping.category;
|
|
108041
|
-
const targetPath = category ?
|
|
108132
|
+
const targetPath = category ? join126(tempDir, category, skillName) : join126(tempDir, skillName);
|
|
108042
108133
|
if (category) {
|
|
108043
|
-
await mkdir33(
|
|
108134
|
+
await mkdir33(join126(tempDir, category), { recursive: true });
|
|
108044
108135
|
}
|
|
108045
108136
|
await copySkillDirectory(currentSkillPath, targetPath);
|
|
108046
108137
|
migrated.push(skillName);
|
|
@@ -108107,7 +108198,7 @@ init_logger();
|
|
|
108107
108198
|
init_types3();
|
|
108108
108199
|
var import_fs_extra29 = __toESM(require_lib(), 1);
|
|
108109
108200
|
import { copyFile as copyFile7, mkdir as mkdir34, readdir as readdir37, rm as rm14, stat as stat21 } from "node:fs/promises";
|
|
108110
|
-
import { basename as basename27, join as
|
|
108201
|
+
import { basename as basename27, join as join127, normalize as normalize9 } from "node:path";
|
|
108111
108202
|
function validatePath2(path17, paramName) {
|
|
108112
108203
|
if (!path17 || typeof path17 !== "string") {
|
|
108113
108204
|
throw new SkillsMigrationError(`${paramName} must be a non-empty string`);
|
|
@@ -108133,7 +108224,7 @@ class SkillsBackupManager {
|
|
|
108133
108224
|
const timestamp = Date.now();
|
|
108134
108225
|
const randomSuffix = Math.random().toString(36).substring(2, 8);
|
|
108135
108226
|
const backupDirName = `${SkillsBackupManager.BACKUP_PREFIX}${timestamp}-${randomSuffix}`;
|
|
108136
|
-
const backupDir = parentDir ?
|
|
108227
|
+
const backupDir = parentDir ? join127(parentDir, backupDirName) : join127(skillsDir2, "..", backupDirName);
|
|
108137
108228
|
logger.info(`Creating backup at: ${backupDir}`);
|
|
108138
108229
|
try {
|
|
108139
108230
|
await mkdir34(backupDir, { recursive: true });
|
|
@@ -108184,7 +108275,7 @@ class SkillsBackupManager {
|
|
|
108184
108275
|
}
|
|
108185
108276
|
try {
|
|
108186
108277
|
const entries = await readdir37(parentDir, { withFileTypes: true });
|
|
108187
|
-
const backups = entries.filter((entry) => entry.isDirectory() && entry.name.startsWith(SkillsBackupManager.BACKUP_PREFIX)).map((entry) =>
|
|
108278
|
+
const backups = entries.filter((entry) => entry.isDirectory() && entry.name.startsWith(SkillsBackupManager.BACKUP_PREFIX)).map((entry) => join127(parentDir, entry.name));
|
|
108188
108279
|
backups.sort().reverse();
|
|
108189
108280
|
return backups;
|
|
108190
108281
|
} catch (error) {
|
|
@@ -108212,8 +108303,8 @@ class SkillsBackupManager {
|
|
|
108212
108303
|
static async copyDirectory(sourceDir, destDir) {
|
|
108213
108304
|
const entries = await readdir37(sourceDir, { withFileTypes: true });
|
|
108214
108305
|
for (const entry of entries) {
|
|
108215
|
-
const sourcePath =
|
|
108216
|
-
const destPath =
|
|
108306
|
+
const sourcePath = join127(sourceDir, entry.name);
|
|
108307
|
+
const destPath = join127(destDir, entry.name);
|
|
108217
108308
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.isSymbolicLink()) {
|
|
108218
108309
|
continue;
|
|
108219
108310
|
}
|
|
@@ -108229,7 +108320,7 @@ class SkillsBackupManager {
|
|
|
108229
108320
|
let size = 0;
|
|
108230
108321
|
const entries = await readdir37(dirPath, { withFileTypes: true });
|
|
108231
108322
|
for (const entry of entries) {
|
|
108232
|
-
const fullPath =
|
|
108323
|
+
const fullPath = join127(dirPath, entry.name);
|
|
108233
108324
|
if (entry.isSymbolicLink()) {
|
|
108234
108325
|
continue;
|
|
108235
108326
|
}
|
|
@@ -108265,12 +108356,12 @@ init_skip_directories();
|
|
|
108265
108356
|
import { createHash as createHash8 } from "node:crypto";
|
|
108266
108357
|
import { createReadStream as createReadStream2 } from "node:fs";
|
|
108267
108358
|
import { readFile as readFile59, readdir as readdir38 } from "node:fs/promises";
|
|
108268
|
-
import { join as
|
|
108359
|
+
import { join as join128, relative as relative28 } from "node:path";
|
|
108269
108360
|
async function getAllFiles(dirPath) {
|
|
108270
108361
|
const files = [];
|
|
108271
108362
|
const entries = await readdir38(dirPath, { withFileTypes: true });
|
|
108272
108363
|
for (const entry of entries) {
|
|
108273
|
-
const fullPath =
|
|
108364
|
+
const fullPath = join128(dirPath, entry.name);
|
|
108274
108365
|
if (entry.name.startsWith(".") || BUILD_ARTIFACT_DIRS.includes(entry.name) || entry.isSymbolicLink()) {
|
|
108275
108366
|
continue;
|
|
108276
108367
|
}
|
|
@@ -108397,7 +108488,7 @@ async function detectFileChanges(currentSkillPath, baselineSkillPath) {
|
|
|
108397
108488
|
init_types3();
|
|
108398
108489
|
var import_fs_extra31 = __toESM(require_lib(), 1);
|
|
108399
108490
|
import { readdir as readdir39 } from "node:fs/promises";
|
|
108400
|
-
import { join as
|
|
108491
|
+
import { join as join129, normalize as normalize10 } from "node:path";
|
|
108401
108492
|
function validatePath3(path17, paramName) {
|
|
108402
108493
|
if (!path17 || typeof path17 !== "string") {
|
|
108403
108494
|
throw new SkillsMigrationError(`${paramName} must be a non-empty string`);
|
|
@@ -108418,13 +108509,13 @@ async function scanSkillsDirectory(skillsDir2) {
|
|
|
108418
108509
|
if (dirs.length === 0) {
|
|
108419
108510
|
return ["flat", []];
|
|
108420
108511
|
}
|
|
108421
|
-
const firstDirPath =
|
|
108512
|
+
const firstDirPath = join129(skillsDir2, dirs[0].name);
|
|
108422
108513
|
const subEntries = await readdir39(firstDirPath, { withFileTypes: true });
|
|
108423
108514
|
const subdirs = subEntries.filter((entry) => entry.isDirectory() && !entry.name.startsWith("."));
|
|
108424
108515
|
if (subdirs.length > 0) {
|
|
108425
108516
|
let skillLikeCount = 0;
|
|
108426
108517
|
for (const subdir of subdirs.slice(0, 3)) {
|
|
108427
|
-
const subdirPath =
|
|
108518
|
+
const subdirPath = join129(firstDirPath, subdir.name);
|
|
108428
108519
|
const subdirFiles = await readdir39(subdirPath, { withFileTypes: true });
|
|
108429
108520
|
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"));
|
|
108430
108521
|
if (hasSkillMarker) {
|
|
@@ -108434,7 +108525,7 @@ async function scanSkillsDirectory(skillsDir2) {
|
|
|
108434
108525
|
if (skillLikeCount > 0) {
|
|
108435
108526
|
const skills = [];
|
|
108436
108527
|
for (const dir of dirs) {
|
|
108437
|
-
const categoryPath =
|
|
108528
|
+
const categoryPath = join129(skillsDir2, dir.name);
|
|
108438
108529
|
const skillDirs = await readdir39(categoryPath, { withFileTypes: true });
|
|
108439
108530
|
skills.push(...skillDirs.filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name));
|
|
108440
108531
|
}
|
|
@@ -108444,7 +108535,7 @@ async function scanSkillsDirectory(skillsDir2) {
|
|
|
108444
108535
|
return ["flat", dirs.map((dir) => dir.name)];
|
|
108445
108536
|
}
|
|
108446
108537
|
async function findSkillPath(skillsDir2, skillName) {
|
|
108447
|
-
const flatPath =
|
|
108538
|
+
const flatPath = join129(skillsDir2, skillName);
|
|
108448
108539
|
if (await import_fs_extra31.pathExists(flatPath)) {
|
|
108449
108540
|
return { path: flatPath, category: undefined };
|
|
108450
108541
|
}
|
|
@@ -108453,8 +108544,8 @@ async function findSkillPath(skillsDir2, skillName) {
|
|
|
108453
108544
|
if (!entry.isDirectory() || entry.name.startsWith(".") || entry.name === "node_modules") {
|
|
108454
108545
|
continue;
|
|
108455
108546
|
}
|
|
108456
|
-
const categoryPath =
|
|
108457
|
-
const skillPath =
|
|
108547
|
+
const categoryPath = join129(skillsDir2, entry.name);
|
|
108548
|
+
const skillPath = join129(categoryPath, skillName);
|
|
108458
108549
|
if (await import_fs_extra31.pathExists(skillPath)) {
|
|
108459
108550
|
return { path: skillPath, category: entry.name };
|
|
108460
108551
|
}
|
|
@@ -108548,7 +108639,7 @@ class SkillsMigrator {
|
|
|
108548
108639
|
}
|
|
108549
108640
|
}
|
|
108550
108641
|
if (options2.backup && !options2.dryRun) {
|
|
108551
|
-
const claudeDir3 =
|
|
108642
|
+
const claudeDir3 = join130(currentSkillsDir, "..");
|
|
108552
108643
|
result.backupPath = await SkillsBackupManager.createBackup(currentSkillsDir, claudeDir3);
|
|
108553
108644
|
logger.success(`Backup created at: ${result.backupPath}`);
|
|
108554
108645
|
}
|
|
@@ -108609,7 +108700,7 @@ async function handleMigration(ctx) {
|
|
|
108609
108700
|
logger.debug("Skipping skills migration (fresh installation)");
|
|
108610
108701
|
return ctx;
|
|
108611
108702
|
}
|
|
108612
|
-
const newSkillsDir =
|
|
108703
|
+
const newSkillsDir = join131(ctx.extractDir, ".claude", "skills");
|
|
108613
108704
|
const currentSkillsDir = PathResolver.buildSkillsPath(ctx.resolvedDir, ctx.options.global);
|
|
108614
108705
|
if (!await import_fs_extra32.pathExists(newSkillsDir) || !await import_fs_extra32.pathExists(currentSkillsDir)) {
|
|
108615
108706
|
return ctx;
|
|
@@ -108633,13 +108724,13 @@ async function handleMigration(ctx) {
|
|
|
108633
108724
|
}
|
|
108634
108725
|
// src/commands/init/phases/opencode-handler.ts
|
|
108635
108726
|
import { cp as cp4, readdir as readdir41, rm as rm15 } from "node:fs/promises";
|
|
108636
|
-
import { join as
|
|
108727
|
+
import { join as join133 } from "node:path";
|
|
108637
108728
|
|
|
108638
108729
|
// src/services/transformers/opencode-path-transformer.ts
|
|
108639
108730
|
init_logger();
|
|
108640
108731
|
import { readFile as readFile60, readdir as readdir40, writeFile as writeFile33 } from "node:fs/promises";
|
|
108641
108732
|
import { platform as platform15 } from "node:os";
|
|
108642
|
-
import { extname as extname6, join as
|
|
108733
|
+
import { extname as extname6, join as join132 } from "node:path";
|
|
108643
108734
|
var IS_WINDOWS2 = platform15() === "win32";
|
|
108644
108735
|
function getOpenCodeGlobalPath() {
|
|
108645
108736
|
return "$HOME/.config/opencode/";
|
|
@@ -108700,7 +108791,7 @@ async function transformPathsForGlobalOpenCode(directory, options2 = {}) {
|
|
|
108700
108791
|
async function processDirectory2(dir) {
|
|
108701
108792
|
const entries = await readdir40(dir, { withFileTypes: true });
|
|
108702
108793
|
for (const entry of entries) {
|
|
108703
|
-
const fullPath =
|
|
108794
|
+
const fullPath = join132(dir, entry.name);
|
|
108704
108795
|
if (entry.isDirectory()) {
|
|
108705
108796
|
if (entry.name === "node_modules" || entry.name.startsWith(".")) {
|
|
108706
108797
|
continue;
|
|
@@ -108739,7 +108830,7 @@ async function handleOpenCode(ctx) {
|
|
|
108739
108830
|
if (ctx.cancelled || !ctx.extractDir || !ctx.resolvedDir) {
|
|
108740
108831
|
return ctx;
|
|
108741
108832
|
}
|
|
108742
|
-
const openCodeSource =
|
|
108833
|
+
const openCodeSource = join133(ctx.extractDir, ".opencode");
|
|
108743
108834
|
if (!await import_fs_extra33.pathExists(openCodeSource)) {
|
|
108744
108835
|
logger.debug("No .opencode directory in archive, skipping");
|
|
108745
108836
|
return ctx;
|
|
@@ -108757,8 +108848,8 @@ async function handleOpenCode(ctx) {
|
|
|
108757
108848
|
await import_fs_extra33.ensureDir(targetDir);
|
|
108758
108849
|
const entries = await readdir41(openCodeSource, { withFileTypes: true });
|
|
108759
108850
|
for (const entry of entries) {
|
|
108760
|
-
const sourcePath =
|
|
108761
|
-
const targetPath =
|
|
108851
|
+
const sourcePath = join133(openCodeSource, entry.name);
|
|
108852
|
+
const targetPath = join133(targetDir, entry.name);
|
|
108762
108853
|
if (await import_fs_extra33.pathExists(targetPath)) {
|
|
108763
108854
|
if (!ctx.options.forceOverwrite) {
|
|
108764
108855
|
logger.verbose(`Skipping existing: ${entry.name}`);
|
|
@@ -108857,7 +108948,7 @@ Please use only one download method.`);
|
|
|
108857
108948
|
}
|
|
108858
108949
|
// src/commands/init/phases/post-install-handler.ts
|
|
108859
108950
|
init_projects_registry();
|
|
108860
|
-
import { join as
|
|
108951
|
+
import { join as join134 } from "node:path";
|
|
108861
108952
|
init_logger();
|
|
108862
108953
|
init_path_resolver();
|
|
108863
108954
|
var import_fs_extra34 = __toESM(require_lib(), 1);
|
|
@@ -108866,8 +108957,8 @@ async function handlePostInstall(ctx) {
|
|
|
108866
108957
|
return ctx;
|
|
108867
108958
|
}
|
|
108868
108959
|
if (ctx.options.global) {
|
|
108869
|
-
const claudeMdSource =
|
|
108870
|
-
const claudeMdDest =
|
|
108960
|
+
const claudeMdSource = join134(ctx.extractDir, "CLAUDE.md");
|
|
108961
|
+
const claudeMdDest = join134(ctx.resolvedDir, "CLAUDE.md");
|
|
108871
108962
|
if (await import_fs_extra34.pathExists(claudeMdSource)) {
|
|
108872
108963
|
if (ctx.options.fresh || !await import_fs_extra34.pathExists(claudeMdDest)) {
|
|
108873
108964
|
await import_fs_extra34.copy(claudeMdSource, claudeMdDest);
|
|
@@ -108890,24 +108981,24 @@ async function handlePostInstall(ctx) {
|
|
|
108890
108981
|
});
|
|
108891
108982
|
}
|
|
108892
108983
|
if (!ctx.isNonInteractive) {
|
|
108893
|
-
const {
|
|
108894
|
-
const {
|
|
108895
|
-
const
|
|
108896
|
-
const existingConfig =
|
|
108984
|
+
const { isAgyInstalled: isAgyInstalled2 } = await Promise.resolve().then(() => (init_package_installer(), exports_package_installer));
|
|
108985
|
+
const { checkExistingAgyConfig: checkExistingAgyConfig2, findMcpConfigPath: findMcpConfigPath2, processAgyMcpLinking: processAgyMcpLinking2 } = await Promise.resolve().then(() => (init_agy_mcp_linker(), exports_agy_mcp_linker));
|
|
108986
|
+
const agyInstalled = await isAgyInstalled2();
|
|
108987
|
+
const existingConfig = checkExistingAgyConfig2(ctx.resolvedDir, ctx.options.global);
|
|
108897
108988
|
const mcpConfigPath = findMcpConfigPath2(ctx.resolvedDir);
|
|
108898
108989
|
const mcpConfigExists = mcpConfigPath !== null;
|
|
108899
|
-
if (
|
|
108900
|
-
const
|
|
108990
|
+
if (agyInstalled && !existingConfig.exists && mcpConfigExists) {
|
|
108991
|
+
const agyPath = ctx.options.global ? "~/.gemini/config/mcp_config.json" : ".agents/mcp_config.json";
|
|
108901
108992
|
const mcpPath = ctx.options.global ? "~/.claude/.mcp.json" : ".mcp.json";
|
|
108902
108993
|
const promptMessage = [
|
|
108903
|
-
"
|
|
108904
|
-
` → Creates ${
|
|
108905
|
-
" →
|
|
108994
|
+
"Antigravity CLI (agy) detected. Set up MCP integration?",
|
|
108995
|
+
` → Creates ${agyPath} symlink to ${mcpPath}`,
|
|
108996
|
+
" → agy will share MCP servers with Claude Code"
|
|
108906
108997
|
].join(`
|
|
108907
108998
|
`);
|
|
108908
|
-
const
|
|
108909
|
-
if (
|
|
108910
|
-
await
|
|
108999
|
+
const shouldSetupAgy = await ctx.prompts.confirm(promptMessage);
|
|
109000
|
+
if (shouldSetupAgy) {
|
|
109001
|
+
await processAgyMcpLinking2(ctx.resolvedDir, {
|
|
108911
109002
|
isGlobal: ctx.options.global
|
|
108912
109003
|
});
|
|
108913
109004
|
}
|
|
@@ -108915,7 +109006,7 @@ async function handlePostInstall(ctx) {
|
|
|
108915
109006
|
}
|
|
108916
109007
|
if (!ctx.options.skipSetup) {
|
|
108917
109008
|
await promptSetupWizardIfNeeded({
|
|
108918
|
-
envPath:
|
|
109009
|
+
envPath: join134(ctx.claudeDir, ".env"),
|
|
108919
109010
|
claudeDir: ctx.claudeDir,
|
|
108920
109011
|
isGlobal: ctx.options.global,
|
|
108921
109012
|
isNonInteractive: ctx.isNonInteractive,
|
|
@@ -108938,12 +109029,12 @@ async function handlePostInstall(ctx) {
|
|
|
108938
109029
|
// src/commands/init/phases/plugin-install-handler.ts
|
|
108939
109030
|
init_codex_plugin_installer();
|
|
108940
109031
|
import { cpSync as cpSync2, existsSync as existsSync69, mkdirSync as mkdirSync6, readFileSync as readFileSync21, rmSync as rmSync4, writeFileSync as writeFileSync8 } from "node:fs";
|
|
108941
|
-
import { join as
|
|
109032
|
+
import { join as join136 } from "node:path";
|
|
108942
109033
|
|
|
108943
109034
|
// src/domains/installation/plugin/migrate-legacy-to-plugin.ts
|
|
108944
109035
|
init_install_mode_detector();
|
|
108945
109036
|
import { cpSync, existsSync as existsSync68, mkdirSync as mkdirSync5, readFileSync as readFileSync20, rmSync as rmSync3, writeFileSync as writeFileSync7 } from "node:fs";
|
|
108946
|
-
import { dirname as dirname43, join as
|
|
109037
|
+
import { dirname as dirname43, join as join135 } from "node:path";
|
|
108947
109038
|
|
|
108948
109039
|
// src/domains/installation/plugin/plugin-installer.ts
|
|
108949
109040
|
init_install_mode_detector();
|
|
@@ -109075,7 +109166,7 @@ async function migrateLegacyToPlugin(opts) {
|
|
|
109075
109166
|
let backupDir = null;
|
|
109076
109167
|
let removedPaths = [];
|
|
109077
109168
|
if (before.legacy.installed) {
|
|
109078
|
-
backupDir =
|
|
109169
|
+
backupDir = join135(claudeDir3, "backups", `ck-legacy-${ts.replace(/[:.]/g, "-")}`);
|
|
109079
109170
|
mkdirSync5(backupDir, { recursive: true });
|
|
109080
109171
|
removedPaths = removeLegacy(claudeDir3, backupDir);
|
|
109081
109172
|
}
|
|
@@ -109109,7 +109200,7 @@ function base(action, modeBefore, pluginVerified) {
|
|
|
109109
109200
|
}
|
|
109110
109201
|
var PLUGIN_SUPPLIED_LEGACY_PREFIXES2 = ["agents/", "skills/"];
|
|
109111
109202
|
function defaultLegacyRemover(claudeDir3, backupDir) {
|
|
109112
|
-
const meta = readJsonSafe2(
|
|
109203
|
+
const meta = readJsonSafe2(join135(claudeDir3, "metadata.json"));
|
|
109113
109204
|
const files = collectTrackedFiles2(meta);
|
|
109114
109205
|
const removed = [];
|
|
109115
109206
|
for (const file of files) {
|
|
@@ -109117,10 +109208,10 @@ function defaultLegacyRemover(claudeDir3, backupDir) {
|
|
|
109117
109208
|
continue;
|
|
109118
109209
|
if (!isPluginSuppliedLegacyPath(file.path))
|
|
109119
109210
|
continue;
|
|
109120
|
-
const abs =
|
|
109211
|
+
const abs = join135(claudeDir3, file.path);
|
|
109121
109212
|
if (!existsSync68(abs))
|
|
109122
109213
|
continue;
|
|
109123
|
-
const backupTarget =
|
|
109214
|
+
const backupTarget = join135(backupDir, file.path);
|
|
109124
109215
|
mkdirSync5(dirname43(backupTarget), { recursive: true });
|
|
109125
109216
|
cpSync(abs, backupTarget, { recursive: true });
|
|
109126
109217
|
rmSync3(abs, { recursive: true, force: true });
|
|
@@ -109156,7 +109247,7 @@ function collectTrackedFiles2(meta) {
|
|
|
109156
109247
|
return out;
|
|
109157
109248
|
}
|
|
109158
109249
|
function writeReceipt(claudeDir3, receipt) {
|
|
109159
|
-
const receiptPath =
|
|
109250
|
+
const receiptPath = join135(claudeDir3, ".ck-migration-log.json");
|
|
109160
109251
|
const existing = readJsonSafe2(receiptPath);
|
|
109161
109252
|
const history = Array.isArray(existing) ? existing : [];
|
|
109162
109253
|
history.push(receipt);
|
|
@@ -109205,14 +109296,14 @@ async function handlePluginInstall(ctx, deps = {}) {
|
|
|
109205
109296
|
return ctx;
|
|
109206
109297
|
}
|
|
109207
109298
|
function stagePluginSource(extractDir, stageBaseDir) {
|
|
109208
|
-
const base2 = stageBaseDir ??
|
|
109209
|
-
const payloadSrc =
|
|
109299
|
+
const base2 = stageBaseDir ?? join136(PathResolver.getCacheDir(true), "ck-plugin-source");
|
|
109300
|
+
const payloadSrc = join136(extractDir, ".claude");
|
|
109210
109301
|
if (!existsSync69(payloadSrc)) {
|
|
109211
109302
|
throw new Error(`plugin payload not found in archive: ${payloadSrc}`);
|
|
109212
109303
|
}
|
|
109213
109304
|
rmSync4(base2, { recursive: true, force: true });
|
|
109214
109305
|
mkdirSync6(base2, { recursive: true });
|
|
109215
|
-
const stagedPayload =
|
|
109306
|
+
const stagedPayload = join136(base2, ".claude");
|
|
109216
109307
|
cpSync2(payloadSrc, stagedPayload, { recursive: true });
|
|
109217
109308
|
ensureCodexPluginManifest(stagedPayload);
|
|
109218
109309
|
const claudeMarketplace = {
|
|
@@ -109220,8 +109311,8 @@ function stagePluginSource(extractDir, stageBaseDir) {
|
|
|
109220
109311
|
owner: { name: "ClaudeKit" },
|
|
109221
109312
|
plugins: [{ name: "ck", source: "./.claude", description: "ClaudeKit Engineer" }]
|
|
109222
109313
|
};
|
|
109223
|
-
mkdirSync6(
|
|
109224
|
-
writeFileSync8(
|
|
109314
|
+
mkdirSync6(join136(base2, ".claude-plugin"), { recursive: true });
|
|
109315
|
+
writeFileSync8(join136(base2, ".claude-plugin", "marketplace.json"), `${JSON.stringify(claudeMarketplace, null, 2)}
|
|
109225
109316
|
`, "utf-8");
|
|
109226
109317
|
const codexMarketplace = {
|
|
109227
109318
|
name: "claudekit",
|
|
@@ -109235,16 +109326,16 @@ function stagePluginSource(extractDir, stageBaseDir) {
|
|
|
109235
109326
|
}
|
|
109236
109327
|
]
|
|
109237
109328
|
};
|
|
109238
|
-
mkdirSync6(
|
|
109239
|
-
writeFileSync8(
|
|
109329
|
+
mkdirSync6(join136(base2, ".agents", "plugins"), { recursive: true });
|
|
109330
|
+
writeFileSync8(join136(base2, ".agents", "plugins", "marketplace.json"), `${JSON.stringify(codexMarketplace, null, 2)}
|
|
109240
109331
|
`, "utf-8");
|
|
109241
109332
|
return base2;
|
|
109242
109333
|
}
|
|
109243
109334
|
function ensureCodexPluginManifest(pluginRoot) {
|
|
109244
|
-
const manifestPath =
|
|
109335
|
+
const manifestPath = join136(pluginRoot, ".codex-plugin", "plugin.json");
|
|
109245
109336
|
if (existsSync69(manifestPath))
|
|
109246
109337
|
return;
|
|
109247
|
-
const claudeManifest = readJsonSafe3(
|
|
109338
|
+
const claudeManifest = readJsonSafe3(join136(pluginRoot, ".claude-plugin", "plugin.json"));
|
|
109248
109339
|
const manifest = pruneUndefined({
|
|
109249
109340
|
name: stringField(claudeManifest, "name") ?? "ck",
|
|
109250
109341
|
version: stringField(claudeManifest, "version") ?? "0.0.0",
|
|
@@ -109265,7 +109356,7 @@ function ensureCodexPluginManifest(pluginRoot) {
|
|
|
109265
109356
|
websiteURL: "https://github.com/claudekit/claudekit-engineer"
|
|
109266
109357
|
}
|
|
109267
109358
|
});
|
|
109268
|
-
mkdirSync6(
|
|
109359
|
+
mkdirSync6(join136(pluginRoot, ".codex-plugin"), { recursive: true });
|
|
109269
109360
|
writeFileSync8(manifestPath, `${JSON.stringify(manifest, null, 2)}
|
|
109270
109361
|
`, "utf-8");
|
|
109271
109362
|
}
|
|
@@ -109330,7 +109421,7 @@ function logCodexPluginResult(result) {
|
|
|
109330
109421
|
init_config_manager();
|
|
109331
109422
|
init_github_client();
|
|
109332
109423
|
import { mkdir as mkdir36 } from "node:fs/promises";
|
|
109333
|
-
import { join as
|
|
109424
|
+
import { join as join139, resolve as resolve46 } from "node:path";
|
|
109334
109425
|
|
|
109335
109426
|
// src/domains/github/kit-access-checker.ts
|
|
109336
109427
|
init_error2();
|
|
@@ -109497,10 +109588,13 @@ async function runPreflightChecks() {
|
|
|
109497
109588
|
return result;
|
|
109498
109589
|
}
|
|
109499
109590
|
|
|
109591
|
+
// src/commands/init/phases/selection-handler.ts
|
|
109592
|
+
init_hook_health_checker();
|
|
109593
|
+
|
|
109500
109594
|
// src/domains/installation/fresh-installer.ts
|
|
109501
109595
|
init_metadata_migration();
|
|
109502
109596
|
import { existsSync as existsSync70, readdirSync as readdirSync11, rmSync as rmSync5, rmdirSync as rmdirSync2, unlinkSync as unlinkSync5 } from "node:fs";
|
|
109503
|
-
import { basename as basename28, dirname as dirname44, join as
|
|
109597
|
+
import { basename as basename28, dirname as dirname44, join as join137, resolve as resolve44 } from "node:path";
|
|
109504
109598
|
init_logger();
|
|
109505
109599
|
init_safe_spinner();
|
|
109506
109600
|
var import_fs_extra35 = __toESM(require_lib(), 1);
|
|
@@ -109582,7 +109676,7 @@ async function removeFilesByOwnership(claudeDir3, analysis, includeModified) {
|
|
|
109582
109676
|
logger.debug(`${KIT_MANIFEST_FILE} was self-tracked; skipping from delete loop — will be rewritten by updateMetadataAfterFresh`);
|
|
109583
109677
|
}
|
|
109584
109678
|
for (const file of filesToRemove) {
|
|
109585
|
-
const fullPath =
|
|
109679
|
+
const fullPath = join137(claudeDir3, file.path);
|
|
109586
109680
|
if (!existsSync70(fullPath)) {
|
|
109587
109681
|
continue;
|
|
109588
109682
|
}
|
|
@@ -109610,7 +109704,7 @@ async function removeFilesByOwnership(claudeDir3, analysis, includeModified) {
|
|
|
109610
109704
|
};
|
|
109611
109705
|
}
|
|
109612
109706
|
async function updateMetadataAfterFresh(claudeDir3, removedFiles, metadata) {
|
|
109613
|
-
const metadataPath =
|
|
109707
|
+
const metadataPath = join137(claudeDir3, KIT_MANIFEST_FILE);
|
|
109614
109708
|
const removedSet = new Set(removedFiles);
|
|
109615
109709
|
if (metadata.kits) {
|
|
109616
109710
|
for (const kitName of Object.keys(metadata.kits)) {
|
|
@@ -109641,8 +109735,8 @@ function getFreshBackupTargets(claudeDir3, analysis, includeModified) {
|
|
|
109641
109735
|
mutatePaths: filesToRemove.length > 0 ? ["metadata.json"] : []
|
|
109642
109736
|
};
|
|
109643
109737
|
}
|
|
109644
|
-
const deletePaths = CLAUDEKIT_SUBDIRECTORIES.filter((subdir) => existsSync70(
|
|
109645
|
-
if (existsSync70(
|
|
109738
|
+
const deletePaths = CLAUDEKIT_SUBDIRECTORIES.filter((subdir) => existsSync70(join137(claudeDir3, subdir)));
|
|
109739
|
+
if (existsSync70(join137(claudeDir3, "metadata.json"))) {
|
|
109646
109740
|
deletePaths.push("metadata.json");
|
|
109647
109741
|
}
|
|
109648
109742
|
return {
|
|
@@ -109664,7 +109758,7 @@ async function removeSubdirectoriesFallback(claudeDir3) {
|
|
|
109664
109758
|
const removedFiles = [];
|
|
109665
109759
|
let removedDirCount = 0;
|
|
109666
109760
|
for (const subdir of CLAUDEKIT_SUBDIRECTORIES) {
|
|
109667
|
-
const subdirPath =
|
|
109761
|
+
const subdirPath = join137(claudeDir3, subdir);
|
|
109668
109762
|
if (await import_fs_extra35.pathExists(subdirPath)) {
|
|
109669
109763
|
rmSync5(subdirPath, { recursive: true, force: true });
|
|
109670
109764
|
removedDirCount++;
|
|
@@ -109672,7 +109766,7 @@ async function removeSubdirectoriesFallback(claudeDir3) {
|
|
|
109672
109766
|
logger.debug(`Removed subdirectory: ${subdir}/`);
|
|
109673
109767
|
}
|
|
109674
109768
|
}
|
|
109675
|
-
const metadataPath =
|
|
109769
|
+
const metadataPath = join137(claudeDir3, "metadata.json");
|
|
109676
109770
|
if (await import_fs_extra35.pathExists(metadataPath)) {
|
|
109677
109771
|
unlinkSync5(metadataPath);
|
|
109678
109772
|
removedFiles.push("metadata.json");
|
|
@@ -109750,7 +109844,7 @@ async function handleFreshInstallation(claudeDir3, prompts) {
|
|
|
109750
109844
|
var import_fs_extra36 = __toESM(require_lib(), 1);
|
|
109751
109845
|
import { cp as cp5, mkdir as mkdir35, readdir as readdir42, rename as rename11, rm as rm16, stat as stat22 } from "node:fs/promises";
|
|
109752
109846
|
import { homedir as homedir47 } from "node:os";
|
|
109753
|
-
import { dirname as dirname45, join as
|
|
109847
|
+
import { dirname as dirname45, join as join138, normalize as normalize11, resolve as resolve45 } from "node:path";
|
|
109754
109848
|
var LEGACY_KIT_MARKERS = [
|
|
109755
109849
|
"metadata.json",
|
|
109756
109850
|
".ck.json",
|
|
@@ -109789,10 +109883,10 @@ function getLegacyWindowsGlobalKitDirCandidates(env2 = process.env, homeDir = ho
|
|
|
109789
109883
|
const localAppData = safeEnvPath(env2.LOCALAPPDATA);
|
|
109790
109884
|
const appData = safeEnvPath(env2.APPDATA);
|
|
109791
109885
|
if (localAppData) {
|
|
109792
|
-
candidates.push(
|
|
109886
|
+
candidates.push(join138(localAppData, ".claude"));
|
|
109793
109887
|
}
|
|
109794
109888
|
if (appData) {
|
|
109795
|
-
candidates.push(
|
|
109889
|
+
candidates.push(join138(appData, ".claude"));
|
|
109796
109890
|
}
|
|
109797
109891
|
if (homeDir) {
|
|
109798
109892
|
candidates.push(`${withoutTrailingSeparators(homeDir)}.claude`);
|
|
@@ -109810,7 +109904,7 @@ async function hasKitMarkers(dir) {
|
|
|
109810
109904
|
if (!await isDirectory(dir))
|
|
109811
109905
|
return false;
|
|
109812
109906
|
for (const marker of LEGACY_KIT_MARKERS) {
|
|
109813
|
-
if (await import_fs_extra36.pathExists(
|
|
109907
|
+
if (await import_fs_extra36.pathExists(join138(dir, marker))) {
|
|
109814
109908
|
return true;
|
|
109815
109909
|
}
|
|
109816
109910
|
}
|
|
@@ -110112,7 +110206,7 @@ async function handleSelection(ctx) {
|
|
|
110112
110206
|
}
|
|
110113
110207
|
if (!ctx.options.fresh) {
|
|
110114
110208
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
110115
|
-
const claudeDir3 = prefix ?
|
|
110209
|
+
const claudeDir3 = prefix ? join139(resolvedDir, prefix) : resolvedDir;
|
|
110116
110210
|
try {
|
|
110117
110211
|
const existingMetadata = await readManifest(claudeDir3);
|
|
110118
110212
|
if (existingMetadata?.kits) {
|
|
@@ -110149,7 +110243,7 @@ async function handleSelection(ctx) {
|
|
|
110149
110243
|
}
|
|
110150
110244
|
if (ctx.options.fresh) {
|
|
110151
110245
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
110152
|
-
const claudeDir3 = prefix ?
|
|
110246
|
+
const claudeDir3 = prefix ? join139(resolvedDir, prefix) : resolvedDir;
|
|
110153
110247
|
const canProceed = await handleFreshInstallation(claudeDir3, ctx.prompts);
|
|
110154
110248
|
if (!canProceed) {
|
|
110155
110249
|
return { ...ctx, cancelled: true };
|
|
@@ -110169,7 +110263,7 @@ async function handleSelection(ctx) {
|
|
|
110169
110263
|
let currentVersion = null;
|
|
110170
110264
|
try {
|
|
110171
110265
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
110172
|
-
const claudeDir3 = prefix ?
|
|
110266
|
+
const claudeDir3 = prefix ? join139(resolvedDir, prefix) : resolvedDir;
|
|
110173
110267
|
const existingMetadata = await readManifest(claudeDir3);
|
|
110174
110268
|
currentVersion = existingMetadata?.kits?.[kitType]?.version || null;
|
|
110175
110269
|
if (currentVersion) {
|
|
@@ -110238,12 +110332,17 @@ async function handleSelection(ctx) {
|
|
|
110238
110332
|
if (ctx.options.yes && !ctx.options.fresh && !ctx.options.force && !ctx.options.restoreCkHooks && releaseTag && !isOfflineMode && !pendingKits?.length) {
|
|
110239
110333
|
try {
|
|
110240
110334
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
110241
|
-
const claudeDir3 = prefix ?
|
|
110335
|
+
const claudeDir3 = prefix ? join139(resolvedDir, prefix) : resolvedDir;
|
|
110242
110336
|
const existingMetadata = await readManifest(claudeDir3);
|
|
110243
110337
|
const installedKitVersion = existingMetadata?.kits?.[kitType]?.version;
|
|
110244
110338
|
if (installedKitVersion && versionsMatch(installedKitVersion, releaseTag)) {
|
|
110245
|
-
|
|
110246
|
-
|
|
110339
|
+
const missingHookFiles = await countMissingHookFileReferencesForClaudeDir(claudeDir3);
|
|
110340
|
+
if (missingHookFiles > 0) {
|
|
110341
|
+
logger.warning(`Detected ${missingHookFiles} registered hook(s) whose script is missing on disk; reinstalling to restore them`);
|
|
110342
|
+
} else {
|
|
110343
|
+
logger.success(`Already at latest version (${kitType}@${installedKitVersion}), skipping reinstall`);
|
|
110344
|
+
return { ...ctx, cancelled: true };
|
|
110345
|
+
}
|
|
110247
110346
|
}
|
|
110248
110347
|
} catch (error) {
|
|
110249
110348
|
logger.verbose(`Metadata read failed, proceeding with installation: ${error instanceof Error ? error.message : "unknown"}`);
|
|
@@ -110262,7 +110361,7 @@ async function handleSelection(ctx) {
|
|
|
110262
110361
|
}
|
|
110263
110362
|
// src/commands/init/phases/sync-handler.ts
|
|
110264
110363
|
import { copyFile as copyFile8, mkdir as mkdir37, open as open5, readFile as readFile61, rename as rename12, stat as stat23, unlink as unlink13, writeFile as writeFile35 } from "node:fs/promises";
|
|
110265
|
-
import { dirname as dirname46, join as
|
|
110364
|
+
import { dirname as dirname46, join as join140, resolve as resolve47 } from "node:path";
|
|
110266
110365
|
init_logger();
|
|
110267
110366
|
init_path_resolver();
|
|
110268
110367
|
var import_fs_extra38 = __toESM(require_lib(), 1);
|
|
@@ -110272,13 +110371,13 @@ async function handleSync(ctx) {
|
|
|
110272
110371
|
return ctx;
|
|
110273
110372
|
}
|
|
110274
110373
|
const resolvedDir = ctx.options.global ? PathResolver.getGlobalKitDir() : resolve47(ctx.options.dir || ".");
|
|
110275
|
-
const claudeDir3 = ctx.options.global ? resolvedDir :
|
|
110374
|
+
const claudeDir3 = ctx.options.global ? resolvedDir : join140(resolvedDir, ".claude");
|
|
110276
110375
|
if (!await import_fs_extra38.pathExists(claudeDir3)) {
|
|
110277
110376
|
logger.error("Cannot sync: no .claude directory found");
|
|
110278
110377
|
ctx.prompts.note("Run 'ck init' without --sync to install first.", "No Installation Found");
|
|
110279
110378
|
return { ...ctx, cancelled: true };
|
|
110280
110379
|
}
|
|
110281
|
-
const metadataPath =
|
|
110380
|
+
const metadataPath = join140(claudeDir3, "metadata.json");
|
|
110282
110381
|
if (!await import_fs_extra38.pathExists(metadataPath)) {
|
|
110283
110382
|
logger.error("Cannot sync: no metadata.json found");
|
|
110284
110383
|
ctx.prompts.note(`Your installation may be from an older version.
|
|
@@ -110378,7 +110477,7 @@ function getLockTimeout() {
|
|
|
110378
110477
|
var STALE_LOCK_THRESHOLD_MS = 5 * 60 * 1000;
|
|
110379
110478
|
async function acquireSyncLock(global3) {
|
|
110380
110479
|
const cacheDir = PathResolver.getCacheDir(global3);
|
|
110381
|
-
const lockPath =
|
|
110480
|
+
const lockPath = join140(cacheDir, ".sync-lock");
|
|
110382
110481
|
const startTime = Date.now();
|
|
110383
110482
|
const lockTimeout = getLockTimeout();
|
|
110384
110483
|
await mkdir37(dirname46(lockPath), { recursive: true });
|
|
@@ -110424,11 +110523,11 @@ async function executeSyncMerge(ctx) {
|
|
|
110424
110523
|
const releaseLock = await acquireSyncLock(ctx.options.global);
|
|
110425
110524
|
try {
|
|
110426
110525
|
const trackedFiles = ctx.syncTrackedFiles;
|
|
110427
|
-
const upstreamDir = ctx.options.global ?
|
|
110526
|
+
const upstreamDir = ctx.options.global ? join140(ctx.extractDir, ".claude") : ctx.extractDir;
|
|
110428
110527
|
let sourceMetadata = null;
|
|
110429
110528
|
let deletions = [];
|
|
110430
110529
|
try {
|
|
110431
|
-
const sourceMetadataPath =
|
|
110530
|
+
const sourceMetadataPath = join140(upstreamDir, "metadata.json");
|
|
110432
110531
|
if (await import_fs_extra38.pathExists(sourceMetadataPath)) {
|
|
110433
110532
|
const content = await readFile61(sourceMetadataPath, "utf-8");
|
|
110434
110533
|
sourceMetadata = JSON.parse(content);
|
|
@@ -110490,7 +110589,7 @@ async function executeSyncMerge(ctx) {
|
|
|
110490
110589
|
try {
|
|
110491
110590
|
const sourcePath = await validateSyncPath(upstreamDir, file.path);
|
|
110492
110591
|
const targetPath = await validateSyncPath(ctx.claudeDir, file.path);
|
|
110493
|
-
const targetDir =
|
|
110592
|
+
const targetDir = join140(targetPath, "..");
|
|
110494
110593
|
try {
|
|
110495
110594
|
await mkdir37(targetDir, { recursive: true });
|
|
110496
110595
|
} catch (mkdirError) {
|
|
@@ -110661,7 +110760,7 @@ async function createBackup(claudeDir3, files, backupDir) {
|
|
|
110661
110760
|
const sourcePath = await validateSyncPath(claudeDir3, file.path);
|
|
110662
110761
|
if (await import_fs_extra38.pathExists(sourcePath)) {
|
|
110663
110762
|
const targetPath = await validateSyncPath(backupDir, file.path);
|
|
110664
|
-
const targetDir =
|
|
110763
|
+
const targetDir = join140(targetPath, "..");
|
|
110665
110764
|
await mkdir37(targetDir, { recursive: true });
|
|
110666
110765
|
await copyFile8(sourcePath, targetPath);
|
|
110667
110766
|
}
|
|
@@ -110676,7 +110775,7 @@ async function createBackup(claudeDir3, files, backupDir) {
|
|
|
110676
110775
|
}
|
|
110677
110776
|
// src/commands/init/phases/transform-handler.ts
|
|
110678
110777
|
init_config_manager();
|
|
110679
|
-
import { join as
|
|
110778
|
+
import { join as join144 } from "node:path";
|
|
110680
110779
|
|
|
110681
110780
|
// src/services/transformers/folder-path-transformer.ts
|
|
110682
110781
|
init_logger();
|
|
@@ -110687,38 +110786,38 @@ init_logger();
|
|
|
110687
110786
|
init_types3();
|
|
110688
110787
|
var import_fs_extra39 = __toESM(require_lib(), 1);
|
|
110689
110788
|
import { rename as rename13, rm as rm17 } from "node:fs/promises";
|
|
110690
|
-
import { join as
|
|
110789
|
+
import { join as join141, relative as relative30 } from "node:path";
|
|
110691
110790
|
async function collectDirsToRename(extractDir, folders) {
|
|
110692
110791
|
const dirsToRename = [];
|
|
110693
110792
|
if (folders.docs !== DEFAULT_FOLDERS.docs) {
|
|
110694
|
-
const docsPath =
|
|
110793
|
+
const docsPath = join141(extractDir, DEFAULT_FOLDERS.docs);
|
|
110695
110794
|
if (await import_fs_extra39.pathExists(docsPath)) {
|
|
110696
110795
|
dirsToRename.push({
|
|
110697
110796
|
from: docsPath,
|
|
110698
|
-
to:
|
|
110797
|
+
to: join141(extractDir, folders.docs)
|
|
110699
110798
|
});
|
|
110700
110799
|
}
|
|
110701
|
-
const claudeDocsPath =
|
|
110800
|
+
const claudeDocsPath = join141(extractDir, ".claude", DEFAULT_FOLDERS.docs);
|
|
110702
110801
|
if (await import_fs_extra39.pathExists(claudeDocsPath)) {
|
|
110703
110802
|
dirsToRename.push({
|
|
110704
110803
|
from: claudeDocsPath,
|
|
110705
|
-
to:
|
|
110804
|
+
to: join141(extractDir, ".claude", folders.docs)
|
|
110706
110805
|
});
|
|
110707
110806
|
}
|
|
110708
110807
|
}
|
|
110709
110808
|
if (folders.plans !== DEFAULT_FOLDERS.plans) {
|
|
110710
|
-
const plansPath =
|
|
110809
|
+
const plansPath = join141(extractDir, DEFAULT_FOLDERS.plans);
|
|
110711
110810
|
if (await import_fs_extra39.pathExists(plansPath)) {
|
|
110712
110811
|
dirsToRename.push({
|
|
110713
110812
|
from: plansPath,
|
|
110714
|
-
to:
|
|
110813
|
+
to: join141(extractDir, folders.plans)
|
|
110715
110814
|
});
|
|
110716
110815
|
}
|
|
110717
|
-
const claudePlansPath =
|
|
110816
|
+
const claudePlansPath = join141(extractDir, ".claude", DEFAULT_FOLDERS.plans);
|
|
110718
110817
|
if (await import_fs_extra39.pathExists(claudePlansPath)) {
|
|
110719
110818
|
dirsToRename.push({
|
|
110720
110819
|
from: claudePlansPath,
|
|
110721
|
-
to:
|
|
110820
|
+
to: join141(extractDir, ".claude", folders.plans)
|
|
110722
110821
|
});
|
|
110723
110822
|
}
|
|
110724
110823
|
}
|
|
@@ -110759,7 +110858,7 @@ async function renameFolders(dirsToRename, extractDir, options2) {
|
|
|
110759
110858
|
init_logger();
|
|
110760
110859
|
init_types3();
|
|
110761
110860
|
import { readFile as readFile62, readdir as readdir43, writeFile as writeFile36 } from "node:fs/promises";
|
|
110762
|
-
import { join as
|
|
110861
|
+
import { join as join142, relative as relative31 } from "node:path";
|
|
110763
110862
|
var TRANSFORMABLE_FILE_PATTERNS = [
|
|
110764
110863
|
".md",
|
|
110765
110864
|
".txt",
|
|
@@ -110812,7 +110911,7 @@ async function transformFileContents(dir, compiledReplacements, options2) {
|
|
|
110812
110911
|
let replacementsCount = 0;
|
|
110813
110912
|
const entries = await readdir43(dir, { withFileTypes: true });
|
|
110814
110913
|
for (const entry of entries) {
|
|
110815
|
-
const fullPath =
|
|
110914
|
+
const fullPath = join142(dir, entry.name);
|
|
110816
110915
|
if (entry.isDirectory()) {
|
|
110817
110916
|
if (entry.name === "node_modules" || entry.name === ".git") {
|
|
110818
110917
|
continue;
|
|
@@ -110949,7 +111048,7 @@ async function transformFolderPaths(extractDir, folders, options2 = {}) {
|
|
|
110949
111048
|
init_logger();
|
|
110950
111049
|
import { readFile as readFile63, readdir as readdir44, writeFile as writeFile37 } from "node:fs/promises";
|
|
110951
111050
|
import { homedir as homedir48, platform as platform16 } from "node:os";
|
|
110952
|
-
import { extname as extname7, join as
|
|
111051
|
+
import { extname as extname7, join as join143 } from "node:path";
|
|
110953
111052
|
var IS_WINDOWS3 = platform16() === "win32";
|
|
110954
111053
|
var HOME_PREFIX = "$HOME";
|
|
110955
111054
|
function getHomeDirPrefix() {
|
|
@@ -110959,7 +111058,7 @@ function normalizeInstallPath(path17) {
|
|
|
110959
111058
|
return path17.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
110960
111059
|
}
|
|
110961
111060
|
function getDefaultGlobalClaudeDir() {
|
|
110962
|
-
return normalizeInstallPath(
|
|
111061
|
+
return normalizeInstallPath(join143(homedir48(), ".claude"));
|
|
110963
111062
|
}
|
|
110964
111063
|
function getCustomGlobalClaudeDir(targetClaudeDir) {
|
|
110965
111064
|
if (!targetClaudeDir)
|
|
@@ -111090,7 +111189,7 @@ async function transformPathsForGlobalInstall(directory, options2 = {}) {
|
|
|
111090
111189
|
async function processDirectory2(dir) {
|
|
111091
111190
|
const entries = await readdir44(dir, { withFileTypes: true });
|
|
111092
111191
|
for (const entry of entries) {
|
|
111093
|
-
const fullPath =
|
|
111192
|
+
const fullPath = join143(dir, entry.name);
|
|
111094
111193
|
if (entry.isDirectory()) {
|
|
111095
111194
|
if (entry.name === "node_modules" || entry.name.startsWith(".") && entry.name !== ".claude") {
|
|
111096
111195
|
continue;
|
|
@@ -111169,7 +111268,7 @@ async function handleTransforms(ctx) {
|
|
|
111169
111268
|
logger.debug(ctx.options.global ? "Saved folder configuration to ~/.claude/.ck.json" : "Saved folder configuration to .claude/.ck.json");
|
|
111170
111269
|
}
|
|
111171
111270
|
}
|
|
111172
|
-
const claudeDir3 = ctx.options.global ? ctx.resolvedDir :
|
|
111271
|
+
const claudeDir3 = ctx.options.global ? ctx.resolvedDir : join144(ctx.resolvedDir, ".claude");
|
|
111173
111272
|
return {
|
|
111174
111273
|
...ctx,
|
|
111175
111274
|
foldersConfig,
|
|
@@ -111396,7 +111495,7 @@ var import_picocolors30 = __toESM(require_picocolors(), 1);
|
|
|
111396
111495
|
import { existsSync as existsSync71 } from "node:fs";
|
|
111397
111496
|
import { readFile as readFile67, rm as rm18, unlink as unlink14 } from "node:fs/promises";
|
|
111398
111497
|
import { homedir as homedir52 } from "node:os";
|
|
111399
|
-
import { basename as basename30, join as
|
|
111498
|
+
import { basename as basename30, join as join148, resolve as resolve48 } from "node:path";
|
|
111400
111499
|
init_logger();
|
|
111401
111500
|
|
|
111402
111501
|
// src/ui/ck-cli-design/next-steps-footer.ts
|
|
@@ -111611,13 +111710,13 @@ init_dist2();
|
|
|
111611
111710
|
init_model_taxonomy();
|
|
111612
111711
|
import { mkdir as mkdir39, readFile as readFile66, writeFile as writeFile39 } from "node:fs/promises";
|
|
111613
111712
|
import { homedir as homedir51 } from "node:os";
|
|
111614
|
-
import { dirname as dirname47, join as
|
|
111713
|
+
import { dirname as dirname47, join as join147 } from "node:path";
|
|
111615
111714
|
|
|
111616
111715
|
// src/commands/portable/models-dev-cache.ts
|
|
111617
111716
|
init_logger();
|
|
111618
111717
|
import { mkdir as mkdir38, readFile as readFile64, rename as rename14, writeFile as writeFile38 } from "node:fs/promises";
|
|
111619
111718
|
import { homedir as homedir49 } from "node:os";
|
|
111620
|
-
import { join as
|
|
111719
|
+
import { join as join145 } from "node:path";
|
|
111621
111720
|
|
|
111622
111721
|
class ModelsDevUnavailableError extends Error {
|
|
111623
111722
|
constructor(message, cause) {
|
|
@@ -111629,13 +111728,13 @@ var MODELS_DEV_URL = "https://models.dev/api.json";
|
|
|
111629
111728
|
var CACHE_TTL_MS3 = 24 * 60 * 60 * 1000;
|
|
111630
111729
|
var FETCH_TIMEOUT_MS = 1e4;
|
|
111631
111730
|
function defaultCacheDir() {
|
|
111632
|
-
return
|
|
111731
|
+
return join145(homedir49(), ".config", "claudekit", "cache");
|
|
111633
111732
|
}
|
|
111634
111733
|
function cacheFilePath(cacheDir) {
|
|
111635
|
-
return
|
|
111734
|
+
return join145(cacheDir, "models-dev.json");
|
|
111636
111735
|
}
|
|
111637
111736
|
function tmpFilePath(cacheDir) {
|
|
111638
|
-
return
|
|
111737
|
+
return join145(cacheDir, "models-dev.json.tmp");
|
|
111639
111738
|
}
|
|
111640
111739
|
async function readCacheEntry(cacheDir) {
|
|
111641
111740
|
const filePath = cacheFilePath(cacheDir);
|
|
@@ -111710,14 +111809,14 @@ async function getModelsDevCatalog(opts = {}) {
|
|
|
111710
111809
|
init_logger();
|
|
111711
111810
|
import { readFile as readFile65 } from "node:fs/promises";
|
|
111712
111811
|
import { homedir as homedir50, platform as platform17 } from "node:os";
|
|
111713
|
-
import { join as
|
|
111812
|
+
import { join as join146 } from "node:path";
|
|
111714
111813
|
function resolveOpenCodeAuthPath(homeDir) {
|
|
111715
111814
|
if (platform17() === "win32") {
|
|
111716
|
-
const dataRoot2 = process.env.LOCALAPPDATA ??
|
|
111717
|
-
return
|
|
111815
|
+
const dataRoot2 = process.env.LOCALAPPDATA ?? join146(homeDir, "AppData", "Local");
|
|
111816
|
+
return join146(dataRoot2, "opencode", "auth.json");
|
|
111718
111817
|
}
|
|
111719
|
-
const dataRoot = process.env.XDG_DATA_HOME ??
|
|
111720
|
-
return
|
|
111818
|
+
const dataRoot = process.env.XDG_DATA_HOME ?? join146(homeDir, ".local", "share");
|
|
111819
|
+
return join146(dataRoot, "opencode", "auth.json");
|
|
111721
111820
|
}
|
|
111722
111821
|
async function readAuthedProviders(homeDir) {
|
|
111723
111822
|
const authPath = resolveOpenCodeAuthPath(homeDir);
|
|
@@ -111819,9 +111918,9 @@ function messageForReason(reason) {
|
|
|
111819
111918
|
}
|
|
111820
111919
|
function getOpenCodeConfigPath(options2) {
|
|
111821
111920
|
if (options2.global) {
|
|
111822
|
-
return
|
|
111921
|
+
return join147(options2.homeDir ?? homedir51(), ".config", "opencode", "opencode.json");
|
|
111823
111922
|
}
|
|
111824
|
-
return
|
|
111923
|
+
return join147(options2.cwd ?? process.cwd(), "opencode.json");
|
|
111825
111924
|
}
|
|
111826
111925
|
function makeCatalogOpts(options2) {
|
|
111827
111926
|
return {
|
|
@@ -112694,7 +112793,7 @@ function appendFallbackSkillActionsToPlan(plan, skills, selectedProviders, insta
|
|
|
112694
112793
|
reason: "New item, not previously installed",
|
|
112695
112794
|
reasonCode: "new-item",
|
|
112696
112795
|
reasonCopy: "New - not previously installed",
|
|
112697
|
-
targetPath:
|
|
112796
|
+
targetPath: join148(basePath, skill.name),
|
|
112698
112797
|
type: "skill"
|
|
112699
112798
|
});
|
|
112700
112799
|
}
|
|
@@ -112915,7 +113014,7 @@ function createSkippedPathMigrationCleanupResult2(action) {
|
|
|
112915
113014
|
async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
112916
113015
|
if (!skillSourcePath)
|
|
112917
113016
|
return;
|
|
112918
|
-
const sourceMetadataPath =
|
|
113017
|
+
const sourceMetadataPath = join148(resolve48(skillSourcePath, ".."), "metadata.json");
|
|
112919
113018
|
if (!existsSync71(sourceMetadataPath))
|
|
112920
113019
|
return;
|
|
112921
113020
|
let sourceMetadata;
|
|
@@ -112928,7 +113027,7 @@ async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
|
112928
113027
|
}
|
|
112929
113028
|
if (!sourceMetadata.deletions || sourceMetadata.deletions.length === 0)
|
|
112930
113029
|
return;
|
|
112931
|
-
const claudeDir3 = installGlobally ?
|
|
113030
|
+
const claudeDir3 = installGlobally ? join148(homedir52(), ".claude") : join148(process.cwd(), ".claude");
|
|
112932
113031
|
if (!existsSync71(claudeDir3))
|
|
112933
113032
|
return;
|
|
112934
113033
|
try {
|
|
@@ -113056,8 +113155,8 @@ async function migrateCommand(options2) {
|
|
|
113056
113155
|
let requestedGlobal = options2.global ?? false;
|
|
113057
113156
|
let installGlobally = requestedGlobal;
|
|
113058
113157
|
if (options2.global === undefined && !options2.yes) {
|
|
113059
|
-
const projectTarget =
|
|
113060
|
-
const globalTarget =
|
|
113158
|
+
const projectTarget = join148(process.cwd(), ".claude");
|
|
113159
|
+
const globalTarget = join148(homedir52(), ".claude");
|
|
113061
113160
|
const scopeChoice = await ie({
|
|
113062
113161
|
message: "Installation scope",
|
|
113063
113162
|
options: [
|
|
@@ -113130,7 +113229,7 @@ async function migrateCommand(options2) {
|
|
|
113130
113229
|
}).join(`
|
|
113131
113230
|
`));
|
|
113132
113231
|
if (sourceGlobalOnly) {
|
|
113133
|
-
f2.info(import_picocolors30.default.dim(` Scope: global (--global / -g) - reading from ${formatDisplayPath(
|
|
113232
|
+
f2.info(import_picocolors30.default.dim(` Scope: global (--global / -g) - reading from ${formatDisplayPath(join148(homedir52(), ".claude"))}`));
|
|
113134
113233
|
} else {
|
|
113135
113234
|
f2.info(import_picocolors30.default.dim(` CWD: ${process.cwd()}`));
|
|
113136
113235
|
}
|
|
@@ -113794,7 +113893,7 @@ async function handleDirectorySetup(ctx) {
|
|
|
113794
113893
|
// src/commands/new/phases/project-creation.ts
|
|
113795
113894
|
init_config_manager();
|
|
113796
113895
|
init_github_client();
|
|
113797
|
-
import { join as
|
|
113896
|
+
import { join as join149 } from "node:path";
|
|
113798
113897
|
init_logger();
|
|
113799
113898
|
init_output_manager();
|
|
113800
113899
|
init_types3();
|
|
@@ -113920,7 +114019,7 @@ async function projectCreation(kit, resolvedDir, validOptions, isNonInteractive2
|
|
|
113920
114019
|
output.section("Installing");
|
|
113921
114020
|
logger.verbose("Installation target", { directory: resolvedDir });
|
|
113922
114021
|
const merger = new FileMerger;
|
|
113923
|
-
const claudeDir3 =
|
|
114022
|
+
const claudeDir3 = join149(resolvedDir, ".claude");
|
|
113924
114023
|
merger.setMultiKitContext(claudeDir3, kit);
|
|
113925
114024
|
if (validOptions.exclude && validOptions.exclude.length > 0) {
|
|
113926
114025
|
merger.addIgnorePatterns(validOptions.exclude);
|
|
@@ -113967,28 +114066,28 @@ async function handleProjectCreation(ctx) {
|
|
|
113967
114066
|
}
|
|
113968
114067
|
// src/commands/new/phases/post-setup.ts
|
|
113969
114068
|
init_projects_registry();
|
|
113970
|
-
import { join as
|
|
114069
|
+
import { join as join150 } from "node:path";
|
|
113971
114070
|
init_package_installer();
|
|
113972
114071
|
init_logger();
|
|
113973
114072
|
init_path_resolver();
|
|
113974
114073
|
async function postSetup(resolvedDir, validOptions, isNonInteractive2, prompts) {
|
|
113975
114074
|
let installOpenCode2 = validOptions.opencode;
|
|
113976
|
-
let
|
|
114075
|
+
let installAgy2 = validOptions.gemini;
|
|
113977
114076
|
let installSkills = validOptions.installSkills;
|
|
113978
|
-
if (!isNonInteractive2 && !installOpenCode2 && !
|
|
114077
|
+
if (!isNonInteractive2 && !installOpenCode2 && !installAgy2 && !installSkills) {
|
|
113979
114078
|
const packageChoices = await prompts.promptPackageInstallations();
|
|
113980
114079
|
installOpenCode2 = packageChoices.installOpenCode;
|
|
113981
|
-
|
|
114080
|
+
installAgy2 = packageChoices.installAgy;
|
|
113982
114081
|
installSkills = await prompts.promptSkillsInstallation();
|
|
113983
114082
|
}
|
|
113984
|
-
if (installOpenCode2 ||
|
|
114083
|
+
if (installOpenCode2 || installAgy2) {
|
|
113985
114084
|
logger.info("Installing optional packages...");
|
|
113986
114085
|
try {
|
|
113987
|
-
const installationResults = await processPackageInstallations(installOpenCode2,
|
|
114086
|
+
const installationResults = await processPackageInstallations(installOpenCode2, installAgy2, resolvedDir);
|
|
113988
114087
|
prompts.showPackageInstallationResults(installationResults);
|
|
113989
114088
|
} catch (error) {
|
|
113990
114089
|
logger.warning(`Package installation failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
113991
|
-
logger.info("You can install these packages manually later
|
|
114090
|
+
logger.info("You can install these packages manually later from each tool's official install guide.");
|
|
113992
114091
|
}
|
|
113993
114092
|
}
|
|
113994
114093
|
if (installSkills) {
|
|
@@ -113999,9 +114098,9 @@ async function postSetup(resolvedDir, validOptions, isNonInteractive2, prompts)
|
|
|
113999
114098
|
withSudo: validOptions.withSudo
|
|
114000
114099
|
});
|
|
114001
114100
|
}
|
|
114002
|
-
const claudeDir3 =
|
|
114101
|
+
const claudeDir3 = join150(resolvedDir, ".claude");
|
|
114003
114102
|
await promptSetupWizardIfNeeded({
|
|
114004
|
-
envPath:
|
|
114103
|
+
envPath: join150(claudeDir3, ".env"),
|
|
114005
114104
|
claudeDir: claudeDir3,
|
|
114006
114105
|
isGlobal: false,
|
|
114007
114106
|
isNonInteractive: isNonInteractive2,
|
|
@@ -114071,7 +114170,7 @@ Please use only one download method.`);
|
|
|
114071
114170
|
// src/commands/plan/plan-command.ts
|
|
114072
114171
|
init_output_manager();
|
|
114073
114172
|
import { existsSync as existsSync74, statSync as statSync13 } from "node:fs";
|
|
114074
|
-
import { dirname as dirname52, isAbsolute as isAbsolute14, join as
|
|
114173
|
+
import { dirname as dirname52, isAbsolute as isAbsolute14, join as join153, parse as parse7, resolve as resolve53 } from "node:path";
|
|
114075
114174
|
|
|
114076
114175
|
// src/commands/plan/plan-read-handlers.ts
|
|
114077
114176
|
init_config();
|
|
@@ -114081,14 +114180,14 @@ init_logger();
|
|
|
114081
114180
|
init_output_manager();
|
|
114082
114181
|
var import_picocolors32 = __toESM(require_picocolors(), 1);
|
|
114083
114182
|
import { existsSync as existsSync73, statSync as statSync12 } from "node:fs";
|
|
114084
|
-
import { basename as basename31, dirname as dirname50, join as
|
|
114183
|
+
import { basename as basename31, dirname as dirname50, join as join152, relative as relative32, resolve as resolve51 } from "node:path";
|
|
114085
114184
|
|
|
114086
114185
|
// src/commands/plan/plan-dependencies.ts
|
|
114087
114186
|
init_config();
|
|
114088
114187
|
init_plan_parser();
|
|
114089
114188
|
init_plans_registry();
|
|
114090
114189
|
import { existsSync as existsSync72 } from "node:fs";
|
|
114091
|
-
import { dirname as dirname49, join as
|
|
114190
|
+
import { dirname as dirname49, join as join151 } from "node:path";
|
|
114092
114191
|
async function resolvePlanDependencies(references, currentPlanFile, options2 = {}) {
|
|
114093
114192
|
if (references.length === 0)
|
|
114094
114193
|
return [];
|
|
@@ -114108,7 +114207,7 @@ async function resolvePlanDependencies(references, currentPlanFile, options2 = {
|
|
|
114108
114207
|
};
|
|
114109
114208
|
}
|
|
114110
114209
|
const scopeRoot = resolvePlanDirForScope(scope, projectRoot, config);
|
|
114111
|
-
const planFile =
|
|
114210
|
+
const planFile = join151(scopeRoot, planId, "plan.md");
|
|
114112
114211
|
const isSelfReference = planFile === currentPlanFile;
|
|
114113
114212
|
if (!existsSync72(planFile)) {
|
|
114114
114213
|
return {
|
|
@@ -114250,7 +114349,7 @@ async function handleStatus(target, options2) {
|
|
|
114250
114349
|
}
|
|
114251
114350
|
const effectiveTarget = !resolvedTarget && globalBaseDir ? globalBaseDir : resolvedTarget;
|
|
114252
114351
|
const t = effectiveTarget ? resolve51(effectiveTarget) : null;
|
|
114253
|
-
const plansDir = t && existsSync73(t) && statSync12(t).isDirectory() && !existsSync73(
|
|
114352
|
+
const plansDir = t && existsSync73(t) && statSync12(t).isDirectory() && !existsSync73(join152(t, "plan.md")) ? t : null;
|
|
114254
114353
|
if (plansDir) {
|
|
114255
114354
|
const planFiles = scanPlanDir(plansDir);
|
|
114256
114355
|
if (planFiles.length === 0) {
|
|
@@ -114679,7 +114778,7 @@ function resolvePlanFile(target, baseDir) {
|
|
|
114679
114778
|
const stat24 = statSync13(t);
|
|
114680
114779
|
if (stat24.isFile())
|
|
114681
114780
|
return t;
|
|
114682
|
-
const candidate =
|
|
114781
|
+
const candidate = join153(t, "plan.md");
|
|
114683
114782
|
if (existsSync74(candidate))
|
|
114684
114783
|
return candidate;
|
|
114685
114784
|
}
|
|
@@ -114687,7 +114786,7 @@ function resolvePlanFile(target, baseDir) {
|
|
|
114687
114786
|
let dir = process.cwd();
|
|
114688
114787
|
const root = parse7(dir).root;
|
|
114689
114788
|
while (dir !== root) {
|
|
114690
|
-
const candidate =
|
|
114789
|
+
const candidate = join153(dir, "plan.md");
|
|
114691
114790
|
if (existsSync74(candidate))
|
|
114692
114791
|
return candidate;
|
|
114693
114792
|
dir = dirname52(dir);
|
|
@@ -115049,7 +115148,7 @@ async function handleEnvironmentConfig(ctx) {
|
|
|
115049
115148
|
};
|
|
115050
115149
|
}
|
|
115051
115150
|
// src/commands/setup/phases/packages-optional.ts
|
|
115052
|
-
|
|
115151
|
+
init_agy_installer();
|
|
115053
115152
|
init_opencode_installer();
|
|
115054
115153
|
init_dist2();
|
|
115055
115154
|
async function handleOptionalPackages(ctx) {
|
|
@@ -115079,23 +115178,23 @@ async function handleOptionalPackages(ctx) {
|
|
|
115079
115178
|
}
|
|
115080
115179
|
}
|
|
115081
115180
|
}
|
|
115082
|
-
const
|
|
115083
|
-
if (
|
|
115084
|
-
f2.success("
|
|
115181
|
+
const hasAgy = await isAgyInstalled();
|
|
115182
|
+
if (hasAgy) {
|
|
115183
|
+
f2.success("Antigravity CLI (agy): already installed");
|
|
115085
115184
|
} else {
|
|
115086
|
-
const
|
|
115087
|
-
message: "Install
|
|
115185
|
+
const installAgyChoice = await se({
|
|
115186
|
+
message: "Install Antigravity CLI (agy)? (AI assistant)",
|
|
115088
115187
|
initialValue: false
|
|
115089
115188
|
});
|
|
115090
|
-
if (lD(
|
|
115189
|
+
if (lD(installAgyChoice)) {
|
|
115091
115190
|
return { ...ctx, cancelled: true };
|
|
115092
115191
|
}
|
|
115093
|
-
if (
|
|
115094
|
-
const result = await
|
|
115192
|
+
if (installAgyChoice) {
|
|
115193
|
+
const result = await installAgy();
|
|
115095
115194
|
if (result.success) {
|
|
115096
|
-
installedPackages.push("
|
|
115195
|
+
installedPackages.push("Antigravity CLI (agy)");
|
|
115097
115196
|
} else {
|
|
115098
|
-
f2.warning(`Failed to install
|
|
115197
|
+
f2.warning(`Failed to install Antigravity CLI (agy): ${result.error || "Unknown error"}`);
|
|
115099
115198
|
}
|
|
115100
115199
|
}
|
|
115101
115200
|
}
|
|
@@ -115207,10 +115306,10 @@ init_agents();
|
|
|
115207
115306
|
var import_gray_matter12 = __toESM(require_gray_matter(), 1);
|
|
115208
115307
|
var import_picocolors37 = __toESM(require_picocolors(), 1);
|
|
115209
115308
|
import { readFile as readFile68 } from "node:fs/promises";
|
|
115210
|
-
import { join as
|
|
115309
|
+
import { join as join155 } from "node:path";
|
|
115211
115310
|
|
|
115212
115311
|
// src/commands/skills/installed-skills-inventory.ts
|
|
115213
|
-
import { join as
|
|
115312
|
+
import { join as join154, resolve as resolve55 } from "node:path";
|
|
115214
115313
|
init_path_resolver();
|
|
115215
115314
|
var SCOPE_SORT_ORDER = {
|
|
115216
115315
|
project: 0,
|
|
@@ -115222,8 +115321,8 @@ async function getActiveClaudeSkillInstallations(options2 = {}) {
|
|
|
115222
115321
|
const projectClaudeDir = resolve55(projectDir, ".claude");
|
|
115223
115322
|
const projectScopeAliasesGlobal = projectClaudeDir === globalDir;
|
|
115224
115323
|
const [projectSkills, globalSkills] = await Promise.all([
|
|
115225
|
-
projectScopeAliasesGlobal ? Promise.resolve([]) : scanSkills2(
|
|
115226
|
-
scanSkills2(
|
|
115324
|
+
projectScopeAliasesGlobal ? Promise.resolve([]) : scanSkills2(join154(projectClaudeDir, "skills")),
|
|
115325
|
+
scanSkills2(join154(globalDir, "skills"))
|
|
115227
115326
|
]);
|
|
115228
115327
|
const projectIds = new Set(projectSkills.map((skill) => skill.id));
|
|
115229
115328
|
const globalIds = new Set(globalSkills.map((skill) => skill.id));
|
|
@@ -115384,7 +115483,7 @@ async function handleValidate2(sourcePath) {
|
|
|
115384
115483
|
spinner.stop(`Checked ${skills.length} skill(s)`);
|
|
115385
115484
|
let hasIssues = false;
|
|
115386
115485
|
for (const skill of skills) {
|
|
115387
|
-
const skillMdPath =
|
|
115486
|
+
const skillMdPath = join155(skill.path, "SKILL.md");
|
|
115388
115487
|
try {
|
|
115389
115488
|
const content = await readFile68(skillMdPath, "utf-8");
|
|
115390
115489
|
const { data } = import_gray_matter12.default(content, {
|
|
@@ -115920,7 +116019,7 @@ init_skills_uninstaller();
|
|
|
115920
116019
|
// src/domains/installation/plugin/uninstall-plugin.ts
|
|
115921
116020
|
init_install_mode_detector();
|
|
115922
116021
|
import { existsSync as existsSync76, rmSync as rmSync6 } from "node:fs";
|
|
115923
|
-
import { join as
|
|
116022
|
+
import { join as join156 } from "node:path";
|
|
115924
116023
|
init_path_resolver();
|
|
115925
116024
|
async function uninstallEnginePlugin(opts = {}) {
|
|
115926
116025
|
const claudeDir3 = opts.claudeDir ?? PathResolver.getGlobalKitDir();
|
|
@@ -115934,7 +116033,7 @@ async function uninstallEnginePlugin(opts = {}) {
|
|
|
115934
116033
|
}
|
|
115935
116034
|
let staleCacheRemoved = false;
|
|
115936
116035
|
const marketplace = state.marketplace ?? CK_MARKETPLACE_NAME;
|
|
115937
|
-
const cacheDir =
|
|
116036
|
+
const cacheDir = join156(claudeDir3, "plugins", "cache", marketplace, CK_PLUGIN_NAME);
|
|
115938
116037
|
if (existsSync76(cacheDir)) {
|
|
115939
116038
|
rmSync6(cacheDir, { recursive: true, force: true });
|
|
115940
116039
|
staleCacheRemoved = true;
|
|
@@ -115992,16 +116091,16 @@ async function detectInstallations() {
|
|
|
115992
116091
|
|
|
115993
116092
|
// src/commands/uninstall/removal-handler.ts
|
|
115994
116093
|
import { readdirSync as readdirSync13, rmSync as rmSync8 } from "node:fs";
|
|
115995
|
-
import { basename as basename33, join as
|
|
116094
|
+
import { basename as basename33, join as join159, resolve as resolve56, sep as sep14 } from "node:path";
|
|
115996
116095
|
init_logger();
|
|
115997
116096
|
init_safe_prompts();
|
|
115998
116097
|
init_safe_spinner();
|
|
115999
|
-
var
|
|
116098
|
+
var import_fs_extra44 = __toESM(require_lib(), 1);
|
|
116000
116099
|
|
|
116001
116100
|
// src/commands/uninstall/analysis-handler.ts
|
|
116002
116101
|
init_metadata_migration();
|
|
116003
116102
|
import { readdirSync as readdirSync12, rmSync as rmSync7 } from "node:fs";
|
|
116004
|
-
import { dirname as dirname53, join as
|
|
116103
|
+
import { dirname as dirname53, join as join157 } from "node:path";
|
|
116005
116104
|
init_logger();
|
|
116006
116105
|
init_safe_prompts();
|
|
116007
116106
|
var import_fs_extra42 = __toESM(require_lib(), 1);
|
|
@@ -116061,7 +116160,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
116061
116160
|
const remainingFiles = metadata.kits?.[remainingKit]?.files || [];
|
|
116062
116161
|
for (const file of remainingFiles) {
|
|
116063
116162
|
const relativePath = normalizeTrackedPath(file.path);
|
|
116064
|
-
if (await import_fs_extra42.pathExists(
|
|
116163
|
+
if (await import_fs_extra42.pathExists(join157(installation.path, relativePath))) {
|
|
116065
116164
|
result.retainedManifestPaths.push(relativePath);
|
|
116066
116165
|
}
|
|
116067
116166
|
}
|
|
@@ -116069,7 +116168,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
116069
116168
|
const kitFiles = metadata.kits[kit].files || [];
|
|
116070
116169
|
for (const trackedFile of kitFiles) {
|
|
116071
116170
|
const relativePath = normalizeTrackedPath(trackedFile.path);
|
|
116072
|
-
const filePath =
|
|
116171
|
+
const filePath = join157(installation.path, relativePath);
|
|
116073
116172
|
if (preservedPaths.has(relativePath)) {
|
|
116074
116173
|
result.toPreserve.push({ path: relativePath, reason: "shared with other kit" });
|
|
116075
116174
|
continue;
|
|
@@ -116102,7 +116201,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
116102
116201
|
}
|
|
116103
116202
|
for (const trackedFile of allTrackedFiles) {
|
|
116104
116203
|
const relativePath = normalizeTrackedPath(trackedFile.path);
|
|
116105
|
-
const filePath =
|
|
116204
|
+
const filePath = join157(installation.path, relativePath);
|
|
116106
116205
|
const ownershipResult = await OwnershipChecker.checkOwnership(filePath, metadata, installation.path);
|
|
116107
116206
|
if (!ownershipResult.exists)
|
|
116108
116207
|
continue;
|
|
@@ -116148,10 +116247,170 @@ function displayDryRunPreview(analysis, installationType) {
|
|
|
116148
116247
|
}
|
|
116149
116248
|
}
|
|
116150
116249
|
|
|
116250
|
+
// src/commands/uninstall/settings-cleanup.ts
|
|
116251
|
+
init_settings_merger();
|
|
116252
|
+
init_command_normalizer();
|
|
116253
|
+
init_logger();
|
|
116254
|
+
var import_fs_extra43 = __toESM(require_lib(), 1);
|
|
116255
|
+
import { join as join158 } from "node:path";
|
|
116256
|
+
var CK_JSON_FILE2 = ".ck.json";
|
|
116257
|
+
var SETTINGS_FILE = "settings.json";
|
|
116258
|
+
var EMPTY_RESULT = {
|
|
116259
|
+
hooksRemoved: 0,
|
|
116260
|
+
mcpServersRemoved: 0,
|
|
116261
|
+
settingsFileRemoved: false,
|
|
116262
|
+
ckJsonRemoved: false
|
|
116263
|
+
};
|
|
116264
|
+
function resolveRemovalTargets(kits, removedKitNames, remainingKits) {
|
|
116265
|
+
const retainedHooks = new Set;
|
|
116266
|
+
const retainedServers = new Set;
|
|
116267
|
+
for (const remainingKit of remainingKits) {
|
|
116268
|
+
const installed = kits[remainingKit]?.installedSettings;
|
|
116269
|
+
for (const command of installed?.hooks ?? []) {
|
|
116270
|
+
const normalized = normalizeCommand(command);
|
|
116271
|
+
if (normalized)
|
|
116272
|
+
retainedHooks.add(normalized);
|
|
116273
|
+
}
|
|
116274
|
+
for (const server of installed?.mcpServers ?? []) {
|
|
116275
|
+
retainedServers.add(server);
|
|
116276
|
+
}
|
|
116277
|
+
}
|
|
116278
|
+
const hooks = new Set;
|
|
116279
|
+
const servers = new Set;
|
|
116280
|
+
for (const kitName of removedKitNames) {
|
|
116281
|
+
const installed = kits[kitName]?.installedSettings;
|
|
116282
|
+
for (const command of installed?.hooks ?? []) {
|
|
116283
|
+
const normalized = normalizeCommand(command);
|
|
116284
|
+
if (normalized && !retainedHooks.has(normalized))
|
|
116285
|
+
hooks.add(normalized);
|
|
116286
|
+
}
|
|
116287
|
+
for (const server of installed?.mcpServers ?? []) {
|
|
116288
|
+
if (!retainedServers.has(server))
|
|
116289
|
+
servers.add(server);
|
|
116290
|
+
}
|
|
116291
|
+
}
|
|
116292
|
+
return { hooks, servers };
|
|
116293
|
+
}
|
|
116294
|
+
function removeHooksFromSettings(settings, normalizedToRemove) {
|
|
116295
|
+
if (!settings.hooks || normalizedToRemove.size === 0)
|
|
116296
|
+
return 0;
|
|
116297
|
+
let removed = 0;
|
|
116298
|
+
const eventKeysToDelete = [];
|
|
116299
|
+
for (const [eventName, entries] of Object.entries(settings.hooks)) {
|
|
116300
|
+
const keptEntries = [];
|
|
116301
|
+
for (const entry of entries) {
|
|
116302
|
+
if (Array.isArray(entry.hooks)) {
|
|
116303
|
+
const keptHooks = entry.hooks.filter((hook) => {
|
|
116304
|
+
if (typeof hook.command === "string" && normalizedToRemove.has(normalizeCommand(hook.command))) {
|
|
116305
|
+
removed++;
|
|
116306
|
+
return false;
|
|
116307
|
+
}
|
|
116308
|
+
return true;
|
|
116309
|
+
});
|
|
116310
|
+
if (keptHooks.length > 0) {
|
|
116311
|
+
keptEntries.push({ ...entry, hooks: keptHooks });
|
|
116312
|
+
}
|
|
116313
|
+
continue;
|
|
116314
|
+
}
|
|
116315
|
+
if (typeof entry.command === "string" && normalizedToRemove.has(normalizeCommand(entry.command))) {
|
|
116316
|
+
removed++;
|
|
116317
|
+
continue;
|
|
116318
|
+
}
|
|
116319
|
+
keptEntries.push(entry);
|
|
116320
|
+
}
|
|
116321
|
+
if (keptEntries.length > 0) {
|
|
116322
|
+
settings.hooks[eventName] = keptEntries;
|
|
116323
|
+
} else {
|
|
116324
|
+
eventKeysToDelete.push(eventName);
|
|
116325
|
+
}
|
|
116326
|
+
}
|
|
116327
|
+
for (const eventName of eventKeysToDelete) {
|
|
116328
|
+
delete settings.hooks[eventName];
|
|
116329
|
+
}
|
|
116330
|
+
if (Object.keys(settings.hooks).length === 0) {
|
|
116331
|
+
Reflect.deleteProperty(settings, "hooks");
|
|
116332
|
+
}
|
|
116333
|
+
return removed;
|
|
116334
|
+
}
|
|
116335
|
+
function removeMcpServersFromSettings(settings, serversToRemove) {
|
|
116336
|
+
const servers = settings.mcp?.servers;
|
|
116337
|
+
if (!servers || serversToRemove.size === 0)
|
|
116338
|
+
return 0;
|
|
116339
|
+
let removed = 0;
|
|
116340
|
+
for (const name2 of serversToRemove) {
|
|
116341
|
+
if (Object.hasOwn(servers, name2)) {
|
|
116342
|
+
delete servers[name2];
|
|
116343
|
+
removed++;
|
|
116344
|
+
}
|
|
116345
|
+
}
|
|
116346
|
+
if (removed > 0 && settings.mcp) {
|
|
116347
|
+
if (Object.keys(servers).length === 0) {
|
|
116348
|
+
Reflect.deleteProperty(settings.mcp, "servers");
|
|
116349
|
+
}
|
|
116350
|
+
if (Object.keys(settings.mcp).length === 0) {
|
|
116351
|
+
Reflect.deleteProperty(settings, "mcp");
|
|
116352
|
+
}
|
|
116353
|
+
}
|
|
116354
|
+
return removed;
|
|
116355
|
+
}
|
|
116356
|
+
async function cleanupCkJson(ckJsonPath, data, removedKitNames, dryRun) {
|
|
116357
|
+
if (!data.kits)
|
|
116358
|
+
return false;
|
|
116359
|
+
for (const kitName of removedKitNames) {
|
|
116360
|
+
delete data.kits[kitName];
|
|
116361
|
+
}
|
|
116362
|
+
const noKitsLeft = Object.keys(data.kits).length === 0;
|
|
116363
|
+
const otherTopLevelKeys = Object.keys(data).filter((key) => key !== "kits");
|
|
116364
|
+
if (dryRun)
|
|
116365
|
+
return noKitsLeft && otherTopLevelKeys.length === 0;
|
|
116366
|
+
if (noKitsLeft && otherTopLevelKeys.length === 0) {
|
|
116367
|
+
await import_fs_extra43.remove(ckJsonPath);
|
|
116368
|
+
return true;
|
|
116369
|
+
}
|
|
116370
|
+
if (noKitsLeft) {
|
|
116371
|
+
Reflect.deleteProperty(data, "kits");
|
|
116372
|
+
}
|
|
116373
|
+
await import_fs_extra43.writeFile(ckJsonPath, JSON.stringify(data, null, 2), "utf-8");
|
|
116374
|
+
return false;
|
|
116375
|
+
}
|
|
116376
|
+
async function cleanupUninstalledSettings(installationPath, options2) {
|
|
116377
|
+
const ckJsonPath = join158(installationPath, CK_JSON_FILE2);
|
|
116378
|
+
if (!await import_fs_extra43.pathExists(ckJsonPath)) {
|
|
116379
|
+
return { ...EMPTY_RESULT };
|
|
116380
|
+
}
|
|
116381
|
+
let data;
|
|
116382
|
+
try {
|
|
116383
|
+
data = parseJsonContent(await import_fs_extra43.readFile(ckJsonPath, "utf-8"));
|
|
116384
|
+
} catch (error) {
|
|
116385
|
+
logger.debug(`Settings cleanup: failed to parse ${ckJsonPath}: ${error instanceof Error ? error.message : "unknown error"}`);
|
|
116386
|
+
return { ...EMPTY_RESULT };
|
|
116387
|
+
}
|
|
116388
|
+
const kits = data.kits ?? {};
|
|
116389
|
+
const removedKitNames = options2.kit ? [options2.kit] : Object.keys(kits);
|
|
116390
|
+
const { hooks, servers } = resolveRemovalTargets(kits, removedKitNames, options2.remainingKits);
|
|
116391
|
+
const result = { ...EMPTY_RESULT };
|
|
116392
|
+
const settingsPath = join158(installationPath, SETTINGS_FILE);
|
|
116393
|
+
const settings = await SettingsMerger.readSettingsFile(settingsPath);
|
|
116394
|
+
if (settings) {
|
|
116395
|
+
result.hooksRemoved = removeHooksFromSettings(settings, hooks);
|
|
116396
|
+
result.mcpServersRemoved = removeMcpServersFromSettings(settings, servers);
|
|
116397
|
+
if (!options2.dryRun && (result.hooksRemoved > 0 || result.mcpServersRemoved > 0)) {
|
|
116398
|
+
if (Object.keys(settings).length === 0) {
|
|
116399
|
+
await import_fs_extra43.remove(settingsPath);
|
|
116400
|
+
result.settingsFileRemoved = true;
|
|
116401
|
+
} else {
|
|
116402
|
+
await SettingsMerger.writeSettingsFile(settingsPath, settings);
|
|
116403
|
+
}
|
|
116404
|
+
}
|
|
116405
|
+
}
|
|
116406
|
+
result.ckJsonRemoved = await cleanupCkJson(ckJsonPath, data, removedKitNames, options2.dryRun ?? false);
|
|
116407
|
+
return result;
|
|
116408
|
+
}
|
|
116409
|
+
|
|
116151
116410
|
// src/commands/uninstall/removal-handler.ts
|
|
116152
116411
|
async function isDirectory2(filePath) {
|
|
116153
116412
|
try {
|
|
116154
|
-
const stats = await
|
|
116413
|
+
const stats = await import_fs_extra44.lstat(filePath);
|
|
116155
116414
|
return stats.isDirectory();
|
|
116156
116415
|
} catch {
|
|
116157
116416
|
logger.debug(`Failed to check if path is directory: ${filePath}`);
|
|
@@ -116159,10 +116418,30 @@ async function isDirectory2(filePath) {
|
|
|
116159
116418
|
}
|
|
116160
116419
|
}
|
|
116161
116420
|
function getUninstallMutatePaths(options2) {
|
|
116421
|
+
const paths = [];
|
|
116162
116422
|
if (options2.retainedManifestPaths.length > 0) {
|
|
116163
|
-
|
|
116423
|
+
paths.push("metadata.json");
|
|
116164
116424
|
}
|
|
116165
|
-
|
|
116425
|
+
if (options2.settingsFileExists) {
|
|
116426
|
+
paths.push("settings.json");
|
|
116427
|
+
}
|
|
116428
|
+
if (options2.ckJsonExists) {
|
|
116429
|
+
paths.push(".ck.json");
|
|
116430
|
+
}
|
|
116431
|
+
return paths;
|
|
116432
|
+
}
|
|
116433
|
+
function logSettingsCleanup(result, dryRun) {
|
|
116434
|
+
if (result.hooksRemoved === 0 && result.mcpServersRemoved === 0)
|
|
116435
|
+
return;
|
|
116436
|
+
const parts = [];
|
|
116437
|
+
if (result.hooksRemoved > 0) {
|
|
116438
|
+
parts.push(`${result.hooksRemoved} hook${result.hooksRemoved === 1 ? "" : "s"}`);
|
|
116439
|
+
}
|
|
116440
|
+
if (result.mcpServersRemoved > 0) {
|
|
116441
|
+
parts.push(`${result.mcpServersRemoved} MCP server${result.mcpServersRemoved === 1 ? "" : "s"}`);
|
|
116442
|
+
}
|
|
116443
|
+
const verb = dryRun ? "Would remove" : "Removed";
|
|
116444
|
+
log.info(`${verb} ${parts.join(" and ")} from settings.json`);
|
|
116166
116445
|
}
|
|
116167
116446
|
async function restoreUninstallBackup(backup) {
|
|
116168
116447
|
const restoreSpinner = createSpinner("Restoring installation from recovery backup...").start();
|
|
@@ -116178,15 +116457,15 @@ async function isPathSafeToRemove(filePath, baseDir) {
|
|
|
116178
116457
|
try {
|
|
116179
116458
|
const resolvedPath = resolve56(filePath);
|
|
116180
116459
|
const resolvedBase = resolve56(baseDir);
|
|
116181
|
-
if (!resolvedPath.startsWith(resolvedBase +
|
|
116460
|
+
if (!resolvedPath.startsWith(resolvedBase + sep14) && resolvedPath !== resolvedBase) {
|
|
116182
116461
|
logger.debug(`Path outside installation directory: ${filePath}`);
|
|
116183
116462
|
return false;
|
|
116184
116463
|
}
|
|
116185
|
-
const stats = await
|
|
116464
|
+
const stats = await import_fs_extra44.lstat(filePath);
|
|
116186
116465
|
if (stats.isSymbolicLink()) {
|
|
116187
|
-
const realPath = await
|
|
116466
|
+
const realPath = await import_fs_extra44.realpath(filePath);
|
|
116188
116467
|
const resolvedReal = resolve56(realPath);
|
|
116189
|
-
if (!resolvedReal.startsWith(resolvedBase +
|
|
116468
|
+
if (!resolvedReal.startsWith(resolvedBase + sep14) && resolvedReal !== resolvedBase) {
|
|
116190
116469
|
logger.debug(`Symlink points outside installation directory: ${filePath} -> ${realPath}`);
|
|
116191
116470
|
return false;
|
|
116192
116471
|
}
|
|
@@ -116208,6 +116487,12 @@ async function removeInstallations(installations, options2) {
|
|
|
116208
116487
|
const label = options2.kit ? `${installation.type} (${options2.kit} kit)` : installation.type;
|
|
116209
116488
|
const legacyLabel2 = !installation.hasMetadata ? " [legacy]" : "";
|
|
116210
116489
|
displayDryRunPreview(analysis, `${label}${legacyLabel2}`);
|
|
116490
|
+
const settingsPreview = await cleanupUninstalledSettings(installation.path, {
|
|
116491
|
+
kit: options2.kit,
|
|
116492
|
+
remainingKits: analysis.remainingKits,
|
|
116493
|
+
dryRun: true
|
|
116494
|
+
});
|
|
116495
|
+
logSettingsCleanup(settingsPreview, true);
|
|
116211
116496
|
if (analysis.remainingKits.length > 0) {
|
|
116212
116497
|
log.info(`Remaining kits after uninstall: ${analysis.remainingKits.join(", ")}`);
|
|
116213
116498
|
}
|
|
@@ -116217,7 +116502,9 @@ async function removeInstallations(installations, options2) {
|
|
|
116217
116502
|
continue;
|
|
116218
116503
|
}
|
|
116219
116504
|
const mutatePaths = getUninstallMutatePaths({
|
|
116220
|
-
retainedManifestPaths: analysis.retainedManifestPaths
|
|
116505
|
+
retainedManifestPaths: analysis.retainedManifestPaths,
|
|
116506
|
+
settingsFileExists: await import_fs_extra44.pathExists(join159(installation.path, "settings.json")),
|
|
116507
|
+
ckJsonExists: await import_fs_extra44.pathExists(join159(installation.path, ".ck.json"))
|
|
116221
116508
|
});
|
|
116222
116509
|
let backup = null;
|
|
116223
116510
|
if (analysis.toDelete.length > 0 || mutatePaths.length > 0) {
|
|
@@ -116245,15 +116532,15 @@ async function removeInstallations(installations, options2) {
|
|
|
116245
116532
|
let removedCount = 0;
|
|
116246
116533
|
let cleanedDirs = 0;
|
|
116247
116534
|
for (const item of analysis.toDelete) {
|
|
116248
|
-
const filePath =
|
|
116249
|
-
if (!await
|
|
116535
|
+
const filePath = join159(installation.path, item.path);
|
|
116536
|
+
if (!await import_fs_extra44.pathExists(filePath))
|
|
116250
116537
|
continue;
|
|
116251
116538
|
if (!await isPathSafeToRemove(filePath, installation.path)) {
|
|
116252
116539
|
logger.debug(`Skipping unsafe path: ${item.path}`);
|
|
116253
116540
|
continue;
|
|
116254
116541
|
}
|
|
116255
116542
|
const isDir2 = await isDirectory2(filePath);
|
|
116256
|
-
await
|
|
116543
|
+
await import_fs_extra44.remove(filePath);
|
|
116257
116544
|
removedCount++;
|
|
116258
116545
|
logger.debug(`Removed ${isDir2 ? "directory" : "file"}: ${item.path}`);
|
|
116259
116546
|
if (!isDir2) {
|
|
@@ -116269,6 +116556,11 @@ async function removeInstallations(installations, options2) {
|
|
|
116269
116556
|
throw new Error("Failed to update metadata.json after partial uninstall");
|
|
116270
116557
|
}
|
|
116271
116558
|
}
|
|
116559
|
+
const settingsCleanup = await cleanupUninstalledSettings(installation.path, {
|
|
116560
|
+
kit: options2.kit,
|
|
116561
|
+
remainingKits: analysis.remainingKits
|
|
116562
|
+
});
|
|
116563
|
+
logSettingsCleanup(settingsCleanup, false);
|
|
116272
116564
|
try {
|
|
116273
116565
|
const remaining = readdirSync13(installation.path);
|
|
116274
116566
|
if (remaining.length === 0) {
|
|
@@ -116667,7 +116959,7 @@ ${import_picocolors40.default.bold(import_picocolors40.default.cyan(result.kitCo
|
|
|
116667
116959
|
init_logger();
|
|
116668
116960
|
import { existsSync as existsSync82 } from "node:fs";
|
|
116669
116961
|
import { rm as rm19 } from "node:fs/promises";
|
|
116670
|
-
import { join as
|
|
116962
|
+
import { join as join166 } from "node:path";
|
|
116671
116963
|
var import_picocolors41 = __toESM(require_picocolors(), 1);
|
|
116672
116964
|
|
|
116673
116965
|
// src/commands/watch/phases/implementation-runner.ts
|
|
@@ -117185,8 +117477,8 @@ function spawnAndCollect3(command, args) {
|
|
|
117185
117477
|
}
|
|
117186
117478
|
|
|
117187
117479
|
// src/commands/watch/phases/issue-processor.ts
|
|
117188
|
-
import { mkdir as mkdir40, writeFile as
|
|
117189
|
-
import { join as
|
|
117480
|
+
import { mkdir as mkdir40, writeFile as writeFile42 } from "node:fs/promises";
|
|
117481
|
+
import { join as join162 } from "node:path";
|
|
117190
117482
|
|
|
117191
117483
|
// src/commands/watch/phases/approval-detector.ts
|
|
117192
117484
|
init_logger();
|
|
@@ -117564,9 +117856,9 @@ async function checkAwaitingApproval(state, setup, options2, watchLog, projectDi
|
|
|
117564
117856
|
|
|
117565
117857
|
// src/commands/watch/phases/plan-dir-finder.ts
|
|
117566
117858
|
import { readdir as readdir46, stat as stat24 } from "node:fs/promises";
|
|
117567
|
-
import { join as
|
|
117859
|
+
import { join as join161 } from "node:path";
|
|
117568
117860
|
async function findRecentPlanDir(cwd2, issueNumber, watchLog) {
|
|
117569
|
-
const plansRoot =
|
|
117861
|
+
const plansRoot = join161(cwd2, "plans");
|
|
117570
117862
|
try {
|
|
117571
117863
|
const entries = await readdir46(plansRoot);
|
|
117572
117864
|
const tenMinAgo = Date.now() - 10 * 60 * 1000;
|
|
@@ -117575,14 +117867,14 @@ async function findRecentPlanDir(cwd2, issueNumber, watchLog) {
|
|
|
117575
117867
|
for (const entry of entries) {
|
|
117576
117868
|
if (entry === "watch" || entry === "reports" || entry === "visuals")
|
|
117577
117869
|
continue;
|
|
117578
|
-
const dirPath =
|
|
117870
|
+
const dirPath = join161(plansRoot, entry);
|
|
117579
117871
|
const dirStat = await stat24(dirPath);
|
|
117580
117872
|
if (!dirStat.isDirectory())
|
|
117581
117873
|
continue;
|
|
117582
117874
|
if (dirStat.mtimeMs < tenMinAgo)
|
|
117583
117875
|
continue;
|
|
117584
117876
|
try {
|
|
117585
|
-
await stat24(
|
|
117877
|
+
await stat24(join161(dirPath, "plan.md"));
|
|
117586
117878
|
} catch {
|
|
117587
117879
|
continue;
|
|
117588
117880
|
}
|
|
@@ -117813,14 +118105,14 @@ async function handlePlanGeneration(issue, state, config, setup, options2, watch
|
|
|
117813
118105
|
stats.plansCreated++;
|
|
117814
118106
|
const detectedPlanDir = await findRecentPlanDir(projectDir, issue.number, watchLog);
|
|
117815
118107
|
if (detectedPlanDir) {
|
|
117816
|
-
state.activeIssues[numStr].planPath =
|
|
118108
|
+
state.activeIssues[numStr].planPath = join162(detectedPlanDir, "plan.md");
|
|
117817
118109
|
watchLog.info(`Plan directory detected: ${detectedPlanDir}`);
|
|
117818
118110
|
} else {
|
|
117819
118111
|
try {
|
|
117820
|
-
const planDir =
|
|
118112
|
+
const planDir = join162(projectDir, "plans", "watch");
|
|
117821
118113
|
await mkdir40(planDir, { recursive: true });
|
|
117822
|
-
const planFilePath =
|
|
117823
|
-
await
|
|
118114
|
+
const planFilePath = join162(planDir, `issue-${issue.number}-plan.md`);
|
|
118115
|
+
await writeFile42(planFilePath, planResult.planText, "utf-8");
|
|
117824
118116
|
state.activeIssues[numStr].planPath = planFilePath;
|
|
117825
118117
|
watchLog.info(`Plan saved (fallback) to ${planFilePath}`);
|
|
117826
118118
|
} catch (err) {
|
|
@@ -117965,7 +118257,7 @@ init_ck_config_manager();
|
|
|
117965
118257
|
init_file_io();
|
|
117966
118258
|
init_logger();
|
|
117967
118259
|
import { existsSync as existsSync78 } from "node:fs";
|
|
117968
|
-
import { mkdir as mkdir41, readFile as
|
|
118260
|
+
import { mkdir as mkdir41, readFile as readFile71 } from "node:fs/promises";
|
|
117969
118261
|
import { dirname as dirname54 } from "node:path";
|
|
117970
118262
|
var PROCESSED_ISSUES_CAP = 500;
|
|
117971
118263
|
async function readCkJson(projectDir) {
|
|
@@ -117973,7 +118265,7 @@ async function readCkJson(projectDir) {
|
|
|
117973
118265
|
try {
|
|
117974
118266
|
if (!existsSync78(configPath))
|
|
117975
118267
|
return {};
|
|
117976
|
-
const content = await
|
|
118268
|
+
const content = await readFile71(configPath, "utf-8");
|
|
117977
118269
|
return JSON.parse(content);
|
|
117978
118270
|
} catch (error) {
|
|
117979
118271
|
logger.warning(`Failed to parse .ck.json: ${error instanceof Error ? error.message : "Unknown"}`);
|
|
@@ -118126,18 +118418,18 @@ init_logger();
|
|
|
118126
118418
|
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
118127
118419
|
import { existsSync as existsSync79 } from "node:fs";
|
|
118128
118420
|
import { readdir as readdir47, stat as stat25 } from "node:fs/promises";
|
|
118129
|
-
import { join as
|
|
118421
|
+
import { join as join163 } from "node:path";
|
|
118130
118422
|
async function scanForRepos(parentDir) {
|
|
118131
118423
|
const repos = [];
|
|
118132
118424
|
const entries = await readdir47(parentDir);
|
|
118133
118425
|
for (const entry of entries) {
|
|
118134
118426
|
if (entry.startsWith("."))
|
|
118135
118427
|
continue;
|
|
118136
|
-
const fullPath =
|
|
118428
|
+
const fullPath = join163(parentDir, entry);
|
|
118137
118429
|
const entryStat = await stat25(fullPath);
|
|
118138
118430
|
if (!entryStat.isDirectory())
|
|
118139
118431
|
continue;
|
|
118140
|
-
const gitDir =
|
|
118432
|
+
const gitDir = join163(fullPath, ".git");
|
|
118141
118433
|
if (!existsSync79(gitDir))
|
|
118142
118434
|
continue;
|
|
118143
118435
|
const result = spawnSync7("gh", ["repo", "view", "--json", "owner,name"], {
|
|
@@ -118164,7 +118456,7 @@ init_logger();
|
|
|
118164
118456
|
import { spawnSync as spawnSync8 } from "node:child_process";
|
|
118165
118457
|
import { existsSync as existsSync80 } from "node:fs";
|
|
118166
118458
|
import { homedir as homedir53 } from "node:os";
|
|
118167
|
-
import { join as
|
|
118459
|
+
import { join as join164 } from "node:path";
|
|
118168
118460
|
async function validateSetup(cwd2) {
|
|
118169
118461
|
const workDir = cwd2 ?? process.cwd();
|
|
118170
118462
|
const ghVersion = spawnSync8("gh", ["--version"], { encoding: "utf-8", timeout: 1e4 });
|
|
@@ -118195,7 +118487,7 @@ Run this command from a directory with a GitHub remote.`);
|
|
|
118195
118487
|
} catch {
|
|
118196
118488
|
throw new Error(`Failed to parse repository info: ${ghRepo.stdout}`);
|
|
118197
118489
|
}
|
|
118198
|
-
const skillsPath =
|
|
118490
|
+
const skillsPath = join164(homedir53(), ".claude", "skills");
|
|
118199
118491
|
const skillsAvailable = existsSync80(skillsPath);
|
|
118200
118492
|
if (!skillsAvailable) {
|
|
118201
118493
|
logger.warning(`ClaudeKit Engineer skills not found at ${skillsPath}`);
|
|
@@ -118214,7 +118506,7 @@ init_path_resolver();
|
|
|
118214
118506
|
import { createWriteStream as createWriteStream3, statSync as statSync14 } from "node:fs";
|
|
118215
118507
|
import { existsSync as existsSync81 } from "node:fs";
|
|
118216
118508
|
import { mkdir as mkdir42, rename as rename15 } from "node:fs/promises";
|
|
118217
|
-
import { join as
|
|
118509
|
+
import { join as join165 } from "node:path";
|
|
118218
118510
|
|
|
118219
118511
|
class WatchLogger {
|
|
118220
118512
|
logStream = null;
|
|
@@ -118222,7 +118514,7 @@ class WatchLogger {
|
|
|
118222
118514
|
logPath = null;
|
|
118223
118515
|
maxBytes;
|
|
118224
118516
|
constructor(logDir, maxBytes = 0) {
|
|
118225
|
-
this.logDir = logDir ??
|
|
118517
|
+
this.logDir = logDir ?? join165(PathResolver.getClaudeKitDir(), "logs");
|
|
118226
118518
|
this.maxBytes = maxBytes;
|
|
118227
118519
|
}
|
|
118228
118520
|
async init() {
|
|
@@ -118231,7 +118523,7 @@ class WatchLogger {
|
|
|
118231
118523
|
await mkdir42(this.logDir, { recursive: true });
|
|
118232
118524
|
}
|
|
118233
118525
|
const dateStr = formatDate(new Date);
|
|
118234
|
-
this.logPath =
|
|
118526
|
+
this.logPath = join165(this.logDir, `watch-${dateStr}.log`);
|
|
118235
118527
|
this.logStream = createWriteStream3(this.logPath, { flags: "a", mode: 384 });
|
|
118236
118528
|
} catch (error) {
|
|
118237
118529
|
logger.warning(`Cannot create watch log file: ${error instanceof Error ? error.message : "Unknown"}`);
|
|
@@ -118413,7 +118705,7 @@ async function watchCommand(options2) {
|
|
|
118413
118705
|
}
|
|
118414
118706
|
async function discoverRepos(options2, watchLog) {
|
|
118415
118707
|
const cwd2 = process.cwd();
|
|
118416
|
-
const isGitRepo = existsSync82(
|
|
118708
|
+
const isGitRepo = existsSync82(join166(cwd2, ".git"));
|
|
118417
118709
|
if (options2.force) {
|
|
118418
118710
|
await forceRemoveLock(watchLog);
|
|
118419
118711
|
}
|
|
@@ -118671,7 +118963,7 @@ function registerCommands(cli) {
|
|
|
118671
118963
|
init_package();
|
|
118672
118964
|
init_config_version_checker();
|
|
118673
118965
|
import { existsSync as existsSync94, readFileSync as readFileSync26 } from "node:fs";
|
|
118674
|
-
import { join as
|
|
118966
|
+
import { join as join178 } from "node:path";
|
|
118675
118967
|
|
|
118676
118968
|
// src/domains/versioning/version-checker.ts
|
|
118677
118969
|
init_version_utils();
|
|
@@ -118685,15 +118977,15 @@ init_types3();
|
|
|
118685
118977
|
init_logger();
|
|
118686
118978
|
init_path_resolver();
|
|
118687
118979
|
import { existsSync as existsSync93 } from "node:fs";
|
|
118688
|
-
import { mkdir as mkdir43, readFile as
|
|
118689
|
-
import { join as
|
|
118980
|
+
import { mkdir as mkdir43, readFile as readFile73, writeFile as writeFile45 } from "node:fs/promises";
|
|
118981
|
+
import { join as join177 } from "node:path";
|
|
118690
118982
|
|
|
118691
118983
|
class VersionCacheManager {
|
|
118692
118984
|
static CACHE_FILENAME = "version-check.json";
|
|
118693
118985
|
static CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000;
|
|
118694
118986
|
static getCacheFile() {
|
|
118695
118987
|
const cacheDir = PathResolver.getCacheDir(false);
|
|
118696
|
-
return
|
|
118988
|
+
return join177(cacheDir, VersionCacheManager.CACHE_FILENAME);
|
|
118697
118989
|
}
|
|
118698
118990
|
static async load() {
|
|
118699
118991
|
const cacheFile = VersionCacheManager.getCacheFile();
|
|
@@ -118702,7 +118994,7 @@ class VersionCacheManager {
|
|
|
118702
118994
|
logger.debug("Version check cache not found");
|
|
118703
118995
|
return null;
|
|
118704
118996
|
}
|
|
118705
|
-
const content = await
|
|
118997
|
+
const content = await readFile73(cacheFile, "utf-8");
|
|
118706
118998
|
const cache5 = JSON.parse(content);
|
|
118707
118999
|
if (!cache5.lastCheck || !cache5.currentVersion || !cache5.latestVersion) {
|
|
118708
119000
|
logger.debug("Invalid cache structure, ignoring");
|
|
@@ -118722,7 +119014,7 @@ class VersionCacheManager {
|
|
|
118722
119014
|
if (!existsSync93(cacheDir)) {
|
|
118723
119015
|
await mkdir43(cacheDir, { recursive: true, mode: 448 });
|
|
118724
119016
|
}
|
|
118725
|
-
await
|
|
119017
|
+
await writeFile45(cacheFile, JSON.stringify(cache5, null, 2), "utf-8");
|
|
118726
119018
|
logger.debug(`Version check cache saved to ${cacheFile}`);
|
|
118727
119019
|
} catch (error) {
|
|
118728
119020
|
logger.debug(`Failed to save version check cache: ${error}`);
|
|
@@ -119004,9 +119296,9 @@ async function displayVersion() {
|
|
|
119004
119296
|
let localInstalledKits = [];
|
|
119005
119297
|
let globalInstalledKits = [];
|
|
119006
119298
|
const globalKitDir = PathResolver.getGlobalKitDir();
|
|
119007
|
-
const globalMetadataPath =
|
|
119299
|
+
const globalMetadataPath = join178(globalKitDir, "metadata.json");
|
|
119008
119300
|
const prefix = PathResolver.getPathPrefix(false);
|
|
119009
|
-
const localMetadataPath = prefix ?
|
|
119301
|
+
const localMetadataPath = prefix ? join178(process.cwd(), prefix, "metadata.json") : join178(process.cwd(), "metadata.json");
|
|
119010
119302
|
const isLocalSameAsGlobal = localMetadataPath === globalMetadataPath;
|
|
119011
119303
|
if (!isLocalSameAsGlobal && existsSync94(localMetadataPath)) {
|
|
119012
119304
|
try {
|
|
@@ -119394,7 +119686,7 @@ var output2 = new OutputManager2;
|
|
|
119394
119686
|
|
|
119395
119687
|
// src/shared/temp-cleanup.ts
|
|
119396
119688
|
init_logger();
|
|
119397
|
-
var
|
|
119689
|
+
var import_fs_extra45 = __toESM(require_lib(), 1);
|
|
119398
119690
|
import { rmSync as rmSync9 } from "node:fs";
|
|
119399
119691
|
var tempDirs2 = new Set;
|
|
119400
119692
|
async function cleanup() {
|
|
@@ -119403,7 +119695,7 @@ async function cleanup() {
|
|
|
119403
119695
|
logger.debug(`Cleaning up ${tempDirs2.size} temporary director(ies)...`);
|
|
119404
119696
|
for (const dir of tempDirs2) {
|
|
119405
119697
|
try {
|
|
119406
|
-
await
|
|
119698
|
+
await import_fs_extra45.remove(dir);
|
|
119407
119699
|
logger.debug(`Cleaned up temp directory: ${dir}`);
|
|
119408
119700
|
} catch (error) {
|
|
119409
119701
|
logger.debug(`Failed to clean temp directory ${dir}: ${error}`);
|