claudekit-cli 3.34.1-dev.4 → 3.34.1-dev.5
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 +66 -22
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -44585,10 +44585,38 @@ var init_pnpm_detector = __esm(() => {
|
|
|
44585
44585
|
});
|
|
44586
44586
|
|
|
44587
44587
|
// src/domains/installation/package-managers/detection-core.ts
|
|
44588
|
-
import { existsSync as existsSync17 } from "node:fs";
|
|
44588
|
+
import { existsSync as existsSync17, realpathSync } from "node:fs";
|
|
44589
44589
|
import { chmod as chmod2, mkdir as mkdir6, readFile as readFile13, writeFile as writeFile7 } from "node:fs/promises";
|
|
44590
44590
|
import { platform as platform4 } from "node:os";
|
|
44591
|
-
import { join as join23 } from "node:path";
|
|
44591
|
+
import { join as join23, sep } from "node:path";
|
|
44592
|
+
function detectFromBinaryPath() {
|
|
44593
|
+
try {
|
|
44594
|
+
const scriptPath = process.argv[1];
|
|
44595
|
+
if (!scriptPath)
|
|
44596
|
+
return "unknown";
|
|
44597
|
+
let resolvedPath;
|
|
44598
|
+
try {
|
|
44599
|
+
resolvedPath = realpathSync(scriptPath);
|
|
44600
|
+
} catch {
|
|
44601
|
+
resolvedPath = scriptPath;
|
|
44602
|
+
}
|
|
44603
|
+
const normalized = resolvedPath.split(sep).join("/").toLowerCase();
|
|
44604
|
+
logger.verbose(`Binary path resolved: ${normalized}`);
|
|
44605
|
+
if (normalized.includes("/.bun/install/") || normalized.includes("/bun/install/global/")) {
|
|
44606
|
+
return "bun";
|
|
44607
|
+
}
|
|
44608
|
+
if (normalized.includes("/pnpm/global/") || normalized.includes("/.local/share/pnpm/")) {
|
|
44609
|
+
return "pnpm";
|
|
44610
|
+
}
|
|
44611
|
+
if (normalized.includes("/yarn/global/") || normalized.includes("/.config/yarn/")) {
|
|
44612
|
+
return "yarn";
|
|
44613
|
+
}
|
|
44614
|
+
if (normalized.includes("/npm/node_modules/") || normalized.includes("/usr/local/lib/node_modules/") || normalized.includes("/usr/lib/node_modules/") || normalized.includes("/opt/homebrew/lib/node_modules/") || normalized.includes("/.nvm/versions/node/") || normalized.includes("/n/versions/node/") || normalized.includes("/appdata/roaming/npm/")) {
|
|
44615
|
+
return "npm";
|
|
44616
|
+
}
|
|
44617
|
+
} catch {}
|
|
44618
|
+
return "unknown";
|
|
44619
|
+
}
|
|
44592
44620
|
function detectFromEnv() {
|
|
44593
44621
|
const userAgent = process.env.npm_config_user_agent;
|
|
44594
44622
|
if (userAgent) {
|
|
@@ -44605,13 +44633,14 @@ function detectFromEnv() {
|
|
|
44605
44633
|
const execPath = process.env.npm_execpath;
|
|
44606
44634
|
if (execPath) {
|
|
44607
44635
|
logger.debug(`Detected exec path: ${execPath}`);
|
|
44608
|
-
|
|
44636
|
+
const normalizedExec = execPath.replace(/\\/g, "/").toLowerCase();
|
|
44637
|
+
if (/\/bun([/.]|$)/.test(normalizedExec) || normalizedExec.startsWith("bun"))
|
|
44609
44638
|
return "bun";
|
|
44610
|
-
if (
|
|
44639
|
+
if (/\/yarn([/.]|$)/.test(normalizedExec) || normalizedExec.startsWith("yarn"))
|
|
44611
44640
|
return "yarn";
|
|
44612
|
-
if (
|
|
44641
|
+
if (/\/pnpm([/.]|$)/.test(normalizedExec) || normalizedExec.startsWith("pnpm"))
|
|
44613
44642
|
return "pnpm";
|
|
44614
|
-
if (
|
|
44643
|
+
if (/\/npm([/.]|$)/.test(normalizedExec) || normalizedExec.startsWith("npm"))
|
|
44615
44644
|
return "npm";
|
|
44616
44645
|
}
|
|
44617
44646
|
return "unknown";
|
|
@@ -44629,8 +44658,8 @@ async function readCachedPm() {
|
|
|
44629
44658
|
return null;
|
|
44630
44659
|
}
|
|
44631
44660
|
const age = Date.now() - data.detectedAt;
|
|
44632
|
-
if (age > CACHE_TTL) {
|
|
44633
|
-
logger.debug("Cache expired, will re-detect");
|
|
44661
|
+
if (age < 0 || age > CACHE_TTL) {
|
|
44662
|
+
logger.debug(age < 0 ? "Cache timestamp in future, ignoring" : "Cache expired, will re-detect");
|
|
44634
44663
|
return null;
|
|
44635
44664
|
}
|
|
44636
44665
|
const validPms = ["npm", "bun", "yarn", "pnpm"];
|
|
@@ -44739,6 +44768,18 @@ var init_package_manager_detector = __esm(() => {
|
|
|
44739
44768
|
PackageManagerDetector = class PackageManagerDetector {
|
|
44740
44769
|
static async detect() {
|
|
44741
44770
|
logger.verbose("PackageManagerDetector: Starting detection");
|
|
44771
|
+
const binaryPm = detectFromBinaryPath();
|
|
44772
|
+
if (binaryPm !== "unknown") {
|
|
44773
|
+
logger.verbose(`PackageManagerDetector: Detected from binary path: ${binaryPm}`);
|
|
44774
|
+
const cachedPm2 = await readCachedPm();
|
|
44775
|
+
if (cachedPm2 && cachedPm2 !== binaryPm) {
|
|
44776
|
+
logger.verbose(`PackageManagerDetector: Cache says ${cachedPm2}, binary says ${binaryPm} — updating cache`);
|
|
44777
|
+
await saveCachedPm(binaryPm, PackageManagerDetector.getVersion);
|
|
44778
|
+
} else if (!cachedPm2) {
|
|
44779
|
+
await saveCachedPm(binaryPm, PackageManagerDetector.getVersion);
|
|
44780
|
+
}
|
|
44781
|
+
return binaryPm;
|
|
44782
|
+
}
|
|
44742
44783
|
const envPm = detectFromEnv();
|
|
44743
44784
|
if (envPm !== "unknown") {
|
|
44744
44785
|
logger.verbose(`PackageManagerDetector: Detected from env: ${envPm}`);
|
|
@@ -45236,7 +45277,7 @@ var package_default;
|
|
|
45236
45277
|
var init_package = __esm(() => {
|
|
45237
45278
|
package_default = {
|
|
45238
45279
|
name: "claudekit-cli",
|
|
45239
|
-
version: "3.34.1-dev.
|
|
45280
|
+
version: "3.34.1-dev.5",
|
|
45240
45281
|
description: "CLI tool for bootstrapping and updating ClaudeKit projects",
|
|
45241
45282
|
type: "module",
|
|
45242
45283
|
repository: {
|
|
@@ -45551,12 +45592,15 @@ Run 'ck update' to install`, "Update Check");
|
|
|
45551
45592
|
s.stop("Update failed");
|
|
45552
45593
|
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
45553
45594
|
if (errorMessage.includes("EACCES") || errorMessage.includes("EPERM") || errorMessage.includes("permission") || errorMessage.includes("Access is denied")) {
|
|
45554
|
-
|
|
45595
|
+
const permHint = pm === "npm" ? `
|
|
45555
45596
|
|
|
45556
|
-
Or fix npm permissions: https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally`
|
|
45597
|
+
Or fix npm permissions: https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally` : "";
|
|
45598
|
+
const isWindows3 = process.platform === "win32";
|
|
45599
|
+
const elevationHint = isWindows3 ? `Run your terminal as Administrator and retry: ${updateCmd}` : `sudo ${updateCmd}`;
|
|
45600
|
+
throw new CliUpdateError(`Permission denied. Try: ${elevationHint}${permHint}`);
|
|
45557
45601
|
}
|
|
45558
45602
|
logger.error(`Update failed: ${errorMessage}`);
|
|
45559
|
-
logger.info(
|
|
45603
|
+
logger.info(`Try running: ${updateCmd}`);
|
|
45560
45604
|
throw new CliUpdateError(`Update failed: ${errorMessage}
|
|
45561
45605
|
|
|
45562
45606
|
Manual update: ${updateCmd}`);
|
|
@@ -66041,7 +66085,7 @@ init_types2();
|
|
|
66041
66085
|
|
|
66042
66086
|
// src/domains/installation/utils/path-security.ts
|
|
66043
66087
|
init_types2();
|
|
66044
|
-
import { lstatSync as lstatSync2, realpathSync } from "node:fs";
|
|
66088
|
+
import { lstatSync as lstatSync2, realpathSync as realpathSync2 } from "node:fs";
|
|
66045
66089
|
import { relative as relative5, resolve as resolve10 } from "node:path";
|
|
66046
66090
|
var MAX_EXTRACTION_SIZE = 500 * 1024 * 1024;
|
|
66047
66091
|
function isPathSafe(basePath, targetPath) {
|
|
@@ -66049,7 +66093,7 @@ function isPathSafe(basePath, targetPath) {
|
|
|
66049
66093
|
try {
|
|
66050
66094
|
const stat10 = lstatSync2(targetPath);
|
|
66051
66095
|
if (stat10.isSymbolicLink()) {
|
|
66052
|
-
const realTarget =
|
|
66096
|
+
const realTarget = realpathSync2(targetPath);
|
|
66053
66097
|
if (!realTarget.startsWith(resolvedBase)) {
|
|
66054
66098
|
return false;
|
|
66055
66099
|
}
|
|
@@ -73832,7 +73876,7 @@ import { join as join77 } from "node:path";
|
|
|
73832
73876
|
|
|
73833
73877
|
// src/domains/installation/deletion-handler.ts
|
|
73834
73878
|
import { existsSync as existsSync35, lstatSync as lstatSync3, readdirSync as readdirSync2, rmSync as rmSync2, rmdirSync, unlinkSync as unlinkSync3 } from "node:fs";
|
|
73835
|
-
import { dirname as dirname14, join as join64, relative as relative7, resolve as resolve12, sep } from "node:path";
|
|
73879
|
+
import { dirname as dirname14, join as join64, relative as relative7, resolve as resolve12, sep as sep2 } from "node:path";
|
|
73836
73880
|
|
|
73837
73881
|
// src/services/file-operations/manifest/manifest-reader.ts
|
|
73838
73882
|
init_metadata_migration();
|
|
@@ -74071,7 +74115,7 @@ function cleanupEmptyDirectories(filePath, claudeDir2) {
|
|
|
74071
74115
|
function deletePath(fullPath, claudeDir2) {
|
|
74072
74116
|
const normalizedPath = resolve12(fullPath);
|
|
74073
74117
|
const normalizedClaudeDir = resolve12(claudeDir2);
|
|
74074
|
-
if (!normalizedPath.startsWith(`${normalizedClaudeDir}${
|
|
74118
|
+
if (!normalizedPath.startsWith(`${normalizedClaudeDir}${sep2}`) && normalizedPath !== normalizedClaudeDir) {
|
|
74075
74119
|
throw new Error(`Path traversal detected: ${fullPath}`);
|
|
74076
74120
|
}
|
|
74077
74121
|
try {
|
|
@@ -74145,7 +74189,7 @@ async function handleDeletions(sourceMetadata, claudeDir2) {
|
|
|
74145
74189
|
const fullPath = join64(claudeDir2, path11);
|
|
74146
74190
|
const normalizedPath = resolve12(fullPath);
|
|
74147
74191
|
const normalizedClaudeDir = resolve12(claudeDir2);
|
|
74148
|
-
if (!normalizedPath.startsWith(`${normalizedClaudeDir}${
|
|
74192
|
+
if (!normalizedPath.startsWith(`${normalizedClaudeDir}${sep2}`)) {
|
|
74149
74193
|
logger.warning(`Skipping invalid path: ${path11}`);
|
|
74150
74194
|
result.errors.push(path11);
|
|
74151
74195
|
continue;
|
|
@@ -75168,8 +75212,8 @@ var path11 = {
|
|
|
75168
75212
|
win32: { sep: "\\" },
|
|
75169
75213
|
posix: { sep: "/" }
|
|
75170
75214
|
};
|
|
75171
|
-
var
|
|
75172
|
-
minimatch.sep =
|
|
75215
|
+
var sep3 = defaultPlatform === "win32" ? path11.win32.sep : path11.posix.sep;
|
|
75216
|
+
minimatch.sep = sep3;
|
|
75173
75217
|
var GLOBSTAR = Symbol("globstar **");
|
|
75174
75218
|
minimatch.GLOBSTAR = GLOBSTAR;
|
|
75175
75219
|
var qmark2 = "[^/]";
|
|
@@ -82330,7 +82374,7 @@ async function detectInstallations() {
|
|
|
82330
82374
|
|
|
82331
82375
|
// src/commands/uninstall/removal-handler.ts
|
|
82332
82376
|
import { readdirSync as readdirSync5, rmSync as rmSync5 } from "node:fs";
|
|
82333
|
-
import { join as join99, resolve as resolve19, sep as
|
|
82377
|
+
import { join as join99, resolve as resolve19, sep as sep4 } from "node:path";
|
|
82334
82378
|
init_logger();
|
|
82335
82379
|
init_safe_prompts();
|
|
82336
82380
|
init_safe_spinner();
|
|
@@ -82473,7 +82517,7 @@ async function isPathSafeToRemove(filePath, baseDir) {
|
|
|
82473
82517
|
try {
|
|
82474
82518
|
const resolvedPath = resolve19(filePath);
|
|
82475
82519
|
const resolvedBase = resolve19(baseDir);
|
|
82476
|
-
if (!resolvedPath.startsWith(resolvedBase +
|
|
82520
|
+
if (!resolvedPath.startsWith(resolvedBase + sep4) && resolvedPath !== resolvedBase) {
|
|
82477
82521
|
logger.debug(`Path outside installation directory: ${filePath}`);
|
|
82478
82522
|
return false;
|
|
82479
82523
|
}
|
|
@@ -82481,7 +82525,7 @@ async function isPathSafeToRemove(filePath, baseDir) {
|
|
|
82481
82525
|
if (stats.isSymbolicLink()) {
|
|
82482
82526
|
const realPath = await import_fs_extra37.realpath(filePath);
|
|
82483
82527
|
const resolvedReal = resolve19(realPath);
|
|
82484
|
-
if (!resolvedReal.startsWith(resolvedBase +
|
|
82528
|
+
if (!resolvedReal.startsWith(resolvedBase + sep4) && resolvedReal !== resolvedBase) {
|
|
82485
82529
|
logger.debug(`Symlink points outside installation directory: ${filePath} -> ${realPath}`);
|
|
82486
82530
|
return false;
|
|
82487
82531
|
}
|