claudekit-cli 3.26.1 → 3.27.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +321 -88
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -16194,7 +16194,7 @@ var init_init_command_help = __esm(() => {
|
|
|
16194
16194
|
},
|
|
16195
16195
|
{
|
|
16196
16196
|
flags: "--fresh",
|
|
16197
|
-
description: "
|
|
16197
|
+
description: "Remove ClaudeKit directories (commands/, agents/, skills/, rules/, hooks/) and reinstall"
|
|
16198
16198
|
}
|
|
16199
16199
|
]
|
|
16200
16200
|
},
|
|
@@ -16592,7 +16592,7 @@ function getPagerArgs(pagerCmd) {
|
|
|
16592
16592
|
return [];
|
|
16593
16593
|
}
|
|
16594
16594
|
async function trySystemPager(content) {
|
|
16595
|
-
return new Promise((
|
|
16595
|
+
return new Promise((resolve11) => {
|
|
16596
16596
|
const pagerCmd = process.env.PAGER || "less";
|
|
16597
16597
|
const pagerArgs = getPagerArgs(pagerCmd);
|
|
16598
16598
|
try {
|
|
@@ -16602,20 +16602,20 @@ async function trySystemPager(content) {
|
|
|
16602
16602
|
});
|
|
16603
16603
|
const timeout = setTimeout(() => {
|
|
16604
16604
|
pager.kill();
|
|
16605
|
-
|
|
16605
|
+
resolve11(false);
|
|
16606
16606
|
}, 30000);
|
|
16607
16607
|
pager.stdin.write(content);
|
|
16608
16608
|
pager.stdin.end();
|
|
16609
16609
|
pager.on("close", (code2) => {
|
|
16610
16610
|
clearTimeout(timeout);
|
|
16611
|
-
|
|
16611
|
+
resolve11(code2 === 0);
|
|
16612
16612
|
});
|
|
16613
16613
|
pager.on("error", () => {
|
|
16614
16614
|
clearTimeout(timeout);
|
|
16615
|
-
|
|
16615
|
+
resolve11(false);
|
|
16616
16616
|
});
|
|
16617
16617
|
} catch {
|
|
16618
|
-
|
|
16618
|
+
resolve11(false);
|
|
16619
16619
|
}
|
|
16620
16620
|
});
|
|
16621
16621
|
}
|
|
@@ -16642,16 +16642,16 @@ async function basicPager(content) {
|
|
|
16642
16642
|
break;
|
|
16643
16643
|
}
|
|
16644
16644
|
const remaining = lines.length - currentLine;
|
|
16645
|
-
await new Promise((
|
|
16645
|
+
await new Promise((resolve11) => {
|
|
16646
16646
|
rl.question(`-- More (${remaining} lines) [Enter/q] --`, (answer) => {
|
|
16647
16647
|
if (answer.toLowerCase() === "q") {
|
|
16648
16648
|
rl.close();
|
|
16649
16649
|
process.exitCode = 0;
|
|
16650
|
-
|
|
16650
|
+
resolve11();
|
|
16651
16651
|
return;
|
|
16652
16652
|
}
|
|
16653
16653
|
process.stdout.write("\x1B[1A\x1B[2K");
|
|
16654
|
-
|
|
16654
|
+
resolve11();
|
|
16655
16655
|
});
|
|
16656
16656
|
});
|
|
16657
16657
|
}
|
|
@@ -24690,12 +24690,25 @@ async function promptDirectorySelection(global2 = false) {
|
|
|
24690
24690
|
}
|
|
24691
24691
|
return selectedCategories;
|
|
24692
24692
|
}
|
|
24693
|
-
async function promptFreshConfirmation(targetPath) {
|
|
24694
|
-
logger.warning("[!]
|
|
24693
|
+
async function promptFreshConfirmation(targetPath, analysis) {
|
|
24694
|
+
logger.warning("[!] Fresh installation will remove ClaudeKit files:");
|
|
24695
24695
|
logger.info(`Path: ${targetPath}`);
|
|
24696
|
-
|
|
24696
|
+
if (analysis?.hasMetadata) {
|
|
24697
|
+
const ckCount = analysis.ckFiles.length + analysis.ckModifiedFiles.length;
|
|
24698
|
+
const userCount = analysis.userFiles.length;
|
|
24699
|
+
logger.info(` Remove: ${ckCount} CK-owned files`);
|
|
24700
|
+
logger.info(` Preserve: ${userCount} user-created files`);
|
|
24701
|
+
if (userCount > 0) {
|
|
24702
|
+
const samples = analysis.userFiles.slice(0, 3).map((f3) => f3.path);
|
|
24703
|
+
const remaining = userCount - samples.length;
|
|
24704
|
+
logger.info(` Examples preserved: ${samples.join(", ")}${remaining > 0 ? ` (+${remaining} more)` : ""}`);
|
|
24705
|
+
}
|
|
24706
|
+
} else {
|
|
24707
|
+
logger.info(" Remove: commands/, agents/, skills/, rules/, hooks/");
|
|
24708
|
+
logger.info(" Preserve: settings.json, Claude Code data");
|
|
24709
|
+
}
|
|
24697
24710
|
const confirmation = await te({
|
|
24698
|
-
message: "Type 'yes' to confirm
|
|
24711
|
+
message: "Type 'yes' to confirm:",
|
|
24699
24712
|
placeholder: "yes",
|
|
24700
24713
|
validate: (value) => {
|
|
24701
24714
|
if (value.toLowerCase() !== "yes") {
|
|
@@ -24893,8 +24906,8 @@ class PromptsManager {
|
|
|
24893
24906
|
logger.info("You can install these manually later using npm install -g <package>");
|
|
24894
24907
|
}
|
|
24895
24908
|
}
|
|
24896
|
-
async promptFreshConfirmation(targetPath) {
|
|
24897
|
-
return promptFreshConfirmation(targetPath);
|
|
24909
|
+
async promptFreshConfirmation(targetPath, analysis) {
|
|
24910
|
+
return promptFreshConfirmation(targetPath, analysis);
|
|
24898
24911
|
}
|
|
24899
24912
|
async promptUpdateMode() {
|
|
24900
24913
|
return promptUpdateMode();
|
|
@@ -26449,7 +26462,7 @@ var import_ignore = __toESM(require_ignore(), 1);
|
|
|
26449
26462
|
// src/domains/installation/download/file-downloader.ts
|
|
26450
26463
|
init_logger();
|
|
26451
26464
|
init_output_manager();
|
|
26452
|
-
import { createWriteStream as createWriteStream2 } from "node:fs";
|
|
26465
|
+
import { createWriteStream as createWriteStream2, rmSync } from "node:fs";
|
|
26453
26466
|
import { mkdir as mkdir9 } from "node:fs/promises";
|
|
26454
26467
|
import { join as join28 } from "node:path";
|
|
26455
26468
|
|
|
@@ -26697,11 +26710,29 @@ class FileDownloader {
|
|
|
26697
26710
|
downloadedSize += value.length;
|
|
26698
26711
|
progressBar.update(downloadedSize);
|
|
26699
26712
|
}
|
|
26713
|
+
if (downloadedSize !== totalSize) {
|
|
26714
|
+
fileStream.end();
|
|
26715
|
+
await new Promise((resolve5) => fileStream.once("close", resolve5));
|
|
26716
|
+
try {
|
|
26717
|
+
rmSync(destPath, { force: true });
|
|
26718
|
+
} catch (cleanupError) {
|
|
26719
|
+
const errorMsg = cleanupError instanceof Error ? cleanupError.message : String(cleanupError);
|
|
26720
|
+
logger.debug(`Failed to clean up partial download ${destPath}: ${errorMsg}`);
|
|
26721
|
+
}
|
|
26722
|
+
throw new DownloadError(`Incomplete download: received ${formatBytes(downloadedSize)} of ${formatBytes(totalSize)}`);
|
|
26723
|
+
}
|
|
26700
26724
|
fileStream.end();
|
|
26701
26725
|
progressBar.complete(`Downloaded ${asset.name}`);
|
|
26702
26726
|
return destPath;
|
|
26703
26727
|
} catch (error) {
|
|
26704
|
-
fileStream.
|
|
26728
|
+
fileStream.end();
|
|
26729
|
+
await new Promise((resolve5) => fileStream.once("close", resolve5));
|
|
26730
|
+
try {
|
|
26731
|
+
rmSync(destPath, { force: true });
|
|
26732
|
+
} catch (cleanupError) {
|
|
26733
|
+
const errorMsg = cleanupError instanceof Error ? cleanupError.message : String(cleanupError);
|
|
26734
|
+
logger.debug(`Failed to clean up partial download ${destPath}: ${errorMsg}`);
|
|
26735
|
+
}
|
|
26705
26736
|
throw error;
|
|
26706
26737
|
}
|
|
26707
26738
|
} catch (error) {
|
|
@@ -26751,11 +26782,19 @@ class FileDownloader {
|
|
|
26751
26782
|
progressBar.update(downloadedSize);
|
|
26752
26783
|
}
|
|
26753
26784
|
}
|
|
26754
|
-
fileStream.end();
|
|
26755
26785
|
const expectedSize = Number(response.headers.get("content-length"));
|
|
26756
26786
|
if (expectedSize > 0 && downloadedSize !== expectedSize) {
|
|
26787
|
+
fileStream.end();
|
|
26788
|
+
await new Promise((resolve5) => fileStream.once("close", resolve5));
|
|
26789
|
+
try {
|
|
26790
|
+
rmSync(destPath, { force: true });
|
|
26791
|
+
} catch (cleanupError) {
|
|
26792
|
+
const errorMsg = cleanupError instanceof Error ? cleanupError.message : String(cleanupError);
|
|
26793
|
+
logger.debug(`Failed to clean up partial download ${destPath}: ${errorMsg}`);
|
|
26794
|
+
}
|
|
26757
26795
|
throw new DownloadError(`Incomplete download: received ${formatBytes(downloadedSize)} of ${formatBytes(expectedSize)}`);
|
|
26758
26796
|
}
|
|
26797
|
+
fileStream.end();
|
|
26759
26798
|
if (progressBar) {
|
|
26760
26799
|
progressBar.complete(`Downloaded ${name}`);
|
|
26761
26800
|
} else {
|
|
@@ -26763,7 +26802,14 @@ class FileDownloader {
|
|
|
26763
26802
|
}
|
|
26764
26803
|
return destPath;
|
|
26765
26804
|
} catch (error) {
|
|
26766
|
-
fileStream.
|
|
26805
|
+
fileStream.end();
|
|
26806
|
+
await new Promise((resolve5) => fileStream.once("close", resolve5));
|
|
26807
|
+
try {
|
|
26808
|
+
rmSync(destPath, { force: true });
|
|
26809
|
+
} catch (cleanupError) {
|
|
26810
|
+
const errorMsg = cleanupError instanceof Error ? cleanupError.message : String(cleanupError);
|
|
26811
|
+
logger.debug(`Failed to clean up partial download ${destPath}: ${errorMsg}`);
|
|
26812
|
+
}
|
|
26767
26813
|
throw error;
|
|
26768
26814
|
}
|
|
26769
26815
|
}
|
|
@@ -34621,15 +34667,24 @@ class SelectiveMerger {
|
|
|
34621
34667
|
conflictInfo: { ...conflictBase, winner: "existing", reason: "no-timestamps" }
|
|
34622
34668
|
};
|
|
34623
34669
|
}
|
|
34670
|
+
logger.debug(`Updating shared file (version fallback): ${relativePath} - incoming ${incomingVersion} > installed ${installedVersion}`);
|
|
34671
|
+
return {
|
|
34672
|
+
changed: true,
|
|
34673
|
+
reason: "shared-newer",
|
|
34674
|
+
sourceChecksum: manifestEntry.checksum,
|
|
34675
|
+
destChecksum: installed.checksum,
|
|
34676
|
+
sharedWithKit: installed.ownerKit,
|
|
34677
|
+
conflictInfo: { ...conflictBase, winner: "incoming", reason: "no-timestamps" }
|
|
34678
|
+
};
|
|
34624
34679
|
}
|
|
34625
|
-
logger.debug(`
|
|
34680
|
+
logger.debug(`Shared file version comparison skipped (non-semver): ${relativePath} - incoming ${incomingVersion}, installed ${installedVersion}`);
|
|
34626
34681
|
return {
|
|
34627
|
-
changed:
|
|
34628
|
-
reason: "shared-
|
|
34682
|
+
changed: false,
|
|
34683
|
+
reason: "shared-older",
|
|
34629
34684
|
sourceChecksum: manifestEntry.checksum,
|
|
34630
34685
|
destChecksum: installed.checksum,
|
|
34631
34686
|
sharedWithKit: installed.ownerKit,
|
|
34632
|
-
conflictInfo: { ...conflictBase, winner: "
|
|
34687
|
+
conflictInfo: { ...conflictBase, winner: "existing", reason: "no-timestamps" }
|
|
34633
34688
|
};
|
|
34634
34689
|
}
|
|
34635
34690
|
}
|
|
@@ -38293,9 +38348,10 @@ init_logger();
|
|
|
38293
38348
|
init_output_manager();
|
|
38294
38349
|
var import_fs_extra16 = __toESM(require_lib(), 1);
|
|
38295
38350
|
async function handleMerge(ctx) {
|
|
38296
|
-
if (ctx.cancelled || !ctx.extractDir || !ctx.resolvedDir || !ctx.claudeDir || !ctx.kit || !ctx.
|
|
38351
|
+
if (ctx.cancelled || !ctx.extractDir || !ctx.resolvedDir || !ctx.claudeDir || !ctx.kit || !ctx.kitType) {
|
|
38297
38352
|
return ctx;
|
|
38298
38353
|
}
|
|
38354
|
+
const installedVersion = ctx.release?.tag_name ?? "local";
|
|
38299
38355
|
let customClaudeFiles = [];
|
|
38300
38356
|
if (!ctx.options.fresh) {
|
|
38301
38357
|
logger.info("Scanning for custom .claude files...");
|
|
@@ -38347,7 +38403,7 @@ async function handleMerge(ctx) {
|
|
|
38347
38403
|
const legacyDetection = await LegacyMigration.detectLegacy(ctx.claudeDir);
|
|
38348
38404
|
if (legacyDetection.isLegacy && releaseManifest) {
|
|
38349
38405
|
logger.info("Legacy installation detected - migrating to ownership tracking...");
|
|
38350
|
-
await LegacyMigration.migrate(ctx.claudeDir, releaseManifest, ctx.kit.name,
|
|
38406
|
+
await LegacyMigration.migrate(ctx.claudeDir, releaseManifest, ctx.kit.name, installedVersion, !ctx.isNonInteractive);
|
|
38351
38407
|
logger.success("Migration complete");
|
|
38352
38408
|
}
|
|
38353
38409
|
}
|
|
@@ -38375,13 +38431,13 @@ async function handleMerge(ctx) {
|
|
|
38375
38431
|
installedFiles,
|
|
38376
38432
|
claudeDir: ctx.claudeDir,
|
|
38377
38433
|
releaseManifest,
|
|
38378
|
-
installedVersion
|
|
38434
|
+
installedVersion,
|
|
38379
38435
|
isGlobal: ctx.options.global
|
|
38380
38436
|
});
|
|
38381
38437
|
await trackFilesWithProgress(filesToTrack, {
|
|
38382
38438
|
claudeDir: ctx.claudeDir,
|
|
38383
38439
|
kitName: ctx.kit.name,
|
|
38384
|
-
releaseTag:
|
|
38440
|
+
releaseTag: installedVersion,
|
|
38385
38441
|
mode: ctx.options.global ? "global" : "local",
|
|
38386
38442
|
kitType: ctx.kitType
|
|
38387
38443
|
});
|
|
@@ -40339,7 +40395,7 @@ Optional: DISCORD_WEBHOOK_URL, TELEGRAM_BOT_TOKEN`, "Configuration skipped");
|
|
|
40339
40395
|
}
|
|
40340
40396
|
// src/commands/init/phases/selection-handler.ts
|
|
40341
40397
|
import { mkdir as mkdir20 } from "node:fs/promises";
|
|
40342
|
-
import { join as join66, resolve as
|
|
40398
|
+
import { join as join66, resolve as resolve8 } from "node:path";
|
|
40343
40399
|
|
|
40344
40400
|
// src/domains/github/kit-access-checker.ts
|
|
40345
40401
|
init_logger();
|
|
@@ -40466,38 +40522,196 @@ async function runPreflightChecks() {
|
|
|
40466
40522
|
}
|
|
40467
40523
|
|
|
40468
40524
|
// src/domains/installation/fresh-installer.ts
|
|
40525
|
+
import { existsSync as existsSync19, readdirSync, rmSync as rmSync2, rmdirSync, unlinkSync as unlinkSync3 } from "node:fs";
|
|
40526
|
+
import { dirname as dirname9, join as join65, resolve as resolve7 } from "node:path";
|
|
40469
40527
|
init_logger();
|
|
40470
|
-
import { join as join65 } from "node:path";
|
|
40471
40528
|
var import_fs_extra29 = __toESM(require_lib(), 1);
|
|
40472
40529
|
var CLAUDEKIT_SUBDIRECTORIES = ["commands", "agents", "skills", "rules", "hooks"];
|
|
40530
|
+
async function analyzeFreshInstallation(claudeDir) {
|
|
40531
|
+
const metadata = await readManifest(claudeDir);
|
|
40532
|
+
if (!metadata) {
|
|
40533
|
+
return {
|
|
40534
|
+
ckFiles: [],
|
|
40535
|
+
ckModifiedFiles: [],
|
|
40536
|
+
userFiles: [],
|
|
40537
|
+
hasMetadata: false
|
|
40538
|
+
};
|
|
40539
|
+
}
|
|
40540
|
+
const allFiles = getAllTrackedFiles(metadata);
|
|
40541
|
+
if (allFiles.length === 0) {
|
|
40542
|
+
return {
|
|
40543
|
+
ckFiles: [],
|
|
40544
|
+
ckModifiedFiles: [],
|
|
40545
|
+
userFiles: [],
|
|
40546
|
+
hasMetadata: false
|
|
40547
|
+
};
|
|
40548
|
+
}
|
|
40549
|
+
const ckFiles = [];
|
|
40550
|
+
const ckModifiedFiles = [];
|
|
40551
|
+
const userFiles = [];
|
|
40552
|
+
for (const file of allFiles) {
|
|
40553
|
+
switch (file.ownership) {
|
|
40554
|
+
case "ck":
|
|
40555
|
+
ckFiles.push(file);
|
|
40556
|
+
break;
|
|
40557
|
+
case "ck-modified":
|
|
40558
|
+
ckModifiedFiles.push(file);
|
|
40559
|
+
break;
|
|
40560
|
+
case "user":
|
|
40561
|
+
userFiles.push(file);
|
|
40562
|
+
break;
|
|
40563
|
+
}
|
|
40564
|
+
}
|
|
40565
|
+
return {
|
|
40566
|
+
ckFiles,
|
|
40567
|
+
ckModifiedFiles,
|
|
40568
|
+
userFiles,
|
|
40569
|
+
hasMetadata: true
|
|
40570
|
+
};
|
|
40571
|
+
}
|
|
40572
|
+
function cleanupEmptyDirectories(filePath, claudeDir) {
|
|
40573
|
+
const normalizedClaudeDir = resolve7(claudeDir);
|
|
40574
|
+
let currentDir = resolve7(dirname9(filePath));
|
|
40575
|
+
while (currentDir !== normalizedClaudeDir && currentDir.startsWith(normalizedClaudeDir)) {
|
|
40576
|
+
try {
|
|
40577
|
+
const entries = readdirSync(currentDir);
|
|
40578
|
+
if (entries.length === 0) {
|
|
40579
|
+
rmdirSync(currentDir);
|
|
40580
|
+
logger.debug(`Removed empty directory: ${currentDir}`);
|
|
40581
|
+
currentDir = resolve7(dirname9(currentDir));
|
|
40582
|
+
} else {
|
|
40583
|
+
break;
|
|
40584
|
+
}
|
|
40585
|
+
} catch (error) {
|
|
40586
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
40587
|
+
logger.debug(`Could not remove directory ${currentDir}: ${errorMsg}`);
|
|
40588
|
+
break;
|
|
40589
|
+
}
|
|
40590
|
+
}
|
|
40591
|
+
}
|
|
40592
|
+
async function removeFilesByOwnership(claudeDir, analysis, includeModified) {
|
|
40593
|
+
const removedFiles = [];
|
|
40594
|
+
const preservedFiles = [];
|
|
40595
|
+
const filesToRemove = includeModified ? [...analysis.ckFiles, ...analysis.ckModifiedFiles] : analysis.ckFiles;
|
|
40596
|
+
const filesToPreserve = includeModified ? analysis.userFiles : [...analysis.ckModifiedFiles, ...analysis.userFiles];
|
|
40597
|
+
for (const file of filesToRemove) {
|
|
40598
|
+
const fullPath = join65(claudeDir, file.path);
|
|
40599
|
+
try {
|
|
40600
|
+
if (existsSync19(fullPath)) {
|
|
40601
|
+
unlinkSync3(fullPath);
|
|
40602
|
+
removedFiles.push(file.path);
|
|
40603
|
+
logger.debug(`Removed: ${file.path}`);
|
|
40604
|
+
cleanupEmptyDirectories(fullPath, claudeDir);
|
|
40605
|
+
}
|
|
40606
|
+
} catch (error) {
|
|
40607
|
+
logger.debug(`Failed to remove ${file.path}: ${error}`);
|
|
40608
|
+
}
|
|
40609
|
+
}
|
|
40610
|
+
for (const file of filesToPreserve) {
|
|
40611
|
+
preservedFiles.push(file.path);
|
|
40612
|
+
}
|
|
40613
|
+
await updateMetadataAfterFresh(claudeDir, removedFiles);
|
|
40614
|
+
return {
|
|
40615
|
+
success: true,
|
|
40616
|
+
removedCount: removedFiles.length,
|
|
40617
|
+
preservedCount: preservedFiles.length,
|
|
40618
|
+
removedFiles,
|
|
40619
|
+
preservedFiles
|
|
40620
|
+
};
|
|
40621
|
+
}
|
|
40622
|
+
async function updateMetadataAfterFresh(claudeDir, removedFiles) {
|
|
40623
|
+
const metadataPath = join65(claudeDir, "metadata.json");
|
|
40624
|
+
if (!await import_fs_extra29.pathExists(metadataPath)) {
|
|
40625
|
+
return;
|
|
40626
|
+
}
|
|
40627
|
+
let content;
|
|
40628
|
+
try {
|
|
40629
|
+
content = await import_fs_extra29.readFile(metadataPath, "utf-8");
|
|
40630
|
+
} catch (readError) {
|
|
40631
|
+
logger.warning(`Failed to read metadata.json: ${readError instanceof Error ? readError.message : String(readError)}`);
|
|
40632
|
+
return;
|
|
40633
|
+
}
|
|
40634
|
+
let metadata;
|
|
40635
|
+
try {
|
|
40636
|
+
metadata = JSON.parse(content);
|
|
40637
|
+
} catch (parseError) {
|
|
40638
|
+
logger.warning(`Failed to parse metadata.json: ${parseError instanceof Error ? parseError.message : String(parseError)}`);
|
|
40639
|
+
logger.info("Recommendation: Run 'ck init' to rebuild metadata");
|
|
40640
|
+
return;
|
|
40641
|
+
}
|
|
40642
|
+
const removedSet = new Set(removedFiles);
|
|
40643
|
+
if (metadata.kits) {
|
|
40644
|
+
for (const kitName of Object.keys(metadata.kits)) {
|
|
40645
|
+
const kit = metadata.kits[kitName];
|
|
40646
|
+
if (kit?.files) {
|
|
40647
|
+
kit.files = kit.files.filter((f3) => !removedSet.has(f3.path));
|
|
40648
|
+
}
|
|
40649
|
+
}
|
|
40650
|
+
}
|
|
40651
|
+
if (metadata.files) {
|
|
40652
|
+
metadata.files = metadata.files.filter((f3) => !removedSet.has(f3.path));
|
|
40653
|
+
}
|
|
40654
|
+
try {
|
|
40655
|
+
await import_fs_extra29.writeFile(metadataPath, JSON.stringify(metadata, null, 2));
|
|
40656
|
+
logger.debug(`Updated metadata.json, removed ${removedFiles.length} file entries`);
|
|
40657
|
+
} catch (writeError) {
|
|
40658
|
+
logger.warning(`Failed to write metadata.json: ${writeError instanceof Error ? writeError.message : String(writeError)}`);
|
|
40659
|
+
logger.info("Recommendation: Check file permissions and run 'ck init' to rebuild metadata");
|
|
40660
|
+
}
|
|
40661
|
+
}
|
|
40662
|
+
async function removeSubdirectoriesFallback(claudeDir) {
|
|
40663
|
+
const removedFiles = [];
|
|
40664
|
+
let removedDirCount = 0;
|
|
40665
|
+
for (const subdir of CLAUDEKIT_SUBDIRECTORIES) {
|
|
40666
|
+
const subdirPath = join65(claudeDir, subdir);
|
|
40667
|
+
if (await import_fs_extra29.pathExists(subdirPath)) {
|
|
40668
|
+
rmSync2(subdirPath, { recursive: true, force: true });
|
|
40669
|
+
removedDirCount++;
|
|
40670
|
+
removedFiles.push(`${subdir}/ (entire directory)`);
|
|
40671
|
+
logger.debug(`Removed subdirectory: ${subdir}/`);
|
|
40672
|
+
}
|
|
40673
|
+
}
|
|
40674
|
+
const metadataPath = join65(claudeDir, "metadata.json");
|
|
40675
|
+
if (await import_fs_extra29.pathExists(metadataPath)) {
|
|
40676
|
+
unlinkSync3(metadataPath);
|
|
40677
|
+
removedFiles.push("metadata.json");
|
|
40678
|
+
}
|
|
40679
|
+
return {
|
|
40680
|
+
success: true,
|
|
40681
|
+
removedCount: removedDirCount,
|
|
40682
|
+
preservedCount: 0,
|
|
40683
|
+
removedFiles,
|
|
40684
|
+
preservedFiles: []
|
|
40685
|
+
};
|
|
40686
|
+
}
|
|
40473
40687
|
async function handleFreshInstallation(claudeDir, prompts) {
|
|
40474
40688
|
if (!await import_fs_extra29.pathExists(claudeDir)) {
|
|
40475
40689
|
logger.info(".claude directory does not exist, proceeding with fresh installation");
|
|
40476
40690
|
return true;
|
|
40477
40691
|
}
|
|
40478
|
-
const
|
|
40692
|
+
const analysis = await analyzeFreshInstallation(claudeDir);
|
|
40693
|
+
const confirmed = await prompts.promptFreshConfirmation(claudeDir, analysis);
|
|
40479
40694
|
if (!confirmed) {
|
|
40480
40695
|
logger.info("Fresh installation cancelled");
|
|
40481
40696
|
return false;
|
|
40482
40697
|
}
|
|
40483
|
-
|
|
40484
|
-
const spinner = createSpinner("Removing ClaudeKit subdirectories...").start();
|
|
40698
|
+
const spinner = createSpinner("Removing ClaudeKit files...").start();
|
|
40485
40699
|
try {
|
|
40486
|
-
|
|
40487
|
-
|
|
40488
|
-
|
|
40489
|
-
|
|
40490
|
-
|
|
40491
|
-
|
|
40492
|
-
|
|
40493
|
-
|
|
40494
|
-
|
|
40700
|
+
let result;
|
|
40701
|
+
if (analysis.hasMetadata && (analysis.ckFiles.length > 0 || analysis.ckModifiedFiles.length > 0)) {
|
|
40702
|
+
result = await removeFilesByOwnership(claudeDir, analysis, true);
|
|
40703
|
+
spinner.succeed(`Removed ${result.removedCount} CK files, preserved ${result.preservedCount} user files`);
|
|
40704
|
+
} else {
|
|
40705
|
+
result = await removeSubdirectoriesFallback(claudeDir);
|
|
40706
|
+
spinner.succeed(`Removed ${result.removedCount} ClaudeKit directories`);
|
|
40707
|
+
}
|
|
40708
|
+
if (result.preservedCount > 0) {
|
|
40709
|
+
logger.verbose(`Preserved user files: ${result.preservedFiles.slice(0, 5).join(", ")}${result.preservedFiles.length > 5 ? ` and ${result.preservedFiles.length - 5} more` : ""}`);
|
|
40495
40710
|
}
|
|
40496
|
-
spinner.succeed(`Successfully removed ${removedCount} ClaudeKit subdirectories (preserving user configs)`);
|
|
40497
40711
|
return true;
|
|
40498
40712
|
} catch (error) {
|
|
40499
|
-
spinner.fail("Failed to remove ClaudeKit
|
|
40500
|
-
throw new Error(`Failed to remove
|
|
40713
|
+
spinner.fail("Failed to remove ClaudeKit files");
|
|
40714
|
+
throw new Error(`Failed to remove files: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
40501
40715
|
}
|
|
40502
40716
|
}
|
|
40503
40717
|
|
|
@@ -40526,6 +40740,18 @@ async function handleSelection(ctx) {
|
|
|
40526
40740
|
release: release2
|
|
40527
40741
|
};
|
|
40528
40742
|
}
|
|
40743
|
+
const downloadMethods = [];
|
|
40744
|
+
if (ctx.options.useGit)
|
|
40745
|
+
downloadMethods.push("--use-git");
|
|
40746
|
+
if (ctx.options.archive)
|
|
40747
|
+
downloadMethods.push("--archive");
|
|
40748
|
+
if (ctx.options.kitPath)
|
|
40749
|
+
downloadMethods.push("--kit-path");
|
|
40750
|
+
if (downloadMethods.length > 1) {
|
|
40751
|
+
logger.error(`Mutually exclusive download methods: ${downloadMethods.join(", ")}`);
|
|
40752
|
+
logger.info("Use only one of: --use-git, --archive, or --kit-path");
|
|
40753
|
+
return { ...ctx, cancelled: true };
|
|
40754
|
+
}
|
|
40529
40755
|
const config = await ConfigManager.get();
|
|
40530
40756
|
let accessibleKits;
|
|
40531
40757
|
if (!ctx.options.useGit && !ctx.options.kitPath && !ctx.options.archive) {
|
|
@@ -40661,7 +40887,7 @@ async function handleSelection(ctx) {
|
|
|
40661
40887
|
}
|
|
40662
40888
|
}
|
|
40663
40889
|
}
|
|
40664
|
-
const resolvedDir =
|
|
40890
|
+
const resolvedDir = resolve8(targetDir);
|
|
40665
40891
|
logger.info(`Target directory: ${resolvedDir}`);
|
|
40666
40892
|
if (!ctx.options.global && PathResolver.isLocalSameAsGlobal(resolvedDir)) {
|
|
40667
40893
|
logger.warning("You're at HOME directory. Installing here modifies your GLOBAL ClaudeKit.");
|
|
@@ -40733,15 +40959,16 @@ async function handleSelection(ctx) {
|
|
|
40733
40959
|
return { ...ctx, cancelled: true };
|
|
40734
40960
|
}
|
|
40735
40961
|
}
|
|
40736
|
-
const
|
|
40962
|
+
const isOfflineMode = !!(ctx.options.kitPath || ctx.options.archive);
|
|
40963
|
+
const github = isOfflineMode ? null : new GitHubClient;
|
|
40737
40964
|
let selectedVersion = ctx.options.release;
|
|
40738
|
-
if (!selectedVersion && ctx.isNonInteractive && !ctx.options.yes) {
|
|
40965
|
+
if (!selectedVersion && ctx.isNonInteractive && !ctx.options.yes && !isOfflineMode) {
|
|
40739
40966
|
throw new Error("Non-interactive mode requires either: --release <tag> OR --yes (uses latest)");
|
|
40740
40967
|
}
|
|
40741
|
-
if (!selectedVersion && ctx.options.yes) {
|
|
40968
|
+
if (!selectedVersion && ctx.options.yes && !isOfflineMode) {
|
|
40742
40969
|
logger.info("Using latest stable version (--yes flag)");
|
|
40743
40970
|
}
|
|
40744
|
-
if (!selectedVersion && !ctx.isNonInteractive) {
|
|
40971
|
+
if (!selectedVersion && !ctx.isNonInteractive && !isOfflineMode) {
|
|
40745
40972
|
logger.info("Fetching available versions...");
|
|
40746
40973
|
let currentVersion = null;
|
|
40747
40974
|
try {
|
|
@@ -40774,7 +41001,13 @@ async function handleSelection(ctx) {
|
|
|
40774
41001
|
}
|
|
40775
41002
|
}
|
|
40776
41003
|
let release;
|
|
40777
|
-
if (
|
|
41004
|
+
if (isOfflineMode) {
|
|
41005
|
+
release = undefined;
|
|
41006
|
+
logger.verbose("Offline mode - skipping release fetch", {
|
|
41007
|
+
kitPath: ctx.options.kitPath,
|
|
41008
|
+
archive: ctx.options.archive
|
|
41009
|
+
});
|
|
41010
|
+
} else if (ctx.options.useGit && selectedVersion) {
|
|
40778
41011
|
release = {
|
|
40779
41012
|
id: 0,
|
|
40780
41013
|
tag_name: selectedVersion,
|
|
@@ -40786,9 +41019,9 @@ async function handleSelection(ctx) {
|
|
|
40786
41019
|
assets: []
|
|
40787
41020
|
};
|
|
40788
41021
|
logger.verbose("Using git clone mode with tag", { tag: selectedVersion });
|
|
40789
|
-
} else if (selectedVersion) {
|
|
41022
|
+
} else if (selectedVersion && github) {
|
|
40790
41023
|
release = await github.getReleaseByTag(kit, selectedVersion);
|
|
40791
|
-
} else {
|
|
41024
|
+
} else if (github) {
|
|
40792
41025
|
if (ctx.options.beta) {
|
|
40793
41026
|
logger.info("Fetching latest beta release...");
|
|
40794
41027
|
} else {
|
|
@@ -40813,8 +41046,8 @@ async function handleSelection(ctx) {
|
|
|
40813
41046
|
};
|
|
40814
41047
|
}
|
|
40815
41048
|
// src/commands/init/phases/sync-handler.ts
|
|
40816
|
-
import { copyFile as copyFile6, mkdir as mkdir21, open, rename as rename3, stat as stat10, unlink as unlink7, writeFile as
|
|
40817
|
-
import { dirname as
|
|
41049
|
+
import { copyFile as copyFile6, mkdir as mkdir21, open, rename as rename3, stat as stat10, unlink as unlink7, writeFile as writeFile20 } from "node:fs/promises";
|
|
41050
|
+
import { dirname as dirname10, join as join67, resolve as resolve9 } from "node:path";
|
|
40818
41051
|
init_logger();
|
|
40819
41052
|
var import_fs_extra31 = __toESM(require_lib(), 1);
|
|
40820
41053
|
var import_picocolors19 = __toESM(require_picocolors(), 1);
|
|
@@ -40822,7 +41055,7 @@ async function handleSync(ctx) {
|
|
|
40822
41055
|
if (!ctx.options.sync) {
|
|
40823
41056
|
return ctx;
|
|
40824
41057
|
}
|
|
40825
|
-
const resolvedDir = ctx.options.global ? PathResolver.getGlobalKitDir() :
|
|
41058
|
+
const resolvedDir = ctx.options.global ? PathResolver.getGlobalKitDir() : resolve9(ctx.options.dir || ".");
|
|
40826
41059
|
const claudeDir = ctx.options.global ? resolvedDir : join67(resolvedDir, ".claude");
|
|
40827
41060
|
if (!await import_fs_extra31.pathExists(claudeDir)) {
|
|
40828
41061
|
logger.error("Cannot sync: no .claude directory found");
|
|
@@ -40932,7 +41165,7 @@ async function acquireSyncLock(global3) {
|
|
|
40932
41165
|
const lockPath = join67(cacheDir, ".sync-lock");
|
|
40933
41166
|
const startTime = Date.now();
|
|
40934
41167
|
const lockTimeout = getLockTimeout();
|
|
40935
|
-
await mkdir21(
|
|
41168
|
+
await mkdir21(dirname10(lockPath), { recursive: true });
|
|
40936
41169
|
while (Date.now() - startTime < lockTimeout) {
|
|
40937
41170
|
try {
|
|
40938
41171
|
const handle = await open(lockPath, "wx");
|
|
@@ -40956,7 +41189,7 @@ async function acquireSyncLock(global3) {
|
|
|
40956
41189
|
}
|
|
40957
41190
|
logger.debug(`Lock stat failed: ${statError}`);
|
|
40958
41191
|
}
|
|
40959
|
-
await new Promise((
|
|
41192
|
+
await new Promise((resolve10) => setTimeout(resolve10, 100));
|
|
40960
41193
|
continue;
|
|
40961
41194
|
}
|
|
40962
41195
|
throw err;
|
|
@@ -41075,7 +41308,7 @@ async function executeSyncMerge(ctx) {
|
|
|
41075
41308
|
try {
|
|
41076
41309
|
const tempPath = `${currentPath}.tmp.${Date.now()}`;
|
|
41077
41310
|
try {
|
|
41078
|
-
await
|
|
41311
|
+
await writeFile20(tempPath, result.result, "utf-8");
|
|
41079
41312
|
await rename3(tempPath, currentPath);
|
|
41080
41313
|
} catch (atomicError) {
|
|
41081
41314
|
await unlink7(tempPath).catch(() => {});
|
|
@@ -41261,7 +41494,7 @@ async function renameFolders(dirsToRename, extractDir, options) {
|
|
|
41261
41494
|
// src/services/transformers/folder-transform/path-replacer.ts
|
|
41262
41495
|
init_logger();
|
|
41263
41496
|
init_types2();
|
|
41264
|
-
import { readFile as
|
|
41497
|
+
import { readFile as readFile24, readdir as readdir23, writeFile as writeFile21 } from "node:fs/promises";
|
|
41265
41498
|
import { join as join69, relative as relative13 } from "node:path";
|
|
41266
41499
|
var TRANSFORMABLE_FILE_PATTERNS = [
|
|
41267
41500
|
".md",
|
|
@@ -41328,7 +41561,7 @@ async function transformFileContents(dir, compiledReplacements, options) {
|
|
|
41328
41561
|
if (!shouldTransform)
|
|
41329
41562
|
continue;
|
|
41330
41563
|
try {
|
|
41331
|
-
const content = await
|
|
41564
|
+
const content = await readFile24(fullPath, "utf-8");
|
|
41332
41565
|
let newContent = content;
|
|
41333
41566
|
let changeCount = 0;
|
|
41334
41567
|
for (const { regex: regex2, replacement } of compiledReplacements) {
|
|
@@ -41344,7 +41577,7 @@ async function transformFileContents(dir, compiledReplacements, options) {
|
|
|
41344
41577
|
if (options.dryRun) {
|
|
41345
41578
|
logger.debug(`[dry-run] Would update ${relative13(dir, fullPath)}: ${changeCount} replacement(s)`);
|
|
41346
41579
|
} else {
|
|
41347
|
-
await
|
|
41580
|
+
await writeFile21(fullPath, newContent, "utf-8");
|
|
41348
41581
|
logger.debug(`Updated ${relative13(dir, fullPath)}: ${changeCount} replacement(s)`);
|
|
41349
41582
|
}
|
|
41350
41583
|
filesChanged++;
|
|
@@ -41450,7 +41683,7 @@ async function transformFolderPaths(extractDir, folders, options = {}) {
|
|
|
41450
41683
|
|
|
41451
41684
|
// src/services/transformers/global-path-transformer.ts
|
|
41452
41685
|
init_logger();
|
|
41453
|
-
import { readFile as
|
|
41686
|
+
import { readFile as readFile25, readdir as readdir24, writeFile as writeFile22 } from "node:fs/promises";
|
|
41454
41687
|
import { platform as platform12 } from "node:os";
|
|
41455
41688
|
import { extname as extname3, join as join70 } from "node:path";
|
|
41456
41689
|
var IS_WINDOWS4 = platform12() === "win32";
|
|
@@ -41570,10 +41803,10 @@ async function transformPathsForGlobalInstall(directory, options = {}) {
|
|
|
41570
41803
|
await processDirectory2(fullPath);
|
|
41571
41804
|
} else if (entry.isFile() && shouldTransformFile3(entry.name)) {
|
|
41572
41805
|
try {
|
|
41573
|
-
const content = await
|
|
41806
|
+
const content = await readFile25(fullPath, "utf-8");
|
|
41574
41807
|
const { transformed, changes } = transformContent(content);
|
|
41575
41808
|
if (changes > 0) {
|
|
41576
|
-
await
|
|
41809
|
+
await writeFile22(fullPath, transformed, "utf-8");
|
|
41577
41810
|
filesTransformed++;
|
|
41578
41811
|
totalChanges += changes;
|
|
41579
41812
|
if (options.verbose) {
|
|
@@ -41828,7 +42061,7 @@ init_types2();
|
|
|
41828
42061
|
var import_picocolors20 = __toESM(require_picocolors(), 1);
|
|
41829
42062
|
|
|
41830
42063
|
// src/commands/new/phases/directory-setup.ts
|
|
41831
|
-
import { resolve as
|
|
42064
|
+
import { resolve as resolve10 } from "node:path";
|
|
41832
42065
|
init_logger();
|
|
41833
42066
|
init_types2();
|
|
41834
42067
|
var import_fs_extra33 = __toESM(require_lib(), 1);
|
|
@@ -41912,7 +42145,7 @@ async function directorySetup(validOptions, prompts) {
|
|
|
41912
42145
|
targetDir = await prompts.getDirectory(targetDir);
|
|
41913
42146
|
}
|
|
41914
42147
|
}
|
|
41915
|
-
const resolvedDir =
|
|
42148
|
+
const resolvedDir = resolve10(targetDir);
|
|
41916
42149
|
logger.info(`Target directory: ${resolvedDir}`);
|
|
41917
42150
|
if (PathResolver.isLocalSameAsGlobal(resolvedDir)) {
|
|
41918
42151
|
logger.warning("You're creating a project at HOME directory.");
|
|
@@ -42253,14 +42486,14 @@ async function detectInstallations() {
|
|
|
42253
42486
|
}
|
|
42254
42487
|
|
|
42255
42488
|
// src/commands/uninstall/removal-handler.ts
|
|
42256
|
-
import { readdirSync as
|
|
42489
|
+
import { readdirSync as readdirSync3, rmSync as rmSync4 } from "node:fs";
|
|
42257
42490
|
import { join as join74 } from "node:path";
|
|
42258
42491
|
init_logger();
|
|
42259
42492
|
var import_fs_extra35 = __toESM(require_lib(), 1);
|
|
42260
42493
|
|
|
42261
42494
|
// src/commands/uninstall/analysis-handler.ts
|
|
42262
|
-
import { readdirSync, rmSync } from "node:fs";
|
|
42263
|
-
import { dirname as
|
|
42495
|
+
import { readdirSync as readdirSync2, rmSync as rmSync3 } from "node:fs";
|
|
42496
|
+
import { dirname as dirname11, join as join73 } from "node:path";
|
|
42264
42497
|
init_logger();
|
|
42265
42498
|
var import_picocolors21 = __toESM(require_picocolors(), 1);
|
|
42266
42499
|
function classifyFileByOwnership(ownership, forceOverwrite, deleteReason) {
|
|
@@ -42275,17 +42508,17 @@ function classifyFileByOwnership(ownership, forceOverwrite, deleteReason) {
|
|
|
42275
42508
|
}
|
|
42276
42509
|
return { action: "preserve", reason: "user-created" };
|
|
42277
42510
|
}
|
|
42278
|
-
async function
|
|
42511
|
+
async function cleanupEmptyDirectories2(filePath, installationRoot) {
|
|
42279
42512
|
let cleaned = 0;
|
|
42280
|
-
let currentDir =
|
|
42513
|
+
let currentDir = dirname11(filePath);
|
|
42281
42514
|
while (currentDir !== installationRoot && currentDir.startsWith(installationRoot)) {
|
|
42282
42515
|
try {
|
|
42283
|
-
const entries =
|
|
42516
|
+
const entries = readdirSync2(currentDir);
|
|
42284
42517
|
if (entries.length === 0) {
|
|
42285
|
-
|
|
42518
|
+
rmSync3(currentDir, { recursive: true });
|
|
42286
42519
|
cleaned++;
|
|
42287
42520
|
logger.debug(`Removed empty directory: ${currentDir}`);
|
|
42288
|
-
currentDir =
|
|
42521
|
+
currentDir = dirname11(currentDir);
|
|
42289
42522
|
} else {
|
|
42290
42523
|
break;
|
|
42291
42524
|
}
|
|
@@ -42402,16 +42635,16 @@ async function removeInstallations(installations, options) {
|
|
|
42402
42635
|
await import_fs_extra35.remove(filePath);
|
|
42403
42636
|
removedCount++;
|
|
42404
42637
|
logger.debug(`Removed: ${item.path}`);
|
|
42405
|
-
cleanedDirs += await
|
|
42638
|
+
cleanedDirs += await cleanupEmptyDirectories2(filePath, installation.path);
|
|
42406
42639
|
}
|
|
42407
42640
|
}
|
|
42408
42641
|
if (options.kit && analysis.remainingKits.length > 0) {
|
|
42409
42642
|
await ManifestWriter.removeKitFromManifest(installation.path, options.kit);
|
|
42410
42643
|
}
|
|
42411
42644
|
try {
|
|
42412
|
-
const remaining =
|
|
42645
|
+
const remaining = readdirSync3(installation.path);
|
|
42413
42646
|
if (remaining.length === 0) {
|
|
42414
|
-
|
|
42647
|
+
rmSync4(installation.path, { recursive: true });
|
|
42415
42648
|
logger.debug(`Removed empty installation directory: ${installation.path}`);
|
|
42416
42649
|
}
|
|
42417
42650
|
} catch {}
|
|
@@ -42715,7 +42948,7 @@ var import_fs_extra36 = __toESM(require_lib(), 1);
|
|
|
42715
42948
|
// package.json
|
|
42716
42949
|
var package_default = {
|
|
42717
42950
|
name: "claudekit-cli",
|
|
42718
|
-
version: "3.
|
|
42951
|
+
version: "3.27.1",
|
|
42719
42952
|
description: "CLI tool for bootstrapping and updating ClaudeKit projects",
|
|
42720
42953
|
type: "module",
|
|
42721
42954
|
repository: {
|
|
@@ -43193,7 +43426,7 @@ function registerCommands(cli) {
|
|
|
43193
43426
|
}
|
|
43194
43427
|
|
|
43195
43428
|
// src/cli/version-display.ts
|
|
43196
|
-
import { existsSync as
|
|
43429
|
+
import { existsSync as existsSync21, readFileSync as readFileSync7 } from "node:fs";
|
|
43197
43430
|
import { join as join77 } from "node:path";
|
|
43198
43431
|
|
|
43199
43432
|
// src/domains/versioning/checking/version-utils.ts
|
|
@@ -43219,8 +43452,8 @@ init_types2();
|
|
|
43219
43452
|
|
|
43220
43453
|
// src/domains/versioning/version-cache.ts
|
|
43221
43454
|
init_logger();
|
|
43222
|
-
import { existsSync as
|
|
43223
|
-
import { mkdir as mkdir22, readFile as
|
|
43455
|
+
import { existsSync as existsSync20 } from "node:fs";
|
|
43456
|
+
import { mkdir as mkdir22, readFile as readFile27, writeFile as writeFile23 } from "node:fs/promises";
|
|
43224
43457
|
import { join as join76 } from "node:path";
|
|
43225
43458
|
class VersionCacheManager {
|
|
43226
43459
|
static CACHE_FILENAME = "version-check.json";
|
|
@@ -43232,11 +43465,11 @@ class VersionCacheManager {
|
|
|
43232
43465
|
static async load() {
|
|
43233
43466
|
const cacheFile = VersionCacheManager.getCacheFile();
|
|
43234
43467
|
try {
|
|
43235
|
-
if (!
|
|
43468
|
+
if (!existsSync20(cacheFile)) {
|
|
43236
43469
|
logger.debug("Version check cache not found");
|
|
43237
43470
|
return null;
|
|
43238
43471
|
}
|
|
43239
|
-
const content = await
|
|
43472
|
+
const content = await readFile27(cacheFile, "utf-8");
|
|
43240
43473
|
const cache2 = JSON.parse(content);
|
|
43241
43474
|
if (!cache2.lastCheck || !cache2.currentVersion || !cache2.latestVersion) {
|
|
43242
43475
|
logger.debug("Invalid cache structure, ignoring");
|
|
@@ -43253,10 +43486,10 @@ class VersionCacheManager {
|
|
|
43253
43486
|
const cacheFile = VersionCacheManager.getCacheFile();
|
|
43254
43487
|
const cacheDir = PathResolver.getCacheDir(false);
|
|
43255
43488
|
try {
|
|
43256
|
-
if (!
|
|
43489
|
+
if (!existsSync20(cacheDir)) {
|
|
43257
43490
|
await mkdir22(cacheDir, { recursive: true, mode: 448 });
|
|
43258
43491
|
}
|
|
43259
|
-
await
|
|
43492
|
+
await writeFile23(cacheFile, JSON.stringify(cache2, null, 2), "utf-8");
|
|
43260
43493
|
logger.debug(`Version check cache saved to ${cacheFile}`);
|
|
43261
43494
|
} catch (error) {
|
|
43262
43495
|
logger.debug(`Failed to save version check cache: ${error}`);
|
|
@@ -43275,7 +43508,7 @@ class VersionCacheManager {
|
|
|
43275
43508
|
static async clear() {
|
|
43276
43509
|
const cacheFile = VersionCacheManager.getCacheFile();
|
|
43277
43510
|
try {
|
|
43278
|
-
if (
|
|
43511
|
+
if (existsSync20(cacheFile)) {
|
|
43279
43512
|
const fs14 = await import("node:fs/promises");
|
|
43280
43513
|
await fs14.unlink(cacheFile);
|
|
43281
43514
|
logger.debug("Version check cache cleared");
|
|
@@ -43498,7 +43731,7 @@ async function displayVersion() {
|
|
|
43498
43731
|
const prefix = PathResolver.getPathPrefix(false);
|
|
43499
43732
|
const localMetadataPath = prefix ? join77(process.cwd(), prefix, "metadata.json") : join77(process.cwd(), "metadata.json");
|
|
43500
43733
|
const isLocalSameAsGlobal = localMetadataPath === globalMetadataPath;
|
|
43501
|
-
if (!isLocalSameAsGlobal &&
|
|
43734
|
+
if (!isLocalSameAsGlobal && existsSync21(localMetadataPath)) {
|
|
43502
43735
|
try {
|
|
43503
43736
|
const rawMetadata = JSON.parse(readFileSync7(localMetadataPath, "utf-8"));
|
|
43504
43737
|
const metadata = MetadataSchema.parse(rawMetadata);
|
|
@@ -43512,7 +43745,7 @@ async function displayVersion() {
|
|
|
43512
43745
|
logger.verbose("Failed to parse local metadata.json", { error });
|
|
43513
43746
|
}
|
|
43514
43747
|
}
|
|
43515
|
-
if (
|
|
43748
|
+
if (existsSync21(globalMetadataPath)) {
|
|
43516
43749
|
try {
|
|
43517
43750
|
const rawMetadata = JSON.parse(readFileSync7(globalMetadataPath, "utf-8"));
|
|
43518
43751
|
const metadata = MetadataSchema.parse(rawMetadata);
|