claudekit-cli 3.36.0-dev.12 → 3.36.0-dev.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +662 -445
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -48304,11 +48304,38 @@ var init_skill_directory_installer = __esm(() => {
|
|
|
48304
48304
|
import { existsSync as existsSync17 } from "node:fs";
|
|
48305
48305
|
import { readFile as readFile12, readdir as readdir5 } from "node:fs/promises";
|
|
48306
48306
|
import { homedir as homedir13 } from "node:os";
|
|
48307
|
-
import { extname as extname3, join as join21, relative as relative5 } from "node:path";
|
|
48307
|
+
import { extname as extname3, join as join21, relative as relative5, sep as sep3 } from "node:path";
|
|
48308
|
+
function resolveSourceOrigin(sourcePath) {
|
|
48309
|
+
if (!sourcePath)
|
|
48310
|
+
return "global";
|
|
48311
|
+
const home5 = homedir13();
|
|
48312
|
+
const cwd2 = process.cwd();
|
|
48313
|
+
if (cwd2 === home5)
|
|
48314
|
+
return "global";
|
|
48315
|
+
const cwdPrefix = cwd2.endsWith(sep3) ? cwd2 : `${cwd2}${sep3}`;
|
|
48316
|
+
if (sourcePath === cwd2 || sourcePath.startsWith(cwdPrefix))
|
|
48317
|
+
return "project";
|
|
48318
|
+
return "global";
|
|
48319
|
+
}
|
|
48308
48320
|
function getConfigSourcePath() {
|
|
48321
|
+
const projectPath = join21(process.cwd(), "CLAUDE.md");
|
|
48322
|
+
if (existsSync17(projectPath)) {
|
|
48323
|
+
return projectPath;
|
|
48324
|
+
}
|
|
48325
|
+
const projectDotClaudePath = join21(process.cwd(), ".claude", "CLAUDE.md");
|
|
48326
|
+
if (existsSync17(projectDotClaudePath)) {
|
|
48327
|
+
return projectDotClaudePath;
|
|
48328
|
+
}
|
|
48329
|
+
return getGlobalConfigSourcePath();
|
|
48330
|
+
}
|
|
48331
|
+
function getGlobalConfigSourcePath() {
|
|
48309
48332
|
return join21(homedir13(), ".claude", "CLAUDE.md");
|
|
48310
48333
|
}
|
|
48311
48334
|
function getRulesSourcePath() {
|
|
48335
|
+
const projectPath = join21(process.cwd(), ".claude", "rules");
|
|
48336
|
+
if (existsSync17(projectPath)) {
|
|
48337
|
+
return projectPath;
|
|
48338
|
+
}
|
|
48312
48339
|
return join21(homedir13(), ".claude", "rules");
|
|
48313
48340
|
}
|
|
48314
48341
|
function getHooksSourcePath() {
|
|
@@ -50720,12 +50747,31 @@ function determineAction(source, providerConfig, input, targetStateIndex, delete
|
|
|
50720
50747
|
const registeredSourceChecksum = normalizeChecksum(registryEntry.sourceChecksum);
|
|
50721
50748
|
const registeredTargetChecksum = normalizeChecksum(registryEntry.targetChecksum);
|
|
50722
50749
|
if (isUnknownChecksum(registeredSourceChecksum)) {
|
|
50750
|
+
const targetState2 = lookupTargetState(targetStateIndex, registryEntry.path);
|
|
50751
|
+
const currentTargetChecksum = normalizeChecksum(targetState2?.currentChecksum);
|
|
50752
|
+
if (currentTargetChecksum === convertedChecksum) {
|
|
50753
|
+
return {
|
|
50754
|
+
...common,
|
|
50755
|
+
action: "skip",
|
|
50756
|
+
reason: "Target up-to-date after registry upgrade — checksums will be backfilled",
|
|
50757
|
+
sourceChecksum: convertedChecksum,
|
|
50758
|
+
currentTargetChecksum
|
|
50759
|
+
};
|
|
50760
|
+
}
|
|
50761
|
+
if (!targetState2 || !targetState2.exists) {
|
|
50762
|
+
return {
|
|
50763
|
+
...common,
|
|
50764
|
+
action: "install",
|
|
50765
|
+
reason: "Target deleted — reinstalling after registry upgrade",
|
|
50766
|
+
sourceChecksum: convertedChecksum
|
|
50767
|
+
};
|
|
50768
|
+
}
|
|
50723
50769
|
return {
|
|
50724
50770
|
...common,
|
|
50725
|
-
action: "
|
|
50726
|
-
reason: "
|
|
50771
|
+
action: "update",
|
|
50772
|
+
reason: "Healing stale target after registry upgrade",
|
|
50727
50773
|
sourceChecksum: convertedChecksum,
|
|
50728
|
-
currentTargetChecksum
|
|
50774
|
+
currentTargetChecksum
|
|
50729
50775
|
};
|
|
50730
50776
|
}
|
|
50731
50777
|
const sourceChanged = convertedChecksum !== registeredSourceChecksum;
|
|
@@ -51102,7 +51148,8 @@ var init_migration_result_utils = __esm(() => {
|
|
|
51102
51148
|
// src/domains/web-server/routes/migration-routes.ts
|
|
51103
51149
|
import { existsSync as existsSync21 } from "node:fs";
|
|
51104
51150
|
import { readFile as readFile15, rm as rm5 } from "node:fs/promises";
|
|
51105
|
-
import {
|
|
51151
|
+
import { homedir as homedir15 } from "node:os";
|
|
51152
|
+
import { basename as basename7, join as join24, resolve as resolve8 } from "node:path";
|
|
51106
51153
|
function isDisallowedControlCode(codePoint) {
|
|
51107
51154
|
return codePoint >= 0 && codePoint <= 8 || codePoint >= 11 && codePoint <= 31 || codePoint >= 127 && codePoint <= 159;
|
|
51108
51155
|
}
|
|
@@ -51253,7 +51300,7 @@ function parseConfigSource(input) {
|
|
|
51253
51300
|
return { ok: true, value: undefined };
|
|
51254
51301
|
}
|
|
51255
51302
|
const projectSourcePath = resolve8(process.cwd(), "CLAUDE.md");
|
|
51256
|
-
const globalSourcePath = resolve8(
|
|
51303
|
+
const globalSourcePath = resolve8(getGlobalConfigSourcePath());
|
|
51257
51304
|
const sourceMap = {
|
|
51258
51305
|
default: undefined,
|
|
51259
51306
|
global: globalSourcePath,
|
|
@@ -51548,12 +51595,14 @@ async function discoverMigrationItems(include, configSource) {
|
|
|
51548
51595
|
const commandsSource = include.commands ? getCommandSourcePath() : null;
|
|
51549
51596
|
const skillsSource = include.skills ? getSkillSourcePath() : null;
|
|
51550
51597
|
const hooksSource = include.hooks ? getHooksSourcePath() : null;
|
|
51598
|
+
const configSourcePath = include.config ? configSource ?? getConfigSourcePath() : null;
|
|
51599
|
+
const rulesSourcePath = include.rules ? getRulesSourcePath() : null;
|
|
51551
51600
|
const [agents, commands, skills, configItem, ruleItems, hookItems] = await Promise.all([
|
|
51552
51601
|
agentsSource ? discoverAgents(agentsSource) : Promise.resolve([]),
|
|
51553
51602
|
commandsSource ? discoverCommands(commandsSource) : Promise.resolve([]),
|
|
51554
51603
|
skillsSource ? discoverSkills(skillsSource) : Promise.resolve([]),
|
|
51555
|
-
|
|
51556
|
-
|
|
51604
|
+
configSourcePath ? discoverConfig(configSourcePath) : Promise.resolve(null),
|
|
51605
|
+
rulesSourcePath ? discoverRules(rulesSourcePath) : Promise.resolve([]),
|
|
51557
51606
|
hooksSource ? discoverHooks(hooksSource).then(({ items, skippedShellHooks }) => {
|
|
51558
51607
|
if (skippedShellHooks.length > 0) {
|
|
51559
51608
|
console.warn(`[migrate] Skipping ${skippedShellHooks.length} shell hook(s) not supported for migration (node-runnable only): ${skippedShellHooks.join(", ")}`);
|
|
@@ -51572,7 +51621,9 @@ async function discoverMigrationItems(include, configSource) {
|
|
|
51572
51621
|
agents: agentsSource,
|
|
51573
51622
|
commands: commandsSource,
|
|
51574
51623
|
skills: skillsSource,
|
|
51575
|
-
hooks: hooksSource
|
|
51624
|
+
hooks: hooksSource,
|
|
51625
|
+
config: configSourcePath,
|
|
51626
|
+
rules: rulesSourcePath
|
|
51576
51627
|
}
|
|
51577
51628
|
};
|
|
51578
51629
|
}
|
|
@@ -51620,8 +51671,23 @@ function registerMigrationRoutes(app) {
|
|
|
51620
51671
|
hooks: true
|
|
51621
51672
|
};
|
|
51622
51673
|
const discovered = await discoverMigrationItems(includeAll);
|
|
51674
|
+
const cwd2 = process.cwd();
|
|
51675
|
+
const home6 = homedir15();
|
|
51623
51676
|
res.status(200).json({
|
|
51677
|
+
cwd: cwd2,
|
|
51678
|
+
targetPaths: {
|
|
51679
|
+
project: join24(cwd2, ".claude"),
|
|
51680
|
+
global: join24(home6, ".claude")
|
|
51681
|
+
},
|
|
51624
51682
|
sourcePaths: discovered.sourcePaths,
|
|
51683
|
+
sourceOrigins: {
|
|
51684
|
+
agents: discovered.sourcePaths.agents ? resolveSourceOrigin(discovered.sourcePaths.agents) : null,
|
|
51685
|
+
commands: discovered.sourcePaths.commands ? resolveSourceOrigin(discovered.sourcePaths.commands) : null,
|
|
51686
|
+
skills: discovered.sourcePaths.skills ? resolveSourceOrigin(discovered.sourcePaths.skills) : null,
|
|
51687
|
+
config: discovered.sourcePaths.config ? resolveSourceOrigin(discovered.sourcePaths.config) : null,
|
|
51688
|
+
rules: discovered.sourcePaths.rules ? resolveSourceOrigin(discovered.sourcePaths.rules) : null,
|
|
51689
|
+
hooks: discovered.sourcePaths.hooks ? resolveSourceOrigin(discovered.sourcePaths.hooks) : null
|
|
51690
|
+
},
|
|
51625
51691
|
counts: {
|
|
51626
51692
|
agents: discovered.agents.length,
|
|
51627
51693
|
commands: discovered.commands.length,
|
|
@@ -52644,12 +52710,12 @@ var init_plan_table_parser = __esm(() => {
|
|
|
52644
52710
|
|
|
52645
52711
|
// src/domains/plan-parser/plan-scanner.ts
|
|
52646
52712
|
import { existsSync as existsSync22, readdirSync as readdirSync3 } from "node:fs";
|
|
52647
|
-
import { join as
|
|
52713
|
+
import { join as join25 } from "node:path";
|
|
52648
52714
|
function scanPlanDir(dir) {
|
|
52649
52715
|
if (!existsSync22(dir))
|
|
52650
52716
|
return [];
|
|
52651
52717
|
try {
|
|
52652
|
-
return readdirSync3(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) =>
|
|
52718
|
+
return readdirSync3(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join25(dir, entry.name, "plan.md")).filter(existsSync22);
|
|
52653
52719
|
} catch {
|
|
52654
52720
|
return [];
|
|
52655
52721
|
}
|
|
@@ -52724,7 +52790,7 @@ var init_plan_validator = __esm(() => {
|
|
|
52724
52790
|
// src/domains/plan-parser/plan-writer.ts
|
|
52725
52791
|
import { mkdirSync as mkdirSync2, readFileSync as readFileSync6, writeFileSync as writeFileSync2 } from "node:fs";
|
|
52726
52792
|
import { existsSync as existsSync24 } from "node:fs";
|
|
52727
|
-
import { basename as basename9, dirname as dirname13, join as
|
|
52793
|
+
import { basename as basename9, dirname as dirname13, join as join26 } from "node:path";
|
|
52728
52794
|
function phaseNameToFilename(id, name) {
|
|
52729
52795
|
const numMatch = /^(\d+)([a-z]*)$/i.exec(id);
|
|
52730
52796
|
const num = numMatch ? numMatch[1] : id;
|
|
@@ -52832,12 +52898,12 @@ function scaffoldPlan(options2) {
|
|
|
52832
52898
|
mkdirSync2(dir, { recursive: true });
|
|
52833
52899
|
const resolvedPhases = resolvePhaseIds(options2.phases);
|
|
52834
52900
|
const optionsWithResolved = { ...options2, phases: resolvedPhases };
|
|
52835
|
-
const planFile =
|
|
52901
|
+
const planFile = join26(dir, "plan.md");
|
|
52836
52902
|
writeFileSync2(planFile, generatePlanMd(optionsWithResolved), "utf8");
|
|
52837
52903
|
const phaseFiles = [];
|
|
52838
52904
|
for (const phase of resolvedPhases) {
|
|
52839
52905
|
const filename = phaseNameToFilename(phase.id, phase.name);
|
|
52840
|
-
const phaseFile =
|
|
52906
|
+
const phaseFile = join26(dir, filename);
|
|
52841
52907
|
writeFileSync2(phaseFile, generatePhaseTemplate(phase), "utf8");
|
|
52842
52908
|
phaseFiles.push(phaseFile);
|
|
52843
52909
|
}
|
|
@@ -52917,7 +52983,7 @@ function phaseNameFilenameFromTableRow(body, phaseId, planDir) {
|
|
|
52917
52983
|
continue;
|
|
52918
52984
|
const linkMatch = /\[([^\]]+)\]\(\.\/([^)]+)\)/.exec(row);
|
|
52919
52985
|
if (linkMatch)
|
|
52920
|
-
return
|
|
52986
|
+
return join26(planDir, linkMatch[2]);
|
|
52921
52987
|
}
|
|
52922
52988
|
return null;
|
|
52923
52989
|
}
|
|
@@ -52998,7 +53064,7 @@ function addPhase(planFile, name, afterId) {
|
|
|
52998
53064
|
`);
|
|
52999
53065
|
}
|
|
53000
53066
|
writeFileSync2(planFile, import_gray_matter7.default.stringify(updatedBody, frontmatter), "utf8");
|
|
53001
|
-
const phaseFilePath =
|
|
53067
|
+
const phaseFilePath = join26(planDir, filename);
|
|
53002
53068
|
writeFileSync2(phaseFilePath, generatePhaseTemplate({ id: phaseId, name }), "utf8");
|
|
53003
53069
|
return { phaseId, phaseFile: phaseFilePath };
|
|
53004
53070
|
}
|
|
@@ -53037,11 +53103,11 @@ var init_plan_parser = __esm(() => {
|
|
|
53037
53103
|
|
|
53038
53104
|
// src/domains/web-server/routes/plan-routes.ts
|
|
53039
53105
|
import { existsSync as existsSync25, realpathSync } from "node:fs";
|
|
53040
|
-
import { basename as basename10, dirname as dirname15, relative as relative6, resolve as resolve10, sep as
|
|
53106
|
+
import { basename as basename10, dirname as dirname15, relative as relative6, resolve as resolve10, sep as sep4 } from "node:path";
|
|
53041
53107
|
function isWithinCwd(filePath) {
|
|
53042
53108
|
const cwd2 = process.cwd();
|
|
53043
53109
|
const resolved = resolve10(filePath);
|
|
53044
|
-
const cwdPrefix = cwd2.endsWith(
|
|
53110
|
+
const cwdPrefix = cwd2.endsWith(sep4) ? cwd2 : `${cwd2}${sep4}`;
|
|
53045
53111
|
if (!resolved.startsWith(cwdPrefix) && resolved !== cwd2)
|
|
53046
53112
|
return false;
|
|
53047
53113
|
if (existsSync25(resolved)) {
|
|
@@ -53188,11 +53254,11 @@ var init_types5 = __esm(() => {
|
|
|
53188
53254
|
|
|
53189
53255
|
// src/services/claude-data/history-parser.ts
|
|
53190
53256
|
import { createReadStream, statSync as statSync4 } from "node:fs";
|
|
53191
|
-
import { homedir as
|
|
53192
|
-
import { join as
|
|
53257
|
+
import { homedir as homedir16 } from "node:os";
|
|
53258
|
+
import { join as join27 } from "node:path";
|
|
53193
53259
|
import { createInterface as createInterface2 } from "node:readline";
|
|
53194
53260
|
function getHistoryPath() {
|
|
53195
|
-
return process.env.CLAUDE_HISTORY_PATH ??
|
|
53261
|
+
return process.env.CLAUDE_HISTORY_PATH ?? join27(homedir16(), ".claude", "history.jsonl");
|
|
53196
53262
|
}
|
|
53197
53263
|
function emptyResult(parseTimeMs, error) {
|
|
53198
53264
|
return { projects: [], totalEntries: 0, errorCount: 0, parseTimeMs, error };
|
|
@@ -53276,7 +53342,7 @@ var init_history_parser = __esm(() => {
|
|
|
53276
53342
|
// src/services/claude-data/session-parser.ts
|
|
53277
53343
|
import { existsSync as existsSync26 } from "node:fs";
|
|
53278
53344
|
import { readFile as readFile16, readdir as readdir7, stat as stat5 } from "node:fs/promises";
|
|
53279
|
-
import { join as
|
|
53345
|
+
import { join as join28 } from "node:path";
|
|
53280
53346
|
function formatTimestamp(date) {
|
|
53281
53347
|
const now = new Date;
|
|
53282
53348
|
const isToday = date.toDateString() === now.toDateString();
|
|
@@ -53373,7 +53439,7 @@ async function getProjectSessions(projectDir, limit = 10) {
|
|
|
53373
53439
|
const files = await readdir7(projectDir);
|
|
53374
53440
|
const jsonlFiles = files.filter((f3) => f3.endsWith(".jsonl"));
|
|
53375
53441
|
const fileStats = await Promise.all(jsonlFiles.map(async (file) => {
|
|
53376
|
-
const filePath =
|
|
53442
|
+
const filePath = join28(projectDir, file);
|
|
53377
53443
|
const fileStat = await stat5(filePath).catch(() => null);
|
|
53378
53444
|
return { file, filePath, mtime: fileStat?.mtime || new Date(0) };
|
|
53379
53445
|
}));
|
|
@@ -53390,10 +53456,10 @@ var init_session_parser = () => {};
|
|
|
53390
53456
|
// src/services/claude-data/skill-scanner.ts
|
|
53391
53457
|
import { existsSync as existsSync27 } from "node:fs";
|
|
53392
53458
|
import { readFile as readFile17, readdir as readdir8 } from "node:fs/promises";
|
|
53393
|
-
import { homedir as
|
|
53394
|
-
import { join as
|
|
53459
|
+
import { homedir as homedir17 } from "node:os";
|
|
53460
|
+
import { join as join29 } from "node:path";
|
|
53395
53461
|
async function getCkSkillMetadata(scope) {
|
|
53396
|
-
const metaPath = scope === "global" ?
|
|
53462
|
+
const metaPath = scope === "global" ? join29(homedir17(), ".claude", "metadata.json") : join29(process.cwd(), ".claude", "metadata.json");
|
|
53397
53463
|
if (!existsSync27(metaPath))
|
|
53398
53464
|
return null;
|
|
53399
53465
|
const result = new Map;
|
|
@@ -53429,7 +53495,7 @@ async function getCkSkillMetadata(scope) {
|
|
|
53429
53495
|
return result.size > 0 ? result : null;
|
|
53430
53496
|
}
|
|
53431
53497
|
async function getSkillMetadata(skillPath) {
|
|
53432
|
-
const skillMdPath =
|
|
53498
|
+
const skillMdPath = join29(skillPath, "SKILL.md");
|
|
53433
53499
|
if (!existsSync27(skillMdPath))
|
|
53434
53500
|
return null;
|
|
53435
53501
|
try {
|
|
@@ -53478,8 +53544,8 @@ async function scanSkills() {
|
|
|
53478
53544
|
continue;
|
|
53479
53545
|
if (ckMeta && !ckMeta.has(entry))
|
|
53480
53546
|
continue;
|
|
53481
|
-
const entryPath =
|
|
53482
|
-
const skillMdPath =
|
|
53547
|
+
const entryPath = join29(skillsDir, entry);
|
|
53548
|
+
const skillMdPath = join29(entryPath, "SKILL.md");
|
|
53483
53549
|
if (!existsSync27(skillMdPath))
|
|
53484
53550
|
continue;
|
|
53485
53551
|
const frontmatter = await getSkillMetadata(entryPath);
|
|
@@ -53524,17 +53590,17 @@ async function scanSkills() {
|
|
|
53524
53590
|
var import_gray_matter8, skillsDir, SKIP_DIRS3;
|
|
53525
53591
|
var init_skill_scanner = __esm(() => {
|
|
53526
53592
|
import_gray_matter8 = __toESM(require_gray_matter(), 1);
|
|
53527
|
-
skillsDir =
|
|
53593
|
+
skillsDir = join29(homedir17(), ".claude", "skills");
|
|
53528
53594
|
SKIP_DIRS3 = [".venv", "scripts", "__pycache__", "node_modules", ".git", "common"];
|
|
53529
53595
|
});
|
|
53530
53596
|
|
|
53531
53597
|
// src/services/claude-data/settings-reader.ts
|
|
53532
53598
|
import { existsSync as existsSync28 } from "node:fs";
|
|
53533
53599
|
import { copyFile as copyFile2, mkdir as mkdir8, readFile as readFile18, rename as rename5, rm as rm6, writeFile as writeFile10 } from "node:fs/promises";
|
|
53534
|
-
import { homedir as
|
|
53535
|
-
import { join as
|
|
53600
|
+
import { homedir as homedir18 } from "node:os";
|
|
53601
|
+
import { join as join30 } from "node:path";
|
|
53536
53602
|
function getSettingsPath() {
|
|
53537
|
-
return
|
|
53603
|
+
return join30(claudeDir, settingsFilename);
|
|
53538
53604
|
}
|
|
53539
53605
|
async function readSettings() {
|
|
53540
53606
|
const settingsPath = getSettingsPath();
|
|
@@ -53556,7 +53622,7 @@ async function backupAndSaveSettings(settings) {
|
|
|
53556
53622
|
let backupPath = null;
|
|
53557
53623
|
if (existsSync28(settingsPath)) {
|
|
53558
53624
|
await mkdir8(settingsBackupDir, { recursive: true });
|
|
53559
|
-
backupPath =
|
|
53625
|
+
backupPath = join30(settingsBackupDir, `${getBackupTimestamp()}-${settingsFilename}`);
|
|
53560
53626
|
await copyFile2(settingsPath, backupPath);
|
|
53561
53627
|
}
|
|
53562
53628
|
const tempPath = `${settingsPath}.tmp-${Date.now()}`;
|
|
@@ -53593,19 +53659,19 @@ function countMcpServers(settings) {
|
|
|
53593
53659
|
}
|
|
53594
53660
|
var claudeDir, settingsFilename = "settings.json", settingsBackupDir;
|
|
53595
53661
|
var init_settings_reader = __esm(() => {
|
|
53596
|
-
claudeDir =
|
|
53597
|
-
settingsBackupDir =
|
|
53662
|
+
claudeDir = join30(homedir18(), ".claude");
|
|
53663
|
+
settingsBackupDir = join30(claudeDir, ".ck-backups", "settings");
|
|
53598
53664
|
});
|
|
53599
53665
|
|
|
53600
53666
|
// src/services/claude-data/project-scanner.ts
|
|
53601
|
-
import { homedir as
|
|
53602
|
-
import { basename as basename11, join as
|
|
53667
|
+
import { homedir as homedir19 } from "node:os";
|
|
53668
|
+
import { basename as basename11, join as join31, normalize as normalize3 } from "node:path";
|
|
53603
53669
|
function encodePath(path4) {
|
|
53604
53670
|
return path4.replace(/\//g, "-").replace(/^-/, "-");
|
|
53605
53671
|
}
|
|
53606
53672
|
var projectsDir;
|
|
53607
53673
|
var init_project_scanner = __esm(() => {
|
|
53608
|
-
projectsDir =
|
|
53674
|
+
projectsDir = join31(homedir19(), ".claude", "projects");
|
|
53609
53675
|
});
|
|
53610
53676
|
|
|
53611
53677
|
// src/services/claude-data/project-discovery.ts
|
|
@@ -53700,10 +53766,10 @@ var init_project_discovery = __esm(() => {
|
|
|
53700
53766
|
|
|
53701
53767
|
// src/services/claude-data/user-preferences.ts
|
|
53702
53768
|
import { readFile as readFile19, stat as stat6 } from "node:fs/promises";
|
|
53703
|
-
import { homedir as
|
|
53704
|
-
import { join as
|
|
53769
|
+
import { homedir as homedir20 } from "node:os";
|
|
53770
|
+
import { join as join32 } from "node:path";
|
|
53705
53771
|
function getPreferencesPath() {
|
|
53706
|
-
return
|
|
53772
|
+
return join32(homedir20(), ".claude.json");
|
|
53707
53773
|
}
|
|
53708
53774
|
async function readUserPreferences(filePath) {
|
|
53709
53775
|
const path4 = filePath ?? getPreferencesPath();
|
|
@@ -53793,8 +53859,8 @@ var init_claude_data = __esm(() => {
|
|
|
53793
53859
|
// src/domains/web-server/routes/project-routes.ts
|
|
53794
53860
|
import { existsSync as existsSync29 } from "node:fs";
|
|
53795
53861
|
import { readFile as readFile20 } from "node:fs/promises";
|
|
53796
|
-
import { homedir as
|
|
53797
|
-
import { basename as basename13, join as
|
|
53862
|
+
import { homedir as homedir21 } from "node:os";
|
|
53863
|
+
import { basename as basename13, join as join33, resolve as resolve11 } from "node:path";
|
|
53798
53864
|
function registerProjectRoutes(app) {
|
|
53799
53865
|
app.get("/api/projects", async (req, res) => {
|
|
53800
53866
|
try {
|
|
@@ -53813,7 +53879,7 @@ function registerProjectRoutes(app) {
|
|
|
53813
53879
|
for (const discovered of discoveredProjects) {
|
|
53814
53880
|
if (registeredPaths.has(discovered.path))
|
|
53815
53881
|
continue;
|
|
53816
|
-
if (discovered.path ===
|
|
53882
|
+
if (discovered.path === join33(homedir21(), ".claude"))
|
|
53817
53883
|
continue;
|
|
53818
53884
|
const projectInfo = await detectAndBuildProjectInfo(discovered.path, `discovered-${discovered.path}`);
|
|
53819
53885
|
if (projectInfo) {
|
|
@@ -53829,7 +53895,7 @@ function registerProjectRoutes(app) {
|
|
|
53829
53895
|
if (cwdProject) {
|
|
53830
53896
|
projects.push(cwdProject);
|
|
53831
53897
|
}
|
|
53832
|
-
const globalDir =
|
|
53898
|
+
const globalDir = join33(homedir21(), ".claude");
|
|
53833
53899
|
const globalProject = await detectAndBuildProjectInfo(globalDir, "global");
|
|
53834
53900
|
if (globalProject) {
|
|
53835
53901
|
projects.push(globalProject);
|
|
@@ -53901,12 +53967,12 @@ function registerProjectRoutes(app) {
|
|
|
53901
53967
|
const body = validation.data;
|
|
53902
53968
|
let projectPath = body.path;
|
|
53903
53969
|
if (projectPath.startsWith("~/") || projectPath === "~") {
|
|
53904
|
-
projectPath =
|
|
53970
|
+
projectPath = join33(homedir21(), projectPath.slice(1));
|
|
53905
53971
|
} else if (projectPath.startsWith("~\\")) {
|
|
53906
|
-
projectPath =
|
|
53972
|
+
projectPath = join33(homedir21(), projectPath.slice(1));
|
|
53907
53973
|
}
|
|
53908
53974
|
projectPath = resolve11(projectPath);
|
|
53909
|
-
const homeDir =
|
|
53975
|
+
const homeDir = homedir21();
|
|
53910
53976
|
if (projectPath.includes("..") || !projectPath.startsWith(homeDir)) {
|
|
53911
53977
|
res.status(400).json({ error: "Invalid path after expansion" });
|
|
53912
53978
|
return;
|
|
@@ -53963,7 +54029,7 @@ function registerProjectRoutes(app) {
|
|
|
53963
54029
|
if (id === "current") {
|
|
53964
54030
|
projectPath = process.cwd();
|
|
53965
54031
|
} else if (id === "global") {
|
|
53966
|
-
projectPath =
|
|
54032
|
+
projectPath = join33(homedir21(), ".claude");
|
|
53967
54033
|
} else {
|
|
53968
54034
|
res.status(404).json({ error: "Project not found" });
|
|
53969
54035
|
return;
|
|
@@ -54025,8 +54091,8 @@ function registerProjectRoutes(app) {
|
|
|
54025
54091
|
});
|
|
54026
54092
|
}
|
|
54027
54093
|
async function buildProjectInfoFromRegistry(registered) {
|
|
54028
|
-
const claudeDir2 =
|
|
54029
|
-
const metadataPath =
|
|
54094
|
+
const claudeDir2 = join33(registered.path, ".claude");
|
|
54095
|
+
const metadataPath = join33(claudeDir2, "metadata.json");
|
|
54030
54096
|
if (!existsSync29(registered.path)) {
|
|
54031
54097
|
return null;
|
|
54032
54098
|
}
|
|
@@ -54043,7 +54109,7 @@ async function buildProjectInfoFromRegistry(registered) {
|
|
|
54043
54109
|
const hasLocalConfig = hasClaudeDir && CkConfigManager.projectConfigExists(registered.path, false);
|
|
54044
54110
|
const settings = await readSettings();
|
|
54045
54111
|
const skills = await scanSkills();
|
|
54046
|
-
const settingsPath =
|
|
54112
|
+
const settingsPath = join33(homedir21(), ".claude", "settings.json");
|
|
54047
54113
|
const health = existsSync29(settingsPath) ? "healthy" : "warning";
|
|
54048
54114
|
const model = getCurrentModel() || settings?.model || "claude-sonnet-4";
|
|
54049
54115
|
return {
|
|
@@ -54066,8 +54132,8 @@ async function buildProjectInfoFromRegistry(registered) {
|
|
|
54066
54132
|
};
|
|
54067
54133
|
}
|
|
54068
54134
|
async function detectAndBuildProjectInfo(path4, id) {
|
|
54069
|
-
const claudeDir2 = id === "global" ? path4 :
|
|
54070
|
-
const metadataPath =
|
|
54135
|
+
const claudeDir2 = id === "global" ? path4 : join33(path4, ".claude");
|
|
54136
|
+
const metadataPath = join33(claudeDir2, "metadata.json");
|
|
54071
54137
|
if (!existsSync29(metadataPath)) {
|
|
54072
54138
|
if (!existsSync29(claudeDir2)) {
|
|
54073
54139
|
return null;
|
|
@@ -54085,7 +54151,7 @@ async function detectAndBuildProjectInfo(path4, id) {
|
|
|
54085
54151
|
const hasLocalConfig = CkConfigManager.projectConfigExists(path4, id === "global");
|
|
54086
54152
|
const settings = await readSettings();
|
|
54087
54153
|
const skills = await scanSkills();
|
|
54088
|
-
const settingsPath =
|
|
54154
|
+
const settingsPath = join33(homedir21(), ".claude", "settings.json");
|
|
54089
54155
|
const health = existsSync29(settingsPath) ? "healthy" : "warning";
|
|
54090
54156
|
const model = getCurrentModel() || settings?.model || "claude-sonnet-4";
|
|
54091
54157
|
return {
|
|
@@ -54126,32 +54192,32 @@ var init_project_routes = __esm(() => {
|
|
|
54126
54192
|
});
|
|
54127
54193
|
|
|
54128
54194
|
// src/domains/web-server/routes/session-routes.ts
|
|
54129
|
-
import { homedir as
|
|
54130
|
-
import { join as
|
|
54195
|
+
import { homedir as homedir22 } from "node:os";
|
|
54196
|
+
import { join as join34 } from "node:path";
|
|
54131
54197
|
async function resolveSessionDir(projectId) {
|
|
54132
|
-
const home6 =
|
|
54198
|
+
const home6 = homedir22();
|
|
54133
54199
|
if (projectId.startsWith("discovered-")) {
|
|
54134
54200
|
try {
|
|
54135
54201
|
const encodedPathB64 = projectId.slice("discovered-".length);
|
|
54136
54202
|
const projectPath = Buffer.from(encodedPathB64, "base64url").toString("utf-8");
|
|
54137
54203
|
const claudeEncoded = encodePath(projectPath);
|
|
54138
|
-
return
|
|
54204
|
+
return join34(home6, ".claude", "projects", claudeEncoded);
|
|
54139
54205
|
} catch {
|
|
54140
54206
|
return null;
|
|
54141
54207
|
}
|
|
54142
54208
|
}
|
|
54143
54209
|
if (projectId === "current") {
|
|
54144
54210
|
const cwdEncoded = encodePath(process.cwd());
|
|
54145
|
-
return
|
|
54211
|
+
return join34(home6, ".claude", "projects", cwdEncoded);
|
|
54146
54212
|
}
|
|
54147
54213
|
if (projectId === "global") {
|
|
54148
|
-
const globalEncoded = encodePath(
|
|
54149
|
-
return
|
|
54214
|
+
const globalEncoded = encodePath(join34(home6, ".claude"));
|
|
54215
|
+
return join34(home6, ".claude", "projects", globalEncoded);
|
|
54150
54216
|
}
|
|
54151
54217
|
const registered = await ProjectsRegistryManager.getProject(projectId);
|
|
54152
54218
|
if (registered) {
|
|
54153
54219
|
const claudeEncoded = encodePath(registered.path);
|
|
54154
|
-
return
|
|
54220
|
+
return join34(home6, ".claude", "projects", claudeEncoded);
|
|
54155
54221
|
}
|
|
54156
54222
|
return null;
|
|
54157
54223
|
}
|
|
@@ -54168,7 +54234,7 @@ function registerSessionRoutes(app) {
|
|
|
54168
54234
|
res.status(404).json({ error: "Project not found" });
|
|
54169
54235
|
return;
|
|
54170
54236
|
}
|
|
54171
|
-
const allowedBase =
|
|
54237
|
+
const allowedBase = join34(homedir22(), ".claude", "projects");
|
|
54172
54238
|
if (!projectDir.startsWith(allowedBase)) {
|
|
54173
54239
|
res.status(403).json({ error: "Access denied" });
|
|
54174
54240
|
return;
|
|
@@ -54190,7 +54256,7 @@ var init_session_routes = __esm(() => {
|
|
|
54190
54256
|
});
|
|
54191
54257
|
|
|
54192
54258
|
// src/domains/web-server/routes/settings-routes.ts
|
|
54193
|
-
import { homedir as
|
|
54259
|
+
import { homedir as homedir23 } from "node:os";
|
|
54194
54260
|
function registerSettingsRoutes(app) {
|
|
54195
54261
|
app.get("/api/settings", async (_req, res) => {
|
|
54196
54262
|
try {
|
|
@@ -54246,7 +54312,7 @@ function registerSettingsRoutes(app) {
|
|
|
54246
54312
|
res.json({
|
|
54247
54313
|
success: true,
|
|
54248
54314
|
path: "~/.claude/settings.json",
|
|
54249
|
-
backupPath: saveResult.backupPath ? saveResult.backupPath.replace(
|
|
54315
|
+
backupPath: saveResult.backupPath ? saveResult.backupPath.replace(homedir23(), "~") : null,
|
|
54250
54316
|
absolutePath: getSettingsPath()
|
|
54251
54317
|
});
|
|
54252
54318
|
} catch (error) {
|
|
@@ -54280,8 +54346,8 @@ var init_settings_routes = __esm(() => {
|
|
|
54280
54346
|
|
|
54281
54347
|
// src/commands/skills/agents.ts
|
|
54282
54348
|
import { existsSync as existsSync30 } from "node:fs";
|
|
54283
|
-
import { homedir as
|
|
54284
|
-
import { join as
|
|
54349
|
+
import { homedir as homedir24 } from "node:os";
|
|
54350
|
+
import { join as join35 } from "node:path";
|
|
54285
54351
|
async function detectInstalledAgents() {
|
|
54286
54352
|
const installed = [];
|
|
54287
54353
|
for (const [type, config] of Object.entries(agents)) {
|
|
@@ -54297,7 +54363,7 @@ function getAgentConfig(type) {
|
|
|
54297
54363
|
function getInstallPath(skillName, agent, options2) {
|
|
54298
54364
|
const config = agents[agent];
|
|
54299
54365
|
const basePath = options2.global ? config.globalPath : config.projectPath;
|
|
54300
|
-
return
|
|
54366
|
+
return join35(basePath, skillName);
|
|
54301
54367
|
}
|
|
54302
54368
|
function isSkillInstalled(skillName, agent, options2) {
|
|
54303
54369
|
const installPath = getInstallPath(skillName, agent, options2);
|
|
@@ -54305,105 +54371,105 @@ function isSkillInstalled(skillName, agent, options2) {
|
|
|
54305
54371
|
}
|
|
54306
54372
|
var home6, agents;
|
|
54307
54373
|
var init_agents = __esm(() => {
|
|
54308
|
-
home6 =
|
|
54374
|
+
home6 = homedir24();
|
|
54309
54375
|
agents = {
|
|
54310
54376
|
"claude-code": {
|
|
54311
54377
|
name: "claude-code",
|
|
54312
54378
|
displayName: "Claude Code",
|
|
54313
54379
|
projectPath: ".claude/skills",
|
|
54314
|
-
globalPath:
|
|
54315
|
-
detect: async () => existsSync30(
|
|
54380
|
+
globalPath: join35(home6, ".claude/skills"),
|
|
54381
|
+
detect: async () => existsSync30(join35(home6, ".claude"))
|
|
54316
54382
|
},
|
|
54317
54383
|
cursor: {
|
|
54318
54384
|
name: "cursor",
|
|
54319
54385
|
displayName: "Cursor",
|
|
54320
54386
|
projectPath: ".cursor/skills",
|
|
54321
|
-
globalPath:
|
|
54322
|
-
detect: async () => existsSync30(
|
|
54387
|
+
globalPath: join35(home6, ".cursor/skills"),
|
|
54388
|
+
detect: async () => existsSync30(join35(home6, ".cursor"))
|
|
54323
54389
|
},
|
|
54324
54390
|
codex: {
|
|
54325
54391
|
name: "codex",
|
|
54326
54392
|
displayName: "Codex",
|
|
54327
54393
|
projectPath: ".codex/skills",
|
|
54328
|
-
globalPath:
|
|
54329
|
-
detect: async () => existsSync30(
|
|
54394
|
+
globalPath: join35(home6, ".codex/skills"),
|
|
54395
|
+
detect: async () => existsSync30(join35(home6, ".codex"))
|
|
54330
54396
|
},
|
|
54331
54397
|
opencode: {
|
|
54332
54398
|
name: "opencode",
|
|
54333
54399
|
displayName: "OpenCode",
|
|
54334
54400
|
projectPath: ".opencode/skills",
|
|
54335
|
-
globalPath:
|
|
54336
|
-
detect: async () => existsSync30(
|
|
54401
|
+
globalPath: join35(home6, ".config/opencode/skills"),
|
|
54402
|
+
detect: async () => existsSync30(join35(home6, ".config/opencode"))
|
|
54337
54403
|
},
|
|
54338
54404
|
goose: {
|
|
54339
54405
|
name: "goose",
|
|
54340
54406
|
displayName: "Goose",
|
|
54341
54407
|
projectPath: ".goose/skills",
|
|
54342
|
-
globalPath:
|
|
54343
|
-
detect: async () => existsSync30(
|
|
54408
|
+
globalPath: join35(home6, ".config/goose/skills"),
|
|
54409
|
+
detect: async () => existsSync30(join35(home6, ".config/goose"))
|
|
54344
54410
|
},
|
|
54345
54411
|
"gemini-cli": {
|
|
54346
54412
|
name: "gemini-cli",
|
|
54347
54413
|
displayName: "Gemini CLI",
|
|
54348
54414
|
projectPath: ".gemini/skills",
|
|
54349
|
-
globalPath:
|
|
54350
|
-
detect: async () => existsSync30(
|
|
54415
|
+
globalPath: join35(home6, ".gemini/skills"),
|
|
54416
|
+
detect: async () => existsSync30(join35(home6, ".gemini"))
|
|
54351
54417
|
},
|
|
54352
54418
|
antigravity: {
|
|
54353
54419
|
name: "antigravity",
|
|
54354
54420
|
displayName: "Antigravity",
|
|
54355
54421
|
projectPath: ".agent/skills",
|
|
54356
|
-
globalPath:
|
|
54357
|
-
detect: async () => existsSync30(
|
|
54422
|
+
globalPath: join35(home6, ".gemini/antigravity/skills"),
|
|
54423
|
+
detect: async () => existsSync30(join35(process.cwd(), ".agent")) || existsSync30(join35(home6, ".gemini/antigravity"))
|
|
54358
54424
|
},
|
|
54359
54425
|
"github-copilot": {
|
|
54360
54426
|
name: "github-copilot",
|
|
54361
54427
|
displayName: "GitHub Copilot",
|
|
54362
54428
|
projectPath: ".github/skills",
|
|
54363
|
-
globalPath:
|
|
54364
|
-
detect: async () => existsSync30(
|
|
54429
|
+
globalPath: join35(home6, ".copilot/skills"),
|
|
54430
|
+
detect: async () => existsSync30(join35(home6, ".copilot"))
|
|
54365
54431
|
},
|
|
54366
54432
|
amp: {
|
|
54367
54433
|
name: "amp",
|
|
54368
54434
|
displayName: "Amp",
|
|
54369
54435
|
projectPath: ".agents/skills",
|
|
54370
|
-
globalPath:
|
|
54371
|
-
detect: async () => existsSync30(
|
|
54436
|
+
globalPath: join35(home6, ".config/agents/skills"),
|
|
54437
|
+
detect: async () => existsSync30(join35(home6, ".config/amp"))
|
|
54372
54438
|
},
|
|
54373
54439
|
kilo: {
|
|
54374
54440
|
name: "kilo",
|
|
54375
54441
|
displayName: "Kilo Code",
|
|
54376
54442
|
projectPath: ".kilocode/skills",
|
|
54377
|
-
globalPath:
|
|
54378
|
-
detect: async () => existsSync30(
|
|
54443
|
+
globalPath: join35(home6, ".kilocode/skills"),
|
|
54444
|
+
detect: async () => existsSync30(join35(home6, ".kilocode"))
|
|
54379
54445
|
},
|
|
54380
54446
|
roo: {
|
|
54381
54447
|
name: "roo",
|
|
54382
54448
|
displayName: "Roo Code",
|
|
54383
54449
|
projectPath: ".roo/skills",
|
|
54384
|
-
globalPath:
|
|
54385
|
-
detect: async () => existsSync30(
|
|
54450
|
+
globalPath: join35(home6, ".roo/skills"),
|
|
54451
|
+
detect: async () => existsSync30(join35(home6, ".roo"))
|
|
54386
54452
|
},
|
|
54387
54453
|
windsurf: {
|
|
54388
54454
|
name: "windsurf",
|
|
54389
54455
|
displayName: "Windsurf",
|
|
54390
54456
|
projectPath: ".windsurf/skills",
|
|
54391
|
-
globalPath:
|
|
54392
|
-
detect: async () => existsSync30(
|
|
54457
|
+
globalPath: join35(home6, ".codeium/windsurf/skills"),
|
|
54458
|
+
detect: async () => existsSync30(join35(home6, ".codeium/windsurf"))
|
|
54393
54459
|
},
|
|
54394
54460
|
cline: {
|
|
54395
54461
|
name: "cline",
|
|
54396
54462
|
displayName: "Cline",
|
|
54397
54463
|
projectPath: ".cline/skills",
|
|
54398
|
-
globalPath:
|
|
54399
|
-
detect: async () => existsSync30(
|
|
54464
|
+
globalPath: join35(home6, ".cline/skills"),
|
|
54465
|
+
detect: async () => existsSync30(join35(home6, ".cline"))
|
|
54400
54466
|
},
|
|
54401
54467
|
openhands: {
|
|
54402
54468
|
name: "openhands",
|
|
54403
54469
|
displayName: "OpenHands",
|
|
54404
54470
|
projectPath: ".openhands/skills",
|
|
54405
|
-
globalPath:
|
|
54406
|
-
detect: async () => existsSync30(
|
|
54471
|
+
globalPath: join35(home6, ".openhands/skills"),
|
|
54472
|
+
detect: async () => existsSync30(join35(home6, ".openhands"))
|
|
54407
54473
|
}
|
|
54408
54474
|
};
|
|
54409
54475
|
});
|
|
@@ -54411,8 +54477,8 @@ var init_agents = __esm(() => {
|
|
|
54411
54477
|
// src/commands/skills/skills-registry.ts
|
|
54412
54478
|
import { existsSync as existsSync31 } from "node:fs";
|
|
54413
54479
|
import { mkdir as mkdir9, readFile as readFile21, writeFile as writeFile11 } from "node:fs/promises";
|
|
54414
|
-
import { homedir as
|
|
54415
|
-
import { dirname as dirname16, join as
|
|
54480
|
+
import { homedir as homedir25 } from "node:os";
|
|
54481
|
+
import { dirname as dirname16, join as join36 } from "node:path";
|
|
54416
54482
|
function getCliVersion3() {
|
|
54417
54483
|
try {
|
|
54418
54484
|
if (process.env.npm_package_version) {
|
|
@@ -54504,8 +54570,8 @@ async function syncRegistry() {
|
|
|
54504
54570
|
var home7, REGISTRY_PATH2, SkillInstallationSchema, SkillRegistrySchema;
|
|
54505
54571
|
var init_skills_registry = __esm(() => {
|
|
54506
54572
|
init_zod();
|
|
54507
|
-
home7 =
|
|
54508
|
-
REGISTRY_PATH2 =
|
|
54573
|
+
home7 = homedir25();
|
|
54574
|
+
REGISTRY_PATH2 = join36(home7, ".claudekit", "skill-registry.json");
|
|
54509
54575
|
SkillInstallationSchema = exports_external.object({
|
|
54510
54576
|
skill: exports_external.string(),
|
|
54511
54577
|
agent: exports_external.string(),
|
|
@@ -54628,7 +54694,7 @@ var init_skills_installer = __esm(() => {
|
|
|
54628
54694
|
// src/commands/skills/skills-uninstaller.ts
|
|
54629
54695
|
import { existsSync as existsSync33 } from "node:fs";
|
|
54630
54696
|
import { rm as rm7 } from "node:fs/promises";
|
|
54631
|
-
import { join as
|
|
54697
|
+
import { join as join37 } from "node:path";
|
|
54632
54698
|
async function uninstallSkillFromAgent(skill, agent, global3) {
|
|
54633
54699
|
const agentConfig = agents[agent];
|
|
54634
54700
|
const registry = await readRegistry();
|
|
@@ -54676,7 +54742,7 @@ async function uninstallSkillFromAgent(skill, agent, global3) {
|
|
|
54676
54742
|
async function forceUninstallSkill(skill, agent, global3) {
|
|
54677
54743
|
const agentConfig = agents[agent];
|
|
54678
54744
|
const basePath = global3 ? agentConfig.globalPath : agentConfig.projectPath;
|
|
54679
|
-
const path4 =
|
|
54745
|
+
const path4 = join37(basePath, skill);
|
|
54680
54746
|
if (!existsSync33(path4)) {
|
|
54681
54747
|
return {
|
|
54682
54748
|
skill,
|
|
@@ -55220,7 +55286,7 @@ var init_pnpm_detector = __esm(() => {
|
|
|
55220
55286
|
import { existsSync as existsSync34, realpathSync as realpathSync2 } from "node:fs";
|
|
55221
55287
|
import { chmod as chmod2, mkdir as mkdir11, readFile as readFile22, writeFile as writeFile12 } from "node:fs/promises";
|
|
55222
55288
|
import { platform as platform4 } from "node:os";
|
|
55223
|
-
import { join as
|
|
55289
|
+
import { join as join38 } from "node:path";
|
|
55224
55290
|
function detectFromBinaryPath() {
|
|
55225
55291
|
const normalizePath2 = (pathValue) => pathValue.replace(/\\/g, "/").toLowerCase();
|
|
55226
55292
|
const detectFromNormalizedPath = (normalized) => {
|
|
@@ -55297,7 +55363,7 @@ function detectFromEnv() {
|
|
|
55297
55363
|
}
|
|
55298
55364
|
async function readCachedPm() {
|
|
55299
55365
|
try {
|
|
55300
|
-
const cacheFile =
|
|
55366
|
+
const cacheFile = join38(PathResolver.getConfigDir(false), CACHE_FILE);
|
|
55301
55367
|
if (!existsSync34(cacheFile)) {
|
|
55302
55368
|
return null;
|
|
55303
55369
|
}
|
|
@@ -55328,7 +55394,7 @@ async function saveCachedPm(pm, getVersion) {
|
|
|
55328
55394
|
return;
|
|
55329
55395
|
try {
|
|
55330
55396
|
const configDir = PathResolver.getConfigDir(false);
|
|
55331
|
-
const cacheFile =
|
|
55397
|
+
const cacheFile = join38(configDir, CACHE_FILE);
|
|
55332
55398
|
if (!existsSync34(configDir)) {
|
|
55333
55399
|
await mkdir11(configDir, { recursive: true });
|
|
55334
55400
|
if (platform4() !== "win32") {
|
|
@@ -55391,7 +55457,7 @@ async function findOwningPm() {
|
|
|
55391
55457
|
async function clearCache() {
|
|
55392
55458
|
try {
|
|
55393
55459
|
const { unlink: unlink6 } = await import("node:fs/promises");
|
|
55394
|
-
const cacheFile =
|
|
55460
|
+
const cacheFile = join38(PathResolver.getConfigDir(false), CACHE_FILE);
|
|
55395
55461
|
if (existsSync34(cacheFile)) {
|
|
55396
55462
|
await unlink6(cacheFile);
|
|
55397
55463
|
logger.debug("Package manager cache cleared");
|
|
@@ -55548,9 +55614,9 @@ var init_package_manager_detector = __esm(() => {
|
|
|
55548
55614
|
});
|
|
55549
55615
|
|
|
55550
55616
|
// src/domains/migration/metadata-migration.ts
|
|
55551
|
-
import { join as
|
|
55617
|
+
import { join as join39 } from "node:path";
|
|
55552
55618
|
async function detectMetadataFormat(claudeDir2) {
|
|
55553
|
-
const metadataPath =
|
|
55619
|
+
const metadataPath = join39(claudeDir2, "metadata.json");
|
|
55554
55620
|
if (!await import_fs_extra3.pathExists(metadataPath)) {
|
|
55555
55621
|
return { format: "none", metadata: null, detectedKit: null };
|
|
55556
55622
|
}
|
|
@@ -55602,7 +55668,7 @@ async function migrateToMultiKit(claudeDir2) {
|
|
|
55602
55668
|
toFormat: "multi-kit"
|
|
55603
55669
|
};
|
|
55604
55670
|
}
|
|
55605
|
-
const metadataPath =
|
|
55671
|
+
const metadataPath = join39(claudeDir2, "metadata.json");
|
|
55606
55672
|
const legacy = detection.metadata;
|
|
55607
55673
|
if (!legacy) {
|
|
55608
55674
|
return {
|
|
@@ -55714,7 +55780,7 @@ var init_metadata_migration = __esm(() => {
|
|
|
55714
55780
|
});
|
|
55715
55781
|
|
|
55716
55782
|
// src/services/file-operations/claudekit-scanner.ts
|
|
55717
|
-
import { join as
|
|
55783
|
+
import { join as join40 } from "node:path";
|
|
55718
55784
|
async function scanClaudeKitDirectory(directoryPath) {
|
|
55719
55785
|
const counts = {
|
|
55720
55786
|
agents: 0,
|
|
@@ -55728,33 +55794,33 @@ async function scanClaudeKitDirectory(directoryPath) {
|
|
|
55728
55794
|
}
|
|
55729
55795
|
const items = await import_fs_extra4.readdir(directoryPath);
|
|
55730
55796
|
if (items.includes("agents")) {
|
|
55731
|
-
const agentsPath =
|
|
55797
|
+
const agentsPath = join40(directoryPath, "agents");
|
|
55732
55798
|
const agentFiles = await import_fs_extra4.readdir(agentsPath);
|
|
55733
55799
|
counts.agents = agentFiles.filter((file) => file.endsWith(".md")).length;
|
|
55734
55800
|
}
|
|
55735
55801
|
if (items.includes("commands")) {
|
|
55736
|
-
const commandsPath =
|
|
55802
|
+
const commandsPath = join40(directoryPath, "commands");
|
|
55737
55803
|
const commandFiles = await import_fs_extra4.readdir(commandsPath);
|
|
55738
55804
|
counts.commands = commandFiles.filter((file) => file.endsWith(".md")).length;
|
|
55739
55805
|
}
|
|
55740
55806
|
if (items.includes("rules")) {
|
|
55741
|
-
const rulesPath =
|
|
55807
|
+
const rulesPath = join40(directoryPath, "rules");
|
|
55742
55808
|
const ruleFiles = await import_fs_extra4.readdir(rulesPath);
|
|
55743
55809
|
counts.rules = ruleFiles.filter((file) => file.endsWith(".md")).length;
|
|
55744
55810
|
} else if (items.includes("workflows")) {
|
|
55745
|
-
const workflowsPath =
|
|
55811
|
+
const workflowsPath = join40(directoryPath, "workflows");
|
|
55746
55812
|
const workflowFiles = await import_fs_extra4.readdir(workflowsPath);
|
|
55747
55813
|
counts.rules = workflowFiles.filter((file) => file.endsWith(".md")).length;
|
|
55748
55814
|
}
|
|
55749
55815
|
if (items.includes("skills")) {
|
|
55750
|
-
const skillsPath =
|
|
55816
|
+
const skillsPath = join40(directoryPath, "skills");
|
|
55751
55817
|
const skillItems = await import_fs_extra4.readdir(skillsPath);
|
|
55752
55818
|
let skillCount = 0;
|
|
55753
55819
|
for (const item of skillItems) {
|
|
55754
55820
|
if (SKIP_DIRS_CLAUDE_INTERNAL.includes(item)) {
|
|
55755
55821
|
continue;
|
|
55756
55822
|
}
|
|
55757
|
-
const itemPath =
|
|
55823
|
+
const itemPath = join40(skillsPath, item);
|
|
55758
55824
|
const stat8 = await import_fs_extra4.readdir(itemPath).catch(() => null);
|
|
55759
55825
|
if (stat8?.includes("SKILL.md")) {
|
|
55760
55826
|
skillCount++;
|
|
@@ -55796,14 +55862,14 @@ async function getClaudeKitSetup(projectDir = process.cwd()) {
|
|
|
55796
55862
|
const globalDir = getGlobalInstallDir();
|
|
55797
55863
|
if (await import_fs_extra4.pathExists(globalDir)) {
|
|
55798
55864
|
setup.global.path = globalDir;
|
|
55799
|
-
setup.global.metadata = await readClaudeKitMetadata(
|
|
55865
|
+
setup.global.metadata = await readClaudeKitMetadata(join40(globalDir, "metadata.json"));
|
|
55800
55866
|
setup.global.components = await scanClaudeKitDirectory(globalDir);
|
|
55801
55867
|
}
|
|
55802
|
-
const projectClaudeDir =
|
|
55868
|
+
const projectClaudeDir = join40(projectDir, ".claude");
|
|
55803
55869
|
const isLocalSameAsGlobal = projectClaudeDir === globalDir;
|
|
55804
55870
|
if (!isLocalSameAsGlobal && await import_fs_extra4.pathExists(projectClaudeDir)) {
|
|
55805
55871
|
setup.project.path = projectClaudeDir;
|
|
55806
|
-
setup.project.metadata = await readClaudeKitMetadata(
|
|
55872
|
+
setup.project.metadata = await readClaudeKitMetadata(join40(projectClaudeDir, "metadata.json"));
|
|
55807
55873
|
setup.project.components = await scanClaudeKitDirectory(projectClaudeDir);
|
|
55808
55874
|
}
|
|
55809
55875
|
return setup;
|
|
@@ -55942,7 +56008,7 @@ var package_default;
|
|
|
55942
56008
|
var init_package = __esm(() => {
|
|
55943
56009
|
package_default = {
|
|
55944
56010
|
name: "claudekit-cli",
|
|
55945
|
-
version: "3.36.0-dev.
|
|
56011
|
+
version: "3.36.0-dev.14",
|
|
55946
56012
|
description: "CLI tool for bootstrapping and updating ClaudeKit projects",
|
|
55947
56013
|
type: "module",
|
|
55948
56014
|
repository: {
|
|
@@ -56051,7 +56117,7 @@ var init_package = __esm(() => {
|
|
|
56051
56117
|
|
|
56052
56118
|
// src/commands/update-cli.ts
|
|
56053
56119
|
import { exec as exec2 } from "node:child_process";
|
|
56054
|
-
import { join as
|
|
56120
|
+
import { join as join41 } from "node:path";
|
|
56055
56121
|
import { promisify as promisify8 } from "node:util";
|
|
56056
56122
|
function getDefaultUpdateCliCommandDeps() {
|
|
56057
56123
|
return {
|
|
@@ -56130,7 +56196,7 @@ function selectKitForUpdate(params) {
|
|
|
56130
56196
|
};
|
|
56131
56197
|
}
|
|
56132
56198
|
async function readMetadataFile(claudeDir2) {
|
|
56133
|
-
const metadataPath =
|
|
56199
|
+
const metadataPath = join41(claudeDir2, "metadata.json");
|
|
56134
56200
|
try {
|
|
56135
56201
|
if (!await import_fs_extra5.pathExists(metadataPath)) {
|
|
56136
56202
|
return null;
|
|
@@ -56148,9 +56214,10 @@ async function readMetadataFile(claudeDir2) {
|
|
|
56148
56214
|
return null;
|
|
56149
56215
|
}
|
|
56150
56216
|
}
|
|
56151
|
-
async function promptKitUpdate(beta, yes) {
|
|
56217
|
+
async function promptKitUpdate(beta, yes, deps) {
|
|
56152
56218
|
try {
|
|
56153
|
-
const
|
|
56219
|
+
const execFn = deps?.execAsyncFn ?? execAsync2;
|
|
56220
|
+
const setup = await (deps?.getSetupFn ?? getClaudeKitSetup)();
|
|
56154
56221
|
const hasLocal = !!setup.project.metadata;
|
|
56155
56222
|
const hasGlobal = !!setup.global.metadata;
|
|
56156
56223
|
const localMetadata = hasLocal ? await readMetadataFile(setup.project.path) : null;
|
|
@@ -56166,6 +56233,9 @@ async function promptKitUpdate(beta, yes) {
|
|
|
56166
56233
|
const isBetaInstalled = isBetaVersion(kitVersion);
|
|
56167
56234
|
const initCmd = buildInitCommand(selection.isGlobal, selection.kit, beta || isBetaInstalled);
|
|
56168
56235
|
const promptMessage = selection.promptMessage;
|
|
56236
|
+
if (selection.kit && kitVersion) {
|
|
56237
|
+
logger.info(`Current kit version: ${selection.kit}@${kitVersion}`);
|
|
56238
|
+
}
|
|
56169
56239
|
if (!yes) {
|
|
56170
56240
|
logger.info("");
|
|
56171
56241
|
const shouldUpdate = await se({
|
|
@@ -56179,13 +56249,25 @@ async function promptKitUpdate(beta, yes) {
|
|
|
56179
56249
|
logger.verbose("Auto-proceeding with kit update (--yes flag)");
|
|
56180
56250
|
}
|
|
56181
56251
|
logger.info(`Running: ${initCmd}`);
|
|
56182
|
-
const s = de();
|
|
56252
|
+
const s = (deps?.spinnerFn ?? de)();
|
|
56183
56253
|
s.start("Updating ClaudeKit content...");
|
|
56184
56254
|
try {
|
|
56185
|
-
await
|
|
56255
|
+
await execFn(initCmd, {
|
|
56186
56256
|
timeout: 300000
|
|
56187
56257
|
});
|
|
56188
|
-
|
|
56258
|
+
let newKitVersion;
|
|
56259
|
+
try {
|
|
56260
|
+
const claudeDir2 = selection.isGlobal ? setup.global.path : setup.project.path;
|
|
56261
|
+
const updatedMetadata = await readMetadataFile(claudeDir2);
|
|
56262
|
+
newKitVersion = selection.kit ? updatedMetadata?.kits?.[selection.kit]?.version : undefined;
|
|
56263
|
+
} catch {}
|
|
56264
|
+
if (selection.kit && kitVersion && newKitVersion && kitVersion !== newKitVersion) {
|
|
56265
|
+
s.stop(`Kit updated: ${selection.kit}@${kitVersion} -> ${newKitVersion}`);
|
|
56266
|
+
} else if (selection.kit && newKitVersion) {
|
|
56267
|
+
s.stop(`Kit content updated (${selection.kit}@${newKitVersion})`);
|
|
56268
|
+
} else {
|
|
56269
|
+
s.stop("Kit content updated");
|
|
56270
|
+
}
|
|
56189
56271
|
} catch (error) {
|
|
56190
56272
|
s.stop("Kit update finished");
|
|
56191
56273
|
const errorMsg = error instanceof Error ? error.message : "unknown";
|
|
@@ -56838,7 +56920,7 @@ var init_error_handler2 = __esm(() => {
|
|
|
56838
56920
|
// src/domains/versioning/release-cache.ts
|
|
56839
56921
|
import { existsSync as existsSync35 } from "node:fs";
|
|
56840
56922
|
import { mkdir as mkdir12, readFile as readFile26, unlink as unlink6, writeFile as writeFile14 } from "node:fs/promises";
|
|
56841
|
-
import { join as
|
|
56923
|
+
import { join as join42 } from "node:path";
|
|
56842
56924
|
var ReleaseCacheEntrySchema, ReleaseCache;
|
|
56843
56925
|
var init_release_cache = __esm(() => {
|
|
56844
56926
|
init_logger();
|
|
@@ -56853,7 +56935,7 @@ var init_release_cache = __esm(() => {
|
|
|
56853
56935
|
static CACHE_TTL_SECONDS = Number(process.env.CK_CACHE_TTL) || 3600;
|
|
56854
56936
|
cacheDir;
|
|
56855
56937
|
constructor() {
|
|
56856
|
-
this.cacheDir =
|
|
56938
|
+
this.cacheDir = join42(PathResolver.getCacheDir(false), ReleaseCache.CACHE_DIR);
|
|
56857
56939
|
}
|
|
56858
56940
|
async get(key) {
|
|
56859
56941
|
const cacheFile = this.getCachePath(key);
|
|
@@ -56911,7 +56993,7 @@ var init_release_cache = __esm(() => {
|
|
|
56911
56993
|
const files = await readdir10(this.cacheDir);
|
|
56912
56994
|
for (const file of files) {
|
|
56913
56995
|
if (file.endsWith(".json")) {
|
|
56914
|
-
await unlink6(
|
|
56996
|
+
await unlink6(join42(this.cacheDir, file));
|
|
56915
56997
|
}
|
|
56916
56998
|
}
|
|
56917
56999
|
logger.debug("All release cache cleared");
|
|
@@ -56922,7 +57004,7 @@ var init_release_cache = __esm(() => {
|
|
|
56922
57004
|
}
|
|
56923
57005
|
getCachePath(key) {
|
|
56924
57006
|
const safeKey = key.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
56925
|
-
return
|
|
57007
|
+
return join42(this.cacheDir, `${safeKey}.json`);
|
|
56926
57008
|
}
|
|
56927
57009
|
isExpired(timestamp) {
|
|
56928
57010
|
const now = Date.now();
|
|
@@ -57600,7 +57682,7 @@ var init_version_utils = __esm(() => {
|
|
|
57600
57682
|
// src/domains/versioning/version-cache.ts
|
|
57601
57683
|
import { existsSync as existsSync36 } from "node:fs";
|
|
57602
57684
|
import { mkdir as mkdir13, readFile as readFile27, writeFile as writeFile15 } from "node:fs/promises";
|
|
57603
|
-
import { join as
|
|
57685
|
+
import { join as join43 } from "node:path";
|
|
57604
57686
|
var VersionCacheManager;
|
|
57605
57687
|
var init_version_cache = __esm(() => {
|
|
57606
57688
|
init_logger();
|
|
@@ -57610,7 +57692,7 @@ var init_version_cache = __esm(() => {
|
|
|
57610
57692
|
static CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000;
|
|
57611
57693
|
static getCacheFile() {
|
|
57612
57694
|
const cacheDir = PathResolver.getCacheDir(false);
|
|
57613
|
-
return
|
|
57695
|
+
return join43(cacheDir, VersionCacheManager.CACHE_FILENAME);
|
|
57614
57696
|
}
|
|
57615
57697
|
static async load() {
|
|
57616
57698
|
const cacheFile = VersionCacheManager.getCacheFile();
|
|
@@ -57879,7 +57961,7 @@ var init_version_checker = __esm(() => {
|
|
|
57879
57961
|
import { spawn as spawn2 } from "node:child_process";
|
|
57880
57962
|
import { existsSync as existsSync37 } from "node:fs";
|
|
57881
57963
|
import { readFile as readFile28 } from "node:fs/promises";
|
|
57882
|
-
import { join as
|
|
57964
|
+
import { join as join44 } from "node:path";
|
|
57883
57965
|
function hasCliUpdate(currentVersion, latestVersion) {
|
|
57884
57966
|
if (!latestVersion) {
|
|
57885
57967
|
return false;
|
|
@@ -58122,7 +58204,7 @@ async function getPackageJson() {
|
|
|
58122
58204
|
}
|
|
58123
58205
|
async function getKitMetadata2(kitName) {
|
|
58124
58206
|
try {
|
|
58125
|
-
const metadataPath =
|
|
58207
|
+
const metadataPath = join44(PathResolver.getGlobalKitDir(), "metadata.json");
|
|
58126
58208
|
if (!existsSync37(metadataPath))
|
|
58127
58209
|
return null;
|
|
58128
58210
|
const content = await readFile28(metadataPath, "utf-8");
|
|
@@ -58267,7 +58349,7 @@ var init_routes = __esm(() => {
|
|
|
58267
58349
|
|
|
58268
58350
|
// src/domains/web-server/static-server.ts
|
|
58269
58351
|
import { existsSync as existsSync38 } from "node:fs";
|
|
58270
|
-
import { dirname as dirname18, extname as extname4, join as
|
|
58352
|
+
import { dirname as dirname18, extname as extname4, join as join45 } from "node:path";
|
|
58271
58353
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
58272
58354
|
function tryServeFromEmbedded(app) {
|
|
58273
58355
|
if (typeof globalThis.Bun === "undefined" || !globalThis.Bun.embeddedFiles?.length) {
|
|
@@ -58328,12 +58410,12 @@ function tryServeFromEmbedded(app) {
|
|
|
58328
58410
|
}
|
|
58329
58411
|
function resolveUiDistPath() {
|
|
58330
58412
|
const candidates = [
|
|
58331
|
-
|
|
58332
|
-
|
|
58333
|
-
|
|
58413
|
+
join45(__dirname3, "ui"),
|
|
58414
|
+
join45(process.cwd(), "dist", "ui"),
|
|
58415
|
+
join45(process.cwd(), "src", "ui", "dist")
|
|
58334
58416
|
];
|
|
58335
58417
|
for (const path4 of candidates) {
|
|
58336
|
-
if (existsSync38(
|
|
58418
|
+
if (existsSync38(join45(path4, "index.html"))) {
|
|
58337
58419
|
return path4;
|
|
58338
58420
|
}
|
|
58339
58421
|
}
|
|
@@ -58376,7 +58458,7 @@ function serveStatic(app) {
|
|
|
58376
58458
|
if (req.path.startsWith("/assets/") || req.path.match(/\.(js|css|ico|png|jpg|svg|woff2?)$/)) {
|
|
58377
58459
|
return next();
|
|
58378
58460
|
}
|
|
58379
|
-
res.sendFile(
|
|
58461
|
+
res.sendFile(join45(uiDistPath, "index.html"), { dotfiles: "allow" });
|
|
58380
58462
|
});
|
|
58381
58463
|
logger.debug(`Serving static files from ${uiDistPath}`);
|
|
58382
58464
|
}
|
|
@@ -63376,7 +63458,7 @@ var init_gemini_installer = __esm(() => {
|
|
|
63376
63458
|
});
|
|
63377
63459
|
|
|
63378
63460
|
// src/services/package-installer/opencode-installer.ts
|
|
63379
|
-
import { join as
|
|
63461
|
+
import { join as join63 } from "node:path";
|
|
63380
63462
|
async function isOpenCodeInstalled() {
|
|
63381
63463
|
try {
|
|
63382
63464
|
await execAsync7("opencode --version", { timeout: 5000 });
|
|
@@ -63399,7 +63481,7 @@ async function installOpenCode() {
|
|
|
63399
63481
|
logger.info(`Installing ${displayName}...`);
|
|
63400
63482
|
const { unlink: unlink11 } = await import("node:fs/promises");
|
|
63401
63483
|
const { tmpdir: tmpdir4 } = await import("node:os");
|
|
63402
|
-
const tempScriptPath =
|
|
63484
|
+
const tempScriptPath = join63(tmpdir4(), "opencode-install.sh");
|
|
63403
63485
|
try {
|
|
63404
63486
|
logger.info("Downloading OpenCode installation script...");
|
|
63405
63487
|
await execFileAsync5("curl", ["-fsSL", "https://opencode.ai/install", "-o", tempScriptPath], {
|
|
@@ -63451,7 +63533,7 @@ var PARTIAL_INSTALL_VERSION = "partial", EXIT_CODE_CRITICAL_FAILURE = 1, EXIT_CO
|
|
|
63451
63533
|
|
|
63452
63534
|
// src/services/package-installer/install-error-handler.ts
|
|
63453
63535
|
import { existsSync as existsSync49, readFileSync as readFileSync12, unlinkSync as unlinkSync2 } from "node:fs";
|
|
63454
|
-
import { join as
|
|
63536
|
+
import { join as join64 } from "node:path";
|
|
63455
63537
|
function parseNameReason(str2) {
|
|
63456
63538
|
const colonIndex = str2.indexOf(":");
|
|
63457
63539
|
if (colonIndex === -1) {
|
|
@@ -63460,7 +63542,7 @@ function parseNameReason(str2) {
|
|
|
63460
63542
|
return [str2.slice(0, colonIndex).trim(), str2.slice(colonIndex + 1).trim()];
|
|
63461
63543
|
}
|
|
63462
63544
|
function displayInstallErrors(skillsDir2) {
|
|
63463
|
-
const summaryPath =
|
|
63545
|
+
const summaryPath = join64(skillsDir2, ".install-error-summary.json");
|
|
63464
63546
|
if (!existsSync49(summaryPath)) {
|
|
63465
63547
|
logger.error("Skills installation failed. Run with --verbose for details.");
|
|
63466
63548
|
return;
|
|
@@ -63551,7 +63633,7 @@ async function checkNeedsSudoPackages() {
|
|
|
63551
63633
|
}
|
|
63552
63634
|
}
|
|
63553
63635
|
function hasInstallState(skillsDir2) {
|
|
63554
|
-
const stateFilePath =
|
|
63636
|
+
const stateFilePath = join64(skillsDir2, ".install-state.json");
|
|
63555
63637
|
return existsSync49(stateFilePath);
|
|
63556
63638
|
}
|
|
63557
63639
|
var WHICH_COMMAND_TIMEOUT_MS = 5000;
|
|
@@ -63560,7 +63642,7 @@ var init_install_error_handler = __esm(() => {
|
|
|
63560
63642
|
});
|
|
63561
63643
|
|
|
63562
63644
|
// src/services/package-installer/skills-installer.ts
|
|
63563
|
-
import { join as
|
|
63645
|
+
import { join as join65 } from "node:path";
|
|
63564
63646
|
async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
63565
63647
|
const { skipConfirm = false, withSudo = false } = options2;
|
|
63566
63648
|
const displayName = "Skills Dependencies";
|
|
@@ -63586,7 +63668,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
63586
63668
|
const clack = await Promise.resolve().then(() => (init_dist2(), exports_dist));
|
|
63587
63669
|
const platform7 = process.platform;
|
|
63588
63670
|
const scriptName = platform7 === "win32" ? "install.ps1" : "install.sh";
|
|
63589
|
-
const scriptPath =
|
|
63671
|
+
const scriptPath = join65(skillsDir2, scriptName);
|
|
63590
63672
|
try {
|
|
63591
63673
|
validateScriptPath(skillsDir2, scriptPath);
|
|
63592
63674
|
} catch (error) {
|
|
@@ -63602,7 +63684,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
63602
63684
|
logger.warning(`Skills installation script not found: ${scriptPath}`);
|
|
63603
63685
|
logger.info("");
|
|
63604
63686
|
logger.info("\uD83D\uDCD6 Manual Installation Instructions:");
|
|
63605
|
-
logger.info(` See: ${
|
|
63687
|
+
logger.info(` See: ${join65(skillsDir2, "INSTALLATION.md")}`);
|
|
63606
63688
|
logger.info("");
|
|
63607
63689
|
logger.info("Quick start:");
|
|
63608
63690
|
logger.info(" cd .claude/skills/ai-multimodal/scripts");
|
|
@@ -63649,7 +63731,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
63649
63731
|
logger.info(` ${platform7 === "win32" ? `powershell -File "${scriptPath}"` : `bash ${scriptPath}`}`);
|
|
63650
63732
|
logger.info("");
|
|
63651
63733
|
logger.info("Or see complete guide:");
|
|
63652
|
-
logger.info(` ${
|
|
63734
|
+
logger.info(` ${join65(skillsDir2, "INSTALLATION.md")}`);
|
|
63653
63735
|
return {
|
|
63654
63736
|
success: false,
|
|
63655
63737
|
package: displayName,
|
|
@@ -63770,7 +63852,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
63770
63852
|
logger.info("\uD83D\uDCD6 Manual Installation Instructions:");
|
|
63771
63853
|
logger.info("");
|
|
63772
63854
|
logger.info("See complete guide:");
|
|
63773
|
-
logger.info(` cat ${
|
|
63855
|
+
logger.info(` cat ${join65(skillsDir2, "INSTALLATION.md")}`);
|
|
63774
63856
|
logger.info("");
|
|
63775
63857
|
logger.info("Quick start:");
|
|
63776
63858
|
logger.info(" cd .claude/skills/ai-multimodal/scripts");
|
|
@@ -63816,7 +63898,7 @@ var init_skills_installer2 = __esm(() => {
|
|
|
63816
63898
|
// src/services/package-installer/gemini-mcp/config-manager.ts
|
|
63817
63899
|
import { existsSync as existsSync50 } from "node:fs";
|
|
63818
63900
|
import { mkdir as mkdir17, readFile as readFile35, writeFile as writeFile20 } from "node:fs/promises";
|
|
63819
|
-
import { dirname as dirname21, join as
|
|
63901
|
+
import { dirname as dirname21, join as join66 } from "node:path";
|
|
63820
63902
|
async function readJsonFile(filePath) {
|
|
63821
63903
|
try {
|
|
63822
63904
|
const content = await readFile35(filePath, "utf-8");
|
|
@@ -63828,7 +63910,7 @@ async function readJsonFile(filePath) {
|
|
|
63828
63910
|
}
|
|
63829
63911
|
}
|
|
63830
63912
|
async function addGeminiToGitignore(projectDir) {
|
|
63831
|
-
const gitignorePath =
|
|
63913
|
+
const gitignorePath = join66(projectDir, ".gitignore");
|
|
63832
63914
|
const geminiPattern = ".gemini/";
|
|
63833
63915
|
try {
|
|
63834
63916
|
let content = "";
|
|
@@ -63919,13 +64001,13 @@ var init_config_manager2 = __esm(() => {
|
|
|
63919
64001
|
|
|
63920
64002
|
// src/services/package-installer/gemini-mcp/validation.ts
|
|
63921
64003
|
import { existsSync as existsSync51, lstatSync, readlinkSync } from "node:fs";
|
|
63922
|
-
import { homedir as
|
|
63923
|
-
import { join as
|
|
64004
|
+
import { homedir as homedir28 } from "node:os";
|
|
64005
|
+
import { join as join67 } from "node:path";
|
|
63924
64006
|
function getGlobalMcpConfigPath() {
|
|
63925
|
-
return
|
|
64007
|
+
return join67(homedir28(), ".claude", ".mcp.json");
|
|
63926
64008
|
}
|
|
63927
64009
|
function getLocalMcpConfigPath(projectDir) {
|
|
63928
|
-
return
|
|
64010
|
+
return join67(projectDir, ".mcp.json");
|
|
63929
64011
|
}
|
|
63930
64012
|
function findMcpConfigPath(projectDir) {
|
|
63931
64013
|
const localPath = getLocalMcpConfigPath(projectDir);
|
|
@@ -63943,9 +64025,9 @@ function findMcpConfigPath(projectDir) {
|
|
|
63943
64025
|
}
|
|
63944
64026
|
function getGeminiSettingsPath(projectDir, isGlobal) {
|
|
63945
64027
|
if (isGlobal) {
|
|
63946
|
-
return
|
|
64028
|
+
return join67(homedir28(), ".gemini", "settings.json");
|
|
63947
64029
|
}
|
|
63948
|
-
return
|
|
64030
|
+
return join67(projectDir, ".gemini", "settings.json");
|
|
63949
64031
|
}
|
|
63950
64032
|
function checkExistingGeminiConfig(projectDir, isGlobal = false) {
|
|
63951
64033
|
const geminiSettingsPath = getGeminiSettingsPath(projectDir, isGlobal);
|
|
@@ -63975,7 +64057,7 @@ var init_validation = __esm(() => {
|
|
|
63975
64057
|
// src/services/package-installer/gemini-mcp/linker-core.ts
|
|
63976
64058
|
import { existsSync as existsSync52 } from "node:fs";
|
|
63977
64059
|
import { mkdir as mkdir18, symlink as symlink2 } from "node:fs/promises";
|
|
63978
|
-
import { dirname as dirname22, join as
|
|
64060
|
+
import { dirname as dirname22, join as join68 } from "node:path";
|
|
63979
64061
|
async function createSymlink(targetPath, linkPath, projectDir, isGlobal) {
|
|
63980
64062
|
const linkDir = dirname22(linkPath);
|
|
63981
64063
|
if (!existsSync52(linkDir)) {
|
|
@@ -63986,7 +64068,7 @@ async function createSymlink(targetPath, linkPath, projectDir, isGlobal) {
|
|
|
63986
64068
|
if (isGlobal) {
|
|
63987
64069
|
symlinkTarget = getGlobalMcpConfigPath();
|
|
63988
64070
|
} else {
|
|
63989
|
-
const localMcpPath =
|
|
64071
|
+
const localMcpPath = join68(projectDir, ".mcp.json");
|
|
63990
64072
|
const isLocalConfig = targetPath === localMcpPath;
|
|
63991
64073
|
symlinkTarget = isLocalConfig ? "../.mcp.json" : targetPath;
|
|
63992
64074
|
}
|
|
@@ -70887,14 +70969,14 @@ async function checkCliInstallMethod() {
|
|
|
70887
70969
|
}
|
|
70888
70970
|
// src/domains/health-checks/checkers/claude-md-checker.ts
|
|
70889
70971
|
import { existsSync as existsSync40, statSync as statSync5 } from "node:fs";
|
|
70890
|
-
import { join as
|
|
70972
|
+
import { join as join46 } from "node:path";
|
|
70891
70973
|
function checkClaudeMd(setup, projectDir) {
|
|
70892
70974
|
const results = [];
|
|
70893
70975
|
if (setup.global.path) {
|
|
70894
|
-
const globalClaudeMd =
|
|
70976
|
+
const globalClaudeMd = join46(setup.global.path, "CLAUDE.md");
|
|
70895
70977
|
results.push(checkClaudeMdFile(globalClaudeMd, "Global CLAUDE.md", "ck-global-claude-md"));
|
|
70896
70978
|
}
|
|
70897
|
-
const projectClaudeMd =
|
|
70979
|
+
const projectClaudeMd = join46(projectDir, ".claude", "CLAUDE.md");
|
|
70898
70980
|
results.push(checkClaudeMdFile(projectClaudeMd, "Project CLAUDE.md", "ck-project-claude-md"));
|
|
70899
70981
|
return results;
|
|
70900
70982
|
}
|
|
@@ -70953,9 +71035,9 @@ function checkClaudeMdFile(path4, name, id) {
|
|
|
70953
71035
|
}
|
|
70954
71036
|
// src/domains/health-checks/checkers/active-plan-checker.ts
|
|
70955
71037
|
import { existsSync as existsSync41, readFileSync as readFileSync9 } from "node:fs";
|
|
70956
|
-
import { join as
|
|
71038
|
+
import { join as join47 } from "node:path";
|
|
70957
71039
|
function checkActivePlan(projectDir) {
|
|
70958
|
-
const activePlanPath =
|
|
71040
|
+
const activePlanPath = join47(projectDir, ".claude", "active-plan");
|
|
70959
71041
|
if (!existsSync41(activePlanPath)) {
|
|
70960
71042
|
return {
|
|
70961
71043
|
id: "ck-active-plan",
|
|
@@ -70969,7 +71051,7 @@ function checkActivePlan(projectDir) {
|
|
|
70969
71051
|
}
|
|
70970
71052
|
try {
|
|
70971
71053
|
const targetPath = readFileSync9(activePlanPath, "utf-8").trim();
|
|
70972
|
-
const fullPath =
|
|
71054
|
+
const fullPath = join47(projectDir, targetPath);
|
|
70973
71055
|
if (!existsSync41(fullPath)) {
|
|
70974
71056
|
return {
|
|
70975
71057
|
id: "ck-active-plan",
|
|
@@ -71007,13 +71089,13 @@ function checkActivePlan(projectDir) {
|
|
|
71007
71089
|
}
|
|
71008
71090
|
// src/domains/health-checks/checkers/skills-checker.ts
|
|
71009
71091
|
import { existsSync as existsSync42 } from "node:fs";
|
|
71010
|
-
import { join as
|
|
71092
|
+
import { join as join48 } from "node:path";
|
|
71011
71093
|
function checkSkillsScripts(setup) {
|
|
71012
71094
|
const results = [];
|
|
71013
71095
|
const platform5 = process.platform;
|
|
71014
71096
|
const scriptName = platform5 === "win32" ? "install.ps1" : "install.sh";
|
|
71015
71097
|
if (setup.global.path) {
|
|
71016
|
-
const globalScriptPath =
|
|
71098
|
+
const globalScriptPath = join48(setup.global.path, "skills", scriptName);
|
|
71017
71099
|
const hasGlobalScript = existsSync42(globalScriptPath);
|
|
71018
71100
|
results.push({
|
|
71019
71101
|
id: "ck-global-skills-script",
|
|
@@ -71028,7 +71110,7 @@ function checkSkillsScripts(setup) {
|
|
|
71028
71110
|
});
|
|
71029
71111
|
}
|
|
71030
71112
|
if (setup.project.metadata) {
|
|
71031
|
-
const projectScriptPath =
|
|
71113
|
+
const projectScriptPath = join48(setup.project.path, "skills", scriptName);
|
|
71032
71114
|
const hasProjectScript = existsSync42(projectScriptPath);
|
|
71033
71115
|
results.push({
|
|
71034
71116
|
id: "ck-project-skills-script",
|
|
@@ -71067,7 +71149,7 @@ function checkComponentCounts(setup) {
|
|
|
71067
71149
|
init_logger();
|
|
71068
71150
|
init_path_resolver();
|
|
71069
71151
|
import { constants as constants2, access as access2, unlink as unlink7, writeFile as writeFile16 } from "node:fs/promises";
|
|
71070
|
-
import { join as
|
|
71152
|
+
import { join as join49 } from "node:path";
|
|
71071
71153
|
|
|
71072
71154
|
// src/domains/health-checks/checkers/shared.ts
|
|
71073
71155
|
init_environment();
|
|
@@ -71133,7 +71215,7 @@ async function checkGlobalDirWritable() {
|
|
|
71133
71215
|
}
|
|
71134
71216
|
const timestamp = Date.now();
|
|
71135
71217
|
const random = Math.random().toString(36).substring(2);
|
|
71136
|
-
const testFile =
|
|
71218
|
+
const testFile = join49(globalDir, `.ck-write-test-${timestamp}-${random}`);
|
|
71137
71219
|
try {
|
|
71138
71220
|
await writeFile16(testFile, "test", { encoding: "utf-8", flag: "wx" });
|
|
71139
71221
|
} catch (error) {
|
|
@@ -71169,7 +71251,7 @@ async function checkGlobalDirWritable() {
|
|
|
71169
71251
|
init_path_resolver();
|
|
71170
71252
|
import { existsSync as existsSync43 } from "node:fs";
|
|
71171
71253
|
import { readdir as readdir10 } from "node:fs/promises";
|
|
71172
|
-
import { join as
|
|
71254
|
+
import { join as join50 } from "node:path";
|
|
71173
71255
|
|
|
71174
71256
|
// src/domains/health-checks/utils/path-normalizer.ts
|
|
71175
71257
|
import { normalize as normalize4 } from "node:path";
|
|
@@ -71181,8 +71263,8 @@ function normalizePath2(filePath) {
|
|
|
71181
71263
|
|
|
71182
71264
|
// src/domains/health-checks/checkers/hooks-checker.ts
|
|
71183
71265
|
async function checkHooksExist(projectDir) {
|
|
71184
|
-
const globalHooksDir =
|
|
71185
|
-
const projectHooksDir =
|
|
71266
|
+
const globalHooksDir = join50(PathResolver.getGlobalKitDir(), "hooks");
|
|
71267
|
+
const projectHooksDir = join50(projectDir, ".claude", "hooks");
|
|
71186
71268
|
const globalExists = existsSync43(globalHooksDir);
|
|
71187
71269
|
const projectExists = existsSync43(projectHooksDir);
|
|
71188
71270
|
let hookCount = 0;
|
|
@@ -71191,7 +71273,7 @@ async function checkHooksExist(projectDir) {
|
|
|
71191
71273
|
const files = await readdir10(globalHooksDir, { withFileTypes: false });
|
|
71192
71274
|
const hooks = files.filter((f3) => HOOK_EXTENSIONS2.some((ext) => f3.endsWith(ext)));
|
|
71193
71275
|
hooks.forEach((hook) => {
|
|
71194
|
-
const fullPath =
|
|
71276
|
+
const fullPath = join50(globalHooksDir, hook);
|
|
71195
71277
|
checkedFiles.add(normalizePath2(fullPath));
|
|
71196
71278
|
});
|
|
71197
71279
|
}
|
|
@@ -71201,7 +71283,7 @@ async function checkHooksExist(projectDir) {
|
|
|
71201
71283
|
const files = await readdir10(projectHooksDir, { withFileTypes: false });
|
|
71202
71284
|
const hooks = files.filter((f3) => HOOK_EXTENSIONS2.some((ext) => f3.endsWith(ext)));
|
|
71203
71285
|
hooks.forEach((hook) => {
|
|
71204
|
-
const fullPath =
|
|
71286
|
+
const fullPath = join50(projectHooksDir, hook);
|
|
71205
71287
|
checkedFiles.add(normalizePath2(fullPath));
|
|
71206
71288
|
});
|
|
71207
71289
|
}
|
|
@@ -71233,10 +71315,10 @@ init_logger();
|
|
|
71233
71315
|
init_path_resolver();
|
|
71234
71316
|
import { existsSync as existsSync44 } from "node:fs";
|
|
71235
71317
|
import { readFile as readFile29 } from "node:fs/promises";
|
|
71236
|
-
import { join as
|
|
71318
|
+
import { join as join51 } from "node:path";
|
|
71237
71319
|
async function checkSettingsValid(projectDir) {
|
|
71238
|
-
const globalSettings =
|
|
71239
|
-
const projectSettings =
|
|
71320
|
+
const globalSettings = join51(PathResolver.getGlobalKitDir(), "settings.json");
|
|
71321
|
+
const projectSettings = join51(projectDir, ".claude", "settings.json");
|
|
71240
71322
|
const settingsPath = existsSync44(globalSettings) ? globalSettings : existsSync44(projectSettings) ? projectSettings : null;
|
|
71241
71323
|
if (!settingsPath) {
|
|
71242
71324
|
return {
|
|
@@ -71308,11 +71390,11 @@ init_logger();
|
|
|
71308
71390
|
init_path_resolver();
|
|
71309
71391
|
import { existsSync as existsSync45 } from "node:fs";
|
|
71310
71392
|
import { readFile as readFile30 } from "node:fs/promises";
|
|
71311
|
-
import { homedir as
|
|
71312
|
-
import { dirname as dirname19, join as
|
|
71393
|
+
import { homedir as homedir26 } from "node:os";
|
|
71394
|
+
import { dirname as dirname19, join as join52, normalize as normalize5, resolve as resolve13 } from "node:path";
|
|
71313
71395
|
async function checkPathRefsValid(projectDir) {
|
|
71314
|
-
const globalClaudeMd =
|
|
71315
|
-
const projectClaudeMd =
|
|
71396
|
+
const globalClaudeMd = join52(PathResolver.getGlobalKitDir(), "CLAUDE.md");
|
|
71397
|
+
const projectClaudeMd = join52(projectDir, ".claude", "CLAUDE.md");
|
|
71316
71398
|
const claudeMdPath = existsSync45(globalClaudeMd) ? globalClaudeMd : existsSync45(projectClaudeMd) ? projectClaudeMd : null;
|
|
71317
71399
|
if (!claudeMdPath) {
|
|
71318
71400
|
return {
|
|
@@ -71341,7 +71423,7 @@ async function checkPathRefsValid(projectDir) {
|
|
|
71341
71423
|
};
|
|
71342
71424
|
}
|
|
71343
71425
|
const baseDir = dirname19(claudeMdPath);
|
|
71344
|
-
const home8 =
|
|
71426
|
+
const home8 = homedir26();
|
|
71345
71427
|
const broken = [];
|
|
71346
71428
|
for (const ref of refs) {
|
|
71347
71429
|
let refPath;
|
|
@@ -71407,7 +71489,7 @@ async function checkPathRefsValid(projectDir) {
|
|
|
71407
71489
|
// src/domains/health-checks/checkers/config-completeness-checker.ts
|
|
71408
71490
|
import { existsSync as existsSync46 } from "node:fs";
|
|
71409
71491
|
import { readdir as readdir11 } from "node:fs/promises";
|
|
71410
|
-
import { join as
|
|
71492
|
+
import { join as join53 } from "node:path";
|
|
71411
71493
|
async function checkProjectConfigCompleteness(setup, projectDir) {
|
|
71412
71494
|
if (setup.project.path === setup.global.path) {
|
|
71413
71495
|
return {
|
|
@@ -71420,16 +71502,16 @@ async function checkProjectConfigCompleteness(setup, projectDir) {
|
|
|
71420
71502
|
autoFixable: false
|
|
71421
71503
|
};
|
|
71422
71504
|
}
|
|
71423
|
-
const projectClaudeDir =
|
|
71505
|
+
const projectClaudeDir = join53(projectDir, ".claude");
|
|
71424
71506
|
const requiredDirs = ["agents", "commands", "skills"];
|
|
71425
71507
|
const missingDirs = [];
|
|
71426
71508
|
for (const dir of requiredDirs) {
|
|
71427
|
-
const dirPath =
|
|
71509
|
+
const dirPath = join53(projectClaudeDir, dir);
|
|
71428
71510
|
if (!existsSync46(dirPath)) {
|
|
71429
71511
|
missingDirs.push(dir);
|
|
71430
71512
|
}
|
|
71431
71513
|
}
|
|
71432
|
-
const hasRulesOrWorkflows = existsSync46(
|
|
71514
|
+
const hasRulesOrWorkflows = existsSync46(join53(projectClaudeDir, "rules")) || existsSync46(join53(projectClaudeDir, "workflows"));
|
|
71433
71515
|
if (!hasRulesOrWorkflows) {
|
|
71434
71516
|
missingDirs.push("rules");
|
|
71435
71517
|
}
|
|
@@ -71474,7 +71556,7 @@ async function checkProjectConfigCompleteness(setup, projectDir) {
|
|
|
71474
71556
|
};
|
|
71475
71557
|
}
|
|
71476
71558
|
// src/domains/health-checks/checkers/env-keys-checker.ts
|
|
71477
|
-
import { join as
|
|
71559
|
+
import { join as join55 } from "node:path";
|
|
71478
71560
|
|
|
71479
71561
|
// src/domains/installation/setup-wizard.ts
|
|
71480
71562
|
init_config_generator();
|
|
@@ -71483,7 +71565,7 @@ init_logger();
|
|
|
71483
71565
|
init_path_resolver();
|
|
71484
71566
|
init_dist2();
|
|
71485
71567
|
var import_fs_extra6 = __toESM(require_lib3(), 1);
|
|
71486
|
-
import { join as
|
|
71568
|
+
import { join as join54 } from "node:path";
|
|
71487
71569
|
var REQUIRED_ENV_KEYS = [
|
|
71488
71570
|
{ key: "GEMINI_API_KEY", label: "Gemini API Key" }
|
|
71489
71571
|
];
|
|
@@ -71560,7 +71642,7 @@ async function parseEnvFile(path4) {
|
|
|
71560
71642
|
}
|
|
71561
71643
|
}
|
|
71562
71644
|
async function checkGlobalConfig() {
|
|
71563
|
-
const globalEnvPath =
|
|
71645
|
+
const globalEnvPath = join54(PathResolver.getGlobalKitDir(), ".env");
|
|
71564
71646
|
if (!await import_fs_extra6.pathExists(globalEnvPath))
|
|
71565
71647
|
return false;
|
|
71566
71648
|
const env2 = await parseEnvFile(globalEnvPath);
|
|
@@ -71576,7 +71658,7 @@ async function runSetupWizard(options2) {
|
|
|
71576
71658
|
let globalEnv = {};
|
|
71577
71659
|
const hasGlobalConfig = !isGlobal && await checkGlobalConfig();
|
|
71578
71660
|
if (!isGlobal) {
|
|
71579
|
-
const globalEnvPath =
|
|
71661
|
+
const globalEnvPath = join54(PathResolver.getGlobalKitDir(), ".env");
|
|
71580
71662
|
if (await import_fs_extra6.pathExists(globalEnvPath)) {
|
|
71581
71663
|
globalEnv = await parseEnvFile(globalEnvPath);
|
|
71582
71664
|
}
|
|
@@ -71639,7 +71721,7 @@ async function runSetupWizard(options2) {
|
|
|
71639
71721
|
}
|
|
71640
71722
|
}
|
|
71641
71723
|
await generateEnvFile(targetDir, values);
|
|
71642
|
-
f2.success(`Configuration saved to ${
|
|
71724
|
+
f2.success(`Configuration saved to ${join54(targetDir, ".env")}`);
|
|
71643
71725
|
return true;
|
|
71644
71726
|
}
|
|
71645
71727
|
async function promptForAdditionalGeminiKeys(primaryKey) {
|
|
@@ -71714,7 +71796,7 @@ Optional: DISCORD_WEBHOOK_URL, TELEGRAM_BOT_TOKEN`, "Configuration skipped");
|
|
|
71714
71796
|
async function checkEnvKeys(setup) {
|
|
71715
71797
|
const results = [];
|
|
71716
71798
|
if (setup.global.path) {
|
|
71717
|
-
const globalEnvPath =
|
|
71799
|
+
const globalEnvPath = join55(setup.global.path, ".env");
|
|
71718
71800
|
const globalCheck = await checkRequiredKeysExist(globalEnvPath);
|
|
71719
71801
|
if (!globalCheck.allPresent) {
|
|
71720
71802
|
const missingKeys = globalCheck.missing.map((m2) => m2.label).join(", ");
|
|
@@ -71743,7 +71825,7 @@ async function checkEnvKeys(setup) {
|
|
|
71743
71825
|
}
|
|
71744
71826
|
}
|
|
71745
71827
|
if (setup.project.metadata) {
|
|
71746
|
-
const projectEnvPath =
|
|
71828
|
+
const projectEnvPath = join55(setup.project.path, ".env");
|
|
71747
71829
|
const projectCheck = await checkRequiredKeysExist(projectEnvPath);
|
|
71748
71830
|
if (!projectCheck.allPresent) {
|
|
71749
71831
|
const missingKeys = projectCheck.missing.map((m2) => m2.label).join(", ");
|
|
@@ -71781,7 +71863,7 @@ import { spawnSync as spawnSync2 } from "node:child_process";
|
|
|
71781
71863
|
import { existsSync as existsSync47, readFileSync as readFileSync10, statSync as statSync6, writeFileSync as writeFileSync3 } from "node:fs";
|
|
71782
71864
|
import { readdir as readdir12 } from "node:fs/promises";
|
|
71783
71865
|
import { tmpdir } from "node:os";
|
|
71784
|
-
import { join as
|
|
71866
|
+
import { join as join56, resolve as resolve14 } from "node:path";
|
|
71785
71867
|
var HOOK_CHECK_TIMEOUT_MS = 5000;
|
|
71786
71868
|
var PYTHON_CHECK_TIMEOUT_MS = 3000;
|
|
71787
71869
|
var MAX_LOG_FILE_SIZE_BYTES = 10 * 1024 * 1024;
|
|
@@ -71826,7 +71908,7 @@ async function checkHookSyntax(projectDir) {
|
|
|
71826
71908
|
}
|
|
71827
71909
|
const errors2 = [];
|
|
71828
71910
|
for (const file of cjsFiles) {
|
|
71829
|
-
const filePath =
|
|
71911
|
+
const filePath = join56(hooksDir, file);
|
|
71830
71912
|
if (!isPathWithin(filePath, hooksDir))
|
|
71831
71913
|
continue;
|
|
71832
71914
|
const result = spawnSync2("node", ["--check", filePath], {
|
|
@@ -71912,7 +71994,7 @@ async function checkHookDeps(projectDir) {
|
|
|
71912
71994
|
const missingDeps = [];
|
|
71913
71995
|
const requireRegex = /require\(['"]([^'"]+)['"]\)/g;
|
|
71914
71996
|
for (const file of cjsFiles) {
|
|
71915
|
-
const filePath =
|
|
71997
|
+
const filePath = join56(hooksDir, file);
|
|
71916
71998
|
if (!isPathWithin(filePath, hooksDir))
|
|
71917
71999
|
continue;
|
|
71918
72000
|
const content = readFileSync10(filePath, "utf-8");
|
|
@@ -71922,10 +72004,10 @@ async function checkHookDeps(projectDir) {
|
|
|
71922
72004
|
continue;
|
|
71923
72005
|
}
|
|
71924
72006
|
if (depPath.startsWith(".")) {
|
|
71925
|
-
const resolvedPath =
|
|
72007
|
+
const resolvedPath = join56(hooksDir, depPath);
|
|
71926
72008
|
const extensions = [".js", ".cjs", ".mjs", ".json"];
|
|
71927
72009
|
const indexFiles = ["index.js", "index.cjs", "index.mjs"];
|
|
71928
|
-
const exists = existsSync47(resolvedPath) || extensions.some((ext) => existsSync47(resolvedPath + ext)) || indexFiles.some((idx) => existsSync47(
|
|
72010
|
+
const exists = existsSync47(resolvedPath) || extensions.some((ext) => existsSync47(resolvedPath + ext)) || indexFiles.some((idx) => existsSync47(join56(resolvedPath, idx)));
|
|
71929
72011
|
if (!exists) {
|
|
71930
72012
|
missingDeps.push(`${file}: ${depPath}`);
|
|
71931
72013
|
}
|
|
@@ -72042,11 +72124,11 @@ async function checkHookRuntime(projectDir) {
|
|
|
72042
72124
|
}
|
|
72043
72125
|
const syntheticPayload = JSON.stringify({
|
|
72044
72126
|
tool_name: "Read",
|
|
72045
|
-
tool_input: { file_path:
|
|
72127
|
+
tool_input: { file_path: join56(tmpdir(), "ck-doctor-test.txt") }
|
|
72046
72128
|
});
|
|
72047
72129
|
const failures = [];
|
|
72048
72130
|
for (const file of cjsFiles) {
|
|
72049
|
-
const filePath =
|
|
72131
|
+
const filePath = join56(hooksDir, file);
|
|
72050
72132
|
if (!isPathWithin(filePath, hooksDir))
|
|
72051
72133
|
continue;
|
|
72052
72134
|
const result = spawnSync2("node", [filePath], {
|
|
@@ -72108,8 +72190,8 @@ async function checkHookRuntime(projectDir) {
|
|
|
72108
72190
|
}
|
|
72109
72191
|
}
|
|
72110
72192
|
async function checkHookConfig(projectDir) {
|
|
72111
|
-
const projectConfigPath =
|
|
72112
|
-
const globalConfigPath =
|
|
72193
|
+
const projectConfigPath = join56(projectDir, ".claude", ".ck.json");
|
|
72194
|
+
const globalConfigPath = join56(PathResolver.getGlobalKitDir(), ".ck.json");
|
|
72113
72195
|
const configPath = existsSync47(projectConfigPath) ? projectConfigPath : existsSync47(globalConfigPath) ? globalConfigPath : null;
|
|
72114
72196
|
if (!configPath) {
|
|
72115
72197
|
return {
|
|
@@ -72233,7 +72315,7 @@ async function checkHookLogs(projectDir) {
|
|
|
72233
72315
|
autoFixable: false
|
|
72234
72316
|
};
|
|
72235
72317
|
}
|
|
72236
|
-
const logPath =
|
|
72318
|
+
const logPath = join56(hooksDir, ".logs", "hook-log.jsonl");
|
|
72237
72319
|
if (!existsSync47(logPath)) {
|
|
72238
72320
|
return {
|
|
72239
72321
|
id: "hook-logs",
|
|
@@ -72488,9 +72570,9 @@ async function checkCliVersion() {
|
|
|
72488
72570
|
}
|
|
72489
72571
|
async function checkPythonVenv(projectDir) {
|
|
72490
72572
|
const isWindows3 = process.platform === "win32";
|
|
72491
|
-
const venvBin = isWindows3 ?
|
|
72492
|
-
const projectVenvPath =
|
|
72493
|
-
const globalVenvPath =
|
|
72573
|
+
const venvBin = isWindows3 ? join56("Scripts", "python.exe") : join56("bin", "python3");
|
|
72574
|
+
const projectVenvPath = join56(projectDir, ".claude", "skills", ".venv", venvBin);
|
|
72575
|
+
const globalVenvPath = join56(PathResolver.getGlobalKitDir(), "skills", ".venv", venvBin);
|
|
72494
72576
|
const venvPath = existsSync47(projectVenvPath) ? projectVenvPath : existsSync47(globalVenvPath) ? globalVenvPath : null;
|
|
72495
72577
|
if (!venvPath) {
|
|
72496
72578
|
return {
|
|
@@ -72970,8 +73052,8 @@ import { platform as platform6 } from "node:os";
|
|
|
72970
73052
|
init_environment();
|
|
72971
73053
|
init_path_resolver();
|
|
72972
73054
|
import { constants as constants3, access as access3, mkdir as mkdir14, readFile as readFile32, unlink as unlink8, writeFile as writeFile17 } from "node:fs/promises";
|
|
72973
|
-
import { arch as arch2, homedir as
|
|
72974
|
-
import { join as
|
|
73055
|
+
import { arch as arch2, homedir as homedir27, platform as platform5 } from "node:os";
|
|
73056
|
+
import { join as join58, normalize as normalize6 } from "node:path";
|
|
72975
73057
|
function shouldSkipExpensiveOperations4() {
|
|
72976
73058
|
return shouldSkipExpensiveOperations();
|
|
72977
73059
|
}
|
|
@@ -72993,7 +73075,7 @@ async function checkPlatformDetect() {
|
|
|
72993
73075
|
};
|
|
72994
73076
|
}
|
|
72995
73077
|
async function checkHomeDirResolution() {
|
|
72996
|
-
const nodeHome = normalize6(
|
|
73078
|
+
const nodeHome = normalize6(homedir27());
|
|
72997
73079
|
const rawEnvHome = getHomeDirectoryFromEnv(platform5());
|
|
72998
73080
|
const envHome = rawEnvHome ? normalize6(rawEnvHome) : "";
|
|
72999
73081
|
const match = nodeHome === envHome && envHome !== "";
|
|
@@ -73062,7 +73144,7 @@ async function checkGlobalDirAccess() {
|
|
|
73062
73144
|
autoFixable: false
|
|
73063
73145
|
};
|
|
73064
73146
|
}
|
|
73065
|
-
const testFile =
|
|
73147
|
+
const testFile = join58(globalDir, ".ck-doctor-access-test");
|
|
73066
73148
|
try {
|
|
73067
73149
|
await mkdir14(globalDir, { recursive: true });
|
|
73068
73150
|
await writeFile17(testFile, "test", "utf-8");
|
|
@@ -73140,7 +73222,7 @@ async function checkWSLBoundary() {
|
|
|
73140
73222
|
// src/domains/health-checks/platform/windows-checker.ts
|
|
73141
73223
|
init_path_resolver();
|
|
73142
73224
|
import { mkdir as mkdir15, symlink, unlink as unlink9, writeFile as writeFile18 } from "node:fs/promises";
|
|
73143
|
-
import { join as
|
|
73225
|
+
import { join as join59 } from "node:path";
|
|
73144
73226
|
async function checkLongPathSupport() {
|
|
73145
73227
|
if (shouldSkipExpensiveOperations4()) {
|
|
73146
73228
|
return {
|
|
@@ -73192,8 +73274,8 @@ async function checkSymlinkSupport() {
|
|
|
73192
73274
|
};
|
|
73193
73275
|
}
|
|
73194
73276
|
const testDir = PathResolver.getGlobalKitDir();
|
|
73195
|
-
const target =
|
|
73196
|
-
const link =
|
|
73277
|
+
const target = join59(testDir, ".ck-symlink-test-target");
|
|
73278
|
+
const link = join59(testDir, ".ck-symlink-test-link");
|
|
73197
73279
|
try {
|
|
73198
73280
|
await mkdir15(testDir, { recursive: true });
|
|
73199
73281
|
await writeFile18(target, "test", "utf-8");
|
|
@@ -73487,7 +73569,7 @@ class AutoHealer {
|
|
|
73487
73569
|
import { execSync as execSync3, spawnSync as spawnSync5 } from "node:child_process";
|
|
73488
73570
|
import { readFileSync as readFileSync11, unlinkSync, writeFileSync as writeFileSync4 } from "node:fs";
|
|
73489
73571
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
73490
|
-
import { dirname as dirname20, join as
|
|
73572
|
+
import { dirname as dirname20, join as join60 } from "node:path";
|
|
73491
73573
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
73492
73574
|
init_environment();
|
|
73493
73575
|
init_logger();
|
|
@@ -73495,7 +73577,7 @@ init_dist2();
|
|
|
73495
73577
|
function getCliVersion4() {
|
|
73496
73578
|
try {
|
|
73497
73579
|
const __dirname4 = dirname20(fileURLToPath4(import.meta.url));
|
|
73498
|
-
const pkgPath =
|
|
73580
|
+
const pkgPath = join60(__dirname4, "../../../package.json");
|
|
73499
73581
|
const pkg = JSON.parse(readFileSync11(pkgPath, "utf-8"));
|
|
73500
73582
|
return pkg.version || "unknown";
|
|
73501
73583
|
} catch (err) {
|
|
@@ -73634,7 +73716,7 @@ class ReportGenerator {
|
|
|
73634
73716
|
return null;
|
|
73635
73717
|
}
|
|
73636
73718
|
}
|
|
73637
|
-
const tmpFile =
|
|
73719
|
+
const tmpFile = join60(tmpdir3(), `ck-report-${Date.now()}.txt`);
|
|
73638
73720
|
writeFileSync4(tmpFile, report);
|
|
73639
73721
|
try {
|
|
73640
73722
|
const result = spawnSync5("gh", ["gist", "create", tmpFile, "--desc", "ClaudeKit Diagnostic Report"], {
|
|
@@ -73960,7 +74042,7 @@ init_logger();
|
|
|
73960
74042
|
init_path_resolver();
|
|
73961
74043
|
var import_compare_versions6 = __toESM(require_umd(), 1);
|
|
73962
74044
|
import { mkdir as mkdir16, readFile as readFile33, unlink as unlink10, writeFile as writeFile19 } from "node:fs/promises";
|
|
73963
|
-
import { join as
|
|
74045
|
+
import { join as join61 } from "node:path";
|
|
73964
74046
|
var CACHE_TTL_HOURS = 24;
|
|
73965
74047
|
var DEFAULT_CACHE_TTL_MS = CACHE_TTL_HOURS * 60 * 60 * 1000;
|
|
73966
74048
|
var MIN_CACHE_TTL_MS = 60 * 1000;
|
|
@@ -73997,7 +74079,7 @@ var KIT_REPOS = {
|
|
|
73997
74079
|
class ConfigVersionChecker {
|
|
73998
74080
|
static getCacheFilePath(kitType, global3) {
|
|
73999
74081
|
const cacheDir = PathResolver.getCacheDir(global3);
|
|
74000
|
-
return
|
|
74082
|
+
return join61(cacheDir, `${kitType}-${CACHE_FILENAME}`);
|
|
74001
74083
|
}
|
|
74002
74084
|
static async loadCache(kitType, global3) {
|
|
74003
74085
|
try {
|
|
@@ -74160,7 +74242,7 @@ class ConfigVersionChecker {
|
|
|
74160
74242
|
}
|
|
74161
74243
|
// src/domains/sync/sync-engine.ts
|
|
74162
74244
|
import { lstat as lstat3, readFile as readFile34, readlink, realpath as realpath3, stat as stat9 } from "node:fs/promises";
|
|
74163
|
-
import { isAbsolute as isAbsolute3, join as
|
|
74245
|
+
import { isAbsolute as isAbsolute3, join as join62, normalize as normalize7, relative as relative8 } from "node:path";
|
|
74164
74246
|
|
|
74165
74247
|
// src/services/file-operations/ownership-checker.ts
|
|
74166
74248
|
init_metadata_migration();
|
|
@@ -75521,7 +75603,7 @@ async function validateSymlinkChain(path5, basePath, maxDepth = MAX_SYMLINK_DEPT
|
|
|
75521
75603
|
if (!stats.isSymbolicLink())
|
|
75522
75604
|
break;
|
|
75523
75605
|
const target = await readlink(current);
|
|
75524
|
-
const resolvedTarget = isAbsolute3(target) ? target :
|
|
75606
|
+
const resolvedTarget = isAbsolute3(target) ? target : join62(current, "..", target);
|
|
75525
75607
|
const normalizedTarget = normalize7(resolvedTarget);
|
|
75526
75608
|
const rel = relative8(basePath, normalizedTarget);
|
|
75527
75609
|
if (rel.startsWith("..") || isAbsolute3(rel)) {
|
|
@@ -75557,7 +75639,7 @@ async function validateSyncPath(basePath, filePath) {
|
|
|
75557
75639
|
if (normalized.startsWith("..") || normalized.includes("/../")) {
|
|
75558
75640
|
throw new Error(`Path traversal not allowed: ${filePath}`);
|
|
75559
75641
|
}
|
|
75560
|
-
const fullPath =
|
|
75642
|
+
const fullPath = join62(basePath, normalized);
|
|
75561
75643
|
const rel = relative8(basePath, fullPath);
|
|
75562
75644
|
if (rel.startsWith("..") || isAbsolute3(rel)) {
|
|
75563
75645
|
throw new Error(`Path escapes base directory: ${filePath}`);
|
|
@@ -75572,7 +75654,7 @@ async function validateSyncPath(basePath, filePath) {
|
|
|
75572
75654
|
}
|
|
75573
75655
|
} catch (error) {
|
|
75574
75656
|
if (error.code === "ENOENT") {
|
|
75575
|
-
const parentPath =
|
|
75657
|
+
const parentPath = join62(fullPath, "..");
|
|
75576
75658
|
try {
|
|
75577
75659
|
const resolvedBase = await realpath3(basePath);
|
|
75578
75660
|
const resolvedParent = await realpath3(parentPath);
|
|
@@ -76754,7 +76836,7 @@ init_logger();
|
|
|
76754
76836
|
var import_proper_lockfile4 = __toESM(require_proper_lockfile(), 1);
|
|
76755
76837
|
import { mkdir as mkdir19 } from "node:fs/promises";
|
|
76756
76838
|
import os5 from "node:os";
|
|
76757
|
-
import { join as
|
|
76839
|
+
import { join as join69 } from "node:path";
|
|
76758
76840
|
var LOCK_CONFIG = {
|
|
76759
76841
|
stale: 60000,
|
|
76760
76842
|
retries: 0
|
|
@@ -76762,12 +76844,12 @@ var LOCK_CONFIG = {
|
|
|
76762
76844
|
var activeLocks = new Set;
|
|
76763
76845
|
var cleanupRegistered = false;
|
|
76764
76846
|
function getLocksDir() {
|
|
76765
|
-
return
|
|
76847
|
+
return join69(os5.homedir(), ".claudekit", "locks");
|
|
76766
76848
|
}
|
|
76767
76849
|
function cleanupLocks() {
|
|
76768
76850
|
for (const name of activeLocks) {
|
|
76769
76851
|
try {
|
|
76770
|
-
const lockPath =
|
|
76852
|
+
const lockPath = join69(getLocksDir(), `${name}.lock`);
|
|
76771
76853
|
import_proper_lockfile4.default.unlockSync(lockPath, { realpath: false });
|
|
76772
76854
|
} catch {
|
|
76773
76855
|
try {
|
|
@@ -76790,7 +76872,7 @@ async function ensureLocksDir() {
|
|
|
76790
76872
|
async function withProcessLock(lockName, fn) {
|
|
76791
76873
|
registerCleanupHandlers();
|
|
76792
76874
|
await ensureLocksDir();
|
|
76793
|
-
const lockPath =
|
|
76875
|
+
const lockPath = join69(getLocksDir(), `${lockName}.lock`);
|
|
76794
76876
|
let release;
|
|
76795
76877
|
try {
|
|
76796
76878
|
release = await import_proper_lockfile4.default.lock(lockPath, { ...LOCK_CONFIG, realpath: false });
|
|
@@ -76821,7 +76903,7 @@ init_logger();
|
|
|
76821
76903
|
init_logger();
|
|
76822
76904
|
init_path_resolver();
|
|
76823
76905
|
var import_fs_extra7 = __toESM(require_lib3(), 1);
|
|
76824
|
-
import { join as
|
|
76906
|
+
import { join as join70 } from "node:path";
|
|
76825
76907
|
async function handleConflicts(ctx) {
|
|
76826
76908
|
if (ctx.cancelled)
|
|
76827
76909
|
return ctx;
|
|
@@ -76830,7 +76912,7 @@ async function handleConflicts(ctx) {
|
|
|
76830
76912
|
if (PathResolver.isLocalSameAsGlobal()) {
|
|
76831
76913
|
return ctx;
|
|
76832
76914
|
}
|
|
76833
|
-
const localSettingsPath =
|
|
76915
|
+
const localSettingsPath = join70(process.cwd(), ".claude", "settings.json");
|
|
76834
76916
|
if (!await import_fs_extra7.pathExists(localSettingsPath)) {
|
|
76835
76917
|
return ctx;
|
|
76836
76918
|
}
|
|
@@ -76845,7 +76927,7 @@ async function handleConflicts(ctx) {
|
|
|
76845
76927
|
return { ...ctx, cancelled: true };
|
|
76846
76928
|
}
|
|
76847
76929
|
if (choice === "remove") {
|
|
76848
|
-
const localClaudeDir =
|
|
76930
|
+
const localClaudeDir = join70(process.cwd(), ".claude");
|
|
76849
76931
|
try {
|
|
76850
76932
|
await import_fs_extra7.remove(localClaudeDir);
|
|
76851
76933
|
logger.success("Removed local .claude/ directory");
|
|
@@ -76942,7 +77024,7 @@ init_logger();
|
|
|
76942
77024
|
init_safe_spinner();
|
|
76943
77025
|
import { mkdir as mkdir25, stat as stat12 } from "node:fs/promises";
|
|
76944
77026
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
76945
|
-
import { join as
|
|
77027
|
+
import { join as join77 } from "node:path";
|
|
76946
77028
|
|
|
76947
77029
|
// src/shared/temp-cleanup.ts
|
|
76948
77030
|
init_logger();
|
|
@@ -76961,7 +77043,7 @@ init_logger();
|
|
|
76961
77043
|
init_output_manager();
|
|
76962
77044
|
import { createWriteStream as createWriteStream2, rmSync as rmSync2 } from "node:fs";
|
|
76963
77045
|
import { mkdir as mkdir20 } from "node:fs/promises";
|
|
76964
|
-
import { join as
|
|
77046
|
+
import { join as join71 } from "node:path";
|
|
76965
77047
|
|
|
76966
77048
|
// src/shared/progress-bar.ts
|
|
76967
77049
|
init_output_manager();
|
|
@@ -77171,7 +77253,7 @@ var MAX_DOWNLOAD_SIZE = 500 * 1024 * 1024;
|
|
|
77171
77253
|
class FileDownloader {
|
|
77172
77254
|
async downloadAsset(asset, destDir) {
|
|
77173
77255
|
try {
|
|
77174
|
-
const destPath =
|
|
77256
|
+
const destPath = join71(destDir, asset.name);
|
|
77175
77257
|
await mkdir20(destDir, { recursive: true });
|
|
77176
77258
|
output.info(`Downloading ${asset.name} (${formatBytes(asset.size)})...`);
|
|
77177
77259
|
logger.verbose("Download details", {
|
|
@@ -77256,7 +77338,7 @@ class FileDownloader {
|
|
|
77256
77338
|
}
|
|
77257
77339
|
async downloadFile(params) {
|
|
77258
77340
|
const { url, name, size, destDir, token } = params;
|
|
77259
|
-
const destPath =
|
|
77341
|
+
const destPath = join71(destDir, name);
|
|
77260
77342
|
await mkdir20(destDir, { recursive: true });
|
|
77261
77343
|
output.info(`Downloading ${name}${size ? ` (${formatBytes(size)})` : ""}...`);
|
|
77262
77344
|
const headers = {};
|
|
@@ -77342,7 +77424,7 @@ init_logger();
|
|
|
77342
77424
|
init_types3();
|
|
77343
77425
|
import { constants as constants4 } from "node:fs";
|
|
77344
77426
|
import { access as access4, readdir as readdir13 } from "node:fs/promises";
|
|
77345
|
-
import { join as
|
|
77427
|
+
import { join as join72 } from "node:path";
|
|
77346
77428
|
async function validateExtraction(extractDir) {
|
|
77347
77429
|
try {
|
|
77348
77430
|
const entries = await readdir13(extractDir, { encoding: "utf8" });
|
|
@@ -77354,7 +77436,7 @@ async function validateExtraction(extractDir) {
|
|
|
77354
77436
|
const missingPaths = [];
|
|
77355
77437
|
for (const path5 of criticalPaths) {
|
|
77356
77438
|
try {
|
|
77357
|
-
await access4(
|
|
77439
|
+
await access4(join72(extractDir, path5), constants4.F_OK);
|
|
77358
77440
|
logger.debug(`Found: ${path5}`);
|
|
77359
77441
|
} catch {
|
|
77360
77442
|
logger.warning(`Expected path not found: ${path5}`);
|
|
@@ -77376,7 +77458,7 @@ async function validateExtraction(extractDir) {
|
|
|
77376
77458
|
// src/domains/installation/extraction/tar-extractor.ts
|
|
77377
77459
|
init_logger();
|
|
77378
77460
|
import { copyFile as copyFile4, mkdir as mkdir23, readdir as readdir15, rm as rm8, stat as stat10 } from "node:fs/promises";
|
|
77379
|
-
import { join as
|
|
77461
|
+
import { join as join75 } from "node:path";
|
|
77380
77462
|
|
|
77381
77463
|
// node_modules/@isaacs/fs-minipass/dist/esm/index.js
|
|
77382
77464
|
import EE from "events";
|
|
@@ -83138,7 +83220,7 @@ var mkdirSync3 = (dir, opt) => {
|
|
|
83138
83220
|
};
|
|
83139
83221
|
|
|
83140
83222
|
// node_modules/tar/dist/esm/path-reservations.js
|
|
83141
|
-
import { join as
|
|
83223
|
+
import { join as join73 } from "node:path";
|
|
83142
83224
|
|
|
83143
83225
|
// node_modules/tar/dist/esm/normalize-unicode.js
|
|
83144
83226
|
var normalizeCache = Object.create(null);
|
|
@@ -83171,7 +83253,7 @@ var getDirs = (path10) => {
|
|
|
83171
83253
|
const dirs = path10.split("/").slice(0, -1).reduce((set, path11) => {
|
|
83172
83254
|
const s = set[set.length - 1];
|
|
83173
83255
|
if (s !== undefined) {
|
|
83174
|
-
path11 =
|
|
83256
|
+
path11 = join73(s, path11);
|
|
83175
83257
|
}
|
|
83176
83258
|
set.push(path11 || "/");
|
|
83177
83259
|
return set;
|
|
@@ -83185,7 +83267,7 @@ class PathReservations {
|
|
|
83185
83267
|
#running = new Set;
|
|
83186
83268
|
reserve(paths, fn) {
|
|
83187
83269
|
paths = isWindows4 ? ["win32 parallelization disabled"] : paths.map((p) => {
|
|
83188
|
-
return stripTrailingSlashes(
|
|
83270
|
+
return stripTrailingSlashes(join73(normalizeUnicode(p))).toLowerCase();
|
|
83189
83271
|
});
|
|
83190
83272
|
const dirs = new Set(paths.map((path10) => getDirs(path10)).reduce((a3, b3) => a3.concat(b3)));
|
|
83191
83273
|
this.#reservations.set(fn, { dirs, paths });
|
|
@@ -84245,7 +84327,7 @@ function decodeFilePath(path12) {
|
|
|
84245
84327
|
init_logger();
|
|
84246
84328
|
init_types3();
|
|
84247
84329
|
import { copyFile as copyFile3, lstat as lstat4, mkdir as mkdir22, readdir as readdir14 } from "node:fs/promises";
|
|
84248
|
-
import { join as
|
|
84330
|
+
import { join as join74, relative as relative10 } from "node:path";
|
|
84249
84331
|
async function withRetry(fn, retries = 3) {
|
|
84250
84332
|
for (let i = 0;i < retries; i++) {
|
|
84251
84333
|
try {
|
|
@@ -84267,8 +84349,8 @@ async function moveDirectoryContents(sourceDir, destDir, shouldExclude, sizeTrac
|
|
|
84267
84349
|
await mkdir22(destDir, { recursive: true });
|
|
84268
84350
|
const entries = await readdir14(sourceDir, { encoding: "utf8" });
|
|
84269
84351
|
for (const entry of entries) {
|
|
84270
|
-
const sourcePath =
|
|
84271
|
-
const destPath =
|
|
84352
|
+
const sourcePath = join74(sourceDir, entry);
|
|
84353
|
+
const destPath = join74(destDir, entry);
|
|
84272
84354
|
const relativePath = relative10(sourceDir, sourcePath);
|
|
84273
84355
|
if (!isPathSafe(destDir, destPath)) {
|
|
84274
84356
|
logger.warning(`Skipping unsafe path: ${relativePath}`);
|
|
@@ -84295,8 +84377,8 @@ async function copyDirectory(sourceDir, destDir, shouldExclude, sizeTracker) {
|
|
|
84295
84377
|
await mkdir22(destDir, { recursive: true });
|
|
84296
84378
|
const entries = await readdir14(sourceDir, { encoding: "utf8" });
|
|
84297
84379
|
for (const entry of entries) {
|
|
84298
|
-
const sourcePath =
|
|
84299
|
-
const destPath =
|
|
84380
|
+
const sourcePath = join74(sourceDir, entry);
|
|
84381
|
+
const destPath = join74(destDir, entry);
|
|
84300
84382
|
const relativePath = relative10(sourceDir, sourcePath);
|
|
84301
84383
|
if (!isPathSafe(destDir, destPath)) {
|
|
84302
84384
|
logger.warning(`Skipping unsafe path: ${relativePath}`);
|
|
@@ -84344,7 +84426,7 @@ class TarExtractor {
|
|
|
84344
84426
|
logger.debug(`Root entries: ${entries.join(", ")}`);
|
|
84345
84427
|
if (entries.length === 1) {
|
|
84346
84428
|
const rootEntry = entries[0];
|
|
84347
|
-
const rootPath =
|
|
84429
|
+
const rootPath = join75(tempExtractDir, rootEntry);
|
|
84348
84430
|
const rootStat = await stat10(rootPath);
|
|
84349
84431
|
if (rootStat.isDirectory()) {
|
|
84350
84432
|
const rootContents = await readdir15(rootPath, { encoding: "utf8" });
|
|
@@ -84360,7 +84442,7 @@ class TarExtractor {
|
|
|
84360
84442
|
}
|
|
84361
84443
|
} else {
|
|
84362
84444
|
await mkdir23(destDir, { recursive: true });
|
|
84363
|
-
await copyFile4(rootPath,
|
|
84445
|
+
await copyFile4(rootPath, join75(destDir, rootEntry));
|
|
84364
84446
|
}
|
|
84365
84447
|
} else {
|
|
84366
84448
|
logger.debug("Multiple root entries - moving all");
|
|
@@ -84383,7 +84465,7 @@ init_logger();
|
|
|
84383
84465
|
var import_extract_zip = __toESM(require_extract_zip(), 1);
|
|
84384
84466
|
import { execFile as execFile8 } from "node:child_process";
|
|
84385
84467
|
import { copyFile as copyFile5, mkdir as mkdir24, readdir as readdir16, rm as rm9, stat as stat11 } from "node:fs/promises";
|
|
84386
|
-
import { join as
|
|
84468
|
+
import { join as join76 } from "node:path";
|
|
84387
84469
|
class ZipExtractor {
|
|
84388
84470
|
async tryNativeUnzip(archivePath, destDir) {
|
|
84389
84471
|
if (!isMacOS()) {
|
|
@@ -84431,7 +84513,7 @@ class ZipExtractor {
|
|
|
84431
84513
|
logger.debug(`Root entries: ${entries.join(", ")}`);
|
|
84432
84514
|
if (entries.length === 1) {
|
|
84433
84515
|
const rootEntry = entries[0];
|
|
84434
|
-
const rootPath =
|
|
84516
|
+
const rootPath = join76(tempExtractDir, rootEntry);
|
|
84435
84517
|
const rootStat = await stat11(rootPath);
|
|
84436
84518
|
if (rootStat.isDirectory()) {
|
|
84437
84519
|
const rootContents = await readdir16(rootPath, { encoding: "utf8" });
|
|
@@ -84447,7 +84529,7 @@ class ZipExtractor {
|
|
|
84447
84529
|
}
|
|
84448
84530
|
} else {
|
|
84449
84531
|
await mkdir24(destDir, { recursive: true });
|
|
84450
|
-
await copyFile5(rootPath,
|
|
84532
|
+
await copyFile5(rootPath, join76(destDir, rootEntry));
|
|
84451
84533
|
}
|
|
84452
84534
|
} else {
|
|
84453
84535
|
logger.debug("Multiple root entries - moving all");
|
|
@@ -84546,7 +84628,7 @@ class DownloadManager {
|
|
|
84546
84628
|
async createTempDir() {
|
|
84547
84629
|
const timestamp = Date.now();
|
|
84548
84630
|
const counter = DownloadManager.tempDirCounter++;
|
|
84549
|
-
const primaryTempDir =
|
|
84631
|
+
const primaryTempDir = join77(tmpdir4(), `claudekit-${timestamp}-${counter}`);
|
|
84550
84632
|
try {
|
|
84551
84633
|
await mkdir25(primaryTempDir, { recursive: true });
|
|
84552
84634
|
logger.debug(`Created temp directory: ${primaryTempDir}`);
|
|
@@ -84563,7 +84645,7 @@ Solutions:
|
|
|
84563
84645
|
2. Set HOME environment variable
|
|
84564
84646
|
3. Try running from a different directory`);
|
|
84565
84647
|
}
|
|
84566
|
-
const fallbackTempDir =
|
|
84648
|
+
const fallbackTempDir = join77(homeDir, ".claudekit", "tmp", `claudekit-${timestamp}-${counter}`);
|
|
84567
84649
|
try {
|
|
84568
84650
|
await mkdir25(fallbackTempDir, { recursive: true });
|
|
84569
84651
|
logger.debug(`Created temp directory (fallback): ${fallbackTempDir}`);
|
|
@@ -84912,20 +84994,20 @@ async function handleDownload(ctx) {
|
|
|
84912
84994
|
};
|
|
84913
84995
|
}
|
|
84914
84996
|
// src/commands/init/phases/merge-handler.ts
|
|
84915
|
-
import { join as
|
|
84997
|
+
import { join as join93 } from "node:path";
|
|
84916
84998
|
|
|
84917
84999
|
// src/domains/installation/deletion-handler.ts
|
|
84918
85000
|
import { existsSync as existsSync53, lstatSync as lstatSync3, readdirSync as readdirSync4, rmSync as rmSync3, rmdirSync, unlinkSync as unlinkSync3 } from "node:fs";
|
|
84919
|
-
import { dirname as dirname24, join as
|
|
85001
|
+
import { dirname as dirname24, join as join80, relative as relative11, resolve as resolve19, sep as sep5 } from "node:path";
|
|
84920
85002
|
|
|
84921
85003
|
// src/services/file-operations/manifest/manifest-reader.ts
|
|
84922
85004
|
init_metadata_migration();
|
|
84923
85005
|
init_logger();
|
|
84924
85006
|
init_types3();
|
|
84925
85007
|
var import_fs_extra8 = __toESM(require_lib3(), 1);
|
|
84926
|
-
import { join as
|
|
85008
|
+
import { join as join79 } from "node:path";
|
|
84927
85009
|
async function readManifest(claudeDir2) {
|
|
84928
|
-
const metadataPath =
|
|
85010
|
+
const metadataPath = join79(claudeDir2, "metadata.json");
|
|
84929
85011
|
if (!await import_fs_extra8.pathExists(metadataPath)) {
|
|
84930
85012
|
return null;
|
|
84931
85013
|
}
|
|
@@ -85103,7 +85185,7 @@ function collectFilesRecursively(dir, baseDir) {
|
|
|
85103
85185
|
try {
|
|
85104
85186
|
const entries = readdirSync4(dir, { withFileTypes: true });
|
|
85105
85187
|
for (const entry of entries) {
|
|
85106
|
-
const fullPath =
|
|
85188
|
+
const fullPath = join80(dir, entry.name);
|
|
85107
85189
|
const relativePath = relative11(baseDir, fullPath);
|
|
85108
85190
|
if (entry.isDirectory()) {
|
|
85109
85191
|
results.push(...collectFilesRecursively(fullPath, baseDir));
|
|
@@ -85155,7 +85237,7 @@ function cleanupEmptyDirectories(filePath, claudeDir2) {
|
|
|
85155
85237
|
function deletePath(fullPath, claudeDir2) {
|
|
85156
85238
|
const normalizedPath = resolve19(fullPath);
|
|
85157
85239
|
const normalizedClaudeDir = resolve19(claudeDir2);
|
|
85158
|
-
if (!normalizedPath.startsWith(`${normalizedClaudeDir}${
|
|
85240
|
+
if (!normalizedPath.startsWith(`${normalizedClaudeDir}${sep5}`) && normalizedPath !== normalizedClaudeDir) {
|
|
85159
85241
|
throw new Error(`Path traversal detected: ${fullPath}`);
|
|
85160
85242
|
}
|
|
85161
85243
|
try {
|
|
@@ -85171,7 +85253,7 @@ function deletePath(fullPath, claudeDir2) {
|
|
|
85171
85253
|
}
|
|
85172
85254
|
}
|
|
85173
85255
|
async function updateMetadataAfterDeletion(claudeDir2, deletedPaths) {
|
|
85174
|
-
const metadataPath =
|
|
85256
|
+
const metadataPath = join80(claudeDir2, "metadata.json");
|
|
85175
85257
|
if (!await import_fs_extra9.pathExists(metadataPath)) {
|
|
85176
85258
|
return;
|
|
85177
85259
|
}
|
|
@@ -85226,10 +85308,10 @@ async function handleDeletions(sourceMetadata, claudeDir2) {
|
|
|
85226
85308
|
const userMetadata = await readManifest(claudeDir2);
|
|
85227
85309
|
const result = { deletedPaths: [], preservedPaths: [], errors: [] };
|
|
85228
85310
|
for (const path13 of deletions) {
|
|
85229
|
-
const fullPath =
|
|
85311
|
+
const fullPath = join80(claudeDir2, path13);
|
|
85230
85312
|
const normalizedPath = resolve19(fullPath);
|
|
85231
85313
|
const normalizedClaudeDir = resolve19(claudeDir2);
|
|
85232
|
-
if (!normalizedPath.startsWith(`${normalizedClaudeDir}${
|
|
85314
|
+
if (!normalizedPath.startsWith(`${normalizedClaudeDir}${sep5}`)) {
|
|
85233
85315
|
logger.warning(`Skipping invalid path: ${path13}`);
|
|
85234
85316
|
result.errors.push(path13);
|
|
85235
85317
|
continue;
|
|
@@ -85266,7 +85348,7 @@ init_logger();
|
|
|
85266
85348
|
init_types3();
|
|
85267
85349
|
var import_fs_extra12 = __toESM(require_lib3(), 1);
|
|
85268
85350
|
var import_ignore3 = __toESM(require_ignore(), 1);
|
|
85269
|
-
import { dirname as dirname26, join as
|
|
85351
|
+
import { dirname as dirname26, join as join83, relative as relative13 } from "node:path";
|
|
85270
85352
|
|
|
85271
85353
|
// src/domains/installation/selective-merger.ts
|
|
85272
85354
|
import { stat as stat13 } from "node:fs/promises";
|
|
@@ -85445,7 +85527,7 @@ init_logger();
|
|
|
85445
85527
|
var import_fs_extra10 = __toESM(require_lib3(), 1);
|
|
85446
85528
|
var import_ignore2 = __toESM(require_ignore(), 1);
|
|
85447
85529
|
import { relative as relative12 } from "node:path";
|
|
85448
|
-
import { join as
|
|
85530
|
+
import { join as join81 } from "node:path";
|
|
85449
85531
|
|
|
85450
85532
|
// node_modules/@isaacs/balanced-match/dist/esm/index.js
|
|
85451
85533
|
var balanced = (a3, b3, str2) => {
|
|
@@ -86252,8 +86334,8 @@ var path13 = {
|
|
|
86252
86334
|
win32: { sep: "\\" },
|
|
86253
86335
|
posix: { sep: "/" }
|
|
86254
86336
|
};
|
|
86255
|
-
var
|
|
86256
|
-
minimatch.sep =
|
|
86337
|
+
var sep6 = defaultPlatform === "win32" ? path13.win32.sep : path13.posix.sep;
|
|
86338
|
+
minimatch.sep = sep6;
|
|
86257
86339
|
var GLOBSTAR = Symbol("globstar **");
|
|
86258
86340
|
minimatch.GLOBSTAR = GLOBSTAR;
|
|
86259
86341
|
var qmark2 = "[^/]";
|
|
@@ -86901,7 +86983,7 @@ class FileScanner {
|
|
|
86901
86983
|
const files = [];
|
|
86902
86984
|
const entries = await import_fs_extra10.readdir(dir, { encoding: "utf8" });
|
|
86903
86985
|
for (const entry of entries) {
|
|
86904
|
-
const fullPath =
|
|
86986
|
+
const fullPath = join81(dir, entry);
|
|
86905
86987
|
const relativePath = relative12(baseDir, fullPath);
|
|
86906
86988
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
86907
86989
|
const stats = await import_fs_extra10.lstat(fullPath);
|
|
@@ -86941,7 +87023,7 @@ import { execSync as execSync4 } from "node:child_process";
|
|
|
86941
87023
|
init_shared();
|
|
86942
87024
|
import { existsSync as existsSync54 } from "node:fs";
|
|
86943
87025
|
import { mkdir as mkdir26, readFile as readFile38, writeFile as writeFile22 } from "node:fs/promises";
|
|
86944
|
-
import { dirname as dirname25, join as
|
|
87026
|
+
import { dirname as dirname25, join as join82 } from "node:path";
|
|
86945
87027
|
var CK_JSON_FILE = ".ck.json";
|
|
86946
87028
|
|
|
86947
87029
|
class InstalledSettingsTracker {
|
|
@@ -86955,9 +87037,9 @@ class InstalledSettingsTracker {
|
|
|
86955
87037
|
}
|
|
86956
87038
|
getCkJsonPath() {
|
|
86957
87039
|
if (this.isGlobal) {
|
|
86958
|
-
return
|
|
87040
|
+
return join82(this.projectDir, CK_JSON_FILE);
|
|
86959
87041
|
}
|
|
86960
|
-
return
|
|
87042
|
+
return join82(this.projectDir, ".claude", CK_JSON_FILE);
|
|
86961
87043
|
}
|
|
86962
87044
|
async loadInstalledSettings() {
|
|
86963
87045
|
const ckJsonPath = this.getCkJsonPath();
|
|
@@ -87045,6 +87127,7 @@ class SettingsProcessor {
|
|
|
87045
87127
|
tracker = null;
|
|
87046
87128
|
installingKit;
|
|
87047
87129
|
cachedVersion = undefined;
|
|
87130
|
+
deletionPatterns = [];
|
|
87048
87131
|
setGlobalFlag(isGlobal) {
|
|
87049
87132
|
this.isGlobal = isGlobal;
|
|
87050
87133
|
}
|
|
@@ -87062,6 +87145,9 @@ class SettingsProcessor {
|
|
|
87062
87145
|
setInstallingKit(kit) {
|
|
87063
87146
|
this.installingKit = kit;
|
|
87064
87147
|
}
|
|
87148
|
+
setDeletions(deletions) {
|
|
87149
|
+
this.deletionPatterns = deletions;
|
|
87150
|
+
}
|
|
87065
87151
|
initTracker() {
|
|
87066
87152
|
if (this.projectDir) {
|
|
87067
87153
|
this.tracker = new InstalledSettingsTracker(this.projectDir, this.isGlobal, this.kitName);
|
|
@@ -87171,6 +87257,10 @@ class SettingsProcessor {
|
|
|
87171
87257
|
if (pathsFixed) {
|
|
87172
87258
|
logger.info("Fixed hook command paths to canonical quoted format");
|
|
87173
87259
|
}
|
|
87260
|
+
const hooksPruned = this.pruneDeletedHooks(mergeResult.merged);
|
|
87261
|
+
if (hooksPruned > 0) {
|
|
87262
|
+
logger.info(`Pruned ${hooksPruned} stale hook(s) referencing deleted files`);
|
|
87263
|
+
}
|
|
87174
87264
|
await SettingsMerger.writeSettingsFile(destFile, mergeResult.merged);
|
|
87175
87265
|
logger.success("Merged settings.json (user customizations preserved)");
|
|
87176
87266
|
await this.injectTeamHooksIfSupported(destFile, mergeResult.merged);
|
|
@@ -87215,6 +87305,59 @@ class SettingsProcessor {
|
|
|
87215
87305
|
}
|
|
87216
87306
|
}
|
|
87217
87307
|
}
|
|
87308
|
+
pruneDeletedHooks(settings) {
|
|
87309
|
+
if (this.deletionPatterns.length === 0 || !settings.hooks)
|
|
87310
|
+
return 0;
|
|
87311
|
+
const hookDeletions = new Set(this.deletionPatterns.filter((p) => p.startsWith("hooks/")));
|
|
87312
|
+
if (hookDeletions.size === 0)
|
|
87313
|
+
return 0;
|
|
87314
|
+
let pruned = 0;
|
|
87315
|
+
const eventKeysToDelete = [];
|
|
87316
|
+
for (const [eventName, entries] of Object.entries(settings.hooks)) {
|
|
87317
|
+
const filteredEntries = [];
|
|
87318
|
+
for (const entry of entries) {
|
|
87319
|
+
if ("hooks" in entry && entry.hooks) {
|
|
87320
|
+
const remainingHooks = entry.hooks.filter((h2) => {
|
|
87321
|
+
const relativePath = this.extractHookRelativePath(h2.command);
|
|
87322
|
+
if (relativePath && hookDeletions.has(relativePath)) {
|
|
87323
|
+
logger.info(`Pruned stale hook: ${h2.command.slice(0, 80)}`);
|
|
87324
|
+
pruned++;
|
|
87325
|
+
return false;
|
|
87326
|
+
}
|
|
87327
|
+
return true;
|
|
87328
|
+
});
|
|
87329
|
+
if (remainingHooks.length > 0) {
|
|
87330
|
+
filteredEntries.push({ ...entry, hooks: remainingHooks });
|
|
87331
|
+
}
|
|
87332
|
+
} else if ("command" in entry) {
|
|
87333
|
+
const relativePath = this.extractHookRelativePath(entry.command);
|
|
87334
|
+
if (relativePath && hookDeletions.has(relativePath)) {
|
|
87335
|
+
logger.info(`Pruned stale hook: ${entry.command.slice(0, 80)}`);
|
|
87336
|
+
pruned++;
|
|
87337
|
+
} else {
|
|
87338
|
+
filteredEntries.push(entry);
|
|
87339
|
+
}
|
|
87340
|
+
} else {
|
|
87341
|
+
filteredEntries.push(entry);
|
|
87342
|
+
}
|
|
87343
|
+
}
|
|
87344
|
+
if (filteredEntries.length > 0) {
|
|
87345
|
+
settings.hooks[eventName] = filteredEntries;
|
|
87346
|
+
} else {
|
|
87347
|
+
eventKeysToDelete.push(eventName);
|
|
87348
|
+
}
|
|
87349
|
+
}
|
|
87350
|
+
for (const key of eventKeysToDelete) {
|
|
87351
|
+
delete settings.hooks[key];
|
|
87352
|
+
}
|
|
87353
|
+
return pruned;
|
|
87354
|
+
}
|
|
87355
|
+
extractHookRelativePath(command) {
|
|
87356
|
+
if (!command)
|
|
87357
|
+
return null;
|
|
87358
|
+
const match2 = command.match(/\.claude[/\\]([\w.\-/\\]+)/);
|
|
87359
|
+
return match2 ? match2[1].replace(/\\/g, "/") : null;
|
|
87360
|
+
}
|
|
87218
87361
|
async trackInstalledSettings(settings) {
|
|
87219
87362
|
if (!this.tracker)
|
|
87220
87363
|
return;
|
|
@@ -87483,6 +87626,9 @@ class CopyExecutor {
|
|
|
87483
87626
|
setForceOverwriteSettings(force) {
|
|
87484
87627
|
this.settingsProcessor.setForceOverwriteSettings(force);
|
|
87485
87628
|
}
|
|
87629
|
+
setDeletions(deletions) {
|
|
87630
|
+
this.settingsProcessor.setDeletions(deletions);
|
|
87631
|
+
}
|
|
87486
87632
|
setProjectDir(dir) {
|
|
87487
87633
|
this.settingsProcessor.setProjectDir(dir);
|
|
87488
87634
|
}
|
|
@@ -87510,7 +87656,7 @@ class CopyExecutor {
|
|
|
87510
87656
|
for (const file of files) {
|
|
87511
87657
|
const relativePath = relative13(sourceDir, file);
|
|
87512
87658
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
87513
|
-
const destPath =
|
|
87659
|
+
const destPath = join83(destDir, relativePath);
|
|
87514
87660
|
if (await import_fs_extra12.pathExists(destPath)) {
|
|
87515
87661
|
if (this.fileScanner.shouldNeverCopy(normalizedRelativePath)) {
|
|
87516
87662
|
logger.debug(`Security-sensitive file exists but won't be overwritten: ${normalizedRelativePath}`);
|
|
@@ -87532,7 +87678,7 @@ class CopyExecutor {
|
|
|
87532
87678
|
for (const file of files) {
|
|
87533
87679
|
const relativePath = relative13(sourceDir, file);
|
|
87534
87680
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
87535
|
-
const destPath =
|
|
87681
|
+
const destPath = join83(destDir, relativePath);
|
|
87536
87682
|
if (this.fileScanner.shouldNeverCopy(normalizedRelativePath)) {
|
|
87537
87683
|
logger.debug(`Skipping security-sensitive file: ${normalizedRelativePath}`);
|
|
87538
87684
|
skippedCount++;
|
|
@@ -87655,6 +87801,9 @@ class FileMerger {
|
|
|
87655
87801
|
setKitName(kit) {
|
|
87656
87802
|
this.copyExecutor.setKitName(kit);
|
|
87657
87803
|
}
|
|
87804
|
+
setDeletions(deletions) {
|
|
87805
|
+
this.copyExecutor.setDeletions(deletions);
|
|
87806
|
+
}
|
|
87658
87807
|
setManifest(manifest) {
|
|
87659
87808
|
this.copyExecutor.setManifest(manifest);
|
|
87660
87809
|
}
|
|
@@ -87702,15 +87851,15 @@ class FileMerger {
|
|
|
87702
87851
|
|
|
87703
87852
|
// src/domains/migration/legacy-migration.ts
|
|
87704
87853
|
import { readdir as readdir18, stat as stat14 } from "node:fs/promises";
|
|
87705
|
-
import { join as
|
|
87854
|
+
import { join as join87, relative as relative14 } from "node:path";
|
|
87706
87855
|
// src/services/file-operations/manifest/manifest-tracker.ts
|
|
87707
|
-
import { join as
|
|
87856
|
+
import { join as join86 } from "node:path";
|
|
87708
87857
|
|
|
87709
87858
|
// src/domains/migration/release-manifest.ts
|
|
87710
87859
|
init_logger();
|
|
87711
87860
|
init_zod();
|
|
87712
87861
|
var import_fs_extra13 = __toESM(require_lib3(), 1);
|
|
87713
|
-
import { join as
|
|
87862
|
+
import { join as join84 } from "node:path";
|
|
87714
87863
|
var ReleaseManifestFileSchema = exports_external.object({
|
|
87715
87864
|
path: exports_external.string(),
|
|
87716
87865
|
checksum: exports_external.string().regex(/^[a-f0-9]{64}$/),
|
|
@@ -87725,7 +87874,7 @@ var ReleaseManifestSchema = exports_external.object({
|
|
|
87725
87874
|
|
|
87726
87875
|
class ReleaseManifestLoader {
|
|
87727
87876
|
static async load(extractDir) {
|
|
87728
|
-
const manifestPath =
|
|
87877
|
+
const manifestPath = join84(extractDir, "release-manifest.json");
|
|
87729
87878
|
try {
|
|
87730
87879
|
const content = await import_fs_extra13.readFile(manifestPath, "utf-8");
|
|
87731
87880
|
const parsed = JSON.parse(content);
|
|
@@ -87751,9 +87900,9 @@ init_logger();
|
|
|
87751
87900
|
init_types3();
|
|
87752
87901
|
var import_fs_extra14 = __toESM(require_lib3(), 1);
|
|
87753
87902
|
var import_proper_lockfile5 = __toESM(require_proper_lockfile(), 1);
|
|
87754
|
-
import { join as
|
|
87903
|
+
import { join as join85 } from "node:path";
|
|
87755
87904
|
async function writeManifest(claudeDir2, kitName, version, scope, kitType, trackedFiles, userConfigFiles) {
|
|
87756
|
-
const metadataPath =
|
|
87905
|
+
const metadataPath = join85(claudeDir2, "metadata.json");
|
|
87757
87906
|
const kit = kitType || (/\bmarketing\b/i.test(kitName) ? "marketing" : "engineer");
|
|
87758
87907
|
await import_fs_extra14.ensureFile(metadataPath);
|
|
87759
87908
|
let release = null;
|
|
@@ -87809,7 +87958,7 @@ async function writeManifest(claudeDir2, kitName, version, scope, kitType, track
|
|
|
87809
87958
|
}
|
|
87810
87959
|
}
|
|
87811
87960
|
async function removeKitFromManifest(claudeDir2, kit) {
|
|
87812
|
-
const metadataPath =
|
|
87961
|
+
const metadataPath = join85(claudeDir2, "metadata.json");
|
|
87813
87962
|
if (!await import_fs_extra14.pathExists(metadataPath))
|
|
87814
87963
|
return false;
|
|
87815
87964
|
let release = null;
|
|
@@ -87939,7 +88088,7 @@ function buildFileTrackingList(options2) {
|
|
|
87939
88088
|
if (!isGlobal && !installedPath.startsWith(".claude/"))
|
|
87940
88089
|
continue;
|
|
87941
88090
|
const relativePath = isGlobal ? installedPath : installedPath.replace(/^\.claude\//, "");
|
|
87942
|
-
const filePath =
|
|
88091
|
+
const filePath = join86(claudeDir2, relativePath);
|
|
87943
88092
|
const manifestEntry = releaseManifest ? ReleaseManifestLoader.findFile(releaseManifest, installedPath) : null;
|
|
87944
88093
|
const ownership = manifestEntry ? "ck" : "user";
|
|
87945
88094
|
filesToTrack.push({
|
|
@@ -88046,7 +88195,7 @@ class LegacyMigration {
|
|
|
88046
88195
|
continue;
|
|
88047
88196
|
if (SKIP_DIRS_ALL.includes(entry))
|
|
88048
88197
|
continue;
|
|
88049
|
-
const fullPath =
|
|
88198
|
+
const fullPath = join87(dir, entry);
|
|
88050
88199
|
let stats;
|
|
88051
88200
|
try {
|
|
88052
88201
|
stats = await stat14(fullPath);
|
|
@@ -88148,7 +88297,7 @@ User-created files (sample):`);
|
|
|
88148
88297
|
];
|
|
88149
88298
|
if (filesToChecksum.length > 0) {
|
|
88150
88299
|
const checksumResults = await mapWithLimit(filesToChecksum, async ({ relativePath, ownership }) => {
|
|
88151
|
-
const fullPath =
|
|
88300
|
+
const fullPath = join87(claudeDir2, relativePath);
|
|
88152
88301
|
const checksum = await OwnershipChecker.calculateChecksum(fullPath);
|
|
88153
88302
|
return { relativePath, checksum, ownership };
|
|
88154
88303
|
});
|
|
@@ -88169,7 +88318,7 @@ User-created files (sample):`);
|
|
|
88169
88318
|
installedAt: new Date().toISOString(),
|
|
88170
88319
|
files: trackedFiles
|
|
88171
88320
|
};
|
|
88172
|
-
const metadataPath =
|
|
88321
|
+
const metadataPath = join87(claudeDir2, "metadata.json");
|
|
88173
88322
|
await import_fs_extra15.writeFile(metadataPath, JSON.stringify(updatedMetadata, null, 2));
|
|
88174
88323
|
logger.success(`Migration complete: tracked ${trackedFiles.length} files`);
|
|
88175
88324
|
return true;
|
|
@@ -88275,7 +88424,7 @@ function buildConflictSummary(fileConflicts, hookConflicts, mcpConflicts) {
|
|
|
88275
88424
|
init_logger();
|
|
88276
88425
|
init_skip_directories();
|
|
88277
88426
|
var import_fs_extra16 = __toESM(require_lib3(), 1);
|
|
88278
|
-
import { join as
|
|
88427
|
+
import { join as join88, relative as relative15, resolve as resolve20 } from "node:path";
|
|
88279
88428
|
|
|
88280
88429
|
class FileScanner2 {
|
|
88281
88430
|
static async getFiles(dirPath, relativeTo) {
|
|
@@ -88291,7 +88440,7 @@ class FileScanner2 {
|
|
|
88291
88440
|
logger.debug(`Skipping directory: ${entry}`);
|
|
88292
88441
|
continue;
|
|
88293
88442
|
}
|
|
88294
|
-
const fullPath =
|
|
88443
|
+
const fullPath = join88(dirPath, entry);
|
|
88295
88444
|
if (!FileScanner2.isSafePath(basePath, fullPath)) {
|
|
88296
88445
|
logger.warning(`Skipping potentially unsafe path: ${entry}`);
|
|
88297
88446
|
continue;
|
|
@@ -88326,8 +88475,8 @@ class FileScanner2 {
|
|
|
88326
88475
|
return files;
|
|
88327
88476
|
}
|
|
88328
88477
|
static async findCustomFiles(destDir, sourceDir, subPath) {
|
|
88329
|
-
const destSubDir =
|
|
88330
|
-
const sourceSubDir =
|
|
88478
|
+
const destSubDir = join88(destDir, subPath);
|
|
88479
|
+
const sourceSubDir = join88(sourceDir, subPath);
|
|
88331
88480
|
logger.debug(`findCustomFiles - destDir: ${destDir}`);
|
|
88332
88481
|
logger.debug(`findCustomFiles - sourceDir: ${sourceDir}`);
|
|
88333
88482
|
logger.debug(`findCustomFiles - subPath: "${subPath}"`);
|
|
@@ -88368,12 +88517,12 @@ class FileScanner2 {
|
|
|
88368
88517
|
init_logger();
|
|
88369
88518
|
var import_fs_extra17 = __toESM(require_lib3(), 1);
|
|
88370
88519
|
import { lstat as lstat7, mkdir as mkdir27, readdir as readdir21, stat as stat15 } from "node:fs/promises";
|
|
88371
|
-
import { join as
|
|
88520
|
+
import { join as join90 } from "node:path";
|
|
88372
88521
|
|
|
88373
88522
|
// src/services/transformers/commands-prefix/content-transformer.ts
|
|
88374
88523
|
init_logger();
|
|
88375
88524
|
import { readFile as readFile42, readdir as readdir20, writeFile as writeFile26 } from "node:fs/promises";
|
|
88376
|
-
import { join as
|
|
88525
|
+
import { join as join89 } from "node:path";
|
|
88377
88526
|
var TRANSFORMABLE_EXTENSIONS = new Set([
|
|
88378
88527
|
".md",
|
|
88379
88528
|
".txt",
|
|
@@ -88434,7 +88583,7 @@ async function transformCommandReferences(directory, options2 = {}) {
|
|
|
88434
88583
|
async function processDirectory(dir) {
|
|
88435
88584
|
const entries = await readdir20(dir, { withFileTypes: true });
|
|
88436
88585
|
for (const entry of entries) {
|
|
88437
|
-
const fullPath =
|
|
88586
|
+
const fullPath = join89(dir, entry.name);
|
|
88438
88587
|
if (entry.isDirectory()) {
|
|
88439
88588
|
if (entry.name === "node_modules" || entry.name.startsWith(".") && entry.name !== ".claude") {
|
|
88440
88589
|
continue;
|
|
@@ -88509,14 +88658,14 @@ function shouldApplyPrefix(options2) {
|
|
|
88509
88658
|
// src/services/transformers/commands-prefix/prefix-applier.ts
|
|
88510
88659
|
async function applyPrefix(extractDir) {
|
|
88511
88660
|
validatePath(extractDir, "extractDir");
|
|
88512
|
-
const commandsDir =
|
|
88661
|
+
const commandsDir = join90(extractDir, ".claude", "commands");
|
|
88513
88662
|
if (!await import_fs_extra17.pathExists(commandsDir)) {
|
|
88514
88663
|
logger.verbose("No commands directory found, skipping prefix application");
|
|
88515
88664
|
return;
|
|
88516
88665
|
}
|
|
88517
88666
|
logger.info("Applying /ck: prefix to slash commands...");
|
|
88518
|
-
const backupDir =
|
|
88519
|
-
const tempDir =
|
|
88667
|
+
const backupDir = join90(extractDir, ".commands-backup");
|
|
88668
|
+
const tempDir = join90(extractDir, ".commands-prefix-temp");
|
|
88520
88669
|
try {
|
|
88521
88670
|
const entries = await readdir21(commandsDir);
|
|
88522
88671
|
if (entries.length === 0) {
|
|
@@ -88524,7 +88673,7 @@ async function applyPrefix(extractDir) {
|
|
|
88524
88673
|
return;
|
|
88525
88674
|
}
|
|
88526
88675
|
if (entries.length === 1 && entries[0] === "ck") {
|
|
88527
|
-
const ckDir2 =
|
|
88676
|
+
const ckDir2 = join90(commandsDir, "ck");
|
|
88528
88677
|
const ckStat = await stat15(ckDir2);
|
|
88529
88678
|
if (ckStat.isDirectory()) {
|
|
88530
88679
|
logger.verbose("Commands already have /ck: prefix, skipping");
|
|
@@ -88534,17 +88683,17 @@ async function applyPrefix(extractDir) {
|
|
|
88534
88683
|
await import_fs_extra17.copy(commandsDir, backupDir);
|
|
88535
88684
|
logger.verbose("Created backup of commands directory");
|
|
88536
88685
|
await mkdir27(tempDir, { recursive: true });
|
|
88537
|
-
const ckDir =
|
|
88686
|
+
const ckDir = join90(tempDir, "ck");
|
|
88538
88687
|
await mkdir27(ckDir, { recursive: true });
|
|
88539
88688
|
let processedCount = 0;
|
|
88540
88689
|
for (const entry of entries) {
|
|
88541
|
-
const sourcePath =
|
|
88690
|
+
const sourcePath = join90(commandsDir, entry);
|
|
88542
88691
|
const stats = await lstat7(sourcePath);
|
|
88543
88692
|
if (stats.isSymbolicLink()) {
|
|
88544
88693
|
logger.warning(`Skipping symlink for security: ${entry}`);
|
|
88545
88694
|
continue;
|
|
88546
88695
|
}
|
|
88547
|
-
const destPath =
|
|
88696
|
+
const destPath = join90(ckDir, entry);
|
|
88548
88697
|
await import_fs_extra17.copy(sourcePath, destPath, {
|
|
88549
88698
|
overwrite: false,
|
|
88550
88699
|
errorOnExist: true
|
|
@@ -88562,7 +88711,7 @@ async function applyPrefix(extractDir) {
|
|
|
88562
88711
|
await import_fs_extra17.move(tempDir, commandsDir);
|
|
88563
88712
|
await import_fs_extra17.remove(backupDir);
|
|
88564
88713
|
logger.success("Successfully reorganized commands to /ck: prefix");
|
|
88565
|
-
const claudeDir2 =
|
|
88714
|
+
const claudeDir2 = join90(extractDir, ".claude");
|
|
88566
88715
|
logger.info("Transforming command references in file contents...");
|
|
88567
88716
|
const transformResult = await transformCommandReferences(claudeDir2, {
|
|
88568
88717
|
verbose: logger.isVerbose()
|
|
@@ -88600,20 +88749,20 @@ async function applyPrefix(extractDir) {
|
|
|
88600
88749
|
// src/services/transformers/commands-prefix/prefix-cleaner.ts
|
|
88601
88750
|
init_metadata_migration();
|
|
88602
88751
|
import { lstat as lstat9, readdir as readdir23 } from "node:fs/promises";
|
|
88603
|
-
import { join as
|
|
88752
|
+
import { join as join92 } from "node:path";
|
|
88604
88753
|
init_logger();
|
|
88605
88754
|
var import_fs_extra19 = __toESM(require_lib3(), 1);
|
|
88606
88755
|
|
|
88607
88756
|
// src/services/transformers/commands-prefix/file-processor.ts
|
|
88608
88757
|
import { lstat as lstat8, readdir as readdir22 } from "node:fs/promises";
|
|
88609
|
-
import { join as
|
|
88758
|
+
import { join as join91 } from "node:path";
|
|
88610
88759
|
init_logger();
|
|
88611
88760
|
var import_fs_extra18 = __toESM(require_lib3(), 1);
|
|
88612
88761
|
async function scanDirectoryFiles(dir) {
|
|
88613
88762
|
const files = [];
|
|
88614
88763
|
const entries = await readdir22(dir);
|
|
88615
88764
|
for (const entry of entries) {
|
|
88616
|
-
const fullPath =
|
|
88765
|
+
const fullPath = join91(dir, entry);
|
|
88617
88766
|
const stats = await lstat8(fullPath);
|
|
88618
88767
|
if (stats.isSymbolicLink()) {
|
|
88619
88768
|
continue;
|
|
@@ -88741,8 +88890,8 @@ function isDifferentKitDirectory(dirName, currentKit) {
|
|
|
88741
88890
|
async function cleanupCommandsDirectory(targetDir, isGlobal, options2 = {}) {
|
|
88742
88891
|
const { dryRun = false } = options2;
|
|
88743
88892
|
validatePath(targetDir, "targetDir");
|
|
88744
|
-
const claudeDir2 = isGlobal ? targetDir :
|
|
88745
|
-
const commandsDir =
|
|
88893
|
+
const claudeDir2 = isGlobal ? targetDir : join92(targetDir, ".claude");
|
|
88894
|
+
const commandsDir = join92(claudeDir2, "commands");
|
|
88746
88895
|
const accumulator = {
|
|
88747
88896
|
results: [],
|
|
88748
88897
|
deletedCount: 0,
|
|
@@ -88784,7 +88933,7 @@ async function cleanupCommandsDirectory(targetDir, isGlobal, options2 = {}) {
|
|
|
88784
88933
|
}
|
|
88785
88934
|
const metadataForChecks = options2.kitType ? createKitSpecificMetadata(metadata, options2.kitType) : metadata;
|
|
88786
88935
|
for (const entry of entries) {
|
|
88787
|
-
const entryPath =
|
|
88936
|
+
const entryPath = join92(commandsDir, entry);
|
|
88788
88937
|
const stats = await lstat9(entryPath);
|
|
88789
88938
|
if (stats.isSymbolicLink()) {
|
|
88790
88939
|
addSymlinkSkip(entry, accumulator);
|
|
@@ -88841,7 +88990,7 @@ async function handleMerge(ctx) {
|
|
|
88841
88990
|
let customClaudeFiles = [];
|
|
88842
88991
|
if (!ctx.options.fresh) {
|
|
88843
88992
|
logger.info("Scanning for custom .claude files...");
|
|
88844
|
-
const scanSourceDir = ctx.options.global ?
|
|
88993
|
+
const scanSourceDir = ctx.options.global ? join93(ctx.extractDir, ".claude") : ctx.extractDir;
|
|
88845
88994
|
const scanTargetSubdir = ctx.options.global ? "" : ".claude";
|
|
88846
88995
|
customClaudeFiles = await FileScanner2.findCustomFiles(ctx.resolvedDir, scanSourceDir, scanTargetSubdir);
|
|
88847
88996
|
} else {
|
|
@@ -88906,7 +89055,20 @@ async function handleMerge(ctx) {
|
|
|
88906
89055
|
return { ...ctx, cancelled: true };
|
|
88907
89056
|
}
|
|
88908
89057
|
}
|
|
88909
|
-
const sourceDir = ctx.options.global ?
|
|
89058
|
+
const sourceDir = ctx.options.global ? join93(ctx.extractDir, ".claude") : ctx.extractDir;
|
|
89059
|
+
const sourceMetadataPath = ctx.options.global ? join93(sourceDir, "metadata.json") : join93(sourceDir, ".claude", "metadata.json");
|
|
89060
|
+
let sourceMetadata = null;
|
|
89061
|
+
try {
|
|
89062
|
+
if (await import_fs_extra20.pathExists(sourceMetadataPath)) {
|
|
89063
|
+
const metadataContent = await import_fs_extra20.readFile(sourceMetadataPath, "utf-8");
|
|
89064
|
+
sourceMetadata = JSON.parse(metadataContent);
|
|
89065
|
+
}
|
|
89066
|
+
} catch (error) {
|
|
89067
|
+
logger.debug(`Failed to load source metadata: ${error}`);
|
|
89068
|
+
}
|
|
89069
|
+
if (sourceMetadata?.deletions && sourceMetadata.deletions.length > 0) {
|
|
89070
|
+
merger.setDeletions(sourceMetadata.deletions);
|
|
89071
|
+
}
|
|
88910
89072
|
await merger.merge(sourceDir, ctx.resolvedDir, ctx.isNonInteractive);
|
|
88911
89073
|
const fileConflicts = merger.getFileConflicts();
|
|
88912
89074
|
if (fileConflicts.length > 0 && !ctx.isNonInteractive) {
|
|
@@ -88914,24 +89076,17 @@ async function handleMerge(ctx) {
|
|
|
88914
89076
|
displayConflictSummary(summary);
|
|
88915
89077
|
}
|
|
88916
89078
|
try {
|
|
88917
|
-
|
|
88918
|
-
|
|
88919
|
-
|
|
88920
|
-
|
|
88921
|
-
|
|
88922
|
-
|
|
88923
|
-
if (deletionResult.deletedPaths.length > 0) {
|
|
88924
|
-
logger.info(`Removed ${deletionResult.deletedPaths.length} deprecated file(s)`);
|
|
88925
|
-
for (const path14 of deletionResult.deletedPaths) {
|
|
88926
|
-
logger.verbose(` - ${path14}`);
|
|
88927
|
-
}
|
|
88928
|
-
}
|
|
88929
|
-
if (deletionResult.preservedPaths.length > 0) {
|
|
88930
|
-
logger.verbose(`Preserved ${deletionResult.preservedPaths.length} user-owned file(s)`);
|
|
89079
|
+
if (sourceMetadata?.deletions && sourceMetadata.deletions.length > 0) {
|
|
89080
|
+
const deletionResult = await handleDeletions(sourceMetadata, ctx.claudeDir);
|
|
89081
|
+
if (deletionResult.deletedPaths.length > 0) {
|
|
89082
|
+
logger.info(`Removed ${deletionResult.deletedPaths.length} deprecated file(s)`);
|
|
89083
|
+
for (const path14 of deletionResult.deletedPaths) {
|
|
89084
|
+
logger.verbose(` - ${path14}`);
|
|
88931
89085
|
}
|
|
88932
89086
|
}
|
|
88933
|
-
|
|
88934
|
-
|
|
89087
|
+
if (deletionResult.preservedPaths.length > 0) {
|
|
89088
|
+
logger.verbose(`Preserved ${deletionResult.preservedPaths.length} user-owned file(s)`);
|
|
89089
|
+
}
|
|
88935
89090
|
}
|
|
88936
89091
|
} catch (error) {
|
|
88937
89092
|
logger.debug(`Cleanup of deprecated files failed: ${error}`);
|
|
@@ -88958,7 +89113,7 @@ async function handleMerge(ctx) {
|
|
|
88958
89113
|
};
|
|
88959
89114
|
}
|
|
88960
89115
|
// src/commands/init/phases/migration-handler.ts
|
|
88961
|
-
import { join as
|
|
89116
|
+
import { join as join101 } from "node:path";
|
|
88962
89117
|
|
|
88963
89118
|
// src/domains/skills/skills-detector.ts
|
|
88964
89119
|
init_logger();
|
|
@@ -88974,7 +89129,7 @@ init_types3();
|
|
|
88974
89129
|
var import_fs_extra21 = __toESM(require_lib3(), 1);
|
|
88975
89130
|
import { createHash as createHash4 } from "node:crypto";
|
|
88976
89131
|
import { readFile as readFile44, readdir as readdir24, writeFile as writeFile27 } from "node:fs/promises";
|
|
88977
|
-
import { join as
|
|
89132
|
+
import { join as join94, relative as relative16 } from "node:path";
|
|
88978
89133
|
|
|
88979
89134
|
class SkillsManifestManager {
|
|
88980
89135
|
static MANIFEST_FILENAME = ".skills-manifest.json";
|
|
@@ -88996,12 +89151,12 @@ class SkillsManifestManager {
|
|
|
88996
89151
|
return manifest;
|
|
88997
89152
|
}
|
|
88998
89153
|
static async writeManifest(skillsDir2, manifest) {
|
|
88999
|
-
const manifestPath =
|
|
89154
|
+
const manifestPath = join94(skillsDir2, SkillsManifestManager.MANIFEST_FILENAME);
|
|
89000
89155
|
await writeFile27(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
89001
89156
|
logger.debug(`Wrote manifest to: ${manifestPath}`);
|
|
89002
89157
|
}
|
|
89003
89158
|
static async readManifest(skillsDir2) {
|
|
89004
|
-
const manifestPath =
|
|
89159
|
+
const manifestPath = join94(skillsDir2, SkillsManifestManager.MANIFEST_FILENAME);
|
|
89005
89160
|
if (!await import_fs_extra21.pathExists(manifestPath)) {
|
|
89006
89161
|
logger.debug(`No manifest found at: ${manifestPath}`);
|
|
89007
89162
|
return null;
|
|
@@ -89024,7 +89179,7 @@ class SkillsManifestManager {
|
|
|
89024
89179
|
return "flat";
|
|
89025
89180
|
}
|
|
89026
89181
|
for (const dir of dirs.slice(0, 3)) {
|
|
89027
|
-
const dirPath =
|
|
89182
|
+
const dirPath = join94(skillsDir2, dir.name);
|
|
89028
89183
|
const subEntries = await readdir24(dirPath, { withFileTypes: true });
|
|
89029
89184
|
const hasSubdirs = subEntries.some((entry) => entry.isDirectory());
|
|
89030
89185
|
if (hasSubdirs) {
|
|
@@ -89043,7 +89198,7 @@ class SkillsManifestManager {
|
|
|
89043
89198
|
const entries = await readdir24(skillsDir2, { withFileTypes: true });
|
|
89044
89199
|
for (const entry of entries) {
|
|
89045
89200
|
if (entry.isDirectory() && !BUILD_ARTIFACT_DIRS.includes(entry.name) && !entry.name.startsWith(".")) {
|
|
89046
|
-
const skillPath =
|
|
89201
|
+
const skillPath = join94(skillsDir2, entry.name);
|
|
89047
89202
|
const hash = await SkillsManifestManager.hashDirectory(skillPath);
|
|
89048
89203
|
skills.push({
|
|
89049
89204
|
name: entry.name,
|
|
@@ -89055,11 +89210,11 @@ class SkillsManifestManager {
|
|
|
89055
89210
|
const categories = await readdir24(skillsDir2, { withFileTypes: true });
|
|
89056
89211
|
for (const category of categories) {
|
|
89057
89212
|
if (category.isDirectory() && !BUILD_ARTIFACT_DIRS.includes(category.name) && !category.name.startsWith(".")) {
|
|
89058
|
-
const categoryPath =
|
|
89213
|
+
const categoryPath = join94(skillsDir2, category.name);
|
|
89059
89214
|
const skillEntries = await readdir24(categoryPath, { withFileTypes: true });
|
|
89060
89215
|
for (const skillEntry of skillEntries) {
|
|
89061
89216
|
if (skillEntry.isDirectory() && !skillEntry.name.startsWith(".")) {
|
|
89062
|
-
const skillPath =
|
|
89217
|
+
const skillPath = join94(categoryPath, skillEntry.name);
|
|
89063
89218
|
const hash = await SkillsManifestManager.hashDirectory(skillPath);
|
|
89064
89219
|
skills.push({
|
|
89065
89220
|
name: skillEntry.name,
|
|
@@ -89089,7 +89244,7 @@ class SkillsManifestManager {
|
|
|
89089
89244
|
const files = [];
|
|
89090
89245
|
const entries = await readdir24(dirPath, { withFileTypes: true });
|
|
89091
89246
|
for (const entry of entries) {
|
|
89092
|
-
const fullPath =
|
|
89247
|
+
const fullPath = join94(dirPath, entry.name);
|
|
89093
89248
|
if (entry.name.startsWith(".") || BUILD_ARTIFACT_DIRS.includes(entry.name)) {
|
|
89094
89249
|
continue;
|
|
89095
89250
|
}
|
|
@@ -89211,7 +89366,7 @@ function getPathMapping(skillName, oldBasePath, newBasePath) {
|
|
|
89211
89366
|
// src/domains/skills/detection/script-detector.ts
|
|
89212
89367
|
var import_fs_extra22 = __toESM(require_lib3(), 1);
|
|
89213
89368
|
import { readdir as readdir25 } from "node:fs/promises";
|
|
89214
|
-
import { join as
|
|
89369
|
+
import { join as join95 } from "node:path";
|
|
89215
89370
|
async function scanDirectory(skillsDir2) {
|
|
89216
89371
|
if (!await import_fs_extra22.pathExists(skillsDir2)) {
|
|
89217
89372
|
return ["flat", []];
|
|
@@ -89224,12 +89379,12 @@ async function scanDirectory(skillsDir2) {
|
|
|
89224
89379
|
let totalSkillLikeCount = 0;
|
|
89225
89380
|
const allSkills = [];
|
|
89226
89381
|
for (const dir of dirs) {
|
|
89227
|
-
const dirPath =
|
|
89382
|
+
const dirPath = join95(skillsDir2, dir.name);
|
|
89228
89383
|
const subEntries = await readdir25(dirPath, { withFileTypes: true });
|
|
89229
89384
|
const subdirs = subEntries.filter((entry) => entry.isDirectory() && !entry.name.startsWith("."));
|
|
89230
89385
|
if (subdirs.length > 0) {
|
|
89231
89386
|
for (const subdir of subdirs.slice(0, 3)) {
|
|
89232
|
-
const subdirPath =
|
|
89387
|
+
const subdirPath = join95(dirPath, subdir.name);
|
|
89233
89388
|
const subdirFiles = await readdir25(subdirPath, { withFileTypes: true });
|
|
89234
89389
|
const hasSkillMarker = subdirFiles.some((file) => file.isFile() && (file.name === "skill.md" || file.name === "README.md" || file.name === "readme.md" || file.name === "config.json" || file.name === "package.json"));
|
|
89235
89390
|
if (hasSkillMarker) {
|
|
@@ -89386,12 +89541,12 @@ class SkillsMigrationDetector {
|
|
|
89386
89541
|
// src/domains/skills/skills-migrator.ts
|
|
89387
89542
|
init_logger();
|
|
89388
89543
|
init_types3();
|
|
89389
|
-
import { join as
|
|
89544
|
+
import { join as join100 } from "node:path";
|
|
89390
89545
|
|
|
89391
89546
|
// src/domains/skills/migrator/migration-executor.ts
|
|
89392
89547
|
init_logger();
|
|
89393
89548
|
import { copyFile as copyFile6, mkdir as mkdir28, readdir as readdir26, rm as rm10 } from "node:fs/promises";
|
|
89394
|
-
import { join as
|
|
89549
|
+
import { join as join96 } from "node:path";
|
|
89395
89550
|
var import_fs_extra24 = __toESM(require_lib3(), 1);
|
|
89396
89551
|
|
|
89397
89552
|
// src/domains/skills/skills-migration-prompts.ts
|
|
@@ -89556,8 +89711,8 @@ async function copySkillDirectory(sourceDir, destDir) {
|
|
|
89556
89711
|
await mkdir28(destDir, { recursive: true });
|
|
89557
89712
|
const entries = await readdir26(sourceDir, { withFileTypes: true });
|
|
89558
89713
|
for (const entry of entries) {
|
|
89559
|
-
const sourcePath =
|
|
89560
|
-
const destPath =
|
|
89714
|
+
const sourcePath = join96(sourceDir, entry.name);
|
|
89715
|
+
const destPath = join96(destDir, entry.name);
|
|
89561
89716
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.isSymbolicLink()) {
|
|
89562
89717
|
continue;
|
|
89563
89718
|
}
|
|
@@ -89572,7 +89727,7 @@ async function executeInternal(mappings, customizations, currentSkillsDir, inter
|
|
|
89572
89727
|
const migrated = [];
|
|
89573
89728
|
const preserved = [];
|
|
89574
89729
|
const errors2 = [];
|
|
89575
|
-
const tempDir =
|
|
89730
|
+
const tempDir = join96(currentSkillsDir, "..", ".skills-migration-temp");
|
|
89576
89731
|
await mkdir28(tempDir, { recursive: true });
|
|
89577
89732
|
try {
|
|
89578
89733
|
for (const mapping of mappings) {
|
|
@@ -89593,9 +89748,9 @@ async function executeInternal(mappings, customizations, currentSkillsDir, inter
|
|
|
89593
89748
|
}
|
|
89594
89749
|
}
|
|
89595
89750
|
const category = mapping.category;
|
|
89596
|
-
const targetPath = category ?
|
|
89751
|
+
const targetPath = category ? join96(tempDir, category, skillName) : join96(tempDir, skillName);
|
|
89597
89752
|
if (category) {
|
|
89598
|
-
await mkdir28(
|
|
89753
|
+
await mkdir28(join96(tempDir, category), { recursive: true });
|
|
89599
89754
|
}
|
|
89600
89755
|
await copySkillDirectory(currentSkillPath, targetPath);
|
|
89601
89756
|
migrated.push(skillName);
|
|
@@ -89662,7 +89817,7 @@ init_logger();
|
|
|
89662
89817
|
init_types3();
|
|
89663
89818
|
var import_fs_extra25 = __toESM(require_lib3(), 1);
|
|
89664
89819
|
import { copyFile as copyFile7, mkdir as mkdir29, readdir as readdir27, rm as rm11, stat as stat16 } from "node:fs/promises";
|
|
89665
|
-
import { basename as basename15, join as
|
|
89820
|
+
import { basename as basename15, join as join97, normalize as normalize8 } from "node:path";
|
|
89666
89821
|
function validatePath2(path14, paramName) {
|
|
89667
89822
|
if (!path14 || typeof path14 !== "string") {
|
|
89668
89823
|
throw new SkillsMigrationError(`${paramName} must be a non-empty string`);
|
|
@@ -89688,7 +89843,7 @@ class SkillsBackupManager {
|
|
|
89688
89843
|
const timestamp = Date.now();
|
|
89689
89844
|
const randomSuffix = Math.random().toString(36).substring(2, 8);
|
|
89690
89845
|
const backupDirName = `${SkillsBackupManager.BACKUP_PREFIX}${timestamp}-${randomSuffix}`;
|
|
89691
|
-
const backupDir = parentDir ?
|
|
89846
|
+
const backupDir = parentDir ? join97(parentDir, backupDirName) : join97(skillsDir2, "..", backupDirName);
|
|
89692
89847
|
logger.info(`Creating backup at: ${backupDir}`);
|
|
89693
89848
|
try {
|
|
89694
89849
|
await mkdir29(backupDir, { recursive: true });
|
|
@@ -89739,7 +89894,7 @@ class SkillsBackupManager {
|
|
|
89739
89894
|
}
|
|
89740
89895
|
try {
|
|
89741
89896
|
const entries = await readdir27(parentDir, { withFileTypes: true });
|
|
89742
|
-
const backups = entries.filter((entry) => entry.isDirectory() && entry.name.startsWith(SkillsBackupManager.BACKUP_PREFIX)).map((entry) =>
|
|
89897
|
+
const backups = entries.filter((entry) => entry.isDirectory() && entry.name.startsWith(SkillsBackupManager.BACKUP_PREFIX)).map((entry) => join97(parentDir, entry.name));
|
|
89743
89898
|
backups.sort().reverse();
|
|
89744
89899
|
return backups;
|
|
89745
89900
|
} catch (error) {
|
|
@@ -89767,8 +89922,8 @@ class SkillsBackupManager {
|
|
|
89767
89922
|
static async copyDirectory(sourceDir, destDir) {
|
|
89768
89923
|
const entries = await readdir27(sourceDir, { withFileTypes: true });
|
|
89769
89924
|
for (const entry of entries) {
|
|
89770
|
-
const sourcePath =
|
|
89771
|
-
const destPath =
|
|
89925
|
+
const sourcePath = join97(sourceDir, entry.name);
|
|
89926
|
+
const destPath = join97(destDir, entry.name);
|
|
89772
89927
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.isSymbolicLink()) {
|
|
89773
89928
|
continue;
|
|
89774
89929
|
}
|
|
@@ -89784,7 +89939,7 @@ class SkillsBackupManager {
|
|
|
89784
89939
|
let size = 0;
|
|
89785
89940
|
const entries = await readdir27(dirPath, { withFileTypes: true });
|
|
89786
89941
|
for (const entry of entries) {
|
|
89787
|
-
const fullPath =
|
|
89942
|
+
const fullPath = join97(dirPath, entry.name);
|
|
89788
89943
|
if (entry.isSymbolicLink()) {
|
|
89789
89944
|
continue;
|
|
89790
89945
|
}
|
|
@@ -89820,12 +89975,12 @@ init_skip_directories();
|
|
|
89820
89975
|
import { createHash as createHash5 } from "node:crypto";
|
|
89821
89976
|
import { createReadStream as createReadStream3 } from "node:fs";
|
|
89822
89977
|
import { readFile as readFile45, readdir as readdir28 } from "node:fs/promises";
|
|
89823
|
-
import { join as
|
|
89978
|
+
import { join as join98, relative as relative17 } from "node:path";
|
|
89824
89979
|
async function getAllFiles(dirPath) {
|
|
89825
89980
|
const files = [];
|
|
89826
89981
|
const entries = await readdir28(dirPath, { withFileTypes: true });
|
|
89827
89982
|
for (const entry of entries) {
|
|
89828
|
-
const fullPath =
|
|
89983
|
+
const fullPath = join98(dirPath, entry.name);
|
|
89829
89984
|
if (entry.name.startsWith(".") || BUILD_ARTIFACT_DIRS.includes(entry.name) || entry.isSymbolicLink()) {
|
|
89830
89985
|
continue;
|
|
89831
89986
|
}
|
|
@@ -89952,7 +90107,7 @@ async function detectFileChanges(currentSkillPath, baselineSkillPath) {
|
|
|
89952
90107
|
init_types3();
|
|
89953
90108
|
var import_fs_extra27 = __toESM(require_lib3(), 1);
|
|
89954
90109
|
import { readdir as readdir29 } from "node:fs/promises";
|
|
89955
|
-
import { join as
|
|
90110
|
+
import { join as join99, normalize as normalize9 } from "node:path";
|
|
89956
90111
|
function validatePath3(path14, paramName) {
|
|
89957
90112
|
if (!path14 || typeof path14 !== "string") {
|
|
89958
90113
|
throw new SkillsMigrationError(`${paramName} must be a non-empty string`);
|
|
@@ -89973,13 +90128,13 @@ async function scanSkillsDirectory(skillsDir2) {
|
|
|
89973
90128
|
if (dirs.length === 0) {
|
|
89974
90129
|
return ["flat", []];
|
|
89975
90130
|
}
|
|
89976
|
-
const firstDirPath =
|
|
90131
|
+
const firstDirPath = join99(skillsDir2, dirs[0].name);
|
|
89977
90132
|
const subEntries = await readdir29(firstDirPath, { withFileTypes: true });
|
|
89978
90133
|
const subdirs = subEntries.filter((entry) => entry.isDirectory() && !entry.name.startsWith("."));
|
|
89979
90134
|
if (subdirs.length > 0) {
|
|
89980
90135
|
let skillLikeCount = 0;
|
|
89981
90136
|
for (const subdir of subdirs.slice(0, 3)) {
|
|
89982
|
-
const subdirPath =
|
|
90137
|
+
const subdirPath = join99(firstDirPath, subdir.name);
|
|
89983
90138
|
const subdirFiles = await readdir29(subdirPath, { withFileTypes: true });
|
|
89984
90139
|
const hasSkillMarker = subdirFiles.some((file) => file.isFile() && (file.name === "skill.md" || file.name === "README.md" || file.name === "readme.md" || file.name === "config.json" || file.name === "package.json"));
|
|
89985
90140
|
if (hasSkillMarker) {
|
|
@@ -89989,7 +90144,7 @@ async function scanSkillsDirectory(skillsDir2) {
|
|
|
89989
90144
|
if (skillLikeCount > 0) {
|
|
89990
90145
|
const skills = [];
|
|
89991
90146
|
for (const dir of dirs) {
|
|
89992
|
-
const categoryPath =
|
|
90147
|
+
const categoryPath = join99(skillsDir2, dir.name);
|
|
89993
90148
|
const skillDirs = await readdir29(categoryPath, { withFileTypes: true });
|
|
89994
90149
|
skills.push(...skillDirs.filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name));
|
|
89995
90150
|
}
|
|
@@ -89999,7 +90154,7 @@ async function scanSkillsDirectory(skillsDir2) {
|
|
|
89999
90154
|
return ["flat", dirs.map((dir) => dir.name)];
|
|
90000
90155
|
}
|
|
90001
90156
|
async function findSkillPath(skillsDir2, skillName) {
|
|
90002
|
-
const flatPath =
|
|
90157
|
+
const flatPath = join99(skillsDir2, skillName);
|
|
90003
90158
|
if (await import_fs_extra27.pathExists(flatPath)) {
|
|
90004
90159
|
return { path: flatPath, category: undefined };
|
|
90005
90160
|
}
|
|
@@ -90008,8 +90163,8 @@ async function findSkillPath(skillsDir2, skillName) {
|
|
|
90008
90163
|
if (!entry.isDirectory() || entry.name.startsWith(".") || entry.name === "node_modules") {
|
|
90009
90164
|
continue;
|
|
90010
90165
|
}
|
|
90011
|
-
const categoryPath =
|
|
90012
|
-
const skillPath =
|
|
90166
|
+
const categoryPath = join99(skillsDir2, entry.name);
|
|
90167
|
+
const skillPath = join99(categoryPath, skillName);
|
|
90013
90168
|
if (await import_fs_extra27.pathExists(skillPath)) {
|
|
90014
90169
|
return { path: skillPath, category: entry.name };
|
|
90015
90170
|
}
|
|
@@ -90103,7 +90258,7 @@ class SkillsMigrator {
|
|
|
90103
90258
|
}
|
|
90104
90259
|
}
|
|
90105
90260
|
if (options2.backup && !options2.dryRun) {
|
|
90106
|
-
const claudeDir2 =
|
|
90261
|
+
const claudeDir2 = join100(currentSkillsDir, "..");
|
|
90107
90262
|
result.backupPath = await SkillsBackupManager.createBackup(currentSkillsDir, claudeDir2);
|
|
90108
90263
|
logger.success(`Backup created at: ${result.backupPath}`);
|
|
90109
90264
|
}
|
|
@@ -90164,7 +90319,7 @@ async function handleMigration(ctx) {
|
|
|
90164
90319
|
logger.debug("Skipping skills migration (fresh installation)");
|
|
90165
90320
|
return ctx;
|
|
90166
90321
|
}
|
|
90167
|
-
const newSkillsDir =
|
|
90322
|
+
const newSkillsDir = join101(ctx.extractDir, ".claude", "skills");
|
|
90168
90323
|
const currentSkillsDir = PathResolver.buildSkillsPath(ctx.resolvedDir, ctx.options.global);
|
|
90169
90324
|
if (!await import_fs_extra28.pathExists(newSkillsDir) || !await import_fs_extra28.pathExists(currentSkillsDir)) {
|
|
90170
90325
|
return ctx;
|
|
@@ -90188,13 +90343,13 @@ async function handleMigration(ctx) {
|
|
|
90188
90343
|
}
|
|
90189
90344
|
// src/commands/init/phases/opencode-handler.ts
|
|
90190
90345
|
import { cp as cp3, readdir as readdir31, rm as rm12 } from "node:fs/promises";
|
|
90191
|
-
import { join as
|
|
90346
|
+
import { join as join103 } from "node:path";
|
|
90192
90347
|
|
|
90193
90348
|
// src/services/transformers/opencode-path-transformer.ts
|
|
90194
90349
|
init_logger();
|
|
90195
90350
|
import { readFile as readFile46, readdir as readdir30, writeFile as writeFile28 } from "node:fs/promises";
|
|
90196
90351
|
import { platform as platform12 } from "node:os";
|
|
90197
|
-
import { extname as extname6, join as
|
|
90352
|
+
import { extname as extname6, join as join102 } from "node:path";
|
|
90198
90353
|
var IS_WINDOWS2 = platform12() === "win32";
|
|
90199
90354
|
function getOpenCodeGlobalPath() {
|
|
90200
90355
|
return "$HOME/.config/opencode/";
|
|
@@ -90255,7 +90410,7 @@ async function transformPathsForGlobalOpenCode(directory, options2 = {}) {
|
|
|
90255
90410
|
async function processDirectory2(dir) {
|
|
90256
90411
|
const entries = await readdir30(dir, { withFileTypes: true });
|
|
90257
90412
|
for (const entry of entries) {
|
|
90258
|
-
const fullPath =
|
|
90413
|
+
const fullPath = join102(dir, entry.name);
|
|
90259
90414
|
if (entry.isDirectory()) {
|
|
90260
90415
|
if (entry.name === "node_modules" || entry.name.startsWith(".")) {
|
|
90261
90416
|
continue;
|
|
@@ -90294,7 +90449,7 @@ async function handleOpenCode(ctx) {
|
|
|
90294
90449
|
if (ctx.cancelled || !ctx.extractDir || !ctx.resolvedDir) {
|
|
90295
90450
|
return ctx;
|
|
90296
90451
|
}
|
|
90297
|
-
const openCodeSource =
|
|
90452
|
+
const openCodeSource = join103(ctx.extractDir, ".opencode");
|
|
90298
90453
|
if (!await import_fs_extra29.pathExists(openCodeSource)) {
|
|
90299
90454
|
logger.debug("No .opencode directory in archive, skipping");
|
|
90300
90455
|
return ctx;
|
|
@@ -90312,8 +90467,8 @@ async function handleOpenCode(ctx) {
|
|
|
90312
90467
|
await import_fs_extra29.ensureDir(targetDir);
|
|
90313
90468
|
const entries = await readdir31(openCodeSource, { withFileTypes: true });
|
|
90314
90469
|
for (const entry of entries) {
|
|
90315
|
-
const sourcePath =
|
|
90316
|
-
const targetPath =
|
|
90470
|
+
const sourcePath = join103(openCodeSource, entry.name);
|
|
90471
|
+
const targetPath = join103(targetDir, entry.name);
|
|
90317
90472
|
if (await import_fs_extra29.pathExists(targetPath)) {
|
|
90318
90473
|
if (!ctx.options.forceOverwrite) {
|
|
90319
90474
|
logger.verbose(`Skipping existing: ${entry.name}`);
|
|
@@ -90410,7 +90565,7 @@ Please use only one download method.`);
|
|
|
90410
90565
|
}
|
|
90411
90566
|
// src/commands/init/phases/post-install-handler.ts
|
|
90412
90567
|
init_projects_registry();
|
|
90413
|
-
import { join as
|
|
90568
|
+
import { join as join104 } from "node:path";
|
|
90414
90569
|
init_logger();
|
|
90415
90570
|
init_path_resolver();
|
|
90416
90571
|
var import_fs_extra30 = __toESM(require_lib3(), 1);
|
|
@@ -90419,8 +90574,8 @@ async function handlePostInstall(ctx) {
|
|
|
90419
90574
|
return ctx;
|
|
90420
90575
|
}
|
|
90421
90576
|
if (ctx.options.global) {
|
|
90422
|
-
const claudeMdSource =
|
|
90423
|
-
const claudeMdDest =
|
|
90577
|
+
const claudeMdSource = join104(ctx.extractDir, "CLAUDE.md");
|
|
90578
|
+
const claudeMdDest = join104(ctx.resolvedDir, "CLAUDE.md");
|
|
90424
90579
|
if (await import_fs_extra30.pathExists(claudeMdSource)) {
|
|
90425
90580
|
if (ctx.options.fresh || !await import_fs_extra30.pathExists(claudeMdDest)) {
|
|
90426
90581
|
await import_fs_extra30.copy(claudeMdSource, claudeMdDest);
|
|
@@ -90468,7 +90623,7 @@ async function handlePostInstall(ctx) {
|
|
|
90468
90623
|
}
|
|
90469
90624
|
if (!ctx.options.skipSetup) {
|
|
90470
90625
|
await promptSetupWizardIfNeeded({
|
|
90471
|
-
envPath:
|
|
90626
|
+
envPath: join104(ctx.claudeDir, ".env"),
|
|
90472
90627
|
claudeDir: ctx.claudeDir,
|
|
90473
90628
|
isGlobal: ctx.options.global,
|
|
90474
90629
|
isNonInteractive: ctx.isNonInteractive,
|
|
@@ -90492,7 +90647,7 @@ async function handlePostInstall(ctx) {
|
|
|
90492
90647
|
init_config_manager();
|
|
90493
90648
|
init_github_client();
|
|
90494
90649
|
import { mkdir as mkdir30 } from "node:fs/promises";
|
|
90495
|
-
import { join as
|
|
90650
|
+
import { join as join106, resolve as resolve22 } from "node:path";
|
|
90496
90651
|
|
|
90497
90652
|
// src/domains/github/kit-access-checker.ts
|
|
90498
90653
|
init_logger();
|
|
@@ -90623,7 +90778,7 @@ async function runPreflightChecks() {
|
|
|
90623
90778
|
// src/domains/installation/fresh-installer.ts
|
|
90624
90779
|
init_metadata_migration();
|
|
90625
90780
|
import { existsSync as existsSync55, readdirSync as readdirSync5, rmSync as rmSync4, rmdirSync as rmdirSync2, unlinkSync as unlinkSync4 } from "node:fs";
|
|
90626
|
-
import { dirname as dirname27, join as
|
|
90781
|
+
import { dirname as dirname27, join as join105, resolve as resolve21 } from "node:path";
|
|
90627
90782
|
init_logger();
|
|
90628
90783
|
init_safe_spinner();
|
|
90629
90784
|
var import_fs_extra31 = __toESM(require_lib3(), 1);
|
|
@@ -90696,7 +90851,7 @@ async function removeFilesByOwnership(claudeDir2, analysis, includeModified) {
|
|
|
90696
90851
|
const filesToRemove = includeModified ? [...analysis.ckFiles, ...analysis.ckModifiedFiles] : analysis.ckFiles;
|
|
90697
90852
|
const filesToPreserve = includeModified ? analysis.userFiles : [...analysis.ckModifiedFiles, ...analysis.userFiles];
|
|
90698
90853
|
for (const file of filesToRemove) {
|
|
90699
|
-
const fullPath =
|
|
90854
|
+
const fullPath = join105(claudeDir2, file.path);
|
|
90700
90855
|
try {
|
|
90701
90856
|
if (existsSync55(fullPath)) {
|
|
90702
90857
|
unlinkSync4(fullPath);
|
|
@@ -90721,7 +90876,7 @@ async function removeFilesByOwnership(claudeDir2, analysis, includeModified) {
|
|
|
90721
90876
|
};
|
|
90722
90877
|
}
|
|
90723
90878
|
async function updateMetadataAfterFresh(claudeDir2, removedFiles) {
|
|
90724
|
-
const metadataPath =
|
|
90879
|
+
const metadataPath = join105(claudeDir2, "metadata.json");
|
|
90725
90880
|
if (!await import_fs_extra31.pathExists(metadataPath)) {
|
|
90726
90881
|
return;
|
|
90727
90882
|
}
|
|
@@ -90764,7 +90919,7 @@ async function removeSubdirectoriesFallback(claudeDir2) {
|
|
|
90764
90919
|
const removedFiles = [];
|
|
90765
90920
|
let removedDirCount = 0;
|
|
90766
90921
|
for (const subdir of CLAUDEKIT_SUBDIRECTORIES) {
|
|
90767
|
-
const subdirPath =
|
|
90922
|
+
const subdirPath = join105(claudeDir2, subdir);
|
|
90768
90923
|
if (await import_fs_extra31.pathExists(subdirPath)) {
|
|
90769
90924
|
rmSync4(subdirPath, { recursive: true, force: true });
|
|
90770
90925
|
removedDirCount++;
|
|
@@ -90772,7 +90927,7 @@ async function removeSubdirectoriesFallback(claudeDir2) {
|
|
|
90772
90927
|
logger.debug(`Removed subdirectory: ${subdir}/`);
|
|
90773
90928
|
}
|
|
90774
90929
|
}
|
|
90775
|
-
const metadataPath =
|
|
90930
|
+
const metadataPath = join105(claudeDir2, "metadata.json");
|
|
90776
90931
|
if (await import_fs_extra31.pathExists(metadataPath)) {
|
|
90777
90932
|
unlinkSync4(metadataPath);
|
|
90778
90933
|
removedFiles.push("metadata.json");
|
|
@@ -91024,7 +91179,7 @@ async function handleSelection(ctx) {
|
|
|
91024
91179
|
}
|
|
91025
91180
|
if (!ctx.options.fresh) {
|
|
91026
91181
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
91027
|
-
const claudeDir2 = prefix ?
|
|
91182
|
+
const claudeDir2 = prefix ? join106(resolvedDir, prefix) : resolvedDir;
|
|
91028
91183
|
try {
|
|
91029
91184
|
const existingMetadata = await readManifest(claudeDir2);
|
|
91030
91185
|
if (existingMetadata?.kits) {
|
|
@@ -91056,7 +91211,7 @@ async function handleSelection(ctx) {
|
|
|
91056
91211
|
}
|
|
91057
91212
|
if (ctx.options.fresh) {
|
|
91058
91213
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
91059
|
-
const claudeDir2 = prefix ?
|
|
91214
|
+
const claudeDir2 = prefix ? join106(resolvedDir, prefix) : resolvedDir;
|
|
91060
91215
|
const canProceed = await handleFreshInstallation(claudeDir2, ctx.prompts);
|
|
91061
91216
|
if (!canProceed) {
|
|
91062
91217
|
return { ...ctx, cancelled: true };
|
|
@@ -91075,7 +91230,7 @@ async function handleSelection(ctx) {
|
|
|
91075
91230
|
logger.info("Fetching available versions...");
|
|
91076
91231
|
let currentVersion = null;
|
|
91077
91232
|
try {
|
|
91078
|
-
const metadataPath = ctx.options.global ?
|
|
91233
|
+
const metadataPath = ctx.options.global ? join106(PathResolver.getGlobalKitDir(), "metadata.json") : join106(resolvedDir, ".claude", "metadata.json");
|
|
91079
91234
|
const metadata = await readClaudeKitMetadata(metadataPath);
|
|
91080
91235
|
currentVersion = metadata?.version || null;
|
|
91081
91236
|
if (currentVersion) {
|
|
@@ -91150,7 +91305,7 @@ async function handleSelection(ctx) {
|
|
|
91150
91305
|
}
|
|
91151
91306
|
// src/commands/init/phases/sync-handler.ts
|
|
91152
91307
|
import { copyFile as copyFile8, mkdir as mkdir31, open as open4, readFile as readFile48, rename as rename6, stat as stat17, unlink as unlink11, writeFile as writeFile30 } from "node:fs/promises";
|
|
91153
|
-
import { dirname as dirname28, join as
|
|
91308
|
+
import { dirname as dirname28, join as join107, resolve as resolve23 } from "node:path";
|
|
91154
91309
|
init_logger();
|
|
91155
91310
|
init_path_resolver();
|
|
91156
91311
|
var import_fs_extra33 = __toESM(require_lib3(), 1);
|
|
@@ -91160,13 +91315,13 @@ async function handleSync(ctx) {
|
|
|
91160
91315
|
return ctx;
|
|
91161
91316
|
}
|
|
91162
91317
|
const resolvedDir = ctx.options.global ? PathResolver.getGlobalKitDir() : resolve23(ctx.options.dir || ".");
|
|
91163
|
-
const claudeDir2 = ctx.options.global ? resolvedDir :
|
|
91318
|
+
const claudeDir2 = ctx.options.global ? resolvedDir : join107(resolvedDir, ".claude");
|
|
91164
91319
|
if (!await import_fs_extra33.pathExists(claudeDir2)) {
|
|
91165
91320
|
logger.error("Cannot sync: no .claude directory found");
|
|
91166
91321
|
ctx.prompts.note("Run 'ck init' without --sync to install first.", "No Installation Found");
|
|
91167
91322
|
return { ...ctx, cancelled: true };
|
|
91168
91323
|
}
|
|
91169
|
-
const metadataPath =
|
|
91324
|
+
const metadataPath = join107(claudeDir2, "metadata.json");
|
|
91170
91325
|
if (!await import_fs_extra33.pathExists(metadataPath)) {
|
|
91171
91326
|
logger.error("Cannot sync: no metadata.json found");
|
|
91172
91327
|
ctx.prompts.note(`Your installation may be from an older version.
|
|
@@ -91266,7 +91421,7 @@ function getLockTimeout() {
|
|
|
91266
91421
|
var STALE_LOCK_THRESHOLD_MS = 5 * 60 * 1000;
|
|
91267
91422
|
async function acquireSyncLock(global3) {
|
|
91268
91423
|
const cacheDir = PathResolver.getCacheDir(global3);
|
|
91269
|
-
const lockPath =
|
|
91424
|
+
const lockPath = join107(cacheDir, ".sync-lock");
|
|
91270
91425
|
const startTime = Date.now();
|
|
91271
91426
|
const lockTimeout = getLockTimeout();
|
|
91272
91427
|
await mkdir31(dirname28(lockPath), { recursive: true });
|
|
@@ -91312,10 +91467,10 @@ async function executeSyncMerge(ctx) {
|
|
|
91312
91467
|
const releaseLock = await acquireSyncLock(ctx.options.global);
|
|
91313
91468
|
try {
|
|
91314
91469
|
const trackedFiles = ctx.syncTrackedFiles;
|
|
91315
|
-
const upstreamDir = ctx.options.global ?
|
|
91470
|
+
const upstreamDir = ctx.options.global ? join107(ctx.extractDir, ".claude") : ctx.extractDir;
|
|
91316
91471
|
let deletions = [];
|
|
91317
91472
|
try {
|
|
91318
|
-
const sourceMetadataPath =
|
|
91473
|
+
const sourceMetadataPath = join107(upstreamDir, "metadata.json");
|
|
91319
91474
|
if (await import_fs_extra33.pathExists(sourceMetadataPath)) {
|
|
91320
91475
|
const content = await readFile48(sourceMetadataPath, "utf-8");
|
|
91321
91476
|
const sourceMetadata = JSON.parse(content);
|
|
@@ -91347,7 +91502,7 @@ async function executeSyncMerge(ctx) {
|
|
|
91347
91502
|
try {
|
|
91348
91503
|
const sourcePath = await validateSyncPath(upstreamDir, file.path);
|
|
91349
91504
|
const targetPath = await validateSyncPath(ctx.claudeDir, file.path);
|
|
91350
|
-
const targetDir =
|
|
91505
|
+
const targetDir = join107(targetPath, "..");
|
|
91351
91506
|
try {
|
|
91352
91507
|
await mkdir31(targetDir, { recursive: true });
|
|
91353
91508
|
} catch (mkdirError) {
|
|
@@ -91518,7 +91673,7 @@ async function createBackup(claudeDir2, files, backupDir) {
|
|
|
91518
91673
|
const sourcePath = await validateSyncPath(claudeDir2, file.path);
|
|
91519
91674
|
if (await import_fs_extra33.pathExists(sourcePath)) {
|
|
91520
91675
|
const targetPath = await validateSyncPath(backupDir, file.path);
|
|
91521
|
-
const targetDir =
|
|
91676
|
+
const targetDir = join107(targetPath, "..");
|
|
91522
91677
|
await mkdir31(targetDir, { recursive: true });
|
|
91523
91678
|
await copyFile8(sourcePath, targetPath);
|
|
91524
91679
|
}
|
|
@@ -91533,7 +91688,7 @@ async function createBackup(claudeDir2, files, backupDir) {
|
|
|
91533
91688
|
}
|
|
91534
91689
|
// src/commands/init/phases/transform-handler.ts
|
|
91535
91690
|
init_config_manager();
|
|
91536
|
-
import { join as
|
|
91691
|
+
import { join as join111 } from "node:path";
|
|
91537
91692
|
|
|
91538
91693
|
// src/services/transformers/folder-path-transformer.ts
|
|
91539
91694
|
init_logger();
|
|
@@ -91544,38 +91699,38 @@ init_logger();
|
|
|
91544
91699
|
init_types3();
|
|
91545
91700
|
var import_fs_extra34 = __toESM(require_lib3(), 1);
|
|
91546
91701
|
import { rename as rename7, rm as rm13 } from "node:fs/promises";
|
|
91547
|
-
import { join as
|
|
91702
|
+
import { join as join108, relative as relative19 } from "node:path";
|
|
91548
91703
|
async function collectDirsToRename(extractDir, folders) {
|
|
91549
91704
|
const dirsToRename = [];
|
|
91550
91705
|
if (folders.docs !== DEFAULT_FOLDERS.docs) {
|
|
91551
|
-
const docsPath =
|
|
91706
|
+
const docsPath = join108(extractDir, DEFAULT_FOLDERS.docs);
|
|
91552
91707
|
if (await import_fs_extra34.pathExists(docsPath)) {
|
|
91553
91708
|
dirsToRename.push({
|
|
91554
91709
|
from: docsPath,
|
|
91555
|
-
to:
|
|
91710
|
+
to: join108(extractDir, folders.docs)
|
|
91556
91711
|
});
|
|
91557
91712
|
}
|
|
91558
|
-
const claudeDocsPath =
|
|
91713
|
+
const claudeDocsPath = join108(extractDir, ".claude", DEFAULT_FOLDERS.docs);
|
|
91559
91714
|
if (await import_fs_extra34.pathExists(claudeDocsPath)) {
|
|
91560
91715
|
dirsToRename.push({
|
|
91561
91716
|
from: claudeDocsPath,
|
|
91562
|
-
to:
|
|
91717
|
+
to: join108(extractDir, ".claude", folders.docs)
|
|
91563
91718
|
});
|
|
91564
91719
|
}
|
|
91565
91720
|
}
|
|
91566
91721
|
if (folders.plans !== DEFAULT_FOLDERS.plans) {
|
|
91567
|
-
const plansPath =
|
|
91722
|
+
const plansPath = join108(extractDir, DEFAULT_FOLDERS.plans);
|
|
91568
91723
|
if (await import_fs_extra34.pathExists(plansPath)) {
|
|
91569
91724
|
dirsToRename.push({
|
|
91570
91725
|
from: plansPath,
|
|
91571
|
-
to:
|
|
91726
|
+
to: join108(extractDir, folders.plans)
|
|
91572
91727
|
});
|
|
91573
91728
|
}
|
|
91574
|
-
const claudePlansPath =
|
|
91729
|
+
const claudePlansPath = join108(extractDir, ".claude", DEFAULT_FOLDERS.plans);
|
|
91575
91730
|
if (await import_fs_extra34.pathExists(claudePlansPath)) {
|
|
91576
91731
|
dirsToRename.push({
|
|
91577
91732
|
from: claudePlansPath,
|
|
91578
|
-
to:
|
|
91733
|
+
to: join108(extractDir, ".claude", folders.plans)
|
|
91579
91734
|
});
|
|
91580
91735
|
}
|
|
91581
91736
|
}
|
|
@@ -91616,7 +91771,7 @@ async function renameFolders(dirsToRename, extractDir, options2) {
|
|
|
91616
91771
|
init_logger();
|
|
91617
91772
|
init_types3();
|
|
91618
91773
|
import { readFile as readFile49, readdir as readdir32, writeFile as writeFile31 } from "node:fs/promises";
|
|
91619
|
-
import { join as
|
|
91774
|
+
import { join as join109, relative as relative20 } from "node:path";
|
|
91620
91775
|
var TRANSFORMABLE_FILE_PATTERNS = [
|
|
91621
91776
|
".md",
|
|
91622
91777
|
".txt",
|
|
@@ -91669,7 +91824,7 @@ async function transformFileContents(dir, compiledReplacements, options2) {
|
|
|
91669
91824
|
let replacementsCount = 0;
|
|
91670
91825
|
const entries = await readdir32(dir, { withFileTypes: true });
|
|
91671
91826
|
for (const entry of entries) {
|
|
91672
|
-
const fullPath =
|
|
91827
|
+
const fullPath = join109(dir, entry.name);
|
|
91673
91828
|
if (entry.isDirectory()) {
|
|
91674
91829
|
if (entry.name === "node_modules" || entry.name === ".git") {
|
|
91675
91830
|
continue;
|
|
@@ -91806,7 +91961,7 @@ async function transformFolderPaths(extractDir, folders, options2 = {}) {
|
|
|
91806
91961
|
init_logger();
|
|
91807
91962
|
import { readFile as readFile50, readdir as readdir33, writeFile as writeFile32 } from "node:fs/promises";
|
|
91808
91963
|
import { platform as platform13 } from "node:os";
|
|
91809
|
-
import { extname as extname7, join as
|
|
91964
|
+
import { extname as extname7, join as join110 } from "node:path";
|
|
91810
91965
|
var IS_WINDOWS3 = platform13() === "win32";
|
|
91811
91966
|
var HOME_PREFIX = IS_WINDOWS3 ? "%USERPROFILE%" : "$HOME";
|
|
91812
91967
|
function getHomeDirPrefix() {
|
|
@@ -91916,7 +92071,7 @@ async function transformPathsForGlobalInstall(directory, options2 = {}) {
|
|
|
91916
92071
|
async function processDirectory2(dir) {
|
|
91917
92072
|
const entries = await readdir33(dir, { withFileTypes: true });
|
|
91918
92073
|
for (const entry of entries) {
|
|
91919
|
-
const fullPath =
|
|
92074
|
+
const fullPath = join110(dir, entry.name);
|
|
91920
92075
|
if (entry.isDirectory()) {
|
|
91921
92076
|
if (entry.name === "node_modules" || entry.name.startsWith(".") && entry.name !== ".claude") {
|
|
91922
92077
|
continue;
|
|
@@ -91992,7 +92147,7 @@ async function handleTransforms(ctx) {
|
|
|
91992
92147
|
logger.debug(ctx.options.global ? "Saved folder configuration to ~/.claude/.ck.json" : "Saved folder configuration to .claude/.ck.json");
|
|
91993
92148
|
}
|
|
91994
92149
|
}
|
|
91995
|
-
const claudeDir2 = ctx.options.global ? ctx.resolvedDir :
|
|
92150
|
+
const claudeDir2 = ctx.options.global ? ctx.resolvedDir : join111(ctx.resolvedDir, ".claude");
|
|
91996
92151
|
return {
|
|
91997
92152
|
...ctx,
|
|
91998
92153
|
foldersConfig,
|
|
@@ -92179,15 +92334,16 @@ async function initCommand(options2) {
|
|
|
92179
92334
|
}
|
|
92180
92335
|
// src/commands/migrate/migrate-command.ts
|
|
92181
92336
|
init_dist2();
|
|
92337
|
+
var import_picocolors25 = __toESM(require_picocolors(), 1);
|
|
92338
|
+
import { existsSync as existsSync56 } from "node:fs";
|
|
92339
|
+
import { readFile as readFile51, rm as rm14, unlink as unlink12 } from "node:fs/promises";
|
|
92340
|
+
import { homedir as homedir29 } from "node:os";
|
|
92341
|
+
import { basename as basename16, join as join112, resolve as resolve24 } from "node:path";
|
|
92182
92342
|
init_logger();
|
|
92183
92343
|
init_agents_discovery();
|
|
92184
92344
|
init_commands_discovery();
|
|
92185
92345
|
init_checksum_utils();
|
|
92186
92346
|
init_config_discovery();
|
|
92187
|
-
var import_picocolors25 = __toESM(require_picocolors(), 1);
|
|
92188
|
-
import { existsSync as existsSync56 } from "node:fs";
|
|
92189
|
-
import { readFile as readFile51, rm as rm14, unlink as unlink12 } from "node:fs/promises";
|
|
92190
|
-
import { basename as basename16, resolve as resolve24 } from "node:path";
|
|
92191
92347
|
|
|
92192
92348
|
// src/commands/portable/conflict-resolver.ts
|
|
92193
92349
|
init_dist2();
|
|
@@ -92600,6 +92756,34 @@ async function executeDeleteAction(action, options2) {
|
|
|
92600
92756
|
};
|
|
92601
92757
|
}
|
|
92602
92758
|
}
|
|
92759
|
+
async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
92760
|
+
if (!skillSourcePath)
|
|
92761
|
+
return;
|
|
92762
|
+
const sourceMetadataPath = join112(resolve24(skillSourcePath, ".."), "metadata.json");
|
|
92763
|
+
if (!existsSync56(sourceMetadataPath))
|
|
92764
|
+
return;
|
|
92765
|
+
let sourceMetadata;
|
|
92766
|
+
try {
|
|
92767
|
+
const content = await readFile51(sourceMetadataPath, "utf-8");
|
|
92768
|
+
sourceMetadata = JSON.parse(content);
|
|
92769
|
+
} catch (error) {
|
|
92770
|
+
logger.debug(`[migrate] Failed to parse source metadata.json: ${error}`);
|
|
92771
|
+
return;
|
|
92772
|
+
}
|
|
92773
|
+
if (!sourceMetadata.deletions || sourceMetadata.deletions.length === 0)
|
|
92774
|
+
return;
|
|
92775
|
+
const claudeDir2 = installGlobally ? join112(homedir29(), ".claude") : join112(process.cwd(), ".claude");
|
|
92776
|
+
if (!existsSync56(claudeDir2))
|
|
92777
|
+
return;
|
|
92778
|
+
try {
|
|
92779
|
+
const result = await handleDeletions(sourceMetadata, claudeDir2);
|
|
92780
|
+
if (result.deletedPaths.length > 0) {
|
|
92781
|
+
logger.verbose(`[migrate] Cleaned up ${result.deletedPaths.length} deprecated path(s): ${result.deletedPaths.join(", ")}`);
|
|
92782
|
+
}
|
|
92783
|
+
} catch (error) {
|
|
92784
|
+
logger.warning(`[migrate] Deletion cleanup failed: ${error}`);
|
|
92785
|
+
}
|
|
92786
|
+
}
|
|
92603
92787
|
async function migrateCommand(options2) {
|
|
92604
92788
|
console.log();
|
|
92605
92789
|
oe(import_picocolors25.default.bgMagenta(import_picocolors25.default.black(" ck migrate ")));
|
|
@@ -92611,11 +92795,12 @@ async function migrateCommand(options2) {
|
|
|
92611
92795
|
const commandSource = scope.commands ? getCommandSourcePath() : null;
|
|
92612
92796
|
const skillSource = scope.skills ? getSkillSourcePath() : null;
|
|
92613
92797
|
const hooksSource = scope.hooks ? getHooksSourcePath() : null;
|
|
92798
|
+
const rulesSourcePath = scope.rules ? getRulesSourcePath() : null;
|
|
92614
92799
|
const agents2 = agentSource ? await discoverAgents(agentSource) : [];
|
|
92615
92800
|
const commands = commandSource ? await discoverCommands(commandSource) : [];
|
|
92616
92801
|
const skills = skillSource ? await discoverSkills(skillSource) : [];
|
|
92617
92802
|
const configItem = scope.config ? await discoverConfig(options2.source) : null;
|
|
92618
|
-
const ruleItems =
|
|
92803
|
+
const ruleItems = rulesSourcePath ? await discoverRules(rulesSourcePath) : [];
|
|
92619
92804
|
const { items: hookItems, skippedShellHooks } = hooksSource ? await discoverHooks(hooksSource) : { items: [], skippedShellHooks: [] };
|
|
92620
92805
|
if (skippedShellHooks.length > 0) {
|
|
92621
92806
|
logger.warning(`[migrate] Skipping ${skippedShellHooks.length} shell hook(s) not supported for migration (node-runnable only): ${skippedShellHooks.join(", ")}`);
|
|
@@ -92624,23 +92809,36 @@ async function migrateCommand(options2) {
|
|
|
92624
92809
|
const hasItems = agents2.length > 0 || commands.length > 0 || skills.length > 0 || configItem !== null || ruleItems.length > 0 || hookItems.length > 0;
|
|
92625
92810
|
if (!hasItems) {
|
|
92626
92811
|
f2.error("Nothing to migrate.");
|
|
92627
|
-
f2.info(import_picocolors25.default.dim("Check
|
|
92812
|
+
f2.info(import_picocolors25.default.dim("Check .claude/agents/, .claude/commands/, .claude/skills/, .claude/rules/, .claude/hooks/, and CLAUDE.md (project or ~/.claude/)"));
|
|
92628
92813
|
$e(import_picocolors25.default.red("Nothing to migrate"));
|
|
92629
92814
|
return;
|
|
92630
92815
|
}
|
|
92816
|
+
f2.info(import_picocolors25.default.dim(` CWD: ${process.cwd()}`));
|
|
92631
92817
|
const parts = [];
|
|
92632
|
-
if (agents2.length > 0)
|
|
92633
|
-
|
|
92634
|
-
|
|
92635
|
-
|
|
92636
|
-
if (
|
|
92637
|
-
|
|
92638
|
-
|
|
92639
|
-
|
|
92640
|
-
if (
|
|
92641
|
-
|
|
92642
|
-
|
|
92643
|
-
|
|
92818
|
+
if (agents2.length > 0) {
|
|
92819
|
+
const origin = resolveSourceOrigin(agentSource);
|
|
92820
|
+
parts.push(`${agents2.length} agent(s) ${import_picocolors25.default.dim(`<- ${origin}`)}`);
|
|
92821
|
+
}
|
|
92822
|
+
if (commands.length > 0) {
|
|
92823
|
+
const origin = resolveSourceOrigin(commandSource);
|
|
92824
|
+
parts.push(`${commands.length} command(s) ${import_picocolors25.default.dim(`<- ${origin}`)}`);
|
|
92825
|
+
}
|
|
92826
|
+
if (skills.length > 0) {
|
|
92827
|
+
const origin = resolveSourceOrigin(skillSource);
|
|
92828
|
+
parts.push(`${skills.length} skill(s) ${import_picocolors25.default.dim(`<- ${origin}`)}`);
|
|
92829
|
+
}
|
|
92830
|
+
if (configItem) {
|
|
92831
|
+
const origin = resolveSourceOrigin(configItem.sourcePath);
|
|
92832
|
+
parts.push(`config ${import_picocolors25.default.dim(`<- ${origin}`)}`);
|
|
92833
|
+
}
|
|
92834
|
+
if (ruleItems.length > 0) {
|
|
92835
|
+
const origin = resolveSourceOrigin(rulesSourcePath);
|
|
92836
|
+
parts.push(`${ruleItems.length} rule(s) ${import_picocolors25.default.dim(`<- ${origin}`)}`);
|
|
92837
|
+
}
|
|
92838
|
+
if (hookItems.length > 0) {
|
|
92839
|
+
const origin = resolveSourceOrigin(hooksSource);
|
|
92840
|
+
parts.push(`${hookItems.length} hook(s) ${import_picocolors25.default.dim(`<- ${origin}`)}`);
|
|
92841
|
+
}
|
|
92644
92842
|
f2.info(`Found: ${parts.join(", ")}`);
|
|
92645
92843
|
const detectedProviders = await detectInstalledProviders();
|
|
92646
92844
|
let selectedProviders;
|
|
@@ -92722,18 +92920,20 @@ async function migrateCommand(options2) {
|
|
|
92722
92920
|
selectedProviders = Array.from(new Set(selectedProviders));
|
|
92723
92921
|
let installGlobally = options2.global ?? false;
|
|
92724
92922
|
if (options2.global === undefined && !options2.yes) {
|
|
92923
|
+
const projectTarget = join112(process.cwd(), ".claude");
|
|
92924
|
+
const globalTarget = join112(homedir29(), ".claude");
|
|
92725
92925
|
const scopeChoice = await ie({
|
|
92726
92926
|
message: "Installation scope",
|
|
92727
92927
|
options: [
|
|
92728
92928
|
{
|
|
92729
92929
|
value: false,
|
|
92730
92930
|
label: "Project",
|
|
92731
|
-
hint:
|
|
92931
|
+
hint: `-> ${projectTarget}`
|
|
92732
92932
|
},
|
|
92733
92933
|
{
|
|
92734
92934
|
value: true,
|
|
92735
92935
|
label: "Global",
|
|
92736
|
-
hint:
|
|
92936
|
+
hint: `-> ${globalTarget}`
|
|
92737
92937
|
}
|
|
92738
92938
|
]
|
|
92739
92939
|
});
|
|
@@ -92773,7 +92973,8 @@ async function migrateCommand(options2) {
|
|
|
92773
92973
|
}
|
|
92774
92974
|
const providerNames = selectedProviders.map((prov) => import_picocolors25.default.cyan(providers[prov].displayName)).join(", ");
|
|
92775
92975
|
f2.message(` Providers: ${providerNames}`);
|
|
92776
|
-
|
|
92976
|
+
const targetDir = installGlobally ? join112(homedir29(), ".claude") : join112(process.cwd(), ".claude");
|
|
92977
|
+
f2.message(` Scope: ${installGlobally ? "Global" : "Project"} ${import_picocolors25.default.dim(`-> ${targetDir}`)}`);
|
|
92777
92978
|
const cmdProviders = getProvidersSupporting("commands");
|
|
92778
92979
|
const unsupportedCmd = selectedProviders.filter((pv) => !cmdProviders.includes(pv));
|
|
92779
92980
|
if (commands.length > 0 && unsupportedCmd.length > 0) {
|
|
@@ -92942,12 +93143,28 @@ async function migrateCommand(options2) {
|
|
|
92942
93143
|
allResults.push(...await installSkillDirectories(skills, skillProviders, installOpts));
|
|
92943
93144
|
}
|
|
92944
93145
|
}
|
|
93146
|
+
await processMetadataDeletions(skillSource, installGlobally);
|
|
92945
93147
|
const writtenPaths = new Set(allResults.filter((result) => result.success && !result.skipped && result.path.length > 0).map((result) => resolve24(result.path)));
|
|
92946
93148
|
for (const deleteAction of plannedDeleteActions) {
|
|
92947
93149
|
allResults.push(await executeDeleteAction(deleteAction, {
|
|
92948
93150
|
preservePaths: writtenPaths
|
|
92949
93151
|
}));
|
|
92950
93152
|
}
|
|
93153
|
+
const skipActionsToPopulate = plan.actions.filter((a3) => a3.action === "skip" && a3.sourceChecksum && !isUnknownChecksum(a3.sourceChecksum) && a3.targetPath);
|
|
93154
|
+
for (const action of skipActionsToPopulate) {
|
|
93155
|
+
const registryEntry = registry.installations.find((i) => i.item === action.item && i.type === action.type && i.provider === action.provider && i.global === action.global);
|
|
93156
|
+
if (registryEntry && isUnknownChecksum(registryEntry.sourceChecksum)) {
|
|
93157
|
+
try {
|
|
93158
|
+
await addPortableInstallation(action.item, action.type, action.provider, action.global, action.targetPath, registryEntry.sourcePath, {
|
|
93159
|
+
sourceChecksum: action.sourceChecksum,
|
|
93160
|
+
targetChecksum: action.currentTargetChecksum,
|
|
93161
|
+
installSource: registryEntry.installSource === "manual" ? "manual" : "kit"
|
|
93162
|
+
});
|
|
93163
|
+
} catch {
|
|
93164
|
+
logger.debug(`Failed to populate checksums for ${action.item} — will retry on next run`);
|
|
93165
|
+
}
|
|
93166
|
+
}
|
|
93167
|
+
}
|
|
92951
93168
|
installSpinner.stop("Migrate complete");
|
|
92952
93169
|
displayMigrationSummary(plan, allResults, { color: useColor });
|
|
92953
93170
|
const failed = allResults.filter((r2) => !r2.success);
|
|
@@ -93260,7 +93477,7 @@ async function handleDirectorySetup(ctx) {
|
|
|
93260
93477
|
// src/commands/new/phases/project-creation.ts
|
|
93261
93478
|
init_config_manager();
|
|
93262
93479
|
init_github_client();
|
|
93263
|
-
import { join as
|
|
93480
|
+
import { join as join113 } from "node:path";
|
|
93264
93481
|
init_logger();
|
|
93265
93482
|
init_output_manager();
|
|
93266
93483
|
init_types3();
|
|
@@ -93386,7 +93603,7 @@ async function projectCreation(kit, resolvedDir, validOptions, isNonInteractive2
|
|
|
93386
93603
|
output.section("Installing");
|
|
93387
93604
|
logger.verbose("Installation target", { directory: resolvedDir });
|
|
93388
93605
|
const merger = new FileMerger;
|
|
93389
|
-
const claudeDir2 =
|
|
93606
|
+
const claudeDir2 = join113(resolvedDir, ".claude");
|
|
93390
93607
|
merger.setMultiKitContext(claudeDir2, kit);
|
|
93391
93608
|
if (validOptions.exclude && validOptions.exclude.length > 0) {
|
|
93392
93609
|
merger.addIgnorePatterns(validOptions.exclude);
|
|
@@ -93433,7 +93650,7 @@ async function handleProjectCreation(ctx) {
|
|
|
93433
93650
|
}
|
|
93434
93651
|
// src/commands/new/phases/post-setup.ts
|
|
93435
93652
|
init_projects_registry();
|
|
93436
|
-
import { join as
|
|
93653
|
+
import { join as join114 } from "node:path";
|
|
93437
93654
|
init_package_installer();
|
|
93438
93655
|
init_logger();
|
|
93439
93656
|
init_path_resolver();
|
|
@@ -93465,9 +93682,9 @@ async function postSetup(resolvedDir, validOptions, isNonInteractive2, prompts)
|
|
|
93465
93682
|
withSudo: validOptions.withSudo
|
|
93466
93683
|
});
|
|
93467
93684
|
}
|
|
93468
|
-
const claudeDir2 =
|
|
93685
|
+
const claudeDir2 = join114(resolvedDir, ".claude");
|
|
93469
93686
|
await promptSetupWizardIfNeeded({
|
|
93470
|
-
envPath:
|
|
93687
|
+
envPath: join114(claudeDir2, ".env"),
|
|
93471
93688
|
claudeDir: claudeDir2,
|
|
93472
93689
|
isGlobal: false,
|
|
93473
93690
|
isNonInteractive: isNonInteractive2,
|
|
@@ -93537,7 +93754,7 @@ Please use only one download method.`);
|
|
|
93537
93754
|
// src/commands/plan/plan-command.ts
|
|
93538
93755
|
init_output_manager();
|
|
93539
93756
|
import { existsSync as existsSync58, statSync as statSync8 } from "node:fs";
|
|
93540
|
-
import { dirname as dirname30, join as
|
|
93757
|
+
import { dirname as dirname30, join as join116, parse as parse6, resolve as resolve28 } from "node:path";
|
|
93541
93758
|
|
|
93542
93759
|
// src/commands/plan/plan-read-handlers.ts
|
|
93543
93760
|
init_plan_parser();
|
|
@@ -93545,7 +93762,7 @@ init_logger();
|
|
|
93545
93762
|
init_output_manager();
|
|
93546
93763
|
var import_picocolors27 = __toESM(require_picocolors(), 1);
|
|
93547
93764
|
import { existsSync as existsSync57, statSync as statSync7 } from "node:fs";
|
|
93548
|
-
import { basename as basename17, dirname as dirname29, join as
|
|
93765
|
+
import { basename as basename17, dirname as dirname29, join as join115, relative as relative21, resolve as resolve26 } from "node:path";
|
|
93549
93766
|
async function handleParse(target, options2) {
|
|
93550
93767
|
const planFile = resolvePlanFile(target);
|
|
93551
93768
|
if (!planFile) {
|
|
@@ -93621,7 +93838,7 @@ async function handleValidate(target, options2) {
|
|
|
93621
93838
|
}
|
|
93622
93839
|
async function handleStatus(target, options2) {
|
|
93623
93840
|
const t = target ? resolve26(target) : null;
|
|
93624
|
-
const plansDir = t && existsSync57(t) && statSync7(t).isDirectory() && !existsSync57(
|
|
93841
|
+
const plansDir = t && existsSync57(t) && statSync7(t).isDirectory() && !existsSync57(join115(t, "plan.md")) ? t : null;
|
|
93625
93842
|
if (plansDir) {
|
|
93626
93843
|
const planFiles = scanPlanDir(plansDir);
|
|
93627
93844
|
if (planFiles.length === 0) {
|
|
@@ -93893,7 +94110,7 @@ function resolvePlanFile(target) {
|
|
|
93893
94110
|
const stat18 = statSync8(t);
|
|
93894
94111
|
if (stat18.isFile())
|
|
93895
94112
|
return t;
|
|
93896
|
-
const candidate =
|
|
94113
|
+
const candidate = join116(t, "plan.md");
|
|
93897
94114
|
if (existsSync58(candidate))
|
|
93898
94115
|
return candidate;
|
|
93899
94116
|
}
|
|
@@ -93901,7 +94118,7 @@ function resolvePlanFile(target) {
|
|
|
93901
94118
|
let dir = process.cwd();
|
|
93902
94119
|
const root = parse6(dir).root;
|
|
93903
94120
|
while (dir !== root) {
|
|
93904
|
-
const candidate =
|
|
94121
|
+
const candidate = join116(dir, "plan.md");
|
|
93905
94122
|
if (existsSync58(candidate))
|
|
93906
94123
|
return candidate;
|
|
93907
94124
|
dir = dirname30(dir);
|
|
@@ -94928,7 +95145,7 @@ async function detectInstallations() {
|
|
|
94928
95145
|
|
|
94929
95146
|
// src/commands/uninstall/removal-handler.ts
|
|
94930
95147
|
import { readdirSync as readdirSync7, rmSync as rmSync6 } from "node:fs";
|
|
94931
|
-
import { join as
|
|
95148
|
+
import { join as join118, resolve as resolve30, sep as sep7 } from "node:path";
|
|
94932
95149
|
init_logger();
|
|
94933
95150
|
init_safe_prompts();
|
|
94934
95151
|
init_safe_spinner();
|
|
@@ -94937,7 +95154,7 @@ var import_fs_extra37 = __toESM(require_lib3(), 1);
|
|
|
94937
95154
|
// src/commands/uninstall/analysis-handler.ts
|
|
94938
95155
|
init_metadata_migration();
|
|
94939
95156
|
import { readdirSync as readdirSync6, rmSync as rmSync5 } from "node:fs";
|
|
94940
|
-
import { dirname as dirname31, join as
|
|
95157
|
+
import { dirname as dirname31, join as join117 } from "node:path";
|
|
94941
95158
|
init_logger();
|
|
94942
95159
|
init_safe_prompts();
|
|
94943
95160
|
var import_picocolors33 = __toESM(require_picocolors(), 1);
|
|
@@ -94985,7 +95202,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
94985
95202
|
if (uninstallManifest.isMultiKit && kit && metadata?.kits?.[kit]) {
|
|
94986
95203
|
const kitFiles = metadata.kits[kit].files || [];
|
|
94987
95204
|
for (const trackedFile of kitFiles) {
|
|
94988
|
-
const filePath =
|
|
95205
|
+
const filePath = join117(installation.path, trackedFile.path);
|
|
94989
95206
|
if (uninstallManifest.filesToPreserve.includes(trackedFile.path)) {
|
|
94990
95207
|
result.toPreserve.push({ path: trackedFile.path, reason: "shared with other kit" });
|
|
94991
95208
|
continue;
|
|
@@ -95015,7 +95232,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
95015
95232
|
return result;
|
|
95016
95233
|
}
|
|
95017
95234
|
for (const trackedFile of allTrackedFiles) {
|
|
95018
|
-
const filePath =
|
|
95235
|
+
const filePath = join117(installation.path, trackedFile.path);
|
|
95019
95236
|
const ownershipResult = await OwnershipChecker.checkOwnership(filePath, metadata, installation.path);
|
|
95020
95237
|
if (!ownershipResult.exists)
|
|
95021
95238
|
continue;
|
|
@@ -95071,7 +95288,7 @@ async function isPathSafeToRemove(filePath, baseDir) {
|
|
|
95071
95288
|
try {
|
|
95072
95289
|
const resolvedPath = resolve30(filePath);
|
|
95073
95290
|
const resolvedBase = resolve30(baseDir);
|
|
95074
|
-
if (!resolvedPath.startsWith(resolvedBase +
|
|
95291
|
+
if (!resolvedPath.startsWith(resolvedBase + sep7) && resolvedPath !== resolvedBase) {
|
|
95075
95292
|
logger.debug(`Path outside installation directory: ${filePath}`);
|
|
95076
95293
|
return false;
|
|
95077
95294
|
}
|
|
@@ -95079,7 +95296,7 @@ async function isPathSafeToRemove(filePath, baseDir) {
|
|
|
95079
95296
|
if (stats.isSymbolicLink()) {
|
|
95080
95297
|
const realPath = await import_fs_extra37.realpath(filePath);
|
|
95081
95298
|
const resolvedReal = resolve30(realPath);
|
|
95082
|
-
if (!resolvedReal.startsWith(resolvedBase +
|
|
95299
|
+
if (!resolvedReal.startsWith(resolvedBase + sep7) && resolvedReal !== resolvedBase) {
|
|
95083
95300
|
logger.debug(`Symlink points outside installation directory: ${filePath} -> ${realPath}`);
|
|
95084
95301
|
return false;
|
|
95085
95302
|
}
|
|
@@ -95112,7 +95329,7 @@ async function removeInstallations(installations, options2) {
|
|
|
95112
95329
|
let removedCount = 0;
|
|
95113
95330
|
let cleanedDirs = 0;
|
|
95114
95331
|
for (const item of analysis.toDelete) {
|
|
95115
|
-
const filePath =
|
|
95332
|
+
const filePath = join118(installation.path, item.path);
|
|
95116
95333
|
if (!await import_fs_extra37.pathExists(filePath))
|
|
95117
95334
|
continue;
|
|
95118
95335
|
if (!await isPathSafeToRemove(filePath, installation.path)) {
|
|
@@ -95508,7 +95725,7 @@ init_logger();
|
|
|
95508
95725
|
init_path_resolver();
|
|
95509
95726
|
init_types3();
|
|
95510
95727
|
import { existsSync as existsSync60, readFileSync as readFileSync13 } from "node:fs";
|
|
95511
|
-
import { join as
|
|
95728
|
+
import { join as join119 } from "node:path";
|
|
95512
95729
|
var packageVersion = package_default.version;
|
|
95513
95730
|
function formatInstalledKits(metadata) {
|
|
95514
95731
|
if (!metadata.kits || Object.keys(metadata.kits).length === 0) {
|
|
@@ -95540,9 +95757,9 @@ async function displayVersion() {
|
|
|
95540
95757
|
let localKitVersion = null;
|
|
95541
95758
|
let isGlobalOnlyKit = false;
|
|
95542
95759
|
const globalKitDir = PathResolver.getGlobalKitDir();
|
|
95543
|
-
const globalMetadataPath =
|
|
95760
|
+
const globalMetadataPath = join119(globalKitDir, "metadata.json");
|
|
95544
95761
|
const prefix = PathResolver.getPathPrefix(false);
|
|
95545
|
-
const localMetadataPath = prefix ?
|
|
95762
|
+
const localMetadataPath = prefix ? join119(process.cwd(), prefix, "metadata.json") : join119(process.cwd(), "metadata.json");
|
|
95546
95763
|
const isLocalSameAsGlobal = localMetadataPath === globalMetadataPath;
|
|
95547
95764
|
if (!isLocalSameAsGlobal && existsSync60(localMetadataPath)) {
|
|
95548
95765
|
try {
|