claudekit-cli 4.3.1-dev.17 → 4.3.1-dev.18
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 +545 -469
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -12622,6 +12622,217 @@ var init_converters = __esm(() => {
|
|
|
12622
12622
|
init_skill_md();
|
|
12623
12623
|
});
|
|
12624
12624
|
|
|
12625
|
+
// src/shared/path-resolver.ts
|
|
12626
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
12627
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
|
|
12628
|
+
import { homedir as homedir3, platform as platform2 } from "node:os";
|
|
12629
|
+
import { join as join2, normalize, resolve } from "node:path";
|
|
12630
|
+
function getEnvVar(name) {
|
|
12631
|
+
const val = process.env[name];
|
|
12632
|
+
if (!val || val.trim() === "")
|
|
12633
|
+
return;
|
|
12634
|
+
if (val.includes("..")) {
|
|
12635
|
+
console.warn(`Environment variable ${name} contains path traversal: ${val}`);
|
|
12636
|
+
return;
|
|
12637
|
+
}
|
|
12638
|
+
return val;
|
|
12639
|
+
}
|
|
12640
|
+
function isWSL() {
|
|
12641
|
+
try {
|
|
12642
|
+
return process.platform === "linux" && existsSync2("/proc/version") && readFileSync2("/proc/version", "utf8").toLowerCase().includes("microsoft");
|
|
12643
|
+
} catch {
|
|
12644
|
+
return false;
|
|
12645
|
+
}
|
|
12646
|
+
}
|
|
12647
|
+
function normalizeWSLPath(p) {
|
|
12648
|
+
if (!isWSL())
|
|
12649
|
+
return p;
|
|
12650
|
+
const windowsMatch = p.match(/^([A-Za-z]):(.*)/);
|
|
12651
|
+
if (windowsMatch) {
|
|
12652
|
+
const drive = windowsMatch[1].toLowerCase();
|
|
12653
|
+
const rest = windowsMatch[2].replace(/\\/g, "/");
|
|
12654
|
+
return `/mnt/${drive}${rest}`;
|
|
12655
|
+
}
|
|
12656
|
+
return p;
|
|
12657
|
+
}
|
|
12658
|
+
|
|
12659
|
+
class PathResolver {
|
|
12660
|
+
static getTestHomeDir() {
|
|
12661
|
+
return process.env.CK_TEST_HOME;
|
|
12662
|
+
}
|
|
12663
|
+
static isValidComponentName(name) {
|
|
12664
|
+
if (!name || typeof name !== "string") {
|
|
12665
|
+
return false;
|
|
12666
|
+
}
|
|
12667
|
+
const dangerousPatterns = [
|
|
12668
|
+
"..",
|
|
12669
|
+
"~"
|
|
12670
|
+
];
|
|
12671
|
+
for (const pattern of dangerousPatterns) {
|
|
12672
|
+
if (name.includes(pattern)) {
|
|
12673
|
+
return false;
|
|
12674
|
+
}
|
|
12675
|
+
}
|
|
12676
|
+
const normalized = normalize(name);
|
|
12677
|
+
for (const pattern of dangerousPatterns) {
|
|
12678
|
+
if (normalized.includes(pattern)) {
|
|
12679
|
+
return false;
|
|
12680
|
+
}
|
|
12681
|
+
}
|
|
12682
|
+
if (name.startsWith("/") || normalized.startsWith("/") || /^[a-zA-Z]:/.test(name) || name.startsWith("\\\\") || normalized.startsWith("\\\\")) {
|
|
12683
|
+
return false;
|
|
12684
|
+
}
|
|
12685
|
+
return true;
|
|
12686
|
+
}
|
|
12687
|
+
static getConfigDir(global2 = false) {
|
|
12688
|
+
const testHome = PathResolver.getTestHomeDir();
|
|
12689
|
+
if (testHome) {
|
|
12690
|
+
return global2 ? join2(testHome, ".config", "claude") : join2(testHome, ".claudekit");
|
|
12691
|
+
}
|
|
12692
|
+
if (!global2) {
|
|
12693
|
+
return join2(homedir3(), ".claudekit");
|
|
12694
|
+
}
|
|
12695
|
+
const os = platform2();
|
|
12696
|
+
if (os === "win32") {
|
|
12697
|
+
const localAppData = getEnvVar("LOCALAPPDATA") ?? join2(homedir3(), "AppData", "Local");
|
|
12698
|
+
return join2(localAppData, "claude");
|
|
12699
|
+
}
|
|
12700
|
+
const xdgConfigHome = getEnvVar("XDG_CONFIG_HOME");
|
|
12701
|
+
if (xdgConfigHome) {
|
|
12702
|
+
return join2(xdgConfigHome, "claude");
|
|
12703
|
+
}
|
|
12704
|
+
return join2(homedir3(), ".config", "claude");
|
|
12705
|
+
}
|
|
12706
|
+
static getConfigFile(global2 = false) {
|
|
12707
|
+
return join2(PathResolver.getConfigDir(global2), "config.json");
|
|
12708
|
+
}
|
|
12709
|
+
static getCacheDir(global2 = false) {
|
|
12710
|
+
const testHome = PathResolver.getTestHomeDir();
|
|
12711
|
+
if (testHome) {
|
|
12712
|
+
return global2 ? join2(testHome, ".cache", "claude") : join2(testHome, ".claudekit", "cache");
|
|
12713
|
+
}
|
|
12714
|
+
if (!global2) {
|
|
12715
|
+
return join2(homedir3(), ".claudekit", "cache");
|
|
12716
|
+
}
|
|
12717
|
+
const os = platform2();
|
|
12718
|
+
if (os === "win32") {
|
|
12719
|
+
const localAppData = getEnvVar("LOCALAPPDATA") ?? join2(homedir3(), "AppData", "Local");
|
|
12720
|
+
return join2(localAppData, "claude", "cache");
|
|
12721
|
+
}
|
|
12722
|
+
const xdgCacheHome = getEnvVar("XDG_CACHE_HOME");
|
|
12723
|
+
if (xdgCacheHome) {
|
|
12724
|
+
return join2(xdgCacheHome, "claude");
|
|
12725
|
+
}
|
|
12726
|
+
return join2(homedir3(), ".cache", "claude");
|
|
12727
|
+
}
|
|
12728
|
+
static getGlobalKitDir() {
|
|
12729
|
+
const testHome = PathResolver.getTestHomeDir();
|
|
12730
|
+
if (testHome) {
|
|
12731
|
+
return join2(testHome, ".claude");
|
|
12732
|
+
}
|
|
12733
|
+
const claudeConfigDir = process.env.CLAUDE_CONFIG_DIR;
|
|
12734
|
+
if (claudeConfigDir) {
|
|
12735
|
+
return claudeConfigDir;
|
|
12736
|
+
}
|
|
12737
|
+
return join2(homedir3(), ".claude");
|
|
12738
|
+
}
|
|
12739
|
+
static getClaudeKitDir() {
|
|
12740
|
+
const testHome = PathResolver.getTestHomeDir();
|
|
12741
|
+
if (testHome) {
|
|
12742
|
+
return join2(testHome, ".claudekit");
|
|
12743
|
+
}
|
|
12744
|
+
return join2(homedir3(), ".claudekit");
|
|
12745
|
+
}
|
|
12746
|
+
static getProjectsRegistryPath() {
|
|
12747
|
+
return join2(PathResolver.getClaudeKitDir(), "projects.json");
|
|
12748
|
+
}
|
|
12749
|
+
static getOpenCodeDir(global2, baseDir) {
|
|
12750
|
+
const testHome = PathResolver.getTestHomeDir();
|
|
12751
|
+
if (testHome) {
|
|
12752
|
+
return global2 ? join2(testHome, ".config", "opencode") : join2(baseDir || testHome, ".opencode");
|
|
12753
|
+
}
|
|
12754
|
+
if (!global2) {
|
|
12755
|
+
return join2(baseDir || process.cwd(), ".opencode");
|
|
12756
|
+
}
|
|
12757
|
+
const xdgConfigHome = process.env.XDG_CONFIG_HOME;
|
|
12758
|
+
if (xdgConfigHome) {
|
|
12759
|
+
return join2(xdgConfigHome, "opencode");
|
|
12760
|
+
}
|
|
12761
|
+
return join2(homedir3(), ".config", "opencode");
|
|
12762
|
+
}
|
|
12763
|
+
static getPathPrefix(global2) {
|
|
12764
|
+
return global2 ? "" : ".claude";
|
|
12765
|
+
}
|
|
12766
|
+
static buildSkillsPath(baseDir, global2) {
|
|
12767
|
+
const prefix = PathResolver.getPathPrefix(global2);
|
|
12768
|
+
if (prefix) {
|
|
12769
|
+
return join2(baseDir, prefix, "skills");
|
|
12770
|
+
}
|
|
12771
|
+
return join2(baseDir, "skills");
|
|
12772
|
+
}
|
|
12773
|
+
static buildComponentPath(baseDir, component, global2) {
|
|
12774
|
+
if (!PathResolver.isValidComponentName(component)) {
|
|
12775
|
+
throw new Error(`Invalid component name: "${component}" contains path traversal patterns. Valid names are simple directory names like "agents", "commands", "rules", "skills", or "hooks".`);
|
|
12776
|
+
}
|
|
12777
|
+
const prefix = PathResolver.getPathPrefix(global2);
|
|
12778
|
+
if (prefix) {
|
|
12779
|
+
return join2(baseDir, prefix, component);
|
|
12780
|
+
}
|
|
12781
|
+
return join2(baseDir, component);
|
|
12782
|
+
}
|
|
12783
|
+
static getBackupDir(timestamp) {
|
|
12784
|
+
const testHome = PathResolver.getTestHomeDir();
|
|
12785
|
+
const baseDir = testHome ? join2(testHome, ".claudekit") : join2(homedir3(), ".claudekit");
|
|
12786
|
+
if (timestamp) {
|
|
12787
|
+
return join2(baseDir, "backups", timestamp);
|
|
12788
|
+
}
|
|
12789
|
+
const now = new Date;
|
|
12790
|
+
const dateStr = now.toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
12791
|
+
const ms = now.getMilliseconds().toString().padStart(3, "0");
|
|
12792
|
+
const random = Math.random().toString(36).slice(2, 6);
|
|
12793
|
+
const ts = `${dateStr}-${ms}-${random}`;
|
|
12794
|
+
return join2(baseDir, "backups", ts);
|
|
12795
|
+
}
|
|
12796
|
+
static normalizeWSLPath(p) {
|
|
12797
|
+
return normalizeWSLPath(p);
|
|
12798
|
+
}
|
|
12799
|
+
static isWSL() {
|
|
12800
|
+
return isWSL();
|
|
12801
|
+
}
|
|
12802
|
+
static isAtHomeDirectory(cwd2) {
|
|
12803
|
+
const currentDir = normalize(cwd2 || process.cwd());
|
|
12804
|
+
const homeDir = normalize(homedir3());
|
|
12805
|
+
return currentDir === homeDir;
|
|
12806
|
+
}
|
|
12807
|
+
static getLocalClaudeDir(baseDir) {
|
|
12808
|
+
const dir = baseDir || process.cwd();
|
|
12809
|
+
return join2(dir, ".claude");
|
|
12810
|
+
}
|
|
12811
|
+
static isLocalSameAsGlobal(cwd2) {
|
|
12812
|
+
const localPath = normalize(PathResolver.getLocalClaudeDir(cwd2));
|
|
12813
|
+
const globalPath = normalize(PathResolver.getGlobalKitDir());
|
|
12814
|
+
return localPath === globalPath;
|
|
12815
|
+
}
|
|
12816
|
+
static isGlobPattern(pattern) {
|
|
12817
|
+
return pattern.includes("*") || pattern.includes("?") || pattern.includes("{");
|
|
12818
|
+
}
|
|
12819
|
+
static computeProjectHash(projectRoot) {
|
|
12820
|
+
let normalized = resolve(projectRoot).replace(/[/\\]+$/, "");
|
|
12821
|
+
if (process.platform === "darwin" || process.platform === "win32") {
|
|
12822
|
+
normalized = normalized.toLowerCase();
|
|
12823
|
+
}
|
|
12824
|
+
return createHash3("sha256").update(normalized).digest("hex").slice(0, 12);
|
|
12825
|
+
}
|
|
12826
|
+
static getPlansRegistriesDir() {
|
|
12827
|
+
return join2(PathResolver.getGlobalKitDir(), "plans-registries");
|
|
12828
|
+
}
|
|
12829
|
+
static getPlansRegistryPath(projectRoot) {
|
|
12830
|
+
const hash = PathResolver.computeProjectHash(projectRoot);
|
|
12831
|
+
return join2(PathResolver.getPlansRegistriesDir(), `${hash}.json`);
|
|
12832
|
+
}
|
|
12833
|
+
}
|
|
12834
|
+
var init_path_resolver = () => {};
|
|
12835
|
+
|
|
12625
12836
|
// src/commands/portable/reconcile-types.ts
|
|
12626
12837
|
function normalizeChecksum(checksum) {
|
|
12627
12838
|
if (!checksum)
|
|
@@ -12686,18 +12897,16 @@ function providerConfigAppliesToType(config, type) {
|
|
|
12686
12897
|
var UNKNOWN_CHECKSUM = "unknown";
|
|
12687
12898
|
|
|
12688
12899
|
// src/commands/portable/portable-registry.ts
|
|
12689
|
-
import { existsSync as
|
|
12900
|
+
import { existsSync as existsSync3 } from "node:fs";
|
|
12690
12901
|
import { mkdir, readFile as readFile2, rename, unlink, writeFile } from "node:fs/promises";
|
|
12691
|
-
import {
|
|
12692
|
-
import { dirname, join as join2, resolve } from "node:path";
|
|
12902
|
+
import { dirname, join as join3, resolve as resolve2 } from "node:path";
|
|
12693
12903
|
function getPortableRegistryPaths() {
|
|
12694
|
-
const
|
|
12695
|
-
const claudekitDir = join2(home2, ".claudekit");
|
|
12904
|
+
const claudekitDir = PathResolver.getConfigDir(false);
|
|
12696
12905
|
return {
|
|
12697
|
-
registryPath:
|
|
12698
|
-
registryLockPath:
|
|
12699
|
-
legacyRegistryPath:
|
|
12700
|
-
migrationLockPath:
|
|
12906
|
+
registryPath: join3(claudekitDir, "portable-registry.json"),
|
|
12907
|
+
registryLockPath: join3(claudekitDir, "portable-registry.lock"),
|
|
12908
|
+
legacyRegistryPath: join3(claudekitDir, "skill-registry.json"),
|
|
12909
|
+
migrationLockPath: join3(claudekitDir, ".migration.lock")
|
|
12701
12910
|
};
|
|
12702
12911
|
}
|
|
12703
12912
|
function isErrnoCode(error, code) {
|
|
@@ -12721,12 +12930,12 @@ function getCliVersion() {
|
|
|
12721
12930
|
if (process.env.npm_package_version) {
|
|
12722
12931
|
return process.env.npm_package_version;
|
|
12723
12932
|
}
|
|
12724
|
-
const { readFileSync:
|
|
12933
|
+
const { readFileSync: readFileSync3 } = __require("node:fs");
|
|
12725
12934
|
const { dirname: dn, join: jp } = __require("node:path");
|
|
12726
12935
|
const { fileURLToPath } = __require("node:url");
|
|
12727
12936
|
const __dirname2 = dn(fileURLToPath(import.meta.url));
|
|
12728
12937
|
const pkgPath = jp(__dirname2, "../../../package.json");
|
|
12729
|
-
const pkg = JSON.parse(
|
|
12938
|
+
const pkg = JSON.parse(readFileSync3(pkgPath, "utf-8"));
|
|
12730
12939
|
return pkg.version || "unknown";
|
|
12731
12940
|
} catch {
|
|
12732
12941
|
return "unknown";
|
|
@@ -12762,7 +12971,7 @@ async function migrateRegistryV2ToV3(v2Registry) {
|
|
|
12762
12971
|
for (const item of v2Registry.installations) {
|
|
12763
12972
|
let targetChecksum = UNKNOWN_CHECKSUM;
|
|
12764
12973
|
try {
|
|
12765
|
-
if (
|
|
12974
|
+
if (existsSync3(item.path)) {
|
|
12766
12975
|
targetChecksum = await computeFileChecksum(item.path);
|
|
12767
12976
|
}
|
|
12768
12977
|
} catch (error) {
|
|
@@ -12819,7 +13028,7 @@ async function repairStaleRegistryV3(registry) {
|
|
|
12819
13028
|
const installations = [];
|
|
12820
13029
|
for (const item of registry.installations) {
|
|
12821
13030
|
let targetChecksum = normalizeChecksum(getStringField(item, "targetChecksum")) || UNKNOWN_CHECKSUM;
|
|
12822
|
-
if (targetChecksum === UNKNOWN_CHECKSUM &&
|
|
13031
|
+
if (targetChecksum === UNKNOWN_CHECKSUM && existsSync3(item.path)) {
|
|
12823
13032
|
try {
|
|
12824
13033
|
targetChecksum = await computeFileChecksum(item.path);
|
|
12825
13034
|
} catch {
|
|
@@ -12906,7 +13115,7 @@ async function isMigrationLocked() {
|
|
|
12906
13115
|
async function createMigrationLock() {
|
|
12907
13116
|
const { migrationLockPath } = getPortableRegistryPaths();
|
|
12908
13117
|
const lockDir = dirname(migrationLockPath);
|
|
12909
|
-
if (!
|
|
13118
|
+
if (!existsSync3(lockDir)) {
|
|
12910
13119
|
await mkdir(lockDir, { recursive: true });
|
|
12911
13120
|
}
|
|
12912
13121
|
await writeFile(migrationLockPath, Date.now().toString(), "utf-8");
|
|
@@ -12994,7 +13203,7 @@ async function readPortableRegistryWithinRegistryLock() {
|
|
|
12994
13203
|
async function writePortableRegistry(registry) {
|
|
12995
13204
|
const { registryPath } = getPortableRegistryPaths();
|
|
12996
13205
|
const dir = dirname(registryPath);
|
|
12997
|
-
if (!
|
|
13206
|
+
if (!existsSync3(dir)) {
|
|
12998
13207
|
await mkdir(dir, { recursive: true });
|
|
12999
13208
|
}
|
|
13000
13209
|
const normalizedRegistry = normalizePortableRegistryChecksums(registry);
|
|
@@ -13012,10 +13221,10 @@ async function writePortableRegistry(registry) {
|
|
|
13012
13221
|
async function withRegistryLock(operation) {
|
|
13013
13222
|
const { registryLockPath } = getPortableRegistryPaths();
|
|
13014
13223
|
const lockDir = dirname(registryLockPath);
|
|
13015
|
-
if (!
|
|
13224
|
+
if (!existsSync3(lockDir)) {
|
|
13016
13225
|
await mkdir(lockDir, { recursive: true });
|
|
13017
13226
|
}
|
|
13018
|
-
if (!
|
|
13227
|
+
if (!existsSync3(registryLockPath)) {
|
|
13019
13228
|
await writeFile(registryLockPath, "", "utf-8");
|
|
13020
13229
|
}
|
|
13021
13230
|
const release = await import_proper_lockfile.default.lock(registryLockPath, {
|
|
@@ -13057,7 +13266,7 @@ async function addPortableInstallation(item, type, provider, global2, path2, sou
|
|
|
13057
13266
|
async function removePortableInstallation(item, type, provider, global2, options2) {
|
|
13058
13267
|
return withRegistryLock(async () => {
|
|
13059
13268
|
const registry = await readPortableRegistryWithinRegistryLock();
|
|
13060
|
-
const index = registry.installations.findIndex((i) => i.item === item && i.type === type && i.provider === provider && i.global === global2 && (!options2?.path ||
|
|
13269
|
+
const index = registry.installations.findIndex((i) => i.item === item && i.type === type && i.provider === provider && i.global === global2 && (!options2?.path || resolve2(i.path) === resolve2(options2.path)));
|
|
13061
13270
|
if (index === -1)
|
|
13062
13271
|
return null;
|
|
13063
13272
|
const [removed] = registry.installations.splice(index, 1);
|
|
@@ -13107,7 +13316,7 @@ async function syncPortableRegistry() {
|
|
|
13107
13316
|
const registry = await readPortableRegistryWithinRegistryLock();
|
|
13108
13317
|
const removed = [];
|
|
13109
13318
|
registry.installations = registry.installations.filter((i) => {
|
|
13110
|
-
if (!
|
|
13319
|
+
if (!existsSync3(i.path)) {
|
|
13111
13320
|
removed.push(i);
|
|
13112
13321
|
return false;
|
|
13113
13322
|
}
|
|
@@ -13123,6 +13332,7 @@ var import_proper_lockfile, PortableInstallationSchema, PortableRegistrySchema,
|
|
|
13123
13332
|
var init_portable_registry = __esm(() => {
|
|
13124
13333
|
init_zod();
|
|
13125
13334
|
init_logger();
|
|
13335
|
+
init_path_resolver();
|
|
13126
13336
|
init_checksum_utils();
|
|
13127
13337
|
import_proper_lockfile = __toESM(require_proper_lockfile(), 1);
|
|
13128
13338
|
PortableInstallationSchema = exports_external.object({
|
|
@@ -13181,10 +13391,10 @@ var init_portable_registry = __esm(() => {
|
|
|
13181
13391
|
});
|
|
13182
13392
|
|
|
13183
13393
|
// src/commands/portable/codex-toml-installer.ts
|
|
13184
|
-
import { existsSync as
|
|
13394
|
+
import { existsSync as existsSync4 } from "node:fs";
|
|
13185
13395
|
import { mkdir as mkdir2, readFile as readFile3, realpath, unlink as unlink2, writeFile as writeFile2 } from "node:fs/promises";
|
|
13186
13396
|
import { homedir as homedir4 } from "node:os";
|
|
13187
|
-
import { basename, dirname as dirname2, isAbsolute, join as
|
|
13397
|
+
import { basename, dirname as dirname2, isAbsolute, join as join4, relative, resolve as resolve3 } from "node:path";
|
|
13188
13398
|
function resolveCodexTomlRegistryDeps(deps) {
|
|
13189
13399
|
return {
|
|
13190
13400
|
...defaultCodexTomlRegistryDeps,
|
|
@@ -13193,7 +13403,7 @@ function resolveCodexTomlRegistryDeps(deps) {
|
|
|
13193
13403
|
}
|
|
13194
13404
|
async function ensureDir(filePath) {
|
|
13195
13405
|
const dir = dirname2(filePath);
|
|
13196
|
-
if (!
|
|
13406
|
+
if (!existsSync4(dir)) {
|
|
13197
13407
|
await mkdir2(dir, { recursive: true });
|
|
13198
13408
|
}
|
|
13199
13409
|
}
|
|
@@ -13201,7 +13411,7 @@ function isErrnoCode2(error, code) {
|
|
|
13201
13411
|
return typeof error === "object" && error !== null && "code" in error && error.code === code;
|
|
13202
13412
|
}
|
|
13203
13413
|
function normalizePathForComparison(path2) {
|
|
13204
|
-
const normalized =
|
|
13414
|
+
const normalized = resolve3(path2);
|
|
13205
13415
|
return process.platform === "win32" ? normalized.toLowerCase() : normalized;
|
|
13206
13416
|
}
|
|
13207
13417
|
function isPathWithinBoundary(targetPath, boundaryPath) {
|
|
@@ -13217,7 +13427,7 @@ async function resolveRealPathSafe(path2) {
|
|
|
13217
13427
|
try {
|
|
13218
13428
|
return await realpath(path2);
|
|
13219
13429
|
} catch {
|
|
13220
|
-
return
|
|
13430
|
+
return resolve3(path2);
|
|
13221
13431
|
}
|
|
13222
13432
|
}
|
|
13223
13433
|
async function isCanonicalPathWithinBoundary(targetPath, boundaryPath) {
|
|
@@ -13391,10 +13601,10 @@ function mergeConfigTomlWithDiagnostics(existing, managedBlock) {
|
|
|
13391
13601
|
};
|
|
13392
13602
|
}
|
|
13393
13603
|
function getCodexLockPath(configTomlPath) {
|
|
13394
|
-
return
|
|
13604
|
+
return join4(dirname2(configTomlPath), `.${basename(configTomlPath)}.ck-codex.lock`);
|
|
13395
13605
|
}
|
|
13396
13606
|
async function withCodexTargetLock(configTomlPath, operation) {
|
|
13397
|
-
const resolvedTargetPath =
|
|
13607
|
+
const resolvedTargetPath = resolve3(configTomlPath);
|
|
13398
13608
|
await ensureDir(resolvedTargetPath);
|
|
13399
13609
|
const release = await import_proper_lockfile2.default.lock(dirname2(resolvedTargetPath), {
|
|
13400
13610
|
realpath: false,
|
|
@@ -13473,8 +13683,8 @@ async function installCodexToml(items, provider, portableType, options2, deps) {
|
|
|
13473
13683
|
};
|
|
13474
13684
|
}
|
|
13475
13685
|
const boundary = options2.global ? homedir4() : process.cwd();
|
|
13476
|
-
const agentsDir =
|
|
13477
|
-
const configTomlPath =
|
|
13686
|
+
const agentsDir = resolve3(basePath);
|
|
13687
|
+
const configTomlPath = join4(dirname2(agentsDir), "config.toml");
|
|
13478
13688
|
if (!isPathWithinBoundary(agentsDir, boundary)) {
|
|
13479
13689
|
return {
|
|
13480
13690
|
provider,
|
|
@@ -13568,7 +13778,7 @@ async function installCodexToml(items, provider, portableType, options2, deps) {
|
|
|
13568
13778
|
continue;
|
|
13569
13779
|
}
|
|
13570
13780
|
seenSlugOwners.set(slug, item.name);
|
|
13571
|
-
const agentTomlPath =
|
|
13781
|
+
const agentTomlPath = join4(agentsDir, `${slug}.toml`);
|
|
13572
13782
|
if (process.platform === "win32" && agentTomlPath.length > MAX_WINDOWS_PATH_LENGTH) {
|
|
13573
13783
|
allWarnings.push(`Skipped ${item.name}: target path exceeds ${MAX_WINDOWS_PATH_LENGTH} characters on Windows`);
|
|
13574
13784
|
continue;
|
|
@@ -13695,9 +13905,9 @@ async function cleanupStaleCodexConfigEntries(options2) {
|
|
|
13695
13905
|
const basePath = options2.global ? pathConfig.globalPath : pathConfig.projectPath;
|
|
13696
13906
|
if (!basePath)
|
|
13697
13907
|
return [];
|
|
13698
|
-
const agentsDir =
|
|
13699
|
-
const configTomlPath =
|
|
13700
|
-
if (!
|
|
13908
|
+
const agentsDir = resolve3(basePath);
|
|
13909
|
+
const configTomlPath = join4(dirname2(agentsDir), "config.toml");
|
|
13910
|
+
if (!existsSync4(configTomlPath))
|
|
13701
13911
|
return [];
|
|
13702
13912
|
try {
|
|
13703
13913
|
return await withCodexTargetLock(configTomlPath, async () => {
|
|
@@ -13713,8 +13923,8 @@ async function cleanupStaleCodexConfigEntries(options2) {
|
|
|
13713
13923
|
if (managedEntries.size > 0) {
|
|
13714
13924
|
const validEntries = new Map;
|
|
13715
13925
|
for (const [slug, entry] of managedEntries) {
|
|
13716
|
-
const tomlPath =
|
|
13717
|
-
if (
|
|
13926
|
+
const tomlPath = join4(agentsDir, `${slug}.toml`);
|
|
13927
|
+
if (existsSync4(tomlPath)) {
|
|
13718
13928
|
validEntries.set(slug, entry);
|
|
13719
13929
|
} else {
|
|
13720
13930
|
allStaleSlugs.push(slug);
|
|
@@ -13744,10 +13954,10 @@ async function cleanupStaleCodexConfigEntries(options2) {
|
|
|
13744
13954
|
const unmanagedSlugs = extractUnmanagedAgentSlugs(analysis.unmanagedContent);
|
|
13745
13955
|
const legacyStaleSlugs = [];
|
|
13746
13956
|
for (const slug of unmanagedSlugs) {
|
|
13747
|
-
const tomlPath =
|
|
13957
|
+
const tomlPath = join4(agentsDir, `${slug}.toml`);
|
|
13748
13958
|
if (!isPathWithinBoundary(tomlPath, agentsDir))
|
|
13749
13959
|
continue;
|
|
13750
|
-
if (!
|
|
13960
|
+
if (!existsSync4(tomlPath)) {
|
|
13751
13961
|
legacyStaleSlugs.push(slug);
|
|
13752
13962
|
}
|
|
13753
13963
|
}
|
|
@@ -13992,13 +14202,13 @@ var init_merge_single_sections = __esm(() => {
|
|
|
13992
14202
|
});
|
|
13993
14203
|
|
|
13994
14204
|
// src/commands/portable/portable-installer.ts
|
|
13995
|
-
import { existsSync as
|
|
14205
|
+
import { existsSync as existsSync5 } from "node:fs";
|
|
13996
14206
|
import { lstat, mkdir as mkdir3, readFile as readFile4, realpath as realpath2, unlink as unlink3, writeFile as writeFile3 } from "node:fs/promises";
|
|
13997
14207
|
import { homedir as homedir5 } from "node:os";
|
|
13998
|
-
import { basename as basename2, dirname as dirname3, join as
|
|
14208
|
+
import { basename as basename2, dirname as dirname3, join as join5, relative as relative2, resolve as resolve4, sep } from "node:path";
|
|
13999
14209
|
function isSamePath(path1, path2) {
|
|
14000
14210
|
try {
|
|
14001
|
-
return
|
|
14211
|
+
return resolve4(path1) === resolve4(path2);
|
|
14002
14212
|
} catch {
|
|
14003
14213
|
return false;
|
|
14004
14214
|
}
|
|
@@ -14027,8 +14237,8 @@ function isWindowsAbsolutePath(path2) {
|
|
|
14027
14237
|
return /^[a-zA-Z]:[\\/]/.test(path2) || /^\\\\/.test(path2);
|
|
14028
14238
|
}
|
|
14029
14239
|
function isPathWithinBoundary2(targetPath, boundaryPath) {
|
|
14030
|
-
const resolvedTarget =
|
|
14031
|
-
const resolvedBoundary =
|
|
14240
|
+
const resolvedTarget = resolve4(targetPath);
|
|
14241
|
+
const resolvedBoundary = resolve4(boundaryPath);
|
|
14032
14242
|
return resolvedTarget === resolvedBoundary || resolvedTarget.startsWith(`${resolvedBoundary}${sep}`);
|
|
14033
14243
|
}
|
|
14034
14244
|
function validateStrategyTargetPath(targetPath, options2) {
|
|
@@ -14054,16 +14264,16 @@ function resolvePerFileOutputFilename(filename, pathConfig) {
|
|
|
14054
14264
|
return `${nameWithoutExt.replace(/\//g, "-")}${ext}`;
|
|
14055
14265
|
}
|
|
14056
14266
|
function validateResolvedTargetWithinBase(targetPath, basePath, pathConfig) {
|
|
14057
|
-
const resolvedTarget =
|
|
14058
|
-
const resolvedBase = pathConfig.writeStrategy === "single-file" ?
|
|
14267
|
+
const resolvedTarget = resolve4(targetPath);
|
|
14268
|
+
const resolvedBase = pathConfig.writeStrategy === "single-file" ? resolve4(dirname3(basePath)) : resolve4(basePath);
|
|
14059
14269
|
if (!resolvedTarget.startsWith(`${resolvedBase}${sep}`) && resolvedTarget !== resolvedBase) {
|
|
14060
14270
|
return "Unsafe path: target escapes base directory";
|
|
14061
14271
|
}
|
|
14062
14272
|
return null;
|
|
14063
14273
|
}
|
|
14064
14274
|
async function validateNoSymlinkComponents(targetPath, boundaryPath) {
|
|
14065
|
-
const resolvedTarget =
|
|
14066
|
-
const resolvedBoundary =
|
|
14275
|
+
const resolvedTarget = resolve4(targetPath);
|
|
14276
|
+
const resolvedBoundary = resolve4(boundaryPath);
|
|
14067
14277
|
if (!isPathWithinBoundary2(resolvedTarget, resolvedBoundary)) {
|
|
14068
14278
|
return `Unsafe path: target escapes ${resolvedBoundary}`;
|
|
14069
14279
|
}
|
|
@@ -14071,7 +14281,7 @@ async function validateNoSymlinkComponents(targetPath, boundaryPath) {
|
|
|
14071
14281
|
let cursor = resolvedBoundary;
|
|
14072
14282
|
let deepestExisting = resolvedBoundary;
|
|
14073
14283
|
for (const segment of segments) {
|
|
14074
|
-
cursor =
|
|
14284
|
+
cursor = join5(cursor, segment);
|
|
14075
14285
|
try {
|
|
14076
14286
|
await lstat(cursor);
|
|
14077
14287
|
deepestExisting = cursor;
|
|
@@ -14181,13 +14391,13 @@ function buildPerFileCollisionSkips(items, provider, configDisplayName, basePath
|
|
|
14181
14391
|
continue;
|
|
14182
14392
|
}
|
|
14183
14393
|
const resolvedFilename = resolvePerFileOutputFilename(result.filename, pathConfig);
|
|
14184
|
-
const targetPath = pathConfig.writeStrategy === "single-file" ? basePath :
|
|
14394
|
+
const targetPath = pathConfig.writeStrategy === "single-file" ? basePath : join5(basePath, resolvedFilename);
|
|
14185
14395
|
if (validateResolvedTargetWithinBase(targetPath, basePath, pathConfig)) {
|
|
14186
14396
|
continue;
|
|
14187
14397
|
}
|
|
14188
|
-
const first = seenTargets.get(
|
|
14398
|
+
const first = seenTargets.get(resolve4(targetPath));
|
|
14189
14399
|
if (!first) {
|
|
14190
|
-
seenTargets.set(
|
|
14400
|
+
seenTargets.set(resolve4(targetPath), { itemName: item.name, targetPath });
|
|
14191
14401
|
continue;
|
|
14192
14402
|
}
|
|
14193
14403
|
skipped.set(index, {
|
|
@@ -14267,16 +14477,16 @@ async function installPerFileItems(items, provider, portableType, pathConfig, op
|
|
|
14267
14477
|
}
|
|
14268
14478
|
async function ensureDir2(filePath) {
|
|
14269
14479
|
const dir = dirname3(filePath);
|
|
14270
|
-
if (!
|
|
14480
|
+
if (!existsSync5(dir)) {
|
|
14271
14481
|
await mkdir3(dir, { recursive: true });
|
|
14272
14482
|
}
|
|
14273
14483
|
}
|
|
14274
14484
|
function getMergeTargetLockPath(targetPath) {
|
|
14275
14485
|
const lockName = `.${basename2(targetPath)}.ck-merge.lock`;
|
|
14276
|
-
return
|
|
14486
|
+
return join5(dirname3(targetPath), lockName);
|
|
14277
14487
|
}
|
|
14278
14488
|
async function withMergeTargetLock(targetPath, operation) {
|
|
14279
|
-
const resolvedTargetPath =
|
|
14489
|
+
const resolvedTargetPath = resolve4(targetPath);
|
|
14280
14490
|
await ensureDir2(resolvedTargetPath);
|
|
14281
14491
|
const release = await import_proper_lockfile3.default.lock(dirname3(resolvedTargetPath), {
|
|
14282
14492
|
realpath: false,
|
|
@@ -14393,7 +14603,7 @@ async function installPerFile(item, provider, portableType, options2, registryDe
|
|
|
14393
14603
|
};
|
|
14394
14604
|
}
|
|
14395
14605
|
const resolvedFilename = resolvePerFileOutputFilename(result.filename, pathConfig);
|
|
14396
|
-
targetPath = pathConfig.writeStrategy === "single-file" ? basePath :
|
|
14606
|
+
targetPath = pathConfig.writeStrategy === "single-file" ? basePath : join5(basePath, resolvedFilename);
|
|
14397
14607
|
const targetPathError = validateResolvedTargetWithinBase(targetPath, basePath, pathConfig);
|
|
14398
14608
|
if (targetPathError) {
|
|
14399
14609
|
return {
|
|
@@ -14520,7 +14730,7 @@ async function installMergeSingle(items, provider, portableType, options2, regis
|
|
|
14520
14730
|
error: "Config merge target accepts only one item per install"
|
|
14521
14731
|
};
|
|
14522
14732
|
}
|
|
14523
|
-
const alreadyExists =
|
|
14733
|
+
const alreadyExists = existsSync5(targetPath);
|
|
14524
14734
|
let existingSections = [];
|
|
14525
14735
|
let existingPreamble = "";
|
|
14526
14736
|
const allWarnings = [];
|
|
@@ -14723,7 +14933,7 @@ async function installYamlMerge(items, provider, portableType, options2, registr
|
|
|
14723
14933
|
}
|
|
14724
14934
|
let targetSnapshot = null;
|
|
14725
14935
|
try {
|
|
14726
|
-
const alreadyExists =
|
|
14936
|
+
const alreadyExists = existsSync5(targetPath);
|
|
14727
14937
|
let existingModes = new Map;
|
|
14728
14938
|
if (alreadyExists) {
|
|
14729
14939
|
try {
|
|
@@ -14899,7 +15109,7 @@ async function installJsonMerge(items, provider, portableType, options2, registr
|
|
|
14899
15109
|
}
|
|
14900
15110
|
modes.push(parsedMode.data);
|
|
14901
15111
|
}
|
|
14902
|
-
const modesPath =
|
|
15112
|
+
const modesPath = join5(basePath, "cline_custom_modes.json");
|
|
14903
15113
|
failurePath = modesPath;
|
|
14904
15114
|
const modesSymlinkError = await validateWritableTargetPath(modesPath, options2);
|
|
14905
15115
|
if (modesSymlinkError) {
|
|
@@ -14912,7 +15122,7 @@ async function installJsonMerge(items, provider, portableType, options2, registr
|
|
|
14912
15122
|
};
|
|
14913
15123
|
}
|
|
14914
15124
|
await ensureDir2(modesPath);
|
|
14915
|
-
const alreadyExists =
|
|
15125
|
+
const alreadyExists = existsSync5(modesPath);
|
|
14916
15126
|
if (alreadyExists) {
|
|
14917
15127
|
try {
|
|
14918
15128
|
const existingRaw = JSON.parse(await readFile4(modesPath, "utf-8"));
|
|
@@ -14948,7 +15158,7 @@ async function installJsonMerge(items, provider, portableType, options2, registr
|
|
|
14948
15158
|
await writeFile3(modesPath, modesJson, "utf-8");
|
|
14949
15159
|
const targetChecksum = computeContentChecksum(modesJson);
|
|
14950
15160
|
const ownedSections = modes.map((m2) => m2.slug);
|
|
14951
|
-
const rulesDir =
|
|
15161
|
+
const rulesDir = join5(dirname3(basePath), ".clinerules");
|
|
14952
15162
|
await mkdir3(rulesDir, { recursive: true });
|
|
14953
15163
|
const capturedRuleSnapshots = new Set;
|
|
14954
15164
|
for (const item of items) {
|
|
@@ -14970,10 +15180,10 @@ async function installJsonMerge(items, provider, portableType, options2, registr
|
|
|
14970
15180
|
}
|
|
14971
15181
|
}
|
|
14972
15182
|
const filename = `${namespacedName}.md`;
|
|
14973
|
-
const rulePath =
|
|
15183
|
+
const rulePath = join5(rulesDir, filename);
|
|
14974
15184
|
failurePath = rulePath;
|
|
14975
|
-
const resolvedRulePath =
|
|
14976
|
-
const resolvedRulesDir =
|
|
15185
|
+
const resolvedRulePath = resolve4(rulePath);
|
|
15186
|
+
const resolvedRulesDir = resolve4(rulesDir);
|
|
14977
15187
|
if (!resolvedRulePath.startsWith(resolvedRulesDir + sep) && resolvedRulePath !== resolvedRulesDir) {
|
|
14978
15188
|
throw new Error(`Unsafe path: rule target escapes rules directory (${rulePath})`);
|
|
14979
15189
|
}
|
|
@@ -16182,26 +16392,26 @@ var init_types3 = __esm(() => {
|
|
|
16182
16392
|
});
|
|
16183
16393
|
|
|
16184
16394
|
// src/shared/kit-layout.ts
|
|
16185
|
-
import { existsSync as
|
|
16186
|
-
import { join as
|
|
16395
|
+
import { existsSync as existsSync6, readFileSync as readFileSync3 } from "node:fs";
|
|
16396
|
+
import { join as join6 } from "node:path";
|
|
16187
16397
|
function uniquePaths(paths) {
|
|
16188
16398
|
return [...new Set(paths)];
|
|
16189
16399
|
}
|
|
16190
16400
|
function findFirstExistingPath(paths) {
|
|
16191
16401
|
for (const candidate of paths) {
|
|
16192
|
-
if (
|
|
16402
|
+
if (existsSync6(candidate)) {
|
|
16193
16403
|
return candidate;
|
|
16194
16404
|
}
|
|
16195
16405
|
}
|
|
16196
16406
|
return null;
|
|
16197
16407
|
}
|
|
16198
16408
|
function resolveKitLayout(projectRoot) {
|
|
16199
|
-
const packageJsonPath =
|
|
16200
|
-
if (!
|
|
16409
|
+
const packageJsonPath = join6(projectRoot, "package.json");
|
|
16410
|
+
if (!existsSync6(packageJsonPath)) {
|
|
16201
16411
|
return DEFAULT_KIT_LAYOUT;
|
|
16202
16412
|
}
|
|
16203
16413
|
try {
|
|
16204
|
-
const parsed = ClaudeKitPackageMetadataSchema.parse(JSON.parse(
|
|
16414
|
+
const parsed = ClaudeKitPackageMetadataSchema.parse(JSON.parse(readFileSync3(packageJsonPath, "utf8")));
|
|
16205
16415
|
return KitLayoutSchema.parse({
|
|
16206
16416
|
...DEFAULT_KIT_LAYOUT,
|
|
16207
16417
|
...parsed.claudekit ?? {}
|
|
@@ -16213,8 +16423,8 @@ function resolveKitLayout(projectRoot) {
|
|
|
16213
16423
|
function getProjectLayoutCandidates(projectRoot, subPath) {
|
|
16214
16424
|
const layout = resolveKitLayout(projectRoot);
|
|
16215
16425
|
return uniquePaths([
|
|
16216
|
-
|
|
16217
|
-
|
|
16426
|
+
join6(projectRoot, layout.sourceDir, subPath),
|
|
16427
|
+
join6(projectRoot, DEFAULT_KIT_LAYOUT.sourceDir, subPath)
|
|
16218
16428
|
]);
|
|
16219
16429
|
}
|
|
16220
16430
|
function findExistingProjectLayoutPath(projectRoot, subPath) {
|
|
@@ -16223,9 +16433,9 @@ function findExistingProjectLayoutPath(projectRoot, subPath) {
|
|
|
16223
16433
|
function getProjectConfigCandidates(projectRoot) {
|
|
16224
16434
|
const layout = resolveKitLayout(projectRoot);
|
|
16225
16435
|
return uniquePaths([
|
|
16226
|
-
|
|
16227
|
-
|
|
16228
|
-
|
|
16436
|
+
join6(projectRoot, "CLAUDE.md"),
|
|
16437
|
+
join6(projectRoot, layout.sourceDir, "CLAUDE.md"),
|
|
16438
|
+
join6(projectRoot, DEFAULT_KIT_LAYOUT.sourceDir, "CLAUDE.md")
|
|
16229
16439
|
]);
|
|
16230
16440
|
}
|
|
16231
16441
|
function findExistingProjectConfigPath(projectRoot) {
|
|
@@ -16339,9 +16549,9 @@ var init_frontmatter_parser = __esm(() => {
|
|
|
16339
16549
|
// src/commands/agents/agents-discovery.ts
|
|
16340
16550
|
import { readdir } from "node:fs/promises";
|
|
16341
16551
|
import { homedir as homedir6 } from "node:os";
|
|
16342
|
-
import { join as
|
|
16552
|
+
import { join as join7 } from "node:path";
|
|
16343
16553
|
function getAgentSourcePath(globalOnly = false) {
|
|
16344
|
-
const globalPath =
|
|
16554
|
+
const globalPath = join7(homedir6(), ".claude/agents");
|
|
16345
16555
|
if (globalOnly) {
|
|
16346
16556
|
return findFirstExistingPath([globalPath]);
|
|
16347
16557
|
}
|
|
@@ -16360,7 +16570,7 @@ async function discoverAgents(sourcePath) {
|
|
|
16360
16570
|
for (const entry of entries) {
|
|
16361
16571
|
if (!entry.isFile() || !entry.name.endsWith(".md"))
|
|
16362
16572
|
continue;
|
|
16363
|
-
const filePath =
|
|
16573
|
+
const filePath = join7(searchPath, entry.name);
|
|
16364
16574
|
try {
|
|
16365
16575
|
const { frontmatter, body } = await parseFrontmatterFile(filePath);
|
|
16366
16576
|
const name = entry.name.replace(/\.md$/, "");
|
|
@@ -19423,217 +19633,6 @@ var init_safe_spinner = __esm(() => {
|
|
|
19423
19633
|
};
|
|
19424
19634
|
});
|
|
19425
19635
|
|
|
19426
|
-
// src/shared/path-resolver.ts
|
|
19427
|
-
import { createHash as createHash3 } from "node:crypto";
|
|
19428
|
-
import { existsSync as existsSync8, readFileSync as readFileSync4 } from "node:fs";
|
|
19429
|
-
import { homedir as homedir9, platform as platform2 } from "node:os";
|
|
19430
|
-
import { join as join11, normalize, resolve as resolve4 } from "node:path";
|
|
19431
|
-
function getEnvVar(name) {
|
|
19432
|
-
const val = process.env[name];
|
|
19433
|
-
if (!val || val.trim() === "")
|
|
19434
|
-
return;
|
|
19435
|
-
if (val.includes("..")) {
|
|
19436
|
-
console.warn(`Environment variable ${name} contains path traversal: ${val}`);
|
|
19437
|
-
return;
|
|
19438
|
-
}
|
|
19439
|
-
return val;
|
|
19440
|
-
}
|
|
19441
|
-
function isWSL() {
|
|
19442
|
-
try {
|
|
19443
|
-
return process.platform === "linux" && existsSync8("/proc/version") && readFileSync4("/proc/version", "utf8").toLowerCase().includes("microsoft");
|
|
19444
|
-
} catch {
|
|
19445
|
-
return false;
|
|
19446
|
-
}
|
|
19447
|
-
}
|
|
19448
|
-
function normalizeWSLPath(p) {
|
|
19449
|
-
if (!isWSL())
|
|
19450
|
-
return p;
|
|
19451
|
-
const windowsMatch = p.match(/^([A-Za-z]):(.*)/);
|
|
19452
|
-
if (windowsMatch) {
|
|
19453
|
-
const drive = windowsMatch[1].toLowerCase();
|
|
19454
|
-
const rest = windowsMatch[2].replace(/\\/g, "/");
|
|
19455
|
-
return `/mnt/${drive}${rest}`;
|
|
19456
|
-
}
|
|
19457
|
-
return p;
|
|
19458
|
-
}
|
|
19459
|
-
|
|
19460
|
-
class PathResolver {
|
|
19461
|
-
static getTestHomeDir() {
|
|
19462
|
-
return process.env.CK_TEST_HOME;
|
|
19463
|
-
}
|
|
19464
|
-
static isValidComponentName(name) {
|
|
19465
|
-
if (!name || typeof name !== "string") {
|
|
19466
|
-
return false;
|
|
19467
|
-
}
|
|
19468
|
-
const dangerousPatterns = [
|
|
19469
|
-
"..",
|
|
19470
|
-
"~"
|
|
19471
|
-
];
|
|
19472
|
-
for (const pattern of dangerousPatterns) {
|
|
19473
|
-
if (name.includes(pattern)) {
|
|
19474
|
-
return false;
|
|
19475
|
-
}
|
|
19476
|
-
}
|
|
19477
|
-
const normalized = normalize(name);
|
|
19478
|
-
for (const pattern of dangerousPatterns) {
|
|
19479
|
-
if (normalized.includes(pattern)) {
|
|
19480
|
-
return false;
|
|
19481
|
-
}
|
|
19482
|
-
}
|
|
19483
|
-
if (name.startsWith("/") || normalized.startsWith("/") || /^[a-zA-Z]:/.test(name) || name.startsWith("\\\\") || normalized.startsWith("\\\\")) {
|
|
19484
|
-
return false;
|
|
19485
|
-
}
|
|
19486
|
-
return true;
|
|
19487
|
-
}
|
|
19488
|
-
static getConfigDir(global3 = false) {
|
|
19489
|
-
const testHome = PathResolver.getTestHomeDir();
|
|
19490
|
-
if (testHome) {
|
|
19491
|
-
return global3 ? join11(testHome, ".config", "claude") : join11(testHome, ".claudekit");
|
|
19492
|
-
}
|
|
19493
|
-
if (!global3) {
|
|
19494
|
-
return join11(homedir9(), ".claudekit");
|
|
19495
|
-
}
|
|
19496
|
-
const os2 = platform2();
|
|
19497
|
-
if (os2 === "win32") {
|
|
19498
|
-
const localAppData = getEnvVar("LOCALAPPDATA") ?? join11(homedir9(), "AppData", "Local");
|
|
19499
|
-
return join11(localAppData, "claude");
|
|
19500
|
-
}
|
|
19501
|
-
const xdgConfigHome = getEnvVar("XDG_CONFIG_HOME");
|
|
19502
|
-
if (xdgConfigHome) {
|
|
19503
|
-
return join11(xdgConfigHome, "claude");
|
|
19504
|
-
}
|
|
19505
|
-
return join11(homedir9(), ".config", "claude");
|
|
19506
|
-
}
|
|
19507
|
-
static getConfigFile(global3 = false) {
|
|
19508
|
-
return join11(PathResolver.getConfigDir(global3), "config.json");
|
|
19509
|
-
}
|
|
19510
|
-
static getCacheDir(global3 = false) {
|
|
19511
|
-
const testHome = PathResolver.getTestHomeDir();
|
|
19512
|
-
if (testHome) {
|
|
19513
|
-
return global3 ? join11(testHome, ".cache", "claude") : join11(testHome, ".claudekit", "cache");
|
|
19514
|
-
}
|
|
19515
|
-
if (!global3) {
|
|
19516
|
-
return join11(homedir9(), ".claudekit", "cache");
|
|
19517
|
-
}
|
|
19518
|
-
const os2 = platform2();
|
|
19519
|
-
if (os2 === "win32") {
|
|
19520
|
-
const localAppData = getEnvVar("LOCALAPPDATA") ?? join11(homedir9(), "AppData", "Local");
|
|
19521
|
-
return join11(localAppData, "claude", "cache");
|
|
19522
|
-
}
|
|
19523
|
-
const xdgCacheHome = getEnvVar("XDG_CACHE_HOME");
|
|
19524
|
-
if (xdgCacheHome) {
|
|
19525
|
-
return join11(xdgCacheHome, "claude");
|
|
19526
|
-
}
|
|
19527
|
-
return join11(homedir9(), ".cache", "claude");
|
|
19528
|
-
}
|
|
19529
|
-
static getGlobalKitDir() {
|
|
19530
|
-
const testHome = PathResolver.getTestHomeDir();
|
|
19531
|
-
if (testHome) {
|
|
19532
|
-
return join11(testHome, ".claude");
|
|
19533
|
-
}
|
|
19534
|
-
const claudeConfigDir = process.env.CLAUDE_CONFIG_DIR;
|
|
19535
|
-
if (claudeConfigDir) {
|
|
19536
|
-
return claudeConfigDir;
|
|
19537
|
-
}
|
|
19538
|
-
return join11(homedir9(), ".claude");
|
|
19539
|
-
}
|
|
19540
|
-
static getClaudeKitDir() {
|
|
19541
|
-
const testHome = PathResolver.getTestHomeDir();
|
|
19542
|
-
if (testHome) {
|
|
19543
|
-
return join11(testHome, ".claudekit");
|
|
19544
|
-
}
|
|
19545
|
-
return join11(homedir9(), ".claudekit");
|
|
19546
|
-
}
|
|
19547
|
-
static getProjectsRegistryPath() {
|
|
19548
|
-
return join11(PathResolver.getClaudeKitDir(), "projects.json");
|
|
19549
|
-
}
|
|
19550
|
-
static getOpenCodeDir(global3, baseDir) {
|
|
19551
|
-
const testHome = PathResolver.getTestHomeDir();
|
|
19552
|
-
if (testHome) {
|
|
19553
|
-
return global3 ? join11(testHome, ".config", "opencode") : join11(baseDir || testHome, ".opencode");
|
|
19554
|
-
}
|
|
19555
|
-
if (!global3) {
|
|
19556
|
-
return join11(baseDir || process.cwd(), ".opencode");
|
|
19557
|
-
}
|
|
19558
|
-
const xdgConfigHome = process.env.XDG_CONFIG_HOME;
|
|
19559
|
-
if (xdgConfigHome) {
|
|
19560
|
-
return join11(xdgConfigHome, "opencode");
|
|
19561
|
-
}
|
|
19562
|
-
return join11(homedir9(), ".config", "opencode");
|
|
19563
|
-
}
|
|
19564
|
-
static getPathPrefix(global3) {
|
|
19565
|
-
return global3 ? "" : ".claude";
|
|
19566
|
-
}
|
|
19567
|
-
static buildSkillsPath(baseDir, global3) {
|
|
19568
|
-
const prefix = PathResolver.getPathPrefix(global3);
|
|
19569
|
-
if (prefix) {
|
|
19570
|
-
return join11(baseDir, prefix, "skills");
|
|
19571
|
-
}
|
|
19572
|
-
return join11(baseDir, "skills");
|
|
19573
|
-
}
|
|
19574
|
-
static buildComponentPath(baseDir, component, global3) {
|
|
19575
|
-
if (!PathResolver.isValidComponentName(component)) {
|
|
19576
|
-
throw new Error(`Invalid component name: "${component}" contains path traversal patterns. Valid names are simple directory names like "agents", "commands", "rules", "skills", or "hooks".`);
|
|
19577
|
-
}
|
|
19578
|
-
const prefix = PathResolver.getPathPrefix(global3);
|
|
19579
|
-
if (prefix) {
|
|
19580
|
-
return join11(baseDir, prefix, component);
|
|
19581
|
-
}
|
|
19582
|
-
return join11(baseDir, component);
|
|
19583
|
-
}
|
|
19584
|
-
static getBackupDir(timestamp) {
|
|
19585
|
-
const testHome = PathResolver.getTestHomeDir();
|
|
19586
|
-
const baseDir = testHome ? join11(testHome, ".claudekit") : join11(homedir9(), ".claudekit");
|
|
19587
|
-
if (timestamp) {
|
|
19588
|
-
return join11(baseDir, "backups", timestamp);
|
|
19589
|
-
}
|
|
19590
|
-
const now = new Date;
|
|
19591
|
-
const dateStr = now.toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
19592
|
-
const ms = now.getMilliseconds().toString().padStart(3, "0");
|
|
19593
|
-
const random = Math.random().toString(36).slice(2, 6);
|
|
19594
|
-
const ts = `${dateStr}-${ms}-${random}`;
|
|
19595
|
-
return join11(baseDir, "backups", ts);
|
|
19596
|
-
}
|
|
19597
|
-
static normalizeWSLPath(p) {
|
|
19598
|
-
return normalizeWSLPath(p);
|
|
19599
|
-
}
|
|
19600
|
-
static isWSL() {
|
|
19601
|
-
return isWSL();
|
|
19602
|
-
}
|
|
19603
|
-
static isAtHomeDirectory(cwd2) {
|
|
19604
|
-
const currentDir = normalize(cwd2 || process.cwd());
|
|
19605
|
-
const homeDir = normalize(homedir9());
|
|
19606
|
-
return currentDir === homeDir;
|
|
19607
|
-
}
|
|
19608
|
-
static getLocalClaudeDir(baseDir) {
|
|
19609
|
-
const dir = baseDir || process.cwd();
|
|
19610
|
-
return join11(dir, ".claude");
|
|
19611
|
-
}
|
|
19612
|
-
static isLocalSameAsGlobal(cwd2) {
|
|
19613
|
-
const localPath = normalize(PathResolver.getLocalClaudeDir(cwd2));
|
|
19614
|
-
const globalPath = normalize(PathResolver.getGlobalKitDir());
|
|
19615
|
-
return localPath === globalPath;
|
|
19616
|
-
}
|
|
19617
|
-
static isGlobPattern(pattern) {
|
|
19618
|
-
return pattern.includes("*") || pattern.includes("?") || pattern.includes("{");
|
|
19619
|
-
}
|
|
19620
|
-
static computeProjectHash(projectRoot) {
|
|
19621
|
-
let normalized = resolve4(projectRoot).replace(/[/\\]+$/, "");
|
|
19622
|
-
if (process.platform === "darwin" || process.platform === "win32") {
|
|
19623
|
-
normalized = normalized.toLowerCase();
|
|
19624
|
-
}
|
|
19625
|
-
return createHash3("sha256").update(normalized).digest("hex").slice(0, 12);
|
|
19626
|
-
}
|
|
19627
|
-
static getPlansRegistriesDir() {
|
|
19628
|
-
return join11(PathResolver.getGlobalKitDir(), "plans-registries");
|
|
19629
|
-
}
|
|
19630
|
-
static getPlansRegistryPath(projectRoot) {
|
|
19631
|
-
const hash = PathResolver.computeProjectHash(projectRoot);
|
|
19632
|
-
return join11(PathResolver.getPlansRegistriesDir(), `${hash}.json`);
|
|
19633
|
-
}
|
|
19634
|
-
}
|
|
19635
|
-
var init_path_resolver = () => {};
|
|
19636
|
-
|
|
19637
19636
|
// node_modules/universalify/index.js
|
|
19638
19637
|
var require_universalify = __commonJS((exports) => {
|
|
19639
19638
|
exports.fromCallback = function(fn) {
|
|
@@ -21022,10 +21021,10 @@ var init_safe_prompts = __esm(() => {
|
|
|
21022
21021
|
|
|
21023
21022
|
// src/commands/commands/commands-discovery.ts
|
|
21024
21023
|
import { readdir as readdir4 } from "node:fs/promises";
|
|
21025
|
-
import { homedir as
|
|
21024
|
+
import { homedir as homedir9 } from "node:os";
|
|
21026
21025
|
import { join as join16, relative as relative3 } from "node:path";
|
|
21027
21026
|
function getCommandSourcePath(globalOnly = false) {
|
|
21028
|
-
const globalPath = join16(
|
|
21027
|
+
const globalPath = join16(homedir9(), ".claude/commands");
|
|
21029
21028
|
if (globalOnly) {
|
|
21030
21029
|
return findFirstExistingPath([globalPath]);
|
|
21031
21030
|
}
|
|
@@ -45405,7 +45404,7 @@ __export(exports_ck_config_manager, {
|
|
|
45405
45404
|
});
|
|
45406
45405
|
import { existsSync as existsSync11 } from "node:fs";
|
|
45407
45406
|
import { mkdir as mkdir7, readFile as readFile8, writeFile as writeFile6 } from "node:fs/promises";
|
|
45408
|
-
import { homedir as
|
|
45407
|
+
import { homedir as homedir10 } from "node:os";
|
|
45409
45408
|
import { join as join19 } from "node:path";
|
|
45410
45409
|
function getNestedValue(obj, path4) {
|
|
45411
45410
|
if (!obj || typeof obj !== "object")
|
|
@@ -45480,7 +45479,7 @@ function valuesEqual(a3, b3) {
|
|
|
45480
45479
|
|
|
45481
45480
|
class CkConfigManager {
|
|
45482
45481
|
static getGlobalConfigDir() {
|
|
45483
|
-
return join19(
|
|
45482
|
+
return join19(homedir10(), ".claude");
|
|
45484
45483
|
}
|
|
45485
45484
|
static getGlobalConfigPath() {
|
|
45486
45485
|
return join19(CkConfigManager.getGlobalConfigDir(), CK_CONFIG_FILE);
|
|
@@ -45739,7 +45738,7 @@ function notFoundError(type, name, hint) {
|
|
|
45739
45738
|
}
|
|
45740
45739
|
|
|
45741
45740
|
// src/shared/command-normalizer.ts
|
|
45742
|
-
import { homedir as
|
|
45741
|
+
import { homedir as homedir11 } from "node:os";
|
|
45743
45742
|
import { join as join20 } from "node:path";
|
|
45744
45743
|
function escapeRegex(value) {
|
|
45745
45744
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -45779,7 +45778,7 @@ function resolveClaudePathArg(arg, root) {
|
|
|
45779
45778
|
const isWin2 = process.platform === "win32";
|
|
45780
45779
|
const cmp = (s) => isWin2 ? s.toLowerCase() : s;
|
|
45781
45780
|
const globalRoots = [
|
|
45782
|
-
`${
|
|
45781
|
+
`${homedir11().replace(/\\/g, "/").replace(/\/+$/, "")}/.claude/`,
|
|
45783
45782
|
`${PathResolver.getGlobalKitDir().replace(/\\/g, "/").replace(/\/+$/, "")}/`
|
|
45784
45783
|
];
|
|
45785
45784
|
const isUnderGlobal = globalRoots.some((g2) => cmp(absolutePath).startsWith(cmp(g2)));
|
|
@@ -45856,7 +45855,7 @@ function repairClaudeNodeCommandPath(cmd, root) {
|
|
|
45856
45855
|
const isWin2 = process.platform === "win32";
|
|
45857
45856
|
const cmp = (s) => isWin2 ? s.toLowerCase() : s;
|
|
45858
45857
|
const globalRoots = [
|
|
45859
|
-
`${
|
|
45858
|
+
`${homedir11().replace(/\\/g, "/").replace(/\/+$/, "")}/.claude/`,
|
|
45860
45859
|
`${PathResolver.getGlobalKitDir().replace(/\\/g, "/").replace(/\/+$/, "")}/`
|
|
45861
45860
|
];
|
|
45862
45861
|
const isUnderGlobal = globalRoots.some((g2) => cmp(normalizedAbsPath).startsWith(cmp(g2)));
|
|
@@ -45905,7 +45904,7 @@ function normalizeCommand(cmd) {
|
|
|
45905
45904
|
return "";
|
|
45906
45905
|
let normalized = cmd;
|
|
45907
45906
|
const globalKitDir = PathResolver.getGlobalKitDir().replace(/\\/g, "/").replace(/\/+$/, "");
|
|
45908
|
-
const defaultGlobalKitDir = join20(
|
|
45907
|
+
const defaultGlobalKitDir = join20(homedir11(), ".claude").replace(/\\/g, "/");
|
|
45909
45908
|
normalized = normalized.replace(/"/g, "");
|
|
45910
45909
|
normalized = normalized.replace(/~\//g, "$HOME/");
|
|
45911
45910
|
normalized = normalized.replace(/\$CLAUDE_PROJECT_DIR/g, "$HOME");
|
|
@@ -46103,11 +46102,15 @@ function mergeHookEntries(sourceEntries, destEntries, eventName, result, install
|
|
|
46103
46102
|
const isFullyDuplicated = commands.length > 0 && commands.every((cmd) => existingCommands.has(normalizeCommand(cmd)));
|
|
46104
46103
|
const duplicateCommands = commands.filter((cmd) => existingCommands.has(normalizeCommand(cmd)));
|
|
46105
46104
|
logDuplicates(duplicateCommands, eventName, result);
|
|
46106
|
-
const
|
|
46105
|
+
const newCommands = commands.filter((cmd) => !existingCommands.has(normalizeCommand(cmd)) && !wasCommandInstalled(cmd, installedHooks));
|
|
46106
|
+
const hasNonRemovedCommands = commands.length === 0 || newCommands.length > 0;
|
|
46107
46107
|
if (!isFullyDuplicated && hasNonRemovedCommands) {
|
|
46108
46108
|
let filteredEntry = entry;
|
|
46109
|
-
if ("hooks" in entry && entry.hooks &&
|
|
46110
|
-
const filteredHooks = entry.hooks.filter((h2) => !h2.command || !wasCommandInstalled(h2.command, installedHooks));
|
|
46109
|
+
if ("hooks" in entry && entry.hooks && commands.length > 0) {
|
|
46110
|
+
const filteredHooks = entry.hooks.filter((h2) => !h2.command || !existingCommands.has(normalizeCommand(h2.command)) && !wasCommandInstalled(h2.command, installedHooks));
|
|
46111
|
+
if (filteredHooks.length === 0) {
|
|
46112
|
+
continue;
|
|
46113
|
+
}
|
|
46111
46114
|
filteredEntry = { ...entry, hooks: filteredHooks };
|
|
46112
46115
|
} else if ("command" in entry && wasCommandInstalled(entry.command, installedHooks)) {
|
|
46113
46116
|
continue;
|
|
@@ -46118,16 +46121,12 @@ function mergeHookEntries(sourceEntries, destEntries, eventName, result, install
|
|
|
46118
46121
|
if (sourceMatcher) {
|
|
46119
46122
|
matcherIndex.set(sourceMatcher, merged.length - 1);
|
|
46120
46123
|
}
|
|
46121
|
-
for (const cmd of
|
|
46124
|
+
for (const cmd of newCommands) {
|
|
46122
46125
|
const normalizedCmd = normalizeCommand(cmd);
|
|
46123
|
-
|
|
46124
|
-
|
|
46125
|
-
|
|
46126
|
-
|
|
46127
|
-
trackHookOrigin(result, sourceKit, cmd);
|
|
46128
|
-
}
|
|
46129
|
-
} else if (!existingCommands.has(normalizedCmd)) {
|
|
46130
|
-
existingCommands.add(normalizedCmd);
|
|
46126
|
+
existingCommands.add(normalizedCmd);
|
|
46127
|
+
result.newlyInstalledHooks.push(cmd);
|
|
46128
|
+
if (sourceKit) {
|
|
46129
|
+
trackHookOrigin(result, sourceKit, cmd);
|
|
46131
46130
|
}
|
|
46132
46131
|
}
|
|
46133
46132
|
}
|
|
@@ -48098,7 +48097,7 @@ var init_chokidar = __esm(() => {
|
|
|
48098
48097
|
});
|
|
48099
48098
|
|
|
48100
48099
|
// src/domains/web-server/file-watcher.ts
|
|
48101
|
-
import { homedir as
|
|
48100
|
+
import { homedir as homedir12 } from "node:os";
|
|
48102
48101
|
import { join as join25 } from "node:path";
|
|
48103
48102
|
|
|
48104
48103
|
class FileWatcher {
|
|
@@ -48121,9 +48120,9 @@ class FileWatcher {
|
|
|
48121
48120
|
}
|
|
48122
48121
|
getWatchPaths() {
|
|
48123
48122
|
const paths = [];
|
|
48124
|
-
const globalDir = join25(
|
|
48123
|
+
const globalDir = join25(homedir12(), ".claudekit");
|
|
48125
48124
|
paths.push(join25(globalDir, "config.json"));
|
|
48126
|
-
const globalKitDir = join25(
|
|
48125
|
+
const globalKitDir = join25(homedir12(), ".claude");
|
|
48127
48126
|
paths.push(join25(globalKitDir, ".ck.json"));
|
|
48128
48127
|
paths.push(join25(globalKitDir, "settings.json"));
|
|
48129
48128
|
paths.push(join25(globalKitDir, "settings.local.json"));
|
|
@@ -48173,8 +48172,8 @@ class FileWatcher {
|
|
|
48173
48172
|
return path4.endsWith("config.json") || path4.endsWith(".ck.json") || path4.endsWith("settings.json") || path4.endsWith("settings.local.json");
|
|
48174
48173
|
}
|
|
48175
48174
|
getConfigScope(path4) {
|
|
48176
|
-
const globalDir = join25(
|
|
48177
|
-
const globalKitDir = join25(
|
|
48175
|
+
const globalDir = join25(homedir12(), ".claudekit");
|
|
48176
|
+
const globalKitDir = join25(homedir12(), ".claude");
|
|
48178
48177
|
return path4.startsWith(globalDir) || path4.startsWith(globalKitDir) ? "global" : "local";
|
|
48179
48178
|
}
|
|
48180
48179
|
stop() {
|
|
@@ -48665,7 +48664,7 @@ var init_claudekit_data2 = __esm(() => {
|
|
|
48665
48664
|
// src/domains/web-server/routes/action-routes.ts
|
|
48666
48665
|
import { spawn, spawnSync } from "node:child_process";
|
|
48667
48666
|
import { existsSync as existsSync14 } from "node:fs";
|
|
48668
|
-
import { homedir as
|
|
48667
|
+
import { homedir as homedir13 } from "node:os";
|
|
48669
48668
|
import { join as join27, resolve as resolve12, sep as sep5 } from "node:path";
|
|
48670
48669
|
function getWindowsPaths(...relativePaths) {
|
|
48671
48670
|
const roots = [
|
|
@@ -48942,7 +48941,7 @@ async function isActionPathAllowed(dirPath, projectId) {
|
|
|
48942
48941
|
try {
|
|
48943
48942
|
const encodedPath = projectId.slice("discovered-".length);
|
|
48944
48943
|
const discoveredPath = resolve12(Buffer.from(encodedPath, "base64url").toString("utf-8"));
|
|
48945
|
-
if (discoveredPath === dirPath && (isPathInsideBase(discoveredPath, process.cwd()) || isPathInsideBase(discoveredPath,
|
|
48944
|
+
if (discoveredPath === dirPath && (isPathInsideBase(discoveredPath, process.cwd()) || isPathInsideBase(discoveredPath, homedir13()))) {
|
|
48946
48945
|
return true;
|
|
48947
48946
|
}
|
|
48948
48947
|
} catch {}
|
|
@@ -48954,7 +48953,7 @@ async function isActionPathAllowed(dirPath, projectId) {
|
|
|
48954
48953
|
if (isPathInsideBase(dirPath, process.cwd())) {
|
|
48955
48954
|
return true;
|
|
48956
48955
|
}
|
|
48957
|
-
return isPathInsideBase(dirPath,
|
|
48956
|
+
return isPathInsideBase(dirPath, homedir13());
|
|
48958
48957
|
}
|
|
48959
48958
|
function buildSystemTerminalCommand(dirPath) {
|
|
48960
48959
|
if (isMacOS()) {
|
|
@@ -49293,7 +49292,7 @@ var init_action_routes = __esm(() => {
|
|
|
49293
49292
|
projectId: exports_external.string().min(1).max(256).optional()
|
|
49294
49293
|
}).strict();
|
|
49295
49294
|
WINDOWS_PATHS = {
|
|
49296
|
-
localAppData: process.env.LOCALAPPDATA || join27(
|
|
49295
|
+
localAppData: process.env.LOCALAPPDATA || join27(homedir13(), "AppData", "Local"),
|
|
49297
49296
|
programFiles: process.env.ProgramFiles || "C:\\Program Files",
|
|
49298
49297
|
programFilesX86: process.env["ProgramFiles(x86)"] || "C:\\Program Files (x86)"
|
|
49299
49298
|
};
|
|
@@ -49314,7 +49313,7 @@ var init_action_routes = __esm(() => {
|
|
|
49314
49313
|
openMode: "open-directory",
|
|
49315
49314
|
capabilities: ["open-directory", "run-command"],
|
|
49316
49315
|
macAppName: "iTerm",
|
|
49317
|
-
macAppPaths: ["/Applications/iTerm.app", join27(
|
|
49316
|
+
macAppPaths: ["/Applications/iTerm.app", join27(homedir13(), "Applications", "iTerm.app")]
|
|
49318
49317
|
},
|
|
49319
49318
|
{
|
|
49320
49319
|
id: "warp",
|
|
@@ -49325,7 +49324,7 @@ var init_action_routes = __esm(() => {
|
|
|
49325
49324
|
capabilities: ["open-directory", "uri-scheme"],
|
|
49326
49325
|
commands: ["warp"],
|
|
49327
49326
|
macAppName: "Warp",
|
|
49328
|
-
macAppPaths: ["/Applications/Warp.app", join27(
|
|
49327
|
+
macAppPaths: ["/Applications/Warp.app", join27(homedir13(), "Applications", "Warp.app")],
|
|
49329
49328
|
windowsAppPaths: getWindowsPaths("Warp\\Warp.exe"),
|
|
49330
49329
|
linuxAppPaths: ["/usr/bin/warp", "/usr/local/bin/warp"]
|
|
49331
49330
|
},
|
|
@@ -49348,7 +49347,7 @@ var init_action_routes = __esm(() => {
|
|
|
49348
49347
|
capabilities: ["open-directory"],
|
|
49349
49348
|
commands: ["wezterm"],
|
|
49350
49349
|
macAppName: "WezTerm",
|
|
49351
|
-
macAppPaths: ["/Applications/WezTerm.app", join27(
|
|
49350
|
+
macAppPaths: ["/Applications/WezTerm.app", join27(homedir13(), "Applications", "WezTerm.app")],
|
|
49352
49351
|
windowsAppPaths: getWindowsPaths("WezTerm\\wezterm-gui.exe", "WezTerm\\wezterm.exe"),
|
|
49353
49352
|
linuxAppPaths: ["/usr/bin/wezterm", "/usr/local/bin/wezterm"]
|
|
49354
49353
|
},
|
|
@@ -49361,7 +49360,7 @@ var init_action_routes = __esm(() => {
|
|
|
49361
49360
|
capabilities: ["open-directory"],
|
|
49362
49361
|
commands: ["kitty"],
|
|
49363
49362
|
macAppName: "kitty",
|
|
49364
|
-
macAppPaths: ["/Applications/kitty.app", join27(
|
|
49363
|
+
macAppPaths: ["/Applications/kitty.app", join27(homedir13(), "Applications", "kitty.app")],
|
|
49365
49364
|
windowsAppPaths: getWindowsPaths("kitty\\kitty.exe"),
|
|
49366
49365
|
linuxAppPaths: ["/usr/bin/kitty", "/usr/local/bin/kitty"]
|
|
49367
49366
|
},
|
|
@@ -49374,7 +49373,7 @@ var init_action_routes = __esm(() => {
|
|
|
49374
49373
|
capabilities: ["open-directory"],
|
|
49375
49374
|
commands: ["alacritty"],
|
|
49376
49375
|
macAppName: "Alacritty",
|
|
49377
|
-
macAppPaths: ["/Applications/Alacritty.app", join27(
|
|
49376
|
+
macAppPaths: ["/Applications/Alacritty.app", join27(homedir13(), "Applications", "Alacritty.app")],
|
|
49378
49377
|
windowsAppPaths: getWindowsPaths("Alacritty\\alacritty.exe"),
|
|
49379
49378
|
linuxAppPaths: ["/usr/bin/alacritty", "/usr/local/bin/alacritty"]
|
|
49380
49379
|
},
|
|
@@ -49447,7 +49446,7 @@ var init_action_routes = __esm(() => {
|
|
|
49447
49446
|
capabilities: ["open-app"],
|
|
49448
49447
|
commands: ["termius"],
|
|
49449
49448
|
macAppName: "Termius",
|
|
49450
|
-
macAppPaths: ["/Applications/Termius.app", join27(
|
|
49449
|
+
macAppPaths: ["/Applications/Termius.app", join27(homedir13(), "Applications", "Termius.app")],
|
|
49451
49450
|
windowsAppPaths: getWindowsPaths("Termius\\Termius.exe"),
|
|
49452
49451
|
linuxAppPaths: ["/usr/bin/termius"]
|
|
49453
49452
|
},
|
|
@@ -49470,7 +49469,7 @@ var init_action_routes = __esm(() => {
|
|
|
49470
49469
|
macAppName: "Visual Studio Code",
|
|
49471
49470
|
macAppPaths: [
|
|
49472
49471
|
"/Applications/Visual Studio Code.app",
|
|
49473
|
-
join27(
|
|
49472
|
+
join27(homedir13(), "Applications", "Visual Studio Code.app")
|
|
49474
49473
|
],
|
|
49475
49474
|
windowsAppPaths: getWindowsPaths("Programs\\Microsoft VS Code\\Code.exe", "Microsoft VS Code\\Code.exe"),
|
|
49476
49475
|
linuxAppPaths: ["/usr/bin/code", "/snap/bin/code"]
|
|
@@ -49484,7 +49483,7 @@ var init_action_routes = __esm(() => {
|
|
|
49484
49483
|
capabilities: ["open-directory"],
|
|
49485
49484
|
commands: ["cursor"],
|
|
49486
49485
|
macAppName: "Cursor",
|
|
49487
|
-
macAppPaths: ["/Applications/Cursor.app", join27(
|
|
49486
|
+
macAppPaths: ["/Applications/Cursor.app", join27(homedir13(), "Applications", "Cursor.app")],
|
|
49488
49487
|
windowsAppPaths: getWindowsPaths("Programs\\Cursor\\Cursor.exe", "Cursor\\Cursor.exe"),
|
|
49489
49488
|
linuxAppPaths: ["/usr/bin/cursor"]
|
|
49490
49489
|
},
|
|
@@ -49497,7 +49496,7 @@ var init_action_routes = __esm(() => {
|
|
|
49497
49496
|
capabilities: ["open-directory"],
|
|
49498
49497
|
commands: ["windsurf"],
|
|
49499
49498
|
macAppName: "Windsurf",
|
|
49500
|
-
macAppPaths: ["/Applications/Windsurf.app", join27(
|
|
49499
|
+
macAppPaths: ["/Applications/Windsurf.app", join27(homedir13(), "Applications", "Windsurf.app")],
|
|
49501
49500
|
windowsAppPaths: getWindowsPaths("Programs\\Windsurf\\Windsurf.exe", "Windsurf\\Windsurf.exe"),
|
|
49502
49501
|
linuxAppPaths: ["/usr/bin/windsurf"]
|
|
49503
49502
|
},
|
|
@@ -49512,11 +49511,11 @@ var init_action_routes = __esm(() => {
|
|
|
49512
49511
|
macAppName: "Antigravity",
|
|
49513
49512
|
macAppPaths: [
|
|
49514
49513
|
"/Applications/Antigravity.app",
|
|
49515
|
-
join27(
|
|
49514
|
+
join27(homedir13(), "Applications", "Antigravity.app")
|
|
49516
49515
|
],
|
|
49517
49516
|
windowsAppPaths: getWindowsPaths("Programs\\Antigravity\\Antigravity.exe"),
|
|
49518
49517
|
linuxAppPaths: ["/usr/bin/antigravity"],
|
|
49519
|
-
fallbackDetectionPaths: [join27(
|
|
49518
|
+
fallbackDetectionPaths: [join27(homedir13(), ".gemini", "antigravity")]
|
|
49520
49519
|
},
|
|
49521
49520
|
{
|
|
49522
49521
|
id: "zed",
|
|
@@ -49527,7 +49526,7 @@ var init_action_routes = __esm(() => {
|
|
|
49527
49526
|
capabilities: ["open-directory"],
|
|
49528
49527
|
commands: ["zed"],
|
|
49529
49528
|
macAppName: "Zed",
|
|
49530
|
-
macAppPaths: ["/Applications/Zed.app", join27(
|
|
49529
|
+
macAppPaths: ["/Applications/Zed.app", join27(homedir13(), "Applications", "Zed.app")],
|
|
49531
49530
|
windowsAppPaths: getWindowsPaths("Zed\\Zed.exe"),
|
|
49532
49531
|
linuxAppPaths: ["/usr/bin/zed", "/usr/local/bin/zed"]
|
|
49533
49532
|
},
|
|
@@ -49542,7 +49541,7 @@ var init_action_routes = __esm(() => {
|
|
|
49542
49541
|
macAppName: "Sublime Text",
|
|
49543
49542
|
macAppPaths: [
|
|
49544
49543
|
"/Applications/Sublime Text.app",
|
|
49545
|
-
join27(
|
|
49544
|
+
join27(homedir13(), "Applications", "Sublime Text.app")
|
|
49546
49545
|
],
|
|
49547
49546
|
windowsAppPaths: getWindowsPaths("Sublime Text\\sublime_text.exe"),
|
|
49548
49547
|
linuxAppPaths: ["/usr/bin/subl", "/snap/bin/subl"]
|
|
@@ -49583,7 +49582,7 @@ var init_action_routes = __esm(() => {
|
|
|
49583
49582
|
|
|
49584
49583
|
// src/domains/web-server/routes/agents-routes.ts
|
|
49585
49584
|
import { readdir as readdir7 } from "node:fs/promises";
|
|
49586
|
-
import { homedir as
|
|
49585
|
+
import { homedir as homedir14 } from "node:os";
|
|
49587
49586
|
import { isAbsolute as isAbsolute4, join as join28, relative as relative7 } from "node:path";
|
|
49588
49587
|
function resolveAgentDirs() {
|
|
49589
49588
|
const dirs = [];
|
|
@@ -49628,7 +49627,7 @@ async function scanAgentDir(dirPath, dirLabel) {
|
|
|
49628
49627
|
color: frontmatter.color || null,
|
|
49629
49628
|
skillCount: countSkills(frontmatter.tools),
|
|
49630
49629
|
dirLabel,
|
|
49631
|
-
relativePath: relative7(
|
|
49630
|
+
relativePath: relative7(homedir14(), filePath)
|
|
49632
49631
|
});
|
|
49633
49632
|
} catch {}
|
|
49634
49633
|
}
|
|
@@ -49672,7 +49671,7 @@ function registerAgentsBrowserRoutes(app) {
|
|
|
49672
49671
|
color: frontmatter.color || null,
|
|
49673
49672
|
skillCount: countSkills(frontmatter.tools),
|
|
49674
49673
|
dirLabel: dir.label,
|
|
49675
|
-
relativePath: relative7(
|
|
49674
|
+
relativePath: relative7(homedir14(), filePath),
|
|
49676
49675
|
frontmatter,
|
|
49677
49676
|
body
|
|
49678
49677
|
};
|
|
@@ -49687,7 +49686,7 @@ var home2;
|
|
|
49687
49686
|
var init_agents_routes = __esm(() => {
|
|
49688
49687
|
init_frontmatter_parser();
|
|
49689
49688
|
init_kit_layout();
|
|
49690
|
-
home2 =
|
|
49689
|
+
home2 = homedir14();
|
|
49691
49690
|
});
|
|
49692
49691
|
|
|
49693
49692
|
// src/schemas/ck-config.schema.json
|
|
@@ -50524,7 +50523,7 @@ var init_ck_config_routes = __esm(() => {
|
|
|
50524
50523
|
// src/domains/web-server/routes/command-routes.ts
|
|
50525
50524
|
import { existsSync as existsSync16 } from "node:fs";
|
|
50526
50525
|
import { readFile as readFile12, readdir as readdir8 } from "node:fs/promises";
|
|
50527
|
-
import { homedir as
|
|
50526
|
+
import { homedir as homedir15 } from "node:os";
|
|
50528
50527
|
import { basename as basename9, isAbsolute as isAbsolute5, join as join30, relative as relative8, resolve as resolve13 } from "node:path";
|
|
50529
50528
|
async function buildCommandTree(dir, baseDir) {
|
|
50530
50529
|
let dirents;
|
|
@@ -50566,7 +50565,7 @@ async function buildCommandTree(dir, baseDir) {
|
|
|
50566
50565
|
}
|
|
50567
50566
|
function registerCommandRoutes(app) {
|
|
50568
50567
|
app.get("/api/commands", async (_req, res) => {
|
|
50569
|
-
const commandsDir = join30(
|
|
50568
|
+
const commandsDir = join30(homedir15(), ".claude", "commands");
|
|
50570
50569
|
if (!existsSync16(commandsDir)) {
|
|
50571
50570
|
res.json({ tree: [] });
|
|
50572
50571
|
return;
|
|
@@ -50589,7 +50588,7 @@ function registerCommandRoutes(app) {
|
|
|
50589
50588
|
res.status(400).json({ error: "Invalid path" });
|
|
50590
50589
|
return;
|
|
50591
50590
|
}
|
|
50592
|
-
const commandsDir = join30(
|
|
50591
|
+
const commandsDir = join30(homedir15(), ".claude", "commands");
|
|
50593
50592
|
const safePath = resolve13(commandsDir, rawPath);
|
|
50594
50593
|
const rel = relative8(commandsDir, safePath);
|
|
50595
50594
|
if (rel.startsWith("..") || isAbsolute5(rel)) {
|
|
@@ -50663,11 +50662,11 @@ var init_types5 = __esm(() => {
|
|
|
50663
50662
|
|
|
50664
50663
|
// src/services/claude-data/history-parser.ts
|
|
50665
50664
|
import { createReadStream, statSync as statSync4 } from "node:fs";
|
|
50666
|
-
import { homedir as
|
|
50665
|
+
import { homedir as homedir16 } from "node:os";
|
|
50667
50666
|
import { join as join31 } from "node:path";
|
|
50668
50667
|
import { createInterface as createInterface2 } from "node:readline";
|
|
50669
50668
|
function getHistoryPath() {
|
|
50670
|
-
return process.env.CLAUDE_HISTORY_PATH ?? join31(
|
|
50669
|
+
return process.env.CLAUDE_HISTORY_PATH ?? join31(homedir16(), ".claude", "history.jsonl");
|
|
50671
50670
|
}
|
|
50672
50671
|
function emptyResult(parseTimeMs, error) {
|
|
50673
50672
|
return { projects: [], totalEntries: 0, errorCount: 0, parseTimeMs, error };
|
|
@@ -50865,10 +50864,10 @@ var init_session_parser = () => {};
|
|
|
50865
50864
|
// src/services/claude-data/skill-scanner.ts
|
|
50866
50865
|
import { existsSync as existsSync18 } from "node:fs";
|
|
50867
50866
|
import { readFile as readFile14, readdir as readdir10, stat as stat6 } from "node:fs/promises";
|
|
50868
|
-
import { homedir as
|
|
50867
|
+
import { homedir as homedir17 } from "node:os";
|
|
50869
50868
|
import { join as join33 } from "node:path";
|
|
50870
50869
|
async function getCkSkillMetadata(scope) {
|
|
50871
|
-
const metaPath = scope === "global" ? join33(
|
|
50870
|
+
const metaPath = scope === "global" ? join33(homedir17(), ".claude", "metadata.json") : join33(process.cwd(), ".claude", "metadata.json");
|
|
50872
50871
|
if (!existsSync18(metaPath))
|
|
50873
50872
|
return null;
|
|
50874
50873
|
const result = new Map;
|
|
@@ -50998,14 +50997,14 @@ async function scanSkills() {
|
|
|
50998
50997
|
var import_gray_matter4, skillsDir, SKIP_DIRS2;
|
|
50999
50998
|
var init_skill_scanner = __esm(() => {
|
|
51000
50999
|
import_gray_matter4 = __toESM(require_gray_matter(), 1);
|
|
51001
|
-
skillsDir = join33(
|
|
51000
|
+
skillsDir = join33(homedir17(), ".claude", "skills");
|
|
51002
51001
|
SKIP_DIRS2 = [".venv", "scripts", "__pycache__", "node_modules", ".git", "common"];
|
|
51003
51002
|
});
|
|
51004
51003
|
|
|
51005
51004
|
// src/services/claude-data/settings-reader.ts
|
|
51006
51005
|
import { existsSync as existsSync19 } from "node:fs";
|
|
51007
51006
|
import { copyFile as copyFile2, mkdir as mkdir9, readFile as readFile15, rename as rename5, rm as rm4, writeFile as writeFile10 } from "node:fs/promises";
|
|
51008
|
-
import { homedir as
|
|
51007
|
+
import { homedir as homedir18 } from "node:os";
|
|
51009
51008
|
import { join as join34 } from "node:path";
|
|
51010
51009
|
function getSettingsPath() {
|
|
51011
51010
|
return join34(claudeDir, settingsFilename);
|
|
@@ -51067,7 +51066,7 @@ function countMcpServers(settings) {
|
|
|
51067
51066
|
}
|
|
51068
51067
|
var claudeDir, settingsFilename = "settings.json", settingsBackupDir;
|
|
51069
51068
|
var init_settings_reader = __esm(() => {
|
|
51070
|
-
claudeDir = join34(
|
|
51069
|
+
claudeDir = join34(homedir18(), ".claude");
|
|
51071
51070
|
settingsBackupDir = join34(claudeDir, ".ck-backups", "settings");
|
|
51072
51071
|
});
|
|
51073
51072
|
|
|
@@ -51235,7 +51234,7 @@ var init_hook_log_reader = __esm(() => {
|
|
|
51235
51234
|
});
|
|
51236
51235
|
|
|
51237
51236
|
// src/services/claude-data/project-scanner.ts
|
|
51238
|
-
import { homedir as
|
|
51237
|
+
import { homedir as homedir19 } from "node:os";
|
|
51239
51238
|
import { basename as basename10, join as join36, normalize as normalize4 } from "node:path";
|
|
51240
51239
|
function decodePath(encoded) {
|
|
51241
51240
|
const decoded = encoded.replace(/^-/, "/").replace(/-/g, "/");
|
|
@@ -51250,7 +51249,7 @@ function encodePath(path4) {
|
|
|
51250
51249
|
}
|
|
51251
51250
|
var projectsDir;
|
|
51252
51251
|
var init_project_scanner = __esm(() => {
|
|
51253
|
-
projectsDir = join36(
|
|
51252
|
+
projectsDir = join36(homedir19(), ".claude", "projects");
|
|
51254
51253
|
});
|
|
51255
51254
|
|
|
51256
51255
|
// src/services/claude-data/project-discovery.ts
|
|
@@ -51345,10 +51344,10 @@ var init_project_discovery = __esm(() => {
|
|
|
51345
51344
|
|
|
51346
51345
|
// src/services/claude-data/user-preferences.ts
|
|
51347
51346
|
import { readFile as readFile16, stat as stat7 } from "node:fs/promises";
|
|
51348
|
-
import { homedir as
|
|
51347
|
+
import { homedir as homedir20 } from "node:os";
|
|
51349
51348
|
import { join as join37 } from "node:path";
|
|
51350
51349
|
function getPreferencesPath() {
|
|
51351
|
-
return join37(
|
|
51350
|
+
return join37(homedir20(), ".claude.json");
|
|
51352
51351
|
}
|
|
51353
51352
|
async function readUserPreferences(filePath) {
|
|
51354
51353
|
const path4 = filePath ?? getPreferencesPath();
|
|
@@ -51439,7 +51438,7 @@ var init_claude_data = __esm(() => {
|
|
|
51439
51438
|
// src/domains/web-server/routes/dashboard-routes.ts
|
|
51440
51439
|
import { existsSync as existsSync20 } from "node:fs";
|
|
51441
51440
|
import { readFile as readFile17, readdir as readdir11 } from "node:fs/promises";
|
|
51442
|
-
import { homedir as
|
|
51441
|
+
import { homedir as homedir21 } from "node:os";
|
|
51443
51442
|
import { join as join38 } from "node:path";
|
|
51444
51443
|
async function readAgents() {
|
|
51445
51444
|
const agentsDir = join38(claudeDir2, "agents");
|
|
@@ -51509,7 +51508,7 @@ async function countAllMcpServers() {
|
|
|
51509
51508
|
}
|
|
51510
51509
|
let claudeJsonCount = 0;
|
|
51511
51510
|
try {
|
|
51512
|
-
const claudeJsonPath = join38(
|
|
51511
|
+
const claudeJsonPath = join38(homedir21(), ".claude.json");
|
|
51513
51512
|
if (existsSync20(claudeJsonPath)) {
|
|
51514
51513
|
const content = await readFile17(claudeJsonPath, "utf-8");
|
|
51515
51514
|
const data = JSON.parse(content);
|
|
@@ -51636,7 +51635,7 @@ var claudeDir2;
|
|
|
51636
51635
|
var init_dashboard_routes = __esm(() => {
|
|
51637
51636
|
init_frontmatter_parser();
|
|
51638
51637
|
init_claude_data();
|
|
51639
|
-
claudeDir2 = join38(
|
|
51638
|
+
claudeDir2 = join38(homedir21(), ".claude");
|
|
51640
51639
|
});
|
|
51641
51640
|
|
|
51642
51641
|
// src/domains/web-server/routes/health-routes.ts
|
|
@@ -51710,7 +51709,7 @@ var init_hook_log_routes = __esm(() => {
|
|
|
51710
51709
|
// src/domains/web-server/routes/mcp-routes.ts
|
|
51711
51710
|
import { existsSync as existsSync21 } from "node:fs";
|
|
51712
51711
|
import { readFile as readFile18 } from "node:fs/promises";
|
|
51713
|
-
import { homedir as
|
|
51712
|
+
import { homedir as homedir22 } from "node:os";
|
|
51714
51713
|
import { basename as basename12, join as join39, resolve as resolve14 } from "node:path";
|
|
51715
51714
|
function parseMcpServers(raw, source, sourceLabel) {
|
|
51716
51715
|
const entries = [];
|
|
@@ -51759,7 +51758,7 @@ function mergeServers(lists) {
|
|
|
51759
51758
|
function isSafeProjectPath(projectPath) {
|
|
51760
51759
|
if (projectPath.includes(".."))
|
|
51761
51760
|
return false;
|
|
51762
|
-
const home3 =
|
|
51761
|
+
const home3 = homedir22();
|
|
51763
51762
|
try {
|
|
51764
51763
|
const resolved = resolve14(projectPath);
|
|
51765
51764
|
if (!resolved.startsWith(home3))
|
|
@@ -51772,7 +51771,7 @@ function isSafeProjectPath(projectPath) {
|
|
|
51772
51771
|
function registerMcpRoutes(app) {
|
|
51773
51772
|
app.get("/api/mcp-servers", async (_req, res) => {
|
|
51774
51773
|
try {
|
|
51775
|
-
const claudeDir3 = join39(
|
|
51774
|
+
const claudeDir3 = join39(homedir22(), ".claude");
|
|
51776
51775
|
const allLists = [];
|
|
51777
51776
|
try {
|
|
51778
51777
|
const settings = await readSettings();
|
|
@@ -51782,7 +51781,7 @@ function registerMcpRoutes(app) {
|
|
|
51782
51781
|
}
|
|
51783
51782
|
} catch {}
|
|
51784
51783
|
try {
|
|
51785
|
-
const claudeJsonPath = join39(
|
|
51784
|
+
const claudeJsonPath = join39(homedir22(), ".claude.json");
|
|
51786
51785
|
if (existsSync21(claudeJsonPath)) {
|
|
51787
51786
|
const content = await readFile18(claudeJsonPath, "utf-8");
|
|
51788
51787
|
const parsed = JSON.parse(content);
|
|
@@ -52043,7 +52042,7 @@ var init_skill_directory_installer = __esm(() => {
|
|
|
52043
52042
|
// src/commands/portable/config-discovery.ts
|
|
52044
52043
|
import { existsSync as existsSync23, readFileSync as readFileSync6 } from "node:fs";
|
|
52045
52044
|
import { cp as cp2, mkdir as mkdir11, readFile as readFile19, readdir as readdir12, stat as stat8 } from "node:fs/promises";
|
|
52046
|
-
import { homedir as
|
|
52045
|
+
import { homedir as homedir23 } from "node:os";
|
|
52047
52046
|
import { basename as basename13, dirname as dirname12, extname as extname3, join as join41, relative as relative9, resolve as resolve16, sep as sep6 } from "node:path";
|
|
52048
52047
|
async function copyHooksCompanionDirs(sourceDir, targetDir) {
|
|
52049
52048
|
const result = {
|
|
@@ -52126,7 +52125,7 @@ async function copyHooksCompanionDirs(sourceDir, targetDir) {
|
|
|
52126
52125
|
function resolveSourceOrigin(sourcePath) {
|
|
52127
52126
|
if (!sourcePath)
|
|
52128
52127
|
return "global";
|
|
52129
|
-
const home3 =
|
|
52128
|
+
const home3 = homedir23();
|
|
52130
52129
|
const cwd2 = process.cwd();
|
|
52131
52130
|
if (cwd2 === home3)
|
|
52132
52131
|
return "global";
|
|
@@ -52141,16 +52140,16 @@ function getConfigSourcePath(globalOnly = false) {
|
|
|
52141
52140
|
return findExistingProjectConfigPath(process.cwd()) ?? getGlobalConfigSourcePath();
|
|
52142
52141
|
}
|
|
52143
52142
|
function getGlobalConfigSourcePath() {
|
|
52144
|
-
return join41(
|
|
52143
|
+
return join41(homedir23(), ".claude", "CLAUDE.md");
|
|
52145
52144
|
}
|
|
52146
52145
|
function getRulesSourcePath(globalOnly = false) {
|
|
52147
|
-
const globalPath = join41(
|
|
52146
|
+
const globalPath = join41(homedir23(), ".claude", "rules");
|
|
52148
52147
|
if (globalOnly)
|
|
52149
52148
|
return globalPath;
|
|
52150
52149
|
return findExistingProjectLayoutPath(process.cwd(), "rules") ?? globalPath;
|
|
52151
52150
|
}
|
|
52152
52151
|
function getHooksSourcePath(globalOnly = false) {
|
|
52153
|
-
const globalPath = join41(
|
|
52152
|
+
const globalPath = join41(homedir23(), ".claude", "hooks");
|
|
52154
52153
|
if (globalOnly)
|
|
52155
52154
|
return globalPath;
|
|
52156
52155
|
return findExistingProjectLayoutPath(process.cwd(), "hooks") ?? globalPath;
|
|
@@ -54339,7 +54338,7 @@ var init_codex_capabilities = __esm(() => {
|
|
|
54339
54338
|
// src/commands/portable/codex-path-safety.ts
|
|
54340
54339
|
import { existsSync as existsSync24 } from "node:fs";
|
|
54341
54340
|
import { mkdir as mkdir12, realpath as realpath7 } from "node:fs/promises";
|
|
54342
|
-
import { homedir as
|
|
54341
|
+
import { homedir as homedir24 } from "node:os";
|
|
54343
54342
|
import { dirname as dirname13, join as join42, resolve as resolve17, sep as sep7 } from "node:path";
|
|
54344
54343
|
function isPathWithinBoundary3(targetPath, boundaryPath) {
|
|
54345
54344
|
const resolvedTarget = resolve17(targetPath);
|
|
@@ -54386,7 +54385,7 @@ async function withCodexTargetLock2(targetFilePath, operation) {
|
|
|
54386
54385
|
}
|
|
54387
54386
|
}
|
|
54388
54387
|
function getCodexGlobalBoundary() {
|
|
54389
|
-
return join42(
|
|
54388
|
+
return join42(homedir24(), ".codex");
|
|
54390
54389
|
}
|
|
54391
54390
|
var import_proper_lockfile6;
|
|
54392
54391
|
var init_codex_path_safety = __esm(() => {
|
|
@@ -54781,7 +54780,7 @@ var init_codex_hook_wrapper = __esm(() => {
|
|
|
54781
54780
|
});
|
|
54782
54781
|
|
|
54783
54782
|
// src/commands/portable/converters/claude-to-codex-hooks.ts
|
|
54784
|
-
import { homedir as
|
|
54783
|
+
import { homedir as homedir25 } from "node:os";
|
|
54785
54784
|
function convertClaudeHooksToCodex(sourceHooks, capabilities, pathRewrite) {
|
|
54786
54785
|
const result = {};
|
|
54787
54786
|
for (const [event, groups] of Object.entries(sourceHooks)) {
|
|
@@ -54839,7 +54838,7 @@ function rewriteCommandPath(command, pathRewrite) {
|
|
|
54839
54838
|
const normalizeSlashes = (s) => s.replace(/\\/g, "/");
|
|
54840
54839
|
let rewritten = command;
|
|
54841
54840
|
if (pathRewrite.commandSubstitutions && pathRewrite.commandSubstitutions.size > 0) {
|
|
54842
|
-
const home3 =
|
|
54841
|
+
const home3 = homedir25();
|
|
54843
54842
|
const homeForward = normalizeSlashes(home3);
|
|
54844
54843
|
for (const [originalAbsPath, wrapperAbsPath] of pathRewrite.commandSubstitutions) {
|
|
54845
54844
|
const originalAbsForward = normalizeSlashes(originalAbsPath);
|
|
@@ -54942,7 +54941,7 @@ var init_gemini_hook_event_map = __esm(() => {
|
|
|
54942
54941
|
// src/commands/portable/hooks-settings-merger.ts
|
|
54943
54942
|
import { existsSync as existsSync26 } from "node:fs";
|
|
54944
54943
|
import { mkdir as mkdir13, readFile as readFile21, rename as rename8, rm as rm6, writeFile as writeFile12 } from "node:fs/promises";
|
|
54945
|
-
import { homedir as
|
|
54944
|
+
import { homedir as homedir26 } from "node:os";
|
|
54946
54945
|
import { basename as basename14, dirname as dirname16, extname as extname4, join as join44, resolve as resolve20 } from "node:path";
|
|
54947
54946
|
function isCodexWrappableHookPath(filePath) {
|
|
54948
54947
|
return hookAssetBasename(filePath) !== "node-hook-runner.sh" && CODEX_WRAPPABLE_HOOK_EXTENSIONS.has(extname4(filePath).toLowerCase());
|
|
@@ -55025,7 +55024,7 @@ function normalizeDirPattern(value) {
|
|
|
55025
55024
|
}
|
|
55026
55025
|
function homeRelativeDir(value) {
|
|
55027
55026
|
const normalized = normalizeDirPattern(value);
|
|
55028
|
-
const home3 = normalizeDirPattern(
|
|
55027
|
+
const home3 = normalizeDirPattern(homedir26());
|
|
55029
55028
|
return normalized.startsWith(`${home3}/`) ? normalized.slice(home3.length + 1) : normalized;
|
|
55030
55029
|
}
|
|
55031
55030
|
function buildHookDirRewritePairs(sourceHooksDir, targetHooksDir) {
|
|
@@ -55582,7 +55581,7 @@ async function migrateHooksSettingsForCodex(options2) {
|
|
|
55582
55581
|
}
|
|
55583
55582
|
let featureFlagWritten = false;
|
|
55584
55583
|
if (capabilities.requiresFeatureFlag) {
|
|
55585
|
-
const configTomlPath = isGlobal ? join44(
|
|
55584
|
+
const configTomlPath = isGlobal ? join44(homedir26(), ".codex", "config.toml") : join44(process.cwd(), ".codex", "config.toml");
|
|
55586
55585
|
const flagResult = await ensureCodexHooksFeatureFlag(configTomlPath, isGlobal);
|
|
55587
55586
|
featureFlagWritten = flagResult.status === "written" || flagResult.status === "updated";
|
|
55588
55587
|
}
|
|
@@ -56987,10 +56986,10 @@ __export(exports_skills_discovery, {
|
|
|
56987
56986
|
discoverSkills: () => discoverSkills
|
|
56988
56987
|
});
|
|
56989
56988
|
import { readFile as readFile25, readdir as readdir13, stat as stat9 } from "node:fs/promises";
|
|
56990
|
-
import { homedir as
|
|
56989
|
+
import { homedir as homedir27 } from "node:os";
|
|
56991
56990
|
import { dirname as dirname17, join as join45 } from "node:path";
|
|
56992
56991
|
function getSkillSourcePath(globalOnly = false) {
|
|
56993
|
-
const globalPath = join45(
|
|
56992
|
+
const globalPath = join45(homedir27(), ".claude/skills");
|
|
56994
56993
|
if (globalOnly) {
|
|
56995
56994
|
return findFirstExistingPath([globalPath]);
|
|
56996
56995
|
}
|
|
@@ -57231,7 +57230,7 @@ var init_migration_result_utils = __esm(() => {
|
|
|
57231
57230
|
// src/domains/web-server/routes/migration-routes.ts
|
|
57232
57231
|
import { existsSync as existsSync30 } from "node:fs";
|
|
57233
57232
|
import { readFile as readFile26, rm as rm8 } from "node:fs/promises";
|
|
57234
|
-
import { homedir as
|
|
57233
|
+
import { homedir as homedir28 } from "node:os";
|
|
57235
57234
|
import { basename as basename17, join as join46, resolve as resolve23 } from "node:path";
|
|
57236
57235
|
function resolveRegistryDeps(deps) {
|
|
57237
57236
|
return {
|
|
@@ -57910,7 +57909,7 @@ function registerMigrationRoutes(app, deps) {
|
|
|
57910
57909
|
};
|
|
57911
57910
|
const discovered = await discoverMigrationItems(includeAll);
|
|
57912
57911
|
const cwd2 = process.cwd();
|
|
57913
|
-
const home3 =
|
|
57912
|
+
const home3 = homedir28();
|
|
57914
57913
|
res.status(200).json({
|
|
57915
57914
|
cwd: cwd2,
|
|
57916
57915
|
targetPaths: {
|
|
@@ -59426,7 +59425,7 @@ function scanPlanDir(dir) {
|
|
|
59426
59425
|
var init_plan_scanner = () => {};
|
|
59427
59426
|
|
|
59428
59427
|
// src/domains/plan-parser/plan-scope.ts
|
|
59429
|
-
import { homedir as
|
|
59428
|
+
import { homedir as homedir29 } from "node:os";
|
|
59430
59429
|
import { isAbsolute as isAbsolute8, join as join49, relative as relative12, resolve as resolve25 } from "node:path";
|
|
59431
59430
|
function resolveConfiguredDir(configuredPath, baseDir) {
|
|
59432
59431
|
const trimmed = configuredPath?.trim();
|
|
@@ -59439,7 +59438,7 @@ function resolveProjectPlansDir(projectRoot, config) {
|
|
|
59439
59438
|
return resolveConfiguredDir(config?.paths?.plans, projectRoot);
|
|
59440
59439
|
}
|
|
59441
59440
|
function resolveGlobalPlansDir(config) {
|
|
59442
|
-
return resolveConfiguredDir(config?.paths?.globalPlans, join49(
|
|
59441
|
+
return resolveConfiguredDir(config?.paths?.globalPlans, join49(homedir29(), ".claude"));
|
|
59443
59442
|
}
|
|
59444
59443
|
function resolvePlanDirForScope(scope, projectRoot, config) {
|
|
59445
59444
|
return scope === "global" ? resolveGlobalPlansDir(config) : resolveProjectPlansDir(projectRoot, config);
|
|
@@ -60711,7 +60710,7 @@ var init_p_limit = __esm(() => {
|
|
|
60711
60710
|
|
|
60712
60711
|
// src/domains/web-server/routes/plan-routes.ts
|
|
60713
60712
|
import { existsSync as existsSync36, readFileSync as readFileSync12, realpathSync as realpathSync2 } from "node:fs";
|
|
60714
|
-
import { homedir as
|
|
60713
|
+
import { homedir as homedir30 } from "node:os";
|
|
60715
60714
|
import { basename as basename20, dirname as dirname24, join as join54, relative as relative14, resolve as resolve27, sep as sep8 } from "node:path";
|
|
60716
60715
|
function sanitizeError(err) {
|
|
60717
60716
|
if (err instanceof Error) {
|
|
@@ -60902,7 +60901,7 @@ function withTimeout(promiseFactory, timeoutMs, label) {
|
|
|
60902
60901
|
function isCurrentProjectFallbackCandidate(currentPath, globalProjectKey) {
|
|
60903
60902
|
if (toProjectPathKey(currentPath) === globalProjectKey)
|
|
60904
60903
|
return false;
|
|
60905
|
-
if (toProjectPathKey(currentPath) === toProjectPathKey(
|
|
60904
|
+
if (toProjectPathKey(currentPath) === toProjectPathKey(homedir30()))
|
|
60906
60905
|
return false;
|
|
60907
60906
|
return existsSync36(join54(currentPath, ".git")) || existsSync36(CkConfigManager.getProjectConfigPath(currentPath)) || existsSync36(join54(currentPath, "plans"));
|
|
60908
60907
|
}
|
|
@@ -60967,7 +60966,7 @@ function registerPlanRoutes(app) {
|
|
|
60967
60966
|
});
|
|
60968
60967
|
app.get("/api/plan/list-all", async (_req, res) => {
|
|
60969
60968
|
try {
|
|
60970
|
-
const globalProjectKey = toProjectPathKey(join54(
|
|
60969
|
+
const globalProjectKey = toProjectPathKey(join54(homedir30(), ".claude"));
|
|
60971
60970
|
const seenProjectKeys = new Set;
|
|
60972
60971
|
const scanTargets = [];
|
|
60973
60972
|
for (const project of await ProjectsRegistryManager.listProjects()) {
|
|
@@ -61214,7 +61213,7 @@ var init_project_plan_data = __esm(() => {
|
|
|
61214
61213
|
// src/domains/web-server/routes/project-routes.ts
|
|
61215
61214
|
import { existsSync as existsSync37 } from "node:fs";
|
|
61216
61215
|
import { readFile as readFile27 } from "node:fs/promises";
|
|
61217
|
-
import { homedir as
|
|
61216
|
+
import { homedir as homedir31 } from "node:os";
|
|
61218
61217
|
import { basename as basename21, join as join55, resolve as resolve28 } from "node:path";
|
|
61219
61218
|
function registerProjectRoutes(app) {
|
|
61220
61219
|
app.get("/api/projects", async (req, res) => {
|
|
@@ -61235,7 +61234,7 @@ function registerProjectRoutes(app) {
|
|
|
61235
61234
|
for (const discovered of discoveredProjects) {
|
|
61236
61235
|
if (registeredPaths.has(discovered.path))
|
|
61237
61236
|
continue;
|
|
61238
|
-
if (discovered.path === join55(
|
|
61237
|
+
if (discovered.path === join55(homedir31(), ".claude"))
|
|
61239
61238
|
continue;
|
|
61240
61239
|
const projectInfo = await detectAndBuildProjectInfo(discovered.path, `discovered-${discovered.path}`, cachedSettings, cachedSkills, false);
|
|
61241
61240
|
if (projectInfo) {
|
|
@@ -61251,7 +61250,7 @@ function registerProjectRoutes(app) {
|
|
|
61251
61250
|
if (cwdProject) {
|
|
61252
61251
|
projects.push(cwdProject);
|
|
61253
61252
|
}
|
|
61254
|
-
const globalDir = join55(
|
|
61253
|
+
const globalDir = join55(homedir31(), ".claude");
|
|
61255
61254
|
const globalProject = await detectAndBuildProjectInfo(globalDir, "global", undefined, undefined, false);
|
|
61256
61255
|
if (globalProject) {
|
|
61257
61256
|
projects.push(globalProject);
|
|
@@ -61323,12 +61322,12 @@ function registerProjectRoutes(app) {
|
|
|
61323
61322
|
const body = validation.data;
|
|
61324
61323
|
let projectPath = body.path;
|
|
61325
61324
|
if (projectPath.startsWith("~/") || projectPath === "~") {
|
|
61326
|
-
projectPath = join55(
|
|
61325
|
+
projectPath = join55(homedir31(), projectPath.slice(1));
|
|
61327
61326
|
} else if (projectPath.startsWith("~\\")) {
|
|
61328
|
-
projectPath = join55(
|
|
61327
|
+
projectPath = join55(homedir31(), projectPath.slice(1));
|
|
61329
61328
|
}
|
|
61330
61329
|
projectPath = resolve28(projectPath);
|
|
61331
|
-
const homeDir =
|
|
61330
|
+
const homeDir = homedir31();
|
|
61332
61331
|
if (projectPath.includes("..") || !projectPath.startsWith(homeDir)) {
|
|
61333
61332
|
res.status(400).json({ error: "Invalid path after expansion" });
|
|
61334
61333
|
return;
|
|
@@ -61385,7 +61384,7 @@ function registerProjectRoutes(app) {
|
|
|
61385
61384
|
if (id === "current") {
|
|
61386
61385
|
projectPath = process.cwd();
|
|
61387
61386
|
} else if (id === "global") {
|
|
61388
|
-
projectPath = join55(
|
|
61387
|
+
projectPath = join55(homedir31(), ".claude");
|
|
61389
61388
|
} else {
|
|
61390
61389
|
res.status(404).json({ error: "Project not found" });
|
|
61391
61390
|
return;
|
|
@@ -61465,7 +61464,7 @@ async function buildProjectInfoFromRegistry(registered, cachedSettings, cachedSk
|
|
|
61465
61464
|
const hasLocalConfig = hasClaudeDir && CkConfigManager.projectConfigExists(registered.path, false);
|
|
61466
61465
|
const settings = cachedSettings !== undefined ? cachedSettings : await readSettings();
|
|
61467
61466
|
const skills = cachedSkills !== undefined ? cachedSkills : await scanSkills();
|
|
61468
|
-
const settingsPath = join55(
|
|
61467
|
+
const settingsPath = join55(homedir31(), ".claude", "settings.json");
|
|
61469
61468
|
const health = existsSync37(settingsPath) ? "healthy" : "warning";
|
|
61470
61469
|
const model = getCurrentModel() || settings?.model || "claude-sonnet-4";
|
|
61471
61470
|
const planData = includePlanData ? await buildProjectPlanData(registered.path, "project") : null;
|
|
@@ -61507,7 +61506,7 @@ async function detectAndBuildProjectInfo(path6, id, cachedSettings, cachedSkills
|
|
|
61507
61506
|
const hasLocalConfig = CkConfigManager.projectConfigExists(path6, id === "global");
|
|
61508
61507
|
const settings = cachedSettings !== undefined ? cachedSettings : await readSettings();
|
|
61509
61508
|
const skills = cachedSkills !== undefined ? cachedSkills : await scanSkills();
|
|
61510
|
-
const settingsPath = join55(
|
|
61509
|
+
const settingsPath = join55(homedir31(), ".claude", "settings.json");
|
|
61511
61510
|
const health = existsSync37(settingsPath) ? "healthy" : "warning";
|
|
61512
61511
|
const model = getCurrentModel() || settings?.model || "claude-sonnet-4";
|
|
61513
61512
|
const scope = id === "global" ? "global" : "project";
|
|
@@ -61555,7 +61554,7 @@ var init_project_routes = __esm(() => {
|
|
|
61555
61554
|
// src/domains/web-server/routes/session-routes.ts
|
|
61556
61555
|
import { existsSync as existsSync38 } from "node:fs";
|
|
61557
61556
|
import { readFile as readFile28, readdir as readdir14, stat as stat10 } from "node:fs/promises";
|
|
61558
|
-
import { homedir as
|
|
61557
|
+
import { homedir as homedir32 } from "node:os";
|
|
61559
61558
|
import { basename as basename22, join as join56 } from "node:path";
|
|
61560
61559
|
function toDateStr(d3) {
|
|
61561
61560
|
const y3 = d3.getFullYear();
|
|
@@ -61564,7 +61563,7 @@ function toDateStr(d3) {
|
|
|
61564
61563
|
return `${y3}-${m2}-${day}`;
|
|
61565
61564
|
}
|
|
61566
61565
|
async function scanActivityMetrics(periodDays) {
|
|
61567
|
-
const home3 =
|
|
61566
|
+
const home3 = homedir32();
|
|
61568
61567
|
const projectsDir2 = join56(home3, ".claude", "projects");
|
|
61569
61568
|
const cutoff = new Date;
|
|
61570
61569
|
cutoff.setDate(cutoff.getDate() - periodDays);
|
|
@@ -61635,7 +61634,7 @@ async function scanActivityMetrics(periodDays) {
|
|
|
61635
61634
|
return { totalSessions, projects: projectActivities, dailyCounts };
|
|
61636
61635
|
}
|
|
61637
61636
|
async function resolveSessionDir(projectId) {
|
|
61638
|
-
const home3 =
|
|
61637
|
+
const home3 = homedir32();
|
|
61639
61638
|
if (projectId.startsWith("discovered-")) {
|
|
61640
61639
|
try {
|
|
61641
61640
|
const encodedPathB64 = projectId.slice("discovered-".length);
|
|
@@ -61809,7 +61808,7 @@ async function parseSessionDetail(filePath, limit, offset) {
|
|
|
61809
61808
|
}
|
|
61810
61809
|
function registerSessionRoutes(app) {
|
|
61811
61810
|
app.get("/api/sessions", async (_req, res) => {
|
|
61812
|
-
const home3 =
|
|
61811
|
+
const home3 = homedir32();
|
|
61813
61812
|
const projectsDir2 = join56(home3, ".claude", "projects");
|
|
61814
61813
|
if (!existsSync38(projectsDir2)) {
|
|
61815
61814
|
res.json({ projects: [] });
|
|
@@ -61878,7 +61877,7 @@ function registerSessionRoutes(app) {
|
|
|
61878
61877
|
res.status(404).json({ error: "Project not found" });
|
|
61879
61878
|
return;
|
|
61880
61879
|
}
|
|
61881
|
-
const allowedBase = join56(
|
|
61880
|
+
const allowedBase = join56(homedir32(), ".claude", "projects");
|
|
61882
61881
|
if (!projectDir.startsWith(allowedBase)) {
|
|
61883
61882
|
res.status(403).json({ error: "Access denied" });
|
|
61884
61883
|
return;
|
|
@@ -61908,7 +61907,7 @@ function registerSessionRoutes(app) {
|
|
|
61908
61907
|
res.status(404).json({ error: "Project not found" });
|
|
61909
61908
|
return;
|
|
61910
61909
|
}
|
|
61911
|
-
const allowedBase = join56(
|
|
61910
|
+
const allowedBase = join56(homedir32(), ".claude", "projects");
|
|
61912
61911
|
if (!projectDir.startsWith(allowedBase)) {
|
|
61913
61912
|
res.status(403).json({ error: "Access denied" });
|
|
61914
61913
|
return;
|
|
@@ -61942,7 +61941,7 @@ var init_session_routes = __esm(() => {
|
|
|
61942
61941
|
});
|
|
61943
61942
|
|
|
61944
61943
|
// src/domains/web-server/routes/settings-routes.ts
|
|
61945
|
-
import { homedir as
|
|
61944
|
+
import { homedir as homedir33 } from "node:os";
|
|
61946
61945
|
function registerSettingsRoutes(app) {
|
|
61947
61946
|
app.get("/api/settings", async (_req, res) => {
|
|
61948
61947
|
try {
|
|
@@ -61998,7 +61997,7 @@ function registerSettingsRoutes(app) {
|
|
|
61998
61997
|
res.json({
|
|
61999
61998
|
success: true,
|
|
62000
61999
|
path: "~/.claude/settings.json",
|
|
62001
|
-
backupPath: saveResult.backupPath ? saveResult.backupPath.replace(
|
|
62000
|
+
backupPath: saveResult.backupPath ? saveResult.backupPath.replace(homedir33(), "~") : null,
|
|
62002
62001
|
absolutePath: getSettingsPath()
|
|
62003
62002
|
});
|
|
62004
62003
|
} catch (error) {
|
|
@@ -62032,7 +62031,7 @@ var init_settings_routes = __esm(() => {
|
|
|
62032
62031
|
|
|
62033
62032
|
// src/domains/skills/skill-catalog-generator.ts
|
|
62034
62033
|
import { mkdir as mkdir14, readFile as readFile29, readdir as readdir15, rename as rename10, stat as stat11, writeFile as writeFile14 } from "node:fs/promises";
|
|
62035
|
-
import { homedir as
|
|
62034
|
+
import { homedir as homedir34 } from "node:os";
|
|
62036
62035
|
import { dirname as dirname25, join as join57, relative as relative15 } from "node:path";
|
|
62037
62036
|
async function hasScripts(skillPath) {
|
|
62038
62037
|
try {
|
|
@@ -62175,7 +62174,7 @@ var CATALOG_PATH, CATALOG_VERSION = "1.0.0", SKIP_DIRS4, skillCatalogGenerator;
|
|
|
62175
62174
|
var init_skill_catalog_generator = __esm(() => {
|
|
62176
62175
|
init_skills_discovery();
|
|
62177
62176
|
init_logger();
|
|
62178
|
-
CATALOG_PATH = join57(
|
|
62177
|
+
CATALOG_PATH = join57(homedir34(), ".claude", ".skills-catalog.json");
|
|
62179
62178
|
SKIP_DIRS4 = [".venv", "__pycache__", "node_modules", ".git"];
|
|
62180
62179
|
skillCatalogGenerator = new SkillCatalogGenerator;
|
|
62181
62180
|
});
|
|
@@ -62465,7 +62464,7 @@ var init_skill_browser_routes = __esm(() => {
|
|
|
62465
62464
|
|
|
62466
62465
|
// src/commands/skills/agents.ts
|
|
62467
62466
|
import { existsSync as existsSync39, readdirSync as readdirSync6, statSync as statSync8 } from "node:fs";
|
|
62468
|
-
import { homedir as
|
|
62467
|
+
import { homedir as homedir36, platform as platform5 } from "node:os";
|
|
62469
62468
|
import { join as join59 } from "node:path";
|
|
62470
62469
|
function hasInstallSignal2(path7) {
|
|
62471
62470
|
if (!path7 || !existsSync39(path7)) {
|
|
@@ -62522,7 +62521,7 @@ function isSkillInstalled(skillName, agent, options2) {
|
|
|
62522
62521
|
}
|
|
62523
62522
|
var home3, OPENCODE_BINARY_NAME2, agents;
|
|
62524
62523
|
var init_agents = __esm(() => {
|
|
62525
|
-
home3 =
|
|
62524
|
+
home3 = homedir36();
|
|
62526
62525
|
OPENCODE_BINARY_NAME2 = platform5() === "win32" ? "opencode.exe" : "opencode";
|
|
62527
62526
|
agents = {
|
|
62528
62527
|
"claude-code": {
|
|
@@ -62629,7 +62628,7 @@ var init_agents = __esm(() => {
|
|
|
62629
62628
|
// src/commands/skills/skills-registry.ts
|
|
62630
62629
|
import { existsSync as existsSync40 } from "node:fs";
|
|
62631
62630
|
import { mkdir as mkdir15, readFile as readFile31, writeFile as writeFile15 } from "node:fs/promises";
|
|
62632
|
-
import { homedir as
|
|
62631
|
+
import { homedir as homedir37 } from "node:os";
|
|
62633
62632
|
import { dirname as dirname26, join as join60, sep as sep10 } from "node:path";
|
|
62634
62633
|
function getCliVersion3() {
|
|
62635
62634
|
try {
|
|
@@ -62741,7 +62740,7 @@ async function syncRegistry() {
|
|
|
62741
62740
|
var home4, REGISTRY_PATH, SkillInstallationSchema, SkillRegistrySchema, REGISTRY_PATH_MIGRATIONS;
|
|
62742
62741
|
var init_skills_registry = __esm(() => {
|
|
62743
62742
|
init_zod();
|
|
62744
|
-
home4 =
|
|
62743
|
+
home4 = homedir37();
|
|
62745
62744
|
REGISTRY_PATH = join60(home4, ".claudekit", "skill-registry.json");
|
|
62746
62745
|
SkillInstallationSchema = exports_external.object({
|
|
62747
62746
|
skill: exports_external.string(),
|
|
@@ -62773,7 +62772,7 @@ var init_skills_registry = __esm(() => {
|
|
|
62773
62772
|
// src/commands/skills/skills-installer.ts
|
|
62774
62773
|
import { existsSync as existsSync41 } from "node:fs";
|
|
62775
62774
|
import { cp as cp3, mkdir as mkdir16, rm as rm9, stat as stat12 } from "node:fs/promises";
|
|
62776
|
-
import { homedir as
|
|
62775
|
+
import { homedir as homedir38 } from "node:os";
|
|
62777
62776
|
import { dirname as dirname27, join as join61, resolve as resolve30 } from "node:path";
|
|
62778
62777
|
function isSamePath2(path1, path22) {
|
|
62779
62778
|
try {
|
|
@@ -62904,7 +62903,7 @@ var init_skills_installer = __esm(() => {
|
|
|
62904
62903
|
LEGACY_SKILL_PATHS = {
|
|
62905
62904
|
"gemini-cli": {
|
|
62906
62905
|
project: ".gemini/skills",
|
|
62907
|
-
global: join61(
|
|
62906
|
+
global: join61(homedir38(), ".gemini/skills")
|
|
62908
62907
|
}
|
|
62909
62908
|
};
|
|
62910
62909
|
});
|
|
@@ -63853,7 +63852,7 @@ var package_default;
|
|
|
63853
63852
|
var init_package = __esm(() => {
|
|
63854
63853
|
package_default = {
|
|
63855
63854
|
name: "claudekit-cli",
|
|
63856
|
-
version: "4.3.1-dev.
|
|
63855
|
+
version: "4.3.1-dev.18",
|
|
63857
63856
|
description: "CLI tool for bootstrapping and updating ClaudeKit projects",
|
|
63858
63857
|
type: "module",
|
|
63859
63858
|
repository: {
|
|
@@ -64335,7 +64334,7 @@ var init_package_manager_runner = __esm(() => {
|
|
|
64335
64334
|
|
|
64336
64335
|
// src/domains/installation/merger/zombie-wirings-pruner.ts
|
|
64337
64336
|
import { existsSync as existsSync44, readdirSync as readdirSync7 } from "node:fs";
|
|
64338
|
-
import { homedir as
|
|
64337
|
+
import { homedir as homedir39 } from "node:os";
|
|
64339
64338
|
import { basename as basename23, dirname as dirname28, isAbsolute as isAbsolute10, resolve as resolve32, sep as sep11 } from "node:path";
|
|
64340
64339
|
function pruneZombieEngineerWirings(settings, hookDir, preserveCommands = new Set) {
|
|
64341
64340
|
const pruned = [];
|
|
@@ -64415,7 +64414,7 @@ function extractHookFilePath(command, hookDir) {
|
|
|
64415
64414
|
return null;
|
|
64416
64415
|
if (/&&|\|\||;|(?<!["|'])\|(?!["|'])/.test(command))
|
|
64417
64416
|
return null;
|
|
64418
|
-
const home5 =
|
|
64417
|
+
const home5 = homedir39().replace(/\\/g, "/");
|
|
64419
64418
|
const hookDirNorm = hookDir.replace(/\\/g, "/");
|
|
64420
64419
|
function resolveEnvPath(prefix, rest) {
|
|
64421
64420
|
const normRest = rest.replace(/\\/g, "/");
|
|
@@ -64495,7 +64494,7 @@ var init_shared2 = __esm(() => {
|
|
|
64495
64494
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
64496
64495
|
import { existsSync as existsSync45, readFileSync as readFileSync13, readdirSync as readdirSync8, statSync as statSync9, writeFileSync as writeFileSync5 } from "node:fs";
|
|
64497
64496
|
import { readdir as readdir17 } from "node:fs/promises";
|
|
64498
|
-
import { homedir as
|
|
64497
|
+
import { homedir as homedir40, tmpdir } from "node:os";
|
|
64499
64498
|
import { join as join64, resolve as resolve33 } from "node:path";
|
|
64500
64499
|
function resolveDoctorCkExecutable(platformName = process.platform) {
|
|
64501
64500
|
return platformName === "win32" ? "ck.cmd" : "ck";
|
|
@@ -64525,12 +64524,12 @@ function isPathWithin2(filePath, parentDir) {
|
|
|
64525
64524
|
}
|
|
64526
64525
|
function getCanonicalGlobalCommandRoot() {
|
|
64527
64526
|
const configuredGlobalDir = PathResolver.getGlobalKitDir().replace(/\\/g, "/").replace(/\/+$/, "");
|
|
64528
|
-
const defaultGlobalDir = join64(
|
|
64527
|
+
const defaultGlobalDir = join64(homedir40(), ".claude").replace(/\\/g, "/");
|
|
64529
64528
|
return configuredGlobalDir === defaultGlobalDir ? "$HOME" : configuredGlobalDir;
|
|
64530
64529
|
}
|
|
64531
64530
|
function getClaudeSettingsFiles(projectDir) {
|
|
64532
64531
|
const globalClaudeDir = PathResolver.getGlobalKitDir();
|
|
64533
|
-
const ccsSettingsDir = join64(process.env.CK_TEST_HOME ??
|
|
64532
|
+
const ccsSettingsDir = join64(process.env.CK_TEST_HOME ?? homedir40(), ".ccs");
|
|
64534
64533
|
const candidates = [
|
|
64535
64534
|
{
|
|
64536
64535
|
path: resolve33(projectDir, ".claude", "settings.json"),
|
|
@@ -65229,7 +65228,7 @@ function extractHookReferencePaths(cmd) {
|
|
|
65229
65228
|
}
|
|
65230
65229
|
function resolveHookScriptPath(scriptPath, projectDir) {
|
|
65231
65230
|
let resolved = scriptPath.replace(/\\/g, "/");
|
|
65232
|
-
const home5 =
|
|
65231
|
+
const home5 = homedir40();
|
|
65233
65232
|
resolved = resolved.replace(/^\$\{?HOME\}?/, home5);
|
|
65234
65233
|
resolved = resolved.replace(/^\$\{?CLAUDE_PROJECT_DIR\}?/, projectDir);
|
|
65235
65234
|
resolved = resolved.replace(/^%USERPROFILE%/, home5);
|
|
@@ -67444,6 +67443,61 @@ async function readMetadataFile(claudeDir3) {
|
|
|
67444
67443
|
return null;
|
|
67445
67444
|
}
|
|
67446
67445
|
}
|
|
67446
|
+
function extractCkHookName(command) {
|
|
67447
|
+
if (!command.trim().startsWith("node "))
|
|
67448
|
+
return null;
|
|
67449
|
+
const normalized = command.replace(/\\/g, "/");
|
|
67450
|
+
const match = normalized.match(/\/hooks\/([^/"'\s]+)\.(?:cjs|mjs|js)(?:["'\s]|$)/);
|
|
67451
|
+
return match?.[1] ?? null;
|
|
67452
|
+
}
|
|
67453
|
+
function collectSettingsHookCommands(settings) {
|
|
67454
|
+
const commands = new Set;
|
|
67455
|
+
for (const entries of Object.values(settings.hooks ?? {})) {
|
|
67456
|
+
for (const entry of entries) {
|
|
67457
|
+
if (typeof entry.command === "string") {
|
|
67458
|
+
commands.add(normalizeCommand(entry.command));
|
|
67459
|
+
}
|
|
67460
|
+
for (const hook of entry.hooks ?? []) {
|
|
67461
|
+
if (typeof hook.command === "string") {
|
|
67462
|
+
commands.add(normalizeCommand(hook.command));
|
|
67463
|
+
}
|
|
67464
|
+
}
|
|
67465
|
+
}
|
|
67466
|
+
}
|
|
67467
|
+
return commands;
|
|
67468
|
+
}
|
|
67469
|
+
function getInstalledHookCommands(config, kit) {
|
|
67470
|
+
const kits = Object.entries(config.kits ?? {});
|
|
67471
|
+
if (kits.length === 0)
|
|
67472
|
+
return [];
|
|
67473
|
+
const kitKey = kit?.toLowerCase();
|
|
67474
|
+
const preferred = kitKey ? kits.filter(([name]) => {
|
|
67475
|
+
const normalizedName = name.toLowerCase();
|
|
67476
|
+
return normalizedName === kitKey || normalizedName.includes(kitKey);
|
|
67477
|
+
}) : [];
|
|
67478
|
+
const candidates = preferred.length > 0 ? preferred : kits;
|
|
67479
|
+
return candidates.flatMap(([, entry]) => entry.installedSettings?.hooks ?? []);
|
|
67480
|
+
}
|
|
67481
|
+
async function countMissingCkHookRegistrations(claudeDir3, kit) {
|
|
67482
|
+
const settingsPath = join68(claudeDir3, "settings.json");
|
|
67483
|
+
const configPath = join68(claudeDir3, ".ck.json");
|
|
67484
|
+
if (!existsSync47(settingsPath) || !existsSync47(configPath))
|
|
67485
|
+
return 0;
|
|
67486
|
+
const settings = parseJsonContent(await import_fs_extra8.readFile(settingsPath, "utf-8"));
|
|
67487
|
+
const config = parseJsonContent(await import_fs_extra8.readFile(configPath, "utf-8"));
|
|
67488
|
+
const existingCommands = collectSettingsHookCommands(settings);
|
|
67489
|
+
const disabledHooks = new Set(Object.entries(config.hooks ?? {}).filter(([, enabled]) => enabled === false).map(([name]) => name));
|
|
67490
|
+
let missing = 0;
|
|
67491
|
+
for (const command of getInstalledHookCommands(config, kit)) {
|
|
67492
|
+
const hookName = extractCkHookName(command);
|
|
67493
|
+
if (hookName && disabledHooks.has(hookName))
|
|
67494
|
+
continue;
|
|
67495
|
+
if (!existingCommands.has(normalizeCommand(command))) {
|
|
67496
|
+
missing++;
|
|
67497
|
+
}
|
|
67498
|
+
}
|
|
67499
|
+
return missing;
|
|
67500
|
+
}
|
|
67447
67501
|
function buildInitCommand(isGlobal, kit, beta, yes, restoreCkHooks) {
|
|
67448
67502
|
const parts = ["ck init"];
|
|
67449
67503
|
if (isGlobal)
|
|
@@ -67565,6 +67619,27 @@ async function promptKitUpdate(beta, yes, deps) {
|
|
|
67565
67619
|
};
|
|
67566
67620
|
}
|
|
67567
67621
|
}
|
|
67622
|
+
const selectedClaudeDir = selection.isGlobal ? setup.global.path : setup.project.path;
|
|
67623
|
+
if (selectedClaudeDir) {
|
|
67624
|
+
try {
|
|
67625
|
+
const missingHookDeps = await findMissingHookDepsFn(selectedClaudeDir);
|
|
67626
|
+
if (missingHookDeps.length > 0) {
|
|
67627
|
+
logger.warning(`Detected ${missingHookDeps.length} ${selection.isGlobal ? "global" : "local"} missing hook dependency(ies); reinstalling kit content`);
|
|
67628
|
+
forceKitReinstall = true;
|
|
67629
|
+
}
|
|
67630
|
+
} catch (error) {
|
|
67631
|
+
logger.verbose(`Selected hook dependency self-heal check skipped: ${error instanceof Error ? error.message : "unknown"}`);
|
|
67632
|
+
}
|
|
67633
|
+
try {
|
|
67634
|
+
const missingHookRegistrations = await countMissingCkHookRegistrations(selectedClaudeDir, selection.kit);
|
|
67635
|
+
if (missingHookRegistrations > 0) {
|
|
67636
|
+
logger.warning(`Detected ${missingHookRegistrations} ${selection.isGlobal ? "global" : "local"} missing hook registration(s); reinstalling kit content`);
|
|
67637
|
+
forceKitReinstall = true;
|
|
67638
|
+
}
|
|
67639
|
+
} catch (error) {
|
|
67640
|
+
logger.verbose(`Selected hook registration self-heal check skipped: ${error instanceof Error ? error.message : "unknown"}`);
|
|
67641
|
+
}
|
|
67642
|
+
}
|
|
67568
67643
|
let kitVersion = selection.kit ? selection.isGlobal ? globalMetadata?.kits?.[selection.kit]?.version : localMetadata?.kits?.[selection.kit]?.version : undefined;
|
|
67569
67644
|
const isBetaInstalled = isBetaVersion(kitVersion);
|
|
67570
67645
|
const promptMessage = selection.promptMessage;
|
|
@@ -67834,6 +67909,7 @@ var init_post_update_handler = __esm(() => {
|
|
|
67834
67909
|
init_metadata_migration();
|
|
67835
67910
|
init_version_utils();
|
|
67836
67911
|
init_claudekit_scanner();
|
|
67912
|
+
init_command_normalizer();
|
|
67837
67913
|
init_logger();
|
|
67838
67914
|
init_safe_prompts();
|
|
67839
67915
|
init_types3();
|
|
@@ -68239,7 +68315,7 @@ import { spawn as spawn3 } from "node:child_process";
|
|
|
68239
68315
|
import { execFile as execFile8 } from "node:child_process";
|
|
68240
68316
|
import { existsSync as existsSync48 } from "node:fs";
|
|
68241
68317
|
import { readFile as readFile38 } from "node:fs/promises";
|
|
68242
|
-
import { cpus, homedir as
|
|
68318
|
+
import { cpus, homedir as homedir41, totalmem } from "node:os";
|
|
68243
68319
|
import { join as join70 } from "node:path";
|
|
68244
68320
|
function runCommand(cmd, args, fallback2) {
|
|
68245
68321
|
return new Promise((resolve34) => {
|
|
@@ -68405,7 +68481,7 @@ function registerSystemRoutes(app) {
|
|
|
68405
68481
|
gitVersion,
|
|
68406
68482
|
ghVersion,
|
|
68407
68483
|
shell: process.env.SHELL ?? process.env.ComSpec ?? "unknown",
|
|
68408
|
-
homeDir:
|
|
68484
|
+
homeDir: homedir41(),
|
|
68409
68485
|
cpuCores: cpus().length,
|
|
68410
68486
|
totalMemoryGb: (totalmem() / 1024 ** 3).toFixed(1)
|
|
68411
68487
|
};
|
|
@@ -74367,10 +74443,10 @@ var init_config_manager2 = __esm(() => {
|
|
|
74367
74443
|
|
|
74368
74444
|
// src/services/package-installer/gemini-mcp/validation.ts
|
|
74369
74445
|
import { existsSync as existsSync63, lstatSync, readlinkSync } from "node:fs";
|
|
74370
|
-
import { homedir as
|
|
74446
|
+
import { homedir as homedir44 } from "node:os";
|
|
74371
74447
|
import { join as join93 } from "node:path";
|
|
74372
74448
|
function getGlobalMcpConfigPath() {
|
|
74373
|
-
return join93(
|
|
74449
|
+
return join93(homedir44(), ".claude", ".mcp.json");
|
|
74374
74450
|
}
|
|
74375
74451
|
function getLocalMcpConfigPath(projectDir) {
|
|
74376
74452
|
return join93(projectDir, ".mcp.json");
|
|
@@ -74391,7 +74467,7 @@ function findMcpConfigPath(projectDir) {
|
|
|
74391
74467
|
}
|
|
74392
74468
|
function getGeminiSettingsPath(projectDir, isGlobal) {
|
|
74393
74469
|
if (isGlobal) {
|
|
74394
|
-
return join93(
|
|
74470
|
+
return join93(homedir44(), ".gemini", "settings.json");
|
|
74395
74471
|
}
|
|
74396
74472
|
return join93(projectDir, ".gemini", "settings.json");
|
|
74397
74473
|
}
|
|
@@ -77019,7 +77095,7 @@ var init_content_validator = __esm(() => {
|
|
|
77019
77095
|
import { createHash as createHash9 } from "node:crypto";
|
|
77020
77096
|
import { existsSync as existsSync79, mkdirSync as mkdirSync5, readFileSync as readFileSync19, readdirSync as readdirSync13, statSync as statSync14 } from "node:fs";
|
|
77021
77097
|
import { rename as rename16, writeFile as writeFile40 } from "node:fs/promises";
|
|
77022
|
-
import { homedir as
|
|
77098
|
+
import { homedir as homedir54 } from "node:os";
|
|
77023
77099
|
import { basename as basename34, join as join160 } from "node:path";
|
|
77024
77100
|
function getCachedContext(repoPath) {
|
|
77025
77101
|
const cachePath = getCacheFilePath(repoPath);
|
|
@@ -77094,7 +77170,7 @@ function getCacheFilePath(repoPath) {
|
|
|
77094
77170
|
}
|
|
77095
77171
|
var CACHE_DIR, CACHE_TTL_MS5;
|
|
77096
77172
|
var init_context_cache_manager = __esm(() => {
|
|
77097
|
-
CACHE_DIR = join160(
|
|
77173
|
+
CACHE_DIR = join160(homedir54(), ".claudekit", "cache");
|
|
77098
77174
|
CACHE_TTL_MS5 = 24 * 60 * 60 * 1000;
|
|
77099
77175
|
});
|
|
77100
77176
|
|
|
@@ -77548,10 +77624,10 @@ IMPORTANT: Generate the image and output the path as JSON: {"imagePath": "/path/
|
|
|
77548
77624
|
// src/commands/content/phases/photo-generator.ts
|
|
77549
77625
|
import { execSync as execSync8 } from "node:child_process";
|
|
77550
77626
|
import { existsSync as existsSync81, mkdirSync as mkdirSync6, readdirSync as readdirSync15 } from "node:fs";
|
|
77551
|
-
import { homedir as
|
|
77627
|
+
import { homedir as homedir55 } from "node:os";
|
|
77552
77628
|
import { join as join162 } from "node:path";
|
|
77553
77629
|
async function generatePhoto(_content, context, config, platform18, contentId, contentLogger) {
|
|
77554
|
-
const mediaDir = join162(config.contentDir.replace(/^~/,
|
|
77630
|
+
const mediaDir = join162(config.contentDir.replace(/^~/, homedir55()), "media", String(contentId));
|
|
77555
77631
|
if (!existsSync81(mediaDir)) {
|
|
77556
77632
|
mkdirSync6(mediaDir, { recursive: true });
|
|
77557
77633
|
}
|
|
@@ -77665,7 +77741,7 @@ var init_content_creator = __esm(() => {
|
|
|
77665
77741
|
|
|
77666
77742
|
// src/commands/content/phases/content-logger.ts
|
|
77667
77743
|
import { createWriteStream as createWriteStream4, existsSync as existsSync82, mkdirSync as mkdirSync7, statSync as statSync15 } from "node:fs";
|
|
77668
|
-
import { homedir as
|
|
77744
|
+
import { homedir as homedir56 } from "node:os";
|
|
77669
77745
|
import { join as join163 } from "node:path";
|
|
77670
77746
|
|
|
77671
77747
|
class ContentLogger {
|
|
@@ -77674,7 +77750,7 @@ class ContentLogger {
|
|
|
77674
77750
|
logDir;
|
|
77675
77751
|
maxBytes;
|
|
77676
77752
|
constructor(maxBytes = 0) {
|
|
77677
|
-
this.logDir = join163(
|
|
77753
|
+
this.logDir = join163(homedir56(), ".claudekit", "logs");
|
|
77678
77754
|
this.maxBytes = maxBytes;
|
|
77679
77755
|
}
|
|
77680
77756
|
init() {
|
|
@@ -79285,11 +79361,11 @@ var init_setup_wizard = __esm(() => {
|
|
|
79285
79361
|
|
|
79286
79362
|
// src/commands/content/content-review-commands.ts
|
|
79287
79363
|
import { existsSync as existsSync86 } from "node:fs";
|
|
79288
|
-
import { homedir as
|
|
79364
|
+
import { homedir as homedir57 } from "node:os";
|
|
79289
79365
|
async function queueContent() {
|
|
79290
79366
|
const cwd2 = process.cwd();
|
|
79291
79367
|
const config = await loadContentConfig(cwd2);
|
|
79292
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
79368
|
+
const dbPath = config.dbPath.replace(/^~/, homedir57());
|
|
79293
79369
|
if (!existsSync86(dbPath)) {
|
|
79294
79370
|
logger.info("No content database found. Run 'ck content setup' first.");
|
|
79295
79371
|
return;
|
|
@@ -79316,7 +79392,7 @@ async function queueContent() {
|
|
|
79316
79392
|
async function approveContentCmd(id) {
|
|
79317
79393
|
const cwd2 = process.cwd();
|
|
79318
79394
|
const config = await loadContentConfig(cwd2);
|
|
79319
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
79395
|
+
const dbPath = config.dbPath.replace(/^~/, homedir57());
|
|
79320
79396
|
const db = initDatabase(dbPath);
|
|
79321
79397
|
try {
|
|
79322
79398
|
approveContent(db, Number.parseInt(id, 10));
|
|
@@ -79328,7 +79404,7 @@ async function approveContentCmd(id) {
|
|
|
79328
79404
|
async function rejectContentCmd(id, reason) {
|
|
79329
79405
|
const cwd2 = process.cwd();
|
|
79330
79406
|
const config = await loadContentConfig(cwd2);
|
|
79331
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
79407
|
+
const dbPath = config.dbPath.replace(/^~/, homedir57());
|
|
79332
79408
|
const db = initDatabase(dbPath);
|
|
79333
79409
|
try {
|
|
79334
79410
|
rejectContent(db, Number.parseInt(id, 10), reason);
|
|
@@ -79359,7 +79435,7 @@ __export(exports_content_subcommands, {
|
|
|
79359
79435
|
approveContentCmd: () => approveContentCmd
|
|
79360
79436
|
});
|
|
79361
79437
|
import { existsSync as existsSync87, readFileSync as readFileSync22, unlinkSync as unlinkSync6 } from "node:fs";
|
|
79362
|
-
import { homedir as
|
|
79438
|
+
import { homedir as homedir58 } from "node:os";
|
|
79363
79439
|
import { join as join168 } from "node:path";
|
|
79364
79440
|
function isDaemonRunning() {
|
|
79365
79441
|
const lockFile = join168(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
@@ -79433,7 +79509,7 @@ async function statusContent() {
|
|
|
79433
79509
|
} catch {}
|
|
79434
79510
|
}
|
|
79435
79511
|
async function logsContent(options2) {
|
|
79436
|
-
const logDir = join168(
|
|
79512
|
+
const logDir = join168(homedir58(), ".claudekit", "logs");
|
|
79437
79513
|
const dateStr = new Date().toISOString().slice(0, 10).replace(/-/g, "");
|
|
79438
79514
|
const logPath = join168(logDir, `content-${dateStr}.log`);
|
|
79439
79515
|
if (!existsSync87(logPath)) {
|
|
@@ -79467,12 +79543,12 @@ var init_content_subcommands = __esm(() => {
|
|
|
79467
79543
|
init_setup_wizard();
|
|
79468
79544
|
init_state_manager();
|
|
79469
79545
|
init_content_review_commands();
|
|
79470
|
-
LOCK_DIR = join168(
|
|
79546
|
+
LOCK_DIR = join168(homedir58(), ".claudekit", "locks");
|
|
79471
79547
|
});
|
|
79472
79548
|
|
|
79473
79549
|
// src/commands/content/content-command.ts
|
|
79474
79550
|
import { existsSync as existsSync88, mkdirSync as mkdirSync9, unlinkSync as unlinkSync7, writeFileSync as writeFileSync7 } from "node:fs";
|
|
79475
|
-
import { homedir as
|
|
79551
|
+
import { homedir as homedir59 } from "node:os";
|
|
79476
79552
|
import { join as join169 } from "node:path";
|
|
79477
79553
|
async function contentCommand(options2) {
|
|
79478
79554
|
const cwd2 = process.cwd();
|
|
@@ -79505,7 +79581,7 @@ async function contentCommand(options2) {
|
|
|
79505
79581
|
if (!existsSync88(LOCK_DIR2))
|
|
79506
79582
|
mkdirSync9(LOCK_DIR2, { recursive: true });
|
|
79507
79583
|
writeFileSync7(LOCK_FILE, String(process.pid), "utf-8");
|
|
79508
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
79584
|
+
const dbPath = config.dbPath.replace(/^~/, homedir59());
|
|
79509
79585
|
const db = initDatabase(dbPath);
|
|
79510
79586
|
contentLogger.info(`Database initialised at ${dbPath}`);
|
|
79511
79587
|
const adapters = initializeAdapters(config);
|
|
@@ -79651,7 +79727,7 @@ var init_content_command = __esm(() => {
|
|
|
79651
79727
|
init_publisher();
|
|
79652
79728
|
init_review_manager();
|
|
79653
79729
|
init_state_manager();
|
|
79654
|
-
LOCK_DIR2 = join169(
|
|
79730
|
+
LOCK_DIR2 = join169(homedir59(), ".claudekit", "locks");
|
|
79655
79731
|
LOCK_FILE = join169(LOCK_DIR2, "ck-content.lock");
|
|
79656
79732
|
});
|
|
79657
79733
|
|
|
@@ -82872,9 +82948,9 @@ var import_picocolors6 = __toESM(require_picocolors(), 1);
|
|
|
82872
82948
|
init_fm_to_json();
|
|
82873
82949
|
init_portable_registry();
|
|
82874
82950
|
init_provider_registry();
|
|
82875
|
-
import { existsSync as
|
|
82951
|
+
import { existsSync as existsSync7 } from "node:fs";
|
|
82876
82952
|
import { readFile as readFile6, rm, writeFile as writeFile4 } from "node:fs/promises";
|
|
82877
|
-
import { dirname as dirname4, join as
|
|
82953
|
+
import { dirname as dirname4, join as join8 } from "node:path";
|
|
82878
82954
|
function toSlug3(name) {
|
|
82879
82955
|
return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
82880
82956
|
}
|
|
@@ -82994,7 +83070,7 @@ async function removeFromJsonMerge(agentName, filePath) {
|
|
|
82994
83070
|
const rulesDir = dirname4(filePath);
|
|
82995
83071
|
const ruleNames = new Set([`${agentName}.md`, `${slug}.md`]);
|
|
82996
83072
|
for (const ruleName of ruleNames) {
|
|
82997
|
-
await rm(
|
|
83073
|
+
await rm(join8(rulesDir, ruleName), { force: true });
|
|
82998
83074
|
}
|
|
82999
83075
|
if (filtered.length === 0) {
|
|
83000
83076
|
await rm(filePath, { force: true });
|
|
@@ -83024,7 +83100,7 @@ async function uninstallAgentFromProvider(agentName, provider, global2) {
|
|
|
83024
83100
|
};
|
|
83025
83101
|
}
|
|
83026
83102
|
const installation = installations[0];
|
|
83027
|
-
const fileExists =
|
|
83103
|
+
const fileExists = existsSync7(installation.path);
|
|
83028
83104
|
try {
|
|
83029
83105
|
const config = providers[provider];
|
|
83030
83106
|
const pathConfig = config.agents;
|
|
@@ -83113,8 +83189,8 @@ async function forceUninstallAgentFromProvider(agentName, provider, global2) {
|
|
|
83113
83189
|
};
|
|
83114
83190
|
}
|
|
83115
83191
|
const writeStrategy = pathConfig.writeStrategy;
|
|
83116
|
-
const targetPath = writeStrategy === "json-merge" ?
|
|
83117
|
-
const fileExists =
|
|
83192
|
+
const targetPath = writeStrategy === "json-merge" ? join8(basePath, "cline_custom_modes.json") : writeStrategy === "merge-single" || writeStrategy === "yaml-merge" || writeStrategy === "single-file" ? basePath : join8(basePath, `${agentName}${pathConfig.fileExtension}`);
|
|
83193
|
+
const fileExists = existsSync7(targetPath);
|
|
83118
83194
|
try {
|
|
83119
83195
|
if (!fileExists) {
|
|
83120
83196
|
return {
|
|
@@ -83633,7 +83709,7 @@ var import_picocolors8 = __toESM(require_picocolors(), 1);
|
|
|
83633
83709
|
|
|
83634
83710
|
// src/domains/claudekit-api/index.ts
|
|
83635
83711
|
import { homedir as homedir7 } from "node:os";
|
|
83636
|
-
import { join as
|
|
83712
|
+
import { join as join10 } from "node:path";
|
|
83637
83713
|
|
|
83638
83714
|
// src/domains/api-key/validator.ts
|
|
83639
83715
|
var API_BASE_URL = "https://claudekit.cc/api";
|
|
@@ -83680,20 +83756,20 @@ function isValidKeyFormat(key) {
|
|
|
83680
83756
|
return /^ck_live_[A-Za-z0-9_-]{32}$/.test(key);
|
|
83681
83757
|
}
|
|
83682
83758
|
// src/domains/api-key/storage.ts
|
|
83683
|
-
import { existsSync as
|
|
83684
|
-
import { join as
|
|
83759
|
+
import { existsSync as existsSync8, readFileSync as readFileSync4, writeFileSync } from "node:fs";
|
|
83760
|
+
import { join as join9 } from "node:path";
|
|
83685
83761
|
var ENV_FILE = ".env";
|
|
83686
83762
|
var API_KEY_VAR = "CLAUDEKIT_API_KEY";
|
|
83687
83763
|
function getEnvFilePath(claudeDir) {
|
|
83688
|
-
return
|
|
83764
|
+
return join9(claudeDir, ENV_FILE);
|
|
83689
83765
|
}
|
|
83690
83766
|
function readExistingApiKey(claudeDir) {
|
|
83691
83767
|
const envPath = getEnvFilePath(claudeDir);
|
|
83692
|
-
if (!
|
|
83768
|
+
if (!existsSync8(envPath)) {
|
|
83693
83769
|
return null;
|
|
83694
83770
|
}
|
|
83695
83771
|
try {
|
|
83696
|
-
const content =
|
|
83772
|
+
const content = readFileSync4(envPath, "utf-8");
|
|
83697
83773
|
const match = content.match(new RegExp(`^${API_KEY_VAR}=(.+)$`, "m"));
|
|
83698
83774
|
return match?.[1]?.trim() ?? null;
|
|
83699
83775
|
} catch {
|
|
@@ -83703,8 +83779,8 @@ function readExistingApiKey(claudeDir) {
|
|
|
83703
83779
|
function saveApiKey(claudeDir, apiKey) {
|
|
83704
83780
|
const envPath = getEnvFilePath(claudeDir);
|
|
83705
83781
|
let content = "";
|
|
83706
|
-
if (
|
|
83707
|
-
content =
|
|
83782
|
+
if (existsSync8(envPath)) {
|
|
83783
|
+
content = readFileSync4(envPath, "utf-8");
|
|
83708
83784
|
if (content.includes(`${API_KEY_VAR}=`)) {
|
|
83709
83785
|
content = content.replace(new RegExp(`^${API_KEY_VAR}=.*$`, "m"), `${API_KEY_VAR}=${apiKey}`);
|
|
83710
83786
|
} else {
|
|
@@ -83860,7 +83936,7 @@ class ClaudekitHttpClient {
|
|
|
83860
83936
|
} catch (error) {
|
|
83861
83937
|
if (error instanceof CkApiError && error.code === "RATE_LIMIT_EXCEEDED" && error.retryAfter) {
|
|
83862
83938
|
const delayMs = error.retryAfter * 1000;
|
|
83863
|
-
await new Promise((
|
|
83939
|
+
await new Promise((resolve5) => setTimeout(resolve5, delayMs));
|
|
83864
83940
|
return fn();
|
|
83865
83941
|
}
|
|
83866
83942
|
throw error;
|
|
@@ -83870,7 +83946,7 @@ class ClaudekitHttpClient {
|
|
|
83870
83946
|
|
|
83871
83947
|
// src/domains/claudekit-api/index.ts
|
|
83872
83948
|
function createApiClient(claudeDir) {
|
|
83873
|
-
const dir = claudeDir ??
|
|
83949
|
+
const dir = claudeDir ?? join10(homedir7(), ".claude");
|
|
83874
83950
|
const apiKey = readExistingApiKey(dir);
|
|
83875
83951
|
if (!apiKey) {
|
|
83876
83952
|
throw new CkApiError("MISSING_API_KEY", "No API key found. Run `ck api setup` to configure your ClaudeKit API key.", 401);
|
|
@@ -84301,13 +84377,13 @@ async function handleApiServices(options2) {
|
|
|
84301
84377
|
|
|
84302
84378
|
// src/commands/api/subcommands/api-setup-handler.ts
|
|
84303
84379
|
import { homedir as homedir8 } from "node:os";
|
|
84304
|
-
import { join as
|
|
84380
|
+
import { join as join11 } from "node:path";
|
|
84305
84381
|
init_logger();
|
|
84306
84382
|
init_dist2();
|
|
84307
84383
|
var DASHBOARD_URL = "https://claudekit.cc/api-keys";
|
|
84308
84384
|
var MAX_ATTEMPTS = 3;
|
|
84309
84385
|
async function handleApiSetup(options2) {
|
|
84310
|
-
const claudeDir =
|
|
84386
|
+
const claudeDir = join11(homedir8(), ".claude");
|
|
84311
84387
|
const existing = readExistingApiKey(claudeDir);
|
|
84312
84388
|
if (existing && !options2.force) {
|
|
84313
84389
|
const masked = `${existing.slice(0, 15)}...`;
|
|
@@ -88291,7 +88367,7 @@ init_logger();
|
|
|
88291
88367
|
init_path_resolver();
|
|
88292
88368
|
import { existsSync as existsSync58 } from "node:fs";
|
|
88293
88369
|
import { readFile as readFile42 } from "node:fs/promises";
|
|
88294
|
-
import { homedir as
|
|
88370
|
+
import { homedir as homedir42 } from "node:os";
|
|
88295
88371
|
import { dirname as dirname31, join as join80, normalize as normalize6, resolve as resolve36 } from "node:path";
|
|
88296
88372
|
async function checkPathRefsValid(projectDir) {
|
|
88297
88373
|
const globalClaudeMd = join80(PathResolver.getGlobalKitDir(), "CLAUDE.md");
|
|
@@ -88324,7 +88400,7 @@ async function checkPathRefsValid(projectDir) {
|
|
|
88324
88400
|
};
|
|
88325
88401
|
}
|
|
88326
88402
|
const baseDir = dirname31(claudeMdPath);
|
|
88327
|
-
const home5 =
|
|
88403
|
+
const home5 = homedir42();
|
|
88328
88404
|
const broken = [];
|
|
88329
88405
|
for (const ref of refs) {
|
|
88330
88406
|
let refPath;
|
|
@@ -89328,7 +89404,7 @@ import { platform as platform8 } from "node:os";
|
|
|
89328
89404
|
init_environment();
|
|
89329
89405
|
init_path_resolver();
|
|
89330
89406
|
import { constants as constants3, access as access4, mkdir as mkdir21, readFile as readFile44, unlink as unlink11, writeFile as writeFile21 } from "node:fs/promises";
|
|
89331
|
-
import { arch as arch2, homedir as
|
|
89407
|
+
import { arch as arch2, homedir as homedir43, platform as platform7 } from "node:os";
|
|
89332
89408
|
import { join as join85, normalize as normalize7 } from "node:path";
|
|
89333
89409
|
function shouldSkipExpensiveOperations4() {
|
|
89334
89410
|
return shouldSkipExpensiveOperations();
|
|
@@ -89351,7 +89427,7 @@ async function checkPlatformDetect() {
|
|
|
89351
89427
|
};
|
|
89352
89428
|
}
|
|
89353
89429
|
async function checkHomeDirResolution() {
|
|
89354
|
-
const nodeHome = normalize7(
|
|
89430
|
+
const nodeHome = normalize7(homedir43());
|
|
89355
89431
|
const rawEnvHome = getHomeDirectoryFromEnv(platform7());
|
|
89356
89432
|
const envHome = rawEnvHome ? normalize7(rawEnvHome) : "";
|
|
89357
89433
|
const match = nodeHome === envHome && envHome !== "";
|
|
@@ -103436,7 +103512,7 @@ class FileScanner {
|
|
|
103436
103512
|
|
|
103437
103513
|
// src/domains/installation/merger/settings-processor.ts
|
|
103438
103514
|
import { execSync as execSync5 } from "node:child_process";
|
|
103439
|
-
import { homedir as
|
|
103515
|
+
import { homedir as homedir45 } from "node:os";
|
|
103440
103516
|
import { dirname as dirname39, join as join109 } from "node:path";
|
|
103441
103517
|
|
|
103442
103518
|
// src/domains/config/installed-settings-tracker.ts
|
|
@@ -104053,7 +104129,7 @@ class SettingsProcessor {
|
|
|
104053
104129
|
return false;
|
|
104054
104130
|
}
|
|
104055
104131
|
const configuredGlobalDir = PathResolver.getGlobalKitDir().replace(/\\/g, "/").replace(/\/+$/, "");
|
|
104056
|
-
const defaultGlobalDir = join109(
|
|
104132
|
+
const defaultGlobalDir = join109(homedir45(), ".claude").replace(/\\/g, "/");
|
|
104057
104133
|
return configuredGlobalDir !== defaultGlobalDir;
|
|
104058
104134
|
}
|
|
104059
104135
|
getClaudeCommandRoot() {
|
|
@@ -107750,7 +107826,7 @@ async function handleFreshInstallation(claudeDir3, prompts) {
|
|
|
107750
107826
|
// src/domains/installation/global-kit-legacy-repair.ts
|
|
107751
107827
|
var import_fs_extra35 = __toESM(require_lib(), 1);
|
|
107752
107828
|
import { cp as cp5, mkdir as mkdir35, readdir as readdir42, rename as rename11, rm as rm16, stat as stat22 } from "node:fs/promises";
|
|
107753
|
-
import { homedir as
|
|
107829
|
+
import { homedir as homedir46 } from "node:os";
|
|
107754
107830
|
import { dirname as dirname42, join as join133, normalize as normalize11, resolve as resolve46 } from "node:path";
|
|
107755
107831
|
var LEGACY_KIT_MARKERS = [
|
|
107756
107832
|
"metadata.json",
|
|
@@ -107785,7 +107861,7 @@ function uniqueNormalizedPaths(paths) {
|
|
|
107785
107861
|
}
|
|
107786
107862
|
return result;
|
|
107787
107863
|
}
|
|
107788
|
-
function getLegacyWindowsGlobalKitDirCandidates(env2 = process.env, homeDir =
|
|
107864
|
+
function getLegacyWindowsGlobalKitDirCandidates(env2 = process.env, homeDir = homedir46()) {
|
|
107789
107865
|
const candidates = [];
|
|
107790
107866
|
const localAppData = safeEnvPath(env2.LOCALAPPDATA);
|
|
107791
107867
|
const appData = safeEnvPath(env2.APPDATA);
|
|
@@ -108918,7 +108994,7 @@ async function transformFolderPaths(extractDir, folders, options2 = {}) {
|
|
|
108918
108994
|
// src/services/transformers/global-path-transformer.ts
|
|
108919
108995
|
init_logger();
|
|
108920
108996
|
import { readFile as readFile61, readdir as readdir44, writeFile as writeFile35 } from "node:fs/promises";
|
|
108921
|
-
import { homedir as
|
|
108997
|
+
import { homedir as homedir47, platform as platform15 } from "node:os";
|
|
108922
108998
|
import { extname as extname7, join as join138 } from "node:path";
|
|
108923
108999
|
var IS_WINDOWS3 = platform15() === "win32";
|
|
108924
109000
|
var HOME_PREFIX = "$HOME";
|
|
@@ -108929,7 +109005,7 @@ function normalizeInstallPath(path17) {
|
|
|
108929
109005
|
return path17.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
108930
109006
|
}
|
|
108931
109007
|
function getDefaultGlobalClaudeDir() {
|
|
108932
|
-
return normalizeInstallPath(join138(
|
|
109008
|
+
return normalizeInstallPath(join138(homedir47(), ".claude"));
|
|
108933
109009
|
}
|
|
108934
109010
|
function getCustomGlobalClaudeDir(targetClaudeDir) {
|
|
108935
109011
|
if (!targetClaudeDir)
|
|
@@ -109361,13 +109437,13 @@ init_dist2();
|
|
|
109361
109437
|
var import_picocolors30 = __toESM(require_picocolors(), 1);
|
|
109362
109438
|
import { existsSync as existsSync68 } from "node:fs";
|
|
109363
109439
|
import { readFile as readFile65, rm as rm18, unlink as unlink14 } from "node:fs/promises";
|
|
109364
|
-
import { homedir as
|
|
109440
|
+
import { homedir as homedir52 } from "node:os";
|
|
109365
109441
|
import { basename as basename30, join as join143, resolve as resolve50 } from "node:path";
|
|
109366
109442
|
init_logger();
|
|
109367
109443
|
|
|
109368
109444
|
// src/ui/ck-cli-design/tokens.ts
|
|
109369
109445
|
var import_picocolors27 = __toESM(require_picocolors(), 1);
|
|
109370
|
-
import { homedir as
|
|
109446
|
+
import { homedir as homedir48, platform as platform16 } from "node:os";
|
|
109371
109447
|
import { resolve as resolve49, win32 as win322 } from "node:path";
|
|
109372
109448
|
var PANEL_MIN_WIDTH = 60;
|
|
109373
109449
|
var PANEL_MAX_WIDTH = 72;
|
|
@@ -109525,7 +109601,7 @@ function wrapText(value, width) {
|
|
|
109525
109601
|
}
|
|
109526
109602
|
function formatDisplayPath(value) {
|
|
109527
109603
|
const normalized = value.replace(/\\/g, "/");
|
|
109528
|
-
const home5 =
|
|
109604
|
+
const home5 = homedir48().replace(/\\/g, "/");
|
|
109529
109605
|
if (normalized === home5)
|
|
109530
109606
|
return "~";
|
|
109531
109607
|
if (normalized.startsWith(`${home5}/`)) {
|
|
@@ -109839,13 +109915,13 @@ init_logger();
|
|
|
109839
109915
|
init_dist2();
|
|
109840
109916
|
init_model_taxonomy();
|
|
109841
109917
|
import { mkdir as mkdir39, readFile as readFile64, writeFile as writeFile37 } from "node:fs/promises";
|
|
109842
|
-
import { homedir as
|
|
109918
|
+
import { homedir as homedir51 } from "node:os";
|
|
109843
109919
|
import { dirname as dirname44, join as join142 } from "node:path";
|
|
109844
109920
|
|
|
109845
109921
|
// src/commands/portable/models-dev-cache.ts
|
|
109846
109922
|
init_logger();
|
|
109847
109923
|
import { mkdir as mkdir38, readFile as readFile62, rename as rename14, writeFile as writeFile36 } from "node:fs/promises";
|
|
109848
|
-
import { homedir as
|
|
109924
|
+
import { homedir as homedir49 } from "node:os";
|
|
109849
109925
|
import { join as join140 } from "node:path";
|
|
109850
109926
|
|
|
109851
109927
|
class ModelsDevUnavailableError extends Error {
|
|
@@ -109858,7 +109934,7 @@ var MODELS_DEV_URL = "https://models.dev/api.json";
|
|
|
109858
109934
|
var CACHE_TTL_MS3 = 24 * 60 * 60 * 1000;
|
|
109859
109935
|
var FETCH_TIMEOUT_MS = 1e4;
|
|
109860
109936
|
function defaultCacheDir() {
|
|
109861
|
-
return join140(
|
|
109937
|
+
return join140(homedir49(), ".config", "claudekit", "cache");
|
|
109862
109938
|
}
|
|
109863
109939
|
function cacheFilePath(cacheDir) {
|
|
109864
109940
|
return join140(cacheDir, "models-dev.json");
|
|
@@ -109938,7 +110014,7 @@ async function getModelsDevCatalog(opts = {}) {
|
|
|
109938
110014
|
// src/commands/portable/opencode-model-discovery.ts
|
|
109939
110015
|
init_logger();
|
|
109940
110016
|
import { readFile as readFile63 } from "node:fs/promises";
|
|
109941
|
-
import { homedir as
|
|
110017
|
+
import { homedir as homedir50, platform as platform17 } from "node:os";
|
|
109942
110018
|
import { join as join141 } from "node:path";
|
|
109943
110019
|
function resolveOpenCodeAuthPath(homeDir) {
|
|
109944
110020
|
if (platform17() === "win32") {
|
|
@@ -109984,7 +110060,7 @@ function pickGenericModel(models) {
|
|
|
109984
110060
|
return sorted[0] ?? null;
|
|
109985
110061
|
}
|
|
109986
110062
|
async function resolveOpenCodeDefaultModel(opts = {}) {
|
|
109987
|
-
const home5 = opts.homeDir ??
|
|
110063
|
+
const home5 = opts.homeDir ?? homedir50();
|
|
109988
110064
|
const authedProviders = await readAuthedProviders(home5);
|
|
109989
110065
|
if (authedProviders.length === 0) {
|
|
109990
110066
|
return { ok: false, reason: "no-auth", authedProviders: [] };
|
|
@@ -110048,7 +110124,7 @@ function messageForReason(reason) {
|
|
|
110048
110124
|
}
|
|
110049
110125
|
function getOpenCodeConfigPath(options2) {
|
|
110050
110126
|
if (options2.global) {
|
|
110051
|
-
return join142(options2.homeDir ??
|
|
110127
|
+
return join142(options2.homeDir ?? homedir51(), ".config", "opencode", "opencode.json");
|
|
110052
110128
|
}
|
|
110053
110129
|
return join142(options2.cwd ?? process.cwd(), "opencode.json");
|
|
110054
110130
|
}
|
|
@@ -111055,7 +111131,7 @@ async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
|
111055
111131
|
}
|
|
111056
111132
|
if (!sourceMetadata.deletions || sourceMetadata.deletions.length === 0)
|
|
111057
111133
|
return;
|
|
111058
|
-
const claudeDir3 = installGlobally ? join143(
|
|
111134
|
+
const claudeDir3 = installGlobally ? join143(homedir52(), ".claude") : join143(process.cwd(), ".claude");
|
|
111059
111135
|
if (!existsSync68(claudeDir3))
|
|
111060
111136
|
return;
|
|
111061
111137
|
try {
|
|
@@ -111184,7 +111260,7 @@ async function migrateCommand(options2) {
|
|
|
111184
111260
|
let installGlobally = requestedGlobal;
|
|
111185
111261
|
if (options2.global === undefined && !options2.yes) {
|
|
111186
111262
|
const projectTarget = join143(process.cwd(), ".claude");
|
|
111187
|
-
const globalTarget = join143(
|
|
111263
|
+
const globalTarget = join143(homedir52(), ".claude");
|
|
111188
111264
|
const scopeChoice = await ie({
|
|
111189
111265
|
message: "Installation scope",
|
|
111190
111266
|
options: [
|
|
@@ -111257,7 +111333,7 @@ async function migrateCommand(options2) {
|
|
|
111257
111333
|
}).join(`
|
|
111258
111334
|
`));
|
|
111259
111335
|
if (sourceGlobalOnly) {
|
|
111260
|
-
f2.info(import_picocolors30.default.dim(` Scope: global (--global / -g) - reading from ${formatDisplayPath(join143(
|
|
111336
|
+
f2.info(import_picocolors30.default.dim(` Scope: global (--global / -g) - reading from ${formatDisplayPath(join143(homedir52(), ".claude"))}`));
|
|
111261
111337
|
} else {
|
|
111262
111338
|
f2.info(import_picocolors30.default.dim(` CWD: ${process.cwd()}`));
|
|
111263
111339
|
}
|
|
@@ -116286,7 +116362,7 @@ async function scanForRepos(parentDir) {
|
|
|
116286
116362
|
init_logger();
|
|
116287
116363
|
import { spawnSync as spawnSync8 } from "node:child_process";
|
|
116288
116364
|
import { existsSync as existsSync76 } from "node:fs";
|
|
116289
|
-
import { homedir as
|
|
116365
|
+
import { homedir as homedir53 } from "node:os";
|
|
116290
116366
|
import { join as join157 } from "node:path";
|
|
116291
116367
|
async function validateSetup(cwd2) {
|
|
116292
116368
|
const workDir = cwd2 ?? process.cwd();
|
|
@@ -116318,7 +116394,7 @@ Run this command from a directory with a GitHub remote.`);
|
|
|
116318
116394
|
} catch {
|
|
116319
116395
|
throw new Error(`Failed to parse repository info: ${ghRepo.stdout}`);
|
|
116320
116396
|
}
|
|
116321
|
-
const skillsPath = join157(
|
|
116397
|
+
const skillsPath = join157(homedir53(), ".claude", "skills");
|
|
116322
116398
|
const skillsAvailable = existsSync76(skillsPath);
|
|
116323
116399
|
if (!skillsAvailable) {
|
|
116324
116400
|
logger.warning(`ClaudeKit Engineer skills not found at ${skillsPath}`);
|