claudekit-cli 4.2.3-dev.1 → 4.2.3-dev.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli-manifest.json +2 -2
- package/dist/index.js +485 -326
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -63000,7 +63000,7 @@ var package_default;
|
|
|
63000
63000
|
var init_package = __esm(() => {
|
|
63001
63001
|
package_default = {
|
|
63002
63002
|
name: "claudekit-cli",
|
|
63003
|
-
version: "4.2.3-dev.
|
|
63003
|
+
version: "4.2.3-dev.3",
|
|
63004
63004
|
description: "CLI tool for bootstrapping and updating ClaudeKit projects",
|
|
63005
63005
|
type: "module",
|
|
63006
63006
|
repository: {
|
|
@@ -71252,20 +71252,40 @@ function isSystemToolFailure(failure) {
|
|
|
71252
71252
|
function isWindowsSummary(summary) {
|
|
71253
71253
|
return Boolean(summary.remediation.winget_packages || summary.remediation.pip_retry.includes(".ps1") || summary.remediation.pip_retry.includes("\\"));
|
|
71254
71254
|
}
|
|
71255
|
-
function
|
|
71256
|
-
|
|
71257
|
-
|
|
71258
|
-
|
|
71259
|
-
|
|
71260
|
-
|
|
71261
|
-
|
|
71255
|
+
function isWindowsWingetToolKey(key) {
|
|
71256
|
+
return key in WINDOWS_SYSTEM_PACKAGES;
|
|
71257
|
+
}
|
|
71258
|
+
function getWindowsSystemPackageCommands(systemFailures) {
|
|
71259
|
+
const packageIds = new Set;
|
|
71260
|
+
let needsRsvg = false;
|
|
71261
|
+
for (const failure of systemFailures) {
|
|
71262
|
+
const key = getSystemToolKey(failure);
|
|
71263
|
+
if (!key)
|
|
71264
|
+
continue;
|
|
71265
|
+
if (isWindowsWingetToolKey(key)) {
|
|
71266
|
+
packageIds.add(WINDOWS_SYSTEM_PACKAGES[key]);
|
|
71267
|
+
} else {
|
|
71268
|
+
needsRsvg = true;
|
|
71262
71269
|
}
|
|
71263
|
-
|
|
71264
|
-
|
|
71270
|
+
}
|
|
71271
|
+
const commands = [];
|
|
71272
|
+
if (packageIds.size > 0) {
|
|
71273
|
+
commands.push(`winget install ${Array.from(packageIds).join(" ")}`);
|
|
71274
|
+
}
|
|
71275
|
+
if (needsRsvg) {
|
|
71276
|
+
commands.push(...WINDOWS_RSVG_COMMANDS);
|
|
71277
|
+
}
|
|
71278
|
+
return commands;
|
|
71279
|
+
}
|
|
71280
|
+
function getSystemPackageCommands(summary, systemFailures) {
|
|
71281
|
+
if (isWindowsSummary(summary)) {
|
|
71282
|
+
const commands = getWindowsSystemPackageCommands(systemFailures);
|
|
71283
|
+
if (commands.length > 0) {
|
|
71284
|
+
return commands;
|
|
71265
71285
|
}
|
|
71266
|
-
return summary.remediation.winget_packages;
|
|
71286
|
+
return summary.remediation.winget_packages ? [summary.remediation.winget_packages] : [];
|
|
71267
71287
|
}
|
|
71268
|
-
return summary.remediation.sudo_packages
|
|
71288
|
+
return summary.remediation.sudo_packages ? [summary.remediation.sudo_packages] : [];
|
|
71269
71289
|
}
|
|
71270
71290
|
function displayInstallErrors(skillsDir2) {
|
|
71271
71291
|
const summaryPath = join90(skillsDir2, ".install-error-summary.json");
|
|
@@ -71284,7 +71304,7 @@ function displayInstallErrors(skillsDir2) {
|
|
|
71284
71304
|
try {
|
|
71285
71305
|
const systemOptionalFailures = summary.optional_failures.filter(isSystemToolFailure);
|
|
71286
71306
|
const pythonOptionalFailures = summary.optional_failures.filter((f3) => !isSystemToolFailure(f3));
|
|
71287
|
-
const
|
|
71307
|
+
const systemPackageCommands = getSystemPackageCommands(summary, [
|
|
71288
71308
|
...systemOptionalFailures,
|
|
71289
71309
|
...summary.skipped
|
|
71290
71310
|
]);
|
|
@@ -71326,9 +71346,11 @@ function displayInstallErrors(skillsDir2) {
|
|
|
71326
71346
|
logger.info(` ${summary.remediation.build_tools}`);
|
|
71327
71347
|
logger.info("");
|
|
71328
71348
|
}
|
|
71329
|
-
if ((summary.skipped.length > 0 || systemOptionalFailures.length > 0) &&
|
|
71349
|
+
if ((summary.skipped.length > 0 || systemOptionalFailures.length > 0) && systemPackageCommands.length > 0) {
|
|
71330
71350
|
logger.info("Install system packages:");
|
|
71331
|
-
|
|
71351
|
+
for (const command of systemPackageCommands) {
|
|
71352
|
+
logger.info(` ${command}`);
|
|
71353
|
+
}
|
|
71332
71354
|
logger.info("");
|
|
71333
71355
|
}
|
|
71334
71356
|
if (pythonOptionalFailures.length > 0 && summary.remediation.pip_retry) {
|
|
@@ -71368,16 +71390,18 @@ function hasInstallState(skillsDir2) {
|
|
|
71368
71390
|
const stateFilePath = join90(skillsDir2, ".install-state.json");
|
|
71369
71391
|
return existsSync58(stateFilePath);
|
|
71370
71392
|
}
|
|
71371
|
-
var WHICH_COMMAND_TIMEOUT_MS = 5000, WINDOWS_SYSTEM_PACKAGES, SYSTEM_TOOL_KEYS;
|
|
71393
|
+
var WHICH_COMMAND_TIMEOUT_MS = 5000, WINDOWS_SYSTEM_PACKAGES, SYSTEM_TOOL_KEYS, WINDOWS_RSVG_COMMANDS;
|
|
71372
71394
|
var init_install_error_handler = __esm(() => {
|
|
71373
71395
|
init_logger();
|
|
71374
71396
|
WINDOWS_SYSTEM_PACKAGES = {
|
|
71375
71397
|
ffmpeg: "Gyan.FFmpeg",
|
|
71376
|
-
imagemagick: "ImageMagick.ImageMagick"
|
|
71377
|
-
librsvg: "GNOME.librsvg",
|
|
71378
|
-
"rsvg-convert": "GNOME.librsvg"
|
|
71398
|
+
imagemagick: "ImageMagick.ImageMagick"
|
|
71379
71399
|
};
|
|
71380
|
-
SYSTEM_TOOL_KEYS =
|
|
71400
|
+
SYSTEM_TOOL_KEYS = ["ffmpeg", "imagemagick", "librsvg", "rsvg-convert"];
|
|
71401
|
+
WINDOWS_RSVG_COMMANDS = [
|
|
71402
|
+
"choco install rsvg-convert -y # run from elevated PowerShell",
|
|
71403
|
+
"pacman -S mingw-w64-x86_64-librsvg # MSYS2 alternative"
|
|
71404
|
+
];
|
|
71381
71405
|
});
|
|
71382
71406
|
|
|
71383
71407
|
// src/services/package-installer/skills-installer.ts
|
|
@@ -74224,9 +74248,9 @@ __export(exports_worktree_manager, {
|
|
|
74224
74248
|
});
|
|
74225
74249
|
import { existsSync as existsSync70 } from "node:fs";
|
|
74226
74250
|
import { readFile as readFile66, writeFile as writeFile37 } from "node:fs/promises";
|
|
74227
|
-
import { join as
|
|
74251
|
+
import { join as join153 } from "node:path";
|
|
74228
74252
|
async function createWorktree(projectDir, issueNumber, baseBranch) {
|
|
74229
|
-
const worktreePath =
|
|
74253
|
+
const worktreePath = join153(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
|
|
74230
74254
|
const branchName = `ck-watch/issue-${issueNumber}`;
|
|
74231
74255
|
await spawnAndCollect("git", ["fetch", "origin", baseBranch], projectDir).catch(() => {
|
|
74232
74256
|
logger.warning(`[worktree] Could not fetch origin/${baseBranch}, using local`);
|
|
@@ -74244,7 +74268,7 @@ async function createWorktree(projectDir, issueNumber, baseBranch) {
|
|
|
74244
74268
|
return worktreePath;
|
|
74245
74269
|
}
|
|
74246
74270
|
async function removeWorktree(projectDir, issueNumber) {
|
|
74247
|
-
const worktreePath =
|
|
74271
|
+
const worktreePath = join153(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
|
|
74248
74272
|
const branchName = `ck-watch/issue-${issueNumber}`;
|
|
74249
74273
|
try {
|
|
74250
74274
|
await spawnAndCollect("git", ["worktree", "remove", worktreePath, "--force"], projectDir);
|
|
@@ -74258,7 +74282,7 @@ async function listActiveWorktrees(projectDir) {
|
|
|
74258
74282
|
try {
|
|
74259
74283
|
const output2 = await spawnAndCollect("git", ["worktree", "list", "--porcelain"], projectDir);
|
|
74260
74284
|
const issueNumbers = [];
|
|
74261
|
-
const worktreePrefix =
|
|
74285
|
+
const worktreePrefix = join153(projectDir, WORKTREE_DIR, "issue-").replace(/\\/g, "/");
|
|
74262
74286
|
for (const line of output2.split(`
|
|
74263
74287
|
`)) {
|
|
74264
74288
|
if (line.startsWith("worktree ")) {
|
|
@@ -74286,7 +74310,7 @@ async function cleanupAllWorktrees(projectDir) {
|
|
|
74286
74310
|
await spawnAndCollect("git", ["worktree", "prune"], projectDir).catch(() => {});
|
|
74287
74311
|
}
|
|
74288
74312
|
async function ensureGitignore(projectDir) {
|
|
74289
|
-
const gitignorePath =
|
|
74313
|
+
const gitignorePath = join153(projectDir, ".gitignore");
|
|
74290
74314
|
try {
|
|
74291
74315
|
const content = existsSync70(gitignorePath) ? await readFile66(gitignorePath, "utf-8") : "";
|
|
74292
74316
|
if (!content.includes(".worktrees")) {
|
|
@@ -74315,8 +74339,8 @@ function countTwitterChars(text) {
|
|
|
74315
74339
|
const withoutUrls = text.replace(urlPattern, "");
|
|
74316
74340
|
let count = urlCount * 23;
|
|
74317
74341
|
for (const char of withoutUrls) {
|
|
74318
|
-
const
|
|
74319
|
-
if (
|
|
74342
|
+
const cp6 = char.codePointAt(0) ?? 0;
|
|
74343
|
+
if (cp6 >= 19968 && cp6 <= 40959 || cp6 >= 13312 && cp6 <= 19903 || cp6 >= 131072 && cp6 <= 173791 || cp6 >= 173824 && cp6 <= 191471 || cp6 >= 196608 && cp6 <= 205743 || cp6 >= 63744 && cp6 <= 64255 || cp6 >= 12288 && cp6 <= 12351 || cp6 >= 12352 && cp6 <= 12447 || cp6 >= 12448 && cp6 <= 12543 || cp6 >= 65280 && cp6 <= 65519) {
|
|
74320
74344
|
count += 2;
|
|
74321
74345
|
} else {
|
|
74322
74346
|
count += 1;
|
|
@@ -74391,9 +74415,9 @@ var init_content_validator = __esm(() => {
|
|
|
74391
74415
|
// src/commands/content/phases/context-cache-manager.ts
|
|
74392
74416
|
import { createHash as createHash9 } from "node:crypto";
|
|
74393
74417
|
import { existsSync as existsSync76, mkdirSync as mkdirSync5, readFileSync as readFileSync18, readdirSync as readdirSync11, statSync as statSync14 } from "node:fs";
|
|
74394
|
-
import { rename as
|
|
74395
|
-
import { homedir as
|
|
74396
|
-
import { basename as basename31, join as
|
|
74418
|
+
import { rename as rename15, writeFile as writeFile39 } from "node:fs/promises";
|
|
74419
|
+
import { homedir as homedir54 } from "node:os";
|
|
74420
|
+
import { basename as basename31, join as join160 } from "node:path";
|
|
74397
74421
|
function getCachedContext(repoPath) {
|
|
74398
74422
|
const cachePath = getCacheFilePath(repoPath);
|
|
74399
74423
|
if (!existsSync76(cachePath))
|
|
@@ -74419,15 +74443,15 @@ async function saveCachedContext(repoPath, cache5) {
|
|
|
74419
74443
|
const cachePath = getCacheFilePath(repoPath);
|
|
74420
74444
|
const tmpPath = `${cachePath}.tmp`;
|
|
74421
74445
|
await writeFile39(tmpPath, JSON.stringify(cache5, null, 2), "utf-8");
|
|
74422
|
-
await
|
|
74446
|
+
await rename15(tmpPath, cachePath);
|
|
74423
74447
|
}
|
|
74424
74448
|
function computeSourceHash(repoPath) {
|
|
74425
74449
|
const hash = createHash9("sha256");
|
|
74426
74450
|
const paths = getDocSourcePaths(repoPath);
|
|
74427
74451
|
for (const filePath of paths) {
|
|
74428
74452
|
try {
|
|
74429
|
-
const
|
|
74430
|
-
hash.update(`${filePath}:${
|
|
74453
|
+
const stat26 = statSync14(filePath);
|
|
74454
|
+
hash.update(`${filePath}:${stat26.mtimeMs}`);
|
|
74431
74455
|
} catch {
|
|
74432
74456
|
hash.update(`${filePath}:0`);
|
|
74433
74457
|
}
|
|
@@ -74436,25 +74460,25 @@ function computeSourceHash(repoPath) {
|
|
|
74436
74460
|
}
|
|
74437
74461
|
function getDocSourcePaths(repoPath) {
|
|
74438
74462
|
const paths = [];
|
|
74439
|
-
const docsDir =
|
|
74463
|
+
const docsDir = join160(repoPath, "docs");
|
|
74440
74464
|
if (existsSync76(docsDir)) {
|
|
74441
74465
|
try {
|
|
74442
74466
|
const files = readdirSync11(docsDir);
|
|
74443
74467
|
for (const f3 of files) {
|
|
74444
74468
|
if (f3.endsWith(".md"))
|
|
74445
|
-
paths.push(
|
|
74469
|
+
paths.push(join160(docsDir, f3));
|
|
74446
74470
|
}
|
|
74447
74471
|
} catch {}
|
|
74448
74472
|
}
|
|
74449
|
-
const readme =
|
|
74473
|
+
const readme = join160(repoPath, "README.md");
|
|
74450
74474
|
if (existsSync76(readme))
|
|
74451
74475
|
paths.push(readme);
|
|
74452
|
-
const stylesDir =
|
|
74476
|
+
const stylesDir = join160(repoPath, "assets", "writing-styles");
|
|
74453
74477
|
if (existsSync76(stylesDir)) {
|
|
74454
74478
|
try {
|
|
74455
74479
|
const files = readdirSync11(stylesDir);
|
|
74456
74480
|
for (const f3 of files) {
|
|
74457
|
-
paths.push(
|
|
74481
|
+
paths.push(join160(stylesDir, f3));
|
|
74458
74482
|
}
|
|
74459
74483
|
} catch {}
|
|
74460
74484
|
}
|
|
@@ -74463,11 +74487,11 @@ function getDocSourcePaths(repoPath) {
|
|
|
74463
74487
|
function getCacheFilePath(repoPath) {
|
|
74464
74488
|
const repoName = basename31(repoPath).replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
74465
74489
|
const pathHash = createHash9("sha256").update(repoPath).digest("hex").slice(0, 8);
|
|
74466
|
-
return
|
|
74490
|
+
return join160(CACHE_DIR, `${repoName}-${pathHash}-context-cache.json`);
|
|
74467
74491
|
}
|
|
74468
74492
|
var CACHE_DIR, CACHE_TTL_MS5;
|
|
74469
74493
|
var init_context_cache_manager = __esm(() => {
|
|
74470
|
-
CACHE_DIR =
|
|
74494
|
+
CACHE_DIR = join160(homedir54(), ".claudekit", "cache");
|
|
74471
74495
|
CACHE_TTL_MS5 = 24 * 60 * 60 * 1000;
|
|
74472
74496
|
});
|
|
74473
74497
|
|
|
@@ -74648,7 +74672,7 @@ function extractContentFromResponse(response) {
|
|
|
74648
74672
|
// src/commands/content/phases/docs-summarizer.ts
|
|
74649
74673
|
import { execSync as execSync7 } from "node:child_process";
|
|
74650
74674
|
import { existsSync as existsSync77, readFileSync as readFileSync19, readdirSync as readdirSync12 } from "node:fs";
|
|
74651
|
-
import { join as
|
|
74675
|
+
import { join as join161 } from "node:path";
|
|
74652
74676
|
async function summarizeProjectDocs(repoPath, contentLogger) {
|
|
74653
74677
|
const rawContent = collectRawDocs(repoPath);
|
|
74654
74678
|
if (rawContent.total.length < 200) {
|
|
@@ -74702,12 +74726,12 @@ function collectRawDocs(repoPath) {
|
|
|
74702
74726
|
return capped;
|
|
74703
74727
|
};
|
|
74704
74728
|
const docsContent = [];
|
|
74705
|
-
const docsDir =
|
|
74729
|
+
const docsDir = join161(repoPath, "docs");
|
|
74706
74730
|
if (existsSync77(docsDir)) {
|
|
74707
74731
|
try {
|
|
74708
74732
|
const files = readdirSync12(docsDir).filter((f3) => f3.endsWith(".md")).sort();
|
|
74709
74733
|
for (const f3 of files) {
|
|
74710
|
-
const content = readCapped(
|
|
74734
|
+
const content = readCapped(join161(docsDir, f3), 5000);
|
|
74711
74735
|
if (content) {
|
|
74712
74736
|
docsContent.push(`### ${f3}
|
|
74713
74737
|
${content}`);
|
|
@@ -74721,21 +74745,21 @@ ${content}`);
|
|
|
74721
74745
|
let brand = "";
|
|
74722
74746
|
const brandCandidates = ["docs/brand-guidelines.md", "docs/design-guidelines.md"];
|
|
74723
74747
|
for (const p of brandCandidates) {
|
|
74724
|
-
brand = readCapped(
|
|
74748
|
+
brand = readCapped(join161(repoPath, p), 3000);
|
|
74725
74749
|
if (brand)
|
|
74726
74750
|
break;
|
|
74727
74751
|
}
|
|
74728
74752
|
let styles3 = "";
|
|
74729
|
-
const stylesDir =
|
|
74753
|
+
const stylesDir = join161(repoPath, "assets", "writing-styles");
|
|
74730
74754
|
if (existsSync77(stylesDir)) {
|
|
74731
74755
|
try {
|
|
74732
74756
|
const files = readdirSync12(stylesDir).slice(0, 3);
|
|
74733
|
-
styles3 = files.map((f3) => readCapped(
|
|
74757
|
+
styles3 = files.map((f3) => readCapped(join161(stylesDir, f3), 1000)).filter(Boolean).join(`
|
|
74734
74758
|
|
|
74735
74759
|
`);
|
|
74736
74760
|
} catch {}
|
|
74737
74761
|
}
|
|
74738
|
-
const readme = readCapped(
|
|
74762
|
+
const readme = readCapped(join161(repoPath, "README.md"), 3000);
|
|
74739
74763
|
const total = [docs, brand, styles3, readme].join(`
|
|
74740
74764
|
`);
|
|
74741
74765
|
return { docs, brand, styles: styles3, readme, total };
|
|
@@ -74921,10 +74945,10 @@ IMPORTANT: Generate the image and output the path as JSON: {"imagePath": "/path/
|
|
|
74921
74945
|
// src/commands/content/phases/photo-generator.ts
|
|
74922
74946
|
import { execSync as execSync8 } from "node:child_process";
|
|
74923
74947
|
import { existsSync as existsSync78, mkdirSync as mkdirSync6, readdirSync as readdirSync13 } from "node:fs";
|
|
74924
|
-
import { homedir as
|
|
74925
|
-
import { join as
|
|
74948
|
+
import { homedir as homedir55 } from "node:os";
|
|
74949
|
+
import { join as join162 } from "node:path";
|
|
74926
74950
|
async function generatePhoto(_content, context, config, platform18, contentId, contentLogger) {
|
|
74927
|
-
const mediaDir =
|
|
74951
|
+
const mediaDir = join162(config.contentDir.replace(/^~/, homedir55()), "media", String(contentId));
|
|
74928
74952
|
if (!existsSync78(mediaDir)) {
|
|
74929
74953
|
mkdirSync6(mediaDir, { recursive: true });
|
|
74930
74954
|
}
|
|
@@ -74949,7 +74973,7 @@ async function generatePhoto(_content, context, config, platform18, contentId, c
|
|
|
74949
74973
|
const imageFile = files.find((f3) => /\.(png|jpg|jpeg|webp)$/i.test(f3));
|
|
74950
74974
|
if (imageFile) {
|
|
74951
74975
|
const ext2 = imageFile.split(".").pop() ?? "png";
|
|
74952
|
-
return { path:
|
|
74976
|
+
return { path: join162(mediaDir, imageFile), ...dimensions, format: ext2 };
|
|
74953
74977
|
}
|
|
74954
74978
|
contentLogger.warn(`Photo generation produced no image for content ${contentId}`);
|
|
74955
74979
|
return null;
|
|
@@ -75038,8 +75062,8 @@ var init_content_creator = __esm(() => {
|
|
|
75038
75062
|
|
|
75039
75063
|
// src/commands/content/phases/content-logger.ts
|
|
75040
75064
|
import { createWriteStream as createWriteStream4, existsSync as existsSync79, mkdirSync as mkdirSync7, statSync as statSync15 } from "node:fs";
|
|
75041
|
-
import { homedir as
|
|
75042
|
-
import { join as
|
|
75065
|
+
import { homedir as homedir56 } from "node:os";
|
|
75066
|
+
import { join as join163 } from "node:path";
|
|
75043
75067
|
|
|
75044
75068
|
class ContentLogger {
|
|
75045
75069
|
stream = null;
|
|
@@ -75047,7 +75071,7 @@ class ContentLogger {
|
|
|
75047
75071
|
logDir;
|
|
75048
75072
|
maxBytes;
|
|
75049
75073
|
constructor(maxBytes = 0) {
|
|
75050
|
-
this.logDir =
|
|
75074
|
+
this.logDir = join163(homedir56(), ".claudekit", "logs");
|
|
75051
75075
|
this.maxBytes = maxBytes;
|
|
75052
75076
|
}
|
|
75053
75077
|
init() {
|
|
@@ -75079,7 +75103,7 @@ class ContentLogger {
|
|
|
75079
75103
|
}
|
|
75080
75104
|
}
|
|
75081
75105
|
getLogPath() {
|
|
75082
|
-
return
|
|
75106
|
+
return join163(this.logDir, `content-${this.getDateStr()}.log`);
|
|
75083
75107
|
}
|
|
75084
75108
|
write(level, message) {
|
|
75085
75109
|
this.rotateIfNeeded();
|
|
@@ -75096,19 +75120,19 @@ class ContentLogger {
|
|
|
75096
75120
|
if (dateStr !== this.currentDate) {
|
|
75097
75121
|
this.close();
|
|
75098
75122
|
this.currentDate = dateStr;
|
|
75099
|
-
const logPath =
|
|
75123
|
+
const logPath = join163(this.logDir, `content-${dateStr}.log`);
|
|
75100
75124
|
this.stream = createWriteStream4(logPath, { flags: "a", mode: 384 });
|
|
75101
75125
|
return;
|
|
75102
75126
|
}
|
|
75103
75127
|
if (this.maxBytes > 0 && this.stream) {
|
|
75104
|
-
const logPath =
|
|
75128
|
+
const logPath = join163(this.logDir, `content-${this.currentDate}.log`);
|
|
75105
75129
|
try {
|
|
75106
|
-
const
|
|
75107
|
-
if (
|
|
75130
|
+
const stat26 = statSync15(logPath);
|
|
75131
|
+
if (stat26.size >= this.maxBytes) {
|
|
75108
75132
|
this.close();
|
|
75109
75133
|
const suffix = Date.now();
|
|
75110
|
-
const rotatedPath =
|
|
75111
|
-
import("node:fs/promises").then(({ rename:
|
|
75134
|
+
const rotatedPath = join163(this.logDir, `content-${this.currentDate}-${suffix}.log`);
|
|
75135
|
+
import("node:fs/promises").then(({ rename: rename16 }) => rename16(logPath, rotatedPath).catch(() => {}));
|
|
75112
75136
|
this.stream = createWriteStream4(logPath, { flags: "w", mode: 384 });
|
|
75113
75137
|
}
|
|
75114
75138
|
} catch {}
|
|
@@ -75145,7 +75169,7 @@ var init_sqlite_client = () => {};
|
|
|
75145
75169
|
|
|
75146
75170
|
// src/commands/content/phases/db-manager.ts
|
|
75147
75171
|
import { existsSync as existsSync80, mkdirSync as mkdirSync8 } from "node:fs";
|
|
75148
|
-
import { dirname as
|
|
75172
|
+
import { dirname as dirname49 } from "node:path";
|
|
75149
75173
|
function initDatabase(dbPath) {
|
|
75150
75174
|
ensureParentDir(dbPath);
|
|
75151
75175
|
const db = openDatabase(dbPath);
|
|
@@ -75166,7 +75190,7 @@ function runRetentionCleanup(db, retentionDays = 90) {
|
|
|
75166
75190
|
db.prepare("DELETE FROM git_events WHERE processed = 1 AND created_at < ?").run(cutoff);
|
|
75167
75191
|
}
|
|
75168
75192
|
function ensureParentDir(dbPath) {
|
|
75169
|
-
const dir =
|
|
75193
|
+
const dir = dirname49(dbPath);
|
|
75170
75194
|
if (dir && !existsSync80(dir)) {
|
|
75171
75195
|
mkdirSync8(dir, { recursive: true });
|
|
75172
75196
|
}
|
|
@@ -75333,7 +75357,7 @@ function isNoiseCommit(title, author) {
|
|
|
75333
75357
|
// src/commands/content/phases/change-detector.ts
|
|
75334
75358
|
import { execSync as execSync10, spawnSync as spawnSync9 } from "node:child_process";
|
|
75335
75359
|
import { existsSync as existsSync81, readFileSync as readFileSync20, readdirSync as readdirSync14, statSync as statSync16 } from "node:fs";
|
|
75336
|
-
import { join as
|
|
75360
|
+
import { join as join164 } from "node:path";
|
|
75337
75361
|
function detectCommits(repo, since) {
|
|
75338
75362
|
try {
|
|
75339
75363
|
const fetchUrl = sshToHttps(repo.remoteUrl);
|
|
@@ -75442,7 +75466,7 @@ function detectTags(repo, since) {
|
|
|
75442
75466
|
}
|
|
75443
75467
|
}
|
|
75444
75468
|
function detectCompletedPlans(repo, since) {
|
|
75445
|
-
const plansDir =
|
|
75469
|
+
const plansDir = join164(repo.path, "plans");
|
|
75446
75470
|
if (!existsSync81(plansDir))
|
|
75447
75471
|
return [];
|
|
75448
75472
|
const sinceMs = new Date(since).getTime();
|
|
@@ -75452,12 +75476,12 @@ function detectCompletedPlans(repo, since) {
|
|
|
75452
75476
|
for (const entry of entries) {
|
|
75453
75477
|
if (!entry.isDirectory())
|
|
75454
75478
|
continue;
|
|
75455
|
-
const planFile =
|
|
75479
|
+
const planFile = join164(plansDir, entry.name, "plan.md");
|
|
75456
75480
|
if (!existsSync81(planFile))
|
|
75457
75481
|
continue;
|
|
75458
75482
|
try {
|
|
75459
|
-
const
|
|
75460
|
-
if (
|
|
75483
|
+
const stat26 = statSync16(planFile);
|
|
75484
|
+
if (stat26.mtimeMs < sinceMs)
|
|
75461
75485
|
continue;
|
|
75462
75486
|
const content = readFileSync20(planFile, "utf-8");
|
|
75463
75487
|
const frontmatterMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
@@ -75473,7 +75497,7 @@ function detectCompletedPlans(repo, since) {
|
|
|
75473
75497
|
title: `Plan completed: ${entry.name}`,
|
|
75474
75498
|
body: "",
|
|
75475
75499
|
author: "",
|
|
75476
|
-
createdAt: new Date(
|
|
75500
|
+
createdAt: new Date(stat26.mtimeMs).toISOString()
|
|
75477
75501
|
});
|
|
75478
75502
|
} catch {}
|
|
75479
75503
|
}
|
|
@@ -75530,7 +75554,7 @@ function classifyCommit(event) {
|
|
|
75530
75554
|
// src/commands/content/phases/repo-discoverer.ts
|
|
75531
75555
|
import { execSync as execSync11 } from "node:child_process";
|
|
75532
75556
|
import { readdirSync as readdirSync15 } from "node:fs";
|
|
75533
|
-
import { join as
|
|
75557
|
+
import { join as join165 } from "node:path";
|
|
75534
75558
|
function discoverRepos2(cwd2) {
|
|
75535
75559
|
const repos = [];
|
|
75536
75560
|
if (isGitRepoRoot(cwd2)) {
|
|
@@ -75543,7 +75567,7 @@ function discoverRepos2(cwd2) {
|
|
|
75543
75567
|
for (const entry of entries) {
|
|
75544
75568
|
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
75545
75569
|
continue;
|
|
75546
|
-
const dirPath =
|
|
75570
|
+
const dirPath = join165(cwd2, entry.name);
|
|
75547
75571
|
if (isGitRepoRoot(dirPath)) {
|
|
75548
75572
|
const info = getRepoInfo(dirPath);
|
|
75549
75573
|
if (info)
|
|
@@ -76210,10 +76234,10 @@ var init_types6 = __esm(() => {
|
|
|
76210
76234
|
});
|
|
76211
76235
|
|
|
76212
76236
|
// src/commands/content/phases/state-manager.ts
|
|
76213
|
-
import { readFile as readFile68, rename as
|
|
76214
|
-
import { join as
|
|
76237
|
+
import { readFile as readFile68, rename as rename16, writeFile as writeFile40 } from "node:fs/promises";
|
|
76238
|
+
import { join as join166 } from "node:path";
|
|
76215
76239
|
async function loadContentConfig(projectDir) {
|
|
76216
|
-
const configPath =
|
|
76240
|
+
const configPath = join166(projectDir, CK_CONFIG_FILE2);
|
|
76217
76241
|
try {
|
|
76218
76242
|
const raw2 = await readFile68(configPath, "utf-8");
|
|
76219
76243
|
const json = JSON.parse(raw2);
|
|
@@ -76223,13 +76247,13 @@ async function loadContentConfig(projectDir) {
|
|
|
76223
76247
|
}
|
|
76224
76248
|
}
|
|
76225
76249
|
async function saveContentConfig(projectDir, config) {
|
|
76226
|
-
const configPath =
|
|
76250
|
+
const configPath = join166(projectDir, CK_CONFIG_FILE2);
|
|
76227
76251
|
const json = await readJsonSafe(configPath);
|
|
76228
76252
|
json.content = { ...json.content, ...config };
|
|
76229
76253
|
await atomicWrite2(configPath, json);
|
|
76230
76254
|
}
|
|
76231
76255
|
async function loadContentState(projectDir) {
|
|
76232
|
-
const configPath =
|
|
76256
|
+
const configPath = join166(projectDir, CK_CONFIG_FILE2);
|
|
76233
76257
|
try {
|
|
76234
76258
|
const raw2 = await readFile68(configPath, "utf-8");
|
|
76235
76259
|
const json = JSON.parse(raw2);
|
|
@@ -76240,7 +76264,7 @@ async function loadContentState(projectDir) {
|
|
|
76240
76264
|
}
|
|
76241
76265
|
}
|
|
76242
76266
|
async function saveContentState(projectDir, state) {
|
|
76243
|
-
const configPath =
|
|
76267
|
+
const configPath = join166(projectDir, CK_CONFIG_FILE2);
|
|
76244
76268
|
const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().slice(0, 10);
|
|
76245
76269
|
for (const key of Object.keys(state.dailyPostCounts)) {
|
|
76246
76270
|
const dateStr = key.slice(-10);
|
|
@@ -76267,7 +76291,7 @@ async function readJsonSafe(filePath) {
|
|
|
76267
76291
|
async function atomicWrite2(filePath, data) {
|
|
76268
76292
|
const tmpPath = `${filePath}.tmp`;
|
|
76269
76293
|
await writeFile40(tmpPath, JSON.stringify(data, null, 2), "utf-8");
|
|
76270
|
-
await
|
|
76294
|
+
await rename16(tmpPath, filePath);
|
|
76271
76295
|
}
|
|
76272
76296
|
var CK_CONFIG_FILE2 = ".ck.json";
|
|
76273
76297
|
var init_state_manager = __esm(() => {
|
|
@@ -76522,7 +76546,7 @@ var init_platform_setup_x = __esm(() => {
|
|
|
76522
76546
|
|
|
76523
76547
|
// src/commands/content/phases/setup-wizard.ts
|
|
76524
76548
|
import { existsSync as existsSync82 } from "node:fs";
|
|
76525
|
-
import { join as
|
|
76549
|
+
import { join as join167 } from "node:path";
|
|
76526
76550
|
async function runSetupWizard2(cwd2, contentLogger) {
|
|
76527
76551
|
console.log();
|
|
76528
76552
|
oe(import_picocolors43.default.bgCyan(import_picocolors43.default.white(" CK Content — Multi-Channel Content Engine ")));
|
|
@@ -76590,8 +76614,8 @@ async function showRepoSummary(cwd2) {
|
|
|
76590
76614
|
function detectBrandAssets(cwd2, contentLogger) {
|
|
76591
76615
|
const repos = discoverRepos2(cwd2);
|
|
76592
76616
|
for (const repo of repos) {
|
|
76593
|
-
const hasGuidelines = existsSync82(
|
|
76594
|
-
const hasStyles = existsSync82(
|
|
76617
|
+
const hasGuidelines = existsSync82(join167(repo.path, "docs", "brand-guidelines.md"));
|
|
76618
|
+
const hasStyles = existsSync82(join167(repo.path, "assets", "writing-styles"));
|
|
76595
76619
|
if (!hasGuidelines) {
|
|
76596
76620
|
f2.warning(`${repo.name}: No docs/brand-guidelines.md — content will use generic tone.`);
|
|
76597
76621
|
contentLogger.warn(`${repo.name}: missing docs/brand-guidelines.md`);
|
|
@@ -76658,11 +76682,11 @@ var init_setup_wizard = __esm(() => {
|
|
|
76658
76682
|
|
|
76659
76683
|
// src/commands/content/content-review-commands.ts
|
|
76660
76684
|
import { existsSync as existsSync83 } from "node:fs";
|
|
76661
|
-
import { homedir as
|
|
76685
|
+
import { homedir as homedir57 } from "node:os";
|
|
76662
76686
|
async function queueContent() {
|
|
76663
76687
|
const cwd2 = process.cwd();
|
|
76664
76688
|
const config = await loadContentConfig(cwd2);
|
|
76665
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
76689
|
+
const dbPath = config.dbPath.replace(/^~/, homedir57());
|
|
76666
76690
|
if (!existsSync83(dbPath)) {
|
|
76667
76691
|
logger.info("No content database found. Run 'ck content setup' first.");
|
|
76668
76692
|
return;
|
|
@@ -76689,7 +76713,7 @@ async function queueContent() {
|
|
|
76689
76713
|
async function approveContentCmd(id) {
|
|
76690
76714
|
const cwd2 = process.cwd();
|
|
76691
76715
|
const config = await loadContentConfig(cwd2);
|
|
76692
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
76716
|
+
const dbPath = config.dbPath.replace(/^~/, homedir57());
|
|
76693
76717
|
const db = initDatabase(dbPath);
|
|
76694
76718
|
try {
|
|
76695
76719
|
approveContent(db, Number.parseInt(id, 10));
|
|
@@ -76701,7 +76725,7 @@ async function approveContentCmd(id) {
|
|
|
76701
76725
|
async function rejectContentCmd(id, reason) {
|
|
76702
76726
|
const cwd2 = process.cwd();
|
|
76703
76727
|
const config = await loadContentConfig(cwd2);
|
|
76704
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
76728
|
+
const dbPath = config.dbPath.replace(/^~/, homedir57());
|
|
76705
76729
|
const db = initDatabase(dbPath);
|
|
76706
76730
|
try {
|
|
76707
76731
|
rejectContent(db, Number.parseInt(id, 10), reason);
|
|
@@ -76732,10 +76756,10 @@ __export(exports_content_subcommands, {
|
|
|
76732
76756
|
approveContentCmd: () => approveContentCmd
|
|
76733
76757
|
});
|
|
76734
76758
|
import { existsSync as existsSync84, readFileSync as readFileSync21, unlinkSync as unlinkSync6 } from "node:fs";
|
|
76735
|
-
import { homedir as
|
|
76736
|
-
import { join as
|
|
76759
|
+
import { homedir as homedir58 } from "node:os";
|
|
76760
|
+
import { join as join168 } from "node:path";
|
|
76737
76761
|
function isDaemonRunning() {
|
|
76738
|
-
const lockFile =
|
|
76762
|
+
const lockFile = join168(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
76739
76763
|
if (!existsSync84(lockFile))
|
|
76740
76764
|
return { running: false, pid: null };
|
|
76741
76765
|
try {
|
|
@@ -76767,7 +76791,7 @@ async function startContent(options2) {
|
|
|
76767
76791
|
await contentCommand(options2);
|
|
76768
76792
|
}
|
|
76769
76793
|
async function stopContent() {
|
|
76770
|
-
const lockFile =
|
|
76794
|
+
const lockFile = join168(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
76771
76795
|
if (!existsSync84(lockFile)) {
|
|
76772
76796
|
logger.info("Content daemon is not running.");
|
|
76773
76797
|
return;
|
|
@@ -76806,9 +76830,9 @@ async function statusContent() {
|
|
|
76806
76830
|
} catch {}
|
|
76807
76831
|
}
|
|
76808
76832
|
async function logsContent(options2) {
|
|
76809
|
-
const logDir =
|
|
76833
|
+
const logDir = join168(homedir58(), ".claudekit", "logs");
|
|
76810
76834
|
const dateStr = new Date().toISOString().slice(0, 10).replace(/-/g, "");
|
|
76811
|
-
const logPath =
|
|
76835
|
+
const logPath = join168(logDir, `content-${dateStr}.log`);
|
|
76812
76836
|
if (!existsSync84(logPath)) {
|
|
76813
76837
|
logger.info("No content logs found for today.");
|
|
76814
76838
|
return;
|
|
@@ -76840,13 +76864,13 @@ var init_content_subcommands = __esm(() => {
|
|
|
76840
76864
|
init_setup_wizard();
|
|
76841
76865
|
init_state_manager();
|
|
76842
76866
|
init_content_review_commands();
|
|
76843
|
-
LOCK_DIR =
|
|
76867
|
+
LOCK_DIR = join168(homedir58(), ".claudekit", "locks");
|
|
76844
76868
|
});
|
|
76845
76869
|
|
|
76846
76870
|
// src/commands/content/content-command.ts
|
|
76847
76871
|
import { existsSync as existsSync85, mkdirSync as mkdirSync9, unlinkSync as unlinkSync7, writeFileSync as writeFileSync7 } from "node:fs";
|
|
76848
|
-
import { homedir as
|
|
76849
|
-
import { join as
|
|
76872
|
+
import { homedir as homedir59 } from "node:os";
|
|
76873
|
+
import { join as join169 } from "node:path";
|
|
76850
76874
|
async function contentCommand(options2) {
|
|
76851
76875
|
const cwd2 = process.cwd();
|
|
76852
76876
|
const contentLogger = new ContentLogger;
|
|
@@ -76878,7 +76902,7 @@ async function contentCommand(options2) {
|
|
|
76878
76902
|
if (!existsSync85(LOCK_DIR2))
|
|
76879
76903
|
mkdirSync9(LOCK_DIR2, { recursive: true });
|
|
76880
76904
|
writeFileSync7(LOCK_FILE, String(process.pid), "utf-8");
|
|
76881
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
76905
|
+
const dbPath = config.dbPath.replace(/^~/, homedir59());
|
|
76882
76906
|
const db = initDatabase(dbPath);
|
|
76883
76907
|
contentLogger.info(`Database initialised at ${dbPath}`);
|
|
76884
76908
|
const adapters = initializeAdapters(config);
|
|
@@ -77024,8 +77048,8 @@ var init_content_command = __esm(() => {
|
|
|
77024
77048
|
init_publisher();
|
|
77025
77049
|
init_review_manager();
|
|
77026
77050
|
init_state_manager();
|
|
77027
|
-
LOCK_DIR2 =
|
|
77028
|
-
LOCK_FILE =
|
|
77051
|
+
LOCK_DIR2 = join169(homedir59(), ".claudekit", "locks");
|
|
77052
|
+
LOCK_FILE = join169(LOCK_DIR2, "ck-content.lock");
|
|
77029
77053
|
});
|
|
77030
77054
|
|
|
77031
77055
|
// src/commands/content/index.ts
|
|
@@ -105688,8 +105712,8 @@ async function handlePostInstall(ctx) {
|
|
|
105688
105712
|
// src/commands/init/phases/selection-handler.ts
|
|
105689
105713
|
init_config_manager();
|
|
105690
105714
|
init_github_client();
|
|
105691
|
-
import { mkdir as
|
|
105692
|
-
import { join as
|
|
105715
|
+
import { mkdir as mkdir36 } from "node:fs/promises";
|
|
105716
|
+
import { join as join134, resolve as resolve43 } from "node:path";
|
|
105693
105717
|
|
|
105694
105718
|
// src/domains/github/kit-access-checker.ts
|
|
105695
105719
|
init_error2();
|
|
@@ -106105,12 +106129,134 @@ async function handleFreshInstallation(claudeDir3, prompts) {
|
|
|
106105
106129
|
}
|
|
106106
106130
|
}
|
|
106107
106131
|
|
|
106132
|
+
// src/domains/installation/global-kit-legacy-repair.ts
|
|
106133
|
+
var import_fs_extra35 = __toESM(require_lib(), 1);
|
|
106134
|
+
import { cp as cp5, mkdir as mkdir35, readdir as readdir41, rename as rename10, rm as rm15, stat as stat22 } from "node:fs/promises";
|
|
106135
|
+
import { homedir as homedir46 } from "node:os";
|
|
106136
|
+
import { dirname as dirname39, join as join133, normalize as normalize11, resolve as resolve41 } from "node:path";
|
|
106137
|
+
var LEGACY_KIT_MARKERS = [
|
|
106138
|
+
"metadata.json",
|
|
106139
|
+
".ck.json",
|
|
106140
|
+
"settings.json",
|
|
106141
|
+
"settings.local.json",
|
|
106142
|
+
"agents",
|
|
106143
|
+
"commands",
|
|
106144
|
+
"rules",
|
|
106145
|
+
"hooks",
|
|
106146
|
+
"skills",
|
|
106147
|
+
"CLAUDE.md"
|
|
106148
|
+
];
|
|
106149
|
+
function safeEnvPath(value) {
|
|
106150
|
+
if (!value || value.trim() === "" || value.includes("..")) {
|
|
106151
|
+
return;
|
|
106152
|
+
}
|
|
106153
|
+
return value;
|
|
106154
|
+
}
|
|
106155
|
+
function withoutTrailingSeparators(path16) {
|
|
106156
|
+
return path16.replace(/[\\/]+$/, "");
|
|
106157
|
+
}
|
|
106158
|
+
function uniqueNormalizedPaths(paths) {
|
|
106159
|
+
const seen = new Set;
|
|
106160
|
+
const result = [];
|
|
106161
|
+
for (const path16 of paths) {
|
|
106162
|
+
const normalized = normalize11(resolve41(path16));
|
|
106163
|
+
if (seen.has(normalized))
|
|
106164
|
+
continue;
|
|
106165
|
+
seen.add(normalized);
|
|
106166
|
+
result.push(path16);
|
|
106167
|
+
}
|
|
106168
|
+
return result;
|
|
106169
|
+
}
|
|
106170
|
+
function getLegacyWindowsGlobalKitDirCandidates(env2 = process.env, homeDir = homedir46()) {
|
|
106171
|
+
const candidates = [];
|
|
106172
|
+
const localAppData = safeEnvPath(env2.LOCALAPPDATA);
|
|
106173
|
+
const appData = safeEnvPath(env2.APPDATA);
|
|
106174
|
+
if (localAppData) {
|
|
106175
|
+
candidates.push(join133(localAppData, ".claude"));
|
|
106176
|
+
}
|
|
106177
|
+
if (appData) {
|
|
106178
|
+
candidates.push(join133(appData, ".claude"));
|
|
106179
|
+
}
|
|
106180
|
+
if (homeDir) {
|
|
106181
|
+
candidates.push(`${withoutTrailingSeparators(homeDir)}.claude`);
|
|
106182
|
+
}
|
|
106183
|
+
return uniqueNormalizedPaths(candidates);
|
|
106184
|
+
}
|
|
106185
|
+
async function isDirectory(path16) {
|
|
106186
|
+
try {
|
|
106187
|
+
return (await stat22(path16)).isDirectory();
|
|
106188
|
+
} catch {
|
|
106189
|
+
return false;
|
|
106190
|
+
}
|
|
106191
|
+
}
|
|
106192
|
+
async function hasKitMarkers(dir) {
|
|
106193
|
+
if (!await isDirectory(dir))
|
|
106194
|
+
return false;
|
|
106195
|
+
for (const marker of LEGACY_KIT_MARKERS) {
|
|
106196
|
+
if (await import_fs_extra35.pathExists(join133(dir, marker))) {
|
|
106197
|
+
return true;
|
|
106198
|
+
}
|
|
106199
|
+
}
|
|
106200
|
+
return false;
|
|
106201
|
+
}
|
|
106202
|
+
async function isEmptyDirectory(dir) {
|
|
106203
|
+
if (!await isDirectory(dir))
|
|
106204
|
+
return false;
|
|
106205
|
+
return (await readdir41(dir)).length === 0;
|
|
106206
|
+
}
|
|
106207
|
+
async function moveDirectory(source, target) {
|
|
106208
|
+
try {
|
|
106209
|
+
await rename10(source, target);
|
|
106210
|
+
} catch (error) {
|
|
106211
|
+
if (error.code !== "EXDEV") {
|
|
106212
|
+
throw error;
|
|
106213
|
+
}
|
|
106214
|
+
await cp5(source, target, { recursive: true, errorOnExist: true, force: false });
|
|
106215
|
+
await rm15(source, { recursive: true, force: true });
|
|
106216
|
+
}
|
|
106217
|
+
}
|
|
106218
|
+
async function repairLegacyWindowsGlobalKitDir(options2) {
|
|
106219
|
+
const env2 = options2.env ?? process.env;
|
|
106220
|
+
const os7 = options2.platform ?? process.platform;
|
|
106221
|
+
if (os7 !== "win32") {
|
|
106222
|
+
return { status: "skipped", reason: "not-windows", candidateDirs: [] };
|
|
106223
|
+
}
|
|
106224
|
+
if (safeEnvPath(env2.CLAUDE_CONFIG_DIR)) {
|
|
106225
|
+
return { status: "skipped", reason: "custom-global-dir", candidateDirs: [] };
|
|
106226
|
+
}
|
|
106227
|
+
const targetDir = normalize11(resolve41(options2.targetDir));
|
|
106228
|
+
const candidateDirs = getLegacyWindowsGlobalKitDirCandidates(env2, options2.homeDir).filter((candidate) => normalize11(resolve41(candidate)) !== targetDir);
|
|
106229
|
+
const legacyDirs = [];
|
|
106230
|
+
for (const candidate of candidateDirs) {
|
|
106231
|
+
if (await hasKitMarkers(candidate)) {
|
|
106232
|
+
legacyDirs.push(candidate);
|
|
106233
|
+
}
|
|
106234
|
+
}
|
|
106235
|
+
if (legacyDirs.length === 0) {
|
|
106236
|
+
return { status: "skipped", reason: "no-legacy-dir", candidateDirs };
|
|
106237
|
+
}
|
|
106238
|
+
if (legacyDirs.length > 1) {
|
|
106239
|
+
return { status: "skipped", reason: "ambiguous-legacy-dirs", candidateDirs };
|
|
106240
|
+
}
|
|
106241
|
+
const [legacyDir] = legacyDirs;
|
|
106242
|
+
const targetExists = await import_fs_extra35.pathExists(targetDir);
|
|
106243
|
+
if (targetExists && !await isEmptyDirectory(targetDir)) {
|
|
106244
|
+
return { status: "skipped", reason: "target-exists", legacyDir, candidateDirs };
|
|
106245
|
+
}
|
|
106246
|
+
if (targetExists) {
|
|
106247
|
+
await rm15(targetDir, { recursive: true, force: true });
|
|
106248
|
+
}
|
|
106249
|
+
await mkdir35(dirname39(targetDir), { recursive: true });
|
|
106250
|
+
await moveDirectory(legacyDir, targetDir);
|
|
106251
|
+
return { status: "repaired", reason: "repaired", legacyDir, candidateDirs };
|
|
106252
|
+
}
|
|
106253
|
+
|
|
106108
106254
|
// src/commands/init/phases/selection-handler.ts
|
|
106109
106255
|
init_version_utils();
|
|
106110
106256
|
init_logger();
|
|
106111
106257
|
init_path_resolver();
|
|
106112
106258
|
init_types3();
|
|
106113
|
-
var
|
|
106259
|
+
var import_fs_extra36 = __toESM(require_lib(), 1);
|
|
106114
106260
|
|
|
106115
106261
|
// src/commands/init/types.ts
|
|
106116
106262
|
function isSyncContext(ctx) {
|
|
@@ -106302,7 +106448,20 @@ async function handleSelection(ctx) {
|
|
|
106302
106448
|
}
|
|
106303
106449
|
}
|
|
106304
106450
|
}
|
|
106305
|
-
const resolvedDir =
|
|
106451
|
+
const resolvedDir = resolve43(targetDir);
|
|
106452
|
+
if (ctx.options.global) {
|
|
106453
|
+
try {
|
|
106454
|
+
const repairResult = await repairLegacyWindowsGlobalKitDir({ targetDir: resolvedDir });
|
|
106455
|
+
if (repairResult.status === "repaired") {
|
|
106456
|
+
logger.success(`Migrated legacy Windows global kit directory from ${repairResult.legacyDir} to ${resolvedDir}`);
|
|
106457
|
+
} else if (repairResult.reason === "target-exists" || repairResult.reason === "ambiguous-legacy-dirs") {
|
|
106458
|
+
logger.warning(`Detected legacy Windows global kit directory but did not auto-migrate it (${repairResult.reason}).`);
|
|
106459
|
+
logger.info(`Using global kit directory: ${resolvedDir}`);
|
|
106460
|
+
}
|
|
106461
|
+
} catch (err) {
|
|
106462
|
+
logger.warning(`Legacy global kit dir repair failed, continuing: ${err instanceof Error ? err.message : String(err)}`);
|
|
106463
|
+
}
|
|
106464
|
+
}
|
|
106306
106465
|
logger.info(`Target directory: ${resolvedDir}`);
|
|
106307
106466
|
if (!ctx.options.global && PathResolver.isLocalSameAsGlobal(resolvedDir)) {
|
|
106308
106467
|
logger.warning("You're at HOME directory. Installing here modifies your GLOBAL ClaudeKit.");
|
|
@@ -106324,9 +106483,9 @@ async function handleSelection(ctx) {
|
|
|
106324
106483
|
return { ...ctx, cancelled: true };
|
|
106325
106484
|
}
|
|
106326
106485
|
}
|
|
106327
|
-
if (!await
|
|
106486
|
+
if (!await import_fs_extra36.pathExists(resolvedDir)) {
|
|
106328
106487
|
if (ctx.options.global) {
|
|
106329
|
-
await
|
|
106488
|
+
await mkdir36(resolvedDir, { recursive: true });
|
|
106330
106489
|
logger.info(`Created global directory: ${resolvedDir}`);
|
|
106331
106490
|
} else {
|
|
106332
106491
|
logger.error(`Directory does not exist: ${resolvedDir}`);
|
|
@@ -106336,7 +106495,7 @@ async function handleSelection(ctx) {
|
|
|
106336
106495
|
}
|
|
106337
106496
|
if (!ctx.options.fresh) {
|
|
106338
106497
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
106339
|
-
const claudeDir3 = prefix ?
|
|
106498
|
+
const claudeDir3 = prefix ? join134(resolvedDir, prefix) : resolvedDir;
|
|
106340
106499
|
try {
|
|
106341
106500
|
const existingMetadata = await readManifest(claudeDir3);
|
|
106342
106501
|
if (existingMetadata?.kits) {
|
|
@@ -106373,7 +106532,7 @@ async function handleSelection(ctx) {
|
|
|
106373
106532
|
}
|
|
106374
106533
|
if (ctx.options.fresh) {
|
|
106375
106534
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
106376
|
-
const claudeDir3 = prefix ?
|
|
106535
|
+
const claudeDir3 = prefix ? join134(resolvedDir, prefix) : resolvedDir;
|
|
106377
106536
|
const canProceed = await handleFreshInstallation(claudeDir3, ctx.prompts);
|
|
106378
106537
|
if (!canProceed) {
|
|
106379
106538
|
return { ...ctx, cancelled: true };
|
|
@@ -106393,7 +106552,7 @@ async function handleSelection(ctx) {
|
|
|
106393
106552
|
let currentVersion = null;
|
|
106394
106553
|
try {
|
|
106395
106554
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
106396
|
-
const claudeDir3 = prefix ?
|
|
106555
|
+
const claudeDir3 = prefix ? join134(resolvedDir, prefix) : resolvedDir;
|
|
106397
106556
|
const existingMetadata = await readManifest(claudeDir3);
|
|
106398
106557
|
currentVersion = existingMetadata?.kits?.[kitType]?.version || null;
|
|
106399
106558
|
if (currentVersion) {
|
|
@@ -106462,7 +106621,7 @@ async function handleSelection(ctx) {
|
|
|
106462
106621
|
if (ctx.options.yes && !ctx.options.fresh && !ctx.options.force && releaseTag && !isOfflineMode && !pendingKits?.length) {
|
|
106463
106622
|
try {
|
|
106464
106623
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
106465
|
-
const claudeDir3 = prefix ?
|
|
106624
|
+
const claudeDir3 = prefix ? join134(resolvedDir, prefix) : resolvedDir;
|
|
106466
106625
|
const existingMetadata = await readManifest(claudeDir3);
|
|
106467
106626
|
const installedKitVersion = existingMetadata?.kits?.[kitType]?.version;
|
|
106468
106627
|
if (installedKitVersion && versionsMatch(installedKitVersion, releaseTag)) {
|
|
@@ -106485,25 +106644,25 @@ async function handleSelection(ctx) {
|
|
|
106485
106644
|
};
|
|
106486
106645
|
}
|
|
106487
106646
|
// src/commands/init/phases/sync-handler.ts
|
|
106488
|
-
import { copyFile as copyFile8, mkdir as
|
|
106489
|
-
import { dirname as
|
|
106647
|
+
import { copyFile as copyFile8, mkdir as mkdir37, open as open5, readFile as readFile58, rename as rename11, stat as stat23, unlink as unlink12, writeFile as writeFile32 } from "node:fs/promises";
|
|
106648
|
+
import { dirname as dirname40, join as join135, resolve as resolve45 } from "node:path";
|
|
106490
106649
|
init_logger();
|
|
106491
106650
|
init_path_resolver();
|
|
106492
|
-
var
|
|
106651
|
+
var import_fs_extra37 = __toESM(require_lib(), 1);
|
|
106493
106652
|
var import_picocolors26 = __toESM(require_picocolors(), 1);
|
|
106494
106653
|
async function handleSync(ctx) {
|
|
106495
106654
|
if (!ctx.options.sync) {
|
|
106496
106655
|
return ctx;
|
|
106497
106656
|
}
|
|
106498
|
-
const resolvedDir = ctx.options.global ? PathResolver.getGlobalKitDir() :
|
|
106499
|
-
const claudeDir3 = ctx.options.global ? resolvedDir :
|
|
106500
|
-
if (!await
|
|
106657
|
+
const resolvedDir = ctx.options.global ? PathResolver.getGlobalKitDir() : resolve45(ctx.options.dir || ".");
|
|
106658
|
+
const claudeDir3 = ctx.options.global ? resolvedDir : join135(resolvedDir, ".claude");
|
|
106659
|
+
if (!await import_fs_extra37.pathExists(claudeDir3)) {
|
|
106501
106660
|
logger.error("Cannot sync: no .claude directory found");
|
|
106502
106661
|
ctx.prompts.note("Run 'ck init' without --sync to install first.", "No Installation Found");
|
|
106503
106662
|
return { ...ctx, cancelled: true };
|
|
106504
106663
|
}
|
|
106505
|
-
const metadataPath =
|
|
106506
|
-
if (!await
|
|
106664
|
+
const metadataPath = join135(claudeDir3, "metadata.json");
|
|
106665
|
+
if (!await import_fs_extra37.pathExists(metadataPath)) {
|
|
106507
106666
|
logger.error("Cannot sync: no metadata.json found");
|
|
106508
106667
|
ctx.prompts.note(`Your installation may be from an older version.
|
|
106509
106668
|
Run 'ck init' to update.`, "Legacy Installation");
|
|
@@ -106602,10 +106761,10 @@ function getLockTimeout() {
|
|
|
106602
106761
|
var STALE_LOCK_THRESHOLD_MS = 5 * 60 * 1000;
|
|
106603
106762
|
async function acquireSyncLock(global3) {
|
|
106604
106763
|
const cacheDir = PathResolver.getCacheDir(global3);
|
|
106605
|
-
const lockPath =
|
|
106764
|
+
const lockPath = join135(cacheDir, ".sync-lock");
|
|
106606
106765
|
const startTime = Date.now();
|
|
106607
106766
|
const lockTimeout = getLockTimeout();
|
|
106608
|
-
await
|
|
106767
|
+
await mkdir37(dirname40(lockPath), { recursive: true });
|
|
106609
106768
|
while (Date.now() - startTime < lockTimeout) {
|
|
106610
106769
|
try {
|
|
106611
106770
|
const handle = await open5(lockPath, "wx");
|
|
@@ -106616,7 +106775,7 @@ async function acquireSyncLock(global3) {
|
|
|
106616
106775
|
} catch (err) {
|
|
106617
106776
|
if (err.code === "EEXIST") {
|
|
106618
106777
|
try {
|
|
106619
|
-
const lockStat = await
|
|
106778
|
+
const lockStat = await stat23(lockPath);
|
|
106620
106779
|
const lockAge = Math.abs(Date.now() - lockStat.mtimeMs);
|
|
106621
106780
|
if (lockAge > STALE_LOCK_THRESHOLD_MS) {
|
|
106622
106781
|
logger.warning(`Removing stale sync lock (age: ${Math.round(lockAge / 1000)}s)`);
|
|
@@ -106648,11 +106807,11 @@ async function executeSyncMerge(ctx) {
|
|
|
106648
106807
|
const releaseLock = await acquireSyncLock(ctx.options.global);
|
|
106649
106808
|
try {
|
|
106650
106809
|
const trackedFiles = ctx.syncTrackedFiles;
|
|
106651
|
-
const upstreamDir = ctx.options.global ?
|
|
106810
|
+
const upstreamDir = ctx.options.global ? join135(ctx.extractDir, ".claude") : ctx.extractDir;
|
|
106652
106811
|
let deletions = [];
|
|
106653
106812
|
try {
|
|
106654
|
-
const sourceMetadataPath =
|
|
106655
|
-
if (await
|
|
106813
|
+
const sourceMetadataPath = join135(upstreamDir, "metadata.json");
|
|
106814
|
+
if (await import_fs_extra37.pathExists(sourceMetadataPath)) {
|
|
106656
106815
|
const content = await readFile58(sourceMetadataPath, "utf-8");
|
|
106657
106816
|
const sourceMetadata = JSON.parse(content);
|
|
106658
106817
|
deletions = sourceMetadata.deletions || [];
|
|
@@ -106683,9 +106842,9 @@ async function executeSyncMerge(ctx) {
|
|
|
106683
106842
|
try {
|
|
106684
106843
|
const sourcePath = await validateSyncPath(upstreamDir, file.path);
|
|
106685
106844
|
const targetPath = await validateSyncPath(ctx.claudeDir, file.path);
|
|
106686
|
-
const targetDir =
|
|
106845
|
+
const targetDir = join135(targetPath, "..");
|
|
106687
106846
|
try {
|
|
106688
|
-
await
|
|
106847
|
+
await mkdir37(targetDir, { recursive: true });
|
|
106689
106848
|
} catch (mkdirError) {
|
|
106690
106849
|
const errCode = mkdirError.code;
|
|
106691
106850
|
if (errCode === "ENOSPC") {
|
|
@@ -106765,7 +106924,7 @@ async function executeSyncMerge(ctx) {
|
|
|
106765
106924
|
const tempPath = `${currentPath}.tmp.${Date.now()}`;
|
|
106766
106925
|
try {
|
|
106767
106926
|
await writeFile32(tempPath, result.result, "utf-8");
|
|
106768
|
-
await
|
|
106927
|
+
await rename11(tempPath, currentPath);
|
|
106769
106928
|
} catch (atomicError) {
|
|
106770
106929
|
await unlink12(tempPath).catch(() => {});
|
|
106771
106930
|
throw atomicError;
|
|
@@ -106848,14 +107007,14 @@ function displaySyncPlan(plan) {
|
|
|
106848
107007
|
console.log(import_picocolors26.default.dim("─".repeat(40)));
|
|
106849
107008
|
}
|
|
106850
107009
|
async function createBackup(claudeDir3, files, backupDir) {
|
|
106851
|
-
await
|
|
107010
|
+
await mkdir37(backupDir, { recursive: true });
|
|
106852
107011
|
for (const file of files) {
|
|
106853
107012
|
try {
|
|
106854
107013
|
const sourcePath = await validateSyncPath(claudeDir3, file.path);
|
|
106855
|
-
if (await
|
|
107014
|
+
if (await import_fs_extra37.pathExists(sourcePath)) {
|
|
106856
107015
|
const targetPath = await validateSyncPath(backupDir, file.path);
|
|
106857
|
-
const targetDir =
|
|
106858
|
-
await
|
|
107016
|
+
const targetDir = join135(targetPath, "..");
|
|
107017
|
+
await mkdir37(targetDir, { recursive: true });
|
|
106859
107018
|
await copyFile8(sourcePath, targetPath);
|
|
106860
107019
|
}
|
|
106861
107020
|
} catch (error) {
|
|
@@ -106869,7 +107028,7 @@ async function createBackup(claudeDir3, files, backupDir) {
|
|
|
106869
107028
|
}
|
|
106870
107029
|
// src/commands/init/phases/transform-handler.ts
|
|
106871
107030
|
init_config_manager();
|
|
106872
|
-
import { join as
|
|
107031
|
+
import { join as join139 } from "node:path";
|
|
106873
107032
|
|
|
106874
107033
|
// src/services/transformers/folder-path-transformer.ts
|
|
106875
107034
|
init_logger();
|
|
@@ -106878,40 +107037,40 @@ init_types3();
|
|
|
106878
107037
|
// src/services/transformers/folder-transform/folder-renamer.ts
|
|
106879
107038
|
init_logger();
|
|
106880
107039
|
init_types3();
|
|
106881
|
-
var
|
|
106882
|
-
import { rename as
|
|
106883
|
-
import { join as
|
|
107040
|
+
var import_fs_extra38 = __toESM(require_lib(), 1);
|
|
107041
|
+
import { rename as rename12, rm as rm16 } from "node:fs/promises";
|
|
107042
|
+
import { join as join136, relative as relative28 } from "node:path";
|
|
106884
107043
|
async function collectDirsToRename(extractDir, folders) {
|
|
106885
107044
|
const dirsToRename = [];
|
|
106886
107045
|
if (folders.docs !== DEFAULT_FOLDERS.docs) {
|
|
106887
|
-
const docsPath =
|
|
106888
|
-
if (await
|
|
107046
|
+
const docsPath = join136(extractDir, DEFAULT_FOLDERS.docs);
|
|
107047
|
+
if (await import_fs_extra38.pathExists(docsPath)) {
|
|
106889
107048
|
dirsToRename.push({
|
|
106890
107049
|
from: docsPath,
|
|
106891
|
-
to:
|
|
107050
|
+
to: join136(extractDir, folders.docs)
|
|
106892
107051
|
});
|
|
106893
107052
|
}
|
|
106894
|
-
const claudeDocsPath =
|
|
106895
|
-
if (await
|
|
107053
|
+
const claudeDocsPath = join136(extractDir, ".claude", DEFAULT_FOLDERS.docs);
|
|
107054
|
+
if (await import_fs_extra38.pathExists(claudeDocsPath)) {
|
|
106896
107055
|
dirsToRename.push({
|
|
106897
107056
|
from: claudeDocsPath,
|
|
106898
|
-
to:
|
|
107057
|
+
to: join136(extractDir, ".claude", folders.docs)
|
|
106899
107058
|
});
|
|
106900
107059
|
}
|
|
106901
107060
|
}
|
|
106902
107061
|
if (folders.plans !== DEFAULT_FOLDERS.plans) {
|
|
106903
|
-
const plansPath =
|
|
106904
|
-
if (await
|
|
107062
|
+
const plansPath = join136(extractDir, DEFAULT_FOLDERS.plans);
|
|
107063
|
+
if (await import_fs_extra38.pathExists(plansPath)) {
|
|
106905
107064
|
dirsToRename.push({
|
|
106906
107065
|
from: plansPath,
|
|
106907
|
-
to:
|
|
107066
|
+
to: join136(extractDir, folders.plans)
|
|
106908
107067
|
});
|
|
106909
107068
|
}
|
|
106910
|
-
const claudePlansPath =
|
|
106911
|
-
if (await
|
|
107069
|
+
const claudePlansPath = join136(extractDir, ".claude", DEFAULT_FOLDERS.plans);
|
|
107070
|
+
if (await import_fs_extra38.pathExists(claudePlansPath)) {
|
|
106912
107071
|
dirsToRename.push({
|
|
106913
107072
|
from: claudePlansPath,
|
|
106914
|
-
to:
|
|
107073
|
+
to: join136(extractDir, ".claude", folders.plans)
|
|
106915
107074
|
});
|
|
106916
107075
|
}
|
|
106917
107076
|
}
|
|
@@ -106919,12 +107078,12 @@ async function collectDirsToRename(extractDir, folders) {
|
|
|
106919
107078
|
}
|
|
106920
107079
|
async function moveAcrossDevices(src, dest) {
|
|
106921
107080
|
try {
|
|
106922
|
-
await
|
|
107081
|
+
await rename12(src, dest);
|
|
106923
107082
|
} catch (e2) {
|
|
106924
107083
|
if (e2.code === "EXDEV") {
|
|
106925
107084
|
logger.debug(`Cross-device move detected, using copy+delete: ${src} -> ${dest}`);
|
|
106926
|
-
await
|
|
106927
|
-
await
|
|
107085
|
+
await import_fs_extra38.copy(src, dest, { overwrite: true });
|
|
107086
|
+
await rm16(src, { recursive: true, force: true });
|
|
106928
107087
|
} else {
|
|
106929
107088
|
throw e2;
|
|
106930
107089
|
}
|
|
@@ -106951,8 +107110,8 @@ async function renameFolders(dirsToRename, extractDir, options2) {
|
|
|
106951
107110
|
// src/services/transformers/folder-transform/path-replacer.ts
|
|
106952
107111
|
init_logger();
|
|
106953
107112
|
init_types3();
|
|
106954
|
-
import { readFile as readFile59, readdir as
|
|
106955
|
-
import { join as
|
|
107113
|
+
import { readFile as readFile59, readdir as readdir42, writeFile as writeFile33 } from "node:fs/promises";
|
|
107114
|
+
import { join as join137, relative as relative29 } from "node:path";
|
|
106956
107115
|
var TRANSFORMABLE_FILE_PATTERNS = [
|
|
106957
107116
|
".md",
|
|
106958
107117
|
".txt",
|
|
@@ -107003,9 +107162,9 @@ function compileReplacements(replacements) {
|
|
|
107003
107162
|
async function transformFileContents(dir, compiledReplacements, options2) {
|
|
107004
107163
|
let filesChanged = 0;
|
|
107005
107164
|
let replacementsCount = 0;
|
|
107006
|
-
const entries = await
|
|
107165
|
+
const entries = await readdir42(dir, { withFileTypes: true });
|
|
107007
107166
|
for (const entry of entries) {
|
|
107008
|
-
const fullPath =
|
|
107167
|
+
const fullPath = join137(dir, entry.name);
|
|
107009
107168
|
if (entry.isDirectory()) {
|
|
107010
107169
|
if (entry.name === "node_modules" || entry.name === ".git") {
|
|
107011
107170
|
continue;
|
|
@@ -107140,9 +107299,9 @@ async function transformFolderPaths(extractDir, folders, options2 = {}) {
|
|
|
107140
107299
|
|
|
107141
107300
|
// src/services/transformers/global-path-transformer.ts
|
|
107142
107301
|
init_logger();
|
|
107143
|
-
import { readFile as readFile60, readdir as
|
|
107144
|
-
import { homedir as
|
|
107145
|
-
import { extname as extname6, join as
|
|
107302
|
+
import { readFile as readFile60, readdir as readdir43, writeFile as writeFile34 } from "node:fs/promises";
|
|
107303
|
+
import { homedir as homedir47, platform as platform15 } from "node:os";
|
|
107304
|
+
import { extname as extname6, join as join138 } from "node:path";
|
|
107146
107305
|
var IS_WINDOWS3 = platform15() === "win32";
|
|
107147
107306
|
var HOME_PREFIX = "$HOME";
|
|
107148
107307
|
function getHomeDirPrefix() {
|
|
@@ -107152,7 +107311,7 @@ function normalizeInstallPath(path16) {
|
|
|
107152
107311
|
return path16.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
107153
107312
|
}
|
|
107154
107313
|
function getDefaultGlobalClaudeDir() {
|
|
107155
|
-
return normalizeInstallPath(
|
|
107314
|
+
return normalizeInstallPath(join138(homedir47(), ".claude"));
|
|
107156
107315
|
}
|
|
107157
107316
|
function getCustomGlobalClaudeDir(targetClaudeDir) {
|
|
107158
107317
|
if (!targetClaudeDir)
|
|
@@ -107281,9 +107440,9 @@ async function transformPathsForGlobalInstall(directory, options2 = {}) {
|
|
|
107281
107440
|
let filesSkipped = 0;
|
|
107282
107441
|
const skippedFiles = [];
|
|
107283
107442
|
async function processDirectory2(dir) {
|
|
107284
|
-
const entries = await
|
|
107443
|
+
const entries = await readdir43(dir, { withFileTypes: true });
|
|
107285
107444
|
for (const entry of entries) {
|
|
107286
|
-
const fullPath =
|
|
107445
|
+
const fullPath = join138(dir, entry.name);
|
|
107287
107446
|
if (entry.isDirectory()) {
|
|
107288
107447
|
if (entry.name === "node_modules" || entry.name.startsWith(".") && entry.name !== ".claude") {
|
|
107289
107448
|
continue;
|
|
@@ -107362,7 +107521,7 @@ async function handleTransforms(ctx) {
|
|
|
107362
107521
|
logger.debug(ctx.options.global ? "Saved folder configuration to ~/.claude/.ck.json" : "Saved folder configuration to .claude/.ck.json");
|
|
107363
107522
|
}
|
|
107364
107523
|
}
|
|
107365
|
-
const claudeDir3 = ctx.options.global ? ctx.resolvedDir :
|
|
107524
|
+
const claudeDir3 = ctx.options.global ? ctx.resolvedDir : join139(ctx.resolvedDir, ".claude");
|
|
107366
107525
|
return {
|
|
107367
107526
|
...ctx,
|
|
107368
107527
|
foldersConfig,
|
|
@@ -107552,15 +107711,15 @@ async function initCommand(options2) {
|
|
|
107552
107711
|
init_dist2();
|
|
107553
107712
|
var import_picocolors30 = __toESM(require_picocolors(), 1);
|
|
107554
107713
|
import { existsSync as existsSync65 } from "node:fs";
|
|
107555
|
-
import { readFile as readFile64, rm as
|
|
107556
|
-
import { homedir as
|
|
107557
|
-
import { basename as basename27, join as
|
|
107714
|
+
import { readFile as readFile64, rm as rm17, unlink as unlink13 } from "node:fs/promises";
|
|
107715
|
+
import { homedir as homedir52 } from "node:os";
|
|
107716
|
+
import { basename as basename27, join as join143, resolve as resolve47 } from "node:path";
|
|
107558
107717
|
init_logger();
|
|
107559
107718
|
|
|
107560
107719
|
// src/ui/ck-cli-design/tokens.ts
|
|
107561
107720
|
var import_picocolors27 = __toESM(require_picocolors(), 1);
|
|
107562
|
-
import { homedir as
|
|
107563
|
-
import { resolve as
|
|
107721
|
+
import { homedir as homedir48, platform as platform16 } from "node:os";
|
|
107722
|
+
import { resolve as resolve46, win32 as win322 } from "node:path";
|
|
107564
107723
|
var PANEL_MIN_WIDTH = 60;
|
|
107565
107724
|
var PANEL_MAX_WIDTH = 72;
|
|
107566
107725
|
var DEFAULT_WIDTH = PANEL_MAX_WIDTH;
|
|
@@ -107717,7 +107876,7 @@ function wrapText(value, width) {
|
|
|
107717
107876
|
}
|
|
107718
107877
|
function formatDisplayPath(value) {
|
|
107719
107878
|
const normalized = value.replace(/\\/g, "/");
|
|
107720
|
-
const home6 =
|
|
107879
|
+
const home6 = homedir48().replace(/\\/g, "/");
|
|
107721
107880
|
if (normalized === home6)
|
|
107722
107881
|
return "~";
|
|
107723
107882
|
if (normalized.startsWith(`${home6}/`)) {
|
|
@@ -107730,7 +107889,7 @@ function formatCdHint(value, currentPlatform = platform16()) {
|
|
|
107730
107889
|
const absolutePath2 = win322.resolve(value);
|
|
107731
107890
|
return `cd /d "${absolutePath2}"`;
|
|
107732
107891
|
}
|
|
107733
|
-
const absolutePath =
|
|
107892
|
+
const absolutePath = resolve46(value);
|
|
107734
107893
|
const displayPath = formatDisplayPath(absolutePath);
|
|
107735
107894
|
if (displayPath.includes(" ")) {
|
|
107736
107895
|
return `cd "${displayPath}"`;
|
|
@@ -108029,15 +108188,15 @@ init_model_taxonomy();
|
|
|
108029
108188
|
init_logger();
|
|
108030
108189
|
init_dist2();
|
|
108031
108190
|
init_model_taxonomy();
|
|
108032
|
-
import { mkdir as
|
|
108033
|
-
import { homedir as
|
|
108034
|
-
import { dirname as
|
|
108191
|
+
import { mkdir as mkdir39, readFile as readFile63, writeFile as writeFile36 } from "node:fs/promises";
|
|
108192
|
+
import { homedir as homedir51 } from "node:os";
|
|
108193
|
+
import { dirname as dirname41, join as join142 } from "node:path";
|
|
108035
108194
|
|
|
108036
108195
|
// src/commands/portable/models-dev-cache.ts
|
|
108037
108196
|
init_logger();
|
|
108038
|
-
import { mkdir as
|
|
108039
|
-
import { homedir as
|
|
108040
|
-
import { join as
|
|
108197
|
+
import { mkdir as mkdir38, readFile as readFile61, rename as rename13, writeFile as writeFile35 } from "node:fs/promises";
|
|
108198
|
+
import { homedir as homedir49 } from "node:os";
|
|
108199
|
+
import { join as join140 } from "node:path";
|
|
108041
108200
|
|
|
108042
108201
|
class ModelsDevUnavailableError extends Error {
|
|
108043
108202
|
constructor(message, cause) {
|
|
@@ -108049,13 +108208,13 @@ var MODELS_DEV_URL = "https://models.dev/api.json";
|
|
|
108049
108208
|
var CACHE_TTL_MS3 = 24 * 60 * 60 * 1000;
|
|
108050
108209
|
var FETCH_TIMEOUT_MS = 1e4;
|
|
108051
108210
|
function defaultCacheDir() {
|
|
108052
|
-
return
|
|
108211
|
+
return join140(homedir49(), ".config", "claudekit", "cache");
|
|
108053
108212
|
}
|
|
108054
108213
|
function cacheFilePath(cacheDir) {
|
|
108055
|
-
return
|
|
108214
|
+
return join140(cacheDir, "models-dev.json");
|
|
108056
108215
|
}
|
|
108057
108216
|
function tmpFilePath(cacheDir) {
|
|
108058
|
-
return
|
|
108217
|
+
return join140(cacheDir, "models-dev.json.tmp");
|
|
108059
108218
|
}
|
|
108060
108219
|
async function readCacheEntry(cacheDir) {
|
|
108061
108220
|
const filePath = cacheFilePath(cacheDir);
|
|
@@ -108075,11 +108234,11 @@ function isCacheFresh(entry) {
|
|
|
108075
108234
|
return Date.now() - fetchedAt < CACHE_TTL_MS3;
|
|
108076
108235
|
}
|
|
108077
108236
|
async function writeCacheEntry(cacheDir, entry) {
|
|
108078
|
-
await
|
|
108237
|
+
await mkdir38(cacheDir, { recursive: true });
|
|
108079
108238
|
const tmp = tmpFilePath(cacheDir);
|
|
108080
108239
|
const dest = cacheFilePath(cacheDir);
|
|
108081
108240
|
await writeFile35(tmp, JSON.stringify(entry), "utf-8");
|
|
108082
|
-
await
|
|
108241
|
+
await rename13(tmp, dest);
|
|
108083
108242
|
}
|
|
108084
108243
|
async function fetchCatalog(fetcher) {
|
|
108085
108244
|
const controller = new AbortController;
|
|
@@ -108129,15 +108288,15 @@ async function getModelsDevCatalog(opts = {}) {
|
|
|
108129
108288
|
// src/commands/portable/opencode-model-discovery.ts
|
|
108130
108289
|
init_logger();
|
|
108131
108290
|
import { readFile as readFile62 } from "node:fs/promises";
|
|
108132
|
-
import { homedir as
|
|
108133
|
-
import { join as
|
|
108291
|
+
import { homedir as homedir50, platform as platform17 } from "node:os";
|
|
108292
|
+
import { join as join141 } from "node:path";
|
|
108134
108293
|
function resolveOpenCodeAuthPath(homeDir) {
|
|
108135
108294
|
if (platform17() === "win32") {
|
|
108136
|
-
const dataRoot2 = process.env.LOCALAPPDATA ??
|
|
108137
|
-
return
|
|
108295
|
+
const dataRoot2 = process.env.LOCALAPPDATA ?? join141(homeDir, "AppData", "Local");
|
|
108296
|
+
return join141(dataRoot2, "opencode", "auth.json");
|
|
108138
108297
|
}
|
|
108139
|
-
const dataRoot = process.env.XDG_DATA_HOME ??
|
|
108140
|
-
return
|
|
108298
|
+
const dataRoot = process.env.XDG_DATA_HOME ?? join141(homeDir, ".local", "share");
|
|
108299
|
+
return join141(dataRoot, "opencode", "auth.json");
|
|
108141
108300
|
}
|
|
108142
108301
|
async function readAuthedProviders(homeDir) {
|
|
108143
108302
|
const authPath = resolveOpenCodeAuthPath(homeDir);
|
|
@@ -108175,7 +108334,7 @@ function pickGenericModel(models) {
|
|
|
108175
108334
|
return sorted[0] ?? null;
|
|
108176
108335
|
}
|
|
108177
108336
|
async function resolveOpenCodeDefaultModel(opts = {}) {
|
|
108178
|
-
const home6 = opts.homeDir ??
|
|
108337
|
+
const home6 = opts.homeDir ?? homedir50();
|
|
108179
108338
|
const authedProviders = await readAuthedProviders(home6);
|
|
108180
108339
|
if (authedProviders.length === 0) {
|
|
108181
108340
|
return { ok: false, reason: "no-auth", authedProviders: [] };
|
|
@@ -108239,9 +108398,9 @@ function messageForReason(reason) {
|
|
|
108239
108398
|
}
|
|
108240
108399
|
function getOpenCodeConfigPath(options2) {
|
|
108241
108400
|
if (options2.global) {
|
|
108242
|
-
return
|
|
108401
|
+
return join142(options2.homeDir ?? homedir51(), ".config", "opencode", "opencode.json");
|
|
108243
108402
|
}
|
|
108244
|
-
return
|
|
108403
|
+
return join142(options2.cwd ?? process.cwd(), "opencode.json");
|
|
108245
108404
|
}
|
|
108246
108405
|
function makeCatalogOpts(options2) {
|
|
108247
108406
|
return {
|
|
@@ -108384,7 +108543,7 @@ async function ensureOpenCodeModel(options2) {
|
|
|
108384
108543
|
}
|
|
108385
108544
|
const chosenModel2 = response2.action === "custom" ? response2.value : suggestion2.model;
|
|
108386
108545
|
const next2 = { ...existing, model: chosenModel2 };
|
|
108387
|
-
await
|
|
108546
|
+
await mkdir39(dirname41(configPath), { recursive: true });
|
|
108388
108547
|
await writeFile36(configPath, `${JSON.stringify(next2, null, 2)}
|
|
108389
108548
|
`, "utf-8");
|
|
108390
108549
|
return { path: configPath, action: "added", model: chosenModel2, reason: suggestion2.reason };
|
|
@@ -108395,7 +108554,7 @@ async function ensureOpenCodeModel(options2) {
|
|
|
108395
108554
|
throw new OpenCodeAuthRequiredError(suggestion.failure);
|
|
108396
108555
|
}
|
|
108397
108556
|
const next2 = { ...existing ?? {}, model: suggestion.model };
|
|
108398
|
-
await
|
|
108557
|
+
await mkdir39(dirname41(configPath), { recursive: true });
|
|
108399
108558
|
await writeFile36(configPath, `${JSON.stringify(next2, null, 2)}
|
|
108400
108559
|
`, "utf-8");
|
|
108401
108560
|
return {
|
|
@@ -108417,7 +108576,7 @@ async function ensureOpenCodeModel(options2) {
|
|
|
108417
108576
|
}
|
|
108418
108577
|
const chosenModel = response.action === "custom" ? response.value : suggestion.ok ? suggestion.model : "";
|
|
108419
108578
|
const next = { ...existing ?? {}, model: chosenModel };
|
|
108420
|
-
await
|
|
108579
|
+
await mkdir39(dirname41(configPath), { recursive: true });
|
|
108421
108580
|
await writeFile36(configPath, `${JSON.stringify(next, null, 2)}
|
|
108422
108581
|
`, "utf-8");
|
|
108423
108582
|
return {
|
|
@@ -108430,7 +108589,7 @@ async function ensureOpenCodeModel(options2) {
|
|
|
108430
108589
|
|
|
108431
108590
|
// src/commands/portable/plan-display.ts
|
|
108432
108591
|
var import_picocolors28 = __toESM(require_picocolors(), 1);
|
|
108433
|
-
import { basename as basename26, dirname as
|
|
108592
|
+
import { basename as basename26, dirname as dirname42, extname as extname7 } from "node:path";
|
|
108434
108593
|
var DEFAULT_MAX_PLAN_GROUP_ITEMS = 20;
|
|
108435
108594
|
var TYPE_ORDER = [
|
|
108436
108595
|
"agent",
|
|
@@ -108656,21 +108815,21 @@ function collectPlannedWhereLines(plan) {
|
|
|
108656
108815
|
return destinations.map((destination) => `${formatDisplayPath(destination)} -> ${formatCdHint(resolveCdTarget(destination))}`);
|
|
108657
108816
|
}
|
|
108658
108817
|
function resolveCdTarget(destination) {
|
|
108659
|
-
return extname7(destination).length > 0 ?
|
|
108818
|
+
return extname7(destination).length > 0 ? dirname42(destination) : destination;
|
|
108660
108819
|
}
|
|
108661
108820
|
function normalizeWhereDestination(path16, portableType) {
|
|
108662
108821
|
if (portableType === "agent" || portableType === "command" || portableType === "skill") {
|
|
108663
|
-
return
|
|
108822
|
+
return dirname42(path16);
|
|
108664
108823
|
}
|
|
108665
108824
|
if (portableType === "hooks") {
|
|
108666
|
-
return
|
|
108825
|
+
return dirname42(path16);
|
|
108667
108826
|
}
|
|
108668
108827
|
if (portableType === "rules") {
|
|
108669
108828
|
const fileName = basename26(path16).toLowerCase();
|
|
108670
108829
|
if (fileName === "agents.md" || fileName === "gemini.md" || fileName === ".goosehints" || fileName === "custom_modes.yaml" || fileName === "custom_modes.yml") {
|
|
108671
108830
|
return path16;
|
|
108672
108831
|
}
|
|
108673
|
-
return
|
|
108832
|
+
return dirname42(path16);
|
|
108674
108833
|
}
|
|
108675
108834
|
return path16;
|
|
108676
108835
|
}
|
|
@@ -109179,10 +109338,10 @@ function shouldExecuteAction2(action) {
|
|
|
109179
109338
|
}
|
|
109180
109339
|
async function executeDeleteAction(action, options2) {
|
|
109181
109340
|
const preservePaths = options2?.preservePaths ?? new Set;
|
|
109182
|
-
const shouldPreserveTarget = action.targetPath.length > 0 && preservePaths.has(
|
|
109341
|
+
const shouldPreserveTarget = action.targetPath.length > 0 && preservePaths.has(resolve47(action.targetPath));
|
|
109183
109342
|
try {
|
|
109184
109343
|
if (!shouldPreserveTarget && action.targetPath && existsSync65(action.targetPath)) {
|
|
109185
|
-
await
|
|
109344
|
+
await rm17(action.targetPath, { recursive: true, force: true });
|
|
109186
109345
|
}
|
|
109187
109346
|
await removePortableInstallation(action.item, action.type, action.provider, action.global, action.targetPath ? { path: action.targetPath } : undefined);
|
|
109188
109347
|
return {
|
|
@@ -109212,7 +109371,7 @@ async function executeDeleteAction(action, options2) {
|
|
|
109212
109371
|
async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
109213
109372
|
if (!skillSourcePath)
|
|
109214
109373
|
return;
|
|
109215
|
-
const sourceMetadataPath =
|
|
109374
|
+
const sourceMetadataPath = join143(resolve47(skillSourcePath, ".."), "metadata.json");
|
|
109216
109375
|
if (!existsSync65(sourceMetadataPath))
|
|
109217
109376
|
return;
|
|
109218
109377
|
let sourceMetadata;
|
|
@@ -109225,7 +109384,7 @@ async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
|
109225
109384
|
}
|
|
109226
109385
|
if (!sourceMetadata.deletions || sourceMetadata.deletions.length === 0)
|
|
109227
109386
|
return;
|
|
109228
|
-
const claudeDir3 = installGlobally ?
|
|
109387
|
+
const claudeDir3 = installGlobally ? join143(homedir52(), ".claude") : join143(process.cwd(), ".claude");
|
|
109229
109388
|
if (!existsSync65(claudeDir3))
|
|
109230
109389
|
return;
|
|
109231
109390
|
try {
|
|
@@ -109348,8 +109507,8 @@ async function migrateCommand(options2) {
|
|
|
109348
109507
|
let requestedGlobal = options2.global ?? false;
|
|
109349
109508
|
let installGlobally = requestedGlobal;
|
|
109350
109509
|
if (options2.global === undefined && !options2.yes) {
|
|
109351
|
-
const projectTarget =
|
|
109352
|
-
const globalTarget =
|
|
109510
|
+
const projectTarget = join143(process.cwd(), ".claude");
|
|
109511
|
+
const globalTarget = join143(homedir52(), ".claude");
|
|
109353
109512
|
const scopeChoice = await ie({
|
|
109354
109513
|
message: "Installation scope",
|
|
109355
109514
|
options: [
|
|
@@ -109413,7 +109572,7 @@ async function migrateCommand(options2) {
|
|
|
109413
109572
|
}).join(`
|
|
109414
109573
|
`));
|
|
109415
109574
|
if (sourceGlobalOnly) {
|
|
109416
|
-
f2.info(import_picocolors30.default.dim(` Scope: global (--global / -g) - reading from ${formatDisplayPath(
|
|
109575
|
+
f2.info(import_picocolors30.default.dim(` Scope: global (--global / -g) - reading from ${formatDisplayPath(join143(homedir52(), ".claude"))}`));
|
|
109417
109576
|
} else {
|
|
109418
109577
|
f2.info(import_picocolors30.default.dim(` CWD: ${process.cwd()}`));
|
|
109419
109578
|
}
|
|
@@ -109619,7 +109778,7 @@ async function migrateCommand(options2) {
|
|
|
109619
109778
|
const recordSuccessfulWrites = (task, taskResults) => {
|
|
109620
109779
|
for (const result of taskResults.filter((entry) => entry.success && !entry.skipped)) {
|
|
109621
109780
|
if (result.path.length > 0) {
|
|
109622
|
-
writtenPaths.add(
|
|
109781
|
+
writtenPaths.add(resolve47(result.path));
|
|
109623
109782
|
}
|
|
109624
109783
|
if (task.type === "hooks") {
|
|
109625
109784
|
const existing = successfulHookFiles.get(task.provider) ?? {
|
|
@@ -109630,7 +109789,7 @@ async function migrateCommand(options2) {
|
|
|
109630
109789
|
successfulHookFiles.set(task.provider, existing);
|
|
109631
109790
|
if (result.path.length > 0) {
|
|
109632
109791
|
const absExisting = successfulHookAbsPaths.get(task.provider) ?? [];
|
|
109633
|
-
absExisting.push(
|
|
109792
|
+
absExisting.push(resolve47(result.path));
|
|
109634
109793
|
successfulHookAbsPaths.set(task.provider, absExisting);
|
|
109635
109794
|
}
|
|
109636
109795
|
}
|
|
@@ -109772,7 +109931,7 @@ async function migrateCommand(options2) {
|
|
|
109772
109931
|
}
|
|
109773
109932
|
}
|
|
109774
109933
|
try {
|
|
109775
|
-
const kitRoot = (agentSource ?
|
|
109934
|
+
const kitRoot = (agentSource ? resolve47(agentSource, "..") : null) ?? (commandSource ? resolve47(commandSource, "..") : null) ?? (skillSource ? resolve47(skillSource, "..") : null) ?? null;
|
|
109776
109935
|
const manifest = kitRoot ? await loadPortableManifest(kitRoot) : null;
|
|
109777
109936
|
if (manifest?.cliVersion) {
|
|
109778
109937
|
await updateAppliedManifestVersion(manifest.cliVersion);
|
|
@@ -109825,9 +109984,9 @@ async function rollbackResults(results) {
|
|
|
109825
109984
|
try {
|
|
109826
109985
|
if (result.overwritten)
|
|
109827
109986
|
continue;
|
|
109828
|
-
const
|
|
109829
|
-
if (
|
|
109830
|
-
await
|
|
109987
|
+
const stat24 = await import("node:fs/promises").then((fs20) => fs20.stat(result.path));
|
|
109988
|
+
if (stat24.isDirectory()) {
|
|
109989
|
+
await rm17(result.path, { recursive: true, force: true });
|
|
109831
109990
|
} else {
|
|
109832
109991
|
await unlink13(result.path);
|
|
109833
109992
|
}
|
|
@@ -109951,7 +110110,7 @@ function buildDryRunFallbackResults(skills, selectedProviders, installGlobally,
|
|
|
109951
110110
|
results.push({
|
|
109952
110111
|
itemName: skill.name,
|
|
109953
110112
|
operation: "apply",
|
|
109954
|
-
path:
|
|
110113
|
+
path: join143(basePath, skill.name),
|
|
109955
110114
|
portableType: "skill",
|
|
109956
110115
|
provider,
|
|
109957
110116
|
providerDisplayName: providers[provider].displayName,
|
|
@@ -109969,11 +110128,11 @@ var import_picocolors31 = __toESM(require_picocolors(), 1);
|
|
|
109969
110128
|
|
|
109970
110129
|
// src/commands/new/phases/directory-setup.ts
|
|
109971
110130
|
init_config_manager();
|
|
109972
|
-
import { resolve as
|
|
110131
|
+
import { resolve as resolve48 } from "node:path";
|
|
109973
110132
|
init_logger();
|
|
109974
110133
|
init_path_resolver();
|
|
109975
110134
|
init_types3();
|
|
109976
|
-
var
|
|
110135
|
+
var import_fs_extra39 = __toESM(require_lib(), 1);
|
|
109977
110136
|
async function directorySetup(validOptions, prompts) {
|
|
109978
110137
|
const isNonInteractive2 = !process.stdin.isTTY || process.env.CI === "true" || process.env.NON_INTERACTIVE === "true";
|
|
109979
110138
|
const config = await ConfigManager.get();
|
|
@@ -110054,7 +110213,7 @@ async function directorySetup(validOptions, prompts) {
|
|
|
110054
110213
|
targetDir = await prompts.getDirectory(targetDir);
|
|
110055
110214
|
}
|
|
110056
110215
|
}
|
|
110057
|
-
const resolvedDir =
|
|
110216
|
+
const resolvedDir = resolve48(targetDir);
|
|
110058
110217
|
logger.info(`Target directory: ${resolvedDir}`);
|
|
110059
110218
|
if (PathResolver.isLocalSameAsGlobal(resolvedDir)) {
|
|
110060
110219
|
logger.warning("You're creating a project at HOME directory.");
|
|
@@ -110072,8 +110231,8 @@ async function directorySetup(validOptions, prompts) {
|
|
|
110072
110231
|
return null;
|
|
110073
110232
|
}
|
|
110074
110233
|
}
|
|
110075
|
-
if (await
|
|
110076
|
-
const files = await
|
|
110234
|
+
if (await import_fs_extra39.pathExists(resolvedDir)) {
|
|
110235
|
+
const files = await import_fs_extra39.readdir(resolvedDir);
|
|
110077
110236
|
const isEmpty = files.length === 0;
|
|
110078
110237
|
if (!isEmpty) {
|
|
110079
110238
|
if (isNonInteractive2) {
|
|
@@ -110111,7 +110270,7 @@ async function handleDirectorySetup(ctx) {
|
|
|
110111
110270
|
// src/commands/new/phases/project-creation.ts
|
|
110112
110271
|
init_config_manager();
|
|
110113
110272
|
init_github_client();
|
|
110114
|
-
import { join as
|
|
110273
|
+
import { join as join144 } from "node:path";
|
|
110115
110274
|
init_logger();
|
|
110116
110275
|
init_output_manager();
|
|
110117
110276
|
init_types3();
|
|
@@ -110237,7 +110396,7 @@ async function projectCreation(kit, resolvedDir, validOptions, isNonInteractive2
|
|
|
110237
110396
|
output.section("Installing");
|
|
110238
110397
|
logger.verbose("Installation target", { directory: resolvedDir });
|
|
110239
110398
|
const merger = new FileMerger;
|
|
110240
|
-
const claudeDir3 =
|
|
110399
|
+
const claudeDir3 = join144(resolvedDir, ".claude");
|
|
110241
110400
|
merger.setMultiKitContext(claudeDir3, kit);
|
|
110242
110401
|
if (validOptions.exclude && validOptions.exclude.length > 0) {
|
|
110243
110402
|
merger.addIgnorePatterns(validOptions.exclude);
|
|
@@ -110284,7 +110443,7 @@ async function handleProjectCreation(ctx) {
|
|
|
110284
110443
|
}
|
|
110285
110444
|
// src/commands/new/phases/post-setup.ts
|
|
110286
110445
|
init_projects_registry();
|
|
110287
|
-
import { join as
|
|
110446
|
+
import { join as join145 } from "node:path";
|
|
110288
110447
|
init_package_installer();
|
|
110289
110448
|
init_logger();
|
|
110290
110449
|
init_path_resolver();
|
|
@@ -110316,9 +110475,9 @@ async function postSetup(resolvedDir, validOptions, isNonInteractive2, prompts)
|
|
|
110316
110475
|
withSudo: validOptions.withSudo
|
|
110317
110476
|
});
|
|
110318
110477
|
}
|
|
110319
|
-
const claudeDir3 =
|
|
110478
|
+
const claudeDir3 = join145(resolvedDir, ".claude");
|
|
110320
110479
|
await promptSetupWizardIfNeeded({
|
|
110321
|
-
envPath:
|
|
110480
|
+
envPath: join145(claudeDir3, ".env"),
|
|
110322
110481
|
claudeDir: claudeDir3,
|
|
110323
110482
|
isGlobal: false,
|
|
110324
110483
|
isNonInteractive: isNonInteractive2,
|
|
@@ -110388,7 +110547,7 @@ Please use only one download method.`);
|
|
|
110388
110547
|
// src/commands/plan/plan-command.ts
|
|
110389
110548
|
init_output_manager();
|
|
110390
110549
|
import { existsSync as existsSync68, statSync as statSync12 } from "node:fs";
|
|
110391
|
-
import { dirname as
|
|
110550
|
+
import { dirname as dirname46, isAbsolute as isAbsolute11, join as join148, parse as parse7, resolve as resolve52 } from "node:path";
|
|
110392
110551
|
|
|
110393
110552
|
// src/commands/plan/plan-read-handlers.ts
|
|
110394
110553
|
init_config();
|
|
@@ -110398,18 +110557,18 @@ init_logger();
|
|
|
110398
110557
|
init_output_manager();
|
|
110399
110558
|
var import_picocolors32 = __toESM(require_picocolors(), 1);
|
|
110400
110559
|
import { existsSync as existsSync67, statSync as statSync11 } from "node:fs";
|
|
110401
|
-
import { basename as basename28, dirname as
|
|
110560
|
+
import { basename as basename28, dirname as dirname44, join as join147, relative as relative30, resolve as resolve50 } from "node:path";
|
|
110402
110561
|
|
|
110403
110562
|
// src/commands/plan/plan-dependencies.ts
|
|
110404
110563
|
init_config();
|
|
110405
110564
|
init_plan_parser();
|
|
110406
110565
|
init_plans_registry();
|
|
110407
110566
|
import { existsSync as existsSync66 } from "node:fs";
|
|
110408
|
-
import { dirname as
|
|
110567
|
+
import { dirname as dirname43, join as join146 } from "node:path";
|
|
110409
110568
|
async function resolvePlanDependencies(references, currentPlanFile, options2 = {}) {
|
|
110410
110569
|
if (references.length === 0)
|
|
110411
110570
|
return [];
|
|
110412
|
-
const currentPlanDir =
|
|
110571
|
+
const currentPlanDir = dirname43(currentPlanFile);
|
|
110413
110572
|
const projectRoot = findProjectRoot(currentPlanDir);
|
|
110414
110573
|
const config = options2.preloadedConfig ?? (await CkConfigManager.loadFull(projectRoot)).config;
|
|
110415
110574
|
const defaultScope = inferPlanScopeForDir(currentPlanDir, config);
|
|
@@ -110425,7 +110584,7 @@ async function resolvePlanDependencies(references, currentPlanFile, options2 = {
|
|
|
110425
110584
|
};
|
|
110426
110585
|
}
|
|
110427
110586
|
const scopeRoot = resolvePlanDirForScope(scope, projectRoot, config);
|
|
110428
|
-
const planFile =
|
|
110587
|
+
const planFile = join146(scopeRoot, planId, "plan.md");
|
|
110429
110588
|
const isSelfReference = planFile === currentPlanFile;
|
|
110430
110589
|
if (!existsSync66(planFile)) {
|
|
110431
110590
|
return {
|
|
@@ -110456,14 +110615,14 @@ init_config();
|
|
|
110456
110615
|
init_plan_parser();
|
|
110457
110616
|
init_plan_scope();
|
|
110458
110617
|
init_plans_registry();
|
|
110459
|
-
import { isAbsolute as isAbsolute10, resolve as
|
|
110618
|
+
import { isAbsolute as isAbsolute10, resolve as resolve49 } from "node:path";
|
|
110460
110619
|
async function getGlobalPlansDirFromCwd() {
|
|
110461
110620
|
const projectRoot = findProjectRoot(process.cwd());
|
|
110462
110621
|
const { config } = await CkConfigManager.loadFull(projectRoot);
|
|
110463
110622
|
return resolveGlobalPlansDir(config);
|
|
110464
110623
|
}
|
|
110465
110624
|
function resolveTargetFromBase(target, baseDir) {
|
|
110466
|
-
const resolvedTarget = isAbsolute10(target) ?
|
|
110625
|
+
const resolvedTarget = isAbsolute10(target) ? resolve49(target) : resolve49(baseDir, target);
|
|
110467
110626
|
return isWithinDir(resolvedTarget, baseDir) ? resolvedTarget : null;
|
|
110468
110627
|
}
|
|
110469
110628
|
|
|
@@ -110496,7 +110655,7 @@ async function handleParse(target, options2) {
|
|
|
110496
110655
|
console.log(JSON.stringify({ file: relative30(process.cwd(), planFile), frontmatter, phases }, null, 2));
|
|
110497
110656
|
return;
|
|
110498
110657
|
}
|
|
110499
|
-
const title = typeof frontmatter.title === "string" ? frontmatter.title : basename28(
|
|
110658
|
+
const title = typeof frontmatter.title === "string" ? frontmatter.title : basename28(dirname44(planFile));
|
|
110500
110659
|
console.log();
|
|
110501
110660
|
console.log(import_picocolors32.default.bold(` Plan: ${title}`));
|
|
110502
110661
|
console.log(` File: ${planFile}`);
|
|
@@ -110566,8 +110725,8 @@ async function handleStatus(target, options2) {
|
|
|
110566
110725
|
return;
|
|
110567
110726
|
}
|
|
110568
110727
|
const effectiveTarget = !resolvedTarget && globalBaseDir ? globalBaseDir : resolvedTarget;
|
|
110569
|
-
const t = effectiveTarget ?
|
|
110570
|
-
const plansDir = t && existsSync67(t) && statSync11(t).isDirectory() && !existsSync67(
|
|
110728
|
+
const t = effectiveTarget ? resolve50(effectiveTarget) : null;
|
|
110729
|
+
const plansDir = t && existsSync67(t) && statSync11(t).isDirectory() && !existsSync67(join147(t, "plan.md")) ? t : null;
|
|
110571
110730
|
if (plansDir) {
|
|
110572
110731
|
const planFiles = scanPlanDir(plansDir);
|
|
110573
110732
|
if (planFiles.length === 0) {
|
|
@@ -110607,7 +110766,7 @@ async function handleStatus(target, options2) {
|
|
|
110607
110766
|
const blockedBy2 = await resolvePlanDependencies(s.blockedBy, pf, { preloadedConfig });
|
|
110608
110767
|
const blocks2 = await resolvePlanDependencies(s.blocks, pf, { preloadedConfig });
|
|
110609
110768
|
const bar = progressBar(s.completed, s.totalPhases);
|
|
110610
|
-
const title2 = s.title ?? basename28(
|
|
110769
|
+
const title2 = s.title ?? basename28(dirname44(pf));
|
|
110611
110770
|
console.log(` ${import_picocolors32.default.bold(title2)}`);
|
|
110612
110771
|
console.log(` ${bar}`);
|
|
110613
110772
|
if (s.inProgress > 0)
|
|
@@ -110626,7 +110785,7 @@ async function handleStatus(target, options2) {
|
|
|
110626
110785
|
}
|
|
110627
110786
|
console.log();
|
|
110628
110787
|
} catch {
|
|
110629
|
-
console.log(` [X] Failed to read: ${basename28(
|
|
110788
|
+
console.log(` [X] Failed to read: ${basename28(dirname44(pf))}`);
|
|
110630
110789
|
console.log();
|
|
110631
110790
|
}
|
|
110632
110791
|
}
|
|
@@ -110653,7 +110812,7 @@ async function handleStatus(target, options2) {
|
|
|
110653
110812
|
console.log(JSON.stringify({ ...summary, dependencyStatus: { blockedBy, blocks } }, null, 2));
|
|
110654
110813
|
return;
|
|
110655
110814
|
}
|
|
110656
|
-
const title = summary.title ?? basename28(
|
|
110815
|
+
const title = summary.title ?? basename28(dirname44(planFile));
|
|
110657
110816
|
console.log();
|
|
110658
110817
|
console.log(import_picocolors32.default.bold(` ${title}`));
|
|
110659
110818
|
if (summary.status)
|
|
@@ -110716,7 +110875,7 @@ async function handleKanban(target, options2) {
|
|
|
110716
110875
|
process.exitCode = 1;
|
|
110717
110876
|
return;
|
|
110718
110877
|
}
|
|
110719
|
-
const route = `/plans?dir=${encodeURIComponent(
|
|
110878
|
+
const route = `/plans?dir=${encodeURIComponent(dirname44(dirname44(planFile)))}&view=kanban`;
|
|
110720
110879
|
const url = `http://localhost:${server.port}${route}`;
|
|
110721
110880
|
console.log();
|
|
110722
110881
|
console.log(import_picocolors32.default.bold(" ClaudeKit Dashboard — Plans"));
|
|
@@ -110751,7 +110910,7 @@ init_plan_parser();
|
|
|
110751
110910
|
init_plans_registry();
|
|
110752
110911
|
init_output_manager();
|
|
110753
110912
|
var import_picocolors33 = __toESM(require_picocolors(), 1);
|
|
110754
|
-
import { basename as basename29, dirname as
|
|
110913
|
+
import { basename as basename29, dirname as dirname45, relative as relative31, resolve as resolve51 } from "node:path";
|
|
110755
110914
|
async function handleCreate(target, options2) {
|
|
110756
110915
|
if (!options2.title) {
|
|
110757
110916
|
output.error("[X] --title is required for create");
|
|
@@ -110783,13 +110942,13 @@ async function handleCreate(target, options2) {
|
|
|
110783
110942
|
return;
|
|
110784
110943
|
}
|
|
110785
110944
|
const globalBaseDir = options2.global ? await getGlobalPlansDirFromCwd() : undefined;
|
|
110786
|
-
const resolvedDir = globalBaseDir ? resolveTargetFromBase(dir, globalBaseDir) :
|
|
110945
|
+
const resolvedDir = globalBaseDir ? resolveTargetFromBase(dir, globalBaseDir) : resolve51(dir);
|
|
110787
110946
|
if (globalBaseDir && !resolvedDir) {
|
|
110788
110947
|
output.error("[X] Target directory must stay within the configured global plans root");
|
|
110789
110948
|
process.exitCode = 1;
|
|
110790
110949
|
return;
|
|
110791
110950
|
}
|
|
110792
|
-
const safeResolvedDir = resolvedDir ??
|
|
110951
|
+
const safeResolvedDir = resolvedDir ?? resolve51(dir);
|
|
110793
110952
|
const result = scaffoldPlan({
|
|
110794
110953
|
title: options2.title,
|
|
110795
110954
|
phases: phaseNames.map((name2) => ({ name: name2 })),
|
|
@@ -110851,7 +111010,7 @@ async function handleCheck(target, options2) {
|
|
|
110851
111010
|
process.exitCode = 1;
|
|
110852
111011
|
return;
|
|
110853
111012
|
}
|
|
110854
|
-
const planDir =
|
|
111013
|
+
const planDir = dirname45(planFile);
|
|
110855
111014
|
let planStatus = "pending";
|
|
110856
111015
|
try {
|
|
110857
111016
|
const projectRoot = findProjectRoot(planDir);
|
|
@@ -110900,7 +111059,7 @@ async function handleUncheck(target, options2) {
|
|
|
110900
111059
|
process.exitCode = 1;
|
|
110901
111060
|
return;
|
|
110902
111061
|
}
|
|
110903
|
-
const planDir =
|
|
111062
|
+
const planDir = dirname45(planFile);
|
|
110904
111063
|
try {
|
|
110905
111064
|
const projectRoot = findProjectRoot(planDir);
|
|
110906
111065
|
const summary = buildPlanSummary(planFile);
|
|
@@ -110939,7 +111098,7 @@ async function handleAddPhase(target, options2) {
|
|
|
110939
111098
|
try {
|
|
110940
111099
|
const result = addPhase(planFile, target, options2.after);
|
|
110941
111100
|
try {
|
|
110942
|
-
const planDir =
|
|
111101
|
+
const planDir = dirname45(planFile);
|
|
110943
111102
|
const projectRoot = findProjectRoot(planDir);
|
|
110944
111103
|
updateRegistryAddPhase({
|
|
110945
111104
|
planDir,
|
|
@@ -110965,24 +111124,24 @@ async function handleAddPhase(target, options2) {
|
|
|
110965
111124
|
// src/commands/plan/plan-command.ts
|
|
110966
111125
|
function resolveTargetPath(target, baseDir) {
|
|
110967
111126
|
if (!baseDir) {
|
|
110968
|
-
return
|
|
111127
|
+
return resolve52(target);
|
|
110969
111128
|
}
|
|
110970
111129
|
if (isAbsolute11(target)) {
|
|
110971
|
-
return
|
|
111130
|
+
return resolve52(target);
|
|
110972
111131
|
}
|
|
110973
|
-
const cwdCandidate =
|
|
111132
|
+
const cwdCandidate = resolve52(target);
|
|
110974
111133
|
if (existsSync68(cwdCandidate)) {
|
|
110975
111134
|
return cwdCandidate;
|
|
110976
111135
|
}
|
|
110977
|
-
return
|
|
111136
|
+
return resolve52(baseDir, target);
|
|
110978
111137
|
}
|
|
110979
111138
|
function resolvePlanFile(target, baseDir) {
|
|
110980
|
-
const t = target ? resolveTargetPath(target, baseDir) : baseDir ?
|
|
111139
|
+
const t = target ? resolveTargetPath(target, baseDir) : baseDir ? resolve52(baseDir) : process.cwd();
|
|
110981
111140
|
if (existsSync68(t)) {
|
|
110982
|
-
const
|
|
110983
|
-
if (
|
|
111141
|
+
const stat24 = statSync12(t);
|
|
111142
|
+
if (stat24.isFile())
|
|
110984
111143
|
return t;
|
|
110985
|
-
const candidate =
|
|
111144
|
+
const candidate = join148(t, "plan.md");
|
|
110986
111145
|
if (existsSync68(candidate))
|
|
110987
111146
|
return candidate;
|
|
110988
111147
|
}
|
|
@@ -110990,10 +111149,10 @@ function resolvePlanFile(target, baseDir) {
|
|
|
110990
111149
|
let dir = process.cwd();
|
|
110991
111150
|
const root = parse7(dir).root;
|
|
110992
111151
|
while (dir !== root) {
|
|
110993
|
-
const candidate =
|
|
111152
|
+
const candidate = join148(dir, "plan.md");
|
|
110994
111153
|
if (existsSync68(candidate))
|
|
110995
111154
|
return candidate;
|
|
110996
|
-
dir =
|
|
111155
|
+
dir = dirname46(dir);
|
|
110997
111156
|
}
|
|
110998
111157
|
}
|
|
110999
111158
|
return null;
|
|
@@ -111041,7 +111200,7 @@ async function planCommand(action, target, options2) {
|
|
|
111041
111200
|
let resolvedTarget = target;
|
|
111042
111201
|
if (resolvedAction && !knownActions.has(resolvedAction)) {
|
|
111043
111202
|
const looksLikePath = resolvedAction.includes("/") || resolvedAction.includes("\\") || resolvedAction.endsWith(".md") || resolvedAction === "." || resolvedAction === "..";
|
|
111044
|
-
const existsOnDisk = !looksLikePath && existsSync68(
|
|
111203
|
+
const existsOnDisk = !looksLikePath && existsSync68(resolve52(resolvedAction));
|
|
111045
111204
|
if (looksLikePath || existsOnDisk) {
|
|
111046
111205
|
resolvedTarget = resolvedAction;
|
|
111047
111206
|
resolvedAction = undefined;
|
|
@@ -111084,11 +111243,11 @@ init_logger();
|
|
|
111084
111243
|
init_safe_prompts();
|
|
111085
111244
|
var import_picocolors34 = __toESM(require_picocolors(), 1);
|
|
111086
111245
|
import { existsSync as existsSync69 } from "node:fs";
|
|
111087
|
-
import { resolve as
|
|
111246
|
+
import { resolve as resolve53 } from "node:path";
|
|
111088
111247
|
async function handleAdd(projectPath, options2) {
|
|
111089
111248
|
logger.debug(`Adding project: ${projectPath}, options: ${JSON.stringify(options2)}`);
|
|
111090
111249
|
intro("Add Project");
|
|
111091
|
-
const absolutePath =
|
|
111250
|
+
const absolutePath = resolve53(projectPath);
|
|
111092
111251
|
if (!existsSync69(absolutePath)) {
|
|
111093
111252
|
log.error(`Path does not exist: ${absolutePath}`);
|
|
111094
111253
|
process.exitCode = 1;
|
|
@@ -111509,10 +111668,10 @@ init_agents();
|
|
|
111509
111668
|
var import_gray_matter12 = __toESM(require_gray_matter(), 1);
|
|
111510
111669
|
var import_picocolors37 = __toESM(require_picocolors(), 1);
|
|
111511
111670
|
import { readFile as readFile65 } from "node:fs/promises";
|
|
111512
|
-
import { join as
|
|
111671
|
+
import { join as join150 } from "node:path";
|
|
111513
111672
|
|
|
111514
111673
|
// src/commands/skills/installed-skills-inventory.ts
|
|
111515
|
-
import { join as
|
|
111674
|
+
import { join as join149, resolve as resolve54 } from "node:path";
|
|
111516
111675
|
init_path_resolver();
|
|
111517
111676
|
var SCOPE_SORT_ORDER = {
|
|
111518
111677
|
project: 0,
|
|
@@ -111520,12 +111679,12 @@ var SCOPE_SORT_ORDER = {
|
|
|
111520
111679
|
};
|
|
111521
111680
|
async function getActiveClaudeSkillInstallations(options2 = {}) {
|
|
111522
111681
|
const projectDir = options2.projectDir ?? process.cwd();
|
|
111523
|
-
const globalDir =
|
|
111524
|
-
const projectClaudeDir =
|
|
111682
|
+
const globalDir = resolve54(options2.globalDir ?? PathResolver.getGlobalKitDir());
|
|
111683
|
+
const projectClaudeDir = resolve54(projectDir, ".claude");
|
|
111525
111684
|
const projectScopeAliasesGlobal = projectClaudeDir === globalDir;
|
|
111526
111685
|
const [projectSkills, globalSkills] = await Promise.all([
|
|
111527
|
-
projectScopeAliasesGlobal ? Promise.resolve([]) : scanSkills2(
|
|
111528
|
-
scanSkills2(
|
|
111686
|
+
projectScopeAliasesGlobal ? Promise.resolve([]) : scanSkills2(join149(projectClaudeDir, "skills")),
|
|
111687
|
+
scanSkills2(join149(globalDir, "skills"))
|
|
111529
111688
|
]);
|
|
111530
111689
|
const projectIds = new Set(projectSkills.map((skill) => skill.id));
|
|
111531
111690
|
const globalIds = new Set(globalSkills.map((skill) => skill.id));
|
|
@@ -111685,7 +111844,7 @@ async function handleValidate2(sourcePath) {
|
|
|
111685
111844
|
spinner.stop(`Checked ${skills.length} skill(s)`);
|
|
111686
111845
|
let hasIssues = false;
|
|
111687
111846
|
for (const skill of skills) {
|
|
111688
|
-
const skillMdPath =
|
|
111847
|
+
const skillMdPath = join150(skill.path, "SKILL.md");
|
|
111689
111848
|
try {
|
|
111690
111849
|
const content = await readFile65(skillMdPath, "utf-8");
|
|
111691
111850
|
const { data } = import_gray_matter12.default(content, {
|
|
@@ -112229,7 +112388,7 @@ var import_picocolors39 = __toESM(require_picocolors(), 1);
|
|
|
112229
112388
|
// src/commands/uninstall/installation-detector.ts
|
|
112230
112389
|
init_claudekit_scanner();
|
|
112231
112390
|
init_path_resolver();
|
|
112232
|
-
var
|
|
112391
|
+
var import_fs_extra40 = __toESM(require_lib(), 1);
|
|
112233
112392
|
function hasClaudeKitComponents(components) {
|
|
112234
112393
|
return components.agents > 0 || components.commands > 0 || components.rules > 0 || components.skills > 0;
|
|
112235
112394
|
}
|
|
@@ -112244,7 +112403,7 @@ async function detectInstallations() {
|
|
|
112244
112403
|
installations.push({
|
|
112245
112404
|
type: "local",
|
|
112246
112405
|
path: setup.project.path,
|
|
112247
|
-
exists: await
|
|
112406
|
+
exists: await import_fs_extra40.pathExists(setup.project.path),
|
|
112248
112407
|
hasMetadata,
|
|
112249
112408
|
components: setup.project.components
|
|
112250
112409
|
});
|
|
@@ -112257,7 +112416,7 @@ async function detectInstallations() {
|
|
|
112257
112416
|
installations.push({
|
|
112258
112417
|
type: "global",
|
|
112259
112418
|
path: setup.global.path,
|
|
112260
|
-
exists: await
|
|
112419
|
+
exists: await import_fs_extra40.pathExists(setup.global.path),
|
|
112261
112420
|
hasMetadata,
|
|
112262
112421
|
components: setup.global.components
|
|
112263
112422
|
});
|
|
@@ -112268,19 +112427,19 @@ async function detectInstallations() {
|
|
|
112268
112427
|
|
|
112269
112428
|
// src/commands/uninstall/removal-handler.ts
|
|
112270
112429
|
import { readdirSync as readdirSync10, rmSync as rmSync5 } from "node:fs";
|
|
112271
|
-
import { basename as basename30, join as
|
|
112430
|
+
import { basename as basename30, join as join152, resolve as resolve55, sep as sep13 } from "node:path";
|
|
112272
112431
|
init_logger();
|
|
112273
112432
|
init_safe_prompts();
|
|
112274
112433
|
init_safe_spinner();
|
|
112275
|
-
var
|
|
112434
|
+
var import_fs_extra42 = __toESM(require_lib(), 1);
|
|
112276
112435
|
|
|
112277
112436
|
// src/commands/uninstall/analysis-handler.ts
|
|
112278
112437
|
init_metadata_migration();
|
|
112279
112438
|
import { readdirSync as readdirSync9, rmSync as rmSync4 } from "node:fs";
|
|
112280
|
-
import { dirname as
|
|
112439
|
+
import { dirname as dirname47, join as join151 } from "node:path";
|
|
112281
112440
|
init_logger();
|
|
112282
112441
|
init_safe_prompts();
|
|
112283
|
-
var
|
|
112442
|
+
var import_fs_extra41 = __toESM(require_lib(), 1);
|
|
112284
112443
|
var import_picocolors38 = __toESM(require_picocolors(), 1);
|
|
112285
112444
|
function normalizeTrackedPath(relativePath) {
|
|
112286
112445
|
return relativePath.replace(/\\/g, "/");
|
|
@@ -112299,7 +112458,7 @@ function classifyFileByOwnership(ownership, forceOverwrite, deleteReason) {
|
|
|
112299
112458
|
}
|
|
112300
112459
|
async function cleanupEmptyDirectories3(filePath, installationRoot) {
|
|
112301
112460
|
let cleaned = 0;
|
|
112302
|
-
let currentDir =
|
|
112461
|
+
let currentDir = dirname47(filePath);
|
|
112303
112462
|
while (currentDir !== installationRoot && currentDir.startsWith(installationRoot)) {
|
|
112304
112463
|
try {
|
|
112305
112464
|
const entries = readdirSync9(currentDir);
|
|
@@ -112307,7 +112466,7 @@ async function cleanupEmptyDirectories3(filePath, installationRoot) {
|
|
|
112307
112466
|
rmSync4(currentDir, { recursive: true });
|
|
112308
112467
|
cleaned++;
|
|
112309
112468
|
logger.debug(`Removed empty directory: ${currentDir}`);
|
|
112310
|
-
currentDir =
|
|
112469
|
+
currentDir = dirname47(currentDir);
|
|
112311
112470
|
} else {
|
|
112312
112471
|
break;
|
|
112313
112472
|
}
|
|
@@ -112337,7 +112496,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
112337
112496
|
const remainingFiles = metadata.kits?.[remainingKit]?.files || [];
|
|
112338
112497
|
for (const file of remainingFiles) {
|
|
112339
112498
|
const relativePath = normalizeTrackedPath(file.path);
|
|
112340
|
-
if (await
|
|
112499
|
+
if (await import_fs_extra41.pathExists(join151(installation.path, relativePath))) {
|
|
112341
112500
|
result.retainedManifestPaths.push(relativePath);
|
|
112342
112501
|
}
|
|
112343
112502
|
}
|
|
@@ -112345,7 +112504,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
112345
112504
|
const kitFiles = metadata.kits[kit].files || [];
|
|
112346
112505
|
for (const trackedFile of kitFiles) {
|
|
112347
112506
|
const relativePath = normalizeTrackedPath(trackedFile.path);
|
|
112348
|
-
const filePath =
|
|
112507
|
+
const filePath = join151(installation.path, relativePath);
|
|
112349
112508
|
if (preservedPaths.has(relativePath)) {
|
|
112350
112509
|
result.toPreserve.push({ path: relativePath, reason: "shared with other kit" });
|
|
112351
112510
|
continue;
|
|
@@ -112378,7 +112537,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
112378
112537
|
}
|
|
112379
112538
|
for (const trackedFile of allTrackedFiles) {
|
|
112380
112539
|
const relativePath = normalizeTrackedPath(trackedFile.path);
|
|
112381
|
-
const filePath =
|
|
112540
|
+
const filePath = join151(installation.path, relativePath);
|
|
112382
112541
|
const ownershipResult = await OwnershipChecker.checkOwnership(filePath, metadata, installation.path);
|
|
112383
112542
|
if (!ownershipResult.exists)
|
|
112384
112543
|
continue;
|
|
@@ -112425,9 +112584,9 @@ function displayDryRunPreview(analysis, installationType) {
|
|
|
112425
112584
|
}
|
|
112426
112585
|
|
|
112427
112586
|
// src/commands/uninstall/removal-handler.ts
|
|
112428
|
-
async function
|
|
112587
|
+
async function isDirectory2(filePath) {
|
|
112429
112588
|
try {
|
|
112430
|
-
const stats = await
|
|
112589
|
+
const stats = await import_fs_extra42.lstat(filePath);
|
|
112431
112590
|
return stats.isDirectory();
|
|
112432
112591
|
} catch {
|
|
112433
112592
|
logger.debug(`Failed to check if path is directory: ${filePath}`);
|
|
@@ -112452,16 +112611,16 @@ async function restoreUninstallBackup(backup) {
|
|
|
112452
112611
|
}
|
|
112453
112612
|
async function isPathSafeToRemove(filePath, baseDir) {
|
|
112454
112613
|
try {
|
|
112455
|
-
const resolvedPath =
|
|
112456
|
-
const resolvedBase =
|
|
112614
|
+
const resolvedPath = resolve55(filePath);
|
|
112615
|
+
const resolvedBase = resolve55(baseDir);
|
|
112457
112616
|
if (!resolvedPath.startsWith(resolvedBase + sep13) && resolvedPath !== resolvedBase) {
|
|
112458
112617
|
logger.debug(`Path outside installation directory: ${filePath}`);
|
|
112459
112618
|
return false;
|
|
112460
112619
|
}
|
|
112461
|
-
const stats = await
|
|
112620
|
+
const stats = await import_fs_extra42.lstat(filePath);
|
|
112462
112621
|
if (stats.isSymbolicLink()) {
|
|
112463
|
-
const realPath = await
|
|
112464
|
-
const resolvedReal =
|
|
112622
|
+
const realPath = await import_fs_extra42.realpath(filePath);
|
|
112623
|
+
const resolvedReal = resolve55(realPath);
|
|
112465
112624
|
if (!resolvedReal.startsWith(resolvedBase + sep13) && resolvedReal !== resolvedBase) {
|
|
112466
112625
|
logger.debug(`Symlink points outside installation directory: ${filePath} -> ${realPath}`);
|
|
112467
112626
|
return false;
|
|
@@ -112521,15 +112680,15 @@ async function removeInstallations(installations, options2) {
|
|
|
112521
112680
|
let removedCount = 0;
|
|
112522
112681
|
let cleanedDirs = 0;
|
|
112523
112682
|
for (const item of analysis.toDelete) {
|
|
112524
|
-
const filePath =
|
|
112525
|
-
if (!await
|
|
112683
|
+
const filePath = join152(installation.path, item.path);
|
|
112684
|
+
if (!await import_fs_extra42.pathExists(filePath))
|
|
112526
112685
|
continue;
|
|
112527
112686
|
if (!await isPathSafeToRemove(filePath, installation.path)) {
|
|
112528
112687
|
logger.debug(`Skipping unsafe path: ${item.path}`);
|
|
112529
112688
|
continue;
|
|
112530
112689
|
}
|
|
112531
|
-
const isDir = await
|
|
112532
|
-
await
|
|
112690
|
+
const isDir = await isDirectory2(filePath);
|
|
112691
|
+
await import_fs_extra42.remove(filePath);
|
|
112533
112692
|
removedCount++;
|
|
112534
112693
|
logger.debug(`Removed ${isDir ? "directory" : "file"}: ${item.path}`);
|
|
112535
112694
|
if (!isDir) {
|
|
@@ -112929,8 +113088,8 @@ ${import_picocolors40.default.bold(import_picocolors40.default.cyan(result.kitCo
|
|
|
112929
113088
|
// src/commands/watch/watch-command.ts
|
|
112930
113089
|
init_logger();
|
|
112931
113090
|
import { existsSync as existsSync75 } from "node:fs";
|
|
112932
|
-
import { rm as
|
|
112933
|
-
import { join as
|
|
113091
|
+
import { rm as rm18 } from "node:fs/promises";
|
|
113092
|
+
import { join as join159 } from "node:path";
|
|
112934
113093
|
var import_picocolors41 = __toESM(require_picocolors(), 1);
|
|
112935
113094
|
|
|
112936
113095
|
// src/commands/watch/phases/implementation-runner.ts
|
|
@@ -113448,8 +113607,8 @@ function spawnAndCollect3(command, args) {
|
|
|
113448
113607
|
}
|
|
113449
113608
|
|
|
113450
113609
|
// src/commands/watch/phases/issue-processor.ts
|
|
113451
|
-
import { mkdir as
|
|
113452
|
-
import { join as
|
|
113610
|
+
import { mkdir as mkdir40, writeFile as writeFile38 } from "node:fs/promises";
|
|
113611
|
+
import { join as join155 } from "node:path";
|
|
113453
113612
|
|
|
113454
113613
|
// src/commands/watch/phases/approval-detector.ts
|
|
113455
113614
|
init_logger();
|
|
@@ -113826,26 +113985,26 @@ async function checkAwaitingApproval(state, setup, options2, watchLog, projectDi
|
|
|
113826
113985
|
}
|
|
113827
113986
|
|
|
113828
113987
|
// src/commands/watch/phases/plan-dir-finder.ts
|
|
113829
|
-
import { readdir as
|
|
113830
|
-
import { join as
|
|
113988
|
+
import { readdir as readdir45, stat as stat24 } from "node:fs/promises";
|
|
113989
|
+
import { join as join154 } from "node:path";
|
|
113831
113990
|
async function findRecentPlanDir(cwd2, issueNumber, watchLog) {
|
|
113832
|
-
const plansRoot =
|
|
113991
|
+
const plansRoot = join154(cwd2, "plans");
|
|
113833
113992
|
try {
|
|
113834
|
-
const entries = await
|
|
113993
|
+
const entries = await readdir45(plansRoot);
|
|
113835
113994
|
const tenMinAgo = Date.now() - 10 * 60 * 1000;
|
|
113836
113995
|
const issueStr = String(issueNumber);
|
|
113837
113996
|
const candidates = [];
|
|
113838
113997
|
for (const entry of entries) {
|
|
113839
113998
|
if (entry === "watch" || entry === "reports" || entry === "visuals")
|
|
113840
113999
|
continue;
|
|
113841
|
-
const dirPath =
|
|
113842
|
-
const dirStat = await
|
|
114000
|
+
const dirPath = join154(plansRoot, entry);
|
|
114001
|
+
const dirStat = await stat24(dirPath);
|
|
113843
114002
|
if (!dirStat.isDirectory())
|
|
113844
114003
|
continue;
|
|
113845
114004
|
if (dirStat.mtimeMs < tenMinAgo)
|
|
113846
114005
|
continue;
|
|
113847
114006
|
try {
|
|
113848
|
-
await
|
|
114007
|
+
await stat24(join154(dirPath, "plan.md"));
|
|
113849
114008
|
} catch {
|
|
113850
114009
|
continue;
|
|
113851
114010
|
}
|
|
@@ -114076,13 +114235,13 @@ async function handlePlanGeneration(issue, state, config, setup, options2, watch
|
|
|
114076
114235
|
stats.plansCreated++;
|
|
114077
114236
|
const detectedPlanDir = await findRecentPlanDir(projectDir, issue.number, watchLog);
|
|
114078
114237
|
if (detectedPlanDir) {
|
|
114079
|
-
state.activeIssues[numStr].planPath =
|
|
114238
|
+
state.activeIssues[numStr].planPath = join155(detectedPlanDir, "plan.md");
|
|
114080
114239
|
watchLog.info(`Plan directory detected: ${detectedPlanDir}`);
|
|
114081
114240
|
} else {
|
|
114082
114241
|
try {
|
|
114083
|
-
const planDir =
|
|
114084
|
-
await
|
|
114085
|
-
const planFilePath =
|
|
114242
|
+
const planDir = join155(projectDir, "plans", "watch");
|
|
114243
|
+
await mkdir40(planDir, { recursive: true });
|
|
114244
|
+
const planFilePath = join155(planDir, `issue-${issue.number}-plan.md`);
|
|
114086
114245
|
await writeFile38(planFilePath, planResult.planText, "utf-8");
|
|
114087
114246
|
state.activeIssues[numStr].planPath = planFilePath;
|
|
114088
114247
|
watchLog.info(`Plan saved (fallback) to ${planFilePath}`);
|
|
@@ -114228,8 +114387,8 @@ init_ck_config_manager();
|
|
|
114228
114387
|
init_file_io();
|
|
114229
114388
|
init_logger();
|
|
114230
114389
|
import { existsSync as existsSync71 } from "node:fs";
|
|
114231
|
-
import { mkdir as
|
|
114232
|
-
import { dirname as
|
|
114390
|
+
import { mkdir as mkdir41, readFile as readFile67 } from "node:fs/promises";
|
|
114391
|
+
import { dirname as dirname48 } from "node:path";
|
|
114233
114392
|
var PROCESSED_ISSUES_CAP = 500;
|
|
114234
114393
|
async function readCkJson(projectDir) {
|
|
114235
114394
|
const configPath = CkConfigManager.getProjectConfigPath(projectDir);
|
|
@@ -114259,9 +114418,9 @@ async function loadWatchState(projectDir) {
|
|
|
114259
114418
|
}
|
|
114260
114419
|
async function saveWatchState(projectDir, state) {
|
|
114261
114420
|
const configPath = CkConfigManager.getProjectConfigPath(projectDir);
|
|
114262
|
-
const configDir =
|
|
114421
|
+
const configDir = dirname48(configPath);
|
|
114263
114422
|
if (!existsSync71(configDir)) {
|
|
114264
|
-
await
|
|
114423
|
+
await mkdir41(configDir, { recursive: true });
|
|
114265
114424
|
}
|
|
114266
114425
|
const raw2 = await readCkJson(projectDir);
|
|
114267
114426
|
const watchRaw = raw2.watch ?? {};
|
|
@@ -114388,19 +114547,19 @@ async function processImplementationQueue(state, config, setup, options2, watchL
|
|
|
114388
114547
|
init_logger();
|
|
114389
114548
|
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
114390
114549
|
import { existsSync as existsSync72 } from "node:fs";
|
|
114391
|
-
import { readdir as
|
|
114392
|
-
import { join as
|
|
114550
|
+
import { readdir as readdir46, stat as stat25 } from "node:fs/promises";
|
|
114551
|
+
import { join as join156 } from "node:path";
|
|
114393
114552
|
async function scanForRepos(parentDir) {
|
|
114394
114553
|
const repos = [];
|
|
114395
|
-
const entries = await
|
|
114554
|
+
const entries = await readdir46(parentDir);
|
|
114396
114555
|
for (const entry of entries) {
|
|
114397
114556
|
if (entry.startsWith("."))
|
|
114398
114557
|
continue;
|
|
114399
|
-
const fullPath =
|
|
114400
|
-
const entryStat = await
|
|
114558
|
+
const fullPath = join156(parentDir, entry);
|
|
114559
|
+
const entryStat = await stat25(fullPath);
|
|
114401
114560
|
if (!entryStat.isDirectory())
|
|
114402
114561
|
continue;
|
|
114403
|
-
const gitDir =
|
|
114562
|
+
const gitDir = join156(fullPath, ".git");
|
|
114404
114563
|
if (!existsSync72(gitDir))
|
|
114405
114564
|
continue;
|
|
114406
114565
|
const result = spawnSync7("gh", ["repo", "view", "--json", "owner,name"], {
|
|
@@ -114426,8 +114585,8 @@ async function scanForRepos(parentDir) {
|
|
|
114426
114585
|
init_logger();
|
|
114427
114586
|
import { spawnSync as spawnSync8 } from "node:child_process";
|
|
114428
114587
|
import { existsSync as existsSync73 } from "node:fs";
|
|
114429
|
-
import { homedir as
|
|
114430
|
-
import { join as
|
|
114588
|
+
import { homedir as homedir53 } from "node:os";
|
|
114589
|
+
import { join as join157 } from "node:path";
|
|
114431
114590
|
async function validateSetup(cwd2) {
|
|
114432
114591
|
const workDir = cwd2 ?? process.cwd();
|
|
114433
114592
|
const ghVersion = spawnSync8("gh", ["--version"], { encoding: "utf-8", timeout: 1e4 });
|
|
@@ -114458,7 +114617,7 @@ Run this command from a directory with a GitHub remote.`);
|
|
|
114458
114617
|
} catch {
|
|
114459
114618
|
throw new Error(`Failed to parse repository info: ${ghRepo.stdout}`);
|
|
114460
114619
|
}
|
|
114461
|
-
const skillsPath =
|
|
114620
|
+
const skillsPath = join157(homedir53(), ".claude", "skills");
|
|
114462
114621
|
const skillsAvailable = existsSync73(skillsPath);
|
|
114463
114622
|
if (!skillsAvailable) {
|
|
114464
114623
|
logger.warning(`ClaudeKit Engineer skills not found at ${skillsPath}`);
|
|
@@ -114476,8 +114635,8 @@ init_logger();
|
|
|
114476
114635
|
init_path_resolver();
|
|
114477
114636
|
import { createWriteStream as createWriteStream3, statSync as statSync13 } from "node:fs";
|
|
114478
114637
|
import { existsSync as existsSync74 } from "node:fs";
|
|
114479
|
-
import { mkdir as
|
|
114480
|
-
import { join as
|
|
114638
|
+
import { mkdir as mkdir42, rename as rename14 } from "node:fs/promises";
|
|
114639
|
+
import { join as join158 } from "node:path";
|
|
114481
114640
|
|
|
114482
114641
|
class WatchLogger {
|
|
114483
114642
|
logStream = null;
|
|
@@ -114485,16 +114644,16 @@ class WatchLogger {
|
|
|
114485
114644
|
logPath = null;
|
|
114486
114645
|
maxBytes;
|
|
114487
114646
|
constructor(logDir, maxBytes = 0) {
|
|
114488
|
-
this.logDir = logDir ??
|
|
114647
|
+
this.logDir = logDir ?? join158(PathResolver.getClaudeKitDir(), "logs");
|
|
114489
114648
|
this.maxBytes = maxBytes;
|
|
114490
114649
|
}
|
|
114491
114650
|
async init() {
|
|
114492
114651
|
try {
|
|
114493
114652
|
if (!existsSync74(this.logDir)) {
|
|
114494
|
-
await
|
|
114653
|
+
await mkdir42(this.logDir, { recursive: true });
|
|
114495
114654
|
}
|
|
114496
114655
|
const dateStr = formatDate(new Date);
|
|
114497
|
-
this.logPath =
|
|
114656
|
+
this.logPath = join158(this.logDir, `watch-${dateStr}.log`);
|
|
114498
114657
|
this.logStream = createWriteStream3(this.logPath, { flags: "a", mode: 384 });
|
|
114499
114658
|
} catch (error) {
|
|
114500
114659
|
logger.warning(`Cannot create watch log file: ${error instanceof Error ? error.message : "Unknown"}`);
|
|
@@ -114559,7 +114718,7 @@ class WatchLogger {
|
|
|
114559
114718
|
try {
|
|
114560
114719
|
this.logStream.end();
|
|
114561
114720
|
const rotatedPath = `${this.logPath}.1`;
|
|
114562
|
-
|
|
114721
|
+
rename14(this.logPath, rotatedPath).catch(() => {});
|
|
114563
114722
|
this.logStream = createWriteStream3(this.logPath, { flags: "w", mode: 384 });
|
|
114564
114723
|
} catch {}
|
|
114565
114724
|
}
|
|
@@ -114676,7 +114835,7 @@ async function watchCommand(options2) {
|
|
|
114676
114835
|
}
|
|
114677
114836
|
async function discoverRepos(options2, watchLog) {
|
|
114678
114837
|
const cwd2 = process.cwd();
|
|
114679
|
-
const isGitRepo = existsSync75(
|
|
114838
|
+
const isGitRepo = existsSync75(join159(cwd2, ".git"));
|
|
114680
114839
|
if (options2.force) {
|
|
114681
114840
|
await forceRemoveLock(watchLog);
|
|
114682
114841
|
}
|
|
@@ -114749,8 +114908,8 @@ async function forceRemoveLock(watchLog) {
|
|
|
114749
114908
|
const { resource, lockfile: lockfile7 } = getLockPaths(LOCK_NAME);
|
|
114750
114909
|
try {
|
|
114751
114910
|
await Promise.all([
|
|
114752
|
-
|
|
114753
|
-
|
|
114911
|
+
rm18(resource, { recursive: true, force: true }),
|
|
114912
|
+
rm18(lockfile7, { recursive: true, force: true })
|
|
114754
114913
|
]);
|
|
114755
114914
|
watchLog.info("Removed existing lock file (--force)");
|
|
114756
114915
|
} catch {}
|
|
@@ -114934,7 +115093,7 @@ function registerCommands(cli) {
|
|
|
114934
115093
|
init_package();
|
|
114935
115094
|
init_config_version_checker();
|
|
114936
115095
|
import { existsSync as existsSync87, readFileSync as readFileSync22 } from "node:fs";
|
|
114937
|
-
import { join as
|
|
115096
|
+
import { join as join171 } from "node:path";
|
|
114938
115097
|
|
|
114939
115098
|
// src/domains/versioning/version-checker.ts
|
|
114940
115099
|
init_version_utils();
|
|
@@ -114948,15 +115107,15 @@ init_types3();
|
|
|
114948
115107
|
init_logger();
|
|
114949
115108
|
init_path_resolver();
|
|
114950
115109
|
import { existsSync as existsSync86 } from "node:fs";
|
|
114951
|
-
import { mkdir as
|
|
114952
|
-
import { join as
|
|
115110
|
+
import { mkdir as mkdir43, readFile as readFile69, writeFile as writeFile41 } from "node:fs/promises";
|
|
115111
|
+
import { join as join170 } from "node:path";
|
|
114953
115112
|
|
|
114954
115113
|
class VersionCacheManager {
|
|
114955
115114
|
static CACHE_FILENAME = "version-check.json";
|
|
114956
115115
|
static CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000;
|
|
114957
115116
|
static getCacheFile() {
|
|
114958
115117
|
const cacheDir = PathResolver.getCacheDir(false);
|
|
114959
|
-
return
|
|
115118
|
+
return join170(cacheDir, VersionCacheManager.CACHE_FILENAME);
|
|
114960
115119
|
}
|
|
114961
115120
|
static async load() {
|
|
114962
115121
|
const cacheFile = VersionCacheManager.getCacheFile();
|
|
@@ -114983,7 +115142,7 @@ class VersionCacheManager {
|
|
|
114983
115142
|
const cacheDir = PathResolver.getCacheDir(false);
|
|
114984
115143
|
try {
|
|
114985
115144
|
if (!existsSync86(cacheDir)) {
|
|
114986
|
-
await
|
|
115145
|
+
await mkdir43(cacheDir, { recursive: true, mode: 448 });
|
|
114987
115146
|
}
|
|
114988
115147
|
await writeFile41(cacheFile, JSON.stringify(cache5, null, 2), "utf-8");
|
|
114989
115148
|
logger.debug(`Version check cache saved to ${cacheFile}`);
|
|
@@ -115267,9 +115426,9 @@ async function displayVersion() {
|
|
|
115267
115426
|
let localInstalledKits = [];
|
|
115268
115427
|
let globalInstalledKits = [];
|
|
115269
115428
|
const globalKitDir = PathResolver.getGlobalKitDir();
|
|
115270
|
-
const globalMetadataPath =
|
|
115429
|
+
const globalMetadataPath = join171(globalKitDir, "metadata.json");
|
|
115271
115430
|
const prefix = PathResolver.getPathPrefix(false);
|
|
115272
|
-
const localMetadataPath = prefix ?
|
|
115431
|
+
const localMetadataPath = prefix ? join171(process.cwd(), prefix, "metadata.json") : join171(process.cwd(), "metadata.json");
|
|
115273
115432
|
const isLocalSameAsGlobal = localMetadataPath === globalMetadataPath;
|
|
115274
115433
|
if (!isLocalSameAsGlobal && existsSync87(localMetadataPath)) {
|
|
115275
115434
|
try {
|
|
@@ -115657,7 +115816,7 @@ var output2 = new OutputManager2;
|
|
|
115657
115816
|
|
|
115658
115817
|
// src/shared/temp-cleanup.ts
|
|
115659
115818
|
init_logger();
|
|
115660
|
-
var
|
|
115819
|
+
var import_fs_extra43 = __toESM(require_lib(), 1);
|
|
115661
115820
|
import { rmSync as rmSync6 } from "node:fs";
|
|
115662
115821
|
var tempDirs2 = new Set;
|
|
115663
115822
|
async function cleanup() {
|
|
@@ -115666,7 +115825,7 @@ async function cleanup() {
|
|
|
115666
115825
|
logger.debug(`Cleaning up ${tempDirs2.size} temporary director(ies)...`);
|
|
115667
115826
|
for (const dir of tempDirs2) {
|
|
115668
115827
|
try {
|
|
115669
|
-
await
|
|
115828
|
+
await import_fs_extra43.remove(dir);
|
|
115670
115829
|
logger.debug(`Cleaned up temp directory: ${dir}`);
|
|
115671
115830
|
} catch (error) {
|
|
115672
115831
|
logger.debug(`Failed to clean temp directory ${dir}: ${error}`);
|