claudekit-cli 3.41.3-dev.1 → 3.41.3-dev.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1035 -716
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -44763,10 +44763,69 @@ function notFoundError(type, name, hint) {
|
|
|
44763
44763
|
}
|
|
44764
44764
|
|
|
44765
44765
|
// src/shared/command-normalizer.ts
|
|
44766
|
+
import { homedir as homedir12 } from "node:os";
|
|
44767
|
+
import { join as join20 } from "node:path";
|
|
44768
|
+
function escapeRegex(value) {
|
|
44769
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
44770
|
+
}
|
|
44771
|
+
function normalizeCommandRoot(root) {
|
|
44772
|
+
return root.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
44773
|
+
}
|
|
44774
|
+
function formatCanonicalClaudeCommand(nodePrefix, root, relativePath, suffix = "") {
|
|
44775
|
+
const normalizedRoot = normalizeCommandRoot(root);
|
|
44776
|
+
let normalizedRelativePath = relativePath.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
44777
|
+
if (normalizedRoot !== "$HOME" && normalizedRoot !== "$CLAUDE_PROJECT_DIR") {
|
|
44778
|
+
normalizedRelativePath = normalizedRelativePath.replace(/^\.claude\//, "");
|
|
44779
|
+
}
|
|
44780
|
+
return normalizedRoot === "$CLAUDE_PROJECT_DIR" ? `${nodePrefix}"${normalizedRoot}"/${normalizedRelativePath}${suffix}` : `${nodePrefix}"${normalizedRoot}/${normalizedRelativePath}"${suffix}`;
|
|
44781
|
+
}
|
|
44782
|
+
function isNodeClaudeCommand(cmd) {
|
|
44783
|
+
if (!cmd)
|
|
44784
|
+
return false;
|
|
44785
|
+
return /^\s*node\s+/.test(cmd) && (cmd.includes(".claude/") || cmd.includes(".claude\\"));
|
|
44786
|
+
}
|
|
44787
|
+
function repairClaudeNodeCommandPath(cmd, root) {
|
|
44788
|
+
if (!cmd || !isNodeClaudeCommand(cmd)) {
|
|
44789
|
+
return { command: cmd ?? "", changed: false, issue: null };
|
|
44790
|
+
}
|
|
44791
|
+
const bareRelativeMatch = cmd.match(/^(node\s+)(?:\.\/)?(\.claude[/\\][^\s"]+)(.*)$/);
|
|
44792
|
+
if (bareRelativeMatch) {
|
|
44793
|
+
const [, nodePrefix, relativePath, suffix] = bareRelativeMatch;
|
|
44794
|
+
const command = formatCanonicalClaudeCommand(nodePrefix, root, relativePath, suffix);
|
|
44795
|
+
return { command, changed: command !== cmd, issue: "raw-relative" };
|
|
44796
|
+
}
|
|
44797
|
+
const embeddedQuotedMatch = cmd.match(/^(node\s+)"(?:\$HOME|\$CLAUDE_PROJECT_DIR|%USERPROFILE%|%CLAUDE_PROJECT_DIR%)[/\\](\.claude[/\\][^"]+)"(.*)$/);
|
|
44798
|
+
if (embeddedQuotedMatch) {
|
|
44799
|
+
const [, nodePrefix, relativePath, suffix] = embeddedQuotedMatch;
|
|
44800
|
+
const command = formatCanonicalClaudeCommand(nodePrefix, root, relativePath, suffix);
|
|
44801
|
+
return { command, changed: command !== cmd, issue: "invalid-format" };
|
|
44802
|
+
}
|
|
44803
|
+
const varOnlyQuotedMatch = cmd.match(/^(node\s+)"(?:\$HOME|\$CLAUDE_PROJECT_DIR|%USERPROFILE%|%CLAUDE_PROJECT_DIR%)"[/\\](\.claude[/\\][^\s"]+)(.*)$/);
|
|
44804
|
+
if (varOnlyQuotedMatch) {
|
|
44805
|
+
const [, nodePrefix, relativePath, suffix] = varOnlyQuotedMatch;
|
|
44806
|
+
const command = formatCanonicalClaudeCommand(nodePrefix, root, relativePath, suffix);
|
|
44807
|
+
return { command, changed: command !== cmd, issue: "invalid-format" };
|
|
44808
|
+
}
|
|
44809
|
+
const tildeMatch = cmd.match(/^(node\s+)~[/\\](\.claude[/\\][^\s"]+)(.*)$/);
|
|
44810
|
+
if (tildeMatch) {
|
|
44811
|
+
const [, nodePrefix, relativePath, suffix] = tildeMatch;
|
|
44812
|
+
const command = formatCanonicalClaudeCommand(nodePrefix, root, relativePath, suffix);
|
|
44813
|
+
return { command, changed: command !== cmd, issue: "invalid-format" };
|
|
44814
|
+
}
|
|
44815
|
+
const unquotedMatch = cmd.match(/^(node\s+)(?:\$HOME|\$CLAUDE_PROJECT_DIR|%USERPROFILE%|%CLAUDE_PROJECT_DIR%)[/\\](\.claude[/\\][^\s"]+)(.*)$/);
|
|
44816
|
+
if (unquotedMatch) {
|
|
44817
|
+
const [, nodePrefix, relativePath, suffix] = unquotedMatch;
|
|
44818
|
+
const command = formatCanonicalClaudeCommand(nodePrefix, root, relativePath, suffix);
|
|
44819
|
+
return { command, changed: command !== cmd, issue: "invalid-format" };
|
|
44820
|
+
}
|
|
44821
|
+
return { command: cmd, changed: false, issue: null };
|
|
44822
|
+
}
|
|
44766
44823
|
function normalizeCommand(cmd) {
|
|
44767
44824
|
if (!cmd)
|
|
44768
44825
|
return "";
|
|
44769
44826
|
let normalized = cmd;
|
|
44827
|
+
const globalKitDir = PathResolver.getGlobalKitDir().replace(/\\/g, "/").replace(/\/+$/, "");
|
|
44828
|
+
const defaultGlobalKitDir = join20(homedir12(), ".claude").replace(/\\/g, "/");
|
|
44770
44829
|
normalized = normalized.replace(/"/g, "");
|
|
44771
44830
|
normalized = normalized.replace(/~\//g, "$HOME/");
|
|
44772
44831
|
normalized = normalized.replace(/\$CLAUDE_PROJECT_DIR/g, "$HOME");
|
|
@@ -44775,9 +44834,17 @@ function normalizeCommand(cmd) {
|
|
|
44775
44834
|
normalized = normalized.replace(/%CLAUDE_PROJECT_DIR%/g, "$HOME");
|
|
44776
44835
|
normalized = normalized.replace(/(^|\s)(?:\.\/)?\.claude\//g, "$1$HOME/.claude/");
|
|
44777
44836
|
normalized = normalized.replace(/\\/g, "/");
|
|
44837
|
+
const globalPaths = [...new Set([globalKitDir, defaultGlobalKitDir].filter(Boolean))];
|
|
44838
|
+
for (const absoluteGlobalPath of globalPaths) {
|
|
44839
|
+
const absoluteGlobalPathPattern = new RegExp(escapeRegex(absoluteGlobalPath), "g");
|
|
44840
|
+
normalized = normalized.replace(absoluteGlobalPathPattern, "$HOME/.claude");
|
|
44841
|
+
}
|
|
44778
44842
|
normalized = normalized.replace(/\s+/g, " ").trim();
|
|
44779
44843
|
return normalized;
|
|
44780
44844
|
}
|
|
44845
|
+
var init_command_normalizer = __esm(() => {
|
|
44846
|
+
init_path_resolver();
|
|
44847
|
+
});
|
|
44781
44848
|
|
|
44782
44849
|
// src/shared/parse-timeout.ts
|
|
44783
44850
|
function parseTimeoutMs(rawValue, fallback2, min = 500, max = 60000) {
|
|
@@ -44807,6 +44874,7 @@ var init_shared = __esm(() => {
|
|
|
44807
44874
|
init_safe_spinner();
|
|
44808
44875
|
init_safe_prompts();
|
|
44809
44876
|
init_skip_directories();
|
|
44877
|
+
init_command_normalizer();
|
|
44810
44878
|
});
|
|
44811
44879
|
|
|
44812
44880
|
// src/domains/config/merger/diff-calculator.ts
|
|
@@ -45206,7 +45274,7 @@ var init_merge_engine = __esm(() => {
|
|
|
45206
45274
|
|
|
45207
45275
|
// src/domains/config/merger/file-io.ts
|
|
45208
45276
|
import { randomUUID } from "node:crypto";
|
|
45209
|
-
import { dirname as dirname6, join as
|
|
45277
|
+
import { dirname as dirname6, join as join21 } from "node:path";
|
|
45210
45278
|
function stripBOM(content) {
|
|
45211
45279
|
return content.charCodeAt(0) === 65279 ? content.slice(1) : content;
|
|
45212
45280
|
}
|
|
@@ -45230,7 +45298,7 @@ async function readSettingsFile(filePath) {
|
|
|
45230
45298
|
}
|
|
45231
45299
|
async function atomicWriteFile(filePath, content) {
|
|
45232
45300
|
const dir = dirname6(filePath);
|
|
45233
|
-
const tempPath =
|
|
45301
|
+
const tempPath = join21(dir, `.settings-${randomUUID()}.tmp`);
|
|
45234
45302
|
try {
|
|
45235
45303
|
await import_fs_extra4.writeFile(tempPath, content, "utf-8");
|
|
45236
45304
|
await import_fs_extra4.rename(tempPath, filePath);
|
|
@@ -45281,7 +45349,7 @@ var init_settings_merger = __esm(() => {
|
|
|
45281
45349
|
});
|
|
45282
45350
|
|
|
45283
45351
|
// src/domains/config/config-generator.ts
|
|
45284
|
-
import { join as
|
|
45352
|
+
import { join as join22 } from "node:path";
|
|
45285
45353
|
async function generateEnvFile(targetDir, values) {
|
|
45286
45354
|
const lines = [
|
|
45287
45355
|
"# Generated by ClaudeKit CLI setup wizard",
|
|
@@ -45323,7 +45391,7 @@ async function generateEnvFile(targetDir, values) {
|
|
|
45323
45391
|
for (const [key, value] of otherValues) {
|
|
45324
45392
|
lines.push(`${key}=${value}`);
|
|
45325
45393
|
}
|
|
45326
|
-
const envPath =
|
|
45394
|
+
const envPath = join22(targetDir, ".env");
|
|
45327
45395
|
await import_fs_extra5.writeFile(envPath, `${lines.join(`
|
|
45328
45396
|
`)}
|
|
45329
45397
|
`, { mode: 384 });
|
|
@@ -46947,8 +47015,8 @@ var init_chokidar = __esm(() => {
|
|
|
46947
47015
|
});
|
|
46948
47016
|
|
|
46949
47017
|
// src/domains/web-server/file-watcher.ts
|
|
46950
|
-
import { homedir as
|
|
46951
|
-
import { join as
|
|
47018
|
+
import { homedir as homedir13 } from "node:os";
|
|
47019
|
+
import { join as join25 } from "node:path";
|
|
46952
47020
|
|
|
46953
47021
|
class FileWatcher {
|
|
46954
47022
|
watcher = null;
|
|
@@ -46970,16 +47038,16 @@ class FileWatcher {
|
|
|
46970
47038
|
}
|
|
46971
47039
|
getWatchPaths() {
|
|
46972
47040
|
const paths = [];
|
|
46973
|
-
const globalDir =
|
|
46974
|
-
paths.push(
|
|
46975
|
-
const globalKitDir =
|
|
46976
|
-
paths.push(
|
|
46977
|
-
paths.push(
|
|
46978
|
-
paths.push(
|
|
47041
|
+
const globalDir = join25(homedir13(), ".claudekit");
|
|
47042
|
+
paths.push(join25(globalDir, "config.json"));
|
|
47043
|
+
const globalKitDir = join25(homedir13(), ".claude");
|
|
47044
|
+
paths.push(join25(globalKitDir, ".ck.json"));
|
|
47045
|
+
paths.push(join25(globalKitDir, "settings.json"));
|
|
47046
|
+
paths.push(join25(globalKitDir, "settings.local.json"));
|
|
46979
47047
|
const cwd2 = process.cwd();
|
|
46980
|
-
paths.push(
|
|
46981
|
-
paths.push(
|
|
46982
|
-
paths.push(
|
|
47048
|
+
paths.push(join25(cwd2, ".claude", ".ck.json"));
|
|
47049
|
+
paths.push(join25(cwd2, ".claude", "settings.json"));
|
|
47050
|
+
paths.push(join25(cwd2, ".claude", "settings.local.json"));
|
|
46983
47051
|
return paths;
|
|
46984
47052
|
}
|
|
46985
47053
|
handleFileChange(path3, type) {
|
|
@@ -47022,8 +47090,8 @@ class FileWatcher {
|
|
|
47022
47090
|
return path3.endsWith("config.json") || path3.endsWith(".ck.json") || path3.endsWith("settings.json") || path3.endsWith("settings.local.json");
|
|
47023
47091
|
}
|
|
47024
47092
|
getConfigScope(path3) {
|
|
47025
|
-
const globalDir =
|
|
47026
|
-
const globalKitDir =
|
|
47093
|
+
const globalDir = join25(homedir13(), ".claudekit");
|
|
47094
|
+
const globalKitDir = join25(homedir13(), ".claude");
|
|
47027
47095
|
return path3.startsWith(globalDir) || path3.startsWith(globalKitDir) ? "global" : "local";
|
|
47028
47096
|
}
|
|
47029
47097
|
stop() {
|
|
@@ -47416,14 +47484,14 @@ var init_projects_registry = __esm(() => {
|
|
|
47416
47484
|
|
|
47417
47485
|
// src/domains/claudekit-data/claude-projects-scanner.ts
|
|
47418
47486
|
import { existsSync as existsSync13, readFileSync as readFileSync5, readdirSync as readdirSync2, statSync as statSync3 } from "node:fs";
|
|
47419
|
-
import { join as
|
|
47487
|
+
import { join as join26 } from "node:path";
|
|
47420
47488
|
function extractProjectPath(claudeProjectDir) {
|
|
47421
47489
|
try {
|
|
47422
47490
|
const files = readdirSync2(claudeProjectDir);
|
|
47423
47491
|
const jsonlFile = files.find((f3) => f3.endsWith(".jsonl"));
|
|
47424
47492
|
if (!jsonlFile)
|
|
47425
47493
|
return null;
|
|
47426
|
-
const filePath =
|
|
47494
|
+
const filePath = join26(claudeProjectDir, jsonlFile);
|
|
47427
47495
|
const content = readFileSync5(filePath, "utf-8");
|
|
47428
47496
|
const lines = content.split(`
|
|
47429
47497
|
`).slice(0, 10);
|
|
@@ -47443,7 +47511,7 @@ function extractProjectPath(claudeProjectDir) {
|
|
|
47443
47511
|
}
|
|
47444
47512
|
}
|
|
47445
47513
|
function scanClaudeProjects() {
|
|
47446
|
-
const claudeProjectsDir =
|
|
47514
|
+
const claudeProjectsDir = join26(PathResolver.getGlobalKitDir(), "projects");
|
|
47447
47515
|
const now = Date.now();
|
|
47448
47516
|
if (cachedDiscoveredProjects && cachedDiscoveredProjects.expiresAt > now) {
|
|
47449
47517
|
return cachedDiscoveredProjects.projects;
|
|
@@ -47460,7 +47528,7 @@ function scanClaudeProjects() {
|
|
|
47460
47528
|
for (const entry of entries) {
|
|
47461
47529
|
if (!entry.isDirectory())
|
|
47462
47530
|
continue;
|
|
47463
|
-
const projectDirPath =
|
|
47531
|
+
const projectDirPath = join26(claudeProjectsDir, entry.name);
|
|
47464
47532
|
const projectPath = extractProjectPath(projectDirPath);
|
|
47465
47533
|
if (!projectPath) {
|
|
47466
47534
|
logger.debug(`Could not extract path from: ${entry.name}`);
|
|
@@ -47514,15 +47582,15 @@ var init_claudekit_data2 = __esm(() => {
|
|
|
47514
47582
|
// src/domains/web-server/routes/action-routes.ts
|
|
47515
47583
|
import { spawn, spawnSync } from "node:child_process";
|
|
47516
47584
|
import { existsSync as existsSync14 } from "node:fs";
|
|
47517
|
-
import { homedir as
|
|
47518
|
-
import { join as
|
|
47585
|
+
import { homedir as homedir14 } from "node:os";
|
|
47586
|
+
import { join as join27, resolve as resolve9, sep as sep4 } from "node:path";
|
|
47519
47587
|
function getWindowsPaths(...relativePaths) {
|
|
47520
47588
|
const roots = [
|
|
47521
47589
|
WINDOWS_PATHS.localAppData,
|
|
47522
47590
|
WINDOWS_PATHS.programFiles,
|
|
47523
47591
|
WINDOWS_PATHS.programFilesX86
|
|
47524
47592
|
];
|
|
47525
|
-
return roots.flatMap((root) => relativePaths.map((rel) =>
|
|
47593
|
+
return roots.flatMap((root) => relativePaths.map((rel) => join27(root, rel)));
|
|
47526
47594
|
}
|
|
47527
47595
|
function isCommandAvailable(command) {
|
|
47528
47596
|
const checkCommand = isWindows() ? "where" : "which";
|
|
@@ -47802,7 +47870,7 @@ async function isActionPathAllowed(dirPath, projectId) {
|
|
|
47802
47870
|
if (isPathInsideBase(dirPath, process.cwd())) {
|
|
47803
47871
|
return true;
|
|
47804
47872
|
}
|
|
47805
|
-
return isPathInsideBase(dirPath,
|
|
47873
|
+
return isPathInsideBase(dirPath, homedir14());
|
|
47806
47874
|
}
|
|
47807
47875
|
function buildSystemTerminalCommand(dirPath) {
|
|
47808
47876
|
if (isMacOS()) {
|
|
@@ -48141,7 +48209,7 @@ var init_action_routes = __esm(() => {
|
|
|
48141
48209
|
projectId: exports_external.string().min(1).max(256).optional()
|
|
48142
48210
|
}).strict();
|
|
48143
48211
|
WINDOWS_PATHS = {
|
|
48144
|
-
localAppData: process.env.LOCALAPPDATA ||
|
|
48212
|
+
localAppData: process.env.LOCALAPPDATA || join27(homedir14(), "AppData", "Local"),
|
|
48145
48213
|
programFiles: process.env.ProgramFiles || "C:\\Program Files",
|
|
48146
48214
|
programFilesX86: process.env["ProgramFiles(x86)"] || "C:\\Program Files (x86)"
|
|
48147
48215
|
};
|
|
@@ -48162,7 +48230,7 @@ var init_action_routes = __esm(() => {
|
|
|
48162
48230
|
openMode: "open-directory",
|
|
48163
48231
|
capabilities: ["open-directory", "run-command"],
|
|
48164
48232
|
macAppName: "iTerm",
|
|
48165
|
-
macAppPaths: ["/Applications/iTerm.app",
|
|
48233
|
+
macAppPaths: ["/Applications/iTerm.app", join27(homedir14(), "Applications", "iTerm.app")]
|
|
48166
48234
|
},
|
|
48167
48235
|
{
|
|
48168
48236
|
id: "warp",
|
|
@@ -48173,7 +48241,7 @@ var init_action_routes = __esm(() => {
|
|
|
48173
48241
|
capabilities: ["open-directory", "uri-scheme"],
|
|
48174
48242
|
commands: ["warp"],
|
|
48175
48243
|
macAppName: "Warp",
|
|
48176
|
-
macAppPaths: ["/Applications/Warp.app",
|
|
48244
|
+
macAppPaths: ["/Applications/Warp.app", join27(homedir14(), "Applications", "Warp.app")],
|
|
48177
48245
|
windowsAppPaths: getWindowsPaths("Warp\\Warp.exe"),
|
|
48178
48246
|
linuxAppPaths: ["/usr/bin/warp", "/usr/local/bin/warp"]
|
|
48179
48247
|
},
|
|
@@ -48185,7 +48253,7 @@ var init_action_routes = __esm(() => {
|
|
|
48185
48253
|
openMode: "open-directory",
|
|
48186
48254
|
capabilities: ["open-directory", "run-command"],
|
|
48187
48255
|
commands: ["wt"],
|
|
48188
|
-
windowsAppPaths: [
|
|
48256
|
+
windowsAppPaths: [join27(WINDOWS_PATHS.localAppData, "Microsoft", "WindowsApps", "wt.exe")]
|
|
48189
48257
|
},
|
|
48190
48258
|
{
|
|
48191
48259
|
id: "wezterm",
|
|
@@ -48196,7 +48264,7 @@ var init_action_routes = __esm(() => {
|
|
|
48196
48264
|
capabilities: ["open-directory"],
|
|
48197
48265
|
commands: ["wezterm"],
|
|
48198
48266
|
macAppName: "WezTerm",
|
|
48199
|
-
macAppPaths: ["/Applications/WezTerm.app",
|
|
48267
|
+
macAppPaths: ["/Applications/WezTerm.app", join27(homedir14(), "Applications", "WezTerm.app")],
|
|
48200
48268
|
windowsAppPaths: getWindowsPaths("WezTerm\\wezterm-gui.exe", "WezTerm\\wezterm.exe"),
|
|
48201
48269
|
linuxAppPaths: ["/usr/bin/wezterm", "/usr/local/bin/wezterm"]
|
|
48202
48270
|
},
|
|
@@ -48209,7 +48277,7 @@ var init_action_routes = __esm(() => {
|
|
|
48209
48277
|
capabilities: ["open-directory"],
|
|
48210
48278
|
commands: ["kitty"],
|
|
48211
48279
|
macAppName: "kitty",
|
|
48212
|
-
macAppPaths: ["/Applications/kitty.app",
|
|
48280
|
+
macAppPaths: ["/Applications/kitty.app", join27(homedir14(), "Applications", "kitty.app")],
|
|
48213
48281
|
windowsAppPaths: getWindowsPaths("kitty\\kitty.exe"),
|
|
48214
48282
|
linuxAppPaths: ["/usr/bin/kitty", "/usr/local/bin/kitty"]
|
|
48215
48283
|
},
|
|
@@ -48222,7 +48290,7 @@ var init_action_routes = __esm(() => {
|
|
|
48222
48290
|
capabilities: ["open-directory"],
|
|
48223
48291
|
commands: ["alacritty"],
|
|
48224
48292
|
macAppName: "Alacritty",
|
|
48225
|
-
macAppPaths: ["/Applications/Alacritty.app",
|
|
48293
|
+
macAppPaths: ["/Applications/Alacritty.app", join27(homedir14(), "Applications", "Alacritty.app")],
|
|
48226
48294
|
windowsAppPaths: getWindowsPaths("Alacritty\\alacritty.exe"),
|
|
48227
48295
|
linuxAppPaths: ["/usr/bin/alacritty", "/usr/local/bin/alacritty"]
|
|
48228
48296
|
},
|
|
@@ -48295,7 +48363,7 @@ var init_action_routes = __esm(() => {
|
|
|
48295
48363
|
capabilities: ["open-app"],
|
|
48296
48364
|
commands: ["termius"],
|
|
48297
48365
|
macAppName: "Termius",
|
|
48298
|
-
macAppPaths: ["/Applications/Termius.app",
|
|
48366
|
+
macAppPaths: ["/Applications/Termius.app", join27(homedir14(), "Applications", "Termius.app")],
|
|
48299
48367
|
windowsAppPaths: getWindowsPaths("Termius\\Termius.exe"),
|
|
48300
48368
|
linuxAppPaths: ["/usr/bin/termius"]
|
|
48301
48369
|
},
|
|
@@ -48318,7 +48386,7 @@ var init_action_routes = __esm(() => {
|
|
|
48318
48386
|
macAppName: "Visual Studio Code",
|
|
48319
48387
|
macAppPaths: [
|
|
48320
48388
|
"/Applications/Visual Studio Code.app",
|
|
48321
|
-
|
|
48389
|
+
join27(homedir14(), "Applications", "Visual Studio Code.app")
|
|
48322
48390
|
],
|
|
48323
48391
|
windowsAppPaths: getWindowsPaths("Programs\\Microsoft VS Code\\Code.exe", "Microsoft VS Code\\Code.exe"),
|
|
48324
48392
|
linuxAppPaths: ["/usr/bin/code", "/snap/bin/code"]
|
|
@@ -48332,7 +48400,7 @@ var init_action_routes = __esm(() => {
|
|
|
48332
48400
|
capabilities: ["open-directory"],
|
|
48333
48401
|
commands: ["cursor"],
|
|
48334
48402
|
macAppName: "Cursor",
|
|
48335
|
-
macAppPaths: ["/Applications/Cursor.app",
|
|
48403
|
+
macAppPaths: ["/Applications/Cursor.app", join27(homedir14(), "Applications", "Cursor.app")],
|
|
48336
48404
|
windowsAppPaths: getWindowsPaths("Programs\\Cursor\\Cursor.exe", "Cursor\\Cursor.exe"),
|
|
48337
48405
|
linuxAppPaths: ["/usr/bin/cursor"]
|
|
48338
48406
|
},
|
|
@@ -48345,7 +48413,7 @@ var init_action_routes = __esm(() => {
|
|
|
48345
48413
|
capabilities: ["open-directory"],
|
|
48346
48414
|
commands: ["windsurf"],
|
|
48347
48415
|
macAppName: "Windsurf",
|
|
48348
|
-
macAppPaths: ["/Applications/Windsurf.app",
|
|
48416
|
+
macAppPaths: ["/Applications/Windsurf.app", join27(homedir14(), "Applications", "Windsurf.app")],
|
|
48349
48417
|
windowsAppPaths: getWindowsPaths("Programs\\Windsurf\\Windsurf.exe", "Windsurf\\Windsurf.exe"),
|
|
48350
48418
|
linuxAppPaths: ["/usr/bin/windsurf"]
|
|
48351
48419
|
},
|
|
@@ -48360,11 +48428,11 @@ var init_action_routes = __esm(() => {
|
|
|
48360
48428
|
macAppName: "Antigravity",
|
|
48361
48429
|
macAppPaths: [
|
|
48362
48430
|
"/Applications/Antigravity.app",
|
|
48363
|
-
|
|
48431
|
+
join27(homedir14(), "Applications", "Antigravity.app")
|
|
48364
48432
|
],
|
|
48365
48433
|
windowsAppPaths: getWindowsPaths("Programs\\Antigravity\\Antigravity.exe"),
|
|
48366
48434
|
linuxAppPaths: ["/usr/bin/antigravity"],
|
|
48367
|
-
fallbackDetectionPaths: [
|
|
48435
|
+
fallbackDetectionPaths: [join27(homedir14(), ".gemini", "antigravity")]
|
|
48368
48436
|
},
|
|
48369
48437
|
{
|
|
48370
48438
|
id: "zed",
|
|
@@ -48375,7 +48443,7 @@ var init_action_routes = __esm(() => {
|
|
|
48375
48443
|
capabilities: ["open-directory"],
|
|
48376
48444
|
commands: ["zed"],
|
|
48377
48445
|
macAppName: "Zed",
|
|
48378
|
-
macAppPaths: ["/Applications/Zed.app",
|
|
48446
|
+
macAppPaths: ["/Applications/Zed.app", join27(homedir14(), "Applications", "Zed.app")],
|
|
48379
48447
|
windowsAppPaths: getWindowsPaths("Zed\\Zed.exe"),
|
|
48380
48448
|
linuxAppPaths: ["/usr/bin/zed", "/usr/local/bin/zed"]
|
|
48381
48449
|
},
|
|
@@ -48390,7 +48458,7 @@ var init_action_routes = __esm(() => {
|
|
|
48390
48458
|
macAppName: "Sublime Text",
|
|
48391
48459
|
macAppPaths: [
|
|
48392
48460
|
"/Applications/Sublime Text.app",
|
|
48393
|
-
|
|
48461
|
+
join27(homedir14(), "Applications", "Sublime Text.app")
|
|
48394
48462
|
],
|
|
48395
48463
|
windowsAppPaths: getWindowsPaths("Sublime Text\\sublime_text.exe"),
|
|
48396
48464
|
linuxAppPaths: ["/usr/bin/subl", "/snap/bin/subl"]
|
|
@@ -49013,7 +49081,7 @@ var init_ck_config_schema = __esm(() => {
|
|
|
49013
49081
|
// src/domains/web-server/routes/ck-config-routes.ts
|
|
49014
49082
|
import { existsSync as existsSync15 } from "node:fs";
|
|
49015
49083
|
import { readFile as readFile11 } from "node:fs/promises";
|
|
49016
|
-
import { join as
|
|
49084
|
+
import { join as join28 } from "node:path";
|
|
49017
49085
|
async function resolveProjectDir(projectId) {
|
|
49018
49086
|
if (!projectId)
|
|
49019
49087
|
return null;
|
|
@@ -49155,7 +49223,7 @@ function registerCkConfigRoutes(app) {
|
|
|
49155
49223
|
});
|
|
49156
49224
|
app.get("/api/metadata/global", async (_req, res) => {
|
|
49157
49225
|
try {
|
|
49158
|
-
const metadataPath =
|
|
49226
|
+
const metadataPath = join28(PathResolver.getGlobalKitDir(), "metadata.json");
|
|
49159
49227
|
let metadata = {};
|
|
49160
49228
|
if (existsSync15(metadataPath)) {
|
|
49161
49229
|
const content = await readFile11(metadataPath, "utf-8");
|
|
@@ -49235,11 +49303,11 @@ var init_types5 = __esm(() => {
|
|
|
49235
49303
|
|
|
49236
49304
|
// src/services/claude-data/history-parser.ts
|
|
49237
49305
|
import { createReadStream, statSync as statSync4 } from "node:fs";
|
|
49238
|
-
import { homedir as
|
|
49239
|
-
import { join as
|
|
49306
|
+
import { homedir as homedir15 } from "node:os";
|
|
49307
|
+
import { join as join29 } from "node:path";
|
|
49240
49308
|
import { createInterface as createInterface2 } from "node:readline";
|
|
49241
49309
|
function getHistoryPath() {
|
|
49242
|
-
return process.env.CLAUDE_HISTORY_PATH ??
|
|
49310
|
+
return process.env.CLAUDE_HISTORY_PATH ?? join29(homedir15(), ".claude", "history.jsonl");
|
|
49243
49311
|
}
|
|
49244
49312
|
function emptyResult(parseTimeMs, error) {
|
|
49245
49313
|
return { projects: [], totalEntries: 0, errorCount: 0, parseTimeMs, error };
|
|
@@ -49323,7 +49391,7 @@ var init_history_parser = __esm(() => {
|
|
|
49323
49391
|
// src/services/claude-data/session-parser.ts
|
|
49324
49392
|
import { existsSync as existsSync16 } from "node:fs";
|
|
49325
49393
|
import { readFile as readFile12, readdir as readdir7, stat as stat5 } from "node:fs/promises";
|
|
49326
|
-
import { join as
|
|
49394
|
+
import { join as join30 } from "node:path";
|
|
49327
49395
|
function formatTimestamp(date) {
|
|
49328
49396
|
const now = new Date;
|
|
49329
49397
|
const isToday = date.toDateString() === now.toDateString();
|
|
@@ -49420,7 +49488,7 @@ async function getProjectSessions(projectDir, limit = 10) {
|
|
|
49420
49488
|
const files = await readdir7(projectDir);
|
|
49421
49489
|
const jsonlFiles = files.filter((f3) => f3.endsWith(".jsonl"));
|
|
49422
49490
|
const fileStats = await Promise.all(jsonlFiles.map(async (file) => {
|
|
49423
|
-
const filePath =
|
|
49491
|
+
const filePath = join30(projectDir, file);
|
|
49424
49492
|
const fileStat = await stat5(filePath).catch(() => null);
|
|
49425
49493
|
return { file, filePath, mtime: fileStat?.mtime || new Date(0) };
|
|
49426
49494
|
}));
|
|
@@ -49437,10 +49505,10 @@ var init_session_parser = () => {};
|
|
|
49437
49505
|
// src/services/claude-data/skill-scanner.ts
|
|
49438
49506
|
import { existsSync as existsSync17 } from "node:fs";
|
|
49439
49507
|
import { readFile as readFile13, readdir as readdir8 } from "node:fs/promises";
|
|
49440
|
-
import { homedir as
|
|
49441
|
-
import { join as
|
|
49508
|
+
import { homedir as homedir16 } from "node:os";
|
|
49509
|
+
import { join as join31 } from "node:path";
|
|
49442
49510
|
async function getCkSkillMetadata(scope) {
|
|
49443
|
-
const metaPath = scope === "global" ?
|
|
49511
|
+
const metaPath = scope === "global" ? join31(homedir16(), ".claude", "metadata.json") : join31(process.cwd(), ".claude", "metadata.json");
|
|
49444
49512
|
if (!existsSync17(metaPath))
|
|
49445
49513
|
return null;
|
|
49446
49514
|
const result = new Map;
|
|
@@ -49476,7 +49544,7 @@ async function getCkSkillMetadata(scope) {
|
|
|
49476
49544
|
return result.size > 0 ? result : null;
|
|
49477
49545
|
}
|
|
49478
49546
|
async function getSkillMetadata(skillPath) {
|
|
49479
|
-
const skillMdPath =
|
|
49547
|
+
const skillMdPath = join31(skillPath, "SKILL.md");
|
|
49480
49548
|
if (!existsSync17(skillMdPath))
|
|
49481
49549
|
return null;
|
|
49482
49550
|
try {
|
|
@@ -49525,8 +49593,8 @@ async function scanSkills() {
|
|
|
49525
49593
|
continue;
|
|
49526
49594
|
if (ckMeta && !ckMeta.has(entry))
|
|
49527
49595
|
continue;
|
|
49528
|
-
const entryPath =
|
|
49529
|
-
const skillMdPath =
|
|
49596
|
+
const entryPath = join31(skillsDir, entry);
|
|
49597
|
+
const skillMdPath = join31(entryPath, "SKILL.md");
|
|
49530
49598
|
if (!existsSync17(skillMdPath))
|
|
49531
49599
|
continue;
|
|
49532
49600
|
const frontmatter = await getSkillMetadata(entryPath);
|
|
@@ -49571,17 +49639,17 @@ async function scanSkills() {
|
|
|
49571
49639
|
var import_gray_matter4, skillsDir, SKIP_DIRS2;
|
|
49572
49640
|
var init_skill_scanner = __esm(() => {
|
|
49573
49641
|
import_gray_matter4 = __toESM(require_gray_matter(), 1);
|
|
49574
|
-
skillsDir =
|
|
49642
|
+
skillsDir = join31(homedir16(), ".claude", "skills");
|
|
49575
49643
|
SKIP_DIRS2 = [".venv", "scripts", "__pycache__", "node_modules", ".git", "common"];
|
|
49576
49644
|
});
|
|
49577
49645
|
|
|
49578
49646
|
// src/services/claude-data/settings-reader.ts
|
|
49579
49647
|
import { existsSync as existsSync18 } from "node:fs";
|
|
49580
49648
|
import { copyFile as copyFile2, mkdir as mkdir9, readFile as readFile14, rename as rename5, rm as rm4, writeFile as writeFile10 } from "node:fs/promises";
|
|
49581
|
-
import { homedir as
|
|
49582
|
-
import { join as
|
|
49649
|
+
import { homedir as homedir17 } from "node:os";
|
|
49650
|
+
import { join as join32 } from "node:path";
|
|
49583
49651
|
function getSettingsPath() {
|
|
49584
|
-
return
|
|
49652
|
+
return join32(claudeDir, settingsFilename);
|
|
49585
49653
|
}
|
|
49586
49654
|
async function readSettings() {
|
|
49587
49655
|
const settingsPath = getSettingsPath();
|
|
@@ -49603,7 +49671,7 @@ async function backupAndSaveSettings(settings) {
|
|
|
49603
49671
|
let backupPath = null;
|
|
49604
49672
|
if (existsSync18(settingsPath)) {
|
|
49605
49673
|
await mkdir9(settingsBackupDir, { recursive: true });
|
|
49606
|
-
backupPath =
|
|
49674
|
+
backupPath = join32(settingsBackupDir, `${getBackupTimestamp()}-${settingsFilename}`);
|
|
49607
49675
|
await copyFile2(settingsPath, backupPath);
|
|
49608
49676
|
}
|
|
49609
49677
|
const tempPath = `${settingsPath}.tmp-${Date.now()}`;
|
|
@@ -49640,13 +49708,13 @@ function countMcpServers(settings) {
|
|
|
49640
49708
|
}
|
|
49641
49709
|
var claudeDir, settingsFilename = "settings.json", settingsBackupDir;
|
|
49642
49710
|
var init_settings_reader = __esm(() => {
|
|
49643
|
-
claudeDir =
|
|
49644
|
-
settingsBackupDir =
|
|
49711
|
+
claudeDir = join32(homedir17(), ".claude");
|
|
49712
|
+
settingsBackupDir = join32(claudeDir, ".ck-backups", "settings");
|
|
49645
49713
|
});
|
|
49646
49714
|
|
|
49647
49715
|
// src/services/claude-data/hook-log-reader.ts
|
|
49648
49716
|
import { open as open4 } from "node:fs/promises";
|
|
49649
|
-
import { join as
|
|
49717
|
+
import { join as join33 } from "node:path";
|
|
49650
49718
|
function createEmptySummary() {
|
|
49651
49719
|
return {
|
|
49652
49720
|
total: 0,
|
|
@@ -49694,9 +49762,9 @@ async function resolveProjectPath(projectId) {
|
|
|
49694
49762
|
}
|
|
49695
49763
|
function getHookLogPath(scope, basePath) {
|
|
49696
49764
|
if (scope === "global") {
|
|
49697
|
-
return
|
|
49765
|
+
return join33(basePath, "hooks", ".logs", "hook-log.jsonl");
|
|
49698
49766
|
}
|
|
49699
|
-
return
|
|
49767
|
+
return join33(basePath, ".claude", "hooks", ".logs", "hook-log.jsonl");
|
|
49700
49768
|
}
|
|
49701
49769
|
function parseEntry(line) {
|
|
49702
49770
|
try {
|
|
@@ -49808,14 +49876,14 @@ var init_hook_log_reader = __esm(() => {
|
|
|
49808
49876
|
});
|
|
49809
49877
|
|
|
49810
49878
|
// src/services/claude-data/project-scanner.ts
|
|
49811
|
-
import { homedir as
|
|
49812
|
-
import { basename as basename8, join as
|
|
49879
|
+
import { homedir as homedir18 } from "node:os";
|
|
49880
|
+
import { basename as basename8, join as join34, normalize as normalize4 } from "node:path";
|
|
49813
49881
|
function encodePath(path3) {
|
|
49814
49882
|
return path3.replace(/\//g, "-").replace(/^-/, "-");
|
|
49815
49883
|
}
|
|
49816
49884
|
var projectsDir;
|
|
49817
49885
|
var init_project_scanner = __esm(() => {
|
|
49818
|
-
projectsDir =
|
|
49886
|
+
projectsDir = join34(homedir18(), ".claude", "projects");
|
|
49819
49887
|
});
|
|
49820
49888
|
|
|
49821
49889
|
// src/services/claude-data/project-discovery.ts
|
|
@@ -49910,10 +49978,10 @@ var init_project_discovery = __esm(() => {
|
|
|
49910
49978
|
|
|
49911
49979
|
// src/services/claude-data/user-preferences.ts
|
|
49912
49980
|
import { readFile as readFile15, stat as stat6 } from "node:fs/promises";
|
|
49913
|
-
import { homedir as
|
|
49914
|
-
import { join as
|
|
49981
|
+
import { homedir as homedir19 } from "node:os";
|
|
49982
|
+
import { join as join35 } from "node:path";
|
|
49915
49983
|
function getPreferencesPath() {
|
|
49916
|
-
return
|
|
49984
|
+
return join35(homedir19(), ".claude.json");
|
|
49917
49985
|
}
|
|
49918
49986
|
async function readUserPreferences(filePath) {
|
|
49919
49987
|
const path3 = filePath ?? getPreferencesPath();
|
|
@@ -50047,7 +50115,7 @@ var init_hook_log_routes = __esm(() => {
|
|
|
50047
50115
|
// src/commands/migrate/skill-directory-installer.ts
|
|
50048
50116
|
import { existsSync as existsSync19 } from "node:fs";
|
|
50049
50117
|
import { cp, mkdir as mkdir10, rename as rename6, rm as rm5 } from "node:fs/promises";
|
|
50050
|
-
import { join as
|
|
50118
|
+
import { join as join36, resolve as resolve10 } from "node:path";
|
|
50051
50119
|
async function installSkillDirectories(skills, targetProviders, options2) {
|
|
50052
50120
|
const results = [];
|
|
50053
50121
|
for (const provider of targetProviders) {
|
|
@@ -50075,7 +50143,7 @@ async function installSkillDirectories(skills, targetProviders, options2) {
|
|
|
50075
50143
|
continue;
|
|
50076
50144
|
}
|
|
50077
50145
|
for (const skill of skills) {
|
|
50078
|
-
const targetDir =
|
|
50146
|
+
const targetDir = join36(basePath, skill.name);
|
|
50079
50147
|
if (resolve10(skill.path) === resolve10(targetDir)) {
|
|
50080
50148
|
results.push({
|
|
50081
50149
|
provider,
|
|
@@ -50151,12 +50219,12 @@ var init_skill_directory_installer = __esm(() => {
|
|
|
50151
50219
|
// src/commands/portable/config-discovery.ts
|
|
50152
50220
|
import { existsSync as existsSync20 } from "node:fs";
|
|
50153
50221
|
import { readFile as readFile16, readdir as readdir9 } from "node:fs/promises";
|
|
50154
|
-
import { homedir as
|
|
50155
|
-
import { extname as extname3, join as
|
|
50222
|
+
import { homedir as homedir20 } from "node:os";
|
|
50223
|
+
import { extname as extname3, join as join37, relative as relative5, sep as sep5 } from "node:path";
|
|
50156
50224
|
function resolveSourceOrigin(sourcePath) {
|
|
50157
50225
|
if (!sourcePath)
|
|
50158
50226
|
return "global";
|
|
50159
|
-
const home5 =
|
|
50227
|
+
const home5 = homedir20();
|
|
50160
50228
|
const cwd2 = process.cwd();
|
|
50161
50229
|
if (cwd2 === home5)
|
|
50162
50230
|
return "global";
|
|
@@ -50169,13 +50237,13 @@ function getConfigSourcePath() {
|
|
|
50169
50237
|
return findExistingProjectConfigPath(process.cwd()) ?? getGlobalConfigSourcePath();
|
|
50170
50238
|
}
|
|
50171
50239
|
function getGlobalConfigSourcePath() {
|
|
50172
|
-
return
|
|
50240
|
+
return join37(homedir20(), ".claude", "CLAUDE.md");
|
|
50173
50241
|
}
|
|
50174
50242
|
function getRulesSourcePath() {
|
|
50175
|
-
return findExistingProjectLayoutPath(process.cwd(), "rules") ??
|
|
50243
|
+
return findExistingProjectLayoutPath(process.cwd(), "rules") ?? join37(homedir20(), ".claude", "rules");
|
|
50176
50244
|
}
|
|
50177
50245
|
function getHooksSourcePath() {
|
|
50178
|
-
return findExistingProjectLayoutPath(process.cwd(), "hooks") ??
|
|
50246
|
+
return findExistingProjectLayoutPath(process.cwd(), "hooks") ?? join37(homedir20(), ".claude", "hooks");
|
|
50179
50247
|
}
|
|
50180
50248
|
async function discoverConfig(sourcePath) {
|
|
50181
50249
|
const path3 = sourcePath ?? getConfigSourcePath();
|
|
@@ -50227,7 +50295,7 @@ async function discoverHooks(sourcePath) {
|
|
|
50227
50295
|
}
|
|
50228
50296
|
if (!HOOK_EXTENSIONS.has(ext))
|
|
50229
50297
|
continue;
|
|
50230
|
-
const fullPath =
|
|
50298
|
+
const fullPath = join37(path3, entry.name);
|
|
50231
50299
|
try {
|
|
50232
50300
|
const content = await readFile16(fullPath, "utf-8");
|
|
50233
50301
|
items.push({
|
|
@@ -50253,7 +50321,7 @@ async function discoverPortableFiles(dir, baseDir, options2) {
|
|
|
50253
50321
|
for (const entry of entries) {
|
|
50254
50322
|
if (entry.name.startsWith("."))
|
|
50255
50323
|
continue;
|
|
50256
|
-
const fullPath =
|
|
50324
|
+
const fullPath = join37(dir, entry.name);
|
|
50257
50325
|
if (entry.isSymbolicLink()) {
|
|
50258
50326
|
continue;
|
|
50259
50327
|
}
|
|
@@ -50297,7 +50365,7 @@ var init_config_discovery = __esm(() => {
|
|
|
50297
50365
|
// src/commands/portable/hooks-settings-merger.ts
|
|
50298
50366
|
import { existsSync as existsSync21, mkdirSync, renameSync, rmSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
50299
50367
|
import { readFile as readFile17 } from "node:fs/promises";
|
|
50300
|
-
import { basename as basename10, dirname as dirname10, join as
|
|
50368
|
+
import { basename as basename10, dirname as dirname10, join as join38 } from "node:path";
|
|
50301
50369
|
async function inspectHooksSettings(settingsPath) {
|
|
50302
50370
|
try {
|
|
50303
50371
|
if (!existsSync21(settingsPath)) {
|
|
@@ -50478,8 +50546,8 @@ async function migrateHooksSettings(options2) {
|
|
|
50478
50546
|
targetSettingsPath: null
|
|
50479
50547
|
};
|
|
50480
50548
|
}
|
|
50481
|
-
const resolvedSourcePath = isGlobal ? sourceSettingsPath :
|
|
50482
|
-
const resolvedTargetPath = isGlobal ? targetSettingsPath :
|
|
50549
|
+
const resolvedSourcePath = isGlobal ? sourceSettingsPath : join38(process.cwd(), sourceSettingsPath);
|
|
50550
|
+
const resolvedTargetPath = isGlobal ? targetSettingsPath : join38(process.cwd(), targetSettingsPath);
|
|
50483
50551
|
const sourceHooksResult = await inspectHooksSettings(resolvedSourcePath);
|
|
50484
50552
|
if (sourceHooksResult.status === "missing-file") {
|
|
50485
50553
|
return {
|
|
@@ -53075,20 +53143,20 @@ var init_reconciler = __esm(() => {
|
|
|
53075
53143
|
|
|
53076
53144
|
// src/commands/skills/skills-discovery.ts
|
|
53077
53145
|
import { readFile as readFile20, readdir as readdir10, stat as stat7 } from "node:fs/promises";
|
|
53078
|
-
import { homedir as
|
|
53079
|
-
import { dirname as dirname11, join as
|
|
53146
|
+
import { homedir as homedir21 } from "node:os";
|
|
53147
|
+
import { dirname as dirname11, join as join39 } from "node:path";
|
|
53080
53148
|
function getSkillSourcePath() {
|
|
53081
|
-
const bundledRoot =
|
|
53149
|
+
const bundledRoot = join39(process.cwd(), "node_modules", "claudekit-engineer");
|
|
53082
53150
|
return findFirstExistingPath([
|
|
53083
|
-
|
|
53151
|
+
join39(bundledRoot, "skills"),
|
|
53084
53152
|
...getProjectLayoutCandidates(bundledRoot, "skills"),
|
|
53085
53153
|
...getProjectLayoutCandidates(process.cwd(), "skills"),
|
|
53086
|
-
|
|
53154
|
+
join39(home5, ".claude/skills")
|
|
53087
53155
|
]);
|
|
53088
53156
|
}
|
|
53089
53157
|
async function hasSkillMd(dir) {
|
|
53090
53158
|
try {
|
|
53091
|
-
const skillPath =
|
|
53159
|
+
const skillPath = join39(dir, "SKILL.md");
|
|
53092
53160
|
const stats = await stat7(skillPath);
|
|
53093
53161
|
return stats.isFile();
|
|
53094
53162
|
} catch {
|
|
@@ -53136,9 +53204,9 @@ async function discoverSkills(sourcePath) {
|
|
|
53136
53204
|
if (!entry.isDirectory() || SKIP_DIRS3.includes(entry.name)) {
|
|
53137
53205
|
continue;
|
|
53138
53206
|
}
|
|
53139
|
-
const skillDir =
|
|
53207
|
+
const skillDir = join39(searchPath, entry.name);
|
|
53140
53208
|
if (await hasSkillMd(skillDir)) {
|
|
53141
|
-
const skill = await parseSkillMd(
|
|
53209
|
+
const skill = await parseSkillMd(join39(skillDir, "SKILL.md"));
|
|
53142
53210
|
if (skill && !seenNames.has(skill.name)) {
|
|
53143
53211
|
skills.push(skill);
|
|
53144
53212
|
seenNames.add(skill.name);
|
|
@@ -53157,7 +53225,7 @@ var init_skills_discovery = __esm(() => {
|
|
|
53157
53225
|
init_kit_layout();
|
|
53158
53226
|
init_logger();
|
|
53159
53227
|
import_gray_matter5 = __toESM(require_gray_matter(), 1);
|
|
53160
|
-
home5 =
|
|
53228
|
+
home5 = homedir21();
|
|
53161
53229
|
SKIP_DIRS3 = ["node_modules", ".git", "dist", "build", ".venv", "__pycache__", "common"];
|
|
53162
53230
|
});
|
|
53163
53231
|
|
|
@@ -53260,8 +53328,8 @@ var init_migration_result_utils = __esm(() => {
|
|
|
53260
53328
|
// src/domains/web-server/routes/migration-routes.ts
|
|
53261
53329
|
import { existsSync as existsSync24 } from "node:fs";
|
|
53262
53330
|
import { readFile as readFile21, rm as rm6 } from "node:fs/promises";
|
|
53263
|
-
import { homedir as
|
|
53264
|
-
import { basename as basename11, join as
|
|
53331
|
+
import { homedir as homedir22 } from "node:os";
|
|
53332
|
+
import { basename as basename11, join as join40, resolve as resolve11 } from "node:path";
|
|
53265
53333
|
function isDisallowedControlCode(codePoint) {
|
|
53266
53334
|
return codePoint >= 0 && codePoint <= 8 || codePoint >= 11 && codePoint <= 31 || codePoint >= 127 && codePoint <= 159;
|
|
53267
53335
|
}
|
|
@@ -53828,12 +53896,12 @@ function registerMigrationRoutes(app) {
|
|
|
53828
53896
|
};
|
|
53829
53897
|
const discovered = await discoverMigrationItems(includeAll);
|
|
53830
53898
|
const cwd2 = process.cwd();
|
|
53831
|
-
const home6 =
|
|
53899
|
+
const home6 = homedir22();
|
|
53832
53900
|
res.status(200).json({
|
|
53833
53901
|
cwd: cwd2,
|
|
53834
53902
|
targetPaths: {
|
|
53835
|
-
project:
|
|
53836
|
-
global:
|
|
53903
|
+
project: join40(cwd2, ".claude"),
|
|
53904
|
+
global: join40(home6, ".claude")
|
|
53837
53905
|
},
|
|
53838
53906
|
sourcePaths: discovered.sourcePaths,
|
|
53839
53907
|
sourceOrigins: {
|
|
@@ -54862,12 +54930,12 @@ var init_plan_table_parser = __esm(() => {
|
|
|
54862
54930
|
|
|
54863
54931
|
// src/domains/plan-parser/plan-scanner.ts
|
|
54864
54932
|
import { existsSync as existsSync25, readdirSync as readdirSync3 } from "node:fs";
|
|
54865
|
-
import { join as
|
|
54933
|
+
import { join as join41 } from "node:path";
|
|
54866
54934
|
function scanPlanDir(dir) {
|
|
54867
54935
|
if (!existsSync25(dir))
|
|
54868
54936
|
return [];
|
|
54869
54937
|
try {
|
|
54870
|
-
return readdirSync3(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) =>
|
|
54938
|
+
return readdirSync3(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join41(dir, entry.name, "plan.md")).filter(existsSync25);
|
|
54871
54939
|
} catch {
|
|
54872
54940
|
return [];
|
|
54873
54941
|
}
|
|
@@ -54942,7 +55010,7 @@ var init_plan_validator = __esm(() => {
|
|
|
54942
55010
|
// src/domains/plan-parser/plan-writer.ts
|
|
54943
55011
|
import { mkdirSync as mkdirSync2, readFileSync as readFileSync8, writeFileSync as writeFileSync3 } from "node:fs";
|
|
54944
55012
|
import { existsSync as existsSync27 } from "node:fs";
|
|
54945
|
-
import { basename as basename13, dirname as dirname14, join as
|
|
55013
|
+
import { basename as basename13, dirname as dirname14, join as join42 } from "node:path";
|
|
54946
55014
|
function phaseNameToFilename(id, name) {
|
|
54947
55015
|
const numMatch = /^(\d+)([a-z]*)$/i.exec(id);
|
|
54948
55016
|
const num = numMatch ? numMatch[1] : id;
|
|
@@ -55050,12 +55118,12 @@ function scaffoldPlan(options2) {
|
|
|
55050
55118
|
mkdirSync2(dir, { recursive: true });
|
|
55051
55119
|
const resolvedPhases = resolvePhaseIds(options2.phases);
|
|
55052
55120
|
const optionsWithResolved = { ...options2, phases: resolvedPhases };
|
|
55053
|
-
const planFile =
|
|
55121
|
+
const planFile = join42(dir, "plan.md");
|
|
55054
55122
|
writeFileSync3(planFile, generatePlanMd(optionsWithResolved), "utf8");
|
|
55055
55123
|
const phaseFiles = [];
|
|
55056
55124
|
for (const phase of resolvedPhases) {
|
|
55057
55125
|
const filename = phaseNameToFilename(phase.id, phase.name);
|
|
55058
|
-
const phaseFile =
|
|
55126
|
+
const phaseFile = join42(dir, filename);
|
|
55059
55127
|
writeFileSync3(phaseFile, generatePhaseTemplate(phase), "utf8");
|
|
55060
55128
|
phaseFiles.push(phaseFile);
|
|
55061
55129
|
}
|
|
@@ -55135,7 +55203,7 @@ function phaseNameFilenameFromTableRow(body, phaseId, planDir) {
|
|
|
55135
55203
|
continue;
|
|
55136
55204
|
const linkMatch = /\[([^\]]+)\]\(\.\/([^)]+)\)/.exec(row);
|
|
55137
55205
|
if (linkMatch)
|
|
55138
|
-
return
|
|
55206
|
+
return join42(planDir, linkMatch[2]);
|
|
55139
55207
|
}
|
|
55140
55208
|
return null;
|
|
55141
55209
|
}
|
|
@@ -55216,7 +55284,7 @@ function addPhase(planFile, name, afterId) {
|
|
|
55216
55284
|
`);
|
|
55217
55285
|
}
|
|
55218
55286
|
writeFileSync3(planFile, import_gray_matter8.default.stringify(updatedBody, frontmatter), "utf8");
|
|
55219
|
-
const phaseFilePath =
|
|
55287
|
+
const phaseFilePath = join42(planDir, filename);
|
|
55220
55288
|
writeFileSync3(phaseFilePath, generatePhaseTemplate({ id: phaseId, name }), "utf8");
|
|
55221
55289
|
return { phaseId, phaseFile: phaseFilePath };
|
|
55222
55290
|
}
|
|
@@ -55380,8 +55448,8 @@ var init_plan_routes = __esm(() => {
|
|
|
55380
55448
|
// src/domains/web-server/routes/project-routes.ts
|
|
55381
55449
|
import { existsSync as existsSync29 } from "node:fs";
|
|
55382
55450
|
import { readFile as readFile22 } from "node:fs/promises";
|
|
55383
|
-
import { homedir as
|
|
55384
|
-
import { basename as basename15, join as
|
|
55451
|
+
import { homedir as homedir23 } from "node:os";
|
|
55452
|
+
import { basename as basename15, join as join43, resolve as resolve14 } from "node:path";
|
|
55385
55453
|
function registerProjectRoutes(app) {
|
|
55386
55454
|
app.get("/api/projects", async (req, res) => {
|
|
55387
55455
|
try {
|
|
@@ -55400,7 +55468,7 @@ function registerProjectRoutes(app) {
|
|
|
55400
55468
|
for (const discovered of discoveredProjects) {
|
|
55401
55469
|
if (registeredPaths.has(discovered.path))
|
|
55402
55470
|
continue;
|
|
55403
|
-
if (discovered.path ===
|
|
55471
|
+
if (discovered.path === join43(homedir23(), ".claude"))
|
|
55404
55472
|
continue;
|
|
55405
55473
|
const projectInfo = await detectAndBuildProjectInfo(discovered.path, `discovered-${discovered.path}`);
|
|
55406
55474
|
if (projectInfo) {
|
|
@@ -55416,7 +55484,7 @@ function registerProjectRoutes(app) {
|
|
|
55416
55484
|
if (cwdProject) {
|
|
55417
55485
|
projects.push(cwdProject);
|
|
55418
55486
|
}
|
|
55419
|
-
const globalDir =
|
|
55487
|
+
const globalDir = join43(homedir23(), ".claude");
|
|
55420
55488
|
const globalProject = await detectAndBuildProjectInfo(globalDir, "global");
|
|
55421
55489
|
if (globalProject) {
|
|
55422
55490
|
projects.push(globalProject);
|
|
@@ -55488,12 +55556,12 @@ function registerProjectRoutes(app) {
|
|
|
55488
55556
|
const body = validation.data;
|
|
55489
55557
|
let projectPath = body.path;
|
|
55490
55558
|
if (projectPath.startsWith("~/") || projectPath === "~") {
|
|
55491
|
-
projectPath =
|
|
55559
|
+
projectPath = join43(homedir23(), projectPath.slice(1));
|
|
55492
55560
|
} else if (projectPath.startsWith("~\\")) {
|
|
55493
|
-
projectPath =
|
|
55561
|
+
projectPath = join43(homedir23(), projectPath.slice(1));
|
|
55494
55562
|
}
|
|
55495
55563
|
projectPath = resolve14(projectPath);
|
|
55496
|
-
const homeDir =
|
|
55564
|
+
const homeDir = homedir23();
|
|
55497
55565
|
if (projectPath.includes("..") || !projectPath.startsWith(homeDir)) {
|
|
55498
55566
|
res.status(400).json({ error: "Invalid path after expansion" });
|
|
55499
55567
|
return;
|
|
@@ -55550,7 +55618,7 @@ function registerProjectRoutes(app) {
|
|
|
55550
55618
|
if (id === "current") {
|
|
55551
55619
|
projectPath = process.cwd();
|
|
55552
55620
|
} else if (id === "global") {
|
|
55553
|
-
projectPath =
|
|
55621
|
+
projectPath = join43(homedir23(), ".claude");
|
|
55554
55622
|
} else {
|
|
55555
55623
|
res.status(404).json({ error: "Project not found" });
|
|
55556
55624
|
return;
|
|
@@ -55612,8 +55680,8 @@ function registerProjectRoutes(app) {
|
|
|
55612
55680
|
});
|
|
55613
55681
|
}
|
|
55614
55682
|
async function buildProjectInfoFromRegistry(registered) {
|
|
55615
|
-
const claudeDir2 =
|
|
55616
|
-
const metadataPath =
|
|
55683
|
+
const claudeDir2 = join43(registered.path, ".claude");
|
|
55684
|
+
const metadataPath = join43(claudeDir2, "metadata.json");
|
|
55617
55685
|
if (!existsSync29(registered.path)) {
|
|
55618
55686
|
return null;
|
|
55619
55687
|
}
|
|
@@ -55630,7 +55698,7 @@ async function buildProjectInfoFromRegistry(registered) {
|
|
|
55630
55698
|
const hasLocalConfig = hasClaudeDir && CkConfigManager.projectConfigExists(registered.path, false);
|
|
55631
55699
|
const settings = await readSettings();
|
|
55632
55700
|
const skills = await scanSkills();
|
|
55633
|
-
const settingsPath =
|
|
55701
|
+
const settingsPath = join43(homedir23(), ".claude", "settings.json");
|
|
55634
55702
|
const health = existsSync29(settingsPath) ? "healthy" : "warning";
|
|
55635
55703
|
const model = getCurrentModel() || settings?.model || "claude-sonnet-4";
|
|
55636
55704
|
return {
|
|
@@ -55653,8 +55721,8 @@ async function buildProjectInfoFromRegistry(registered) {
|
|
|
55653
55721
|
};
|
|
55654
55722
|
}
|
|
55655
55723
|
async function detectAndBuildProjectInfo(path5, id) {
|
|
55656
|
-
const claudeDir2 = id === "global" ? path5 :
|
|
55657
|
-
const metadataPath =
|
|
55724
|
+
const claudeDir2 = id === "global" ? path5 : join43(path5, ".claude");
|
|
55725
|
+
const metadataPath = join43(claudeDir2, "metadata.json");
|
|
55658
55726
|
if (!existsSync29(metadataPath)) {
|
|
55659
55727
|
if (!existsSync29(claudeDir2)) {
|
|
55660
55728
|
return null;
|
|
@@ -55672,7 +55740,7 @@ async function detectAndBuildProjectInfo(path5, id) {
|
|
|
55672
55740
|
const hasLocalConfig = CkConfigManager.projectConfigExists(path5, id === "global");
|
|
55673
55741
|
const settings = await readSettings();
|
|
55674
55742
|
const skills = await scanSkills();
|
|
55675
|
-
const settingsPath =
|
|
55743
|
+
const settingsPath = join43(homedir23(), ".claude", "settings.json");
|
|
55676
55744
|
const health = existsSync29(settingsPath) ? "healthy" : "warning";
|
|
55677
55745
|
const model = getCurrentModel() || settings?.model || "claude-sonnet-4";
|
|
55678
55746
|
return {
|
|
@@ -55713,32 +55781,32 @@ var init_project_routes = __esm(() => {
|
|
|
55713
55781
|
});
|
|
55714
55782
|
|
|
55715
55783
|
// src/domains/web-server/routes/session-routes.ts
|
|
55716
|
-
import { homedir as
|
|
55717
|
-
import { join as
|
|
55784
|
+
import { homedir as homedir24 } from "node:os";
|
|
55785
|
+
import { join as join44 } from "node:path";
|
|
55718
55786
|
async function resolveSessionDir(projectId) {
|
|
55719
|
-
const home6 =
|
|
55787
|
+
const home6 = homedir24();
|
|
55720
55788
|
if (projectId.startsWith("discovered-")) {
|
|
55721
55789
|
try {
|
|
55722
55790
|
const encodedPathB64 = projectId.slice("discovered-".length);
|
|
55723
55791
|
const projectPath = Buffer.from(encodedPathB64, "base64url").toString("utf-8");
|
|
55724
55792
|
const claudeEncoded = encodePath(projectPath);
|
|
55725
|
-
return
|
|
55793
|
+
return join44(home6, ".claude", "projects", claudeEncoded);
|
|
55726
55794
|
} catch {
|
|
55727
55795
|
return null;
|
|
55728
55796
|
}
|
|
55729
55797
|
}
|
|
55730
55798
|
if (projectId === "current") {
|
|
55731
55799
|
const cwdEncoded = encodePath(process.cwd());
|
|
55732
|
-
return
|
|
55800
|
+
return join44(home6, ".claude", "projects", cwdEncoded);
|
|
55733
55801
|
}
|
|
55734
55802
|
if (projectId === "global") {
|
|
55735
|
-
const globalEncoded = encodePath(
|
|
55736
|
-
return
|
|
55803
|
+
const globalEncoded = encodePath(join44(home6, ".claude"));
|
|
55804
|
+
return join44(home6, ".claude", "projects", globalEncoded);
|
|
55737
55805
|
}
|
|
55738
55806
|
const registered = await ProjectsRegistryManager.getProject(projectId);
|
|
55739
55807
|
if (registered) {
|
|
55740
55808
|
const claudeEncoded = encodePath(registered.path);
|
|
55741
|
-
return
|
|
55809
|
+
return join44(home6, ".claude", "projects", claudeEncoded);
|
|
55742
55810
|
}
|
|
55743
55811
|
return null;
|
|
55744
55812
|
}
|
|
@@ -55755,7 +55823,7 @@ function registerSessionRoutes(app) {
|
|
|
55755
55823
|
res.status(404).json({ error: "Project not found" });
|
|
55756
55824
|
return;
|
|
55757
55825
|
}
|
|
55758
|
-
const allowedBase =
|
|
55826
|
+
const allowedBase = join44(homedir24(), ".claude", "projects");
|
|
55759
55827
|
if (!projectDir.startsWith(allowedBase)) {
|
|
55760
55828
|
res.status(403).json({ error: "Access denied" });
|
|
55761
55829
|
return;
|
|
@@ -55777,7 +55845,7 @@ var init_session_routes = __esm(() => {
|
|
|
55777
55845
|
});
|
|
55778
55846
|
|
|
55779
55847
|
// src/domains/web-server/routes/settings-routes.ts
|
|
55780
|
-
import { homedir as
|
|
55848
|
+
import { homedir as homedir25 } from "node:os";
|
|
55781
55849
|
function registerSettingsRoutes(app) {
|
|
55782
55850
|
app.get("/api/settings", async (_req, res) => {
|
|
55783
55851
|
try {
|
|
@@ -55833,7 +55901,7 @@ function registerSettingsRoutes(app) {
|
|
|
55833
55901
|
res.json({
|
|
55834
55902
|
success: true,
|
|
55835
55903
|
path: "~/.claude/settings.json",
|
|
55836
|
-
backupPath: saveResult.backupPath ? saveResult.backupPath.replace(
|
|
55904
|
+
backupPath: saveResult.backupPath ? saveResult.backupPath.replace(homedir25(), "~") : null,
|
|
55837
55905
|
absolutePath: getSettingsPath()
|
|
55838
55906
|
});
|
|
55839
55907
|
} catch (error) {
|
|
@@ -55867,8 +55935,8 @@ var init_settings_routes = __esm(() => {
|
|
|
55867
55935
|
|
|
55868
55936
|
// src/commands/skills/agents.ts
|
|
55869
55937
|
import { existsSync as existsSync30, readdirSync as readdirSync4, statSync as statSync5 } from "node:fs";
|
|
55870
|
-
import { homedir as
|
|
55871
|
-
import { join as
|
|
55938
|
+
import { homedir as homedir26, platform as platform5 } from "node:os";
|
|
55939
|
+
import { join as join45 } from "node:path";
|
|
55872
55940
|
function hasInstallSignal2(path5) {
|
|
55873
55941
|
if (!path5 || !existsSync30(path5)) {
|
|
55874
55942
|
return false;
|
|
@@ -55891,14 +55959,14 @@ function hasAnyInstallSignal2(paths) {
|
|
|
55891
55959
|
}
|
|
55892
55960
|
function hasOpenCodeInstallSignal2() {
|
|
55893
55961
|
return hasAnyInstallSignal2([
|
|
55894
|
-
|
|
55895
|
-
|
|
55896
|
-
|
|
55897
|
-
|
|
55898
|
-
|
|
55899
|
-
|
|
55900
|
-
|
|
55901
|
-
|
|
55962
|
+
join45(process.cwd(), "opencode.json"),
|
|
55963
|
+
join45(process.cwd(), "opencode.jsonc"),
|
|
55964
|
+
join45(process.cwd(), ".opencode/agents"),
|
|
55965
|
+
join45(process.cwd(), ".opencode/commands"),
|
|
55966
|
+
join45(home6, ".config/opencode/AGENTS.md"),
|
|
55967
|
+
join45(home6, ".config/opencode/agents"),
|
|
55968
|
+
join45(home6, ".config/opencode/commands"),
|
|
55969
|
+
join45(home6, ".opencode", "bin", OPENCODE_BINARY_NAME2)
|
|
55902
55970
|
]);
|
|
55903
55971
|
}
|
|
55904
55972
|
async function detectInstalledAgents() {
|
|
@@ -55916,7 +55984,7 @@ function getAgentConfig(type) {
|
|
|
55916
55984
|
function getInstallPath(skillName, agent, options2) {
|
|
55917
55985
|
const config = agents[agent];
|
|
55918
55986
|
const basePath = options2.global ? config.globalPath : config.projectPath;
|
|
55919
|
-
return
|
|
55987
|
+
return join45(basePath, skillName);
|
|
55920
55988
|
}
|
|
55921
55989
|
function isSkillInstalled(skillName, agent, options2) {
|
|
55922
55990
|
const installPath = getInstallPath(skillName, agent, options2);
|
|
@@ -55924,106 +55992,106 @@ function isSkillInstalled(skillName, agent, options2) {
|
|
|
55924
55992
|
}
|
|
55925
55993
|
var home6, OPENCODE_BINARY_NAME2, agents;
|
|
55926
55994
|
var init_agents = __esm(() => {
|
|
55927
|
-
home6 =
|
|
55995
|
+
home6 = homedir26();
|
|
55928
55996
|
OPENCODE_BINARY_NAME2 = platform5() === "win32" ? "opencode.exe" : "opencode";
|
|
55929
55997
|
agents = {
|
|
55930
55998
|
"claude-code": {
|
|
55931
55999
|
name: "claude-code",
|
|
55932
56000
|
displayName: "Claude Code",
|
|
55933
56001
|
projectPath: ".claude/skills",
|
|
55934
|
-
globalPath:
|
|
55935
|
-
detect: async () => existsSync30(
|
|
56002
|
+
globalPath: join45(home6, ".claude/skills"),
|
|
56003
|
+
detect: async () => existsSync30(join45(home6, ".claude"))
|
|
55936
56004
|
},
|
|
55937
56005
|
cursor: {
|
|
55938
56006
|
name: "cursor",
|
|
55939
56007
|
displayName: "Cursor",
|
|
55940
56008
|
projectPath: ".cursor/skills",
|
|
55941
|
-
globalPath:
|
|
55942
|
-
detect: async () => existsSync30(
|
|
56009
|
+
globalPath: join45(home6, ".cursor/skills"),
|
|
56010
|
+
detect: async () => existsSync30(join45(home6, ".cursor"))
|
|
55943
56011
|
},
|
|
55944
56012
|
codex: {
|
|
55945
56013
|
name: "codex",
|
|
55946
56014
|
displayName: "Codex",
|
|
55947
56015
|
projectPath: ".codex/skills",
|
|
55948
|
-
globalPath:
|
|
55949
|
-
detect: async () => existsSync30(
|
|
56016
|
+
globalPath: join45(home6, ".codex/skills"),
|
|
56017
|
+
detect: async () => existsSync30(join45(home6, ".codex"))
|
|
55950
56018
|
},
|
|
55951
56019
|
opencode: {
|
|
55952
56020
|
name: "opencode",
|
|
55953
56021
|
displayName: "OpenCode",
|
|
55954
56022
|
projectPath: ".claude/skills",
|
|
55955
|
-
globalPath:
|
|
56023
|
+
globalPath: join45(home6, ".claude/skills"),
|
|
55956
56024
|
detect: async () => hasOpenCodeInstallSignal2()
|
|
55957
56025
|
},
|
|
55958
56026
|
goose: {
|
|
55959
56027
|
name: "goose",
|
|
55960
56028
|
displayName: "Goose",
|
|
55961
56029
|
projectPath: ".goose/skills",
|
|
55962
|
-
globalPath:
|
|
55963
|
-
detect: async () => existsSync30(
|
|
56030
|
+
globalPath: join45(home6, ".config/goose/skills"),
|
|
56031
|
+
detect: async () => existsSync30(join45(home6, ".config/goose"))
|
|
55964
56032
|
},
|
|
55965
56033
|
"gemini-cli": {
|
|
55966
56034
|
name: "gemini-cli",
|
|
55967
56035
|
displayName: "Gemini CLI",
|
|
55968
56036
|
projectPath: ".agents/skills",
|
|
55969
|
-
globalPath:
|
|
55970
|
-
detect: async () => existsSync30(
|
|
56037
|
+
globalPath: join45(home6, ".agents/skills"),
|
|
56038
|
+
detect: async () => existsSync30(join45(home6, ".gemini"))
|
|
55971
56039
|
},
|
|
55972
56040
|
antigravity: {
|
|
55973
56041
|
name: "antigravity",
|
|
55974
56042
|
displayName: "Antigravity",
|
|
55975
56043
|
projectPath: ".agent/skills",
|
|
55976
|
-
globalPath:
|
|
55977
|
-
detect: async () => existsSync30(
|
|
56044
|
+
globalPath: join45(home6, ".gemini/antigravity/skills"),
|
|
56045
|
+
detect: async () => existsSync30(join45(process.cwd(), ".agent")) || existsSync30(join45(home6, ".gemini/antigravity"))
|
|
55978
56046
|
},
|
|
55979
56047
|
"github-copilot": {
|
|
55980
56048
|
name: "github-copilot",
|
|
55981
56049
|
displayName: "GitHub Copilot",
|
|
55982
56050
|
projectPath: ".github/skills",
|
|
55983
|
-
globalPath:
|
|
55984
|
-
detect: async () => existsSync30(
|
|
56051
|
+
globalPath: join45(home6, ".copilot/skills"),
|
|
56052
|
+
detect: async () => existsSync30(join45(home6, ".copilot"))
|
|
55985
56053
|
},
|
|
55986
56054
|
amp: {
|
|
55987
56055
|
name: "amp",
|
|
55988
56056
|
displayName: "Amp",
|
|
55989
56057
|
projectPath: ".agents/skills",
|
|
55990
|
-
globalPath:
|
|
55991
|
-
detect: async () => existsSync30(
|
|
56058
|
+
globalPath: join45(home6, ".config/agents/skills"),
|
|
56059
|
+
detect: async () => existsSync30(join45(home6, ".config/amp"))
|
|
55992
56060
|
},
|
|
55993
56061
|
kilo: {
|
|
55994
56062
|
name: "kilo",
|
|
55995
56063
|
displayName: "Kilo Code",
|
|
55996
56064
|
projectPath: ".kilocode/skills",
|
|
55997
|
-
globalPath:
|
|
55998
|
-
detect: async () => existsSync30(
|
|
56065
|
+
globalPath: join45(home6, ".kilocode/skills"),
|
|
56066
|
+
detect: async () => existsSync30(join45(home6, ".kilocode"))
|
|
55999
56067
|
},
|
|
56000
56068
|
roo: {
|
|
56001
56069
|
name: "roo",
|
|
56002
56070
|
displayName: "Roo Code",
|
|
56003
56071
|
projectPath: ".roo/skills",
|
|
56004
|
-
globalPath:
|
|
56005
|
-
detect: async () => existsSync30(
|
|
56072
|
+
globalPath: join45(home6, ".roo/skills"),
|
|
56073
|
+
detect: async () => existsSync30(join45(home6, ".roo"))
|
|
56006
56074
|
},
|
|
56007
56075
|
windsurf: {
|
|
56008
56076
|
name: "windsurf",
|
|
56009
56077
|
displayName: "Windsurf",
|
|
56010
56078
|
projectPath: ".windsurf/skills",
|
|
56011
|
-
globalPath:
|
|
56012
|
-
detect: async () => existsSync30(
|
|
56079
|
+
globalPath: join45(home6, ".codeium/windsurf/skills"),
|
|
56080
|
+
detect: async () => existsSync30(join45(home6, ".codeium/windsurf"))
|
|
56013
56081
|
},
|
|
56014
56082
|
cline: {
|
|
56015
56083
|
name: "cline",
|
|
56016
56084
|
displayName: "Cline",
|
|
56017
56085
|
projectPath: ".cline/skills",
|
|
56018
|
-
globalPath:
|
|
56019
|
-
detect: async () => existsSync30(
|
|
56086
|
+
globalPath: join45(home6, ".cline/skills"),
|
|
56087
|
+
detect: async () => existsSync30(join45(home6, ".cline"))
|
|
56020
56088
|
},
|
|
56021
56089
|
openhands: {
|
|
56022
56090
|
name: "openhands",
|
|
56023
56091
|
displayName: "OpenHands",
|
|
56024
56092
|
projectPath: ".openhands/skills",
|
|
56025
|
-
globalPath:
|
|
56026
|
-
detect: async () => existsSync30(
|
|
56093
|
+
globalPath: join45(home6, ".openhands/skills"),
|
|
56094
|
+
detect: async () => existsSync30(join45(home6, ".openhands"))
|
|
56027
56095
|
}
|
|
56028
56096
|
};
|
|
56029
56097
|
});
|
|
@@ -56031,8 +56099,8 @@ var init_agents = __esm(() => {
|
|
|
56031
56099
|
// src/commands/skills/skills-registry.ts
|
|
56032
56100
|
import { existsSync as existsSync31 } from "node:fs";
|
|
56033
56101
|
import { mkdir as mkdir11, readFile as readFile23, writeFile as writeFile11 } from "node:fs/promises";
|
|
56034
|
-
import { homedir as
|
|
56035
|
-
import { dirname as dirname17, join as
|
|
56102
|
+
import { homedir as homedir27 } from "node:os";
|
|
56103
|
+
import { dirname as dirname17, join as join46, sep as sep7 } from "node:path";
|
|
56036
56104
|
function getCliVersion3() {
|
|
56037
56105
|
try {
|
|
56038
56106
|
if (process.env.npm_package_version) {
|
|
@@ -56143,8 +56211,8 @@ async function syncRegistry() {
|
|
|
56143
56211
|
var home7, REGISTRY_PATH2, SkillInstallationSchema, SkillRegistrySchema, REGISTRY_PATH_MIGRATIONS;
|
|
56144
56212
|
var init_skills_registry = __esm(() => {
|
|
56145
56213
|
init_zod();
|
|
56146
|
-
home7 =
|
|
56147
|
-
REGISTRY_PATH2 =
|
|
56214
|
+
home7 = homedir27();
|
|
56215
|
+
REGISTRY_PATH2 = join46(home7, ".claudekit", "skill-registry.json");
|
|
56148
56216
|
SkillInstallationSchema = exports_external.object({
|
|
56149
56217
|
skill: exports_external.string(),
|
|
56150
56218
|
agent: exports_external.string(),
|
|
@@ -56175,8 +56243,8 @@ var init_skills_registry = __esm(() => {
|
|
|
56175
56243
|
// src/commands/skills/skills-installer.ts
|
|
56176
56244
|
import { existsSync as existsSync32 } from "node:fs";
|
|
56177
56245
|
import { cp as cp2, mkdir as mkdir12, rm as rm7, stat as stat8 } from "node:fs/promises";
|
|
56178
|
-
import { homedir as
|
|
56179
|
-
import { dirname as dirname18, join as
|
|
56246
|
+
import { homedir as homedir28 } from "node:os";
|
|
56247
|
+
import { dirname as dirname18, join as join47, resolve as resolve15 } from "node:path";
|
|
56180
56248
|
function isSamePath2(path1, path22) {
|
|
56181
56249
|
try {
|
|
56182
56250
|
return resolve15(path1) === resolve15(path22);
|
|
@@ -56208,7 +56276,7 @@ async function cleanupLegacySkillPath(skillName, agent, global3) {
|
|
|
56208
56276
|
if (!legacy)
|
|
56209
56277
|
return;
|
|
56210
56278
|
const legacyBase = global3 ? legacy.global : legacy.project;
|
|
56211
|
-
const legacyPath =
|
|
56279
|
+
const legacyPath = join47(legacyBase, skillName);
|
|
56212
56280
|
if (!existsSync32(legacyPath))
|
|
56213
56281
|
return;
|
|
56214
56282
|
await rm7(legacyPath, { recursive: true, force: true });
|
|
@@ -56218,7 +56286,7 @@ async function cleanupLegacySkillPath(skillName, agent, global3) {
|
|
|
56218
56286
|
if (entry.skill === skillName && entry.agent === agent && entry.global === global3) {
|
|
56219
56287
|
if (entry.path === legacyPath) {
|
|
56220
56288
|
const newBase = global3 ? agents[agent].globalPath : agents[agent].projectPath;
|
|
56221
|
-
entry.path =
|
|
56289
|
+
entry.path = join47(newBase, skillName);
|
|
56222
56290
|
changed = true;
|
|
56223
56291
|
}
|
|
56224
56292
|
}
|
|
@@ -56306,7 +56374,7 @@ var init_skills_installer = __esm(() => {
|
|
|
56306
56374
|
LEGACY_SKILL_PATHS = {
|
|
56307
56375
|
"gemini-cli": {
|
|
56308
56376
|
project: ".gemini/skills",
|
|
56309
|
-
global:
|
|
56377
|
+
global: join47(homedir28(), ".gemini/skills")
|
|
56310
56378
|
}
|
|
56311
56379
|
};
|
|
56312
56380
|
});
|
|
@@ -56314,7 +56382,7 @@ var init_skills_installer = __esm(() => {
|
|
|
56314
56382
|
// src/commands/skills/skills-uninstaller.ts
|
|
56315
56383
|
import { existsSync as existsSync33 } from "node:fs";
|
|
56316
56384
|
import { rm as rm8 } from "node:fs/promises";
|
|
56317
|
-
import { join as
|
|
56385
|
+
import { join as join48, resolve as resolve16 } from "node:path";
|
|
56318
56386
|
function isSamePath3(path1, path22) {
|
|
56319
56387
|
try {
|
|
56320
56388
|
return resolve16(path1) === resolve16(path22);
|
|
@@ -56370,7 +56438,7 @@ async function uninstallSkillFromAgent(skill, agent, global3) {
|
|
|
56370
56438
|
async function forceUninstallSkill(skill, agent, global3) {
|
|
56371
56439
|
const agentConfig = agents[agent];
|
|
56372
56440
|
const basePath = global3 ? agentConfig.globalPath : agentConfig.projectPath;
|
|
56373
|
-
const path5 =
|
|
56441
|
+
const path5 = join48(basePath, skill);
|
|
56374
56442
|
const registry = await readRegistry();
|
|
56375
56443
|
if (!existsSync33(path5)) {
|
|
56376
56444
|
return {
|
|
@@ -56923,7 +56991,7 @@ var init_pnpm_detector = __esm(() => {
|
|
|
56923
56991
|
import { existsSync as existsSync34, realpathSync as realpathSync2 } from "node:fs";
|
|
56924
56992
|
import { chmod as chmod2, mkdir as mkdir13, readFile as readFile24, writeFile as writeFile12 } from "node:fs/promises";
|
|
56925
56993
|
import { platform as platform6 } from "node:os";
|
|
56926
|
-
import { join as
|
|
56994
|
+
import { join as join49 } from "node:path";
|
|
56927
56995
|
function detectFromBinaryPath() {
|
|
56928
56996
|
const normalizePath2 = (pathValue) => pathValue.replace(/\\/g, "/").toLowerCase();
|
|
56929
56997
|
const detectFromNormalizedPath = (normalized) => {
|
|
@@ -57000,7 +57068,7 @@ function detectFromEnv() {
|
|
|
57000
57068
|
}
|
|
57001
57069
|
async function readCachedPm() {
|
|
57002
57070
|
try {
|
|
57003
|
-
const cacheFile =
|
|
57071
|
+
const cacheFile = join49(PathResolver.getConfigDir(false), CACHE_FILE);
|
|
57004
57072
|
if (!existsSync34(cacheFile)) {
|
|
57005
57073
|
return null;
|
|
57006
57074
|
}
|
|
@@ -57031,7 +57099,7 @@ async function saveCachedPm(pm, getVersion) {
|
|
|
57031
57099
|
return;
|
|
57032
57100
|
try {
|
|
57033
57101
|
const configDir = PathResolver.getConfigDir(false);
|
|
57034
|
-
const cacheFile =
|
|
57102
|
+
const cacheFile = join49(configDir, CACHE_FILE);
|
|
57035
57103
|
if (!existsSync34(configDir)) {
|
|
57036
57104
|
await mkdir13(configDir, { recursive: true });
|
|
57037
57105
|
if (platform6() !== "win32") {
|
|
@@ -57094,7 +57162,7 @@ async function findOwningPm() {
|
|
|
57094
57162
|
async function clearCache() {
|
|
57095
57163
|
try {
|
|
57096
57164
|
const { unlink: unlink6 } = await import("node:fs/promises");
|
|
57097
|
-
const cacheFile =
|
|
57165
|
+
const cacheFile = join49(PathResolver.getConfigDir(false), CACHE_FILE);
|
|
57098
57166
|
if (existsSync34(cacheFile)) {
|
|
57099
57167
|
await unlink6(cacheFile);
|
|
57100
57168
|
logger.debug("Package manager cache cleared");
|
|
@@ -57255,7 +57323,7 @@ var package_default;
|
|
|
57255
57323
|
var init_package = __esm(() => {
|
|
57256
57324
|
package_default = {
|
|
57257
57325
|
name: "claudekit-cli",
|
|
57258
|
-
version: "3.41.3-dev.
|
|
57326
|
+
version: "3.41.3-dev.3",
|
|
57259
57327
|
description: "CLI tool for bootstrapping and updating ClaudeKit projects",
|
|
57260
57328
|
type: "module",
|
|
57261
57329
|
repository: {
|
|
@@ -57728,9 +57796,9 @@ var init_package_manager_runner = __esm(() => {
|
|
|
57728
57796
|
});
|
|
57729
57797
|
|
|
57730
57798
|
// src/domains/migration/metadata-migration.ts
|
|
57731
|
-
import { join as
|
|
57799
|
+
import { join as join50 } from "node:path";
|
|
57732
57800
|
async function detectMetadataFormat(claudeDir2) {
|
|
57733
|
-
const metadataPath =
|
|
57801
|
+
const metadataPath = join50(claudeDir2, "metadata.json");
|
|
57734
57802
|
if (!await import_fs_extra6.pathExists(metadataPath)) {
|
|
57735
57803
|
return { format: "none", metadata: null, detectedKit: null };
|
|
57736
57804
|
}
|
|
@@ -57782,7 +57850,7 @@ async function migrateToMultiKit(claudeDir2) {
|
|
|
57782
57850
|
toFormat: "multi-kit"
|
|
57783
57851
|
};
|
|
57784
57852
|
}
|
|
57785
|
-
const metadataPath =
|
|
57853
|
+
const metadataPath = join50(claudeDir2, "metadata.json");
|
|
57786
57854
|
const legacy = detection.metadata;
|
|
57787
57855
|
if (!legacy) {
|
|
57788
57856
|
return {
|
|
@@ -57894,7 +57962,7 @@ var init_metadata_migration = __esm(() => {
|
|
|
57894
57962
|
});
|
|
57895
57963
|
|
|
57896
57964
|
// src/services/file-operations/claudekit-scanner.ts
|
|
57897
|
-
import { join as
|
|
57965
|
+
import { join as join51 } from "node:path";
|
|
57898
57966
|
async function scanClaudeKitDirectory(directoryPath) {
|
|
57899
57967
|
const counts = {
|
|
57900
57968
|
agents: 0,
|
|
@@ -57908,33 +57976,33 @@ async function scanClaudeKitDirectory(directoryPath) {
|
|
|
57908
57976
|
}
|
|
57909
57977
|
const items = await import_fs_extra7.readdir(directoryPath);
|
|
57910
57978
|
if (items.includes("agents")) {
|
|
57911
|
-
const agentsPath =
|
|
57979
|
+
const agentsPath = join51(directoryPath, "agents");
|
|
57912
57980
|
const agentFiles = await import_fs_extra7.readdir(agentsPath);
|
|
57913
57981
|
counts.agents = agentFiles.filter((file) => file.endsWith(".md")).length;
|
|
57914
57982
|
}
|
|
57915
57983
|
if (items.includes("commands")) {
|
|
57916
|
-
const commandsPath =
|
|
57984
|
+
const commandsPath = join51(directoryPath, "commands");
|
|
57917
57985
|
const commandFiles = await import_fs_extra7.readdir(commandsPath);
|
|
57918
57986
|
counts.commands = commandFiles.filter((file) => file.endsWith(".md")).length;
|
|
57919
57987
|
}
|
|
57920
57988
|
if (items.includes("rules")) {
|
|
57921
|
-
const rulesPath =
|
|
57989
|
+
const rulesPath = join51(directoryPath, "rules");
|
|
57922
57990
|
const ruleFiles = await import_fs_extra7.readdir(rulesPath);
|
|
57923
57991
|
counts.rules = ruleFiles.filter((file) => file.endsWith(".md")).length;
|
|
57924
57992
|
} else if (items.includes("workflows")) {
|
|
57925
|
-
const workflowsPath =
|
|
57993
|
+
const workflowsPath = join51(directoryPath, "workflows");
|
|
57926
57994
|
const workflowFiles = await import_fs_extra7.readdir(workflowsPath);
|
|
57927
57995
|
counts.rules = workflowFiles.filter((file) => file.endsWith(".md")).length;
|
|
57928
57996
|
}
|
|
57929
57997
|
if (items.includes("skills")) {
|
|
57930
|
-
const skillsPath =
|
|
57998
|
+
const skillsPath = join51(directoryPath, "skills");
|
|
57931
57999
|
const skillItems = await import_fs_extra7.readdir(skillsPath);
|
|
57932
58000
|
let skillCount = 0;
|
|
57933
58001
|
for (const item of skillItems) {
|
|
57934
58002
|
if (SKIP_DIRS_CLAUDE_INTERNAL.includes(item)) {
|
|
57935
58003
|
continue;
|
|
57936
58004
|
}
|
|
57937
|
-
const itemPath =
|
|
58005
|
+
const itemPath = join51(skillsPath, item);
|
|
57938
58006
|
const stat9 = await import_fs_extra7.readdir(itemPath).catch(() => null);
|
|
57939
58007
|
if (stat9?.includes("SKILL.md")) {
|
|
57940
58008
|
skillCount++;
|
|
@@ -57976,14 +58044,14 @@ async function getClaudeKitSetup(projectDir = process.cwd()) {
|
|
|
57976
58044
|
const globalDir = getGlobalInstallDir();
|
|
57977
58045
|
if (await import_fs_extra7.pathExists(globalDir)) {
|
|
57978
58046
|
setup.global.path = globalDir;
|
|
57979
|
-
setup.global.metadata = await readClaudeKitMetadata(
|
|
58047
|
+
setup.global.metadata = await readClaudeKitMetadata(join51(globalDir, "metadata.json"));
|
|
57980
58048
|
setup.global.components = await scanClaudeKitDirectory(globalDir);
|
|
57981
58049
|
}
|
|
57982
|
-
const projectClaudeDir =
|
|
58050
|
+
const projectClaudeDir = join51(projectDir, ".claude");
|
|
57983
58051
|
const isLocalSameAsGlobal = projectClaudeDir === globalDir;
|
|
57984
58052
|
if (!isLocalSameAsGlobal && await import_fs_extra7.pathExists(projectClaudeDir)) {
|
|
57985
58053
|
setup.project.path = projectClaudeDir;
|
|
57986
|
-
setup.project.metadata = await readClaudeKitMetadata(
|
|
58054
|
+
setup.project.metadata = await readClaudeKitMetadata(join51(projectClaudeDir, "metadata.json"));
|
|
57987
58055
|
setup.project.components = await scanClaudeKitDirectory(projectClaudeDir);
|
|
57988
58056
|
}
|
|
57989
58057
|
return setup;
|
|
@@ -58441,7 +58509,7 @@ var init_error_handler2 = __esm(() => {
|
|
|
58441
58509
|
// src/domains/versioning/release-cache.ts
|
|
58442
58510
|
import { existsSync as existsSync35 } from "node:fs";
|
|
58443
58511
|
import { mkdir as mkdir14, readFile as readFile27, unlink as unlink6, writeFile as writeFile14 } from "node:fs/promises";
|
|
58444
|
-
import { join as
|
|
58512
|
+
import { join as join52 } from "node:path";
|
|
58445
58513
|
var ReleaseCacheEntrySchema, ReleaseCache;
|
|
58446
58514
|
var init_release_cache = __esm(() => {
|
|
58447
58515
|
init_logger();
|
|
@@ -58456,7 +58524,7 @@ var init_release_cache = __esm(() => {
|
|
|
58456
58524
|
static CACHE_TTL_SECONDS = Number(process.env.CK_CACHE_TTL) || 3600;
|
|
58457
58525
|
cacheDir;
|
|
58458
58526
|
constructor() {
|
|
58459
|
-
this.cacheDir =
|
|
58527
|
+
this.cacheDir = join52(PathResolver.getCacheDir(false), ReleaseCache.CACHE_DIR);
|
|
58460
58528
|
}
|
|
58461
58529
|
async get(key) {
|
|
58462
58530
|
const cacheFile = this.getCachePath(key);
|
|
@@ -58514,7 +58582,7 @@ var init_release_cache = __esm(() => {
|
|
|
58514
58582
|
const files = await readdir12(this.cacheDir);
|
|
58515
58583
|
for (const file of files) {
|
|
58516
58584
|
if (file.endsWith(".json")) {
|
|
58517
|
-
await unlink6(
|
|
58585
|
+
await unlink6(join52(this.cacheDir, file));
|
|
58518
58586
|
}
|
|
58519
58587
|
}
|
|
58520
58588
|
logger.debug("All release cache cleared");
|
|
@@ -58525,7 +58593,7 @@ var init_release_cache = __esm(() => {
|
|
|
58525
58593
|
}
|
|
58526
58594
|
getCachePath(key) {
|
|
58527
58595
|
const safeKey = key.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
58528
|
-
return
|
|
58596
|
+
return join52(this.cacheDir, `${safeKey}.json`);
|
|
58529
58597
|
}
|
|
58530
58598
|
isExpired(timestamp) {
|
|
58531
58599
|
const now = Date.now();
|
|
@@ -59166,7 +59234,7 @@ var init_github_client = __esm(() => {
|
|
|
59166
59234
|
|
|
59167
59235
|
// src/commands/update/post-update-handler.ts
|
|
59168
59236
|
import { exec as exec2, spawn as spawn2 } from "node:child_process";
|
|
59169
|
-
import { join as
|
|
59237
|
+
import { join as join53 } from "node:path";
|
|
59170
59238
|
import { promisify as promisify8 } from "node:util";
|
|
59171
59239
|
function selectKitForUpdate(params) {
|
|
59172
59240
|
const { hasLocal, hasGlobal, localKits, globalKits } = params;
|
|
@@ -59198,7 +59266,7 @@ function selectKitForUpdate(params) {
|
|
|
59198
59266
|
};
|
|
59199
59267
|
}
|
|
59200
59268
|
async function readMetadataFile(claudeDir2) {
|
|
59201
|
-
const metadataPath =
|
|
59269
|
+
const metadataPath = join53(claudeDir2, "metadata.json");
|
|
59202
59270
|
try {
|
|
59203
59271
|
if (!await import_fs_extra8.pathExists(metadataPath))
|
|
59204
59272
|
return null;
|
|
@@ -59569,7 +59637,7 @@ var init_update_cli = __esm(() => {
|
|
|
59569
59637
|
// src/domains/versioning/version-cache.ts
|
|
59570
59638
|
import { existsSync as existsSync36 } from "node:fs";
|
|
59571
59639
|
import { mkdir as mkdir15, readFile as readFile29, writeFile as writeFile15 } from "node:fs/promises";
|
|
59572
|
-
import { join as
|
|
59640
|
+
import { join as join54 } from "node:path";
|
|
59573
59641
|
var VersionCacheManager;
|
|
59574
59642
|
var init_version_cache = __esm(() => {
|
|
59575
59643
|
init_logger();
|
|
@@ -59579,7 +59647,7 @@ var init_version_cache = __esm(() => {
|
|
|
59579
59647
|
static CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000;
|
|
59580
59648
|
static getCacheFile() {
|
|
59581
59649
|
const cacheDir = PathResolver.getCacheDir(false);
|
|
59582
|
-
return
|
|
59650
|
+
return join54(cacheDir, VersionCacheManager.CACHE_FILENAME);
|
|
59583
59651
|
}
|
|
59584
59652
|
static async load() {
|
|
59585
59653
|
const cacheFile = VersionCacheManager.getCacheFile();
|
|
@@ -59848,7 +59916,7 @@ var init_version_checker = __esm(() => {
|
|
|
59848
59916
|
import { spawn as spawn3 } from "node:child_process";
|
|
59849
59917
|
import { existsSync as existsSync37 } from "node:fs";
|
|
59850
59918
|
import { readFile as readFile30 } from "node:fs/promises";
|
|
59851
|
-
import { join as
|
|
59919
|
+
import { join as join55 } from "node:path";
|
|
59852
59920
|
function hasCliUpdate(currentVersion, latestVersion) {
|
|
59853
59921
|
if (!latestVersion) {
|
|
59854
59922
|
return false;
|
|
@@ -60091,7 +60159,7 @@ async function getPackageJson() {
|
|
|
60091
60159
|
}
|
|
60092
60160
|
async function getKitMetadata2(kitName) {
|
|
60093
60161
|
try {
|
|
60094
|
-
const metadataPath =
|
|
60162
|
+
const metadataPath = join55(PathResolver.getGlobalKitDir(), "metadata.json");
|
|
60095
60163
|
if (!existsSync37(metadataPath))
|
|
60096
60164
|
return null;
|
|
60097
60165
|
const content = await readFile30(metadataPath, "utf-8");
|
|
@@ -60238,7 +60306,7 @@ var init_routes = __esm(() => {
|
|
|
60238
60306
|
|
|
60239
60307
|
// src/domains/web-server/static-server.ts
|
|
60240
60308
|
import { existsSync as existsSync38 } from "node:fs";
|
|
60241
|
-
import { dirname as dirname19, join as
|
|
60309
|
+
import { dirname as dirname19, join as join56, resolve as resolve17 } from "node:path";
|
|
60242
60310
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
60243
60311
|
function addRuntimeUiCandidate(candidates, runtimePath) {
|
|
60244
60312
|
if (!runtimePath) {
|
|
@@ -60249,21 +60317,21 @@ function addRuntimeUiCandidate(candidates, runtimePath) {
|
|
|
60249
60317
|
return;
|
|
60250
60318
|
}
|
|
60251
60319
|
const entryDir = dirname19(resolve17(runtimePath));
|
|
60252
|
-
candidates.add(
|
|
60253
|
-
candidates.add(
|
|
60320
|
+
candidates.add(join56(entryDir, "ui"));
|
|
60321
|
+
candidates.add(join56(entryDir, "..", "dist", "ui"));
|
|
60254
60322
|
}
|
|
60255
60323
|
function resolveUiDistPath() {
|
|
60256
60324
|
const candidates = new Set;
|
|
60257
60325
|
addRuntimeUiCandidate(candidates, process.argv[1]);
|
|
60258
|
-
candidates.add(
|
|
60259
|
-
candidates.add(
|
|
60260
|
-
candidates.add(
|
|
60326
|
+
candidates.add(join56(__dirname3, "ui"));
|
|
60327
|
+
candidates.add(join56(process.cwd(), "dist", "ui"));
|
|
60328
|
+
candidates.add(join56(process.cwd(), "src", "ui", "dist"));
|
|
60261
60329
|
for (const path5 of candidates) {
|
|
60262
|
-
if (existsSync38(
|
|
60330
|
+
if (existsSync38(join56(path5, "index.html"))) {
|
|
60263
60331
|
return path5;
|
|
60264
60332
|
}
|
|
60265
60333
|
}
|
|
60266
|
-
return Array.from(candidates)[0] ??
|
|
60334
|
+
return Array.from(candidates)[0] ?? join56(process.cwd(), "dist", "ui");
|
|
60267
60335
|
}
|
|
60268
60336
|
function serveStatic(app) {
|
|
60269
60337
|
const uiDistPath = resolveUiDistPath();
|
|
@@ -60299,7 +60367,7 @@ function serveStatic(app) {
|
|
|
60299
60367
|
if (req.path.startsWith("/assets/") || req.path.match(/\.(js|css|ico|png|jpg|svg|woff2?)$/)) {
|
|
60300
60368
|
return next();
|
|
60301
60369
|
}
|
|
60302
|
-
res.sendFile(
|
|
60370
|
+
res.sendFile(join56(uiDistPath, "index.html"), { dotfiles: "allow" });
|
|
60303
60371
|
});
|
|
60304
60372
|
logger.debug(`Serving static files from ${uiDistPath}`);
|
|
60305
60373
|
}
|
|
@@ -65148,7 +65216,7 @@ function getNpmLookupTimeoutMs() {
|
|
|
65148
65216
|
function getNpmInstallTimeoutMs() {
|
|
65149
65217
|
return parseTimeoutMs(process.env.CK_NPM_INSTALL_TIMEOUT_MS, DEFAULT_NPM_INSTALL_TIMEOUT_MS, MIN_NPM_TIMEOUT_MS, MAX_NPM_TIMEOUT_MS);
|
|
65150
65218
|
}
|
|
65151
|
-
function
|
|
65219
|
+
function escapeRegex2(value) {
|
|
65152
65220
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
65153
65221
|
}
|
|
65154
65222
|
async function isPackageInstalled(packageName) {
|
|
@@ -65180,7 +65248,7 @@ async function isPackageInstalled(packageName) {
|
|
|
65180
65248
|
const { stdout: stdout2 } = await execAsync7(`${getNpmCommand()} list -g ${packageName} --depth=0`, {
|
|
65181
65249
|
timeout: getNpmLookupTimeoutMs()
|
|
65182
65250
|
});
|
|
65183
|
-
const exactPattern = new RegExp(`(?:^|\\s|[├└│─]+)${
|
|
65251
|
+
const exactPattern = new RegExp(`(?:^|\\s|[├└│─]+)${escapeRegex2(packageName)}@([^\\s\\n]+)(?:\\s|$)`, "m");
|
|
65184
65252
|
return exactPattern.test(stdout2);
|
|
65185
65253
|
} catch {
|
|
65186
65254
|
return false;
|
|
@@ -65226,8 +65294,8 @@ async function getPackageVersion(packageName) {
|
|
|
65226
65294
|
timeout: getNpmLookupTimeoutMs()
|
|
65227
65295
|
});
|
|
65228
65296
|
const patterns = [
|
|
65229
|
-
new RegExp(`${
|
|
65230
|
-
new RegExp(`${
|
|
65297
|
+
new RegExp(`${escapeRegex2(packageName)}@([^\\s\\n]+)`),
|
|
65298
|
+
new RegExp(`${escapeRegex2(packageName)}@([0-9]+\\.[0-9]+\\.[0-9]+(?:-[\\w.-]+)?)`)
|
|
65231
65299
|
];
|
|
65232
65300
|
for (const pattern of patterns) {
|
|
65233
65301
|
const match = stdout2.match(pattern);
|
|
@@ -65306,7 +65374,7 @@ var init_gemini_installer = __esm(() => {
|
|
|
65306
65374
|
});
|
|
65307
65375
|
|
|
65308
65376
|
// src/services/package-installer/opencode-installer.ts
|
|
65309
|
-
import { join as
|
|
65377
|
+
import { join as join74 } from "node:path";
|
|
65310
65378
|
async function isOpenCodeInstalled() {
|
|
65311
65379
|
try {
|
|
65312
65380
|
await execAsync7("opencode --version", { timeout: 5000 });
|
|
@@ -65329,7 +65397,7 @@ async function installOpenCode() {
|
|
|
65329
65397
|
logger.info(`Installing ${displayName}...`);
|
|
65330
65398
|
const { unlink: unlink11 } = await import("node:fs/promises");
|
|
65331
65399
|
const { tmpdir: tmpdir4 } = await import("node:os");
|
|
65332
|
-
const tempScriptPath =
|
|
65400
|
+
const tempScriptPath = join74(tmpdir4(), "opencode-install.sh");
|
|
65333
65401
|
try {
|
|
65334
65402
|
logger.info("Downloading OpenCode installation script...");
|
|
65335
65403
|
await execFileAsync5("curl", ["-fsSL", "https://opencode.ai/install", "-o", tempScriptPath], {
|
|
@@ -65381,7 +65449,7 @@ var PARTIAL_INSTALL_VERSION = "partial", EXIT_CODE_CRITICAL_FAILURE = 1, EXIT_CO
|
|
|
65381
65449
|
|
|
65382
65450
|
// src/services/package-installer/install-error-handler.ts
|
|
65383
65451
|
import { existsSync as existsSync49, readFileSync as readFileSync14, unlinkSync as unlinkSync2 } from "node:fs";
|
|
65384
|
-
import { join as
|
|
65452
|
+
import { join as join75 } from "node:path";
|
|
65385
65453
|
function parseNameReason(str2) {
|
|
65386
65454
|
const colonIndex = str2.indexOf(":");
|
|
65387
65455
|
if (colonIndex === -1) {
|
|
@@ -65390,7 +65458,7 @@ function parseNameReason(str2) {
|
|
|
65390
65458
|
return [str2.slice(0, colonIndex).trim(), str2.slice(colonIndex + 1).trim()];
|
|
65391
65459
|
}
|
|
65392
65460
|
function displayInstallErrors(skillsDir2) {
|
|
65393
|
-
const summaryPath =
|
|
65461
|
+
const summaryPath = join75(skillsDir2, ".install-error-summary.json");
|
|
65394
65462
|
if (!existsSync49(summaryPath)) {
|
|
65395
65463
|
logger.error("Skills installation failed. Run with --verbose for details.");
|
|
65396
65464
|
return;
|
|
@@ -65481,7 +65549,7 @@ async function checkNeedsSudoPackages() {
|
|
|
65481
65549
|
}
|
|
65482
65550
|
}
|
|
65483
65551
|
function hasInstallState(skillsDir2) {
|
|
65484
|
-
const stateFilePath =
|
|
65552
|
+
const stateFilePath = join75(skillsDir2, ".install-state.json");
|
|
65485
65553
|
return existsSync49(stateFilePath);
|
|
65486
65554
|
}
|
|
65487
65555
|
var WHICH_COMMAND_TIMEOUT_MS = 5000;
|
|
@@ -65490,7 +65558,7 @@ var init_install_error_handler = __esm(() => {
|
|
|
65490
65558
|
});
|
|
65491
65559
|
|
|
65492
65560
|
// src/services/package-installer/skills-installer.ts
|
|
65493
|
-
import { join as
|
|
65561
|
+
import { join as join76 } from "node:path";
|
|
65494
65562
|
async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
65495
65563
|
const { skipConfirm = false, withSudo = false } = options2;
|
|
65496
65564
|
const displayName = "Skills Dependencies";
|
|
@@ -65516,7 +65584,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
65516
65584
|
const clack = await Promise.resolve().then(() => (init_dist2(), exports_dist));
|
|
65517
65585
|
const platform9 = process.platform;
|
|
65518
65586
|
const scriptName = platform9 === "win32" ? "install.ps1" : "install.sh";
|
|
65519
|
-
const scriptPath =
|
|
65587
|
+
const scriptPath = join76(skillsDir2, scriptName);
|
|
65520
65588
|
try {
|
|
65521
65589
|
validateScriptPath(skillsDir2, scriptPath);
|
|
65522
65590
|
} catch (error) {
|
|
@@ -65532,7 +65600,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
65532
65600
|
logger.warning(`Skills installation script not found: ${scriptPath}`);
|
|
65533
65601
|
logger.info("");
|
|
65534
65602
|
logger.info("\uD83D\uDCD6 Manual Installation Instructions:");
|
|
65535
|
-
logger.info(` See: ${
|
|
65603
|
+
logger.info(` See: ${join76(skillsDir2, "INSTALLATION.md")}`);
|
|
65536
65604
|
logger.info("");
|
|
65537
65605
|
logger.info("Quick start:");
|
|
65538
65606
|
logger.info(" cd .claude/skills/ai-multimodal/scripts");
|
|
@@ -65579,7 +65647,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
65579
65647
|
logger.info(` ${platform9 === "win32" ? `powershell -File "${scriptPath}"` : `bash ${scriptPath}`}`);
|
|
65580
65648
|
logger.info("");
|
|
65581
65649
|
logger.info("Or see complete guide:");
|
|
65582
|
-
logger.info(` ${
|
|
65650
|
+
logger.info(` ${join76(skillsDir2, "INSTALLATION.md")}`);
|
|
65583
65651
|
return {
|
|
65584
65652
|
success: false,
|
|
65585
65653
|
package: displayName,
|
|
@@ -65700,7 +65768,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
65700
65768
|
logger.info("\uD83D\uDCD6 Manual Installation Instructions:");
|
|
65701
65769
|
logger.info("");
|
|
65702
65770
|
logger.info("See complete guide:");
|
|
65703
|
-
logger.info(` cat ${
|
|
65771
|
+
logger.info(` cat ${join76(skillsDir2, "INSTALLATION.md")}`);
|
|
65704
65772
|
logger.info("");
|
|
65705
65773
|
logger.info("Quick start:");
|
|
65706
65774
|
logger.info(" cd .claude/skills/ai-multimodal/scripts");
|
|
@@ -65746,7 +65814,7 @@ var init_skills_installer2 = __esm(() => {
|
|
|
65746
65814
|
// src/services/package-installer/gemini-mcp/config-manager.ts
|
|
65747
65815
|
import { existsSync as existsSync50 } from "node:fs";
|
|
65748
65816
|
import { mkdir as mkdir19, readFile as readFile37, writeFile as writeFile20 } from "node:fs/promises";
|
|
65749
|
-
import { dirname as dirname22, join as
|
|
65817
|
+
import { dirname as dirname22, join as join77 } from "node:path";
|
|
65750
65818
|
async function readJsonFile(filePath) {
|
|
65751
65819
|
try {
|
|
65752
65820
|
const content = await readFile37(filePath, "utf-8");
|
|
@@ -65758,7 +65826,7 @@ async function readJsonFile(filePath) {
|
|
|
65758
65826
|
}
|
|
65759
65827
|
}
|
|
65760
65828
|
async function addGeminiToGitignore(projectDir) {
|
|
65761
|
-
const gitignorePath =
|
|
65829
|
+
const gitignorePath = join77(projectDir, ".gitignore");
|
|
65762
65830
|
const geminiPattern = ".gemini/";
|
|
65763
65831
|
try {
|
|
65764
65832
|
let content = "";
|
|
@@ -65849,13 +65917,13 @@ var init_config_manager2 = __esm(() => {
|
|
|
65849
65917
|
|
|
65850
65918
|
// src/services/package-installer/gemini-mcp/validation.ts
|
|
65851
65919
|
import { existsSync as existsSync51, lstatSync, readlinkSync } from "node:fs";
|
|
65852
|
-
import { homedir as
|
|
65853
|
-
import { join as
|
|
65920
|
+
import { homedir as homedir32 } from "node:os";
|
|
65921
|
+
import { join as join78 } from "node:path";
|
|
65854
65922
|
function getGlobalMcpConfigPath() {
|
|
65855
|
-
return
|
|
65923
|
+
return join78(homedir32(), ".claude", ".mcp.json");
|
|
65856
65924
|
}
|
|
65857
65925
|
function getLocalMcpConfigPath(projectDir) {
|
|
65858
|
-
return
|
|
65926
|
+
return join78(projectDir, ".mcp.json");
|
|
65859
65927
|
}
|
|
65860
65928
|
function findMcpConfigPath(projectDir) {
|
|
65861
65929
|
const localPath = getLocalMcpConfigPath(projectDir);
|
|
@@ -65873,9 +65941,9 @@ function findMcpConfigPath(projectDir) {
|
|
|
65873
65941
|
}
|
|
65874
65942
|
function getGeminiSettingsPath(projectDir, isGlobal) {
|
|
65875
65943
|
if (isGlobal) {
|
|
65876
|
-
return
|
|
65944
|
+
return join78(homedir32(), ".gemini", "settings.json");
|
|
65877
65945
|
}
|
|
65878
|
-
return
|
|
65946
|
+
return join78(projectDir, ".gemini", "settings.json");
|
|
65879
65947
|
}
|
|
65880
65948
|
function checkExistingGeminiConfig(projectDir, isGlobal = false) {
|
|
65881
65949
|
const geminiSettingsPath = getGeminiSettingsPath(projectDir, isGlobal);
|
|
@@ -65905,7 +65973,7 @@ var init_validation = __esm(() => {
|
|
|
65905
65973
|
// src/services/package-installer/gemini-mcp/linker-core.ts
|
|
65906
65974
|
import { existsSync as existsSync52 } from "node:fs";
|
|
65907
65975
|
import { mkdir as mkdir20, symlink as symlink3 } from "node:fs/promises";
|
|
65908
|
-
import { dirname as dirname23, join as
|
|
65976
|
+
import { dirname as dirname23, join as join79 } from "node:path";
|
|
65909
65977
|
async function createSymlink(targetPath, linkPath, projectDir, isGlobal) {
|
|
65910
65978
|
const linkDir = dirname23(linkPath);
|
|
65911
65979
|
if (!existsSync52(linkDir)) {
|
|
@@ -65916,7 +65984,7 @@ async function createSymlink(targetPath, linkPath, projectDir, isGlobal) {
|
|
|
65916
65984
|
if (isGlobal) {
|
|
65917
65985
|
symlinkTarget = getGlobalMcpConfigPath();
|
|
65918
65986
|
} else {
|
|
65919
|
-
const localMcpPath =
|
|
65987
|
+
const localMcpPath = join79(projectDir, ".mcp.json");
|
|
65920
65988
|
const isLocalConfig = targetPath === localMcpPath;
|
|
65921
65989
|
symlinkTarget = isLocalConfig ? "../.mcp.json" : targetPath;
|
|
65922
65990
|
}
|
|
@@ -68333,9 +68401,9 @@ __export(exports_worktree_manager, {
|
|
|
68333
68401
|
});
|
|
68334
68402
|
import { existsSync as existsSync60 } from "node:fs";
|
|
68335
68403
|
import { readFile as readFile54, writeFile as writeFile33 } from "node:fs/promises";
|
|
68336
|
-
import { join as
|
|
68404
|
+
import { join as join131 } from "node:path";
|
|
68337
68405
|
async function createWorktree(projectDir, issueNumber, baseBranch) {
|
|
68338
|
-
const worktreePath =
|
|
68406
|
+
const worktreePath = join131(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
|
|
68339
68407
|
const branchName = `ck-watch/issue-${issueNumber}`;
|
|
68340
68408
|
await spawnAndCollect("git", ["fetch", "origin", baseBranch], projectDir).catch(() => {
|
|
68341
68409
|
logger.warning(`[worktree] Could not fetch origin/${baseBranch}, using local`);
|
|
@@ -68353,7 +68421,7 @@ async function createWorktree(projectDir, issueNumber, baseBranch) {
|
|
|
68353
68421
|
return worktreePath;
|
|
68354
68422
|
}
|
|
68355
68423
|
async function removeWorktree(projectDir, issueNumber) {
|
|
68356
|
-
const worktreePath =
|
|
68424
|
+
const worktreePath = join131(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
|
|
68357
68425
|
const branchName = `ck-watch/issue-${issueNumber}`;
|
|
68358
68426
|
try {
|
|
68359
68427
|
await spawnAndCollect("git", ["worktree", "remove", worktreePath, "--force"], projectDir);
|
|
@@ -68367,7 +68435,7 @@ async function listActiveWorktrees(projectDir) {
|
|
|
68367
68435
|
try {
|
|
68368
68436
|
const output2 = await spawnAndCollect("git", ["worktree", "list", "--porcelain"], projectDir);
|
|
68369
68437
|
const issueNumbers = [];
|
|
68370
|
-
const worktreePrefix =
|
|
68438
|
+
const worktreePrefix = join131(projectDir, WORKTREE_DIR, "issue-").replace(/\\/g, "/");
|
|
68371
68439
|
for (const line of output2.split(`
|
|
68372
68440
|
`)) {
|
|
68373
68441
|
if (line.startsWith("worktree ")) {
|
|
@@ -68395,7 +68463,7 @@ async function cleanupAllWorktrees(projectDir) {
|
|
|
68395
68463
|
await spawnAndCollect("git", ["worktree", "prune"], projectDir).catch(() => {});
|
|
68396
68464
|
}
|
|
68397
68465
|
async function ensureGitignore(projectDir) {
|
|
68398
|
-
const gitignorePath =
|
|
68466
|
+
const gitignorePath = join131(projectDir, ".gitignore");
|
|
68399
68467
|
try {
|
|
68400
68468
|
const content = existsSync60(gitignorePath) ? await readFile54(gitignorePath, "utf-8") : "";
|
|
68401
68469
|
if (!content.includes(".worktrees")) {
|
|
@@ -68501,8 +68569,8 @@ var init_content_validator = __esm(() => {
|
|
|
68501
68569
|
import { createHash as createHash7 } from "node:crypto";
|
|
68502
68570
|
import { existsSync as existsSync66, mkdirSync as mkdirSync4, readFileSync as readFileSync15, readdirSync as readdirSync9, statSync as statSync11 } from "node:fs";
|
|
68503
68571
|
import { rename as rename10, writeFile as writeFile35 } from "node:fs/promises";
|
|
68504
|
-
import { homedir as
|
|
68505
|
-
import { basename as basename23, join as
|
|
68572
|
+
import { homedir as homedir37 } from "node:os";
|
|
68573
|
+
import { basename as basename23, join as join138 } from "node:path";
|
|
68506
68574
|
function getCachedContext(repoPath) {
|
|
68507
68575
|
const cachePath = getCacheFilePath(repoPath);
|
|
68508
68576
|
if (!existsSync66(cachePath))
|
|
@@ -68545,25 +68613,25 @@ function computeSourceHash(repoPath) {
|
|
|
68545
68613
|
}
|
|
68546
68614
|
function getDocSourcePaths(repoPath) {
|
|
68547
68615
|
const paths = [];
|
|
68548
|
-
const docsDir =
|
|
68616
|
+
const docsDir = join138(repoPath, "docs");
|
|
68549
68617
|
if (existsSync66(docsDir)) {
|
|
68550
68618
|
try {
|
|
68551
68619
|
const files = readdirSync9(docsDir);
|
|
68552
68620
|
for (const f3 of files) {
|
|
68553
68621
|
if (f3.endsWith(".md"))
|
|
68554
|
-
paths.push(
|
|
68622
|
+
paths.push(join138(docsDir, f3));
|
|
68555
68623
|
}
|
|
68556
68624
|
} catch {}
|
|
68557
68625
|
}
|
|
68558
|
-
const readme =
|
|
68626
|
+
const readme = join138(repoPath, "README.md");
|
|
68559
68627
|
if (existsSync66(readme))
|
|
68560
68628
|
paths.push(readme);
|
|
68561
|
-
const stylesDir =
|
|
68629
|
+
const stylesDir = join138(repoPath, "assets", "writing-styles");
|
|
68562
68630
|
if (existsSync66(stylesDir)) {
|
|
68563
68631
|
try {
|
|
68564
68632
|
const files = readdirSync9(stylesDir);
|
|
68565
68633
|
for (const f3 of files) {
|
|
68566
|
-
paths.push(
|
|
68634
|
+
paths.push(join138(stylesDir, f3));
|
|
68567
68635
|
}
|
|
68568
68636
|
} catch {}
|
|
68569
68637
|
}
|
|
@@ -68572,11 +68640,11 @@ function getDocSourcePaths(repoPath) {
|
|
|
68572
68640
|
function getCacheFilePath(repoPath) {
|
|
68573
68641
|
const repoName = basename23(repoPath).replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
68574
68642
|
const pathHash = createHash7("sha256").update(repoPath).digest("hex").slice(0, 8);
|
|
68575
|
-
return
|
|
68643
|
+
return join138(CACHE_DIR, `${repoName}-${pathHash}-context-cache.json`);
|
|
68576
68644
|
}
|
|
68577
68645
|
var CACHE_DIR, CACHE_TTL_MS4;
|
|
68578
68646
|
var init_context_cache_manager = __esm(() => {
|
|
68579
|
-
CACHE_DIR =
|
|
68647
|
+
CACHE_DIR = join138(homedir37(), ".claudekit", "cache");
|
|
68580
68648
|
CACHE_TTL_MS4 = 24 * 60 * 60 * 1000;
|
|
68581
68649
|
});
|
|
68582
68650
|
|
|
@@ -68757,7 +68825,7 @@ function extractContentFromResponse(response) {
|
|
|
68757
68825
|
// src/commands/content/phases/docs-summarizer.ts
|
|
68758
68826
|
import { execSync as execSync6 } from "node:child_process";
|
|
68759
68827
|
import { existsSync as existsSync67, readFileSync as readFileSync16, readdirSync as readdirSync10 } from "node:fs";
|
|
68760
|
-
import { join as
|
|
68828
|
+
import { join as join139 } from "node:path";
|
|
68761
68829
|
async function summarizeProjectDocs(repoPath, contentLogger) {
|
|
68762
68830
|
const rawContent = collectRawDocs(repoPath);
|
|
68763
68831
|
if (rawContent.total.length < 200) {
|
|
@@ -68811,12 +68879,12 @@ function collectRawDocs(repoPath) {
|
|
|
68811
68879
|
return capped;
|
|
68812
68880
|
};
|
|
68813
68881
|
const docsContent = [];
|
|
68814
|
-
const docsDir =
|
|
68882
|
+
const docsDir = join139(repoPath, "docs");
|
|
68815
68883
|
if (existsSync67(docsDir)) {
|
|
68816
68884
|
try {
|
|
68817
68885
|
const files = readdirSync10(docsDir).filter((f3) => f3.endsWith(".md")).sort();
|
|
68818
68886
|
for (const f3 of files) {
|
|
68819
|
-
const content = readCapped(
|
|
68887
|
+
const content = readCapped(join139(docsDir, f3), 5000);
|
|
68820
68888
|
if (content) {
|
|
68821
68889
|
docsContent.push(`### ${f3}
|
|
68822
68890
|
${content}`);
|
|
@@ -68830,21 +68898,21 @@ ${content}`);
|
|
|
68830
68898
|
let brand = "";
|
|
68831
68899
|
const brandCandidates = ["docs/brand-guidelines.md", "docs/design-guidelines.md"];
|
|
68832
68900
|
for (const p of brandCandidates) {
|
|
68833
|
-
brand = readCapped(
|
|
68901
|
+
brand = readCapped(join139(repoPath, p), 3000);
|
|
68834
68902
|
if (brand)
|
|
68835
68903
|
break;
|
|
68836
68904
|
}
|
|
68837
68905
|
let styles3 = "";
|
|
68838
|
-
const stylesDir =
|
|
68906
|
+
const stylesDir = join139(repoPath, "assets", "writing-styles");
|
|
68839
68907
|
if (existsSync67(stylesDir)) {
|
|
68840
68908
|
try {
|
|
68841
68909
|
const files = readdirSync10(stylesDir).slice(0, 3);
|
|
68842
|
-
styles3 = files.map((f3) => readCapped(
|
|
68910
|
+
styles3 = files.map((f3) => readCapped(join139(stylesDir, f3), 1000)).filter(Boolean).join(`
|
|
68843
68911
|
|
|
68844
68912
|
`);
|
|
68845
68913
|
} catch {}
|
|
68846
68914
|
}
|
|
68847
|
-
const readme = readCapped(
|
|
68915
|
+
const readme = readCapped(join139(repoPath, "README.md"), 3000);
|
|
68848
68916
|
const total = [docs, brand, styles3, readme].join(`
|
|
68849
68917
|
`);
|
|
68850
68918
|
return { docs, brand, styles: styles3, readme, total };
|
|
@@ -69030,10 +69098,10 @@ IMPORTANT: Generate the image and output the path as JSON: {"imagePath": "/path/
|
|
|
69030
69098
|
// src/commands/content/phases/photo-generator.ts
|
|
69031
69099
|
import { execSync as execSync7 } from "node:child_process";
|
|
69032
69100
|
import { existsSync as existsSync68, mkdirSync as mkdirSync5, readdirSync as readdirSync11 } from "node:fs";
|
|
69033
|
-
import { homedir as
|
|
69034
|
-
import { join as
|
|
69101
|
+
import { homedir as homedir38 } from "node:os";
|
|
69102
|
+
import { join as join140 } from "node:path";
|
|
69035
69103
|
async function generatePhoto(_content, context, config, platform16, contentId, contentLogger) {
|
|
69036
|
-
const mediaDir =
|
|
69104
|
+
const mediaDir = join140(config.contentDir.replace(/^~/, homedir38()), "media", String(contentId));
|
|
69037
69105
|
if (!existsSync68(mediaDir)) {
|
|
69038
69106
|
mkdirSync5(mediaDir, { recursive: true });
|
|
69039
69107
|
}
|
|
@@ -69058,7 +69126,7 @@ async function generatePhoto(_content, context, config, platform16, contentId, c
|
|
|
69058
69126
|
const imageFile = files.find((f3) => /\.(png|jpg|jpeg|webp)$/i.test(f3));
|
|
69059
69127
|
if (imageFile) {
|
|
69060
69128
|
const ext2 = imageFile.split(".").pop() ?? "png";
|
|
69061
|
-
return { path:
|
|
69129
|
+
return { path: join140(mediaDir, imageFile), ...dimensions, format: ext2 };
|
|
69062
69130
|
}
|
|
69063
69131
|
contentLogger.warn(`Photo generation produced no image for content ${contentId}`);
|
|
69064
69132
|
return null;
|
|
@@ -69147,8 +69215,8 @@ var init_content_creator = __esm(() => {
|
|
|
69147
69215
|
|
|
69148
69216
|
// src/commands/content/phases/content-logger.ts
|
|
69149
69217
|
import { createWriteStream as createWriteStream4, existsSync as existsSync69, mkdirSync as mkdirSync6, statSync as statSync12 } from "node:fs";
|
|
69150
|
-
import { homedir as
|
|
69151
|
-
import { join as
|
|
69218
|
+
import { homedir as homedir39 } from "node:os";
|
|
69219
|
+
import { join as join141 } from "node:path";
|
|
69152
69220
|
|
|
69153
69221
|
class ContentLogger {
|
|
69154
69222
|
stream = null;
|
|
@@ -69156,7 +69224,7 @@ class ContentLogger {
|
|
|
69156
69224
|
logDir;
|
|
69157
69225
|
maxBytes;
|
|
69158
69226
|
constructor(maxBytes = 0) {
|
|
69159
|
-
this.logDir =
|
|
69227
|
+
this.logDir = join141(homedir39(), ".claudekit", "logs");
|
|
69160
69228
|
this.maxBytes = maxBytes;
|
|
69161
69229
|
}
|
|
69162
69230
|
init() {
|
|
@@ -69188,7 +69256,7 @@ class ContentLogger {
|
|
|
69188
69256
|
}
|
|
69189
69257
|
}
|
|
69190
69258
|
getLogPath() {
|
|
69191
|
-
return
|
|
69259
|
+
return join141(this.logDir, `content-${this.getDateStr()}.log`);
|
|
69192
69260
|
}
|
|
69193
69261
|
write(level, message) {
|
|
69194
69262
|
this.rotateIfNeeded();
|
|
@@ -69205,18 +69273,18 @@ class ContentLogger {
|
|
|
69205
69273
|
if (dateStr !== this.currentDate) {
|
|
69206
69274
|
this.close();
|
|
69207
69275
|
this.currentDate = dateStr;
|
|
69208
|
-
const logPath =
|
|
69276
|
+
const logPath = join141(this.logDir, `content-${dateStr}.log`);
|
|
69209
69277
|
this.stream = createWriteStream4(logPath, { flags: "a", mode: 384 });
|
|
69210
69278
|
return;
|
|
69211
69279
|
}
|
|
69212
69280
|
if (this.maxBytes > 0 && this.stream) {
|
|
69213
|
-
const logPath =
|
|
69281
|
+
const logPath = join141(this.logDir, `content-${this.currentDate}.log`);
|
|
69214
69282
|
try {
|
|
69215
69283
|
const stat21 = statSync12(logPath);
|
|
69216
69284
|
if (stat21.size >= this.maxBytes) {
|
|
69217
69285
|
this.close();
|
|
69218
69286
|
const suffix = Date.now();
|
|
69219
|
-
const rotatedPath =
|
|
69287
|
+
const rotatedPath = join141(this.logDir, `content-${this.currentDate}-${suffix}.log`);
|
|
69220
69288
|
import("node:fs/promises").then(({ rename: rename11 }) => rename11(logPath, rotatedPath).catch(() => {}));
|
|
69221
69289
|
this.stream = createWriteStream4(logPath, { flags: "w", mode: 384 });
|
|
69222
69290
|
}
|
|
@@ -69254,7 +69322,7 @@ var init_sqlite_client = () => {};
|
|
|
69254
69322
|
|
|
69255
69323
|
// src/commands/content/phases/db-manager.ts
|
|
69256
69324
|
import { existsSync as existsSync70, mkdirSync as mkdirSync7 } from "node:fs";
|
|
69257
|
-
import { dirname as
|
|
69325
|
+
import { dirname as dirname36 } from "node:path";
|
|
69258
69326
|
function initDatabase(dbPath) {
|
|
69259
69327
|
ensureParentDir(dbPath);
|
|
69260
69328
|
const db = openDatabase(dbPath);
|
|
@@ -69275,7 +69343,7 @@ function runRetentionCleanup(db, retentionDays = 90) {
|
|
|
69275
69343
|
db.prepare("DELETE FROM git_events WHERE processed = 1 AND created_at < ?").run(cutoff);
|
|
69276
69344
|
}
|
|
69277
69345
|
function ensureParentDir(dbPath) {
|
|
69278
|
-
const dir =
|
|
69346
|
+
const dir = dirname36(dbPath);
|
|
69279
69347
|
if (dir && !existsSync70(dir)) {
|
|
69280
69348
|
mkdirSync7(dir, { recursive: true });
|
|
69281
69349
|
}
|
|
@@ -69442,7 +69510,7 @@ function isNoiseCommit(title, author) {
|
|
|
69442
69510
|
// src/commands/content/phases/change-detector.ts
|
|
69443
69511
|
import { execSync as execSync9 } from "node:child_process";
|
|
69444
69512
|
import { existsSync as existsSync71, readFileSync as readFileSync17, readdirSync as readdirSync12, statSync as statSync13 } from "node:fs";
|
|
69445
|
-
import { join as
|
|
69513
|
+
import { join as join142 } from "node:path";
|
|
69446
69514
|
function detectCommits(repo, since) {
|
|
69447
69515
|
try {
|
|
69448
69516
|
const fetchUrl = sshToHttps(repo.remoteUrl);
|
|
@@ -69540,7 +69608,7 @@ function detectTags(repo, since) {
|
|
|
69540
69608
|
}
|
|
69541
69609
|
}
|
|
69542
69610
|
function detectCompletedPlans(repo, since) {
|
|
69543
|
-
const plansDir =
|
|
69611
|
+
const plansDir = join142(repo.path, "plans");
|
|
69544
69612
|
if (!existsSync71(plansDir))
|
|
69545
69613
|
return [];
|
|
69546
69614
|
const sinceMs = new Date(since).getTime();
|
|
@@ -69550,7 +69618,7 @@ function detectCompletedPlans(repo, since) {
|
|
|
69550
69618
|
for (const entry of entries) {
|
|
69551
69619
|
if (!entry.isDirectory())
|
|
69552
69620
|
continue;
|
|
69553
|
-
const planFile =
|
|
69621
|
+
const planFile = join142(plansDir, entry.name, "plan.md");
|
|
69554
69622
|
if (!existsSync71(planFile))
|
|
69555
69623
|
continue;
|
|
69556
69624
|
try {
|
|
@@ -69628,7 +69696,7 @@ function classifyCommit(event) {
|
|
|
69628
69696
|
// src/commands/content/phases/repo-discoverer.ts
|
|
69629
69697
|
import { execSync as execSync10 } from "node:child_process";
|
|
69630
69698
|
import { readdirSync as readdirSync13 } from "node:fs";
|
|
69631
|
-
import { join as
|
|
69699
|
+
import { join as join143 } from "node:path";
|
|
69632
69700
|
function discoverRepos2(cwd2) {
|
|
69633
69701
|
const repos = [];
|
|
69634
69702
|
if (isGitRepoRoot(cwd2)) {
|
|
@@ -69641,7 +69709,7 @@ function discoverRepos2(cwd2) {
|
|
|
69641
69709
|
for (const entry of entries) {
|
|
69642
69710
|
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
69643
69711
|
continue;
|
|
69644
|
-
const dirPath =
|
|
69712
|
+
const dirPath = join143(cwd2, entry.name);
|
|
69645
69713
|
if (isGitRepoRoot(dirPath)) {
|
|
69646
69714
|
const info = getRepoInfo(dirPath);
|
|
69647
69715
|
if (info)
|
|
@@ -70308,9 +70376,9 @@ var init_types6 = __esm(() => {
|
|
|
70308
70376
|
|
|
70309
70377
|
// src/commands/content/phases/state-manager.ts
|
|
70310
70378
|
import { readFile as readFile56, rename as rename11, writeFile as writeFile36 } from "node:fs/promises";
|
|
70311
|
-
import { join as
|
|
70379
|
+
import { join as join144 } from "node:path";
|
|
70312
70380
|
async function loadContentConfig(projectDir) {
|
|
70313
|
-
const configPath =
|
|
70381
|
+
const configPath = join144(projectDir, CK_CONFIG_FILE2);
|
|
70314
70382
|
try {
|
|
70315
70383
|
const raw2 = await readFile56(configPath, "utf-8");
|
|
70316
70384
|
const json = JSON.parse(raw2);
|
|
@@ -70320,13 +70388,13 @@ async function loadContentConfig(projectDir) {
|
|
|
70320
70388
|
}
|
|
70321
70389
|
}
|
|
70322
70390
|
async function saveContentConfig(projectDir, config) {
|
|
70323
|
-
const configPath =
|
|
70391
|
+
const configPath = join144(projectDir, CK_CONFIG_FILE2);
|
|
70324
70392
|
const json = await readJsonSafe(configPath);
|
|
70325
70393
|
json.content = { ...json.content, ...config };
|
|
70326
70394
|
await atomicWrite(configPath, json);
|
|
70327
70395
|
}
|
|
70328
70396
|
async function loadContentState(projectDir) {
|
|
70329
|
-
const configPath =
|
|
70397
|
+
const configPath = join144(projectDir, CK_CONFIG_FILE2);
|
|
70330
70398
|
try {
|
|
70331
70399
|
const raw2 = await readFile56(configPath, "utf-8");
|
|
70332
70400
|
const json = JSON.parse(raw2);
|
|
@@ -70337,7 +70405,7 @@ async function loadContentState(projectDir) {
|
|
|
70337
70405
|
}
|
|
70338
70406
|
}
|
|
70339
70407
|
async function saveContentState(projectDir, state) {
|
|
70340
|
-
const configPath =
|
|
70408
|
+
const configPath = join144(projectDir, CK_CONFIG_FILE2);
|
|
70341
70409
|
const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().slice(0, 10);
|
|
70342
70410
|
for (const key of Object.keys(state.dailyPostCounts)) {
|
|
70343
70411
|
const dateStr = key.slice(-10);
|
|
@@ -70619,7 +70687,7 @@ var init_platform_setup_x = __esm(() => {
|
|
|
70619
70687
|
|
|
70620
70688
|
// src/commands/content/phases/setup-wizard.ts
|
|
70621
70689
|
import { existsSync as existsSync72 } from "node:fs";
|
|
70622
|
-
import { join as
|
|
70690
|
+
import { join as join145 } from "node:path";
|
|
70623
70691
|
async function runSetupWizard2(cwd2, contentLogger) {
|
|
70624
70692
|
console.log();
|
|
70625
70693
|
oe(import_picocolors42.default.bgCyan(import_picocolors42.default.white(" CK Content — Multi-Channel Content Engine ")));
|
|
@@ -70687,8 +70755,8 @@ async function showRepoSummary(cwd2) {
|
|
|
70687
70755
|
function detectBrandAssets(cwd2, contentLogger) {
|
|
70688
70756
|
const repos = discoverRepos2(cwd2);
|
|
70689
70757
|
for (const repo of repos) {
|
|
70690
|
-
const hasGuidelines = existsSync72(
|
|
70691
|
-
const hasStyles = existsSync72(
|
|
70758
|
+
const hasGuidelines = existsSync72(join145(repo.path, "docs", "brand-guidelines.md"));
|
|
70759
|
+
const hasStyles = existsSync72(join145(repo.path, "assets", "writing-styles"));
|
|
70692
70760
|
if (!hasGuidelines) {
|
|
70693
70761
|
f2.warning(`${repo.name}: No docs/brand-guidelines.md — content will use generic tone.`);
|
|
70694
70762
|
contentLogger.warn(`${repo.name}: missing docs/brand-guidelines.md`);
|
|
@@ -70755,11 +70823,11 @@ var init_setup_wizard = __esm(() => {
|
|
|
70755
70823
|
|
|
70756
70824
|
// src/commands/content/content-review-commands.ts
|
|
70757
70825
|
import { existsSync as existsSync73 } from "node:fs";
|
|
70758
|
-
import { homedir as
|
|
70826
|
+
import { homedir as homedir40 } from "node:os";
|
|
70759
70827
|
async function queueContent() {
|
|
70760
70828
|
const cwd2 = process.cwd();
|
|
70761
70829
|
const config = await loadContentConfig(cwd2);
|
|
70762
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
70830
|
+
const dbPath = config.dbPath.replace(/^~/, homedir40());
|
|
70763
70831
|
if (!existsSync73(dbPath)) {
|
|
70764
70832
|
logger.info("No content database found. Run 'ck content setup' first.");
|
|
70765
70833
|
return;
|
|
@@ -70786,7 +70854,7 @@ async function queueContent() {
|
|
|
70786
70854
|
async function approveContentCmd(id) {
|
|
70787
70855
|
const cwd2 = process.cwd();
|
|
70788
70856
|
const config = await loadContentConfig(cwd2);
|
|
70789
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
70857
|
+
const dbPath = config.dbPath.replace(/^~/, homedir40());
|
|
70790
70858
|
const db = initDatabase(dbPath);
|
|
70791
70859
|
try {
|
|
70792
70860
|
approveContent(db, Number.parseInt(id, 10));
|
|
@@ -70798,7 +70866,7 @@ async function approveContentCmd(id) {
|
|
|
70798
70866
|
async function rejectContentCmd(id, reason) {
|
|
70799
70867
|
const cwd2 = process.cwd();
|
|
70800
70868
|
const config = await loadContentConfig(cwd2);
|
|
70801
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
70869
|
+
const dbPath = config.dbPath.replace(/^~/, homedir40());
|
|
70802
70870
|
const db = initDatabase(dbPath);
|
|
70803
70871
|
try {
|
|
70804
70872
|
rejectContent(db, Number.parseInt(id, 10), reason);
|
|
@@ -70829,10 +70897,10 @@ __export(exports_content_subcommands, {
|
|
|
70829
70897
|
approveContentCmd: () => approveContentCmd
|
|
70830
70898
|
});
|
|
70831
70899
|
import { existsSync as existsSync74, readFileSync as readFileSync18, unlinkSync as unlinkSync5 } from "node:fs";
|
|
70832
|
-
import { homedir as
|
|
70833
|
-
import { join as
|
|
70900
|
+
import { homedir as homedir41 } from "node:os";
|
|
70901
|
+
import { join as join146 } from "node:path";
|
|
70834
70902
|
function isDaemonRunning() {
|
|
70835
|
-
const lockFile =
|
|
70903
|
+
const lockFile = join146(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
70836
70904
|
if (!existsSync74(lockFile))
|
|
70837
70905
|
return { running: false, pid: null };
|
|
70838
70906
|
try {
|
|
@@ -70864,7 +70932,7 @@ async function startContent(options2) {
|
|
|
70864
70932
|
await contentCommand(options2);
|
|
70865
70933
|
}
|
|
70866
70934
|
async function stopContent() {
|
|
70867
|
-
const lockFile =
|
|
70935
|
+
const lockFile = join146(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
70868
70936
|
if (!existsSync74(lockFile)) {
|
|
70869
70937
|
logger.info("Content daemon is not running.");
|
|
70870
70938
|
return;
|
|
@@ -70903,9 +70971,9 @@ async function statusContent() {
|
|
|
70903
70971
|
} catch {}
|
|
70904
70972
|
}
|
|
70905
70973
|
async function logsContent(options2) {
|
|
70906
|
-
const logDir =
|
|
70974
|
+
const logDir = join146(homedir41(), ".claudekit", "logs");
|
|
70907
70975
|
const dateStr = new Date().toISOString().slice(0, 10).replace(/-/g, "");
|
|
70908
|
-
const logPath =
|
|
70976
|
+
const logPath = join146(logDir, `content-${dateStr}.log`);
|
|
70909
70977
|
if (!existsSync74(logPath)) {
|
|
70910
70978
|
logger.info("No content logs found for today.");
|
|
70911
70979
|
return;
|
|
@@ -70937,13 +71005,13 @@ var init_content_subcommands = __esm(() => {
|
|
|
70937
71005
|
init_setup_wizard();
|
|
70938
71006
|
init_state_manager();
|
|
70939
71007
|
init_content_review_commands();
|
|
70940
|
-
LOCK_DIR =
|
|
71008
|
+
LOCK_DIR = join146(homedir41(), ".claudekit", "locks");
|
|
70941
71009
|
});
|
|
70942
71010
|
|
|
70943
71011
|
// src/commands/content/content-command.ts
|
|
70944
71012
|
import { existsSync as existsSync75, mkdirSync as mkdirSync8, unlinkSync as unlinkSync6, writeFileSync as writeFileSync6 } from "node:fs";
|
|
70945
|
-
import { homedir as
|
|
70946
|
-
import { join as
|
|
71013
|
+
import { homedir as homedir42 } from "node:os";
|
|
71014
|
+
import { join as join147 } from "node:path";
|
|
70947
71015
|
async function contentCommand(options2) {
|
|
70948
71016
|
const cwd2 = process.cwd();
|
|
70949
71017
|
const contentLogger = new ContentLogger;
|
|
@@ -70975,7 +71043,7 @@ async function contentCommand(options2) {
|
|
|
70975
71043
|
if (!existsSync75(LOCK_DIR2))
|
|
70976
71044
|
mkdirSync8(LOCK_DIR2, { recursive: true });
|
|
70977
71045
|
writeFileSync6(LOCK_FILE, String(process.pid), "utf-8");
|
|
70978
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
71046
|
+
const dbPath = config.dbPath.replace(/^~/, homedir42());
|
|
70979
71047
|
const db = initDatabase(dbPath);
|
|
70980
71048
|
contentLogger.info(`Database initialised at ${dbPath}`);
|
|
70981
71049
|
const adapters = initializeAdapters(config);
|
|
@@ -71121,8 +71189,8 @@ var init_content_command = __esm(() => {
|
|
|
71121
71189
|
init_publisher();
|
|
71122
71190
|
init_review_manager();
|
|
71123
71191
|
init_state_manager();
|
|
71124
|
-
LOCK_DIR2 =
|
|
71125
|
-
LOCK_FILE =
|
|
71192
|
+
LOCK_DIR2 = join147(homedir42(), ".claudekit", "locks");
|
|
71193
|
+
LOCK_FILE = join147(LOCK_DIR2, "ck-content.lock");
|
|
71126
71194
|
});
|
|
71127
71195
|
|
|
71128
71196
|
// src/commands/content/index.ts
|
|
@@ -77985,14 +78053,14 @@ async function checkCliInstallMethod() {
|
|
|
77985
78053
|
}
|
|
77986
78054
|
// src/domains/health-checks/checkers/claude-md-checker.ts
|
|
77987
78055
|
import { existsSync as existsSync40, statSync as statSync6 } from "node:fs";
|
|
77988
|
-
import { join as
|
|
78056
|
+
import { join as join57 } from "node:path";
|
|
77989
78057
|
function checkClaudeMd(setup, projectDir) {
|
|
77990
78058
|
const results = [];
|
|
77991
78059
|
if (setup.global.path) {
|
|
77992
|
-
const globalClaudeMd =
|
|
78060
|
+
const globalClaudeMd = join57(setup.global.path, "CLAUDE.md");
|
|
77993
78061
|
results.push(checkClaudeMdFile(globalClaudeMd, "Global CLAUDE.md", "ck-global-claude-md"));
|
|
77994
78062
|
}
|
|
77995
|
-
const projectClaudeMd =
|
|
78063
|
+
const projectClaudeMd = join57(projectDir, ".claude", "CLAUDE.md");
|
|
77996
78064
|
results.push(checkClaudeMdFile(projectClaudeMd, "Project CLAUDE.md", "ck-project-claude-md"));
|
|
77997
78065
|
return results;
|
|
77998
78066
|
}
|
|
@@ -78051,9 +78119,9 @@ function checkClaudeMdFile(path5, name, id) {
|
|
|
78051
78119
|
}
|
|
78052
78120
|
// src/domains/health-checks/checkers/active-plan-checker.ts
|
|
78053
78121
|
import { existsSync as existsSync41, readFileSync as readFileSync11 } from "node:fs";
|
|
78054
|
-
import { join as
|
|
78122
|
+
import { join as join58 } from "node:path";
|
|
78055
78123
|
function checkActivePlan(projectDir) {
|
|
78056
|
-
const activePlanPath =
|
|
78124
|
+
const activePlanPath = join58(projectDir, ".claude", "active-plan");
|
|
78057
78125
|
if (!existsSync41(activePlanPath)) {
|
|
78058
78126
|
return {
|
|
78059
78127
|
id: "ck-active-plan",
|
|
@@ -78067,7 +78135,7 @@ function checkActivePlan(projectDir) {
|
|
|
78067
78135
|
}
|
|
78068
78136
|
try {
|
|
78069
78137
|
const targetPath = readFileSync11(activePlanPath, "utf-8").trim();
|
|
78070
|
-
const fullPath =
|
|
78138
|
+
const fullPath = join58(projectDir, targetPath);
|
|
78071
78139
|
if (!existsSync41(fullPath)) {
|
|
78072
78140
|
return {
|
|
78073
78141
|
id: "ck-active-plan",
|
|
@@ -78105,13 +78173,13 @@ function checkActivePlan(projectDir) {
|
|
|
78105
78173
|
}
|
|
78106
78174
|
// src/domains/health-checks/checkers/skills-checker.ts
|
|
78107
78175
|
import { existsSync as existsSync42 } from "node:fs";
|
|
78108
|
-
import { join as
|
|
78176
|
+
import { join as join59 } from "node:path";
|
|
78109
78177
|
function checkSkillsScripts(setup) {
|
|
78110
78178
|
const results = [];
|
|
78111
78179
|
const platform7 = process.platform;
|
|
78112
78180
|
const scriptName = platform7 === "win32" ? "install.ps1" : "install.sh";
|
|
78113
78181
|
if (setup.global.path) {
|
|
78114
|
-
const globalScriptPath =
|
|
78182
|
+
const globalScriptPath = join59(setup.global.path, "skills", scriptName);
|
|
78115
78183
|
const hasGlobalScript = existsSync42(globalScriptPath);
|
|
78116
78184
|
results.push({
|
|
78117
78185
|
id: "ck-global-skills-script",
|
|
@@ -78126,7 +78194,7 @@ function checkSkillsScripts(setup) {
|
|
|
78126
78194
|
});
|
|
78127
78195
|
}
|
|
78128
78196
|
if (setup.project.metadata) {
|
|
78129
|
-
const projectScriptPath =
|
|
78197
|
+
const projectScriptPath = join59(setup.project.path, "skills", scriptName);
|
|
78130
78198
|
const hasProjectScript = existsSync42(projectScriptPath);
|
|
78131
78199
|
results.push({
|
|
78132
78200
|
id: "ck-project-skills-script",
|
|
@@ -78165,7 +78233,7 @@ function checkComponentCounts(setup) {
|
|
|
78165
78233
|
init_logger();
|
|
78166
78234
|
init_path_resolver();
|
|
78167
78235
|
import { constants as constants2, access as access2, unlink as unlink7, writeFile as writeFile16 } from "node:fs/promises";
|
|
78168
|
-
import { join as
|
|
78236
|
+
import { join as join60 } from "node:path";
|
|
78169
78237
|
|
|
78170
78238
|
// src/domains/health-checks/checkers/shared.ts
|
|
78171
78239
|
init_environment();
|
|
@@ -78231,7 +78299,7 @@ async function checkGlobalDirWritable() {
|
|
|
78231
78299
|
}
|
|
78232
78300
|
const timestamp = Date.now();
|
|
78233
78301
|
const random = Math.random().toString(36).substring(2);
|
|
78234
|
-
const testFile =
|
|
78302
|
+
const testFile = join60(globalDir, `.ck-write-test-${timestamp}-${random}`);
|
|
78235
78303
|
try {
|
|
78236
78304
|
await writeFile16(testFile, "test", { encoding: "utf-8", flag: "wx" });
|
|
78237
78305
|
} catch (error) {
|
|
@@ -78267,7 +78335,7 @@ async function checkGlobalDirWritable() {
|
|
|
78267
78335
|
init_path_resolver();
|
|
78268
78336
|
import { existsSync as existsSync43 } from "node:fs";
|
|
78269
78337
|
import { readdir as readdir12 } from "node:fs/promises";
|
|
78270
|
-
import { join as
|
|
78338
|
+
import { join as join61 } from "node:path";
|
|
78271
78339
|
|
|
78272
78340
|
// src/domains/health-checks/utils/path-normalizer.ts
|
|
78273
78341
|
import { normalize as normalize5 } from "node:path";
|
|
@@ -78279,8 +78347,8 @@ function normalizePath2(filePath) {
|
|
|
78279
78347
|
|
|
78280
78348
|
// src/domains/health-checks/checkers/hooks-checker.ts
|
|
78281
78349
|
async function checkHooksExist(projectDir) {
|
|
78282
|
-
const globalHooksDir =
|
|
78283
|
-
const projectHooksDir =
|
|
78350
|
+
const globalHooksDir = join61(PathResolver.getGlobalKitDir(), "hooks");
|
|
78351
|
+
const projectHooksDir = join61(projectDir, ".claude", "hooks");
|
|
78284
78352
|
const globalExists = existsSync43(globalHooksDir);
|
|
78285
78353
|
const projectExists = existsSync43(projectHooksDir);
|
|
78286
78354
|
let hookCount = 0;
|
|
@@ -78289,7 +78357,7 @@ async function checkHooksExist(projectDir) {
|
|
|
78289
78357
|
const files = await readdir12(globalHooksDir, { withFileTypes: false });
|
|
78290
78358
|
const hooks = files.filter((f3) => HOOK_EXTENSIONS2.some((ext) => f3.endsWith(ext)));
|
|
78291
78359
|
hooks.forEach((hook) => {
|
|
78292
|
-
const fullPath =
|
|
78360
|
+
const fullPath = join61(globalHooksDir, hook);
|
|
78293
78361
|
checkedFiles.add(normalizePath2(fullPath));
|
|
78294
78362
|
});
|
|
78295
78363
|
}
|
|
@@ -78299,7 +78367,7 @@ async function checkHooksExist(projectDir) {
|
|
|
78299
78367
|
const files = await readdir12(projectHooksDir, { withFileTypes: false });
|
|
78300
78368
|
const hooks = files.filter((f3) => HOOK_EXTENSIONS2.some((ext) => f3.endsWith(ext)));
|
|
78301
78369
|
hooks.forEach((hook) => {
|
|
78302
|
-
const fullPath =
|
|
78370
|
+
const fullPath = join61(projectHooksDir, hook);
|
|
78303
78371
|
checkedFiles.add(normalizePath2(fullPath));
|
|
78304
78372
|
});
|
|
78305
78373
|
}
|
|
@@ -78331,10 +78399,10 @@ init_logger();
|
|
|
78331
78399
|
init_path_resolver();
|
|
78332
78400
|
import { existsSync as existsSync44 } from "node:fs";
|
|
78333
78401
|
import { readFile as readFile31 } from "node:fs/promises";
|
|
78334
|
-
import { join as
|
|
78402
|
+
import { join as join62 } from "node:path";
|
|
78335
78403
|
async function checkSettingsValid(projectDir) {
|
|
78336
|
-
const globalSettings =
|
|
78337
|
-
const projectSettings =
|
|
78404
|
+
const globalSettings = join62(PathResolver.getGlobalKitDir(), "settings.json");
|
|
78405
|
+
const projectSettings = join62(projectDir, ".claude", "settings.json");
|
|
78338
78406
|
const settingsPath = existsSync44(globalSettings) ? globalSettings : existsSync44(projectSettings) ? projectSettings : null;
|
|
78339
78407
|
if (!settingsPath) {
|
|
78340
78408
|
return {
|
|
@@ -78406,11 +78474,11 @@ init_logger();
|
|
|
78406
78474
|
init_path_resolver();
|
|
78407
78475
|
import { existsSync as existsSync45 } from "node:fs";
|
|
78408
78476
|
import { readFile as readFile32 } from "node:fs/promises";
|
|
78409
|
-
import { homedir as
|
|
78410
|
-
import { dirname as dirname20, join as
|
|
78477
|
+
import { homedir as homedir29 } from "node:os";
|
|
78478
|
+
import { dirname as dirname20, join as join63, normalize as normalize6, resolve as resolve18 } from "node:path";
|
|
78411
78479
|
async function checkPathRefsValid(projectDir) {
|
|
78412
|
-
const globalClaudeMd =
|
|
78413
|
-
const projectClaudeMd =
|
|
78480
|
+
const globalClaudeMd = join63(PathResolver.getGlobalKitDir(), "CLAUDE.md");
|
|
78481
|
+
const projectClaudeMd = join63(projectDir, ".claude", "CLAUDE.md");
|
|
78414
78482
|
const claudeMdPath = existsSync45(globalClaudeMd) ? globalClaudeMd : existsSync45(projectClaudeMd) ? projectClaudeMd : null;
|
|
78415
78483
|
if (!claudeMdPath) {
|
|
78416
78484
|
return {
|
|
@@ -78439,7 +78507,7 @@ async function checkPathRefsValid(projectDir) {
|
|
|
78439
78507
|
};
|
|
78440
78508
|
}
|
|
78441
78509
|
const baseDir = dirname20(claudeMdPath);
|
|
78442
|
-
const home8 =
|
|
78510
|
+
const home8 = homedir29();
|
|
78443
78511
|
const broken = [];
|
|
78444
78512
|
for (const ref of refs) {
|
|
78445
78513
|
let refPath;
|
|
@@ -78505,7 +78573,7 @@ async function checkPathRefsValid(projectDir) {
|
|
|
78505
78573
|
// src/domains/health-checks/checkers/config-completeness-checker.ts
|
|
78506
78574
|
import { existsSync as existsSync46 } from "node:fs";
|
|
78507
78575
|
import { readdir as readdir13 } from "node:fs/promises";
|
|
78508
|
-
import { join as
|
|
78576
|
+
import { join as join64 } from "node:path";
|
|
78509
78577
|
async function checkProjectConfigCompleteness(setup, projectDir) {
|
|
78510
78578
|
if (setup.project.path === setup.global.path) {
|
|
78511
78579
|
return {
|
|
@@ -78518,16 +78586,16 @@ async function checkProjectConfigCompleteness(setup, projectDir) {
|
|
|
78518
78586
|
autoFixable: false
|
|
78519
78587
|
};
|
|
78520
78588
|
}
|
|
78521
|
-
const projectClaudeDir =
|
|
78589
|
+
const projectClaudeDir = join64(projectDir, ".claude");
|
|
78522
78590
|
const requiredDirs = ["agents", "commands", "skills"];
|
|
78523
78591
|
const missingDirs = [];
|
|
78524
78592
|
for (const dir of requiredDirs) {
|
|
78525
|
-
const dirPath =
|
|
78593
|
+
const dirPath = join64(projectClaudeDir, dir);
|
|
78526
78594
|
if (!existsSync46(dirPath)) {
|
|
78527
78595
|
missingDirs.push(dir);
|
|
78528
78596
|
}
|
|
78529
78597
|
}
|
|
78530
|
-
const hasRulesOrWorkflows = existsSync46(
|
|
78598
|
+
const hasRulesOrWorkflows = existsSync46(join64(projectClaudeDir, "rules")) || existsSync46(join64(projectClaudeDir, "workflows"));
|
|
78531
78599
|
if (!hasRulesOrWorkflows) {
|
|
78532
78600
|
missingDirs.push("rules");
|
|
78533
78601
|
}
|
|
@@ -78572,7 +78640,7 @@ async function checkProjectConfigCompleteness(setup, projectDir) {
|
|
|
78572
78640
|
};
|
|
78573
78641
|
}
|
|
78574
78642
|
// src/domains/health-checks/checkers/env-keys-checker.ts
|
|
78575
|
-
import { join as
|
|
78643
|
+
import { join as join66 } from "node:path";
|
|
78576
78644
|
|
|
78577
78645
|
// src/domains/installation/setup-wizard.ts
|
|
78578
78646
|
init_config_generator();
|
|
@@ -78581,7 +78649,7 @@ init_logger();
|
|
|
78581
78649
|
init_path_resolver();
|
|
78582
78650
|
init_dist2();
|
|
78583
78651
|
var import_fs_extra9 = __toESM(require_lib(), 1);
|
|
78584
|
-
import { join as
|
|
78652
|
+
import { join as join65 } from "node:path";
|
|
78585
78653
|
var REQUIRED_ENV_KEYS = [
|
|
78586
78654
|
{ key: "GEMINI_API_KEY", label: "Gemini API Key" }
|
|
78587
78655
|
];
|
|
@@ -78658,7 +78726,7 @@ async function parseEnvFile(path5) {
|
|
|
78658
78726
|
}
|
|
78659
78727
|
}
|
|
78660
78728
|
async function checkGlobalConfig() {
|
|
78661
|
-
const globalEnvPath =
|
|
78729
|
+
const globalEnvPath = join65(PathResolver.getGlobalKitDir(), ".env");
|
|
78662
78730
|
if (!await import_fs_extra9.pathExists(globalEnvPath))
|
|
78663
78731
|
return false;
|
|
78664
78732
|
const env2 = await parseEnvFile(globalEnvPath);
|
|
@@ -78674,7 +78742,7 @@ async function runSetupWizard(options2) {
|
|
|
78674
78742
|
let globalEnv = {};
|
|
78675
78743
|
const hasGlobalConfig = !isGlobal && await checkGlobalConfig();
|
|
78676
78744
|
if (!isGlobal) {
|
|
78677
|
-
const globalEnvPath =
|
|
78745
|
+
const globalEnvPath = join65(PathResolver.getGlobalKitDir(), ".env");
|
|
78678
78746
|
if (await import_fs_extra9.pathExists(globalEnvPath)) {
|
|
78679
78747
|
globalEnv = await parseEnvFile(globalEnvPath);
|
|
78680
78748
|
}
|
|
@@ -78737,7 +78805,7 @@ async function runSetupWizard(options2) {
|
|
|
78737
78805
|
}
|
|
78738
78806
|
}
|
|
78739
78807
|
await generateEnvFile(targetDir, values);
|
|
78740
|
-
f2.success(`Configuration saved to ${
|
|
78808
|
+
f2.success(`Configuration saved to ${join65(targetDir, ".env")}`);
|
|
78741
78809
|
return true;
|
|
78742
78810
|
}
|
|
78743
78811
|
async function promptForAdditionalGeminiKeys(primaryKey) {
|
|
@@ -78812,7 +78880,7 @@ Optional: DISCORD_WEBHOOK_URL, TELEGRAM_BOT_TOKEN`, "Configuration skipped");
|
|
|
78812
78880
|
async function checkEnvKeys(setup) {
|
|
78813
78881
|
const results = [];
|
|
78814
78882
|
if (setup.global.path) {
|
|
78815
|
-
const globalEnvPath =
|
|
78883
|
+
const globalEnvPath = join66(setup.global.path, ".env");
|
|
78816
78884
|
const globalCheck = await checkRequiredKeysExist(globalEnvPath);
|
|
78817
78885
|
if (!globalCheck.allPresent) {
|
|
78818
78886
|
const missingKeys = globalCheck.missing.map((m2) => m2.label).join(", ");
|
|
@@ -78841,7 +78909,7 @@ async function checkEnvKeys(setup) {
|
|
|
78841
78909
|
}
|
|
78842
78910
|
}
|
|
78843
78911
|
if (setup.project.metadata) {
|
|
78844
|
-
const projectEnvPath =
|
|
78912
|
+
const projectEnvPath = join66(setup.project.path, ".env");
|
|
78845
78913
|
const projectCheck = await checkRequiredKeysExist(projectEnvPath);
|
|
78846
78914
|
if (!projectCheck.allPresent) {
|
|
78847
78915
|
const missingKeys = projectCheck.missing.map((m2) => m2.label).join(", ");
|
|
@@ -78872,14 +78940,16 @@ async function checkEnvKeys(setup) {
|
|
|
78872
78940
|
return results;
|
|
78873
78941
|
}
|
|
78874
78942
|
// src/domains/health-checks/checkers/hook-health-checker.ts
|
|
78943
|
+
init_settings_merger();
|
|
78875
78944
|
init_claudekit_constants();
|
|
78945
|
+
init_command_normalizer();
|
|
78876
78946
|
init_logger();
|
|
78877
78947
|
init_path_resolver();
|
|
78878
78948
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
78879
78949
|
import { existsSync as existsSync47, readFileSync as readFileSync12, statSync as statSync7, writeFileSync as writeFileSync4 } from "node:fs";
|
|
78880
78950
|
import { readdir as readdir14 } from "node:fs/promises";
|
|
78881
|
-
import { tmpdir } from "node:os";
|
|
78882
|
-
import { join as
|
|
78951
|
+
import { homedir as homedir30, tmpdir } from "node:os";
|
|
78952
|
+
import { join as join67, resolve as resolve19 } from "node:path";
|
|
78883
78953
|
var HOOK_CHECK_TIMEOUT_MS = 5000;
|
|
78884
78954
|
var PYTHON_CHECK_TIMEOUT_MS = 3000;
|
|
78885
78955
|
var MAX_LOG_FILE_SIZE_BYTES = 10 * 1024 * 1024;
|
|
@@ -78895,6 +78965,117 @@ function getHooksDir(projectDir) {
|
|
|
78895
78965
|
function isPathWithin(filePath, parentDir) {
|
|
78896
78966
|
return resolve19(filePath).startsWith(resolve19(parentDir));
|
|
78897
78967
|
}
|
|
78968
|
+
function getCanonicalGlobalCommandRoot() {
|
|
78969
|
+
const configuredGlobalDir = PathResolver.getGlobalKitDir().replace(/\\/g, "/").replace(/\/+$/, "");
|
|
78970
|
+
const defaultGlobalDir = join67(homedir30(), ".claude").replace(/\\/g, "/");
|
|
78971
|
+
return configuredGlobalDir === defaultGlobalDir ? "$HOME" : configuredGlobalDir;
|
|
78972
|
+
}
|
|
78973
|
+
function getClaudeSettingsFiles(projectDir) {
|
|
78974
|
+
const globalClaudeDir = PathResolver.getGlobalKitDir();
|
|
78975
|
+
const candidates = [
|
|
78976
|
+
{
|
|
78977
|
+
path: resolve19(projectDir, ".claude", "settings.json"),
|
|
78978
|
+
label: "project settings.json",
|
|
78979
|
+
root: "$CLAUDE_PROJECT_DIR"
|
|
78980
|
+
},
|
|
78981
|
+
{
|
|
78982
|
+
path: resolve19(projectDir, ".claude", "settings.local.json"),
|
|
78983
|
+
label: "project settings.local.json",
|
|
78984
|
+
root: "$CLAUDE_PROJECT_DIR"
|
|
78985
|
+
},
|
|
78986
|
+
{
|
|
78987
|
+
path: resolve19(globalClaudeDir, "settings.json"),
|
|
78988
|
+
label: "global settings.json",
|
|
78989
|
+
root: getCanonicalGlobalCommandRoot()
|
|
78990
|
+
},
|
|
78991
|
+
{
|
|
78992
|
+
path: resolve19(globalClaudeDir, "settings.local.json"),
|
|
78993
|
+
label: "global settings.local.json",
|
|
78994
|
+
root: getCanonicalGlobalCommandRoot()
|
|
78995
|
+
}
|
|
78996
|
+
];
|
|
78997
|
+
return candidates.filter((candidate) => existsSync47(candidate.path));
|
|
78998
|
+
}
|
|
78999
|
+
function collectHookCommandFindings(settings, settingsFile) {
|
|
79000
|
+
if (!settings.hooks) {
|
|
79001
|
+
return [];
|
|
79002
|
+
}
|
|
79003
|
+
const findings = [];
|
|
79004
|
+
for (const [eventName, entries] of Object.entries(settings.hooks)) {
|
|
79005
|
+
for (const entry of entries) {
|
|
79006
|
+
if ("command" in entry && typeof entry.command === "string") {
|
|
79007
|
+
const repair = repairClaudeNodeCommandPath(entry.command, settingsFile.root);
|
|
79008
|
+
if (repair.changed && repair.issue) {
|
|
79009
|
+
findings.push({
|
|
79010
|
+
path: settingsFile.path,
|
|
79011
|
+
label: settingsFile.label,
|
|
79012
|
+
eventName,
|
|
79013
|
+
command: entry.command,
|
|
79014
|
+
expected: repair.command,
|
|
79015
|
+
issue: repair.issue
|
|
79016
|
+
});
|
|
79017
|
+
}
|
|
79018
|
+
}
|
|
79019
|
+
if (!("hooks" in entry) || !entry.hooks) {
|
|
79020
|
+
continue;
|
|
79021
|
+
}
|
|
79022
|
+
for (const hook of entry.hooks) {
|
|
79023
|
+
if (!hook.command) {
|
|
79024
|
+
continue;
|
|
79025
|
+
}
|
|
79026
|
+
const repair = repairClaudeNodeCommandPath(hook.command, settingsFile.root);
|
|
79027
|
+
if (!repair.changed || !repair.issue) {
|
|
79028
|
+
continue;
|
|
79029
|
+
}
|
|
79030
|
+
findings.push({
|
|
79031
|
+
path: settingsFile.path,
|
|
79032
|
+
label: settingsFile.label,
|
|
79033
|
+
eventName,
|
|
79034
|
+
matcher: "matcher" in entry ? entry.matcher : undefined,
|
|
79035
|
+
command: hook.command,
|
|
79036
|
+
expected: repair.command,
|
|
79037
|
+
issue: repair.issue
|
|
79038
|
+
});
|
|
79039
|
+
}
|
|
79040
|
+
}
|
|
79041
|
+
}
|
|
79042
|
+
return findings;
|
|
79043
|
+
}
|
|
79044
|
+
async function repairHookCommandsInSettingsFile(settingsFile) {
|
|
79045
|
+
const settings = await SettingsMerger.readSettingsFile(settingsFile.path);
|
|
79046
|
+
if (!settings?.hooks) {
|
|
79047
|
+
return 0;
|
|
79048
|
+
}
|
|
79049
|
+
let repaired = 0;
|
|
79050
|
+
for (const entries of Object.values(settings.hooks)) {
|
|
79051
|
+
for (const entry of entries) {
|
|
79052
|
+
if ("command" in entry && typeof entry.command === "string") {
|
|
79053
|
+
const repair = repairClaudeNodeCommandPath(entry.command, settingsFile.root);
|
|
79054
|
+
if (repair.changed) {
|
|
79055
|
+
entry.command = repair.command;
|
|
79056
|
+
repaired++;
|
|
79057
|
+
}
|
|
79058
|
+
}
|
|
79059
|
+
if (!("hooks" in entry) || !entry.hooks) {
|
|
79060
|
+
continue;
|
|
79061
|
+
}
|
|
79062
|
+
for (const hook of entry.hooks) {
|
|
79063
|
+
if (!hook.command) {
|
|
79064
|
+
continue;
|
|
79065
|
+
}
|
|
79066
|
+
const repair = repairClaudeNodeCommandPath(hook.command, settingsFile.root);
|
|
79067
|
+
if (repair.changed) {
|
|
79068
|
+
hook.command = repair.command;
|
|
79069
|
+
repaired++;
|
|
79070
|
+
}
|
|
79071
|
+
}
|
|
79072
|
+
}
|
|
79073
|
+
}
|
|
79074
|
+
if (repaired > 0) {
|
|
79075
|
+
await SettingsMerger.writeSettingsFile(settingsFile.path, settings);
|
|
79076
|
+
}
|
|
79077
|
+
return repaired;
|
|
79078
|
+
}
|
|
78898
79079
|
async function checkHookSyntax(projectDir) {
|
|
78899
79080
|
const hooksDir = getHooksDir(projectDir);
|
|
78900
79081
|
if (!hooksDir) {
|
|
@@ -78924,7 +79105,7 @@ async function checkHookSyntax(projectDir) {
|
|
|
78924
79105
|
}
|
|
78925
79106
|
const errors2 = [];
|
|
78926
79107
|
for (const file of cjsFiles) {
|
|
78927
|
-
const filePath =
|
|
79108
|
+
const filePath = join67(hooksDir, file);
|
|
78928
79109
|
if (!isPathWithin(filePath, hooksDir))
|
|
78929
79110
|
continue;
|
|
78930
79111
|
const result = spawnSync2("node", ["--check", filePath], {
|
|
@@ -79010,7 +79191,7 @@ async function checkHookDeps(projectDir) {
|
|
|
79010
79191
|
const missingDeps = [];
|
|
79011
79192
|
const requireRegex = /require\(['"]([^'"]+)['"]\)/g;
|
|
79012
79193
|
for (const file of cjsFiles) {
|
|
79013
|
-
const filePath =
|
|
79194
|
+
const filePath = join67(hooksDir, file);
|
|
79014
79195
|
if (!isPathWithin(filePath, hooksDir))
|
|
79015
79196
|
continue;
|
|
79016
79197
|
const content = readFileSync12(filePath, "utf-8");
|
|
@@ -79020,10 +79201,10 @@ async function checkHookDeps(projectDir) {
|
|
|
79020
79201
|
continue;
|
|
79021
79202
|
}
|
|
79022
79203
|
if (depPath.startsWith(".")) {
|
|
79023
|
-
const resolvedPath =
|
|
79204
|
+
const resolvedPath = join67(hooksDir, depPath);
|
|
79024
79205
|
const extensions = [".js", ".cjs", ".mjs", ".json"];
|
|
79025
79206
|
const indexFiles = ["index.js", "index.cjs", "index.mjs"];
|
|
79026
|
-
const exists = existsSync47(resolvedPath) || extensions.some((ext) => existsSync47(resolvedPath + ext)) || indexFiles.some((idx) => existsSync47(
|
|
79207
|
+
const exists = existsSync47(resolvedPath) || extensions.some((ext) => existsSync47(resolvedPath + ext)) || indexFiles.some((idx) => existsSync47(join67(resolvedPath, idx)));
|
|
79027
79208
|
if (!exists) {
|
|
79028
79209
|
missingDeps.push(`${file}: ${depPath}`);
|
|
79029
79210
|
}
|
|
@@ -79140,11 +79321,11 @@ async function checkHookRuntime(projectDir) {
|
|
|
79140
79321
|
}
|
|
79141
79322
|
const syntheticPayload = JSON.stringify({
|
|
79142
79323
|
tool_name: "Read",
|
|
79143
|
-
tool_input: { file_path:
|
|
79324
|
+
tool_input: { file_path: join67(tmpdir(), "ck-doctor-test.txt") }
|
|
79144
79325
|
});
|
|
79145
79326
|
const failures = [];
|
|
79146
79327
|
for (const file of cjsFiles) {
|
|
79147
|
-
const filePath =
|
|
79328
|
+
const filePath = join67(hooksDir, file);
|
|
79148
79329
|
if (!isPathWithin(filePath, hooksDir))
|
|
79149
79330
|
continue;
|
|
79150
79331
|
const result = spawnSync2("node", [filePath], {
|
|
@@ -79205,9 +79386,85 @@ async function checkHookRuntime(projectDir) {
|
|
|
79205
79386
|
};
|
|
79206
79387
|
}
|
|
79207
79388
|
}
|
|
79389
|
+
async function checkHookCommandPaths(projectDir) {
|
|
79390
|
+
const settingsFiles = getClaudeSettingsFiles(projectDir);
|
|
79391
|
+
if (settingsFiles.length === 0) {
|
|
79392
|
+
return {
|
|
79393
|
+
id: "hook-command-paths",
|
|
79394
|
+
name: "Hook Command Paths",
|
|
79395
|
+
group: "claudekit",
|
|
79396
|
+
priority: "standard",
|
|
79397
|
+
status: "info",
|
|
79398
|
+
message: "No Claude settings files",
|
|
79399
|
+
autoFixable: false
|
|
79400
|
+
};
|
|
79401
|
+
}
|
|
79402
|
+
const findings = [];
|
|
79403
|
+
for (const settingsFile of settingsFiles) {
|
|
79404
|
+
const settings = await SettingsMerger.readSettingsFile(settingsFile.path);
|
|
79405
|
+
if (!settings) {
|
|
79406
|
+
continue;
|
|
79407
|
+
}
|
|
79408
|
+
findings.push(...collectHookCommandFindings(settings, settingsFile));
|
|
79409
|
+
}
|
|
79410
|
+
if (findings.length === 0) {
|
|
79411
|
+
return {
|
|
79412
|
+
id: "hook-command-paths",
|
|
79413
|
+
name: "Hook Command Paths",
|
|
79414
|
+
group: "claudekit",
|
|
79415
|
+
priority: "standard",
|
|
79416
|
+
status: "pass",
|
|
79417
|
+
message: `${settingsFiles.length} settings file(s) canonical`,
|
|
79418
|
+
autoFixable: false
|
|
79419
|
+
};
|
|
79420
|
+
}
|
|
79421
|
+
const details = findings.slice(0, 5).map((finding) => {
|
|
79422
|
+
const matcher = finding.matcher ? ` [${finding.matcher}]` : "";
|
|
79423
|
+
return `${finding.label} :: ${finding.eventName}${matcher} :: ${finding.issue} :: ${finding.command}`;
|
|
79424
|
+
}).join(`
|
|
79425
|
+
`);
|
|
79426
|
+
return {
|
|
79427
|
+
id: "hook-command-paths",
|
|
79428
|
+
name: "Hook Command Paths",
|
|
79429
|
+
group: "claudekit",
|
|
79430
|
+
priority: "standard",
|
|
79431
|
+
status: "fail",
|
|
79432
|
+
message: `${findings.length} stale hook command path(s)`,
|
|
79433
|
+
details,
|
|
79434
|
+
suggestion: "Run: ck doctor --fix",
|
|
79435
|
+
autoFixable: true,
|
|
79436
|
+
fix: {
|
|
79437
|
+
id: "fix-hook-command-paths",
|
|
79438
|
+
description: "Canonicalize stale .claude hook command paths in settings files",
|
|
79439
|
+
execute: async () => {
|
|
79440
|
+
try {
|
|
79441
|
+
let repaired = 0;
|
|
79442
|
+
for (const settingsFile of settingsFiles) {
|
|
79443
|
+
repaired += await repairHookCommandsInSettingsFile(settingsFile);
|
|
79444
|
+
}
|
|
79445
|
+
if (repaired === 0) {
|
|
79446
|
+
return {
|
|
79447
|
+
success: true,
|
|
79448
|
+
message: "No stale hook command paths needed repair"
|
|
79449
|
+
};
|
|
79450
|
+
}
|
|
79451
|
+
return {
|
|
79452
|
+
success: true,
|
|
79453
|
+
message: `Repaired ${repaired} stale hook command path(s)`
|
|
79454
|
+
};
|
|
79455
|
+
} catch (error) {
|
|
79456
|
+
return {
|
|
79457
|
+
success: false,
|
|
79458
|
+
message: `Failed to repair hook command paths: ${error}`
|
|
79459
|
+
};
|
|
79460
|
+
}
|
|
79461
|
+
}
|
|
79462
|
+
}
|
|
79463
|
+
};
|
|
79464
|
+
}
|
|
79208
79465
|
async function checkHookConfig(projectDir) {
|
|
79209
|
-
const projectConfigPath =
|
|
79210
|
-
const globalConfigPath =
|
|
79466
|
+
const projectConfigPath = join67(projectDir, ".claude", ".ck.json");
|
|
79467
|
+
const globalConfigPath = join67(PathResolver.getGlobalKitDir(), ".ck.json");
|
|
79211
79468
|
const configPath = existsSync47(projectConfigPath) ? projectConfigPath : existsSync47(globalConfigPath) ? globalConfigPath : null;
|
|
79212
79469
|
if (!configPath) {
|
|
79213
79470
|
return {
|
|
@@ -79331,7 +79588,7 @@ async function checkHookLogs(projectDir) {
|
|
|
79331
79588
|
autoFixable: false
|
|
79332
79589
|
};
|
|
79333
79590
|
}
|
|
79334
|
-
const logPath =
|
|
79591
|
+
const logPath = join67(hooksDir, ".logs", "hook-log.jsonl");
|
|
79335
79592
|
if (!existsSync47(logPath)) {
|
|
79336
79593
|
return {
|
|
79337
79594
|
id: "hook-logs",
|
|
@@ -79586,9 +79843,9 @@ async function checkCliVersion() {
|
|
|
79586
79843
|
}
|
|
79587
79844
|
async function checkPythonVenv(projectDir) {
|
|
79588
79845
|
const isWindows3 = process.platform === "win32";
|
|
79589
|
-
const venvBin = isWindows3 ?
|
|
79590
|
-
const projectVenvPath =
|
|
79591
|
-
const globalVenvPath =
|
|
79846
|
+
const venvBin = isWindows3 ? join67("Scripts", "python.exe") : join67("bin", "python3");
|
|
79847
|
+
const projectVenvPath = join67(projectDir, ".claude", "skills", ".venv", venvBin);
|
|
79848
|
+
const globalVenvPath = join67(PathResolver.getGlobalKitDir(), "skills", ".venv", venvBin);
|
|
79592
79849
|
const venvPath = existsSync47(projectVenvPath) ? projectVenvPath : existsSync47(globalVenvPath) ? globalVenvPath : null;
|
|
79593
79850
|
if (!venvPath) {
|
|
79594
79851
|
return {
|
|
@@ -79704,6 +79961,8 @@ class ClaudekitChecker {
|
|
|
79704
79961
|
results.push(await checkHookDeps(this.projectDir));
|
|
79705
79962
|
logger.verbose("ClaudekitChecker: Checking hook runtime");
|
|
79706
79963
|
results.push(await checkHookRuntime(this.projectDir));
|
|
79964
|
+
logger.verbose("ClaudekitChecker: Checking hook command paths");
|
|
79965
|
+
results.push(await checkHookCommandPaths(this.projectDir));
|
|
79707
79966
|
logger.verbose("ClaudekitChecker: Checking hook config");
|
|
79708
79967
|
results.push(await checkHookConfig(this.projectDir));
|
|
79709
79968
|
logger.verbose("ClaudekitChecker: Checking hook crash logs");
|
|
@@ -80068,8 +80327,8 @@ import { platform as platform8 } from "node:os";
|
|
|
80068
80327
|
init_environment();
|
|
80069
80328
|
init_path_resolver();
|
|
80070
80329
|
import { constants as constants3, access as access3, mkdir as mkdir16, readFile as readFile34, unlink as unlink8, writeFile as writeFile17 } from "node:fs/promises";
|
|
80071
|
-
import { arch as arch2, homedir as
|
|
80072
|
-
import { join as
|
|
80330
|
+
import { arch as arch2, homedir as homedir31, platform as platform7 } from "node:os";
|
|
80331
|
+
import { join as join69, normalize as normalize7 } from "node:path";
|
|
80073
80332
|
function shouldSkipExpensiveOperations4() {
|
|
80074
80333
|
return shouldSkipExpensiveOperations();
|
|
80075
80334
|
}
|
|
@@ -80091,7 +80350,7 @@ async function checkPlatformDetect() {
|
|
|
80091
80350
|
};
|
|
80092
80351
|
}
|
|
80093
80352
|
async function checkHomeDirResolution() {
|
|
80094
|
-
const nodeHome = normalize7(
|
|
80353
|
+
const nodeHome = normalize7(homedir31());
|
|
80095
80354
|
const rawEnvHome = getHomeDirectoryFromEnv(platform7());
|
|
80096
80355
|
const envHome = rawEnvHome ? normalize7(rawEnvHome) : "";
|
|
80097
80356
|
const match = nodeHome === envHome && envHome !== "";
|
|
@@ -80160,7 +80419,7 @@ async function checkGlobalDirAccess() {
|
|
|
80160
80419
|
autoFixable: false
|
|
80161
80420
|
};
|
|
80162
80421
|
}
|
|
80163
|
-
const testFile =
|
|
80422
|
+
const testFile = join69(globalDir, ".ck-doctor-access-test");
|
|
80164
80423
|
try {
|
|
80165
80424
|
await mkdir16(globalDir, { recursive: true });
|
|
80166
80425
|
await writeFile17(testFile, "test", "utf-8");
|
|
@@ -80238,7 +80497,7 @@ async function checkWSLBoundary() {
|
|
|
80238
80497
|
// src/domains/health-checks/platform/windows-checker.ts
|
|
80239
80498
|
init_path_resolver();
|
|
80240
80499
|
import { mkdir as mkdir17, symlink as symlink2, unlink as unlink9, writeFile as writeFile18 } from "node:fs/promises";
|
|
80241
|
-
import { join as
|
|
80500
|
+
import { join as join70 } from "node:path";
|
|
80242
80501
|
async function checkLongPathSupport() {
|
|
80243
80502
|
if (shouldSkipExpensiveOperations4()) {
|
|
80244
80503
|
return {
|
|
@@ -80290,8 +80549,8 @@ async function checkSymlinkSupport() {
|
|
|
80290
80549
|
};
|
|
80291
80550
|
}
|
|
80292
80551
|
const testDir = PathResolver.getGlobalKitDir();
|
|
80293
|
-
const target =
|
|
80294
|
-
const link =
|
|
80552
|
+
const target = join70(testDir, ".ck-symlink-test-target");
|
|
80553
|
+
const link = join70(testDir, ".ck-symlink-test-link");
|
|
80295
80554
|
try {
|
|
80296
80555
|
await mkdir17(testDir, { recursive: true });
|
|
80297
80556
|
await writeFile18(target, "test", "utf-8");
|
|
@@ -80585,7 +80844,7 @@ class AutoHealer {
|
|
|
80585
80844
|
import { execSync as execSync3, spawnSync as spawnSync5 } from "node:child_process";
|
|
80586
80845
|
import { readFileSync as readFileSync13, unlinkSync, writeFileSync as writeFileSync5 } from "node:fs";
|
|
80587
80846
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
80588
|
-
import { dirname as dirname21, join as
|
|
80847
|
+
import { dirname as dirname21, join as join71 } from "node:path";
|
|
80589
80848
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
80590
80849
|
init_environment();
|
|
80591
80850
|
init_logger();
|
|
@@ -80593,7 +80852,7 @@ init_dist2();
|
|
|
80593
80852
|
function getCliVersion4() {
|
|
80594
80853
|
try {
|
|
80595
80854
|
const __dirname4 = dirname21(fileURLToPath4(import.meta.url));
|
|
80596
|
-
const pkgPath =
|
|
80855
|
+
const pkgPath = join71(__dirname4, "../../../package.json");
|
|
80597
80856
|
const pkg = JSON.parse(readFileSync13(pkgPath, "utf-8"));
|
|
80598
80857
|
return pkg.version || "unknown";
|
|
80599
80858
|
} catch (err) {
|
|
@@ -80732,7 +80991,7 @@ class ReportGenerator {
|
|
|
80732
80991
|
return null;
|
|
80733
80992
|
}
|
|
80734
80993
|
}
|
|
80735
|
-
const tmpFile =
|
|
80994
|
+
const tmpFile = join71(tmpdir3(), `ck-report-${Date.now()}.txt`);
|
|
80736
80995
|
writeFileSync5(tmpFile, report);
|
|
80737
80996
|
try {
|
|
80738
80997
|
const result = spawnSync5("gh", ["gist", "create", tmpFile, "--desc", "ClaudeKit Diagnostic Report"], {
|
|
@@ -81058,7 +81317,7 @@ init_claudekit_constants();
|
|
|
81058
81317
|
init_logger();
|
|
81059
81318
|
init_path_resolver();
|
|
81060
81319
|
import { mkdir as mkdir18, readFile as readFile35, unlink as unlink10, writeFile as writeFile19 } from "node:fs/promises";
|
|
81061
|
-
import { join as
|
|
81320
|
+
import { join as join72 } from "node:path";
|
|
81062
81321
|
var CACHE_TTL_HOURS = 24;
|
|
81063
81322
|
var DEFAULT_CACHE_TTL_MS = CACHE_TTL_HOURS * 60 * 60 * 1000;
|
|
81064
81323
|
var MIN_CACHE_TTL_MS = 60 * 1000;
|
|
@@ -81095,7 +81354,7 @@ var KIT_REPOS = {
|
|
|
81095
81354
|
class ConfigVersionChecker {
|
|
81096
81355
|
static getCacheFilePath(kitType, global3) {
|
|
81097
81356
|
const cacheDir = PathResolver.getCacheDir(global3);
|
|
81098
|
-
return
|
|
81357
|
+
return join72(cacheDir, `${kitType}-${CACHE_FILENAME}`);
|
|
81099
81358
|
}
|
|
81100
81359
|
static async loadCache(kitType, global3) {
|
|
81101
81360
|
try {
|
|
@@ -81258,7 +81517,7 @@ class ConfigVersionChecker {
|
|
|
81258
81517
|
}
|
|
81259
81518
|
// src/domains/sync/sync-engine.ts
|
|
81260
81519
|
import { lstat as lstat4, readFile as readFile36, readlink as readlink2, realpath as realpath5, stat as stat10 } from "node:fs/promises";
|
|
81261
|
-
import { isAbsolute as isAbsolute4, join as
|
|
81520
|
+
import { isAbsolute as isAbsolute4, join as join73, normalize as normalize8, relative as relative8 } from "node:path";
|
|
81262
81521
|
|
|
81263
81522
|
// src/services/file-operations/ownership-checker.ts
|
|
81264
81523
|
init_metadata_migration();
|
|
@@ -82619,7 +82878,7 @@ async function validateSymlinkChain(path6, basePath, maxDepth = MAX_SYMLINK_DEPT
|
|
|
82619
82878
|
if (!stats.isSymbolicLink())
|
|
82620
82879
|
break;
|
|
82621
82880
|
const target = await readlink2(current);
|
|
82622
|
-
const resolvedTarget = isAbsolute4(target) ? target :
|
|
82881
|
+
const resolvedTarget = isAbsolute4(target) ? target : join73(current, "..", target);
|
|
82623
82882
|
const normalizedTarget = normalize8(resolvedTarget);
|
|
82624
82883
|
const rel = relative8(basePath, normalizedTarget);
|
|
82625
82884
|
if (rel.startsWith("..") || isAbsolute4(rel)) {
|
|
@@ -82655,7 +82914,7 @@ async function validateSyncPath(basePath, filePath) {
|
|
|
82655
82914
|
if (normalized.startsWith("..") || normalized.includes("/../")) {
|
|
82656
82915
|
throw new Error(`Path traversal not allowed: ${filePath}`);
|
|
82657
82916
|
}
|
|
82658
|
-
const fullPath =
|
|
82917
|
+
const fullPath = join73(basePath, normalized);
|
|
82659
82918
|
const rel = relative8(basePath, fullPath);
|
|
82660
82919
|
if (rel.startsWith("..") || isAbsolute4(rel)) {
|
|
82661
82920
|
throw new Error(`Path escapes base directory: ${filePath}`);
|
|
@@ -82670,7 +82929,7 @@ async function validateSyncPath(basePath, filePath) {
|
|
|
82670
82929
|
}
|
|
82671
82930
|
} catch (error) {
|
|
82672
82931
|
if (error.code === "ENOENT") {
|
|
82673
|
-
const parentPath =
|
|
82932
|
+
const parentPath = join73(fullPath, "..");
|
|
82674
82933
|
try {
|
|
82675
82934
|
const resolvedBase = await realpath5(basePath);
|
|
82676
82935
|
const resolvedParent = await realpath5(parentPath);
|
|
@@ -83578,7 +83837,7 @@ async function getLatestVersion(kit, includePrereleases = false) {
|
|
|
83578
83837
|
init_logger();
|
|
83579
83838
|
init_path_resolver();
|
|
83580
83839
|
init_safe_prompts();
|
|
83581
|
-
import { join as
|
|
83840
|
+
import { join as join80 } from "node:path";
|
|
83582
83841
|
async function promptUpdateMode() {
|
|
83583
83842
|
const updateEverything = await se({
|
|
83584
83843
|
message: "Do you want to update everything?"
|
|
@@ -83620,7 +83879,7 @@ async function promptDirectorySelection(global3 = false) {
|
|
|
83620
83879
|
return selectedCategories;
|
|
83621
83880
|
}
|
|
83622
83881
|
async function promptFreshConfirmation(targetPath, analysis) {
|
|
83623
|
-
const backupRoot =
|
|
83882
|
+
const backupRoot = join80(PathResolver.getConfigDir(false), "backups");
|
|
83624
83883
|
logger.warning("[!] Fresh installation will remove ClaudeKit files:");
|
|
83625
83884
|
logger.info(`Path: ${targetPath}`);
|
|
83626
83885
|
logger.info(`Recovery backup: ${backupRoot}`);
|
|
@@ -83894,7 +84153,7 @@ init_logger();
|
|
|
83894
84153
|
init_logger();
|
|
83895
84154
|
init_path_resolver();
|
|
83896
84155
|
var import_fs_extra10 = __toESM(require_lib(), 1);
|
|
83897
|
-
import { join as
|
|
84156
|
+
import { join as join81 } from "node:path";
|
|
83898
84157
|
async function handleConflicts(ctx) {
|
|
83899
84158
|
if (ctx.cancelled)
|
|
83900
84159
|
return ctx;
|
|
@@ -83903,7 +84162,7 @@ async function handleConflicts(ctx) {
|
|
|
83903
84162
|
if (PathResolver.isLocalSameAsGlobal()) {
|
|
83904
84163
|
return ctx;
|
|
83905
84164
|
}
|
|
83906
|
-
const localSettingsPath =
|
|
84165
|
+
const localSettingsPath = join81(process.cwd(), ".claude", "settings.json");
|
|
83907
84166
|
if (!await import_fs_extra10.pathExists(localSettingsPath)) {
|
|
83908
84167
|
return ctx;
|
|
83909
84168
|
}
|
|
@@ -83918,7 +84177,7 @@ async function handleConflicts(ctx) {
|
|
|
83918
84177
|
return { ...ctx, cancelled: true };
|
|
83919
84178
|
}
|
|
83920
84179
|
if (choice === "remove") {
|
|
83921
|
-
const localClaudeDir =
|
|
84180
|
+
const localClaudeDir = join81(process.cwd(), ".claude");
|
|
83922
84181
|
try {
|
|
83923
84182
|
await import_fs_extra10.remove(localClaudeDir);
|
|
83924
84183
|
logger.success("Removed local .claude/ directory");
|
|
@@ -84015,7 +84274,7 @@ init_logger();
|
|
|
84015
84274
|
init_safe_spinner();
|
|
84016
84275
|
import { mkdir as mkdir26, stat as stat13 } from "node:fs/promises";
|
|
84017
84276
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
84018
|
-
import { join as
|
|
84277
|
+
import { join as join88 } from "node:path";
|
|
84019
84278
|
|
|
84020
84279
|
// src/shared/temp-cleanup.ts
|
|
84021
84280
|
init_logger();
|
|
@@ -84034,7 +84293,7 @@ init_logger();
|
|
|
84034
84293
|
init_output_manager();
|
|
84035
84294
|
import { createWriteStream as createWriteStream2, rmSync as rmSync2 } from "node:fs";
|
|
84036
84295
|
import { mkdir as mkdir21 } from "node:fs/promises";
|
|
84037
|
-
import { join as
|
|
84296
|
+
import { join as join82 } from "node:path";
|
|
84038
84297
|
|
|
84039
84298
|
// src/shared/progress-bar.ts
|
|
84040
84299
|
init_output_manager();
|
|
@@ -84244,7 +84503,7 @@ var MAX_DOWNLOAD_SIZE = 500 * 1024 * 1024;
|
|
|
84244
84503
|
class FileDownloader {
|
|
84245
84504
|
async downloadAsset(asset, destDir) {
|
|
84246
84505
|
try {
|
|
84247
|
-
const destPath =
|
|
84506
|
+
const destPath = join82(destDir, asset.name);
|
|
84248
84507
|
await mkdir21(destDir, { recursive: true });
|
|
84249
84508
|
output.info(`Downloading ${asset.name} (${formatBytes2(asset.size)})...`);
|
|
84250
84509
|
logger.verbose("Download details", {
|
|
@@ -84329,7 +84588,7 @@ class FileDownloader {
|
|
|
84329
84588
|
}
|
|
84330
84589
|
async downloadFile(params) {
|
|
84331
84590
|
const { url, name, size, destDir, token } = params;
|
|
84332
|
-
const destPath =
|
|
84591
|
+
const destPath = join82(destDir, name);
|
|
84333
84592
|
await mkdir21(destDir, { recursive: true });
|
|
84334
84593
|
output.info(`Downloading ${name}${size ? ` (${formatBytes2(size)})` : ""}...`);
|
|
84335
84594
|
const headers = {};
|
|
@@ -84415,7 +84674,7 @@ init_logger();
|
|
|
84415
84674
|
init_types3();
|
|
84416
84675
|
import { constants as constants4 } from "node:fs";
|
|
84417
84676
|
import { access as access4, readdir as readdir15 } from "node:fs/promises";
|
|
84418
|
-
import { join as
|
|
84677
|
+
import { join as join83 } from "node:path";
|
|
84419
84678
|
async function validateExtraction(extractDir) {
|
|
84420
84679
|
try {
|
|
84421
84680
|
const entries = await readdir15(extractDir, { encoding: "utf8" });
|
|
@@ -84427,7 +84686,7 @@ async function validateExtraction(extractDir) {
|
|
|
84427
84686
|
const missingPaths = [];
|
|
84428
84687
|
for (const path6 of criticalPaths) {
|
|
84429
84688
|
try {
|
|
84430
|
-
await access4(
|
|
84689
|
+
await access4(join83(extractDir, path6), constants4.F_OK);
|
|
84431
84690
|
logger.debug(`Found: ${path6}`);
|
|
84432
84691
|
} catch {
|
|
84433
84692
|
logger.warning(`Expected path not found: ${path6}`);
|
|
@@ -84449,7 +84708,7 @@ async function validateExtraction(extractDir) {
|
|
|
84449
84708
|
// src/domains/installation/extraction/tar-extractor.ts
|
|
84450
84709
|
init_logger();
|
|
84451
84710
|
import { copyFile as copyFile4, mkdir as mkdir24, readdir as readdir17, rm as rm9, stat as stat11 } from "node:fs/promises";
|
|
84452
|
-
import { join as
|
|
84711
|
+
import { join as join86 } from "node:path";
|
|
84453
84712
|
|
|
84454
84713
|
// node_modules/@isaacs/fs-minipass/dist/esm/index.js
|
|
84455
84714
|
import EE from "events";
|
|
@@ -90211,7 +90470,7 @@ var mkdirSync3 = (dir, opt) => {
|
|
|
90211
90470
|
};
|
|
90212
90471
|
|
|
90213
90472
|
// node_modules/tar/dist/esm/path-reservations.js
|
|
90214
|
-
import { join as
|
|
90473
|
+
import { join as join84 } from "node:path";
|
|
90215
90474
|
|
|
90216
90475
|
// node_modules/tar/dist/esm/normalize-unicode.js
|
|
90217
90476
|
var normalizeCache = Object.create(null);
|
|
@@ -90244,7 +90503,7 @@ var getDirs = (path11) => {
|
|
|
90244
90503
|
const dirs = path11.split("/").slice(0, -1).reduce((set, path12) => {
|
|
90245
90504
|
const s = set[set.length - 1];
|
|
90246
90505
|
if (s !== undefined) {
|
|
90247
|
-
path12 =
|
|
90506
|
+
path12 = join84(s, path12);
|
|
90248
90507
|
}
|
|
90249
90508
|
set.push(path12 || "/");
|
|
90250
90509
|
return set;
|
|
@@ -90258,7 +90517,7 @@ class PathReservations {
|
|
|
90258
90517
|
#running = new Set;
|
|
90259
90518
|
reserve(paths, fn) {
|
|
90260
90519
|
paths = isWindows4 ? ["win32 parallelization disabled"] : paths.map((p) => {
|
|
90261
|
-
return stripTrailingSlashes(
|
|
90520
|
+
return stripTrailingSlashes(join84(normalizeUnicode(p))).toLowerCase();
|
|
90262
90521
|
});
|
|
90263
90522
|
const dirs = new Set(paths.map((path11) => getDirs(path11)).reduce((a3, b3) => a3.concat(b3)));
|
|
90264
90523
|
this.#reservations.set(fn, { dirs, paths });
|
|
@@ -91318,7 +91577,7 @@ function decodeFilePath(path13) {
|
|
|
91318
91577
|
init_logger();
|
|
91319
91578
|
init_types3();
|
|
91320
91579
|
import { copyFile as copyFile3, lstat as lstat5, mkdir as mkdir23, readdir as readdir16 } from "node:fs/promises";
|
|
91321
|
-
import { join as
|
|
91580
|
+
import { join as join85, relative as relative10 } from "node:path";
|
|
91322
91581
|
async function withRetry(fn, retries = 3) {
|
|
91323
91582
|
for (let i = 0;i < retries; i++) {
|
|
91324
91583
|
try {
|
|
@@ -91340,8 +91599,8 @@ async function moveDirectoryContents(sourceDir, destDir, shouldExclude, sizeTrac
|
|
|
91340
91599
|
await mkdir23(destDir, { recursive: true });
|
|
91341
91600
|
const entries = await readdir16(sourceDir, { encoding: "utf8" });
|
|
91342
91601
|
for (const entry of entries) {
|
|
91343
|
-
const sourcePath =
|
|
91344
|
-
const destPath =
|
|
91602
|
+
const sourcePath = join85(sourceDir, entry);
|
|
91603
|
+
const destPath = join85(destDir, entry);
|
|
91345
91604
|
const relativePath = relative10(sourceDir, sourcePath);
|
|
91346
91605
|
if (!isPathSafe(destDir, destPath)) {
|
|
91347
91606
|
logger.warning(`Skipping unsafe path: ${relativePath}`);
|
|
@@ -91368,8 +91627,8 @@ async function copyDirectory(sourceDir, destDir, shouldExclude, sizeTracker) {
|
|
|
91368
91627
|
await mkdir23(destDir, { recursive: true });
|
|
91369
91628
|
const entries = await readdir16(sourceDir, { encoding: "utf8" });
|
|
91370
91629
|
for (const entry of entries) {
|
|
91371
|
-
const sourcePath =
|
|
91372
|
-
const destPath =
|
|
91630
|
+
const sourcePath = join85(sourceDir, entry);
|
|
91631
|
+
const destPath = join85(destDir, entry);
|
|
91373
91632
|
const relativePath = relative10(sourceDir, sourcePath);
|
|
91374
91633
|
if (!isPathSafe(destDir, destPath)) {
|
|
91375
91634
|
logger.warning(`Skipping unsafe path: ${relativePath}`);
|
|
@@ -91417,7 +91676,7 @@ class TarExtractor {
|
|
|
91417
91676
|
logger.debug(`Root entries: ${entries.join(", ")}`);
|
|
91418
91677
|
if (entries.length === 1) {
|
|
91419
91678
|
const rootEntry = entries[0];
|
|
91420
|
-
const rootPath =
|
|
91679
|
+
const rootPath = join86(tempExtractDir, rootEntry);
|
|
91421
91680
|
const rootStat = await stat11(rootPath);
|
|
91422
91681
|
if (rootStat.isDirectory()) {
|
|
91423
91682
|
const rootContents = await readdir17(rootPath, { encoding: "utf8" });
|
|
@@ -91433,7 +91692,7 @@ class TarExtractor {
|
|
|
91433
91692
|
}
|
|
91434
91693
|
} else {
|
|
91435
91694
|
await mkdir24(destDir, { recursive: true });
|
|
91436
|
-
await copyFile4(rootPath,
|
|
91695
|
+
await copyFile4(rootPath, join86(destDir, rootEntry));
|
|
91437
91696
|
}
|
|
91438
91697
|
} else {
|
|
91439
91698
|
logger.debug("Multiple root entries - moving all");
|
|
@@ -91456,7 +91715,7 @@ init_logger();
|
|
|
91456
91715
|
var import_extract_zip = __toESM(require_extract_zip(), 1);
|
|
91457
91716
|
import { execFile as execFile8 } from "node:child_process";
|
|
91458
91717
|
import { copyFile as copyFile5, mkdir as mkdir25, readdir as readdir18, rm as rm10, stat as stat12 } from "node:fs/promises";
|
|
91459
|
-
import { join as
|
|
91718
|
+
import { join as join87 } from "node:path";
|
|
91460
91719
|
class ZipExtractor {
|
|
91461
91720
|
async tryNativeUnzip(archivePath, destDir) {
|
|
91462
91721
|
if (!isMacOS()) {
|
|
@@ -91504,7 +91763,7 @@ class ZipExtractor {
|
|
|
91504
91763
|
logger.debug(`Root entries: ${entries.join(", ")}`);
|
|
91505
91764
|
if (entries.length === 1) {
|
|
91506
91765
|
const rootEntry = entries[0];
|
|
91507
|
-
const rootPath =
|
|
91766
|
+
const rootPath = join87(tempExtractDir, rootEntry);
|
|
91508
91767
|
const rootStat = await stat12(rootPath);
|
|
91509
91768
|
if (rootStat.isDirectory()) {
|
|
91510
91769
|
const rootContents = await readdir18(rootPath, { encoding: "utf8" });
|
|
@@ -91520,7 +91779,7 @@ class ZipExtractor {
|
|
|
91520
91779
|
}
|
|
91521
91780
|
} else {
|
|
91522
91781
|
await mkdir25(destDir, { recursive: true });
|
|
91523
|
-
await copyFile5(rootPath,
|
|
91782
|
+
await copyFile5(rootPath, join87(destDir, rootEntry));
|
|
91524
91783
|
}
|
|
91525
91784
|
} else {
|
|
91526
91785
|
logger.debug("Multiple root entries - moving all");
|
|
@@ -91619,7 +91878,7 @@ class DownloadManager {
|
|
|
91619
91878
|
async createTempDir() {
|
|
91620
91879
|
const timestamp = Date.now();
|
|
91621
91880
|
const counter = DownloadManager.tempDirCounter++;
|
|
91622
|
-
const primaryTempDir =
|
|
91881
|
+
const primaryTempDir = join88(tmpdir4(), `claudekit-${timestamp}-${counter}`);
|
|
91623
91882
|
try {
|
|
91624
91883
|
await mkdir26(primaryTempDir, { recursive: true });
|
|
91625
91884
|
logger.debug(`Created temp directory: ${primaryTempDir}`);
|
|
@@ -91636,7 +91895,7 @@ Solutions:
|
|
|
91636
91895
|
2. Set HOME environment variable
|
|
91637
91896
|
3. Try running from a different directory`);
|
|
91638
91897
|
}
|
|
91639
|
-
const fallbackTempDir =
|
|
91898
|
+
const fallbackTempDir = join88(homeDir, ".claudekit", "tmp", `claudekit-${timestamp}-${counter}`);
|
|
91640
91899
|
try {
|
|
91641
91900
|
await mkdir26(fallbackTempDir, { recursive: true });
|
|
91642
91901
|
logger.debug(`Created temp directory (fallback): ${fallbackTempDir}`);
|
|
@@ -92056,20 +92315,20 @@ async function handleDownload(ctx) {
|
|
|
92056
92315
|
};
|
|
92057
92316
|
}
|
|
92058
92317
|
// src/commands/init/phases/merge-handler.ts
|
|
92059
|
-
import { join as
|
|
92318
|
+
import { join as join105 } from "node:path";
|
|
92060
92319
|
|
|
92061
92320
|
// src/domains/installation/deletion-handler.ts
|
|
92062
92321
|
import { existsSync as existsSync53, lstatSync as lstatSync3, readdirSync as readdirSync5, rmSync as rmSync3, rmdirSync, unlinkSync as unlinkSync3 } from "node:fs";
|
|
92063
|
-
import { dirname as dirname26, join as
|
|
92322
|
+
import { dirname as dirname26, join as join91, relative as relative11, resolve as resolve24, sep as sep8 } from "node:path";
|
|
92064
92323
|
|
|
92065
92324
|
// src/services/file-operations/manifest/manifest-reader.ts
|
|
92066
92325
|
init_metadata_migration();
|
|
92067
92326
|
init_logger();
|
|
92068
92327
|
init_types3();
|
|
92069
92328
|
var import_fs_extra11 = __toESM(require_lib(), 1);
|
|
92070
|
-
import { join as
|
|
92329
|
+
import { join as join90 } from "node:path";
|
|
92071
92330
|
async function readManifest(claudeDir2) {
|
|
92072
|
-
const metadataPath =
|
|
92331
|
+
const metadataPath = join90(claudeDir2, "metadata.json");
|
|
92073
92332
|
if (!await import_fs_extra11.pathExists(metadataPath)) {
|
|
92074
92333
|
return null;
|
|
92075
92334
|
}
|
|
@@ -92255,7 +92514,7 @@ function collectFilesRecursively(dir, baseDir) {
|
|
|
92255
92514
|
try {
|
|
92256
92515
|
const entries = readdirSync5(dir, { withFileTypes: true });
|
|
92257
92516
|
for (const entry of entries) {
|
|
92258
|
-
const fullPath =
|
|
92517
|
+
const fullPath = join91(dir, entry.name);
|
|
92259
92518
|
const relativePath = relative11(baseDir, fullPath);
|
|
92260
92519
|
if (entry.isDirectory()) {
|
|
92261
92520
|
results.push(...collectFilesRecursively(fullPath, baseDir));
|
|
@@ -92323,7 +92582,7 @@ function deletePath(fullPath, claudeDir2) {
|
|
|
92323
92582
|
}
|
|
92324
92583
|
}
|
|
92325
92584
|
async function updateMetadataAfterDeletion(claudeDir2, deletedPaths) {
|
|
92326
|
-
const metadataPath =
|
|
92585
|
+
const metadataPath = join91(claudeDir2, "metadata.json");
|
|
92327
92586
|
if (!await import_fs_extra12.pathExists(metadataPath)) {
|
|
92328
92587
|
return;
|
|
92329
92588
|
}
|
|
@@ -92378,7 +92637,7 @@ async function handleDeletions(sourceMetadata, claudeDir2, kitType) {
|
|
|
92378
92637
|
const userMetadata = await readManifest(claudeDir2);
|
|
92379
92638
|
const result = { deletedPaths: [], preservedPaths: [], errors: [] };
|
|
92380
92639
|
for (const path14 of deletions) {
|
|
92381
|
-
const fullPath =
|
|
92640
|
+
const fullPath = join91(claudeDir2, path14);
|
|
92382
92641
|
const normalizedPath = resolve24(fullPath);
|
|
92383
92642
|
const normalizedClaudeDir = resolve24(claudeDir2);
|
|
92384
92643
|
if (!normalizedPath.startsWith(`${normalizedClaudeDir}${sep8}`)) {
|
|
@@ -92418,7 +92677,7 @@ init_logger();
|
|
|
92418
92677
|
init_types3();
|
|
92419
92678
|
var import_fs_extra15 = __toESM(require_lib(), 1);
|
|
92420
92679
|
var import_ignore3 = __toESM(require_ignore(), 1);
|
|
92421
|
-
import { dirname as
|
|
92680
|
+
import { dirname as dirname29, join as join95, relative as relative13 } from "node:path";
|
|
92422
92681
|
|
|
92423
92682
|
// src/domains/installation/selective-merger.ts
|
|
92424
92683
|
import { stat as stat14 } from "node:fs/promises";
|
|
@@ -92597,7 +92856,7 @@ init_logger();
|
|
|
92597
92856
|
var import_fs_extra13 = __toESM(require_lib(), 1);
|
|
92598
92857
|
var import_ignore2 = __toESM(require_ignore(), 1);
|
|
92599
92858
|
import { relative as relative12 } from "node:path";
|
|
92600
|
-
import { join as
|
|
92859
|
+
import { join as join92 } from "node:path";
|
|
92601
92860
|
|
|
92602
92861
|
// node_modules/@isaacs/balanced-match/dist/esm/index.js
|
|
92603
92862
|
var balanced = (a3, b3, str2) => {
|
|
@@ -94053,7 +94312,7 @@ class FileScanner {
|
|
|
94053
94312
|
const files = [];
|
|
94054
94313
|
const entries = await import_fs_extra13.readdir(dir, { encoding: "utf8" });
|
|
94055
94314
|
for (const entry of entries) {
|
|
94056
|
-
const fullPath =
|
|
94315
|
+
const fullPath = join92(dir, entry);
|
|
94057
94316
|
const relativePath = relative12(baseDir, fullPath);
|
|
94058
94317
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
94059
94318
|
const stats = await import_fs_extra13.lstat(fullPath);
|
|
@@ -94088,12 +94347,14 @@ class FileScanner {
|
|
|
94088
94347
|
|
|
94089
94348
|
// src/domains/installation/merger/settings-processor.ts
|
|
94090
94349
|
import { execSync as execSync4 } from "node:child_process";
|
|
94350
|
+
import { homedir as homedir33 } from "node:os";
|
|
94351
|
+
import { dirname as dirname28, join as join94 } from "node:path";
|
|
94091
94352
|
|
|
94092
94353
|
// src/domains/config/installed-settings-tracker.ts
|
|
94093
94354
|
init_shared();
|
|
94094
94355
|
import { existsSync as existsSync54 } from "node:fs";
|
|
94095
94356
|
import { mkdir as mkdir27, readFile as readFile40, writeFile as writeFile22 } from "node:fs/promises";
|
|
94096
|
-
import { dirname as dirname27, join as
|
|
94357
|
+
import { dirname as dirname27, join as join93 } from "node:path";
|
|
94097
94358
|
var CK_JSON_FILE = ".ck.json";
|
|
94098
94359
|
|
|
94099
94360
|
class InstalledSettingsTracker {
|
|
@@ -94107,9 +94368,9 @@ class InstalledSettingsTracker {
|
|
|
94107
94368
|
}
|
|
94108
94369
|
getCkJsonPath() {
|
|
94109
94370
|
if (this.isGlobal) {
|
|
94110
|
-
return
|
|
94371
|
+
return join93(this.projectDir, CK_JSON_FILE);
|
|
94111
94372
|
}
|
|
94112
|
-
return
|
|
94373
|
+
return join93(this.projectDir, ".claude", CK_JSON_FILE);
|
|
94113
94374
|
}
|
|
94114
94375
|
async loadInstalledSettings() {
|
|
94115
94376
|
const ckJsonPath = this.getCkJsonPath();
|
|
@@ -94184,7 +94445,9 @@ class InstalledSettingsTracker {
|
|
|
94184
94445
|
|
|
94185
94446
|
// src/domains/installation/merger/settings-processor.ts
|
|
94186
94447
|
init_settings_merger();
|
|
94448
|
+
init_command_normalizer();
|
|
94187
94449
|
init_logger();
|
|
94450
|
+
init_path_resolver();
|
|
94188
94451
|
var import_fs_extra14 = __toESM(require_lib(), 1);
|
|
94189
94452
|
var import_semver3 = __toESM(require_semver2(), 1);
|
|
94190
94453
|
|
|
@@ -94228,16 +94491,15 @@ class SettingsProcessor {
|
|
|
94228
94491
|
const sourceContent = await import_fs_extra14.readFile(sourceFile, "utf-8");
|
|
94229
94492
|
let transformedSource = sourceContent;
|
|
94230
94493
|
if (this.isGlobal) {
|
|
94231
|
-
const
|
|
94232
|
-
transformedSource = this.transformClaudePaths(sourceContent,
|
|
94494
|
+
const globalRoot = this.getCanonicalGlobalCommandRoot();
|
|
94495
|
+
transformedSource = this.transformClaudePaths(sourceContent, globalRoot);
|
|
94233
94496
|
if (transformedSource !== sourceContent) {
|
|
94234
|
-
logger.debug(`Transformed .claude/ paths to ${
|
|
94497
|
+
logger.debug(`Transformed .claude/ paths to ${globalRoot} in settings.json for global installation`);
|
|
94235
94498
|
}
|
|
94236
94499
|
} else {
|
|
94237
|
-
|
|
94238
|
-
transformedSource = this.transformClaudePaths(sourceContent, projectDirVar);
|
|
94500
|
+
transformedSource = this.transformClaudePaths(sourceContent, "$CLAUDE_PROJECT_DIR");
|
|
94239
94501
|
if (transformedSource !== sourceContent) {
|
|
94240
|
-
logger.debug(
|
|
94502
|
+
logger.debug('Transformed .claude/ paths to "$CLAUDE_PROJECT_DIR"/.claude/ in settings.json for local installation');
|
|
94241
94503
|
}
|
|
94242
94504
|
}
|
|
94243
94505
|
const destExists = await import_fs_extra14.pathExists(destFile);
|
|
@@ -94265,6 +94527,7 @@ class SettingsProcessor {
|
|
|
94265
94527
|
}
|
|
94266
94528
|
await this.injectTeamHooksIfSupported(destFile);
|
|
94267
94529
|
}
|
|
94530
|
+
await this.repairSiblingSettingsLocal(destFile);
|
|
94268
94531
|
} catch (error) {
|
|
94269
94532
|
logger.error(`Failed to process settings.json: ${error}`);
|
|
94270
94533
|
await import_fs_extra14.copy(sourceFile, destFile, { overwrite: true });
|
|
@@ -94469,36 +94732,27 @@ class SettingsProcessor {
|
|
|
94469
94732
|
const content = await import_fs_extra14.readFile(destFile, "utf-8");
|
|
94470
94733
|
if (!content.trim())
|
|
94471
94734
|
return null;
|
|
94472
|
-
const
|
|
94473
|
-
|
|
94474
|
-
|
|
94475
|
-
normalized = normalized.replace(/\$CLAUDE_PROJECT_DIR/g, homeVar);
|
|
94476
|
-
normalized = normalized.replace(/"%CLAUDE_PROJECT_DIR%"/g, `"${homeVar}"`);
|
|
94477
|
-
normalized = normalized.replace(/%CLAUDE_PROJECT_DIR%/g, homeVar);
|
|
94478
|
-
normalized = normalized.replace(/"%USERPROFILE%"/g, `"${homeVar}"`);
|
|
94479
|
-
normalized = normalized.replace(/%USERPROFILE%/g, homeVar);
|
|
94480
|
-
if (normalized !== content) {
|
|
94481
|
-
logger.debug("Normalized $CLAUDE_PROJECT_DIR paths to $HOME in existing global settings");
|
|
94482
|
-
}
|
|
94483
|
-
return JSON.parse(normalized);
|
|
94735
|
+
const parsedSettings = JSON.parse(content);
|
|
94736
|
+
this.fixHookCommandPaths(parsedSettings);
|
|
94737
|
+
return parsedSettings;
|
|
94484
94738
|
} catch {
|
|
94485
94739
|
return null;
|
|
94486
94740
|
}
|
|
94487
94741
|
}
|
|
94488
|
-
transformClaudePaths(content,
|
|
94742
|
+
transformClaudePaths(content, root) {
|
|
94489
94743
|
if (/\.claude\/[^\s"']*[;`$&|><]/.test(content)) {
|
|
94490
94744
|
logger.warning("Potentially unsafe characters detected in .claude/ paths");
|
|
94491
94745
|
throw new Error("Settings file contains potentially unsafe path characters");
|
|
94492
94746
|
}
|
|
94493
94747
|
let transformed = content;
|
|
94494
|
-
const rawPrefix = prefix.replace(/"/g, "");
|
|
94495
94748
|
transformed = transformed.replace(/(node\s+)(?:\.\/)?(\.claude\/[^\s"\\]+)([^"\\]*)/g, (_match, nodePrefix, relativePath, suffix) => {
|
|
94496
|
-
|
|
94497
|
-
return rawPrefix === "$CLAUDE_PROJECT_DIR" ? `${nodePrefix}\\"${rawPrefix}\\"/${normalizedRelativePath}${suffix}` : `${nodePrefix}\\"${rawPrefix}/${normalizedRelativePath}\\"${suffix}`;
|
|
94749
|
+
return this.formatCommandPath(nodePrefix, root, relativePath, suffix).replace(/"/g, "\\\"");
|
|
94498
94750
|
});
|
|
94499
|
-
if (
|
|
94500
|
-
transformed = transformed.replace(
|
|
94501
|
-
transformed = transformed.replace(
|
|
94751
|
+
if (this.isGlobal) {
|
|
94752
|
+
transformed = transformed.replace(/"\$CLAUDE_PROJECT_DIR"/g, `"${root}"`);
|
|
94753
|
+
transformed = transformed.replace(/\$CLAUDE_PROJECT_DIR/g, root);
|
|
94754
|
+
transformed = transformed.replace(/"%CLAUDE_PROJECT_DIR%"/g, `"${root}"`);
|
|
94755
|
+
transformed = transformed.replace(/%CLAUDE_PROJECT_DIR%/g, root);
|
|
94502
94756
|
}
|
|
94503
94757
|
return transformed;
|
|
94504
94758
|
}
|
|
@@ -94539,48 +94793,71 @@ class SettingsProcessor {
|
|
|
94539
94793
|
return fixed;
|
|
94540
94794
|
}
|
|
94541
94795
|
fixSingleCommandPath(cmd) {
|
|
94542
|
-
|
|
94543
|
-
return cmd;
|
|
94544
|
-
const bareRelativeMatch = cmd.match(/^(node\s+)(?:\.\/)?(\.claude[/\\][^\s"]+)(.*)$/);
|
|
94545
|
-
if (bareRelativeMatch) {
|
|
94546
|
-
const [, nodePrefix, relativePath, suffix] = bareRelativeMatch;
|
|
94547
|
-
return this.formatCommandPath(nodePrefix, this.isGlobal ? "$HOME" : "$CLAUDE_PROJECT_DIR", relativePath, suffix);
|
|
94548
|
-
}
|
|
94549
|
-
const embeddedQuotedMatch = cmd.match(/^(node\s+)"(\$HOME|\$CLAUDE_PROJECT_DIR|%USERPROFILE%|%CLAUDE_PROJECT_DIR%)[/\\](\.claude[/\\][^"]+)"(.*)$/);
|
|
94550
|
-
if (embeddedQuotedMatch) {
|
|
94551
|
-
const [, nodePrefix, capturedVar, relativePath, suffix] = embeddedQuotedMatch;
|
|
94552
|
-
return this.formatCommandPath(nodePrefix, capturedVar, relativePath, suffix);
|
|
94553
|
-
}
|
|
94554
|
-
const varOnlyQuotedMatch = cmd.match(/^(node\s+)"(\$HOME|\$CLAUDE_PROJECT_DIR|%USERPROFILE%|%CLAUDE_PROJECT_DIR%)"[/\\](\.claude[/\\][^\s"]+)(.*)$/);
|
|
94555
|
-
if (varOnlyQuotedMatch) {
|
|
94556
|
-
const [, nodePrefix, capturedVar, relativePath, suffix] = varOnlyQuotedMatch;
|
|
94557
|
-
return this.formatCommandPath(nodePrefix, capturedVar, relativePath, suffix);
|
|
94558
|
-
}
|
|
94559
|
-
const tildeMatch = cmd.match(/^(node\s+)~[/\\](\.claude[/\\][^\s"]+)(.*)$/);
|
|
94560
|
-
if (tildeMatch) {
|
|
94561
|
-
const [, nodePrefix, relativePath, suffix] = tildeMatch;
|
|
94562
|
-
return this.formatCommandPath(nodePrefix, "$HOME", relativePath, suffix);
|
|
94563
|
-
}
|
|
94564
|
-
const unquotedMatch = cmd.match(/^(node\s+)(\$HOME|\$CLAUDE_PROJECT_DIR|%USERPROFILE%|%CLAUDE_PROJECT_DIR%)[/\\](\.claude[/\\][^\s"]+)(.*)$/);
|
|
94565
|
-
if (unquotedMatch) {
|
|
94566
|
-
const [, nodePrefix, capturedVar, relativePath, suffix] = unquotedMatch;
|
|
94567
|
-
return this.formatCommandPath(nodePrefix, capturedVar, relativePath, suffix);
|
|
94568
|
-
}
|
|
94569
|
-
return cmd;
|
|
94796
|
+
return repairClaudeNodeCommandPath(cmd, this.getClaudeCommandRoot()).command;
|
|
94570
94797
|
}
|
|
94571
94798
|
formatCommandPath(nodePrefix, capturedVar, relativePath, suffix = "") {
|
|
94572
|
-
const
|
|
94573
|
-
const normalizedRelativePath =
|
|
94574
|
-
return
|
|
94799
|
+
const canonicalRoot = this.canonicalizePathRoot(capturedVar);
|
|
94800
|
+
const normalizedRelativePath = this.normalizeRelativePath(canonicalRoot, relativePath);
|
|
94801
|
+
return canonicalRoot === "$CLAUDE_PROJECT_DIR" ? `${nodePrefix}"${canonicalRoot}"/${normalizedRelativePath}${suffix}` : `${nodePrefix}"${canonicalRoot}/${normalizedRelativePath}"${suffix}`;
|
|
94575
94802
|
}
|
|
94576
|
-
|
|
94803
|
+
canonicalizePathRoot(capturedVar) {
|
|
94577
94804
|
switch (capturedVar) {
|
|
94578
94805
|
case "%USERPROFILE%":
|
|
94579
|
-
|
|
94806
|
+
case "$HOME":
|
|
94807
|
+
return this.isGlobal ? this.getCanonicalGlobalCommandRoot() : "$HOME";
|
|
94580
94808
|
case "%CLAUDE_PROJECT_DIR%":
|
|
94581
|
-
|
|
94809
|
+
case "$CLAUDE_PROJECT_DIR":
|
|
94810
|
+
return this.isGlobal ? this.getCanonicalGlobalCommandRoot() : "$CLAUDE_PROJECT_DIR";
|
|
94582
94811
|
default:
|
|
94583
|
-
return capturedVar;
|
|
94812
|
+
return capturedVar.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
94813
|
+
}
|
|
94814
|
+
}
|
|
94815
|
+
normalizeRelativePath(root, relativePath) {
|
|
94816
|
+
const normalizedRelativePath = relativePath.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
94817
|
+
if (root !== "$CLAUDE_PROJECT_DIR" && this.usesCustomGlobalInstallPath()) {
|
|
94818
|
+
return normalizedRelativePath.replace(/^\.claude\//, "");
|
|
94819
|
+
}
|
|
94820
|
+
return normalizedRelativePath;
|
|
94821
|
+
}
|
|
94822
|
+
getCanonicalGlobalCommandRoot() {
|
|
94823
|
+
if (this.usesCustomGlobalInstallPath()) {
|
|
94824
|
+
return PathResolver.getGlobalKitDir().replace(/\\/g, "/").replace(/\/+$/, "");
|
|
94825
|
+
}
|
|
94826
|
+
return "$HOME";
|
|
94827
|
+
}
|
|
94828
|
+
usesCustomGlobalInstallPath() {
|
|
94829
|
+
if (!this.isGlobal || !this.projectDir) {
|
|
94830
|
+
if (this.isGlobal && !this.projectDir) {
|
|
94831
|
+
logger.debug("usesCustomGlobalInstallPath: global mode but projectDir not set — defaulting to $HOME");
|
|
94832
|
+
}
|
|
94833
|
+
return false;
|
|
94834
|
+
}
|
|
94835
|
+
const configuredGlobalDir = PathResolver.getGlobalKitDir().replace(/\\/g, "/").replace(/\/+$/, "");
|
|
94836
|
+
const defaultGlobalDir = join94(homedir33(), ".claude").replace(/\\/g, "/");
|
|
94837
|
+
return configuredGlobalDir !== defaultGlobalDir;
|
|
94838
|
+
}
|
|
94839
|
+
getClaudeCommandRoot() {
|
|
94840
|
+
return this.isGlobal ? this.getCanonicalGlobalCommandRoot() : "$CLAUDE_PROJECT_DIR";
|
|
94841
|
+
}
|
|
94842
|
+
async repairSettingsFile(filePath) {
|
|
94843
|
+
const settings = await SettingsMerger.readSettingsFile(filePath);
|
|
94844
|
+
if (!settings) {
|
|
94845
|
+
return false;
|
|
94846
|
+
}
|
|
94847
|
+
const pathsFixed = this.fixHookCommandPaths(settings);
|
|
94848
|
+
if (!pathsFixed) {
|
|
94849
|
+
return false;
|
|
94850
|
+
}
|
|
94851
|
+
await SettingsMerger.writeSettingsFile(filePath, settings);
|
|
94852
|
+
return true;
|
|
94853
|
+
}
|
|
94854
|
+
async repairSiblingSettingsLocal(destFile) {
|
|
94855
|
+
const settingsLocalPath = join94(dirname28(destFile), "settings.local.json");
|
|
94856
|
+
if (settingsLocalPath === destFile || !await import_fs_extra14.pathExists(settingsLocalPath)) {
|
|
94857
|
+
return;
|
|
94858
|
+
}
|
|
94859
|
+
if (await this.repairSettingsFile(settingsLocalPath)) {
|
|
94860
|
+
logger.info(`Repaired stale .claude command paths in ${settingsLocalPath}`);
|
|
94584
94861
|
}
|
|
94585
94862
|
}
|
|
94586
94863
|
detectClaudeCodeVersion() {
|
|
@@ -94631,7 +94908,7 @@ class SettingsProcessor {
|
|
|
94631
94908
|
{ event: "TeammateIdle", handler: "teammate-idle-handler.cjs" }
|
|
94632
94909
|
];
|
|
94633
94910
|
for (const { event, handler } of teamHooks) {
|
|
94634
|
-
const hookCommand = this.formatCommandPath("node ", this.isGlobal ?
|
|
94911
|
+
const hookCommand = this.formatCommandPath("node ", this.isGlobal ? this.getCanonicalGlobalCommandRoot() : "$CLAUDE_PROJECT_DIR", `.claude/hooks/${handler}`);
|
|
94635
94912
|
const eventHooks = settings.hooks[event];
|
|
94636
94913
|
if (eventHooks && eventHooks.length > 0)
|
|
94637
94914
|
continue;
|
|
@@ -94738,7 +95015,7 @@ class CopyExecutor {
|
|
|
94738
95015
|
for (const file of files) {
|
|
94739
95016
|
const relativePath = relative13(sourceDir, file);
|
|
94740
95017
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
94741
|
-
const destPath =
|
|
95018
|
+
const destPath = join95(destDir, relativePath);
|
|
94742
95019
|
if (await import_fs_extra15.pathExists(destPath)) {
|
|
94743
95020
|
if (this.fileScanner.shouldNeverCopy(normalizedRelativePath)) {
|
|
94744
95021
|
logger.debug(`Security-sensitive file exists but won't be overwritten: ${normalizedRelativePath}`);
|
|
@@ -94760,7 +95037,7 @@ class CopyExecutor {
|
|
|
94760
95037
|
for (const file of files) {
|
|
94761
95038
|
const relativePath = relative13(sourceDir, file);
|
|
94762
95039
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
94763
|
-
const destPath =
|
|
95040
|
+
const destPath = join95(destDir, relativePath);
|
|
94764
95041
|
if (this.fileScanner.shouldNeverCopy(normalizedRelativePath)) {
|
|
94765
95042
|
logger.debug(`Skipping security-sensitive file: ${normalizedRelativePath}`);
|
|
94766
95043
|
skippedCount++;
|
|
@@ -94837,10 +95114,10 @@ class CopyExecutor {
|
|
|
94837
95114
|
}
|
|
94838
95115
|
trackInstalledFile(relativePath) {
|
|
94839
95116
|
this.installedFiles.add(relativePath);
|
|
94840
|
-
let dir =
|
|
95117
|
+
let dir = dirname29(relativePath);
|
|
94841
95118
|
while (dir && dir !== "." && dir !== "/") {
|
|
94842
95119
|
this.installedDirectories.add(`${dir}/`);
|
|
94843
|
-
dir =
|
|
95120
|
+
dir = dirname29(dir);
|
|
94844
95121
|
}
|
|
94845
95122
|
}
|
|
94846
95123
|
}
|
|
@@ -94933,15 +95210,15 @@ class FileMerger {
|
|
|
94933
95210
|
|
|
94934
95211
|
// src/domains/migration/legacy-migration.ts
|
|
94935
95212
|
import { readdir as readdir20, stat as stat15 } from "node:fs/promises";
|
|
94936
|
-
import { join as
|
|
95213
|
+
import { join as join99, relative as relative14 } from "node:path";
|
|
94937
95214
|
// src/services/file-operations/manifest/manifest-tracker.ts
|
|
94938
|
-
import { join as
|
|
95215
|
+
import { join as join98 } from "node:path";
|
|
94939
95216
|
|
|
94940
95217
|
// src/domains/migration/release-manifest.ts
|
|
94941
95218
|
init_logger();
|
|
94942
95219
|
init_zod();
|
|
94943
95220
|
var import_fs_extra16 = __toESM(require_lib(), 1);
|
|
94944
|
-
import { join as
|
|
95221
|
+
import { join as join96 } from "node:path";
|
|
94945
95222
|
var ReleaseManifestFileSchema = exports_external.object({
|
|
94946
95223
|
path: exports_external.string(),
|
|
94947
95224
|
checksum: exports_external.string().regex(/^[a-f0-9]{64}$/),
|
|
@@ -94956,7 +95233,7 @@ var ReleaseManifestSchema = exports_external.object({
|
|
|
94956
95233
|
|
|
94957
95234
|
class ReleaseManifestLoader {
|
|
94958
95235
|
static async load(extractDir) {
|
|
94959
|
-
const manifestPath =
|
|
95236
|
+
const manifestPath = join96(extractDir, "release-manifest.json");
|
|
94960
95237
|
try {
|
|
94961
95238
|
const content = await import_fs_extra16.readFile(manifestPath, "utf-8");
|
|
94962
95239
|
const parsed = JSON.parse(content);
|
|
@@ -94978,12 +95255,12 @@ init_safe_spinner();
|
|
|
94978
95255
|
|
|
94979
95256
|
// src/services/file-operations/manifest/manifest-updater.ts
|
|
94980
95257
|
init_metadata_migration();
|
|
94981
|
-
import { join as
|
|
95258
|
+
import { join as join97 } from "node:path";
|
|
94982
95259
|
init_logger();
|
|
94983
95260
|
init_types3();
|
|
94984
95261
|
var import_fs_extra17 = __toESM(require_lib(), 1);
|
|
94985
95262
|
async function writeManifest(claudeDir2, kitName, version, scope, kitType, trackedFiles, userConfigFiles) {
|
|
94986
|
-
const metadataPath =
|
|
95263
|
+
const metadataPath = join97(claudeDir2, "metadata.json");
|
|
94987
95264
|
const kit = kitType || (/\bmarketing\b/i.test(kitName) ? "marketing" : "engineer");
|
|
94988
95265
|
await import_fs_extra17.ensureFile(metadataPath);
|
|
94989
95266
|
let release = null;
|
|
@@ -95035,7 +95312,7 @@ async function writeManifest(claudeDir2, kitName, version, scope, kitType, track
|
|
|
95035
95312
|
}
|
|
95036
95313
|
}
|
|
95037
95314
|
async function removeKitFromManifest(claudeDir2, kit, options2) {
|
|
95038
|
-
const metadataPath =
|
|
95315
|
+
const metadataPath = join97(claudeDir2, "metadata.json");
|
|
95039
95316
|
if (!await import_fs_extra17.pathExists(metadataPath))
|
|
95040
95317
|
return false;
|
|
95041
95318
|
let release = null;
|
|
@@ -95067,7 +95344,7 @@ async function removeKitFromManifest(claudeDir2, kit, options2) {
|
|
|
95067
95344
|
}
|
|
95068
95345
|
}
|
|
95069
95346
|
async function retainTrackedFilesInManifest(claudeDir2, retainedPaths, options2) {
|
|
95070
|
-
const metadataPath =
|
|
95347
|
+
const metadataPath = join97(claudeDir2, "metadata.json");
|
|
95071
95348
|
if (!await import_fs_extra17.pathExists(metadataPath))
|
|
95072
95349
|
return false;
|
|
95073
95350
|
const normalizedPaths = new Set(retainedPaths.map((path15) => path15.replace(/\\/g, "/")));
|
|
@@ -95248,7 +95525,7 @@ function buildFileTrackingList(options2) {
|
|
|
95248
95525
|
if (!isGlobal && !installedPath.startsWith(".claude/"))
|
|
95249
95526
|
continue;
|
|
95250
95527
|
const relativePath = isGlobal ? installedPath : installedPath.replace(/^\.claude\//, "");
|
|
95251
|
-
const filePath =
|
|
95528
|
+
const filePath = join98(claudeDir2, relativePath);
|
|
95252
95529
|
const manifestEntry = releaseManifest ? ReleaseManifestLoader.findFile(releaseManifest, installedPath) : null;
|
|
95253
95530
|
const ownership = manifestEntry ? "ck" : "user";
|
|
95254
95531
|
filesToTrack.push({
|
|
@@ -95358,7 +95635,7 @@ class LegacyMigration {
|
|
|
95358
95635
|
continue;
|
|
95359
95636
|
if (SKIP_DIRS_ALL.includes(entry))
|
|
95360
95637
|
continue;
|
|
95361
|
-
const fullPath =
|
|
95638
|
+
const fullPath = join99(dir, entry);
|
|
95362
95639
|
let stats;
|
|
95363
95640
|
try {
|
|
95364
95641
|
stats = await stat15(fullPath);
|
|
@@ -95460,7 +95737,7 @@ User-created files (sample):`);
|
|
|
95460
95737
|
];
|
|
95461
95738
|
if (filesToChecksum.length > 0) {
|
|
95462
95739
|
const checksumResults = await mapWithLimit(filesToChecksum, async ({ relativePath, ownership }) => {
|
|
95463
|
-
const fullPath =
|
|
95740
|
+
const fullPath = join99(claudeDir2, relativePath);
|
|
95464
95741
|
const checksum = await OwnershipChecker.calculateChecksum(fullPath);
|
|
95465
95742
|
return { relativePath, checksum, ownership };
|
|
95466
95743
|
});
|
|
@@ -95481,7 +95758,7 @@ User-created files (sample):`);
|
|
|
95481
95758
|
installedAt: new Date().toISOString(),
|
|
95482
95759
|
files: trackedFiles
|
|
95483
95760
|
};
|
|
95484
|
-
const metadataPath =
|
|
95761
|
+
const metadataPath = join99(claudeDir2, "metadata.json");
|
|
95485
95762
|
await import_fs_extra18.writeFile(metadataPath, JSON.stringify(updatedMetadata, null, 2));
|
|
95486
95763
|
logger.success(`Migration complete: tracked ${trackedFiles.length} files`);
|
|
95487
95764
|
return true;
|
|
@@ -95587,7 +95864,7 @@ function buildConflictSummary(fileConflicts, hookConflicts, mcpConflicts) {
|
|
|
95587
95864
|
init_logger();
|
|
95588
95865
|
init_skip_directories();
|
|
95589
95866
|
var import_fs_extra19 = __toESM(require_lib(), 1);
|
|
95590
|
-
import { join as
|
|
95867
|
+
import { join as join100, relative as relative15, resolve as resolve25 } from "node:path";
|
|
95591
95868
|
|
|
95592
95869
|
class FileScanner2 {
|
|
95593
95870
|
static async getFiles(dirPath, relativeTo) {
|
|
@@ -95603,7 +95880,7 @@ class FileScanner2 {
|
|
|
95603
95880
|
logger.debug(`Skipping directory: ${entry}`);
|
|
95604
95881
|
continue;
|
|
95605
95882
|
}
|
|
95606
|
-
const fullPath =
|
|
95883
|
+
const fullPath = join100(dirPath, entry);
|
|
95607
95884
|
if (!FileScanner2.isSafePath(basePath, fullPath)) {
|
|
95608
95885
|
logger.warning(`Skipping potentially unsafe path: ${entry}`);
|
|
95609
95886
|
continue;
|
|
@@ -95638,8 +95915,8 @@ class FileScanner2 {
|
|
|
95638
95915
|
return files;
|
|
95639
95916
|
}
|
|
95640
95917
|
static async findCustomFiles(destDir, sourceDir, subPath) {
|
|
95641
|
-
const destSubDir =
|
|
95642
|
-
const sourceSubDir =
|
|
95918
|
+
const destSubDir = join100(destDir, subPath);
|
|
95919
|
+
const sourceSubDir = join100(sourceDir, subPath);
|
|
95643
95920
|
logger.debug(`findCustomFiles - destDir: ${destDir}`);
|
|
95644
95921
|
logger.debug(`findCustomFiles - sourceDir: ${sourceDir}`);
|
|
95645
95922
|
logger.debug(`findCustomFiles - subPath: "${subPath}"`);
|
|
@@ -95680,12 +95957,12 @@ class FileScanner2 {
|
|
|
95680
95957
|
init_logger();
|
|
95681
95958
|
var import_fs_extra20 = __toESM(require_lib(), 1);
|
|
95682
95959
|
import { lstat as lstat8, mkdir as mkdir28, readdir as readdir23, stat as stat16 } from "node:fs/promises";
|
|
95683
|
-
import { join as
|
|
95960
|
+
import { join as join102 } from "node:path";
|
|
95684
95961
|
|
|
95685
95962
|
// src/services/transformers/commands-prefix/content-transformer.ts
|
|
95686
95963
|
init_logger();
|
|
95687
95964
|
import { readFile as readFile44, readdir as readdir22, writeFile as writeFile26 } from "node:fs/promises";
|
|
95688
|
-
import { join as
|
|
95965
|
+
import { join as join101 } from "node:path";
|
|
95689
95966
|
var TRANSFORMABLE_EXTENSIONS = new Set([
|
|
95690
95967
|
".md",
|
|
95691
95968
|
".txt",
|
|
@@ -95746,7 +96023,7 @@ async function transformCommandReferences(directory, options2 = {}) {
|
|
|
95746
96023
|
async function processDirectory(dir) {
|
|
95747
96024
|
const entries = await readdir22(dir, { withFileTypes: true });
|
|
95748
96025
|
for (const entry of entries) {
|
|
95749
|
-
const fullPath =
|
|
96026
|
+
const fullPath = join101(dir, entry.name);
|
|
95750
96027
|
if (entry.isDirectory()) {
|
|
95751
96028
|
if (entry.name === "node_modules" || entry.name.startsWith(".") && entry.name !== ".claude") {
|
|
95752
96029
|
continue;
|
|
@@ -95821,14 +96098,14 @@ function shouldApplyPrefix(options2) {
|
|
|
95821
96098
|
// src/services/transformers/commands-prefix/prefix-applier.ts
|
|
95822
96099
|
async function applyPrefix(extractDir) {
|
|
95823
96100
|
validatePath(extractDir, "extractDir");
|
|
95824
|
-
const commandsDir =
|
|
96101
|
+
const commandsDir = join102(extractDir, ".claude", "commands");
|
|
95825
96102
|
if (!await import_fs_extra20.pathExists(commandsDir)) {
|
|
95826
96103
|
logger.verbose("No commands directory found, skipping prefix application");
|
|
95827
96104
|
return;
|
|
95828
96105
|
}
|
|
95829
96106
|
logger.info("Applying /ck: prefix to slash commands...");
|
|
95830
|
-
const backupDir =
|
|
95831
|
-
const tempDir =
|
|
96107
|
+
const backupDir = join102(extractDir, ".commands-backup");
|
|
96108
|
+
const tempDir = join102(extractDir, ".commands-prefix-temp");
|
|
95832
96109
|
try {
|
|
95833
96110
|
const entries = await readdir23(commandsDir);
|
|
95834
96111
|
if (entries.length === 0) {
|
|
@@ -95836,7 +96113,7 @@ async function applyPrefix(extractDir) {
|
|
|
95836
96113
|
return;
|
|
95837
96114
|
}
|
|
95838
96115
|
if (entries.length === 1 && entries[0] === "ck") {
|
|
95839
|
-
const ckDir2 =
|
|
96116
|
+
const ckDir2 = join102(commandsDir, "ck");
|
|
95840
96117
|
const ckStat = await stat16(ckDir2);
|
|
95841
96118
|
if (ckStat.isDirectory()) {
|
|
95842
96119
|
logger.verbose("Commands already have /ck: prefix, skipping");
|
|
@@ -95846,17 +96123,17 @@ async function applyPrefix(extractDir) {
|
|
|
95846
96123
|
await import_fs_extra20.copy(commandsDir, backupDir);
|
|
95847
96124
|
logger.verbose("Created backup of commands directory");
|
|
95848
96125
|
await mkdir28(tempDir, { recursive: true });
|
|
95849
|
-
const ckDir =
|
|
96126
|
+
const ckDir = join102(tempDir, "ck");
|
|
95850
96127
|
await mkdir28(ckDir, { recursive: true });
|
|
95851
96128
|
let processedCount = 0;
|
|
95852
96129
|
for (const entry of entries) {
|
|
95853
|
-
const sourcePath =
|
|
96130
|
+
const sourcePath = join102(commandsDir, entry);
|
|
95854
96131
|
const stats = await lstat8(sourcePath);
|
|
95855
96132
|
if (stats.isSymbolicLink()) {
|
|
95856
96133
|
logger.warning(`Skipping symlink for security: ${entry}`);
|
|
95857
96134
|
continue;
|
|
95858
96135
|
}
|
|
95859
|
-
const destPath =
|
|
96136
|
+
const destPath = join102(ckDir, entry);
|
|
95860
96137
|
await import_fs_extra20.copy(sourcePath, destPath, {
|
|
95861
96138
|
overwrite: false,
|
|
95862
96139
|
errorOnExist: true
|
|
@@ -95874,7 +96151,7 @@ async function applyPrefix(extractDir) {
|
|
|
95874
96151
|
await import_fs_extra20.move(tempDir, commandsDir);
|
|
95875
96152
|
await import_fs_extra20.remove(backupDir);
|
|
95876
96153
|
logger.success("Successfully reorganized commands to /ck: prefix");
|
|
95877
|
-
const claudeDir2 =
|
|
96154
|
+
const claudeDir2 = join102(extractDir, ".claude");
|
|
95878
96155
|
logger.info("Transforming command references in file contents...");
|
|
95879
96156
|
const transformResult = await transformCommandReferences(claudeDir2, {
|
|
95880
96157
|
verbose: logger.isVerbose()
|
|
@@ -95912,20 +96189,20 @@ async function applyPrefix(extractDir) {
|
|
|
95912
96189
|
// src/services/transformers/commands-prefix/prefix-cleaner.ts
|
|
95913
96190
|
init_metadata_migration();
|
|
95914
96191
|
import { lstat as lstat10, readdir as readdir25 } from "node:fs/promises";
|
|
95915
|
-
import { join as
|
|
96192
|
+
import { join as join104 } from "node:path";
|
|
95916
96193
|
init_logger();
|
|
95917
96194
|
var import_fs_extra22 = __toESM(require_lib(), 1);
|
|
95918
96195
|
|
|
95919
96196
|
// src/services/transformers/commands-prefix/file-processor.ts
|
|
95920
96197
|
import { lstat as lstat9, readdir as readdir24 } from "node:fs/promises";
|
|
95921
|
-
import { join as
|
|
96198
|
+
import { join as join103 } from "node:path";
|
|
95922
96199
|
init_logger();
|
|
95923
96200
|
var import_fs_extra21 = __toESM(require_lib(), 1);
|
|
95924
96201
|
async function scanDirectoryFiles(dir) {
|
|
95925
96202
|
const files = [];
|
|
95926
96203
|
const entries = await readdir24(dir);
|
|
95927
96204
|
for (const entry of entries) {
|
|
95928
|
-
const fullPath =
|
|
96205
|
+
const fullPath = join103(dir, entry);
|
|
95929
96206
|
const stats = await lstat9(fullPath);
|
|
95930
96207
|
if (stats.isSymbolicLink()) {
|
|
95931
96208
|
continue;
|
|
@@ -96053,8 +96330,8 @@ function isDifferentKitDirectory(dirName, currentKit) {
|
|
|
96053
96330
|
async function cleanupCommandsDirectory(targetDir, isGlobal, options2 = {}) {
|
|
96054
96331
|
const { dryRun = false } = options2;
|
|
96055
96332
|
validatePath(targetDir, "targetDir");
|
|
96056
|
-
const claudeDir2 = isGlobal ? targetDir :
|
|
96057
|
-
const commandsDir =
|
|
96333
|
+
const claudeDir2 = isGlobal ? targetDir : join104(targetDir, ".claude");
|
|
96334
|
+
const commandsDir = join104(claudeDir2, "commands");
|
|
96058
96335
|
const accumulator = {
|
|
96059
96336
|
results: [],
|
|
96060
96337
|
deletedCount: 0,
|
|
@@ -96096,7 +96373,7 @@ async function cleanupCommandsDirectory(targetDir, isGlobal, options2 = {}) {
|
|
|
96096
96373
|
}
|
|
96097
96374
|
const metadataForChecks = options2.kitType ? createKitSpecificMetadata(metadata, options2.kitType) : metadata;
|
|
96098
96375
|
for (const entry of entries) {
|
|
96099
|
-
const entryPath =
|
|
96376
|
+
const entryPath = join104(commandsDir, entry);
|
|
96100
96377
|
const stats = await lstat10(entryPath);
|
|
96101
96378
|
if (stats.isSymbolicLink()) {
|
|
96102
96379
|
addSymlinkSkip(entry, accumulator);
|
|
@@ -96153,7 +96430,7 @@ async function handleMerge(ctx) {
|
|
|
96153
96430
|
let customClaudeFiles = [];
|
|
96154
96431
|
if (!ctx.options.fresh) {
|
|
96155
96432
|
logger.info("Scanning for custom .claude files...");
|
|
96156
|
-
const scanSourceDir = ctx.options.global ?
|
|
96433
|
+
const scanSourceDir = ctx.options.global ? join105(ctx.extractDir, ".claude") : ctx.extractDir;
|
|
96157
96434
|
const scanTargetSubdir = ctx.options.global ? "" : ".claude";
|
|
96158
96435
|
customClaudeFiles = await FileScanner2.findCustomFiles(ctx.resolvedDir, scanSourceDir, scanTargetSubdir);
|
|
96159
96436
|
} else {
|
|
@@ -96218,8 +96495,8 @@ async function handleMerge(ctx) {
|
|
|
96218
96495
|
return { ...ctx, cancelled: true };
|
|
96219
96496
|
}
|
|
96220
96497
|
}
|
|
96221
|
-
const sourceDir = ctx.options.global ?
|
|
96222
|
-
const sourceMetadataPath = ctx.options.global ?
|
|
96498
|
+
const sourceDir = ctx.options.global ? join105(ctx.extractDir, ".claude") : ctx.extractDir;
|
|
96499
|
+
const sourceMetadataPath = ctx.options.global ? join105(sourceDir, "metadata.json") : join105(sourceDir, ".claude", "metadata.json");
|
|
96223
96500
|
let sourceMetadata = null;
|
|
96224
96501
|
try {
|
|
96225
96502
|
if (await import_fs_extra23.pathExists(sourceMetadataPath)) {
|
|
@@ -96276,7 +96553,7 @@ async function handleMerge(ctx) {
|
|
|
96276
96553
|
};
|
|
96277
96554
|
}
|
|
96278
96555
|
// src/commands/init/phases/migration-handler.ts
|
|
96279
|
-
import { join as
|
|
96556
|
+
import { join as join113 } from "node:path";
|
|
96280
96557
|
|
|
96281
96558
|
// src/domains/skills/skills-detector.ts
|
|
96282
96559
|
init_logger();
|
|
@@ -96292,7 +96569,7 @@ init_types3();
|
|
|
96292
96569
|
var import_fs_extra24 = __toESM(require_lib(), 1);
|
|
96293
96570
|
import { createHash as createHash5 } from "node:crypto";
|
|
96294
96571
|
import { readFile as readFile46, readdir as readdir26, writeFile as writeFile27 } from "node:fs/promises";
|
|
96295
|
-
import { join as
|
|
96572
|
+
import { join as join106, relative as relative16 } from "node:path";
|
|
96296
96573
|
|
|
96297
96574
|
class SkillsManifestManager {
|
|
96298
96575
|
static MANIFEST_FILENAME = ".skills-manifest.json";
|
|
@@ -96314,12 +96591,12 @@ class SkillsManifestManager {
|
|
|
96314
96591
|
return manifest;
|
|
96315
96592
|
}
|
|
96316
96593
|
static async writeManifest(skillsDir2, manifest) {
|
|
96317
|
-
const manifestPath =
|
|
96594
|
+
const manifestPath = join106(skillsDir2, SkillsManifestManager.MANIFEST_FILENAME);
|
|
96318
96595
|
await writeFile27(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
96319
96596
|
logger.debug(`Wrote manifest to: ${manifestPath}`);
|
|
96320
96597
|
}
|
|
96321
96598
|
static async readManifest(skillsDir2) {
|
|
96322
|
-
const manifestPath =
|
|
96599
|
+
const manifestPath = join106(skillsDir2, SkillsManifestManager.MANIFEST_FILENAME);
|
|
96323
96600
|
if (!await import_fs_extra24.pathExists(manifestPath)) {
|
|
96324
96601
|
logger.debug(`No manifest found at: ${manifestPath}`);
|
|
96325
96602
|
return null;
|
|
@@ -96342,7 +96619,7 @@ class SkillsManifestManager {
|
|
|
96342
96619
|
return "flat";
|
|
96343
96620
|
}
|
|
96344
96621
|
for (const dir of dirs.slice(0, 3)) {
|
|
96345
|
-
const dirPath =
|
|
96622
|
+
const dirPath = join106(skillsDir2, dir.name);
|
|
96346
96623
|
const subEntries = await readdir26(dirPath, { withFileTypes: true });
|
|
96347
96624
|
const hasSubdirs = subEntries.some((entry) => entry.isDirectory());
|
|
96348
96625
|
if (hasSubdirs) {
|
|
@@ -96361,7 +96638,7 @@ class SkillsManifestManager {
|
|
|
96361
96638
|
const entries = await readdir26(skillsDir2, { withFileTypes: true });
|
|
96362
96639
|
for (const entry of entries) {
|
|
96363
96640
|
if (entry.isDirectory() && !BUILD_ARTIFACT_DIRS.includes(entry.name) && !entry.name.startsWith(".")) {
|
|
96364
|
-
const skillPath =
|
|
96641
|
+
const skillPath = join106(skillsDir2, entry.name);
|
|
96365
96642
|
const hash = await SkillsManifestManager.hashDirectory(skillPath);
|
|
96366
96643
|
skills.push({
|
|
96367
96644
|
name: entry.name,
|
|
@@ -96373,11 +96650,11 @@ class SkillsManifestManager {
|
|
|
96373
96650
|
const categories = await readdir26(skillsDir2, { withFileTypes: true });
|
|
96374
96651
|
for (const category of categories) {
|
|
96375
96652
|
if (category.isDirectory() && !BUILD_ARTIFACT_DIRS.includes(category.name) && !category.name.startsWith(".")) {
|
|
96376
|
-
const categoryPath =
|
|
96653
|
+
const categoryPath = join106(skillsDir2, category.name);
|
|
96377
96654
|
const skillEntries = await readdir26(categoryPath, { withFileTypes: true });
|
|
96378
96655
|
for (const skillEntry of skillEntries) {
|
|
96379
96656
|
if (skillEntry.isDirectory() && !skillEntry.name.startsWith(".")) {
|
|
96380
|
-
const skillPath =
|
|
96657
|
+
const skillPath = join106(categoryPath, skillEntry.name);
|
|
96381
96658
|
const hash = await SkillsManifestManager.hashDirectory(skillPath);
|
|
96382
96659
|
skills.push({
|
|
96383
96660
|
name: skillEntry.name,
|
|
@@ -96407,7 +96684,7 @@ class SkillsManifestManager {
|
|
|
96407
96684
|
const files = [];
|
|
96408
96685
|
const entries = await readdir26(dirPath, { withFileTypes: true });
|
|
96409
96686
|
for (const entry of entries) {
|
|
96410
|
-
const fullPath =
|
|
96687
|
+
const fullPath = join106(dirPath, entry.name);
|
|
96411
96688
|
if (entry.name.startsWith(".") || BUILD_ARTIFACT_DIRS.includes(entry.name)) {
|
|
96412
96689
|
continue;
|
|
96413
96690
|
}
|
|
@@ -96529,7 +96806,7 @@ function getPathMapping(skillName, oldBasePath, newBasePath) {
|
|
|
96529
96806
|
// src/domains/skills/detection/script-detector.ts
|
|
96530
96807
|
var import_fs_extra25 = __toESM(require_lib(), 1);
|
|
96531
96808
|
import { readdir as readdir27 } from "node:fs/promises";
|
|
96532
|
-
import { join as
|
|
96809
|
+
import { join as join107 } from "node:path";
|
|
96533
96810
|
async function scanDirectory(skillsDir2) {
|
|
96534
96811
|
if (!await import_fs_extra25.pathExists(skillsDir2)) {
|
|
96535
96812
|
return ["flat", []];
|
|
@@ -96542,12 +96819,12 @@ async function scanDirectory(skillsDir2) {
|
|
|
96542
96819
|
let totalSkillLikeCount = 0;
|
|
96543
96820
|
const allSkills = [];
|
|
96544
96821
|
for (const dir of dirs) {
|
|
96545
|
-
const dirPath =
|
|
96822
|
+
const dirPath = join107(skillsDir2, dir.name);
|
|
96546
96823
|
const subEntries = await readdir27(dirPath, { withFileTypes: true });
|
|
96547
96824
|
const subdirs = subEntries.filter((entry) => entry.isDirectory() && !entry.name.startsWith("."));
|
|
96548
96825
|
if (subdirs.length > 0) {
|
|
96549
96826
|
for (const subdir of subdirs.slice(0, 3)) {
|
|
96550
|
-
const subdirPath =
|
|
96827
|
+
const subdirPath = join107(dirPath, subdir.name);
|
|
96551
96828
|
const subdirFiles = await readdir27(subdirPath, { withFileTypes: true });
|
|
96552
96829
|
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"));
|
|
96553
96830
|
if (hasSkillMarker) {
|
|
@@ -96704,12 +96981,12 @@ class SkillsMigrationDetector {
|
|
|
96704
96981
|
// src/domains/skills/skills-migrator.ts
|
|
96705
96982
|
init_logger();
|
|
96706
96983
|
init_types3();
|
|
96707
|
-
import { join as
|
|
96984
|
+
import { join as join112 } from "node:path";
|
|
96708
96985
|
|
|
96709
96986
|
// src/domains/skills/migrator/migration-executor.ts
|
|
96710
96987
|
init_logger();
|
|
96711
96988
|
import { copyFile as copyFile6, mkdir as mkdir29, readdir as readdir28, rm as rm11 } from "node:fs/promises";
|
|
96712
|
-
import { join as
|
|
96989
|
+
import { join as join108 } from "node:path";
|
|
96713
96990
|
var import_fs_extra27 = __toESM(require_lib(), 1);
|
|
96714
96991
|
|
|
96715
96992
|
// src/domains/skills/skills-migration-prompts.ts
|
|
@@ -96874,8 +97151,8 @@ async function copySkillDirectory(sourceDir, destDir) {
|
|
|
96874
97151
|
await mkdir29(destDir, { recursive: true });
|
|
96875
97152
|
const entries = await readdir28(sourceDir, { withFileTypes: true });
|
|
96876
97153
|
for (const entry of entries) {
|
|
96877
|
-
const sourcePath =
|
|
96878
|
-
const destPath =
|
|
97154
|
+
const sourcePath = join108(sourceDir, entry.name);
|
|
97155
|
+
const destPath = join108(destDir, entry.name);
|
|
96879
97156
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.isSymbolicLink()) {
|
|
96880
97157
|
continue;
|
|
96881
97158
|
}
|
|
@@ -96890,7 +97167,7 @@ async function executeInternal(mappings, customizations, currentSkillsDir, inter
|
|
|
96890
97167
|
const migrated = [];
|
|
96891
97168
|
const preserved = [];
|
|
96892
97169
|
const errors2 = [];
|
|
96893
|
-
const tempDir =
|
|
97170
|
+
const tempDir = join108(currentSkillsDir, "..", ".skills-migration-temp");
|
|
96894
97171
|
await mkdir29(tempDir, { recursive: true });
|
|
96895
97172
|
try {
|
|
96896
97173
|
for (const mapping of mappings) {
|
|
@@ -96911,9 +97188,9 @@ async function executeInternal(mappings, customizations, currentSkillsDir, inter
|
|
|
96911
97188
|
}
|
|
96912
97189
|
}
|
|
96913
97190
|
const category = mapping.category;
|
|
96914
|
-
const targetPath = category ?
|
|
97191
|
+
const targetPath = category ? join108(tempDir, category, skillName) : join108(tempDir, skillName);
|
|
96915
97192
|
if (category) {
|
|
96916
|
-
await mkdir29(
|
|
97193
|
+
await mkdir29(join108(tempDir, category), { recursive: true });
|
|
96917
97194
|
}
|
|
96918
97195
|
await copySkillDirectory(currentSkillPath, targetPath);
|
|
96919
97196
|
migrated.push(skillName);
|
|
@@ -96980,7 +97257,7 @@ init_logger();
|
|
|
96980
97257
|
init_types3();
|
|
96981
97258
|
var import_fs_extra28 = __toESM(require_lib(), 1);
|
|
96982
97259
|
import { copyFile as copyFile7, mkdir as mkdir30, readdir as readdir29, rm as rm12, stat as stat17 } from "node:fs/promises";
|
|
96983
|
-
import { basename as basename17, join as
|
|
97260
|
+
import { basename as basename17, join as join109, normalize as normalize9 } from "node:path";
|
|
96984
97261
|
function validatePath2(path15, paramName) {
|
|
96985
97262
|
if (!path15 || typeof path15 !== "string") {
|
|
96986
97263
|
throw new SkillsMigrationError(`${paramName} must be a non-empty string`);
|
|
@@ -97006,7 +97283,7 @@ class SkillsBackupManager {
|
|
|
97006
97283
|
const timestamp = Date.now();
|
|
97007
97284
|
const randomSuffix = Math.random().toString(36).substring(2, 8);
|
|
97008
97285
|
const backupDirName = `${SkillsBackupManager.BACKUP_PREFIX}${timestamp}-${randomSuffix}`;
|
|
97009
|
-
const backupDir = parentDir ?
|
|
97286
|
+
const backupDir = parentDir ? join109(parentDir, backupDirName) : join109(skillsDir2, "..", backupDirName);
|
|
97010
97287
|
logger.info(`Creating backup at: ${backupDir}`);
|
|
97011
97288
|
try {
|
|
97012
97289
|
await mkdir30(backupDir, { recursive: true });
|
|
@@ -97057,7 +97334,7 @@ class SkillsBackupManager {
|
|
|
97057
97334
|
}
|
|
97058
97335
|
try {
|
|
97059
97336
|
const entries = await readdir29(parentDir, { withFileTypes: true });
|
|
97060
|
-
const backups = entries.filter((entry) => entry.isDirectory() && entry.name.startsWith(SkillsBackupManager.BACKUP_PREFIX)).map((entry) =>
|
|
97337
|
+
const backups = entries.filter((entry) => entry.isDirectory() && entry.name.startsWith(SkillsBackupManager.BACKUP_PREFIX)).map((entry) => join109(parentDir, entry.name));
|
|
97061
97338
|
backups.sort().reverse();
|
|
97062
97339
|
return backups;
|
|
97063
97340
|
} catch (error) {
|
|
@@ -97085,8 +97362,8 @@ class SkillsBackupManager {
|
|
|
97085
97362
|
static async copyDirectory(sourceDir, destDir) {
|
|
97086
97363
|
const entries = await readdir29(sourceDir, { withFileTypes: true });
|
|
97087
97364
|
for (const entry of entries) {
|
|
97088
|
-
const sourcePath =
|
|
97089
|
-
const destPath =
|
|
97365
|
+
const sourcePath = join109(sourceDir, entry.name);
|
|
97366
|
+
const destPath = join109(destDir, entry.name);
|
|
97090
97367
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.isSymbolicLink()) {
|
|
97091
97368
|
continue;
|
|
97092
97369
|
}
|
|
@@ -97102,7 +97379,7 @@ class SkillsBackupManager {
|
|
|
97102
97379
|
let size = 0;
|
|
97103
97380
|
const entries = await readdir29(dirPath, { withFileTypes: true });
|
|
97104
97381
|
for (const entry of entries) {
|
|
97105
|
-
const fullPath =
|
|
97382
|
+
const fullPath = join109(dirPath, entry.name);
|
|
97106
97383
|
if (entry.isSymbolicLink()) {
|
|
97107
97384
|
continue;
|
|
97108
97385
|
}
|
|
@@ -97138,12 +97415,12 @@ init_skip_directories();
|
|
|
97138
97415
|
import { createHash as createHash6 } from "node:crypto";
|
|
97139
97416
|
import { createReadStream as createReadStream3 } from "node:fs";
|
|
97140
97417
|
import { readFile as readFile47, readdir as readdir30 } from "node:fs/promises";
|
|
97141
|
-
import { join as
|
|
97418
|
+
import { join as join110, relative as relative17 } from "node:path";
|
|
97142
97419
|
async function getAllFiles(dirPath) {
|
|
97143
97420
|
const files = [];
|
|
97144
97421
|
const entries = await readdir30(dirPath, { withFileTypes: true });
|
|
97145
97422
|
for (const entry of entries) {
|
|
97146
|
-
const fullPath =
|
|
97423
|
+
const fullPath = join110(dirPath, entry.name);
|
|
97147
97424
|
if (entry.name.startsWith(".") || BUILD_ARTIFACT_DIRS.includes(entry.name) || entry.isSymbolicLink()) {
|
|
97148
97425
|
continue;
|
|
97149
97426
|
}
|
|
@@ -97270,7 +97547,7 @@ async function detectFileChanges(currentSkillPath, baselineSkillPath) {
|
|
|
97270
97547
|
init_types3();
|
|
97271
97548
|
var import_fs_extra30 = __toESM(require_lib(), 1);
|
|
97272
97549
|
import { readdir as readdir31 } from "node:fs/promises";
|
|
97273
|
-
import { join as
|
|
97550
|
+
import { join as join111, normalize as normalize10 } from "node:path";
|
|
97274
97551
|
function validatePath3(path15, paramName) {
|
|
97275
97552
|
if (!path15 || typeof path15 !== "string") {
|
|
97276
97553
|
throw new SkillsMigrationError(`${paramName} must be a non-empty string`);
|
|
@@ -97291,13 +97568,13 @@ async function scanSkillsDirectory(skillsDir2) {
|
|
|
97291
97568
|
if (dirs.length === 0) {
|
|
97292
97569
|
return ["flat", []];
|
|
97293
97570
|
}
|
|
97294
|
-
const firstDirPath =
|
|
97571
|
+
const firstDirPath = join111(skillsDir2, dirs[0].name);
|
|
97295
97572
|
const subEntries = await readdir31(firstDirPath, { withFileTypes: true });
|
|
97296
97573
|
const subdirs = subEntries.filter((entry) => entry.isDirectory() && !entry.name.startsWith("."));
|
|
97297
97574
|
if (subdirs.length > 0) {
|
|
97298
97575
|
let skillLikeCount = 0;
|
|
97299
97576
|
for (const subdir of subdirs.slice(0, 3)) {
|
|
97300
|
-
const subdirPath =
|
|
97577
|
+
const subdirPath = join111(firstDirPath, subdir.name);
|
|
97301
97578
|
const subdirFiles = await readdir31(subdirPath, { withFileTypes: true });
|
|
97302
97579
|
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"));
|
|
97303
97580
|
if (hasSkillMarker) {
|
|
@@ -97307,7 +97584,7 @@ async function scanSkillsDirectory(skillsDir2) {
|
|
|
97307
97584
|
if (skillLikeCount > 0) {
|
|
97308
97585
|
const skills = [];
|
|
97309
97586
|
for (const dir of dirs) {
|
|
97310
|
-
const categoryPath =
|
|
97587
|
+
const categoryPath = join111(skillsDir2, dir.name);
|
|
97311
97588
|
const skillDirs = await readdir31(categoryPath, { withFileTypes: true });
|
|
97312
97589
|
skills.push(...skillDirs.filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name));
|
|
97313
97590
|
}
|
|
@@ -97317,7 +97594,7 @@ async function scanSkillsDirectory(skillsDir2) {
|
|
|
97317
97594
|
return ["flat", dirs.map((dir) => dir.name)];
|
|
97318
97595
|
}
|
|
97319
97596
|
async function findSkillPath(skillsDir2, skillName) {
|
|
97320
|
-
const flatPath =
|
|
97597
|
+
const flatPath = join111(skillsDir2, skillName);
|
|
97321
97598
|
if (await import_fs_extra30.pathExists(flatPath)) {
|
|
97322
97599
|
return { path: flatPath, category: undefined };
|
|
97323
97600
|
}
|
|
@@ -97326,8 +97603,8 @@ async function findSkillPath(skillsDir2, skillName) {
|
|
|
97326
97603
|
if (!entry.isDirectory() || entry.name.startsWith(".") || entry.name === "node_modules") {
|
|
97327
97604
|
continue;
|
|
97328
97605
|
}
|
|
97329
|
-
const categoryPath =
|
|
97330
|
-
const skillPath =
|
|
97606
|
+
const categoryPath = join111(skillsDir2, entry.name);
|
|
97607
|
+
const skillPath = join111(categoryPath, skillName);
|
|
97331
97608
|
if (await import_fs_extra30.pathExists(skillPath)) {
|
|
97332
97609
|
return { path: skillPath, category: entry.name };
|
|
97333
97610
|
}
|
|
@@ -97421,7 +97698,7 @@ class SkillsMigrator {
|
|
|
97421
97698
|
}
|
|
97422
97699
|
}
|
|
97423
97700
|
if (options2.backup && !options2.dryRun) {
|
|
97424
|
-
const claudeDir2 =
|
|
97701
|
+
const claudeDir2 = join112(currentSkillsDir, "..");
|
|
97425
97702
|
result.backupPath = await SkillsBackupManager.createBackup(currentSkillsDir, claudeDir2);
|
|
97426
97703
|
logger.success(`Backup created at: ${result.backupPath}`);
|
|
97427
97704
|
}
|
|
@@ -97482,7 +97759,7 @@ async function handleMigration(ctx) {
|
|
|
97482
97759
|
logger.debug("Skipping skills migration (fresh installation)");
|
|
97483
97760
|
return ctx;
|
|
97484
97761
|
}
|
|
97485
|
-
const newSkillsDir =
|
|
97762
|
+
const newSkillsDir = join113(ctx.extractDir, ".claude", "skills");
|
|
97486
97763
|
const currentSkillsDir = PathResolver.buildSkillsPath(ctx.resolvedDir, ctx.options.global);
|
|
97487
97764
|
if (!await import_fs_extra31.pathExists(newSkillsDir) || !await import_fs_extra31.pathExists(currentSkillsDir)) {
|
|
97488
97765
|
return ctx;
|
|
@@ -97506,13 +97783,13 @@ async function handleMigration(ctx) {
|
|
|
97506
97783
|
}
|
|
97507
97784
|
// src/commands/init/phases/opencode-handler.ts
|
|
97508
97785
|
import { cp as cp3, readdir as readdir33, rm as rm13 } from "node:fs/promises";
|
|
97509
|
-
import { join as
|
|
97786
|
+
import { join as join115 } from "node:path";
|
|
97510
97787
|
|
|
97511
97788
|
// src/services/transformers/opencode-path-transformer.ts
|
|
97512
97789
|
init_logger();
|
|
97513
97790
|
import { readFile as readFile48, readdir as readdir32, writeFile as writeFile28 } from "node:fs/promises";
|
|
97514
97791
|
import { platform as platform14 } from "node:os";
|
|
97515
|
-
import { extname as extname5, join as
|
|
97792
|
+
import { extname as extname5, join as join114 } from "node:path";
|
|
97516
97793
|
var IS_WINDOWS2 = platform14() === "win32";
|
|
97517
97794
|
function getOpenCodeGlobalPath() {
|
|
97518
97795
|
return "$HOME/.config/opencode/";
|
|
@@ -97573,7 +97850,7 @@ async function transformPathsForGlobalOpenCode(directory, options2 = {}) {
|
|
|
97573
97850
|
async function processDirectory2(dir) {
|
|
97574
97851
|
const entries = await readdir32(dir, { withFileTypes: true });
|
|
97575
97852
|
for (const entry of entries) {
|
|
97576
|
-
const fullPath =
|
|
97853
|
+
const fullPath = join114(dir, entry.name);
|
|
97577
97854
|
if (entry.isDirectory()) {
|
|
97578
97855
|
if (entry.name === "node_modules" || entry.name.startsWith(".")) {
|
|
97579
97856
|
continue;
|
|
@@ -97612,7 +97889,7 @@ async function handleOpenCode(ctx) {
|
|
|
97612
97889
|
if (ctx.cancelled || !ctx.extractDir || !ctx.resolvedDir) {
|
|
97613
97890
|
return ctx;
|
|
97614
97891
|
}
|
|
97615
|
-
const openCodeSource =
|
|
97892
|
+
const openCodeSource = join115(ctx.extractDir, ".opencode");
|
|
97616
97893
|
if (!await import_fs_extra32.pathExists(openCodeSource)) {
|
|
97617
97894
|
logger.debug("No .opencode directory in archive, skipping");
|
|
97618
97895
|
return ctx;
|
|
@@ -97630,8 +97907,8 @@ async function handleOpenCode(ctx) {
|
|
|
97630
97907
|
await import_fs_extra32.ensureDir(targetDir);
|
|
97631
97908
|
const entries = await readdir33(openCodeSource, { withFileTypes: true });
|
|
97632
97909
|
for (const entry of entries) {
|
|
97633
|
-
const sourcePath =
|
|
97634
|
-
const targetPath =
|
|
97910
|
+
const sourcePath = join115(openCodeSource, entry.name);
|
|
97911
|
+
const targetPath = join115(targetDir, entry.name);
|
|
97635
97912
|
if (await import_fs_extra32.pathExists(targetPath)) {
|
|
97636
97913
|
if (!ctx.options.forceOverwrite) {
|
|
97637
97914
|
logger.verbose(`Skipping existing: ${entry.name}`);
|
|
@@ -97729,7 +98006,7 @@ Please use only one download method.`);
|
|
|
97729
98006
|
}
|
|
97730
98007
|
// src/commands/init/phases/post-install-handler.ts
|
|
97731
98008
|
init_projects_registry();
|
|
97732
|
-
import { join as
|
|
98009
|
+
import { join as join116 } from "node:path";
|
|
97733
98010
|
init_logger();
|
|
97734
98011
|
init_path_resolver();
|
|
97735
98012
|
var import_fs_extra33 = __toESM(require_lib(), 1);
|
|
@@ -97738,8 +98015,8 @@ async function handlePostInstall(ctx) {
|
|
|
97738
98015
|
return ctx;
|
|
97739
98016
|
}
|
|
97740
98017
|
if (ctx.options.global) {
|
|
97741
|
-
const claudeMdSource =
|
|
97742
|
-
const claudeMdDest =
|
|
98018
|
+
const claudeMdSource = join116(ctx.extractDir, "CLAUDE.md");
|
|
98019
|
+
const claudeMdDest = join116(ctx.resolvedDir, "CLAUDE.md");
|
|
97743
98020
|
if (await import_fs_extra33.pathExists(claudeMdSource)) {
|
|
97744
98021
|
if (ctx.options.fresh || !await import_fs_extra33.pathExists(claudeMdDest)) {
|
|
97745
98022
|
await import_fs_extra33.copy(claudeMdSource, claudeMdDest);
|
|
@@ -97787,7 +98064,7 @@ async function handlePostInstall(ctx) {
|
|
|
97787
98064
|
}
|
|
97788
98065
|
if (!ctx.options.skipSetup) {
|
|
97789
98066
|
await promptSetupWizardIfNeeded({
|
|
97790
|
-
envPath:
|
|
98067
|
+
envPath: join116(ctx.claudeDir, ".env"),
|
|
97791
98068
|
claudeDir: ctx.claudeDir,
|
|
97792
98069
|
isGlobal: ctx.options.global,
|
|
97793
98070
|
isNonInteractive: ctx.isNonInteractive,
|
|
@@ -97811,7 +98088,7 @@ async function handlePostInstall(ctx) {
|
|
|
97811
98088
|
init_config_manager();
|
|
97812
98089
|
init_github_client();
|
|
97813
98090
|
import { mkdir as mkdir31 } from "node:fs/promises";
|
|
97814
|
-
import { join as
|
|
98091
|
+
import { join as join118, resolve as resolve27 } from "node:path";
|
|
97815
98092
|
|
|
97816
98093
|
// src/domains/github/kit-access-checker.ts
|
|
97817
98094
|
init_logger();
|
|
@@ -97942,7 +98219,7 @@ async function runPreflightChecks() {
|
|
|
97942
98219
|
// src/domains/installation/fresh-installer.ts
|
|
97943
98220
|
init_metadata_migration();
|
|
97944
98221
|
import { existsSync as existsSync55, readdirSync as readdirSync6, rmSync as rmSync4, rmdirSync as rmdirSync2, unlinkSync as unlinkSync4 } from "node:fs";
|
|
97945
|
-
import { basename as basename18, dirname as
|
|
98222
|
+
import { basename as basename18, dirname as dirname30, join as join117, resolve as resolve26 } from "node:path";
|
|
97946
98223
|
init_logger();
|
|
97947
98224
|
init_safe_spinner();
|
|
97948
98225
|
var import_fs_extra34 = __toESM(require_lib(), 1);
|
|
@@ -97991,14 +98268,14 @@ async function analyzeFreshInstallation(claudeDir2) {
|
|
|
97991
98268
|
}
|
|
97992
98269
|
function cleanupEmptyDirectories2(filePath, claudeDir2) {
|
|
97993
98270
|
const normalizedClaudeDir = resolve26(claudeDir2);
|
|
97994
|
-
let currentDir = resolve26(
|
|
98271
|
+
let currentDir = resolve26(dirname30(filePath));
|
|
97995
98272
|
while (currentDir !== normalizedClaudeDir && currentDir.startsWith(normalizedClaudeDir)) {
|
|
97996
98273
|
try {
|
|
97997
98274
|
const entries = readdirSync6(currentDir);
|
|
97998
98275
|
if (entries.length === 0) {
|
|
97999
98276
|
rmdirSync2(currentDir);
|
|
98000
98277
|
logger.debug(`Removed empty directory: ${currentDir}`);
|
|
98001
|
-
currentDir = resolve26(
|
|
98278
|
+
currentDir = resolve26(dirname30(currentDir));
|
|
98002
98279
|
} else {
|
|
98003
98280
|
break;
|
|
98004
98281
|
}
|
|
@@ -98015,7 +98292,7 @@ async function removeFilesByOwnership(claudeDir2, analysis, includeModified) {
|
|
|
98015
98292
|
const filesToRemove = includeModified ? [...analysis.ckFiles, ...analysis.ckModifiedFiles] : analysis.ckFiles;
|
|
98016
98293
|
const filesToPreserve = includeModified ? analysis.userFiles : [...analysis.ckModifiedFiles, ...analysis.userFiles];
|
|
98017
98294
|
for (const file of filesToRemove) {
|
|
98018
|
-
const fullPath =
|
|
98295
|
+
const fullPath = join117(claudeDir2, file.path);
|
|
98019
98296
|
if (!existsSync55(fullPath)) {
|
|
98020
98297
|
continue;
|
|
98021
98298
|
}
|
|
@@ -98043,7 +98320,7 @@ async function removeFilesByOwnership(claudeDir2, analysis, includeModified) {
|
|
|
98043
98320
|
};
|
|
98044
98321
|
}
|
|
98045
98322
|
async function updateMetadataAfterFresh(claudeDir2, removedFiles) {
|
|
98046
|
-
const metadataPath =
|
|
98323
|
+
const metadataPath = join117(claudeDir2, "metadata.json");
|
|
98047
98324
|
if (!await import_fs_extra34.pathExists(metadataPath)) {
|
|
98048
98325
|
throw new Error("metadata.json is missing during fresh install cleanup");
|
|
98049
98326
|
}
|
|
@@ -98086,8 +98363,8 @@ function getFreshBackupTargets(claudeDir2, analysis, includeModified) {
|
|
|
98086
98363
|
mutatePaths: filesToRemove.length > 0 ? ["metadata.json"] : []
|
|
98087
98364
|
};
|
|
98088
98365
|
}
|
|
98089
|
-
const deletePaths = CLAUDEKIT_SUBDIRECTORIES.filter((subdir) => existsSync55(
|
|
98090
|
-
if (existsSync55(
|
|
98366
|
+
const deletePaths = CLAUDEKIT_SUBDIRECTORIES.filter((subdir) => existsSync55(join117(claudeDir2, subdir)));
|
|
98367
|
+
if (existsSync55(join117(claudeDir2, "metadata.json"))) {
|
|
98091
98368
|
deletePaths.push("metadata.json");
|
|
98092
98369
|
}
|
|
98093
98370
|
return {
|
|
@@ -98109,7 +98386,7 @@ async function removeSubdirectoriesFallback(claudeDir2) {
|
|
|
98109
98386
|
const removedFiles = [];
|
|
98110
98387
|
let removedDirCount = 0;
|
|
98111
98388
|
for (const subdir of CLAUDEKIT_SUBDIRECTORIES) {
|
|
98112
|
-
const subdirPath =
|
|
98389
|
+
const subdirPath = join117(claudeDir2, subdir);
|
|
98113
98390
|
if (await import_fs_extra34.pathExists(subdirPath)) {
|
|
98114
98391
|
rmSync4(subdirPath, { recursive: true, force: true });
|
|
98115
98392
|
removedDirCount++;
|
|
@@ -98117,7 +98394,7 @@ async function removeSubdirectoriesFallback(claudeDir2) {
|
|
|
98117
98394
|
logger.debug(`Removed subdirectory: ${subdir}/`);
|
|
98118
98395
|
}
|
|
98119
98396
|
}
|
|
98120
|
-
const metadataPath =
|
|
98397
|
+
const metadataPath = join117(claudeDir2, "metadata.json");
|
|
98121
98398
|
if (await import_fs_extra34.pathExists(metadataPath)) {
|
|
98122
98399
|
unlinkSync4(metadataPath);
|
|
98123
98400
|
removedFiles.push("metadata.json");
|
|
@@ -98399,7 +98676,7 @@ async function handleSelection(ctx) {
|
|
|
98399
98676
|
}
|
|
98400
98677
|
if (!ctx.options.fresh) {
|
|
98401
98678
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
98402
|
-
const claudeDir2 = prefix ?
|
|
98679
|
+
const claudeDir2 = prefix ? join118(resolvedDir, prefix) : resolvedDir;
|
|
98403
98680
|
try {
|
|
98404
98681
|
const existingMetadata = await readManifest(claudeDir2);
|
|
98405
98682
|
if (existingMetadata?.kits) {
|
|
@@ -98431,7 +98708,7 @@ async function handleSelection(ctx) {
|
|
|
98431
98708
|
}
|
|
98432
98709
|
if (ctx.options.fresh) {
|
|
98433
98710
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
98434
|
-
const claudeDir2 = prefix ?
|
|
98711
|
+
const claudeDir2 = prefix ? join118(resolvedDir, prefix) : resolvedDir;
|
|
98435
98712
|
const canProceed = await handleFreshInstallation(claudeDir2, ctx.prompts);
|
|
98436
98713
|
if (!canProceed) {
|
|
98437
98714
|
return { ...ctx, cancelled: true };
|
|
@@ -98451,7 +98728,7 @@ async function handleSelection(ctx) {
|
|
|
98451
98728
|
let currentVersion = null;
|
|
98452
98729
|
try {
|
|
98453
98730
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
98454
|
-
const claudeDir2 = prefix ?
|
|
98731
|
+
const claudeDir2 = prefix ? join118(resolvedDir, prefix) : resolvedDir;
|
|
98455
98732
|
const existingMetadata = await readManifest(claudeDir2);
|
|
98456
98733
|
currentVersion = existingMetadata?.kits?.[kitType]?.version || null;
|
|
98457
98734
|
if (currentVersion) {
|
|
@@ -98520,7 +98797,7 @@ async function handleSelection(ctx) {
|
|
|
98520
98797
|
if (ctx.options.yes && !ctx.options.fresh && !ctx.options.force && releaseTag && !isOfflineMode && !pendingKits?.length) {
|
|
98521
98798
|
try {
|
|
98522
98799
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
98523
|
-
const claudeDir2 = prefix ?
|
|
98800
|
+
const claudeDir2 = prefix ? join118(resolvedDir, prefix) : resolvedDir;
|
|
98524
98801
|
const existingMetadata = await readManifest(claudeDir2);
|
|
98525
98802
|
const installedKitVersion = existingMetadata?.kits?.[kitType]?.version;
|
|
98526
98803
|
if (installedKitVersion && versionsMatch(installedKitVersion, releaseTag)) {
|
|
@@ -98544,7 +98821,7 @@ async function handleSelection(ctx) {
|
|
|
98544
98821
|
}
|
|
98545
98822
|
// src/commands/init/phases/sync-handler.ts
|
|
98546
98823
|
import { copyFile as copyFile8, mkdir as mkdir32, open as open5, readFile as readFile50, rename as rename7, stat as stat18, unlink as unlink11, writeFile as writeFile30 } from "node:fs/promises";
|
|
98547
|
-
import { dirname as
|
|
98824
|
+
import { dirname as dirname31, join as join119, resolve as resolve28 } from "node:path";
|
|
98548
98825
|
init_logger();
|
|
98549
98826
|
init_path_resolver();
|
|
98550
98827
|
var import_fs_extra36 = __toESM(require_lib(), 1);
|
|
@@ -98554,13 +98831,13 @@ async function handleSync(ctx) {
|
|
|
98554
98831
|
return ctx;
|
|
98555
98832
|
}
|
|
98556
98833
|
const resolvedDir = ctx.options.global ? PathResolver.getGlobalKitDir() : resolve28(ctx.options.dir || ".");
|
|
98557
|
-
const claudeDir2 = ctx.options.global ? resolvedDir :
|
|
98834
|
+
const claudeDir2 = ctx.options.global ? resolvedDir : join119(resolvedDir, ".claude");
|
|
98558
98835
|
if (!await import_fs_extra36.pathExists(claudeDir2)) {
|
|
98559
98836
|
logger.error("Cannot sync: no .claude directory found");
|
|
98560
98837
|
ctx.prompts.note("Run 'ck init' without --sync to install first.", "No Installation Found");
|
|
98561
98838
|
return { ...ctx, cancelled: true };
|
|
98562
98839
|
}
|
|
98563
|
-
const metadataPath =
|
|
98840
|
+
const metadataPath = join119(claudeDir2, "metadata.json");
|
|
98564
98841
|
if (!await import_fs_extra36.pathExists(metadataPath)) {
|
|
98565
98842
|
logger.error("Cannot sync: no metadata.json found");
|
|
98566
98843
|
ctx.prompts.note(`Your installation may be from an older version.
|
|
@@ -98660,10 +98937,10 @@ function getLockTimeout() {
|
|
|
98660
98937
|
var STALE_LOCK_THRESHOLD_MS = 5 * 60 * 1000;
|
|
98661
98938
|
async function acquireSyncLock(global3) {
|
|
98662
98939
|
const cacheDir = PathResolver.getCacheDir(global3);
|
|
98663
|
-
const lockPath =
|
|
98940
|
+
const lockPath = join119(cacheDir, ".sync-lock");
|
|
98664
98941
|
const startTime = Date.now();
|
|
98665
98942
|
const lockTimeout = getLockTimeout();
|
|
98666
|
-
await mkdir32(
|
|
98943
|
+
await mkdir32(dirname31(lockPath), { recursive: true });
|
|
98667
98944
|
while (Date.now() - startTime < lockTimeout) {
|
|
98668
98945
|
try {
|
|
98669
98946
|
const handle = await open5(lockPath, "wx");
|
|
@@ -98706,10 +98983,10 @@ async function executeSyncMerge(ctx) {
|
|
|
98706
98983
|
const releaseLock = await acquireSyncLock(ctx.options.global);
|
|
98707
98984
|
try {
|
|
98708
98985
|
const trackedFiles = ctx.syncTrackedFiles;
|
|
98709
|
-
const upstreamDir = ctx.options.global ?
|
|
98986
|
+
const upstreamDir = ctx.options.global ? join119(ctx.extractDir, ".claude") : ctx.extractDir;
|
|
98710
98987
|
let deletions = [];
|
|
98711
98988
|
try {
|
|
98712
|
-
const sourceMetadataPath =
|
|
98989
|
+
const sourceMetadataPath = join119(upstreamDir, "metadata.json");
|
|
98713
98990
|
if (await import_fs_extra36.pathExists(sourceMetadataPath)) {
|
|
98714
98991
|
const content = await readFile50(sourceMetadataPath, "utf-8");
|
|
98715
98992
|
const sourceMetadata = JSON.parse(content);
|
|
@@ -98741,7 +99018,7 @@ async function executeSyncMerge(ctx) {
|
|
|
98741
99018
|
try {
|
|
98742
99019
|
const sourcePath = await validateSyncPath(upstreamDir, file.path);
|
|
98743
99020
|
const targetPath = await validateSyncPath(ctx.claudeDir, file.path);
|
|
98744
|
-
const targetDir =
|
|
99021
|
+
const targetDir = join119(targetPath, "..");
|
|
98745
99022
|
try {
|
|
98746
99023
|
await mkdir32(targetDir, { recursive: true });
|
|
98747
99024
|
} catch (mkdirError) {
|
|
@@ -98912,7 +99189,7 @@ async function createBackup(claudeDir2, files, backupDir) {
|
|
|
98912
99189
|
const sourcePath = await validateSyncPath(claudeDir2, file.path);
|
|
98913
99190
|
if (await import_fs_extra36.pathExists(sourcePath)) {
|
|
98914
99191
|
const targetPath = await validateSyncPath(backupDir, file.path);
|
|
98915
|
-
const targetDir =
|
|
99192
|
+
const targetDir = join119(targetPath, "..");
|
|
98916
99193
|
await mkdir32(targetDir, { recursive: true });
|
|
98917
99194
|
await copyFile8(sourcePath, targetPath);
|
|
98918
99195
|
}
|
|
@@ -98927,7 +99204,7 @@ async function createBackup(claudeDir2, files, backupDir) {
|
|
|
98927
99204
|
}
|
|
98928
99205
|
// src/commands/init/phases/transform-handler.ts
|
|
98929
99206
|
init_config_manager();
|
|
98930
|
-
import { join as
|
|
99207
|
+
import { join as join123 } from "node:path";
|
|
98931
99208
|
|
|
98932
99209
|
// src/services/transformers/folder-path-transformer.ts
|
|
98933
99210
|
init_logger();
|
|
@@ -98938,38 +99215,38 @@ init_logger();
|
|
|
98938
99215
|
init_types3();
|
|
98939
99216
|
var import_fs_extra37 = __toESM(require_lib(), 1);
|
|
98940
99217
|
import { rename as rename8, rm as rm14 } from "node:fs/promises";
|
|
98941
|
-
import { join as
|
|
99218
|
+
import { join as join120, relative as relative19 } from "node:path";
|
|
98942
99219
|
async function collectDirsToRename(extractDir, folders) {
|
|
98943
99220
|
const dirsToRename = [];
|
|
98944
99221
|
if (folders.docs !== DEFAULT_FOLDERS.docs) {
|
|
98945
|
-
const docsPath =
|
|
99222
|
+
const docsPath = join120(extractDir, DEFAULT_FOLDERS.docs);
|
|
98946
99223
|
if (await import_fs_extra37.pathExists(docsPath)) {
|
|
98947
99224
|
dirsToRename.push({
|
|
98948
99225
|
from: docsPath,
|
|
98949
|
-
to:
|
|
99226
|
+
to: join120(extractDir, folders.docs)
|
|
98950
99227
|
});
|
|
98951
99228
|
}
|
|
98952
|
-
const claudeDocsPath =
|
|
99229
|
+
const claudeDocsPath = join120(extractDir, ".claude", DEFAULT_FOLDERS.docs);
|
|
98953
99230
|
if (await import_fs_extra37.pathExists(claudeDocsPath)) {
|
|
98954
99231
|
dirsToRename.push({
|
|
98955
99232
|
from: claudeDocsPath,
|
|
98956
|
-
to:
|
|
99233
|
+
to: join120(extractDir, ".claude", folders.docs)
|
|
98957
99234
|
});
|
|
98958
99235
|
}
|
|
98959
99236
|
}
|
|
98960
99237
|
if (folders.plans !== DEFAULT_FOLDERS.plans) {
|
|
98961
|
-
const plansPath =
|
|
99238
|
+
const plansPath = join120(extractDir, DEFAULT_FOLDERS.plans);
|
|
98962
99239
|
if (await import_fs_extra37.pathExists(plansPath)) {
|
|
98963
99240
|
dirsToRename.push({
|
|
98964
99241
|
from: plansPath,
|
|
98965
|
-
to:
|
|
99242
|
+
to: join120(extractDir, folders.plans)
|
|
98966
99243
|
});
|
|
98967
99244
|
}
|
|
98968
|
-
const claudePlansPath =
|
|
99245
|
+
const claudePlansPath = join120(extractDir, ".claude", DEFAULT_FOLDERS.plans);
|
|
98969
99246
|
if (await import_fs_extra37.pathExists(claudePlansPath)) {
|
|
98970
99247
|
dirsToRename.push({
|
|
98971
99248
|
from: claudePlansPath,
|
|
98972
|
-
to:
|
|
99249
|
+
to: join120(extractDir, ".claude", folders.plans)
|
|
98973
99250
|
});
|
|
98974
99251
|
}
|
|
98975
99252
|
}
|
|
@@ -99010,7 +99287,7 @@ async function renameFolders(dirsToRename, extractDir, options2) {
|
|
|
99010
99287
|
init_logger();
|
|
99011
99288
|
init_types3();
|
|
99012
99289
|
import { readFile as readFile51, readdir as readdir34, writeFile as writeFile31 } from "node:fs/promises";
|
|
99013
|
-
import { join as
|
|
99290
|
+
import { join as join121, relative as relative20 } from "node:path";
|
|
99014
99291
|
var TRANSFORMABLE_FILE_PATTERNS = [
|
|
99015
99292
|
".md",
|
|
99016
99293
|
".txt",
|
|
@@ -99063,7 +99340,7 @@ async function transformFileContents(dir, compiledReplacements, options2) {
|
|
|
99063
99340
|
let replacementsCount = 0;
|
|
99064
99341
|
const entries = await readdir34(dir, { withFileTypes: true });
|
|
99065
99342
|
for (const entry of entries) {
|
|
99066
|
-
const fullPath =
|
|
99343
|
+
const fullPath = join121(dir, entry.name);
|
|
99067
99344
|
if (entry.isDirectory()) {
|
|
99068
99345
|
if (entry.name === "node_modules" || entry.name === ".git") {
|
|
99069
99346
|
continue;
|
|
@@ -99199,19 +99476,47 @@ async function transformFolderPaths(extractDir, folders, options2 = {}) {
|
|
|
99199
99476
|
// src/services/transformers/global-path-transformer.ts
|
|
99200
99477
|
init_logger();
|
|
99201
99478
|
import { readFile as readFile52, readdir as readdir35, writeFile as writeFile32 } from "node:fs/promises";
|
|
99202
|
-
import { platform as platform15 } from "node:os";
|
|
99203
|
-
import { extname as extname6, join as
|
|
99479
|
+
import { homedir as homedir34, platform as platform15 } from "node:os";
|
|
99480
|
+
import { extname as extname6, join as join122 } from "node:path";
|
|
99204
99481
|
var IS_WINDOWS3 = platform15() === "win32";
|
|
99205
99482
|
var HOME_PREFIX = IS_WINDOWS3 ? "%USERPROFILE%" : "$HOME";
|
|
99206
99483
|
function getHomeDirPrefix() {
|
|
99207
99484
|
return HOME_PREFIX;
|
|
99208
99485
|
}
|
|
99486
|
+
function normalizeInstallPath(path15) {
|
|
99487
|
+
return path15.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
99488
|
+
}
|
|
99489
|
+
function getDefaultGlobalClaudeDir() {
|
|
99490
|
+
return normalizeInstallPath(join122(homedir34(), ".claude"));
|
|
99491
|
+
}
|
|
99492
|
+
function getCustomGlobalClaudeDir(targetClaudeDir) {
|
|
99493
|
+
if (!targetClaudeDir)
|
|
99494
|
+
return null;
|
|
99495
|
+
const normalizedTargetDir = normalizeInstallPath(targetClaudeDir);
|
|
99496
|
+
return normalizedTargetDir === getDefaultGlobalClaudeDir() ? null : normalizedTargetDir;
|
|
99497
|
+
}
|
|
99498
|
+
function getGlobalClaudePath(targetClaudeDir) {
|
|
99499
|
+
const customGlobalClaudeDir = getCustomGlobalClaudeDir(targetClaudeDir);
|
|
99500
|
+
if (customGlobalClaudeDir) {
|
|
99501
|
+
return `${customGlobalClaudeDir}/`;
|
|
99502
|
+
}
|
|
99503
|
+
return `${getHomeDirPrefix()}/.claude/`;
|
|
99504
|
+
}
|
|
99505
|
+
function replaceTracked(content, pattern, replacement) {
|
|
99506
|
+
let changes = 0;
|
|
99507
|
+
const updated = content.replace(pattern, () => {
|
|
99508
|
+
changes++;
|
|
99509
|
+
return replacement;
|
|
99510
|
+
});
|
|
99511
|
+
return { content: updated, changes };
|
|
99512
|
+
}
|
|
99209
99513
|
var TRANSFORMABLE_EXTENSIONS3 = new Set([
|
|
99210
99514
|
".md",
|
|
99211
99515
|
".js",
|
|
99212
99516
|
".cjs",
|
|
99213
99517
|
".mjs",
|
|
99214
99518
|
".ts",
|
|
99519
|
+
".py",
|
|
99215
99520
|
".json",
|
|
99216
99521
|
".sh",
|
|
99217
99522
|
".ps1",
|
|
@@ -99220,83 +99525,94 @@ var TRANSFORMABLE_EXTENSIONS3 = new Set([
|
|
|
99220
99525
|
".toml"
|
|
99221
99526
|
]);
|
|
99222
99527
|
var ALWAYS_TRANSFORM_FILES = new Set(["CLAUDE.md", "claude.md"]);
|
|
99223
|
-
function transformContent(content) {
|
|
99528
|
+
function transformContent(content, options2 = {}) {
|
|
99224
99529
|
let changes = 0;
|
|
99225
99530
|
let transformed = content;
|
|
99226
99531
|
const homePrefix = getHomeDirPrefix();
|
|
99227
|
-
const
|
|
99532
|
+
const customGlobalClaudeDir = getCustomGlobalClaudeDir(options2.targetClaudeDir);
|
|
99533
|
+
const claudePath = getGlobalClaudePath(options2.targetClaudeDir);
|
|
99228
99534
|
if (IS_WINDOWS3) {
|
|
99229
|
-
|
|
99230
|
-
|
|
99231
|
-
|
|
99232
|
-
});
|
|
99233
|
-
transformed =
|
|
99234
|
-
|
|
99235
|
-
|
|
99236
|
-
|
|
99237
|
-
|
|
99238
|
-
|
|
99239
|
-
|
|
99240
|
-
|
|
99241
|
-
|
|
99242
|
-
|
|
99243
|
-
|
|
99244
|
-
|
|
99245
|
-
}
|
|
99246
|
-
|
|
99247
|
-
|
|
99248
|
-
|
|
99249
|
-
});
|
|
99250
|
-
transformed =
|
|
99251
|
-
|
|
99252
|
-
return `"${homePrefix}"/.claude/`;
|
|
99253
|
-
});
|
|
99254
|
-
transformed = transformed.replace(/\$\{CLAUDE_PROJECT_DIR\}\/\.claude\//g, () => {
|
|
99255
|
-
changes++;
|
|
99256
|
-
return claudePath;
|
|
99257
|
-
});
|
|
99535
|
+
const homePathResult = replaceTracked(transformed, /\$HOME\/\.claude\//g, claudePath);
|
|
99536
|
+
transformed = homePathResult.content;
|
|
99537
|
+
changes += homePathResult.changes;
|
|
99538
|
+
const braceHomePathResult = replaceTracked(transformed, /\$\{HOME\}\/\.claude\//g, claudePath);
|
|
99539
|
+
transformed = braceHomePathResult.content;
|
|
99540
|
+
changes += braceHomePathResult.changes;
|
|
99541
|
+
const homePrefixResult = replaceTracked(transformed, /\$HOME(?=\/|\\)/g, homePrefix);
|
|
99542
|
+
transformed = homePrefixResult.content;
|
|
99543
|
+
changes += homePrefixResult.changes;
|
|
99544
|
+
const braceHomePrefixResult = replaceTracked(transformed, /\$\{HOME\}(?=\/|\\)/g, homePrefix);
|
|
99545
|
+
transformed = braceHomePrefixResult.content;
|
|
99546
|
+
changes += braceHomePrefixResult.changes;
|
|
99547
|
+
}
|
|
99548
|
+
const projectDirPathResult = replaceTracked(transformed, /\$CLAUDE_PROJECT_DIR\/\.claude\//g, claudePath);
|
|
99549
|
+
transformed = projectDirPathResult.content;
|
|
99550
|
+
changes += projectDirPathResult.changes;
|
|
99551
|
+
const quotedProjectDirPath = customGlobalClaudeDir ? `${customGlobalClaudeDir}/` : `"${homePrefix}"/.claude/`;
|
|
99552
|
+
const quotedProjectDirPathResult = replaceTracked(transformed, /"\$CLAUDE_PROJECT_DIR"\/\.claude\//g, quotedProjectDirPath);
|
|
99553
|
+
transformed = quotedProjectDirPathResult.content;
|
|
99554
|
+
changes += quotedProjectDirPathResult.changes;
|
|
99555
|
+
const braceProjectDirPathResult = replaceTracked(transformed, /\$\{CLAUDE_PROJECT_DIR\}\/\.claude\//g, claudePath);
|
|
99556
|
+
transformed = braceProjectDirPathResult.content;
|
|
99557
|
+
changes += braceProjectDirPathResult.changes;
|
|
99258
99558
|
if (IS_WINDOWS3) {
|
|
99259
|
-
|
|
99260
|
-
|
|
99261
|
-
|
|
99262
|
-
|
|
99263
|
-
|
|
99264
|
-
transformed =
|
|
99265
|
-
|
|
99266
|
-
|
|
99267
|
-
|
|
99268
|
-
|
|
99269
|
-
|
|
99270
|
-
|
|
99271
|
-
|
|
99272
|
-
transformed = transformed.replace(/@\.claude\//g, () => {
|
|
99273
|
-
changes++;
|
|
99274
|
-
return `@${claudePath}`;
|
|
99275
|
-
});
|
|
99559
|
+
const windowsProjectDirPathResult = replaceTracked(transformed, /%CLAUDE_PROJECT_DIR%\/\.claude\//g, claudePath);
|
|
99560
|
+
transformed = windowsProjectDirPathResult.content;
|
|
99561
|
+
changes += windowsProjectDirPathResult.changes;
|
|
99562
|
+
}
|
|
99563
|
+
const relativeClaudePathResult = replaceTracked(transformed, /\.\/\.claude\//g, claudePath);
|
|
99564
|
+
transformed = relativeClaudePathResult.content;
|
|
99565
|
+
changes += relativeClaudePathResult.changes;
|
|
99566
|
+
const atRelativeClaudePathResult = replaceTracked(transformed, /@\.\/\.claude\//g, `@${claudePath}`);
|
|
99567
|
+
transformed = atRelativeClaudePathResult.content;
|
|
99568
|
+
changes += atRelativeClaudePathResult.changes;
|
|
99569
|
+
const atClaudePathResult = replaceTracked(transformed, /@\.claude\//g, `@${claudePath}`);
|
|
99570
|
+
transformed = atClaudePathResult.content;
|
|
99571
|
+
changes += atClaudePathResult.changes;
|
|
99276
99572
|
transformed = transformed.replace(/(["'`])\.claude\//g, (_match, quote) => {
|
|
99277
99573
|
changes++;
|
|
99278
99574
|
return `${quote}${claudePath}`;
|
|
99279
99575
|
});
|
|
99280
|
-
|
|
99281
|
-
|
|
99282
|
-
|
|
99283
|
-
});
|
|
99284
|
-
transformed =
|
|
99285
|
-
|
|
99286
|
-
|
|
99287
|
-
|
|
99288
|
-
|
|
99289
|
-
|
|
99290
|
-
|
|
99291
|
-
|
|
99292
|
-
|
|
99293
|
-
|
|
99294
|
-
|
|
99295
|
-
|
|
99296
|
-
|
|
99297
|
-
|
|
99298
|
-
|
|
99299
|
-
|
|
99576
|
+
const markdownClaudePathResult = replaceTracked(transformed, /\(\.claude\//g, `(${claudePath}`);
|
|
99577
|
+
transformed = markdownClaudePathResult.content;
|
|
99578
|
+
changes += markdownClaudePathResult.changes;
|
|
99579
|
+
const spacedClaudePathResult = replaceTracked(transformed, / \.claude\//g, ` ${claudePath}`);
|
|
99580
|
+
transformed = spacedClaudePathResult.content;
|
|
99581
|
+
changes += spacedClaudePathResult.changes;
|
|
99582
|
+
const lineStartClaudePathResult = replaceTracked(transformed, /^\.claude\//gm, claudePath);
|
|
99583
|
+
transformed = lineStartClaudePathResult.content;
|
|
99584
|
+
changes += lineStartClaudePathResult.changes;
|
|
99585
|
+
const colonClaudePathResult = replaceTracked(transformed, /: \.claude\//g, `: ${claudePath}`);
|
|
99586
|
+
transformed = colonClaudePathResult.content;
|
|
99587
|
+
changes += colonClaudePathResult.changes;
|
|
99588
|
+
const compactColonClaudePathResult = replaceTracked(transformed, /:\.claude\//g, `:${claudePath}`);
|
|
99589
|
+
transformed = compactColonClaudePathResult.content;
|
|
99590
|
+
changes += compactColonClaudePathResult.changes;
|
|
99591
|
+
if (customGlobalClaudeDir) {
|
|
99592
|
+
const customPatterns = [
|
|
99593
|
+
{ pattern: /~\/\.claude\//g, replacement: `${customGlobalClaudeDir}/` },
|
|
99594
|
+
{ pattern: /~\/\.claude\b/g, replacement: customGlobalClaudeDir },
|
|
99595
|
+
{ pattern: /\$HOME\/\.claude\//g, replacement: `${customGlobalClaudeDir}/` },
|
|
99596
|
+
{ pattern: /\$HOME\/\.claude\b/g, replacement: customGlobalClaudeDir },
|
|
99597
|
+
{ pattern: /\$\{HOME\}\/\.claude\//g, replacement: `${customGlobalClaudeDir}/` },
|
|
99598
|
+
{ pattern: /\$\{HOME\}\/\.claude\b/g, replacement: customGlobalClaudeDir },
|
|
99599
|
+
{ pattern: /%USERPROFILE%[\\/]\.claude[\\/]/g, replacement: `${customGlobalClaudeDir}/` },
|
|
99600
|
+
{ pattern: /%USERPROFILE%[\\/]\.claude\b/g, replacement: customGlobalClaudeDir },
|
|
99601
|
+
{
|
|
99602
|
+
pattern: /(?:os\.)?homedir\(\)\s*,\s*(["'])\.claude\1/g,
|
|
99603
|
+
replacement: `"${customGlobalClaudeDir}"`
|
|
99604
|
+
},
|
|
99605
|
+
{
|
|
99606
|
+
pattern: /\b(?:homeDir|homedir)\b\s*,\s*(["'])\.claude\1/g,
|
|
99607
|
+
replacement: `"${customGlobalClaudeDir}"`
|
|
99608
|
+
}
|
|
99609
|
+
];
|
|
99610
|
+
for (const { pattern, replacement } of customPatterns) {
|
|
99611
|
+
const customPatternResult = replaceTracked(transformed, pattern, replacement);
|
|
99612
|
+
transformed = customPatternResult.content;
|
|
99613
|
+
changes += customPatternResult.changes;
|
|
99614
|
+
}
|
|
99615
|
+
}
|
|
99300
99616
|
return { transformed, changes };
|
|
99301
99617
|
}
|
|
99302
99618
|
function shouldTransformFile3(filename) {
|
|
@@ -99312,7 +99628,7 @@ async function transformPathsForGlobalInstall(directory, options2 = {}) {
|
|
|
99312
99628
|
async function processDirectory2(dir) {
|
|
99313
99629
|
const entries = await readdir35(dir, { withFileTypes: true });
|
|
99314
99630
|
for (const entry of entries) {
|
|
99315
|
-
const fullPath =
|
|
99631
|
+
const fullPath = join122(dir, entry.name);
|
|
99316
99632
|
if (entry.isDirectory()) {
|
|
99317
99633
|
if (entry.name === "node_modules" || entry.name.startsWith(".") && entry.name !== ".claude") {
|
|
99318
99634
|
continue;
|
|
@@ -99321,7 +99637,9 @@ async function transformPathsForGlobalInstall(directory, options2 = {}) {
|
|
|
99321
99637
|
} else if (entry.isFile() && shouldTransformFile3(entry.name)) {
|
|
99322
99638
|
try {
|
|
99323
99639
|
const content = await readFile52(fullPath, "utf-8");
|
|
99324
|
-
const { transformed, changes } = transformContent(content
|
|
99640
|
+
const { transformed, changes } = transformContent(content, {
|
|
99641
|
+
targetClaudeDir: options2.targetClaudeDir
|
|
99642
|
+
});
|
|
99325
99643
|
if (changes > 0) {
|
|
99326
99644
|
await writeFile32(fullPath, transformed, "utf-8");
|
|
99327
99645
|
filesTransformed++;
|
|
@@ -99361,6 +99679,7 @@ async function handleTransforms(ctx) {
|
|
|
99361
99679
|
if (ctx.options.global) {
|
|
99362
99680
|
logger.info("Transforming paths for global installation...");
|
|
99363
99681
|
const transformResult = await transformPathsForGlobalInstall(ctx.extractDir, {
|
|
99682
|
+
targetClaudeDir: ctx.resolvedDir,
|
|
99364
99683
|
verbose: logger.isVerbose()
|
|
99365
99684
|
});
|
|
99366
99685
|
logger.success(`Transformed ${transformResult.totalChanges} path(s) in ${transformResult.filesTransformed} file(s)`);
|
|
@@ -99388,7 +99707,7 @@ async function handleTransforms(ctx) {
|
|
|
99388
99707
|
logger.debug(ctx.options.global ? "Saved folder configuration to ~/.claude/.ck.json" : "Saved folder configuration to .claude/.ck.json");
|
|
99389
99708
|
}
|
|
99390
99709
|
}
|
|
99391
|
-
const claudeDir2 = ctx.options.global ? ctx.resolvedDir :
|
|
99710
|
+
const claudeDir2 = ctx.options.global ? ctx.resolvedDir : join123(ctx.resolvedDir, ".claude");
|
|
99392
99711
|
return {
|
|
99393
99712
|
...ctx,
|
|
99394
99713
|
foldersConfig,
|
|
@@ -99579,8 +99898,8 @@ init_dist2();
|
|
|
99579
99898
|
var import_picocolors29 = __toESM(require_picocolors(), 1);
|
|
99580
99899
|
import { existsSync as existsSync56 } from "node:fs";
|
|
99581
99900
|
import { readFile as readFile53, rm as rm15, unlink as unlink12 } from "node:fs/promises";
|
|
99582
|
-
import { homedir as
|
|
99583
|
-
import { basename as basename19, join as
|
|
99901
|
+
import { homedir as homedir35 } from "node:os";
|
|
99902
|
+
import { basename as basename19, join as join124, resolve as resolve29 } from "node:path";
|
|
99584
99903
|
init_logger();
|
|
99585
99904
|
init_agents_discovery();
|
|
99586
99905
|
init_commands_discovery();
|
|
@@ -100005,7 +100324,7 @@ async function executeDeleteAction(action, options2) {
|
|
|
100005
100324
|
async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
100006
100325
|
if (!skillSourcePath)
|
|
100007
100326
|
return;
|
|
100008
|
-
const sourceMetadataPath =
|
|
100327
|
+
const sourceMetadataPath = join124(resolve29(skillSourcePath, ".."), "metadata.json");
|
|
100009
100328
|
if (!existsSync56(sourceMetadataPath))
|
|
100010
100329
|
return;
|
|
100011
100330
|
let sourceMetadata;
|
|
@@ -100018,7 +100337,7 @@ async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
|
100018
100337
|
}
|
|
100019
100338
|
if (!sourceMetadata.deletions || sourceMetadata.deletions.length === 0)
|
|
100020
100339
|
return;
|
|
100021
|
-
const claudeDir2 = installGlobally ?
|
|
100340
|
+
const claudeDir2 = installGlobally ? join124(homedir35(), ".claude") : join124(process.cwd(), ".claude");
|
|
100022
100341
|
if (!existsSync56(claudeDir2))
|
|
100023
100342
|
return;
|
|
100024
100343
|
try {
|
|
@@ -100173,8 +100492,8 @@ async function migrateCommand(options2) {
|
|
|
100173
100492
|
selectedProviders = Array.from(new Set(selectedProviders));
|
|
100174
100493
|
let installGlobally = options2.global ?? false;
|
|
100175
100494
|
if (options2.global === undefined && !options2.yes) {
|
|
100176
|
-
const projectTarget =
|
|
100177
|
-
const globalTarget =
|
|
100495
|
+
const projectTarget = join124(process.cwd(), ".claude");
|
|
100496
|
+
const globalTarget = join124(homedir35(), ".claude");
|
|
100178
100497
|
const scopeChoice = await ie({
|
|
100179
100498
|
message: "Installation scope",
|
|
100180
100499
|
options: [
|
|
@@ -100226,7 +100545,7 @@ async function migrateCommand(options2) {
|
|
|
100226
100545
|
}
|
|
100227
100546
|
const providerNames = selectedProviders.map((prov) => import_picocolors29.default.cyan(providers[prov].displayName)).join(", ");
|
|
100228
100547
|
f2.message(` Providers: ${providerNames}`);
|
|
100229
|
-
const targetDir = installGlobally ?
|
|
100548
|
+
const targetDir = installGlobally ? join124(homedir35(), ".claude") : join124(process.cwd(), ".claude");
|
|
100230
100549
|
f2.message(` Scope: ${installGlobally ? "Global" : "Project"} ${import_picocolors29.default.dim(`-> ${targetDir}`)}`);
|
|
100231
100550
|
const cmdProviders = getProvidersSupporting("commands");
|
|
100232
100551
|
const unsupportedCmd = selectedProviders.filter((pv) => !cmdProviders.includes(pv));
|
|
@@ -100722,7 +101041,7 @@ async function handleDirectorySetup(ctx) {
|
|
|
100722
101041
|
// src/commands/new/phases/project-creation.ts
|
|
100723
101042
|
init_config_manager();
|
|
100724
101043
|
init_github_client();
|
|
100725
|
-
import { join as
|
|
101044
|
+
import { join as join125 } from "node:path";
|
|
100726
101045
|
init_logger();
|
|
100727
101046
|
init_output_manager();
|
|
100728
101047
|
init_types3();
|
|
@@ -100848,7 +101167,7 @@ async function projectCreation(kit, resolvedDir, validOptions, isNonInteractive2
|
|
|
100848
101167
|
output.section("Installing");
|
|
100849
101168
|
logger.verbose("Installation target", { directory: resolvedDir });
|
|
100850
101169
|
const merger = new FileMerger;
|
|
100851
|
-
const claudeDir2 =
|
|
101170
|
+
const claudeDir2 = join125(resolvedDir, ".claude");
|
|
100852
101171
|
merger.setMultiKitContext(claudeDir2, kit);
|
|
100853
101172
|
if (validOptions.exclude && validOptions.exclude.length > 0) {
|
|
100854
101173
|
merger.addIgnorePatterns(validOptions.exclude);
|
|
@@ -100895,7 +101214,7 @@ async function handleProjectCreation(ctx) {
|
|
|
100895
101214
|
}
|
|
100896
101215
|
// src/commands/new/phases/post-setup.ts
|
|
100897
101216
|
init_projects_registry();
|
|
100898
|
-
import { join as
|
|
101217
|
+
import { join as join126 } from "node:path";
|
|
100899
101218
|
init_package_installer();
|
|
100900
101219
|
init_logger();
|
|
100901
101220
|
init_path_resolver();
|
|
@@ -100927,9 +101246,9 @@ async function postSetup(resolvedDir, validOptions, isNonInteractive2, prompts)
|
|
|
100927
101246
|
withSudo: validOptions.withSudo
|
|
100928
101247
|
});
|
|
100929
101248
|
}
|
|
100930
|
-
const claudeDir2 =
|
|
101249
|
+
const claudeDir2 = join126(resolvedDir, ".claude");
|
|
100931
101250
|
await promptSetupWizardIfNeeded({
|
|
100932
|
-
envPath:
|
|
101251
|
+
envPath: join126(claudeDir2, ".env"),
|
|
100933
101252
|
claudeDir: claudeDir2,
|
|
100934
101253
|
isGlobal: false,
|
|
100935
101254
|
isNonInteractive: isNonInteractive2,
|
|
@@ -100999,7 +101318,7 @@ Please use only one download method.`);
|
|
|
100999
101318
|
// src/commands/plan/plan-command.ts
|
|
101000
101319
|
init_output_manager();
|
|
101001
101320
|
import { existsSync as existsSync58, statSync as statSync9 } from "node:fs";
|
|
101002
|
-
import { dirname as
|
|
101321
|
+
import { dirname as dirname33, join as join128, parse as parse6, resolve as resolve33 } from "node:path";
|
|
101003
101322
|
|
|
101004
101323
|
// src/commands/plan/plan-read-handlers.ts
|
|
101005
101324
|
init_plan_parser();
|
|
@@ -101007,7 +101326,7 @@ init_logger();
|
|
|
101007
101326
|
init_output_manager();
|
|
101008
101327
|
var import_picocolors31 = __toESM(require_picocolors(), 1);
|
|
101009
101328
|
import { existsSync as existsSync57, statSync as statSync8 } from "node:fs";
|
|
101010
|
-
import { basename as basename20, dirname as
|
|
101329
|
+
import { basename as basename20, dirname as dirname32, join as join127, relative as relative21, resolve as resolve31 } from "node:path";
|
|
101011
101330
|
async function handleParse(target, options2) {
|
|
101012
101331
|
const planFile = resolvePlanFile(target);
|
|
101013
101332
|
if (!planFile) {
|
|
@@ -101028,7 +101347,7 @@ async function handleParse(target, options2) {
|
|
|
101028
101347
|
console.log(JSON.stringify({ file: relative21(process.cwd(), planFile), frontmatter, phases }, null, 2));
|
|
101029
101348
|
return;
|
|
101030
101349
|
}
|
|
101031
|
-
const title = typeof frontmatter.title === "string" ? frontmatter.title : basename20(
|
|
101350
|
+
const title = typeof frontmatter.title === "string" ? frontmatter.title : basename20(dirname32(planFile));
|
|
101032
101351
|
console.log();
|
|
101033
101352
|
console.log(import_picocolors31.default.bold(` Plan: ${title}`));
|
|
101034
101353
|
console.log(` File: ${planFile}`);
|
|
@@ -101083,7 +101402,7 @@ async function handleValidate(target, options2) {
|
|
|
101083
101402
|
}
|
|
101084
101403
|
async function handleStatus(target, options2) {
|
|
101085
101404
|
const t = target ? resolve31(target) : null;
|
|
101086
|
-
const plansDir = t && existsSync57(t) && statSync8(t).isDirectory() && !existsSync57(
|
|
101405
|
+
const plansDir = t && existsSync57(t) && statSync8(t).isDirectory() && !existsSync57(join127(t, "plan.md")) ? t : null;
|
|
101087
101406
|
if (plansDir) {
|
|
101088
101407
|
const planFiles = scanPlanDir(plansDir);
|
|
101089
101408
|
if (planFiles.length === 0) {
|
|
@@ -101108,14 +101427,14 @@ async function handleStatus(target, options2) {
|
|
|
101108
101427
|
try {
|
|
101109
101428
|
const s = buildPlanSummary(pf);
|
|
101110
101429
|
const bar = progressBar(s.completed, s.totalPhases);
|
|
101111
|
-
const title2 = s.title ?? basename20(
|
|
101430
|
+
const title2 = s.title ?? basename20(dirname32(pf));
|
|
101112
101431
|
console.log(` ${import_picocolors31.default.bold(title2)}`);
|
|
101113
101432
|
console.log(` ${bar}`);
|
|
101114
101433
|
if (s.inProgress > 0)
|
|
101115
101434
|
console.log(` [~] ${s.inProgress} in progress`);
|
|
101116
101435
|
console.log();
|
|
101117
101436
|
} catch {
|
|
101118
|
-
console.log(` [X] Failed to read: ${basename20(
|
|
101437
|
+
console.log(` [X] Failed to read: ${basename20(dirname32(pf))}`);
|
|
101119
101438
|
console.log();
|
|
101120
101439
|
}
|
|
101121
101440
|
}
|
|
@@ -101139,7 +101458,7 @@ async function handleStatus(target, options2) {
|
|
|
101139
101458
|
console.log(JSON.stringify(summary, null, 2));
|
|
101140
101459
|
return;
|
|
101141
101460
|
}
|
|
101142
|
-
const title = summary.title ?? basename20(
|
|
101461
|
+
const title = summary.title ?? basename20(dirname32(planFile));
|
|
101143
101462
|
console.log();
|
|
101144
101463
|
console.log(import_picocolors31.default.bold(` ${title}`));
|
|
101145
101464
|
if (summary.status)
|
|
@@ -101355,7 +101674,7 @@ function resolvePlanFile(target) {
|
|
|
101355
101674
|
const stat19 = statSync9(t);
|
|
101356
101675
|
if (stat19.isFile())
|
|
101357
101676
|
return t;
|
|
101358
|
-
const candidate =
|
|
101677
|
+
const candidate = join128(t, "plan.md");
|
|
101359
101678
|
if (existsSync58(candidate))
|
|
101360
101679
|
return candidate;
|
|
101361
101680
|
}
|
|
@@ -101363,10 +101682,10 @@ function resolvePlanFile(target) {
|
|
|
101363
101682
|
let dir = process.cwd();
|
|
101364
101683
|
const root = parse6(dir).root;
|
|
101365
101684
|
while (dir !== root) {
|
|
101366
|
-
const candidate =
|
|
101685
|
+
const candidate = join128(dir, "plan.md");
|
|
101367
101686
|
if (existsSync58(candidate))
|
|
101368
101687
|
return candidate;
|
|
101369
|
-
dir =
|
|
101688
|
+
dir = dirname33(dir);
|
|
101370
101689
|
}
|
|
101371
101690
|
}
|
|
101372
101691
|
return null;
|
|
@@ -102391,7 +102710,7 @@ async function detectInstallations() {
|
|
|
102391
102710
|
|
|
102392
102711
|
// src/commands/uninstall/removal-handler.ts
|
|
102393
102712
|
import { readdirSync as readdirSync8, rmSync as rmSync6 } from "node:fs";
|
|
102394
|
-
import { basename as basename22, join as
|
|
102713
|
+
import { basename as basename22, join as join130, resolve as resolve35, sep as sep10 } from "node:path";
|
|
102395
102714
|
init_logger();
|
|
102396
102715
|
init_safe_prompts();
|
|
102397
102716
|
init_safe_spinner();
|
|
@@ -102400,7 +102719,7 @@ var import_fs_extra41 = __toESM(require_lib(), 1);
|
|
|
102400
102719
|
// src/commands/uninstall/analysis-handler.ts
|
|
102401
102720
|
init_metadata_migration();
|
|
102402
102721
|
import { readdirSync as readdirSync7, rmSync as rmSync5 } from "node:fs";
|
|
102403
|
-
import { dirname as
|
|
102722
|
+
import { dirname as dirname34, join as join129 } from "node:path";
|
|
102404
102723
|
init_logger();
|
|
102405
102724
|
init_safe_prompts();
|
|
102406
102725
|
var import_fs_extra40 = __toESM(require_lib(), 1);
|
|
@@ -102422,7 +102741,7 @@ function classifyFileByOwnership(ownership, forceOverwrite, deleteReason) {
|
|
|
102422
102741
|
}
|
|
102423
102742
|
async function cleanupEmptyDirectories3(filePath, installationRoot) {
|
|
102424
102743
|
let cleaned = 0;
|
|
102425
|
-
let currentDir =
|
|
102744
|
+
let currentDir = dirname34(filePath);
|
|
102426
102745
|
while (currentDir !== installationRoot && currentDir.startsWith(installationRoot)) {
|
|
102427
102746
|
try {
|
|
102428
102747
|
const entries = readdirSync7(currentDir);
|
|
@@ -102430,7 +102749,7 @@ async function cleanupEmptyDirectories3(filePath, installationRoot) {
|
|
|
102430
102749
|
rmSync5(currentDir, { recursive: true });
|
|
102431
102750
|
cleaned++;
|
|
102432
102751
|
logger.debug(`Removed empty directory: ${currentDir}`);
|
|
102433
|
-
currentDir =
|
|
102752
|
+
currentDir = dirname34(currentDir);
|
|
102434
102753
|
} else {
|
|
102435
102754
|
break;
|
|
102436
102755
|
}
|
|
@@ -102457,7 +102776,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
102457
102776
|
const remainingFiles = metadata.kits?.[remainingKit]?.files || [];
|
|
102458
102777
|
for (const file of remainingFiles) {
|
|
102459
102778
|
const relativePath = normalizeTrackedPath(file.path);
|
|
102460
|
-
if (await import_fs_extra40.pathExists(
|
|
102779
|
+
if (await import_fs_extra40.pathExists(join129(installation.path, relativePath))) {
|
|
102461
102780
|
result.retainedManifestPaths.push(relativePath);
|
|
102462
102781
|
}
|
|
102463
102782
|
}
|
|
@@ -102465,7 +102784,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
102465
102784
|
const kitFiles = metadata.kits[kit].files || [];
|
|
102466
102785
|
for (const trackedFile of kitFiles) {
|
|
102467
102786
|
const relativePath = normalizeTrackedPath(trackedFile.path);
|
|
102468
|
-
const filePath =
|
|
102787
|
+
const filePath = join129(installation.path, relativePath);
|
|
102469
102788
|
if (preservedPaths.has(relativePath)) {
|
|
102470
102789
|
result.toPreserve.push({ path: relativePath, reason: "shared with other kit" });
|
|
102471
102790
|
continue;
|
|
@@ -102498,7 +102817,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
102498
102817
|
}
|
|
102499
102818
|
for (const trackedFile of allTrackedFiles) {
|
|
102500
102819
|
const relativePath = normalizeTrackedPath(trackedFile.path);
|
|
102501
|
-
const filePath =
|
|
102820
|
+
const filePath = join129(installation.path, relativePath);
|
|
102502
102821
|
const ownershipResult = await OwnershipChecker.checkOwnership(filePath, metadata, installation.path);
|
|
102503
102822
|
if (!ownershipResult.exists)
|
|
102504
102823
|
continue;
|
|
@@ -102641,7 +102960,7 @@ async function removeInstallations(installations, options2) {
|
|
|
102641
102960
|
let removedCount = 0;
|
|
102642
102961
|
let cleanedDirs = 0;
|
|
102643
102962
|
for (const item of analysis.toDelete) {
|
|
102644
|
-
const filePath =
|
|
102963
|
+
const filePath = join130(installation.path, item.path);
|
|
102645
102964
|
if (!await import_fs_extra41.pathExists(filePath))
|
|
102646
102965
|
continue;
|
|
102647
102966
|
if (!await isPathSafeToRemove(filePath, installation.path)) {
|
|
@@ -102975,7 +103294,7 @@ ${import_picocolors39.default.bold(import_picocolors39.default.cyan(result.kitCo
|
|
|
102975
103294
|
init_logger();
|
|
102976
103295
|
import { existsSync as existsSync65 } from "node:fs";
|
|
102977
103296
|
import { rm as rm16 } from "node:fs/promises";
|
|
102978
|
-
import { join as
|
|
103297
|
+
import { join as join137 } from "node:path";
|
|
102979
103298
|
var import_picocolors40 = __toESM(require_picocolors(), 1);
|
|
102980
103299
|
|
|
102981
103300
|
// src/commands/watch/phases/implementation-runner.ts
|
|
@@ -103494,7 +103813,7 @@ function spawnAndCollect3(command, args) {
|
|
|
103494
103813
|
|
|
103495
103814
|
// src/commands/watch/phases/issue-processor.ts
|
|
103496
103815
|
import { mkdir as mkdir33, writeFile as writeFile34 } from "node:fs/promises";
|
|
103497
|
-
import { join as
|
|
103816
|
+
import { join as join133 } from "node:path";
|
|
103498
103817
|
|
|
103499
103818
|
// src/commands/watch/phases/approval-detector.ts
|
|
103500
103819
|
init_logger();
|
|
@@ -103872,9 +104191,9 @@ async function checkAwaitingApproval(state, setup, options2, watchLog, projectDi
|
|
|
103872
104191
|
|
|
103873
104192
|
// src/commands/watch/phases/plan-dir-finder.ts
|
|
103874
104193
|
import { readdir as readdir37, stat as stat19 } from "node:fs/promises";
|
|
103875
|
-
import { join as
|
|
104194
|
+
import { join as join132 } from "node:path";
|
|
103876
104195
|
async function findRecentPlanDir(cwd2, issueNumber, watchLog) {
|
|
103877
|
-
const plansRoot =
|
|
104196
|
+
const plansRoot = join132(cwd2, "plans");
|
|
103878
104197
|
try {
|
|
103879
104198
|
const entries = await readdir37(plansRoot);
|
|
103880
104199
|
const tenMinAgo = Date.now() - 10 * 60 * 1000;
|
|
@@ -103883,14 +104202,14 @@ async function findRecentPlanDir(cwd2, issueNumber, watchLog) {
|
|
|
103883
104202
|
for (const entry of entries) {
|
|
103884
104203
|
if (entry === "watch" || entry === "reports" || entry === "visuals")
|
|
103885
104204
|
continue;
|
|
103886
|
-
const dirPath =
|
|
104205
|
+
const dirPath = join132(plansRoot, entry);
|
|
103887
104206
|
const dirStat = await stat19(dirPath);
|
|
103888
104207
|
if (!dirStat.isDirectory())
|
|
103889
104208
|
continue;
|
|
103890
104209
|
if (dirStat.mtimeMs < tenMinAgo)
|
|
103891
104210
|
continue;
|
|
103892
104211
|
try {
|
|
103893
|
-
await stat19(
|
|
104212
|
+
await stat19(join132(dirPath, "plan.md"));
|
|
103894
104213
|
} catch {
|
|
103895
104214
|
continue;
|
|
103896
104215
|
}
|
|
@@ -104121,13 +104440,13 @@ async function handlePlanGeneration(issue, state, config, setup, options2, watch
|
|
|
104121
104440
|
stats.plansCreated++;
|
|
104122
104441
|
const detectedPlanDir = await findRecentPlanDir(projectDir, issue.number, watchLog);
|
|
104123
104442
|
if (detectedPlanDir) {
|
|
104124
|
-
state.activeIssues[numStr].planPath =
|
|
104443
|
+
state.activeIssues[numStr].planPath = join133(detectedPlanDir, "plan.md");
|
|
104125
104444
|
watchLog.info(`Plan directory detected: ${detectedPlanDir}`);
|
|
104126
104445
|
} else {
|
|
104127
104446
|
try {
|
|
104128
|
-
const planDir =
|
|
104447
|
+
const planDir = join133(projectDir, "plans", "watch");
|
|
104129
104448
|
await mkdir33(planDir, { recursive: true });
|
|
104130
|
-
const planFilePath =
|
|
104449
|
+
const planFilePath = join133(planDir, `issue-${issue.number}-plan.md`);
|
|
104131
104450
|
await writeFile34(planFilePath, planResult.planText, "utf-8");
|
|
104132
104451
|
state.activeIssues[numStr].planPath = planFilePath;
|
|
104133
104452
|
watchLog.info(`Plan saved (fallback) to ${planFilePath}`);
|
|
@@ -104274,7 +104593,7 @@ init_file_io();
|
|
|
104274
104593
|
init_logger();
|
|
104275
104594
|
import { existsSync as existsSync61 } from "node:fs";
|
|
104276
104595
|
import { mkdir as mkdir34, readFile as readFile55 } from "node:fs/promises";
|
|
104277
|
-
import { dirname as
|
|
104596
|
+
import { dirname as dirname35 } from "node:path";
|
|
104278
104597
|
var PROCESSED_ISSUES_CAP = 500;
|
|
104279
104598
|
async function readCkJson(projectDir) {
|
|
104280
104599
|
const configPath = CkConfigManager.getProjectConfigPath(projectDir);
|
|
@@ -104304,7 +104623,7 @@ async function loadWatchState(projectDir) {
|
|
|
104304
104623
|
}
|
|
104305
104624
|
async function saveWatchState(projectDir, state) {
|
|
104306
104625
|
const configPath = CkConfigManager.getProjectConfigPath(projectDir);
|
|
104307
|
-
const configDir =
|
|
104626
|
+
const configDir = dirname35(configPath);
|
|
104308
104627
|
if (!existsSync61(configDir)) {
|
|
104309
104628
|
await mkdir34(configDir, { recursive: true });
|
|
104310
104629
|
}
|
|
@@ -104434,18 +104753,18 @@ init_logger();
|
|
|
104434
104753
|
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
104435
104754
|
import { existsSync as existsSync62 } from "node:fs";
|
|
104436
104755
|
import { readdir as readdir38, stat as stat20 } from "node:fs/promises";
|
|
104437
|
-
import { join as
|
|
104756
|
+
import { join as join134 } from "node:path";
|
|
104438
104757
|
async function scanForRepos(parentDir) {
|
|
104439
104758
|
const repos = [];
|
|
104440
104759
|
const entries = await readdir38(parentDir);
|
|
104441
104760
|
for (const entry of entries) {
|
|
104442
104761
|
if (entry.startsWith("."))
|
|
104443
104762
|
continue;
|
|
104444
|
-
const fullPath =
|
|
104763
|
+
const fullPath = join134(parentDir, entry);
|
|
104445
104764
|
const entryStat = await stat20(fullPath);
|
|
104446
104765
|
if (!entryStat.isDirectory())
|
|
104447
104766
|
continue;
|
|
104448
|
-
const gitDir =
|
|
104767
|
+
const gitDir = join134(fullPath, ".git");
|
|
104449
104768
|
if (!existsSync62(gitDir))
|
|
104450
104769
|
continue;
|
|
104451
104770
|
const result = spawnSync6("gh", ["repo", "view", "--json", "owner,name"], {
|
|
@@ -104471,8 +104790,8 @@ async function scanForRepos(parentDir) {
|
|
|
104471
104790
|
init_logger();
|
|
104472
104791
|
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
104473
104792
|
import { existsSync as existsSync63 } from "node:fs";
|
|
104474
|
-
import { homedir as
|
|
104475
|
-
import { join as
|
|
104793
|
+
import { homedir as homedir36 } from "node:os";
|
|
104794
|
+
import { join as join135 } from "node:path";
|
|
104476
104795
|
async function validateSetup(cwd2) {
|
|
104477
104796
|
const workDir = cwd2 ?? process.cwd();
|
|
104478
104797
|
const ghVersion = spawnSync7("gh", ["--version"], { encoding: "utf-8", timeout: 1e4 });
|
|
@@ -104503,7 +104822,7 @@ Run this command from a directory with a GitHub remote.`);
|
|
|
104503
104822
|
} catch {
|
|
104504
104823
|
throw new Error(`Failed to parse repository info: ${ghRepo.stdout}`);
|
|
104505
104824
|
}
|
|
104506
|
-
const skillsPath =
|
|
104825
|
+
const skillsPath = join135(homedir36(), ".claude", "skills");
|
|
104507
104826
|
const skillsAvailable = existsSync63(skillsPath);
|
|
104508
104827
|
if (!skillsAvailable) {
|
|
104509
104828
|
logger.warning(`ClaudeKit Engineer skills not found at ${skillsPath}`);
|
|
@@ -104522,7 +104841,7 @@ init_path_resolver();
|
|
|
104522
104841
|
import { createWriteStream as createWriteStream3, statSync as statSync10 } from "node:fs";
|
|
104523
104842
|
import { existsSync as existsSync64 } from "node:fs";
|
|
104524
104843
|
import { mkdir as mkdir35, rename as rename9 } from "node:fs/promises";
|
|
104525
|
-
import { join as
|
|
104844
|
+
import { join as join136 } from "node:path";
|
|
104526
104845
|
|
|
104527
104846
|
class WatchLogger {
|
|
104528
104847
|
logStream = null;
|
|
@@ -104530,7 +104849,7 @@ class WatchLogger {
|
|
|
104530
104849
|
logPath = null;
|
|
104531
104850
|
maxBytes;
|
|
104532
104851
|
constructor(logDir, maxBytes = 0) {
|
|
104533
|
-
this.logDir = logDir ??
|
|
104852
|
+
this.logDir = logDir ?? join136(PathResolver.getClaudeKitDir(), "logs");
|
|
104534
104853
|
this.maxBytes = maxBytes;
|
|
104535
104854
|
}
|
|
104536
104855
|
async init() {
|
|
@@ -104539,7 +104858,7 @@ class WatchLogger {
|
|
|
104539
104858
|
await mkdir35(this.logDir, { recursive: true });
|
|
104540
104859
|
}
|
|
104541
104860
|
const dateStr = formatDate(new Date);
|
|
104542
|
-
this.logPath =
|
|
104861
|
+
this.logPath = join136(this.logDir, `watch-${dateStr}.log`);
|
|
104543
104862
|
this.logStream = createWriteStream3(this.logPath, { flags: "a", mode: 384 });
|
|
104544
104863
|
} catch (error) {
|
|
104545
104864
|
logger.warning(`Cannot create watch log file: ${error instanceof Error ? error.message : "Unknown"}`);
|
|
@@ -104721,7 +105040,7 @@ async function watchCommand(options2) {
|
|
|
104721
105040
|
}
|
|
104722
105041
|
async function discoverRepos(options2, watchLog) {
|
|
104723
105042
|
const cwd2 = process.cwd();
|
|
104724
|
-
const isGitRepo = existsSync65(
|
|
105043
|
+
const isGitRepo = existsSync65(join137(cwd2, ".git"));
|
|
104725
105044
|
if (options2.force) {
|
|
104726
105045
|
await forceRemoveLock(watchLog);
|
|
104727
105046
|
}
|
|
@@ -104979,7 +105298,7 @@ init_logger();
|
|
|
104979
105298
|
init_path_resolver();
|
|
104980
105299
|
init_types3();
|
|
104981
105300
|
import { existsSync as existsSync76, readFileSync as readFileSync19 } from "node:fs";
|
|
104982
|
-
import { join as
|
|
105301
|
+
import { join as join148 } from "node:path";
|
|
104983
105302
|
var packageVersion = package_default.version;
|
|
104984
105303
|
function formatInstalledKits(metadata) {
|
|
104985
105304
|
if (!metadata.kits || Object.keys(metadata.kits).length === 0) {
|
|
@@ -105011,9 +105330,9 @@ async function displayVersion() {
|
|
|
105011
105330
|
let localKitVersion = null;
|
|
105012
105331
|
let isGlobalOnlyKit = false;
|
|
105013
105332
|
const globalKitDir = PathResolver.getGlobalKitDir();
|
|
105014
|
-
const globalMetadataPath =
|
|
105333
|
+
const globalMetadataPath = join148(globalKitDir, "metadata.json");
|
|
105015
105334
|
const prefix = PathResolver.getPathPrefix(false);
|
|
105016
|
-
const localMetadataPath = prefix ?
|
|
105335
|
+
const localMetadataPath = prefix ? join148(process.cwd(), prefix, "metadata.json") : join148(process.cwd(), "metadata.json");
|
|
105017
105336
|
const isLocalSameAsGlobal = localMetadataPath === globalMetadataPath;
|
|
105018
105337
|
if (!isLocalSameAsGlobal && existsSync76(localMetadataPath)) {
|
|
105019
105338
|
try {
|