claudekit-cli 3.41.3 → 3.41.4
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 +918 -641
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -43451,10 +43451,69 @@ function notFoundError(type, name, hint) {
|
|
|
43451
43451
|
}
|
|
43452
43452
|
|
|
43453
43453
|
// src/shared/command-normalizer.ts
|
|
43454
|
+
import { homedir as homedir12 } from "node:os";
|
|
43455
|
+
import { join as join16 } from "node:path";
|
|
43456
|
+
function escapeRegex(value) {
|
|
43457
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
43458
|
+
}
|
|
43459
|
+
function normalizeCommandRoot(root) {
|
|
43460
|
+
return root.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
43461
|
+
}
|
|
43462
|
+
function formatCanonicalClaudeCommand(nodePrefix, root, relativePath, suffix = "") {
|
|
43463
|
+
const normalizedRoot = normalizeCommandRoot(root);
|
|
43464
|
+
let normalizedRelativePath = relativePath.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
43465
|
+
if (normalizedRoot !== "$HOME" && normalizedRoot !== "$CLAUDE_PROJECT_DIR") {
|
|
43466
|
+
normalizedRelativePath = normalizedRelativePath.replace(/^\.claude\//, "");
|
|
43467
|
+
}
|
|
43468
|
+
return normalizedRoot === "$CLAUDE_PROJECT_DIR" ? `${nodePrefix}"${normalizedRoot}"/${normalizedRelativePath}${suffix}` : `${nodePrefix}"${normalizedRoot}/${normalizedRelativePath}"${suffix}`;
|
|
43469
|
+
}
|
|
43470
|
+
function isNodeClaudeCommand(cmd) {
|
|
43471
|
+
if (!cmd)
|
|
43472
|
+
return false;
|
|
43473
|
+
return /^\s*node\s+/.test(cmd) && (cmd.includes(".claude/") || cmd.includes(".claude\\"));
|
|
43474
|
+
}
|
|
43475
|
+
function repairClaudeNodeCommandPath(cmd, root) {
|
|
43476
|
+
if (!cmd || !isNodeClaudeCommand(cmd)) {
|
|
43477
|
+
return { command: cmd ?? "", changed: false, issue: null };
|
|
43478
|
+
}
|
|
43479
|
+
const bareRelativeMatch = cmd.match(/^(node\s+)(?:\.\/)?(\.claude[/\\][^\s"]+)(.*)$/);
|
|
43480
|
+
if (bareRelativeMatch) {
|
|
43481
|
+
const [, nodePrefix, relativePath, suffix] = bareRelativeMatch;
|
|
43482
|
+
const command = formatCanonicalClaudeCommand(nodePrefix, root, relativePath, suffix);
|
|
43483
|
+
return { command, changed: command !== cmd, issue: "raw-relative" };
|
|
43484
|
+
}
|
|
43485
|
+
const embeddedQuotedMatch = cmd.match(/^(node\s+)"(?:\$HOME|\$CLAUDE_PROJECT_DIR|%USERPROFILE%|%CLAUDE_PROJECT_DIR%)[/\\](\.claude[/\\][^"]+)"(.*)$/);
|
|
43486
|
+
if (embeddedQuotedMatch) {
|
|
43487
|
+
const [, nodePrefix, relativePath, suffix] = embeddedQuotedMatch;
|
|
43488
|
+
const command = formatCanonicalClaudeCommand(nodePrefix, root, relativePath, suffix);
|
|
43489
|
+
return { command, changed: command !== cmd, issue: "invalid-format" };
|
|
43490
|
+
}
|
|
43491
|
+
const varOnlyQuotedMatch = cmd.match(/^(node\s+)"(?:\$HOME|\$CLAUDE_PROJECT_DIR|%USERPROFILE%|%CLAUDE_PROJECT_DIR%)"[/\\](\.claude[/\\][^\s"]+)(.*)$/);
|
|
43492
|
+
if (varOnlyQuotedMatch) {
|
|
43493
|
+
const [, nodePrefix, relativePath, suffix] = varOnlyQuotedMatch;
|
|
43494
|
+
const command = formatCanonicalClaudeCommand(nodePrefix, root, relativePath, suffix);
|
|
43495
|
+
return { command, changed: command !== cmd, issue: "invalid-format" };
|
|
43496
|
+
}
|
|
43497
|
+
const tildeMatch = cmd.match(/^(node\s+)~[/\\](\.claude[/\\][^\s"]+)(.*)$/);
|
|
43498
|
+
if (tildeMatch) {
|
|
43499
|
+
const [, nodePrefix, relativePath, suffix] = tildeMatch;
|
|
43500
|
+
const command = formatCanonicalClaudeCommand(nodePrefix, root, relativePath, suffix);
|
|
43501
|
+
return { command, changed: command !== cmd, issue: "invalid-format" };
|
|
43502
|
+
}
|
|
43503
|
+
const unquotedMatch = cmd.match(/^(node\s+)(?:\$HOME|\$CLAUDE_PROJECT_DIR|%USERPROFILE%|%CLAUDE_PROJECT_DIR%)[/\\](\.claude[/\\][^\s"]+)(.*)$/);
|
|
43504
|
+
if (unquotedMatch) {
|
|
43505
|
+
const [, nodePrefix, relativePath, suffix] = unquotedMatch;
|
|
43506
|
+
const command = formatCanonicalClaudeCommand(nodePrefix, root, relativePath, suffix);
|
|
43507
|
+
return { command, changed: command !== cmd, issue: "invalid-format" };
|
|
43508
|
+
}
|
|
43509
|
+
return { command: cmd, changed: false, issue: null };
|
|
43510
|
+
}
|
|
43454
43511
|
function normalizeCommand(cmd) {
|
|
43455
43512
|
if (!cmd)
|
|
43456
43513
|
return "";
|
|
43457
43514
|
let normalized = cmd;
|
|
43515
|
+
const globalKitDir = PathResolver.getGlobalKitDir().replace(/\\/g, "/").replace(/\/+$/, "");
|
|
43516
|
+
const defaultGlobalKitDir = join16(homedir12(), ".claude").replace(/\\/g, "/");
|
|
43458
43517
|
normalized = normalized.replace(/"/g, "");
|
|
43459
43518
|
normalized = normalized.replace(/~\//g, "$HOME/");
|
|
43460
43519
|
normalized = normalized.replace(/\$CLAUDE_PROJECT_DIR/g, "$HOME");
|
|
@@ -43463,9 +43522,17 @@ function normalizeCommand(cmd) {
|
|
|
43463
43522
|
normalized = normalized.replace(/%CLAUDE_PROJECT_DIR%/g, "$HOME");
|
|
43464
43523
|
normalized = normalized.replace(/(^|\s)(?:\.\/)?\.claude\//g, "$1$HOME/.claude/");
|
|
43465
43524
|
normalized = normalized.replace(/\\/g, "/");
|
|
43525
|
+
const globalPaths = [...new Set([globalKitDir, defaultGlobalKitDir].filter(Boolean))];
|
|
43526
|
+
for (const absoluteGlobalPath of globalPaths) {
|
|
43527
|
+
const absoluteGlobalPathPattern = new RegExp(escapeRegex(absoluteGlobalPath), "g");
|
|
43528
|
+
normalized = normalized.replace(absoluteGlobalPathPattern, "$HOME/.claude");
|
|
43529
|
+
}
|
|
43466
43530
|
normalized = normalized.replace(/\s+/g, " ").trim();
|
|
43467
43531
|
return normalized;
|
|
43468
43532
|
}
|
|
43533
|
+
var init_command_normalizer = __esm(() => {
|
|
43534
|
+
init_path_resolver();
|
|
43535
|
+
});
|
|
43469
43536
|
|
|
43470
43537
|
// src/shared/parse-timeout.ts
|
|
43471
43538
|
function parseTimeoutMs(rawValue, fallback2, min = 500, max = 60000) {
|
|
@@ -43495,6 +43562,7 @@ var init_shared = __esm(() => {
|
|
|
43495
43562
|
init_safe_spinner();
|
|
43496
43563
|
init_safe_prompts();
|
|
43497
43564
|
init_skip_directories();
|
|
43565
|
+
init_command_normalizer();
|
|
43498
43566
|
});
|
|
43499
43567
|
|
|
43500
43568
|
// src/domains/config/merger/diff-calculator.ts
|
|
@@ -45202,7 +45270,7 @@ var require_lib3 = __commonJS((exports, module) => {
|
|
|
45202
45270
|
|
|
45203
45271
|
// src/domains/config/merger/file-io.ts
|
|
45204
45272
|
import { randomUUID } from "node:crypto";
|
|
45205
|
-
import { dirname as dirname5, join as
|
|
45273
|
+
import { dirname as dirname5, join as join17 } from "node:path";
|
|
45206
45274
|
function stripBOM(content) {
|
|
45207
45275
|
return content.charCodeAt(0) === 65279 ? content.slice(1) : content;
|
|
45208
45276
|
}
|
|
@@ -45226,7 +45294,7 @@ async function readSettingsFile(filePath) {
|
|
|
45226
45294
|
}
|
|
45227
45295
|
async function atomicWriteFile(filePath, content) {
|
|
45228
45296
|
const dir = dirname5(filePath);
|
|
45229
|
-
const tempPath =
|
|
45297
|
+
const tempPath = join17(dir, `.settings-${randomUUID()}.tmp`);
|
|
45230
45298
|
try {
|
|
45231
45299
|
await import_fs_extra.writeFile(tempPath, content, "utf-8");
|
|
45232
45300
|
await import_fs_extra.rename(tempPath, filePath);
|
|
@@ -45277,7 +45345,7 @@ var init_settings_merger = __esm(() => {
|
|
|
45277
45345
|
});
|
|
45278
45346
|
|
|
45279
45347
|
// src/domains/config/config-generator.ts
|
|
45280
|
-
import { join as
|
|
45348
|
+
import { join as join18 } from "node:path";
|
|
45281
45349
|
async function generateEnvFile(targetDir, values) {
|
|
45282
45350
|
const lines = [
|
|
45283
45351
|
"# Generated by ClaudeKit CLI setup wizard",
|
|
@@ -45319,7 +45387,7 @@ async function generateEnvFile(targetDir, values) {
|
|
|
45319
45387
|
for (const [key, value] of otherValues) {
|
|
45320
45388
|
lines.push(`${key}=${value}`);
|
|
45321
45389
|
}
|
|
45322
|
-
const envPath =
|
|
45390
|
+
const envPath = join18(targetDir, ".env");
|
|
45323
45391
|
await import_fs_extra2.writeFile(envPath, `${lines.join(`
|
|
45324
45392
|
`)}
|
|
45325
45393
|
`, { mode: 384 });
|
|
@@ -46943,8 +47011,8 @@ var init_chokidar = __esm(() => {
|
|
|
46943
47011
|
});
|
|
46944
47012
|
|
|
46945
47013
|
// src/domains/web-server/file-watcher.ts
|
|
46946
|
-
import { homedir as
|
|
46947
|
-
import { join as
|
|
47014
|
+
import { homedir as homedir13 } from "node:os";
|
|
47015
|
+
import { join as join21 } from "node:path";
|
|
46948
47016
|
|
|
46949
47017
|
class FileWatcher {
|
|
46950
47018
|
watcher = null;
|
|
@@ -46966,16 +47034,16 @@ class FileWatcher {
|
|
|
46966
47034
|
}
|
|
46967
47035
|
getWatchPaths() {
|
|
46968
47036
|
const paths = [];
|
|
46969
|
-
const globalDir =
|
|
46970
|
-
paths.push(
|
|
46971
|
-
const globalKitDir =
|
|
46972
|
-
paths.push(
|
|
46973
|
-
paths.push(
|
|
46974
|
-
paths.push(
|
|
47037
|
+
const globalDir = join21(homedir13(), ".claudekit");
|
|
47038
|
+
paths.push(join21(globalDir, "config.json"));
|
|
47039
|
+
const globalKitDir = join21(homedir13(), ".claude");
|
|
47040
|
+
paths.push(join21(globalKitDir, ".ck.json"));
|
|
47041
|
+
paths.push(join21(globalKitDir, "settings.json"));
|
|
47042
|
+
paths.push(join21(globalKitDir, "settings.local.json"));
|
|
46975
47043
|
const cwd2 = process.cwd();
|
|
46976
|
-
paths.push(
|
|
46977
|
-
paths.push(
|
|
46978
|
-
paths.push(
|
|
47044
|
+
paths.push(join21(cwd2, ".claude", ".ck.json"));
|
|
47045
|
+
paths.push(join21(cwd2, ".claude", "settings.json"));
|
|
47046
|
+
paths.push(join21(cwd2, ".claude", "settings.local.json"));
|
|
46979
47047
|
return paths;
|
|
46980
47048
|
}
|
|
46981
47049
|
handleFileChange(path3, type) {
|
|
@@ -47018,8 +47086,8 @@ class FileWatcher {
|
|
|
47018
47086
|
return path3.endsWith("config.json") || path3.endsWith(".ck.json") || path3.endsWith("settings.json") || path3.endsWith("settings.local.json");
|
|
47019
47087
|
}
|
|
47020
47088
|
getConfigScope(path3) {
|
|
47021
|
-
const globalDir =
|
|
47022
|
-
const globalKitDir =
|
|
47089
|
+
const globalDir = join21(homedir13(), ".claudekit");
|
|
47090
|
+
const globalKitDir = join21(homedir13(), ".claude");
|
|
47023
47091
|
return path3.startsWith(globalDir) || path3.startsWith(globalKitDir) ? "global" : "local";
|
|
47024
47092
|
}
|
|
47025
47093
|
stop() {
|
|
@@ -47412,14 +47480,14 @@ var init_projects_registry = __esm(() => {
|
|
|
47412
47480
|
|
|
47413
47481
|
// src/domains/claudekit-data/claude-projects-scanner.ts
|
|
47414
47482
|
import { existsSync as existsSync13, readFileSync as readFileSync5, readdirSync as readdirSync2, statSync as statSync3 } from "node:fs";
|
|
47415
|
-
import { join as
|
|
47483
|
+
import { join as join22 } from "node:path";
|
|
47416
47484
|
function extractProjectPath(claudeProjectDir) {
|
|
47417
47485
|
try {
|
|
47418
47486
|
const files = readdirSync2(claudeProjectDir);
|
|
47419
47487
|
const jsonlFile = files.find((f3) => f3.endsWith(".jsonl"));
|
|
47420
47488
|
if (!jsonlFile)
|
|
47421
47489
|
return null;
|
|
47422
|
-
const filePath =
|
|
47490
|
+
const filePath = join22(claudeProjectDir, jsonlFile);
|
|
47423
47491
|
const content = readFileSync5(filePath, "utf-8");
|
|
47424
47492
|
const lines = content.split(`
|
|
47425
47493
|
`).slice(0, 10);
|
|
@@ -47439,7 +47507,7 @@ function extractProjectPath(claudeProjectDir) {
|
|
|
47439
47507
|
}
|
|
47440
47508
|
}
|
|
47441
47509
|
function scanClaudeProjects() {
|
|
47442
|
-
const claudeProjectsDir =
|
|
47510
|
+
const claudeProjectsDir = join22(PathResolver.getGlobalKitDir(), "projects");
|
|
47443
47511
|
const now = Date.now();
|
|
47444
47512
|
if (cachedDiscoveredProjects && cachedDiscoveredProjects.expiresAt > now) {
|
|
47445
47513
|
return cachedDiscoveredProjects.projects;
|
|
@@ -47456,7 +47524,7 @@ function scanClaudeProjects() {
|
|
|
47456
47524
|
for (const entry of entries) {
|
|
47457
47525
|
if (!entry.isDirectory())
|
|
47458
47526
|
continue;
|
|
47459
|
-
const projectDirPath =
|
|
47527
|
+
const projectDirPath = join22(claudeProjectsDir, entry.name);
|
|
47460
47528
|
const projectPath = extractProjectPath(projectDirPath);
|
|
47461
47529
|
if (!projectPath) {
|
|
47462
47530
|
logger.debug(`Could not extract path from: ${entry.name}`);
|
|
@@ -47510,15 +47578,15 @@ var init_claudekit_data2 = __esm(() => {
|
|
|
47510
47578
|
// src/domains/web-server/routes/action-routes.ts
|
|
47511
47579
|
import { spawn, spawnSync } from "node:child_process";
|
|
47512
47580
|
import { existsSync as existsSync14 } from "node:fs";
|
|
47513
|
-
import { homedir as
|
|
47514
|
-
import { join as
|
|
47581
|
+
import { homedir as homedir14 } from "node:os";
|
|
47582
|
+
import { join as join23, resolve as resolve6, sep as sep2 } from "node:path";
|
|
47515
47583
|
function getWindowsPaths(...relativePaths) {
|
|
47516
47584
|
const roots = [
|
|
47517
47585
|
WINDOWS_PATHS.localAppData,
|
|
47518
47586
|
WINDOWS_PATHS.programFiles,
|
|
47519
47587
|
WINDOWS_PATHS.programFilesX86
|
|
47520
47588
|
];
|
|
47521
|
-
return roots.flatMap((root) => relativePaths.map((rel) =>
|
|
47589
|
+
return roots.flatMap((root) => relativePaths.map((rel) => join23(root, rel)));
|
|
47522
47590
|
}
|
|
47523
47591
|
function isCommandAvailable(command) {
|
|
47524
47592
|
const checkCommand = isWindows() ? "where" : "which";
|
|
@@ -47790,7 +47858,7 @@ async function isActionPathAllowed(dirPath, projectId) {
|
|
|
47790
47858
|
if (isPathInsideBase(dirPath, process.cwd())) {
|
|
47791
47859
|
return true;
|
|
47792
47860
|
}
|
|
47793
|
-
return isPathInsideBase(dirPath,
|
|
47861
|
+
return isPathInsideBase(dirPath, homedir14());
|
|
47794
47862
|
}
|
|
47795
47863
|
function buildSystemTerminalCommand(dirPath) {
|
|
47796
47864
|
if (isMacOS()) {
|
|
@@ -48129,7 +48197,7 @@ var init_action_routes = __esm(() => {
|
|
|
48129
48197
|
projectId: exports_external.string().min(1).max(256).optional()
|
|
48130
48198
|
}).strict();
|
|
48131
48199
|
WINDOWS_PATHS = {
|
|
48132
|
-
localAppData: process.env.LOCALAPPDATA ||
|
|
48200
|
+
localAppData: process.env.LOCALAPPDATA || join23(homedir14(), "AppData", "Local"),
|
|
48133
48201
|
programFiles: process.env.ProgramFiles || "C:\\Program Files",
|
|
48134
48202
|
programFilesX86: process.env["ProgramFiles(x86)"] || "C:\\Program Files (x86)"
|
|
48135
48203
|
};
|
|
@@ -48150,7 +48218,7 @@ var init_action_routes = __esm(() => {
|
|
|
48150
48218
|
openMode: "open-directory",
|
|
48151
48219
|
capabilities: ["open-directory", "run-command"],
|
|
48152
48220
|
macAppName: "iTerm",
|
|
48153
|
-
macAppPaths: ["/Applications/iTerm.app",
|
|
48221
|
+
macAppPaths: ["/Applications/iTerm.app", join23(homedir14(), "Applications", "iTerm.app")]
|
|
48154
48222
|
},
|
|
48155
48223
|
{
|
|
48156
48224
|
id: "warp",
|
|
@@ -48161,7 +48229,7 @@ var init_action_routes = __esm(() => {
|
|
|
48161
48229
|
capabilities: ["open-directory", "uri-scheme"],
|
|
48162
48230
|
commands: ["warp"],
|
|
48163
48231
|
macAppName: "Warp",
|
|
48164
|
-
macAppPaths: ["/Applications/Warp.app",
|
|
48232
|
+
macAppPaths: ["/Applications/Warp.app", join23(homedir14(), "Applications", "Warp.app")],
|
|
48165
48233
|
windowsAppPaths: getWindowsPaths("Warp\\Warp.exe"),
|
|
48166
48234
|
linuxAppPaths: ["/usr/bin/warp", "/usr/local/bin/warp"]
|
|
48167
48235
|
},
|
|
@@ -48173,7 +48241,7 @@ var init_action_routes = __esm(() => {
|
|
|
48173
48241
|
openMode: "open-directory",
|
|
48174
48242
|
capabilities: ["open-directory", "run-command"],
|
|
48175
48243
|
commands: ["wt"],
|
|
48176
|
-
windowsAppPaths: [
|
|
48244
|
+
windowsAppPaths: [join23(WINDOWS_PATHS.localAppData, "Microsoft", "WindowsApps", "wt.exe")]
|
|
48177
48245
|
},
|
|
48178
48246
|
{
|
|
48179
48247
|
id: "wezterm",
|
|
@@ -48184,7 +48252,7 @@ var init_action_routes = __esm(() => {
|
|
|
48184
48252
|
capabilities: ["open-directory"],
|
|
48185
48253
|
commands: ["wezterm"],
|
|
48186
48254
|
macAppName: "WezTerm",
|
|
48187
|
-
macAppPaths: ["/Applications/WezTerm.app",
|
|
48255
|
+
macAppPaths: ["/Applications/WezTerm.app", join23(homedir14(), "Applications", "WezTerm.app")],
|
|
48188
48256
|
windowsAppPaths: getWindowsPaths("WezTerm\\wezterm-gui.exe", "WezTerm\\wezterm.exe"),
|
|
48189
48257
|
linuxAppPaths: ["/usr/bin/wezterm", "/usr/local/bin/wezterm"]
|
|
48190
48258
|
},
|
|
@@ -48197,7 +48265,7 @@ var init_action_routes = __esm(() => {
|
|
|
48197
48265
|
capabilities: ["open-directory"],
|
|
48198
48266
|
commands: ["kitty"],
|
|
48199
48267
|
macAppName: "kitty",
|
|
48200
|
-
macAppPaths: ["/Applications/kitty.app",
|
|
48268
|
+
macAppPaths: ["/Applications/kitty.app", join23(homedir14(), "Applications", "kitty.app")],
|
|
48201
48269
|
windowsAppPaths: getWindowsPaths("kitty\\kitty.exe"),
|
|
48202
48270
|
linuxAppPaths: ["/usr/bin/kitty", "/usr/local/bin/kitty"]
|
|
48203
48271
|
},
|
|
@@ -48210,7 +48278,7 @@ var init_action_routes = __esm(() => {
|
|
|
48210
48278
|
capabilities: ["open-directory"],
|
|
48211
48279
|
commands: ["alacritty"],
|
|
48212
48280
|
macAppName: "Alacritty",
|
|
48213
|
-
macAppPaths: ["/Applications/Alacritty.app",
|
|
48281
|
+
macAppPaths: ["/Applications/Alacritty.app", join23(homedir14(), "Applications", "Alacritty.app")],
|
|
48214
48282
|
windowsAppPaths: getWindowsPaths("Alacritty\\alacritty.exe"),
|
|
48215
48283
|
linuxAppPaths: ["/usr/bin/alacritty", "/usr/local/bin/alacritty"]
|
|
48216
48284
|
},
|
|
@@ -48283,7 +48351,7 @@ var init_action_routes = __esm(() => {
|
|
|
48283
48351
|
capabilities: ["open-app"],
|
|
48284
48352
|
commands: ["termius"],
|
|
48285
48353
|
macAppName: "Termius",
|
|
48286
|
-
macAppPaths: ["/Applications/Termius.app",
|
|
48354
|
+
macAppPaths: ["/Applications/Termius.app", join23(homedir14(), "Applications", "Termius.app")],
|
|
48287
48355
|
windowsAppPaths: getWindowsPaths("Termius\\Termius.exe"),
|
|
48288
48356
|
linuxAppPaths: ["/usr/bin/termius"]
|
|
48289
48357
|
},
|
|
@@ -48306,7 +48374,7 @@ var init_action_routes = __esm(() => {
|
|
|
48306
48374
|
macAppName: "Visual Studio Code",
|
|
48307
48375
|
macAppPaths: [
|
|
48308
48376
|
"/Applications/Visual Studio Code.app",
|
|
48309
|
-
|
|
48377
|
+
join23(homedir14(), "Applications", "Visual Studio Code.app")
|
|
48310
48378
|
],
|
|
48311
48379
|
windowsAppPaths: getWindowsPaths("Programs\\Microsoft VS Code\\Code.exe", "Microsoft VS Code\\Code.exe"),
|
|
48312
48380
|
linuxAppPaths: ["/usr/bin/code", "/snap/bin/code"]
|
|
@@ -48320,7 +48388,7 @@ var init_action_routes = __esm(() => {
|
|
|
48320
48388
|
capabilities: ["open-directory"],
|
|
48321
48389
|
commands: ["cursor"],
|
|
48322
48390
|
macAppName: "Cursor",
|
|
48323
|
-
macAppPaths: ["/Applications/Cursor.app",
|
|
48391
|
+
macAppPaths: ["/Applications/Cursor.app", join23(homedir14(), "Applications", "Cursor.app")],
|
|
48324
48392
|
windowsAppPaths: getWindowsPaths("Programs\\Cursor\\Cursor.exe", "Cursor\\Cursor.exe"),
|
|
48325
48393
|
linuxAppPaths: ["/usr/bin/cursor"]
|
|
48326
48394
|
},
|
|
@@ -48333,7 +48401,7 @@ var init_action_routes = __esm(() => {
|
|
|
48333
48401
|
capabilities: ["open-directory"],
|
|
48334
48402
|
commands: ["windsurf"],
|
|
48335
48403
|
macAppName: "Windsurf",
|
|
48336
|
-
macAppPaths: ["/Applications/Windsurf.app",
|
|
48404
|
+
macAppPaths: ["/Applications/Windsurf.app", join23(homedir14(), "Applications", "Windsurf.app")],
|
|
48337
48405
|
windowsAppPaths: getWindowsPaths("Programs\\Windsurf\\Windsurf.exe", "Windsurf\\Windsurf.exe"),
|
|
48338
48406
|
linuxAppPaths: ["/usr/bin/windsurf"]
|
|
48339
48407
|
},
|
|
@@ -48348,11 +48416,11 @@ var init_action_routes = __esm(() => {
|
|
|
48348
48416
|
macAppName: "Antigravity",
|
|
48349
48417
|
macAppPaths: [
|
|
48350
48418
|
"/Applications/Antigravity.app",
|
|
48351
|
-
|
|
48419
|
+
join23(homedir14(), "Applications", "Antigravity.app")
|
|
48352
48420
|
],
|
|
48353
48421
|
windowsAppPaths: getWindowsPaths("Programs\\Antigravity\\Antigravity.exe"),
|
|
48354
48422
|
linuxAppPaths: ["/usr/bin/antigravity"],
|
|
48355
|
-
fallbackDetectionPaths: [
|
|
48423
|
+
fallbackDetectionPaths: [join23(homedir14(), ".gemini", "antigravity")]
|
|
48356
48424
|
},
|
|
48357
48425
|
{
|
|
48358
48426
|
id: "zed",
|
|
@@ -48363,7 +48431,7 @@ var init_action_routes = __esm(() => {
|
|
|
48363
48431
|
capabilities: ["open-directory"],
|
|
48364
48432
|
commands: ["zed"],
|
|
48365
48433
|
macAppName: "Zed",
|
|
48366
|
-
macAppPaths: ["/Applications/Zed.app",
|
|
48434
|
+
macAppPaths: ["/Applications/Zed.app", join23(homedir14(), "Applications", "Zed.app")],
|
|
48367
48435
|
windowsAppPaths: getWindowsPaths("Zed\\Zed.exe"),
|
|
48368
48436
|
linuxAppPaths: ["/usr/bin/zed", "/usr/local/bin/zed"]
|
|
48369
48437
|
},
|
|
@@ -48378,7 +48446,7 @@ var init_action_routes = __esm(() => {
|
|
|
48378
48446
|
macAppName: "Sublime Text",
|
|
48379
48447
|
macAppPaths: [
|
|
48380
48448
|
"/Applications/Sublime Text.app",
|
|
48381
|
-
|
|
48449
|
+
join23(homedir14(), "Applications", "Sublime Text.app")
|
|
48382
48450
|
],
|
|
48383
48451
|
windowsAppPaths: getWindowsPaths("Sublime Text\\sublime_text.exe"),
|
|
48384
48452
|
linuxAppPaths: ["/usr/bin/subl", "/snap/bin/subl"]
|
|
@@ -49001,7 +49069,7 @@ var init_ck_config_schema = __esm(() => {
|
|
|
49001
49069
|
// src/domains/web-server/routes/ck-config-routes.ts
|
|
49002
49070
|
import { existsSync as existsSync15 } from "node:fs";
|
|
49003
49071
|
import { readFile as readFile11 } from "node:fs/promises";
|
|
49004
|
-
import { join as
|
|
49072
|
+
import { join as join24 } from "node:path";
|
|
49005
49073
|
async function resolveProjectDir(projectId) {
|
|
49006
49074
|
if (!projectId)
|
|
49007
49075
|
return null;
|
|
@@ -49143,7 +49211,7 @@ function registerCkConfigRoutes(app) {
|
|
|
49143
49211
|
});
|
|
49144
49212
|
app.get("/api/metadata/global", async (_req, res) => {
|
|
49145
49213
|
try {
|
|
49146
|
-
const metadataPath =
|
|
49214
|
+
const metadataPath = join24(PathResolver.getGlobalKitDir(), "metadata.json");
|
|
49147
49215
|
let metadata = {};
|
|
49148
49216
|
if (existsSync15(metadataPath)) {
|
|
49149
49217
|
const content = await readFile11(metadataPath, "utf-8");
|
|
@@ -49223,11 +49291,11 @@ var init_types5 = __esm(() => {
|
|
|
49223
49291
|
|
|
49224
49292
|
// src/services/claude-data/history-parser.ts
|
|
49225
49293
|
import { createReadStream, statSync as statSync4 } from "node:fs";
|
|
49226
|
-
import { homedir as
|
|
49227
|
-
import { join as
|
|
49294
|
+
import { homedir as homedir15 } from "node:os";
|
|
49295
|
+
import { join as join25 } from "node:path";
|
|
49228
49296
|
import { createInterface as createInterface2 } from "node:readline";
|
|
49229
49297
|
function getHistoryPath() {
|
|
49230
|
-
return process.env.CLAUDE_HISTORY_PATH ??
|
|
49298
|
+
return process.env.CLAUDE_HISTORY_PATH ?? join25(homedir15(), ".claude", "history.jsonl");
|
|
49231
49299
|
}
|
|
49232
49300
|
function emptyResult(parseTimeMs, error) {
|
|
49233
49301
|
return { projects: [], totalEntries: 0, errorCount: 0, parseTimeMs, error };
|
|
@@ -49311,7 +49379,7 @@ var init_history_parser = __esm(() => {
|
|
|
49311
49379
|
// src/services/claude-data/session-parser.ts
|
|
49312
49380
|
import { existsSync as existsSync16 } from "node:fs";
|
|
49313
49381
|
import { readFile as readFile12, readdir as readdir5, stat as stat4 } from "node:fs/promises";
|
|
49314
|
-
import { join as
|
|
49382
|
+
import { join as join26 } from "node:path";
|
|
49315
49383
|
function formatTimestamp(date) {
|
|
49316
49384
|
const now = new Date;
|
|
49317
49385
|
const isToday = date.toDateString() === now.toDateString();
|
|
@@ -49408,7 +49476,7 @@ async function getProjectSessions(projectDir, limit = 10) {
|
|
|
49408
49476
|
const files = await readdir5(projectDir);
|
|
49409
49477
|
const jsonlFiles = files.filter((f3) => f3.endsWith(".jsonl"));
|
|
49410
49478
|
const fileStats = await Promise.all(jsonlFiles.map(async (file) => {
|
|
49411
|
-
const filePath =
|
|
49479
|
+
const filePath = join26(projectDir, file);
|
|
49412
49480
|
const fileStat = await stat4(filePath).catch(() => null);
|
|
49413
49481
|
return { file, filePath, mtime: fileStat?.mtime || new Date(0) };
|
|
49414
49482
|
}));
|
|
@@ -49425,10 +49493,10 @@ var init_session_parser = () => {};
|
|
|
49425
49493
|
// src/services/claude-data/skill-scanner.ts
|
|
49426
49494
|
import { existsSync as existsSync17 } from "node:fs";
|
|
49427
49495
|
import { readFile as readFile13, readdir as readdir6 } from "node:fs/promises";
|
|
49428
|
-
import { homedir as
|
|
49429
|
-
import { join as
|
|
49496
|
+
import { homedir as homedir16 } from "node:os";
|
|
49497
|
+
import { join as join27 } from "node:path";
|
|
49430
49498
|
async function getCkSkillMetadata(scope) {
|
|
49431
|
-
const metaPath = scope === "global" ?
|
|
49499
|
+
const metaPath = scope === "global" ? join27(homedir16(), ".claude", "metadata.json") : join27(process.cwd(), ".claude", "metadata.json");
|
|
49432
49500
|
if (!existsSync17(metaPath))
|
|
49433
49501
|
return null;
|
|
49434
49502
|
const result = new Map;
|
|
@@ -49464,7 +49532,7 @@ async function getCkSkillMetadata(scope) {
|
|
|
49464
49532
|
return result.size > 0 ? result : null;
|
|
49465
49533
|
}
|
|
49466
49534
|
async function getSkillMetadata(skillPath) {
|
|
49467
|
-
const skillMdPath =
|
|
49535
|
+
const skillMdPath = join27(skillPath, "SKILL.md");
|
|
49468
49536
|
if (!existsSync17(skillMdPath))
|
|
49469
49537
|
return null;
|
|
49470
49538
|
try {
|
|
@@ -49513,8 +49581,8 @@ async function scanSkills() {
|
|
|
49513
49581
|
continue;
|
|
49514
49582
|
if (ckMeta && !ckMeta.has(entry))
|
|
49515
49583
|
continue;
|
|
49516
|
-
const entryPath =
|
|
49517
|
-
const skillMdPath =
|
|
49584
|
+
const entryPath = join27(skillsDir, entry);
|
|
49585
|
+
const skillMdPath = join27(entryPath, "SKILL.md");
|
|
49518
49586
|
if (!existsSync17(skillMdPath))
|
|
49519
49587
|
continue;
|
|
49520
49588
|
const frontmatter = await getSkillMetadata(entryPath);
|
|
@@ -49559,17 +49627,17 @@ async function scanSkills() {
|
|
|
49559
49627
|
var import_gray_matter4, skillsDir, SKIP_DIRS2;
|
|
49560
49628
|
var init_skill_scanner = __esm(() => {
|
|
49561
49629
|
import_gray_matter4 = __toESM(require_gray_matter(), 1);
|
|
49562
|
-
skillsDir =
|
|
49630
|
+
skillsDir = join27(homedir16(), ".claude", "skills");
|
|
49563
49631
|
SKIP_DIRS2 = [".venv", "scripts", "__pycache__", "node_modules", ".git", "common"];
|
|
49564
49632
|
});
|
|
49565
49633
|
|
|
49566
49634
|
// src/services/claude-data/settings-reader.ts
|
|
49567
49635
|
import { existsSync as existsSync18 } from "node:fs";
|
|
49568
49636
|
import { copyFile as copyFile2, mkdir as mkdir7, readFile as readFile14, rename as rename4, rm as rm4, writeFile as writeFile10 } from "node:fs/promises";
|
|
49569
|
-
import { homedir as
|
|
49570
|
-
import { join as
|
|
49637
|
+
import { homedir as homedir17 } from "node:os";
|
|
49638
|
+
import { join as join28 } from "node:path";
|
|
49571
49639
|
function getSettingsPath() {
|
|
49572
|
-
return
|
|
49640
|
+
return join28(claudeDir, settingsFilename);
|
|
49573
49641
|
}
|
|
49574
49642
|
async function readSettings() {
|
|
49575
49643
|
const settingsPath = getSettingsPath();
|
|
@@ -49591,7 +49659,7 @@ async function backupAndSaveSettings(settings) {
|
|
|
49591
49659
|
let backupPath = null;
|
|
49592
49660
|
if (existsSync18(settingsPath)) {
|
|
49593
49661
|
await mkdir7(settingsBackupDir, { recursive: true });
|
|
49594
|
-
backupPath =
|
|
49662
|
+
backupPath = join28(settingsBackupDir, `${getBackupTimestamp()}-${settingsFilename}`);
|
|
49595
49663
|
await copyFile2(settingsPath, backupPath);
|
|
49596
49664
|
}
|
|
49597
49665
|
const tempPath = `${settingsPath}.tmp-${Date.now()}`;
|
|
@@ -49628,13 +49696,13 @@ function countMcpServers(settings) {
|
|
|
49628
49696
|
}
|
|
49629
49697
|
var claudeDir, settingsFilename = "settings.json", settingsBackupDir;
|
|
49630
49698
|
var init_settings_reader = __esm(() => {
|
|
49631
|
-
claudeDir =
|
|
49632
|
-
settingsBackupDir =
|
|
49699
|
+
claudeDir = join28(homedir17(), ".claude");
|
|
49700
|
+
settingsBackupDir = join28(claudeDir, ".ck-backups", "settings");
|
|
49633
49701
|
});
|
|
49634
49702
|
|
|
49635
49703
|
// src/services/claude-data/hook-log-reader.ts
|
|
49636
49704
|
import { open as open4 } from "node:fs/promises";
|
|
49637
|
-
import { join as
|
|
49705
|
+
import { join as join29 } from "node:path";
|
|
49638
49706
|
function createEmptySummary() {
|
|
49639
49707
|
return {
|
|
49640
49708
|
total: 0,
|
|
@@ -49682,9 +49750,9 @@ async function resolveProjectPath(projectId) {
|
|
|
49682
49750
|
}
|
|
49683
49751
|
function getHookLogPath(scope, basePath) {
|
|
49684
49752
|
if (scope === "global") {
|
|
49685
|
-
return
|
|
49753
|
+
return join29(basePath, "hooks", ".logs", "hook-log.jsonl");
|
|
49686
49754
|
}
|
|
49687
|
-
return
|
|
49755
|
+
return join29(basePath, ".claude", "hooks", ".logs", "hook-log.jsonl");
|
|
49688
49756
|
}
|
|
49689
49757
|
function parseEntry(line) {
|
|
49690
49758
|
try {
|
|
@@ -49796,14 +49864,14 @@ var init_hook_log_reader = __esm(() => {
|
|
|
49796
49864
|
});
|
|
49797
49865
|
|
|
49798
49866
|
// src/services/claude-data/project-scanner.ts
|
|
49799
|
-
import { homedir as
|
|
49800
|
-
import { basename as basename6, join as
|
|
49867
|
+
import { homedir as homedir18 } from "node:os";
|
|
49868
|
+
import { basename as basename6, join as join30, normalize as normalize3 } from "node:path";
|
|
49801
49869
|
function encodePath(path3) {
|
|
49802
49870
|
return path3.replace(/\//g, "-").replace(/^-/, "-");
|
|
49803
49871
|
}
|
|
49804
49872
|
var projectsDir;
|
|
49805
49873
|
var init_project_scanner = __esm(() => {
|
|
49806
|
-
projectsDir =
|
|
49874
|
+
projectsDir = join30(homedir18(), ".claude", "projects");
|
|
49807
49875
|
});
|
|
49808
49876
|
|
|
49809
49877
|
// src/services/claude-data/project-discovery.ts
|
|
@@ -49898,10 +49966,10 @@ var init_project_discovery = __esm(() => {
|
|
|
49898
49966
|
|
|
49899
49967
|
// src/services/claude-data/user-preferences.ts
|
|
49900
49968
|
import { readFile as readFile15, stat as stat5 } from "node:fs/promises";
|
|
49901
|
-
import { homedir as
|
|
49902
|
-
import { join as
|
|
49969
|
+
import { homedir as homedir19 } from "node:os";
|
|
49970
|
+
import { join as join31 } from "node:path";
|
|
49903
49971
|
function getPreferencesPath() {
|
|
49904
|
-
return
|
|
49972
|
+
return join31(homedir19(), ".claude.json");
|
|
49905
49973
|
}
|
|
49906
49974
|
async function readUserPreferences(filePath) {
|
|
49907
49975
|
const path3 = filePath ?? getPreferencesPath();
|
|
@@ -50035,7 +50103,7 @@ var init_hook_log_routes = __esm(() => {
|
|
|
50035
50103
|
// src/commands/migrate/skill-directory-installer.ts
|
|
50036
50104
|
import { existsSync as existsSync19 } from "node:fs";
|
|
50037
50105
|
import { cp, mkdir as mkdir8, rename as rename5, rm as rm5 } from "node:fs/promises";
|
|
50038
|
-
import { join as
|
|
50106
|
+
import { join as join32, resolve as resolve7 } from "node:path";
|
|
50039
50107
|
async function installSkillDirectories(skills, targetProviders, options2) {
|
|
50040
50108
|
const results = [];
|
|
50041
50109
|
for (const provider of targetProviders) {
|
|
@@ -50063,7 +50131,7 @@ async function installSkillDirectories(skills, targetProviders, options2) {
|
|
|
50063
50131
|
continue;
|
|
50064
50132
|
}
|
|
50065
50133
|
for (const skill of skills) {
|
|
50066
|
-
const targetDir =
|
|
50134
|
+
const targetDir = join32(basePath, skill.name);
|
|
50067
50135
|
if (resolve7(skill.path) === resolve7(targetDir)) {
|
|
50068
50136
|
results.push({
|
|
50069
50137
|
provider,
|
|
@@ -50139,12 +50207,12 @@ var init_skill_directory_installer = __esm(() => {
|
|
|
50139
50207
|
// src/commands/portable/config-discovery.ts
|
|
50140
50208
|
import { existsSync as existsSync20 } from "node:fs";
|
|
50141
50209
|
import { readFile as readFile16, readdir as readdir7 } from "node:fs/promises";
|
|
50142
|
-
import { homedir as
|
|
50143
|
-
import { extname as extname3, join as
|
|
50210
|
+
import { homedir as homedir20 } from "node:os";
|
|
50211
|
+
import { extname as extname3, join as join33, relative as relative5, sep as sep3 } from "node:path";
|
|
50144
50212
|
function resolveSourceOrigin(sourcePath) {
|
|
50145
50213
|
if (!sourcePath)
|
|
50146
50214
|
return "global";
|
|
50147
|
-
const home5 =
|
|
50215
|
+
const home5 = homedir20();
|
|
50148
50216
|
const cwd2 = process.cwd();
|
|
50149
50217
|
if (cwd2 === home5)
|
|
50150
50218
|
return "global";
|
|
@@ -50157,13 +50225,13 @@ function getConfigSourcePath() {
|
|
|
50157
50225
|
return findExistingProjectConfigPath(process.cwd()) ?? getGlobalConfigSourcePath();
|
|
50158
50226
|
}
|
|
50159
50227
|
function getGlobalConfigSourcePath() {
|
|
50160
|
-
return
|
|
50228
|
+
return join33(homedir20(), ".claude", "CLAUDE.md");
|
|
50161
50229
|
}
|
|
50162
50230
|
function getRulesSourcePath() {
|
|
50163
|
-
return findExistingProjectLayoutPath(process.cwd(), "rules") ??
|
|
50231
|
+
return findExistingProjectLayoutPath(process.cwd(), "rules") ?? join33(homedir20(), ".claude", "rules");
|
|
50164
50232
|
}
|
|
50165
50233
|
function getHooksSourcePath() {
|
|
50166
|
-
return findExistingProjectLayoutPath(process.cwd(), "hooks") ??
|
|
50234
|
+
return findExistingProjectLayoutPath(process.cwd(), "hooks") ?? join33(homedir20(), ".claude", "hooks");
|
|
50167
50235
|
}
|
|
50168
50236
|
async function discoverConfig(sourcePath) {
|
|
50169
50237
|
const path3 = sourcePath ?? getConfigSourcePath();
|
|
@@ -50215,7 +50283,7 @@ async function discoverHooks(sourcePath) {
|
|
|
50215
50283
|
}
|
|
50216
50284
|
if (!HOOK_EXTENSIONS.has(ext))
|
|
50217
50285
|
continue;
|
|
50218
|
-
const fullPath =
|
|
50286
|
+
const fullPath = join33(path3, entry.name);
|
|
50219
50287
|
try {
|
|
50220
50288
|
const content = await readFile16(fullPath, "utf-8");
|
|
50221
50289
|
items.push({
|
|
@@ -50241,7 +50309,7 @@ async function discoverPortableFiles(dir, baseDir, options2) {
|
|
|
50241
50309
|
for (const entry of entries) {
|
|
50242
50310
|
if (entry.name.startsWith("."))
|
|
50243
50311
|
continue;
|
|
50244
|
-
const fullPath =
|
|
50312
|
+
const fullPath = join33(dir, entry.name);
|
|
50245
50313
|
if (entry.isSymbolicLink()) {
|
|
50246
50314
|
continue;
|
|
50247
50315
|
}
|
|
@@ -50285,7 +50353,7 @@ var init_config_discovery = __esm(() => {
|
|
|
50285
50353
|
// src/commands/portable/hooks-settings-merger.ts
|
|
50286
50354
|
import { existsSync as existsSync21, mkdirSync, renameSync, rmSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
50287
50355
|
import { readFile as readFile17 } from "node:fs/promises";
|
|
50288
|
-
import { basename as basename8, dirname as dirname9, join as
|
|
50356
|
+
import { basename as basename8, dirname as dirname9, join as join34 } from "node:path";
|
|
50289
50357
|
async function inspectHooksSettings(settingsPath) {
|
|
50290
50358
|
try {
|
|
50291
50359
|
if (!existsSync21(settingsPath)) {
|
|
@@ -50466,8 +50534,8 @@ async function migrateHooksSettings(options2) {
|
|
|
50466
50534
|
targetSettingsPath: null
|
|
50467
50535
|
};
|
|
50468
50536
|
}
|
|
50469
|
-
const resolvedSourcePath = isGlobal ? sourceSettingsPath :
|
|
50470
|
-
const resolvedTargetPath = isGlobal ? targetSettingsPath :
|
|
50537
|
+
const resolvedSourcePath = isGlobal ? sourceSettingsPath : join34(process.cwd(), sourceSettingsPath);
|
|
50538
|
+
const resolvedTargetPath = isGlobal ? targetSettingsPath : join34(process.cwd(), targetSettingsPath);
|
|
50471
50539
|
const sourceHooksResult = await inspectHooksSettings(resolvedSourcePath);
|
|
50472
50540
|
if (sourceHooksResult.status === "missing-file") {
|
|
50473
50541
|
return {
|
|
@@ -53063,20 +53131,20 @@ var init_reconciler = __esm(() => {
|
|
|
53063
53131
|
|
|
53064
53132
|
// src/commands/skills/skills-discovery.ts
|
|
53065
53133
|
import { readFile as readFile20, readdir as readdir8, stat as stat6 } from "node:fs/promises";
|
|
53066
|
-
import { homedir as
|
|
53067
|
-
import { dirname as dirname10, join as
|
|
53134
|
+
import { homedir as homedir21 } from "node:os";
|
|
53135
|
+
import { dirname as dirname10, join as join35 } from "node:path";
|
|
53068
53136
|
function getSkillSourcePath() {
|
|
53069
|
-
const bundledRoot =
|
|
53137
|
+
const bundledRoot = join35(process.cwd(), "node_modules", "claudekit-engineer");
|
|
53070
53138
|
return findFirstExistingPath([
|
|
53071
|
-
|
|
53139
|
+
join35(bundledRoot, "skills"),
|
|
53072
53140
|
...getProjectLayoutCandidates(bundledRoot, "skills"),
|
|
53073
53141
|
...getProjectLayoutCandidates(process.cwd(), "skills"),
|
|
53074
|
-
|
|
53142
|
+
join35(home5, ".claude/skills")
|
|
53075
53143
|
]);
|
|
53076
53144
|
}
|
|
53077
53145
|
async function hasSkillMd(dir) {
|
|
53078
53146
|
try {
|
|
53079
|
-
const skillPath =
|
|
53147
|
+
const skillPath = join35(dir, "SKILL.md");
|
|
53080
53148
|
const stats = await stat6(skillPath);
|
|
53081
53149
|
return stats.isFile();
|
|
53082
53150
|
} catch {
|
|
@@ -53124,9 +53192,9 @@ async function discoverSkills(sourcePath) {
|
|
|
53124
53192
|
if (!entry.isDirectory() || SKIP_DIRS3.includes(entry.name)) {
|
|
53125
53193
|
continue;
|
|
53126
53194
|
}
|
|
53127
|
-
const skillDir =
|
|
53195
|
+
const skillDir = join35(searchPath, entry.name);
|
|
53128
53196
|
if (await hasSkillMd(skillDir)) {
|
|
53129
|
-
const skill = await parseSkillMd(
|
|
53197
|
+
const skill = await parseSkillMd(join35(skillDir, "SKILL.md"));
|
|
53130
53198
|
if (skill && !seenNames.has(skill.name)) {
|
|
53131
53199
|
skills.push(skill);
|
|
53132
53200
|
seenNames.add(skill.name);
|
|
@@ -53145,7 +53213,7 @@ var init_skills_discovery = __esm(() => {
|
|
|
53145
53213
|
init_kit_layout();
|
|
53146
53214
|
init_logger();
|
|
53147
53215
|
import_gray_matter5 = __toESM(require_gray_matter(), 1);
|
|
53148
|
-
home5 =
|
|
53216
|
+
home5 = homedir21();
|
|
53149
53217
|
SKIP_DIRS3 = ["node_modules", ".git", "dist", "build", ".venv", "__pycache__", "common"];
|
|
53150
53218
|
});
|
|
53151
53219
|
|
|
@@ -53248,8 +53316,8 @@ var init_migration_result_utils = __esm(() => {
|
|
|
53248
53316
|
// src/domains/web-server/routes/migration-routes.ts
|
|
53249
53317
|
import { existsSync as existsSync24 } from "node:fs";
|
|
53250
53318
|
import { readFile as readFile21, rm as rm6 } from "node:fs/promises";
|
|
53251
|
-
import { homedir as
|
|
53252
|
-
import { basename as basename9, join as
|
|
53319
|
+
import { homedir as homedir22 } from "node:os";
|
|
53320
|
+
import { basename as basename9, join as join36, resolve as resolve8 } from "node:path";
|
|
53253
53321
|
function isDisallowedControlCode(codePoint) {
|
|
53254
53322
|
return codePoint >= 0 && codePoint <= 8 || codePoint >= 11 && codePoint <= 31 || codePoint >= 127 && codePoint <= 159;
|
|
53255
53323
|
}
|
|
@@ -53816,12 +53884,12 @@ function registerMigrationRoutes(app) {
|
|
|
53816
53884
|
};
|
|
53817
53885
|
const discovered = await discoverMigrationItems(includeAll);
|
|
53818
53886
|
const cwd2 = process.cwd();
|
|
53819
|
-
const home6 =
|
|
53887
|
+
const home6 = homedir22();
|
|
53820
53888
|
res.status(200).json({
|
|
53821
53889
|
cwd: cwd2,
|
|
53822
53890
|
targetPaths: {
|
|
53823
|
-
project:
|
|
53824
|
-
global:
|
|
53891
|
+
project: join36(cwd2, ".claude"),
|
|
53892
|
+
global: join36(home6, ".claude")
|
|
53825
53893
|
},
|
|
53826
53894
|
sourcePaths: discovered.sourcePaths,
|
|
53827
53895
|
sourceOrigins: {
|
|
@@ -54850,12 +54918,12 @@ var init_plan_table_parser = __esm(() => {
|
|
|
54850
54918
|
|
|
54851
54919
|
// src/domains/plan-parser/plan-scanner.ts
|
|
54852
54920
|
import { existsSync as existsSync25, readdirSync as readdirSync3 } from "node:fs";
|
|
54853
|
-
import { join as
|
|
54921
|
+
import { join as join37 } from "node:path";
|
|
54854
54922
|
function scanPlanDir(dir) {
|
|
54855
54923
|
if (!existsSync25(dir))
|
|
54856
54924
|
return [];
|
|
54857
54925
|
try {
|
|
54858
|
-
return readdirSync3(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) =>
|
|
54926
|
+
return readdirSync3(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join37(dir, entry.name, "plan.md")).filter(existsSync25);
|
|
54859
54927
|
} catch {
|
|
54860
54928
|
return [];
|
|
54861
54929
|
}
|
|
@@ -54930,7 +54998,7 @@ var init_plan_validator = __esm(() => {
|
|
|
54930
54998
|
// src/domains/plan-parser/plan-writer.ts
|
|
54931
54999
|
import { mkdirSync as mkdirSync2, readFileSync as readFileSync8, writeFileSync as writeFileSync3 } from "node:fs";
|
|
54932
55000
|
import { existsSync as existsSync27 } from "node:fs";
|
|
54933
|
-
import { basename as basename11, dirname as dirname13, join as
|
|
55001
|
+
import { basename as basename11, dirname as dirname13, join as join38 } from "node:path";
|
|
54934
55002
|
function phaseNameToFilename(id, name) {
|
|
54935
55003
|
const numMatch = /^(\d+)([a-z]*)$/i.exec(id);
|
|
54936
55004
|
const num = numMatch ? numMatch[1] : id;
|
|
@@ -55038,12 +55106,12 @@ function scaffoldPlan(options2) {
|
|
|
55038
55106
|
mkdirSync2(dir, { recursive: true });
|
|
55039
55107
|
const resolvedPhases = resolvePhaseIds(options2.phases);
|
|
55040
55108
|
const optionsWithResolved = { ...options2, phases: resolvedPhases };
|
|
55041
|
-
const planFile =
|
|
55109
|
+
const planFile = join38(dir, "plan.md");
|
|
55042
55110
|
writeFileSync3(planFile, generatePlanMd(optionsWithResolved), "utf8");
|
|
55043
55111
|
const phaseFiles = [];
|
|
55044
55112
|
for (const phase of resolvedPhases) {
|
|
55045
55113
|
const filename = phaseNameToFilename(phase.id, phase.name);
|
|
55046
|
-
const phaseFile =
|
|
55114
|
+
const phaseFile = join38(dir, filename);
|
|
55047
55115
|
writeFileSync3(phaseFile, generatePhaseTemplate(phase), "utf8");
|
|
55048
55116
|
phaseFiles.push(phaseFile);
|
|
55049
55117
|
}
|
|
@@ -55123,7 +55191,7 @@ function phaseNameFilenameFromTableRow(body, phaseId, planDir) {
|
|
|
55123
55191
|
continue;
|
|
55124
55192
|
const linkMatch = /\[([^\]]+)\]\(\.\/([^)]+)\)/.exec(row);
|
|
55125
55193
|
if (linkMatch)
|
|
55126
|
-
return
|
|
55194
|
+
return join38(planDir, linkMatch[2]);
|
|
55127
55195
|
}
|
|
55128
55196
|
return null;
|
|
55129
55197
|
}
|
|
@@ -55204,7 +55272,7 @@ function addPhase(planFile, name, afterId) {
|
|
|
55204
55272
|
`);
|
|
55205
55273
|
}
|
|
55206
55274
|
writeFileSync3(planFile, import_gray_matter8.default.stringify(updatedBody, frontmatter), "utf8");
|
|
55207
|
-
const phaseFilePath =
|
|
55275
|
+
const phaseFilePath = join38(planDir, filename);
|
|
55208
55276
|
writeFileSync3(phaseFilePath, generatePhaseTemplate({ id: phaseId, name }), "utf8");
|
|
55209
55277
|
return { phaseId, phaseFile: phaseFilePath };
|
|
55210
55278
|
}
|
|
@@ -55368,8 +55436,8 @@ var init_plan_routes = __esm(() => {
|
|
|
55368
55436
|
// src/domains/web-server/routes/project-routes.ts
|
|
55369
55437
|
import { existsSync as existsSync29 } from "node:fs";
|
|
55370
55438
|
import { readFile as readFile22 } from "node:fs/promises";
|
|
55371
|
-
import { homedir as
|
|
55372
|
-
import { basename as basename13, join as
|
|
55439
|
+
import { homedir as homedir23 } from "node:os";
|
|
55440
|
+
import { basename as basename13, join as join39, resolve as resolve11 } from "node:path";
|
|
55373
55441
|
function registerProjectRoutes(app) {
|
|
55374
55442
|
app.get("/api/projects", async (req, res) => {
|
|
55375
55443
|
try {
|
|
@@ -55388,7 +55456,7 @@ function registerProjectRoutes(app) {
|
|
|
55388
55456
|
for (const discovered of discoveredProjects) {
|
|
55389
55457
|
if (registeredPaths.has(discovered.path))
|
|
55390
55458
|
continue;
|
|
55391
|
-
if (discovered.path ===
|
|
55459
|
+
if (discovered.path === join39(homedir23(), ".claude"))
|
|
55392
55460
|
continue;
|
|
55393
55461
|
const projectInfo = await detectAndBuildProjectInfo(discovered.path, `discovered-${discovered.path}`);
|
|
55394
55462
|
if (projectInfo) {
|
|
@@ -55404,7 +55472,7 @@ function registerProjectRoutes(app) {
|
|
|
55404
55472
|
if (cwdProject) {
|
|
55405
55473
|
projects.push(cwdProject);
|
|
55406
55474
|
}
|
|
55407
|
-
const globalDir =
|
|
55475
|
+
const globalDir = join39(homedir23(), ".claude");
|
|
55408
55476
|
const globalProject = await detectAndBuildProjectInfo(globalDir, "global");
|
|
55409
55477
|
if (globalProject) {
|
|
55410
55478
|
projects.push(globalProject);
|
|
@@ -55476,12 +55544,12 @@ function registerProjectRoutes(app) {
|
|
|
55476
55544
|
const body = validation.data;
|
|
55477
55545
|
let projectPath = body.path;
|
|
55478
55546
|
if (projectPath.startsWith("~/") || projectPath === "~") {
|
|
55479
|
-
projectPath =
|
|
55547
|
+
projectPath = join39(homedir23(), projectPath.slice(1));
|
|
55480
55548
|
} else if (projectPath.startsWith("~\\")) {
|
|
55481
|
-
projectPath =
|
|
55549
|
+
projectPath = join39(homedir23(), projectPath.slice(1));
|
|
55482
55550
|
}
|
|
55483
55551
|
projectPath = resolve11(projectPath);
|
|
55484
|
-
const homeDir =
|
|
55552
|
+
const homeDir = homedir23();
|
|
55485
55553
|
if (projectPath.includes("..") || !projectPath.startsWith(homeDir)) {
|
|
55486
55554
|
res.status(400).json({ error: "Invalid path after expansion" });
|
|
55487
55555
|
return;
|
|
@@ -55538,7 +55606,7 @@ function registerProjectRoutes(app) {
|
|
|
55538
55606
|
if (id === "current") {
|
|
55539
55607
|
projectPath = process.cwd();
|
|
55540
55608
|
} else if (id === "global") {
|
|
55541
|
-
projectPath =
|
|
55609
|
+
projectPath = join39(homedir23(), ".claude");
|
|
55542
55610
|
} else {
|
|
55543
55611
|
res.status(404).json({ error: "Project not found" });
|
|
55544
55612
|
return;
|
|
@@ -55600,8 +55668,8 @@ function registerProjectRoutes(app) {
|
|
|
55600
55668
|
});
|
|
55601
55669
|
}
|
|
55602
55670
|
async function buildProjectInfoFromRegistry(registered) {
|
|
55603
|
-
const claudeDir2 =
|
|
55604
|
-
const metadataPath =
|
|
55671
|
+
const claudeDir2 = join39(registered.path, ".claude");
|
|
55672
|
+
const metadataPath = join39(claudeDir2, "metadata.json");
|
|
55605
55673
|
if (!existsSync29(registered.path)) {
|
|
55606
55674
|
return null;
|
|
55607
55675
|
}
|
|
@@ -55618,7 +55686,7 @@ async function buildProjectInfoFromRegistry(registered) {
|
|
|
55618
55686
|
const hasLocalConfig = hasClaudeDir && CkConfigManager.projectConfigExists(registered.path, false);
|
|
55619
55687
|
const settings = await readSettings();
|
|
55620
55688
|
const skills = await scanSkills();
|
|
55621
|
-
const settingsPath =
|
|
55689
|
+
const settingsPath = join39(homedir23(), ".claude", "settings.json");
|
|
55622
55690
|
const health = existsSync29(settingsPath) ? "healthy" : "warning";
|
|
55623
55691
|
const model = getCurrentModel() || settings?.model || "claude-sonnet-4";
|
|
55624
55692
|
return {
|
|
@@ -55641,8 +55709,8 @@ async function buildProjectInfoFromRegistry(registered) {
|
|
|
55641
55709
|
};
|
|
55642
55710
|
}
|
|
55643
55711
|
async function detectAndBuildProjectInfo(path5, id) {
|
|
55644
|
-
const claudeDir2 = id === "global" ? path5 :
|
|
55645
|
-
const metadataPath =
|
|
55712
|
+
const claudeDir2 = id === "global" ? path5 : join39(path5, ".claude");
|
|
55713
|
+
const metadataPath = join39(claudeDir2, "metadata.json");
|
|
55646
55714
|
if (!existsSync29(metadataPath)) {
|
|
55647
55715
|
if (!existsSync29(claudeDir2)) {
|
|
55648
55716
|
return null;
|
|
@@ -55660,7 +55728,7 @@ async function detectAndBuildProjectInfo(path5, id) {
|
|
|
55660
55728
|
const hasLocalConfig = CkConfigManager.projectConfigExists(path5, id === "global");
|
|
55661
55729
|
const settings = await readSettings();
|
|
55662
55730
|
const skills = await scanSkills();
|
|
55663
|
-
const settingsPath =
|
|
55731
|
+
const settingsPath = join39(homedir23(), ".claude", "settings.json");
|
|
55664
55732
|
const health = existsSync29(settingsPath) ? "healthy" : "warning";
|
|
55665
55733
|
const model = getCurrentModel() || settings?.model || "claude-sonnet-4";
|
|
55666
55734
|
return {
|
|
@@ -55701,32 +55769,32 @@ var init_project_routes = __esm(() => {
|
|
|
55701
55769
|
});
|
|
55702
55770
|
|
|
55703
55771
|
// src/domains/web-server/routes/session-routes.ts
|
|
55704
|
-
import { homedir as
|
|
55705
|
-
import { join as
|
|
55772
|
+
import { homedir as homedir24 } from "node:os";
|
|
55773
|
+
import { join as join40 } from "node:path";
|
|
55706
55774
|
async function resolveSessionDir(projectId) {
|
|
55707
|
-
const home6 =
|
|
55775
|
+
const home6 = homedir24();
|
|
55708
55776
|
if (projectId.startsWith("discovered-")) {
|
|
55709
55777
|
try {
|
|
55710
55778
|
const encodedPathB64 = projectId.slice("discovered-".length);
|
|
55711
55779
|
const projectPath = Buffer.from(encodedPathB64, "base64url").toString("utf-8");
|
|
55712
55780
|
const claudeEncoded = encodePath(projectPath);
|
|
55713
|
-
return
|
|
55781
|
+
return join40(home6, ".claude", "projects", claudeEncoded);
|
|
55714
55782
|
} catch {
|
|
55715
55783
|
return null;
|
|
55716
55784
|
}
|
|
55717
55785
|
}
|
|
55718
55786
|
if (projectId === "current") {
|
|
55719
55787
|
const cwdEncoded = encodePath(process.cwd());
|
|
55720
|
-
return
|
|
55788
|
+
return join40(home6, ".claude", "projects", cwdEncoded);
|
|
55721
55789
|
}
|
|
55722
55790
|
if (projectId === "global") {
|
|
55723
|
-
const globalEncoded = encodePath(
|
|
55724
|
-
return
|
|
55791
|
+
const globalEncoded = encodePath(join40(home6, ".claude"));
|
|
55792
|
+
return join40(home6, ".claude", "projects", globalEncoded);
|
|
55725
55793
|
}
|
|
55726
55794
|
const registered = await ProjectsRegistryManager.getProject(projectId);
|
|
55727
55795
|
if (registered) {
|
|
55728
55796
|
const claudeEncoded = encodePath(registered.path);
|
|
55729
|
-
return
|
|
55797
|
+
return join40(home6, ".claude", "projects", claudeEncoded);
|
|
55730
55798
|
}
|
|
55731
55799
|
return null;
|
|
55732
55800
|
}
|
|
@@ -55743,7 +55811,7 @@ function registerSessionRoutes(app) {
|
|
|
55743
55811
|
res.status(404).json({ error: "Project not found" });
|
|
55744
55812
|
return;
|
|
55745
55813
|
}
|
|
55746
|
-
const allowedBase =
|
|
55814
|
+
const allowedBase = join40(homedir24(), ".claude", "projects");
|
|
55747
55815
|
if (!projectDir.startsWith(allowedBase)) {
|
|
55748
55816
|
res.status(403).json({ error: "Access denied" });
|
|
55749
55817
|
return;
|
|
@@ -55765,7 +55833,7 @@ var init_session_routes = __esm(() => {
|
|
|
55765
55833
|
});
|
|
55766
55834
|
|
|
55767
55835
|
// src/domains/web-server/routes/settings-routes.ts
|
|
55768
|
-
import { homedir as
|
|
55836
|
+
import { homedir as homedir25 } from "node:os";
|
|
55769
55837
|
function registerSettingsRoutes(app) {
|
|
55770
55838
|
app.get("/api/settings", async (_req, res) => {
|
|
55771
55839
|
try {
|
|
@@ -55821,7 +55889,7 @@ function registerSettingsRoutes(app) {
|
|
|
55821
55889
|
res.json({
|
|
55822
55890
|
success: true,
|
|
55823
55891
|
path: "~/.claude/settings.json",
|
|
55824
|
-
backupPath: saveResult.backupPath ? saveResult.backupPath.replace(
|
|
55892
|
+
backupPath: saveResult.backupPath ? saveResult.backupPath.replace(homedir25(), "~") : null,
|
|
55825
55893
|
absolutePath: getSettingsPath()
|
|
55826
55894
|
});
|
|
55827
55895
|
} catch (error) {
|
|
@@ -55855,8 +55923,8 @@ var init_settings_routes = __esm(() => {
|
|
|
55855
55923
|
|
|
55856
55924
|
// src/commands/skills/agents.ts
|
|
55857
55925
|
import { existsSync as existsSync30 } from "node:fs";
|
|
55858
|
-
import { homedir as
|
|
55859
|
-
import { join as
|
|
55926
|
+
import { homedir as homedir26 } from "node:os";
|
|
55927
|
+
import { join as join41 } from "node:path";
|
|
55860
55928
|
async function detectInstalledAgents() {
|
|
55861
55929
|
const installed = [];
|
|
55862
55930
|
for (const [type, config] of Object.entries(agents)) {
|
|
@@ -55872,7 +55940,7 @@ function getAgentConfig(type) {
|
|
|
55872
55940
|
function getInstallPath(skillName, agent, options2) {
|
|
55873
55941
|
const config = agents[agent];
|
|
55874
55942
|
const basePath = options2.global ? config.globalPath : config.projectPath;
|
|
55875
|
-
return
|
|
55943
|
+
return join41(basePath, skillName);
|
|
55876
55944
|
}
|
|
55877
55945
|
function isSkillInstalled(skillName, agent, options2) {
|
|
55878
55946
|
const installPath = getInstallPath(skillName, agent, options2);
|
|
@@ -55880,105 +55948,105 @@ function isSkillInstalled(skillName, agent, options2) {
|
|
|
55880
55948
|
}
|
|
55881
55949
|
var home6, agents;
|
|
55882
55950
|
var init_agents = __esm(() => {
|
|
55883
|
-
home6 =
|
|
55951
|
+
home6 = homedir26();
|
|
55884
55952
|
agents = {
|
|
55885
55953
|
"claude-code": {
|
|
55886
55954
|
name: "claude-code",
|
|
55887
55955
|
displayName: "Claude Code",
|
|
55888
55956
|
projectPath: ".claude/skills",
|
|
55889
|
-
globalPath:
|
|
55890
|
-
detect: async () => existsSync30(
|
|
55957
|
+
globalPath: join41(home6, ".claude/skills"),
|
|
55958
|
+
detect: async () => existsSync30(join41(home6, ".claude"))
|
|
55891
55959
|
},
|
|
55892
55960
|
cursor: {
|
|
55893
55961
|
name: "cursor",
|
|
55894
55962
|
displayName: "Cursor",
|
|
55895
55963
|
projectPath: ".cursor/skills",
|
|
55896
|
-
globalPath:
|
|
55897
|
-
detect: async () => existsSync30(
|
|
55964
|
+
globalPath: join41(home6, ".cursor/skills"),
|
|
55965
|
+
detect: async () => existsSync30(join41(home6, ".cursor"))
|
|
55898
55966
|
},
|
|
55899
55967
|
codex: {
|
|
55900
55968
|
name: "codex",
|
|
55901
55969
|
displayName: "Codex",
|
|
55902
55970
|
projectPath: ".codex/skills",
|
|
55903
|
-
globalPath:
|
|
55904
|
-
detect: async () => existsSync30(
|
|
55971
|
+
globalPath: join41(home6, ".codex/skills"),
|
|
55972
|
+
detect: async () => existsSync30(join41(home6, ".codex"))
|
|
55905
55973
|
},
|
|
55906
55974
|
opencode: {
|
|
55907
55975
|
name: "opencode",
|
|
55908
55976
|
displayName: "OpenCode",
|
|
55909
55977
|
projectPath: ".opencode/skills",
|
|
55910
|
-
globalPath:
|
|
55911
|
-
detect: async () => existsSync30(
|
|
55978
|
+
globalPath: join41(home6, ".config/opencode/skills"),
|
|
55979
|
+
detect: async () => existsSync30(join41(home6, ".config/opencode"))
|
|
55912
55980
|
},
|
|
55913
55981
|
goose: {
|
|
55914
55982
|
name: "goose",
|
|
55915
55983
|
displayName: "Goose",
|
|
55916
55984
|
projectPath: ".goose/skills",
|
|
55917
|
-
globalPath:
|
|
55918
|
-
detect: async () => existsSync30(
|
|
55985
|
+
globalPath: join41(home6, ".config/goose/skills"),
|
|
55986
|
+
detect: async () => existsSync30(join41(home6, ".config/goose"))
|
|
55919
55987
|
},
|
|
55920
55988
|
"gemini-cli": {
|
|
55921
55989
|
name: "gemini-cli",
|
|
55922
55990
|
displayName: "Gemini CLI",
|
|
55923
55991
|
projectPath: ".agents/skills",
|
|
55924
|
-
globalPath:
|
|
55925
|
-
detect: async () => existsSync30(
|
|
55992
|
+
globalPath: join41(home6, ".agents/skills"),
|
|
55993
|
+
detect: async () => existsSync30(join41(home6, ".gemini"))
|
|
55926
55994
|
},
|
|
55927
55995
|
antigravity: {
|
|
55928
55996
|
name: "antigravity",
|
|
55929
55997
|
displayName: "Antigravity",
|
|
55930
55998
|
projectPath: ".agent/skills",
|
|
55931
|
-
globalPath:
|
|
55932
|
-
detect: async () => existsSync30(
|
|
55999
|
+
globalPath: join41(home6, ".gemini/antigravity/skills"),
|
|
56000
|
+
detect: async () => existsSync30(join41(process.cwd(), ".agent")) || existsSync30(join41(home6, ".gemini/antigravity"))
|
|
55933
56001
|
},
|
|
55934
56002
|
"github-copilot": {
|
|
55935
56003
|
name: "github-copilot",
|
|
55936
56004
|
displayName: "GitHub Copilot",
|
|
55937
56005
|
projectPath: ".github/skills",
|
|
55938
|
-
globalPath:
|
|
55939
|
-
detect: async () => existsSync30(
|
|
56006
|
+
globalPath: join41(home6, ".copilot/skills"),
|
|
56007
|
+
detect: async () => existsSync30(join41(home6, ".copilot"))
|
|
55940
56008
|
},
|
|
55941
56009
|
amp: {
|
|
55942
56010
|
name: "amp",
|
|
55943
56011
|
displayName: "Amp",
|
|
55944
56012
|
projectPath: ".agents/skills",
|
|
55945
|
-
globalPath:
|
|
55946
|
-
detect: async () => existsSync30(
|
|
56013
|
+
globalPath: join41(home6, ".config/agents/skills"),
|
|
56014
|
+
detect: async () => existsSync30(join41(home6, ".config/amp"))
|
|
55947
56015
|
},
|
|
55948
56016
|
kilo: {
|
|
55949
56017
|
name: "kilo",
|
|
55950
56018
|
displayName: "Kilo Code",
|
|
55951
56019
|
projectPath: ".kilocode/skills",
|
|
55952
|
-
globalPath:
|
|
55953
|
-
detect: async () => existsSync30(
|
|
56020
|
+
globalPath: join41(home6, ".kilocode/skills"),
|
|
56021
|
+
detect: async () => existsSync30(join41(home6, ".kilocode"))
|
|
55954
56022
|
},
|
|
55955
56023
|
roo: {
|
|
55956
56024
|
name: "roo",
|
|
55957
56025
|
displayName: "Roo Code",
|
|
55958
56026
|
projectPath: ".roo/skills",
|
|
55959
|
-
globalPath:
|
|
55960
|
-
detect: async () => existsSync30(
|
|
56027
|
+
globalPath: join41(home6, ".roo/skills"),
|
|
56028
|
+
detect: async () => existsSync30(join41(home6, ".roo"))
|
|
55961
56029
|
},
|
|
55962
56030
|
windsurf: {
|
|
55963
56031
|
name: "windsurf",
|
|
55964
56032
|
displayName: "Windsurf",
|
|
55965
56033
|
projectPath: ".windsurf/skills",
|
|
55966
|
-
globalPath:
|
|
55967
|
-
detect: async () => existsSync30(
|
|
56034
|
+
globalPath: join41(home6, ".codeium/windsurf/skills"),
|
|
56035
|
+
detect: async () => existsSync30(join41(home6, ".codeium/windsurf"))
|
|
55968
56036
|
},
|
|
55969
56037
|
cline: {
|
|
55970
56038
|
name: "cline",
|
|
55971
56039
|
displayName: "Cline",
|
|
55972
56040
|
projectPath: ".cline/skills",
|
|
55973
|
-
globalPath:
|
|
55974
|
-
detect: async () => existsSync30(
|
|
56041
|
+
globalPath: join41(home6, ".cline/skills"),
|
|
56042
|
+
detect: async () => existsSync30(join41(home6, ".cline"))
|
|
55975
56043
|
},
|
|
55976
56044
|
openhands: {
|
|
55977
56045
|
name: "openhands",
|
|
55978
56046
|
displayName: "OpenHands",
|
|
55979
56047
|
projectPath: ".openhands/skills",
|
|
55980
|
-
globalPath:
|
|
55981
|
-
detect: async () => existsSync30(
|
|
56048
|
+
globalPath: join41(home6, ".openhands/skills"),
|
|
56049
|
+
detect: async () => existsSync30(join41(home6, ".openhands"))
|
|
55982
56050
|
}
|
|
55983
56051
|
};
|
|
55984
56052
|
});
|
|
@@ -55986,8 +56054,8 @@ var init_agents = __esm(() => {
|
|
|
55986
56054
|
// src/commands/skills/skills-registry.ts
|
|
55987
56055
|
import { existsSync as existsSync31 } from "node:fs";
|
|
55988
56056
|
import { mkdir as mkdir9, readFile as readFile23, writeFile as writeFile11 } from "node:fs/promises";
|
|
55989
|
-
import { homedir as
|
|
55990
|
-
import { dirname as dirname16, join as
|
|
56057
|
+
import { homedir as homedir27 } from "node:os";
|
|
56058
|
+
import { dirname as dirname16, join as join42, sep as sep5 } from "node:path";
|
|
55991
56059
|
function getCliVersion3() {
|
|
55992
56060
|
try {
|
|
55993
56061
|
if (process.env.npm_package_version) {
|
|
@@ -56098,8 +56166,8 @@ async function syncRegistry() {
|
|
|
56098
56166
|
var home7, REGISTRY_PATH2, SkillInstallationSchema, SkillRegistrySchema, REGISTRY_PATH_MIGRATIONS;
|
|
56099
56167
|
var init_skills_registry = __esm(() => {
|
|
56100
56168
|
init_zod();
|
|
56101
|
-
home7 =
|
|
56102
|
-
REGISTRY_PATH2 =
|
|
56169
|
+
home7 = homedir27();
|
|
56170
|
+
REGISTRY_PATH2 = join42(home7, ".claudekit", "skill-registry.json");
|
|
56103
56171
|
SkillInstallationSchema = exports_external.object({
|
|
56104
56172
|
skill: exports_external.string(),
|
|
56105
56173
|
agent: exports_external.string(),
|
|
@@ -56130,8 +56198,8 @@ var init_skills_registry = __esm(() => {
|
|
|
56130
56198
|
// src/commands/skills/skills-installer.ts
|
|
56131
56199
|
import { existsSync as existsSync32 } from "node:fs";
|
|
56132
56200
|
import { cp as cp2, mkdir as mkdir10, rm as rm7, stat as stat7 } from "node:fs/promises";
|
|
56133
|
-
import { homedir as
|
|
56134
|
-
import { dirname as dirname17, join as
|
|
56201
|
+
import { homedir as homedir28 } from "node:os";
|
|
56202
|
+
import { dirname as dirname17, join as join43, resolve as resolve12 } from "node:path";
|
|
56135
56203
|
function isSamePath2(path1, path22) {
|
|
56136
56204
|
try {
|
|
56137
56205
|
return resolve12(path1) === resolve12(path22);
|
|
@@ -56163,7 +56231,7 @@ async function cleanupLegacySkillPath(skillName, agent, global3) {
|
|
|
56163
56231
|
if (!legacy)
|
|
56164
56232
|
return;
|
|
56165
56233
|
const legacyBase = global3 ? legacy.global : legacy.project;
|
|
56166
|
-
const legacyPath =
|
|
56234
|
+
const legacyPath = join43(legacyBase, skillName);
|
|
56167
56235
|
if (!existsSync32(legacyPath))
|
|
56168
56236
|
return;
|
|
56169
56237
|
await rm7(legacyPath, { recursive: true, force: true });
|
|
@@ -56173,7 +56241,7 @@ async function cleanupLegacySkillPath(skillName, agent, global3) {
|
|
|
56173
56241
|
if (entry.skill === skillName && entry.agent === agent && entry.global === global3) {
|
|
56174
56242
|
if (entry.path === legacyPath) {
|
|
56175
56243
|
const newBase = global3 ? agents[agent].globalPath : agents[agent].projectPath;
|
|
56176
|
-
entry.path =
|
|
56244
|
+
entry.path = join43(newBase, skillName);
|
|
56177
56245
|
changed = true;
|
|
56178
56246
|
}
|
|
56179
56247
|
}
|
|
@@ -56261,7 +56329,7 @@ var init_skills_installer = __esm(() => {
|
|
|
56261
56329
|
LEGACY_SKILL_PATHS = {
|
|
56262
56330
|
"gemini-cli": {
|
|
56263
56331
|
project: ".gemini/skills",
|
|
56264
|
-
global:
|
|
56332
|
+
global: join43(homedir28(), ".gemini/skills")
|
|
56265
56333
|
}
|
|
56266
56334
|
};
|
|
56267
56335
|
});
|
|
@@ -56269,7 +56337,7 @@ var init_skills_installer = __esm(() => {
|
|
|
56269
56337
|
// src/commands/skills/skills-uninstaller.ts
|
|
56270
56338
|
import { existsSync as existsSync33 } from "node:fs";
|
|
56271
56339
|
import { rm as rm8 } from "node:fs/promises";
|
|
56272
|
-
import { join as
|
|
56340
|
+
import { join as join44 } from "node:path";
|
|
56273
56341
|
async function uninstallSkillFromAgent(skill, agent, global3) {
|
|
56274
56342
|
const agentConfig = agents[agent];
|
|
56275
56343
|
const registry = await readRegistry();
|
|
@@ -56317,7 +56385,7 @@ async function uninstallSkillFromAgent(skill, agent, global3) {
|
|
|
56317
56385
|
async function forceUninstallSkill(skill, agent, global3) {
|
|
56318
56386
|
const agentConfig = agents[agent];
|
|
56319
56387
|
const basePath = global3 ? agentConfig.globalPath : agentConfig.projectPath;
|
|
56320
|
-
const path5 =
|
|
56388
|
+
const path5 = join44(basePath, skill);
|
|
56321
56389
|
if (!existsSync33(path5)) {
|
|
56322
56390
|
return {
|
|
56323
56391
|
skill,
|
|
@@ -56861,7 +56929,7 @@ var init_pnpm_detector = __esm(() => {
|
|
|
56861
56929
|
import { existsSync as existsSync34, realpathSync as realpathSync2 } from "node:fs";
|
|
56862
56930
|
import { chmod as chmod2, mkdir as mkdir11, readFile as readFile24, writeFile as writeFile12 } from "node:fs/promises";
|
|
56863
56931
|
import { platform as platform4 } from "node:os";
|
|
56864
|
-
import { join as
|
|
56932
|
+
import { join as join45 } from "node:path";
|
|
56865
56933
|
function detectFromBinaryPath() {
|
|
56866
56934
|
const normalizePath2 = (pathValue) => pathValue.replace(/\\/g, "/").toLowerCase();
|
|
56867
56935
|
const detectFromNormalizedPath = (normalized) => {
|
|
@@ -56938,7 +57006,7 @@ function detectFromEnv() {
|
|
|
56938
57006
|
}
|
|
56939
57007
|
async function readCachedPm() {
|
|
56940
57008
|
try {
|
|
56941
|
-
const cacheFile =
|
|
57009
|
+
const cacheFile = join45(PathResolver.getConfigDir(false), CACHE_FILE);
|
|
56942
57010
|
if (!existsSync34(cacheFile)) {
|
|
56943
57011
|
return null;
|
|
56944
57012
|
}
|
|
@@ -56969,7 +57037,7 @@ async function saveCachedPm(pm, getVersion) {
|
|
|
56969
57037
|
return;
|
|
56970
57038
|
try {
|
|
56971
57039
|
const configDir = PathResolver.getConfigDir(false);
|
|
56972
|
-
const cacheFile =
|
|
57040
|
+
const cacheFile = join45(configDir, CACHE_FILE);
|
|
56973
57041
|
if (!existsSync34(configDir)) {
|
|
56974
57042
|
await mkdir11(configDir, { recursive: true });
|
|
56975
57043
|
if (platform4() !== "win32") {
|
|
@@ -57032,7 +57100,7 @@ async function findOwningPm() {
|
|
|
57032
57100
|
async function clearCache() {
|
|
57033
57101
|
try {
|
|
57034
57102
|
const { unlink: unlink6 } = await import("node:fs/promises");
|
|
57035
|
-
const cacheFile =
|
|
57103
|
+
const cacheFile = join45(PathResolver.getConfigDir(false), CACHE_FILE);
|
|
57036
57104
|
if (existsSync34(cacheFile)) {
|
|
57037
57105
|
await unlink6(cacheFile);
|
|
57038
57106
|
logger.debug("Package manager cache cleared");
|
|
@@ -57189,9 +57257,9 @@ var init_package_manager_detector = __esm(() => {
|
|
|
57189
57257
|
});
|
|
57190
57258
|
|
|
57191
57259
|
// src/domains/migration/metadata-migration.ts
|
|
57192
|
-
import { join as
|
|
57260
|
+
import { join as join46 } from "node:path";
|
|
57193
57261
|
async function detectMetadataFormat(claudeDir2) {
|
|
57194
|
-
const metadataPath =
|
|
57262
|
+
const metadataPath = join46(claudeDir2, "metadata.json");
|
|
57195
57263
|
if (!await import_fs_extra3.pathExists(metadataPath)) {
|
|
57196
57264
|
return { format: "none", metadata: null, detectedKit: null };
|
|
57197
57265
|
}
|
|
@@ -57243,7 +57311,7 @@ async function migrateToMultiKit(claudeDir2) {
|
|
|
57243
57311
|
toFormat: "multi-kit"
|
|
57244
57312
|
};
|
|
57245
57313
|
}
|
|
57246
|
-
const metadataPath =
|
|
57314
|
+
const metadataPath = join46(claudeDir2, "metadata.json");
|
|
57247
57315
|
const legacy = detection.metadata;
|
|
57248
57316
|
if (!legacy) {
|
|
57249
57317
|
return {
|
|
@@ -57526,7 +57594,7 @@ var init_version_utils = __esm(() => {
|
|
|
57526
57594
|
});
|
|
57527
57595
|
|
|
57528
57596
|
// src/services/file-operations/claudekit-scanner.ts
|
|
57529
|
-
import { join as
|
|
57597
|
+
import { join as join47 } from "node:path";
|
|
57530
57598
|
async function scanClaudeKitDirectory(directoryPath) {
|
|
57531
57599
|
const counts = {
|
|
57532
57600
|
agents: 0,
|
|
@@ -57540,33 +57608,33 @@ async function scanClaudeKitDirectory(directoryPath) {
|
|
|
57540
57608
|
}
|
|
57541
57609
|
const items = await import_fs_extra4.readdir(directoryPath);
|
|
57542
57610
|
if (items.includes("agents")) {
|
|
57543
|
-
const agentsPath =
|
|
57611
|
+
const agentsPath = join47(directoryPath, "agents");
|
|
57544
57612
|
const agentFiles = await import_fs_extra4.readdir(agentsPath);
|
|
57545
57613
|
counts.agents = agentFiles.filter((file) => file.endsWith(".md")).length;
|
|
57546
57614
|
}
|
|
57547
57615
|
if (items.includes("commands")) {
|
|
57548
|
-
const commandsPath =
|
|
57616
|
+
const commandsPath = join47(directoryPath, "commands");
|
|
57549
57617
|
const commandFiles = await import_fs_extra4.readdir(commandsPath);
|
|
57550
57618
|
counts.commands = commandFiles.filter((file) => file.endsWith(".md")).length;
|
|
57551
57619
|
}
|
|
57552
57620
|
if (items.includes("rules")) {
|
|
57553
|
-
const rulesPath =
|
|
57621
|
+
const rulesPath = join47(directoryPath, "rules");
|
|
57554
57622
|
const ruleFiles = await import_fs_extra4.readdir(rulesPath);
|
|
57555
57623
|
counts.rules = ruleFiles.filter((file) => file.endsWith(".md")).length;
|
|
57556
57624
|
} else if (items.includes("workflows")) {
|
|
57557
|
-
const workflowsPath =
|
|
57625
|
+
const workflowsPath = join47(directoryPath, "workflows");
|
|
57558
57626
|
const workflowFiles = await import_fs_extra4.readdir(workflowsPath);
|
|
57559
57627
|
counts.rules = workflowFiles.filter((file) => file.endsWith(".md")).length;
|
|
57560
57628
|
}
|
|
57561
57629
|
if (items.includes("skills")) {
|
|
57562
|
-
const skillsPath =
|
|
57630
|
+
const skillsPath = join47(directoryPath, "skills");
|
|
57563
57631
|
const skillItems = await import_fs_extra4.readdir(skillsPath);
|
|
57564
57632
|
let skillCount = 0;
|
|
57565
57633
|
for (const item of skillItems) {
|
|
57566
57634
|
if (SKIP_DIRS_CLAUDE_INTERNAL.includes(item)) {
|
|
57567
57635
|
continue;
|
|
57568
57636
|
}
|
|
57569
|
-
const itemPath =
|
|
57637
|
+
const itemPath = join47(skillsPath, item);
|
|
57570
57638
|
const stat8 = await import_fs_extra4.readdir(itemPath).catch(() => null);
|
|
57571
57639
|
if (stat8?.includes("SKILL.md")) {
|
|
57572
57640
|
skillCount++;
|
|
@@ -57608,14 +57676,14 @@ async function getClaudeKitSetup(projectDir = process.cwd()) {
|
|
|
57608
57676
|
const globalDir = getGlobalInstallDir();
|
|
57609
57677
|
if (await import_fs_extra4.pathExists(globalDir)) {
|
|
57610
57678
|
setup.global.path = globalDir;
|
|
57611
|
-
setup.global.metadata = await readClaudeKitMetadata(
|
|
57679
|
+
setup.global.metadata = await readClaudeKitMetadata(join47(globalDir, "metadata.json"));
|
|
57612
57680
|
setup.global.components = await scanClaudeKitDirectory(globalDir);
|
|
57613
57681
|
}
|
|
57614
|
-
const projectClaudeDir =
|
|
57682
|
+
const projectClaudeDir = join47(projectDir, ".claude");
|
|
57615
57683
|
const isLocalSameAsGlobal = projectClaudeDir === globalDir;
|
|
57616
57684
|
if (!isLocalSameAsGlobal && await import_fs_extra4.pathExists(projectClaudeDir)) {
|
|
57617
57685
|
setup.project.path = projectClaudeDir;
|
|
57618
|
-
setup.project.metadata = await readClaudeKitMetadata(
|
|
57686
|
+
setup.project.metadata = await readClaudeKitMetadata(join47(projectClaudeDir, "metadata.json"));
|
|
57619
57687
|
setup.project.components = await scanClaudeKitDirectory(projectClaudeDir);
|
|
57620
57688
|
}
|
|
57621
57689
|
return setup;
|
|
@@ -57632,7 +57700,7 @@ var package_default;
|
|
|
57632
57700
|
var init_package = __esm(() => {
|
|
57633
57701
|
package_default = {
|
|
57634
57702
|
name: "claudekit-cli",
|
|
57635
|
-
version: "3.41.
|
|
57703
|
+
version: "3.41.4",
|
|
57636
57704
|
description: "CLI tool for bootstrapping and updating ClaudeKit projects",
|
|
57637
57705
|
type: "module",
|
|
57638
57706
|
repository: {
|
|
@@ -58184,7 +58252,7 @@ var init_error_handler2 = __esm(() => {
|
|
|
58184
58252
|
// src/domains/versioning/release-cache.ts
|
|
58185
58253
|
import { existsSync as existsSync35 } from "node:fs";
|
|
58186
58254
|
import { mkdir as mkdir12, readFile as readFile27, unlink as unlink6, writeFile as writeFile14 } from "node:fs/promises";
|
|
58187
|
-
import { join as
|
|
58255
|
+
import { join as join48 } from "node:path";
|
|
58188
58256
|
var ReleaseCacheEntrySchema, ReleaseCache;
|
|
58189
58257
|
var init_release_cache = __esm(() => {
|
|
58190
58258
|
init_logger();
|
|
@@ -58199,7 +58267,7 @@ var init_release_cache = __esm(() => {
|
|
|
58199
58267
|
static CACHE_TTL_SECONDS = Number(process.env.CK_CACHE_TTL) || 3600;
|
|
58200
58268
|
cacheDir;
|
|
58201
58269
|
constructor() {
|
|
58202
|
-
this.cacheDir =
|
|
58270
|
+
this.cacheDir = join48(PathResolver.getCacheDir(false), ReleaseCache.CACHE_DIR);
|
|
58203
58271
|
}
|
|
58204
58272
|
async get(key) {
|
|
58205
58273
|
const cacheFile = this.getCachePath(key);
|
|
@@ -58257,7 +58325,7 @@ var init_release_cache = __esm(() => {
|
|
|
58257
58325
|
const files = await readdir10(this.cacheDir);
|
|
58258
58326
|
for (const file of files) {
|
|
58259
58327
|
if (file.endsWith(".json")) {
|
|
58260
|
-
await unlink6(
|
|
58328
|
+
await unlink6(join48(this.cacheDir, file));
|
|
58261
58329
|
}
|
|
58262
58330
|
}
|
|
58263
58331
|
logger.debug("All release cache cleared");
|
|
@@ -58268,7 +58336,7 @@ var init_release_cache = __esm(() => {
|
|
|
58268
58336
|
}
|
|
58269
58337
|
getCachePath(key) {
|
|
58270
58338
|
const safeKey = key.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
58271
|
-
return
|
|
58339
|
+
return join48(this.cacheDir, `${safeKey}.json`);
|
|
58272
58340
|
}
|
|
58273
58341
|
isExpired(timestamp) {
|
|
58274
58342
|
const now = Date.now();
|
|
@@ -58909,7 +58977,7 @@ var init_github_client = __esm(() => {
|
|
|
58909
58977
|
|
|
58910
58978
|
// src/commands/update-cli.ts
|
|
58911
58979
|
import { exec as exec2, spawn as spawn2 } from "node:child_process";
|
|
58912
|
-
import { join as
|
|
58980
|
+
import { join as join49 } from "node:path";
|
|
58913
58981
|
import { promisify as promisify8 } from "node:util";
|
|
58914
58982
|
function getDefaultUpdateCliCommandDeps() {
|
|
58915
58983
|
return {
|
|
@@ -58989,7 +59057,7 @@ function selectKitForUpdate(params) {
|
|
|
58989
59057
|
};
|
|
58990
59058
|
}
|
|
58991
59059
|
async function readMetadataFile(claudeDir2) {
|
|
58992
|
-
const metadataPath =
|
|
59060
|
+
const metadataPath = join49(claudeDir2, "metadata.json");
|
|
58993
59061
|
try {
|
|
58994
59062
|
if (!await import_fs_extra5.pathExists(metadataPath)) {
|
|
58995
59063
|
return null;
|
|
@@ -59411,7 +59479,7 @@ var init_update_cli = __esm(() => {
|
|
|
59411
59479
|
// src/domains/versioning/version-cache.ts
|
|
59412
59480
|
import { existsSync as existsSync36 } from "node:fs";
|
|
59413
59481
|
import { mkdir as mkdir13, readFile as readFile29, writeFile as writeFile15 } from "node:fs/promises";
|
|
59414
|
-
import { join as
|
|
59482
|
+
import { join as join50 } from "node:path";
|
|
59415
59483
|
var VersionCacheManager;
|
|
59416
59484
|
var init_version_cache = __esm(() => {
|
|
59417
59485
|
init_logger();
|
|
@@ -59421,7 +59489,7 @@ var init_version_cache = __esm(() => {
|
|
|
59421
59489
|
static CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000;
|
|
59422
59490
|
static getCacheFile() {
|
|
59423
59491
|
const cacheDir = PathResolver.getCacheDir(false);
|
|
59424
|
-
return
|
|
59492
|
+
return join50(cacheDir, VersionCacheManager.CACHE_FILENAME);
|
|
59425
59493
|
}
|
|
59426
59494
|
static async load() {
|
|
59427
59495
|
const cacheFile = VersionCacheManager.getCacheFile();
|
|
@@ -59690,7 +59758,7 @@ var init_version_checker = __esm(() => {
|
|
|
59690
59758
|
import { spawn as spawn3 } from "node:child_process";
|
|
59691
59759
|
import { existsSync as existsSync37 } from "node:fs";
|
|
59692
59760
|
import { readFile as readFile30 } from "node:fs/promises";
|
|
59693
|
-
import { join as
|
|
59761
|
+
import { join as join51 } from "node:path";
|
|
59694
59762
|
function hasCliUpdate(currentVersion, latestVersion) {
|
|
59695
59763
|
if (!latestVersion) {
|
|
59696
59764
|
return false;
|
|
@@ -59933,7 +60001,7 @@ async function getPackageJson() {
|
|
|
59933
60001
|
}
|
|
59934
60002
|
async function getKitMetadata2(kitName) {
|
|
59935
60003
|
try {
|
|
59936
|
-
const metadataPath =
|
|
60004
|
+
const metadataPath = join51(PathResolver.getGlobalKitDir(), "metadata.json");
|
|
59937
60005
|
if (!existsSync37(metadataPath))
|
|
59938
60006
|
return null;
|
|
59939
60007
|
const content = await readFile30(metadataPath, "utf-8");
|
|
@@ -60080,7 +60148,7 @@ var init_routes = __esm(() => {
|
|
|
60080
60148
|
|
|
60081
60149
|
// src/domains/web-server/static-server.ts
|
|
60082
60150
|
import { existsSync as existsSync38 } from "node:fs";
|
|
60083
|
-
import { dirname as dirname18, join as
|
|
60151
|
+
import { dirname as dirname18, join as join52, resolve as resolve13 } from "node:path";
|
|
60084
60152
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
60085
60153
|
function addRuntimeUiCandidate(candidates, runtimePath) {
|
|
60086
60154
|
if (!runtimePath) {
|
|
@@ -60091,21 +60159,21 @@ function addRuntimeUiCandidate(candidates, runtimePath) {
|
|
|
60091
60159
|
return;
|
|
60092
60160
|
}
|
|
60093
60161
|
const entryDir = dirname18(resolve13(runtimePath));
|
|
60094
|
-
candidates.add(
|
|
60095
|
-
candidates.add(
|
|
60162
|
+
candidates.add(join52(entryDir, "ui"));
|
|
60163
|
+
candidates.add(join52(entryDir, "..", "dist", "ui"));
|
|
60096
60164
|
}
|
|
60097
60165
|
function resolveUiDistPath() {
|
|
60098
60166
|
const candidates = new Set;
|
|
60099
60167
|
addRuntimeUiCandidate(candidates, process.argv[1]);
|
|
60100
|
-
candidates.add(
|
|
60101
|
-
candidates.add(
|
|
60102
|
-
candidates.add(
|
|
60168
|
+
candidates.add(join52(__dirname3, "ui"));
|
|
60169
|
+
candidates.add(join52(process.cwd(), "dist", "ui"));
|
|
60170
|
+
candidates.add(join52(process.cwd(), "src", "ui", "dist"));
|
|
60103
60171
|
for (const path5 of candidates) {
|
|
60104
|
-
if (existsSync38(
|
|
60172
|
+
if (existsSync38(join52(path5, "index.html"))) {
|
|
60105
60173
|
return path5;
|
|
60106
60174
|
}
|
|
60107
60175
|
}
|
|
60108
|
-
return Array.from(candidates)[0] ??
|
|
60176
|
+
return Array.from(candidates)[0] ?? join52(process.cwd(), "dist", "ui");
|
|
60109
60177
|
}
|
|
60110
60178
|
function serveStatic(app) {
|
|
60111
60179
|
const uiDistPath = resolveUiDistPath();
|
|
@@ -60141,7 +60209,7 @@ function serveStatic(app) {
|
|
|
60141
60209
|
if (req.path.startsWith("/assets/") || req.path.match(/\.(js|css|ico|png|jpg|svg|woff2?)$/)) {
|
|
60142
60210
|
return next();
|
|
60143
60211
|
}
|
|
60144
|
-
res.sendFile(
|
|
60212
|
+
res.sendFile(join52(uiDistPath, "index.html"), { dotfiles: "allow" });
|
|
60145
60213
|
});
|
|
60146
60214
|
logger.debug(`Serving static files from ${uiDistPath}`);
|
|
60147
60215
|
}
|
|
@@ -64990,7 +65058,7 @@ function getNpmLookupTimeoutMs() {
|
|
|
64990
65058
|
function getNpmInstallTimeoutMs() {
|
|
64991
65059
|
return parseTimeoutMs(process.env.CK_NPM_INSTALL_TIMEOUT_MS, DEFAULT_NPM_INSTALL_TIMEOUT_MS, MIN_NPM_TIMEOUT_MS, MAX_NPM_TIMEOUT_MS);
|
|
64992
65060
|
}
|
|
64993
|
-
function
|
|
65061
|
+
function escapeRegex2(value) {
|
|
64994
65062
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
64995
65063
|
}
|
|
64996
65064
|
async function isPackageInstalled(packageName) {
|
|
@@ -65022,7 +65090,7 @@ async function isPackageInstalled(packageName) {
|
|
|
65022
65090
|
const { stdout: stdout2 } = await execAsync7(`${getNpmCommand()} list -g ${packageName} --depth=0`, {
|
|
65023
65091
|
timeout: getNpmLookupTimeoutMs()
|
|
65024
65092
|
});
|
|
65025
|
-
const exactPattern = new RegExp(`(?:^|\\s|[├└│─]+)${
|
|
65093
|
+
const exactPattern = new RegExp(`(?:^|\\s|[├└│─]+)${escapeRegex2(packageName)}@([^\\s\\n]+)(?:\\s|$)`, "m");
|
|
65026
65094
|
return exactPattern.test(stdout2);
|
|
65027
65095
|
} catch {
|
|
65028
65096
|
return false;
|
|
@@ -65068,8 +65136,8 @@ async function getPackageVersion(packageName) {
|
|
|
65068
65136
|
timeout: getNpmLookupTimeoutMs()
|
|
65069
65137
|
});
|
|
65070
65138
|
const patterns = [
|
|
65071
|
-
new RegExp(`${
|
|
65072
|
-
new RegExp(`${
|
|
65139
|
+
new RegExp(`${escapeRegex2(packageName)}@([^\\s\\n]+)`),
|
|
65140
|
+
new RegExp(`${escapeRegex2(packageName)}@([0-9]+\\.[0-9]+\\.[0-9]+(?:-[\\w.-]+)?)`)
|
|
65073
65141
|
];
|
|
65074
65142
|
for (const pattern of patterns) {
|
|
65075
65143
|
const match = stdout2.match(pattern);
|
|
@@ -65148,7 +65216,7 @@ var init_gemini_installer = __esm(() => {
|
|
|
65148
65216
|
});
|
|
65149
65217
|
|
|
65150
65218
|
// src/services/package-installer/opencode-installer.ts
|
|
65151
|
-
import { join as
|
|
65219
|
+
import { join as join70 } from "node:path";
|
|
65152
65220
|
async function isOpenCodeInstalled() {
|
|
65153
65221
|
try {
|
|
65154
65222
|
await execAsync7("opencode --version", { timeout: 5000 });
|
|
@@ -65171,7 +65239,7 @@ async function installOpenCode() {
|
|
|
65171
65239
|
logger.info(`Installing ${displayName}...`);
|
|
65172
65240
|
const { unlink: unlink11 } = await import("node:fs/promises");
|
|
65173
65241
|
const { tmpdir: tmpdir4 } = await import("node:os");
|
|
65174
|
-
const tempScriptPath =
|
|
65242
|
+
const tempScriptPath = join70(tmpdir4(), "opencode-install.sh");
|
|
65175
65243
|
try {
|
|
65176
65244
|
logger.info("Downloading OpenCode installation script...");
|
|
65177
65245
|
await execFileAsync5("curl", ["-fsSL", "https://opencode.ai/install", "-o", tempScriptPath], {
|
|
@@ -65223,7 +65291,7 @@ var PARTIAL_INSTALL_VERSION = "partial", EXIT_CODE_CRITICAL_FAILURE = 1, EXIT_CO
|
|
|
65223
65291
|
|
|
65224
65292
|
// src/services/package-installer/install-error-handler.ts
|
|
65225
65293
|
import { existsSync as existsSync49, readFileSync as readFileSync14, unlinkSync as unlinkSync2 } from "node:fs";
|
|
65226
|
-
import { join as
|
|
65294
|
+
import { join as join71 } from "node:path";
|
|
65227
65295
|
function parseNameReason(str2) {
|
|
65228
65296
|
const colonIndex = str2.indexOf(":");
|
|
65229
65297
|
if (colonIndex === -1) {
|
|
@@ -65232,7 +65300,7 @@ function parseNameReason(str2) {
|
|
|
65232
65300
|
return [str2.slice(0, colonIndex).trim(), str2.slice(colonIndex + 1).trim()];
|
|
65233
65301
|
}
|
|
65234
65302
|
function displayInstallErrors(skillsDir2) {
|
|
65235
|
-
const summaryPath =
|
|
65303
|
+
const summaryPath = join71(skillsDir2, ".install-error-summary.json");
|
|
65236
65304
|
if (!existsSync49(summaryPath)) {
|
|
65237
65305
|
logger.error("Skills installation failed. Run with --verbose for details.");
|
|
65238
65306
|
return;
|
|
@@ -65323,7 +65391,7 @@ async function checkNeedsSudoPackages() {
|
|
|
65323
65391
|
}
|
|
65324
65392
|
}
|
|
65325
65393
|
function hasInstallState(skillsDir2) {
|
|
65326
|
-
const stateFilePath =
|
|
65394
|
+
const stateFilePath = join71(skillsDir2, ".install-state.json");
|
|
65327
65395
|
return existsSync49(stateFilePath);
|
|
65328
65396
|
}
|
|
65329
65397
|
var WHICH_COMMAND_TIMEOUT_MS = 5000;
|
|
@@ -65332,7 +65400,7 @@ var init_install_error_handler = __esm(() => {
|
|
|
65332
65400
|
});
|
|
65333
65401
|
|
|
65334
65402
|
// src/services/package-installer/skills-installer.ts
|
|
65335
|
-
import { join as
|
|
65403
|
+
import { join as join72 } from "node:path";
|
|
65336
65404
|
async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
65337
65405
|
const { skipConfirm = false, withSudo = false } = options2;
|
|
65338
65406
|
const displayName = "Skills Dependencies";
|
|
@@ -65358,7 +65426,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
65358
65426
|
const clack = await Promise.resolve().then(() => (init_dist2(), exports_dist));
|
|
65359
65427
|
const platform7 = process.platform;
|
|
65360
65428
|
const scriptName = platform7 === "win32" ? "install.ps1" : "install.sh";
|
|
65361
|
-
const scriptPath =
|
|
65429
|
+
const scriptPath = join72(skillsDir2, scriptName);
|
|
65362
65430
|
try {
|
|
65363
65431
|
validateScriptPath(skillsDir2, scriptPath);
|
|
65364
65432
|
} catch (error) {
|
|
@@ -65374,7 +65442,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
65374
65442
|
logger.warning(`Skills installation script not found: ${scriptPath}`);
|
|
65375
65443
|
logger.info("");
|
|
65376
65444
|
logger.info("\uD83D\uDCD6 Manual Installation Instructions:");
|
|
65377
|
-
logger.info(` See: ${
|
|
65445
|
+
logger.info(` See: ${join72(skillsDir2, "INSTALLATION.md")}`);
|
|
65378
65446
|
logger.info("");
|
|
65379
65447
|
logger.info("Quick start:");
|
|
65380
65448
|
logger.info(" cd .claude/skills/ai-multimodal/scripts");
|
|
@@ -65421,7 +65489,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
65421
65489
|
logger.info(` ${platform7 === "win32" ? `powershell -File "${scriptPath}"` : `bash ${scriptPath}`}`);
|
|
65422
65490
|
logger.info("");
|
|
65423
65491
|
logger.info("Or see complete guide:");
|
|
65424
|
-
logger.info(` ${
|
|
65492
|
+
logger.info(` ${join72(skillsDir2, "INSTALLATION.md")}`);
|
|
65425
65493
|
return {
|
|
65426
65494
|
success: false,
|
|
65427
65495
|
package: displayName,
|
|
@@ -65542,7 +65610,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
65542
65610
|
logger.info("\uD83D\uDCD6 Manual Installation Instructions:");
|
|
65543
65611
|
logger.info("");
|
|
65544
65612
|
logger.info("See complete guide:");
|
|
65545
|
-
logger.info(` cat ${
|
|
65613
|
+
logger.info(` cat ${join72(skillsDir2, "INSTALLATION.md")}`);
|
|
65546
65614
|
logger.info("");
|
|
65547
65615
|
logger.info("Quick start:");
|
|
65548
65616
|
logger.info(" cd .claude/skills/ai-multimodal/scripts");
|
|
@@ -65588,7 +65656,7 @@ var init_skills_installer2 = __esm(() => {
|
|
|
65588
65656
|
// src/services/package-installer/gemini-mcp/config-manager.ts
|
|
65589
65657
|
import { existsSync as existsSync50 } from "node:fs";
|
|
65590
65658
|
import { mkdir as mkdir17, readFile as readFile37, writeFile as writeFile20 } from "node:fs/promises";
|
|
65591
|
-
import { dirname as dirname21, join as
|
|
65659
|
+
import { dirname as dirname21, join as join73 } from "node:path";
|
|
65592
65660
|
async function readJsonFile(filePath) {
|
|
65593
65661
|
try {
|
|
65594
65662
|
const content = await readFile37(filePath, "utf-8");
|
|
@@ -65600,7 +65668,7 @@ async function readJsonFile(filePath) {
|
|
|
65600
65668
|
}
|
|
65601
65669
|
}
|
|
65602
65670
|
async function addGeminiToGitignore(projectDir) {
|
|
65603
|
-
const gitignorePath =
|
|
65671
|
+
const gitignorePath = join73(projectDir, ".gitignore");
|
|
65604
65672
|
const geminiPattern = ".gemini/";
|
|
65605
65673
|
try {
|
|
65606
65674
|
let content = "";
|
|
@@ -65691,13 +65759,13 @@ var init_config_manager2 = __esm(() => {
|
|
|
65691
65759
|
|
|
65692
65760
|
// src/services/package-installer/gemini-mcp/validation.ts
|
|
65693
65761
|
import { existsSync as existsSync51, lstatSync, readlinkSync } from "node:fs";
|
|
65694
|
-
import { homedir as
|
|
65695
|
-
import { join as
|
|
65762
|
+
import { homedir as homedir32 } from "node:os";
|
|
65763
|
+
import { join as join74 } from "node:path";
|
|
65696
65764
|
function getGlobalMcpConfigPath() {
|
|
65697
|
-
return
|
|
65765
|
+
return join74(homedir32(), ".claude", ".mcp.json");
|
|
65698
65766
|
}
|
|
65699
65767
|
function getLocalMcpConfigPath(projectDir) {
|
|
65700
|
-
return
|
|
65768
|
+
return join74(projectDir, ".mcp.json");
|
|
65701
65769
|
}
|
|
65702
65770
|
function findMcpConfigPath(projectDir) {
|
|
65703
65771
|
const localPath = getLocalMcpConfigPath(projectDir);
|
|
@@ -65715,9 +65783,9 @@ function findMcpConfigPath(projectDir) {
|
|
|
65715
65783
|
}
|
|
65716
65784
|
function getGeminiSettingsPath(projectDir, isGlobal) {
|
|
65717
65785
|
if (isGlobal) {
|
|
65718
|
-
return
|
|
65786
|
+
return join74(homedir32(), ".gemini", "settings.json");
|
|
65719
65787
|
}
|
|
65720
|
-
return
|
|
65788
|
+
return join74(projectDir, ".gemini", "settings.json");
|
|
65721
65789
|
}
|
|
65722
65790
|
function checkExistingGeminiConfig(projectDir, isGlobal = false) {
|
|
65723
65791
|
const geminiSettingsPath = getGeminiSettingsPath(projectDir, isGlobal);
|
|
@@ -65747,7 +65815,7 @@ var init_validation = __esm(() => {
|
|
|
65747
65815
|
// src/services/package-installer/gemini-mcp/linker-core.ts
|
|
65748
65816
|
import { existsSync as existsSync52 } from "node:fs";
|
|
65749
65817
|
import { mkdir as mkdir18, symlink as symlink2 } from "node:fs/promises";
|
|
65750
|
-
import { dirname as dirname22, join as
|
|
65818
|
+
import { dirname as dirname22, join as join75 } from "node:path";
|
|
65751
65819
|
async function createSymlink(targetPath, linkPath, projectDir, isGlobal) {
|
|
65752
65820
|
const linkDir = dirname22(linkPath);
|
|
65753
65821
|
if (!existsSync52(linkDir)) {
|
|
@@ -65758,7 +65826,7 @@ async function createSymlink(targetPath, linkPath, projectDir, isGlobal) {
|
|
|
65758
65826
|
if (isGlobal) {
|
|
65759
65827
|
symlinkTarget = getGlobalMcpConfigPath();
|
|
65760
65828
|
} else {
|
|
65761
|
-
const localMcpPath =
|
|
65829
|
+
const localMcpPath = join75(projectDir, ".mcp.json");
|
|
65762
65830
|
const isLocalConfig = targetPath === localMcpPath;
|
|
65763
65831
|
symlinkTarget = isLocalConfig ? "../.mcp.json" : targetPath;
|
|
65764
65832
|
}
|
|
@@ -68175,9 +68243,9 @@ __export(exports_worktree_manager, {
|
|
|
68175
68243
|
});
|
|
68176
68244
|
import { existsSync as existsSync60 } from "node:fs";
|
|
68177
68245
|
import { readFile as readFile54, writeFile as writeFile33 } from "node:fs/promises";
|
|
68178
|
-
import { join as
|
|
68246
|
+
import { join as join127 } from "node:path";
|
|
68179
68247
|
async function createWorktree(projectDir, issueNumber, baseBranch) {
|
|
68180
|
-
const worktreePath =
|
|
68248
|
+
const worktreePath = join127(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
|
|
68181
68249
|
const branchName = `ck-watch/issue-${issueNumber}`;
|
|
68182
68250
|
await spawnAndCollect("git", ["fetch", "origin", baseBranch], projectDir).catch(() => {
|
|
68183
68251
|
logger.warning(`[worktree] Could not fetch origin/${baseBranch}, using local`);
|
|
@@ -68195,7 +68263,7 @@ async function createWorktree(projectDir, issueNumber, baseBranch) {
|
|
|
68195
68263
|
return worktreePath;
|
|
68196
68264
|
}
|
|
68197
68265
|
async function removeWorktree(projectDir, issueNumber) {
|
|
68198
|
-
const worktreePath =
|
|
68266
|
+
const worktreePath = join127(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
|
|
68199
68267
|
const branchName = `ck-watch/issue-${issueNumber}`;
|
|
68200
68268
|
try {
|
|
68201
68269
|
await spawnAndCollect("git", ["worktree", "remove", worktreePath, "--force"], projectDir);
|
|
@@ -68209,7 +68277,7 @@ async function listActiveWorktrees(projectDir) {
|
|
|
68209
68277
|
try {
|
|
68210
68278
|
const output2 = await spawnAndCollect("git", ["worktree", "list", "--porcelain"], projectDir);
|
|
68211
68279
|
const issueNumbers = [];
|
|
68212
|
-
const worktreePrefix =
|
|
68280
|
+
const worktreePrefix = join127(projectDir, WORKTREE_DIR, "issue-").replace(/\\/g, "/");
|
|
68213
68281
|
for (const line of output2.split(`
|
|
68214
68282
|
`)) {
|
|
68215
68283
|
if (line.startsWith("worktree ")) {
|
|
@@ -68237,7 +68305,7 @@ async function cleanupAllWorktrees(projectDir) {
|
|
|
68237
68305
|
await spawnAndCollect("git", ["worktree", "prune"], projectDir).catch(() => {});
|
|
68238
68306
|
}
|
|
68239
68307
|
async function ensureGitignore(projectDir) {
|
|
68240
|
-
const gitignorePath =
|
|
68308
|
+
const gitignorePath = join127(projectDir, ".gitignore");
|
|
68241
68309
|
try {
|
|
68242
68310
|
const content = existsSync60(gitignorePath) ? await readFile54(gitignorePath, "utf-8") : "";
|
|
68243
68311
|
if (!content.includes(".worktrees")) {
|
|
@@ -68343,8 +68411,8 @@ var init_content_validator = __esm(() => {
|
|
|
68343
68411
|
import { createHash as createHash6 } from "node:crypto";
|
|
68344
68412
|
import { existsSync as existsSync66, mkdirSync as mkdirSync4, readFileSync as readFileSync15, readdirSync as readdirSync8, statSync as statSync10 } from "node:fs";
|
|
68345
68413
|
import { rename as rename9, writeFile as writeFile35 } from "node:fs/promises";
|
|
68346
|
-
import { homedir as
|
|
68347
|
-
import { basename as basename19, join as
|
|
68414
|
+
import { homedir as homedir37 } from "node:os";
|
|
68415
|
+
import { basename as basename19, join as join134 } from "node:path";
|
|
68348
68416
|
function getCachedContext(repoPath) {
|
|
68349
68417
|
const cachePath = getCacheFilePath(repoPath);
|
|
68350
68418
|
if (!existsSync66(cachePath))
|
|
@@ -68387,25 +68455,25 @@ function computeSourceHash(repoPath) {
|
|
|
68387
68455
|
}
|
|
68388
68456
|
function getDocSourcePaths(repoPath) {
|
|
68389
68457
|
const paths = [];
|
|
68390
|
-
const docsDir =
|
|
68458
|
+
const docsDir = join134(repoPath, "docs");
|
|
68391
68459
|
if (existsSync66(docsDir)) {
|
|
68392
68460
|
try {
|
|
68393
68461
|
const files = readdirSync8(docsDir);
|
|
68394
68462
|
for (const f3 of files) {
|
|
68395
68463
|
if (f3.endsWith(".md"))
|
|
68396
|
-
paths.push(
|
|
68464
|
+
paths.push(join134(docsDir, f3));
|
|
68397
68465
|
}
|
|
68398
68466
|
} catch {}
|
|
68399
68467
|
}
|
|
68400
|
-
const readme =
|
|
68468
|
+
const readme = join134(repoPath, "README.md");
|
|
68401
68469
|
if (existsSync66(readme))
|
|
68402
68470
|
paths.push(readme);
|
|
68403
|
-
const stylesDir =
|
|
68471
|
+
const stylesDir = join134(repoPath, "assets", "writing-styles");
|
|
68404
68472
|
if (existsSync66(stylesDir)) {
|
|
68405
68473
|
try {
|
|
68406
68474
|
const files = readdirSync8(stylesDir);
|
|
68407
68475
|
for (const f3 of files) {
|
|
68408
|
-
paths.push(
|
|
68476
|
+
paths.push(join134(stylesDir, f3));
|
|
68409
68477
|
}
|
|
68410
68478
|
} catch {}
|
|
68411
68479
|
}
|
|
@@ -68414,11 +68482,11 @@ function getDocSourcePaths(repoPath) {
|
|
|
68414
68482
|
function getCacheFilePath(repoPath) {
|
|
68415
68483
|
const repoName = basename19(repoPath).replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
68416
68484
|
const pathHash = createHash6("sha256").update(repoPath).digest("hex").slice(0, 8);
|
|
68417
|
-
return
|
|
68485
|
+
return join134(CACHE_DIR, `${repoName}-${pathHash}-context-cache.json`);
|
|
68418
68486
|
}
|
|
68419
68487
|
var CACHE_DIR, CACHE_TTL_MS4;
|
|
68420
68488
|
var init_context_cache_manager = __esm(() => {
|
|
68421
|
-
CACHE_DIR =
|
|
68489
|
+
CACHE_DIR = join134(homedir37(), ".claudekit", "cache");
|
|
68422
68490
|
CACHE_TTL_MS4 = 24 * 60 * 60 * 1000;
|
|
68423
68491
|
});
|
|
68424
68492
|
|
|
@@ -68599,7 +68667,7 @@ function extractContentFromResponse(response) {
|
|
|
68599
68667
|
// src/commands/content/phases/docs-summarizer.ts
|
|
68600
68668
|
import { execSync as execSync6 } from "node:child_process";
|
|
68601
68669
|
import { existsSync as existsSync67, readFileSync as readFileSync16, readdirSync as readdirSync9 } from "node:fs";
|
|
68602
|
-
import { join as
|
|
68670
|
+
import { join as join135 } from "node:path";
|
|
68603
68671
|
async function summarizeProjectDocs(repoPath, contentLogger) {
|
|
68604
68672
|
const rawContent = collectRawDocs(repoPath);
|
|
68605
68673
|
if (rawContent.total.length < 200) {
|
|
@@ -68653,12 +68721,12 @@ function collectRawDocs(repoPath) {
|
|
|
68653
68721
|
return capped;
|
|
68654
68722
|
};
|
|
68655
68723
|
const docsContent = [];
|
|
68656
|
-
const docsDir =
|
|
68724
|
+
const docsDir = join135(repoPath, "docs");
|
|
68657
68725
|
if (existsSync67(docsDir)) {
|
|
68658
68726
|
try {
|
|
68659
68727
|
const files = readdirSync9(docsDir).filter((f3) => f3.endsWith(".md")).sort();
|
|
68660
68728
|
for (const f3 of files) {
|
|
68661
|
-
const content = readCapped(
|
|
68729
|
+
const content = readCapped(join135(docsDir, f3), 5000);
|
|
68662
68730
|
if (content) {
|
|
68663
68731
|
docsContent.push(`### ${f3}
|
|
68664
68732
|
${content}`);
|
|
@@ -68672,21 +68740,21 @@ ${content}`);
|
|
|
68672
68740
|
let brand = "";
|
|
68673
68741
|
const brandCandidates = ["docs/brand-guidelines.md", "docs/design-guidelines.md"];
|
|
68674
68742
|
for (const p of brandCandidates) {
|
|
68675
|
-
brand = readCapped(
|
|
68743
|
+
brand = readCapped(join135(repoPath, p), 3000);
|
|
68676
68744
|
if (brand)
|
|
68677
68745
|
break;
|
|
68678
68746
|
}
|
|
68679
68747
|
let styles3 = "";
|
|
68680
|
-
const stylesDir =
|
|
68748
|
+
const stylesDir = join135(repoPath, "assets", "writing-styles");
|
|
68681
68749
|
if (existsSync67(stylesDir)) {
|
|
68682
68750
|
try {
|
|
68683
68751
|
const files = readdirSync9(stylesDir).slice(0, 3);
|
|
68684
|
-
styles3 = files.map((f3) => readCapped(
|
|
68752
|
+
styles3 = files.map((f3) => readCapped(join135(stylesDir, f3), 1000)).filter(Boolean).join(`
|
|
68685
68753
|
|
|
68686
68754
|
`);
|
|
68687
68755
|
} catch {}
|
|
68688
68756
|
}
|
|
68689
|
-
const readme = readCapped(
|
|
68757
|
+
const readme = readCapped(join135(repoPath, "README.md"), 3000);
|
|
68690
68758
|
const total = [docs, brand, styles3, readme].join(`
|
|
68691
68759
|
`);
|
|
68692
68760
|
return { docs, brand, styles: styles3, readme, total };
|
|
@@ -68872,10 +68940,10 @@ IMPORTANT: Generate the image and output the path as JSON: {"imagePath": "/path/
|
|
|
68872
68940
|
// src/commands/content/phases/photo-generator.ts
|
|
68873
68941
|
import { execSync as execSync7 } from "node:child_process";
|
|
68874
68942
|
import { existsSync as existsSync68, mkdirSync as mkdirSync5, readdirSync as readdirSync10 } from "node:fs";
|
|
68875
|
-
import { homedir as
|
|
68876
|
-
import { join as
|
|
68943
|
+
import { homedir as homedir38 } from "node:os";
|
|
68944
|
+
import { join as join136 } from "node:path";
|
|
68877
68945
|
async function generatePhoto(_content, context, config, platform14, contentId, contentLogger) {
|
|
68878
|
-
const mediaDir =
|
|
68946
|
+
const mediaDir = join136(config.contentDir.replace(/^~/, homedir38()), "media", String(contentId));
|
|
68879
68947
|
if (!existsSync68(mediaDir)) {
|
|
68880
68948
|
mkdirSync5(mediaDir, { recursive: true });
|
|
68881
68949
|
}
|
|
@@ -68900,7 +68968,7 @@ async function generatePhoto(_content, context, config, platform14, contentId, c
|
|
|
68900
68968
|
const imageFile = files.find((f3) => /\.(png|jpg|jpeg|webp)$/i.test(f3));
|
|
68901
68969
|
if (imageFile) {
|
|
68902
68970
|
const ext2 = imageFile.split(".").pop() ?? "png";
|
|
68903
|
-
return { path:
|
|
68971
|
+
return { path: join136(mediaDir, imageFile), ...dimensions, format: ext2 };
|
|
68904
68972
|
}
|
|
68905
68973
|
contentLogger.warn(`Photo generation produced no image for content ${contentId}`);
|
|
68906
68974
|
return null;
|
|
@@ -68989,8 +69057,8 @@ var init_content_creator = __esm(() => {
|
|
|
68989
69057
|
|
|
68990
69058
|
// src/commands/content/phases/content-logger.ts
|
|
68991
69059
|
import { createWriteStream as createWriteStream4, existsSync as existsSync69, mkdirSync as mkdirSync6, statSync as statSync11 } from "node:fs";
|
|
68992
|
-
import { homedir as
|
|
68993
|
-
import { join as
|
|
69060
|
+
import { homedir as homedir39 } from "node:os";
|
|
69061
|
+
import { join as join137 } from "node:path";
|
|
68994
69062
|
|
|
68995
69063
|
class ContentLogger {
|
|
68996
69064
|
stream = null;
|
|
@@ -68998,7 +69066,7 @@ class ContentLogger {
|
|
|
68998
69066
|
logDir;
|
|
68999
69067
|
maxBytes;
|
|
69000
69068
|
constructor(maxBytes = 0) {
|
|
69001
|
-
this.logDir =
|
|
69069
|
+
this.logDir = join137(homedir39(), ".claudekit", "logs");
|
|
69002
69070
|
this.maxBytes = maxBytes;
|
|
69003
69071
|
}
|
|
69004
69072
|
init() {
|
|
@@ -69030,7 +69098,7 @@ class ContentLogger {
|
|
|
69030
69098
|
}
|
|
69031
69099
|
}
|
|
69032
69100
|
getLogPath() {
|
|
69033
|
-
return
|
|
69101
|
+
return join137(this.logDir, `content-${this.getDateStr()}.log`);
|
|
69034
69102
|
}
|
|
69035
69103
|
write(level, message) {
|
|
69036
69104
|
this.rotateIfNeeded();
|
|
@@ -69047,18 +69115,18 @@ class ContentLogger {
|
|
|
69047
69115
|
if (dateStr !== this.currentDate) {
|
|
69048
69116
|
this.close();
|
|
69049
69117
|
this.currentDate = dateStr;
|
|
69050
|
-
const logPath =
|
|
69118
|
+
const logPath = join137(this.logDir, `content-${dateStr}.log`);
|
|
69051
69119
|
this.stream = createWriteStream4(logPath, { flags: "a", mode: 384 });
|
|
69052
69120
|
return;
|
|
69053
69121
|
}
|
|
69054
69122
|
if (this.maxBytes > 0 && this.stream) {
|
|
69055
|
-
const logPath =
|
|
69123
|
+
const logPath = join137(this.logDir, `content-${this.currentDate}.log`);
|
|
69056
69124
|
try {
|
|
69057
69125
|
const stat20 = statSync11(logPath);
|
|
69058
69126
|
if (stat20.size >= this.maxBytes) {
|
|
69059
69127
|
this.close();
|
|
69060
69128
|
const suffix = Date.now();
|
|
69061
|
-
const rotatedPath =
|
|
69129
|
+
const rotatedPath = join137(this.logDir, `content-${this.currentDate}-${suffix}.log`);
|
|
69062
69130
|
import("node:fs/promises").then(({ rename: rename10 }) => rename10(logPath, rotatedPath).catch(() => {}));
|
|
69063
69131
|
this.stream = createWriteStream4(logPath, { flags: "w", mode: 384 });
|
|
69064
69132
|
}
|
|
@@ -69096,7 +69164,7 @@ var init_sqlite_client = () => {};
|
|
|
69096
69164
|
|
|
69097
69165
|
// src/commands/content/phases/db-manager.ts
|
|
69098
69166
|
import { existsSync as existsSync70, mkdirSync as mkdirSync7 } from "node:fs";
|
|
69099
|
-
import { dirname as
|
|
69167
|
+
import { dirname as dirname35 } from "node:path";
|
|
69100
69168
|
function initDatabase(dbPath) {
|
|
69101
69169
|
ensureParentDir(dbPath);
|
|
69102
69170
|
const db = openDatabase(dbPath);
|
|
@@ -69117,7 +69185,7 @@ function runRetentionCleanup(db, retentionDays = 90) {
|
|
|
69117
69185
|
db.prepare("DELETE FROM git_events WHERE processed = 1 AND created_at < ?").run(cutoff);
|
|
69118
69186
|
}
|
|
69119
69187
|
function ensureParentDir(dbPath) {
|
|
69120
|
-
const dir =
|
|
69188
|
+
const dir = dirname35(dbPath);
|
|
69121
69189
|
if (dir && !existsSync70(dir)) {
|
|
69122
69190
|
mkdirSync7(dir, { recursive: true });
|
|
69123
69191
|
}
|
|
@@ -69284,7 +69352,7 @@ function isNoiseCommit(title, author) {
|
|
|
69284
69352
|
// src/commands/content/phases/change-detector.ts
|
|
69285
69353
|
import { execSync as execSync9 } from "node:child_process";
|
|
69286
69354
|
import { existsSync as existsSync71, readFileSync as readFileSync17, readdirSync as readdirSync11, statSync as statSync12 } from "node:fs";
|
|
69287
|
-
import { join as
|
|
69355
|
+
import { join as join138 } from "node:path";
|
|
69288
69356
|
function detectCommits(repo, since) {
|
|
69289
69357
|
try {
|
|
69290
69358
|
const fetchUrl = sshToHttps(repo.remoteUrl);
|
|
@@ -69382,7 +69450,7 @@ function detectTags(repo, since) {
|
|
|
69382
69450
|
}
|
|
69383
69451
|
}
|
|
69384
69452
|
function detectCompletedPlans(repo, since) {
|
|
69385
|
-
const plansDir =
|
|
69453
|
+
const plansDir = join138(repo.path, "plans");
|
|
69386
69454
|
if (!existsSync71(plansDir))
|
|
69387
69455
|
return [];
|
|
69388
69456
|
const sinceMs = new Date(since).getTime();
|
|
@@ -69392,7 +69460,7 @@ function detectCompletedPlans(repo, since) {
|
|
|
69392
69460
|
for (const entry of entries) {
|
|
69393
69461
|
if (!entry.isDirectory())
|
|
69394
69462
|
continue;
|
|
69395
|
-
const planFile =
|
|
69463
|
+
const planFile = join138(plansDir, entry.name, "plan.md");
|
|
69396
69464
|
if (!existsSync71(planFile))
|
|
69397
69465
|
continue;
|
|
69398
69466
|
try {
|
|
@@ -69470,7 +69538,7 @@ function classifyCommit(event) {
|
|
|
69470
69538
|
// src/commands/content/phases/repo-discoverer.ts
|
|
69471
69539
|
import { execSync as execSync10 } from "node:child_process";
|
|
69472
69540
|
import { readdirSync as readdirSync12 } from "node:fs";
|
|
69473
|
-
import { join as
|
|
69541
|
+
import { join as join139 } from "node:path";
|
|
69474
69542
|
function discoverRepos2(cwd2) {
|
|
69475
69543
|
const repos = [];
|
|
69476
69544
|
if (isGitRepoRoot(cwd2)) {
|
|
@@ -69483,7 +69551,7 @@ function discoverRepos2(cwd2) {
|
|
|
69483
69551
|
for (const entry of entries) {
|
|
69484
69552
|
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
69485
69553
|
continue;
|
|
69486
|
-
const dirPath =
|
|
69554
|
+
const dirPath = join139(cwd2, entry.name);
|
|
69487
69555
|
if (isGitRepoRoot(dirPath)) {
|
|
69488
69556
|
const info = getRepoInfo(dirPath);
|
|
69489
69557
|
if (info)
|
|
@@ -70150,9 +70218,9 @@ var init_types6 = __esm(() => {
|
|
|
70150
70218
|
|
|
70151
70219
|
// src/commands/content/phases/state-manager.ts
|
|
70152
70220
|
import { readFile as readFile56, rename as rename10, writeFile as writeFile36 } from "node:fs/promises";
|
|
70153
|
-
import { join as
|
|
70221
|
+
import { join as join140 } from "node:path";
|
|
70154
70222
|
async function loadContentConfig(projectDir) {
|
|
70155
|
-
const configPath =
|
|
70223
|
+
const configPath = join140(projectDir, CK_CONFIG_FILE2);
|
|
70156
70224
|
try {
|
|
70157
70225
|
const raw2 = await readFile56(configPath, "utf-8");
|
|
70158
70226
|
const json = JSON.parse(raw2);
|
|
@@ -70162,13 +70230,13 @@ async function loadContentConfig(projectDir) {
|
|
|
70162
70230
|
}
|
|
70163
70231
|
}
|
|
70164
70232
|
async function saveContentConfig(projectDir, config) {
|
|
70165
|
-
const configPath =
|
|
70233
|
+
const configPath = join140(projectDir, CK_CONFIG_FILE2);
|
|
70166
70234
|
const json = await readJsonSafe(configPath);
|
|
70167
70235
|
json.content = { ...json.content, ...config };
|
|
70168
70236
|
await atomicWrite(configPath, json);
|
|
70169
70237
|
}
|
|
70170
70238
|
async function loadContentState(projectDir) {
|
|
70171
|
-
const configPath =
|
|
70239
|
+
const configPath = join140(projectDir, CK_CONFIG_FILE2);
|
|
70172
70240
|
try {
|
|
70173
70241
|
const raw2 = await readFile56(configPath, "utf-8");
|
|
70174
70242
|
const json = JSON.parse(raw2);
|
|
@@ -70179,7 +70247,7 @@ async function loadContentState(projectDir) {
|
|
|
70179
70247
|
}
|
|
70180
70248
|
}
|
|
70181
70249
|
async function saveContentState(projectDir, state) {
|
|
70182
|
-
const configPath =
|
|
70250
|
+
const configPath = join140(projectDir, CK_CONFIG_FILE2);
|
|
70183
70251
|
const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().slice(0, 10);
|
|
70184
70252
|
for (const key of Object.keys(state.dailyPostCounts)) {
|
|
70185
70253
|
const dateStr = key.slice(-10);
|
|
@@ -70461,7 +70529,7 @@ var init_platform_setup_x = __esm(() => {
|
|
|
70461
70529
|
|
|
70462
70530
|
// src/commands/content/phases/setup-wizard.ts
|
|
70463
70531
|
import { existsSync as existsSync72 } from "node:fs";
|
|
70464
|
-
import { join as
|
|
70532
|
+
import { join as join141 } from "node:path";
|
|
70465
70533
|
async function runSetupWizard2(cwd2, contentLogger) {
|
|
70466
70534
|
console.log();
|
|
70467
70535
|
oe(import_picocolors41.default.bgCyan(import_picocolors41.default.white(" CK Content — Multi-Channel Content Engine ")));
|
|
@@ -70529,8 +70597,8 @@ async function showRepoSummary(cwd2) {
|
|
|
70529
70597
|
function detectBrandAssets(cwd2, contentLogger) {
|
|
70530
70598
|
const repos = discoverRepos2(cwd2);
|
|
70531
70599
|
for (const repo of repos) {
|
|
70532
|
-
const hasGuidelines = existsSync72(
|
|
70533
|
-
const hasStyles = existsSync72(
|
|
70600
|
+
const hasGuidelines = existsSync72(join141(repo.path, "docs", "brand-guidelines.md"));
|
|
70601
|
+
const hasStyles = existsSync72(join141(repo.path, "assets", "writing-styles"));
|
|
70534
70602
|
if (!hasGuidelines) {
|
|
70535
70603
|
f2.warning(`${repo.name}: No docs/brand-guidelines.md — content will use generic tone.`);
|
|
70536
70604
|
contentLogger.warn(`${repo.name}: missing docs/brand-guidelines.md`);
|
|
@@ -70597,11 +70665,11 @@ var init_setup_wizard = __esm(() => {
|
|
|
70597
70665
|
|
|
70598
70666
|
// src/commands/content/content-review-commands.ts
|
|
70599
70667
|
import { existsSync as existsSync73 } from "node:fs";
|
|
70600
|
-
import { homedir as
|
|
70668
|
+
import { homedir as homedir40 } from "node:os";
|
|
70601
70669
|
async function queueContent() {
|
|
70602
70670
|
const cwd2 = process.cwd();
|
|
70603
70671
|
const config = await loadContentConfig(cwd2);
|
|
70604
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
70672
|
+
const dbPath = config.dbPath.replace(/^~/, homedir40());
|
|
70605
70673
|
if (!existsSync73(dbPath)) {
|
|
70606
70674
|
logger.info("No content database found. Run 'ck content setup' first.");
|
|
70607
70675
|
return;
|
|
@@ -70628,7 +70696,7 @@ async function queueContent() {
|
|
|
70628
70696
|
async function approveContentCmd(id) {
|
|
70629
70697
|
const cwd2 = process.cwd();
|
|
70630
70698
|
const config = await loadContentConfig(cwd2);
|
|
70631
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
70699
|
+
const dbPath = config.dbPath.replace(/^~/, homedir40());
|
|
70632
70700
|
const db = initDatabase(dbPath);
|
|
70633
70701
|
try {
|
|
70634
70702
|
approveContent(db, Number.parseInt(id, 10));
|
|
@@ -70640,7 +70708,7 @@ async function approveContentCmd(id) {
|
|
|
70640
70708
|
async function rejectContentCmd(id, reason) {
|
|
70641
70709
|
const cwd2 = process.cwd();
|
|
70642
70710
|
const config = await loadContentConfig(cwd2);
|
|
70643
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
70711
|
+
const dbPath = config.dbPath.replace(/^~/, homedir40());
|
|
70644
70712
|
const db = initDatabase(dbPath);
|
|
70645
70713
|
try {
|
|
70646
70714
|
rejectContent(db, Number.parseInt(id, 10), reason);
|
|
@@ -70671,10 +70739,10 @@ __export(exports_content_subcommands, {
|
|
|
70671
70739
|
approveContentCmd: () => approveContentCmd
|
|
70672
70740
|
});
|
|
70673
70741
|
import { existsSync as existsSync74, readFileSync as readFileSync18, unlinkSync as unlinkSync5 } from "node:fs";
|
|
70674
|
-
import { homedir as
|
|
70675
|
-
import { join as
|
|
70742
|
+
import { homedir as homedir41 } from "node:os";
|
|
70743
|
+
import { join as join142 } from "node:path";
|
|
70676
70744
|
function isDaemonRunning() {
|
|
70677
|
-
const lockFile =
|
|
70745
|
+
const lockFile = join142(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
70678
70746
|
if (!existsSync74(lockFile))
|
|
70679
70747
|
return { running: false, pid: null };
|
|
70680
70748
|
try {
|
|
@@ -70706,7 +70774,7 @@ async function startContent(options2) {
|
|
|
70706
70774
|
await contentCommand(options2);
|
|
70707
70775
|
}
|
|
70708
70776
|
async function stopContent() {
|
|
70709
|
-
const lockFile =
|
|
70777
|
+
const lockFile = join142(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
70710
70778
|
if (!existsSync74(lockFile)) {
|
|
70711
70779
|
logger.info("Content daemon is not running.");
|
|
70712
70780
|
return;
|
|
@@ -70745,9 +70813,9 @@ async function statusContent() {
|
|
|
70745
70813
|
} catch {}
|
|
70746
70814
|
}
|
|
70747
70815
|
async function logsContent(options2) {
|
|
70748
|
-
const logDir =
|
|
70816
|
+
const logDir = join142(homedir41(), ".claudekit", "logs");
|
|
70749
70817
|
const dateStr = new Date().toISOString().slice(0, 10).replace(/-/g, "");
|
|
70750
|
-
const logPath =
|
|
70818
|
+
const logPath = join142(logDir, `content-${dateStr}.log`);
|
|
70751
70819
|
if (!existsSync74(logPath)) {
|
|
70752
70820
|
logger.info("No content logs found for today.");
|
|
70753
70821
|
return;
|
|
@@ -70779,13 +70847,13 @@ var init_content_subcommands = __esm(() => {
|
|
|
70779
70847
|
init_setup_wizard();
|
|
70780
70848
|
init_state_manager();
|
|
70781
70849
|
init_content_review_commands();
|
|
70782
|
-
LOCK_DIR =
|
|
70850
|
+
LOCK_DIR = join142(homedir41(), ".claudekit", "locks");
|
|
70783
70851
|
});
|
|
70784
70852
|
|
|
70785
70853
|
// src/commands/content/content-command.ts
|
|
70786
70854
|
import { existsSync as existsSync75, mkdirSync as mkdirSync8, unlinkSync as unlinkSync6, writeFileSync as writeFileSync6 } from "node:fs";
|
|
70787
|
-
import { homedir as
|
|
70788
|
-
import { join as
|
|
70855
|
+
import { homedir as homedir42 } from "node:os";
|
|
70856
|
+
import { join as join143 } from "node:path";
|
|
70789
70857
|
async function contentCommand(options2) {
|
|
70790
70858
|
const cwd2 = process.cwd();
|
|
70791
70859
|
const contentLogger = new ContentLogger;
|
|
@@ -70817,7 +70885,7 @@ async function contentCommand(options2) {
|
|
|
70817
70885
|
if (!existsSync75(LOCK_DIR2))
|
|
70818
70886
|
mkdirSync8(LOCK_DIR2, { recursive: true });
|
|
70819
70887
|
writeFileSync6(LOCK_FILE, String(process.pid), "utf-8");
|
|
70820
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
70888
|
+
const dbPath = config.dbPath.replace(/^~/, homedir42());
|
|
70821
70889
|
const db = initDatabase(dbPath);
|
|
70822
70890
|
contentLogger.info(`Database initialised at ${dbPath}`);
|
|
70823
70891
|
const adapters = initializeAdapters(config);
|
|
@@ -70963,8 +71031,8 @@ var init_content_command = __esm(() => {
|
|
|
70963
71031
|
init_publisher();
|
|
70964
71032
|
init_review_manager();
|
|
70965
71033
|
init_state_manager();
|
|
70966
|
-
LOCK_DIR2 =
|
|
70967
|
-
LOCK_FILE =
|
|
71034
|
+
LOCK_DIR2 = join143(homedir42(), ".claudekit", "locks");
|
|
71035
|
+
LOCK_FILE = join143(LOCK_DIR2, "ck-content.lock");
|
|
70968
71036
|
});
|
|
70969
71037
|
|
|
70970
71038
|
// src/commands/content/index.ts
|
|
@@ -76924,14 +76992,14 @@ async function checkCliInstallMethod() {
|
|
|
76924
76992
|
}
|
|
76925
76993
|
// src/domains/health-checks/checkers/claude-md-checker.ts
|
|
76926
76994
|
import { existsSync as existsSync40, statSync as statSync5 } from "node:fs";
|
|
76927
|
-
import { join as
|
|
76995
|
+
import { join as join53 } from "node:path";
|
|
76928
76996
|
function checkClaudeMd(setup, projectDir) {
|
|
76929
76997
|
const results = [];
|
|
76930
76998
|
if (setup.global.path) {
|
|
76931
|
-
const globalClaudeMd =
|
|
76999
|
+
const globalClaudeMd = join53(setup.global.path, "CLAUDE.md");
|
|
76932
77000
|
results.push(checkClaudeMdFile(globalClaudeMd, "Global CLAUDE.md", "ck-global-claude-md"));
|
|
76933
77001
|
}
|
|
76934
|
-
const projectClaudeMd =
|
|
77002
|
+
const projectClaudeMd = join53(projectDir, ".claude", "CLAUDE.md");
|
|
76935
77003
|
results.push(checkClaudeMdFile(projectClaudeMd, "Project CLAUDE.md", "ck-project-claude-md"));
|
|
76936
77004
|
return results;
|
|
76937
77005
|
}
|
|
@@ -76990,9 +77058,9 @@ function checkClaudeMdFile(path5, name, id) {
|
|
|
76990
77058
|
}
|
|
76991
77059
|
// src/domains/health-checks/checkers/active-plan-checker.ts
|
|
76992
77060
|
import { existsSync as existsSync41, readFileSync as readFileSync11 } from "node:fs";
|
|
76993
|
-
import { join as
|
|
77061
|
+
import { join as join54 } from "node:path";
|
|
76994
77062
|
function checkActivePlan(projectDir) {
|
|
76995
|
-
const activePlanPath =
|
|
77063
|
+
const activePlanPath = join54(projectDir, ".claude", "active-plan");
|
|
76996
77064
|
if (!existsSync41(activePlanPath)) {
|
|
76997
77065
|
return {
|
|
76998
77066
|
id: "ck-active-plan",
|
|
@@ -77006,7 +77074,7 @@ function checkActivePlan(projectDir) {
|
|
|
77006
77074
|
}
|
|
77007
77075
|
try {
|
|
77008
77076
|
const targetPath = readFileSync11(activePlanPath, "utf-8").trim();
|
|
77009
|
-
const fullPath =
|
|
77077
|
+
const fullPath = join54(projectDir, targetPath);
|
|
77010
77078
|
if (!existsSync41(fullPath)) {
|
|
77011
77079
|
return {
|
|
77012
77080
|
id: "ck-active-plan",
|
|
@@ -77044,13 +77112,13 @@ function checkActivePlan(projectDir) {
|
|
|
77044
77112
|
}
|
|
77045
77113
|
// src/domains/health-checks/checkers/skills-checker.ts
|
|
77046
77114
|
import { existsSync as existsSync42 } from "node:fs";
|
|
77047
|
-
import { join as
|
|
77115
|
+
import { join as join55 } from "node:path";
|
|
77048
77116
|
function checkSkillsScripts(setup) {
|
|
77049
77117
|
const results = [];
|
|
77050
77118
|
const platform5 = process.platform;
|
|
77051
77119
|
const scriptName = platform5 === "win32" ? "install.ps1" : "install.sh";
|
|
77052
77120
|
if (setup.global.path) {
|
|
77053
|
-
const globalScriptPath =
|
|
77121
|
+
const globalScriptPath = join55(setup.global.path, "skills", scriptName);
|
|
77054
77122
|
const hasGlobalScript = existsSync42(globalScriptPath);
|
|
77055
77123
|
results.push({
|
|
77056
77124
|
id: "ck-global-skills-script",
|
|
@@ -77065,7 +77133,7 @@ function checkSkillsScripts(setup) {
|
|
|
77065
77133
|
});
|
|
77066
77134
|
}
|
|
77067
77135
|
if (setup.project.metadata) {
|
|
77068
|
-
const projectScriptPath =
|
|
77136
|
+
const projectScriptPath = join55(setup.project.path, "skills", scriptName);
|
|
77069
77137
|
const hasProjectScript = existsSync42(projectScriptPath);
|
|
77070
77138
|
results.push({
|
|
77071
77139
|
id: "ck-project-skills-script",
|
|
@@ -77104,7 +77172,7 @@ function checkComponentCounts(setup) {
|
|
|
77104
77172
|
init_logger();
|
|
77105
77173
|
init_path_resolver();
|
|
77106
77174
|
import { constants as constants2, access as access2, unlink as unlink7, writeFile as writeFile16 } from "node:fs/promises";
|
|
77107
|
-
import { join as
|
|
77175
|
+
import { join as join56 } from "node:path";
|
|
77108
77176
|
|
|
77109
77177
|
// src/domains/health-checks/checkers/shared.ts
|
|
77110
77178
|
init_environment();
|
|
@@ -77170,7 +77238,7 @@ async function checkGlobalDirWritable() {
|
|
|
77170
77238
|
}
|
|
77171
77239
|
const timestamp = Date.now();
|
|
77172
77240
|
const random = Math.random().toString(36).substring(2);
|
|
77173
|
-
const testFile =
|
|
77241
|
+
const testFile = join56(globalDir, `.ck-write-test-${timestamp}-${random}`);
|
|
77174
77242
|
try {
|
|
77175
77243
|
await writeFile16(testFile, "test", { encoding: "utf-8", flag: "wx" });
|
|
77176
77244
|
} catch (error) {
|
|
@@ -77206,7 +77274,7 @@ async function checkGlobalDirWritable() {
|
|
|
77206
77274
|
init_path_resolver();
|
|
77207
77275
|
import { existsSync as existsSync43 } from "node:fs";
|
|
77208
77276
|
import { readdir as readdir10 } from "node:fs/promises";
|
|
77209
|
-
import { join as
|
|
77277
|
+
import { join as join57 } from "node:path";
|
|
77210
77278
|
|
|
77211
77279
|
// src/domains/health-checks/utils/path-normalizer.ts
|
|
77212
77280
|
import { normalize as normalize4 } from "node:path";
|
|
@@ -77218,8 +77286,8 @@ function normalizePath2(filePath) {
|
|
|
77218
77286
|
|
|
77219
77287
|
// src/domains/health-checks/checkers/hooks-checker.ts
|
|
77220
77288
|
async function checkHooksExist(projectDir) {
|
|
77221
|
-
const globalHooksDir =
|
|
77222
|
-
const projectHooksDir =
|
|
77289
|
+
const globalHooksDir = join57(PathResolver.getGlobalKitDir(), "hooks");
|
|
77290
|
+
const projectHooksDir = join57(projectDir, ".claude", "hooks");
|
|
77223
77291
|
const globalExists = existsSync43(globalHooksDir);
|
|
77224
77292
|
const projectExists = existsSync43(projectHooksDir);
|
|
77225
77293
|
let hookCount = 0;
|
|
@@ -77228,7 +77296,7 @@ async function checkHooksExist(projectDir) {
|
|
|
77228
77296
|
const files = await readdir10(globalHooksDir, { withFileTypes: false });
|
|
77229
77297
|
const hooks = files.filter((f3) => HOOK_EXTENSIONS2.some((ext) => f3.endsWith(ext)));
|
|
77230
77298
|
hooks.forEach((hook) => {
|
|
77231
|
-
const fullPath =
|
|
77299
|
+
const fullPath = join57(globalHooksDir, hook);
|
|
77232
77300
|
checkedFiles.add(normalizePath2(fullPath));
|
|
77233
77301
|
});
|
|
77234
77302
|
}
|
|
@@ -77238,7 +77306,7 @@ async function checkHooksExist(projectDir) {
|
|
|
77238
77306
|
const files = await readdir10(projectHooksDir, { withFileTypes: false });
|
|
77239
77307
|
const hooks = files.filter((f3) => HOOK_EXTENSIONS2.some((ext) => f3.endsWith(ext)));
|
|
77240
77308
|
hooks.forEach((hook) => {
|
|
77241
|
-
const fullPath =
|
|
77309
|
+
const fullPath = join57(projectHooksDir, hook);
|
|
77242
77310
|
checkedFiles.add(normalizePath2(fullPath));
|
|
77243
77311
|
});
|
|
77244
77312
|
}
|
|
@@ -77270,10 +77338,10 @@ init_logger();
|
|
|
77270
77338
|
init_path_resolver();
|
|
77271
77339
|
import { existsSync as existsSync44 } from "node:fs";
|
|
77272
77340
|
import { readFile as readFile31 } from "node:fs/promises";
|
|
77273
|
-
import { join as
|
|
77341
|
+
import { join as join58 } from "node:path";
|
|
77274
77342
|
async function checkSettingsValid(projectDir) {
|
|
77275
|
-
const globalSettings =
|
|
77276
|
-
const projectSettings =
|
|
77343
|
+
const globalSettings = join58(PathResolver.getGlobalKitDir(), "settings.json");
|
|
77344
|
+
const projectSettings = join58(projectDir, ".claude", "settings.json");
|
|
77277
77345
|
const settingsPath = existsSync44(globalSettings) ? globalSettings : existsSync44(projectSettings) ? projectSettings : null;
|
|
77278
77346
|
if (!settingsPath) {
|
|
77279
77347
|
return {
|
|
@@ -77345,11 +77413,11 @@ init_logger();
|
|
|
77345
77413
|
init_path_resolver();
|
|
77346
77414
|
import { existsSync as existsSync45 } from "node:fs";
|
|
77347
77415
|
import { readFile as readFile32 } from "node:fs/promises";
|
|
77348
|
-
import { homedir as
|
|
77349
|
-
import { dirname as dirname19, join as
|
|
77416
|
+
import { homedir as homedir29 } from "node:os";
|
|
77417
|
+
import { dirname as dirname19, join as join59, normalize as normalize5, resolve as resolve14 } from "node:path";
|
|
77350
77418
|
async function checkPathRefsValid(projectDir) {
|
|
77351
|
-
const globalClaudeMd =
|
|
77352
|
-
const projectClaudeMd =
|
|
77419
|
+
const globalClaudeMd = join59(PathResolver.getGlobalKitDir(), "CLAUDE.md");
|
|
77420
|
+
const projectClaudeMd = join59(projectDir, ".claude", "CLAUDE.md");
|
|
77353
77421
|
const claudeMdPath = existsSync45(globalClaudeMd) ? globalClaudeMd : existsSync45(projectClaudeMd) ? projectClaudeMd : null;
|
|
77354
77422
|
if (!claudeMdPath) {
|
|
77355
77423
|
return {
|
|
@@ -77378,7 +77446,7 @@ async function checkPathRefsValid(projectDir) {
|
|
|
77378
77446
|
};
|
|
77379
77447
|
}
|
|
77380
77448
|
const baseDir = dirname19(claudeMdPath);
|
|
77381
|
-
const home8 =
|
|
77449
|
+
const home8 = homedir29();
|
|
77382
77450
|
const broken = [];
|
|
77383
77451
|
for (const ref of refs) {
|
|
77384
77452
|
let refPath;
|
|
@@ -77444,7 +77512,7 @@ async function checkPathRefsValid(projectDir) {
|
|
|
77444
77512
|
// src/domains/health-checks/checkers/config-completeness-checker.ts
|
|
77445
77513
|
import { existsSync as existsSync46 } from "node:fs";
|
|
77446
77514
|
import { readdir as readdir11 } from "node:fs/promises";
|
|
77447
|
-
import { join as
|
|
77515
|
+
import { join as join60 } from "node:path";
|
|
77448
77516
|
async function checkProjectConfigCompleteness(setup, projectDir) {
|
|
77449
77517
|
if (setup.project.path === setup.global.path) {
|
|
77450
77518
|
return {
|
|
@@ -77457,16 +77525,16 @@ async function checkProjectConfigCompleteness(setup, projectDir) {
|
|
|
77457
77525
|
autoFixable: false
|
|
77458
77526
|
};
|
|
77459
77527
|
}
|
|
77460
|
-
const projectClaudeDir =
|
|
77528
|
+
const projectClaudeDir = join60(projectDir, ".claude");
|
|
77461
77529
|
const requiredDirs = ["agents", "commands", "skills"];
|
|
77462
77530
|
const missingDirs = [];
|
|
77463
77531
|
for (const dir of requiredDirs) {
|
|
77464
|
-
const dirPath =
|
|
77532
|
+
const dirPath = join60(projectClaudeDir, dir);
|
|
77465
77533
|
if (!existsSync46(dirPath)) {
|
|
77466
77534
|
missingDirs.push(dir);
|
|
77467
77535
|
}
|
|
77468
77536
|
}
|
|
77469
|
-
const hasRulesOrWorkflows = existsSync46(
|
|
77537
|
+
const hasRulesOrWorkflows = existsSync46(join60(projectClaudeDir, "rules")) || existsSync46(join60(projectClaudeDir, "workflows"));
|
|
77470
77538
|
if (!hasRulesOrWorkflows) {
|
|
77471
77539
|
missingDirs.push("rules");
|
|
77472
77540
|
}
|
|
@@ -77511,7 +77579,7 @@ async function checkProjectConfigCompleteness(setup, projectDir) {
|
|
|
77511
77579
|
};
|
|
77512
77580
|
}
|
|
77513
77581
|
// src/domains/health-checks/checkers/env-keys-checker.ts
|
|
77514
|
-
import { join as
|
|
77582
|
+
import { join as join62 } from "node:path";
|
|
77515
77583
|
|
|
77516
77584
|
// src/domains/installation/setup-wizard.ts
|
|
77517
77585
|
init_config_generator();
|
|
@@ -77520,7 +77588,7 @@ init_logger();
|
|
|
77520
77588
|
init_path_resolver();
|
|
77521
77589
|
init_dist2();
|
|
77522
77590
|
var import_fs_extra6 = __toESM(require_lib3(), 1);
|
|
77523
|
-
import { join as
|
|
77591
|
+
import { join as join61 } from "node:path";
|
|
77524
77592
|
var REQUIRED_ENV_KEYS = [
|
|
77525
77593
|
{ key: "GEMINI_API_KEY", label: "Gemini API Key" }
|
|
77526
77594
|
];
|
|
@@ -77597,7 +77665,7 @@ async function parseEnvFile(path5) {
|
|
|
77597
77665
|
}
|
|
77598
77666
|
}
|
|
77599
77667
|
async function checkGlobalConfig() {
|
|
77600
|
-
const globalEnvPath =
|
|
77668
|
+
const globalEnvPath = join61(PathResolver.getGlobalKitDir(), ".env");
|
|
77601
77669
|
if (!await import_fs_extra6.pathExists(globalEnvPath))
|
|
77602
77670
|
return false;
|
|
77603
77671
|
const env2 = await parseEnvFile(globalEnvPath);
|
|
@@ -77613,7 +77681,7 @@ async function runSetupWizard(options2) {
|
|
|
77613
77681
|
let globalEnv = {};
|
|
77614
77682
|
const hasGlobalConfig = !isGlobal && await checkGlobalConfig();
|
|
77615
77683
|
if (!isGlobal) {
|
|
77616
|
-
const globalEnvPath =
|
|
77684
|
+
const globalEnvPath = join61(PathResolver.getGlobalKitDir(), ".env");
|
|
77617
77685
|
if (await import_fs_extra6.pathExists(globalEnvPath)) {
|
|
77618
77686
|
globalEnv = await parseEnvFile(globalEnvPath);
|
|
77619
77687
|
}
|
|
@@ -77676,7 +77744,7 @@ async function runSetupWizard(options2) {
|
|
|
77676
77744
|
}
|
|
77677
77745
|
}
|
|
77678
77746
|
await generateEnvFile(targetDir, values);
|
|
77679
|
-
f2.success(`Configuration saved to ${
|
|
77747
|
+
f2.success(`Configuration saved to ${join61(targetDir, ".env")}`);
|
|
77680
77748
|
return true;
|
|
77681
77749
|
}
|
|
77682
77750
|
async function promptForAdditionalGeminiKeys(primaryKey) {
|
|
@@ -77751,7 +77819,7 @@ Optional: DISCORD_WEBHOOK_URL, TELEGRAM_BOT_TOKEN`, "Configuration skipped");
|
|
|
77751
77819
|
async function checkEnvKeys(setup) {
|
|
77752
77820
|
const results = [];
|
|
77753
77821
|
if (setup.global.path) {
|
|
77754
|
-
const globalEnvPath =
|
|
77822
|
+
const globalEnvPath = join62(setup.global.path, ".env");
|
|
77755
77823
|
const globalCheck = await checkRequiredKeysExist(globalEnvPath);
|
|
77756
77824
|
if (!globalCheck.allPresent) {
|
|
77757
77825
|
const missingKeys = globalCheck.missing.map((m2) => m2.label).join(", ");
|
|
@@ -77780,7 +77848,7 @@ async function checkEnvKeys(setup) {
|
|
|
77780
77848
|
}
|
|
77781
77849
|
}
|
|
77782
77850
|
if (setup.project.metadata) {
|
|
77783
|
-
const projectEnvPath =
|
|
77851
|
+
const projectEnvPath = join62(setup.project.path, ".env");
|
|
77784
77852
|
const projectCheck = await checkRequiredKeysExist(projectEnvPath);
|
|
77785
77853
|
if (!projectCheck.allPresent) {
|
|
77786
77854
|
const missingKeys = projectCheck.missing.map((m2) => m2.label).join(", ");
|
|
@@ -77811,14 +77879,16 @@ async function checkEnvKeys(setup) {
|
|
|
77811
77879
|
return results;
|
|
77812
77880
|
}
|
|
77813
77881
|
// src/domains/health-checks/checkers/hook-health-checker.ts
|
|
77882
|
+
init_settings_merger();
|
|
77814
77883
|
init_claudekit_constants();
|
|
77884
|
+
init_command_normalizer();
|
|
77815
77885
|
init_logger();
|
|
77816
77886
|
init_path_resolver();
|
|
77817
77887
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
77818
77888
|
import { existsSync as existsSync47, readFileSync as readFileSync12, statSync as statSync6, writeFileSync as writeFileSync4 } from "node:fs";
|
|
77819
77889
|
import { readdir as readdir12 } from "node:fs/promises";
|
|
77820
|
-
import { tmpdir } from "node:os";
|
|
77821
|
-
import { join as
|
|
77890
|
+
import { homedir as homedir30, tmpdir } from "node:os";
|
|
77891
|
+
import { join as join63, resolve as resolve15 } from "node:path";
|
|
77822
77892
|
var HOOK_CHECK_TIMEOUT_MS = 5000;
|
|
77823
77893
|
var PYTHON_CHECK_TIMEOUT_MS = 3000;
|
|
77824
77894
|
var MAX_LOG_FILE_SIZE_BYTES = 10 * 1024 * 1024;
|
|
@@ -77834,6 +77904,117 @@ function getHooksDir(projectDir) {
|
|
|
77834
77904
|
function isPathWithin(filePath, parentDir) {
|
|
77835
77905
|
return resolve15(filePath).startsWith(resolve15(parentDir));
|
|
77836
77906
|
}
|
|
77907
|
+
function getCanonicalGlobalCommandRoot() {
|
|
77908
|
+
const configuredGlobalDir = PathResolver.getGlobalKitDir().replace(/\\/g, "/").replace(/\/+$/, "");
|
|
77909
|
+
const defaultGlobalDir = join63(homedir30(), ".claude").replace(/\\/g, "/");
|
|
77910
|
+
return configuredGlobalDir === defaultGlobalDir ? "$HOME" : configuredGlobalDir;
|
|
77911
|
+
}
|
|
77912
|
+
function getClaudeSettingsFiles(projectDir) {
|
|
77913
|
+
const globalClaudeDir = PathResolver.getGlobalKitDir();
|
|
77914
|
+
const candidates = [
|
|
77915
|
+
{
|
|
77916
|
+
path: resolve15(projectDir, ".claude", "settings.json"),
|
|
77917
|
+
label: "project settings.json",
|
|
77918
|
+
root: "$CLAUDE_PROJECT_DIR"
|
|
77919
|
+
},
|
|
77920
|
+
{
|
|
77921
|
+
path: resolve15(projectDir, ".claude", "settings.local.json"),
|
|
77922
|
+
label: "project settings.local.json",
|
|
77923
|
+
root: "$CLAUDE_PROJECT_DIR"
|
|
77924
|
+
},
|
|
77925
|
+
{
|
|
77926
|
+
path: resolve15(globalClaudeDir, "settings.json"),
|
|
77927
|
+
label: "global settings.json",
|
|
77928
|
+
root: getCanonicalGlobalCommandRoot()
|
|
77929
|
+
},
|
|
77930
|
+
{
|
|
77931
|
+
path: resolve15(globalClaudeDir, "settings.local.json"),
|
|
77932
|
+
label: "global settings.local.json",
|
|
77933
|
+
root: getCanonicalGlobalCommandRoot()
|
|
77934
|
+
}
|
|
77935
|
+
];
|
|
77936
|
+
return candidates.filter((candidate) => existsSync47(candidate.path));
|
|
77937
|
+
}
|
|
77938
|
+
function collectHookCommandFindings(settings, settingsFile) {
|
|
77939
|
+
if (!settings.hooks) {
|
|
77940
|
+
return [];
|
|
77941
|
+
}
|
|
77942
|
+
const findings = [];
|
|
77943
|
+
for (const [eventName, entries] of Object.entries(settings.hooks)) {
|
|
77944
|
+
for (const entry of entries) {
|
|
77945
|
+
if ("command" in entry && typeof entry.command === "string") {
|
|
77946
|
+
const repair = repairClaudeNodeCommandPath(entry.command, settingsFile.root);
|
|
77947
|
+
if (repair.changed && repair.issue) {
|
|
77948
|
+
findings.push({
|
|
77949
|
+
path: settingsFile.path,
|
|
77950
|
+
label: settingsFile.label,
|
|
77951
|
+
eventName,
|
|
77952
|
+
command: entry.command,
|
|
77953
|
+
expected: repair.command,
|
|
77954
|
+
issue: repair.issue
|
|
77955
|
+
});
|
|
77956
|
+
}
|
|
77957
|
+
}
|
|
77958
|
+
if (!("hooks" in entry) || !entry.hooks) {
|
|
77959
|
+
continue;
|
|
77960
|
+
}
|
|
77961
|
+
for (const hook of entry.hooks) {
|
|
77962
|
+
if (!hook.command) {
|
|
77963
|
+
continue;
|
|
77964
|
+
}
|
|
77965
|
+
const repair = repairClaudeNodeCommandPath(hook.command, settingsFile.root);
|
|
77966
|
+
if (!repair.changed || !repair.issue) {
|
|
77967
|
+
continue;
|
|
77968
|
+
}
|
|
77969
|
+
findings.push({
|
|
77970
|
+
path: settingsFile.path,
|
|
77971
|
+
label: settingsFile.label,
|
|
77972
|
+
eventName,
|
|
77973
|
+
matcher: "matcher" in entry ? entry.matcher : undefined,
|
|
77974
|
+
command: hook.command,
|
|
77975
|
+
expected: repair.command,
|
|
77976
|
+
issue: repair.issue
|
|
77977
|
+
});
|
|
77978
|
+
}
|
|
77979
|
+
}
|
|
77980
|
+
}
|
|
77981
|
+
return findings;
|
|
77982
|
+
}
|
|
77983
|
+
async function repairHookCommandsInSettingsFile(settingsFile) {
|
|
77984
|
+
const settings = await SettingsMerger.readSettingsFile(settingsFile.path);
|
|
77985
|
+
if (!settings?.hooks) {
|
|
77986
|
+
return 0;
|
|
77987
|
+
}
|
|
77988
|
+
let repaired = 0;
|
|
77989
|
+
for (const entries of Object.values(settings.hooks)) {
|
|
77990
|
+
for (const entry of entries) {
|
|
77991
|
+
if ("command" in entry && typeof entry.command === "string") {
|
|
77992
|
+
const repair = repairClaudeNodeCommandPath(entry.command, settingsFile.root);
|
|
77993
|
+
if (repair.changed) {
|
|
77994
|
+
entry.command = repair.command;
|
|
77995
|
+
repaired++;
|
|
77996
|
+
}
|
|
77997
|
+
}
|
|
77998
|
+
if (!("hooks" in entry) || !entry.hooks) {
|
|
77999
|
+
continue;
|
|
78000
|
+
}
|
|
78001
|
+
for (const hook of entry.hooks) {
|
|
78002
|
+
if (!hook.command) {
|
|
78003
|
+
continue;
|
|
78004
|
+
}
|
|
78005
|
+
const repair = repairClaudeNodeCommandPath(hook.command, settingsFile.root);
|
|
78006
|
+
if (repair.changed) {
|
|
78007
|
+
hook.command = repair.command;
|
|
78008
|
+
repaired++;
|
|
78009
|
+
}
|
|
78010
|
+
}
|
|
78011
|
+
}
|
|
78012
|
+
}
|
|
78013
|
+
if (repaired > 0) {
|
|
78014
|
+
await SettingsMerger.writeSettingsFile(settingsFile.path, settings);
|
|
78015
|
+
}
|
|
78016
|
+
return repaired;
|
|
78017
|
+
}
|
|
77837
78018
|
async function checkHookSyntax(projectDir) {
|
|
77838
78019
|
const hooksDir = getHooksDir(projectDir);
|
|
77839
78020
|
if (!hooksDir) {
|
|
@@ -77863,7 +78044,7 @@ async function checkHookSyntax(projectDir) {
|
|
|
77863
78044
|
}
|
|
77864
78045
|
const errors2 = [];
|
|
77865
78046
|
for (const file of cjsFiles) {
|
|
77866
|
-
const filePath =
|
|
78047
|
+
const filePath = join63(hooksDir, file);
|
|
77867
78048
|
if (!isPathWithin(filePath, hooksDir))
|
|
77868
78049
|
continue;
|
|
77869
78050
|
const result = spawnSync2("node", ["--check", filePath], {
|
|
@@ -77949,7 +78130,7 @@ async function checkHookDeps(projectDir) {
|
|
|
77949
78130
|
const missingDeps = [];
|
|
77950
78131
|
const requireRegex = /require\(['"]([^'"]+)['"]\)/g;
|
|
77951
78132
|
for (const file of cjsFiles) {
|
|
77952
|
-
const filePath =
|
|
78133
|
+
const filePath = join63(hooksDir, file);
|
|
77953
78134
|
if (!isPathWithin(filePath, hooksDir))
|
|
77954
78135
|
continue;
|
|
77955
78136
|
const content = readFileSync12(filePath, "utf-8");
|
|
@@ -77959,10 +78140,10 @@ async function checkHookDeps(projectDir) {
|
|
|
77959
78140
|
continue;
|
|
77960
78141
|
}
|
|
77961
78142
|
if (depPath.startsWith(".")) {
|
|
77962
|
-
const resolvedPath =
|
|
78143
|
+
const resolvedPath = join63(hooksDir, depPath);
|
|
77963
78144
|
const extensions = [".js", ".cjs", ".mjs", ".json"];
|
|
77964
78145
|
const indexFiles = ["index.js", "index.cjs", "index.mjs"];
|
|
77965
|
-
const exists = existsSync47(resolvedPath) || extensions.some((ext) => existsSync47(resolvedPath + ext)) || indexFiles.some((idx) => existsSync47(
|
|
78146
|
+
const exists = existsSync47(resolvedPath) || extensions.some((ext) => existsSync47(resolvedPath + ext)) || indexFiles.some((idx) => existsSync47(join63(resolvedPath, idx)));
|
|
77966
78147
|
if (!exists) {
|
|
77967
78148
|
missingDeps.push(`${file}: ${depPath}`);
|
|
77968
78149
|
}
|
|
@@ -78079,11 +78260,11 @@ async function checkHookRuntime(projectDir) {
|
|
|
78079
78260
|
}
|
|
78080
78261
|
const syntheticPayload = JSON.stringify({
|
|
78081
78262
|
tool_name: "Read",
|
|
78082
|
-
tool_input: { file_path:
|
|
78263
|
+
tool_input: { file_path: join63(tmpdir(), "ck-doctor-test.txt") }
|
|
78083
78264
|
});
|
|
78084
78265
|
const failures = [];
|
|
78085
78266
|
for (const file of cjsFiles) {
|
|
78086
|
-
const filePath =
|
|
78267
|
+
const filePath = join63(hooksDir, file);
|
|
78087
78268
|
if (!isPathWithin(filePath, hooksDir))
|
|
78088
78269
|
continue;
|
|
78089
78270
|
const result = spawnSync2("node", [filePath], {
|
|
@@ -78144,9 +78325,85 @@ async function checkHookRuntime(projectDir) {
|
|
|
78144
78325
|
};
|
|
78145
78326
|
}
|
|
78146
78327
|
}
|
|
78328
|
+
async function checkHookCommandPaths(projectDir) {
|
|
78329
|
+
const settingsFiles = getClaudeSettingsFiles(projectDir);
|
|
78330
|
+
if (settingsFiles.length === 0) {
|
|
78331
|
+
return {
|
|
78332
|
+
id: "hook-command-paths",
|
|
78333
|
+
name: "Hook Command Paths",
|
|
78334
|
+
group: "claudekit",
|
|
78335
|
+
priority: "standard",
|
|
78336
|
+
status: "info",
|
|
78337
|
+
message: "No Claude settings files",
|
|
78338
|
+
autoFixable: false
|
|
78339
|
+
};
|
|
78340
|
+
}
|
|
78341
|
+
const findings = [];
|
|
78342
|
+
for (const settingsFile of settingsFiles) {
|
|
78343
|
+
const settings = await SettingsMerger.readSettingsFile(settingsFile.path);
|
|
78344
|
+
if (!settings) {
|
|
78345
|
+
continue;
|
|
78346
|
+
}
|
|
78347
|
+
findings.push(...collectHookCommandFindings(settings, settingsFile));
|
|
78348
|
+
}
|
|
78349
|
+
if (findings.length === 0) {
|
|
78350
|
+
return {
|
|
78351
|
+
id: "hook-command-paths",
|
|
78352
|
+
name: "Hook Command Paths",
|
|
78353
|
+
group: "claudekit",
|
|
78354
|
+
priority: "standard",
|
|
78355
|
+
status: "pass",
|
|
78356
|
+
message: `${settingsFiles.length} settings file(s) canonical`,
|
|
78357
|
+
autoFixable: false
|
|
78358
|
+
};
|
|
78359
|
+
}
|
|
78360
|
+
const details = findings.slice(0, 5).map((finding) => {
|
|
78361
|
+
const matcher = finding.matcher ? ` [${finding.matcher}]` : "";
|
|
78362
|
+
return `${finding.label} :: ${finding.eventName}${matcher} :: ${finding.issue} :: ${finding.command}`;
|
|
78363
|
+
}).join(`
|
|
78364
|
+
`);
|
|
78365
|
+
return {
|
|
78366
|
+
id: "hook-command-paths",
|
|
78367
|
+
name: "Hook Command Paths",
|
|
78368
|
+
group: "claudekit",
|
|
78369
|
+
priority: "standard",
|
|
78370
|
+
status: "fail",
|
|
78371
|
+
message: `${findings.length} stale hook command path(s)`,
|
|
78372
|
+
details,
|
|
78373
|
+
suggestion: "Run: ck doctor --fix",
|
|
78374
|
+
autoFixable: true,
|
|
78375
|
+
fix: {
|
|
78376
|
+
id: "fix-hook-command-paths",
|
|
78377
|
+
description: "Canonicalize stale .claude hook command paths in settings files",
|
|
78378
|
+
execute: async () => {
|
|
78379
|
+
try {
|
|
78380
|
+
let repaired = 0;
|
|
78381
|
+
for (const settingsFile of settingsFiles) {
|
|
78382
|
+
repaired += await repairHookCommandsInSettingsFile(settingsFile);
|
|
78383
|
+
}
|
|
78384
|
+
if (repaired === 0) {
|
|
78385
|
+
return {
|
|
78386
|
+
success: true,
|
|
78387
|
+
message: "No stale hook command paths needed repair"
|
|
78388
|
+
};
|
|
78389
|
+
}
|
|
78390
|
+
return {
|
|
78391
|
+
success: true,
|
|
78392
|
+
message: `Repaired ${repaired} stale hook command path(s)`
|
|
78393
|
+
};
|
|
78394
|
+
} catch (error) {
|
|
78395
|
+
return {
|
|
78396
|
+
success: false,
|
|
78397
|
+
message: `Failed to repair hook command paths: ${error}`
|
|
78398
|
+
};
|
|
78399
|
+
}
|
|
78400
|
+
}
|
|
78401
|
+
}
|
|
78402
|
+
};
|
|
78403
|
+
}
|
|
78147
78404
|
async function checkHookConfig(projectDir) {
|
|
78148
|
-
const projectConfigPath =
|
|
78149
|
-
const globalConfigPath =
|
|
78405
|
+
const projectConfigPath = join63(projectDir, ".claude", ".ck.json");
|
|
78406
|
+
const globalConfigPath = join63(PathResolver.getGlobalKitDir(), ".ck.json");
|
|
78150
78407
|
const configPath = existsSync47(projectConfigPath) ? projectConfigPath : existsSync47(globalConfigPath) ? globalConfigPath : null;
|
|
78151
78408
|
if (!configPath) {
|
|
78152
78409
|
return {
|
|
@@ -78270,7 +78527,7 @@ async function checkHookLogs(projectDir) {
|
|
|
78270
78527
|
autoFixable: false
|
|
78271
78528
|
};
|
|
78272
78529
|
}
|
|
78273
|
-
const logPath =
|
|
78530
|
+
const logPath = join63(hooksDir, ".logs", "hook-log.jsonl");
|
|
78274
78531
|
if (!existsSync47(logPath)) {
|
|
78275
78532
|
return {
|
|
78276
78533
|
id: "hook-logs",
|
|
@@ -78525,9 +78782,9 @@ async function checkCliVersion() {
|
|
|
78525
78782
|
}
|
|
78526
78783
|
async function checkPythonVenv(projectDir) {
|
|
78527
78784
|
const isWindows3 = process.platform === "win32";
|
|
78528
|
-
const venvBin = isWindows3 ?
|
|
78529
|
-
const projectVenvPath =
|
|
78530
|
-
const globalVenvPath =
|
|
78785
|
+
const venvBin = isWindows3 ? join63("Scripts", "python.exe") : join63("bin", "python3");
|
|
78786
|
+
const projectVenvPath = join63(projectDir, ".claude", "skills", ".venv", venvBin);
|
|
78787
|
+
const globalVenvPath = join63(PathResolver.getGlobalKitDir(), "skills", ".venv", venvBin);
|
|
78531
78788
|
const venvPath = existsSync47(projectVenvPath) ? projectVenvPath : existsSync47(globalVenvPath) ? globalVenvPath : null;
|
|
78532
78789
|
if (!venvPath) {
|
|
78533
78790
|
return {
|
|
@@ -78643,6 +78900,8 @@ class ClaudekitChecker {
|
|
|
78643
78900
|
results.push(await checkHookDeps(this.projectDir));
|
|
78644
78901
|
logger.verbose("ClaudekitChecker: Checking hook runtime");
|
|
78645
78902
|
results.push(await checkHookRuntime(this.projectDir));
|
|
78903
|
+
logger.verbose("ClaudekitChecker: Checking hook command paths");
|
|
78904
|
+
results.push(await checkHookCommandPaths(this.projectDir));
|
|
78646
78905
|
logger.verbose("ClaudekitChecker: Checking hook config");
|
|
78647
78906
|
results.push(await checkHookConfig(this.projectDir));
|
|
78648
78907
|
logger.verbose("ClaudekitChecker: Checking hook crash logs");
|
|
@@ -79007,8 +79266,8 @@ import { platform as platform6 } from "node:os";
|
|
|
79007
79266
|
init_environment();
|
|
79008
79267
|
init_path_resolver();
|
|
79009
79268
|
import { constants as constants3, access as access3, mkdir as mkdir14, readFile as readFile34, unlink as unlink8, writeFile as writeFile17 } from "node:fs/promises";
|
|
79010
|
-
import { arch as arch2, homedir as
|
|
79011
|
-
import { join as
|
|
79269
|
+
import { arch as arch2, homedir as homedir31, platform as platform5 } from "node:os";
|
|
79270
|
+
import { join as join65, normalize as normalize6 } from "node:path";
|
|
79012
79271
|
function shouldSkipExpensiveOperations4() {
|
|
79013
79272
|
return shouldSkipExpensiveOperations();
|
|
79014
79273
|
}
|
|
@@ -79030,7 +79289,7 @@ async function checkPlatformDetect() {
|
|
|
79030
79289
|
};
|
|
79031
79290
|
}
|
|
79032
79291
|
async function checkHomeDirResolution() {
|
|
79033
|
-
const nodeHome = normalize6(
|
|
79292
|
+
const nodeHome = normalize6(homedir31());
|
|
79034
79293
|
const rawEnvHome = getHomeDirectoryFromEnv(platform5());
|
|
79035
79294
|
const envHome = rawEnvHome ? normalize6(rawEnvHome) : "";
|
|
79036
79295
|
const match = nodeHome === envHome && envHome !== "";
|
|
@@ -79099,7 +79358,7 @@ async function checkGlobalDirAccess() {
|
|
|
79099
79358
|
autoFixable: false
|
|
79100
79359
|
};
|
|
79101
79360
|
}
|
|
79102
|
-
const testFile =
|
|
79361
|
+
const testFile = join65(globalDir, ".ck-doctor-access-test");
|
|
79103
79362
|
try {
|
|
79104
79363
|
await mkdir14(globalDir, { recursive: true });
|
|
79105
79364
|
await writeFile17(testFile, "test", "utf-8");
|
|
@@ -79177,7 +79436,7 @@ async function checkWSLBoundary() {
|
|
|
79177
79436
|
// src/domains/health-checks/platform/windows-checker.ts
|
|
79178
79437
|
init_path_resolver();
|
|
79179
79438
|
import { mkdir as mkdir15, symlink, unlink as unlink9, writeFile as writeFile18 } from "node:fs/promises";
|
|
79180
|
-
import { join as
|
|
79439
|
+
import { join as join66 } from "node:path";
|
|
79181
79440
|
async function checkLongPathSupport() {
|
|
79182
79441
|
if (shouldSkipExpensiveOperations4()) {
|
|
79183
79442
|
return {
|
|
@@ -79229,8 +79488,8 @@ async function checkSymlinkSupport() {
|
|
|
79229
79488
|
};
|
|
79230
79489
|
}
|
|
79231
79490
|
const testDir = PathResolver.getGlobalKitDir();
|
|
79232
|
-
const target =
|
|
79233
|
-
const link =
|
|
79491
|
+
const target = join66(testDir, ".ck-symlink-test-target");
|
|
79492
|
+
const link = join66(testDir, ".ck-symlink-test-link");
|
|
79234
79493
|
try {
|
|
79235
79494
|
await mkdir15(testDir, { recursive: true });
|
|
79236
79495
|
await writeFile18(target, "test", "utf-8");
|
|
@@ -79524,7 +79783,7 @@ class AutoHealer {
|
|
|
79524
79783
|
import { execSync as execSync3, spawnSync as spawnSync5 } from "node:child_process";
|
|
79525
79784
|
import { readFileSync as readFileSync13, unlinkSync, writeFileSync as writeFileSync5 } from "node:fs";
|
|
79526
79785
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
79527
|
-
import { dirname as dirname20, join as
|
|
79786
|
+
import { dirname as dirname20, join as join67 } from "node:path";
|
|
79528
79787
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
79529
79788
|
init_environment();
|
|
79530
79789
|
init_logger();
|
|
@@ -79532,7 +79791,7 @@ init_dist2();
|
|
|
79532
79791
|
function getCliVersion4() {
|
|
79533
79792
|
try {
|
|
79534
79793
|
const __dirname4 = dirname20(fileURLToPath4(import.meta.url));
|
|
79535
|
-
const pkgPath =
|
|
79794
|
+
const pkgPath = join67(__dirname4, "../../../package.json");
|
|
79536
79795
|
const pkg = JSON.parse(readFileSync13(pkgPath, "utf-8"));
|
|
79537
79796
|
return pkg.version || "unknown";
|
|
79538
79797
|
} catch (err) {
|
|
@@ -79671,7 +79930,7 @@ class ReportGenerator {
|
|
|
79671
79930
|
return null;
|
|
79672
79931
|
}
|
|
79673
79932
|
}
|
|
79674
|
-
const tmpFile =
|
|
79933
|
+
const tmpFile = join67(tmpdir3(), `ck-report-${Date.now()}.txt`);
|
|
79675
79934
|
writeFileSync5(tmpFile, report);
|
|
79676
79935
|
try {
|
|
79677
79936
|
const result = spawnSync5("gh", ["gist", "create", tmpFile, "--desc", "ClaudeKit Diagnostic Report"], {
|
|
@@ -79997,7 +80256,7 @@ init_claudekit_constants();
|
|
|
79997
80256
|
init_logger();
|
|
79998
80257
|
init_path_resolver();
|
|
79999
80258
|
import { mkdir as mkdir16, readFile as readFile35, unlink as unlink10, writeFile as writeFile19 } from "node:fs/promises";
|
|
80000
|
-
import { join as
|
|
80259
|
+
import { join as join68 } from "node:path";
|
|
80001
80260
|
var CACHE_TTL_HOURS = 24;
|
|
80002
80261
|
var DEFAULT_CACHE_TTL_MS = CACHE_TTL_HOURS * 60 * 60 * 1000;
|
|
80003
80262
|
var MIN_CACHE_TTL_MS = 60 * 1000;
|
|
@@ -80034,7 +80293,7 @@ var KIT_REPOS = {
|
|
|
80034
80293
|
class ConfigVersionChecker {
|
|
80035
80294
|
static getCacheFilePath(kitType, global3) {
|
|
80036
80295
|
const cacheDir = PathResolver.getCacheDir(global3);
|
|
80037
|
-
return
|
|
80296
|
+
return join68(cacheDir, `${kitType}-${CACHE_FILENAME}`);
|
|
80038
80297
|
}
|
|
80039
80298
|
static async loadCache(kitType, global3) {
|
|
80040
80299
|
try {
|
|
@@ -80197,7 +80456,7 @@ class ConfigVersionChecker {
|
|
|
80197
80456
|
}
|
|
80198
80457
|
// src/domains/sync/sync-engine.ts
|
|
80199
80458
|
import { lstat as lstat3, readFile as readFile36, readlink, realpath as realpath3, stat as stat9 } from "node:fs/promises";
|
|
80200
|
-
import { isAbsolute as isAbsolute3, join as
|
|
80459
|
+
import { isAbsolute as isAbsolute3, join as join69, normalize as normalize7, relative as relative8 } from "node:path";
|
|
80201
80460
|
|
|
80202
80461
|
// src/services/file-operations/ownership-checker.ts
|
|
80203
80462
|
init_metadata_migration();
|
|
@@ -81558,7 +81817,7 @@ async function validateSymlinkChain(path6, basePath, maxDepth = MAX_SYMLINK_DEPT
|
|
|
81558
81817
|
if (!stats.isSymbolicLink())
|
|
81559
81818
|
break;
|
|
81560
81819
|
const target = await readlink(current);
|
|
81561
|
-
const resolvedTarget = isAbsolute3(target) ? target :
|
|
81820
|
+
const resolvedTarget = isAbsolute3(target) ? target : join69(current, "..", target);
|
|
81562
81821
|
const normalizedTarget = normalize7(resolvedTarget);
|
|
81563
81822
|
const rel = relative8(basePath, normalizedTarget);
|
|
81564
81823
|
if (rel.startsWith("..") || isAbsolute3(rel)) {
|
|
@@ -81594,7 +81853,7 @@ async function validateSyncPath(basePath, filePath) {
|
|
|
81594
81853
|
if (normalized.startsWith("..") || normalized.includes("/../")) {
|
|
81595
81854
|
throw new Error(`Path traversal not allowed: ${filePath}`);
|
|
81596
81855
|
}
|
|
81597
|
-
const fullPath =
|
|
81856
|
+
const fullPath = join69(basePath, normalized);
|
|
81598
81857
|
const rel = relative8(basePath, fullPath);
|
|
81599
81858
|
if (rel.startsWith("..") || isAbsolute3(rel)) {
|
|
81600
81859
|
throw new Error(`Path escapes base directory: ${filePath}`);
|
|
@@ -81609,7 +81868,7 @@ async function validateSyncPath(basePath, filePath) {
|
|
|
81609
81868
|
}
|
|
81610
81869
|
} catch (error) {
|
|
81611
81870
|
if (error.code === "ENOENT") {
|
|
81612
|
-
const parentPath =
|
|
81871
|
+
const parentPath = join69(fullPath, "..");
|
|
81613
81872
|
try {
|
|
81614
81873
|
const resolvedBase = await realpath3(basePath);
|
|
81615
81874
|
const resolvedParent = await realpath3(parentPath);
|
|
@@ -82828,7 +83087,7 @@ init_logger();
|
|
|
82828
83087
|
var import_proper_lockfile4 = __toESM(require_proper_lockfile(), 1);
|
|
82829
83088
|
import { mkdir as mkdir19 } from "node:fs/promises";
|
|
82830
83089
|
import os5 from "node:os";
|
|
82831
|
-
import { join as
|
|
83090
|
+
import { join as join76 } from "node:path";
|
|
82832
83091
|
var LOCK_CONFIG = {
|
|
82833
83092
|
stale: 60000,
|
|
82834
83093
|
retries: 0
|
|
@@ -82836,12 +83095,12 @@ var LOCK_CONFIG = {
|
|
|
82836
83095
|
var activeLocks = new Set;
|
|
82837
83096
|
var cleanupRegistered = false;
|
|
82838
83097
|
function getLocksDir() {
|
|
82839
|
-
return
|
|
83098
|
+
return join76(os5.homedir(), ".claudekit", "locks");
|
|
82840
83099
|
}
|
|
82841
83100
|
function cleanupLocks() {
|
|
82842
83101
|
for (const name of activeLocks) {
|
|
82843
83102
|
try {
|
|
82844
|
-
const lockPath =
|
|
83103
|
+
const lockPath = join76(getLocksDir(), `${name}.lock`);
|
|
82845
83104
|
import_proper_lockfile4.default.unlockSync(lockPath, { realpath: false });
|
|
82846
83105
|
} catch {
|
|
82847
83106
|
try {
|
|
@@ -82864,7 +83123,7 @@ async function ensureLocksDir() {
|
|
|
82864
83123
|
async function withProcessLock(lockName, fn) {
|
|
82865
83124
|
registerCleanupHandlers();
|
|
82866
83125
|
await ensureLocksDir();
|
|
82867
|
-
const lockPath =
|
|
83126
|
+
const lockPath = join76(getLocksDir(), `${lockName}.lock`);
|
|
82868
83127
|
let release;
|
|
82869
83128
|
try {
|
|
82870
83129
|
release = await import_proper_lockfile4.default.lock(lockPath, { ...LOCK_CONFIG, realpath: false });
|
|
@@ -82896,7 +83155,7 @@ init_logger();
|
|
|
82896
83155
|
init_logger();
|
|
82897
83156
|
init_path_resolver();
|
|
82898
83157
|
var import_fs_extra7 = __toESM(require_lib3(), 1);
|
|
82899
|
-
import { join as
|
|
83158
|
+
import { join as join77 } from "node:path";
|
|
82900
83159
|
async function handleConflicts(ctx) {
|
|
82901
83160
|
if (ctx.cancelled)
|
|
82902
83161
|
return ctx;
|
|
@@ -82905,7 +83164,7 @@ async function handleConflicts(ctx) {
|
|
|
82905
83164
|
if (PathResolver.isLocalSameAsGlobal()) {
|
|
82906
83165
|
return ctx;
|
|
82907
83166
|
}
|
|
82908
|
-
const localSettingsPath =
|
|
83167
|
+
const localSettingsPath = join77(process.cwd(), ".claude", "settings.json");
|
|
82909
83168
|
if (!await import_fs_extra7.pathExists(localSettingsPath)) {
|
|
82910
83169
|
return ctx;
|
|
82911
83170
|
}
|
|
@@ -82920,7 +83179,7 @@ async function handleConflicts(ctx) {
|
|
|
82920
83179
|
return { ...ctx, cancelled: true };
|
|
82921
83180
|
}
|
|
82922
83181
|
if (choice === "remove") {
|
|
82923
|
-
const localClaudeDir =
|
|
83182
|
+
const localClaudeDir = join77(process.cwd(), ".claude");
|
|
82924
83183
|
try {
|
|
82925
83184
|
await import_fs_extra7.remove(localClaudeDir);
|
|
82926
83185
|
logger.success("Removed local .claude/ directory");
|
|
@@ -83017,7 +83276,7 @@ init_logger();
|
|
|
83017
83276
|
init_safe_spinner();
|
|
83018
83277
|
import { mkdir as mkdir25, stat as stat12 } from "node:fs/promises";
|
|
83019
83278
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
83020
|
-
import { join as
|
|
83279
|
+
import { join as join84 } from "node:path";
|
|
83021
83280
|
|
|
83022
83281
|
// src/shared/temp-cleanup.ts
|
|
83023
83282
|
init_logger();
|
|
@@ -83036,7 +83295,7 @@ init_logger();
|
|
|
83036
83295
|
init_output_manager();
|
|
83037
83296
|
import { createWriteStream as createWriteStream2, rmSync as rmSync2 } from "node:fs";
|
|
83038
83297
|
import { mkdir as mkdir20 } from "node:fs/promises";
|
|
83039
|
-
import { join as
|
|
83298
|
+
import { join as join78 } from "node:path";
|
|
83040
83299
|
|
|
83041
83300
|
// src/shared/progress-bar.ts
|
|
83042
83301
|
init_output_manager();
|
|
@@ -83246,7 +83505,7 @@ var MAX_DOWNLOAD_SIZE = 500 * 1024 * 1024;
|
|
|
83246
83505
|
class FileDownloader {
|
|
83247
83506
|
async downloadAsset(asset, destDir) {
|
|
83248
83507
|
try {
|
|
83249
|
-
const destPath =
|
|
83508
|
+
const destPath = join78(destDir, asset.name);
|
|
83250
83509
|
await mkdir20(destDir, { recursive: true });
|
|
83251
83510
|
output.info(`Downloading ${asset.name} (${formatBytes(asset.size)})...`);
|
|
83252
83511
|
logger.verbose("Download details", {
|
|
@@ -83331,7 +83590,7 @@ class FileDownloader {
|
|
|
83331
83590
|
}
|
|
83332
83591
|
async downloadFile(params) {
|
|
83333
83592
|
const { url, name, size, destDir, token } = params;
|
|
83334
|
-
const destPath =
|
|
83593
|
+
const destPath = join78(destDir, name);
|
|
83335
83594
|
await mkdir20(destDir, { recursive: true });
|
|
83336
83595
|
output.info(`Downloading ${name}${size ? ` (${formatBytes(size)})` : ""}...`);
|
|
83337
83596
|
const headers = {};
|
|
@@ -83417,7 +83676,7 @@ init_logger();
|
|
|
83417
83676
|
init_types3();
|
|
83418
83677
|
import { constants as constants4 } from "node:fs";
|
|
83419
83678
|
import { access as access4, readdir as readdir13 } from "node:fs/promises";
|
|
83420
|
-
import { join as
|
|
83679
|
+
import { join as join79 } from "node:path";
|
|
83421
83680
|
async function validateExtraction(extractDir) {
|
|
83422
83681
|
try {
|
|
83423
83682
|
const entries = await readdir13(extractDir, { encoding: "utf8" });
|
|
@@ -83429,7 +83688,7 @@ async function validateExtraction(extractDir) {
|
|
|
83429
83688
|
const missingPaths = [];
|
|
83430
83689
|
for (const path6 of criticalPaths) {
|
|
83431
83690
|
try {
|
|
83432
|
-
await access4(
|
|
83691
|
+
await access4(join79(extractDir, path6), constants4.F_OK);
|
|
83433
83692
|
logger.debug(`Found: ${path6}`);
|
|
83434
83693
|
} catch {
|
|
83435
83694
|
logger.warning(`Expected path not found: ${path6}`);
|
|
@@ -83451,7 +83710,7 @@ async function validateExtraction(extractDir) {
|
|
|
83451
83710
|
// src/domains/installation/extraction/tar-extractor.ts
|
|
83452
83711
|
init_logger();
|
|
83453
83712
|
import { copyFile as copyFile4, mkdir as mkdir23, readdir as readdir15, rm as rm9, stat as stat10 } from "node:fs/promises";
|
|
83454
|
-
import { join as
|
|
83713
|
+
import { join as join82 } from "node:path";
|
|
83455
83714
|
|
|
83456
83715
|
// node_modules/@isaacs/fs-minipass/dist/esm/index.js
|
|
83457
83716
|
import EE from "events";
|
|
@@ -89213,7 +89472,7 @@ var mkdirSync3 = (dir, opt) => {
|
|
|
89213
89472
|
};
|
|
89214
89473
|
|
|
89215
89474
|
// node_modules/tar/dist/esm/path-reservations.js
|
|
89216
|
-
import { join as
|
|
89475
|
+
import { join as join80 } from "node:path";
|
|
89217
89476
|
|
|
89218
89477
|
// node_modules/tar/dist/esm/normalize-unicode.js
|
|
89219
89478
|
var normalizeCache = Object.create(null);
|
|
@@ -89246,7 +89505,7 @@ var getDirs = (path11) => {
|
|
|
89246
89505
|
const dirs = path11.split("/").slice(0, -1).reduce((set, path12) => {
|
|
89247
89506
|
const s = set[set.length - 1];
|
|
89248
89507
|
if (s !== undefined) {
|
|
89249
|
-
path12 =
|
|
89508
|
+
path12 = join80(s, path12);
|
|
89250
89509
|
}
|
|
89251
89510
|
set.push(path12 || "/");
|
|
89252
89511
|
return set;
|
|
@@ -89260,7 +89519,7 @@ class PathReservations {
|
|
|
89260
89519
|
#running = new Set;
|
|
89261
89520
|
reserve(paths, fn) {
|
|
89262
89521
|
paths = isWindows4 ? ["win32 parallelization disabled"] : paths.map((p) => {
|
|
89263
|
-
return stripTrailingSlashes(
|
|
89522
|
+
return stripTrailingSlashes(join80(normalizeUnicode(p))).toLowerCase();
|
|
89264
89523
|
});
|
|
89265
89524
|
const dirs = new Set(paths.map((path11) => getDirs(path11)).reduce((a3, b3) => a3.concat(b3)));
|
|
89266
89525
|
this.#reservations.set(fn, { dirs, paths });
|
|
@@ -90320,7 +90579,7 @@ function decodeFilePath(path13) {
|
|
|
90320
90579
|
init_logger();
|
|
90321
90580
|
init_types3();
|
|
90322
90581
|
import { copyFile as copyFile3, lstat as lstat4, mkdir as mkdir22, readdir as readdir14 } from "node:fs/promises";
|
|
90323
|
-
import { join as
|
|
90582
|
+
import { join as join81, relative as relative10 } from "node:path";
|
|
90324
90583
|
async function withRetry(fn, retries = 3) {
|
|
90325
90584
|
for (let i = 0;i < retries; i++) {
|
|
90326
90585
|
try {
|
|
@@ -90342,8 +90601,8 @@ async function moveDirectoryContents(sourceDir, destDir, shouldExclude, sizeTrac
|
|
|
90342
90601
|
await mkdir22(destDir, { recursive: true });
|
|
90343
90602
|
const entries = await readdir14(sourceDir, { encoding: "utf8" });
|
|
90344
90603
|
for (const entry of entries) {
|
|
90345
|
-
const sourcePath =
|
|
90346
|
-
const destPath =
|
|
90604
|
+
const sourcePath = join81(sourceDir, entry);
|
|
90605
|
+
const destPath = join81(destDir, entry);
|
|
90347
90606
|
const relativePath = relative10(sourceDir, sourcePath);
|
|
90348
90607
|
if (!isPathSafe(destDir, destPath)) {
|
|
90349
90608
|
logger.warning(`Skipping unsafe path: ${relativePath}`);
|
|
@@ -90370,8 +90629,8 @@ async function copyDirectory(sourceDir, destDir, shouldExclude, sizeTracker) {
|
|
|
90370
90629
|
await mkdir22(destDir, { recursive: true });
|
|
90371
90630
|
const entries = await readdir14(sourceDir, { encoding: "utf8" });
|
|
90372
90631
|
for (const entry of entries) {
|
|
90373
|
-
const sourcePath =
|
|
90374
|
-
const destPath =
|
|
90632
|
+
const sourcePath = join81(sourceDir, entry);
|
|
90633
|
+
const destPath = join81(destDir, entry);
|
|
90375
90634
|
const relativePath = relative10(sourceDir, sourcePath);
|
|
90376
90635
|
if (!isPathSafe(destDir, destPath)) {
|
|
90377
90636
|
logger.warning(`Skipping unsafe path: ${relativePath}`);
|
|
@@ -90419,7 +90678,7 @@ class TarExtractor {
|
|
|
90419
90678
|
logger.debug(`Root entries: ${entries.join(", ")}`);
|
|
90420
90679
|
if (entries.length === 1) {
|
|
90421
90680
|
const rootEntry = entries[0];
|
|
90422
|
-
const rootPath =
|
|
90681
|
+
const rootPath = join82(tempExtractDir, rootEntry);
|
|
90423
90682
|
const rootStat = await stat10(rootPath);
|
|
90424
90683
|
if (rootStat.isDirectory()) {
|
|
90425
90684
|
const rootContents = await readdir15(rootPath, { encoding: "utf8" });
|
|
@@ -90435,7 +90694,7 @@ class TarExtractor {
|
|
|
90435
90694
|
}
|
|
90436
90695
|
} else {
|
|
90437
90696
|
await mkdir23(destDir, { recursive: true });
|
|
90438
|
-
await copyFile4(rootPath,
|
|
90697
|
+
await copyFile4(rootPath, join82(destDir, rootEntry));
|
|
90439
90698
|
}
|
|
90440
90699
|
} else {
|
|
90441
90700
|
logger.debug("Multiple root entries - moving all");
|
|
@@ -90458,7 +90717,7 @@ init_logger();
|
|
|
90458
90717
|
var import_extract_zip = __toESM(require_extract_zip(), 1);
|
|
90459
90718
|
import { execFile as execFile8 } from "node:child_process";
|
|
90460
90719
|
import { copyFile as copyFile5, mkdir as mkdir24, readdir as readdir16, rm as rm10, stat as stat11 } from "node:fs/promises";
|
|
90461
|
-
import { join as
|
|
90720
|
+
import { join as join83 } from "node:path";
|
|
90462
90721
|
class ZipExtractor {
|
|
90463
90722
|
async tryNativeUnzip(archivePath, destDir) {
|
|
90464
90723
|
if (!isMacOS()) {
|
|
@@ -90506,7 +90765,7 @@ class ZipExtractor {
|
|
|
90506
90765
|
logger.debug(`Root entries: ${entries.join(", ")}`);
|
|
90507
90766
|
if (entries.length === 1) {
|
|
90508
90767
|
const rootEntry = entries[0];
|
|
90509
|
-
const rootPath =
|
|
90768
|
+
const rootPath = join83(tempExtractDir, rootEntry);
|
|
90510
90769
|
const rootStat = await stat11(rootPath);
|
|
90511
90770
|
if (rootStat.isDirectory()) {
|
|
90512
90771
|
const rootContents = await readdir16(rootPath, { encoding: "utf8" });
|
|
@@ -90522,7 +90781,7 @@ class ZipExtractor {
|
|
|
90522
90781
|
}
|
|
90523
90782
|
} else {
|
|
90524
90783
|
await mkdir24(destDir, { recursive: true });
|
|
90525
|
-
await copyFile5(rootPath,
|
|
90784
|
+
await copyFile5(rootPath, join83(destDir, rootEntry));
|
|
90526
90785
|
}
|
|
90527
90786
|
} else {
|
|
90528
90787
|
logger.debug("Multiple root entries - moving all");
|
|
@@ -90621,7 +90880,7 @@ class DownloadManager {
|
|
|
90621
90880
|
async createTempDir() {
|
|
90622
90881
|
const timestamp = Date.now();
|
|
90623
90882
|
const counter = DownloadManager.tempDirCounter++;
|
|
90624
|
-
const primaryTempDir =
|
|
90883
|
+
const primaryTempDir = join84(tmpdir4(), `claudekit-${timestamp}-${counter}`);
|
|
90625
90884
|
try {
|
|
90626
90885
|
await mkdir25(primaryTempDir, { recursive: true });
|
|
90627
90886
|
logger.debug(`Created temp directory: ${primaryTempDir}`);
|
|
@@ -90638,7 +90897,7 @@ Solutions:
|
|
|
90638
90897
|
2. Set HOME environment variable
|
|
90639
90898
|
3. Try running from a different directory`);
|
|
90640
90899
|
}
|
|
90641
|
-
const fallbackTempDir =
|
|
90900
|
+
const fallbackTempDir = join84(homeDir, ".claudekit", "tmp", `claudekit-${timestamp}-${counter}`);
|
|
90642
90901
|
try {
|
|
90643
90902
|
await mkdir25(fallbackTempDir, { recursive: true });
|
|
90644
90903
|
logger.debug(`Created temp directory (fallback): ${fallbackTempDir}`);
|
|
@@ -91058,20 +91317,20 @@ async function handleDownload(ctx) {
|
|
|
91058
91317
|
};
|
|
91059
91318
|
}
|
|
91060
91319
|
// src/commands/init/phases/merge-handler.ts
|
|
91061
|
-
import { join as
|
|
91320
|
+
import { join as join101 } from "node:path";
|
|
91062
91321
|
|
|
91063
91322
|
// src/domains/installation/deletion-handler.ts
|
|
91064
91323
|
import { existsSync as existsSync53, lstatSync as lstatSync3, readdirSync as readdirSync4, rmSync as rmSync3, rmdirSync, unlinkSync as unlinkSync3 } from "node:fs";
|
|
91065
|
-
import { dirname as dirname25, join as
|
|
91324
|
+
import { dirname as dirname25, join as join87, relative as relative11, resolve as resolve20, sep as sep6 } from "node:path";
|
|
91066
91325
|
|
|
91067
91326
|
// src/services/file-operations/manifest/manifest-reader.ts
|
|
91068
91327
|
init_metadata_migration();
|
|
91069
91328
|
init_logger();
|
|
91070
91329
|
init_types3();
|
|
91071
91330
|
var import_fs_extra8 = __toESM(require_lib3(), 1);
|
|
91072
|
-
import { join as
|
|
91331
|
+
import { join as join86 } from "node:path";
|
|
91073
91332
|
async function readManifest(claudeDir2) {
|
|
91074
|
-
const metadataPath =
|
|
91333
|
+
const metadataPath = join86(claudeDir2, "metadata.json");
|
|
91075
91334
|
if (!await import_fs_extra8.pathExists(metadataPath)) {
|
|
91076
91335
|
return null;
|
|
91077
91336
|
}
|
|
@@ -91257,7 +91516,7 @@ function collectFilesRecursively(dir, baseDir) {
|
|
|
91257
91516
|
try {
|
|
91258
91517
|
const entries = readdirSync4(dir, { withFileTypes: true });
|
|
91259
91518
|
for (const entry of entries) {
|
|
91260
|
-
const fullPath =
|
|
91519
|
+
const fullPath = join87(dir, entry.name);
|
|
91261
91520
|
const relativePath = relative11(baseDir, fullPath);
|
|
91262
91521
|
if (entry.isDirectory()) {
|
|
91263
91522
|
results.push(...collectFilesRecursively(fullPath, baseDir));
|
|
@@ -91325,7 +91584,7 @@ function deletePath(fullPath, claudeDir2) {
|
|
|
91325
91584
|
}
|
|
91326
91585
|
}
|
|
91327
91586
|
async function updateMetadataAfterDeletion(claudeDir2, deletedPaths) {
|
|
91328
|
-
const metadataPath =
|
|
91587
|
+
const metadataPath = join87(claudeDir2, "metadata.json");
|
|
91329
91588
|
if (!await import_fs_extra9.pathExists(metadataPath)) {
|
|
91330
91589
|
return;
|
|
91331
91590
|
}
|
|
@@ -91380,7 +91639,7 @@ async function handleDeletions(sourceMetadata, claudeDir2, kitType) {
|
|
|
91380
91639
|
const userMetadata = await readManifest(claudeDir2);
|
|
91381
91640
|
const result = { deletedPaths: [], preservedPaths: [], errors: [] };
|
|
91382
91641
|
for (const path14 of deletions) {
|
|
91383
|
-
const fullPath =
|
|
91642
|
+
const fullPath = join87(claudeDir2, path14);
|
|
91384
91643
|
const normalizedPath = resolve20(fullPath);
|
|
91385
91644
|
const normalizedClaudeDir = resolve20(claudeDir2);
|
|
91386
91645
|
if (!normalizedPath.startsWith(`${normalizedClaudeDir}${sep6}`)) {
|
|
@@ -91420,7 +91679,7 @@ init_logger();
|
|
|
91420
91679
|
init_types3();
|
|
91421
91680
|
var import_fs_extra12 = __toESM(require_lib3(), 1);
|
|
91422
91681
|
var import_ignore3 = __toESM(require_ignore(), 1);
|
|
91423
|
-
import { dirname as
|
|
91682
|
+
import { dirname as dirname28, join as join91, relative as relative13 } from "node:path";
|
|
91424
91683
|
|
|
91425
91684
|
// src/domains/installation/selective-merger.ts
|
|
91426
91685
|
import { stat as stat13 } from "node:fs/promises";
|
|
@@ -91599,7 +91858,7 @@ init_logger();
|
|
|
91599
91858
|
var import_fs_extra10 = __toESM(require_lib3(), 1);
|
|
91600
91859
|
var import_ignore2 = __toESM(require_ignore(), 1);
|
|
91601
91860
|
import { relative as relative12 } from "node:path";
|
|
91602
|
-
import { join as
|
|
91861
|
+
import { join as join88 } from "node:path";
|
|
91603
91862
|
|
|
91604
91863
|
// node_modules/@isaacs/balanced-match/dist/esm/index.js
|
|
91605
91864
|
var balanced = (a3, b3, str2) => {
|
|
@@ -93055,7 +93314,7 @@ class FileScanner {
|
|
|
93055
93314
|
const files = [];
|
|
93056
93315
|
const entries = await import_fs_extra10.readdir(dir, { encoding: "utf8" });
|
|
93057
93316
|
for (const entry of entries) {
|
|
93058
|
-
const fullPath =
|
|
93317
|
+
const fullPath = join88(dir, entry);
|
|
93059
93318
|
const relativePath = relative12(baseDir, fullPath);
|
|
93060
93319
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
93061
93320
|
const stats = await import_fs_extra10.lstat(fullPath);
|
|
@@ -93090,12 +93349,14 @@ class FileScanner {
|
|
|
93090
93349
|
|
|
93091
93350
|
// src/domains/installation/merger/settings-processor.ts
|
|
93092
93351
|
import { execSync as execSync4 } from "node:child_process";
|
|
93352
|
+
import { homedir as homedir33 } from "node:os";
|
|
93353
|
+
import { dirname as dirname27, join as join90 } from "node:path";
|
|
93093
93354
|
|
|
93094
93355
|
// src/domains/config/installed-settings-tracker.ts
|
|
93095
93356
|
init_shared();
|
|
93096
93357
|
import { existsSync as existsSync54 } from "node:fs";
|
|
93097
93358
|
import { mkdir as mkdir26, readFile as readFile40, writeFile as writeFile22 } from "node:fs/promises";
|
|
93098
|
-
import { dirname as dirname26, join as
|
|
93359
|
+
import { dirname as dirname26, join as join89 } from "node:path";
|
|
93099
93360
|
var CK_JSON_FILE = ".ck.json";
|
|
93100
93361
|
|
|
93101
93362
|
class InstalledSettingsTracker {
|
|
@@ -93109,9 +93370,9 @@ class InstalledSettingsTracker {
|
|
|
93109
93370
|
}
|
|
93110
93371
|
getCkJsonPath() {
|
|
93111
93372
|
if (this.isGlobal) {
|
|
93112
|
-
return
|
|
93373
|
+
return join89(this.projectDir, CK_JSON_FILE);
|
|
93113
93374
|
}
|
|
93114
|
-
return
|
|
93375
|
+
return join89(this.projectDir, ".claude", CK_JSON_FILE);
|
|
93115
93376
|
}
|
|
93116
93377
|
async loadInstalledSettings() {
|
|
93117
93378
|
const ckJsonPath = this.getCkJsonPath();
|
|
@@ -93186,7 +93447,9 @@ class InstalledSettingsTracker {
|
|
|
93186
93447
|
|
|
93187
93448
|
// src/domains/installation/merger/settings-processor.ts
|
|
93188
93449
|
init_settings_merger();
|
|
93450
|
+
init_command_normalizer();
|
|
93189
93451
|
init_logger();
|
|
93452
|
+
init_path_resolver();
|
|
93190
93453
|
var import_fs_extra11 = __toESM(require_lib3(), 1);
|
|
93191
93454
|
var import_semver3 = __toESM(require_semver2(), 1);
|
|
93192
93455
|
|
|
@@ -93230,16 +93493,15 @@ class SettingsProcessor {
|
|
|
93230
93493
|
const sourceContent = await import_fs_extra11.readFile(sourceFile, "utf-8");
|
|
93231
93494
|
let transformedSource = sourceContent;
|
|
93232
93495
|
if (this.isGlobal) {
|
|
93233
|
-
const
|
|
93234
|
-
transformedSource = this.transformClaudePaths(sourceContent,
|
|
93496
|
+
const globalRoot = this.getCanonicalGlobalCommandRoot();
|
|
93497
|
+
transformedSource = this.transformClaudePaths(sourceContent, globalRoot);
|
|
93235
93498
|
if (transformedSource !== sourceContent) {
|
|
93236
|
-
logger.debug(`Transformed .claude/ paths to ${
|
|
93499
|
+
logger.debug(`Transformed .claude/ paths to ${globalRoot} in settings.json for global installation`);
|
|
93237
93500
|
}
|
|
93238
93501
|
} else {
|
|
93239
|
-
|
|
93240
|
-
transformedSource = this.transformClaudePaths(sourceContent, projectDirVar);
|
|
93502
|
+
transformedSource = this.transformClaudePaths(sourceContent, "$CLAUDE_PROJECT_DIR");
|
|
93241
93503
|
if (transformedSource !== sourceContent) {
|
|
93242
|
-
logger.debug(
|
|
93504
|
+
logger.debug('Transformed .claude/ paths to "$CLAUDE_PROJECT_DIR"/.claude/ in settings.json for local installation');
|
|
93243
93505
|
}
|
|
93244
93506
|
}
|
|
93245
93507
|
const destExists = await import_fs_extra11.pathExists(destFile);
|
|
@@ -93267,6 +93529,7 @@ class SettingsProcessor {
|
|
|
93267
93529
|
}
|
|
93268
93530
|
await this.injectTeamHooksIfSupported(destFile);
|
|
93269
93531
|
}
|
|
93532
|
+
await this.repairSiblingSettingsLocal(destFile);
|
|
93270
93533
|
} catch (error) {
|
|
93271
93534
|
logger.error(`Failed to process settings.json: ${error}`);
|
|
93272
93535
|
await import_fs_extra11.copy(sourceFile, destFile, { overwrite: true });
|
|
@@ -93471,36 +93734,27 @@ class SettingsProcessor {
|
|
|
93471
93734
|
const content = await import_fs_extra11.readFile(destFile, "utf-8");
|
|
93472
93735
|
if (!content.trim())
|
|
93473
93736
|
return null;
|
|
93474
|
-
const
|
|
93475
|
-
|
|
93476
|
-
|
|
93477
|
-
normalized = normalized.replace(/\$CLAUDE_PROJECT_DIR/g, homeVar);
|
|
93478
|
-
normalized = normalized.replace(/"%CLAUDE_PROJECT_DIR%"/g, `"${homeVar}"`);
|
|
93479
|
-
normalized = normalized.replace(/%CLAUDE_PROJECT_DIR%/g, homeVar);
|
|
93480
|
-
normalized = normalized.replace(/"%USERPROFILE%"/g, `"${homeVar}"`);
|
|
93481
|
-
normalized = normalized.replace(/%USERPROFILE%/g, homeVar);
|
|
93482
|
-
if (normalized !== content) {
|
|
93483
|
-
logger.debug("Normalized $CLAUDE_PROJECT_DIR paths to $HOME in existing global settings");
|
|
93484
|
-
}
|
|
93485
|
-
return JSON.parse(normalized);
|
|
93737
|
+
const parsedSettings = JSON.parse(content);
|
|
93738
|
+
this.fixHookCommandPaths(parsedSettings);
|
|
93739
|
+
return parsedSettings;
|
|
93486
93740
|
} catch {
|
|
93487
93741
|
return null;
|
|
93488
93742
|
}
|
|
93489
93743
|
}
|
|
93490
|
-
transformClaudePaths(content,
|
|
93744
|
+
transformClaudePaths(content, root) {
|
|
93491
93745
|
if (/\.claude\/[^\s"']*[;`$&|><]/.test(content)) {
|
|
93492
93746
|
logger.warning("Potentially unsafe characters detected in .claude/ paths");
|
|
93493
93747
|
throw new Error("Settings file contains potentially unsafe path characters");
|
|
93494
93748
|
}
|
|
93495
93749
|
let transformed = content;
|
|
93496
|
-
const rawPrefix = prefix.replace(/"/g, "");
|
|
93497
93750
|
transformed = transformed.replace(/(node\s+)(?:\.\/)?(\.claude\/[^\s"\\]+)([^"\\]*)/g, (_match, nodePrefix, relativePath, suffix) => {
|
|
93498
|
-
|
|
93499
|
-
return rawPrefix === "$CLAUDE_PROJECT_DIR" ? `${nodePrefix}\\"${rawPrefix}\\"/${normalizedRelativePath}${suffix}` : `${nodePrefix}\\"${rawPrefix}/${normalizedRelativePath}\\"${suffix}`;
|
|
93751
|
+
return this.formatCommandPath(nodePrefix, root, relativePath, suffix).replace(/"/g, "\\\"");
|
|
93500
93752
|
});
|
|
93501
|
-
if (
|
|
93502
|
-
transformed = transformed.replace(
|
|
93503
|
-
transformed = transformed.replace(
|
|
93753
|
+
if (this.isGlobal) {
|
|
93754
|
+
transformed = transformed.replace(/"\$CLAUDE_PROJECT_DIR"/g, `"${root}"`);
|
|
93755
|
+
transformed = transformed.replace(/\$CLAUDE_PROJECT_DIR/g, root);
|
|
93756
|
+
transformed = transformed.replace(/"%CLAUDE_PROJECT_DIR%"/g, `"${root}"`);
|
|
93757
|
+
transformed = transformed.replace(/%CLAUDE_PROJECT_DIR%/g, root);
|
|
93504
93758
|
}
|
|
93505
93759
|
return transformed;
|
|
93506
93760
|
}
|
|
@@ -93541,48 +93795,71 @@ class SettingsProcessor {
|
|
|
93541
93795
|
return fixed;
|
|
93542
93796
|
}
|
|
93543
93797
|
fixSingleCommandPath(cmd) {
|
|
93544
|
-
|
|
93545
|
-
return cmd;
|
|
93546
|
-
const bareRelativeMatch = cmd.match(/^(node\s+)(?:\.\/)?(\.claude[/\\][^\s"]+)(.*)$/);
|
|
93547
|
-
if (bareRelativeMatch) {
|
|
93548
|
-
const [, nodePrefix, relativePath, suffix] = bareRelativeMatch;
|
|
93549
|
-
return this.formatCommandPath(nodePrefix, this.isGlobal ? "$HOME" : "$CLAUDE_PROJECT_DIR", relativePath, suffix);
|
|
93550
|
-
}
|
|
93551
|
-
const embeddedQuotedMatch = cmd.match(/^(node\s+)"(\$HOME|\$CLAUDE_PROJECT_DIR|%USERPROFILE%|%CLAUDE_PROJECT_DIR%)[/\\](\.claude[/\\][^"]+)"(.*)$/);
|
|
93552
|
-
if (embeddedQuotedMatch) {
|
|
93553
|
-
const [, nodePrefix, capturedVar, relativePath, suffix] = embeddedQuotedMatch;
|
|
93554
|
-
return this.formatCommandPath(nodePrefix, capturedVar, relativePath, suffix);
|
|
93555
|
-
}
|
|
93556
|
-
const varOnlyQuotedMatch = cmd.match(/^(node\s+)"(\$HOME|\$CLAUDE_PROJECT_DIR|%USERPROFILE%|%CLAUDE_PROJECT_DIR%)"[/\\](\.claude[/\\][^\s"]+)(.*)$/);
|
|
93557
|
-
if (varOnlyQuotedMatch) {
|
|
93558
|
-
const [, nodePrefix, capturedVar, relativePath, suffix] = varOnlyQuotedMatch;
|
|
93559
|
-
return this.formatCommandPath(nodePrefix, capturedVar, relativePath, suffix);
|
|
93560
|
-
}
|
|
93561
|
-
const tildeMatch = cmd.match(/^(node\s+)~[/\\](\.claude[/\\][^\s"]+)(.*)$/);
|
|
93562
|
-
if (tildeMatch) {
|
|
93563
|
-
const [, nodePrefix, relativePath, suffix] = tildeMatch;
|
|
93564
|
-
return this.formatCommandPath(nodePrefix, "$HOME", relativePath, suffix);
|
|
93565
|
-
}
|
|
93566
|
-
const unquotedMatch = cmd.match(/^(node\s+)(\$HOME|\$CLAUDE_PROJECT_DIR|%USERPROFILE%|%CLAUDE_PROJECT_DIR%)[/\\](\.claude[/\\][^\s"]+)(.*)$/);
|
|
93567
|
-
if (unquotedMatch) {
|
|
93568
|
-
const [, nodePrefix, capturedVar, relativePath, suffix] = unquotedMatch;
|
|
93569
|
-
return this.formatCommandPath(nodePrefix, capturedVar, relativePath, suffix);
|
|
93570
|
-
}
|
|
93571
|
-
return cmd;
|
|
93798
|
+
return repairClaudeNodeCommandPath(cmd, this.getClaudeCommandRoot()).command;
|
|
93572
93799
|
}
|
|
93573
93800
|
formatCommandPath(nodePrefix, capturedVar, relativePath, suffix = "") {
|
|
93574
|
-
const
|
|
93575
|
-
const normalizedRelativePath =
|
|
93576
|
-
return
|
|
93801
|
+
const canonicalRoot = this.canonicalizePathRoot(capturedVar);
|
|
93802
|
+
const normalizedRelativePath = this.normalizeRelativePath(canonicalRoot, relativePath);
|
|
93803
|
+
return canonicalRoot === "$CLAUDE_PROJECT_DIR" ? `${nodePrefix}"${canonicalRoot}"/${normalizedRelativePath}${suffix}` : `${nodePrefix}"${canonicalRoot}/${normalizedRelativePath}"${suffix}`;
|
|
93577
93804
|
}
|
|
93578
|
-
|
|
93805
|
+
canonicalizePathRoot(capturedVar) {
|
|
93579
93806
|
switch (capturedVar) {
|
|
93580
93807
|
case "%USERPROFILE%":
|
|
93581
|
-
|
|
93808
|
+
case "$HOME":
|
|
93809
|
+
return this.isGlobal ? this.getCanonicalGlobalCommandRoot() : "$HOME";
|
|
93582
93810
|
case "%CLAUDE_PROJECT_DIR%":
|
|
93583
|
-
|
|
93811
|
+
case "$CLAUDE_PROJECT_DIR":
|
|
93812
|
+
return this.isGlobal ? this.getCanonicalGlobalCommandRoot() : "$CLAUDE_PROJECT_DIR";
|
|
93584
93813
|
default:
|
|
93585
|
-
return capturedVar;
|
|
93814
|
+
return capturedVar.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
93815
|
+
}
|
|
93816
|
+
}
|
|
93817
|
+
normalizeRelativePath(root, relativePath) {
|
|
93818
|
+
const normalizedRelativePath = relativePath.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
93819
|
+
if (root !== "$CLAUDE_PROJECT_DIR" && this.usesCustomGlobalInstallPath()) {
|
|
93820
|
+
return normalizedRelativePath.replace(/^\.claude\//, "");
|
|
93821
|
+
}
|
|
93822
|
+
return normalizedRelativePath;
|
|
93823
|
+
}
|
|
93824
|
+
getCanonicalGlobalCommandRoot() {
|
|
93825
|
+
if (this.usesCustomGlobalInstallPath()) {
|
|
93826
|
+
return PathResolver.getGlobalKitDir().replace(/\\/g, "/").replace(/\/+$/, "");
|
|
93827
|
+
}
|
|
93828
|
+
return "$HOME";
|
|
93829
|
+
}
|
|
93830
|
+
usesCustomGlobalInstallPath() {
|
|
93831
|
+
if (!this.isGlobal || !this.projectDir) {
|
|
93832
|
+
if (this.isGlobal && !this.projectDir) {
|
|
93833
|
+
logger.debug("usesCustomGlobalInstallPath: global mode but projectDir not set — defaulting to $HOME");
|
|
93834
|
+
}
|
|
93835
|
+
return false;
|
|
93836
|
+
}
|
|
93837
|
+
const configuredGlobalDir = PathResolver.getGlobalKitDir().replace(/\\/g, "/").replace(/\/+$/, "");
|
|
93838
|
+
const defaultGlobalDir = join90(homedir33(), ".claude").replace(/\\/g, "/");
|
|
93839
|
+
return configuredGlobalDir !== defaultGlobalDir;
|
|
93840
|
+
}
|
|
93841
|
+
getClaudeCommandRoot() {
|
|
93842
|
+
return this.isGlobal ? this.getCanonicalGlobalCommandRoot() : "$CLAUDE_PROJECT_DIR";
|
|
93843
|
+
}
|
|
93844
|
+
async repairSettingsFile(filePath) {
|
|
93845
|
+
const settings = await SettingsMerger.readSettingsFile(filePath);
|
|
93846
|
+
if (!settings) {
|
|
93847
|
+
return false;
|
|
93848
|
+
}
|
|
93849
|
+
const pathsFixed = this.fixHookCommandPaths(settings);
|
|
93850
|
+
if (!pathsFixed) {
|
|
93851
|
+
return false;
|
|
93852
|
+
}
|
|
93853
|
+
await SettingsMerger.writeSettingsFile(filePath, settings);
|
|
93854
|
+
return true;
|
|
93855
|
+
}
|
|
93856
|
+
async repairSiblingSettingsLocal(destFile) {
|
|
93857
|
+
const settingsLocalPath = join90(dirname27(destFile), "settings.local.json");
|
|
93858
|
+
if (settingsLocalPath === destFile || !await import_fs_extra11.pathExists(settingsLocalPath)) {
|
|
93859
|
+
return;
|
|
93860
|
+
}
|
|
93861
|
+
if (await this.repairSettingsFile(settingsLocalPath)) {
|
|
93862
|
+
logger.info(`Repaired stale .claude command paths in ${settingsLocalPath}`);
|
|
93586
93863
|
}
|
|
93587
93864
|
}
|
|
93588
93865
|
detectClaudeCodeVersion() {
|
|
@@ -93633,7 +93910,7 @@ class SettingsProcessor {
|
|
|
93633
93910
|
{ event: "TeammateIdle", handler: "teammate-idle-handler.cjs" }
|
|
93634
93911
|
];
|
|
93635
93912
|
for (const { event, handler } of teamHooks) {
|
|
93636
|
-
const hookCommand = this.formatCommandPath("node ", this.isGlobal ?
|
|
93913
|
+
const hookCommand = this.formatCommandPath("node ", this.isGlobal ? this.getCanonicalGlobalCommandRoot() : "$CLAUDE_PROJECT_DIR", `.claude/hooks/${handler}`);
|
|
93637
93914
|
const eventHooks = settings.hooks[event];
|
|
93638
93915
|
if (eventHooks && eventHooks.length > 0)
|
|
93639
93916
|
continue;
|
|
@@ -93740,7 +94017,7 @@ class CopyExecutor {
|
|
|
93740
94017
|
for (const file of files) {
|
|
93741
94018
|
const relativePath = relative13(sourceDir, file);
|
|
93742
94019
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
93743
|
-
const destPath =
|
|
94020
|
+
const destPath = join91(destDir, relativePath);
|
|
93744
94021
|
if (await import_fs_extra12.pathExists(destPath)) {
|
|
93745
94022
|
if (this.fileScanner.shouldNeverCopy(normalizedRelativePath)) {
|
|
93746
94023
|
logger.debug(`Security-sensitive file exists but won't be overwritten: ${normalizedRelativePath}`);
|
|
@@ -93762,7 +94039,7 @@ class CopyExecutor {
|
|
|
93762
94039
|
for (const file of files) {
|
|
93763
94040
|
const relativePath = relative13(sourceDir, file);
|
|
93764
94041
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
93765
|
-
const destPath =
|
|
94042
|
+
const destPath = join91(destDir, relativePath);
|
|
93766
94043
|
if (this.fileScanner.shouldNeverCopy(normalizedRelativePath)) {
|
|
93767
94044
|
logger.debug(`Skipping security-sensitive file: ${normalizedRelativePath}`);
|
|
93768
94045
|
skippedCount++;
|
|
@@ -93839,10 +94116,10 @@ class CopyExecutor {
|
|
|
93839
94116
|
}
|
|
93840
94117
|
trackInstalledFile(relativePath) {
|
|
93841
94118
|
this.installedFiles.add(relativePath);
|
|
93842
|
-
let dir =
|
|
94119
|
+
let dir = dirname28(relativePath);
|
|
93843
94120
|
while (dir && dir !== "." && dir !== "/") {
|
|
93844
94121
|
this.installedDirectories.add(`${dir}/`);
|
|
93845
|
-
dir =
|
|
94122
|
+
dir = dirname28(dir);
|
|
93846
94123
|
}
|
|
93847
94124
|
}
|
|
93848
94125
|
}
|
|
@@ -93935,15 +94212,15 @@ class FileMerger {
|
|
|
93935
94212
|
|
|
93936
94213
|
// src/domains/migration/legacy-migration.ts
|
|
93937
94214
|
import { readdir as readdir18, stat as stat14 } from "node:fs/promises";
|
|
93938
|
-
import { join as
|
|
94215
|
+
import { join as join95, relative as relative14 } from "node:path";
|
|
93939
94216
|
// src/services/file-operations/manifest/manifest-tracker.ts
|
|
93940
|
-
import { join as
|
|
94217
|
+
import { join as join94 } from "node:path";
|
|
93941
94218
|
|
|
93942
94219
|
// src/domains/migration/release-manifest.ts
|
|
93943
94220
|
init_logger();
|
|
93944
94221
|
init_zod();
|
|
93945
94222
|
var import_fs_extra13 = __toESM(require_lib3(), 1);
|
|
93946
|
-
import { join as
|
|
94223
|
+
import { join as join92 } from "node:path";
|
|
93947
94224
|
var ReleaseManifestFileSchema = exports_external.object({
|
|
93948
94225
|
path: exports_external.string(),
|
|
93949
94226
|
checksum: exports_external.string().regex(/^[a-f0-9]{64}$/),
|
|
@@ -93958,7 +94235,7 @@ var ReleaseManifestSchema = exports_external.object({
|
|
|
93958
94235
|
|
|
93959
94236
|
class ReleaseManifestLoader {
|
|
93960
94237
|
static async load(extractDir) {
|
|
93961
|
-
const manifestPath =
|
|
94238
|
+
const manifestPath = join92(extractDir, "release-manifest.json");
|
|
93962
94239
|
try {
|
|
93963
94240
|
const content = await import_fs_extra13.readFile(manifestPath, "utf-8");
|
|
93964
94241
|
const parsed = JSON.parse(content);
|
|
@@ -93984,9 +94261,9 @@ init_logger();
|
|
|
93984
94261
|
init_types3();
|
|
93985
94262
|
var import_fs_extra14 = __toESM(require_lib3(), 1);
|
|
93986
94263
|
var import_proper_lockfile5 = __toESM(require_proper_lockfile(), 1);
|
|
93987
|
-
import { join as
|
|
94264
|
+
import { join as join93 } from "node:path";
|
|
93988
94265
|
async function writeManifest(claudeDir2, kitName, version, scope, kitType, trackedFiles, userConfigFiles) {
|
|
93989
|
-
const metadataPath =
|
|
94266
|
+
const metadataPath = join93(claudeDir2, "metadata.json");
|
|
93990
94267
|
const kit = kitType || (/\bmarketing\b/i.test(kitName) ? "marketing" : "engineer");
|
|
93991
94268
|
await import_fs_extra14.ensureFile(metadataPath);
|
|
93992
94269
|
let release = null;
|
|
@@ -94042,7 +94319,7 @@ async function writeManifest(claudeDir2, kitName, version, scope, kitType, track
|
|
|
94042
94319
|
}
|
|
94043
94320
|
}
|
|
94044
94321
|
async function removeKitFromManifest(claudeDir2, kit) {
|
|
94045
|
-
const metadataPath =
|
|
94322
|
+
const metadataPath = join93(claudeDir2, "metadata.json");
|
|
94046
94323
|
if (!await import_fs_extra14.pathExists(metadataPath))
|
|
94047
94324
|
return false;
|
|
94048
94325
|
let release = null;
|
|
@@ -94075,7 +94352,7 @@ async function removeKitFromManifest(claudeDir2, kit) {
|
|
|
94075
94352
|
}
|
|
94076
94353
|
}
|
|
94077
94354
|
async function retainTrackedFilesInManifest(claudeDir2, retainedPaths, options2) {
|
|
94078
|
-
const metadataPath =
|
|
94355
|
+
const metadataPath = join93(claudeDir2, "metadata.json");
|
|
94079
94356
|
if (!await import_fs_extra14.pathExists(metadataPath))
|
|
94080
94357
|
return false;
|
|
94081
94358
|
const normalizedPaths = new Set(retainedPaths.map((path15) => path15.replace(/\\/g, "/")));
|
|
@@ -94258,7 +94535,7 @@ function buildFileTrackingList(options2) {
|
|
|
94258
94535
|
if (!isGlobal && !installedPath.startsWith(".claude/"))
|
|
94259
94536
|
continue;
|
|
94260
94537
|
const relativePath = isGlobal ? installedPath : installedPath.replace(/^\.claude\//, "");
|
|
94261
|
-
const filePath =
|
|
94538
|
+
const filePath = join94(claudeDir2, relativePath);
|
|
94262
94539
|
const manifestEntry = releaseManifest ? ReleaseManifestLoader.findFile(releaseManifest, installedPath) : null;
|
|
94263
94540
|
const ownership = manifestEntry ? "ck" : "user";
|
|
94264
94541
|
filesToTrack.push({
|
|
@@ -94368,7 +94645,7 @@ class LegacyMigration {
|
|
|
94368
94645
|
continue;
|
|
94369
94646
|
if (SKIP_DIRS_ALL.includes(entry))
|
|
94370
94647
|
continue;
|
|
94371
|
-
const fullPath =
|
|
94648
|
+
const fullPath = join95(dir, entry);
|
|
94372
94649
|
let stats;
|
|
94373
94650
|
try {
|
|
94374
94651
|
stats = await stat14(fullPath);
|
|
@@ -94470,7 +94747,7 @@ User-created files (sample):`);
|
|
|
94470
94747
|
];
|
|
94471
94748
|
if (filesToChecksum.length > 0) {
|
|
94472
94749
|
const checksumResults = await mapWithLimit(filesToChecksum, async ({ relativePath, ownership }) => {
|
|
94473
|
-
const fullPath =
|
|
94750
|
+
const fullPath = join95(claudeDir2, relativePath);
|
|
94474
94751
|
const checksum = await OwnershipChecker.calculateChecksum(fullPath);
|
|
94475
94752
|
return { relativePath, checksum, ownership };
|
|
94476
94753
|
});
|
|
@@ -94491,7 +94768,7 @@ User-created files (sample):`);
|
|
|
94491
94768
|
installedAt: new Date().toISOString(),
|
|
94492
94769
|
files: trackedFiles
|
|
94493
94770
|
};
|
|
94494
|
-
const metadataPath =
|
|
94771
|
+
const metadataPath = join95(claudeDir2, "metadata.json");
|
|
94495
94772
|
await import_fs_extra15.writeFile(metadataPath, JSON.stringify(updatedMetadata, null, 2));
|
|
94496
94773
|
logger.success(`Migration complete: tracked ${trackedFiles.length} files`);
|
|
94497
94774
|
return true;
|
|
@@ -94597,7 +94874,7 @@ function buildConflictSummary(fileConflicts, hookConflicts, mcpConflicts) {
|
|
|
94597
94874
|
init_logger();
|
|
94598
94875
|
init_skip_directories();
|
|
94599
94876
|
var import_fs_extra16 = __toESM(require_lib3(), 1);
|
|
94600
|
-
import { join as
|
|
94877
|
+
import { join as join96, relative as relative15, resolve as resolve21 } from "node:path";
|
|
94601
94878
|
|
|
94602
94879
|
class FileScanner2 {
|
|
94603
94880
|
static async getFiles(dirPath, relativeTo) {
|
|
@@ -94613,7 +94890,7 @@ class FileScanner2 {
|
|
|
94613
94890
|
logger.debug(`Skipping directory: ${entry}`);
|
|
94614
94891
|
continue;
|
|
94615
94892
|
}
|
|
94616
|
-
const fullPath =
|
|
94893
|
+
const fullPath = join96(dirPath, entry);
|
|
94617
94894
|
if (!FileScanner2.isSafePath(basePath, fullPath)) {
|
|
94618
94895
|
logger.warning(`Skipping potentially unsafe path: ${entry}`);
|
|
94619
94896
|
continue;
|
|
@@ -94648,8 +94925,8 @@ class FileScanner2 {
|
|
|
94648
94925
|
return files;
|
|
94649
94926
|
}
|
|
94650
94927
|
static async findCustomFiles(destDir, sourceDir, subPath) {
|
|
94651
|
-
const destSubDir =
|
|
94652
|
-
const sourceSubDir =
|
|
94928
|
+
const destSubDir = join96(destDir, subPath);
|
|
94929
|
+
const sourceSubDir = join96(sourceDir, subPath);
|
|
94653
94930
|
logger.debug(`findCustomFiles - destDir: ${destDir}`);
|
|
94654
94931
|
logger.debug(`findCustomFiles - sourceDir: ${sourceDir}`);
|
|
94655
94932
|
logger.debug(`findCustomFiles - subPath: "${subPath}"`);
|
|
@@ -94690,12 +94967,12 @@ class FileScanner2 {
|
|
|
94690
94967
|
init_logger();
|
|
94691
94968
|
var import_fs_extra17 = __toESM(require_lib3(), 1);
|
|
94692
94969
|
import { lstat as lstat7, mkdir as mkdir27, readdir as readdir21, stat as stat15 } from "node:fs/promises";
|
|
94693
|
-
import { join as
|
|
94970
|
+
import { join as join98 } from "node:path";
|
|
94694
94971
|
|
|
94695
94972
|
// src/services/transformers/commands-prefix/content-transformer.ts
|
|
94696
94973
|
init_logger();
|
|
94697
94974
|
import { readFile as readFile44, readdir as readdir20, writeFile as writeFile26 } from "node:fs/promises";
|
|
94698
|
-
import { join as
|
|
94975
|
+
import { join as join97 } from "node:path";
|
|
94699
94976
|
var TRANSFORMABLE_EXTENSIONS = new Set([
|
|
94700
94977
|
".md",
|
|
94701
94978
|
".txt",
|
|
@@ -94756,7 +95033,7 @@ async function transformCommandReferences(directory, options2 = {}) {
|
|
|
94756
95033
|
async function processDirectory(dir) {
|
|
94757
95034
|
const entries = await readdir20(dir, { withFileTypes: true });
|
|
94758
95035
|
for (const entry of entries) {
|
|
94759
|
-
const fullPath =
|
|
95036
|
+
const fullPath = join97(dir, entry.name);
|
|
94760
95037
|
if (entry.isDirectory()) {
|
|
94761
95038
|
if (entry.name === "node_modules" || entry.name.startsWith(".") && entry.name !== ".claude") {
|
|
94762
95039
|
continue;
|
|
@@ -94831,14 +95108,14 @@ function shouldApplyPrefix(options2) {
|
|
|
94831
95108
|
// src/services/transformers/commands-prefix/prefix-applier.ts
|
|
94832
95109
|
async function applyPrefix(extractDir) {
|
|
94833
95110
|
validatePath(extractDir, "extractDir");
|
|
94834
|
-
const commandsDir =
|
|
95111
|
+
const commandsDir = join98(extractDir, ".claude", "commands");
|
|
94835
95112
|
if (!await import_fs_extra17.pathExists(commandsDir)) {
|
|
94836
95113
|
logger.verbose("No commands directory found, skipping prefix application");
|
|
94837
95114
|
return;
|
|
94838
95115
|
}
|
|
94839
95116
|
logger.info("Applying /ck: prefix to slash commands...");
|
|
94840
|
-
const backupDir =
|
|
94841
|
-
const tempDir =
|
|
95117
|
+
const backupDir = join98(extractDir, ".commands-backup");
|
|
95118
|
+
const tempDir = join98(extractDir, ".commands-prefix-temp");
|
|
94842
95119
|
try {
|
|
94843
95120
|
const entries = await readdir21(commandsDir);
|
|
94844
95121
|
if (entries.length === 0) {
|
|
@@ -94846,7 +95123,7 @@ async function applyPrefix(extractDir) {
|
|
|
94846
95123
|
return;
|
|
94847
95124
|
}
|
|
94848
95125
|
if (entries.length === 1 && entries[0] === "ck") {
|
|
94849
|
-
const ckDir2 =
|
|
95126
|
+
const ckDir2 = join98(commandsDir, "ck");
|
|
94850
95127
|
const ckStat = await stat15(ckDir2);
|
|
94851
95128
|
if (ckStat.isDirectory()) {
|
|
94852
95129
|
logger.verbose("Commands already have /ck: prefix, skipping");
|
|
@@ -94856,17 +95133,17 @@ async function applyPrefix(extractDir) {
|
|
|
94856
95133
|
await import_fs_extra17.copy(commandsDir, backupDir);
|
|
94857
95134
|
logger.verbose("Created backup of commands directory");
|
|
94858
95135
|
await mkdir27(tempDir, { recursive: true });
|
|
94859
|
-
const ckDir =
|
|
95136
|
+
const ckDir = join98(tempDir, "ck");
|
|
94860
95137
|
await mkdir27(ckDir, { recursive: true });
|
|
94861
95138
|
let processedCount = 0;
|
|
94862
95139
|
for (const entry of entries) {
|
|
94863
|
-
const sourcePath =
|
|
95140
|
+
const sourcePath = join98(commandsDir, entry);
|
|
94864
95141
|
const stats = await lstat7(sourcePath);
|
|
94865
95142
|
if (stats.isSymbolicLink()) {
|
|
94866
95143
|
logger.warning(`Skipping symlink for security: ${entry}`);
|
|
94867
95144
|
continue;
|
|
94868
95145
|
}
|
|
94869
|
-
const destPath =
|
|
95146
|
+
const destPath = join98(ckDir, entry);
|
|
94870
95147
|
await import_fs_extra17.copy(sourcePath, destPath, {
|
|
94871
95148
|
overwrite: false,
|
|
94872
95149
|
errorOnExist: true
|
|
@@ -94884,7 +95161,7 @@ async function applyPrefix(extractDir) {
|
|
|
94884
95161
|
await import_fs_extra17.move(tempDir, commandsDir);
|
|
94885
95162
|
await import_fs_extra17.remove(backupDir);
|
|
94886
95163
|
logger.success("Successfully reorganized commands to /ck: prefix");
|
|
94887
|
-
const claudeDir2 =
|
|
95164
|
+
const claudeDir2 = join98(extractDir, ".claude");
|
|
94888
95165
|
logger.info("Transforming command references in file contents...");
|
|
94889
95166
|
const transformResult = await transformCommandReferences(claudeDir2, {
|
|
94890
95167
|
verbose: logger.isVerbose()
|
|
@@ -94922,20 +95199,20 @@ async function applyPrefix(extractDir) {
|
|
|
94922
95199
|
// src/services/transformers/commands-prefix/prefix-cleaner.ts
|
|
94923
95200
|
init_metadata_migration();
|
|
94924
95201
|
import { lstat as lstat9, readdir as readdir23 } from "node:fs/promises";
|
|
94925
|
-
import { join as
|
|
95202
|
+
import { join as join100 } from "node:path";
|
|
94926
95203
|
init_logger();
|
|
94927
95204
|
var import_fs_extra19 = __toESM(require_lib3(), 1);
|
|
94928
95205
|
|
|
94929
95206
|
// src/services/transformers/commands-prefix/file-processor.ts
|
|
94930
95207
|
import { lstat as lstat8, readdir as readdir22 } from "node:fs/promises";
|
|
94931
|
-
import { join as
|
|
95208
|
+
import { join as join99 } from "node:path";
|
|
94932
95209
|
init_logger();
|
|
94933
95210
|
var import_fs_extra18 = __toESM(require_lib3(), 1);
|
|
94934
95211
|
async function scanDirectoryFiles(dir) {
|
|
94935
95212
|
const files = [];
|
|
94936
95213
|
const entries = await readdir22(dir);
|
|
94937
95214
|
for (const entry of entries) {
|
|
94938
|
-
const fullPath =
|
|
95215
|
+
const fullPath = join99(dir, entry);
|
|
94939
95216
|
const stats = await lstat8(fullPath);
|
|
94940
95217
|
if (stats.isSymbolicLink()) {
|
|
94941
95218
|
continue;
|
|
@@ -95063,8 +95340,8 @@ function isDifferentKitDirectory(dirName, currentKit) {
|
|
|
95063
95340
|
async function cleanupCommandsDirectory(targetDir, isGlobal, options2 = {}) {
|
|
95064
95341
|
const { dryRun = false } = options2;
|
|
95065
95342
|
validatePath(targetDir, "targetDir");
|
|
95066
|
-
const claudeDir2 = isGlobal ? targetDir :
|
|
95067
|
-
const commandsDir =
|
|
95343
|
+
const claudeDir2 = isGlobal ? targetDir : join100(targetDir, ".claude");
|
|
95344
|
+
const commandsDir = join100(claudeDir2, "commands");
|
|
95068
95345
|
const accumulator = {
|
|
95069
95346
|
results: [],
|
|
95070
95347
|
deletedCount: 0,
|
|
@@ -95106,7 +95383,7 @@ async function cleanupCommandsDirectory(targetDir, isGlobal, options2 = {}) {
|
|
|
95106
95383
|
}
|
|
95107
95384
|
const metadataForChecks = options2.kitType ? createKitSpecificMetadata(metadata, options2.kitType) : metadata;
|
|
95108
95385
|
for (const entry of entries) {
|
|
95109
|
-
const entryPath =
|
|
95386
|
+
const entryPath = join100(commandsDir, entry);
|
|
95110
95387
|
const stats = await lstat9(entryPath);
|
|
95111
95388
|
if (stats.isSymbolicLink()) {
|
|
95112
95389
|
addSymlinkSkip(entry, accumulator);
|
|
@@ -95163,7 +95440,7 @@ async function handleMerge(ctx) {
|
|
|
95163
95440
|
let customClaudeFiles = [];
|
|
95164
95441
|
if (!ctx.options.fresh) {
|
|
95165
95442
|
logger.info("Scanning for custom .claude files...");
|
|
95166
|
-
const scanSourceDir = ctx.options.global ?
|
|
95443
|
+
const scanSourceDir = ctx.options.global ? join101(ctx.extractDir, ".claude") : ctx.extractDir;
|
|
95167
95444
|
const scanTargetSubdir = ctx.options.global ? "" : ".claude";
|
|
95168
95445
|
customClaudeFiles = await FileScanner2.findCustomFiles(ctx.resolvedDir, scanSourceDir, scanTargetSubdir);
|
|
95169
95446
|
} else {
|
|
@@ -95228,8 +95505,8 @@ async function handleMerge(ctx) {
|
|
|
95228
95505
|
return { ...ctx, cancelled: true };
|
|
95229
95506
|
}
|
|
95230
95507
|
}
|
|
95231
|
-
const sourceDir = ctx.options.global ?
|
|
95232
|
-
const sourceMetadataPath = ctx.options.global ?
|
|
95508
|
+
const sourceDir = ctx.options.global ? join101(ctx.extractDir, ".claude") : ctx.extractDir;
|
|
95509
|
+
const sourceMetadataPath = ctx.options.global ? join101(sourceDir, "metadata.json") : join101(sourceDir, ".claude", "metadata.json");
|
|
95233
95510
|
let sourceMetadata = null;
|
|
95234
95511
|
try {
|
|
95235
95512
|
if (await import_fs_extra20.pathExists(sourceMetadataPath)) {
|
|
@@ -95286,7 +95563,7 @@ async function handleMerge(ctx) {
|
|
|
95286
95563
|
};
|
|
95287
95564
|
}
|
|
95288
95565
|
// src/commands/init/phases/migration-handler.ts
|
|
95289
|
-
import { join as
|
|
95566
|
+
import { join as join109 } from "node:path";
|
|
95290
95567
|
|
|
95291
95568
|
// src/domains/skills/skills-detector.ts
|
|
95292
95569
|
init_logger();
|
|
@@ -95302,7 +95579,7 @@ init_types3();
|
|
|
95302
95579
|
var import_fs_extra21 = __toESM(require_lib3(), 1);
|
|
95303
95580
|
import { createHash as createHash4 } from "node:crypto";
|
|
95304
95581
|
import { readFile as readFile46, readdir as readdir24, writeFile as writeFile27 } from "node:fs/promises";
|
|
95305
|
-
import { join as
|
|
95582
|
+
import { join as join102, relative as relative16 } from "node:path";
|
|
95306
95583
|
|
|
95307
95584
|
class SkillsManifestManager {
|
|
95308
95585
|
static MANIFEST_FILENAME = ".skills-manifest.json";
|
|
@@ -95324,12 +95601,12 @@ class SkillsManifestManager {
|
|
|
95324
95601
|
return manifest;
|
|
95325
95602
|
}
|
|
95326
95603
|
static async writeManifest(skillsDir2, manifest) {
|
|
95327
|
-
const manifestPath =
|
|
95604
|
+
const manifestPath = join102(skillsDir2, SkillsManifestManager.MANIFEST_FILENAME);
|
|
95328
95605
|
await writeFile27(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
95329
95606
|
logger.debug(`Wrote manifest to: ${manifestPath}`);
|
|
95330
95607
|
}
|
|
95331
95608
|
static async readManifest(skillsDir2) {
|
|
95332
|
-
const manifestPath =
|
|
95609
|
+
const manifestPath = join102(skillsDir2, SkillsManifestManager.MANIFEST_FILENAME);
|
|
95333
95610
|
if (!await import_fs_extra21.pathExists(manifestPath)) {
|
|
95334
95611
|
logger.debug(`No manifest found at: ${manifestPath}`);
|
|
95335
95612
|
return null;
|
|
@@ -95352,7 +95629,7 @@ class SkillsManifestManager {
|
|
|
95352
95629
|
return "flat";
|
|
95353
95630
|
}
|
|
95354
95631
|
for (const dir of dirs.slice(0, 3)) {
|
|
95355
|
-
const dirPath =
|
|
95632
|
+
const dirPath = join102(skillsDir2, dir.name);
|
|
95356
95633
|
const subEntries = await readdir24(dirPath, { withFileTypes: true });
|
|
95357
95634
|
const hasSubdirs = subEntries.some((entry) => entry.isDirectory());
|
|
95358
95635
|
if (hasSubdirs) {
|
|
@@ -95371,7 +95648,7 @@ class SkillsManifestManager {
|
|
|
95371
95648
|
const entries = await readdir24(skillsDir2, { withFileTypes: true });
|
|
95372
95649
|
for (const entry of entries) {
|
|
95373
95650
|
if (entry.isDirectory() && !BUILD_ARTIFACT_DIRS.includes(entry.name) && !entry.name.startsWith(".")) {
|
|
95374
|
-
const skillPath =
|
|
95651
|
+
const skillPath = join102(skillsDir2, entry.name);
|
|
95375
95652
|
const hash = await SkillsManifestManager.hashDirectory(skillPath);
|
|
95376
95653
|
skills.push({
|
|
95377
95654
|
name: entry.name,
|
|
@@ -95383,11 +95660,11 @@ class SkillsManifestManager {
|
|
|
95383
95660
|
const categories = await readdir24(skillsDir2, { withFileTypes: true });
|
|
95384
95661
|
for (const category of categories) {
|
|
95385
95662
|
if (category.isDirectory() && !BUILD_ARTIFACT_DIRS.includes(category.name) && !category.name.startsWith(".")) {
|
|
95386
|
-
const categoryPath =
|
|
95663
|
+
const categoryPath = join102(skillsDir2, category.name);
|
|
95387
95664
|
const skillEntries = await readdir24(categoryPath, { withFileTypes: true });
|
|
95388
95665
|
for (const skillEntry of skillEntries) {
|
|
95389
95666
|
if (skillEntry.isDirectory() && !skillEntry.name.startsWith(".")) {
|
|
95390
|
-
const skillPath =
|
|
95667
|
+
const skillPath = join102(categoryPath, skillEntry.name);
|
|
95391
95668
|
const hash = await SkillsManifestManager.hashDirectory(skillPath);
|
|
95392
95669
|
skills.push({
|
|
95393
95670
|
name: skillEntry.name,
|
|
@@ -95417,7 +95694,7 @@ class SkillsManifestManager {
|
|
|
95417
95694
|
const files = [];
|
|
95418
95695
|
const entries = await readdir24(dirPath, { withFileTypes: true });
|
|
95419
95696
|
for (const entry of entries) {
|
|
95420
|
-
const fullPath =
|
|
95697
|
+
const fullPath = join102(dirPath, entry.name);
|
|
95421
95698
|
if (entry.name.startsWith(".") || BUILD_ARTIFACT_DIRS.includes(entry.name)) {
|
|
95422
95699
|
continue;
|
|
95423
95700
|
}
|
|
@@ -95539,7 +95816,7 @@ function getPathMapping(skillName, oldBasePath, newBasePath) {
|
|
|
95539
95816
|
// src/domains/skills/detection/script-detector.ts
|
|
95540
95817
|
var import_fs_extra22 = __toESM(require_lib3(), 1);
|
|
95541
95818
|
import { readdir as readdir25 } from "node:fs/promises";
|
|
95542
|
-
import { join as
|
|
95819
|
+
import { join as join103 } from "node:path";
|
|
95543
95820
|
async function scanDirectory(skillsDir2) {
|
|
95544
95821
|
if (!await import_fs_extra22.pathExists(skillsDir2)) {
|
|
95545
95822
|
return ["flat", []];
|
|
@@ -95552,12 +95829,12 @@ async function scanDirectory(skillsDir2) {
|
|
|
95552
95829
|
let totalSkillLikeCount = 0;
|
|
95553
95830
|
const allSkills = [];
|
|
95554
95831
|
for (const dir of dirs) {
|
|
95555
|
-
const dirPath =
|
|
95832
|
+
const dirPath = join103(skillsDir2, dir.name);
|
|
95556
95833
|
const subEntries = await readdir25(dirPath, { withFileTypes: true });
|
|
95557
95834
|
const subdirs = subEntries.filter((entry) => entry.isDirectory() && !entry.name.startsWith("."));
|
|
95558
95835
|
if (subdirs.length > 0) {
|
|
95559
95836
|
for (const subdir of subdirs.slice(0, 3)) {
|
|
95560
|
-
const subdirPath =
|
|
95837
|
+
const subdirPath = join103(dirPath, subdir.name);
|
|
95561
95838
|
const subdirFiles = await readdir25(subdirPath, { withFileTypes: true });
|
|
95562
95839
|
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"));
|
|
95563
95840
|
if (hasSkillMarker) {
|
|
@@ -95714,12 +95991,12 @@ class SkillsMigrationDetector {
|
|
|
95714
95991
|
// src/domains/skills/skills-migrator.ts
|
|
95715
95992
|
init_logger();
|
|
95716
95993
|
init_types3();
|
|
95717
|
-
import { join as
|
|
95994
|
+
import { join as join108 } from "node:path";
|
|
95718
95995
|
|
|
95719
95996
|
// src/domains/skills/migrator/migration-executor.ts
|
|
95720
95997
|
init_logger();
|
|
95721
95998
|
import { copyFile as copyFile6, mkdir as mkdir28, readdir as readdir26, rm as rm11 } from "node:fs/promises";
|
|
95722
|
-
import { join as
|
|
95999
|
+
import { join as join104 } from "node:path";
|
|
95723
96000
|
var import_fs_extra24 = __toESM(require_lib3(), 1);
|
|
95724
96001
|
|
|
95725
96002
|
// src/domains/skills/skills-migration-prompts.ts
|
|
@@ -95884,8 +96161,8 @@ async function copySkillDirectory(sourceDir, destDir) {
|
|
|
95884
96161
|
await mkdir28(destDir, { recursive: true });
|
|
95885
96162
|
const entries = await readdir26(sourceDir, { withFileTypes: true });
|
|
95886
96163
|
for (const entry of entries) {
|
|
95887
|
-
const sourcePath =
|
|
95888
|
-
const destPath =
|
|
96164
|
+
const sourcePath = join104(sourceDir, entry.name);
|
|
96165
|
+
const destPath = join104(destDir, entry.name);
|
|
95889
96166
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.isSymbolicLink()) {
|
|
95890
96167
|
continue;
|
|
95891
96168
|
}
|
|
@@ -95900,7 +96177,7 @@ async function executeInternal(mappings, customizations, currentSkillsDir, inter
|
|
|
95900
96177
|
const migrated = [];
|
|
95901
96178
|
const preserved = [];
|
|
95902
96179
|
const errors2 = [];
|
|
95903
|
-
const tempDir =
|
|
96180
|
+
const tempDir = join104(currentSkillsDir, "..", ".skills-migration-temp");
|
|
95904
96181
|
await mkdir28(tempDir, { recursive: true });
|
|
95905
96182
|
try {
|
|
95906
96183
|
for (const mapping of mappings) {
|
|
@@ -95921,9 +96198,9 @@ async function executeInternal(mappings, customizations, currentSkillsDir, inter
|
|
|
95921
96198
|
}
|
|
95922
96199
|
}
|
|
95923
96200
|
const category = mapping.category;
|
|
95924
|
-
const targetPath = category ?
|
|
96201
|
+
const targetPath = category ? join104(tempDir, category, skillName) : join104(tempDir, skillName);
|
|
95925
96202
|
if (category) {
|
|
95926
|
-
await mkdir28(
|
|
96203
|
+
await mkdir28(join104(tempDir, category), { recursive: true });
|
|
95927
96204
|
}
|
|
95928
96205
|
await copySkillDirectory(currentSkillPath, targetPath);
|
|
95929
96206
|
migrated.push(skillName);
|
|
@@ -95990,7 +96267,7 @@ init_logger();
|
|
|
95990
96267
|
init_types3();
|
|
95991
96268
|
var import_fs_extra25 = __toESM(require_lib3(), 1);
|
|
95992
96269
|
import { copyFile as copyFile7, mkdir as mkdir29, readdir as readdir27, rm as rm12, stat as stat16 } from "node:fs/promises";
|
|
95993
|
-
import { basename as basename15, join as
|
|
96270
|
+
import { basename as basename15, join as join105, normalize as normalize8 } from "node:path";
|
|
95994
96271
|
function validatePath2(path15, paramName) {
|
|
95995
96272
|
if (!path15 || typeof path15 !== "string") {
|
|
95996
96273
|
throw new SkillsMigrationError(`${paramName} must be a non-empty string`);
|
|
@@ -96016,7 +96293,7 @@ class SkillsBackupManager {
|
|
|
96016
96293
|
const timestamp = Date.now();
|
|
96017
96294
|
const randomSuffix = Math.random().toString(36).substring(2, 8);
|
|
96018
96295
|
const backupDirName = `${SkillsBackupManager.BACKUP_PREFIX}${timestamp}-${randomSuffix}`;
|
|
96019
|
-
const backupDir = parentDir ?
|
|
96296
|
+
const backupDir = parentDir ? join105(parentDir, backupDirName) : join105(skillsDir2, "..", backupDirName);
|
|
96020
96297
|
logger.info(`Creating backup at: ${backupDir}`);
|
|
96021
96298
|
try {
|
|
96022
96299
|
await mkdir29(backupDir, { recursive: true });
|
|
@@ -96067,7 +96344,7 @@ class SkillsBackupManager {
|
|
|
96067
96344
|
}
|
|
96068
96345
|
try {
|
|
96069
96346
|
const entries = await readdir27(parentDir, { withFileTypes: true });
|
|
96070
|
-
const backups = entries.filter((entry) => entry.isDirectory() && entry.name.startsWith(SkillsBackupManager.BACKUP_PREFIX)).map((entry) =>
|
|
96347
|
+
const backups = entries.filter((entry) => entry.isDirectory() && entry.name.startsWith(SkillsBackupManager.BACKUP_PREFIX)).map((entry) => join105(parentDir, entry.name));
|
|
96071
96348
|
backups.sort().reverse();
|
|
96072
96349
|
return backups;
|
|
96073
96350
|
} catch (error) {
|
|
@@ -96095,8 +96372,8 @@ class SkillsBackupManager {
|
|
|
96095
96372
|
static async copyDirectory(sourceDir, destDir) {
|
|
96096
96373
|
const entries = await readdir27(sourceDir, { withFileTypes: true });
|
|
96097
96374
|
for (const entry of entries) {
|
|
96098
|
-
const sourcePath =
|
|
96099
|
-
const destPath =
|
|
96375
|
+
const sourcePath = join105(sourceDir, entry.name);
|
|
96376
|
+
const destPath = join105(destDir, entry.name);
|
|
96100
96377
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.isSymbolicLink()) {
|
|
96101
96378
|
continue;
|
|
96102
96379
|
}
|
|
@@ -96112,7 +96389,7 @@ class SkillsBackupManager {
|
|
|
96112
96389
|
let size = 0;
|
|
96113
96390
|
const entries = await readdir27(dirPath, { withFileTypes: true });
|
|
96114
96391
|
for (const entry of entries) {
|
|
96115
|
-
const fullPath =
|
|
96392
|
+
const fullPath = join105(dirPath, entry.name);
|
|
96116
96393
|
if (entry.isSymbolicLink()) {
|
|
96117
96394
|
continue;
|
|
96118
96395
|
}
|
|
@@ -96148,12 +96425,12 @@ init_skip_directories();
|
|
|
96148
96425
|
import { createHash as createHash5 } from "node:crypto";
|
|
96149
96426
|
import { createReadStream as createReadStream3 } from "node:fs";
|
|
96150
96427
|
import { readFile as readFile47, readdir as readdir28 } from "node:fs/promises";
|
|
96151
|
-
import { join as
|
|
96428
|
+
import { join as join106, relative as relative17 } from "node:path";
|
|
96152
96429
|
async function getAllFiles(dirPath) {
|
|
96153
96430
|
const files = [];
|
|
96154
96431
|
const entries = await readdir28(dirPath, { withFileTypes: true });
|
|
96155
96432
|
for (const entry of entries) {
|
|
96156
|
-
const fullPath =
|
|
96433
|
+
const fullPath = join106(dirPath, entry.name);
|
|
96157
96434
|
if (entry.name.startsWith(".") || BUILD_ARTIFACT_DIRS.includes(entry.name) || entry.isSymbolicLink()) {
|
|
96158
96435
|
continue;
|
|
96159
96436
|
}
|
|
@@ -96280,7 +96557,7 @@ async function detectFileChanges(currentSkillPath, baselineSkillPath) {
|
|
|
96280
96557
|
init_types3();
|
|
96281
96558
|
var import_fs_extra27 = __toESM(require_lib3(), 1);
|
|
96282
96559
|
import { readdir as readdir29 } from "node:fs/promises";
|
|
96283
|
-
import { join as
|
|
96560
|
+
import { join as join107, normalize as normalize9 } from "node:path";
|
|
96284
96561
|
function validatePath3(path15, paramName) {
|
|
96285
96562
|
if (!path15 || typeof path15 !== "string") {
|
|
96286
96563
|
throw new SkillsMigrationError(`${paramName} must be a non-empty string`);
|
|
@@ -96301,13 +96578,13 @@ async function scanSkillsDirectory(skillsDir2) {
|
|
|
96301
96578
|
if (dirs.length === 0) {
|
|
96302
96579
|
return ["flat", []];
|
|
96303
96580
|
}
|
|
96304
|
-
const firstDirPath =
|
|
96581
|
+
const firstDirPath = join107(skillsDir2, dirs[0].name);
|
|
96305
96582
|
const subEntries = await readdir29(firstDirPath, { withFileTypes: true });
|
|
96306
96583
|
const subdirs = subEntries.filter((entry) => entry.isDirectory() && !entry.name.startsWith("."));
|
|
96307
96584
|
if (subdirs.length > 0) {
|
|
96308
96585
|
let skillLikeCount = 0;
|
|
96309
96586
|
for (const subdir of subdirs.slice(0, 3)) {
|
|
96310
|
-
const subdirPath =
|
|
96587
|
+
const subdirPath = join107(firstDirPath, subdir.name);
|
|
96311
96588
|
const subdirFiles = await readdir29(subdirPath, { withFileTypes: true });
|
|
96312
96589
|
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"));
|
|
96313
96590
|
if (hasSkillMarker) {
|
|
@@ -96317,7 +96594,7 @@ async function scanSkillsDirectory(skillsDir2) {
|
|
|
96317
96594
|
if (skillLikeCount > 0) {
|
|
96318
96595
|
const skills = [];
|
|
96319
96596
|
for (const dir of dirs) {
|
|
96320
|
-
const categoryPath =
|
|
96597
|
+
const categoryPath = join107(skillsDir2, dir.name);
|
|
96321
96598
|
const skillDirs = await readdir29(categoryPath, { withFileTypes: true });
|
|
96322
96599
|
skills.push(...skillDirs.filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name));
|
|
96323
96600
|
}
|
|
@@ -96327,7 +96604,7 @@ async function scanSkillsDirectory(skillsDir2) {
|
|
|
96327
96604
|
return ["flat", dirs.map((dir) => dir.name)];
|
|
96328
96605
|
}
|
|
96329
96606
|
async function findSkillPath(skillsDir2, skillName) {
|
|
96330
|
-
const flatPath =
|
|
96607
|
+
const flatPath = join107(skillsDir2, skillName);
|
|
96331
96608
|
if (await import_fs_extra27.pathExists(flatPath)) {
|
|
96332
96609
|
return { path: flatPath, category: undefined };
|
|
96333
96610
|
}
|
|
@@ -96336,8 +96613,8 @@ async function findSkillPath(skillsDir2, skillName) {
|
|
|
96336
96613
|
if (!entry.isDirectory() || entry.name.startsWith(".") || entry.name === "node_modules") {
|
|
96337
96614
|
continue;
|
|
96338
96615
|
}
|
|
96339
|
-
const categoryPath =
|
|
96340
|
-
const skillPath =
|
|
96616
|
+
const categoryPath = join107(skillsDir2, entry.name);
|
|
96617
|
+
const skillPath = join107(categoryPath, skillName);
|
|
96341
96618
|
if (await import_fs_extra27.pathExists(skillPath)) {
|
|
96342
96619
|
return { path: skillPath, category: entry.name };
|
|
96343
96620
|
}
|
|
@@ -96431,7 +96708,7 @@ class SkillsMigrator {
|
|
|
96431
96708
|
}
|
|
96432
96709
|
}
|
|
96433
96710
|
if (options2.backup && !options2.dryRun) {
|
|
96434
|
-
const claudeDir2 =
|
|
96711
|
+
const claudeDir2 = join108(currentSkillsDir, "..");
|
|
96435
96712
|
result.backupPath = await SkillsBackupManager.createBackup(currentSkillsDir, claudeDir2);
|
|
96436
96713
|
logger.success(`Backup created at: ${result.backupPath}`);
|
|
96437
96714
|
}
|
|
@@ -96492,7 +96769,7 @@ async function handleMigration(ctx) {
|
|
|
96492
96769
|
logger.debug("Skipping skills migration (fresh installation)");
|
|
96493
96770
|
return ctx;
|
|
96494
96771
|
}
|
|
96495
|
-
const newSkillsDir =
|
|
96772
|
+
const newSkillsDir = join109(ctx.extractDir, ".claude", "skills");
|
|
96496
96773
|
const currentSkillsDir = PathResolver.buildSkillsPath(ctx.resolvedDir, ctx.options.global);
|
|
96497
96774
|
if (!await import_fs_extra28.pathExists(newSkillsDir) || !await import_fs_extra28.pathExists(currentSkillsDir)) {
|
|
96498
96775
|
return ctx;
|
|
@@ -96516,13 +96793,13 @@ async function handleMigration(ctx) {
|
|
|
96516
96793
|
}
|
|
96517
96794
|
// src/commands/init/phases/opencode-handler.ts
|
|
96518
96795
|
import { cp as cp3, readdir as readdir31, rm as rm13 } from "node:fs/promises";
|
|
96519
|
-
import { join as
|
|
96796
|
+
import { join as join111 } from "node:path";
|
|
96520
96797
|
|
|
96521
96798
|
// src/services/transformers/opencode-path-transformer.ts
|
|
96522
96799
|
init_logger();
|
|
96523
96800
|
import { readFile as readFile48, readdir as readdir30, writeFile as writeFile28 } from "node:fs/promises";
|
|
96524
96801
|
import { platform as platform12 } from "node:os";
|
|
96525
|
-
import { extname as extname5, join as
|
|
96802
|
+
import { extname as extname5, join as join110 } from "node:path";
|
|
96526
96803
|
var IS_WINDOWS2 = platform12() === "win32";
|
|
96527
96804
|
function getOpenCodeGlobalPath() {
|
|
96528
96805
|
return "$HOME/.config/opencode/";
|
|
@@ -96583,7 +96860,7 @@ async function transformPathsForGlobalOpenCode(directory, options2 = {}) {
|
|
|
96583
96860
|
async function processDirectory2(dir) {
|
|
96584
96861
|
const entries = await readdir30(dir, { withFileTypes: true });
|
|
96585
96862
|
for (const entry of entries) {
|
|
96586
|
-
const fullPath =
|
|
96863
|
+
const fullPath = join110(dir, entry.name);
|
|
96587
96864
|
if (entry.isDirectory()) {
|
|
96588
96865
|
if (entry.name === "node_modules" || entry.name.startsWith(".")) {
|
|
96589
96866
|
continue;
|
|
@@ -96622,7 +96899,7 @@ async function handleOpenCode(ctx) {
|
|
|
96622
96899
|
if (ctx.cancelled || !ctx.extractDir || !ctx.resolvedDir) {
|
|
96623
96900
|
return ctx;
|
|
96624
96901
|
}
|
|
96625
|
-
const openCodeSource =
|
|
96902
|
+
const openCodeSource = join111(ctx.extractDir, ".opencode");
|
|
96626
96903
|
if (!await import_fs_extra29.pathExists(openCodeSource)) {
|
|
96627
96904
|
logger.debug("No .opencode directory in archive, skipping");
|
|
96628
96905
|
return ctx;
|
|
@@ -96640,8 +96917,8 @@ async function handleOpenCode(ctx) {
|
|
|
96640
96917
|
await import_fs_extra29.ensureDir(targetDir);
|
|
96641
96918
|
const entries = await readdir31(openCodeSource, { withFileTypes: true });
|
|
96642
96919
|
for (const entry of entries) {
|
|
96643
|
-
const sourcePath =
|
|
96644
|
-
const targetPath =
|
|
96920
|
+
const sourcePath = join111(openCodeSource, entry.name);
|
|
96921
|
+
const targetPath = join111(targetDir, entry.name);
|
|
96645
96922
|
if (await import_fs_extra29.pathExists(targetPath)) {
|
|
96646
96923
|
if (!ctx.options.forceOverwrite) {
|
|
96647
96924
|
logger.verbose(`Skipping existing: ${entry.name}`);
|
|
@@ -96739,7 +97016,7 @@ Please use only one download method.`);
|
|
|
96739
97016
|
}
|
|
96740
97017
|
// src/commands/init/phases/post-install-handler.ts
|
|
96741
97018
|
init_projects_registry();
|
|
96742
|
-
import { join as
|
|
97019
|
+
import { join as join112 } from "node:path";
|
|
96743
97020
|
init_logger();
|
|
96744
97021
|
init_path_resolver();
|
|
96745
97022
|
var import_fs_extra30 = __toESM(require_lib3(), 1);
|
|
@@ -96748,8 +97025,8 @@ async function handlePostInstall(ctx) {
|
|
|
96748
97025
|
return ctx;
|
|
96749
97026
|
}
|
|
96750
97027
|
if (ctx.options.global) {
|
|
96751
|
-
const claudeMdSource =
|
|
96752
|
-
const claudeMdDest =
|
|
97028
|
+
const claudeMdSource = join112(ctx.extractDir, "CLAUDE.md");
|
|
97029
|
+
const claudeMdDest = join112(ctx.resolvedDir, "CLAUDE.md");
|
|
96753
97030
|
if (await import_fs_extra30.pathExists(claudeMdSource)) {
|
|
96754
97031
|
if (ctx.options.fresh || !await import_fs_extra30.pathExists(claudeMdDest)) {
|
|
96755
97032
|
await import_fs_extra30.copy(claudeMdSource, claudeMdDest);
|
|
@@ -96797,7 +97074,7 @@ async function handlePostInstall(ctx) {
|
|
|
96797
97074
|
}
|
|
96798
97075
|
if (!ctx.options.skipSetup) {
|
|
96799
97076
|
await promptSetupWizardIfNeeded({
|
|
96800
|
-
envPath:
|
|
97077
|
+
envPath: join112(ctx.claudeDir, ".env"),
|
|
96801
97078
|
claudeDir: ctx.claudeDir,
|
|
96802
97079
|
isGlobal: ctx.options.global,
|
|
96803
97080
|
isNonInteractive: ctx.isNonInteractive,
|
|
@@ -96821,7 +97098,7 @@ async function handlePostInstall(ctx) {
|
|
|
96821
97098
|
init_config_manager();
|
|
96822
97099
|
init_github_client();
|
|
96823
97100
|
import { mkdir as mkdir30 } from "node:fs/promises";
|
|
96824
|
-
import { join as
|
|
97101
|
+
import { join as join114, resolve as resolve23 } from "node:path";
|
|
96825
97102
|
|
|
96826
97103
|
// src/domains/github/kit-access-checker.ts
|
|
96827
97104
|
init_logger();
|
|
@@ -96952,7 +97229,7 @@ async function runPreflightChecks() {
|
|
|
96952
97229
|
// src/domains/installation/fresh-installer.ts
|
|
96953
97230
|
init_metadata_migration();
|
|
96954
97231
|
import { existsSync as existsSync55, readdirSync as readdirSync5, rmSync as rmSync4, rmdirSync as rmdirSync2, unlinkSync as unlinkSync4 } from "node:fs";
|
|
96955
|
-
import { dirname as
|
|
97232
|
+
import { dirname as dirname29, join as join113, resolve as resolve22 } from "node:path";
|
|
96956
97233
|
init_logger();
|
|
96957
97234
|
init_safe_spinner();
|
|
96958
97235
|
var import_fs_extra31 = __toESM(require_lib3(), 1);
|
|
@@ -97001,14 +97278,14 @@ async function analyzeFreshInstallation(claudeDir2) {
|
|
|
97001
97278
|
}
|
|
97002
97279
|
function cleanupEmptyDirectories2(filePath, claudeDir2) {
|
|
97003
97280
|
const normalizedClaudeDir = resolve22(claudeDir2);
|
|
97004
|
-
let currentDir = resolve22(
|
|
97281
|
+
let currentDir = resolve22(dirname29(filePath));
|
|
97005
97282
|
while (currentDir !== normalizedClaudeDir && currentDir.startsWith(normalizedClaudeDir)) {
|
|
97006
97283
|
try {
|
|
97007
97284
|
const entries = readdirSync5(currentDir);
|
|
97008
97285
|
if (entries.length === 0) {
|
|
97009
97286
|
rmdirSync2(currentDir);
|
|
97010
97287
|
logger.debug(`Removed empty directory: ${currentDir}`);
|
|
97011
|
-
currentDir = resolve22(
|
|
97288
|
+
currentDir = resolve22(dirname29(currentDir));
|
|
97012
97289
|
} else {
|
|
97013
97290
|
break;
|
|
97014
97291
|
}
|
|
@@ -97025,7 +97302,7 @@ async function removeFilesByOwnership(claudeDir2, analysis, includeModified) {
|
|
|
97025
97302
|
const filesToRemove = includeModified ? [...analysis.ckFiles, ...analysis.ckModifiedFiles] : analysis.ckFiles;
|
|
97026
97303
|
const filesToPreserve = includeModified ? analysis.userFiles : [...analysis.ckModifiedFiles, ...analysis.userFiles];
|
|
97027
97304
|
for (const file of filesToRemove) {
|
|
97028
|
-
const fullPath =
|
|
97305
|
+
const fullPath = join113(claudeDir2, file.path);
|
|
97029
97306
|
try {
|
|
97030
97307
|
if (existsSync55(fullPath)) {
|
|
97031
97308
|
unlinkSync4(fullPath);
|
|
@@ -97050,7 +97327,7 @@ async function removeFilesByOwnership(claudeDir2, analysis, includeModified) {
|
|
|
97050
97327
|
};
|
|
97051
97328
|
}
|
|
97052
97329
|
async function updateMetadataAfterFresh(claudeDir2, removedFiles) {
|
|
97053
|
-
const metadataPath =
|
|
97330
|
+
const metadataPath = join113(claudeDir2, "metadata.json");
|
|
97054
97331
|
if (!await import_fs_extra31.pathExists(metadataPath)) {
|
|
97055
97332
|
return;
|
|
97056
97333
|
}
|
|
@@ -97093,7 +97370,7 @@ async function removeSubdirectoriesFallback(claudeDir2) {
|
|
|
97093
97370
|
const removedFiles = [];
|
|
97094
97371
|
let removedDirCount = 0;
|
|
97095
97372
|
for (const subdir of CLAUDEKIT_SUBDIRECTORIES) {
|
|
97096
|
-
const subdirPath =
|
|
97373
|
+
const subdirPath = join113(claudeDir2, subdir);
|
|
97097
97374
|
if (await import_fs_extra31.pathExists(subdirPath)) {
|
|
97098
97375
|
rmSync4(subdirPath, { recursive: true, force: true });
|
|
97099
97376
|
removedDirCount++;
|
|
@@ -97101,7 +97378,7 @@ async function removeSubdirectoriesFallback(claudeDir2) {
|
|
|
97101
97378
|
logger.debug(`Removed subdirectory: ${subdir}/`);
|
|
97102
97379
|
}
|
|
97103
97380
|
}
|
|
97104
|
-
const metadataPath =
|
|
97381
|
+
const metadataPath = join113(claudeDir2, "metadata.json");
|
|
97105
97382
|
if (await import_fs_extra31.pathExists(metadataPath)) {
|
|
97106
97383
|
unlinkSync4(metadataPath);
|
|
97107
97384
|
removedFiles.push("metadata.json");
|
|
@@ -97353,7 +97630,7 @@ async function handleSelection(ctx) {
|
|
|
97353
97630
|
}
|
|
97354
97631
|
if (!ctx.options.fresh) {
|
|
97355
97632
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
97356
|
-
const claudeDir2 = prefix ?
|
|
97633
|
+
const claudeDir2 = prefix ? join114(resolvedDir, prefix) : resolvedDir;
|
|
97357
97634
|
try {
|
|
97358
97635
|
const existingMetadata = await readManifest(claudeDir2);
|
|
97359
97636
|
if (existingMetadata?.kits) {
|
|
@@ -97385,7 +97662,7 @@ async function handleSelection(ctx) {
|
|
|
97385
97662
|
}
|
|
97386
97663
|
if (ctx.options.fresh) {
|
|
97387
97664
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
97388
|
-
const claudeDir2 = prefix ?
|
|
97665
|
+
const claudeDir2 = prefix ? join114(resolvedDir, prefix) : resolvedDir;
|
|
97389
97666
|
const canProceed = await handleFreshInstallation(claudeDir2, ctx.prompts);
|
|
97390
97667
|
if (!canProceed) {
|
|
97391
97668
|
return { ...ctx, cancelled: true };
|
|
@@ -97405,7 +97682,7 @@ async function handleSelection(ctx) {
|
|
|
97405
97682
|
let currentVersion = null;
|
|
97406
97683
|
try {
|
|
97407
97684
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
97408
|
-
const claudeDir2 = prefix ?
|
|
97685
|
+
const claudeDir2 = prefix ? join114(resolvedDir, prefix) : resolvedDir;
|
|
97409
97686
|
const existingMetadata = await readManifest(claudeDir2);
|
|
97410
97687
|
currentVersion = existingMetadata?.kits?.[kitType]?.version || null;
|
|
97411
97688
|
if (currentVersion) {
|
|
@@ -97474,7 +97751,7 @@ async function handleSelection(ctx) {
|
|
|
97474
97751
|
if (ctx.options.yes && !ctx.options.fresh && !ctx.options.force && releaseTag && !isOfflineMode && !pendingKits?.length) {
|
|
97475
97752
|
try {
|
|
97476
97753
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
97477
|
-
const claudeDir2 = prefix ?
|
|
97754
|
+
const claudeDir2 = prefix ? join114(resolvedDir, prefix) : resolvedDir;
|
|
97478
97755
|
const existingMetadata = await readManifest(claudeDir2);
|
|
97479
97756
|
const installedKitVersion = existingMetadata?.kits?.[kitType]?.version;
|
|
97480
97757
|
if (installedKitVersion && versionsMatch(installedKitVersion, releaseTag)) {
|
|
@@ -97498,7 +97775,7 @@ async function handleSelection(ctx) {
|
|
|
97498
97775
|
}
|
|
97499
97776
|
// src/commands/init/phases/sync-handler.ts
|
|
97500
97777
|
import { copyFile as copyFile8, mkdir as mkdir31, open as open5, readFile as readFile50, rename as rename6, stat as stat17, unlink as unlink11, writeFile as writeFile30 } from "node:fs/promises";
|
|
97501
|
-
import { dirname as
|
|
97778
|
+
import { dirname as dirname30, join as join115, resolve as resolve24 } from "node:path";
|
|
97502
97779
|
init_logger();
|
|
97503
97780
|
init_path_resolver();
|
|
97504
97781
|
var import_fs_extra33 = __toESM(require_lib3(), 1);
|
|
@@ -97508,13 +97785,13 @@ async function handleSync(ctx) {
|
|
|
97508
97785
|
return ctx;
|
|
97509
97786
|
}
|
|
97510
97787
|
const resolvedDir = ctx.options.global ? PathResolver.getGlobalKitDir() : resolve24(ctx.options.dir || ".");
|
|
97511
|
-
const claudeDir2 = ctx.options.global ? resolvedDir :
|
|
97788
|
+
const claudeDir2 = ctx.options.global ? resolvedDir : join115(resolvedDir, ".claude");
|
|
97512
97789
|
if (!await import_fs_extra33.pathExists(claudeDir2)) {
|
|
97513
97790
|
logger.error("Cannot sync: no .claude directory found");
|
|
97514
97791
|
ctx.prompts.note("Run 'ck init' without --sync to install first.", "No Installation Found");
|
|
97515
97792
|
return { ...ctx, cancelled: true };
|
|
97516
97793
|
}
|
|
97517
|
-
const metadataPath =
|
|
97794
|
+
const metadataPath = join115(claudeDir2, "metadata.json");
|
|
97518
97795
|
if (!await import_fs_extra33.pathExists(metadataPath)) {
|
|
97519
97796
|
logger.error("Cannot sync: no metadata.json found");
|
|
97520
97797
|
ctx.prompts.note(`Your installation may be from an older version.
|
|
@@ -97614,10 +97891,10 @@ function getLockTimeout() {
|
|
|
97614
97891
|
var STALE_LOCK_THRESHOLD_MS = 5 * 60 * 1000;
|
|
97615
97892
|
async function acquireSyncLock(global3) {
|
|
97616
97893
|
const cacheDir = PathResolver.getCacheDir(global3);
|
|
97617
|
-
const lockPath =
|
|
97894
|
+
const lockPath = join115(cacheDir, ".sync-lock");
|
|
97618
97895
|
const startTime = Date.now();
|
|
97619
97896
|
const lockTimeout = getLockTimeout();
|
|
97620
|
-
await mkdir31(
|
|
97897
|
+
await mkdir31(dirname30(lockPath), { recursive: true });
|
|
97621
97898
|
while (Date.now() - startTime < lockTimeout) {
|
|
97622
97899
|
try {
|
|
97623
97900
|
const handle = await open5(lockPath, "wx");
|
|
@@ -97660,10 +97937,10 @@ async function executeSyncMerge(ctx) {
|
|
|
97660
97937
|
const releaseLock = await acquireSyncLock(ctx.options.global);
|
|
97661
97938
|
try {
|
|
97662
97939
|
const trackedFiles = ctx.syncTrackedFiles;
|
|
97663
|
-
const upstreamDir = ctx.options.global ?
|
|
97940
|
+
const upstreamDir = ctx.options.global ? join115(ctx.extractDir, ".claude") : ctx.extractDir;
|
|
97664
97941
|
let deletions = [];
|
|
97665
97942
|
try {
|
|
97666
|
-
const sourceMetadataPath =
|
|
97943
|
+
const sourceMetadataPath = join115(upstreamDir, "metadata.json");
|
|
97667
97944
|
if (await import_fs_extra33.pathExists(sourceMetadataPath)) {
|
|
97668
97945
|
const content = await readFile50(sourceMetadataPath, "utf-8");
|
|
97669
97946
|
const sourceMetadata = JSON.parse(content);
|
|
@@ -97695,7 +97972,7 @@ async function executeSyncMerge(ctx) {
|
|
|
97695
97972
|
try {
|
|
97696
97973
|
const sourcePath = await validateSyncPath(upstreamDir, file.path);
|
|
97697
97974
|
const targetPath = await validateSyncPath(ctx.claudeDir, file.path);
|
|
97698
|
-
const targetDir =
|
|
97975
|
+
const targetDir = join115(targetPath, "..");
|
|
97699
97976
|
try {
|
|
97700
97977
|
await mkdir31(targetDir, { recursive: true });
|
|
97701
97978
|
} catch (mkdirError) {
|
|
@@ -97866,7 +98143,7 @@ async function createBackup(claudeDir2, files, backupDir) {
|
|
|
97866
98143
|
const sourcePath = await validateSyncPath(claudeDir2, file.path);
|
|
97867
98144
|
if (await import_fs_extra33.pathExists(sourcePath)) {
|
|
97868
98145
|
const targetPath = await validateSyncPath(backupDir, file.path);
|
|
97869
|
-
const targetDir =
|
|
98146
|
+
const targetDir = join115(targetPath, "..");
|
|
97870
98147
|
await mkdir31(targetDir, { recursive: true });
|
|
97871
98148
|
await copyFile8(sourcePath, targetPath);
|
|
97872
98149
|
}
|
|
@@ -97881,7 +98158,7 @@ async function createBackup(claudeDir2, files, backupDir) {
|
|
|
97881
98158
|
}
|
|
97882
98159
|
// src/commands/init/phases/transform-handler.ts
|
|
97883
98160
|
init_config_manager();
|
|
97884
|
-
import { join as
|
|
98161
|
+
import { join as join119 } from "node:path";
|
|
97885
98162
|
|
|
97886
98163
|
// src/services/transformers/folder-path-transformer.ts
|
|
97887
98164
|
init_logger();
|
|
@@ -97892,38 +98169,38 @@ init_logger();
|
|
|
97892
98169
|
init_types3();
|
|
97893
98170
|
var import_fs_extra34 = __toESM(require_lib3(), 1);
|
|
97894
98171
|
import { rename as rename7, rm as rm14 } from "node:fs/promises";
|
|
97895
|
-
import { join as
|
|
98172
|
+
import { join as join116, relative as relative19 } from "node:path";
|
|
97896
98173
|
async function collectDirsToRename(extractDir, folders) {
|
|
97897
98174
|
const dirsToRename = [];
|
|
97898
98175
|
if (folders.docs !== DEFAULT_FOLDERS.docs) {
|
|
97899
|
-
const docsPath =
|
|
98176
|
+
const docsPath = join116(extractDir, DEFAULT_FOLDERS.docs);
|
|
97900
98177
|
if (await import_fs_extra34.pathExists(docsPath)) {
|
|
97901
98178
|
dirsToRename.push({
|
|
97902
98179
|
from: docsPath,
|
|
97903
|
-
to:
|
|
98180
|
+
to: join116(extractDir, folders.docs)
|
|
97904
98181
|
});
|
|
97905
98182
|
}
|
|
97906
|
-
const claudeDocsPath =
|
|
98183
|
+
const claudeDocsPath = join116(extractDir, ".claude", DEFAULT_FOLDERS.docs);
|
|
97907
98184
|
if (await import_fs_extra34.pathExists(claudeDocsPath)) {
|
|
97908
98185
|
dirsToRename.push({
|
|
97909
98186
|
from: claudeDocsPath,
|
|
97910
|
-
to:
|
|
98187
|
+
to: join116(extractDir, ".claude", folders.docs)
|
|
97911
98188
|
});
|
|
97912
98189
|
}
|
|
97913
98190
|
}
|
|
97914
98191
|
if (folders.plans !== DEFAULT_FOLDERS.plans) {
|
|
97915
|
-
const plansPath =
|
|
98192
|
+
const plansPath = join116(extractDir, DEFAULT_FOLDERS.plans);
|
|
97916
98193
|
if (await import_fs_extra34.pathExists(plansPath)) {
|
|
97917
98194
|
dirsToRename.push({
|
|
97918
98195
|
from: plansPath,
|
|
97919
|
-
to:
|
|
98196
|
+
to: join116(extractDir, folders.plans)
|
|
97920
98197
|
});
|
|
97921
98198
|
}
|
|
97922
|
-
const claudePlansPath =
|
|
98199
|
+
const claudePlansPath = join116(extractDir, ".claude", DEFAULT_FOLDERS.plans);
|
|
97923
98200
|
if (await import_fs_extra34.pathExists(claudePlansPath)) {
|
|
97924
98201
|
dirsToRename.push({
|
|
97925
98202
|
from: claudePlansPath,
|
|
97926
|
-
to:
|
|
98203
|
+
to: join116(extractDir, ".claude", folders.plans)
|
|
97927
98204
|
});
|
|
97928
98205
|
}
|
|
97929
98206
|
}
|
|
@@ -97964,7 +98241,7 @@ async function renameFolders(dirsToRename, extractDir, options2) {
|
|
|
97964
98241
|
init_logger();
|
|
97965
98242
|
init_types3();
|
|
97966
98243
|
import { readFile as readFile51, readdir as readdir32, writeFile as writeFile31 } from "node:fs/promises";
|
|
97967
|
-
import { join as
|
|
98244
|
+
import { join as join117, relative as relative20 } from "node:path";
|
|
97968
98245
|
var TRANSFORMABLE_FILE_PATTERNS = [
|
|
97969
98246
|
".md",
|
|
97970
98247
|
".txt",
|
|
@@ -98017,7 +98294,7 @@ async function transformFileContents(dir, compiledReplacements, options2) {
|
|
|
98017
98294
|
let replacementsCount = 0;
|
|
98018
98295
|
const entries = await readdir32(dir, { withFileTypes: true });
|
|
98019
98296
|
for (const entry of entries) {
|
|
98020
|
-
const fullPath =
|
|
98297
|
+
const fullPath = join117(dir, entry.name);
|
|
98021
98298
|
if (entry.isDirectory()) {
|
|
98022
98299
|
if (entry.name === "node_modules" || entry.name === ".git") {
|
|
98023
98300
|
continue;
|
|
@@ -98154,7 +98431,7 @@ async function transformFolderPaths(extractDir, folders, options2 = {}) {
|
|
|
98154
98431
|
init_logger();
|
|
98155
98432
|
import { readFile as readFile52, readdir as readdir33, writeFile as writeFile32 } from "node:fs/promises";
|
|
98156
98433
|
import { platform as platform13 } from "node:os";
|
|
98157
|
-
import { extname as extname6, join as
|
|
98434
|
+
import { extname as extname6, join as join118 } from "node:path";
|
|
98158
98435
|
var IS_WINDOWS3 = platform13() === "win32";
|
|
98159
98436
|
var HOME_PREFIX = IS_WINDOWS3 ? "%USERPROFILE%" : "$HOME";
|
|
98160
98437
|
function getHomeDirPrefix() {
|
|
@@ -98266,7 +98543,7 @@ async function transformPathsForGlobalInstall(directory, options2 = {}) {
|
|
|
98266
98543
|
async function processDirectory2(dir) {
|
|
98267
98544
|
const entries = await readdir33(dir, { withFileTypes: true });
|
|
98268
98545
|
for (const entry of entries) {
|
|
98269
|
-
const fullPath =
|
|
98546
|
+
const fullPath = join118(dir, entry.name);
|
|
98270
98547
|
if (entry.isDirectory()) {
|
|
98271
98548
|
if (entry.name === "node_modules" || entry.name.startsWith(".") && entry.name !== ".claude") {
|
|
98272
98549
|
continue;
|
|
@@ -98342,7 +98619,7 @@ async function handleTransforms(ctx) {
|
|
|
98342
98619
|
logger.debug(ctx.options.global ? "Saved folder configuration to ~/.claude/.ck.json" : "Saved folder configuration to .claude/.ck.json");
|
|
98343
98620
|
}
|
|
98344
98621
|
}
|
|
98345
|
-
const claudeDir2 = ctx.options.global ? ctx.resolvedDir :
|
|
98622
|
+
const claudeDir2 = ctx.options.global ? ctx.resolvedDir : join119(ctx.resolvedDir, ".claude");
|
|
98346
98623
|
return {
|
|
98347
98624
|
...ctx,
|
|
98348
98625
|
foldersConfig,
|
|
@@ -98533,8 +98810,8 @@ init_dist2();
|
|
|
98533
98810
|
var import_picocolors28 = __toESM(require_picocolors(), 1);
|
|
98534
98811
|
import { existsSync as existsSync56 } from "node:fs";
|
|
98535
98812
|
import { readFile as readFile53, rm as rm15, unlink as unlink12 } from "node:fs/promises";
|
|
98536
|
-
import { homedir as
|
|
98537
|
-
import { basename as basename16, join as
|
|
98813
|
+
import { homedir as homedir34 } from "node:os";
|
|
98814
|
+
import { basename as basename16, join as join120, resolve as resolve25 } from "node:path";
|
|
98538
98815
|
init_logger();
|
|
98539
98816
|
init_agents_discovery();
|
|
98540
98817
|
init_commands_discovery();
|
|
@@ -98959,7 +99236,7 @@ async function executeDeleteAction(action, options2) {
|
|
|
98959
99236
|
async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
98960
99237
|
if (!skillSourcePath)
|
|
98961
99238
|
return;
|
|
98962
|
-
const sourceMetadataPath =
|
|
99239
|
+
const sourceMetadataPath = join120(resolve25(skillSourcePath, ".."), "metadata.json");
|
|
98963
99240
|
if (!existsSync56(sourceMetadataPath))
|
|
98964
99241
|
return;
|
|
98965
99242
|
let sourceMetadata;
|
|
@@ -98972,7 +99249,7 @@ async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
|
98972
99249
|
}
|
|
98973
99250
|
if (!sourceMetadata.deletions || sourceMetadata.deletions.length === 0)
|
|
98974
99251
|
return;
|
|
98975
|
-
const claudeDir2 = installGlobally ?
|
|
99252
|
+
const claudeDir2 = installGlobally ? join120(homedir34(), ".claude") : join120(process.cwd(), ".claude");
|
|
98976
99253
|
if (!existsSync56(claudeDir2))
|
|
98977
99254
|
return;
|
|
98978
99255
|
try {
|
|
@@ -99127,8 +99404,8 @@ async function migrateCommand(options2) {
|
|
|
99127
99404
|
selectedProviders = Array.from(new Set(selectedProviders));
|
|
99128
99405
|
let installGlobally = options2.global ?? false;
|
|
99129
99406
|
if (options2.global === undefined && !options2.yes) {
|
|
99130
|
-
const projectTarget =
|
|
99131
|
-
const globalTarget =
|
|
99407
|
+
const projectTarget = join120(process.cwd(), ".claude");
|
|
99408
|
+
const globalTarget = join120(homedir34(), ".claude");
|
|
99132
99409
|
const scopeChoice = await ie({
|
|
99133
99410
|
message: "Installation scope",
|
|
99134
99411
|
options: [
|
|
@@ -99180,7 +99457,7 @@ async function migrateCommand(options2) {
|
|
|
99180
99457
|
}
|
|
99181
99458
|
const providerNames = selectedProviders.map((prov) => import_picocolors28.default.cyan(providers[prov].displayName)).join(", ");
|
|
99182
99459
|
f2.message(` Providers: ${providerNames}`);
|
|
99183
|
-
const targetDir = installGlobally ?
|
|
99460
|
+
const targetDir = installGlobally ? join120(homedir34(), ".claude") : join120(process.cwd(), ".claude");
|
|
99184
99461
|
f2.message(` Scope: ${installGlobally ? "Global" : "Project"} ${import_picocolors28.default.dim(`-> ${targetDir}`)}`);
|
|
99185
99462
|
const cmdProviders = getProvidersSupporting("commands");
|
|
99186
99463
|
const unsupportedCmd = selectedProviders.filter((pv) => !cmdProviders.includes(pv));
|
|
@@ -99676,7 +99953,7 @@ async function handleDirectorySetup(ctx) {
|
|
|
99676
99953
|
// src/commands/new/phases/project-creation.ts
|
|
99677
99954
|
init_config_manager();
|
|
99678
99955
|
init_github_client();
|
|
99679
|
-
import { join as
|
|
99956
|
+
import { join as join121 } from "node:path";
|
|
99680
99957
|
init_logger();
|
|
99681
99958
|
init_output_manager();
|
|
99682
99959
|
init_types3();
|
|
@@ -99802,7 +100079,7 @@ async function projectCreation(kit, resolvedDir, validOptions, isNonInteractive2
|
|
|
99802
100079
|
output.section("Installing");
|
|
99803
100080
|
logger.verbose("Installation target", { directory: resolvedDir });
|
|
99804
100081
|
const merger = new FileMerger;
|
|
99805
|
-
const claudeDir2 =
|
|
100082
|
+
const claudeDir2 = join121(resolvedDir, ".claude");
|
|
99806
100083
|
merger.setMultiKitContext(claudeDir2, kit);
|
|
99807
100084
|
if (validOptions.exclude && validOptions.exclude.length > 0) {
|
|
99808
100085
|
merger.addIgnorePatterns(validOptions.exclude);
|
|
@@ -99849,7 +100126,7 @@ async function handleProjectCreation(ctx) {
|
|
|
99849
100126
|
}
|
|
99850
100127
|
// src/commands/new/phases/post-setup.ts
|
|
99851
100128
|
init_projects_registry();
|
|
99852
|
-
import { join as
|
|
100129
|
+
import { join as join122 } from "node:path";
|
|
99853
100130
|
init_package_installer();
|
|
99854
100131
|
init_logger();
|
|
99855
100132
|
init_path_resolver();
|
|
@@ -99881,9 +100158,9 @@ async function postSetup(resolvedDir, validOptions, isNonInteractive2, prompts)
|
|
|
99881
100158
|
withSudo: validOptions.withSudo
|
|
99882
100159
|
});
|
|
99883
100160
|
}
|
|
99884
|
-
const claudeDir2 =
|
|
100161
|
+
const claudeDir2 = join122(resolvedDir, ".claude");
|
|
99885
100162
|
await promptSetupWizardIfNeeded({
|
|
99886
|
-
envPath:
|
|
100163
|
+
envPath: join122(claudeDir2, ".env"),
|
|
99887
100164
|
claudeDir: claudeDir2,
|
|
99888
100165
|
isGlobal: false,
|
|
99889
100166
|
isNonInteractive: isNonInteractive2,
|
|
@@ -99953,7 +100230,7 @@ Please use only one download method.`);
|
|
|
99953
100230
|
// src/commands/plan/plan-command.ts
|
|
99954
100231
|
init_output_manager();
|
|
99955
100232
|
import { existsSync as existsSync58, statSync as statSync8 } from "node:fs";
|
|
99956
|
-
import { dirname as
|
|
100233
|
+
import { dirname as dirname32, join as join124, parse as parse6, resolve as resolve29 } from "node:path";
|
|
99957
100234
|
|
|
99958
100235
|
// src/commands/plan/plan-read-handlers.ts
|
|
99959
100236
|
init_plan_parser();
|
|
@@ -99961,7 +100238,7 @@ init_logger();
|
|
|
99961
100238
|
init_output_manager();
|
|
99962
100239
|
var import_picocolors30 = __toESM(require_picocolors(), 1);
|
|
99963
100240
|
import { existsSync as existsSync57, statSync as statSync7 } from "node:fs";
|
|
99964
|
-
import { basename as basename17, dirname as
|
|
100241
|
+
import { basename as basename17, dirname as dirname31, join as join123, relative as relative21, resolve as resolve27 } from "node:path";
|
|
99965
100242
|
async function handleParse(target, options2) {
|
|
99966
100243
|
const planFile = resolvePlanFile(target);
|
|
99967
100244
|
if (!planFile) {
|
|
@@ -99982,7 +100259,7 @@ async function handleParse(target, options2) {
|
|
|
99982
100259
|
console.log(JSON.stringify({ file: relative21(process.cwd(), planFile), frontmatter, phases }, null, 2));
|
|
99983
100260
|
return;
|
|
99984
100261
|
}
|
|
99985
|
-
const title = typeof frontmatter.title === "string" ? frontmatter.title : basename17(
|
|
100262
|
+
const title = typeof frontmatter.title === "string" ? frontmatter.title : basename17(dirname31(planFile));
|
|
99986
100263
|
console.log();
|
|
99987
100264
|
console.log(import_picocolors30.default.bold(` Plan: ${title}`));
|
|
99988
100265
|
console.log(` File: ${planFile}`);
|
|
@@ -100037,7 +100314,7 @@ async function handleValidate(target, options2) {
|
|
|
100037
100314
|
}
|
|
100038
100315
|
async function handleStatus(target, options2) {
|
|
100039
100316
|
const t = target ? resolve27(target) : null;
|
|
100040
|
-
const plansDir = t && existsSync57(t) && statSync7(t).isDirectory() && !existsSync57(
|
|
100317
|
+
const plansDir = t && existsSync57(t) && statSync7(t).isDirectory() && !existsSync57(join123(t, "plan.md")) ? t : null;
|
|
100041
100318
|
if (plansDir) {
|
|
100042
100319
|
const planFiles = scanPlanDir(plansDir);
|
|
100043
100320
|
if (planFiles.length === 0) {
|
|
@@ -100062,14 +100339,14 @@ async function handleStatus(target, options2) {
|
|
|
100062
100339
|
try {
|
|
100063
100340
|
const s = buildPlanSummary(pf);
|
|
100064
100341
|
const bar = progressBar(s.completed, s.totalPhases);
|
|
100065
|
-
const title2 = s.title ?? basename17(
|
|
100342
|
+
const title2 = s.title ?? basename17(dirname31(pf));
|
|
100066
100343
|
console.log(` ${import_picocolors30.default.bold(title2)}`);
|
|
100067
100344
|
console.log(` ${bar}`);
|
|
100068
100345
|
if (s.inProgress > 0)
|
|
100069
100346
|
console.log(` [~] ${s.inProgress} in progress`);
|
|
100070
100347
|
console.log();
|
|
100071
100348
|
} catch {
|
|
100072
|
-
console.log(` [X] Failed to read: ${basename17(
|
|
100349
|
+
console.log(` [X] Failed to read: ${basename17(dirname31(pf))}`);
|
|
100073
100350
|
console.log();
|
|
100074
100351
|
}
|
|
100075
100352
|
}
|
|
@@ -100093,7 +100370,7 @@ async function handleStatus(target, options2) {
|
|
|
100093
100370
|
console.log(JSON.stringify(summary, null, 2));
|
|
100094
100371
|
return;
|
|
100095
100372
|
}
|
|
100096
|
-
const title = summary.title ?? basename17(
|
|
100373
|
+
const title = summary.title ?? basename17(dirname31(planFile));
|
|
100097
100374
|
console.log();
|
|
100098
100375
|
console.log(import_picocolors30.default.bold(` ${title}`));
|
|
100099
100376
|
if (summary.status)
|
|
@@ -100309,7 +100586,7 @@ function resolvePlanFile(target) {
|
|
|
100309
100586
|
const stat18 = statSync8(t);
|
|
100310
100587
|
if (stat18.isFile())
|
|
100311
100588
|
return t;
|
|
100312
|
-
const candidate =
|
|
100589
|
+
const candidate = join124(t, "plan.md");
|
|
100313
100590
|
if (existsSync58(candidate))
|
|
100314
100591
|
return candidate;
|
|
100315
100592
|
}
|
|
@@ -100317,10 +100594,10 @@ function resolvePlanFile(target) {
|
|
|
100317
100594
|
let dir = process.cwd();
|
|
100318
100595
|
const root = parse6(dir).root;
|
|
100319
100596
|
while (dir !== root) {
|
|
100320
|
-
const candidate =
|
|
100597
|
+
const candidate = join124(dir, "plan.md");
|
|
100321
100598
|
if (existsSync58(candidate))
|
|
100322
100599
|
return candidate;
|
|
100323
|
-
dir =
|
|
100600
|
+
dir = dirname32(dir);
|
|
100324
100601
|
}
|
|
100325
100602
|
}
|
|
100326
100603
|
return null;
|
|
@@ -101345,7 +101622,7 @@ async function detectInstallations() {
|
|
|
101345
101622
|
|
|
101346
101623
|
// src/commands/uninstall/removal-handler.ts
|
|
101347
101624
|
import { readdirSync as readdirSync7, rmSync as rmSync6 } from "node:fs";
|
|
101348
|
-
import { join as
|
|
101625
|
+
import { join as join126, resolve as resolve31, sep as sep8 } from "node:path";
|
|
101349
101626
|
init_logger();
|
|
101350
101627
|
init_safe_prompts();
|
|
101351
101628
|
init_safe_spinner();
|
|
@@ -101354,7 +101631,7 @@ var import_fs_extra38 = __toESM(require_lib3(), 1);
|
|
|
101354
101631
|
// src/commands/uninstall/analysis-handler.ts
|
|
101355
101632
|
init_metadata_migration();
|
|
101356
101633
|
import { readdirSync as readdirSync6, rmSync as rmSync5 } from "node:fs";
|
|
101357
|
-
import { dirname as
|
|
101634
|
+
import { dirname as dirname33, join as join125 } from "node:path";
|
|
101358
101635
|
init_logger();
|
|
101359
101636
|
init_safe_prompts();
|
|
101360
101637
|
var import_fs_extra37 = __toESM(require_lib3(), 1);
|
|
@@ -101376,7 +101653,7 @@ function classifyFileByOwnership(ownership, forceOverwrite, deleteReason) {
|
|
|
101376
101653
|
}
|
|
101377
101654
|
async function cleanupEmptyDirectories3(filePath, installationRoot) {
|
|
101378
101655
|
let cleaned = 0;
|
|
101379
|
-
let currentDir =
|
|
101656
|
+
let currentDir = dirname33(filePath);
|
|
101380
101657
|
while (currentDir !== installationRoot && currentDir.startsWith(installationRoot)) {
|
|
101381
101658
|
try {
|
|
101382
101659
|
const entries = readdirSync6(currentDir);
|
|
@@ -101384,7 +101661,7 @@ async function cleanupEmptyDirectories3(filePath, installationRoot) {
|
|
|
101384
101661
|
rmSync5(currentDir, { recursive: true });
|
|
101385
101662
|
cleaned++;
|
|
101386
101663
|
logger.debug(`Removed empty directory: ${currentDir}`);
|
|
101387
|
-
currentDir =
|
|
101664
|
+
currentDir = dirname33(currentDir);
|
|
101388
101665
|
} else {
|
|
101389
101666
|
break;
|
|
101390
101667
|
}
|
|
@@ -101411,7 +101688,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
101411
101688
|
const remainingFiles = metadata.kits?.[remainingKit]?.files || [];
|
|
101412
101689
|
for (const file of remainingFiles) {
|
|
101413
101690
|
const relativePath = normalizeTrackedPath(file.path);
|
|
101414
|
-
if (await import_fs_extra37.pathExists(
|
|
101691
|
+
if (await import_fs_extra37.pathExists(join125(installation.path, relativePath))) {
|
|
101415
101692
|
result.retainedManifestPaths.push(relativePath);
|
|
101416
101693
|
}
|
|
101417
101694
|
}
|
|
@@ -101419,7 +101696,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
101419
101696
|
const kitFiles = metadata.kits[kit].files || [];
|
|
101420
101697
|
for (const trackedFile of kitFiles) {
|
|
101421
101698
|
const relativePath = normalizeTrackedPath(trackedFile.path);
|
|
101422
|
-
const filePath =
|
|
101699
|
+
const filePath = join125(installation.path, relativePath);
|
|
101423
101700
|
if (preservedPaths.has(relativePath)) {
|
|
101424
101701
|
result.toPreserve.push({ path: relativePath, reason: "shared with other kit" });
|
|
101425
101702
|
continue;
|
|
@@ -101452,7 +101729,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
101452
101729
|
}
|
|
101453
101730
|
for (const trackedFile of allTrackedFiles) {
|
|
101454
101731
|
const relativePath = normalizeTrackedPath(trackedFile.path);
|
|
101455
|
-
const filePath =
|
|
101732
|
+
const filePath = join125(installation.path, relativePath);
|
|
101456
101733
|
const ownershipResult = await OwnershipChecker.checkOwnership(filePath, metadata, installation.path);
|
|
101457
101734
|
if (!ownershipResult.exists)
|
|
101458
101735
|
continue;
|
|
@@ -101554,7 +101831,7 @@ async function removeInstallations(installations, options2) {
|
|
|
101554
101831
|
let removedCount = 0;
|
|
101555
101832
|
let cleanedDirs = 0;
|
|
101556
101833
|
for (const item of analysis.toDelete) {
|
|
101557
|
-
const filePath =
|
|
101834
|
+
const filePath = join126(installation.path, item.path);
|
|
101558
101835
|
if (!await import_fs_extra38.pathExists(filePath))
|
|
101559
101836
|
continue;
|
|
101560
101837
|
if (!await isPathSafeToRemove(filePath, installation.path)) {
|
|
@@ -101875,8 +102152,8 @@ ${import_picocolors38.default.bold(import_picocolors38.default.cyan(result.kitCo
|
|
|
101875
102152
|
init_logger();
|
|
101876
102153
|
import { existsSync as existsSync65 } from "node:fs";
|
|
101877
102154
|
import { rm as rm16 } from "node:fs/promises";
|
|
101878
|
-
import { homedir as
|
|
101879
|
-
import { join as
|
|
102155
|
+
import { homedir as homedir36 } from "node:os";
|
|
102156
|
+
import { join as join133 } from "node:path";
|
|
101880
102157
|
var import_picocolors39 = __toESM(require_picocolors(), 1);
|
|
101881
102158
|
|
|
101882
102159
|
// src/commands/watch/phases/implementation-runner.ts
|
|
@@ -102395,7 +102672,7 @@ function spawnAndCollect3(command, args) {
|
|
|
102395
102672
|
|
|
102396
102673
|
// src/commands/watch/phases/issue-processor.ts
|
|
102397
102674
|
import { mkdir as mkdir32, writeFile as writeFile34 } from "node:fs/promises";
|
|
102398
|
-
import { join as
|
|
102675
|
+
import { join as join129 } from "node:path";
|
|
102399
102676
|
|
|
102400
102677
|
// src/commands/watch/phases/approval-detector.ts
|
|
102401
102678
|
init_logger();
|
|
@@ -102770,9 +103047,9 @@ async function checkAwaitingApproval(state, setup, options2, watchLog, projectDi
|
|
|
102770
103047
|
|
|
102771
103048
|
// src/commands/watch/phases/plan-dir-finder.ts
|
|
102772
103049
|
import { readdir as readdir35, stat as stat18 } from "node:fs/promises";
|
|
102773
|
-
import { join as
|
|
103050
|
+
import { join as join128 } from "node:path";
|
|
102774
103051
|
async function findRecentPlanDir(cwd2, issueNumber, watchLog) {
|
|
102775
|
-
const plansRoot =
|
|
103052
|
+
const plansRoot = join128(cwd2, "plans");
|
|
102776
103053
|
try {
|
|
102777
103054
|
const entries = await readdir35(plansRoot);
|
|
102778
103055
|
const tenMinAgo = Date.now() - 10 * 60 * 1000;
|
|
@@ -102781,14 +103058,14 @@ async function findRecentPlanDir(cwd2, issueNumber, watchLog) {
|
|
|
102781
103058
|
for (const entry of entries) {
|
|
102782
103059
|
if (entry === "watch" || entry === "reports" || entry === "visuals")
|
|
102783
103060
|
continue;
|
|
102784
|
-
const dirPath =
|
|
103061
|
+
const dirPath = join128(plansRoot, entry);
|
|
102785
103062
|
const dirStat = await stat18(dirPath);
|
|
102786
103063
|
if (!dirStat.isDirectory())
|
|
102787
103064
|
continue;
|
|
102788
103065
|
if (dirStat.mtimeMs < tenMinAgo)
|
|
102789
103066
|
continue;
|
|
102790
103067
|
try {
|
|
102791
|
-
await stat18(
|
|
103068
|
+
await stat18(join128(dirPath, "plan.md"));
|
|
102792
103069
|
} catch {
|
|
102793
103070
|
continue;
|
|
102794
103071
|
}
|
|
@@ -103019,13 +103296,13 @@ async function handlePlanGeneration(issue, state, config, setup, options2, watch
|
|
|
103019
103296
|
stats.plansCreated++;
|
|
103020
103297
|
const detectedPlanDir = await findRecentPlanDir(projectDir, issue.number, watchLog);
|
|
103021
103298
|
if (detectedPlanDir) {
|
|
103022
|
-
state.activeIssues[numStr].planPath =
|
|
103299
|
+
state.activeIssues[numStr].planPath = join129(detectedPlanDir, "plan.md");
|
|
103023
103300
|
watchLog.info(`Plan directory detected: ${detectedPlanDir}`);
|
|
103024
103301
|
} else {
|
|
103025
103302
|
try {
|
|
103026
|
-
const planDir =
|
|
103303
|
+
const planDir = join129(projectDir, "plans", "watch");
|
|
103027
103304
|
await mkdir32(planDir, { recursive: true });
|
|
103028
|
-
const planFilePath =
|
|
103305
|
+
const planFilePath = join129(planDir, `issue-${issue.number}-plan.md`);
|
|
103029
103306
|
await writeFile34(planFilePath, planResult.planText, "utf-8");
|
|
103030
103307
|
state.activeIssues[numStr].planPath = planFilePath;
|
|
103031
103308
|
watchLog.info(`Plan saved (fallback) to ${planFilePath}`);
|
|
@@ -103172,7 +103449,7 @@ init_file_io();
|
|
|
103172
103449
|
init_logger();
|
|
103173
103450
|
import { existsSync as existsSync61 } from "node:fs";
|
|
103174
103451
|
import { mkdir as mkdir33, readFile as readFile55 } from "node:fs/promises";
|
|
103175
|
-
import { dirname as
|
|
103452
|
+
import { dirname as dirname34 } from "node:path";
|
|
103176
103453
|
var PROCESSED_ISSUES_CAP = 500;
|
|
103177
103454
|
async function readCkJson(projectDir) {
|
|
103178
103455
|
const configPath = CkConfigManager.getProjectConfigPath(projectDir);
|
|
@@ -103202,7 +103479,7 @@ async function loadWatchState(projectDir) {
|
|
|
103202
103479
|
}
|
|
103203
103480
|
async function saveWatchState(projectDir, state) {
|
|
103204
103481
|
const configPath = CkConfigManager.getProjectConfigPath(projectDir);
|
|
103205
|
-
const configDir =
|
|
103482
|
+
const configDir = dirname34(configPath);
|
|
103206
103483
|
if (!existsSync61(configDir)) {
|
|
103207
103484
|
await mkdir33(configDir, { recursive: true });
|
|
103208
103485
|
}
|
|
@@ -103332,18 +103609,18 @@ init_logger();
|
|
|
103332
103609
|
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
103333
103610
|
import { existsSync as existsSync62 } from "node:fs";
|
|
103334
103611
|
import { readdir as readdir36, stat as stat19 } from "node:fs/promises";
|
|
103335
|
-
import { join as
|
|
103612
|
+
import { join as join130 } from "node:path";
|
|
103336
103613
|
async function scanForRepos(parentDir) {
|
|
103337
103614
|
const repos = [];
|
|
103338
103615
|
const entries = await readdir36(parentDir);
|
|
103339
103616
|
for (const entry of entries) {
|
|
103340
103617
|
if (entry.startsWith("."))
|
|
103341
103618
|
continue;
|
|
103342
|
-
const fullPath =
|
|
103619
|
+
const fullPath = join130(parentDir, entry);
|
|
103343
103620
|
const entryStat = await stat19(fullPath);
|
|
103344
103621
|
if (!entryStat.isDirectory())
|
|
103345
103622
|
continue;
|
|
103346
|
-
const gitDir =
|
|
103623
|
+
const gitDir = join130(fullPath, ".git");
|
|
103347
103624
|
if (!existsSync62(gitDir))
|
|
103348
103625
|
continue;
|
|
103349
103626
|
const result = spawnSync6("gh", ["repo", "view", "--json", "owner,name"], {
|
|
@@ -103369,8 +103646,8 @@ async function scanForRepos(parentDir) {
|
|
|
103369
103646
|
init_logger();
|
|
103370
103647
|
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
103371
103648
|
import { existsSync as existsSync63 } from "node:fs";
|
|
103372
|
-
import { homedir as
|
|
103373
|
-
import { join as
|
|
103649
|
+
import { homedir as homedir35 } from "node:os";
|
|
103650
|
+
import { join as join131 } from "node:path";
|
|
103374
103651
|
async function validateSetup(cwd2) {
|
|
103375
103652
|
const workDir = cwd2 ?? process.cwd();
|
|
103376
103653
|
const ghVersion = spawnSync7("gh", ["--version"], { encoding: "utf-8", timeout: 1e4 });
|
|
@@ -103401,7 +103678,7 @@ Run this command from a directory with a GitHub remote.`);
|
|
|
103401
103678
|
} catch {
|
|
103402
103679
|
throw new Error(`Failed to parse repository info: ${ghRepo.stdout}`);
|
|
103403
103680
|
}
|
|
103404
|
-
const skillsPath =
|
|
103681
|
+
const skillsPath = join131(homedir35(), ".claude", "skills");
|
|
103405
103682
|
const skillsAvailable = existsSync63(skillsPath);
|
|
103406
103683
|
if (!skillsAvailable) {
|
|
103407
103684
|
logger.warning(`ClaudeKit Engineer skills not found at ${skillsPath}`);
|
|
@@ -103420,7 +103697,7 @@ init_path_resolver();
|
|
|
103420
103697
|
import { createWriteStream as createWriteStream3, statSync as statSync9 } from "node:fs";
|
|
103421
103698
|
import { existsSync as existsSync64 } from "node:fs";
|
|
103422
103699
|
import { mkdir as mkdir34, rename as rename8 } from "node:fs/promises";
|
|
103423
|
-
import { join as
|
|
103700
|
+
import { join as join132 } from "node:path";
|
|
103424
103701
|
|
|
103425
103702
|
class WatchLogger {
|
|
103426
103703
|
logStream = null;
|
|
@@ -103428,7 +103705,7 @@ class WatchLogger {
|
|
|
103428
103705
|
logPath = null;
|
|
103429
103706
|
maxBytes;
|
|
103430
103707
|
constructor(logDir, maxBytes = 0) {
|
|
103431
|
-
this.logDir = logDir ??
|
|
103708
|
+
this.logDir = logDir ?? join132(PathResolver.getClaudeKitDir(), "logs");
|
|
103432
103709
|
this.maxBytes = maxBytes;
|
|
103433
103710
|
}
|
|
103434
103711
|
async init() {
|
|
@@ -103437,7 +103714,7 @@ class WatchLogger {
|
|
|
103437
103714
|
await mkdir34(this.logDir, { recursive: true });
|
|
103438
103715
|
}
|
|
103439
103716
|
const dateStr = formatDate(new Date);
|
|
103440
|
-
this.logPath =
|
|
103717
|
+
this.logPath = join132(this.logDir, `watch-${dateStr}.log`);
|
|
103441
103718
|
this.logStream = createWriteStream3(this.logPath, { flags: "a", mode: 384 });
|
|
103442
103719
|
} catch (error) {
|
|
103443
103720
|
logger.warning(`Cannot create watch log file: ${error instanceof Error ? error.message : "Unknown"}`);
|
|
@@ -103617,7 +103894,7 @@ async function watchCommand(options2) {
|
|
|
103617
103894
|
}
|
|
103618
103895
|
async function discoverRepos(options2, watchLog) {
|
|
103619
103896
|
const cwd2 = process.cwd();
|
|
103620
|
-
const isGitRepo = existsSync65(
|
|
103897
|
+
const isGitRepo = existsSync65(join133(cwd2, ".git"));
|
|
103621
103898
|
if (options2.force) {
|
|
103622
103899
|
await forceRemoveLock(watchLog);
|
|
103623
103900
|
}
|
|
@@ -103687,7 +103964,7 @@ async function resetState(state, projectDir, watchLog) {
|
|
|
103687
103964
|
watchLog.info(`Watch state reset (--force) for ${projectDir}`);
|
|
103688
103965
|
}
|
|
103689
103966
|
async function forceRemoveLock(watchLog) {
|
|
103690
|
-
const lockPath =
|
|
103967
|
+
const lockPath = join133(homedir36(), ".claudekit", "locks", `${LOCK_NAME}.lock`);
|
|
103691
103968
|
try {
|
|
103692
103969
|
await rm16(lockPath, { recursive: true, force: true });
|
|
103693
103970
|
watchLog.info("Removed existing lock file (--force)");
|
|
@@ -103871,7 +104148,7 @@ init_logger();
|
|
|
103871
104148
|
init_path_resolver();
|
|
103872
104149
|
init_types3();
|
|
103873
104150
|
import { existsSync as existsSync76, readFileSync as readFileSync19 } from "node:fs";
|
|
103874
|
-
import { join as
|
|
104151
|
+
import { join as join144 } from "node:path";
|
|
103875
104152
|
var packageVersion = package_default.version;
|
|
103876
104153
|
function formatInstalledKits(metadata) {
|
|
103877
104154
|
if (!metadata.kits || Object.keys(metadata.kits).length === 0) {
|
|
@@ -103903,9 +104180,9 @@ async function displayVersion() {
|
|
|
103903
104180
|
let localKitVersion = null;
|
|
103904
104181
|
let isGlobalOnlyKit = false;
|
|
103905
104182
|
const globalKitDir = PathResolver.getGlobalKitDir();
|
|
103906
|
-
const globalMetadataPath =
|
|
104183
|
+
const globalMetadataPath = join144(globalKitDir, "metadata.json");
|
|
103907
104184
|
const prefix = PathResolver.getPathPrefix(false);
|
|
103908
|
-
const localMetadataPath = prefix ?
|
|
104185
|
+
const localMetadataPath = prefix ? join144(process.cwd(), prefix, "metadata.json") : join144(process.cwd(), "metadata.json");
|
|
103909
104186
|
const isLocalSameAsGlobal = localMetadataPath === globalMetadataPath;
|
|
103910
104187
|
if (!isLocalSameAsGlobal && existsSync76(localMetadataPath)) {
|
|
103911
104188
|
try {
|