claudekit-cli 3.38.0-dev.3 → 3.38.0-dev.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +506 -429
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -42046,6 +42046,7 @@ var init_commands = __esm(() => {
|
|
|
42046
42046
|
only: exports_external.array(ExcludePatternSchema).optional().default([]),
|
|
42047
42047
|
global: exports_external.boolean().default(false),
|
|
42048
42048
|
fresh: exports_external.boolean().default(false),
|
|
42049
|
+
force: exports_external.boolean().default(false),
|
|
42049
42050
|
installSkills: exports_external.boolean().default(false),
|
|
42050
42051
|
withSudo: exports_external.boolean().default(false),
|
|
42051
42052
|
prefix: exports_external.boolean().default(false),
|
|
@@ -55546,8 +55547,8 @@ var init_agents = __esm(() => {
|
|
|
55546
55547
|
"gemini-cli": {
|
|
55547
55548
|
name: "gemini-cli",
|
|
55548
55549
|
displayName: "Gemini CLI",
|
|
55549
|
-
projectPath: ".
|
|
55550
|
-
globalPath: join39(home6, ".
|
|
55550
|
+
projectPath: ".agents/skills",
|
|
55551
|
+
globalPath: join39(home6, ".agents/skills"),
|
|
55551
55552
|
detect: async () => existsSync32(join39(home6, ".gemini"))
|
|
55552
55553
|
},
|
|
55553
55554
|
antigravity: {
|
|
@@ -55613,7 +55614,7 @@ var init_agents = __esm(() => {
|
|
|
55613
55614
|
import { existsSync as existsSync33 } from "node:fs";
|
|
55614
55615
|
import { mkdir as mkdir9, readFile as readFile22, writeFile as writeFile11 } from "node:fs/promises";
|
|
55615
55616
|
import { homedir as homedir26 } from "node:os";
|
|
55616
|
-
import { dirname as dirname16, join as join40 } from "node:path";
|
|
55617
|
+
import { dirname as dirname16, join as join40, sep as sep5 } from "node:path";
|
|
55617
55618
|
function getCliVersion3() {
|
|
55618
55619
|
try {
|
|
55619
55620
|
if (process.env.npm_package_version) {
|
|
@@ -55630,6 +55631,19 @@ function getCliVersion3() {
|
|
|
55630
55631
|
return "unknown";
|
|
55631
55632
|
}
|
|
55632
55633
|
}
|
|
55634
|
+
function migrateRegistryPaths(registry) {
|
|
55635
|
+
let changed = false;
|
|
55636
|
+
for (const entry of registry.installations) {
|
|
55637
|
+
for (const migration of REGISTRY_PATH_MIGRATIONS) {
|
|
55638
|
+
if (entry.agent === migration.agent && entry.path.includes(migration.oldSegment)) {
|
|
55639
|
+
entry.path = entry.path.replace(migration.oldSegment, migration.newSegment);
|
|
55640
|
+
changed = true;
|
|
55641
|
+
break;
|
|
55642
|
+
}
|
|
55643
|
+
}
|
|
55644
|
+
}
|
|
55645
|
+
return changed;
|
|
55646
|
+
}
|
|
55633
55647
|
async function readRegistry() {
|
|
55634
55648
|
try {
|
|
55635
55649
|
if (!existsSync33(REGISTRY_PATH2)) {
|
|
@@ -55637,7 +55651,13 @@ async function readRegistry() {
|
|
|
55637
55651
|
}
|
|
55638
55652
|
const content = await readFile22(REGISTRY_PATH2, "utf-8");
|
|
55639
55653
|
const data = JSON.parse(content);
|
|
55640
|
-
|
|
55654
|
+
const registry = SkillRegistrySchema.parse(data);
|
|
55655
|
+
if (migrateRegistryPaths(registry)) {
|
|
55656
|
+
try {
|
|
55657
|
+
await writeFile11(REGISTRY_PATH2, JSON.stringify(registry, null, 2), "utf-8");
|
|
55658
|
+
} catch {}
|
|
55659
|
+
}
|
|
55660
|
+
return registry;
|
|
55641
55661
|
} catch (error) {
|
|
55642
55662
|
const { logger: logger2 } = (init_logger(), __toCommonJS(exports_logger));
|
|
55643
55663
|
const errorMsg = error instanceof Error ? error.message : "Unknown error";
|
|
@@ -55702,7 +55722,7 @@ async function syncRegistry() {
|
|
|
55702
55722
|
}
|
|
55703
55723
|
return { removed };
|
|
55704
55724
|
}
|
|
55705
|
-
var home7, REGISTRY_PATH2, SkillInstallationSchema, SkillRegistrySchema;
|
|
55725
|
+
var home7, REGISTRY_PATH2, SkillInstallationSchema, SkillRegistrySchema, REGISTRY_PATH_MIGRATIONS;
|
|
55706
55726
|
var init_skills_registry = __esm(() => {
|
|
55707
55727
|
init_zod();
|
|
55708
55728
|
home7 = homedir26();
|
|
@@ -55720,12 +55740,25 @@ var init_skills_registry = __esm(() => {
|
|
|
55720
55740
|
version: exports_external.literal("1.0"),
|
|
55721
55741
|
installations: exports_external.array(SkillInstallationSchema)
|
|
55722
55742
|
});
|
|
55743
|
+
REGISTRY_PATH_MIGRATIONS = [
|
|
55744
|
+
{
|
|
55745
|
+
agent: "gemini-cli",
|
|
55746
|
+
oldSegment: `${sep5}.gemini${sep5}skills${sep5}`,
|
|
55747
|
+
newSegment: `${sep5}.agents${sep5}skills${sep5}`
|
|
55748
|
+
},
|
|
55749
|
+
{
|
|
55750
|
+
agent: "gemini-cli",
|
|
55751
|
+
oldSegment: `${sep5}.gemini${sep5}skills`,
|
|
55752
|
+
newSegment: `${sep5}.agents${sep5}skills`
|
|
55753
|
+
}
|
|
55754
|
+
];
|
|
55723
55755
|
});
|
|
55724
55756
|
|
|
55725
55757
|
// src/commands/skills/skills-installer.ts
|
|
55726
55758
|
import { existsSync as existsSync34 } from "node:fs";
|
|
55727
|
-
import { cp as cp2, mkdir as mkdir10, stat as stat7 } from "node:fs/promises";
|
|
55728
|
-
import {
|
|
55759
|
+
import { cp as cp2, mkdir as mkdir10, rm as rm7, stat as stat7 } from "node:fs/promises";
|
|
55760
|
+
import { homedir as homedir27 } from "node:os";
|
|
55761
|
+
import { dirname as dirname17, join as join41, resolve as resolve12 } from "node:path";
|
|
55729
55762
|
function isSamePath2(path1, path22) {
|
|
55730
55763
|
try {
|
|
55731
55764
|
return resolve12(path1) === resolve12(path22);
|
|
@@ -55752,6 +55785,30 @@ function getErrorMessage2(error, targetPath) {
|
|
|
55752
55785
|
}
|
|
55753
55786
|
return error instanceof Error ? error.message : "Unknown error";
|
|
55754
55787
|
}
|
|
55788
|
+
async function cleanupLegacySkillPath(skillName, agent, global3) {
|
|
55789
|
+
const legacy = LEGACY_SKILL_PATHS[agent];
|
|
55790
|
+
if (!legacy)
|
|
55791
|
+
return;
|
|
55792
|
+
const legacyBase = global3 ? legacy.global : legacy.project;
|
|
55793
|
+
const legacyPath = join41(legacyBase, skillName);
|
|
55794
|
+
if (!existsSync34(legacyPath))
|
|
55795
|
+
return;
|
|
55796
|
+
await rm7(legacyPath, { recursive: true, force: true });
|
|
55797
|
+
const registry = await readRegistry();
|
|
55798
|
+
let changed = false;
|
|
55799
|
+
for (const entry of registry.installations) {
|
|
55800
|
+
if (entry.skill === skillName && entry.agent === agent && entry.global === global3) {
|
|
55801
|
+
if (entry.path === legacyPath) {
|
|
55802
|
+
const newBase = global3 ? agents[agent].globalPath : agents[agent].projectPath;
|
|
55803
|
+
entry.path = join41(newBase, skillName);
|
|
55804
|
+
changed = true;
|
|
55805
|
+
}
|
|
55806
|
+
}
|
|
55807
|
+
}
|
|
55808
|
+
if (changed) {
|
|
55809
|
+
await writeRegistry(registry);
|
|
55810
|
+
}
|
|
55811
|
+
}
|
|
55755
55812
|
async function installSkillForAgent(skill, agent, options2) {
|
|
55756
55813
|
const agentConfig = agents[agent];
|
|
55757
55814
|
const targetPath = getInstallPath(skill.name, agent, options2);
|
|
@@ -55767,6 +55824,9 @@ async function installSkillForAgent(skill, agent, options2) {
|
|
|
55767
55824
|
};
|
|
55768
55825
|
}
|
|
55769
55826
|
try {
|
|
55827
|
+
try {
|
|
55828
|
+
await cleanupLegacySkillPath(skill.name, agent, options2.global);
|
|
55829
|
+
} catch {}
|
|
55770
55830
|
const parentDir = dirname17(targetPath);
|
|
55771
55831
|
if (!existsSync34(parentDir)) {
|
|
55772
55832
|
await mkdir10(parentDir, { recursive: true });
|
|
@@ -55821,15 +55881,22 @@ function getInstallPreview(skill, targetAgents, options2) {
|
|
|
55821
55881
|
};
|
|
55822
55882
|
});
|
|
55823
55883
|
}
|
|
55884
|
+
var LEGACY_SKILL_PATHS;
|
|
55824
55885
|
var init_skills_installer = __esm(() => {
|
|
55825
55886
|
init_agents();
|
|
55826
55887
|
init_skills_registry();
|
|
55888
|
+
LEGACY_SKILL_PATHS = {
|
|
55889
|
+
"gemini-cli": {
|
|
55890
|
+
project: ".gemini/skills",
|
|
55891
|
+
global: join41(homedir27(), ".gemini/skills")
|
|
55892
|
+
}
|
|
55893
|
+
};
|
|
55827
55894
|
});
|
|
55828
55895
|
|
|
55829
55896
|
// src/commands/skills/skills-uninstaller.ts
|
|
55830
55897
|
import { existsSync as existsSync35 } from "node:fs";
|
|
55831
|
-
import { rm as
|
|
55832
|
-
import { join as
|
|
55898
|
+
import { rm as rm8 } from "node:fs/promises";
|
|
55899
|
+
import { join as join42 } from "node:path";
|
|
55833
55900
|
async function uninstallSkillFromAgent(skill, agent, global3) {
|
|
55834
55901
|
const agentConfig = agents[agent];
|
|
55835
55902
|
const registry = await readRegistry();
|
|
@@ -55850,7 +55917,7 @@ async function uninstallSkillFromAgent(skill, agent, global3) {
|
|
|
55850
55917
|
const fileExists = existsSync35(path4);
|
|
55851
55918
|
try {
|
|
55852
55919
|
if (fileExists) {
|
|
55853
|
-
await
|
|
55920
|
+
await rm8(path4, { recursive: true, force: true });
|
|
55854
55921
|
}
|
|
55855
55922
|
await removeInstallation(skill, agent, global3);
|
|
55856
55923
|
return {
|
|
@@ -55877,7 +55944,7 @@ async function uninstallSkillFromAgent(skill, agent, global3) {
|
|
|
55877
55944
|
async function forceUninstallSkill(skill, agent, global3) {
|
|
55878
55945
|
const agentConfig = agents[agent];
|
|
55879
55946
|
const basePath = global3 ? agentConfig.globalPath : agentConfig.projectPath;
|
|
55880
|
-
const path4 =
|
|
55947
|
+
const path4 = join42(basePath, skill);
|
|
55881
55948
|
if (!existsSync35(path4)) {
|
|
55882
55949
|
return {
|
|
55883
55950
|
skill,
|
|
@@ -55890,7 +55957,7 @@ async function forceUninstallSkill(skill, agent, global3) {
|
|
|
55890
55957
|
};
|
|
55891
55958
|
}
|
|
55892
55959
|
try {
|
|
55893
|
-
await
|
|
55960
|
+
await rm8(path4, { recursive: true, force: true });
|
|
55894
55961
|
await removeInstallation(skill, agent, global3);
|
|
55895
55962
|
return {
|
|
55896
55963
|
skill,
|
|
@@ -56421,7 +56488,7 @@ var init_pnpm_detector = __esm(() => {
|
|
|
56421
56488
|
import { existsSync as existsSync36, realpathSync as realpathSync2 } from "node:fs";
|
|
56422
56489
|
import { chmod as chmod2, mkdir as mkdir11, readFile as readFile23, writeFile as writeFile12 } from "node:fs/promises";
|
|
56423
56490
|
import { platform as platform4 } from "node:os";
|
|
56424
|
-
import { join as
|
|
56491
|
+
import { join as join43 } from "node:path";
|
|
56425
56492
|
function detectFromBinaryPath() {
|
|
56426
56493
|
const normalizePath2 = (pathValue) => pathValue.replace(/\\/g, "/").toLowerCase();
|
|
56427
56494
|
const detectFromNormalizedPath = (normalized) => {
|
|
@@ -56498,7 +56565,7 @@ function detectFromEnv() {
|
|
|
56498
56565
|
}
|
|
56499
56566
|
async function readCachedPm() {
|
|
56500
56567
|
try {
|
|
56501
|
-
const cacheFile =
|
|
56568
|
+
const cacheFile = join43(PathResolver.getConfigDir(false), CACHE_FILE);
|
|
56502
56569
|
if (!existsSync36(cacheFile)) {
|
|
56503
56570
|
return null;
|
|
56504
56571
|
}
|
|
@@ -56529,7 +56596,7 @@ async function saveCachedPm(pm, getVersion) {
|
|
|
56529
56596
|
return;
|
|
56530
56597
|
try {
|
|
56531
56598
|
const configDir = PathResolver.getConfigDir(false);
|
|
56532
|
-
const cacheFile =
|
|
56599
|
+
const cacheFile = join43(configDir, CACHE_FILE);
|
|
56533
56600
|
if (!existsSync36(configDir)) {
|
|
56534
56601
|
await mkdir11(configDir, { recursive: true });
|
|
56535
56602
|
if (platform4() !== "win32") {
|
|
@@ -56592,7 +56659,7 @@ async function findOwningPm() {
|
|
|
56592
56659
|
async function clearCache() {
|
|
56593
56660
|
try {
|
|
56594
56661
|
const { unlink: unlink6 } = await import("node:fs/promises");
|
|
56595
|
-
const cacheFile =
|
|
56662
|
+
const cacheFile = join43(PathResolver.getConfigDir(false), CACHE_FILE);
|
|
56596
56663
|
if (existsSync36(cacheFile)) {
|
|
56597
56664
|
await unlink6(cacheFile);
|
|
56598
56665
|
logger.debug("Package manager cache cleared");
|
|
@@ -56749,9 +56816,9 @@ var init_package_manager_detector = __esm(() => {
|
|
|
56749
56816
|
});
|
|
56750
56817
|
|
|
56751
56818
|
// src/domains/migration/metadata-migration.ts
|
|
56752
|
-
import { join as
|
|
56819
|
+
import { join as join44 } from "node:path";
|
|
56753
56820
|
async function detectMetadataFormat(claudeDir2) {
|
|
56754
|
-
const metadataPath =
|
|
56821
|
+
const metadataPath = join44(claudeDir2, "metadata.json");
|
|
56755
56822
|
if (!await import_fs_extra3.pathExists(metadataPath)) {
|
|
56756
56823
|
return { format: "none", metadata: null, detectedKit: null };
|
|
56757
56824
|
}
|
|
@@ -56803,7 +56870,7 @@ async function migrateToMultiKit(claudeDir2) {
|
|
|
56803
56870
|
toFormat: "multi-kit"
|
|
56804
56871
|
};
|
|
56805
56872
|
}
|
|
56806
|
-
const metadataPath =
|
|
56873
|
+
const metadataPath = join44(claudeDir2, "metadata.json");
|
|
56807
56874
|
const legacy = detection.metadata;
|
|
56808
56875
|
if (!legacy) {
|
|
56809
56876
|
return {
|
|
@@ -57086,7 +57153,7 @@ var init_version_utils = __esm(() => {
|
|
|
57086
57153
|
});
|
|
57087
57154
|
|
|
57088
57155
|
// src/services/file-operations/claudekit-scanner.ts
|
|
57089
|
-
import { join as
|
|
57156
|
+
import { join as join45 } from "node:path";
|
|
57090
57157
|
async function scanClaudeKitDirectory(directoryPath) {
|
|
57091
57158
|
const counts = {
|
|
57092
57159
|
agents: 0,
|
|
@@ -57100,33 +57167,33 @@ async function scanClaudeKitDirectory(directoryPath) {
|
|
|
57100
57167
|
}
|
|
57101
57168
|
const items = await import_fs_extra4.readdir(directoryPath);
|
|
57102
57169
|
if (items.includes("agents")) {
|
|
57103
|
-
const agentsPath =
|
|
57170
|
+
const agentsPath = join45(directoryPath, "agents");
|
|
57104
57171
|
const agentFiles = await import_fs_extra4.readdir(agentsPath);
|
|
57105
57172
|
counts.agents = agentFiles.filter((file) => file.endsWith(".md")).length;
|
|
57106
57173
|
}
|
|
57107
57174
|
if (items.includes("commands")) {
|
|
57108
|
-
const commandsPath =
|
|
57175
|
+
const commandsPath = join45(directoryPath, "commands");
|
|
57109
57176
|
const commandFiles = await import_fs_extra4.readdir(commandsPath);
|
|
57110
57177
|
counts.commands = commandFiles.filter((file) => file.endsWith(".md")).length;
|
|
57111
57178
|
}
|
|
57112
57179
|
if (items.includes("rules")) {
|
|
57113
|
-
const rulesPath =
|
|
57180
|
+
const rulesPath = join45(directoryPath, "rules");
|
|
57114
57181
|
const ruleFiles = await import_fs_extra4.readdir(rulesPath);
|
|
57115
57182
|
counts.rules = ruleFiles.filter((file) => file.endsWith(".md")).length;
|
|
57116
57183
|
} else if (items.includes("workflows")) {
|
|
57117
|
-
const workflowsPath =
|
|
57184
|
+
const workflowsPath = join45(directoryPath, "workflows");
|
|
57118
57185
|
const workflowFiles = await import_fs_extra4.readdir(workflowsPath);
|
|
57119
57186
|
counts.rules = workflowFiles.filter((file) => file.endsWith(".md")).length;
|
|
57120
57187
|
}
|
|
57121
57188
|
if (items.includes("skills")) {
|
|
57122
|
-
const skillsPath =
|
|
57189
|
+
const skillsPath = join45(directoryPath, "skills");
|
|
57123
57190
|
const skillItems = await import_fs_extra4.readdir(skillsPath);
|
|
57124
57191
|
let skillCount = 0;
|
|
57125
57192
|
for (const item of skillItems) {
|
|
57126
57193
|
if (SKIP_DIRS_CLAUDE_INTERNAL.includes(item)) {
|
|
57127
57194
|
continue;
|
|
57128
57195
|
}
|
|
57129
|
-
const itemPath =
|
|
57196
|
+
const itemPath = join45(skillsPath, item);
|
|
57130
57197
|
const stat8 = await import_fs_extra4.readdir(itemPath).catch(() => null);
|
|
57131
57198
|
if (stat8?.includes("SKILL.md")) {
|
|
57132
57199
|
skillCount++;
|
|
@@ -57168,14 +57235,14 @@ async function getClaudeKitSetup(projectDir = process.cwd()) {
|
|
|
57168
57235
|
const globalDir = getGlobalInstallDir();
|
|
57169
57236
|
if (await import_fs_extra4.pathExists(globalDir)) {
|
|
57170
57237
|
setup.global.path = globalDir;
|
|
57171
|
-
setup.global.metadata = await readClaudeKitMetadata(
|
|
57238
|
+
setup.global.metadata = await readClaudeKitMetadata(join45(globalDir, "metadata.json"));
|
|
57172
57239
|
setup.global.components = await scanClaudeKitDirectory(globalDir);
|
|
57173
57240
|
}
|
|
57174
|
-
const projectClaudeDir =
|
|
57241
|
+
const projectClaudeDir = join45(projectDir, ".claude");
|
|
57175
57242
|
const isLocalSameAsGlobal = projectClaudeDir === globalDir;
|
|
57176
57243
|
if (!isLocalSameAsGlobal && await import_fs_extra4.pathExists(projectClaudeDir)) {
|
|
57177
57244
|
setup.project.path = projectClaudeDir;
|
|
57178
|
-
setup.project.metadata = await readClaudeKitMetadata(
|
|
57245
|
+
setup.project.metadata = await readClaudeKitMetadata(join45(projectClaudeDir, "metadata.json"));
|
|
57179
57246
|
setup.project.components = await scanClaudeKitDirectory(projectClaudeDir);
|
|
57180
57247
|
}
|
|
57181
57248
|
return setup;
|
|
@@ -57192,7 +57259,7 @@ var package_default;
|
|
|
57192
57259
|
var init_package = __esm(() => {
|
|
57193
57260
|
package_default = {
|
|
57194
57261
|
name: "claudekit-cli",
|
|
57195
|
-
version: "3.38.0-dev.
|
|
57262
|
+
version: "3.38.0-dev.5",
|
|
57196
57263
|
description: "CLI tool for bootstrapping and updating ClaudeKit projects",
|
|
57197
57264
|
type: "module",
|
|
57198
57265
|
repository: {
|
|
@@ -57754,7 +57821,7 @@ var init_error_handler2 = __esm(() => {
|
|
|
57754
57821
|
// src/domains/versioning/release-cache.ts
|
|
57755
57822
|
import { existsSync as existsSync37 } from "node:fs";
|
|
57756
57823
|
import { mkdir as mkdir12, readFile as readFile26, unlink as unlink6, writeFile as writeFile14 } from "node:fs/promises";
|
|
57757
|
-
import { join as
|
|
57824
|
+
import { join as join46 } from "node:path";
|
|
57758
57825
|
var ReleaseCacheEntrySchema, ReleaseCache;
|
|
57759
57826
|
var init_release_cache = __esm(() => {
|
|
57760
57827
|
init_logger();
|
|
@@ -57769,7 +57836,7 @@ var init_release_cache = __esm(() => {
|
|
|
57769
57836
|
static CACHE_TTL_SECONDS = Number(process.env.CK_CACHE_TTL) || 3600;
|
|
57770
57837
|
cacheDir;
|
|
57771
57838
|
constructor() {
|
|
57772
|
-
this.cacheDir =
|
|
57839
|
+
this.cacheDir = join46(PathResolver.getCacheDir(false), ReleaseCache.CACHE_DIR);
|
|
57773
57840
|
}
|
|
57774
57841
|
async get(key) {
|
|
57775
57842
|
const cacheFile = this.getCachePath(key);
|
|
@@ -57827,7 +57894,7 @@ var init_release_cache = __esm(() => {
|
|
|
57827
57894
|
const files = await readdir10(this.cacheDir);
|
|
57828
57895
|
for (const file of files) {
|
|
57829
57896
|
if (file.endsWith(".json")) {
|
|
57830
|
-
await unlink6(
|
|
57897
|
+
await unlink6(join46(this.cacheDir, file));
|
|
57831
57898
|
}
|
|
57832
57899
|
}
|
|
57833
57900
|
logger.debug("All release cache cleared");
|
|
@@ -57838,7 +57905,7 @@ var init_release_cache = __esm(() => {
|
|
|
57838
57905
|
}
|
|
57839
57906
|
getCachePath(key) {
|
|
57840
57907
|
const safeKey = key.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
57841
|
-
return
|
|
57908
|
+
return join46(this.cacheDir, `${safeKey}.json`);
|
|
57842
57909
|
}
|
|
57843
57910
|
isExpired(timestamp) {
|
|
57844
57911
|
const now = Date.now();
|
|
@@ -58479,7 +58546,7 @@ var init_github_client = __esm(() => {
|
|
|
58479
58546
|
|
|
58480
58547
|
// src/commands/update-cli.ts
|
|
58481
58548
|
import { exec as exec2 } from "node:child_process";
|
|
58482
|
-
import { join as
|
|
58549
|
+
import { join as join47 } from "node:path";
|
|
58483
58550
|
import { promisify as promisify8 } from "node:util";
|
|
58484
58551
|
function getDefaultUpdateCliCommandDeps() {
|
|
58485
58552
|
return {
|
|
@@ -58556,7 +58623,7 @@ function selectKitForUpdate(params) {
|
|
|
58556
58623
|
};
|
|
58557
58624
|
}
|
|
58558
58625
|
async function readMetadataFile(claudeDir2) {
|
|
58559
|
-
const metadataPath =
|
|
58626
|
+
const metadataPath = join47(claudeDir2, "metadata.json");
|
|
58560
58627
|
try {
|
|
58561
58628
|
if (!await import_fs_extra5.pathExists(metadataPath)) {
|
|
58562
58629
|
return null;
|
|
@@ -58877,7 +58944,7 @@ var init_update_cli = __esm(() => {
|
|
|
58877
58944
|
// src/domains/versioning/version-cache.ts
|
|
58878
58945
|
import { existsSync as existsSync38 } from "node:fs";
|
|
58879
58946
|
import { mkdir as mkdir13, readFile as readFile28, writeFile as writeFile15 } from "node:fs/promises";
|
|
58880
|
-
import { join as
|
|
58947
|
+
import { join as join48 } from "node:path";
|
|
58881
58948
|
var VersionCacheManager;
|
|
58882
58949
|
var init_version_cache = __esm(() => {
|
|
58883
58950
|
init_logger();
|
|
@@ -58887,7 +58954,7 @@ var init_version_cache = __esm(() => {
|
|
|
58887
58954
|
static CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000;
|
|
58888
58955
|
static getCacheFile() {
|
|
58889
58956
|
const cacheDir = PathResolver.getCacheDir(false);
|
|
58890
|
-
return
|
|
58957
|
+
return join48(cacheDir, VersionCacheManager.CACHE_FILENAME);
|
|
58891
58958
|
}
|
|
58892
58959
|
static async load() {
|
|
58893
58960
|
const cacheFile = VersionCacheManager.getCacheFile();
|
|
@@ -59156,7 +59223,7 @@ var init_version_checker = __esm(() => {
|
|
|
59156
59223
|
import { spawn as spawn2 } from "node:child_process";
|
|
59157
59224
|
import { existsSync as existsSync39 } from "node:fs";
|
|
59158
59225
|
import { readFile as readFile29 } from "node:fs/promises";
|
|
59159
|
-
import { join as
|
|
59226
|
+
import { join as join49 } from "node:path";
|
|
59160
59227
|
function hasCliUpdate(currentVersion, latestVersion) {
|
|
59161
59228
|
if (!latestVersion) {
|
|
59162
59229
|
return false;
|
|
@@ -59399,7 +59466,7 @@ async function getPackageJson() {
|
|
|
59399
59466
|
}
|
|
59400
59467
|
async function getKitMetadata2(kitName) {
|
|
59401
59468
|
try {
|
|
59402
|
-
const metadataPath =
|
|
59469
|
+
const metadataPath = join49(PathResolver.getGlobalKitDir(), "metadata.json");
|
|
59403
59470
|
if (!existsSync39(metadataPath))
|
|
59404
59471
|
return null;
|
|
59405
59472
|
const content = await readFile29(metadataPath, "utf-8");
|
|
@@ -59546,7 +59613,7 @@ var init_routes = __esm(() => {
|
|
|
59546
59613
|
|
|
59547
59614
|
// src/domains/web-server/static-server.ts
|
|
59548
59615
|
import { existsSync as existsSync40 } from "node:fs";
|
|
59549
|
-
import { dirname as dirname18, extname as extname4, join as
|
|
59616
|
+
import { dirname as dirname18, extname as extname4, join as join50, resolve as resolve13 } from "node:path";
|
|
59550
59617
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
59551
59618
|
function tryServeFromEmbedded(app) {
|
|
59552
59619
|
if (typeof globalThis.Bun === "undefined" || !globalThis.Bun.embeddedFiles?.length) {
|
|
@@ -59614,22 +59681,22 @@ function addRuntimeUiCandidate(candidates, runtimePath) {
|
|
|
59614
59681
|
return;
|
|
59615
59682
|
}
|
|
59616
59683
|
const entryDir = dirname18(resolve13(runtimePath));
|
|
59617
|
-
candidates.add(
|
|
59618
|
-
candidates.add(
|
|
59684
|
+
candidates.add(join50(entryDir, "ui"));
|
|
59685
|
+
candidates.add(join50(entryDir, "..", "dist", "ui"));
|
|
59619
59686
|
}
|
|
59620
59687
|
function resolveUiDistPath() {
|
|
59621
59688
|
const candidates = new Set;
|
|
59622
59689
|
addRuntimeUiCandidate(candidates, process.execPath);
|
|
59623
59690
|
addRuntimeUiCandidate(candidates, process.argv[1]);
|
|
59624
|
-
candidates.add(
|
|
59625
|
-
candidates.add(
|
|
59626
|
-
candidates.add(
|
|
59691
|
+
candidates.add(join50(__dirname3, "ui"));
|
|
59692
|
+
candidates.add(join50(process.cwd(), "dist", "ui"));
|
|
59693
|
+
candidates.add(join50(process.cwd(), "src", "ui", "dist"));
|
|
59627
59694
|
for (const path4 of candidates) {
|
|
59628
|
-
if (existsSync40(
|
|
59695
|
+
if (existsSync40(join50(path4, "index.html"))) {
|
|
59629
59696
|
return path4;
|
|
59630
59697
|
}
|
|
59631
59698
|
}
|
|
59632
|
-
return Array.from(candidates)[0] ??
|
|
59699
|
+
return Array.from(candidates)[0] ?? join50(process.cwd(), "dist", "ui");
|
|
59633
59700
|
}
|
|
59634
59701
|
function serveStatic(app) {
|
|
59635
59702
|
if (tryServeFromEmbedded(app)) {
|
|
@@ -59668,7 +59735,7 @@ function serveStatic(app) {
|
|
|
59668
59735
|
if (req.path.startsWith("/assets/") || req.path.match(/\.(js|css|ico|png|jpg|svg|woff2?)$/)) {
|
|
59669
59736
|
return next();
|
|
59670
59737
|
}
|
|
59671
|
-
res.sendFile(
|
|
59738
|
+
res.sendFile(join50(uiDistPath, "index.html"), { dotfiles: "allow" });
|
|
59672
59739
|
});
|
|
59673
59740
|
logger.debug(`Serving static files from ${uiDistPath}`);
|
|
59674
59741
|
}
|
|
@@ -64686,7 +64753,7 @@ var init_gemini_installer = __esm(() => {
|
|
|
64686
64753
|
});
|
|
64687
64754
|
|
|
64688
64755
|
// src/services/package-installer/opencode-installer.ts
|
|
64689
|
-
import { join as
|
|
64756
|
+
import { join as join68 } from "node:path";
|
|
64690
64757
|
async function isOpenCodeInstalled() {
|
|
64691
64758
|
try {
|
|
64692
64759
|
await execAsync7("opencode --version", { timeout: 5000 });
|
|
@@ -64709,7 +64776,7 @@ async function installOpenCode() {
|
|
|
64709
64776
|
logger.info(`Installing ${displayName}...`);
|
|
64710
64777
|
const { unlink: unlink11 } = await import("node:fs/promises");
|
|
64711
64778
|
const { tmpdir: tmpdir4 } = await import("node:os");
|
|
64712
|
-
const tempScriptPath =
|
|
64779
|
+
const tempScriptPath = join68(tmpdir4(), "opencode-install.sh");
|
|
64713
64780
|
try {
|
|
64714
64781
|
logger.info("Downloading OpenCode installation script...");
|
|
64715
64782
|
await execFileAsync5("curl", ["-fsSL", "https://opencode.ai/install", "-o", tempScriptPath], {
|
|
@@ -64761,7 +64828,7 @@ var PARTIAL_INSTALL_VERSION = "partial", EXIT_CODE_CRITICAL_FAILURE = 1, EXIT_CO
|
|
|
64761
64828
|
|
|
64762
64829
|
// src/services/package-installer/install-error-handler.ts
|
|
64763
64830
|
import { existsSync as existsSync51, readFileSync as readFileSync13, unlinkSync as unlinkSync2 } from "node:fs";
|
|
64764
|
-
import { join as
|
|
64831
|
+
import { join as join69 } from "node:path";
|
|
64765
64832
|
function parseNameReason(str2) {
|
|
64766
64833
|
const colonIndex = str2.indexOf(":");
|
|
64767
64834
|
if (colonIndex === -1) {
|
|
@@ -64770,7 +64837,7 @@ function parseNameReason(str2) {
|
|
|
64770
64837
|
return [str2.slice(0, colonIndex).trim(), str2.slice(colonIndex + 1).trim()];
|
|
64771
64838
|
}
|
|
64772
64839
|
function displayInstallErrors(skillsDir2) {
|
|
64773
|
-
const summaryPath =
|
|
64840
|
+
const summaryPath = join69(skillsDir2, ".install-error-summary.json");
|
|
64774
64841
|
if (!existsSync51(summaryPath)) {
|
|
64775
64842
|
logger.error("Skills installation failed. Run with --verbose for details.");
|
|
64776
64843
|
return;
|
|
@@ -64861,7 +64928,7 @@ async function checkNeedsSudoPackages() {
|
|
|
64861
64928
|
}
|
|
64862
64929
|
}
|
|
64863
64930
|
function hasInstallState(skillsDir2) {
|
|
64864
|
-
const stateFilePath =
|
|
64931
|
+
const stateFilePath = join69(skillsDir2, ".install-state.json");
|
|
64865
64932
|
return existsSync51(stateFilePath);
|
|
64866
64933
|
}
|
|
64867
64934
|
var WHICH_COMMAND_TIMEOUT_MS = 5000;
|
|
@@ -64870,7 +64937,7 @@ var init_install_error_handler = __esm(() => {
|
|
|
64870
64937
|
});
|
|
64871
64938
|
|
|
64872
64939
|
// src/services/package-installer/skills-installer.ts
|
|
64873
|
-
import { join as
|
|
64940
|
+
import { join as join70 } from "node:path";
|
|
64874
64941
|
async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
64875
64942
|
const { skipConfirm = false, withSudo = false } = options2;
|
|
64876
64943
|
const displayName = "Skills Dependencies";
|
|
@@ -64896,7 +64963,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
64896
64963
|
const clack = await Promise.resolve().then(() => (init_dist2(), exports_dist));
|
|
64897
64964
|
const platform7 = process.platform;
|
|
64898
64965
|
const scriptName = platform7 === "win32" ? "install.ps1" : "install.sh";
|
|
64899
|
-
const scriptPath =
|
|
64966
|
+
const scriptPath = join70(skillsDir2, scriptName);
|
|
64900
64967
|
try {
|
|
64901
64968
|
validateScriptPath(skillsDir2, scriptPath);
|
|
64902
64969
|
} catch (error) {
|
|
@@ -64912,7 +64979,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
64912
64979
|
logger.warning(`Skills installation script not found: ${scriptPath}`);
|
|
64913
64980
|
logger.info("");
|
|
64914
64981
|
logger.info("\uD83D\uDCD6 Manual Installation Instructions:");
|
|
64915
|
-
logger.info(` See: ${
|
|
64982
|
+
logger.info(` See: ${join70(skillsDir2, "INSTALLATION.md")}`);
|
|
64916
64983
|
logger.info("");
|
|
64917
64984
|
logger.info("Quick start:");
|
|
64918
64985
|
logger.info(" cd .claude/skills/ai-multimodal/scripts");
|
|
@@ -64959,7 +65026,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
64959
65026
|
logger.info(` ${platform7 === "win32" ? `powershell -File "${scriptPath}"` : `bash ${scriptPath}`}`);
|
|
64960
65027
|
logger.info("");
|
|
64961
65028
|
logger.info("Or see complete guide:");
|
|
64962
|
-
logger.info(` ${
|
|
65029
|
+
logger.info(` ${join70(skillsDir2, "INSTALLATION.md")}`);
|
|
64963
65030
|
return {
|
|
64964
65031
|
success: false,
|
|
64965
65032
|
package: displayName,
|
|
@@ -65080,7 +65147,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
65080
65147
|
logger.info("\uD83D\uDCD6 Manual Installation Instructions:");
|
|
65081
65148
|
logger.info("");
|
|
65082
65149
|
logger.info("See complete guide:");
|
|
65083
|
-
logger.info(` cat ${
|
|
65150
|
+
logger.info(` cat ${join70(skillsDir2, "INSTALLATION.md")}`);
|
|
65084
65151
|
logger.info("");
|
|
65085
65152
|
logger.info("Quick start:");
|
|
65086
65153
|
logger.info(" cd .claude/skills/ai-multimodal/scripts");
|
|
@@ -65126,7 +65193,7 @@ var init_skills_installer2 = __esm(() => {
|
|
|
65126
65193
|
// src/services/package-installer/gemini-mcp/config-manager.ts
|
|
65127
65194
|
import { existsSync as existsSync52 } from "node:fs";
|
|
65128
65195
|
import { mkdir as mkdir17, readFile as readFile36, writeFile as writeFile20 } from "node:fs/promises";
|
|
65129
|
-
import { dirname as dirname21, join as
|
|
65196
|
+
import { dirname as dirname21, join as join71 } from "node:path";
|
|
65130
65197
|
async function readJsonFile(filePath) {
|
|
65131
65198
|
try {
|
|
65132
65199
|
const content = await readFile36(filePath, "utf-8");
|
|
@@ -65138,7 +65205,7 @@ async function readJsonFile(filePath) {
|
|
|
65138
65205
|
}
|
|
65139
65206
|
}
|
|
65140
65207
|
async function addGeminiToGitignore(projectDir) {
|
|
65141
|
-
const gitignorePath =
|
|
65208
|
+
const gitignorePath = join71(projectDir, ".gitignore");
|
|
65142
65209
|
const geminiPattern = ".gemini/";
|
|
65143
65210
|
try {
|
|
65144
65211
|
let content = "";
|
|
@@ -65229,13 +65296,13 @@ var init_config_manager2 = __esm(() => {
|
|
|
65229
65296
|
|
|
65230
65297
|
// src/services/package-installer/gemini-mcp/validation.ts
|
|
65231
65298
|
import { existsSync as existsSync53, lstatSync, readlinkSync } from "node:fs";
|
|
65232
|
-
import { homedir as
|
|
65233
|
-
import { join as
|
|
65299
|
+
import { homedir as homedir30 } from "node:os";
|
|
65300
|
+
import { join as join72 } from "node:path";
|
|
65234
65301
|
function getGlobalMcpConfigPath() {
|
|
65235
|
-
return
|
|
65302
|
+
return join72(homedir30(), ".claude", ".mcp.json");
|
|
65236
65303
|
}
|
|
65237
65304
|
function getLocalMcpConfigPath(projectDir) {
|
|
65238
|
-
return
|
|
65305
|
+
return join72(projectDir, ".mcp.json");
|
|
65239
65306
|
}
|
|
65240
65307
|
function findMcpConfigPath(projectDir) {
|
|
65241
65308
|
const localPath = getLocalMcpConfigPath(projectDir);
|
|
@@ -65253,9 +65320,9 @@ function findMcpConfigPath(projectDir) {
|
|
|
65253
65320
|
}
|
|
65254
65321
|
function getGeminiSettingsPath(projectDir, isGlobal) {
|
|
65255
65322
|
if (isGlobal) {
|
|
65256
|
-
return
|
|
65323
|
+
return join72(homedir30(), ".gemini", "settings.json");
|
|
65257
65324
|
}
|
|
65258
|
-
return
|
|
65325
|
+
return join72(projectDir, ".gemini", "settings.json");
|
|
65259
65326
|
}
|
|
65260
65327
|
function checkExistingGeminiConfig(projectDir, isGlobal = false) {
|
|
65261
65328
|
const geminiSettingsPath = getGeminiSettingsPath(projectDir, isGlobal);
|
|
@@ -65285,7 +65352,7 @@ var init_validation = __esm(() => {
|
|
|
65285
65352
|
// src/services/package-installer/gemini-mcp/linker-core.ts
|
|
65286
65353
|
import { existsSync as existsSync54 } from "node:fs";
|
|
65287
65354
|
import { mkdir as mkdir18, symlink as symlink2 } from "node:fs/promises";
|
|
65288
|
-
import { dirname as dirname22, join as
|
|
65355
|
+
import { dirname as dirname22, join as join73 } from "node:path";
|
|
65289
65356
|
async function createSymlink(targetPath, linkPath, projectDir, isGlobal) {
|
|
65290
65357
|
const linkDir = dirname22(linkPath);
|
|
65291
65358
|
if (!existsSync54(linkDir)) {
|
|
@@ -65296,7 +65363,7 @@ async function createSymlink(targetPath, linkPath, projectDir, isGlobal) {
|
|
|
65296
65363
|
if (isGlobal) {
|
|
65297
65364
|
symlinkTarget = getGlobalMcpConfigPath();
|
|
65298
65365
|
} else {
|
|
65299
|
-
const localMcpPath =
|
|
65366
|
+
const localMcpPath = join73(projectDir, ".mcp.json");
|
|
65300
65367
|
const isLocalConfig = targetPath === localMcpPath;
|
|
65301
65368
|
symlinkTarget = isLocalConfig ? "../.mcp.json" : targetPath;
|
|
65302
65369
|
}
|
|
@@ -67713,9 +67780,9 @@ __export(exports_worktree_manager, {
|
|
|
67713
67780
|
});
|
|
67714
67781
|
import { existsSync as existsSync62 } from "node:fs";
|
|
67715
67782
|
import { readFile as readFile53, writeFile as writeFile33 } from "node:fs/promises";
|
|
67716
|
-
import { join as
|
|
67783
|
+
import { join as join124 } from "node:path";
|
|
67717
67784
|
async function createWorktree(projectDir, issueNumber, baseBranch) {
|
|
67718
|
-
const worktreePath =
|
|
67785
|
+
const worktreePath = join124(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
|
|
67719
67786
|
const branchName = `ck-watch/issue-${issueNumber}`;
|
|
67720
67787
|
await spawnAndCollect("git", ["fetch", "origin", baseBranch], projectDir).catch(() => {
|
|
67721
67788
|
logger.warning(`[worktree] Could not fetch origin/${baseBranch}, using local`);
|
|
@@ -67733,7 +67800,7 @@ async function createWorktree(projectDir, issueNumber, baseBranch) {
|
|
|
67733
67800
|
return worktreePath;
|
|
67734
67801
|
}
|
|
67735
67802
|
async function removeWorktree(projectDir, issueNumber) {
|
|
67736
|
-
const worktreePath =
|
|
67803
|
+
const worktreePath = join124(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
|
|
67737
67804
|
const branchName = `ck-watch/issue-${issueNumber}`;
|
|
67738
67805
|
try {
|
|
67739
67806
|
await spawnAndCollect("git", ["worktree", "remove", worktreePath, "--force"], projectDir);
|
|
@@ -67747,7 +67814,7 @@ async function listActiveWorktrees(projectDir) {
|
|
|
67747
67814
|
try {
|
|
67748
67815
|
const output2 = await spawnAndCollect("git", ["worktree", "list", "--porcelain"], projectDir);
|
|
67749
67816
|
const issueNumbers = [];
|
|
67750
|
-
const worktreePrefix =
|
|
67817
|
+
const worktreePrefix = join124(projectDir, WORKTREE_DIR, "issue-").replace(/\\/g, "/");
|
|
67751
67818
|
for (const line of output2.split(`
|
|
67752
67819
|
`)) {
|
|
67753
67820
|
if (line.startsWith("worktree ")) {
|
|
@@ -67775,7 +67842,7 @@ async function cleanupAllWorktrees(projectDir) {
|
|
|
67775
67842
|
await spawnAndCollect("git", ["worktree", "prune"], projectDir).catch(() => {});
|
|
67776
67843
|
}
|
|
67777
67844
|
async function ensureGitignore(projectDir) {
|
|
67778
|
-
const gitignorePath =
|
|
67845
|
+
const gitignorePath = join124(projectDir, ".gitignore");
|
|
67779
67846
|
try {
|
|
67780
67847
|
const content = existsSync62(gitignorePath) ? await readFile53(gitignorePath, "utf-8") : "";
|
|
67781
67848
|
if (!content.includes(".worktrees")) {
|
|
@@ -67881,8 +67948,8 @@ var init_content_validator = __esm(() => {
|
|
|
67881
67948
|
import { createHash as createHash6 } from "node:crypto";
|
|
67882
67949
|
import { existsSync as existsSync68, mkdirSync as mkdirSync4, readFileSync as readFileSync14, readdirSync as readdirSync8, statSync as statSync10 } from "node:fs";
|
|
67883
67950
|
import { rename as rename9, writeFile as writeFile35 } from "node:fs/promises";
|
|
67884
|
-
import { homedir as
|
|
67885
|
-
import { basename as basename19, join as
|
|
67951
|
+
import { homedir as homedir34 } from "node:os";
|
|
67952
|
+
import { basename as basename19, join as join131 } from "node:path";
|
|
67886
67953
|
function getCachedContext(repoPath) {
|
|
67887
67954
|
const cachePath = getCacheFilePath(repoPath);
|
|
67888
67955
|
if (!existsSync68(cachePath))
|
|
@@ -67925,25 +67992,25 @@ function computeSourceHash(repoPath) {
|
|
|
67925
67992
|
}
|
|
67926
67993
|
function getDocSourcePaths(repoPath) {
|
|
67927
67994
|
const paths = [];
|
|
67928
|
-
const docsDir =
|
|
67995
|
+
const docsDir = join131(repoPath, "docs");
|
|
67929
67996
|
if (existsSync68(docsDir)) {
|
|
67930
67997
|
try {
|
|
67931
67998
|
const files = readdirSync8(docsDir);
|
|
67932
67999
|
for (const f3 of files) {
|
|
67933
68000
|
if (f3.endsWith(".md"))
|
|
67934
|
-
paths.push(
|
|
68001
|
+
paths.push(join131(docsDir, f3));
|
|
67935
68002
|
}
|
|
67936
68003
|
} catch {}
|
|
67937
68004
|
}
|
|
67938
|
-
const readme =
|
|
68005
|
+
const readme = join131(repoPath, "README.md");
|
|
67939
68006
|
if (existsSync68(readme))
|
|
67940
68007
|
paths.push(readme);
|
|
67941
|
-
const stylesDir =
|
|
68008
|
+
const stylesDir = join131(repoPath, "assets", "writing-styles");
|
|
67942
68009
|
if (existsSync68(stylesDir)) {
|
|
67943
68010
|
try {
|
|
67944
68011
|
const files = readdirSync8(stylesDir);
|
|
67945
68012
|
for (const f3 of files) {
|
|
67946
|
-
paths.push(
|
|
68013
|
+
paths.push(join131(stylesDir, f3));
|
|
67947
68014
|
}
|
|
67948
68015
|
} catch {}
|
|
67949
68016
|
}
|
|
@@ -67952,11 +68019,11 @@ function getDocSourcePaths(repoPath) {
|
|
|
67952
68019
|
function getCacheFilePath(repoPath) {
|
|
67953
68020
|
const repoName = basename19(repoPath).replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
67954
68021
|
const pathHash = createHash6("sha256").update(repoPath).digest("hex").slice(0, 8);
|
|
67955
|
-
return
|
|
68022
|
+
return join131(CACHE_DIR, `${repoName}-${pathHash}-context-cache.json`);
|
|
67956
68023
|
}
|
|
67957
68024
|
var CACHE_DIR, CACHE_TTL_MS4;
|
|
67958
68025
|
var init_context_cache_manager = __esm(() => {
|
|
67959
|
-
CACHE_DIR =
|
|
68026
|
+
CACHE_DIR = join131(homedir34(), ".claudekit", "cache");
|
|
67960
68027
|
CACHE_TTL_MS4 = 24 * 60 * 60 * 1000;
|
|
67961
68028
|
});
|
|
67962
68029
|
|
|
@@ -68137,7 +68204,7 @@ function extractContentFromResponse(response) {
|
|
|
68137
68204
|
// src/commands/content/phases/docs-summarizer.ts
|
|
68138
68205
|
import { execSync as execSync6 } from "node:child_process";
|
|
68139
68206
|
import { existsSync as existsSync69, readFileSync as readFileSync15, readdirSync as readdirSync9 } from "node:fs";
|
|
68140
|
-
import { join as
|
|
68207
|
+
import { join as join132 } from "node:path";
|
|
68141
68208
|
async function summarizeProjectDocs(repoPath, contentLogger) {
|
|
68142
68209
|
const rawContent = collectRawDocs(repoPath);
|
|
68143
68210
|
if (rawContent.total.length < 200) {
|
|
@@ -68191,12 +68258,12 @@ function collectRawDocs(repoPath) {
|
|
|
68191
68258
|
return capped;
|
|
68192
68259
|
};
|
|
68193
68260
|
const docsContent = [];
|
|
68194
|
-
const docsDir =
|
|
68261
|
+
const docsDir = join132(repoPath, "docs");
|
|
68195
68262
|
if (existsSync69(docsDir)) {
|
|
68196
68263
|
try {
|
|
68197
68264
|
const files = readdirSync9(docsDir).filter((f3) => f3.endsWith(".md")).sort();
|
|
68198
68265
|
for (const f3 of files) {
|
|
68199
|
-
const content = readCapped(
|
|
68266
|
+
const content = readCapped(join132(docsDir, f3), 5000);
|
|
68200
68267
|
if (content) {
|
|
68201
68268
|
docsContent.push(`### ${f3}
|
|
68202
68269
|
${content}`);
|
|
@@ -68210,21 +68277,21 @@ ${content}`);
|
|
|
68210
68277
|
let brand = "";
|
|
68211
68278
|
const brandCandidates = ["docs/brand-guidelines.md", "docs/design-guidelines.md"];
|
|
68212
68279
|
for (const p of brandCandidates) {
|
|
68213
|
-
brand = readCapped(
|
|
68280
|
+
brand = readCapped(join132(repoPath, p), 3000);
|
|
68214
68281
|
if (brand)
|
|
68215
68282
|
break;
|
|
68216
68283
|
}
|
|
68217
68284
|
let styles3 = "";
|
|
68218
|
-
const stylesDir =
|
|
68285
|
+
const stylesDir = join132(repoPath, "assets", "writing-styles");
|
|
68219
68286
|
if (existsSync69(stylesDir)) {
|
|
68220
68287
|
try {
|
|
68221
68288
|
const files = readdirSync9(stylesDir).slice(0, 3);
|
|
68222
|
-
styles3 = files.map((f3) => readCapped(
|
|
68289
|
+
styles3 = files.map((f3) => readCapped(join132(stylesDir, f3), 1000)).filter(Boolean).join(`
|
|
68223
68290
|
|
|
68224
68291
|
`);
|
|
68225
68292
|
} catch {}
|
|
68226
68293
|
}
|
|
68227
|
-
const readme = readCapped(
|
|
68294
|
+
const readme = readCapped(join132(repoPath, "README.md"), 3000);
|
|
68228
68295
|
const total = [docs, brand, styles3, readme].join(`
|
|
68229
68296
|
`);
|
|
68230
68297
|
return { docs, brand, styles: styles3, readme, total };
|
|
@@ -68410,10 +68477,10 @@ IMPORTANT: Generate the image and output the path as JSON: {"imagePath": "/path/
|
|
|
68410
68477
|
// src/commands/content/phases/photo-generator.ts
|
|
68411
68478
|
import { execSync as execSync7 } from "node:child_process";
|
|
68412
68479
|
import { existsSync as existsSync70, mkdirSync as mkdirSync5, readdirSync as readdirSync10 } from "node:fs";
|
|
68413
|
-
import { homedir as
|
|
68414
|
-
import { join as
|
|
68480
|
+
import { homedir as homedir35 } from "node:os";
|
|
68481
|
+
import { join as join133 } from "node:path";
|
|
68415
68482
|
async function generatePhoto(_content, context, config, platform14, contentId, contentLogger) {
|
|
68416
|
-
const mediaDir =
|
|
68483
|
+
const mediaDir = join133(config.contentDir.replace(/^~/, homedir35()), "media", String(contentId));
|
|
68417
68484
|
if (!existsSync70(mediaDir)) {
|
|
68418
68485
|
mkdirSync5(mediaDir, { recursive: true });
|
|
68419
68486
|
}
|
|
@@ -68438,7 +68505,7 @@ async function generatePhoto(_content, context, config, platform14, contentId, c
|
|
|
68438
68505
|
const imageFile = files.find((f3) => /\.(png|jpg|jpeg|webp)$/i.test(f3));
|
|
68439
68506
|
if (imageFile) {
|
|
68440
68507
|
const ext2 = imageFile.split(".").pop() ?? "png";
|
|
68441
|
-
return { path:
|
|
68508
|
+
return { path: join133(mediaDir, imageFile), ...dimensions, format: ext2 };
|
|
68442
68509
|
}
|
|
68443
68510
|
contentLogger.warn(`Photo generation produced no image for content ${contentId}`);
|
|
68444
68511
|
return null;
|
|
@@ -68527,8 +68594,8 @@ var init_content_creator = __esm(() => {
|
|
|
68527
68594
|
|
|
68528
68595
|
// src/commands/content/phases/content-logger.ts
|
|
68529
68596
|
import { createWriteStream as createWriteStream4, existsSync as existsSync71, mkdirSync as mkdirSync6, statSync as statSync11 } from "node:fs";
|
|
68530
|
-
import { homedir as
|
|
68531
|
-
import { join as
|
|
68597
|
+
import { homedir as homedir36 } from "node:os";
|
|
68598
|
+
import { join as join134 } from "node:path";
|
|
68532
68599
|
|
|
68533
68600
|
class ContentLogger {
|
|
68534
68601
|
stream = null;
|
|
@@ -68536,7 +68603,7 @@ class ContentLogger {
|
|
|
68536
68603
|
logDir;
|
|
68537
68604
|
maxBytes;
|
|
68538
68605
|
constructor(maxBytes = 0) {
|
|
68539
|
-
this.logDir =
|
|
68606
|
+
this.logDir = join134(homedir36(), ".claudekit", "logs");
|
|
68540
68607
|
this.maxBytes = maxBytes;
|
|
68541
68608
|
}
|
|
68542
68609
|
init() {
|
|
@@ -68568,7 +68635,7 @@ class ContentLogger {
|
|
|
68568
68635
|
}
|
|
68569
68636
|
}
|
|
68570
68637
|
getLogPath() {
|
|
68571
|
-
return
|
|
68638
|
+
return join134(this.logDir, `content-${this.getDateStr()}.log`);
|
|
68572
68639
|
}
|
|
68573
68640
|
write(level, message) {
|
|
68574
68641
|
this.rotateIfNeeded();
|
|
@@ -68585,18 +68652,18 @@ class ContentLogger {
|
|
|
68585
68652
|
if (dateStr !== this.currentDate) {
|
|
68586
68653
|
this.close();
|
|
68587
68654
|
this.currentDate = dateStr;
|
|
68588
|
-
const logPath =
|
|
68655
|
+
const logPath = join134(this.logDir, `content-${dateStr}.log`);
|
|
68589
68656
|
this.stream = createWriteStream4(logPath, { flags: "a", mode: 384 });
|
|
68590
68657
|
return;
|
|
68591
68658
|
}
|
|
68592
68659
|
if (this.maxBytes > 0 && this.stream) {
|
|
68593
|
-
const logPath =
|
|
68660
|
+
const logPath = join134(this.logDir, `content-${this.currentDate}.log`);
|
|
68594
68661
|
try {
|
|
68595
68662
|
const stat20 = statSync11(logPath);
|
|
68596
68663
|
if (stat20.size >= this.maxBytes) {
|
|
68597
68664
|
this.close();
|
|
68598
68665
|
const suffix = Date.now();
|
|
68599
|
-
const rotatedPath =
|
|
68666
|
+
const rotatedPath = join134(this.logDir, `content-${this.currentDate}-${suffix}.log`);
|
|
68600
68667
|
import("node:fs/promises").then(({ rename: rename10 }) => rename10(logPath, rotatedPath).catch(() => {}));
|
|
68601
68668
|
this.stream = createWriteStream4(logPath, { flags: "w", mode: 384 });
|
|
68602
68669
|
}
|
|
@@ -68814,7 +68881,7 @@ function isNoiseCommit(title, author) {
|
|
|
68814
68881
|
// src/commands/content/phases/change-detector.ts
|
|
68815
68882
|
import { execSync as execSync9 } from "node:child_process";
|
|
68816
68883
|
import { existsSync as existsSync73, readFileSync as readFileSync16, readdirSync as readdirSync11, statSync as statSync12 } from "node:fs";
|
|
68817
|
-
import { join as
|
|
68884
|
+
import { join as join135 } from "node:path";
|
|
68818
68885
|
function detectCommits(repo, since) {
|
|
68819
68886
|
try {
|
|
68820
68887
|
const fetchUrl = sshToHttps(repo.remoteUrl);
|
|
@@ -68912,7 +68979,7 @@ function detectTags(repo, since) {
|
|
|
68912
68979
|
}
|
|
68913
68980
|
}
|
|
68914
68981
|
function detectCompletedPlans(repo, since) {
|
|
68915
|
-
const plansDir =
|
|
68982
|
+
const plansDir = join135(repo.path, "plans");
|
|
68916
68983
|
if (!existsSync73(plansDir))
|
|
68917
68984
|
return [];
|
|
68918
68985
|
const sinceMs = new Date(since).getTime();
|
|
@@ -68922,7 +68989,7 @@ function detectCompletedPlans(repo, since) {
|
|
|
68922
68989
|
for (const entry of entries) {
|
|
68923
68990
|
if (!entry.isDirectory())
|
|
68924
68991
|
continue;
|
|
68925
|
-
const planFile =
|
|
68992
|
+
const planFile = join135(plansDir, entry.name, "plan.md");
|
|
68926
68993
|
if (!existsSync73(planFile))
|
|
68927
68994
|
continue;
|
|
68928
68995
|
try {
|
|
@@ -69000,7 +69067,7 @@ function classifyCommit(event) {
|
|
|
69000
69067
|
// src/commands/content/phases/repo-discoverer.ts
|
|
69001
69068
|
import { execSync as execSync10 } from "node:child_process";
|
|
69002
69069
|
import { readdirSync as readdirSync12 } from "node:fs";
|
|
69003
|
-
import { join as
|
|
69070
|
+
import { join as join136 } from "node:path";
|
|
69004
69071
|
function discoverRepos2(cwd2) {
|
|
69005
69072
|
const repos = [];
|
|
69006
69073
|
if (isGitRepoRoot(cwd2)) {
|
|
@@ -69013,7 +69080,7 @@ function discoverRepos2(cwd2) {
|
|
|
69013
69080
|
for (const entry of entries) {
|
|
69014
69081
|
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
69015
69082
|
continue;
|
|
69016
|
-
const dirPath =
|
|
69083
|
+
const dirPath = join136(cwd2, entry.name);
|
|
69017
69084
|
if (isGitRepoRoot(dirPath)) {
|
|
69018
69085
|
const info = getRepoInfo(dirPath);
|
|
69019
69086
|
if (info)
|
|
@@ -69680,9 +69747,9 @@ var init_types6 = __esm(() => {
|
|
|
69680
69747
|
|
|
69681
69748
|
// src/commands/content/phases/state-manager.ts
|
|
69682
69749
|
import { readFile as readFile55, rename as rename10, writeFile as writeFile36 } from "node:fs/promises";
|
|
69683
|
-
import { join as
|
|
69750
|
+
import { join as join137 } from "node:path";
|
|
69684
69751
|
async function loadContentConfig(projectDir) {
|
|
69685
|
-
const configPath =
|
|
69752
|
+
const configPath = join137(projectDir, CK_CONFIG_FILE2);
|
|
69686
69753
|
try {
|
|
69687
69754
|
const raw2 = await readFile55(configPath, "utf-8");
|
|
69688
69755
|
const json = JSON.parse(raw2);
|
|
@@ -69692,13 +69759,13 @@ async function loadContentConfig(projectDir) {
|
|
|
69692
69759
|
}
|
|
69693
69760
|
}
|
|
69694
69761
|
async function saveContentConfig(projectDir, config) {
|
|
69695
|
-
const configPath =
|
|
69762
|
+
const configPath = join137(projectDir, CK_CONFIG_FILE2);
|
|
69696
69763
|
const json = await readJsonSafe(configPath);
|
|
69697
69764
|
json.content = { ...json.content, ...config };
|
|
69698
69765
|
await atomicWrite(configPath, json);
|
|
69699
69766
|
}
|
|
69700
69767
|
async function loadContentState(projectDir) {
|
|
69701
|
-
const configPath =
|
|
69768
|
+
const configPath = join137(projectDir, CK_CONFIG_FILE2);
|
|
69702
69769
|
try {
|
|
69703
69770
|
const raw2 = await readFile55(configPath, "utf-8");
|
|
69704
69771
|
const json = JSON.parse(raw2);
|
|
@@ -69709,7 +69776,7 @@ async function loadContentState(projectDir) {
|
|
|
69709
69776
|
}
|
|
69710
69777
|
}
|
|
69711
69778
|
async function saveContentState(projectDir, state) {
|
|
69712
|
-
const configPath =
|
|
69779
|
+
const configPath = join137(projectDir, CK_CONFIG_FILE2);
|
|
69713
69780
|
const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().slice(0, 10);
|
|
69714
69781
|
for (const key of Object.keys(state.dailyPostCounts)) {
|
|
69715
69782
|
const dateStr = key.slice(-10);
|
|
@@ -69991,7 +70058,7 @@ var init_platform_setup_x = __esm(() => {
|
|
|
69991
70058
|
|
|
69992
70059
|
// src/commands/content/phases/setup-wizard.ts
|
|
69993
70060
|
import { existsSync as existsSync74 } from "node:fs";
|
|
69994
|
-
import { join as
|
|
70061
|
+
import { join as join138 } from "node:path";
|
|
69995
70062
|
async function runSetupWizard2(cwd2, contentLogger) {
|
|
69996
70063
|
console.log();
|
|
69997
70064
|
oe(import_picocolors41.default.bgCyan(import_picocolors41.default.white(" CK Content — Multi-Channel Content Engine ")));
|
|
@@ -70059,8 +70126,8 @@ async function showRepoSummary(cwd2) {
|
|
|
70059
70126
|
function detectBrandAssets(cwd2, contentLogger) {
|
|
70060
70127
|
const repos = discoverRepos2(cwd2);
|
|
70061
70128
|
for (const repo of repos) {
|
|
70062
|
-
const hasGuidelines = existsSync74(
|
|
70063
|
-
const hasStyles = existsSync74(
|
|
70129
|
+
const hasGuidelines = existsSync74(join138(repo.path, "docs", "brand-guidelines.md"));
|
|
70130
|
+
const hasStyles = existsSync74(join138(repo.path, "assets", "writing-styles"));
|
|
70064
70131
|
if (!hasGuidelines) {
|
|
70065
70132
|
f2.warning(`${repo.name}: No docs/brand-guidelines.md — content will use generic tone.`);
|
|
70066
70133
|
contentLogger.warn(`${repo.name}: missing docs/brand-guidelines.md`);
|
|
@@ -70127,11 +70194,11 @@ var init_setup_wizard = __esm(() => {
|
|
|
70127
70194
|
|
|
70128
70195
|
// src/commands/content/content-review-commands.ts
|
|
70129
70196
|
import { existsSync as existsSync75 } from "node:fs";
|
|
70130
|
-
import { homedir as
|
|
70197
|
+
import { homedir as homedir37 } from "node:os";
|
|
70131
70198
|
async function queueContent() {
|
|
70132
70199
|
const cwd2 = process.cwd();
|
|
70133
70200
|
const config = await loadContentConfig(cwd2);
|
|
70134
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
70201
|
+
const dbPath = config.dbPath.replace(/^~/, homedir37());
|
|
70135
70202
|
if (!existsSync75(dbPath)) {
|
|
70136
70203
|
logger.info("No content database found. Run 'ck content setup' first.");
|
|
70137
70204
|
return;
|
|
@@ -70158,7 +70225,7 @@ async function queueContent() {
|
|
|
70158
70225
|
async function approveContentCmd(id) {
|
|
70159
70226
|
const cwd2 = process.cwd();
|
|
70160
70227
|
const config = await loadContentConfig(cwd2);
|
|
70161
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
70228
|
+
const dbPath = config.dbPath.replace(/^~/, homedir37());
|
|
70162
70229
|
const db = initDatabase(dbPath);
|
|
70163
70230
|
try {
|
|
70164
70231
|
approveContent(db, Number.parseInt(id, 10));
|
|
@@ -70170,7 +70237,7 @@ async function approveContentCmd(id) {
|
|
|
70170
70237
|
async function rejectContentCmd(id, reason) {
|
|
70171
70238
|
const cwd2 = process.cwd();
|
|
70172
70239
|
const config = await loadContentConfig(cwd2);
|
|
70173
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
70240
|
+
const dbPath = config.dbPath.replace(/^~/, homedir37());
|
|
70174
70241
|
const db = initDatabase(dbPath);
|
|
70175
70242
|
try {
|
|
70176
70243
|
rejectContent(db, Number.parseInt(id, 10), reason);
|
|
@@ -70201,10 +70268,10 @@ __export(exports_content_subcommands, {
|
|
|
70201
70268
|
approveContentCmd: () => approveContentCmd
|
|
70202
70269
|
});
|
|
70203
70270
|
import { existsSync as existsSync76, readFileSync as readFileSync17, unlinkSync as unlinkSync5 } from "node:fs";
|
|
70204
|
-
import { homedir as
|
|
70205
|
-
import { join as
|
|
70271
|
+
import { homedir as homedir38 } from "node:os";
|
|
70272
|
+
import { join as join139 } from "node:path";
|
|
70206
70273
|
function isDaemonRunning() {
|
|
70207
|
-
const lockFile =
|
|
70274
|
+
const lockFile = join139(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
70208
70275
|
if (!existsSync76(lockFile))
|
|
70209
70276
|
return { running: false, pid: null };
|
|
70210
70277
|
try {
|
|
@@ -70236,7 +70303,7 @@ async function startContent(options2) {
|
|
|
70236
70303
|
await contentCommand(options2);
|
|
70237
70304
|
}
|
|
70238
70305
|
async function stopContent() {
|
|
70239
|
-
const lockFile =
|
|
70306
|
+
const lockFile = join139(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
70240
70307
|
if (!existsSync76(lockFile)) {
|
|
70241
70308
|
logger.info("Content daemon is not running.");
|
|
70242
70309
|
return;
|
|
@@ -70275,9 +70342,9 @@ async function statusContent() {
|
|
|
70275
70342
|
} catch {}
|
|
70276
70343
|
}
|
|
70277
70344
|
async function logsContent(options2) {
|
|
70278
|
-
const logDir =
|
|
70345
|
+
const logDir = join139(homedir38(), ".claudekit", "logs");
|
|
70279
70346
|
const dateStr = new Date().toISOString().slice(0, 10).replace(/-/g, "");
|
|
70280
|
-
const logPath =
|
|
70347
|
+
const logPath = join139(logDir, `content-${dateStr}.log`);
|
|
70281
70348
|
if (!existsSync76(logPath)) {
|
|
70282
70349
|
logger.info("No content logs found for today.");
|
|
70283
70350
|
return;
|
|
@@ -70309,13 +70376,13 @@ var init_content_subcommands = __esm(() => {
|
|
|
70309
70376
|
init_setup_wizard();
|
|
70310
70377
|
init_state_manager();
|
|
70311
70378
|
init_content_review_commands();
|
|
70312
|
-
LOCK_DIR =
|
|
70379
|
+
LOCK_DIR = join139(homedir38(), ".claudekit", "locks");
|
|
70313
70380
|
});
|
|
70314
70381
|
|
|
70315
70382
|
// src/commands/content/content-command.ts
|
|
70316
70383
|
import { existsSync as existsSync77, mkdirSync as mkdirSync8, unlinkSync as unlinkSync6, writeFileSync as writeFileSync6 } from "node:fs";
|
|
70317
|
-
import { homedir as
|
|
70318
|
-
import { join as
|
|
70384
|
+
import { homedir as homedir39 } from "node:os";
|
|
70385
|
+
import { join as join140 } from "node:path";
|
|
70319
70386
|
async function contentCommand(options2) {
|
|
70320
70387
|
const cwd2 = process.cwd();
|
|
70321
70388
|
const contentLogger = new ContentLogger;
|
|
@@ -70347,7 +70414,7 @@ async function contentCommand(options2) {
|
|
|
70347
70414
|
if (!existsSync77(LOCK_DIR2))
|
|
70348
70415
|
mkdirSync8(LOCK_DIR2, { recursive: true });
|
|
70349
70416
|
writeFileSync6(LOCK_FILE, String(process.pid), "utf-8");
|
|
70350
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
70417
|
+
const dbPath = config.dbPath.replace(/^~/, homedir39());
|
|
70351
70418
|
const db = initDatabase(dbPath);
|
|
70352
70419
|
contentLogger.info(`Database initialised at ${dbPath}`);
|
|
70353
70420
|
const adapters = initializeAdapters(config);
|
|
@@ -70493,8 +70560,8 @@ var init_content_command = __esm(() => {
|
|
|
70493
70560
|
init_publisher();
|
|
70494
70561
|
init_review_manager();
|
|
70495
70562
|
init_state_manager();
|
|
70496
|
-
LOCK_DIR2 =
|
|
70497
|
-
LOCK_FILE =
|
|
70563
|
+
LOCK_DIR2 = join140(homedir39(), ".claudekit", "locks");
|
|
70564
|
+
LOCK_FILE = join140(LOCK_DIR2, "ck-content.lock");
|
|
70498
70565
|
});
|
|
70499
70566
|
|
|
70500
70567
|
// src/commands/content/index.ts
|
|
@@ -70696,6 +70763,10 @@ var init_init_command_help = __esm(() => {
|
|
|
70696
70763
|
{
|
|
70697
70764
|
flags: "--fresh",
|
|
70698
70765
|
description: "Full reset: remove CK files, replace settings.json and CLAUDE.md, reinstall from scratch"
|
|
70766
|
+
},
|
|
70767
|
+
{
|
|
70768
|
+
flags: "--force",
|
|
70769
|
+
description: "Force reinstall even if already at latest version (use with --yes; re-onboards missing files without full reset)"
|
|
70699
70770
|
}
|
|
70700
70771
|
]
|
|
70701
70772
|
},
|
|
@@ -76448,14 +76519,14 @@ async function checkCliInstallMethod() {
|
|
|
76448
76519
|
}
|
|
76449
76520
|
// src/domains/health-checks/checkers/claude-md-checker.ts
|
|
76450
76521
|
import { existsSync as existsSync42, statSync as statSync5 } from "node:fs";
|
|
76451
|
-
import { join as
|
|
76522
|
+
import { join as join51 } from "node:path";
|
|
76452
76523
|
function checkClaudeMd(setup, projectDir) {
|
|
76453
76524
|
const results = [];
|
|
76454
76525
|
if (setup.global.path) {
|
|
76455
|
-
const globalClaudeMd =
|
|
76526
|
+
const globalClaudeMd = join51(setup.global.path, "CLAUDE.md");
|
|
76456
76527
|
results.push(checkClaudeMdFile(globalClaudeMd, "Global CLAUDE.md", "ck-global-claude-md"));
|
|
76457
76528
|
}
|
|
76458
|
-
const projectClaudeMd =
|
|
76529
|
+
const projectClaudeMd = join51(projectDir, ".claude", "CLAUDE.md");
|
|
76459
76530
|
results.push(checkClaudeMdFile(projectClaudeMd, "Project CLAUDE.md", "ck-project-claude-md"));
|
|
76460
76531
|
return results;
|
|
76461
76532
|
}
|
|
@@ -76514,9 +76585,9 @@ function checkClaudeMdFile(path4, name, id) {
|
|
|
76514
76585
|
}
|
|
76515
76586
|
// src/domains/health-checks/checkers/active-plan-checker.ts
|
|
76516
76587
|
import { existsSync as existsSync43, readFileSync as readFileSync10 } from "node:fs";
|
|
76517
|
-
import { join as
|
|
76588
|
+
import { join as join52 } from "node:path";
|
|
76518
76589
|
function checkActivePlan(projectDir) {
|
|
76519
|
-
const activePlanPath =
|
|
76590
|
+
const activePlanPath = join52(projectDir, ".claude", "active-plan");
|
|
76520
76591
|
if (!existsSync43(activePlanPath)) {
|
|
76521
76592
|
return {
|
|
76522
76593
|
id: "ck-active-plan",
|
|
@@ -76530,7 +76601,7 @@ function checkActivePlan(projectDir) {
|
|
|
76530
76601
|
}
|
|
76531
76602
|
try {
|
|
76532
76603
|
const targetPath = readFileSync10(activePlanPath, "utf-8").trim();
|
|
76533
|
-
const fullPath =
|
|
76604
|
+
const fullPath = join52(projectDir, targetPath);
|
|
76534
76605
|
if (!existsSync43(fullPath)) {
|
|
76535
76606
|
return {
|
|
76536
76607
|
id: "ck-active-plan",
|
|
@@ -76568,13 +76639,13 @@ function checkActivePlan(projectDir) {
|
|
|
76568
76639
|
}
|
|
76569
76640
|
// src/domains/health-checks/checkers/skills-checker.ts
|
|
76570
76641
|
import { existsSync as existsSync44 } from "node:fs";
|
|
76571
|
-
import { join as
|
|
76642
|
+
import { join as join53 } from "node:path";
|
|
76572
76643
|
function checkSkillsScripts(setup) {
|
|
76573
76644
|
const results = [];
|
|
76574
76645
|
const platform5 = process.platform;
|
|
76575
76646
|
const scriptName = platform5 === "win32" ? "install.ps1" : "install.sh";
|
|
76576
76647
|
if (setup.global.path) {
|
|
76577
|
-
const globalScriptPath =
|
|
76648
|
+
const globalScriptPath = join53(setup.global.path, "skills", scriptName);
|
|
76578
76649
|
const hasGlobalScript = existsSync44(globalScriptPath);
|
|
76579
76650
|
results.push({
|
|
76580
76651
|
id: "ck-global-skills-script",
|
|
@@ -76589,7 +76660,7 @@ function checkSkillsScripts(setup) {
|
|
|
76589
76660
|
});
|
|
76590
76661
|
}
|
|
76591
76662
|
if (setup.project.metadata) {
|
|
76592
|
-
const projectScriptPath =
|
|
76663
|
+
const projectScriptPath = join53(setup.project.path, "skills", scriptName);
|
|
76593
76664
|
const hasProjectScript = existsSync44(projectScriptPath);
|
|
76594
76665
|
results.push({
|
|
76595
76666
|
id: "ck-project-skills-script",
|
|
@@ -76628,7 +76699,7 @@ function checkComponentCounts(setup) {
|
|
|
76628
76699
|
init_logger();
|
|
76629
76700
|
init_path_resolver();
|
|
76630
76701
|
import { constants as constants2, access as access2, unlink as unlink7, writeFile as writeFile16 } from "node:fs/promises";
|
|
76631
|
-
import { join as
|
|
76702
|
+
import { join as join54 } from "node:path";
|
|
76632
76703
|
|
|
76633
76704
|
// src/domains/health-checks/checkers/shared.ts
|
|
76634
76705
|
init_environment();
|
|
@@ -76694,7 +76765,7 @@ async function checkGlobalDirWritable() {
|
|
|
76694
76765
|
}
|
|
76695
76766
|
const timestamp = Date.now();
|
|
76696
76767
|
const random = Math.random().toString(36).substring(2);
|
|
76697
|
-
const testFile =
|
|
76768
|
+
const testFile = join54(globalDir, `.ck-write-test-${timestamp}-${random}`);
|
|
76698
76769
|
try {
|
|
76699
76770
|
await writeFile16(testFile, "test", { encoding: "utf-8", flag: "wx" });
|
|
76700
76771
|
} catch (error) {
|
|
@@ -76730,7 +76801,7 @@ async function checkGlobalDirWritable() {
|
|
|
76730
76801
|
init_path_resolver();
|
|
76731
76802
|
import { existsSync as existsSync45 } from "node:fs";
|
|
76732
76803
|
import { readdir as readdir10 } from "node:fs/promises";
|
|
76733
|
-
import { join as
|
|
76804
|
+
import { join as join55 } from "node:path";
|
|
76734
76805
|
|
|
76735
76806
|
// src/domains/health-checks/utils/path-normalizer.ts
|
|
76736
76807
|
import { normalize as normalize4 } from "node:path";
|
|
@@ -76742,8 +76813,8 @@ function normalizePath2(filePath) {
|
|
|
76742
76813
|
|
|
76743
76814
|
// src/domains/health-checks/checkers/hooks-checker.ts
|
|
76744
76815
|
async function checkHooksExist(projectDir) {
|
|
76745
|
-
const globalHooksDir =
|
|
76746
|
-
const projectHooksDir =
|
|
76816
|
+
const globalHooksDir = join55(PathResolver.getGlobalKitDir(), "hooks");
|
|
76817
|
+
const projectHooksDir = join55(projectDir, ".claude", "hooks");
|
|
76747
76818
|
const globalExists = existsSync45(globalHooksDir);
|
|
76748
76819
|
const projectExists = existsSync45(projectHooksDir);
|
|
76749
76820
|
let hookCount = 0;
|
|
@@ -76752,7 +76823,7 @@ async function checkHooksExist(projectDir) {
|
|
|
76752
76823
|
const files = await readdir10(globalHooksDir, { withFileTypes: false });
|
|
76753
76824
|
const hooks = files.filter((f3) => HOOK_EXTENSIONS2.some((ext) => f3.endsWith(ext)));
|
|
76754
76825
|
hooks.forEach((hook) => {
|
|
76755
|
-
const fullPath =
|
|
76826
|
+
const fullPath = join55(globalHooksDir, hook);
|
|
76756
76827
|
checkedFiles.add(normalizePath2(fullPath));
|
|
76757
76828
|
});
|
|
76758
76829
|
}
|
|
@@ -76762,7 +76833,7 @@ async function checkHooksExist(projectDir) {
|
|
|
76762
76833
|
const files = await readdir10(projectHooksDir, { withFileTypes: false });
|
|
76763
76834
|
const hooks = files.filter((f3) => HOOK_EXTENSIONS2.some((ext) => f3.endsWith(ext)));
|
|
76764
76835
|
hooks.forEach((hook) => {
|
|
76765
|
-
const fullPath =
|
|
76836
|
+
const fullPath = join55(projectHooksDir, hook);
|
|
76766
76837
|
checkedFiles.add(normalizePath2(fullPath));
|
|
76767
76838
|
});
|
|
76768
76839
|
}
|
|
@@ -76794,10 +76865,10 @@ init_logger();
|
|
|
76794
76865
|
init_path_resolver();
|
|
76795
76866
|
import { existsSync as existsSync46 } from "node:fs";
|
|
76796
76867
|
import { readFile as readFile30 } from "node:fs/promises";
|
|
76797
|
-
import { join as
|
|
76868
|
+
import { join as join56 } from "node:path";
|
|
76798
76869
|
async function checkSettingsValid(projectDir) {
|
|
76799
|
-
const globalSettings =
|
|
76800
|
-
const projectSettings =
|
|
76870
|
+
const globalSettings = join56(PathResolver.getGlobalKitDir(), "settings.json");
|
|
76871
|
+
const projectSettings = join56(projectDir, ".claude", "settings.json");
|
|
76801
76872
|
const settingsPath = existsSync46(globalSettings) ? globalSettings : existsSync46(projectSettings) ? projectSettings : null;
|
|
76802
76873
|
if (!settingsPath) {
|
|
76803
76874
|
return {
|
|
@@ -76869,11 +76940,11 @@ init_logger();
|
|
|
76869
76940
|
init_path_resolver();
|
|
76870
76941
|
import { existsSync as existsSync47 } from "node:fs";
|
|
76871
76942
|
import { readFile as readFile31 } from "node:fs/promises";
|
|
76872
|
-
import { homedir as
|
|
76873
|
-
import { dirname as dirname19, join as
|
|
76943
|
+
import { homedir as homedir28 } from "node:os";
|
|
76944
|
+
import { dirname as dirname19, join as join57, normalize as normalize5, resolve as resolve14 } from "node:path";
|
|
76874
76945
|
async function checkPathRefsValid(projectDir) {
|
|
76875
|
-
const globalClaudeMd =
|
|
76876
|
-
const projectClaudeMd =
|
|
76946
|
+
const globalClaudeMd = join57(PathResolver.getGlobalKitDir(), "CLAUDE.md");
|
|
76947
|
+
const projectClaudeMd = join57(projectDir, ".claude", "CLAUDE.md");
|
|
76877
76948
|
const claudeMdPath = existsSync47(globalClaudeMd) ? globalClaudeMd : existsSync47(projectClaudeMd) ? projectClaudeMd : null;
|
|
76878
76949
|
if (!claudeMdPath) {
|
|
76879
76950
|
return {
|
|
@@ -76902,7 +76973,7 @@ async function checkPathRefsValid(projectDir) {
|
|
|
76902
76973
|
};
|
|
76903
76974
|
}
|
|
76904
76975
|
const baseDir = dirname19(claudeMdPath);
|
|
76905
|
-
const home8 =
|
|
76976
|
+
const home8 = homedir28();
|
|
76906
76977
|
const broken = [];
|
|
76907
76978
|
for (const ref of refs) {
|
|
76908
76979
|
let refPath;
|
|
@@ -76968,7 +77039,7 @@ async function checkPathRefsValid(projectDir) {
|
|
|
76968
77039
|
// src/domains/health-checks/checkers/config-completeness-checker.ts
|
|
76969
77040
|
import { existsSync as existsSync48 } from "node:fs";
|
|
76970
77041
|
import { readdir as readdir11 } from "node:fs/promises";
|
|
76971
|
-
import { join as
|
|
77042
|
+
import { join as join58 } from "node:path";
|
|
76972
77043
|
async function checkProjectConfigCompleteness(setup, projectDir) {
|
|
76973
77044
|
if (setup.project.path === setup.global.path) {
|
|
76974
77045
|
return {
|
|
@@ -76981,16 +77052,16 @@ async function checkProjectConfigCompleteness(setup, projectDir) {
|
|
|
76981
77052
|
autoFixable: false
|
|
76982
77053
|
};
|
|
76983
77054
|
}
|
|
76984
|
-
const projectClaudeDir =
|
|
77055
|
+
const projectClaudeDir = join58(projectDir, ".claude");
|
|
76985
77056
|
const requiredDirs = ["agents", "commands", "skills"];
|
|
76986
77057
|
const missingDirs = [];
|
|
76987
77058
|
for (const dir of requiredDirs) {
|
|
76988
|
-
const dirPath =
|
|
77059
|
+
const dirPath = join58(projectClaudeDir, dir);
|
|
76989
77060
|
if (!existsSync48(dirPath)) {
|
|
76990
77061
|
missingDirs.push(dir);
|
|
76991
77062
|
}
|
|
76992
77063
|
}
|
|
76993
|
-
const hasRulesOrWorkflows = existsSync48(
|
|
77064
|
+
const hasRulesOrWorkflows = existsSync48(join58(projectClaudeDir, "rules")) || existsSync48(join58(projectClaudeDir, "workflows"));
|
|
76994
77065
|
if (!hasRulesOrWorkflows) {
|
|
76995
77066
|
missingDirs.push("rules");
|
|
76996
77067
|
}
|
|
@@ -77035,7 +77106,7 @@ async function checkProjectConfigCompleteness(setup, projectDir) {
|
|
|
77035
77106
|
};
|
|
77036
77107
|
}
|
|
77037
77108
|
// src/domains/health-checks/checkers/env-keys-checker.ts
|
|
77038
|
-
import { join as
|
|
77109
|
+
import { join as join60 } from "node:path";
|
|
77039
77110
|
|
|
77040
77111
|
// src/domains/installation/setup-wizard.ts
|
|
77041
77112
|
init_config_generator();
|
|
@@ -77044,7 +77115,7 @@ init_logger();
|
|
|
77044
77115
|
init_path_resolver();
|
|
77045
77116
|
init_dist2();
|
|
77046
77117
|
var import_fs_extra6 = __toESM(require_lib3(), 1);
|
|
77047
|
-
import { join as
|
|
77118
|
+
import { join as join59 } from "node:path";
|
|
77048
77119
|
var REQUIRED_ENV_KEYS = [
|
|
77049
77120
|
{ key: "GEMINI_API_KEY", label: "Gemini API Key" }
|
|
77050
77121
|
];
|
|
@@ -77121,7 +77192,7 @@ async function parseEnvFile(path4) {
|
|
|
77121
77192
|
}
|
|
77122
77193
|
}
|
|
77123
77194
|
async function checkGlobalConfig() {
|
|
77124
|
-
const globalEnvPath =
|
|
77195
|
+
const globalEnvPath = join59(PathResolver.getGlobalKitDir(), ".env");
|
|
77125
77196
|
if (!await import_fs_extra6.pathExists(globalEnvPath))
|
|
77126
77197
|
return false;
|
|
77127
77198
|
const env2 = await parseEnvFile(globalEnvPath);
|
|
@@ -77137,7 +77208,7 @@ async function runSetupWizard(options2) {
|
|
|
77137
77208
|
let globalEnv = {};
|
|
77138
77209
|
const hasGlobalConfig = !isGlobal && await checkGlobalConfig();
|
|
77139
77210
|
if (!isGlobal) {
|
|
77140
|
-
const globalEnvPath =
|
|
77211
|
+
const globalEnvPath = join59(PathResolver.getGlobalKitDir(), ".env");
|
|
77141
77212
|
if (await import_fs_extra6.pathExists(globalEnvPath)) {
|
|
77142
77213
|
globalEnv = await parseEnvFile(globalEnvPath);
|
|
77143
77214
|
}
|
|
@@ -77200,7 +77271,7 @@ async function runSetupWizard(options2) {
|
|
|
77200
77271
|
}
|
|
77201
77272
|
}
|
|
77202
77273
|
await generateEnvFile(targetDir, values);
|
|
77203
|
-
f2.success(`Configuration saved to ${
|
|
77274
|
+
f2.success(`Configuration saved to ${join59(targetDir, ".env")}`);
|
|
77204
77275
|
return true;
|
|
77205
77276
|
}
|
|
77206
77277
|
async function promptForAdditionalGeminiKeys(primaryKey) {
|
|
@@ -77275,7 +77346,7 @@ Optional: DISCORD_WEBHOOK_URL, TELEGRAM_BOT_TOKEN`, "Configuration skipped");
|
|
|
77275
77346
|
async function checkEnvKeys(setup) {
|
|
77276
77347
|
const results = [];
|
|
77277
77348
|
if (setup.global.path) {
|
|
77278
|
-
const globalEnvPath =
|
|
77349
|
+
const globalEnvPath = join60(setup.global.path, ".env");
|
|
77279
77350
|
const globalCheck = await checkRequiredKeysExist(globalEnvPath);
|
|
77280
77351
|
if (!globalCheck.allPresent) {
|
|
77281
77352
|
const missingKeys = globalCheck.missing.map((m2) => m2.label).join(", ");
|
|
@@ -77304,7 +77375,7 @@ async function checkEnvKeys(setup) {
|
|
|
77304
77375
|
}
|
|
77305
77376
|
}
|
|
77306
77377
|
if (setup.project.metadata) {
|
|
77307
|
-
const projectEnvPath =
|
|
77378
|
+
const projectEnvPath = join60(setup.project.path, ".env");
|
|
77308
77379
|
const projectCheck = await checkRequiredKeysExist(projectEnvPath);
|
|
77309
77380
|
if (!projectCheck.allPresent) {
|
|
77310
77381
|
const missingKeys = projectCheck.missing.map((m2) => m2.label).join(", ");
|
|
@@ -77342,7 +77413,7 @@ import { spawnSync as spawnSync2 } from "node:child_process";
|
|
|
77342
77413
|
import { existsSync as existsSync49, readFileSync as readFileSync11, statSync as statSync6, writeFileSync as writeFileSync4 } from "node:fs";
|
|
77343
77414
|
import { readdir as readdir12 } from "node:fs/promises";
|
|
77344
77415
|
import { tmpdir } from "node:os";
|
|
77345
|
-
import { join as
|
|
77416
|
+
import { join as join61, resolve as resolve15 } from "node:path";
|
|
77346
77417
|
var HOOK_CHECK_TIMEOUT_MS = 5000;
|
|
77347
77418
|
var PYTHON_CHECK_TIMEOUT_MS = 3000;
|
|
77348
77419
|
var MAX_LOG_FILE_SIZE_BYTES = 10 * 1024 * 1024;
|
|
@@ -77387,7 +77458,7 @@ async function checkHookSyntax(projectDir) {
|
|
|
77387
77458
|
}
|
|
77388
77459
|
const errors2 = [];
|
|
77389
77460
|
for (const file of cjsFiles) {
|
|
77390
|
-
const filePath =
|
|
77461
|
+
const filePath = join61(hooksDir, file);
|
|
77391
77462
|
if (!isPathWithin(filePath, hooksDir))
|
|
77392
77463
|
continue;
|
|
77393
77464
|
const result = spawnSync2("node", ["--check", filePath], {
|
|
@@ -77473,7 +77544,7 @@ async function checkHookDeps(projectDir) {
|
|
|
77473
77544
|
const missingDeps = [];
|
|
77474
77545
|
const requireRegex = /require\(['"]([^'"]+)['"]\)/g;
|
|
77475
77546
|
for (const file of cjsFiles) {
|
|
77476
|
-
const filePath =
|
|
77547
|
+
const filePath = join61(hooksDir, file);
|
|
77477
77548
|
if (!isPathWithin(filePath, hooksDir))
|
|
77478
77549
|
continue;
|
|
77479
77550
|
const content = readFileSync11(filePath, "utf-8");
|
|
@@ -77483,10 +77554,10 @@ async function checkHookDeps(projectDir) {
|
|
|
77483
77554
|
continue;
|
|
77484
77555
|
}
|
|
77485
77556
|
if (depPath.startsWith(".")) {
|
|
77486
|
-
const resolvedPath =
|
|
77557
|
+
const resolvedPath = join61(hooksDir, depPath);
|
|
77487
77558
|
const extensions = [".js", ".cjs", ".mjs", ".json"];
|
|
77488
77559
|
const indexFiles = ["index.js", "index.cjs", "index.mjs"];
|
|
77489
|
-
const exists = existsSync49(resolvedPath) || extensions.some((ext) => existsSync49(resolvedPath + ext)) || indexFiles.some((idx) => existsSync49(
|
|
77560
|
+
const exists = existsSync49(resolvedPath) || extensions.some((ext) => existsSync49(resolvedPath + ext)) || indexFiles.some((idx) => existsSync49(join61(resolvedPath, idx)));
|
|
77490
77561
|
if (!exists) {
|
|
77491
77562
|
missingDeps.push(`${file}: ${depPath}`);
|
|
77492
77563
|
}
|
|
@@ -77603,11 +77674,11 @@ async function checkHookRuntime(projectDir) {
|
|
|
77603
77674
|
}
|
|
77604
77675
|
const syntheticPayload = JSON.stringify({
|
|
77605
77676
|
tool_name: "Read",
|
|
77606
|
-
tool_input: { file_path:
|
|
77677
|
+
tool_input: { file_path: join61(tmpdir(), "ck-doctor-test.txt") }
|
|
77607
77678
|
});
|
|
77608
77679
|
const failures = [];
|
|
77609
77680
|
for (const file of cjsFiles) {
|
|
77610
|
-
const filePath =
|
|
77681
|
+
const filePath = join61(hooksDir, file);
|
|
77611
77682
|
if (!isPathWithin(filePath, hooksDir))
|
|
77612
77683
|
continue;
|
|
77613
77684
|
const result = spawnSync2("node", [filePath], {
|
|
@@ -77669,8 +77740,8 @@ async function checkHookRuntime(projectDir) {
|
|
|
77669
77740
|
}
|
|
77670
77741
|
}
|
|
77671
77742
|
async function checkHookConfig(projectDir) {
|
|
77672
|
-
const projectConfigPath =
|
|
77673
|
-
const globalConfigPath =
|
|
77743
|
+
const projectConfigPath = join61(projectDir, ".claude", ".ck.json");
|
|
77744
|
+
const globalConfigPath = join61(PathResolver.getGlobalKitDir(), ".ck.json");
|
|
77674
77745
|
const configPath = existsSync49(projectConfigPath) ? projectConfigPath : existsSync49(globalConfigPath) ? globalConfigPath : null;
|
|
77675
77746
|
if (!configPath) {
|
|
77676
77747
|
return {
|
|
@@ -77794,7 +77865,7 @@ async function checkHookLogs(projectDir) {
|
|
|
77794
77865
|
autoFixable: false
|
|
77795
77866
|
};
|
|
77796
77867
|
}
|
|
77797
|
-
const logPath =
|
|
77868
|
+
const logPath = join61(hooksDir, ".logs", "hook-log.jsonl");
|
|
77798
77869
|
if (!existsSync49(logPath)) {
|
|
77799
77870
|
return {
|
|
77800
77871
|
id: "hook-logs",
|
|
@@ -78049,9 +78120,9 @@ async function checkCliVersion() {
|
|
|
78049
78120
|
}
|
|
78050
78121
|
async function checkPythonVenv(projectDir) {
|
|
78051
78122
|
const isWindows3 = process.platform === "win32";
|
|
78052
|
-
const venvBin = isWindows3 ?
|
|
78053
|
-
const projectVenvPath =
|
|
78054
|
-
const globalVenvPath =
|
|
78123
|
+
const venvBin = isWindows3 ? join61("Scripts", "python.exe") : join61("bin", "python3");
|
|
78124
|
+
const projectVenvPath = join61(projectDir, ".claude", "skills", ".venv", venvBin);
|
|
78125
|
+
const globalVenvPath = join61(PathResolver.getGlobalKitDir(), "skills", ".venv", venvBin);
|
|
78055
78126
|
const venvPath = existsSync49(projectVenvPath) ? projectVenvPath : existsSync49(globalVenvPath) ? globalVenvPath : null;
|
|
78056
78127
|
if (!venvPath) {
|
|
78057
78128
|
return {
|
|
@@ -78531,8 +78602,8 @@ import { platform as platform6 } from "node:os";
|
|
|
78531
78602
|
init_environment();
|
|
78532
78603
|
init_path_resolver();
|
|
78533
78604
|
import { constants as constants3, access as access3, mkdir as mkdir14, readFile as readFile33, unlink as unlink8, writeFile as writeFile17 } from "node:fs/promises";
|
|
78534
|
-
import { arch as arch2, homedir as
|
|
78535
|
-
import { join as
|
|
78605
|
+
import { arch as arch2, homedir as homedir29, platform as platform5 } from "node:os";
|
|
78606
|
+
import { join as join63, normalize as normalize6 } from "node:path";
|
|
78536
78607
|
function shouldSkipExpensiveOperations4() {
|
|
78537
78608
|
return shouldSkipExpensiveOperations();
|
|
78538
78609
|
}
|
|
@@ -78554,7 +78625,7 @@ async function checkPlatformDetect() {
|
|
|
78554
78625
|
};
|
|
78555
78626
|
}
|
|
78556
78627
|
async function checkHomeDirResolution() {
|
|
78557
|
-
const nodeHome = normalize6(
|
|
78628
|
+
const nodeHome = normalize6(homedir29());
|
|
78558
78629
|
const rawEnvHome = getHomeDirectoryFromEnv(platform5());
|
|
78559
78630
|
const envHome = rawEnvHome ? normalize6(rawEnvHome) : "";
|
|
78560
78631
|
const match = nodeHome === envHome && envHome !== "";
|
|
@@ -78623,7 +78694,7 @@ async function checkGlobalDirAccess() {
|
|
|
78623
78694
|
autoFixable: false
|
|
78624
78695
|
};
|
|
78625
78696
|
}
|
|
78626
|
-
const testFile =
|
|
78697
|
+
const testFile = join63(globalDir, ".ck-doctor-access-test");
|
|
78627
78698
|
try {
|
|
78628
78699
|
await mkdir14(globalDir, { recursive: true });
|
|
78629
78700
|
await writeFile17(testFile, "test", "utf-8");
|
|
@@ -78701,7 +78772,7 @@ async function checkWSLBoundary() {
|
|
|
78701
78772
|
// src/domains/health-checks/platform/windows-checker.ts
|
|
78702
78773
|
init_path_resolver();
|
|
78703
78774
|
import { mkdir as mkdir15, symlink, unlink as unlink9, writeFile as writeFile18 } from "node:fs/promises";
|
|
78704
|
-
import { join as
|
|
78775
|
+
import { join as join64 } from "node:path";
|
|
78705
78776
|
async function checkLongPathSupport() {
|
|
78706
78777
|
if (shouldSkipExpensiveOperations4()) {
|
|
78707
78778
|
return {
|
|
@@ -78753,8 +78824,8 @@ async function checkSymlinkSupport() {
|
|
|
78753
78824
|
};
|
|
78754
78825
|
}
|
|
78755
78826
|
const testDir = PathResolver.getGlobalKitDir();
|
|
78756
|
-
const target =
|
|
78757
|
-
const link =
|
|
78827
|
+
const target = join64(testDir, ".ck-symlink-test-target");
|
|
78828
|
+
const link = join64(testDir, ".ck-symlink-test-link");
|
|
78758
78829
|
try {
|
|
78759
78830
|
await mkdir15(testDir, { recursive: true });
|
|
78760
78831
|
await writeFile18(target, "test", "utf-8");
|
|
@@ -79048,7 +79119,7 @@ class AutoHealer {
|
|
|
79048
79119
|
import { execSync as execSync3, spawnSync as spawnSync5 } from "node:child_process";
|
|
79049
79120
|
import { readFileSync as readFileSync12, unlinkSync, writeFileSync as writeFileSync5 } from "node:fs";
|
|
79050
79121
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
79051
|
-
import { dirname as dirname20, join as
|
|
79122
|
+
import { dirname as dirname20, join as join65 } from "node:path";
|
|
79052
79123
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
79053
79124
|
init_environment();
|
|
79054
79125
|
init_logger();
|
|
@@ -79056,7 +79127,7 @@ init_dist2();
|
|
|
79056
79127
|
function getCliVersion4() {
|
|
79057
79128
|
try {
|
|
79058
79129
|
const __dirname4 = dirname20(fileURLToPath4(import.meta.url));
|
|
79059
|
-
const pkgPath =
|
|
79130
|
+
const pkgPath = join65(__dirname4, "../../../package.json");
|
|
79060
79131
|
const pkg = JSON.parse(readFileSync12(pkgPath, "utf-8"));
|
|
79061
79132
|
return pkg.version || "unknown";
|
|
79062
79133
|
} catch (err) {
|
|
@@ -79195,7 +79266,7 @@ class ReportGenerator {
|
|
|
79195
79266
|
return null;
|
|
79196
79267
|
}
|
|
79197
79268
|
}
|
|
79198
|
-
const tmpFile =
|
|
79269
|
+
const tmpFile = join65(tmpdir3(), `ck-report-${Date.now()}.txt`);
|
|
79199
79270
|
writeFileSync5(tmpFile, report);
|
|
79200
79271
|
try {
|
|
79201
79272
|
const result = spawnSync5("gh", ["gist", "create", tmpFile, "--desc", "ClaudeKit Diagnostic Report"], {
|
|
@@ -79521,7 +79592,7 @@ init_logger();
|
|
|
79521
79592
|
init_path_resolver();
|
|
79522
79593
|
var import_compare_versions6 = __toESM(require_umd(), 1);
|
|
79523
79594
|
import { mkdir as mkdir16, readFile as readFile34, unlink as unlink10, writeFile as writeFile19 } from "node:fs/promises";
|
|
79524
|
-
import { join as
|
|
79595
|
+
import { join as join66 } from "node:path";
|
|
79525
79596
|
var CACHE_TTL_HOURS = 24;
|
|
79526
79597
|
var DEFAULT_CACHE_TTL_MS = CACHE_TTL_HOURS * 60 * 60 * 1000;
|
|
79527
79598
|
var MIN_CACHE_TTL_MS = 60 * 1000;
|
|
@@ -79558,7 +79629,7 @@ var KIT_REPOS = {
|
|
|
79558
79629
|
class ConfigVersionChecker {
|
|
79559
79630
|
static getCacheFilePath(kitType, global3) {
|
|
79560
79631
|
const cacheDir = PathResolver.getCacheDir(global3);
|
|
79561
|
-
return
|
|
79632
|
+
return join66(cacheDir, `${kitType}-${CACHE_FILENAME}`);
|
|
79562
79633
|
}
|
|
79563
79634
|
static async loadCache(kitType, global3) {
|
|
79564
79635
|
try {
|
|
@@ -79721,7 +79792,7 @@ class ConfigVersionChecker {
|
|
|
79721
79792
|
}
|
|
79722
79793
|
// src/domains/sync/sync-engine.ts
|
|
79723
79794
|
import { lstat as lstat3, readFile as readFile35, readlink, realpath as realpath3, stat as stat9 } from "node:fs/promises";
|
|
79724
|
-
import { isAbsolute as isAbsolute3, join as
|
|
79795
|
+
import { isAbsolute as isAbsolute3, join as join67, normalize as normalize7, relative as relative8 } from "node:path";
|
|
79725
79796
|
|
|
79726
79797
|
// src/services/file-operations/ownership-checker.ts
|
|
79727
79798
|
init_metadata_migration();
|
|
@@ -81082,7 +81153,7 @@ async function validateSymlinkChain(path5, basePath, maxDepth = MAX_SYMLINK_DEPT
|
|
|
81082
81153
|
if (!stats.isSymbolicLink())
|
|
81083
81154
|
break;
|
|
81084
81155
|
const target = await readlink(current);
|
|
81085
|
-
const resolvedTarget = isAbsolute3(target) ? target :
|
|
81156
|
+
const resolvedTarget = isAbsolute3(target) ? target : join67(current, "..", target);
|
|
81086
81157
|
const normalizedTarget = normalize7(resolvedTarget);
|
|
81087
81158
|
const rel = relative8(basePath, normalizedTarget);
|
|
81088
81159
|
if (rel.startsWith("..") || isAbsolute3(rel)) {
|
|
@@ -81118,7 +81189,7 @@ async function validateSyncPath(basePath, filePath) {
|
|
|
81118
81189
|
if (normalized.startsWith("..") || normalized.includes("/../")) {
|
|
81119
81190
|
throw new Error(`Path traversal not allowed: ${filePath}`);
|
|
81120
81191
|
}
|
|
81121
|
-
const fullPath =
|
|
81192
|
+
const fullPath = join67(basePath, normalized);
|
|
81122
81193
|
const rel = relative8(basePath, fullPath);
|
|
81123
81194
|
if (rel.startsWith("..") || isAbsolute3(rel)) {
|
|
81124
81195
|
throw new Error(`Path escapes base directory: ${filePath}`);
|
|
@@ -81133,7 +81204,7 @@ async function validateSyncPath(basePath, filePath) {
|
|
|
81133
81204
|
}
|
|
81134
81205
|
} catch (error) {
|
|
81135
81206
|
if (error.code === "ENOENT") {
|
|
81136
|
-
const parentPath =
|
|
81207
|
+
const parentPath = join67(fullPath, "..");
|
|
81137
81208
|
try {
|
|
81138
81209
|
const resolvedBase = await realpath3(basePath);
|
|
81139
81210
|
const resolvedParent = await realpath3(parentPath);
|
|
@@ -82315,7 +82386,7 @@ init_logger();
|
|
|
82315
82386
|
var import_proper_lockfile4 = __toESM(require_proper_lockfile(), 1);
|
|
82316
82387
|
import { mkdir as mkdir19 } from "node:fs/promises";
|
|
82317
82388
|
import os5 from "node:os";
|
|
82318
|
-
import { join as
|
|
82389
|
+
import { join as join74 } from "node:path";
|
|
82319
82390
|
var LOCK_CONFIG = {
|
|
82320
82391
|
stale: 60000,
|
|
82321
82392
|
retries: 0
|
|
@@ -82323,12 +82394,12 @@ var LOCK_CONFIG = {
|
|
|
82323
82394
|
var activeLocks = new Set;
|
|
82324
82395
|
var cleanupRegistered = false;
|
|
82325
82396
|
function getLocksDir() {
|
|
82326
|
-
return
|
|
82397
|
+
return join74(os5.homedir(), ".claudekit", "locks");
|
|
82327
82398
|
}
|
|
82328
82399
|
function cleanupLocks() {
|
|
82329
82400
|
for (const name of activeLocks) {
|
|
82330
82401
|
try {
|
|
82331
|
-
const lockPath =
|
|
82402
|
+
const lockPath = join74(getLocksDir(), `${name}.lock`);
|
|
82332
82403
|
import_proper_lockfile4.default.unlockSync(lockPath, { realpath: false });
|
|
82333
82404
|
} catch {
|
|
82334
82405
|
try {
|
|
@@ -82351,7 +82422,7 @@ async function ensureLocksDir() {
|
|
|
82351
82422
|
async function withProcessLock(lockName, fn) {
|
|
82352
82423
|
registerCleanupHandlers();
|
|
82353
82424
|
await ensureLocksDir();
|
|
82354
|
-
const lockPath =
|
|
82425
|
+
const lockPath = join74(getLocksDir(), `${lockName}.lock`);
|
|
82355
82426
|
let release;
|
|
82356
82427
|
try {
|
|
82357
82428
|
release = await import_proper_lockfile4.default.lock(lockPath, { ...LOCK_CONFIG, realpath: false });
|
|
@@ -82383,7 +82454,7 @@ init_logger();
|
|
|
82383
82454
|
init_logger();
|
|
82384
82455
|
init_path_resolver();
|
|
82385
82456
|
var import_fs_extra7 = __toESM(require_lib3(), 1);
|
|
82386
|
-
import { join as
|
|
82457
|
+
import { join as join75 } from "node:path";
|
|
82387
82458
|
async function handleConflicts(ctx) {
|
|
82388
82459
|
if (ctx.cancelled)
|
|
82389
82460
|
return ctx;
|
|
@@ -82392,7 +82463,7 @@ async function handleConflicts(ctx) {
|
|
|
82392
82463
|
if (PathResolver.isLocalSameAsGlobal()) {
|
|
82393
82464
|
return ctx;
|
|
82394
82465
|
}
|
|
82395
|
-
const localSettingsPath =
|
|
82466
|
+
const localSettingsPath = join75(process.cwd(), ".claude", "settings.json");
|
|
82396
82467
|
if (!await import_fs_extra7.pathExists(localSettingsPath)) {
|
|
82397
82468
|
return ctx;
|
|
82398
82469
|
}
|
|
@@ -82407,7 +82478,7 @@ async function handleConflicts(ctx) {
|
|
|
82407
82478
|
return { ...ctx, cancelled: true };
|
|
82408
82479
|
}
|
|
82409
82480
|
if (choice === "remove") {
|
|
82410
|
-
const localClaudeDir =
|
|
82481
|
+
const localClaudeDir = join75(process.cwd(), ".claude");
|
|
82411
82482
|
try {
|
|
82412
82483
|
await import_fs_extra7.remove(localClaudeDir);
|
|
82413
82484
|
logger.success("Removed local .claude/ directory");
|
|
@@ -82504,7 +82575,7 @@ init_logger();
|
|
|
82504
82575
|
init_safe_spinner();
|
|
82505
82576
|
import { mkdir as mkdir25, stat as stat12 } from "node:fs/promises";
|
|
82506
82577
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
82507
|
-
import { join as
|
|
82578
|
+
import { join as join82 } from "node:path";
|
|
82508
82579
|
|
|
82509
82580
|
// src/shared/temp-cleanup.ts
|
|
82510
82581
|
init_logger();
|
|
@@ -82523,7 +82594,7 @@ init_logger();
|
|
|
82523
82594
|
init_output_manager();
|
|
82524
82595
|
import { createWriteStream as createWriteStream2, rmSync as rmSync2 } from "node:fs";
|
|
82525
82596
|
import { mkdir as mkdir20 } from "node:fs/promises";
|
|
82526
|
-
import { join as
|
|
82597
|
+
import { join as join76 } from "node:path";
|
|
82527
82598
|
|
|
82528
82599
|
// src/shared/progress-bar.ts
|
|
82529
82600
|
init_output_manager();
|
|
@@ -82733,7 +82804,7 @@ var MAX_DOWNLOAD_SIZE = 500 * 1024 * 1024;
|
|
|
82733
82804
|
class FileDownloader {
|
|
82734
82805
|
async downloadAsset(asset, destDir) {
|
|
82735
82806
|
try {
|
|
82736
|
-
const destPath =
|
|
82807
|
+
const destPath = join76(destDir, asset.name);
|
|
82737
82808
|
await mkdir20(destDir, { recursive: true });
|
|
82738
82809
|
output.info(`Downloading ${asset.name} (${formatBytes(asset.size)})...`);
|
|
82739
82810
|
logger.verbose("Download details", {
|
|
@@ -82818,7 +82889,7 @@ class FileDownloader {
|
|
|
82818
82889
|
}
|
|
82819
82890
|
async downloadFile(params) {
|
|
82820
82891
|
const { url, name, size, destDir, token } = params;
|
|
82821
|
-
const destPath =
|
|
82892
|
+
const destPath = join76(destDir, name);
|
|
82822
82893
|
await mkdir20(destDir, { recursive: true });
|
|
82823
82894
|
output.info(`Downloading ${name}${size ? ` (${formatBytes(size)})` : ""}...`);
|
|
82824
82895
|
const headers = {};
|
|
@@ -82904,7 +82975,7 @@ init_logger();
|
|
|
82904
82975
|
init_types3();
|
|
82905
82976
|
import { constants as constants4 } from "node:fs";
|
|
82906
82977
|
import { access as access4, readdir as readdir13 } from "node:fs/promises";
|
|
82907
|
-
import { join as
|
|
82978
|
+
import { join as join77 } from "node:path";
|
|
82908
82979
|
async function validateExtraction(extractDir) {
|
|
82909
82980
|
try {
|
|
82910
82981
|
const entries = await readdir13(extractDir, { encoding: "utf8" });
|
|
@@ -82916,7 +82987,7 @@ async function validateExtraction(extractDir) {
|
|
|
82916
82987
|
const missingPaths = [];
|
|
82917
82988
|
for (const path5 of criticalPaths) {
|
|
82918
82989
|
try {
|
|
82919
|
-
await access4(
|
|
82990
|
+
await access4(join77(extractDir, path5), constants4.F_OK);
|
|
82920
82991
|
logger.debug(`Found: ${path5}`);
|
|
82921
82992
|
} catch {
|
|
82922
82993
|
logger.warning(`Expected path not found: ${path5}`);
|
|
@@ -82937,8 +83008,8 @@ async function validateExtraction(extractDir) {
|
|
|
82937
83008
|
|
|
82938
83009
|
// src/domains/installation/extraction/tar-extractor.ts
|
|
82939
83010
|
init_logger();
|
|
82940
|
-
import { copyFile as copyFile4, mkdir as mkdir23, readdir as readdir15, rm as
|
|
82941
|
-
import { join as
|
|
83011
|
+
import { copyFile as copyFile4, mkdir as mkdir23, readdir as readdir15, rm as rm9, stat as stat10 } from "node:fs/promises";
|
|
83012
|
+
import { join as join80 } from "node:path";
|
|
82942
83013
|
|
|
82943
83014
|
// node_modules/@isaacs/fs-minipass/dist/esm/index.js
|
|
82944
83015
|
import EE from "events";
|
|
@@ -88700,7 +88771,7 @@ var mkdirSync3 = (dir, opt) => {
|
|
|
88700
88771
|
};
|
|
88701
88772
|
|
|
88702
88773
|
// node_modules/tar/dist/esm/path-reservations.js
|
|
88703
|
-
import { join as
|
|
88774
|
+
import { join as join78 } from "node:path";
|
|
88704
88775
|
|
|
88705
88776
|
// node_modules/tar/dist/esm/normalize-unicode.js
|
|
88706
88777
|
var normalizeCache = Object.create(null);
|
|
@@ -88733,7 +88804,7 @@ var getDirs = (path10) => {
|
|
|
88733
88804
|
const dirs = path10.split("/").slice(0, -1).reduce((set, path11) => {
|
|
88734
88805
|
const s = set[set.length - 1];
|
|
88735
88806
|
if (s !== undefined) {
|
|
88736
|
-
path11 =
|
|
88807
|
+
path11 = join78(s, path11);
|
|
88737
88808
|
}
|
|
88738
88809
|
set.push(path11 || "/");
|
|
88739
88810
|
return set;
|
|
@@ -88747,7 +88818,7 @@ class PathReservations {
|
|
|
88747
88818
|
#running = new Set;
|
|
88748
88819
|
reserve(paths, fn) {
|
|
88749
88820
|
paths = isWindows4 ? ["win32 parallelization disabled"] : paths.map((p) => {
|
|
88750
|
-
return stripTrailingSlashes(
|
|
88821
|
+
return stripTrailingSlashes(join78(normalizeUnicode(p))).toLowerCase();
|
|
88751
88822
|
});
|
|
88752
88823
|
const dirs = new Set(paths.map((path10) => getDirs(path10)).reduce((a3, b3) => a3.concat(b3)));
|
|
88753
88824
|
this.#reservations.set(fn, { dirs, paths });
|
|
@@ -89807,7 +89878,7 @@ function decodeFilePath(path12) {
|
|
|
89807
89878
|
init_logger();
|
|
89808
89879
|
init_types3();
|
|
89809
89880
|
import { copyFile as copyFile3, lstat as lstat4, mkdir as mkdir22, readdir as readdir14 } from "node:fs/promises";
|
|
89810
|
-
import { join as
|
|
89881
|
+
import { join as join79, relative as relative10 } from "node:path";
|
|
89811
89882
|
async function withRetry(fn, retries = 3) {
|
|
89812
89883
|
for (let i = 0;i < retries; i++) {
|
|
89813
89884
|
try {
|
|
@@ -89829,8 +89900,8 @@ async function moveDirectoryContents(sourceDir, destDir, shouldExclude, sizeTrac
|
|
|
89829
89900
|
await mkdir22(destDir, { recursive: true });
|
|
89830
89901
|
const entries = await readdir14(sourceDir, { encoding: "utf8" });
|
|
89831
89902
|
for (const entry of entries) {
|
|
89832
|
-
const sourcePath =
|
|
89833
|
-
const destPath =
|
|
89903
|
+
const sourcePath = join79(sourceDir, entry);
|
|
89904
|
+
const destPath = join79(destDir, entry);
|
|
89834
89905
|
const relativePath = relative10(sourceDir, sourcePath);
|
|
89835
89906
|
if (!isPathSafe(destDir, destPath)) {
|
|
89836
89907
|
logger.warning(`Skipping unsafe path: ${relativePath}`);
|
|
@@ -89857,8 +89928,8 @@ async function copyDirectory(sourceDir, destDir, shouldExclude, sizeTracker) {
|
|
|
89857
89928
|
await mkdir22(destDir, { recursive: true });
|
|
89858
89929
|
const entries = await readdir14(sourceDir, { encoding: "utf8" });
|
|
89859
89930
|
for (const entry of entries) {
|
|
89860
|
-
const sourcePath =
|
|
89861
|
-
const destPath =
|
|
89931
|
+
const sourcePath = join79(sourceDir, entry);
|
|
89932
|
+
const destPath = join79(destDir, entry);
|
|
89862
89933
|
const relativePath = relative10(sourceDir, sourcePath);
|
|
89863
89934
|
if (!isPathSafe(destDir, destPath)) {
|
|
89864
89935
|
logger.warning(`Skipping unsafe path: ${relativePath}`);
|
|
@@ -89906,7 +89977,7 @@ class TarExtractor {
|
|
|
89906
89977
|
logger.debug(`Root entries: ${entries.join(", ")}`);
|
|
89907
89978
|
if (entries.length === 1) {
|
|
89908
89979
|
const rootEntry = entries[0];
|
|
89909
|
-
const rootPath =
|
|
89980
|
+
const rootPath = join80(tempExtractDir, rootEntry);
|
|
89910
89981
|
const rootStat = await stat10(rootPath);
|
|
89911
89982
|
if (rootStat.isDirectory()) {
|
|
89912
89983
|
const rootContents = await readdir15(rootPath, { encoding: "utf8" });
|
|
@@ -89922,17 +89993,17 @@ class TarExtractor {
|
|
|
89922
89993
|
}
|
|
89923
89994
|
} else {
|
|
89924
89995
|
await mkdir23(destDir, { recursive: true });
|
|
89925
|
-
await copyFile4(rootPath,
|
|
89996
|
+
await copyFile4(rootPath, join80(destDir, rootEntry));
|
|
89926
89997
|
}
|
|
89927
89998
|
} else {
|
|
89928
89999
|
logger.debug("Multiple root entries - moving all");
|
|
89929
90000
|
await moveDirectoryContents(tempExtractDir, destDir, shouldExclude, sizeTracker);
|
|
89930
90001
|
}
|
|
89931
90002
|
logger.debug(`Moved contents to: ${destDir}`);
|
|
89932
|
-
await
|
|
90003
|
+
await rm9(tempExtractDir, { recursive: true, force: true });
|
|
89933
90004
|
} catch (error) {
|
|
89934
90005
|
try {
|
|
89935
|
-
await
|
|
90006
|
+
await rm9(tempExtractDir, { recursive: true, force: true });
|
|
89936
90007
|
} catch {}
|
|
89937
90008
|
throw error;
|
|
89938
90009
|
}
|
|
@@ -89944,8 +90015,8 @@ init_environment();
|
|
|
89944
90015
|
init_logger();
|
|
89945
90016
|
var import_extract_zip = __toESM(require_extract_zip(), 1);
|
|
89946
90017
|
import { execFile as execFile8 } from "node:child_process";
|
|
89947
|
-
import { copyFile as copyFile5, mkdir as mkdir24, readdir as readdir16, rm as
|
|
89948
|
-
import { join as
|
|
90018
|
+
import { copyFile as copyFile5, mkdir as mkdir24, readdir as readdir16, rm as rm10, stat as stat11 } from "node:fs/promises";
|
|
90019
|
+
import { join as join81 } from "node:path";
|
|
89949
90020
|
class ZipExtractor {
|
|
89950
90021
|
async tryNativeUnzip(archivePath, destDir) {
|
|
89951
90022
|
if (!isMacOS()) {
|
|
@@ -89993,7 +90064,7 @@ class ZipExtractor {
|
|
|
89993
90064
|
logger.debug(`Root entries: ${entries.join(", ")}`);
|
|
89994
90065
|
if (entries.length === 1) {
|
|
89995
90066
|
const rootEntry = entries[0];
|
|
89996
|
-
const rootPath =
|
|
90067
|
+
const rootPath = join81(tempExtractDir, rootEntry);
|
|
89997
90068
|
const rootStat = await stat11(rootPath);
|
|
89998
90069
|
if (rootStat.isDirectory()) {
|
|
89999
90070
|
const rootContents = await readdir16(rootPath, { encoding: "utf8" });
|
|
@@ -90009,17 +90080,17 @@ class ZipExtractor {
|
|
|
90009
90080
|
}
|
|
90010
90081
|
} else {
|
|
90011
90082
|
await mkdir24(destDir, { recursive: true });
|
|
90012
|
-
await copyFile5(rootPath,
|
|
90083
|
+
await copyFile5(rootPath, join81(destDir, rootEntry));
|
|
90013
90084
|
}
|
|
90014
90085
|
} else {
|
|
90015
90086
|
logger.debug("Multiple root entries - moving all");
|
|
90016
90087
|
await moveDirectoryContents(tempExtractDir, destDir, shouldExclude, sizeTracker);
|
|
90017
90088
|
}
|
|
90018
90089
|
logger.debug(`Moved contents to: ${destDir}`);
|
|
90019
|
-
await
|
|
90090
|
+
await rm10(tempExtractDir, { recursive: true, force: true });
|
|
90020
90091
|
} catch (error) {
|
|
90021
90092
|
try {
|
|
90022
|
-
await
|
|
90093
|
+
await rm10(tempExtractDir, { recursive: true, force: true });
|
|
90023
90094
|
} catch {}
|
|
90024
90095
|
throw error;
|
|
90025
90096
|
}
|
|
@@ -90108,7 +90179,7 @@ class DownloadManager {
|
|
|
90108
90179
|
async createTempDir() {
|
|
90109
90180
|
const timestamp = Date.now();
|
|
90110
90181
|
const counter = DownloadManager.tempDirCounter++;
|
|
90111
|
-
const primaryTempDir =
|
|
90182
|
+
const primaryTempDir = join82(tmpdir4(), `claudekit-${timestamp}-${counter}`);
|
|
90112
90183
|
try {
|
|
90113
90184
|
await mkdir25(primaryTempDir, { recursive: true });
|
|
90114
90185
|
logger.debug(`Created temp directory: ${primaryTempDir}`);
|
|
@@ -90125,7 +90196,7 @@ Solutions:
|
|
|
90125
90196
|
2. Set HOME environment variable
|
|
90126
90197
|
3. Try running from a different directory`);
|
|
90127
90198
|
}
|
|
90128
|
-
const fallbackTempDir =
|
|
90199
|
+
const fallbackTempDir = join82(homeDir, ".claudekit", "tmp", `claudekit-${timestamp}-${counter}`);
|
|
90129
90200
|
try {
|
|
90130
90201
|
await mkdir25(fallbackTempDir, { recursive: true });
|
|
90131
90202
|
logger.debug(`Created temp directory (fallback): ${fallbackTempDir}`);
|
|
@@ -90474,20 +90545,20 @@ async function handleDownload(ctx) {
|
|
|
90474
90545
|
};
|
|
90475
90546
|
}
|
|
90476
90547
|
// src/commands/init/phases/merge-handler.ts
|
|
90477
|
-
import { join as
|
|
90548
|
+
import { join as join98 } from "node:path";
|
|
90478
90549
|
|
|
90479
90550
|
// src/domains/installation/deletion-handler.ts
|
|
90480
90551
|
import { existsSync as existsSync55, lstatSync as lstatSync3, readdirSync as readdirSync4, rmSync as rmSync3, rmdirSync, unlinkSync as unlinkSync3 } from "node:fs";
|
|
90481
|
-
import { dirname as dirname24, join as
|
|
90552
|
+
import { dirname as dirname24, join as join85, relative as relative11, resolve as resolve20, sep as sep6 } from "node:path";
|
|
90482
90553
|
|
|
90483
90554
|
// src/services/file-operations/manifest/manifest-reader.ts
|
|
90484
90555
|
init_metadata_migration();
|
|
90485
90556
|
init_logger();
|
|
90486
90557
|
init_types3();
|
|
90487
90558
|
var import_fs_extra8 = __toESM(require_lib3(), 1);
|
|
90488
|
-
import { join as
|
|
90559
|
+
import { join as join84 } from "node:path";
|
|
90489
90560
|
async function readManifest(claudeDir2) {
|
|
90490
|
-
const metadataPath =
|
|
90561
|
+
const metadataPath = join84(claudeDir2, "metadata.json");
|
|
90491
90562
|
if (!await import_fs_extra8.pathExists(metadataPath)) {
|
|
90492
90563
|
return null;
|
|
90493
90564
|
}
|
|
@@ -90665,7 +90736,7 @@ function collectFilesRecursively(dir, baseDir) {
|
|
|
90665
90736
|
try {
|
|
90666
90737
|
const entries = readdirSync4(dir, { withFileTypes: true });
|
|
90667
90738
|
for (const entry of entries) {
|
|
90668
|
-
const fullPath =
|
|
90739
|
+
const fullPath = join85(dir, entry.name);
|
|
90669
90740
|
const relativePath = relative11(baseDir, fullPath);
|
|
90670
90741
|
if (entry.isDirectory()) {
|
|
90671
90742
|
results.push(...collectFilesRecursively(fullPath, baseDir));
|
|
@@ -90717,7 +90788,7 @@ function cleanupEmptyDirectories(filePath, claudeDir2) {
|
|
|
90717
90788
|
function deletePath(fullPath, claudeDir2) {
|
|
90718
90789
|
const normalizedPath = resolve20(fullPath);
|
|
90719
90790
|
const normalizedClaudeDir = resolve20(claudeDir2);
|
|
90720
|
-
if (!normalizedPath.startsWith(`${normalizedClaudeDir}${
|
|
90791
|
+
if (!normalizedPath.startsWith(`${normalizedClaudeDir}${sep6}`) && normalizedPath !== normalizedClaudeDir) {
|
|
90721
90792
|
throw new Error(`Path traversal detected: ${fullPath}`);
|
|
90722
90793
|
}
|
|
90723
90794
|
try {
|
|
@@ -90733,7 +90804,7 @@ function deletePath(fullPath, claudeDir2) {
|
|
|
90733
90804
|
}
|
|
90734
90805
|
}
|
|
90735
90806
|
async function updateMetadataAfterDeletion(claudeDir2, deletedPaths) {
|
|
90736
|
-
const metadataPath =
|
|
90807
|
+
const metadataPath = join85(claudeDir2, "metadata.json");
|
|
90737
90808
|
if (!await import_fs_extra9.pathExists(metadataPath)) {
|
|
90738
90809
|
return;
|
|
90739
90810
|
}
|
|
@@ -90788,10 +90859,10 @@ async function handleDeletions(sourceMetadata, claudeDir2) {
|
|
|
90788
90859
|
const userMetadata = await readManifest(claudeDir2);
|
|
90789
90860
|
const result = { deletedPaths: [], preservedPaths: [], errors: [] };
|
|
90790
90861
|
for (const path13 of deletions) {
|
|
90791
|
-
const fullPath =
|
|
90862
|
+
const fullPath = join85(claudeDir2, path13);
|
|
90792
90863
|
const normalizedPath = resolve20(fullPath);
|
|
90793
90864
|
const normalizedClaudeDir = resolve20(claudeDir2);
|
|
90794
|
-
if (!normalizedPath.startsWith(`${normalizedClaudeDir}${
|
|
90865
|
+
if (!normalizedPath.startsWith(`${normalizedClaudeDir}${sep6}`)) {
|
|
90795
90866
|
logger.warning(`Skipping invalid path: ${path13}`);
|
|
90796
90867
|
result.errors.push(path13);
|
|
90797
90868
|
continue;
|
|
@@ -90828,7 +90899,7 @@ init_logger();
|
|
|
90828
90899
|
init_types3();
|
|
90829
90900
|
var import_fs_extra12 = __toESM(require_lib3(), 1);
|
|
90830
90901
|
var import_ignore3 = __toESM(require_ignore(), 1);
|
|
90831
|
-
import { dirname as dirname26, join as
|
|
90902
|
+
import { dirname as dirname26, join as join88, relative as relative13 } from "node:path";
|
|
90832
90903
|
|
|
90833
90904
|
// src/domains/installation/selective-merger.ts
|
|
90834
90905
|
import { stat as stat13 } from "node:fs/promises";
|
|
@@ -91007,7 +91078,7 @@ init_logger();
|
|
|
91007
91078
|
var import_fs_extra10 = __toESM(require_lib3(), 1);
|
|
91008
91079
|
var import_ignore2 = __toESM(require_ignore(), 1);
|
|
91009
91080
|
import { relative as relative12 } from "node:path";
|
|
91010
|
-
import { join as
|
|
91081
|
+
import { join as join86 } from "node:path";
|
|
91011
91082
|
|
|
91012
91083
|
// node_modules/@isaacs/balanced-match/dist/esm/index.js
|
|
91013
91084
|
var balanced = (a3, b3, str2) => {
|
|
@@ -91814,8 +91885,8 @@ var path13 = {
|
|
|
91814
91885
|
win32: { sep: "\\" },
|
|
91815
91886
|
posix: { sep: "/" }
|
|
91816
91887
|
};
|
|
91817
|
-
var
|
|
91818
|
-
minimatch.sep =
|
|
91888
|
+
var sep7 = defaultPlatform === "win32" ? path13.win32.sep : path13.posix.sep;
|
|
91889
|
+
minimatch.sep = sep7;
|
|
91819
91890
|
var GLOBSTAR = Symbol("globstar **");
|
|
91820
91891
|
minimatch.GLOBSTAR = GLOBSTAR;
|
|
91821
91892
|
var qmark2 = "[^/]";
|
|
@@ -92463,7 +92534,7 @@ class FileScanner {
|
|
|
92463
92534
|
const files = [];
|
|
92464
92535
|
const entries = await import_fs_extra10.readdir(dir, { encoding: "utf8" });
|
|
92465
92536
|
for (const entry of entries) {
|
|
92466
|
-
const fullPath =
|
|
92537
|
+
const fullPath = join86(dir, entry);
|
|
92467
92538
|
const relativePath = relative12(baseDir, fullPath);
|
|
92468
92539
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
92469
92540
|
const stats = await import_fs_extra10.lstat(fullPath);
|
|
@@ -92503,7 +92574,7 @@ import { execSync as execSync4 } from "node:child_process";
|
|
|
92503
92574
|
init_shared();
|
|
92504
92575
|
import { existsSync as existsSync56 } from "node:fs";
|
|
92505
92576
|
import { mkdir as mkdir26, readFile as readFile39, writeFile as writeFile22 } from "node:fs/promises";
|
|
92506
|
-
import { dirname as dirname25, join as
|
|
92577
|
+
import { dirname as dirname25, join as join87 } from "node:path";
|
|
92507
92578
|
var CK_JSON_FILE = ".ck.json";
|
|
92508
92579
|
|
|
92509
92580
|
class InstalledSettingsTracker {
|
|
@@ -92517,9 +92588,9 @@ class InstalledSettingsTracker {
|
|
|
92517
92588
|
}
|
|
92518
92589
|
getCkJsonPath() {
|
|
92519
92590
|
if (this.isGlobal) {
|
|
92520
|
-
return
|
|
92591
|
+
return join87(this.projectDir, CK_JSON_FILE);
|
|
92521
92592
|
}
|
|
92522
|
-
return
|
|
92593
|
+
return join87(this.projectDir, ".claude", CK_JSON_FILE);
|
|
92523
92594
|
}
|
|
92524
92595
|
async loadInstalledSettings() {
|
|
92525
92596
|
const ckJsonPath = this.getCkJsonPath();
|
|
@@ -93136,7 +93207,7 @@ class CopyExecutor {
|
|
|
93136
93207
|
for (const file of files) {
|
|
93137
93208
|
const relativePath = relative13(sourceDir, file);
|
|
93138
93209
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
93139
|
-
const destPath =
|
|
93210
|
+
const destPath = join88(destDir, relativePath);
|
|
93140
93211
|
if (await import_fs_extra12.pathExists(destPath)) {
|
|
93141
93212
|
if (this.fileScanner.shouldNeverCopy(normalizedRelativePath)) {
|
|
93142
93213
|
logger.debug(`Security-sensitive file exists but won't be overwritten: ${normalizedRelativePath}`);
|
|
@@ -93158,7 +93229,7 @@ class CopyExecutor {
|
|
|
93158
93229
|
for (const file of files) {
|
|
93159
93230
|
const relativePath = relative13(sourceDir, file);
|
|
93160
93231
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
93161
|
-
const destPath =
|
|
93232
|
+
const destPath = join88(destDir, relativePath);
|
|
93162
93233
|
if (this.fileScanner.shouldNeverCopy(normalizedRelativePath)) {
|
|
93163
93234
|
logger.debug(`Skipping security-sensitive file: ${normalizedRelativePath}`);
|
|
93164
93235
|
skippedCount++;
|
|
@@ -93331,15 +93402,15 @@ class FileMerger {
|
|
|
93331
93402
|
|
|
93332
93403
|
// src/domains/migration/legacy-migration.ts
|
|
93333
93404
|
import { readdir as readdir18, stat as stat14 } from "node:fs/promises";
|
|
93334
|
-
import { join as
|
|
93405
|
+
import { join as join92, relative as relative14 } from "node:path";
|
|
93335
93406
|
// src/services/file-operations/manifest/manifest-tracker.ts
|
|
93336
|
-
import { join as
|
|
93407
|
+
import { join as join91 } from "node:path";
|
|
93337
93408
|
|
|
93338
93409
|
// src/domains/migration/release-manifest.ts
|
|
93339
93410
|
init_logger();
|
|
93340
93411
|
init_zod();
|
|
93341
93412
|
var import_fs_extra13 = __toESM(require_lib3(), 1);
|
|
93342
|
-
import { join as
|
|
93413
|
+
import { join as join89 } from "node:path";
|
|
93343
93414
|
var ReleaseManifestFileSchema = exports_external.object({
|
|
93344
93415
|
path: exports_external.string(),
|
|
93345
93416
|
checksum: exports_external.string().regex(/^[a-f0-9]{64}$/),
|
|
@@ -93354,7 +93425,7 @@ var ReleaseManifestSchema = exports_external.object({
|
|
|
93354
93425
|
|
|
93355
93426
|
class ReleaseManifestLoader {
|
|
93356
93427
|
static async load(extractDir) {
|
|
93357
|
-
const manifestPath =
|
|
93428
|
+
const manifestPath = join89(extractDir, "release-manifest.json");
|
|
93358
93429
|
try {
|
|
93359
93430
|
const content = await import_fs_extra13.readFile(manifestPath, "utf-8");
|
|
93360
93431
|
const parsed = JSON.parse(content);
|
|
@@ -93380,9 +93451,9 @@ init_logger();
|
|
|
93380
93451
|
init_types3();
|
|
93381
93452
|
var import_fs_extra14 = __toESM(require_lib3(), 1);
|
|
93382
93453
|
var import_proper_lockfile5 = __toESM(require_proper_lockfile(), 1);
|
|
93383
|
-
import { join as
|
|
93454
|
+
import { join as join90 } from "node:path";
|
|
93384
93455
|
async function writeManifest(claudeDir2, kitName, version, scope, kitType, trackedFiles, userConfigFiles) {
|
|
93385
|
-
const metadataPath =
|
|
93456
|
+
const metadataPath = join90(claudeDir2, "metadata.json");
|
|
93386
93457
|
const kit = kitType || (/\bmarketing\b/i.test(kitName) ? "marketing" : "engineer");
|
|
93387
93458
|
await import_fs_extra14.ensureFile(metadataPath);
|
|
93388
93459
|
let release = null;
|
|
@@ -93438,7 +93509,7 @@ async function writeManifest(claudeDir2, kitName, version, scope, kitType, track
|
|
|
93438
93509
|
}
|
|
93439
93510
|
}
|
|
93440
93511
|
async function removeKitFromManifest(claudeDir2, kit) {
|
|
93441
|
-
const metadataPath =
|
|
93512
|
+
const metadataPath = join90(claudeDir2, "metadata.json");
|
|
93442
93513
|
if (!await import_fs_extra14.pathExists(metadataPath))
|
|
93443
93514
|
return false;
|
|
93444
93515
|
let release = null;
|
|
@@ -93568,7 +93639,7 @@ function buildFileTrackingList(options2) {
|
|
|
93568
93639
|
if (!isGlobal && !installedPath.startsWith(".claude/"))
|
|
93569
93640
|
continue;
|
|
93570
93641
|
const relativePath = isGlobal ? installedPath : installedPath.replace(/^\.claude\//, "");
|
|
93571
|
-
const filePath =
|
|
93642
|
+
const filePath = join91(claudeDir2, relativePath);
|
|
93572
93643
|
const manifestEntry = releaseManifest ? ReleaseManifestLoader.findFile(releaseManifest, installedPath) : null;
|
|
93573
93644
|
const ownership = manifestEntry ? "ck" : "user";
|
|
93574
93645
|
filesToTrack.push({
|
|
@@ -93675,7 +93746,7 @@ class LegacyMigration {
|
|
|
93675
93746
|
continue;
|
|
93676
93747
|
if (SKIP_DIRS_ALL.includes(entry))
|
|
93677
93748
|
continue;
|
|
93678
|
-
const fullPath =
|
|
93749
|
+
const fullPath = join92(dir, entry);
|
|
93679
93750
|
let stats;
|
|
93680
93751
|
try {
|
|
93681
93752
|
stats = await stat14(fullPath);
|
|
@@ -93777,7 +93848,7 @@ User-created files (sample):`);
|
|
|
93777
93848
|
];
|
|
93778
93849
|
if (filesToChecksum.length > 0) {
|
|
93779
93850
|
const checksumResults = await mapWithLimit(filesToChecksum, async ({ relativePath, ownership }) => {
|
|
93780
|
-
const fullPath =
|
|
93851
|
+
const fullPath = join92(claudeDir2, relativePath);
|
|
93781
93852
|
const checksum = await OwnershipChecker.calculateChecksum(fullPath);
|
|
93782
93853
|
return { relativePath, checksum, ownership };
|
|
93783
93854
|
});
|
|
@@ -93798,7 +93869,7 @@ User-created files (sample):`);
|
|
|
93798
93869
|
installedAt: new Date().toISOString(),
|
|
93799
93870
|
files: trackedFiles
|
|
93800
93871
|
};
|
|
93801
|
-
const metadataPath =
|
|
93872
|
+
const metadataPath = join92(claudeDir2, "metadata.json");
|
|
93802
93873
|
await import_fs_extra15.writeFile(metadataPath, JSON.stringify(updatedMetadata, null, 2));
|
|
93803
93874
|
logger.success(`Migration complete: tracked ${trackedFiles.length} files`);
|
|
93804
93875
|
return true;
|
|
@@ -93904,7 +93975,7 @@ function buildConflictSummary(fileConflicts, hookConflicts, mcpConflicts) {
|
|
|
93904
93975
|
init_logger();
|
|
93905
93976
|
init_skip_directories();
|
|
93906
93977
|
var import_fs_extra16 = __toESM(require_lib3(), 1);
|
|
93907
|
-
import { join as
|
|
93978
|
+
import { join as join93, relative as relative15, resolve as resolve21 } from "node:path";
|
|
93908
93979
|
|
|
93909
93980
|
class FileScanner2 {
|
|
93910
93981
|
static async getFiles(dirPath, relativeTo) {
|
|
@@ -93920,7 +93991,7 @@ class FileScanner2 {
|
|
|
93920
93991
|
logger.debug(`Skipping directory: ${entry}`);
|
|
93921
93992
|
continue;
|
|
93922
93993
|
}
|
|
93923
|
-
const fullPath =
|
|
93994
|
+
const fullPath = join93(dirPath, entry);
|
|
93924
93995
|
if (!FileScanner2.isSafePath(basePath, fullPath)) {
|
|
93925
93996
|
logger.warning(`Skipping potentially unsafe path: ${entry}`);
|
|
93926
93997
|
continue;
|
|
@@ -93955,8 +94026,8 @@ class FileScanner2 {
|
|
|
93955
94026
|
return files;
|
|
93956
94027
|
}
|
|
93957
94028
|
static async findCustomFiles(destDir, sourceDir, subPath) {
|
|
93958
|
-
const destSubDir =
|
|
93959
|
-
const sourceSubDir =
|
|
94029
|
+
const destSubDir = join93(destDir, subPath);
|
|
94030
|
+
const sourceSubDir = join93(sourceDir, subPath);
|
|
93960
94031
|
logger.debug(`findCustomFiles - destDir: ${destDir}`);
|
|
93961
94032
|
logger.debug(`findCustomFiles - sourceDir: ${sourceDir}`);
|
|
93962
94033
|
logger.debug(`findCustomFiles - subPath: "${subPath}"`);
|
|
@@ -93997,12 +94068,12 @@ class FileScanner2 {
|
|
|
93997
94068
|
init_logger();
|
|
93998
94069
|
var import_fs_extra17 = __toESM(require_lib3(), 1);
|
|
93999
94070
|
import { lstat as lstat7, mkdir as mkdir27, readdir as readdir21, stat as stat15 } from "node:fs/promises";
|
|
94000
|
-
import { join as
|
|
94071
|
+
import { join as join95 } from "node:path";
|
|
94001
94072
|
|
|
94002
94073
|
// src/services/transformers/commands-prefix/content-transformer.ts
|
|
94003
94074
|
init_logger();
|
|
94004
94075
|
import { readFile as readFile43, readdir as readdir20, writeFile as writeFile26 } from "node:fs/promises";
|
|
94005
|
-
import { join as
|
|
94076
|
+
import { join as join94 } from "node:path";
|
|
94006
94077
|
var TRANSFORMABLE_EXTENSIONS = new Set([
|
|
94007
94078
|
".md",
|
|
94008
94079
|
".txt",
|
|
@@ -94063,7 +94134,7 @@ async function transformCommandReferences(directory, options2 = {}) {
|
|
|
94063
94134
|
async function processDirectory(dir) {
|
|
94064
94135
|
const entries = await readdir20(dir, { withFileTypes: true });
|
|
94065
94136
|
for (const entry of entries) {
|
|
94066
|
-
const fullPath =
|
|
94137
|
+
const fullPath = join94(dir, entry.name);
|
|
94067
94138
|
if (entry.isDirectory()) {
|
|
94068
94139
|
if (entry.name === "node_modules" || entry.name.startsWith(".") && entry.name !== ".claude") {
|
|
94069
94140
|
continue;
|
|
@@ -94138,14 +94209,14 @@ function shouldApplyPrefix(options2) {
|
|
|
94138
94209
|
// src/services/transformers/commands-prefix/prefix-applier.ts
|
|
94139
94210
|
async function applyPrefix(extractDir) {
|
|
94140
94211
|
validatePath(extractDir, "extractDir");
|
|
94141
|
-
const commandsDir =
|
|
94212
|
+
const commandsDir = join95(extractDir, ".claude", "commands");
|
|
94142
94213
|
if (!await import_fs_extra17.pathExists(commandsDir)) {
|
|
94143
94214
|
logger.verbose("No commands directory found, skipping prefix application");
|
|
94144
94215
|
return;
|
|
94145
94216
|
}
|
|
94146
94217
|
logger.info("Applying /ck: prefix to slash commands...");
|
|
94147
|
-
const backupDir =
|
|
94148
|
-
const tempDir =
|
|
94218
|
+
const backupDir = join95(extractDir, ".commands-backup");
|
|
94219
|
+
const tempDir = join95(extractDir, ".commands-prefix-temp");
|
|
94149
94220
|
try {
|
|
94150
94221
|
const entries = await readdir21(commandsDir);
|
|
94151
94222
|
if (entries.length === 0) {
|
|
@@ -94153,7 +94224,7 @@ async function applyPrefix(extractDir) {
|
|
|
94153
94224
|
return;
|
|
94154
94225
|
}
|
|
94155
94226
|
if (entries.length === 1 && entries[0] === "ck") {
|
|
94156
|
-
const ckDir2 =
|
|
94227
|
+
const ckDir2 = join95(commandsDir, "ck");
|
|
94157
94228
|
const ckStat = await stat15(ckDir2);
|
|
94158
94229
|
if (ckStat.isDirectory()) {
|
|
94159
94230
|
logger.verbose("Commands already have /ck: prefix, skipping");
|
|
@@ -94163,17 +94234,17 @@ async function applyPrefix(extractDir) {
|
|
|
94163
94234
|
await import_fs_extra17.copy(commandsDir, backupDir);
|
|
94164
94235
|
logger.verbose("Created backup of commands directory");
|
|
94165
94236
|
await mkdir27(tempDir, { recursive: true });
|
|
94166
|
-
const ckDir =
|
|
94237
|
+
const ckDir = join95(tempDir, "ck");
|
|
94167
94238
|
await mkdir27(ckDir, { recursive: true });
|
|
94168
94239
|
let processedCount = 0;
|
|
94169
94240
|
for (const entry of entries) {
|
|
94170
|
-
const sourcePath =
|
|
94241
|
+
const sourcePath = join95(commandsDir, entry);
|
|
94171
94242
|
const stats = await lstat7(sourcePath);
|
|
94172
94243
|
if (stats.isSymbolicLink()) {
|
|
94173
94244
|
logger.warning(`Skipping symlink for security: ${entry}`);
|
|
94174
94245
|
continue;
|
|
94175
94246
|
}
|
|
94176
|
-
const destPath =
|
|
94247
|
+
const destPath = join95(ckDir, entry);
|
|
94177
94248
|
await import_fs_extra17.copy(sourcePath, destPath, {
|
|
94178
94249
|
overwrite: false,
|
|
94179
94250
|
errorOnExist: true
|
|
@@ -94191,7 +94262,7 @@ async function applyPrefix(extractDir) {
|
|
|
94191
94262
|
await import_fs_extra17.move(tempDir, commandsDir);
|
|
94192
94263
|
await import_fs_extra17.remove(backupDir);
|
|
94193
94264
|
logger.success("Successfully reorganized commands to /ck: prefix");
|
|
94194
|
-
const claudeDir2 =
|
|
94265
|
+
const claudeDir2 = join95(extractDir, ".claude");
|
|
94195
94266
|
logger.info("Transforming command references in file contents...");
|
|
94196
94267
|
const transformResult = await transformCommandReferences(claudeDir2, {
|
|
94197
94268
|
verbose: logger.isVerbose()
|
|
@@ -94229,20 +94300,20 @@ async function applyPrefix(extractDir) {
|
|
|
94229
94300
|
// src/services/transformers/commands-prefix/prefix-cleaner.ts
|
|
94230
94301
|
init_metadata_migration();
|
|
94231
94302
|
import { lstat as lstat9, readdir as readdir23 } from "node:fs/promises";
|
|
94232
|
-
import { join as
|
|
94303
|
+
import { join as join97 } from "node:path";
|
|
94233
94304
|
init_logger();
|
|
94234
94305
|
var import_fs_extra19 = __toESM(require_lib3(), 1);
|
|
94235
94306
|
|
|
94236
94307
|
// src/services/transformers/commands-prefix/file-processor.ts
|
|
94237
94308
|
import { lstat as lstat8, readdir as readdir22 } from "node:fs/promises";
|
|
94238
|
-
import { join as
|
|
94309
|
+
import { join as join96 } from "node:path";
|
|
94239
94310
|
init_logger();
|
|
94240
94311
|
var import_fs_extra18 = __toESM(require_lib3(), 1);
|
|
94241
94312
|
async function scanDirectoryFiles(dir) {
|
|
94242
94313
|
const files = [];
|
|
94243
94314
|
const entries = await readdir22(dir);
|
|
94244
94315
|
for (const entry of entries) {
|
|
94245
|
-
const fullPath =
|
|
94316
|
+
const fullPath = join96(dir, entry);
|
|
94246
94317
|
const stats = await lstat8(fullPath);
|
|
94247
94318
|
if (stats.isSymbolicLink()) {
|
|
94248
94319
|
continue;
|
|
@@ -94370,8 +94441,8 @@ function isDifferentKitDirectory(dirName, currentKit) {
|
|
|
94370
94441
|
async function cleanupCommandsDirectory(targetDir, isGlobal, options2 = {}) {
|
|
94371
94442
|
const { dryRun = false } = options2;
|
|
94372
94443
|
validatePath(targetDir, "targetDir");
|
|
94373
|
-
const claudeDir2 = isGlobal ? targetDir :
|
|
94374
|
-
const commandsDir =
|
|
94444
|
+
const claudeDir2 = isGlobal ? targetDir : join97(targetDir, ".claude");
|
|
94445
|
+
const commandsDir = join97(claudeDir2, "commands");
|
|
94375
94446
|
const accumulator = {
|
|
94376
94447
|
results: [],
|
|
94377
94448
|
deletedCount: 0,
|
|
@@ -94413,7 +94484,7 @@ async function cleanupCommandsDirectory(targetDir, isGlobal, options2 = {}) {
|
|
|
94413
94484
|
}
|
|
94414
94485
|
const metadataForChecks = options2.kitType ? createKitSpecificMetadata(metadata, options2.kitType) : metadata;
|
|
94415
94486
|
for (const entry of entries) {
|
|
94416
|
-
const entryPath =
|
|
94487
|
+
const entryPath = join97(commandsDir, entry);
|
|
94417
94488
|
const stats = await lstat9(entryPath);
|
|
94418
94489
|
if (stats.isSymbolicLink()) {
|
|
94419
94490
|
addSymlinkSkip(entry, accumulator);
|
|
@@ -94470,7 +94541,7 @@ async function handleMerge(ctx) {
|
|
|
94470
94541
|
let customClaudeFiles = [];
|
|
94471
94542
|
if (!ctx.options.fresh) {
|
|
94472
94543
|
logger.info("Scanning for custom .claude files...");
|
|
94473
|
-
const scanSourceDir = ctx.options.global ?
|
|
94544
|
+
const scanSourceDir = ctx.options.global ? join98(ctx.extractDir, ".claude") : ctx.extractDir;
|
|
94474
94545
|
const scanTargetSubdir = ctx.options.global ? "" : ".claude";
|
|
94475
94546
|
customClaudeFiles = await FileScanner2.findCustomFiles(ctx.resolvedDir, scanSourceDir, scanTargetSubdir);
|
|
94476
94547
|
} else {
|
|
@@ -94535,8 +94606,8 @@ async function handleMerge(ctx) {
|
|
|
94535
94606
|
return { ...ctx, cancelled: true };
|
|
94536
94607
|
}
|
|
94537
94608
|
}
|
|
94538
|
-
const sourceDir = ctx.options.global ?
|
|
94539
|
-
const sourceMetadataPath = ctx.options.global ?
|
|
94609
|
+
const sourceDir = ctx.options.global ? join98(ctx.extractDir, ".claude") : ctx.extractDir;
|
|
94610
|
+
const sourceMetadataPath = ctx.options.global ? join98(sourceDir, "metadata.json") : join98(sourceDir, ".claude", "metadata.json");
|
|
94540
94611
|
let sourceMetadata = null;
|
|
94541
94612
|
try {
|
|
94542
94613
|
if (await import_fs_extra20.pathExists(sourceMetadataPath)) {
|
|
@@ -94593,7 +94664,7 @@ async function handleMerge(ctx) {
|
|
|
94593
94664
|
};
|
|
94594
94665
|
}
|
|
94595
94666
|
// src/commands/init/phases/migration-handler.ts
|
|
94596
|
-
import { join as
|
|
94667
|
+
import { join as join106 } from "node:path";
|
|
94597
94668
|
|
|
94598
94669
|
// src/domains/skills/skills-detector.ts
|
|
94599
94670
|
init_logger();
|
|
@@ -94609,7 +94680,7 @@ init_types3();
|
|
|
94609
94680
|
var import_fs_extra21 = __toESM(require_lib3(), 1);
|
|
94610
94681
|
import { createHash as createHash4 } from "node:crypto";
|
|
94611
94682
|
import { readFile as readFile45, readdir as readdir24, writeFile as writeFile27 } from "node:fs/promises";
|
|
94612
|
-
import { join as
|
|
94683
|
+
import { join as join99, relative as relative16 } from "node:path";
|
|
94613
94684
|
|
|
94614
94685
|
class SkillsManifestManager {
|
|
94615
94686
|
static MANIFEST_FILENAME = ".skills-manifest.json";
|
|
@@ -94631,12 +94702,12 @@ class SkillsManifestManager {
|
|
|
94631
94702
|
return manifest;
|
|
94632
94703
|
}
|
|
94633
94704
|
static async writeManifest(skillsDir2, manifest) {
|
|
94634
|
-
const manifestPath =
|
|
94705
|
+
const manifestPath = join99(skillsDir2, SkillsManifestManager.MANIFEST_FILENAME);
|
|
94635
94706
|
await writeFile27(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
94636
94707
|
logger.debug(`Wrote manifest to: ${manifestPath}`);
|
|
94637
94708
|
}
|
|
94638
94709
|
static async readManifest(skillsDir2) {
|
|
94639
|
-
const manifestPath =
|
|
94710
|
+
const manifestPath = join99(skillsDir2, SkillsManifestManager.MANIFEST_FILENAME);
|
|
94640
94711
|
if (!await import_fs_extra21.pathExists(manifestPath)) {
|
|
94641
94712
|
logger.debug(`No manifest found at: ${manifestPath}`);
|
|
94642
94713
|
return null;
|
|
@@ -94659,7 +94730,7 @@ class SkillsManifestManager {
|
|
|
94659
94730
|
return "flat";
|
|
94660
94731
|
}
|
|
94661
94732
|
for (const dir of dirs.slice(0, 3)) {
|
|
94662
|
-
const dirPath =
|
|
94733
|
+
const dirPath = join99(skillsDir2, dir.name);
|
|
94663
94734
|
const subEntries = await readdir24(dirPath, { withFileTypes: true });
|
|
94664
94735
|
const hasSubdirs = subEntries.some((entry) => entry.isDirectory());
|
|
94665
94736
|
if (hasSubdirs) {
|
|
@@ -94678,7 +94749,7 @@ class SkillsManifestManager {
|
|
|
94678
94749
|
const entries = await readdir24(skillsDir2, { withFileTypes: true });
|
|
94679
94750
|
for (const entry of entries) {
|
|
94680
94751
|
if (entry.isDirectory() && !BUILD_ARTIFACT_DIRS.includes(entry.name) && !entry.name.startsWith(".")) {
|
|
94681
|
-
const skillPath =
|
|
94752
|
+
const skillPath = join99(skillsDir2, entry.name);
|
|
94682
94753
|
const hash = await SkillsManifestManager.hashDirectory(skillPath);
|
|
94683
94754
|
skills.push({
|
|
94684
94755
|
name: entry.name,
|
|
@@ -94690,11 +94761,11 @@ class SkillsManifestManager {
|
|
|
94690
94761
|
const categories = await readdir24(skillsDir2, { withFileTypes: true });
|
|
94691
94762
|
for (const category of categories) {
|
|
94692
94763
|
if (category.isDirectory() && !BUILD_ARTIFACT_DIRS.includes(category.name) && !category.name.startsWith(".")) {
|
|
94693
|
-
const categoryPath =
|
|
94764
|
+
const categoryPath = join99(skillsDir2, category.name);
|
|
94694
94765
|
const skillEntries = await readdir24(categoryPath, { withFileTypes: true });
|
|
94695
94766
|
for (const skillEntry of skillEntries) {
|
|
94696
94767
|
if (skillEntry.isDirectory() && !skillEntry.name.startsWith(".")) {
|
|
94697
|
-
const skillPath =
|
|
94768
|
+
const skillPath = join99(categoryPath, skillEntry.name);
|
|
94698
94769
|
const hash = await SkillsManifestManager.hashDirectory(skillPath);
|
|
94699
94770
|
skills.push({
|
|
94700
94771
|
name: skillEntry.name,
|
|
@@ -94724,7 +94795,7 @@ class SkillsManifestManager {
|
|
|
94724
94795
|
const files = [];
|
|
94725
94796
|
const entries = await readdir24(dirPath, { withFileTypes: true });
|
|
94726
94797
|
for (const entry of entries) {
|
|
94727
|
-
const fullPath =
|
|
94798
|
+
const fullPath = join99(dirPath, entry.name);
|
|
94728
94799
|
if (entry.name.startsWith(".") || BUILD_ARTIFACT_DIRS.includes(entry.name)) {
|
|
94729
94800
|
continue;
|
|
94730
94801
|
}
|
|
@@ -94846,7 +94917,7 @@ function getPathMapping(skillName, oldBasePath, newBasePath) {
|
|
|
94846
94917
|
// src/domains/skills/detection/script-detector.ts
|
|
94847
94918
|
var import_fs_extra22 = __toESM(require_lib3(), 1);
|
|
94848
94919
|
import { readdir as readdir25 } from "node:fs/promises";
|
|
94849
|
-
import { join as
|
|
94920
|
+
import { join as join100 } from "node:path";
|
|
94850
94921
|
async function scanDirectory(skillsDir2) {
|
|
94851
94922
|
if (!await import_fs_extra22.pathExists(skillsDir2)) {
|
|
94852
94923
|
return ["flat", []];
|
|
@@ -94859,12 +94930,12 @@ async function scanDirectory(skillsDir2) {
|
|
|
94859
94930
|
let totalSkillLikeCount = 0;
|
|
94860
94931
|
const allSkills = [];
|
|
94861
94932
|
for (const dir of dirs) {
|
|
94862
|
-
const dirPath =
|
|
94933
|
+
const dirPath = join100(skillsDir2, dir.name);
|
|
94863
94934
|
const subEntries = await readdir25(dirPath, { withFileTypes: true });
|
|
94864
94935
|
const subdirs = subEntries.filter((entry) => entry.isDirectory() && !entry.name.startsWith("."));
|
|
94865
94936
|
if (subdirs.length > 0) {
|
|
94866
94937
|
for (const subdir of subdirs.slice(0, 3)) {
|
|
94867
|
-
const subdirPath =
|
|
94938
|
+
const subdirPath = join100(dirPath, subdir.name);
|
|
94868
94939
|
const subdirFiles = await readdir25(subdirPath, { withFileTypes: true });
|
|
94869
94940
|
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"));
|
|
94870
94941
|
if (hasSkillMarker) {
|
|
@@ -95021,12 +95092,12 @@ class SkillsMigrationDetector {
|
|
|
95021
95092
|
// src/domains/skills/skills-migrator.ts
|
|
95022
95093
|
init_logger();
|
|
95023
95094
|
init_types3();
|
|
95024
|
-
import { join as
|
|
95095
|
+
import { join as join105 } from "node:path";
|
|
95025
95096
|
|
|
95026
95097
|
// src/domains/skills/migrator/migration-executor.ts
|
|
95027
95098
|
init_logger();
|
|
95028
|
-
import { copyFile as copyFile6, mkdir as mkdir28, readdir as readdir26, rm as
|
|
95029
|
-
import { join as
|
|
95099
|
+
import { copyFile as copyFile6, mkdir as mkdir28, readdir as readdir26, rm as rm11 } from "node:fs/promises";
|
|
95100
|
+
import { join as join101 } from "node:path";
|
|
95030
95101
|
var import_fs_extra24 = __toESM(require_lib3(), 1);
|
|
95031
95102
|
|
|
95032
95103
|
// src/domains/skills/skills-migration-prompts.ts
|
|
@@ -95191,8 +95262,8 @@ async function copySkillDirectory(sourceDir, destDir) {
|
|
|
95191
95262
|
await mkdir28(destDir, { recursive: true });
|
|
95192
95263
|
const entries = await readdir26(sourceDir, { withFileTypes: true });
|
|
95193
95264
|
for (const entry of entries) {
|
|
95194
|
-
const sourcePath =
|
|
95195
|
-
const destPath =
|
|
95265
|
+
const sourcePath = join101(sourceDir, entry.name);
|
|
95266
|
+
const destPath = join101(destDir, entry.name);
|
|
95196
95267
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.isSymbolicLink()) {
|
|
95197
95268
|
continue;
|
|
95198
95269
|
}
|
|
@@ -95207,7 +95278,7 @@ async function executeInternal(mappings, customizations, currentSkillsDir, inter
|
|
|
95207
95278
|
const migrated = [];
|
|
95208
95279
|
const preserved = [];
|
|
95209
95280
|
const errors2 = [];
|
|
95210
|
-
const tempDir =
|
|
95281
|
+
const tempDir = join101(currentSkillsDir, "..", ".skills-migration-temp");
|
|
95211
95282
|
await mkdir28(tempDir, { recursive: true });
|
|
95212
95283
|
try {
|
|
95213
95284
|
for (const mapping of mappings) {
|
|
@@ -95228,9 +95299,9 @@ async function executeInternal(mappings, customizations, currentSkillsDir, inter
|
|
|
95228
95299
|
}
|
|
95229
95300
|
}
|
|
95230
95301
|
const category = mapping.category;
|
|
95231
|
-
const targetPath = category ?
|
|
95302
|
+
const targetPath = category ? join101(tempDir, category, skillName) : join101(tempDir, skillName);
|
|
95232
95303
|
if (category) {
|
|
95233
|
-
await mkdir28(
|
|
95304
|
+
await mkdir28(join101(tempDir, category), { recursive: true });
|
|
95234
95305
|
}
|
|
95235
95306
|
await copySkillDirectory(currentSkillPath, targetPath);
|
|
95236
95307
|
migrated.push(skillName);
|
|
@@ -95248,14 +95319,14 @@ async function executeInternal(mappings, customizations, currentSkillsDir, inter
|
|
|
95248
95319
|
logger.error(`Failed to migrate ${mapping.skillName}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
95249
95320
|
}
|
|
95250
95321
|
}
|
|
95251
|
-
await
|
|
95322
|
+
await rm11(currentSkillsDir, { recursive: true, force: true });
|
|
95252
95323
|
await mkdir28(currentSkillsDir, { recursive: true });
|
|
95253
95324
|
await copySkillDirectory(tempDir, currentSkillsDir);
|
|
95254
|
-
await
|
|
95325
|
+
await rm11(tempDir, { recursive: true, force: true });
|
|
95255
95326
|
return { migrated, preserved, errors: errors2 };
|
|
95256
95327
|
} catch (error) {
|
|
95257
95328
|
try {
|
|
95258
|
-
await
|
|
95329
|
+
await rm11(tempDir, { recursive: true, force: true });
|
|
95259
95330
|
} catch {}
|
|
95260
95331
|
throw error;
|
|
95261
95332
|
}
|
|
@@ -95296,8 +95367,8 @@ function validateMigrationPath(path14, paramName) {
|
|
|
95296
95367
|
init_logger();
|
|
95297
95368
|
init_types3();
|
|
95298
95369
|
var import_fs_extra25 = __toESM(require_lib3(), 1);
|
|
95299
|
-
import { copyFile as copyFile7, mkdir as mkdir29, readdir as readdir27, rm as
|
|
95300
|
-
import { basename as basename15, join as
|
|
95370
|
+
import { copyFile as copyFile7, mkdir as mkdir29, readdir as readdir27, rm as rm12, stat as stat16 } from "node:fs/promises";
|
|
95371
|
+
import { basename as basename15, join as join102, normalize as normalize8 } from "node:path";
|
|
95301
95372
|
function validatePath2(path14, paramName) {
|
|
95302
95373
|
if (!path14 || typeof path14 !== "string") {
|
|
95303
95374
|
throw new SkillsMigrationError(`${paramName} must be a non-empty string`);
|
|
@@ -95323,7 +95394,7 @@ class SkillsBackupManager {
|
|
|
95323
95394
|
const timestamp = Date.now();
|
|
95324
95395
|
const randomSuffix = Math.random().toString(36).substring(2, 8);
|
|
95325
95396
|
const backupDirName = `${SkillsBackupManager.BACKUP_PREFIX}${timestamp}-${randomSuffix}`;
|
|
95326
|
-
const backupDir = parentDir ?
|
|
95397
|
+
const backupDir = parentDir ? join102(parentDir, backupDirName) : join102(skillsDir2, "..", backupDirName);
|
|
95327
95398
|
logger.info(`Creating backup at: ${backupDir}`);
|
|
95328
95399
|
try {
|
|
95329
95400
|
await mkdir29(backupDir, { recursive: true });
|
|
@@ -95332,7 +95403,7 @@ class SkillsBackupManager {
|
|
|
95332
95403
|
return backupDir;
|
|
95333
95404
|
} catch (error) {
|
|
95334
95405
|
try {
|
|
95335
|
-
await
|
|
95406
|
+
await rm12(backupDir, { recursive: true, force: true });
|
|
95336
95407
|
} catch {}
|
|
95337
95408
|
throw new SkillsMigrationError(`Failed to create backup: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
95338
95409
|
}
|
|
@@ -95346,7 +95417,7 @@ class SkillsBackupManager {
|
|
|
95346
95417
|
logger.info(`Restoring from backup: ${backupDir}`);
|
|
95347
95418
|
try {
|
|
95348
95419
|
if (await import_fs_extra25.pathExists(targetDir)) {
|
|
95349
|
-
await
|
|
95420
|
+
await rm12(targetDir, { recursive: true, force: true });
|
|
95350
95421
|
}
|
|
95351
95422
|
await mkdir29(targetDir, { recursive: true });
|
|
95352
95423
|
await SkillsBackupManager.copyDirectory(backupDir, targetDir);
|
|
@@ -95362,7 +95433,7 @@ class SkillsBackupManager {
|
|
|
95362
95433
|
}
|
|
95363
95434
|
logger.debug(`Deleting backup: ${backupDir}`);
|
|
95364
95435
|
try {
|
|
95365
|
-
await
|
|
95436
|
+
await rm12(backupDir, { recursive: true, force: true });
|
|
95366
95437
|
logger.debug("Backup deleted successfully");
|
|
95367
95438
|
} catch (error) {
|
|
95368
95439
|
logger.warning(`Failed to delete backup: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
@@ -95374,7 +95445,7 @@ class SkillsBackupManager {
|
|
|
95374
95445
|
}
|
|
95375
95446
|
try {
|
|
95376
95447
|
const entries = await readdir27(parentDir, { withFileTypes: true });
|
|
95377
|
-
const backups = entries.filter((entry) => entry.isDirectory() && entry.name.startsWith(SkillsBackupManager.BACKUP_PREFIX)).map((entry) =>
|
|
95448
|
+
const backups = entries.filter((entry) => entry.isDirectory() && entry.name.startsWith(SkillsBackupManager.BACKUP_PREFIX)).map((entry) => join102(parentDir, entry.name));
|
|
95378
95449
|
backups.sort().reverse();
|
|
95379
95450
|
return backups;
|
|
95380
95451
|
} catch (error) {
|
|
@@ -95402,8 +95473,8 @@ class SkillsBackupManager {
|
|
|
95402
95473
|
static async copyDirectory(sourceDir, destDir) {
|
|
95403
95474
|
const entries = await readdir27(sourceDir, { withFileTypes: true });
|
|
95404
95475
|
for (const entry of entries) {
|
|
95405
|
-
const sourcePath =
|
|
95406
|
-
const destPath =
|
|
95476
|
+
const sourcePath = join102(sourceDir, entry.name);
|
|
95477
|
+
const destPath = join102(destDir, entry.name);
|
|
95407
95478
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.isSymbolicLink()) {
|
|
95408
95479
|
continue;
|
|
95409
95480
|
}
|
|
@@ -95419,7 +95490,7 @@ class SkillsBackupManager {
|
|
|
95419
95490
|
let size = 0;
|
|
95420
95491
|
const entries = await readdir27(dirPath, { withFileTypes: true });
|
|
95421
95492
|
for (const entry of entries) {
|
|
95422
|
-
const fullPath =
|
|
95493
|
+
const fullPath = join102(dirPath, entry.name);
|
|
95423
95494
|
if (entry.isSymbolicLink()) {
|
|
95424
95495
|
continue;
|
|
95425
95496
|
}
|
|
@@ -95455,12 +95526,12 @@ init_skip_directories();
|
|
|
95455
95526
|
import { createHash as createHash5 } from "node:crypto";
|
|
95456
95527
|
import { createReadStream as createReadStream3 } from "node:fs";
|
|
95457
95528
|
import { readFile as readFile46, readdir as readdir28 } from "node:fs/promises";
|
|
95458
|
-
import { join as
|
|
95529
|
+
import { join as join103, relative as relative17 } from "node:path";
|
|
95459
95530
|
async function getAllFiles(dirPath) {
|
|
95460
95531
|
const files = [];
|
|
95461
95532
|
const entries = await readdir28(dirPath, { withFileTypes: true });
|
|
95462
95533
|
for (const entry of entries) {
|
|
95463
|
-
const fullPath =
|
|
95534
|
+
const fullPath = join103(dirPath, entry.name);
|
|
95464
95535
|
if (entry.name.startsWith(".") || BUILD_ARTIFACT_DIRS.includes(entry.name) || entry.isSymbolicLink()) {
|
|
95465
95536
|
continue;
|
|
95466
95537
|
}
|
|
@@ -95587,7 +95658,7 @@ async function detectFileChanges(currentSkillPath, baselineSkillPath) {
|
|
|
95587
95658
|
init_types3();
|
|
95588
95659
|
var import_fs_extra27 = __toESM(require_lib3(), 1);
|
|
95589
95660
|
import { readdir as readdir29 } from "node:fs/promises";
|
|
95590
|
-
import { join as
|
|
95661
|
+
import { join as join104, normalize as normalize9 } from "node:path";
|
|
95591
95662
|
function validatePath3(path14, paramName) {
|
|
95592
95663
|
if (!path14 || typeof path14 !== "string") {
|
|
95593
95664
|
throw new SkillsMigrationError(`${paramName} must be a non-empty string`);
|
|
@@ -95608,13 +95679,13 @@ async function scanSkillsDirectory(skillsDir2) {
|
|
|
95608
95679
|
if (dirs.length === 0) {
|
|
95609
95680
|
return ["flat", []];
|
|
95610
95681
|
}
|
|
95611
|
-
const firstDirPath =
|
|
95682
|
+
const firstDirPath = join104(skillsDir2, dirs[0].name);
|
|
95612
95683
|
const subEntries = await readdir29(firstDirPath, { withFileTypes: true });
|
|
95613
95684
|
const subdirs = subEntries.filter((entry) => entry.isDirectory() && !entry.name.startsWith("."));
|
|
95614
95685
|
if (subdirs.length > 0) {
|
|
95615
95686
|
let skillLikeCount = 0;
|
|
95616
95687
|
for (const subdir of subdirs.slice(0, 3)) {
|
|
95617
|
-
const subdirPath =
|
|
95688
|
+
const subdirPath = join104(firstDirPath, subdir.name);
|
|
95618
95689
|
const subdirFiles = await readdir29(subdirPath, { withFileTypes: true });
|
|
95619
95690
|
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"));
|
|
95620
95691
|
if (hasSkillMarker) {
|
|
@@ -95624,7 +95695,7 @@ async function scanSkillsDirectory(skillsDir2) {
|
|
|
95624
95695
|
if (skillLikeCount > 0) {
|
|
95625
95696
|
const skills = [];
|
|
95626
95697
|
for (const dir of dirs) {
|
|
95627
|
-
const categoryPath =
|
|
95698
|
+
const categoryPath = join104(skillsDir2, dir.name);
|
|
95628
95699
|
const skillDirs = await readdir29(categoryPath, { withFileTypes: true });
|
|
95629
95700
|
skills.push(...skillDirs.filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name));
|
|
95630
95701
|
}
|
|
@@ -95634,7 +95705,7 @@ async function scanSkillsDirectory(skillsDir2) {
|
|
|
95634
95705
|
return ["flat", dirs.map((dir) => dir.name)];
|
|
95635
95706
|
}
|
|
95636
95707
|
async function findSkillPath(skillsDir2, skillName) {
|
|
95637
|
-
const flatPath =
|
|
95708
|
+
const flatPath = join104(skillsDir2, skillName);
|
|
95638
95709
|
if (await import_fs_extra27.pathExists(flatPath)) {
|
|
95639
95710
|
return { path: flatPath, category: undefined };
|
|
95640
95711
|
}
|
|
@@ -95643,8 +95714,8 @@ async function findSkillPath(skillsDir2, skillName) {
|
|
|
95643
95714
|
if (!entry.isDirectory() || entry.name.startsWith(".") || entry.name === "node_modules") {
|
|
95644
95715
|
continue;
|
|
95645
95716
|
}
|
|
95646
|
-
const categoryPath =
|
|
95647
|
-
const skillPath =
|
|
95717
|
+
const categoryPath = join104(skillsDir2, entry.name);
|
|
95718
|
+
const skillPath = join104(categoryPath, skillName);
|
|
95648
95719
|
if (await import_fs_extra27.pathExists(skillPath)) {
|
|
95649
95720
|
return { path: skillPath, category: entry.name };
|
|
95650
95721
|
}
|
|
@@ -95738,7 +95809,7 @@ class SkillsMigrator {
|
|
|
95738
95809
|
}
|
|
95739
95810
|
}
|
|
95740
95811
|
if (options2.backup && !options2.dryRun) {
|
|
95741
|
-
const claudeDir2 =
|
|
95812
|
+
const claudeDir2 = join105(currentSkillsDir, "..");
|
|
95742
95813
|
result.backupPath = await SkillsBackupManager.createBackup(currentSkillsDir, claudeDir2);
|
|
95743
95814
|
logger.success(`Backup created at: ${result.backupPath}`);
|
|
95744
95815
|
}
|
|
@@ -95799,7 +95870,7 @@ async function handleMigration(ctx) {
|
|
|
95799
95870
|
logger.debug("Skipping skills migration (fresh installation)");
|
|
95800
95871
|
return ctx;
|
|
95801
95872
|
}
|
|
95802
|
-
const newSkillsDir =
|
|
95873
|
+
const newSkillsDir = join106(ctx.extractDir, ".claude", "skills");
|
|
95803
95874
|
const currentSkillsDir = PathResolver.buildSkillsPath(ctx.resolvedDir, ctx.options.global);
|
|
95804
95875
|
if (!await import_fs_extra28.pathExists(newSkillsDir) || !await import_fs_extra28.pathExists(currentSkillsDir)) {
|
|
95805
95876
|
return ctx;
|
|
@@ -95822,14 +95893,14 @@ async function handleMigration(ctx) {
|
|
|
95822
95893
|
return ctx;
|
|
95823
95894
|
}
|
|
95824
95895
|
// src/commands/init/phases/opencode-handler.ts
|
|
95825
|
-
import { cp as cp3, readdir as readdir31, rm as
|
|
95826
|
-
import { join as
|
|
95896
|
+
import { cp as cp3, readdir as readdir31, rm as rm13 } from "node:fs/promises";
|
|
95897
|
+
import { join as join108 } from "node:path";
|
|
95827
95898
|
|
|
95828
95899
|
// src/services/transformers/opencode-path-transformer.ts
|
|
95829
95900
|
init_logger();
|
|
95830
95901
|
import { readFile as readFile47, readdir as readdir30, writeFile as writeFile28 } from "node:fs/promises";
|
|
95831
95902
|
import { platform as platform12 } from "node:os";
|
|
95832
|
-
import { extname as extname6, join as
|
|
95903
|
+
import { extname as extname6, join as join107 } from "node:path";
|
|
95833
95904
|
var IS_WINDOWS2 = platform12() === "win32";
|
|
95834
95905
|
function getOpenCodeGlobalPath() {
|
|
95835
95906
|
return "$HOME/.config/opencode/";
|
|
@@ -95890,7 +95961,7 @@ async function transformPathsForGlobalOpenCode(directory, options2 = {}) {
|
|
|
95890
95961
|
async function processDirectory2(dir) {
|
|
95891
95962
|
const entries = await readdir30(dir, { withFileTypes: true });
|
|
95892
95963
|
for (const entry of entries) {
|
|
95893
|
-
const fullPath =
|
|
95964
|
+
const fullPath = join107(dir, entry.name);
|
|
95894
95965
|
if (entry.isDirectory()) {
|
|
95895
95966
|
if (entry.name === "node_modules" || entry.name.startsWith(".")) {
|
|
95896
95967
|
continue;
|
|
@@ -95929,7 +96000,7 @@ async function handleOpenCode(ctx) {
|
|
|
95929
96000
|
if (ctx.cancelled || !ctx.extractDir || !ctx.resolvedDir) {
|
|
95930
96001
|
return ctx;
|
|
95931
96002
|
}
|
|
95932
|
-
const openCodeSource =
|
|
96003
|
+
const openCodeSource = join108(ctx.extractDir, ".opencode");
|
|
95933
96004
|
if (!await import_fs_extra29.pathExists(openCodeSource)) {
|
|
95934
96005
|
logger.debug("No .opencode directory in archive, skipping");
|
|
95935
96006
|
return ctx;
|
|
@@ -95947,8 +96018,8 @@ async function handleOpenCode(ctx) {
|
|
|
95947
96018
|
await import_fs_extra29.ensureDir(targetDir);
|
|
95948
96019
|
const entries = await readdir31(openCodeSource, { withFileTypes: true });
|
|
95949
96020
|
for (const entry of entries) {
|
|
95950
|
-
const sourcePath =
|
|
95951
|
-
const targetPath =
|
|
96021
|
+
const sourcePath = join108(openCodeSource, entry.name);
|
|
96022
|
+
const targetPath = join108(targetDir, entry.name);
|
|
95952
96023
|
if (await import_fs_extra29.pathExists(targetPath)) {
|
|
95953
96024
|
if (!ctx.options.forceOverwrite) {
|
|
95954
96025
|
logger.verbose(`Skipping existing: ${entry.name}`);
|
|
@@ -95958,7 +96029,7 @@ async function handleOpenCode(ctx) {
|
|
|
95958
96029
|
await cp3(sourcePath, targetPath, { recursive: true });
|
|
95959
96030
|
logger.verbose(`Copied: ${entry.name}`);
|
|
95960
96031
|
}
|
|
95961
|
-
await
|
|
96032
|
+
await rm13(openCodeSource, { recursive: true, force: true });
|
|
95962
96033
|
logger.success(`OpenCode config installed to ${targetDir}`);
|
|
95963
96034
|
} else {
|
|
95964
96035
|
logger.debug("Local mode: .opencode will be placed at project root");
|
|
@@ -95980,6 +96051,7 @@ async function resolveOptions(ctx) {
|
|
|
95980
96051
|
global: parsed.global ?? false,
|
|
95981
96052
|
yes: parsed.yes ?? false,
|
|
95982
96053
|
fresh: parsed.fresh ?? false,
|
|
96054
|
+
force: parsed.force ?? false,
|
|
95983
96055
|
refresh: parsed.refresh ?? false,
|
|
95984
96056
|
exclude: parsed.exclude ?? [],
|
|
95985
96057
|
only: parsed.only ?? [],
|
|
@@ -96045,7 +96117,7 @@ Please use only one download method.`);
|
|
|
96045
96117
|
}
|
|
96046
96118
|
// src/commands/init/phases/post-install-handler.ts
|
|
96047
96119
|
init_projects_registry();
|
|
96048
|
-
import { join as
|
|
96120
|
+
import { join as join109 } from "node:path";
|
|
96049
96121
|
init_logger();
|
|
96050
96122
|
init_path_resolver();
|
|
96051
96123
|
var import_fs_extra30 = __toESM(require_lib3(), 1);
|
|
@@ -96164,8 +96236,8 @@ async function handlePostInstall(ctx) {
|
|
|
96164
96236
|
return ctx;
|
|
96165
96237
|
}
|
|
96166
96238
|
if (ctx.options.global) {
|
|
96167
|
-
const claudeMdSource =
|
|
96168
|
-
const claudeMdDest =
|
|
96239
|
+
const claudeMdSource = join109(ctx.extractDir, "CLAUDE.md");
|
|
96240
|
+
const claudeMdDest = join109(ctx.resolvedDir, "CLAUDE.md");
|
|
96169
96241
|
if (await import_fs_extra30.pathExists(claudeMdSource)) {
|
|
96170
96242
|
if (ctx.options.fresh || !await import_fs_extra30.pathExists(claudeMdDest)) {
|
|
96171
96243
|
await import_fs_extra30.copy(claudeMdSource, claudeMdDest);
|
|
@@ -96213,7 +96285,7 @@ async function handlePostInstall(ctx) {
|
|
|
96213
96285
|
}
|
|
96214
96286
|
if (!ctx.options.skipSetup) {
|
|
96215
96287
|
await promptSetupWizardIfNeeded({
|
|
96216
|
-
envPath:
|
|
96288
|
+
envPath: join109(ctx.claudeDir, ".env"),
|
|
96217
96289
|
claudeDir: ctx.claudeDir,
|
|
96218
96290
|
isGlobal: ctx.options.global,
|
|
96219
96291
|
isNonInteractive: ctx.isNonInteractive,
|
|
@@ -96238,7 +96310,7 @@ async function handlePostInstall(ctx) {
|
|
|
96238
96310
|
init_config_manager();
|
|
96239
96311
|
init_github_client();
|
|
96240
96312
|
import { mkdir as mkdir30 } from "node:fs/promises";
|
|
96241
|
-
import { join as
|
|
96313
|
+
import { join as join111, resolve as resolve23 } from "node:path";
|
|
96242
96314
|
|
|
96243
96315
|
// src/domains/github/kit-access-checker.ts
|
|
96244
96316
|
init_logger();
|
|
@@ -96369,7 +96441,7 @@ async function runPreflightChecks() {
|
|
|
96369
96441
|
// src/domains/installation/fresh-installer.ts
|
|
96370
96442
|
init_metadata_migration();
|
|
96371
96443
|
import { existsSync as existsSync57, readdirSync as readdirSync5, rmSync as rmSync4, rmdirSync as rmdirSync2, unlinkSync as unlinkSync4 } from "node:fs";
|
|
96372
|
-
import { dirname as dirname27, join as
|
|
96444
|
+
import { dirname as dirname27, join as join110, resolve as resolve22 } from "node:path";
|
|
96373
96445
|
init_logger();
|
|
96374
96446
|
init_safe_spinner();
|
|
96375
96447
|
var import_fs_extra31 = __toESM(require_lib3(), 1);
|
|
@@ -96442,7 +96514,7 @@ async function removeFilesByOwnership(claudeDir2, analysis, includeModified) {
|
|
|
96442
96514
|
const filesToRemove = includeModified ? [...analysis.ckFiles, ...analysis.ckModifiedFiles] : analysis.ckFiles;
|
|
96443
96515
|
const filesToPreserve = includeModified ? analysis.userFiles : [...analysis.ckModifiedFiles, ...analysis.userFiles];
|
|
96444
96516
|
for (const file of filesToRemove) {
|
|
96445
|
-
const fullPath =
|
|
96517
|
+
const fullPath = join110(claudeDir2, file.path);
|
|
96446
96518
|
try {
|
|
96447
96519
|
if (existsSync57(fullPath)) {
|
|
96448
96520
|
unlinkSync4(fullPath);
|
|
@@ -96467,7 +96539,7 @@ async function removeFilesByOwnership(claudeDir2, analysis, includeModified) {
|
|
|
96467
96539
|
};
|
|
96468
96540
|
}
|
|
96469
96541
|
async function updateMetadataAfterFresh(claudeDir2, removedFiles) {
|
|
96470
|
-
const metadataPath =
|
|
96542
|
+
const metadataPath = join110(claudeDir2, "metadata.json");
|
|
96471
96543
|
if (!await import_fs_extra31.pathExists(metadataPath)) {
|
|
96472
96544
|
return;
|
|
96473
96545
|
}
|
|
@@ -96510,7 +96582,7 @@ async function removeSubdirectoriesFallback(claudeDir2) {
|
|
|
96510
96582
|
const removedFiles = [];
|
|
96511
96583
|
let removedDirCount = 0;
|
|
96512
96584
|
for (const subdir of CLAUDEKIT_SUBDIRECTORIES) {
|
|
96513
|
-
const subdirPath =
|
|
96585
|
+
const subdirPath = join110(claudeDir2, subdir);
|
|
96514
96586
|
if (await import_fs_extra31.pathExists(subdirPath)) {
|
|
96515
96587
|
rmSync4(subdirPath, { recursive: true, force: true });
|
|
96516
96588
|
removedDirCount++;
|
|
@@ -96518,7 +96590,7 @@ async function removeSubdirectoriesFallback(claudeDir2) {
|
|
|
96518
96590
|
logger.debug(`Removed subdirectory: ${subdir}/`);
|
|
96519
96591
|
}
|
|
96520
96592
|
}
|
|
96521
|
-
const metadataPath =
|
|
96593
|
+
const metadataPath = join110(claudeDir2, "metadata.json");
|
|
96522
96594
|
if (await import_fs_extra31.pathExists(metadataPath)) {
|
|
96523
96595
|
unlinkSync4(metadataPath);
|
|
96524
96596
|
removedFiles.push("metadata.json");
|
|
@@ -96771,7 +96843,7 @@ async function handleSelection(ctx) {
|
|
|
96771
96843
|
}
|
|
96772
96844
|
if (!ctx.options.fresh) {
|
|
96773
96845
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
96774
|
-
const claudeDir2 = prefix ?
|
|
96846
|
+
const claudeDir2 = prefix ? join111(resolvedDir, prefix) : resolvedDir;
|
|
96775
96847
|
try {
|
|
96776
96848
|
const existingMetadata = await readManifest(claudeDir2);
|
|
96777
96849
|
if (existingMetadata?.kits) {
|
|
@@ -96803,7 +96875,7 @@ async function handleSelection(ctx) {
|
|
|
96803
96875
|
}
|
|
96804
96876
|
if (ctx.options.fresh) {
|
|
96805
96877
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
96806
|
-
const claudeDir2 = prefix ?
|
|
96878
|
+
const claudeDir2 = prefix ? join111(resolvedDir, prefix) : resolvedDir;
|
|
96807
96879
|
const canProceed = await handleFreshInstallation(claudeDir2, ctx.prompts);
|
|
96808
96880
|
if (!canProceed) {
|
|
96809
96881
|
return { ...ctx, cancelled: true };
|
|
@@ -96822,7 +96894,7 @@ async function handleSelection(ctx) {
|
|
|
96822
96894
|
logger.info("Fetching available versions...");
|
|
96823
96895
|
let currentVersion = null;
|
|
96824
96896
|
try {
|
|
96825
|
-
const metadataPath = ctx.options.global ?
|
|
96897
|
+
const metadataPath = ctx.options.global ? join111(PathResolver.getGlobalKitDir(), "metadata.json") : join111(resolvedDir, ".claude", "metadata.json");
|
|
96826
96898
|
const metadata = await readClaudeKitMetadata(metadataPath);
|
|
96827
96899
|
currentVersion = metadata?.version || null;
|
|
96828
96900
|
if (currentVersion) {
|
|
@@ -96884,11 +96956,14 @@ async function handleSelection(ctx) {
|
|
|
96884
96956
|
logger.success(`Found: ${release.tag_name}`);
|
|
96885
96957
|
}
|
|
96886
96958
|
}
|
|
96959
|
+
if (ctx.options.force && !ctx.options.yes) {
|
|
96960
|
+
logger.info("--force has no effect without --yes (the version-match skip only applies in non-interactive mode)");
|
|
96961
|
+
}
|
|
96887
96962
|
const releaseTag = release?.tag_name;
|
|
96888
|
-
if (ctx.options.yes && !ctx.options.fresh && releaseTag && !isOfflineMode && !pendingKits?.length) {
|
|
96963
|
+
if (ctx.options.yes && !ctx.options.fresh && !ctx.options.force && releaseTag && !isOfflineMode && !pendingKits?.length) {
|
|
96889
96964
|
try {
|
|
96890
96965
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
96891
|
-
const claudeDir2 = prefix ?
|
|
96966
|
+
const claudeDir2 = prefix ? join111(resolvedDir, prefix) : resolvedDir;
|
|
96892
96967
|
const existingMetadata = await readManifest(claudeDir2);
|
|
96893
96968
|
const installedKitVersion = existingMetadata?.kits?.[kitType]?.version;
|
|
96894
96969
|
if (installedKitVersion && versionsMatch(installedKitVersion, releaseTag)) {
|
|
@@ -96912,7 +96987,7 @@ async function handleSelection(ctx) {
|
|
|
96912
96987
|
}
|
|
96913
96988
|
// src/commands/init/phases/sync-handler.ts
|
|
96914
96989
|
import { copyFile as copyFile8, mkdir as mkdir31, open as open5, readFile as readFile49, rename as rename6, stat as stat17, unlink as unlink11, writeFile as writeFile30 } from "node:fs/promises";
|
|
96915
|
-
import { dirname as dirname28, join as
|
|
96990
|
+
import { dirname as dirname28, join as join112, resolve as resolve24 } from "node:path";
|
|
96916
96991
|
init_logger();
|
|
96917
96992
|
init_path_resolver();
|
|
96918
96993
|
var import_fs_extra33 = __toESM(require_lib3(), 1);
|
|
@@ -96922,13 +96997,13 @@ async function handleSync(ctx) {
|
|
|
96922
96997
|
return ctx;
|
|
96923
96998
|
}
|
|
96924
96999
|
const resolvedDir = ctx.options.global ? PathResolver.getGlobalKitDir() : resolve24(ctx.options.dir || ".");
|
|
96925
|
-
const claudeDir2 = ctx.options.global ? resolvedDir :
|
|
97000
|
+
const claudeDir2 = ctx.options.global ? resolvedDir : join112(resolvedDir, ".claude");
|
|
96926
97001
|
if (!await import_fs_extra33.pathExists(claudeDir2)) {
|
|
96927
97002
|
logger.error("Cannot sync: no .claude directory found");
|
|
96928
97003
|
ctx.prompts.note("Run 'ck init' without --sync to install first.", "No Installation Found");
|
|
96929
97004
|
return { ...ctx, cancelled: true };
|
|
96930
97005
|
}
|
|
96931
|
-
const metadataPath =
|
|
97006
|
+
const metadataPath = join112(claudeDir2, "metadata.json");
|
|
96932
97007
|
if (!await import_fs_extra33.pathExists(metadataPath)) {
|
|
96933
97008
|
logger.error("Cannot sync: no metadata.json found");
|
|
96934
97009
|
ctx.prompts.note(`Your installation may be from an older version.
|
|
@@ -97028,7 +97103,7 @@ function getLockTimeout() {
|
|
|
97028
97103
|
var STALE_LOCK_THRESHOLD_MS = 5 * 60 * 1000;
|
|
97029
97104
|
async function acquireSyncLock(global3) {
|
|
97030
97105
|
const cacheDir = PathResolver.getCacheDir(global3);
|
|
97031
|
-
const lockPath =
|
|
97106
|
+
const lockPath = join112(cacheDir, ".sync-lock");
|
|
97032
97107
|
const startTime = Date.now();
|
|
97033
97108
|
const lockTimeout = getLockTimeout();
|
|
97034
97109
|
await mkdir31(dirname28(lockPath), { recursive: true });
|
|
@@ -97074,10 +97149,10 @@ async function executeSyncMerge(ctx) {
|
|
|
97074
97149
|
const releaseLock = await acquireSyncLock(ctx.options.global);
|
|
97075
97150
|
try {
|
|
97076
97151
|
const trackedFiles = ctx.syncTrackedFiles;
|
|
97077
|
-
const upstreamDir = ctx.options.global ?
|
|
97152
|
+
const upstreamDir = ctx.options.global ? join112(ctx.extractDir, ".claude") : ctx.extractDir;
|
|
97078
97153
|
let deletions = [];
|
|
97079
97154
|
try {
|
|
97080
|
-
const sourceMetadataPath =
|
|
97155
|
+
const sourceMetadataPath = join112(upstreamDir, "metadata.json");
|
|
97081
97156
|
if (await import_fs_extra33.pathExists(sourceMetadataPath)) {
|
|
97082
97157
|
const content = await readFile49(sourceMetadataPath, "utf-8");
|
|
97083
97158
|
const sourceMetadata = JSON.parse(content);
|
|
@@ -97109,7 +97184,7 @@ async function executeSyncMerge(ctx) {
|
|
|
97109
97184
|
try {
|
|
97110
97185
|
const sourcePath = await validateSyncPath(upstreamDir, file.path);
|
|
97111
97186
|
const targetPath = await validateSyncPath(ctx.claudeDir, file.path);
|
|
97112
|
-
const targetDir =
|
|
97187
|
+
const targetDir = join112(targetPath, "..");
|
|
97113
97188
|
try {
|
|
97114
97189
|
await mkdir31(targetDir, { recursive: true });
|
|
97115
97190
|
} catch (mkdirError) {
|
|
@@ -97280,7 +97355,7 @@ async function createBackup(claudeDir2, files, backupDir) {
|
|
|
97280
97355
|
const sourcePath = await validateSyncPath(claudeDir2, file.path);
|
|
97281
97356
|
if (await import_fs_extra33.pathExists(sourcePath)) {
|
|
97282
97357
|
const targetPath = await validateSyncPath(backupDir, file.path);
|
|
97283
|
-
const targetDir =
|
|
97358
|
+
const targetDir = join112(targetPath, "..");
|
|
97284
97359
|
await mkdir31(targetDir, { recursive: true });
|
|
97285
97360
|
await copyFile8(sourcePath, targetPath);
|
|
97286
97361
|
}
|
|
@@ -97295,7 +97370,7 @@ async function createBackup(claudeDir2, files, backupDir) {
|
|
|
97295
97370
|
}
|
|
97296
97371
|
// src/commands/init/phases/transform-handler.ts
|
|
97297
97372
|
init_config_manager();
|
|
97298
|
-
import { join as
|
|
97373
|
+
import { join as join116 } from "node:path";
|
|
97299
97374
|
|
|
97300
97375
|
// src/services/transformers/folder-path-transformer.ts
|
|
97301
97376
|
init_logger();
|
|
@@ -97305,39 +97380,39 @@ init_types3();
|
|
|
97305
97380
|
init_logger();
|
|
97306
97381
|
init_types3();
|
|
97307
97382
|
var import_fs_extra34 = __toESM(require_lib3(), 1);
|
|
97308
|
-
import { rename as rename7, rm as
|
|
97309
|
-
import { join as
|
|
97383
|
+
import { rename as rename7, rm as rm14 } from "node:fs/promises";
|
|
97384
|
+
import { join as join113, relative as relative19 } from "node:path";
|
|
97310
97385
|
async function collectDirsToRename(extractDir, folders) {
|
|
97311
97386
|
const dirsToRename = [];
|
|
97312
97387
|
if (folders.docs !== DEFAULT_FOLDERS.docs) {
|
|
97313
|
-
const docsPath =
|
|
97388
|
+
const docsPath = join113(extractDir, DEFAULT_FOLDERS.docs);
|
|
97314
97389
|
if (await import_fs_extra34.pathExists(docsPath)) {
|
|
97315
97390
|
dirsToRename.push({
|
|
97316
97391
|
from: docsPath,
|
|
97317
|
-
to:
|
|
97392
|
+
to: join113(extractDir, folders.docs)
|
|
97318
97393
|
});
|
|
97319
97394
|
}
|
|
97320
|
-
const claudeDocsPath =
|
|
97395
|
+
const claudeDocsPath = join113(extractDir, ".claude", DEFAULT_FOLDERS.docs);
|
|
97321
97396
|
if (await import_fs_extra34.pathExists(claudeDocsPath)) {
|
|
97322
97397
|
dirsToRename.push({
|
|
97323
97398
|
from: claudeDocsPath,
|
|
97324
|
-
to:
|
|
97399
|
+
to: join113(extractDir, ".claude", folders.docs)
|
|
97325
97400
|
});
|
|
97326
97401
|
}
|
|
97327
97402
|
}
|
|
97328
97403
|
if (folders.plans !== DEFAULT_FOLDERS.plans) {
|
|
97329
|
-
const plansPath =
|
|
97404
|
+
const plansPath = join113(extractDir, DEFAULT_FOLDERS.plans);
|
|
97330
97405
|
if (await import_fs_extra34.pathExists(plansPath)) {
|
|
97331
97406
|
dirsToRename.push({
|
|
97332
97407
|
from: plansPath,
|
|
97333
|
-
to:
|
|
97408
|
+
to: join113(extractDir, folders.plans)
|
|
97334
97409
|
});
|
|
97335
97410
|
}
|
|
97336
|
-
const claudePlansPath =
|
|
97411
|
+
const claudePlansPath = join113(extractDir, ".claude", DEFAULT_FOLDERS.plans);
|
|
97337
97412
|
if (await import_fs_extra34.pathExists(claudePlansPath)) {
|
|
97338
97413
|
dirsToRename.push({
|
|
97339
97414
|
from: claudePlansPath,
|
|
97340
|
-
to:
|
|
97415
|
+
to: join113(extractDir, ".claude", folders.plans)
|
|
97341
97416
|
});
|
|
97342
97417
|
}
|
|
97343
97418
|
}
|
|
@@ -97350,7 +97425,7 @@ async function moveAcrossDevices(src, dest) {
|
|
|
97350
97425
|
if (e2.code === "EXDEV") {
|
|
97351
97426
|
logger.debug(`Cross-device move detected, using copy+delete: ${src} -> ${dest}`);
|
|
97352
97427
|
await import_fs_extra34.copy(src, dest, { overwrite: true });
|
|
97353
|
-
await
|
|
97428
|
+
await rm14(src, { recursive: true, force: true });
|
|
97354
97429
|
} else {
|
|
97355
97430
|
throw e2;
|
|
97356
97431
|
}
|
|
@@ -97378,7 +97453,7 @@ async function renameFolders(dirsToRename, extractDir, options2) {
|
|
|
97378
97453
|
init_logger();
|
|
97379
97454
|
init_types3();
|
|
97380
97455
|
import { readFile as readFile50, readdir as readdir32, writeFile as writeFile31 } from "node:fs/promises";
|
|
97381
|
-
import { join as
|
|
97456
|
+
import { join as join114, relative as relative20 } from "node:path";
|
|
97382
97457
|
var TRANSFORMABLE_FILE_PATTERNS = [
|
|
97383
97458
|
".md",
|
|
97384
97459
|
".txt",
|
|
@@ -97431,7 +97506,7 @@ async function transformFileContents(dir, compiledReplacements, options2) {
|
|
|
97431
97506
|
let replacementsCount = 0;
|
|
97432
97507
|
const entries = await readdir32(dir, { withFileTypes: true });
|
|
97433
97508
|
for (const entry of entries) {
|
|
97434
|
-
const fullPath =
|
|
97509
|
+
const fullPath = join114(dir, entry.name);
|
|
97435
97510
|
if (entry.isDirectory()) {
|
|
97436
97511
|
if (entry.name === "node_modules" || entry.name === ".git") {
|
|
97437
97512
|
continue;
|
|
@@ -97568,7 +97643,7 @@ async function transformFolderPaths(extractDir, folders, options2 = {}) {
|
|
|
97568
97643
|
init_logger();
|
|
97569
97644
|
import { readFile as readFile51, readdir as readdir33, writeFile as writeFile32 } from "node:fs/promises";
|
|
97570
97645
|
import { platform as platform13 } from "node:os";
|
|
97571
|
-
import { extname as extname7, join as
|
|
97646
|
+
import { extname as extname7, join as join115 } from "node:path";
|
|
97572
97647
|
var IS_WINDOWS3 = platform13() === "win32";
|
|
97573
97648
|
var HOME_PREFIX = IS_WINDOWS3 ? "%USERPROFILE%" : "$HOME";
|
|
97574
97649
|
function getHomeDirPrefix() {
|
|
@@ -97678,7 +97753,7 @@ async function transformPathsForGlobalInstall(directory, options2 = {}) {
|
|
|
97678
97753
|
async function processDirectory2(dir) {
|
|
97679
97754
|
const entries = await readdir33(dir, { withFileTypes: true });
|
|
97680
97755
|
for (const entry of entries) {
|
|
97681
|
-
const fullPath =
|
|
97756
|
+
const fullPath = join115(dir, entry.name);
|
|
97682
97757
|
if (entry.isDirectory()) {
|
|
97683
97758
|
if (entry.name === "node_modules" || entry.name.startsWith(".") && entry.name !== ".claude") {
|
|
97684
97759
|
continue;
|
|
@@ -97754,7 +97829,7 @@ async function handleTransforms(ctx) {
|
|
|
97754
97829
|
logger.debug(ctx.options.global ? "Saved folder configuration to ~/.claude/.ck.json" : "Saved folder configuration to .claude/.ck.json");
|
|
97755
97830
|
}
|
|
97756
97831
|
}
|
|
97757
|
-
const claudeDir2 = ctx.options.global ? ctx.resolvedDir :
|
|
97832
|
+
const claudeDir2 = ctx.options.global ? ctx.resolvedDir : join116(ctx.resolvedDir, ".claude");
|
|
97758
97833
|
return {
|
|
97759
97834
|
...ctx,
|
|
97760
97835
|
foldersConfig,
|
|
@@ -97816,6 +97891,7 @@ function createInitContext(rawOptions, prompts) {
|
|
|
97816
97891
|
global: false,
|
|
97817
97892
|
yes: false,
|
|
97818
97893
|
fresh: false,
|
|
97894
|
+
force: false,
|
|
97819
97895
|
refresh: false,
|
|
97820
97896
|
exclude: [],
|
|
97821
97897
|
only: [],
|
|
@@ -97943,9 +98019,9 @@ async function initCommand(options2) {
|
|
|
97943
98019
|
init_dist2();
|
|
97944
98020
|
var import_picocolors28 = __toESM(require_picocolors(), 1);
|
|
97945
98021
|
import { existsSync as existsSync58 } from "node:fs";
|
|
97946
|
-
import { readFile as readFile52, rm as
|
|
97947
|
-
import { homedir as
|
|
97948
|
-
import { basename as basename16, join as
|
|
98022
|
+
import { readFile as readFile52, rm as rm15, unlink as unlink12 } from "node:fs/promises";
|
|
98023
|
+
import { homedir as homedir31 } from "node:os";
|
|
98024
|
+
import { basename as basename16, join as join117, resolve as resolve25 } from "node:path";
|
|
97949
98025
|
init_logger();
|
|
97950
98026
|
init_agents_discovery();
|
|
97951
98027
|
init_commands_discovery();
|
|
@@ -98346,7 +98422,7 @@ async function executeDeleteAction(action, options2) {
|
|
|
98346
98422
|
const shouldPreserveTarget = action.targetPath.length > 0 && preservePaths.has(resolve25(action.targetPath));
|
|
98347
98423
|
try {
|
|
98348
98424
|
if (!shouldPreserveTarget && action.targetPath && existsSync58(action.targetPath)) {
|
|
98349
|
-
await
|
|
98425
|
+
await rm15(action.targetPath, { recursive: true, force: true });
|
|
98350
98426
|
}
|
|
98351
98427
|
await removePortableInstallation(action.item, action.type, action.provider, action.global);
|
|
98352
98428
|
return {
|
|
@@ -98370,7 +98446,7 @@ async function executeDeleteAction(action, options2) {
|
|
|
98370
98446
|
async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
98371
98447
|
if (!skillSourcePath)
|
|
98372
98448
|
return;
|
|
98373
|
-
const sourceMetadataPath =
|
|
98449
|
+
const sourceMetadataPath = join117(resolve25(skillSourcePath, ".."), "metadata.json");
|
|
98374
98450
|
if (!existsSync58(sourceMetadataPath))
|
|
98375
98451
|
return;
|
|
98376
98452
|
let sourceMetadata;
|
|
@@ -98383,7 +98459,7 @@ async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
|
98383
98459
|
}
|
|
98384
98460
|
if (!sourceMetadata.deletions || sourceMetadata.deletions.length === 0)
|
|
98385
98461
|
return;
|
|
98386
|
-
const claudeDir2 = installGlobally ?
|
|
98462
|
+
const claudeDir2 = installGlobally ? join117(homedir31(), ".claude") : join117(process.cwd(), ".claude");
|
|
98387
98463
|
if (!existsSync58(claudeDir2))
|
|
98388
98464
|
return;
|
|
98389
98465
|
try {
|
|
@@ -98531,8 +98607,8 @@ async function migrateCommand(options2) {
|
|
|
98531
98607
|
selectedProviders = Array.from(new Set(selectedProviders));
|
|
98532
98608
|
let installGlobally = options2.global ?? false;
|
|
98533
98609
|
if (options2.global === undefined && !options2.yes) {
|
|
98534
|
-
const projectTarget =
|
|
98535
|
-
const globalTarget =
|
|
98610
|
+
const projectTarget = join117(process.cwd(), ".claude");
|
|
98611
|
+
const globalTarget = join117(homedir31(), ".claude");
|
|
98536
98612
|
const scopeChoice = await ie({
|
|
98537
98613
|
message: "Installation scope",
|
|
98538
98614
|
options: [
|
|
@@ -98584,7 +98660,7 @@ async function migrateCommand(options2) {
|
|
|
98584
98660
|
}
|
|
98585
98661
|
const providerNames = selectedProviders.map((prov) => import_picocolors28.default.cyan(providers[prov].displayName)).join(", ");
|
|
98586
98662
|
f2.message(` Providers: ${providerNames}`);
|
|
98587
|
-
const targetDir = installGlobally ?
|
|
98663
|
+
const targetDir = installGlobally ? join117(homedir31(), ".claude") : join117(process.cwd(), ".claude");
|
|
98588
98664
|
f2.message(` Scope: ${installGlobally ? "Global" : "Project"} ${import_picocolors28.default.dim(`-> ${targetDir}`)}`);
|
|
98589
98665
|
const cmdProviders = getProvidersSupporting("commands");
|
|
98590
98666
|
const unsupportedCmd = selectedProviders.filter((pv) => !cmdProviders.includes(pv));
|
|
@@ -98845,7 +98921,7 @@ async function rollbackResults(results) {
|
|
|
98845
98921
|
continue;
|
|
98846
98922
|
const stat18 = await import("node:fs/promises").then((fs19) => fs19.stat(result.path));
|
|
98847
98923
|
if (stat18.isDirectory()) {
|
|
98848
|
-
await
|
|
98924
|
+
await rm15(result.path, { recursive: true, force: true });
|
|
98849
98925
|
} else {
|
|
98850
98926
|
await unlink12(result.path);
|
|
98851
98927
|
}
|
|
@@ -99080,7 +99156,7 @@ async function handleDirectorySetup(ctx) {
|
|
|
99080
99156
|
// src/commands/new/phases/project-creation.ts
|
|
99081
99157
|
init_config_manager();
|
|
99082
99158
|
init_github_client();
|
|
99083
|
-
import { join as
|
|
99159
|
+
import { join as join118 } from "node:path";
|
|
99084
99160
|
init_logger();
|
|
99085
99161
|
init_output_manager();
|
|
99086
99162
|
init_types3();
|
|
@@ -99206,7 +99282,7 @@ async function projectCreation(kit, resolvedDir, validOptions, isNonInteractive2
|
|
|
99206
99282
|
output.section("Installing");
|
|
99207
99283
|
logger.verbose("Installation target", { directory: resolvedDir });
|
|
99208
99284
|
const merger = new FileMerger;
|
|
99209
|
-
const claudeDir2 =
|
|
99285
|
+
const claudeDir2 = join118(resolvedDir, ".claude");
|
|
99210
99286
|
merger.setMultiKitContext(claudeDir2, kit);
|
|
99211
99287
|
if (validOptions.exclude && validOptions.exclude.length > 0) {
|
|
99212
99288
|
merger.addIgnorePatterns(validOptions.exclude);
|
|
@@ -99253,7 +99329,7 @@ async function handleProjectCreation(ctx) {
|
|
|
99253
99329
|
}
|
|
99254
99330
|
// src/commands/new/phases/post-setup.ts
|
|
99255
99331
|
init_projects_registry();
|
|
99256
|
-
import { join as
|
|
99332
|
+
import { join as join119 } from "node:path";
|
|
99257
99333
|
init_package_installer();
|
|
99258
99334
|
init_logger();
|
|
99259
99335
|
init_path_resolver();
|
|
@@ -99285,9 +99361,9 @@ async function postSetup(resolvedDir, validOptions, isNonInteractive2, prompts)
|
|
|
99285
99361
|
withSudo: validOptions.withSudo
|
|
99286
99362
|
});
|
|
99287
99363
|
}
|
|
99288
|
-
const claudeDir2 =
|
|
99364
|
+
const claudeDir2 = join119(resolvedDir, ".claude");
|
|
99289
99365
|
await promptSetupWizardIfNeeded({
|
|
99290
|
-
envPath:
|
|
99366
|
+
envPath: join119(claudeDir2, ".env"),
|
|
99291
99367
|
claudeDir: claudeDir2,
|
|
99292
99368
|
isGlobal: false,
|
|
99293
99369
|
isNonInteractive: isNonInteractive2,
|
|
@@ -99357,7 +99433,7 @@ Please use only one download method.`);
|
|
|
99357
99433
|
// src/commands/plan/plan-command.ts
|
|
99358
99434
|
init_output_manager();
|
|
99359
99435
|
import { existsSync as existsSync60, statSync as statSync8 } from "node:fs";
|
|
99360
|
-
import { dirname as dirname30, join as
|
|
99436
|
+
import { dirname as dirname30, join as join121, parse as parse6, resolve as resolve29 } from "node:path";
|
|
99361
99437
|
|
|
99362
99438
|
// src/commands/plan/plan-read-handlers.ts
|
|
99363
99439
|
init_plan_parser();
|
|
@@ -99365,7 +99441,7 @@ init_logger();
|
|
|
99365
99441
|
init_output_manager();
|
|
99366
99442
|
var import_picocolors30 = __toESM(require_picocolors(), 1);
|
|
99367
99443
|
import { existsSync as existsSync59, statSync as statSync7 } from "node:fs";
|
|
99368
|
-
import { basename as basename17, dirname as dirname29, join as
|
|
99444
|
+
import { basename as basename17, dirname as dirname29, join as join120, relative as relative21, resolve as resolve27 } from "node:path";
|
|
99369
99445
|
async function handleParse(target, options2) {
|
|
99370
99446
|
const planFile = resolvePlanFile(target);
|
|
99371
99447
|
if (!planFile) {
|
|
@@ -99441,7 +99517,7 @@ async function handleValidate(target, options2) {
|
|
|
99441
99517
|
}
|
|
99442
99518
|
async function handleStatus(target, options2) {
|
|
99443
99519
|
const t = target ? resolve27(target) : null;
|
|
99444
|
-
const plansDir = t && existsSync59(t) && statSync7(t).isDirectory() && !existsSync59(
|
|
99520
|
+
const plansDir = t && existsSync59(t) && statSync7(t).isDirectory() && !existsSync59(join120(t, "plan.md")) ? t : null;
|
|
99445
99521
|
if (plansDir) {
|
|
99446
99522
|
const planFiles = scanPlanDir(plansDir);
|
|
99447
99523
|
if (planFiles.length === 0) {
|
|
@@ -99713,7 +99789,7 @@ function resolvePlanFile(target) {
|
|
|
99713
99789
|
const stat18 = statSync8(t);
|
|
99714
99790
|
if (stat18.isFile())
|
|
99715
99791
|
return t;
|
|
99716
|
-
const candidate =
|
|
99792
|
+
const candidate = join121(t, "plan.md");
|
|
99717
99793
|
if (existsSync60(candidate))
|
|
99718
99794
|
return candidate;
|
|
99719
99795
|
}
|
|
@@ -99721,7 +99797,7 @@ function resolvePlanFile(target) {
|
|
|
99721
99797
|
let dir = process.cwd();
|
|
99722
99798
|
const root = parse6(dir).root;
|
|
99723
99799
|
while (dir !== root) {
|
|
99724
|
-
const candidate =
|
|
99800
|
+
const candidate = join121(dir, "plan.md");
|
|
99725
99801
|
if (existsSync60(candidate))
|
|
99726
99802
|
return candidate;
|
|
99727
99803
|
dir = dirname30(dir);
|
|
@@ -100168,6 +100244,7 @@ async function handleKitSelection(ctx) {
|
|
|
100168
100244
|
exclude: [],
|
|
100169
100245
|
only: [],
|
|
100170
100246
|
fresh: false,
|
|
100247
|
+
force: false,
|
|
100171
100248
|
installSkills: false,
|
|
100172
100249
|
withSudo: false,
|
|
100173
100250
|
prefix: false,
|
|
@@ -100748,7 +100825,7 @@ async function detectInstallations() {
|
|
|
100748
100825
|
|
|
100749
100826
|
// src/commands/uninstall/removal-handler.ts
|
|
100750
100827
|
import { readdirSync as readdirSync7, rmSync as rmSync6 } from "node:fs";
|
|
100751
|
-
import { join as
|
|
100828
|
+
import { join as join123, resolve as resolve31, sep as sep8 } from "node:path";
|
|
100752
100829
|
init_logger();
|
|
100753
100830
|
init_safe_prompts();
|
|
100754
100831
|
init_safe_spinner();
|
|
@@ -100757,7 +100834,7 @@ var import_fs_extra37 = __toESM(require_lib3(), 1);
|
|
|
100757
100834
|
// src/commands/uninstall/analysis-handler.ts
|
|
100758
100835
|
init_metadata_migration();
|
|
100759
100836
|
import { readdirSync as readdirSync6, rmSync as rmSync5 } from "node:fs";
|
|
100760
|
-
import { dirname as dirname31, join as
|
|
100837
|
+
import { dirname as dirname31, join as join122 } from "node:path";
|
|
100761
100838
|
init_logger();
|
|
100762
100839
|
init_safe_prompts();
|
|
100763
100840
|
var import_picocolors36 = __toESM(require_picocolors(), 1);
|
|
@@ -100805,7 +100882,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
100805
100882
|
if (uninstallManifest.isMultiKit && kit && metadata?.kits?.[kit]) {
|
|
100806
100883
|
const kitFiles = metadata.kits[kit].files || [];
|
|
100807
100884
|
for (const trackedFile of kitFiles) {
|
|
100808
|
-
const filePath =
|
|
100885
|
+
const filePath = join122(installation.path, trackedFile.path);
|
|
100809
100886
|
if (uninstallManifest.filesToPreserve.includes(trackedFile.path)) {
|
|
100810
100887
|
result.toPreserve.push({ path: trackedFile.path, reason: "shared with other kit" });
|
|
100811
100888
|
continue;
|
|
@@ -100835,7 +100912,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
100835
100912
|
return result;
|
|
100836
100913
|
}
|
|
100837
100914
|
for (const trackedFile of allTrackedFiles) {
|
|
100838
|
-
const filePath =
|
|
100915
|
+
const filePath = join122(installation.path, trackedFile.path);
|
|
100839
100916
|
const ownershipResult = await OwnershipChecker.checkOwnership(filePath, metadata, installation.path);
|
|
100840
100917
|
if (!ownershipResult.exists)
|
|
100841
100918
|
continue;
|
|
@@ -100891,7 +100968,7 @@ async function isPathSafeToRemove(filePath, baseDir) {
|
|
|
100891
100968
|
try {
|
|
100892
100969
|
const resolvedPath = resolve31(filePath);
|
|
100893
100970
|
const resolvedBase = resolve31(baseDir);
|
|
100894
|
-
if (!resolvedPath.startsWith(resolvedBase +
|
|
100971
|
+
if (!resolvedPath.startsWith(resolvedBase + sep8) && resolvedPath !== resolvedBase) {
|
|
100895
100972
|
logger.debug(`Path outside installation directory: ${filePath}`);
|
|
100896
100973
|
return false;
|
|
100897
100974
|
}
|
|
@@ -100899,7 +100976,7 @@ async function isPathSafeToRemove(filePath, baseDir) {
|
|
|
100899
100976
|
if (stats.isSymbolicLink()) {
|
|
100900
100977
|
const realPath = await import_fs_extra37.realpath(filePath);
|
|
100901
100978
|
const resolvedReal = resolve31(realPath);
|
|
100902
|
-
if (!resolvedReal.startsWith(resolvedBase +
|
|
100979
|
+
if (!resolvedReal.startsWith(resolvedBase + sep8) && resolvedReal !== resolvedBase) {
|
|
100903
100980
|
logger.debug(`Symlink points outside installation directory: ${filePath} -> ${realPath}`);
|
|
100904
100981
|
return false;
|
|
100905
100982
|
}
|
|
@@ -100932,7 +101009,7 @@ async function removeInstallations(installations, options2) {
|
|
|
100932
101009
|
let removedCount = 0;
|
|
100933
101010
|
let cleanedDirs = 0;
|
|
100934
101011
|
for (const item of analysis.toDelete) {
|
|
100935
|
-
const filePath =
|
|
101012
|
+
const filePath = join123(installation.path, item.path);
|
|
100936
101013
|
if (!await import_fs_extra37.pathExists(filePath))
|
|
100937
101014
|
continue;
|
|
100938
101015
|
if (!await isPathSafeToRemove(filePath, installation.path)) {
|
|
@@ -101234,9 +101311,9 @@ ${import_picocolors38.default.bold(import_picocolors38.default.cyan(result.kitCo
|
|
|
101234
101311
|
// src/commands/watch/watch-command.ts
|
|
101235
101312
|
init_logger();
|
|
101236
101313
|
import { existsSync as existsSync67 } from "node:fs";
|
|
101237
|
-
import { rm as
|
|
101238
|
-
import { homedir as
|
|
101239
|
-
import { join as
|
|
101314
|
+
import { rm as rm16 } from "node:fs/promises";
|
|
101315
|
+
import { homedir as homedir33 } from "node:os";
|
|
101316
|
+
import { join as join130 } from "node:path";
|
|
101240
101317
|
var import_picocolors39 = __toESM(require_picocolors(), 1);
|
|
101241
101318
|
|
|
101242
101319
|
// src/commands/watch/phases/implementation-runner.ts
|
|
@@ -101755,7 +101832,7 @@ function spawnAndCollect3(command, args) {
|
|
|
101755
101832
|
|
|
101756
101833
|
// src/commands/watch/phases/issue-processor.ts
|
|
101757
101834
|
import { mkdir as mkdir32, writeFile as writeFile34 } from "node:fs/promises";
|
|
101758
|
-
import { join as
|
|
101835
|
+
import { join as join126 } from "node:path";
|
|
101759
101836
|
|
|
101760
101837
|
// src/commands/watch/phases/approval-detector.ts
|
|
101761
101838
|
init_logger();
|
|
@@ -102130,9 +102207,9 @@ async function checkAwaitingApproval(state, setup, options2, watchLog, projectDi
|
|
|
102130
102207
|
|
|
102131
102208
|
// src/commands/watch/phases/plan-dir-finder.ts
|
|
102132
102209
|
import { readdir as readdir35, stat as stat18 } from "node:fs/promises";
|
|
102133
|
-
import { join as
|
|
102210
|
+
import { join as join125 } from "node:path";
|
|
102134
102211
|
async function findRecentPlanDir(cwd2, issueNumber, watchLog) {
|
|
102135
|
-
const plansRoot =
|
|
102212
|
+
const plansRoot = join125(cwd2, "plans");
|
|
102136
102213
|
try {
|
|
102137
102214
|
const entries = await readdir35(plansRoot);
|
|
102138
102215
|
const tenMinAgo = Date.now() - 10 * 60 * 1000;
|
|
@@ -102141,14 +102218,14 @@ async function findRecentPlanDir(cwd2, issueNumber, watchLog) {
|
|
|
102141
102218
|
for (const entry of entries) {
|
|
102142
102219
|
if (entry === "watch" || entry === "reports" || entry === "visuals")
|
|
102143
102220
|
continue;
|
|
102144
|
-
const dirPath =
|
|
102221
|
+
const dirPath = join125(plansRoot, entry);
|
|
102145
102222
|
const dirStat = await stat18(dirPath);
|
|
102146
102223
|
if (!dirStat.isDirectory())
|
|
102147
102224
|
continue;
|
|
102148
102225
|
if (dirStat.mtimeMs < tenMinAgo)
|
|
102149
102226
|
continue;
|
|
102150
102227
|
try {
|
|
102151
|
-
await stat18(
|
|
102228
|
+
await stat18(join125(dirPath, "plan.md"));
|
|
102152
102229
|
} catch {
|
|
102153
102230
|
continue;
|
|
102154
102231
|
}
|
|
@@ -102379,13 +102456,13 @@ async function handlePlanGeneration(issue, state, config, setup, options2, watch
|
|
|
102379
102456
|
stats.plansCreated++;
|
|
102380
102457
|
const detectedPlanDir = await findRecentPlanDir(projectDir, issue.number, watchLog);
|
|
102381
102458
|
if (detectedPlanDir) {
|
|
102382
|
-
state.activeIssues[numStr].planPath =
|
|
102459
|
+
state.activeIssues[numStr].planPath = join126(detectedPlanDir, "plan.md");
|
|
102383
102460
|
watchLog.info(`Plan directory detected: ${detectedPlanDir}`);
|
|
102384
102461
|
} else {
|
|
102385
102462
|
try {
|
|
102386
|
-
const planDir =
|
|
102463
|
+
const planDir = join126(projectDir, "plans", "watch");
|
|
102387
102464
|
await mkdir32(planDir, { recursive: true });
|
|
102388
|
-
const planFilePath =
|
|
102465
|
+
const planFilePath = join126(planDir, `issue-${issue.number}-plan.md`);
|
|
102389
102466
|
await writeFile34(planFilePath, planResult.planText, "utf-8");
|
|
102390
102467
|
state.activeIssues[numStr].planPath = planFilePath;
|
|
102391
102468
|
watchLog.info(`Plan saved (fallback) to ${planFilePath}`);
|
|
@@ -102692,18 +102769,18 @@ init_logger();
|
|
|
102692
102769
|
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
102693
102770
|
import { existsSync as existsSync64 } from "node:fs";
|
|
102694
102771
|
import { readdir as readdir36, stat as stat19 } from "node:fs/promises";
|
|
102695
|
-
import { join as
|
|
102772
|
+
import { join as join127 } from "node:path";
|
|
102696
102773
|
async function scanForRepos(parentDir) {
|
|
102697
102774
|
const repos = [];
|
|
102698
102775
|
const entries = await readdir36(parentDir);
|
|
102699
102776
|
for (const entry of entries) {
|
|
102700
102777
|
if (entry.startsWith("."))
|
|
102701
102778
|
continue;
|
|
102702
|
-
const fullPath =
|
|
102779
|
+
const fullPath = join127(parentDir, entry);
|
|
102703
102780
|
const entryStat = await stat19(fullPath);
|
|
102704
102781
|
if (!entryStat.isDirectory())
|
|
102705
102782
|
continue;
|
|
102706
|
-
const gitDir =
|
|
102783
|
+
const gitDir = join127(fullPath, ".git");
|
|
102707
102784
|
if (!existsSync64(gitDir))
|
|
102708
102785
|
continue;
|
|
102709
102786
|
const result = spawnSync6("gh", ["repo", "view", "--json", "owner,name"], {
|
|
@@ -102729,8 +102806,8 @@ async function scanForRepos(parentDir) {
|
|
|
102729
102806
|
init_logger();
|
|
102730
102807
|
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
102731
102808
|
import { existsSync as existsSync65 } from "node:fs";
|
|
102732
|
-
import { homedir as
|
|
102733
|
-
import { join as
|
|
102809
|
+
import { homedir as homedir32 } from "node:os";
|
|
102810
|
+
import { join as join128 } from "node:path";
|
|
102734
102811
|
async function validateSetup(cwd2) {
|
|
102735
102812
|
const workDir = cwd2 ?? process.cwd();
|
|
102736
102813
|
const ghVersion = spawnSync7("gh", ["--version"], { encoding: "utf-8", timeout: 1e4 });
|
|
@@ -102761,7 +102838,7 @@ Run this command from a directory with a GitHub remote.`);
|
|
|
102761
102838
|
} catch {
|
|
102762
102839
|
throw new Error(`Failed to parse repository info: ${ghRepo.stdout}`);
|
|
102763
102840
|
}
|
|
102764
|
-
const skillsPath =
|
|
102841
|
+
const skillsPath = join128(homedir32(), ".claude", "skills");
|
|
102765
102842
|
const skillsAvailable = existsSync65(skillsPath);
|
|
102766
102843
|
if (!skillsAvailable) {
|
|
102767
102844
|
logger.warning(`ClaudeKit Engineer skills not found at ${skillsPath}`);
|
|
@@ -102780,7 +102857,7 @@ init_path_resolver();
|
|
|
102780
102857
|
import { createWriteStream as createWriteStream3, statSync as statSync9 } from "node:fs";
|
|
102781
102858
|
import { existsSync as existsSync66 } from "node:fs";
|
|
102782
102859
|
import { mkdir as mkdir34, rename as rename8 } from "node:fs/promises";
|
|
102783
|
-
import { join as
|
|
102860
|
+
import { join as join129 } from "node:path";
|
|
102784
102861
|
|
|
102785
102862
|
class WatchLogger {
|
|
102786
102863
|
logStream = null;
|
|
@@ -102788,7 +102865,7 @@ class WatchLogger {
|
|
|
102788
102865
|
logPath = null;
|
|
102789
102866
|
maxBytes;
|
|
102790
102867
|
constructor(logDir, maxBytes = 0) {
|
|
102791
|
-
this.logDir = logDir ??
|
|
102868
|
+
this.logDir = logDir ?? join129(PathResolver.getClaudeKitDir(), "logs");
|
|
102792
102869
|
this.maxBytes = maxBytes;
|
|
102793
102870
|
}
|
|
102794
102871
|
async init() {
|
|
@@ -102797,7 +102874,7 @@ class WatchLogger {
|
|
|
102797
102874
|
await mkdir34(this.logDir, { recursive: true });
|
|
102798
102875
|
}
|
|
102799
102876
|
const dateStr = formatDate(new Date);
|
|
102800
|
-
this.logPath =
|
|
102877
|
+
this.logPath = join129(this.logDir, `watch-${dateStr}.log`);
|
|
102801
102878
|
this.logStream = createWriteStream3(this.logPath, { flags: "a", mode: 384 });
|
|
102802
102879
|
} catch (error) {
|
|
102803
102880
|
logger.warning(`Cannot create watch log file: ${error instanceof Error ? error.message : "Unknown"}`);
|
|
@@ -102977,7 +103054,7 @@ async function watchCommand(options2) {
|
|
|
102977
103054
|
}
|
|
102978
103055
|
async function discoverRepos(options2, watchLog) {
|
|
102979
103056
|
const cwd2 = process.cwd();
|
|
102980
|
-
const isGitRepo = existsSync67(
|
|
103057
|
+
const isGitRepo = existsSync67(join130(cwd2, ".git"));
|
|
102981
103058
|
if (options2.force) {
|
|
102982
103059
|
await forceRemoveLock(watchLog);
|
|
102983
103060
|
}
|
|
@@ -103047,9 +103124,9 @@ async function resetState(state, projectDir, watchLog) {
|
|
|
103047
103124
|
watchLog.info(`Watch state reset (--force) for ${projectDir}`);
|
|
103048
103125
|
}
|
|
103049
103126
|
async function forceRemoveLock(watchLog) {
|
|
103050
|
-
const lockPath =
|
|
103127
|
+
const lockPath = join130(homedir33(), ".claudekit", "locks", `${LOCK_NAME}.lock`);
|
|
103051
103128
|
try {
|
|
103052
|
-
await
|
|
103129
|
+
await rm16(lockPath, { recursive: true, force: true });
|
|
103053
103130
|
watchLog.info("Removed existing lock file (--force)");
|
|
103054
103131
|
} catch {}
|
|
103055
103132
|
}
|
|
@@ -103097,7 +103174,7 @@ function registerCommands(cli) {
|
|
|
103097
103174
|
}
|
|
103098
103175
|
await newCommand(options2);
|
|
103099
103176
|
});
|
|
103100
|
-
cli.command("init", "Initialize or update ClaudeKit project (with interactive version selection)").option("--dir <dir>", "Target directory (default: .)").option("--kit <kit>", "Kit to use: engineer, marketing, all, or comma-separated").option("-r, --release <version>", "Skip version selection, use specific version (e.g., latest, v1.0.0)").option("--exclude <pattern>", "Exclude files matching glob pattern (can be used multiple times)").option("--only <pattern>", "Include only files matching glob pattern (can be used multiple times)").option("-g, --global", "Use platform-specific user configuration directory").option("--fresh", "Full reset: remove CK files, replace settings.json and CLAUDE.md, reinstall from scratch").option("--install-skills", "Install skills dependencies (non-interactive mode)").option("--with-sudo", "Include system packages requiring sudo (Linux: ffmpeg, imagemagick)").option("--prefix", "Add /ck: prefix to all slash commands by moving them to commands/ck/ subdirectory").option("--beta", "Show beta versions in selection prompt").option("--refresh", "Bypass release cache to fetch latest versions from GitHub").option("--dry-run", "Preview changes without applying them (requires --prefix)").option("--force-overwrite", "Override ownership protections and delete user-modified files (requires --prefix)").option("--force-overwrite-settings", "Fully replace settings.json instead of selective merge (destroys user customizations)").option("--skip-setup", "Skip interactive configuration wizard").option("--docs-dir <name>", "Custom docs folder name (default: docs)").option("--plans-dir <name>", "Custom plans folder name (default: plans)").option("-y, --yes", "Non-interactive mode with sensible defaults (skip all prompts)").option("--sync", "Sync config files from upstream with interactive hunk-by-hunk merge").option("--use-git", "Use git clone instead of GitHub API (uses SSH/HTTPS credentials)").option("--archive <path>", "Use local archive file instead of downloading (zip/tar.gz)").option("--kit-path <path>", "Use local kit directory instead of downloading").action(async (options2) => {
|
|
103177
|
+
cli.command("init", "Initialize or update ClaudeKit project (with interactive version selection)").option("--dir <dir>", "Target directory (default: .)").option("--kit <kit>", "Kit to use: engineer, marketing, all, or comma-separated").option("-r, --release <version>", "Skip version selection, use specific version (e.g., latest, v1.0.0)").option("--exclude <pattern>", "Exclude files matching glob pattern (can be used multiple times)").option("--only <pattern>", "Include only files matching glob pattern (can be used multiple times)").option("-g, --global", "Use platform-specific user configuration directory").option("--fresh", "Full reset: remove CK files, replace settings.json and CLAUDE.md, reinstall from scratch").option("--force", "Force reinstall even if already at latest version (use with --yes; re-onboards missing files without full reset)").option("--install-skills", "Install skills dependencies (non-interactive mode)").option("--with-sudo", "Include system packages requiring sudo (Linux: ffmpeg, imagemagick)").option("--prefix", "Add /ck: prefix to all slash commands by moving them to commands/ck/ subdirectory").option("--beta", "Show beta versions in selection prompt").option("--refresh", "Bypass release cache to fetch latest versions from GitHub").option("--dry-run", "Preview changes without applying them (requires --prefix)").option("--force-overwrite", "Override ownership protections and delete user-modified files (requires --prefix)").option("--force-overwrite-settings", "Fully replace settings.json instead of selective merge (destroys user customizations)").option("--skip-setup", "Skip interactive configuration wizard").option("--docs-dir <name>", "Custom docs folder name (default: docs)").option("--plans-dir <name>", "Custom plans folder name (default: plans)").option("-y, --yes", "Non-interactive mode with sensible defaults (skip all prompts)").option("--sync", "Sync config files from upstream with interactive hunk-by-hunk merge").option("--use-git", "Use git clone instead of GitHub API (uses SSH/HTTPS credentials)").option("--archive <path>", "Use local archive file instead of downloading (zip/tar.gz)").option("--kit-path <path>", "Use local kit directory instead of downloading").action(async (options2) => {
|
|
103101
103178
|
if (options2.exclude && !Array.isArray(options2.exclude)) {
|
|
103102
103179
|
options2.exclude = [options2.exclude];
|
|
103103
103180
|
}
|
|
@@ -103231,7 +103308,7 @@ init_logger();
|
|
|
103231
103308
|
init_path_resolver();
|
|
103232
103309
|
init_types3();
|
|
103233
103310
|
import { existsSync as existsSync78, readFileSync as readFileSync18 } from "node:fs";
|
|
103234
|
-
import { join as
|
|
103311
|
+
import { join as join141 } from "node:path";
|
|
103235
103312
|
var packageVersion = package_default.version;
|
|
103236
103313
|
function formatInstalledKits(metadata) {
|
|
103237
103314
|
if (!metadata.kits || Object.keys(metadata.kits).length === 0) {
|
|
@@ -103263,9 +103340,9 @@ async function displayVersion() {
|
|
|
103263
103340
|
let localKitVersion = null;
|
|
103264
103341
|
let isGlobalOnlyKit = false;
|
|
103265
103342
|
const globalKitDir = PathResolver.getGlobalKitDir();
|
|
103266
|
-
const globalMetadataPath =
|
|
103343
|
+
const globalMetadataPath = join141(globalKitDir, "metadata.json");
|
|
103267
103344
|
const prefix = PathResolver.getPathPrefix(false);
|
|
103268
|
-
const localMetadataPath = prefix ?
|
|
103345
|
+
const localMetadataPath = prefix ? join141(process.cwd(), prefix, "metadata.json") : join141(process.cwd(), "metadata.json");
|
|
103269
103346
|
const isLocalSameAsGlobal = localMetadataPath === globalMetadataPath;
|
|
103270
103347
|
if (!isLocalSameAsGlobal && existsSync78(localMetadataPath)) {
|
|
103271
103348
|
try {
|