claudekit-cli 3.32.0 → 3.32.1-dev.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 +139 -31
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -23196,7 +23196,7 @@ function getPagerArgs(pagerCmd) {
|
|
|
23196
23196
|
return [];
|
|
23197
23197
|
}
|
|
23198
23198
|
async function trySystemPager(content) {
|
|
23199
|
-
return new Promise((
|
|
23199
|
+
return new Promise((resolve13) => {
|
|
23200
23200
|
const pagerCmd = process.env.PAGER || "less";
|
|
23201
23201
|
const pagerArgs = getPagerArgs(pagerCmd);
|
|
23202
23202
|
try {
|
|
@@ -23206,20 +23206,20 @@ async function trySystemPager(content) {
|
|
|
23206
23206
|
});
|
|
23207
23207
|
const timeout = setTimeout(() => {
|
|
23208
23208
|
pager.kill();
|
|
23209
|
-
|
|
23209
|
+
resolve13(false);
|
|
23210
23210
|
}, 30000);
|
|
23211
23211
|
pager.stdin.write(content);
|
|
23212
23212
|
pager.stdin.end();
|
|
23213
23213
|
pager.on("close", (code2) => {
|
|
23214
23214
|
clearTimeout(timeout);
|
|
23215
|
-
|
|
23215
|
+
resolve13(code2 === 0);
|
|
23216
23216
|
});
|
|
23217
23217
|
pager.on("error", () => {
|
|
23218
23218
|
clearTimeout(timeout);
|
|
23219
|
-
|
|
23219
|
+
resolve13(false);
|
|
23220
23220
|
});
|
|
23221
23221
|
} catch {
|
|
23222
|
-
|
|
23222
|
+
resolve13(false);
|
|
23223
23223
|
}
|
|
23224
23224
|
});
|
|
23225
23225
|
}
|
|
@@ -23246,16 +23246,16 @@ async function basicPager(content) {
|
|
|
23246
23246
|
break;
|
|
23247
23247
|
}
|
|
23248
23248
|
const remaining = lines.length - currentLine;
|
|
23249
|
-
await new Promise((
|
|
23249
|
+
await new Promise((resolve13) => {
|
|
23250
23250
|
rl.question(`-- More (${remaining} lines) [Enter/q] --`, (answer) => {
|
|
23251
23251
|
if (answer.toLowerCase() === "q") {
|
|
23252
23252
|
rl.close();
|
|
23253
23253
|
process.exitCode = 0;
|
|
23254
|
-
|
|
23254
|
+
resolve13();
|
|
23255
23255
|
return;
|
|
23256
23256
|
}
|
|
23257
23257
|
process.stdout.write("\x1B[1A\x1B[2K");
|
|
23258
|
-
|
|
23258
|
+
resolve13();
|
|
23259
23259
|
});
|
|
23260
23260
|
});
|
|
23261
23261
|
}
|
|
@@ -30849,27 +30849,51 @@ class PromptsManager {
|
|
|
30849
30849
|
init_logger();
|
|
30850
30850
|
|
|
30851
30851
|
// src/shared/process-lock.ts
|
|
30852
|
+
init_logger();
|
|
30852
30853
|
var import_proper_lockfile = __toESM(require_proper_lockfile(), 1);
|
|
30853
30854
|
import { mkdir as mkdir8 } from "node:fs/promises";
|
|
30854
30855
|
import os2 from "node:os";
|
|
30855
30856
|
import { join as join29 } from "node:path";
|
|
30856
30857
|
var LOCK_CONFIG = {
|
|
30857
|
-
stale:
|
|
30858
|
+
stale: 60000,
|
|
30858
30859
|
retries: 0
|
|
30859
30860
|
};
|
|
30861
|
+
var activeLocks = new Set;
|
|
30862
|
+
var cleanupRegistered = false;
|
|
30860
30863
|
function getLocksDir() {
|
|
30861
30864
|
return join29(os2.homedir(), ".claudekit", "locks");
|
|
30862
30865
|
}
|
|
30866
|
+
function cleanupLocks() {
|
|
30867
|
+
for (const name of activeLocks) {
|
|
30868
|
+
try {
|
|
30869
|
+
const lockPath = join29(getLocksDir(), `${name}.lock`);
|
|
30870
|
+
import_proper_lockfile.default.unlockSync(lockPath, { realpath: false });
|
|
30871
|
+
} catch {
|
|
30872
|
+
try {
|
|
30873
|
+
logger.verbose(`Failed to cleanup lock: ${name}`);
|
|
30874
|
+
} catch {}
|
|
30875
|
+
}
|
|
30876
|
+
}
|
|
30877
|
+
activeLocks.clear();
|
|
30878
|
+
}
|
|
30879
|
+
function registerCleanupHandlers() {
|
|
30880
|
+
if (cleanupRegistered)
|
|
30881
|
+
return;
|
|
30882
|
+
cleanupRegistered = true;
|
|
30883
|
+
process.on("exit", cleanupLocks);
|
|
30884
|
+
}
|
|
30863
30885
|
async function ensureLocksDir() {
|
|
30864
30886
|
const lockDir = getLocksDir();
|
|
30865
30887
|
await mkdir8(lockDir, { recursive: true });
|
|
30866
30888
|
}
|
|
30867
30889
|
async function withProcessLock(lockName, fn) {
|
|
30890
|
+
registerCleanupHandlers();
|
|
30868
30891
|
await ensureLocksDir();
|
|
30869
30892
|
const lockPath = join29(getLocksDir(), `${lockName}.lock`);
|
|
30870
30893
|
let release;
|
|
30871
30894
|
try {
|
|
30872
30895
|
release = await import_proper_lockfile.default.lock(lockPath, { ...LOCK_CONFIG, realpath: false });
|
|
30896
|
+
activeLocks.add(lockName);
|
|
30873
30897
|
return await fn();
|
|
30874
30898
|
} catch (e2) {
|
|
30875
30899
|
const error = e2;
|
|
@@ -30884,6 +30908,7 @@ Wait for it to complete or remove lock: ${lockPath}`);
|
|
|
30884
30908
|
if (release) {
|
|
30885
30909
|
await release();
|
|
30886
30910
|
}
|
|
30911
|
+
activeLocks.delete(lockName);
|
|
30887
30912
|
}
|
|
30888
30913
|
}
|
|
30889
30914
|
|
|
@@ -47943,7 +47968,8 @@ async function initCommand(options2) {
|
|
|
47943
47968
|
return;
|
|
47944
47969
|
}
|
|
47945
47970
|
logger.error(error instanceof Error ? error.message : "Unknown error occurred");
|
|
47946
|
-
process.
|
|
47971
|
+
process.exitCode = 1;
|
|
47972
|
+
throw error;
|
|
47947
47973
|
}
|
|
47948
47974
|
}
|
|
47949
47975
|
// src/commands/new/new-command.ts
|
|
@@ -49300,30 +49326,45 @@ var import_picocolors23 = __toESM(require_picocolors(), 1);
|
|
|
49300
49326
|
// src/commands/uninstall/installation-detector.ts
|
|
49301
49327
|
init_path_resolver();
|
|
49302
49328
|
var import_fs_extra35 = __toESM(require_lib(), 1);
|
|
49329
|
+
function hasClaudeKitComponents(components) {
|
|
49330
|
+
return components.agents > 0 || components.commands > 0 || components.rules > 0 || components.skills > 0;
|
|
49331
|
+
}
|
|
49303
49332
|
async function detectInstallations() {
|
|
49304
49333
|
const installations = [];
|
|
49305
49334
|
const setup = await getClaudeKitSetup(process.cwd());
|
|
49306
49335
|
const isLocalSameAsGlobal = PathResolver.isLocalSameAsGlobal();
|
|
49307
|
-
if (setup.project.path &&
|
|
49308
|
-
|
|
49309
|
-
|
|
49310
|
-
|
|
49311
|
-
|
|
49312
|
-
|
|
49336
|
+
if (setup.project.path && !isLocalSameAsGlobal) {
|
|
49337
|
+
const hasMetadata = setup.project.metadata !== null;
|
|
49338
|
+
const hasComponents = hasClaudeKitComponents(setup.project.components);
|
|
49339
|
+
if (hasMetadata || hasComponents) {
|
|
49340
|
+
installations.push({
|
|
49341
|
+
type: "local",
|
|
49342
|
+
path: setup.project.path,
|
|
49343
|
+
exists: await import_fs_extra35.pathExists(setup.project.path),
|
|
49344
|
+
hasMetadata,
|
|
49345
|
+
components: setup.project.components
|
|
49346
|
+
});
|
|
49347
|
+
}
|
|
49313
49348
|
}
|
|
49314
|
-
if (setup.global.path
|
|
49315
|
-
|
|
49316
|
-
|
|
49317
|
-
|
|
49318
|
-
|
|
49319
|
-
|
|
49349
|
+
if (setup.global.path) {
|
|
49350
|
+
const hasMetadata = setup.global.metadata !== null;
|
|
49351
|
+
const hasComponents = hasClaudeKitComponents(setup.global.components);
|
|
49352
|
+
if (hasMetadata || hasComponents) {
|
|
49353
|
+
installations.push({
|
|
49354
|
+
type: "global",
|
|
49355
|
+
path: setup.global.path,
|
|
49356
|
+
exists: await import_fs_extra35.pathExists(setup.global.path),
|
|
49357
|
+
hasMetadata,
|
|
49358
|
+
components: setup.global.components
|
|
49359
|
+
});
|
|
49360
|
+
}
|
|
49320
49361
|
}
|
|
49321
49362
|
return installations.filter((i) => i.exists);
|
|
49322
49363
|
}
|
|
49323
49364
|
|
|
49324
49365
|
// src/commands/uninstall/removal-handler.ts
|
|
49325
49366
|
import { readdirSync as readdirSync4, rmSync as rmSync5 } from "node:fs";
|
|
49326
|
-
import { join as join81 } from "node:path";
|
|
49367
|
+
import { join as join81, resolve as resolve12, sep as sep3 } from "node:path";
|
|
49327
49368
|
init_logger();
|
|
49328
49369
|
var import_fs_extra36 = __toESM(require_lib(), 1);
|
|
49329
49370
|
|
|
@@ -49449,28 +49490,72 @@ function displayDryRunPreview(analysis, installationType) {
|
|
|
49449
49490
|
}
|
|
49450
49491
|
|
|
49451
49492
|
// src/commands/uninstall/removal-handler.ts
|
|
49493
|
+
async function isDirectory(filePath) {
|
|
49494
|
+
try {
|
|
49495
|
+
const stats = await import_fs_extra36.lstat(filePath);
|
|
49496
|
+
return stats.isDirectory();
|
|
49497
|
+
} catch {
|
|
49498
|
+
logger.debug(`Failed to check if path is directory: ${filePath}`);
|
|
49499
|
+
return false;
|
|
49500
|
+
}
|
|
49501
|
+
}
|
|
49502
|
+
async function isPathSafeToRemove(filePath, baseDir) {
|
|
49503
|
+
try {
|
|
49504
|
+
const resolvedPath = resolve12(filePath);
|
|
49505
|
+
const resolvedBase = resolve12(baseDir);
|
|
49506
|
+
if (!resolvedPath.startsWith(resolvedBase + sep3) && resolvedPath !== resolvedBase) {
|
|
49507
|
+
logger.debug(`Path outside installation directory: ${filePath}`);
|
|
49508
|
+
return false;
|
|
49509
|
+
}
|
|
49510
|
+
const stats = await import_fs_extra36.lstat(filePath);
|
|
49511
|
+
if (stats.isSymbolicLink()) {
|
|
49512
|
+
const realPath = await import_fs_extra36.realpath(filePath);
|
|
49513
|
+
const resolvedReal = resolve12(realPath);
|
|
49514
|
+
if (!resolvedReal.startsWith(resolvedBase + sep3) && resolvedReal !== resolvedBase) {
|
|
49515
|
+
logger.debug(`Symlink points outside installation directory: ${filePath} -> ${realPath}`);
|
|
49516
|
+
return false;
|
|
49517
|
+
}
|
|
49518
|
+
}
|
|
49519
|
+
return true;
|
|
49520
|
+
} catch {
|
|
49521
|
+
logger.debug(`Failed to validate path safety: ${filePath}`);
|
|
49522
|
+
return false;
|
|
49523
|
+
}
|
|
49524
|
+
}
|
|
49452
49525
|
async function removeInstallations(installations, options2) {
|
|
49453
49526
|
for (const installation of installations) {
|
|
49454
49527
|
const analysis = await analyzeInstallation(installation, options2.forceOverwrite, options2.kit);
|
|
49455
49528
|
if (options2.dryRun) {
|
|
49456
49529
|
const label = options2.kit ? `${installation.type} (${options2.kit} kit)` : installation.type;
|
|
49457
|
-
|
|
49530
|
+
const legacyLabel2 = !installation.hasMetadata ? " [legacy]" : "";
|
|
49531
|
+
displayDryRunPreview(analysis, `${label}${legacyLabel2}`);
|
|
49458
49532
|
if (analysis.remainingKits.length > 0) {
|
|
49459
49533
|
log.info(`Remaining kits after uninstall: ${analysis.remainingKits.join(", ")}`);
|
|
49460
49534
|
}
|
|
49535
|
+
if (!installation.hasMetadata) {
|
|
49536
|
+
log.warn("Legacy installation - directories will be removed recursively");
|
|
49537
|
+
}
|
|
49461
49538
|
continue;
|
|
49462
49539
|
}
|
|
49463
49540
|
const kitLabel = options2.kit ? ` ${options2.kit} kit` : "";
|
|
49464
|
-
const
|
|
49541
|
+
const legacyLabel = !installation.hasMetadata ? " (legacy)" : "";
|
|
49542
|
+
const spinner = createSpinner(`Removing ${installation.type}${kitLabel}${legacyLabel} ClaudeKit files...`).start();
|
|
49465
49543
|
try {
|
|
49466
49544
|
let removedCount = 0;
|
|
49467
49545
|
let cleanedDirs = 0;
|
|
49468
49546
|
for (const item of analysis.toDelete) {
|
|
49469
49547
|
const filePath = join81(installation.path, item.path);
|
|
49470
|
-
if (await import_fs_extra36.pathExists(filePath))
|
|
49471
|
-
|
|
49472
|
-
|
|
49473
|
-
logger.debug(`
|
|
49548
|
+
if (!await import_fs_extra36.pathExists(filePath))
|
|
49549
|
+
continue;
|
|
49550
|
+
if (!await isPathSafeToRemove(filePath, installation.path)) {
|
|
49551
|
+
logger.debug(`Skipping unsafe path: ${item.path}`);
|
|
49552
|
+
continue;
|
|
49553
|
+
}
|
|
49554
|
+
const isDir = await isDirectory(filePath);
|
|
49555
|
+
await import_fs_extra36.remove(filePath);
|
|
49556
|
+
removedCount++;
|
|
49557
|
+
logger.debug(`Removed ${isDir ? "directory" : "file"}: ${item.path}`);
|
|
49558
|
+
if (!isDir) {
|
|
49474
49559
|
cleanedDirs += await cleanupEmptyDirectories3(filePath, installation.path);
|
|
49475
49560
|
}
|
|
49476
49561
|
}
|
|
@@ -49502,11 +49587,34 @@ async function removeInstallations(installations, options2) {
|
|
|
49502
49587
|
|
|
49503
49588
|
// src/commands/uninstall/uninstall-command.ts
|
|
49504
49589
|
var prompts = new PromptsManager;
|
|
49590
|
+
function formatComponentSummary(inst) {
|
|
49591
|
+
const parts = [];
|
|
49592
|
+
if (inst.components.skills > 0)
|
|
49593
|
+
parts.push(`${inst.components.skills} skills`);
|
|
49594
|
+
if (inst.components.commands > 0)
|
|
49595
|
+
parts.push(`${inst.components.commands} commands`);
|
|
49596
|
+
if (inst.components.agents > 0)
|
|
49597
|
+
parts.push(`${inst.components.agents} agents`);
|
|
49598
|
+
if (inst.components.rules > 0)
|
|
49599
|
+
parts.push(`${inst.components.rules} rules`);
|
|
49600
|
+
return parts.length > 0 ? ` (${parts.join(", ")})` : "";
|
|
49601
|
+
}
|
|
49505
49602
|
function displayInstallations(installations, scope) {
|
|
49506
49603
|
prompts.intro("ClaudeKit Uninstaller");
|
|
49507
49604
|
const scopeLabel = scope === "all" ? "all" : scope === "local" ? "local only" : "global only";
|
|
49508
|
-
|
|
49605
|
+
const hasLegacy = installations.some((i) => !i.hasMetadata);
|
|
49606
|
+
const lines = installations.map((i) => {
|
|
49607
|
+
const typeLabel = i.type === "local" ? "Local " : "Global";
|
|
49608
|
+
const legacyTag = !i.hasMetadata ? import_picocolors23.default.yellow(" [legacy]") : "";
|
|
49609
|
+
const components = formatComponentSummary(i);
|
|
49610
|
+
return ` ${typeLabel}: ${i.path}${legacyTag}${components}`;
|
|
49611
|
+
});
|
|
49612
|
+
prompts.note(lines.join(`
|
|
49509
49613
|
`), `Detected ClaudeKit installations (${scopeLabel})`);
|
|
49614
|
+
if (hasLegacy) {
|
|
49615
|
+
log.warn(import_picocolors23.default.yellow(`[!] Legacy installation(s) detected without metadata.json.
|
|
49616
|
+
`) + import_picocolors23.default.yellow(" These files cannot be selectively removed. Full directory cleanup will be performed."));
|
|
49617
|
+
}
|
|
49510
49618
|
log.warn("[!] This will permanently delete ClaudeKit files from the above paths.");
|
|
49511
49619
|
}
|
|
49512
49620
|
async function promptScope(installations) {
|
|
@@ -49787,7 +49895,7 @@ var import_fs_extra37 = __toESM(require_lib(), 1);
|
|
|
49787
49895
|
// package.json
|
|
49788
49896
|
var package_default = {
|
|
49789
49897
|
name: "claudekit-cli",
|
|
49790
|
-
version: "3.32.
|
|
49898
|
+
version: "3.32.1-dev.1",
|
|
49791
49899
|
description: "CLI tool for bootstrapping and updating ClaudeKit projects",
|
|
49792
49900
|
type: "module",
|
|
49793
49901
|
repository: {
|