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.
Files changed (2) hide show
  1. package/dist/index.js +66 -22
  2. 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
- if (execPath.includes("bun"))
44636
+ const normalizedExec = execPath.replace(/\\/g, "/").toLowerCase();
44637
+ if (/\/bun([/.]|$)/.test(normalizedExec) || normalizedExec.startsWith("bun"))
44609
44638
  return "bun";
44610
- if (execPath.includes("yarn"))
44639
+ if (/\/yarn([/.]|$)/.test(normalizedExec) || normalizedExec.startsWith("yarn"))
44611
44640
  return "yarn";
44612
- if (execPath.includes("pnpm"))
44641
+ if (/\/pnpm([/.]|$)/.test(normalizedExec) || normalizedExec.startsWith("pnpm"))
44613
44642
  return "pnpm";
44614
- if (execPath.includes("npm"))
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.4",
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
- throw new CliUpdateError(`Permission denied. Try: sudo ${updateCmd}
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("Try running: npm install -g claudekit-cli@latest");
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 = realpathSync(targetPath);
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}${sep}`) && normalizedPath !== 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}${sep}`)) {
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 sep2 = defaultPlatform === "win32" ? path11.win32.sep : path11.posix.sep;
75172
- minimatch.sep = sep2;
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 sep3 } from "node:path";
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 + sep3) && resolvedPath !== 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 + sep3) && resolvedReal !== 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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudekit-cli",
3
- "version": "3.34.1-dev.4",
3
+ "version": "3.34.1-dev.5",
4
4
  "description": "CLI tool for bootstrapping and updating ClaudeKit projects",
5
5
  "type": "module",
6
6
  "repository": {