claudekit-cli 4.2.2 → 4.2.3-dev.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli-manifest.json +2 -2
- package/dist/index.js +586 -475
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -51663,8 +51663,27 @@ var init_migrate_provider_scopes = __esm(() => {
|
|
|
51663
51663
|
|
|
51664
51664
|
// src/commands/migrate/skill-directory-installer.ts
|
|
51665
51665
|
import { existsSync as existsSync22 } from "node:fs";
|
|
51666
|
-
import { cp, mkdir as mkdir10, rename as rename6, rm as rm5 } from "node:fs/promises";
|
|
51667
|
-
import { join as join40, resolve as resolve15 } from "node:path";
|
|
51666
|
+
import { cp, mkdir as mkdir10, realpath as realpath5, rename as rename6, rm as rm5 } from "node:fs/promises";
|
|
51667
|
+
import { dirname as dirname11, join as join40, resolve as resolve15 } from "node:path";
|
|
51668
|
+
async function canonicalize(path3) {
|
|
51669
|
+
try {
|
|
51670
|
+
return await realpath5(path3);
|
|
51671
|
+
} catch {
|
|
51672
|
+
const parent = dirname11(path3);
|
|
51673
|
+
if (parent === path3) {
|
|
51674
|
+
return resolve15(path3);
|
|
51675
|
+
}
|
|
51676
|
+
try {
|
|
51677
|
+
const canonicalParent = await realpath5(parent);
|
|
51678
|
+
const absPath = resolve15(path3);
|
|
51679
|
+
const absParent = resolve15(parent);
|
|
51680
|
+
const basename13 = absPath.slice(absParent.length + 1) || "";
|
|
51681
|
+
return join40(canonicalParent, basename13);
|
|
51682
|
+
} catch {
|
|
51683
|
+
return resolve15(path3);
|
|
51684
|
+
}
|
|
51685
|
+
}
|
|
51686
|
+
}
|
|
51668
51687
|
async function installSkillDirectories(skills, targetProviders, options2) {
|
|
51669
51688
|
const results = [];
|
|
51670
51689
|
for (const provider of targetProviders) {
|
|
@@ -51691,9 +51710,28 @@ async function installSkillDirectories(skills, targetProviders, options2) {
|
|
|
51691
51710
|
});
|
|
51692
51711
|
continue;
|
|
51693
51712
|
}
|
|
51713
|
+
const sourceRoot = skills.length > 0 ? dirname11(skills[0].path) : null;
|
|
51714
|
+
const canonicalBase = existsSync22(basePath) ? await canonicalize(basePath) : null;
|
|
51715
|
+
const canonicalSourceRoot = sourceRoot ? await canonicalize(sourceRoot) : null;
|
|
51716
|
+
const basePathIsSymlinkedToSource = canonicalBase !== null && canonicalSourceRoot !== null && canonicalBase === canonicalSourceRoot && resolve15(basePath) !== resolve15(sourceRoot ?? "");
|
|
51717
|
+
if (basePathIsSymlinkedToSource) {
|
|
51718
|
+
for (const skill of skills) {
|
|
51719
|
+
results.push({
|
|
51720
|
+
provider,
|
|
51721
|
+
providerDisplayName: config.displayName,
|
|
51722
|
+
success: true,
|
|
51723
|
+
path: join40(basePath, skill.name),
|
|
51724
|
+
skipped: true,
|
|
51725
|
+
skipReason: `Skills directory ${basePath} is symlinked to source (${canonicalBase}); already in place`
|
|
51726
|
+
});
|
|
51727
|
+
}
|
|
51728
|
+
continue;
|
|
51729
|
+
}
|
|
51694
51730
|
for (const skill of skills) {
|
|
51695
51731
|
const targetDir = join40(basePath, skill.name);
|
|
51696
|
-
|
|
51732
|
+
const canonicalSource = await canonicalize(skill.path);
|
|
51733
|
+
const canonicalTarget = await canonicalize(targetDir);
|
|
51734
|
+
if (canonicalSource === canonicalTarget) {
|
|
51697
51735
|
results.push({
|
|
51698
51736
|
provider,
|
|
51699
51737
|
providerDisplayName: config.displayName,
|
|
@@ -53885,9 +53923,9 @@ var init_codex_capabilities = __esm(() => {
|
|
|
53885
53923
|
|
|
53886
53924
|
// src/commands/portable/codex-path-safety.ts
|
|
53887
53925
|
import { existsSync as existsSync24 } from "node:fs";
|
|
53888
|
-
import { mkdir as mkdir12, realpath as
|
|
53926
|
+
import { mkdir as mkdir12, realpath as realpath6 } from "node:fs/promises";
|
|
53889
53927
|
import { homedir as homedir25 } from "node:os";
|
|
53890
|
-
import { dirname as
|
|
53928
|
+
import { dirname as dirname12, join as join42, resolve as resolve17, sep as sep7 } from "node:path";
|
|
53891
53929
|
function isPathWithinBoundary3(targetPath, boundaryPath) {
|
|
53892
53930
|
const resolvedTarget = resolve17(targetPath);
|
|
53893
53931
|
const resolvedBoundary = resolve17(boundaryPath);
|
|
@@ -53895,7 +53933,7 @@ function isPathWithinBoundary3(targetPath, boundaryPath) {
|
|
|
53895
53933
|
}
|
|
53896
53934
|
async function resolveRealPathSafe2(path3) {
|
|
53897
53935
|
try {
|
|
53898
|
-
return await
|
|
53936
|
+
return await realpath6(path3);
|
|
53899
53937
|
} catch {
|
|
53900
53938
|
return resolve17(path3);
|
|
53901
53939
|
}
|
|
@@ -53906,11 +53944,11 @@ async function isCanonicalPathWithinBoundary2(targetPath, boundaryPath) {
|
|
|
53906
53944
|
return isPathWithinBoundary3(canonicalTarget, canonicalBoundary);
|
|
53907
53945
|
}
|
|
53908
53946
|
function getCodexLockPath2(targetFilePath) {
|
|
53909
|
-
return join42(
|
|
53947
|
+
return join42(dirname12(resolve17(targetFilePath)), ".config.toml.ck-codex.lock");
|
|
53910
53948
|
}
|
|
53911
53949
|
async function withCodexTargetLock2(targetFilePath, operation) {
|
|
53912
53950
|
const resolvedTargetPath = resolve17(targetFilePath);
|
|
53913
|
-
const dir =
|
|
53951
|
+
const dir = dirname12(resolvedTargetPath);
|
|
53914
53952
|
if (!existsSync24(dir)) {
|
|
53915
53953
|
await mkdir12(dir, { recursive: true });
|
|
53916
53954
|
}
|
|
@@ -53943,10 +53981,10 @@ var init_codex_path_safety = __esm(() => {
|
|
|
53943
53981
|
// src/commands/portable/codex-features-flag.ts
|
|
53944
53982
|
import { existsSync as existsSync25 } from "node:fs";
|
|
53945
53983
|
import { readFile as readFile20, rename as rename7, unlink as unlink6, writeFile as writeFile11 } from "node:fs/promises";
|
|
53946
|
-
import { dirname as
|
|
53984
|
+
import { dirname as dirname13, resolve as resolve18 } from "node:path";
|
|
53947
53985
|
async function ensureCodexHooksFeatureFlag(configTomlPath, isGlobal = false) {
|
|
53948
|
-
const boundary = isGlobal ? getCodexGlobalBoundary() :
|
|
53949
|
-
if (!await isCanonicalPathWithinBoundary2(
|
|
53986
|
+
const boundary = isGlobal ? getCodexGlobalBoundary() : dirname13(resolve18(configTomlPath));
|
|
53987
|
+
if (!await isCanonicalPathWithinBoundary2(dirname13(resolve18(configTomlPath)), boundary)) {
|
|
53950
53988
|
return {
|
|
53951
53989
|
status: "failed",
|
|
53952
53990
|
configPath: configTomlPath,
|
|
@@ -54112,7 +54150,7 @@ ${SENTINEL_END2}`;
|
|
|
54112
54150
|
// src/commands/portable/codex-hook-wrapper.ts
|
|
54113
54151
|
import { createHash as createHash5 } from "node:crypto";
|
|
54114
54152
|
import { mkdirSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
54115
|
-
import { dirname as
|
|
54153
|
+
import { dirname as dirname14, join as join43, resolve as resolve19 } from "node:path";
|
|
54116
54154
|
function wrapperFilename(originalPath) {
|
|
54117
54155
|
const abs = resolve19(originalPath);
|
|
54118
54156
|
const hash = createHash5("sha256").update(abs).digest("hex").slice(0, 8);
|
|
@@ -54135,7 +54173,7 @@ function generateCodexHookWrappers(originalPaths, wrapperDir, capabilities, time
|
|
|
54135
54173
|
continue;
|
|
54136
54174
|
}
|
|
54137
54175
|
try {
|
|
54138
|
-
mkdirSync(
|
|
54176
|
+
mkdirSync(dirname14(wrapperPath), { recursive: true });
|
|
54139
54177
|
const resolvedPath = resolve19(originalPath);
|
|
54140
54178
|
const hookTimeoutMs = timeoutsByPath?.[resolvedPath] ?? timeoutsByPath?.[originalPath];
|
|
54141
54179
|
const content = buildWrapperScript(originalPath, capabilities, hookTimeoutMs);
|
|
@@ -54455,7 +54493,7 @@ var init_gemini_hook_event_map = __esm(() => {
|
|
|
54455
54493
|
import { existsSync as existsSync26 } from "node:fs";
|
|
54456
54494
|
import { mkdir as mkdir13, readFile as readFile21, rename as rename8, rm as rm6, writeFile as writeFile12 } from "node:fs/promises";
|
|
54457
54495
|
import { homedir as homedir27 } from "node:os";
|
|
54458
|
-
import { basename as basename14, dirname as
|
|
54496
|
+
import { basename as basename14, dirname as dirname15, join as join44, resolve as resolve20 } from "node:path";
|
|
54459
54497
|
function validateHooksSectionShape(value) {
|
|
54460
54498
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
54461
54499
|
return "hooks must be a non-null object";
|
|
@@ -54606,7 +54644,7 @@ async function mergeHooksIntoSettings(targetSettingsPath, newHooks) {
|
|
|
54606
54644
|
const pruned = pruneStaleFileHooks(existingHooks);
|
|
54607
54645
|
const merged = deduplicateMerge(pruned, newHooks);
|
|
54608
54646
|
existingSettings.hooks = merged;
|
|
54609
|
-
const dir =
|
|
54647
|
+
const dir = dirname15(targetSettingsPath);
|
|
54610
54648
|
await mkdir13(dir, { recursive: true });
|
|
54611
54649
|
const tempPath = `${targetSettingsPath}.tmp`;
|
|
54612
54650
|
try {
|
|
@@ -56193,7 +56231,7 @@ __export(exports_skills_discovery, {
|
|
|
56193
56231
|
});
|
|
56194
56232
|
import { readFile as readFile24, readdir as readdir13, stat as stat9 } from "node:fs/promises";
|
|
56195
56233
|
import { homedir as homedir28 } from "node:os";
|
|
56196
|
-
import { dirname as
|
|
56234
|
+
import { dirname as dirname16, join as join45 } from "node:path";
|
|
56197
56235
|
function getSkillSourcePath(globalOnly = false) {
|
|
56198
56236
|
const globalPath = join45(homedir28(), ".claude/skills");
|
|
56199
56237
|
if (globalOnly) {
|
|
@@ -56220,7 +56258,7 @@ async function parseSkillMd(skillMdPath) {
|
|
|
56220
56258
|
try {
|
|
56221
56259
|
const content = await readFile24(skillMdPath, "utf-8");
|
|
56222
56260
|
const { data } = import_gray_matter5.default(content, { engines: { javascript: { parse: () => ({}) } } });
|
|
56223
|
-
const skillDir =
|
|
56261
|
+
const skillDir = dirname16(skillMdPath);
|
|
56224
56262
|
const dirName = skillDir.split(/[/\\]/).pop() || "";
|
|
56225
56263
|
if (!dirName) {
|
|
56226
56264
|
logger.verbose(`Skipping ${skillMdPath}: cannot determine skill directory`);
|
|
@@ -58024,7 +58062,7 @@ var init_plan_metadata = __esm(() => {
|
|
|
58024
58062
|
|
|
58025
58063
|
// src/domains/plan-parser/plan-table-parser.ts
|
|
58026
58064
|
import { readFileSync as readFileSync7 } from "node:fs";
|
|
58027
|
-
import { dirname as
|
|
58065
|
+
import { dirname as dirname17, resolve as resolve22 } from "node:path";
|
|
58028
58066
|
function normalizeStatus(raw) {
|
|
58029
58067
|
const s = raw.toLowerCase().trim();
|
|
58030
58068
|
if (s.includes("complete") || s.includes("done") || s.includes("✓") || s.includes("✅")) {
|
|
@@ -58284,7 +58322,7 @@ function parseFormat4(content, planFilePath, options2) {
|
|
|
58284
58322
|
const hasCheck = /[✅✓]/.test(line);
|
|
58285
58323
|
current = { name, status: hasCheck ? "completed" : "pending" };
|
|
58286
58324
|
} else if (fileMatch && current) {
|
|
58287
|
-
const planDir =
|
|
58325
|
+
const planDir = dirname17(planFilePath);
|
|
58288
58326
|
current.file = resolve22(planDir, fileMatch[1].trim());
|
|
58289
58327
|
} else if (statusMatch && current) {
|
|
58290
58328
|
current.status = normalizeStatus(statusMatch[2]);
|
|
@@ -58389,7 +58427,7 @@ function parsePhasesFromBody(body, dir, options2) {
|
|
|
58389
58427
|
}
|
|
58390
58428
|
function parsePlanFile(planFilePath, options2) {
|
|
58391
58429
|
const content = readFileSync7(planFilePath, "utf8");
|
|
58392
|
-
const dir =
|
|
58430
|
+
const dir = dirname17(planFilePath);
|
|
58393
58431
|
const { data: frontmatter, content: body } = import_gray_matter7.default(content, {
|
|
58394
58432
|
engines: { javascript: { parse: () => ({}) } }
|
|
58395
58433
|
});
|
|
@@ -58685,12 +58723,12 @@ var init_timeline_builder = __esm(() => {
|
|
|
58685
58723
|
|
|
58686
58724
|
// src/domains/plan-parser/plan-validator.ts
|
|
58687
58725
|
import { existsSync as existsSync32, readFileSync as readFileSync8 } from "node:fs";
|
|
58688
|
-
import { basename as basename16, dirname as
|
|
58726
|
+
import { basename as basename16, dirname as dirname18 } from "node:path";
|
|
58689
58727
|
function validatePlanFile(filePath, strict = false) {
|
|
58690
58728
|
const rawContent = readFileSync8(filePath, "utf8");
|
|
58691
58729
|
const content = rawContent.replace(/\r\n/g, `
|
|
58692
58730
|
`);
|
|
58693
|
-
const dir =
|
|
58731
|
+
const dir = dirname18(filePath);
|
|
58694
58732
|
const issues = [];
|
|
58695
58733
|
const lines = content.split(`
|
|
58696
58734
|
`);
|
|
@@ -58756,7 +58794,7 @@ var init_plan_validator = __esm(() => {
|
|
|
58756
58794
|
import { execSync } from "node:child_process";
|
|
58757
58795
|
import { mkdirSync as mkdirSync2, readFileSync as readFileSync9, writeFileSync as writeFileSync3 } from "node:fs";
|
|
58758
58796
|
import { existsSync as existsSync33 } from "node:fs";
|
|
58759
|
-
import { basename as basename17, dirname as
|
|
58797
|
+
import { basename as basename17, dirname as dirname19, join as join51 } from "node:path";
|
|
58760
58798
|
function phaseNameToFilename(id, name) {
|
|
58761
58799
|
const numMatch = /^(\d+)([a-z]*)$/i.exec(id);
|
|
58762
58800
|
const num = numMatch ? numMatch[1] : id;
|
|
@@ -58970,7 +59008,7 @@ function updatePhaseStatus(planFile, phaseId, newStatus) {
|
|
|
58970
59008
|
const updatedFrontmatter = { ...frontmatter, status: planStatus };
|
|
58971
59009
|
const updatedContent = import_gray_matter9.default.stringify(updatedBody, updatedFrontmatter);
|
|
58972
59010
|
writeFileSync3(planFile, updatedContent, "utf8");
|
|
58973
|
-
const planDir =
|
|
59011
|
+
const planDir = dirname19(planFile);
|
|
58974
59012
|
const phaseFilename = phaseNameFilenameFromTableRow(updatedBody, phaseId, planDir);
|
|
58975
59013
|
if (phaseFilename && existsSync33(phaseFilename)) {
|
|
58976
59014
|
updatePhaseFileFrontmatter(phaseFilename, newStatus);
|
|
@@ -59006,7 +59044,7 @@ function addPhase(planFile, name, afterId) {
|
|
|
59006
59044
|
const { data: frontmatter, content: body } = import_gray_matter9.default(raw, {
|
|
59007
59045
|
engines: { javascript: { parse: () => ({}) } }
|
|
59008
59046
|
});
|
|
59009
|
-
const planDir =
|
|
59047
|
+
const planDir = dirname19(planFile);
|
|
59010
59048
|
const existingIds = [];
|
|
59011
59049
|
for (const match of body.matchAll(/^\|\s*(\d+[a-z]?)\s*\|/gim)) {
|
|
59012
59050
|
existingIds.push(match[1].toLowerCase());
|
|
@@ -59079,7 +59117,7 @@ var init_plan_writer = __esm(() => {
|
|
|
59079
59117
|
});
|
|
59080
59118
|
|
|
59081
59119
|
// src/domains/plan-parser/index.ts
|
|
59082
|
-
import { dirname as
|
|
59120
|
+
import { dirname as dirname20 } from "node:path";
|
|
59083
59121
|
function buildPlanSummary(planFile) {
|
|
59084
59122
|
const { frontmatter, phases } = parsePlanFile(planFile);
|
|
59085
59123
|
const completed = phases.filter((p) => p.status === "completed").length;
|
|
@@ -59087,7 +59125,7 @@ function buildPlanSummary(planFile) {
|
|
|
59087
59125
|
const pending = phases.filter((p) => p.status === "pending").length;
|
|
59088
59126
|
const metadata = readPlanMetadata(planFile, { total: phases.length, completed, inProgress });
|
|
59089
59127
|
return {
|
|
59090
|
-
planDir:
|
|
59128
|
+
planDir: dirname20(planFile),
|
|
59091
59129
|
planFile,
|
|
59092
59130
|
title: metadata.title ?? (typeof frontmatter.title === "string" ? frontmatter.title : undefined),
|
|
59093
59131
|
description: metadata.description ?? (typeof frontmatter.description === "string" ? frontmatter.description : undefined),
|
|
@@ -59347,7 +59385,7 @@ import {
|
|
|
59347
59385
|
unlinkSync,
|
|
59348
59386
|
writeFileSync as writeFileSync4
|
|
59349
59387
|
} from "node:fs";
|
|
59350
|
-
import { dirname as
|
|
59388
|
+
import { dirname as dirname21, isAbsolute as isAbsolute7, join as join52, parse as parse2, relative as relative12, resolve as resolve24 } from "node:path";
|
|
59351
59389
|
function createEmptyRegistry() {
|
|
59352
59390
|
return {
|
|
59353
59391
|
version: 1,
|
|
@@ -59413,7 +59451,7 @@ function findProjectRoot(startDir) {
|
|
|
59413
59451
|
if (existsSync34(join52(dir, ".claude")) || existsSync34(join52(dir, ".git"))) {
|
|
59414
59452
|
return dir;
|
|
59415
59453
|
}
|
|
59416
|
-
dir =
|
|
59454
|
+
dir = dirname21(dir);
|
|
59417
59455
|
}
|
|
59418
59456
|
return startDir;
|
|
59419
59457
|
}
|
|
@@ -59434,7 +59472,7 @@ function writeRegistry(registry, cwd2 = process.cwd()) {
|
|
|
59434
59472
|
const globalPath = PathResolver.getPlansRegistryPath(cwd2);
|
|
59435
59473
|
const toWrite = { ...registry, projectRoot: cwd2 };
|
|
59436
59474
|
const validated = PlansRegistrySchema.parse(toWrite);
|
|
59437
|
-
mkdirSync3(
|
|
59475
|
+
mkdirSync3(dirname21(globalPath), { recursive: true });
|
|
59438
59476
|
if (existsSync34(globalPath)) {
|
|
59439
59477
|
try {
|
|
59440
59478
|
writeFileSync4(`${globalPath}.bak`, readFileSync10(globalPath));
|
|
@@ -59544,7 +59582,7 @@ var init_plans_registry = __esm(() => {
|
|
|
59544
59582
|
});
|
|
59545
59583
|
|
|
59546
59584
|
// src/domains/plan-actions/action-executor.ts
|
|
59547
|
-
import { dirname as
|
|
59585
|
+
import { dirname as dirname22, join as join53 } from "node:path";
|
|
59548
59586
|
function getPlanFile(planDir) {
|
|
59549
59587
|
return join53(planDir, "plan.md");
|
|
59550
59588
|
}
|
|
@@ -59558,7 +59596,7 @@ function assertPhaseId(phaseId) {
|
|
|
59558
59596
|
function syncDashboardTracking(planFile) {
|
|
59559
59597
|
const summary = buildPlanSummary(planFile);
|
|
59560
59598
|
try {
|
|
59561
|
-
const planDir =
|
|
59599
|
+
const planDir = dirname22(planFile);
|
|
59562
59600
|
const projectRoot = findProjectRoot(planDir);
|
|
59563
59601
|
updateRegistryPhaseStatus({
|
|
59564
59602
|
planDir,
|
|
@@ -59821,7 +59859,7 @@ var init_p_limit = __esm(() => {
|
|
|
59821
59859
|
// src/domains/web-server/routes/plan-routes.ts
|
|
59822
59860
|
import { existsSync as existsSync35, readFileSync as readFileSync11, realpathSync } from "node:fs";
|
|
59823
59861
|
import { homedir as homedir31 } from "node:os";
|
|
59824
|
-
import { basename as basename18, dirname as
|
|
59862
|
+
import { basename as basename18, dirname as dirname23, join as join54, relative as relative13, resolve as resolve25, sep as sep8 } from "node:path";
|
|
59825
59863
|
function sanitizeError(err) {
|
|
59826
59864
|
if (err instanceof Error) {
|
|
59827
59865
|
if (/^(ENOENT|EACCES|EPERM|EISDIR)/.test(err.message))
|
|
@@ -59972,8 +60010,8 @@ function createDiscoveredProjectId(projectPath) {
|
|
|
59972
60010
|
function toProjectPlanListItem(summary, plansDir) {
|
|
59973
60011
|
return {
|
|
59974
60012
|
file: relative13(plansDir, summary.planFile),
|
|
59975
|
-
name: basename18(
|
|
59976
|
-
slug: basename18(
|
|
60013
|
+
name: basename18(dirname23(summary.planFile)),
|
|
60014
|
+
slug: basename18(dirname23(summary.planFile)),
|
|
59977
60015
|
summary: {
|
|
59978
60016
|
...summary,
|
|
59979
60017
|
planDir: relative13(plansDir, summary.planDir),
|
|
@@ -60055,8 +60093,8 @@ function registerPlanRoutes(app) {
|
|
|
60055
60093
|
const summaries = buildPlanSummaries(entries.slice(offset, offset + limit));
|
|
60056
60094
|
const plans = summaries.map((summary) => ({
|
|
60057
60095
|
file: relative13(process.cwd(), summary.planFile),
|
|
60058
|
-
name: basename18(
|
|
60059
|
-
slug: basename18(
|
|
60096
|
+
name: basename18(dirname23(summary.planFile)),
|
|
60097
|
+
slug: basename18(dirname23(summary.planFile)),
|
|
60060
60098
|
summary: {
|
|
60061
60099
|
...summary,
|
|
60062
60100
|
planDir: relative13(process.cwd(), summary.planDir),
|
|
@@ -61142,7 +61180,7 @@ var init_settings_routes = __esm(() => {
|
|
|
61142
61180
|
// src/domains/skills/skill-catalog-generator.ts
|
|
61143
61181
|
import { mkdir as mkdir14, readFile as readFile28, readdir as readdir15, rename as rename9, stat as stat11, writeFile as writeFile13 } from "node:fs/promises";
|
|
61144
61182
|
import { homedir as homedir35 } from "node:os";
|
|
61145
|
-
import { dirname as
|
|
61183
|
+
import { dirname as dirname24, join as join57, relative as relative14 } from "node:path";
|
|
61146
61184
|
async function hasScripts(skillPath) {
|
|
61147
61185
|
try {
|
|
61148
61186
|
const entries = await readdir15(skillPath, { withFileTypes: true });
|
|
@@ -61208,7 +61246,7 @@ class SkillCatalogGenerator {
|
|
|
61208
61246
|
};
|
|
61209
61247
|
}
|
|
61210
61248
|
async write(catalog) {
|
|
61211
|
-
await mkdir14(
|
|
61249
|
+
await mkdir14(dirname24(CATALOG_PATH), { recursive: true });
|
|
61212
61250
|
const tmpPath = `${CATALOG_PATH}.tmp`;
|
|
61213
61251
|
const json = JSON.stringify(catalog, null, 2);
|
|
61214
61252
|
await writeFile13(tmpPath, json, "utf-8");
|
|
@@ -61739,16 +61777,16 @@ var init_agents = __esm(() => {
|
|
|
61739
61777
|
import { existsSync as existsSync39 } from "node:fs";
|
|
61740
61778
|
import { mkdir as mkdir15, readFile as readFile30, writeFile as writeFile14 } from "node:fs/promises";
|
|
61741
61779
|
import { homedir as homedir38 } from "node:os";
|
|
61742
|
-
import { dirname as
|
|
61780
|
+
import { dirname as dirname25, join as join60, sep as sep10 } from "node:path";
|
|
61743
61781
|
function getCliVersion3() {
|
|
61744
61782
|
try {
|
|
61745
61783
|
if (process.env.npm_package_version) {
|
|
61746
61784
|
return process.env.npm_package_version;
|
|
61747
61785
|
}
|
|
61748
61786
|
const { readFileSync: readFileSync12 } = __require("node:fs");
|
|
61749
|
-
const { dirname:
|
|
61787
|
+
const { dirname: dirname26, join: joinPath } = __require("node:path");
|
|
61750
61788
|
const { fileURLToPath: fileURLToPath2 } = __require("node:url");
|
|
61751
|
-
const __dirname3 =
|
|
61789
|
+
const __dirname3 = dirname26(fileURLToPath2(import.meta.url));
|
|
61752
61790
|
const pkgPath = joinPath(__dirname3, "../../../package.json");
|
|
61753
61791
|
const pkg = JSON.parse(readFileSync12(pkgPath, "utf-8"));
|
|
61754
61792
|
return pkg.version || "unknown";
|
|
@@ -61791,7 +61829,7 @@ async function readRegistry2() {
|
|
|
61791
61829
|
}
|
|
61792
61830
|
}
|
|
61793
61831
|
async function writeRegistry2(registry) {
|
|
61794
|
-
const dir =
|
|
61832
|
+
const dir = dirname25(REGISTRY_PATH2);
|
|
61795
61833
|
if (!existsSync39(dir)) {
|
|
61796
61834
|
await mkdir15(dir, { recursive: true });
|
|
61797
61835
|
}
|
|
@@ -61883,7 +61921,7 @@ var init_skills_registry = __esm(() => {
|
|
|
61883
61921
|
import { existsSync as existsSync40 } from "node:fs";
|
|
61884
61922
|
import { cp as cp3, mkdir as mkdir16, rm as rm8, stat as stat12 } from "node:fs/promises";
|
|
61885
61923
|
import { homedir as homedir39 } from "node:os";
|
|
61886
|
-
import { dirname as
|
|
61924
|
+
import { dirname as dirname26, join as join61, resolve as resolve28 } from "node:path";
|
|
61887
61925
|
function isSamePath2(path1, path22) {
|
|
61888
61926
|
try {
|
|
61889
61927
|
return resolve28(path1) === resolve28(path22);
|
|
@@ -61952,7 +61990,7 @@ async function installSkillForAgent(skill, agent, options2) {
|
|
|
61952
61990
|
try {
|
|
61953
61991
|
await cleanupLegacySkillPath(skill.name, agent, options2.global);
|
|
61954
61992
|
} catch {}
|
|
61955
|
-
const parentDir =
|
|
61993
|
+
const parentDir = dirname26(targetPath);
|
|
61956
61994
|
if (!existsSync40(parentDir)) {
|
|
61957
61995
|
await mkdir16(parentDir, { recursive: true });
|
|
61958
61996
|
}
|
|
@@ -62962,7 +63000,7 @@ var package_default;
|
|
|
62962
63000
|
var init_package = __esm(() => {
|
|
62963
63001
|
package_default = {
|
|
62964
63002
|
name: "claudekit-cli",
|
|
62965
|
-
version: "4.2.2",
|
|
63003
|
+
version: "4.2.3-dev.2",
|
|
62966
63004
|
description: "CLI tool for bootstrapping and updating ClaudeKit projects",
|
|
62967
63005
|
type: "module",
|
|
62968
63006
|
repository: {
|
|
@@ -66042,7 +66080,7 @@ var init_routes = __esm(() => {
|
|
|
66042
66080
|
|
|
66043
66081
|
// src/domains/web-server/static-server.ts
|
|
66044
66082
|
import { existsSync as existsSync45 } from "node:fs";
|
|
66045
|
-
import { basename as basename21, dirname as
|
|
66083
|
+
import { basename as basename21, dirname as dirname27, join as join70, resolve as resolve30 } from "node:path";
|
|
66046
66084
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
66047
66085
|
function addRuntimeUiCandidate(candidates, runtimePath) {
|
|
66048
66086
|
if (!runtimePath) {
|
|
@@ -66052,7 +66090,7 @@ function addRuntimeUiCandidate(candidates, runtimePath) {
|
|
|
66052
66090
|
if (!looksLikePath) {
|
|
66053
66091
|
return;
|
|
66054
66092
|
}
|
|
66055
|
-
const entryDir =
|
|
66093
|
+
const entryDir = dirname27(resolve30(runtimePath));
|
|
66056
66094
|
if (basename21(entryDir) === "dist") {
|
|
66057
66095
|
candidates.add(join70(entryDir, "ui"));
|
|
66058
66096
|
}
|
|
@@ -66113,7 +66151,7 @@ var import_express, __dirname3;
|
|
|
66113
66151
|
var init_static_server = __esm(() => {
|
|
66114
66152
|
init_logger();
|
|
66115
66153
|
import_express = __toESM(require_express2(), 1);
|
|
66116
|
-
__dirname3 =
|
|
66154
|
+
__dirname3 = dirname27(fileURLToPath2(import.meta.url));
|
|
66117
66155
|
});
|
|
66118
66156
|
|
|
66119
66157
|
// node_modules/ws/lib/constants.js
|
|
@@ -71599,7 +71637,7 @@ var init_skills_installer2 = __esm(() => {
|
|
|
71599
71637
|
// src/services/package-installer/gemini-mcp/config-manager.ts
|
|
71600
71638
|
import { existsSync as existsSync59 } from "node:fs";
|
|
71601
71639
|
import { mkdir as mkdir23, readFile as readFile46, writeFile as writeFile22 } from "node:fs/promises";
|
|
71602
|
-
import { dirname as
|
|
71640
|
+
import { dirname as dirname30, join as join92 } from "node:path";
|
|
71603
71641
|
async function readJsonFile(filePath) {
|
|
71604
71642
|
try {
|
|
71605
71643
|
const content = await readFile46(filePath, "utf-8");
|
|
@@ -71639,7 +71677,7 @@ ${geminiPattern}
|
|
|
71639
71677
|
}
|
|
71640
71678
|
}
|
|
71641
71679
|
async function createNewSettingsWithMerge(geminiSettingsPath, mcpConfigPath) {
|
|
71642
|
-
const linkDir =
|
|
71680
|
+
const linkDir = dirname30(geminiSettingsPath);
|
|
71643
71681
|
if (!existsSync59(linkDir)) {
|
|
71644
71682
|
await mkdir23(linkDir, { recursive: true });
|
|
71645
71683
|
logger.debug(`Created directory: ${linkDir}`);
|
|
@@ -71758,9 +71796,9 @@ var init_validation = __esm(() => {
|
|
|
71758
71796
|
// src/services/package-installer/gemini-mcp/linker-core.ts
|
|
71759
71797
|
import { existsSync as existsSync61 } from "node:fs";
|
|
71760
71798
|
import { mkdir as mkdir24, symlink as symlink3 } from "node:fs/promises";
|
|
71761
|
-
import { dirname as
|
|
71799
|
+
import { dirname as dirname31, join as join94 } from "node:path";
|
|
71762
71800
|
async function createSymlink(targetPath, linkPath, projectDir, isGlobal) {
|
|
71763
|
-
const linkDir =
|
|
71801
|
+
const linkDir = dirname31(linkPath);
|
|
71764
71802
|
if (!existsSync61(linkDir)) {
|
|
71765
71803
|
await mkdir24(linkDir, { recursive: true });
|
|
71766
71804
|
logger.debug(`Created directory: ${linkDir}`);
|
|
@@ -74078,76 +74116,6 @@ var init_ownership_display = __esm(() => {
|
|
|
74078
74116
|
import_picocolors25 = __toESM(require_picocolors(), 1);
|
|
74079
74117
|
});
|
|
74080
74118
|
|
|
74081
|
-
// src/ui/node_modules/picocolors/picocolors.js
|
|
74082
|
-
var require_picocolors2 = __commonJS((exports, module) => {
|
|
74083
|
-
var p = process || {};
|
|
74084
|
-
var argv = p.argv || [];
|
|
74085
|
-
var env2 = p.env || {};
|
|
74086
|
-
var isColorSupported = !(!!env2.NO_COLOR || argv.includes("--no-color")) && (!!env2.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env2.TERM !== "dumb" || !!env2.CI);
|
|
74087
|
-
var formatter = (open6, close, replace3 = open6) => (input) => {
|
|
74088
|
-
let string = "" + input, index = string.indexOf(close, open6.length);
|
|
74089
|
-
return ~index ? open6 + replaceClose(string, close, replace3, index) + close : open6 + string + close;
|
|
74090
|
-
};
|
|
74091
|
-
var replaceClose = (string, close, replace3, index) => {
|
|
74092
|
-
let result = "", cursor = 0;
|
|
74093
|
-
do {
|
|
74094
|
-
result += string.substring(cursor, index) + replace3;
|
|
74095
|
-
cursor = index + close.length;
|
|
74096
|
-
index = string.indexOf(close, cursor);
|
|
74097
|
-
} while (~index);
|
|
74098
|
-
return result + string.substring(cursor);
|
|
74099
|
-
};
|
|
74100
|
-
var createColors = (enabled = isColorSupported) => {
|
|
74101
|
-
let f3 = enabled ? formatter : () => String;
|
|
74102
|
-
return {
|
|
74103
|
-
isColorSupported: enabled,
|
|
74104
|
-
reset: f3("\x1B[0m", "\x1B[0m"),
|
|
74105
|
-
bold: f3("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
|
|
74106
|
-
dim: f3("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
|
|
74107
|
-
italic: f3("\x1B[3m", "\x1B[23m"),
|
|
74108
|
-
underline: f3("\x1B[4m", "\x1B[24m"),
|
|
74109
|
-
inverse: f3("\x1B[7m", "\x1B[27m"),
|
|
74110
|
-
hidden: f3("\x1B[8m", "\x1B[28m"),
|
|
74111
|
-
strikethrough: f3("\x1B[9m", "\x1B[29m"),
|
|
74112
|
-
black: f3("\x1B[30m", "\x1B[39m"),
|
|
74113
|
-
red: f3("\x1B[31m", "\x1B[39m"),
|
|
74114
|
-
green: f3("\x1B[32m", "\x1B[39m"),
|
|
74115
|
-
yellow: f3("\x1B[33m", "\x1B[39m"),
|
|
74116
|
-
blue: f3("\x1B[34m", "\x1B[39m"),
|
|
74117
|
-
magenta: f3("\x1B[35m", "\x1B[39m"),
|
|
74118
|
-
cyan: f3("\x1B[36m", "\x1B[39m"),
|
|
74119
|
-
white: f3("\x1B[37m", "\x1B[39m"),
|
|
74120
|
-
gray: f3("\x1B[90m", "\x1B[39m"),
|
|
74121
|
-
bgBlack: f3("\x1B[40m", "\x1B[49m"),
|
|
74122
|
-
bgRed: f3("\x1B[41m", "\x1B[49m"),
|
|
74123
|
-
bgGreen: f3("\x1B[42m", "\x1B[49m"),
|
|
74124
|
-
bgYellow: f3("\x1B[43m", "\x1B[49m"),
|
|
74125
|
-
bgBlue: f3("\x1B[44m", "\x1B[49m"),
|
|
74126
|
-
bgMagenta: f3("\x1B[45m", "\x1B[49m"),
|
|
74127
|
-
bgCyan: f3("\x1B[46m", "\x1B[49m"),
|
|
74128
|
-
bgWhite: f3("\x1B[47m", "\x1B[49m"),
|
|
74129
|
-
blackBright: f3("\x1B[90m", "\x1B[39m"),
|
|
74130
|
-
redBright: f3("\x1B[91m", "\x1B[39m"),
|
|
74131
|
-
greenBright: f3("\x1B[92m", "\x1B[39m"),
|
|
74132
|
-
yellowBright: f3("\x1B[93m", "\x1B[39m"),
|
|
74133
|
-
blueBright: f3("\x1B[94m", "\x1B[39m"),
|
|
74134
|
-
magentaBright: f3("\x1B[95m", "\x1B[39m"),
|
|
74135
|
-
cyanBright: f3("\x1B[96m", "\x1B[39m"),
|
|
74136
|
-
whiteBright: f3("\x1B[97m", "\x1B[39m"),
|
|
74137
|
-
bgBlackBright: f3("\x1B[100m", "\x1B[49m"),
|
|
74138
|
-
bgRedBright: f3("\x1B[101m", "\x1B[49m"),
|
|
74139
|
-
bgGreenBright: f3("\x1B[102m", "\x1B[49m"),
|
|
74140
|
-
bgYellowBright: f3("\x1B[103m", "\x1B[49m"),
|
|
74141
|
-
bgBlueBright: f3("\x1B[104m", "\x1B[49m"),
|
|
74142
|
-
bgMagentaBright: f3("\x1B[105m", "\x1B[49m"),
|
|
74143
|
-
bgCyanBright: f3("\x1B[106m", "\x1B[49m"),
|
|
74144
|
-
bgWhiteBright: f3("\x1B[107m", "\x1B[49m")
|
|
74145
|
-
};
|
|
74146
|
-
};
|
|
74147
|
-
module.exports = createColors();
|
|
74148
|
-
module.exports.createColors = createColors;
|
|
74149
|
-
});
|
|
74150
|
-
|
|
74151
74119
|
// src/commands/watch/phases/implementation-git-helpers.ts
|
|
74152
74120
|
import { spawn as spawn5 } from "node:child_process";
|
|
74153
74121
|
async function getCurrentBranch2(cwd2) {
|
|
@@ -74256,9 +74224,9 @@ __export(exports_worktree_manager, {
|
|
|
74256
74224
|
});
|
|
74257
74225
|
import { existsSync as existsSync70 } from "node:fs";
|
|
74258
74226
|
import { readFile as readFile66, writeFile as writeFile37 } from "node:fs/promises";
|
|
74259
|
-
import { join as
|
|
74227
|
+
import { join as join153 } from "node:path";
|
|
74260
74228
|
async function createWorktree(projectDir, issueNumber, baseBranch) {
|
|
74261
|
-
const worktreePath =
|
|
74229
|
+
const worktreePath = join153(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
|
|
74262
74230
|
const branchName = `ck-watch/issue-${issueNumber}`;
|
|
74263
74231
|
await spawnAndCollect("git", ["fetch", "origin", baseBranch], projectDir).catch(() => {
|
|
74264
74232
|
logger.warning(`[worktree] Could not fetch origin/${baseBranch}, using local`);
|
|
@@ -74276,7 +74244,7 @@ async function createWorktree(projectDir, issueNumber, baseBranch) {
|
|
|
74276
74244
|
return worktreePath;
|
|
74277
74245
|
}
|
|
74278
74246
|
async function removeWorktree(projectDir, issueNumber) {
|
|
74279
|
-
const worktreePath =
|
|
74247
|
+
const worktreePath = join153(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
|
|
74280
74248
|
const branchName = `ck-watch/issue-${issueNumber}`;
|
|
74281
74249
|
try {
|
|
74282
74250
|
await spawnAndCollect("git", ["worktree", "remove", worktreePath, "--force"], projectDir);
|
|
@@ -74290,7 +74258,7 @@ async function listActiveWorktrees(projectDir) {
|
|
|
74290
74258
|
try {
|
|
74291
74259
|
const output2 = await spawnAndCollect("git", ["worktree", "list", "--porcelain"], projectDir);
|
|
74292
74260
|
const issueNumbers = [];
|
|
74293
|
-
const worktreePrefix =
|
|
74261
|
+
const worktreePrefix = join153(projectDir, WORKTREE_DIR, "issue-").replace(/\\/g, "/");
|
|
74294
74262
|
for (const line of output2.split(`
|
|
74295
74263
|
`)) {
|
|
74296
74264
|
if (line.startsWith("worktree ")) {
|
|
@@ -74318,7 +74286,7 @@ async function cleanupAllWorktrees(projectDir) {
|
|
|
74318
74286
|
await spawnAndCollect("git", ["worktree", "prune"], projectDir).catch(() => {});
|
|
74319
74287
|
}
|
|
74320
74288
|
async function ensureGitignore(projectDir) {
|
|
74321
|
-
const gitignorePath =
|
|
74289
|
+
const gitignorePath = join153(projectDir, ".gitignore");
|
|
74322
74290
|
try {
|
|
74323
74291
|
const content = existsSync70(gitignorePath) ? await readFile66(gitignorePath, "utf-8") : "";
|
|
74324
74292
|
if (!content.includes(".worktrees")) {
|
|
@@ -74347,8 +74315,8 @@ function countTwitterChars(text) {
|
|
|
74347
74315
|
const withoutUrls = text.replace(urlPattern, "");
|
|
74348
74316
|
let count = urlCount * 23;
|
|
74349
74317
|
for (const char of withoutUrls) {
|
|
74350
|
-
const
|
|
74351
|
-
if (
|
|
74318
|
+
const cp6 = char.codePointAt(0) ?? 0;
|
|
74319
|
+
if (cp6 >= 19968 && cp6 <= 40959 || cp6 >= 13312 && cp6 <= 19903 || cp6 >= 131072 && cp6 <= 173791 || cp6 >= 173824 && cp6 <= 191471 || cp6 >= 196608 && cp6 <= 205743 || cp6 >= 63744 && cp6 <= 64255 || cp6 >= 12288 && cp6 <= 12351 || cp6 >= 12352 && cp6 <= 12447 || cp6 >= 12448 && cp6 <= 12543 || cp6 >= 65280 && cp6 <= 65519) {
|
|
74352
74320
|
count += 2;
|
|
74353
74321
|
} else {
|
|
74354
74322
|
count += 1;
|
|
@@ -74423,9 +74391,9 @@ var init_content_validator = __esm(() => {
|
|
|
74423
74391
|
// src/commands/content/phases/context-cache-manager.ts
|
|
74424
74392
|
import { createHash as createHash9 } from "node:crypto";
|
|
74425
74393
|
import { existsSync as existsSync76, mkdirSync as mkdirSync5, readFileSync as readFileSync18, readdirSync as readdirSync11, statSync as statSync14 } from "node:fs";
|
|
74426
|
-
import { rename as
|
|
74427
|
-
import { homedir as
|
|
74428
|
-
import { basename as basename31, join as
|
|
74394
|
+
import { rename as rename15, writeFile as writeFile39 } from "node:fs/promises";
|
|
74395
|
+
import { homedir as homedir54 } from "node:os";
|
|
74396
|
+
import { basename as basename31, join as join160 } from "node:path";
|
|
74429
74397
|
function getCachedContext(repoPath) {
|
|
74430
74398
|
const cachePath = getCacheFilePath(repoPath);
|
|
74431
74399
|
if (!existsSync76(cachePath))
|
|
@@ -74451,15 +74419,15 @@ async function saveCachedContext(repoPath, cache5) {
|
|
|
74451
74419
|
const cachePath = getCacheFilePath(repoPath);
|
|
74452
74420
|
const tmpPath = `${cachePath}.tmp`;
|
|
74453
74421
|
await writeFile39(tmpPath, JSON.stringify(cache5, null, 2), "utf-8");
|
|
74454
|
-
await
|
|
74422
|
+
await rename15(tmpPath, cachePath);
|
|
74455
74423
|
}
|
|
74456
74424
|
function computeSourceHash(repoPath) {
|
|
74457
74425
|
const hash = createHash9("sha256");
|
|
74458
74426
|
const paths = getDocSourcePaths(repoPath);
|
|
74459
74427
|
for (const filePath of paths) {
|
|
74460
74428
|
try {
|
|
74461
|
-
const
|
|
74462
|
-
hash.update(`${filePath}:${
|
|
74429
|
+
const stat26 = statSync14(filePath);
|
|
74430
|
+
hash.update(`${filePath}:${stat26.mtimeMs}`);
|
|
74463
74431
|
} catch {
|
|
74464
74432
|
hash.update(`${filePath}:0`);
|
|
74465
74433
|
}
|
|
@@ -74468,25 +74436,25 @@ function computeSourceHash(repoPath) {
|
|
|
74468
74436
|
}
|
|
74469
74437
|
function getDocSourcePaths(repoPath) {
|
|
74470
74438
|
const paths = [];
|
|
74471
|
-
const docsDir =
|
|
74439
|
+
const docsDir = join160(repoPath, "docs");
|
|
74472
74440
|
if (existsSync76(docsDir)) {
|
|
74473
74441
|
try {
|
|
74474
74442
|
const files = readdirSync11(docsDir);
|
|
74475
74443
|
for (const f3 of files) {
|
|
74476
74444
|
if (f3.endsWith(".md"))
|
|
74477
|
-
paths.push(
|
|
74445
|
+
paths.push(join160(docsDir, f3));
|
|
74478
74446
|
}
|
|
74479
74447
|
} catch {}
|
|
74480
74448
|
}
|
|
74481
|
-
const readme =
|
|
74449
|
+
const readme = join160(repoPath, "README.md");
|
|
74482
74450
|
if (existsSync76(readme))
|
|
74483
74451
|
paths.push(readme);
|
|
74484
|
-
const stylesDir =
|
|
74452
|
+
const stylesDir = join160(repoPath, "assets", "writing-styles");
|
|
74485
74453
|
if (existsSync76(stylesDir)) {
|
|
74486
74454
|
try {
|
|
74487
74455
|
const files = readdirSync11(stylesDir);
|
|
74488
74456
|
for (const f3 of files) {
|
|
74489
|
-
paths.push(
|
|
74457
|
+
paths.push(join160(stylesDir, f3));
|
|
74490
74458
|
}
|
|
74491
74459
|
} catch {}
|
|
74492
74460
|
}
|
|
@@ -74495,11 +74463,11 @@ function getDocSourcePaths(repoPath) {
|
|
|
74495
74463
|
function getCacheFilePath(repoPath) {
|
|
74496
74464
|
const repoName = basename31(repoPath).replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
74497
74465
|
const pathHash = createHash9("sha256").update(repoPath).digest("hex").slice(0, 8);
|
|
74498
|
-
return
|
|
74466
|
+
return join160(CACHE_DIR, `${repoName}-${pathHash}-context-cache.json`);
|
|
74499
74467
|
}
|
|
74500
74468
|
var CACHE_DIR, CACHE_TTL_MS5;
|
|
74501
74469
|
var init_context_cache_manager = __esm(() => {
|
|
74502
|
-
CACHE_DIR =
|
|
74470
|
+
CACHE_DIR = join160(homedir54(), ".claudekit", "cache");
|
|
74503
74471
|
CACHE_TTL_MS5 = 24 * 60 * 60 * 1000;
|
|
74504
74472
|
});
|
|
74505
74473
|
|
|
@@ -74680,7 +74648,7 @@ function extractContentFromResponse(response) {
|
|
|
74680
74648
|
// src/commands/content/phases/docs-summarizer.ts
|
|
74681
74649
|
import { execSync as execSync7 } from "node:child_process";
|
|
74682
74650
|
import { existsSync as existsSync77, readFileSync as readFileSync19, readdirSync as readdirSync12 } from "node:fs";
|
|
74683
|
-
import { join as
|
|
74651
|
+
import { join as join161 } from "node:path";
|
|
74684
74652
|
async function summarizeProjectDocs(repoPath, contentLogger) {
|
|
74685
74653
|
const rawContent = collectRawDocs(repoPath);
|
|
74686
74654
|
if (rawContent.total.length < 200) {
|
|
@@ -74734,12 +74702,12 @@ function collectRawDocs(repoPath) {
|
|
|
74734
74702
|
return capped;
|
|
74735
74703
|
};
|
|
74736
74704
|
const docsContent = [];
|
|
74737
|
-
const docsDir =
|
|
74705
|
+
const docsDir = join161(repoPath, "docs");
|
|
74738
74706
|
if (existsSync77(docsDir)) {
|
|
74739
74707
|
try {
|
|
74740
74708
|
const files = readdirSync12(docsDir).filter((f3) => f3.endsWith(".md")).sort();
|
|
74741
74709
|
for (const f3 of files) {
|
|
74742
|
-
const content = readCapped(
|
|
74710
|
+
const content = readCapped(join161(docsDir, f3), 5000);
|
|
74743
74711
|
if (content) {
|
|
74744
74712
|
docsContent.push(`### ${f3}
|
|
74745
74713
|
${content}`);
|
|
@@ -74753,21 +74721,21 @@ ${content}`);
|
|
|
74753
74721
|
let brand = "";
|
|
74754
74722
|
const brandCandidates = ["docs/brand-guidelines.md", "docs/design-guidelines.md"];
|
|
74755
74723
|
for (const p of brandCandidates) {
|
|
74756
|
-
brand = readCapped(
|
|
74724
|
+
brand = readCapped(join161(repoPath, p), 3000);
|
|
74757
74725
|
if (brand)
|
|
74758
74726
|
break;
|
|
74759
74727
|
}
|
|
74760
74728
|
let styles3 = "";
|
|
74761
|
-
const stylesDir =
|
|
74729
|
+
const stylesDir = join161(repoPath, "assets", "writing-styles");
|
|
74762
74730
|
if (existsSync77(stylesDir)) {
|
|
74763
74731
|
try {
|
|
74764
74732
|
const files = readdirSync12(stylesDir).slice(0, 3);
|
|
74765
|
-
styles3 = files.map((f3) => readCapped(
|
|
74733
|
+
styles3 = files.map((f3) => readCapped(join161(stylesDir, f3), 1000)).filter(Boolean).join(`
|
|
74766
74734
|
|
|
74767
74735
|
`);
|
|
74768
74736
|
} catch {}
|
|
74769
74737
|
}
|
|
74770
|
-
const readme = readCapped(
|
|
74738
|
+
const readme = readCapped(join161(repoPath, "README.md"), 3000);
|
|
74771
74739
|
const total = [docs, brand, styles3, readme].join(`
|
|
74772
74740
|
`);
|
|
74773
74741
|
return { docs, brand, styles: styles3, readme, total };
|
|
@@ -74953,10 +74921,10 @@ IMPORTANT: Generate the image and output the path as JSON: {"imagePath": "/path/
|
|
|
74953
74921
|
// src/commands/content/phases/photo-generator.ts
|
|
74954
74922
|
import { execSync as execSync8 } from "node:child_process";
|
|
74955
74923
|
import { existsSync as existsSync78, mkdirSync as mkdirSync6, readdirSync as readdirSync13 } from "node:fs";
|
|
74956
|
-
import { homedir as
|
|
74957
|
-
import { join as
|
|
74924
|
+
import { homedir as homedir55 } from "node:os";
|
|
74925
|
+
import { join as join162 } from "node:path";
|
|
74958
74926
|
async function generatePhoto(_content, context, config, platform18, contentId, contentLogger) {
|
|
74959
|
-
const mediaDir =
|
|
74927
|
+
const mediaDir = join162(config.contentDir.replace(/^~/, homedir55()), "media", String(contentId));
|
|
74960
74928
|
if (!existsSync78(mediaDir)) {
|
|
74961
74929
|
mkdirSync6(mediaDir, { recursive: true });
|
|
74962
74930
|
}
|
|
@@ -74981,7 +74949,7 @@ async function generatePhoto(_content, context, config, platform18, contentId, c
|
|
|
74981
74949
|
const imageFile = files.find((f3) => /\.(png|jpg|jpeg|webp)$/i.test(f3));
|
|
74982
74950
|
if (imageFile) {
|
|
74983
74951
|
const ext2 = imageFile.split(".").pop() ?? "png";
|
|
74984
|
-
return { path:
|
|
74952
|
+
return { path: join162(mediaDir, imageFile), ...dimensions, format: ext2 };
|
|
74985
74953
|
}
|
|
74986
74954
|
contentLogger.warn(`Photo generation produced no image for content ${contentId}`);
|
|
74987
74955
|
return null;
|
|
@@ -75070,8 +75038,8 @@ var init_content_creator = __esm(() => {
|
|
|
75070
75038
|
|
|
75071
75039
|
// src/commands/content/phases/content-logger.ts
|
|
75072
75040
|
import { createWriteStream as createWriteStream4, existsSync as existsSync79, mkdirSync as mkdirSync7, statSync as statSync15 } from "node:fs";
|
|
75073
|
-
import { homedir as
|
|
75074
|
-
import { join as
|
|
75041
|
+
import { homedir as homedir56 } from "node:os";
|
|
75042
|
+
import { join as join163 } from "node:path";
|
|
75075
75043
|
|
|
75076
75044
|
class ContentLogger {
|
|
75077
75045
|
stream = null;
|
|
@@ -75079,7 +75047,7 @@ class ContentLogger {
|
|
|
75079
75047
|
logDir;
|
|
75080
75048
|
maxBytes;
|
|
75081
75049
|
constructor(maxBytes = 0) {
|
|
75082
|
-
this.logDir =
|
|
75050
|
+
this.logDir = join163(homedir56(), ".claudekit", "logs");
|
|
75083
75051
|
this.maxBytes = maxBytes;
|
|
75084
75052
|
}
|
|
75085
75053
|
init() {
|
|
@@ -75111,7 +75079,7 @@ class ContentLogger {
|
|
|
75111
75079
|
}
|
|
75112
75080
|
}
|
|
75113
75081
|
getLogPath() {
|
|
75114
|
-
return
|
|
75082
|
+
return join163(this.logDir, `content-${this.getDateStr()}.log`);
|
|
75115
75083
|
}
|
|
75116
75084
|
write(level, message) {
|
|
75117
75085
|
this.rotateIfNeeded();
|
|
@@ -75128,19 +75096,19 @@ class ContentLogger {
|
|
|
75128
75096
|
if (dateStr !== this.currentDate) {
|
|
75129
75097
|
this.close();
|
|
75130
75098
|
this.currentDate = dateStr;
|
|
75131
|
-
const logPath =
|
|
75099
|
+
const logPath = join163(this.logDir, `content-${dateStr}.log`);
|
|
75132
75100
|
this.stream = createWriteStream4(logPath, { flags: "a", mode: 384 });
|
|
75133
75101
|
return;
|
|
75134
75102
|
}
|
|
75135
75103
|
if (this.maxBytes > 0 && this.stream) {
|
|
75136
|
-
const logPath =
|
|
75104
|
+
const logPath = join163(this.logDir, `content-${this.currentDate}.log`);
|
|
75137
75105
|
try {
|
|
75138
|
-
const
|
|
75139
|
-
if (
|
|
75106
|
+
const stat26 = statSync15(logPath);
|
|
75107
|
+
if (stat26.size >= this.maxBytes) {
|
|
75140
75108
|
this.close();
|
|
75141
75109
|
const suffix = Date.now();
|
|
75142
|
-
const rotatedPath =
|
|
75143
|
-
import("node:fs/promises").then(({ rename:
|
|
75110
|
+
const rotatedPath = join163(this.logDir, `content-${this.currentDate}-${suffix}.log`);
|
|
75111
|
+
import("node:fs/promises").then(({ rename: rename16 }) => rename16(logPath, rotatedPath).catch(() => {}));
|
|
75144
75112
|
this.stream = createWriteStream4(logPath, { flags: "w", mode: 384 });
|
|
75145
75113
|
}
|
|
75146
75114
|
} catch {}
|
|
@@ -75177,7 +75145,7 @@ var init_sqlite_client = () => {};
|
|
|
75177
75145
|
|
|
75178
75146
|
// src/commands/content/phases/db-manager.ts
|
|
75179
75147
|
import { existsSync as existsSync80, mkdirSync as mkdirSync8 } from "node:fs";
|
|
75180
|
-
import { dirname as
|
|
75148
|
+
import { dirname as dirname49 } from "node:path";
|
|
75181
75149
|
function initDatabase(dbPath) {
|
|
75182
75150
|
ensureParentDir(dbPath);
|
|
75183
75151
|
const db = openDatabase(dbPath);
|
|
@@ -75198,7 +75166,7 @@ function runRetentionCleanup(db, retentionDays = 90) {
|
|
|
75198
75166
|
db.prepare("DELETE FROM git_events WHERE processed = 1 AND created_at < ?").run(cutoff);
|
|
75199
75167
|
}
|
|
75200
75168
|
function ensureParentDir(dbPath) {
|
|
75201
|
-
const dir =
|
|
75169
|
+
const dir = dirname49(dbPath);
|
|
75202
75170
|
if (dir && !existsSync80(dir)) {
|
|
75203
75171
|
mkdirSync8(dir, { recursive: true });
|
|
75204
75172
|
}
|
|
@@ -75365,7 +75333,7 @@ function isNoiseCommit(title, author) {
|
|
|
75365
75333
|
// src/commands/content/phases/change-detector.ts
|
|
75366
75334
|
import { execSync as execSync10, spawnSync as spawnSync9 } from "node:child_process";
|
|
75367
75335
|
import { existsSync as existsSync81, readFileSync as readFileSync20, readdirSync as readdirSync14, statSync as statSync16 } from "node:fs";
|
|
75368
|
-
import { join as
|
|
75336
|
+
import { join as join164 } from "node:path";
|
|
75369
75337
|
function detectCommits(repo, since) {
|
|
75370
75338
|
try {
|
|
75371
75339
|
const fetchUrl = sshToHttps(repo.remoteUrl);
|
|
@@ -75474,7 +75442,7 @@ function detectTags(repo, since) {
|
|
|
75474
75442
|
}
|
|
75475
75443
|
}
|
|
75476
75444
|
function detectCompletedPlans(repo, since) {
|
|
75477
|
-
const plansDir =
|
|
75445
|
+
const plansDir = join164(repo.path, "plans");
|
|
75478
75446
|
if (!existsSync81(plansDir))
|
|
75479
75447
|
return [];
|
|
75480
75448
|
const sinceMs = new Date(since).getTime();
|
|
@@ -75484,12 +75452,12 @@ function detectCompletedPlans(repo, since) {
|
|
|
75484
75452
|
for (const entry of entries) {
|
|
75485
75453
|
if (!entry.isDirectory())
|
|
75486
75454
|
continue;
|
|
75487
|
-
const planFile =
|
|
75455
|
+
const planFile = join164(plansDir, entry.name, "plan.md");
|
|
75488
75456
|
if (!existsSync81(planFile))
|
|
75489
75457
|
continue;
|
|
75490
75458
|
try {
|
|
75491
|
-
const
|
|
75492
|
-
if (
|
|
75459
|
+
const stat26 = statSync16(planFile);
|
|
75460
|
+
if (stat26.mtimeMs < sinceMs)
|
|
75493
75461
|
continue;
|
|
75494
75462
|
const content = readFileSync20(planFile, "utf-8");
|
|
75495
75463
|
const frontmatterMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
@@ -75505,7 +75473,7 @@ function detectCompletedPlans(repo, since) {
|
|
|
75505
75473
|
title: `Plan completed: ${entry.name}`,
|
|
75506
75474
|
body: "",
|
|
75507
75475
|
author: "",
|
|
75508
|
-
createdAt: new Date(
|
|
75476
|
+
createdAt: new Date(stat26.mtimeMs).toISOString()
|
|
75509
75477
|
});
|
|
75510
75478
|
} catch {}
|
|
75511
75479
|
}
|
|
@@ -75562,7 +75530,7 @@ function classifyCommit(event) {
|
|
|
75562
75530
|
// src/commands/content/phases/repo-discoverer.ts
|
|
75563
75531
|
import { execSync as execSync11 } from "node:child_process";
|
|
75564
75532
|
import { readdirSync as readdirSync15 } from "node:fs";
|
|
75565
|
-
import { join as
|
|
75533
|
+
import { join as join165 } from "node:path";
|
|
75566
75534
|
function discoverRepos2(cwd2) {
|
|
75567
75535
|
const repos = [];
|
|
75568
75536
|
if (isGitRepoRoot(cwd2)) {
|
|
@@ -75575,7 +75543,7 @@ function discoverRepos2(cwd2) {
|
|
|
75575
75543
|
for (const entry of entries) {
|
|
75576
75544
|
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
75577
75545
|
continue;
|
|
75578
|
-
const dirPath =
|
|
75546
|
+
const dirPath = join165(cwd2, entry.name);
|
|
75579
75547
|
if (isGitRepoRoot(dirPath)) {
|
|
75580
75548
|
const info = getRepoInfo(dirPath);
|
|
75581
75549
|
if (info)
|
|
@@ -76242,10 +76210,10 @@ var init_types6 = __esm(() => {
|
|
|
76242
76210
|
});
|
|
76243
76211
|
|
|
76244
76212
|
// src/commands/content/phases/state-manager.ts
|
|
76245
|
-
import { readFile as readFile68, rename as
|
|
76246
|
-
import { join as
|
|
76213
|
+
import { readFile as readFile68, rename as rename16, writeFile as writeFile40 } from "node:fs/promises";
|
|
76214
|
+
import { join as join166 } from "node:path";
|
|
76247
76215
|
async function loadContentConfig(projectDir) {
|
|
76248
|
-
const configPath =
|
|
76216
|
+
const configPath = join166(projectDir, CK_CONFIG_FILE2);
|
|
76249
76217
|
try {
|
|
76250
76218
|
const raw2 = await readFile68(configPath, "utf-8");
|
|
76251
76219
|
const json = JSON.parse(raw2);
|
|
@@ -76255,13 +76223,13 @@ async function loadContentConfig(projectDir) {
|
|
|
76255
76223
|
}
|
|
76256
76224
|
}
|
|
76257
76225
|
async function saveContentConfig(projectDir, config) {
|
|
76258
|
-
const configPath =
|
|
76226
|
+
const configPath = join166(projectDir, CK_CONFIG_FILE2);
|
|
76259
76227
|
const json = await readJsonSafe(configPath);
|
|
76260
76228
|
json.content = { ...json.content, ...config };
|
|
76261
76229
|
await atomicWrite2(configPath, json);
|
|
76262
76230
|
}
|
|
76263
76231
|
async function loadContentState(projectDir) {
|
|
76264
|
-
const configPath =
|
|
76232
|
+
const configPath = join166(projectDir, CK_CONFIG_FILE2);
|
|
76265
76233
|
try {
|
|
76266
76234
|
const raw2 = await readFile68(configPath, "utf-8");
|
|
76267
76235
|
const json = JSON.parse(raw2);
|
|
@@ -76272,7 +76240,7 @@ async function loadContentState(projectDir) {
|
|
|
76272
76240
|
}
|
|
76273
76241
|
}
|
|
76274
76242
|
async function saveContentState(projectDir, state) {
|
|
76275
|
-
const configPath =
|
|
76243
|
+
const configPath = join166(projectDir, CK_CONFIG_FILE2);
|
|
76276
76244
|
const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().slice(0, 10);
|
|
76277
76245
|
for (const key of Object.keys(state.dailyPostCounts)) {
|
|
76278
76246
|
const dateStr = key.slice(-10);
|
|
@@ -76299,7 +76267,7 @@ async function readJsonSafe(filePath) {
|
|
|
76299
76267
|
async function atomicWrite2(filePath, data) {
|
|
76300
76268
|
const tmpPath = `${filePath}.tmp`;
|
|
76301
76269
|
await writeFile40(tmpPath, JSON.stringify(data, null, 2), "utf-8");
|
|
76302
|
-
await
|
|
76270
|
+
await rename16(tmpPath, filePath);
|
|
76303
76271
|
}
|
|
76304
76272
|
var CK_CONFIG_FILE2 = ".ck.json";
|
|
76305
76273
|
var init_state_manager = __esm(() => {
|
|
@@ -76554,7 +76522,7 @@ var init_platform_setup_x = __esm(() => {
|
|
|
76554
76522
|
|
|
76555
76523
|
// src/commands/content/phases/setup-wizard.ts
|
|
76556
76524
|
import { existsSync as existsSync82 } from "node:fs";
|
|
76557
|
-
import { join as
|
|
76525
|
+
import { join as join167 } from "node:path";
|
|
76558
76526
|
async function runSetupWizard2(cwd2, contentLogger) {
|
|
76559
76527
|
console.log();
|
|
76560
76528
|
oe(import_picocolors43.default.bgCyan(import_picocolors43.default.white(" CK Content — Multi-Channel Content Engine ")));
|
|
@@ -76622,8 +76590,8 @@ async function showRepoSummary(cwd2) {
|
|
|
76622
76590
|
function detectBrandAssets(cwd2, contentLogger) {
|
|
76623
76591
|
const repos = discoverRepos2(cwd2);
|
|
76624
76592
|
for (const repo of repos) {
|
|
76625
|
-
const hasGuidelines = existsSync82(
|
|
76626
|
-
const hasStyles = existsSync82(
|
|
76593
|
+
const hasGuidelines = existsSync82(join167(repo.path, "docs", "brand-guidelines.md"));
|
|
76594
|
+
const hasStyles = existsSync82(join167(repo.path, "assets", "writing-styles"));
|
|
76627
76595
|
if (!hasGuidelines) {
|
|
76628
76596
|
f2.warning(`${repo.name}: No docs/brand-guidelines.md — content will use generic tone.`);
|
|
76629
76597
|
contentLogger.warn(`${repo.name}: missing docs/brand-guidelines.md`);
|
|
@@ -76690,11 +76658,11 @@ var init_setup_wizard = __esm(() => {
|
|
|
76690
76658
|
|
|
76691
76659
|
// src/commands/content/content-review-commands.ts
|
|
76692
76660
|
import { existsSync as existsSync83 } from "node:fs";
|
|
76693
|
-
import { homedir as
|
|
76661
|
+
import { homedir as homedir57 } from "node:os";
|
|
76694
76662
|
async function queueContent() {
|
|
76695
76663
|
const cwd2 = process.cwd();
|
|
76696
76664
|
const config = await loadContentConfig(cwd2);
|
|
76697
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
76665
|
+
const dbPath = config.dbPath.replace(/^~/, homedir57());
|
|
76698
76666
|
if (!existsSync83(dbPath)) {
|
|
76699
76667
|
logger.info("No content database found. Run 'ck content setup' first.");
|
|
76700
76668
|
return;
|
|
@@ -76721,7 +76689,7 @@ async function queueContent() {
|
|
|
76721
76689
|
async function approveContentCmd(id) {
|
|
76722
76690
|
const cwd2 = process.cwd();
|
|
76723
76691
|
const config = await loadContentConfig(cwd2);
|
|
76724
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
76692
|
+
const dbPath = config.dbPath.replace(/^~/, homedir57());
|
|
76725
76693
|
const db = initDatabase(dbPath);
|
|
76726
76694
|
try {
|
|
76727
76695
|
approveContent(db, Number.parseInt(id, 10));
|
|
@@ -76733,7 +76701,7 @@ async function approveContentCmd(id) {
|
|
|
76733
76701
|
async function rejectContentCmd(id, reason) {
|
|
76734
76702
|
const cwd2 = process.cwd();
|
|
76735
76703
|
const config = await loadContentConfig(cwd2);
|
|
76736
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
76704
|
+
const dbPath = config.dbPath.replace(/^~/, homedir57());
|
|
76737
76705
|
const db = initDatabase(dbPath);
|
|
76738
76706
|
try {
|
|
76739
76707
|
rejectContent(db, Number.parseInt(id, 10), reason);
|
|
@@ -76764,10 +76732,10 @@ __export(exports_content_subcommands, {
|
|
|
76764
76732
|
approveContentCmd: () => approveContentCmd
|
|
76765
76733
|
});
|
|
76766
76734
|
import { existsSync as existsSync84, readFileSync as readFileSync21, unlinkSync as unlinkSync6 } from "node:fs";
|
|
76767
|
-
import { homedir as
|
|
76768
|
-
import { join as
|
|
76735
|
+
import { homedir as homedir58 } from "node:os";
|
|
76736
|
+
import { join as join168 } from "node:path";
|
|
76769
76737
|
function isDaemonRunning() {
|
|
76770
|
-
const lockFile =
|
|
76738
|
+
const lockFile = join168(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
76771
76739
|
if (!existsSync84(lockFile))
|
|
76772
76740
|
return { running: false, pid: null };
|
|
76773
76741
|
try {
|
|
@@ -76799,7 +76767,7 @@ async function startContent(options2) {
|
|
|
76799
76767
|
await contentCommand(options2);
|
|
76800
76768
|
}
|
|
76801
76769
|
async function stopContent() {
|
|
76802
|
-
const lockFile =
|
|
76770
|
+
const lockFile = join168(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
76803
76771
|
if (!existsSync84(lockFile)) {
|
|
76804
76772
|
logger.info("Content daemon is not running.");
|
|
76805
76773
|
return;
|
|
@@ -76838,9 +76806,9 @@ async function statusContent() {
|
|
|
76838
76806
|
} catch {}
|
|
76839
76807
|
}
|
|
76840
76808
|
async function logsContent(options2) {
|
|
76841
|
-
const logDir =
|
|
76809
|
+
const logDir = join168(homedir58(), ".claudekit", "logs");
|
|
76842
76810
|
const dateStr = new Date().toISOString().slice(0, 10).replace(/-/g, "");
|
|
76843
|
-
const logPath =
|
|
76811
|
+
const logPath = join168(logDir, `content-${dateStr}.log`);
|
|
76844
76812
|
if (!existsSync84(logPath)) {
|
|
76845
76813
|
logger.info("No content logs found for today.");
|
|
76846
76814
|
return;
|
|
@@ -76872,13 +76840,13 @@ var init_content_subcommands = __esm(() => {
|
|
|
76872
76840
|
init_setup_wizard();
|
|
76873
76841
|
init_state_manager();
|
|
76874
76842
|
init_content_review_commands();
|
|
76875
|
-
LOCK_DIR =
|
|
76843
|
+
LOCK_DIR = join168(homedir58(), ".claudekit", "locks");
|
|
76876
76844
|
});
|
|
76877
76845
|
|
|
76878
76846
|
// src/commands/content/content-command.ts
|
|
76879
76847
|
import { existsSync as existsSync85, mkdirSync as mkdirSync9, unlinkSync as unlinkSync7, writeFileSync as writeFileSync7 } from "node:fs";
|
|
76880
|
-
import { homedir as
|
|
76881
|
-
import { join as
|
|
76848
|
+
import { homedir as homedir59 } from "node:os";
|
|
76849
|
+
import { join as join169 } from "node:path";
|
|
76882
76850
|
async function contentCommand(options2) {
|
|
76883
76851
|
const cwd2 = process.cwd();
|
|
76884
76852
|
const contentLogger = new ContentLogger;
|
|
@@ -76910,7 +76878,7 @@ async function contentCommand(options2) {
|
|
|
76910
76878
|
if (!existsSync85(LOCK_DIR2))
|
|
76911
76879
|
mkdirSync9(LOCK_DIR2, { recursive: true });
|
|
76912
76880
|
writeFileSync7(LOCK_FILE, String(process.pid), "utf-8");
|
|
76913
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
76881
|
+
const dbPath = config.dbPath.replace(/^~/, homedir59());
|
|
76914
76882
|
const db = initDatabase(dbPath);
|
|
76915
76883
|
contentLogger.info(`Database initialised at ${dbPath}`);
|
|
76916
76884
|
const adapters = initializeAdapters(config);
|
|
@@ -77056,8 +77024,8 @@ var init_content_command = __esm(() => {
|
|
|
77056
77024
|
init_publisher();
|
|
77057
77025
|
init_review_manager();
|
|
77058
77026
|
init_state_manager();
|
|
77059
|
-
LOCK_DIR2 =
|
|
77060
|
-
LOCK_FILE =
|
|
77027
|
+
LOCK_DIR2 = join169(homedir59(), ".claudekit", "locks");
|
|
77028
|
+
LOCK_FILE = join169(LOCK_DIR2, "ck-content.lock");
|
|
77061
77029
|
});
|
|
77062
77030
|
|
|
77063
77031
|
// src/commands/content/index.ts
|
|
@@ -85262,12 +85230,13 @@ async function applyBudgetDefaults(settingsPath, projectClaudeDir, requiredFract
|
|
|
85262
85230
|
var ENGINEER_SKILL_COUNT_THRESHOLD = 20;
|
|
85263
85231
|
async function checkSkillBudget(setup, projectDir) {
|
|
85264
85232
|
const projectClaudeDir = resolve31(projectDir, ".claude");
|
|
85265
|
-
const globalClaudeDir = PathResolver.getGlobalKitDir();
|
|
85233
|
+
const globalClaudeDir = resolve31(PathResolver.getGlobalKitDir());
|
|
85234
|
+
const projectScopeAliasesGlobal = projectClaudeDir === globalClaudeDir;
|
|
85266
85235
|
const [projectSkills, globalSkills] = await Promise.all([
|
|
85267
|
-
scanSkills2(join75(projectClaudeDir, "skills")),
|
|
85236
|
+
projectScopeAliasesGlobal ? Promise.resolve([]) : scanSkills2(join75(projectClaudeDir, "skills")),
|
|
85268
85237
|
scanSkills2(join75(globalClaudeDir, "skills"))
|
|
85269
85238
|
]);
|
|
85270
|
-
if (!isEngineerLikeProject(setup, projectSkills))
|
|
85239
|
+
if (!isEngineerLikeProject(setup, [...projectSkills, ...globalSkills]))
|
|
85271
85240
|
return [];
|
|
85272
85241
|
const settingsPath = join75(projectClaudeDir, "settings.json");
|
|
85273
85242
|
const settings = await readProjectSettings(settingsPath);
|
|
@@ -85288,7 +85257,10 @@ function isEngineerLikeProject(setup, projectSkills) {
|
|
|
85288
85257
|
const metadataText = [
|
|
85289
85258
|
setup.project.metadata?.name,
|
|
85290
85259
|
setup.project.metadata?.description,
|
|
85291
|
-
setup.project.metadata?.repository?.url
|
|
85260
|
+
setup.project.metadata?.repository?.url,
|
|
85261
|
+
setup.global.metadata?.name,
|
|
85262
|
+
setup.global.metadata?.description,
|
|
85263
|
+
setup.global.metadata?.repository?.url
|
|
85292
85264
|
].filter(Boolean).join(" ").toLowerCase();
|
|
85293
85265
|
return metadataText.includes("engineer") || projectSkills.length >= ENGINEER_SKILL_COUNT_THRESHOLD;
|
|
85294
85266
|
}
|
|
@@ -85665,7 +85637,7 @@ init_path_resolver();
|
|
|
85665
85637
|
import { existsSync as existsSync54 } from "node:fs";
|
|
85666
85638
|
import { readFile as readFile41 } from "node:fs/promises";
|
|
85667
85639
|
import { homedir as homedir41 } from "node:os";
|
|
85668
|
-
import { dirname as
|
|
85640
|
+
import { dirname as dirname28, join as join79, normalize as normalize6, resolve as resolve32 } from "node:path";
|
|
85669
85641
|
async function checkPathRefsValid(projectDir) {
|
|
85670
85642
|
const globalClaudeMd = join79(PathResolver.getGlobalKitDir(), "CLAUDE.md");
|
|
85671
85643
|
const projectClaudeMd = join79(projectDir, ".claude", "CLAUDE.md");
|
|
@@ -85696,7 +85668,7 @@ async function checkPathRefsValid(projectDir) {
|
|
|
85696
85668
|
autoFixable: false
|
|
85697
85669
|
};
|
|
85698
85670
|
}
|
|
85699
|
-
const baseDir =
|
|
85671
|
+
const baseDir = dirname28(claudeMdPath);
|
|
85700
85672
|
const home6 = homedir41();
|
|
85701
85673
|
const broken = [];
|
|
85702
85674
|
for (const ref of refs) {
|
|
@@ -88719,14 +88691,14 @@ class AutoHealer {
|
|
|
88719
88691
|
import { execSync as execSync4, spawnSync as spawnSync6 } from "node:child_process";
|
|
88720
88692
|
import { readFileSync as readFileSync16, unlinkSync as unlinkSync2, writeFileSync as writeFileSync6 } from "node:fs";
|
|
88721
88693
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
88722
|
-
import { dirname as
|
|
88694
|
+
import { dirname as dirname29, join as join87 } from "node:path";
|
|
88723
88695
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
88724
88696
|
init_environment();
|
|
88725
88697
|
init_logger();
|
|
88726
88698
|
init_dist2();
|
|
88727
88699
|
function getCliVersion4() {
|
|
88728
88700
|
try {
|
|
88729
|
-
const __dirname4 =
|
|
88701
|
+
const __dirname4 = dirname29(fileURLToPath4(import.meta.url));
|
|
88730
88702
|
const pkgPath = join87(__dirname4, "../../../package.json");
|
|
88731
88703
|
const pkg = JSON.parse(readFileSync16(pkgPath, "utf-8"));
|
|
88732
88704
|
return pkg.version || "unknown";
|
|
@@ -89191,7 +89163,7 @@ init_github_client();
|
|
|
89191
89163
|
init_config_version_checker();
|
|
89192
89164
|
|
|
89193
89165
|
// src/domains/sync/sync-engine.ts
|
|
89194
|
-
import { lstat as lstat6, readFile as readFile45, readlink as readlink2, realpath as
|
|
89166
|
+
import { lstat as lstat6, readFile as readFile45, readlink as readlink2, realpath as realpath7, stat as stat14 } from "node:fs/promises";
|
|
89195
89167
|
import { isAbsolute as isAbsolute8, join as join88, normalize as normalize8, relative as relative17 } from "node:path";
|
|
89196
89168
|
|
|
89197
89169
|
// src/services/file-operations/ownership-checker.ts
|
|
@@ -89819,14 +89791,14 @@ class JsonDiff extends Diff {
|
|
|
89819
89791
|
}
|
|
89820
89792
|
castInput(value, options2) {
|
|
89821
89793
|
const { undefinedReplacement, stringifyReplacer = (k2, v2) => typeof v2 === "undefined" ? undefinedReplacement : v2 } = options2;
|
|
89822
|
-
return typeof value === "string" ? value : JSON.stringify(
|
|
89794
|
+
return typeof value === "string" ? value : JSON.stringify(canonicalize2(value, null, null, stringifyReplacer), null, " ");
|
|
89823
89795
|
}
|
|
89824
89796
|
equals(left, right, options2) {
|
|
89825
89797
|
return super.equals(left.replace(/,([\r\n])/g, "$1"), right.replace(/,([\r\n])/g, "$1"), options2);
|
|
89826
89798
|
}
|
|
89827
89799
|
}
|
|
89828
89800
|
var jsonDiff = new JsonDiff;
|
|
89829
|
-
function
|
|
89801
|
+
function canonicalize2(obj, stack, replacementStack, replacer, key) {
|
|
89830
89802
|
stack = stack || [];
|
|
89831
89803
|
replacementStack = replacementStack || [];
|
|
89832
89804
|
if (replacer) {
|
|
@@ -89844,7 +89816,7 @@ function canonicalize(obj, stack, replacementStack, replacer, key) {
|
|
|
89844
89816
|
canonicalizedObj = new Array(obj.length);
|
|
89845
89817
|
replacementStack.push(canonicalizedObj);
|
|
89846
89818
|
for (i = 0;i < obj.length; i += 1) {
|
|
89847
|
-
canonicalizedObj[i] =
|
|
89819
|
+
canonicalizedObj[i] = canonicalize2(obj[i], stack, replacementStack, replacer, String(i));
|
|
89848
89820
|
}
|
|
89849
89821
|
stack.pop();
|
|
89850
89822
|
replacementStack.pop();
|
|
@@ -89867,7 +89839,7 @@ function canonicalize(obj, stack, replacementStack, replacer, key) {
|
|
|
89867
89839
|
sortedKeys.sort();
|
|
89868
89840
|
for (i = 0;i < sortedKeys.length; i += 1) {
|
|
89869
89841
|
key2 = sortedKeys[i];
|
|
89870
|
-
canonicalizedObj[key2] =
|
|
89842
|
+
canonicalizedObj[key2] = canonicalize2(obj[key2], stack, replacementStack, replacer, key2);
|
|
89871
89843
|
}
|
|
89872
89844
|
stack.pop();
|
|
89873
89845
|
replacementStack.pop();
|
|
@@ -90450,8 +90422,8 @@ async function validateSyncPath(basePath, filePath) {
|
|
|
90450
90422
|
}
|
|
90451
90423
|
await validateSymlinkChain(fullPath, basePath);
|
|
90452
90424
|
try {
|
|
90453
|
-
const resolvedBase = await
|
|
90454
|
-
const resolvedFull = await
|
|
90425
|
+
const resolvedBase = await realpath7(basePath);
|
|
90426
|
+
const resolvedFull = await realpath7(fullPath);
|
|
90455
90427
|
const resolvedRel = relative17(resolvedBase, resolvedFull);
|
|
90456
90428
|
if (resolvedRel.startsWith("..") || isAbsolute8(resolvedRel)) {
|
|
90457
90429
|
throw new Error(`Symlink escapes base directory: ${filePath}`);
|
|
@@ -90460,8 +90432,8 @@ async function validateSyncPath(basePath, filePath) {
|
|
|
90460
90432
|
if (error.code === "ENOENT") {
|
|
90461
90433
|
const parentPath = join88(fullPath, "..");
|
|
90462
90434
|
try {
|
|
90463
|
-
const resolvedBase = await
|
|
90464
|
-
const resolvedParent = await
|
|
90435
|
+
const resolvedBase = await realpath7(basePath);
|
|
90436
|
+
const resolvedParent = await realpath7(parentPath);
|
|
90465
90437
|
const resolvedRel = relative17(resolvedBase, resolvedParent);
|
|
90466
90438
|
if (resolvedRel.startsWith("..") || isAbsolute8(resolvedRel)) {
|
|
90467
90439
|
throw new Error(`Parent symlink escapes base directory: ${filePath}`);
|
|
@@ -93294,7 +93266,7 @@ import path9 from "node:path";
|
|
|
93294
93266
|
|
|
93295
93267
|
// node_modules/tar/dist/esm/list.js
|
|
93296
93268
|
import fs10 from "node:fs";
|
|
93297
|
-
import { dirname as
|
|
93269
|
+
import { dirname as dirname32, parse as parse4 } from "path";
|
|
93298
93270
|
|
|
93299
93271
|
// node_modules/tar/dist/esm/options.js
|
|
93300
93272
|
var argmap = new Map([
|
|
@@ -96194,7 +96166,7 @@ var filesFilter = (opt, files) => {
|
|
|
96194
96166
|
if (m2 !== undefined) {
|
|
96195
96167
|
ret = m2;
|
|
96196
96168
|
} else {
|
|
96197
|
-
ret = mapHas(
|
|
96169
|
+
ret = mapHas(dirname32(file), root);
|
|
96198
96170
|
}
|
|
96199
96171
|
}
|
|
96200
96172
|
map.set(file, ret);
|
|
@@ -99937,7 +99909,7 @@ import { join as join120 } from "node:path";
|
|
|
99937
99909
|
|
|
99938
99910
|
// src/domains/installation/deletion-handler.ts
|
|
99939
99911
|
import { existsSync as existsSync62, lstatSync as lstatSync3, readdirSync as readdirSync7, rmSync as rmSync2, rmdirSync, unlinkSync as unlinkSync4 } from "node:fs";
|
|
99940
|
-
import { dirname as
|
|
99912
|
+
import { dirname as dirname34, join as join106, relative as relative20, resolve as resolve38, sep as sep11 } from "node:path";
|
|
99941
99913
|
|
|
99942
99914
|
// src/services/file-operations/manifest/manifest-reader.ts
|
|
99943
99915
|
init_metadata_migration();
|
|
@@ -100163,7 +100135,7 @@ function expandGlobPatterns(patterns, claudeDir3) {
|
|
|
100163
100135
|
var MAX_CLEANUP_ITERATIONS = 50;
|
|
100164
100136
|
function cleanupEmptyDirectories(filePath, claudeDir3) {
|
|
100165
100137
|
const normalizedClaudeDir = resolve38(claudeDir3);
|
|
100166
|
-
let currentDir = resolve38(
|
|
100138
|
+
let currentDir = resolve38(dirname34(filePath));
|
|
100167
100139
|
let iterations = 0;
|
|
100168
100140
|
while (currentDir !== normalizedClaudeDir && currentDir.startsWith(normalizedClaudeDir) && iterations < MAX_CLEANUP_ITERATIONS) {
|
|
100169
100141
|
iterations++;
|
|
@@ -100172,7 +100144,7 @@ function cleanupEmptyDirectories(filePath, claudeDir3) {
|
|
|
100172
100144
|
if (entries.length === 0) {
|
|
100173
100145
|
rmdirSync(currentDir);
|
|
100174
100146
|
logger.debug(`Removed empty directory: ${currentDir}`);
|
|
100175
|
-
currentDir = resolve38(
|
|
100147
|
+
currentDir = resolve38(dirname34(currentDir));
|
|
100176
100148
|
} else {
|
|
100177
100149
|
break;
|
|
100178
100150
|
}
|
|
@@ -100295,7 +100267,7 @@ init_logger();
|
|
|
100295
100267
|
init_types3();
|
|
100296
100268
|
var import_fs_extra15 = __toESM(require_lib(), 1);
|
|
100297
100269
|
var import_ignore3 = __toESM(require_ignore(), 1);
|
|
100298
|
-
import { dirname as
|
|
100270
|
+
import { dirname as dirname37, join as join110, relative as relative22 } from "node:path";
|
|
100299
100271
|
|
|
100300
100272
|
// src/domains/installation/selective-merger.ts
|
|
100301
100273
|
import { stat as stat18 } from "node:fs/promises";
|
|
@@ -101966,13 +101938,13 @@ class FileScanner {
|
|
|
101966
101938
|
// src/domains/installation/merger/settings-processor.ts
|
|
101967
101939
|
import { execSync as execSync5 } from "node:child_process";
|
|
101968
101940
|
import { homedir as homedir45 } from "node:os";
|
|
101969
|
-
import { dirname as
|
|
101941
|
+
import { dirname as dirname36, join as join109 } from "node:path";
|
|
101970
101942
|
|
|
101971
101943
|
// src/domains/config/installed-settings-tracker.ts
|
|
101972
101944
|
init_shared();
|
|
101973
101945
|
import { existsSync as existsSync63 } from "node:fs";
|
|
101974
101946
|
import { mkdir as mkdir31, readFile as readFile49, writeFile as writeFile24 } from "node:fs/promises";
|
|
101975
|
-
import { dirname as
|
|
101947
|
+
import { dirname as dirname35, join as join108 } from "node:path";
|
|
101976
101948
|
var CK_JSON_FILE = ".ck.json";
|
|
101977
101949
|
|
|
101978
101950
|
class InstalledSettingsTracker {
|
|
@@ -102023,7 +101995,7 @@ class InstalledSettingsTracker {
|
|
|
102023
101995
|
data.kits[this.kitName] = {};
|
|
102024
101996
|
}
|
|
102025
101997
|
data.kits[this.kitName].installedSettings = settings;
|
|
102026
|
-
await mkdir31(
|
|
101998
|
+
await mkdir31(dirname35(ckJsonPath), { recursive: true });
|
|
102027
101999
|
await writeFile24(ckJsonPath, JSON.stringify(data, null, 2), "utf-8");
|
|
102028
102000
|
logger.debug(`Saved installed settings to ${ckJsonPath}`);
|
|
102029
102001
|
} catch (error) {
|
|
@@ -102126,7 +102098,7 @@ class SettingsProcessor {
|
|
|
102126
102098
|
} else {
|
|
102127
102099
|
try {
|
|
102128
102100
|
const parsedSettings = JSON.parse(transformedSource);
|
|
102129
|
-
this.fixHookCommandPaths(parsedSettings);
|
|
102101
|
+
this.logHookCommandRepair(this.fixHookCommandPaths(parsedSettings), "fresh install");
|
|
102130
102102
|
await SettingsMerger.writeSettingsFile(destFile, parsedSettings);
|
|
102131
102103
|
try {
|
|
102132
102104
|
if (this.forceOverwriteSettings && destExists) {
|
|
@@ -102204,10 +102176,7 @@ class SettingsProcessor {
|
|
|
102204
102176
|
}
|
|
102205
102177
|
await this.tracker.saveInstalledSettings(installedSettings);
|
|
102206
102178
|
}
|
|
102207
|
-
|
|
102208
|
-
if (pathsFixed) {
|
|
102209
|
-
logger.info("Fixed hook command paths to canonical quoted format");
|
|
102210
|
-
}
|
|
102179
|
+
this.logHookCommandRepair(this.fixHookCommandPaths(mergeResult.merged), "merged settings");
|
|
102211
102180
|
const hooksPruned = this.pruneDeletedHooks(mergeResult.merged);
|
|
102212
102181
|
if (hooksPruned > 0) {
|
|
102213
102182
|
logger.info(`Pruned ${hooksPruned} stale hook(s) referencing deleted files`);
|
|
@@ -102351,7 +102320,7 @@ class SettingsProcessor {
|
|
|
102351
102320
|
if (!content.trim())
|
|
102352
102321
|
return null;
|
|
102353
102322
|
const parsedSettings = JSON.parse(content);
|
|
102354
|
-
this.fixHookCommandPaths(parsedSettings);
|
|
102323
|
+
this.logHookCommandRepair(this.fixHookCommandPaths(parsedSettings), "existing global settings");
|
|
102355
102324
|
return parsedSettings;
|
|
102356
102325
|
} catch {
|
|
102357
102326
|
return null;
|
|
@@ -102374,8 +102343,14 @@ class SettingsProcessor {
|
|
|
102374
102343
|
}
|
|
102375
102344
|
return transformed;
|
|
102376
102345
|
}
|
|
102346
|
+
logHookCommandRepair(count, context) {
|
|
102347
|
+
if (count <= 0)
|
|
102348
|
+
return;
|
|
102349
|
+
const suffix = context ? ` (${context})` : "";
|
|
102350
|
+
logger.info(`Repaired ${count} hook command path(s) to canonical quoted format${suffix} — protects against shells word-splitting on usernames with spaces`);
|
|
102351
|
+
}
|
|
102377
102352
|
fixHookCommandPaths(settings) {
|
|
102378
|
-
let fixed =
|
|
102353
|
+
let fixed = 0;
|
|
102379
102354
|
if (settings.hooks) {
|
|
102380
102355
|
for (const entries of Object.values(settings.hooks)) {
|
|
102381
102356
|
for (const entry of entries) {
|
|
@@ -102383,7 +102358,7 @@ class SettingsProcessor {
|
|
|
102383
102358
|
const result = this.fixSingleCommandPath(entry.command);
|
|
102384
102359
|
if (result !== entry.command) {
|
|
102385
102360
|
entry.command = result;
|
|
102386
|
-
fixed
|
|
102361
|
+
fixed++;
|
|
102387
102362
|
}
|
|
102388
102363
|
}
|
|
102389
102364
|
if ("hooks" in entry && entry.hooks) {
|
|
@@ -102392,7 +102367,7 @@ class SettingsProcessor {
|
|
|
102392
102367
|
const result = this.fixSingleCommandPath(hook.command);
|
|
102393
102368
|
if (result !== hook.command) {
|
|
102394
102369
|
hook.command = result;
|
|
102395
|
-
fixed
|
|
102370
|
+
fixed++;
|
|
102396
102371
|
}
|
|
102397
102372
|
}
|
|
102398
102373
|
}
|
|
@@ -102405,7 +102380,7 @@ class SettingsProcessor {
|
|
|
102405
102380
|
const result = this.fixSingleCommandPath(statusLine.command);
|
|
102406
102381
|
if (result !== statusLine.command) {
|
|
102407
102382
|
statusLine.command = result;
|
|
102408
|
-
fixed
|
|
102383
|
+
fixed++;
|
|
102409
102384
|
}
|
|
102410
102385
|
}
|
|
102411
102386
|
return fixed;
|
|
@@ -102463,20 +102438,19 @@ class SettingsProcessor {
|
|
|
102463
102438
|
return false;
|
|
102464
102439
|
}
|
|
102465
102440
|
const pathsFixed = this.fixHookCommandPaths(settings);
|
|
102466
|
-
if (
|
|
102441
|
+
if (pathsFixed === 0) {
|
|
102467
102442
|
return false;
|
|
102468
102443
|
}
|
|
102444
|
+
this.logHookCommandRepair(pathsFixed, filePath);
|
|
102469
102445
|
await SettingsMerger.writeSettingsFile(filePath, settings);
|
|
102470
102446
|
return true;
|
|
102471
102447
|
}
|
|
102472
102448
|
async repairSiblingSettingsLocal(destFile) {
|
|
102473
|
-
const settingsLocalPath = join109(
|
|
102449
|
+
const settingsLocalPath = join109(dirname36(destFile), "settings.local.json");
|
|
102474
102450
|
if (settingsLocalPath === destFile || !await import_fs_extra14.pathExists(settingsLocalPath)) {
|
|
102475
102451
|
return;
|
|
102476
102452
|
}
|
|
102477
|
-
|
|
102478
|
-
logger.info(`Repaired stale .claude command paths in ${settingsLocalPath}`);
|
|
102479
|
-
}
|
|
102453
|
+
await this.repairSettingsFile(settingsLocalPath);
|
|
102480
102454
|
}
|
|
102481
102455
|
detectClaudeCodeVersion() {
|
|
102482
102456
|
if (this.cachedVersion !== undefined)
|
|
@@ -102732,10 +102706,10 @@ class CopyExecutor {
|
|
|
102732
102706
|
}
|
|
102733
102707
|
trackInstalledFile(relativePath) {
|
|
102734
102708
|
this.installedFiles.add(relativePath);
|
|
102735
|
-
let dir =
|
|
102709
|
+
let dir = dirname37(relativePath);
|
|
102736
102710
|
while (dir && dir !== "." && dir !== "/") {
|
|
102737
102711
|
this.installedDirectories.add(`${dir}/`);
|
|
102738
|
-
dir =
|
|
102712
|
+
dir = dirname37(dir);
|
|
102739
102713
|
}
|
|
102740
102714
|
}
|
|
102741
102715
|
}
|
|
@@ -105714,8 +105688,8 @@ async function handlePostInstall(ctx) {
|
|
|
105714
105688
|
// src/commands/init/phases/selection-handler.ts
|
|
105715
105689
|
init_config_manager();
|
|
105716
105690
|
init_github_client();
|
|
105717
|
-
import { mkdir as
|
|
105718
|
-
import { join as
|
|
105691
|
+
import { mkdir as mkdir36 } from "node:fs/promises";
|
|
105692
|
+
import { join as join134, resolve as resolve43 } from "node:path";
|
|
105719
105693
|
|
|
105720
105694
|
// src/domains/github/kit-access-checker.ts
|
|
105721
105695
|
init_error2();
|
|
@@ -105885,7 +105859,7 @@ async function runPreflightChecks() {
|
|
|
105885
105859
|
// src/domains/installation/fresh-installer.ts
|
|
105886
105860
|
init_metadata_migration();
|
|
105887
105861
|
import { existsSync as existsSync64, readdirSync as readdirSync8, rmSync as rmSync3, rmdirSync as rmdirSync2, unlinkSync as unlinkSync5 } from "node:fs";
|
|
105888
|
-
import { basename as basename25, dirname as
|
|
105862
|
+
import { basename as basename25, dirname as dirname38, join as join132, resolve as resolve40 } from "node:path";
|
|
105889
105863
|
init_logger();
|
|
105890
105864
|
init_safe_spinner();
|
|
105891
105865
|
var import_fs_extra34 = __toESM(require_lib(), 1);
|
|
@@ -105938,14 +105912,14 @@ async function analyzeFreshInstallation(claudeDir3) {
|
|
|
105938
105912
|
}
|
|
105939
105913
|
function cleanupEmptyDirectories2(filePath, claudeDir3) {
|
|
105940
105914
|
const normalizedClaudeDir = resolve40(claudeDir3);
|
|
105941
|
-
let currentDir = resolve40(
|
|
105915
|
+
let currentDir = resolve40(dirname38(filePath));
|
|
105942
105916
|
while (currentDir !== normalizedClaudeDir && currentDir.startsWith(normalizedClaudeDir)) {
|
|
105943
105917
|
try {
|
|
105944
105918
|
const entries = readdirSync8(currentDir);
|
|
105945
105919
|
if (entries.length === 0) {
|
|
105946
105920
|
rmdirSync2(currentDir);
|
|
105947
105921
|
logger.debug(`Removed empty directory: ${currentDir}`);
|
|
105948
|
-
currentDir = resolve40(
|
|
105922
|
+
currentDir = resolve40(dirname38(currentDir));
|
|
105949
105923
|
} else {
|
|
105950
105924
|
break;
|
|
105951
105925
|
}
|
|
@@ -106131,12 +106105,134 @@ async function handleFreshInstallation(claudeDir3, prompts) {
|
|
|
106131
106105
|
}
|
|
106132
106106
|
}
|
|
106133
106107
|
|
|
106108
|
+
// src/domains/installation/global-kit-legacy-repair.ts
|
|
106109
|
+
var import_fs_extra35 = __toESM(require_lib(), 1);
|
|
106110
|
+
import { cp as cp5, mkdir as mkdir35, readdir as readdir41, rename as rename10, rm as rm15, stat as stat22 } from "node:fs/promises";
|
|
106111
|
+
import { homedir as homedir46 } from "node:os";
|
|
106112
|
+
import { dirname as dirname39, join as join133, normalize as normalize11, resolve as resolve41 } from "node:path";
|
|
106113
|
+
var LEGACY_KIT_MARKERS = [
|
|
106114
|
+
"metadata.json",
|
|
106115
|
+
".ck.json",
|
|
106116
|
+
"settings.json",
|
|
106117
|
+
"settings.local.json",
|
|
106118
|
+
"agents",
|
|
106119
|
+
"commands",
|
|
106120
|
+
"rules",
|
|
106121
|
+
"hooks",
|
|
106122
|
+
"skills",
|
|
106123
|
+
"CLAUDE.md"
|
|
106124
|
+
];
|
|
106125
|
+
function safeEnvPath(value) {
|
|
106126
|
+
if (!value || value.trim() === "" || value.includes("..")) {
|
|
106127
|
+
return;
|
|
106128
|
+
}
|
|
106129
|
+
return value;
|
|
106130
|
+
}
|
|
106131
|
+
function withoutTrailingSeparators(path16) {
|
|
106132
|
+
return path16.replace(/[\\/]+$/, "");
|
|
106133
|
+
}
|
|
106134
|
+
function uniqueNormalizedPaths(paths) {
|
|
106135
|
+
const seen = new Set;
|
|
106136
|
+
const result = [];
|
|
106137
|
+
for (const path16 of paths) {
|
|
106138
|
+
const normalized = normalize11(resolve41(path16));
|
|
106139
|
+
if (seen.has(normalized))
|
|
106140
|
+
continue;
|
|
106141
|
+
seen.add(normalized);
|
|
106142
|
+
result.push(path16);
|
|
106143
|
+
}
|
|
106144
|
+
return result;
|
|
106145
|
+
}
|
|
106146
|
+
function getLegacyWindowsGlobalKitDirCandidates(env2 = process.env, homeDir = homedir46()) {
|
|
106147
|
+
const candidates = [];
|
|
106148
|
+
const localAppData = safeEnvPath(env2.LOCALAPPDATA);
|
|
106149
|
+
const appData = safeEnvPath(env2.APPDATA);
|
|
106150
|
+
if (localAppData) {
|
|
106151
|
+
candidates.push(join133(localAppData, ".claude"));
|
|
106152
|
+
}
|
|
106153
|
+
if (appData) {
|
|
106154
|
+
candidates.push(join133(appData, ".claude"));
|
|
106155
|
+
}
|
|
106156
|
+
if (homeDir) {
|
|
106157
|
+
candidates.push(`${withoutTrailingSeparators(homeDir)}.claude`);
|
|
106158
|
+
}
|
|
106159
|
+
return uniqueNormalizedPaths(candidates);
|
|
106160
|
+
}
|
|
106161
|
+
async function isDirectory(path16) {
|
|
106162
|
+
try {
|
|
106163
|
+
return (await stat22(path16)).isDirectory();
|
|
106164
|
+
} catch {
|
|
106165
|
+
return false;
|
|
106166
|
+
}
|
|
106167
|
+
}
|
|
106168
|
+
async function hasKitMarkers(dir) {
|
|
106169
|
+
if (!await isDirectory(dir))
|
|
106170
|
+
return false;
|
|
106171
|
+
for (const marker of LEGACY_KIT_MARKERS) {
|
|
106172
|
+
if (await import_fs_extra35.pathExists(join133(dir, marker))) {
|
|
106173
|
+
return true;
|
|
106174
|
+
}
|
|
106175
|
+
}
|
|
106176
|
+
return false;
|
|
106177
|
+
}
|
|
106178
|
+
async function isEmptyDirectory(dir) {
|
|
106179
|
+
if (!await isDirectory(dir))
|
|
106180
|
+
return false;
|
|
106181
|
+
return (await readdir41(dir)).length === 0;
|
|
106182
|
+
}
|
|
106183
|
+
async function moveDirectory(source, target) {
|
|
106184
|
+
try {
|
|
106185
|
+
await rename10(source, target);
|
|
106186
|
+
} catch (error) {
|
|
106187
|
+
if (error.code !== "EXDEV") {
|
|
106188
|
+
throw error;
|
|
106189
|
+
}
|
|
106190
|
+
await cp5(source, target, { recursive: true, errorOnExist: true, force: false });
|
|
106191
|
+
await rm15(source, { recursive: true, force: true });
|
|
106192
|
+
}
|
|
106193
|
+
}
|
|
106194
|
+
async function repairLegacyWindowsGlobalKitDir(options2) {
|
|
106195
|
+
const env2 = options2.env ?? process.env;
|
|
106196
|
+
const os7 = options2.platform ?? process.platform;
|
|
106197
|
+
if (os7 !== "win32") {
|
|
106198
|
+
return { status: "skipped", reason: "not-windows", candidateDirs: [] };
|
|
106199
|
+
}
|
|
106200
|
+
if (safeEnvPath(env2.CLAUDE_CONFIG_DIR)) {
|
|
106201
|
+
return { status: "skipped", reason: "custom-global-dir", candidateDirs: [] };
|
|
106202
|
+
}
|
|
106203
|
+
const targetDir = normalize11(resolve41(options2.targetDir));
|
|
106204
|
+
const candidateDirs = getLegacyWindowsGlobalKitDirCandidates(env2, options2.homeDir).filter((candidate) => normalize11(resolve41(candidate)) !== targetDir);
|
|
106205
|
+
const legacyDirs = [];
|
|
106206
|
+
for (const candidate of candidateDirs) {
|
|
106207
|
+
if (await hasKitMarkers(candidate)) {
|
|
106208
|
+
legacyDirs.push(candidate);
|
|
106209
|
+
}
|
|
106210
|
+
}
|
|
106211
|
+
if (legacyDirs.length === 0) {
|
|
106212
|
+
return { status: "skipped", reason: "no-legacy-dir", candidateDirs };
|
|
106213
|
+
}
|
|
106214
|
+
if (legacyDirs.length > 1) {
|
|
106215
|
+
return { status: "skipped", reason: "ambiguous-legacy-dirs", candidateDirs };
|
|
106216
|
+
}
|
|
106217
|
+
const [legacyDir] = legacyDirs;
|
|
106218
|
+
const targetExists = await import_fs_extra35.pathExists(targetDir);
|
|
106219
|
+
if (targetExists && !await isEmptyDirectory(targetDir)) {
|
|
106220
|
+
return { status: "skipped", reason: "target-exists", legacyDir, candidateDirs };
|
|
106221
|
+
}
|
|
106222
|
+
if (targetExists) {
|
|
106223
|
+
await rm15(targetDir, { recursive: true, force: true });
|
|
106224
|
+
}
|
|
106225
|
+
await mkdir35(dirname39(targetDir), { recursive: true });
|
|
106226
|
+
await moveDirectory(legacyDir, targetDir);
|
|
106227
|
+
return { status: "repaired", reason: "repaired", legacyDir, candidateDirs };
|
|
106228
|
+
}
|
|
106229
|
+
|
|
106134
106230
|
// src/commands/init/phases/selection-handler.ts
|
|
106135
106231
|
init_version_utils();
|
|
106136
106232
|
init_logger();
|
|
106137
106233
|
init_path_resolver();
|
|
106138
106234
|
init_types3();
|
|
106139
|
-
var
|
|
106235
|
+
var import_fs_extra36 = __toESM(require_lib(), 1);
|
|
106140
106236
|
|
|
106141
106237
|
// src/commands/init/types.ts
|
|
106142
106238
|
function isSyncContext(ctx) {
|
|
@@ -106328,7 +106424,20 @@ async function handleSelection(ctx) {
|
|
|
106328
106424
|
}
|
|
106329
106425
|
}
|
|
106330
106426
|
}
|
|
106331
|
-
const resolvedDir =
|
|
106427
|
+
const resolvedDir = resolve43(targetDir);
|
|
106428
|
+
if (ctx.options.global) {
|
|
106429
|
+
try {
|
|
106430
|
+
const repairResult = await repairLegacyWindowsGlobalKitDir({ targetDir: resolvedDir });
|
|
106431
|
+
if (repairResult.status === "repaired") {
|
|
106432
|
+
logger.success(`Migrated legacy Windows global kit directory from ${repairResult.legacyDir} to ${resolvedDir}`);
|
|
106433
|
+
} else if (repairResult.reason === "target-exists" || repairResult.reason === "ambiguous-legacy-dirs") {
|
|
106434
|
+
logger.warning(`Detected legacy Windows global kit directory but did not auto-migrate it (${repairResult.reason}).`);
|
|
106435
|
+
logger.info(`Using global kit directory: ${resolvedDir}`);
|
|
106436
|
+
}
|
|
106437
|
+
} catch (err) {
|
|
106438
|
+
logger.warning(`Legacy global kit dir repair failed, continuing: ${err instanceof Error ? err.message : String(err)}`);
|
|
106439
|
+
}
|
|
106440
|
+
}
|
|
106332
106441
|
logger.info(`Target directory: ${resolvedDir}`);
|
|
106333
106442
|
if (!ctx.options.global && PathResolver.isLocalSameAsGlobal(resolvedDir)) {
|
|
106334
106443
|
logger.warning("You're at HOME directory. Installing here modifies your GLOBAL ClaudeKit.");
|
|
@@ -106350,9 +106459,9 @@ async function handleSelection(ctx) {
|
|
|
106350
106459
|
return { ...ctx, cancelled: true };
|
|
106351
106460
|
}
|
|
106352
106461
|
}
|
|
106353
|
-
if (!await
|
|
106462
|
+
if (!await import_fs_extra36.pathExists(resolvedDir)) {
|
|
106354
106463
|
if (ctx.options.global) {
|
|
106355
|
-
await
|
|
106464
|
+
await mkdir36(resolvedDir, { recursive: true });
|
|
106356
106465
|
logger.info(`Created global directory: ${resolvedDir}`);
|
|
106357
106466
|
} else {
|
|
106358
106467
|
logger.error(`Directory does not exist: ${resolvedDir}`);
|
|
@@ -106362,7 +106471,7 @@ async function handleSelection(ctx) {
|
|
|
106362
106471
|
}
|
|
106363
106472
|
if (!ctx.options.fresh) {
|
|
106364
106473
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
106365
|
-
const claudeDir3 = prefix ?
|
|
106474
|
+
const claudeDir3 = prefix ? join134(resolvedDir, prefix) : resolvedDir;
|
|
106366
106475
|
try {
|
|
106367
106476
|
const existingMetadata = await readManifest(claudeDir3);
|
|
106368
106477
|
if (existingMetadata?.kits) {
|
|
@@ -106399,7 +106508,7 @@ async function handleSelection(ctx) {
|
|
|
106399
106508
|
}
|
|
106400
106509
|
if (ctx.options.fresh) {
|
|
106401
106510
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
106402
|
-
const claudeDir3 = prefix ?
|
|
106511
|
+
const claudeDir3 = prefix ? join134(resolvedDir, prefix) : resolvedDir;
|
|
106403
106512
|
const canProceed = await handleFreshInstallation(claudeDir3, ctx.prompts);
|
|
106404
106513
|
if (!canProceed) {
|
|
106405
106514
|
return { ...ctx, cancelled: true };
|
|
@@ -106419,7 +106528,7 @@ async function handleSelection(ctx) {
|
|
|
106419
106528
|
let currentVersion = null;
|
|
106420
106529
|
try {
|
|
106421
106530
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
106422
|
-
const claudeDir3 = prefix ?
|
|
106531
|
+
const claudeDir3 = prefix ? join134(resolvedDir, prefix) : resolvedDir;
|
|
106423
106532
|
const existingMetadata = await readManifest(claudeDir3);
|
|
106424
106533
|
currentVersion = existingMetadata?.kits?.[kitType]?.version || null;
|
|
106425
106534
|
if (currentVersion) {
|
|
@@ -106488,7 +106597,7 @@ async function handleSelection(ctx) {
|
|
|
106488
106597
|
if (ctx.options.yes && !ctx.options.fresh && !ctx.options.force && releaseTag && !isOfflineMode && !pendingKits?.length) {
|
|
106489
106598
|
try {
|
|
106490
106599
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
106491
|
-
const claudeDir3 = prefix ?
|
|
106600
|
+
const claudeDir3 = prefix ? join134(resolvedDir, prefix) : resolvedDir;
|
|
106492
106601
|
const existingMetadata = await readManifest(claudeDir3);
|
|
106493
106602
|
const installedKitVersion = existingMetadata?.kits?.[kitType]?.version;
|
|
106494
106603
|
if (installedKitVersion && versionsMatch(installedKitVersion, releaseTag)) {
|
|
@@ -106511,25 +106620,25 @@ async function handleSelection(ctx) {
|
|
|
106511
106620
|
};
|
|
106512
106621
|
}
|
|
106513
106622
|
// src/commands/init/phases/sync-handler.ts
|
|
106514
|
-
import { copyFile as copyFile8, mkdir as
|
|
106515
|
-
import { dirname as
|
|
106623
|
+
import { copyFile as copyFile8, mkdir as mkdir37, open as open5, readFile as readFile58, rename as rename11, stat as stat23, unlink as unlink12, writeFile as writeFile32 } from "node:fs/promises";
|
|
106624
|
+
import { dirname as dirname40, join as join135, resolve as resolve45 } from "node:path";
|
|
106516
106625
|
init_logger();
|
|
106517
106626
|
init_path_resolver();
|
|
106518
|
-
var
|
|
106627
|
+
var import_fs_extra37 = __toESM(require_lib(), 1);
|
|
106519
106628
|
var import_picocolors26 = __toESM(require_picocolors(), 1);
|
|
106520
106629
|
async function handleSync(ctx) {
|
|
106521
106630
|
if (!ctx.options.sync) {
|
|
106522
106631
|
return ctx;
|
|
106523
106632
|
}
|
|
106524
|
-
const resolvedDir = ctx.options.global ? PathResolver.getGlobalKitDir() :
|
|
106525
|
-
const claudeDir3 = ctx.options.global ? resolvedDir :
|
|
106526
|
-
if (!await
|
|
106633
|
+
const resolvedDir = ctx.options.global ? PathResolver.getGlobalKitDir() : resolve45(ctx.options.dir || ".");
|
|
106634
|
+
const claudeDir3 = ctx.options.global ? resolvedDir : join135(resolvedDir, ".claude");
|
|
106635
|
+
if (!await import_fs_extra37.pathExists(claudeDir3)) {
|
|
106527
106636
|
logger.error("Cannot sync: no .claude directory found");
|
|
106528
106637
|
ctx.prompts.note("Run 'ck init' without --sync to install first.", "No Installation Found");
|
|
106529
106638
|
return { ...ctx, cancelled: true };
|
|
106530
106639
|
}
|
|
106531
|
-
const metadataPath =
|
|
106532
|
-
if (!await
|
|
106640
|
+
const metadataPath = join135(claudeDir3, "metadata.json");
|
|
106641
|
+
if (!await import_fs_extra37.pathExists(metadataPath)) {
|
|
106533
106642
|
logger.error("Cannot sync: no metadata.json found");
|
|
106534
106643
|
ctx.prompts.note(`Your installation may be from an older version.
|
|
106535
106644
|
Run 'ck init' to update.`, "Legacy Installation");
|
|
@@ -106628,10 +106737,10 @@ function getLockTimeout() {
|
|
|
106628
106737
|
var STALE_LOCK_THRESHOLD_MS = 5 * 60 * 1000;
|
|
106629
106738
|
async function acquireSyncLock(global3) {
|
|
106630
106739
|
const cacheDir = PathResolver.getCacheDir(global3);
|
|
106631
|
-
const lockPath =
|
|
106740
|
+
const lockPath = join135(cacheDir, ".sync-lock");
|
|
106632
106741
|
const startTime = Date.now();
|
|
106633
106742
|
const lockTimeout = getLockTimeout();
|
|
106634
|
-
await
|
|
106743
|
+
await mkdir37(dirname40(lockPath), { recursive: true });
|
|
106635
106744
|
while (Date.now() - startTime < lockTimeout) {
|
|
106636
106745
|
try {
|
|
106637
106746
|
const handle = await open5(lockPath, "wx");
|
|
@@ -106642,7 +106751,7 @@ async function acquireSyncLock(global3) {
|
|
|
106642
106751
|
} catch (err) {
|
|
106643
106752
|
if (err.code === "EEXIST") {
|
|
106644
106753
|
try {
|
|
106645
|
-
const lockStat = await
|
|
106754
|
+
const lockStat = await stat23(lockPath);
|
|
106646
106755
|
const lockAge = Math.abs(Date.now() - lockStat.mtimeMs);
|
|
106647
106756
|
if (lockAge > STALE_LOCK_THRESHOLD_MS) {
|
|
106648
106757
|
logger.warning(`Removing stale sync lock (age: ${Math.round(lockAge / 1000)}s)`);
|
|
@@ -106674,11 +106783,11 @@ async function executeSyncMerge(ctx) {
|
|
|
106674
106783
|
const releaseLock = await acquireSyncLock(ctx.options.global);
|
|
106675
106784
|
try {
|
|
106676
106785
|
const trackedFiles = ctx.syncTrackedFiles;
|
|
106677
|
-
const upstreamDir = ctx.options.global ?
|
|
106786
|
+
const upstreamDir = ctx.options.global ? join135(ctx.extractDir, ".claude") : ctx.extractDir;
|
|
106678
106787
|
let deletions = [];
|
|
106679
106788
|
try {
|
|
106680
|
-
const sourceMetadataPath =
|
|
106681
|
-
if (await
|
|
106789
|
+
const sourceMetadataPath = join135(upstreamDir, "metadata.json");
|
|
106790
|
+
if (await import_fs_extra37.pathExists(sourceMetadataPath)) {
|
|
106682
106791
|
const content = await readFile58(sourceMetadataPath, "utf-8");
|
|
106683
106792
|
const sourceMetadata = JSON.parse(content);
|
|
106684
106793
|
deletions = sourceMetadata.deletions || [];
|
|
@@ -106709,9 +106818,9 @@ async function executeSyncMerge(ctx) {
|
|
|
106709
106818
|
try {
|
|
106710
106819
|
const sourcePath = await validateSyncPath(upstreamDir, file.path);
|
|
106711
106820
|
const targetPath = await validateSyncPath(ctx.claudeDir, file.path);
|
|
106712
|
-
const targetDir =
|
|
106821
|
+
const targetDir = join135(targetPath, "..");
|
|
106713
106822
|
try {
|
|
106714
|
-
await
|
|
106823
|
+
await mkdir37(targetDir, { recursive: true });
|
|
106715
106824
|
} catch (mkdirError) {
|
|
106716
106825
|
const errCode = mkdirError.code;
|
|
106717
106826
|
if (errCode === "ENOSPC") {
|
|
@@ -106791,7 +106900,7 @@ async function executeSyncMerge(ctx) {
|
|
|
106791
106900
|
const tempPath = `${currentPath}.tmp.${Date.now()}`;
|
|
106792
106901
|
try {
|
|
106793
106902
|
await writeFile32(tempPath, result.result, "utf-8");
|
|
106794
|
-
await
|
|
106903
|
+
await rename11(tempPath, currentPath);
|
|
106795
106904
|
} catch (atomicError) {
|
|
106796
106905
|
await unlink12(tempPath).catch(() => {});
|
|
106797
106906
|
throw atomicError;
|
|
@@ -106874,14 +106983,14 @@ function displaySyncPlan(plan) {
|
|
|
106874
106983
|
console.log(import_picocolors26.default.dim("─".repeat(40)));
|
|
106875
106984
|
}
|
|
106876
106985
|
async function createBackup(claudeDir3, files, backupDir) {
|
|
106877
|
-
await
|
|
106986
|
+
await mkdir37(backupDir, { recursive: true });
|
|
106878
106987
|
for (const file of files) {
|
|
106879
106988
|
try {
|
|
106880
106989
|
const sourcePath = await validateSyncPath(claudeDir3, file.path);
|
|
106881
|
-
if (await
|
|
106990
|
+
if (await import_fs_extra37.pathExists(sourcePath)) {
|
|
106882
106991
|
const targetPath = await validateSyncPath(backupDir, file.path);
|
|
106883
|
-
const targetDir =
|
|
106884
|
-
await
|
|
106992
|
+
const targetDir = join135(targetPath, "..");
|
|
106993
|
+
await mkdir37(targetDir, { recursive: true });
|
|
106885
106994
|
await copyFile8(sourcePath, targetPath);
|
|
106886
106995
|
}
|
|
106887
106996
|
} catch (error) {
|
|
@@ -106895,7 +107004,7 @@ async function createBackup(claudeDir3, files, backupDir) {
|
|
|
106895
107004
|
}
|
|
106896
107005
|
// src/commands/init/phases/transform-handler.ts
|
|
106897
107006
|
init_config_manager();
|
|
106898
|
-
import { join as
|
|
107007
|
+
import { join as join139 } from "node:path";
|
|
106899
107008
|
|
|
106900
107009
|
// src/services/transformers/folder-path-transformer.ts
|
|
106901
107010
|
init_logger();
|
|
@@ -106904,40 +107013,40 @@ init_types3();
|
|
|
106904
107013
|
// src/services/transformers/folder-transform/folder-renamer.ts
|
|
106905
107014
|
init_logger();
|
|
106906
107015
|
init_types3();
|
|
106907
|
-
var
|
|
106908
|
-
import { rename as
|
|
106909
|
-
import { join as
|
|
107016
|
+
var import_fs_extra38 = __toESM(require_lib(), 1);
|
|
107017
|
+
import { rename as rename12, rm as rm16 } from "node:fs/promises";
|
|
107018
|
+
import { join as join136, relative as relative28 } from "node:path";
|
|
106910
107019
|
async function collectDirsToRename(extractDir, folders) {
|
|
106911
107020
|
const dirsToRename = [];
|
|
106912
107021
|
if (folders.docs !== DEFAULT_FOLDERS.docs) {
|
|
106913
|
-
const docsPath =
|
|
106914
|
-
if (await
|
|
107022
|
+
const docsPath = join136(extractDir, DEFAULT_FOLDERS.docs);
|
|
107023
|
+
if (await import_fs_extra38.pathExists(docsPath)) {
|
|
106915
107024
|
dirsToRename.push({
|
|
106916
107025
|
from: docsPath,
|
|
106917
|
-
to:
|
|
107026
|
+
to: join136(extractDir, folders.docs)
|
|
106918
107027
|
});
|
|
106919
107028
|
}
|
|
106920
|
-
const claudeDocsPath =
|
|
106921
|
-
if (await
|
|
107029
|
+
const claudeDocsPath = join136(extractDir, ".claude", DEFAULT_FOLDERS.docs);
|
|
107030
|
+
if (await import_fs_extra38.pathExists(claudeDocsPath)) {
|
|
106922
107031
|
dirsToRename.push({
|
|
106923
107032
|
from: claudeDocsPath,
|
|
106924
|
-
to:
|
|
107033
|
+
to: join136(extractDir, ".claude", folders.docs)
|
|
106925
107034
|
});
|
|
106926
107035
|
}
|
|
106927
107036
|
}
|
|
106928
107037
|
if (folders.plans !== DEFAULT_FOLDERS.plans) {
|
|
106929
|
-
const plansPath =
|
|
106930
|
-
if (await
|
|
107038
|
+
const plansPath = join136(extractDir, DEFAULT_FOLDERS.plans);
|
|
107039
|
+
if (await import_fs_extra38.pathExists(plansPath)) {
|
|
106931
107040
|
dirsToRename.push({
|
|
106932
107041
|
from: plansPath,
|
|
106933
|
-
to:
|
|
107042
|
+
to: join136(extractDir, folders.plans)
|
|
106934
107043
|
});
|
|
106935
107044
|
}
|
|
106936
|
-
const claudePlansPath =
|
|
106937
|
-
if (await
|
|
107045
|
+
const claudePlansPath = join136(extractDir, ".claude", DEFAULT_FOLDERS.plans);
|
|
107046
|
+
if (await import_fs_extra38.pathExists(claudePlansPath)) {
|
|
106938
107047
|
dirsToRename.push({
|
|
106939
107048
|
from: claudePlansPath,
|
|
106940
|
-
to:
|
|
107049
|
+
to: join136(extractDir, ".claude", folders.plans)
|
|
106941
107050
|
});
|
|
106942
107051
|
}
|
|
106943
107052
|
}
|
|
@@ -106945,12 +107054,12 @@ async function collectDirsToRename(extractDir, folders) {
|
|
|
106945
107054
|
}
|
|
106946
107055
|
async function moveAcrossDevices(src, dest) {
|
|
106947
107056
|
try {
|
|
106948
|
-
await
|
|
107057
|
+
await rename12(src, dest);
|
|
106949
107058
|
} catch (e2) {
|
|
106950
107059
|
if (e2.code === "EXDEV") {
|
|
106951
107060
|
logger.debug(`Cross-device move detected, using copy+delete: ${src} -> ${dest}`);
|
|
106952
|
-
await
|
|
106953
|
-
await
|
|
107061
|
+
await import_fs_extra38.copy(src, dest, { overwrite: true });
|
|
107062
|
+
await rm16(src, { recursive: true, force: true });
|
|
106954
107063
|
} else {
|
|
106955
107064
|
throw e2;
|
|
106956
107065
|
}
|
|
@@ -106977,8 +107086,8 @@ async function renameFolders(dirsToRename, extractDir, options2) {
|
|
|
106977
107086
|
// src/services/transformers/folder-transform/path-replacer.ts
|
|
106978
107087
|
init_logger();
|
|
106979
107088
|
init_types3();
|
|
106980
|
-
import { readFile as readFile59, readdir as
|
|
106981
|
-
import { join as
|
|
107089
|
+
import { readFile as readFile59, readdir as readdir42, writeFile as writeFile33 } from "node:fs/promises";
|
|
107090
|
+
import { join as join137, relative as relative29 } from "node:path";
|
|
106982
107091
|
var TRANSFORMABLE_FILE_PATTERNS = [
|
|
106983
107092
|
".md",
|
|
106984
107093
|
".txt",
|
|
@@ -107029,9 +107138,9 @@ function compileReplacements(replacements) {
|
|
|
107029
107138
|
async function transformFileContents(dir, compiledReplacements, options2) {
|
|
107030
107139
|
let filesChanged = 0;
|
|
107031
107140
|
let replacementsCount = 0;
|
|
107032
|
-
const entries = await
|
|
107141
|
+
const entries = await readdir42(dir, { withFileTypes: true });
|
|
107033
107142
|
for (const entry of entries) {
|
|
107034
|
-
const fullPath =
|
|
107143
|
+
const fullPath = join137(dir, entry.name);
|
|
107035
107144
|
if (entry.isDirectory()) {
|
|
107036
107145
|
if (entry.name === "node_modules" || entry.name === ".git") {
|
|
107037
107146
|
continue;
|
|
@@ -107166,9 +107275,9 @@ async function transformFolderPaths(extractDir, folders, options2 = {}) {
|
|
|
107166
107275
|
|
|
107167
107276
|
// src/services/transformers/global-path-transformer.ts
|
|
107168
107277
|
init_logger();
|
|
107169
|
-
import { readFile as readFile60, readdir as
|
|
107170
|
-
import { homedir as
|
|
107171
|
-
import { extname as extname6, join as
|
|
107278
|
+
import { readFile as readFile60, readdir as readdir43, writeFile as writeFile34 } from "node:fs/promises";
|
|
107279
|
+
import { homedir as homedir47, platform as platform15 } from "node:os";
|
|
107280
|
+
import { extname as extname6, join as join138 } from "node:path";
|
|
107172
107281
|
var IS_WINDOWS3 = platform15() === "win32";
|
|
107173
107282
|
var HOME_PREFIX = "$HOME";
|
|
107174
107283
|
function getHomeDirPrefix() {
|
|
@@ -107178,7 +107287,7 @@ function normalizeInstallPath(path16) {
|
|
|
107178
107287
|
return path16.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
107179
107288
|
}
|
|
107180
107289
|
function getDefaultGlobalClaudeDir() {
|
|
107181
|
-
return normalizeInstallPath(
|
|
107290
|
+
return normalizeInstallPath(join138(homedir47(), ".claude"));
|
|
107182
107291
|
}
|
|
107183
107292
|
function getCustomGlobalClaudeDir(targetClaudeDir) {
|
|
107184
107293
|
if (!targetClaudeDir)
|
|
@@ -107307,9 +107416,9 @@ async function transformPathsForGlobalInstall(directory, options2 = {}) {
|
|
|
107307
107416
|
let filesSkipped = 0;
|
|
107308
107417
|
const skippedFiles = [];
|
|
107309
107418
|
async function processDirectory2(dir) {
|
|
107310
|
-
const entries = await
|
|
107419
|
+
const entries = await readdir43(dir, { withFileTypes: true });
|
|
107311
107420
|
for (const entry of entries) {
|
|
107312
|
-
const fullPath =
|
|
107421
|
+
const fullPath = join138(dir, entry.name);
|
|
107313
107422
|
if (entry.isDirectory()) {
|
|
107314
107423
|
if (entry.name === "node_modules" || entry.name.startsWith(".") && entry.name !== ".claude") {
|
|
107315
107424
|
continue;
|
|
@@ -107388,7 +107497,7 @@ async function handleTransforms(ctx) {
|
|
|
107388
107497
|
logger.debug(ctx.options.global ? "Saved folder configuration to ~/.claude/.ck.json" : "Saved folder configuration to .claude/.ck.json");
|
|
107389
107498
|
}
|
|
107390
107499
|
}
|
|
107391
|
-
const claudeDir3 = ctx.options.global ? ctx.resolvedDir :
|
|
107500
|
+
const claudeDir3 = ctx.options.global ? ctx.resolvedDir : join139(ctx.resolvedDir, ".claude");
|
|
107392
107501
|
return {
|
|
107393
107502
|
...ctx,
|
|
107394
107503
|
foldersConfig,
|
|
@@ -107578,15 +107687,15 @@ async function initCommand(options2) {
|
|
|
107578
107687
|
init_dist2();
|
|
107579
107688
|
var import_picocolors30 = __toESM(require_picocolors(), 1);
|
|
107580
107689
|
import { existsSync as existsSync65 } from "node:fs";
|
|
107581
|
-
import { readFile as readFile64, rm as
|
|
107582
|
-
import { homedir as
|
|
107583
|
-
import { basename as basename27, join as
|
|
107690
|
+
import { readFile as readFile64, rm as rm17, unlink as unlink13 } from "node:fs/promises";
|
|
107691
|
+
import { homedir as homedir52 } from "node:os";
|
|
107692
|
+
import { basename as basename27, join as join143, resolve as resolve47 } from "node:path";
|
|
107584
107693
|
init_logger();
|
|
107585
107694
|
|
|
107586
107695
|
// src/ui/ck-cli-design/tokens.ts
|
|
107587
|
-
var import_picocolors27 = __toESM(
|
|
107588
|
-
import { homedir as
|
|
107589
|
-
import { resolve as
|
|
107696
|
+
var import_picocolors27 = __toESM(require_picocolors(), 1);
|
|
107697
|
+
import { homedir as homedir48, platform as platform16 } from "node:os";
|
|
107698
|
+
import { resolve as resolve46, win32 as win322 } from "node:path";
|
|
107590
107699
|
var PANEL_MIN_WIDTH = 60;
|
|
107591
107700
|
var PANEL_MAX_WIDTH = 72;
|
|
107592
107701
|
var DEFAULT_WIDTH = PANEL_MAX_WIDTH;
|
|
@@ -107743,7 +107852,7 @@ function wrapText(value, width) {
|
|
|
107743
107852
|
}
|
|
107744
107853
|
function formatDisplayPath(value) {
|
|
107745
107854
|
const normalized = value.replace(/\\/g, "/");
|
|
107746
|
-
const home6 =
|
|
107855
|
+
const home6 = homedir48().replace(/\\/g, "/");
|
|
107747
107856
|
if (normalized === home6)
|
|
107748
107857
|
return "~";
|
|
107749
107858
|
if (normalized.startsWith(`${home6}/`)) {
|
|
@@ -107756,7 +107865,7 @@ function formatCdHint(value, currentPlatform = platform16()) {
|
|
|
107756
107865
|
const absolutePath2 = win322.resolve(value);
|
|
107757
107866
|
return `cd /d "${absolutePath2}"`;
|
|
107758
107867
|
}
|
|
107759
|
-
const absolutePath =
|
|
107868
|
+
const absolutePath = resolve46(value);
|
|
107760
107869
|
const displayPath = formatDisplayPath(absolutePath);
|
|
107761
107870
|
if (displayPath.includes(" ")) {
|
|
107762
107871
|
return `cd "${displayPath}"`;
|
|
@@ -108055,15 +108164,15 @@ init_model_taxonomy();
|
|
|
108055
108164
|
init_logger();
|
|
108056
108165
|
init_dist2();
|
|
108057
108166
|
init_model_taxonomy();
|
|
108058
|
-
import { mkdir as
|
|
108059
|
-
import { homedir as
|
|
108060
|
-
import { dirname as
|
|
108167
|
+
import { mkdir as mkdir39, readFile as readFile63, writeFile as writeFile36 } from "node:fs/promises";
|
|
108168
|
+
import { homedir as homedir51 } from "node:os";
|
|
108169
|
+
import { dirname as dirname41, join as join142 } from "node:path";
|
|
108061
108170
|
|
|
108062
108171
|
// src/commands/portable/models-dev-cache.ts
|
|
108063
108172
|
init_logger();
|
|
108064
|
-
import { mkdir as
|
|
108065
|
-
import { homedir as
|
|
108066
|
-
import { join as
|
|
108173
|
+
import { mkdir as mkdir38, readFile as readFile61, rename as rename13, writeFile as writeFile35 } from "node:fs/promises";
|
|
108174
|
+
import { homedir as homedir49 } from "node:os";
|
|
108175
|
+
import { join as join140 } from "node:path";
|
|
108067
108176
|
|
|
108068
108177
|
class ModelsDevUnavailableError extends Error {
|
|
108069
108178
|
constructor(message, cause) {
|
|
@@ -108075,13 +108184,13 @@ var MODELS_DEV_URL = "https://models.dev/api.json";
|
|
|
108075
108184
|
var CACHE_TTL_MS3 = 24 * 60 * 60 * 1000;
|
|
108076
108185
|
var FETCH_TIMEOUT_MS = 1e4;
|
|
108077
108186
|
function defaultCacheDir() {
|
|
108078
|
-
return
|
|
108187
|
+
return join140(homedir49(), ".config", "claudekit", "cache");
|
|
108079
108188
|
}
|
|
108080
108189
|
function cacheFilePath(cacheDir) {
|
|
108081
|
-
return
|
|
108190
|
+
return join140(cacheDir, "models-dev.json");
|
|
108082
108191
|
}
|
|
108083
108192
|
function tmpFilePath(cacheDir) {
|
|
108084
|
-
return
|
|
108193
|
+
return join140(cacheDir, "models-dev.json.tmp");
|
|
108085
108194
|
}
|
|
108086
108195
|
async function readCacheEntry(cacheDir) {
|
|
108087
108196
|
const filePath = cacheFilePath(cacheDir);
|
|
@@ -108101,11 +108210,11 @@ function isCacheFresh(entry) {
|
|
|
108101
108210
|
return Date.now() - fetchedAt < CACHE_TTL_MS3;
|
|
108102
108211
|
}
|
|
108103
108212
|
async function writeCacheEntry(cacheDir, entry) {
|
|
108104
|
-
await
|
|
108213
|
+
await mkdir38(cacheDir, { recursive: true });
|
|
108105
108214
|
const tmp = tmpFilePath(cacheDir);
|
|
108106
108215
|
const dest = cacheFilePath(cacheDir);
|
|
108107
108216
|
await writeFile35(tmp, JSON.stringify(entry), "utf-8");
|
|
108108
|
-
await
|
|
108217
|
+
await rename13(tmp, dest);
|
|
108109
108218
|
}
|
|
108110
108219
|
async function fetchCatalog(fetcher) {
|
|
108111
108220
|
const controller = new AbortController;
|
|
@@ -108155,15 +108264,15 @@ async function getModelsDevCatalog(opts = {}) {
|
|
|
108155
108264
|
// src/commands/portable/opencode-model-discovery.ts
|
|
108156
108265
|
init_logger();
|
|
108157
108266
|
import { readFile as readFile62 } from "node:fs/promises";
|
|
108158
|
-
import { homedir as
|
|
108159
|
-
import { join as
|
|
108267
|
+
import { homedir as homedir50, platform as platform17 } from "node:os";
|
|
108268
|
+
import { join as join141 } from "node:path";
|
|
108160
108269
|
function resolveOpenCodeAuthPath(homeDir) {
|
|
108161
108270
|
if (platform17() === "win32") {
|
|
108162
|
-
const dataRoot2 = process.env.LOCALAPPDATA ??
|
|
108163
|
-
return
|
|
108271
|
+
const dataRoot2 = process.env.LOCALAPPDATA ?? join141(homeDir, "AppData", "Local");
|
|
108272
|
+
return join141(dataRoot2, "opencode", "auth.json");
|
|
108164
108273
|
}
|
|
108165
|
-
const dataRoot = process.env.XDG_DATA_HOME ??
|
|
108166
|
-
return
|
|
108274
|
+
const dataRoot = process.env.XDG_DATA_HOME ?? join141(homeDir, ".local", "share");
|
|
108275
|
+
return join141(dataRoot, "opencode", "auth.json");
|
|
108167
108276
|
}
|
|
108168
108277
|
async function readAuthedProviders(homeDir) {
|
|
108169
108278
|
const authPath = resolveOpenCodeAuthPath(homeDir);
|
|
@@ -108201,7 +108310,7 @@ function pickGenericModel(models) {
|
|
|
108201
108310
|
return sorted[0] ?? null;
|
|
108202
108311
|
}
|
|
108203
108312
|
async function resolveOpenCodeDefaultModel(opts = {}) {
|
|
108204
|
-
const home6 = opts.homeDir ??
|
|
108313
|
+
const home6 = opts.homeDir ?? homedir50();
|
|
108205
108314
|
const authedProviders = await readAuthedProviders(home6);
|
|
108206
108315
|
if (authedProviders.length === 0) {
|
|
108207
108316
|
return { ok: false, reason: "no-auth", authedProviders: [] };
|
|
@@ -108265,9 +108374,9 @@ function messageForReason(reason) {
|
|
|
108265
108374
|
}
|
|
108266
108375
|
function getOpenCodeConfigPath(options2) {
|
|
108267
108376
|
if (options2.global) {
|
|
108268
|
-
return
|
|
108377
|
+
return join142(options2.homeDir ?? homedir51(), ".config", "opencode", "opencode.json");
|
|
108269
108378
|
}
|
|
108270
|
-
return
|
|
108379
|
+
return join142(options2.cwd ?? process.cwd(), "opencode.json");
|
|
108271
108380
|
}
|
|
108272
108381
|
function makeCatalogOpts(options2) {
|
|
108273
108382
|
return {
|
|
@@ -108410,7 +108519,7 @@ async function ensureOpenCodeModel(options2) {
|
|
|
108410
108519
|
}
|
|
108411
108520
|
const chosenModel2 = response2.action === "custom" ? response2.value : suggestion2.model;
|
|
108412
108521
|
const next2 = { ...existing, model: chosenModel2 };
|
|
108413
|
-
await
|
|
108522
|
+
await mkdir39(dirname41(configPath), { recursive: true });
|
|
108414
108523
|
await writeFile36(configPath, `${JSON.stringify(next2, null, 2)}
|
|
108415
108524
|
`, "utf-8");
|
|
108416
108525
|
return { path: configPath, action: "added", model: chosenModel2, reason: suggestion2.reason };
|
|
@@ -108421,7 +108530,7 @@ async function ensureOpenCodeModel(options2) {
|
|
|
108421
108530
|
throw new OpenCodeAuthRequiredError(suggestion.failure);
|
|
108422
108531
|
}
|
|
108423
108532
|
const next2 = { ...existing ?? {}, model: suggestion.model };
|
|
108424
|
-
await
|
|
108533
|
+
await mkdir39(dirname41(configPath), { recursive: true });
|
|
108425
108534
|
await writeFile36(configPath, `${JSON.stringify(next2, null, 2)}
|
|
108426
108535
|
`, "utf-8");
|
|
108427
108536
|
return {
|
|
@@ -108443,7 +108552,7 @@ async function ensureOpenCodeModel(options2) {
|
|
|
108443
108552
|
}
|
|
108444
108553
|
const chosenModel = response.action === "custom" ? response.value : suggestion.ok ? suggestion.model : "";
|
|
108445
108554
|
const next = { ...existing ?? {}, model: chosenModel };
|
|
108446
|
-
await
|
|
108555
|
+
await mkdir39(dirname41(configPath), { recursive: true });
|
|
108447
108556
|
await writeFile36(configPath, `${JSON.stringify(next, null, 2)}
|
|
108448
108557
|
`, "utf-8");
|
|
108449
108558
|
return {
|
|
@@ -108456,7 +108565,7 @@ async function ensureOpenCodeModel(options2) {
|
|
|
108456
108565
|
|
|
108457
108566
|
// src/commands/portable/plan-display.ts
|
|
108458
108567
|
var import_picocolors28 = __toESM(require_picocolors(), 1);
|
|
108459
|
-
import { basename as basename26, dirname as
|
|
108568
|
+
import { basename as basename26, dirname as dirname42, extname as extname7 } from "node:path";
|
|
108460
108569
|
var DEFAULT_MAX_PLAN_GROUP_ITEMS = 20;
|
|
108461
108570
|
var TYPE_ORDER = [
|
|
108462
108571
|
"agent",
|
|
@@ -108682,21 +108791,21 @@ function collectPlannedWhereLines(plan) {
|
|
|
108682
108791
|
return destinations.map((destination) => `${formatDisplayPath(destination)} -> ${formatCdHint(resolveCdTarget(destination))}`);
|
|
108683
108792
|
}
|
|
108684
108793
|
function resolveCdTarget(destination) {
|
|
108685
|
-
return extname7(destination).length > 0 ?
|
|
108794
|
+
return extname7(destination).length > 0 ? dirname42(destination) : destination;
|
|
108686
108795
|
}
|
|
108687
108796
|
function normalizeWhereDestination(path16, portableType) {
|
|
108688
108797
|
if (portableType === "agent" || portableType === "command" || portableType === "skill") {
|
|
108689
|
-
return
|
|
108798
|
+
return dirname42(path16);
|
|
108690
108799
|
}
|
|
108691
108800
|
if (portableType === "hooks") {
|
|
108692
|
-
return
|
|
108801
|
+
return dirname42(path16);
|
|
108693
108802
|
}
|
|
108694
108803
|
if (portableType === "rules") {
|
|
108695
108804
|
const fileName = basename26(path16).toLowerCase();
|
|
108696
108805
|
if (fileName === "agents.md" || fileName === "gemini.md" || fileName === ".goosehints" || fileName === "custom_modes.yaml" || fileName === "custom_modes.yml") {
|
|
108697
108806
|
return path16;
|
|
108698
108807
|
}
|
|
108699
|
-
return
|
|
108808
|
+
return dirname42(path16);
|
|
108700
108809
|
}
|
|
108701
108810
|
return path16;
|
|
108702
108811
|
}
|
|
@@ -109205,10 +109314,10 @@ function shouldExecuteAction2(action) {
|
|
|
109205
109314
|
}
|
|
109206
109315
|
async function executeDeleteAction(action, options2) {
|
|
109207
109316
|
const preservePaths = options2?.preservePaths ?? new Set;
|
|
109208
|
-
const shouldPreserveTarget = action.targetPath.length > 0 && preservePaths.has(
|
|
109317
|
+
const shouldPreserveTarget = action.targetPath.length > 0 && preservePaths.has(resolve47(action.targetPath));
|
|
109209
109318
|
try {
|
|
109210
109319
|
if (!shouldPreserveTarget && action.targetPath && existsSync65(action.targetPath)) {
|
|
109211
|
-
await
|
|
109320
|
+
await rm17(action.targetPath, { recursive: true, force: true });
|
|
109212
109321
|
}
|
|
109213
109322
|
await removePortableInstallation(action.item, action.type, action.provider, action.global, action.targetPath ? { path: action.targetPath } : undefined);
|
|
109214
109323
|
return {
|
|
@@ -109238,7 +109347,7 @@ async function executeDeleteAction(action, options2) {
|
|
|
109238
109347
|
async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
109239
109348
|
if (!skillSourcePath)
|
|
109240
109349
|
return;
|
|
109241
|
-
const sourceMetadataPath =
|
|
109350
|
+
const sourceMetadataPath = join143(resolve47(skillSourcePath, ".."), "metadata.json");
|
|
109242
109351
|
if (!existsSync65(sourceMetadataPath))
|
|
109243
109352
|
return;
|
|
109244
109353
|
let sourceMetadata;
|
|
@@ -109251,7 +109360,7 @@ async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
|
109251
109360
|
}
|
|
109252
109361
|
if (!sourceMetadata.deletions || sourceMetadata.deletions.length === 0)
|
|
109253
109362
|
return;
|
|
109254
|
-
const claudeDir3 = installGlobally ?
|
|
109363
|
+
const claudeDir3 = installGlobally ? join143(homedir52(), ".claude") : join143(process.cwd(), ".claude");
|
|
109255
109364
|
if (!existsSync65(claudeDir3))
|
|
109256
109365
|
return;
|
|
109257
109366
|
try {
|
|
@@ -109374,8 +109483,8 @@ async function migrateCommand(options2) {
|
|
|
109374
109483
|
let requestedGlobal = options2.global ?? false;
|
|
109375
109484
|
let installGlobally = requestedGlobal;
|
|
109376
109485
|
if (options2.global === undefined && !options2.yes) {
|
|
109377
|
-
const projectTarget =
|
|
109378
|
-
const globalTarget =
|
|
109486
|
+
const projectTarget = join143(process.cwd(), ".claude");
|
|
109487
|
+
const globalTarget = join143(homedir52(), ".claude");
|
|
109379
109488
|
const scopeChoice = await ie({
|
|
109380
109489
|
message: "Installation scope",
|
|
109381
109490
|
options: [
|
|
@@ -109439,7 +109548,7 @@ async function migrateCommand(options2) {
|
|
|
109439
109548
|
}).join(`
|
|
109440
109549
|
`));
|
|
109441
109550
|
if (sourceGlobalOnly) {
|
|
109442
|
-
f2.info(import_picocolors30.default.dim(` Scope: global (--global / -g) - reading from ${formatDisplayPath(
|
|
109551
|
+
f2.info(import_picocolors30.default.dim(` Scope: global (--global / -g) - reading from ${formatDisplayPath(join143(homedir52(), ".claude"))}`));
|
|
109443
109552
|
} else {
|
|
109444
109553
|
f2.info(import_picocolors30.default.dim(` CWD: ${process.cwd()}`));
|
|
109445
109554
|
}
|
|
@@ -109645,7 +109754,7 @@ async function migrateCommand(options2) {
|
|
|
109645
109754
|
const recordSuccessfulWrites = (task, taskResults) => {
|
|
109646
109755
|
for (const result of taskResults.filter((entry) => entry.success && !entry.skipped)) {
|
|
109647
109756
|
if (result.path.length > 0) {
|
|
109648
|
-
writtenPaths.add(
|
|
109757
|
+
writtenPaths.add(resolve47(result.path));
|
|
109649
109758
|
}
|
|
109650
109759
|
if (task.type === "hooks") {
|
|
109651
109760
|
const existing = successfulHookFiles.get(task.provider) ?? {
|
|
@@ -109656,7 +109765,7 @@ async function migrateCommand(options2) {
|
|
|
109656
109765
|
successfulHookFiles.set(task.provider, existing);
|
|
109657
109766
|
if (result.path.length > 0) {
|
|
109658
109767
|
const absExisting = successfulHookAbsPaths.get(task.provider) ?? [];
|
|
109659
|
-
absExisting.push(
|
|
109768
|
+
absExisting.push(resolve47(result.path));
|
|
109660
109769
|
successfulHookAbsPaths.set(task.provider, absExisting);
|
|
109661
109770
|
}
|
|
109662
109771
|
}
|
|
@@ -109798,7 +109907,7 @@ async function migrateCommand(options2) {
|
|
|
109798
109907
|
}
|
|
109799
109908
|
}
|
|
109800
109909
|
try {
|
|
109801
|
-
const kitRoot = (agentSource ?
|
|
109910
|
+
const kitRoot = (agentSource ? resolve47(agentSource, "..") : null) ?? (commandSource ? resolve47(commandSource, "..") : null) ?? (skillSource ? resolve47(skillSource, "..") : null) ?? null;
|
|
109802
109911
|
const manifest = kitRoot ? await loadPortableManifest(kitRoot) : null;
|
|
109803
109912
|
if (manifest?.cliVersion) {
|
|
109804
109913
|
await updateAppliedManifestVersion(manifest.cliVersion);
|
|
@@ -109851,9 +109960,9 @@ async function rollbackResults(results) {
|
|
|
109851
109960
|
try {
|
|
109852
109961
|
if (result.overwritten)
|
|
109853
109962
|
continue;
|
|
109854
|
-
const
|
|
109855
|
-
if (
|
|
109856
|
-
await
|
|
109963
|
+
const stat24 = await import("node:fs/promises").then((fs20) => fs20.stat(result.path));
|
|
109964
|
+
if (stat24.isDirectory()) {
|
|
109965
|
+
await rm17(result.path, { recursive: true, force: true });
|
|
109857
109966
|
} else {
|
|
109858
109967
|
await unlink13(result.path);
|
|
109859
109968
|
}
|
|
@@ -109977,7 +110086,7 @@ function buildDryRunFallbackResults(skills, selectedProviders, installGlobally,
|
|
|
109977
110086
|
results.push({
|
|
109978
110087
|
itemName: skill.name,
|
|
109979
110088
|
operation: "apply",
|
|
109980
|
-
path:
|
|
110089
|
+
path: join143(basePath, skill.name),
|
|
109981
110090
|
portableType: "skill",
|
|
109982
110091
|
provider,
|
|
109983
110092
|
providerDisplayName: providers[provider].displayName,
|
|
@@ -109995,11 +110104,11 @@ var import_picocolors31 = __toESM(require_picocolors(), 1);
|
|
|
109995
110104
|
|
|
109996
110105
|
// src/commands/new/phases/directory-setup.ts
|
|
109997
110106
|
init_config_manager();
|
|
109998
|
-
import { resolve as
|
|
110107
|
+
import { resolve as resolve48 } from "node:path";
|
|
109999
110108
|
init_logger();
|
|
110000
110109
|
init_path_resolver();
|
|
110001
110110
|
init_types3();
|
|
110002
|
-
var
|
|
110111
|
+
var import_fs_extra39 = __toESM(require_lib(), 1);
|
|
110003
110112
|
async function directorySetup(validOptions, prompts) {
|
|
110004
110113
|
const isNonInteractive2 = !process.stdin.isTTY || process.env.CI === "true" || process.env.NON_INTERACTIVE === "true";
|
|
110005
110114
|
const config = await ConfigManager.get();
|
|
@@ -110080,7 +110189,7 @@ async function directorySetup(validOptions, prompts) {
|
|
|
110080
110189
|
targetDir = await prompts.getDirectory(targetDir);
|
|
110081
110190
|
}
|
|
110082
110191
|
}
|
|
110083
|
-
const resolvedDir =
|
|
110192
|
+
const resolvedDir = resolve48(targetDir);
|
|
110084
110193
|
logger.info(`Target directory: ${resolvedDir}`);
|
|
110085
110194
|
if (PathResolver.isLocalSameAsGlobal(resolvedDir)) {
|
|
110086
110195
|
logger.warning("You're creating a project at HOME directory.");
|
|
@@ -110098,8 +110207,8 @@ async function directorySetup(validOptions, prompts) {
|
|
|
110098
110207
|
return null;
|
|
110099
110208
|
}
|
|
110100
110209
|
}
|
|
110101
|
-
if (await
|
|
110102
|
-
const files = await
|
|
110210
|
+
if (await import_fs_extra39.pathExists(resolvedDir)) {
|
|
110211
|
+
const files = await import_fs_extra39.readdir(resolvedDir);
|
|
110103
110212
|
const isEmpty = files.length === 0;
|
|
110104
110213
|
if (!isEmpty) {
|
|
110105
110214
|
if (isNonInteractive2) {
|
|
@@ -110137,7 +110246,7 @@ async function handleDirectorySetup(ctx) {
|
|
|
110137
110246
|
// src/commands/new/phases/project-creation.ts
|
|
110138
110247
|
init_config_manager();
|
|
110139
110248
|
init_github_client();
|
|
110140
|
-
import { join as
|
|
110249
|
+
import { join as join144 } from "node:path";
|
|
110141
110250
|
init_logger();
|
|
110142
110251
|
init_output_manager();
|
|
110143
110252
|
init_types3();
|
|
@@ -110263,7 +110372,7 @@ async function projectCreation(kit, resolvedDir, validOptions, isNonInteractive2
|
|
|
110263
110372
|
output.section("Installing");
|
|
110264
110373
|
logger.verbose("Installation target", { directory: resolvedDir });
|
|
110265
110374
|
const merger = new FileMerger;
|
|
110266
|
-
const claudeDir3 =
|
|
110375
|
+
const claudeDir3 = join144(resolvedDir, ".claude");
|
|
110267
110376
|
merger.setMultiKitContext(claudeDir3, kit);
|
|
110268
110377
|
if (validOptions.exclude && validOptions.exclude.length > 0) {
|
|
110269
110378
|
merger.addIgnorePatterns(validOptions.exclude);
|
|
@@ -110310,7 +110419,7 @@ async function handleProjectCreation(ctx) {
|
|
|
110310
110419
|
}
|
|
110311
110420
|
// src/commands/new/phases/post-setup.ts
|
|
110312
110421
|
init_projects_registry();
|
|
110313
|
-
import { join as
|
|
110422
|
+
import { join as join145 } from "node:path";
|
|
110314
110423
|
init_package_installer();
|
|
110315
110424
|
init_logger();
|
|
110316
110425
|
init_path_resolver();
|
|
@@ -110342,9 +110451,9 @@ async function postSetup(resolvedDir, validOptions, isNonInteractive2, prompts)
|
|
|
110342
110451
|
withSudo: validOptions.withSudo
|
|
110343
110452
|
});
|
|
110344
110453
|
}
|
|
110345
|
-
const claudeDir3 =
|
|
110454
|
+
const claudeDir3 = join145(resolvedDir, ".claude");
|
|
110346
110455
|
await promptSetupWizardIfNeeded({
|
|
110347
|
-
envPath:
|
|
110456
|
+
envPath: join145(claudeDir3, ".env"),
|
|
110348
110457
|
claudeDir: claudeDir3,
|
|
110349
110458
|
isGlobal: false,
|
|
110350
110459
|
isNonInteractive: isNonInteractive2,
|
|
@@ -110414,7 +110523,7 @@ Please use only one download method.`);
|
|
|
110414
110523
|
// src/commands/plan/plan-command.ts
|
|
110415
110524
|
init_output_manager();
|
|
110416
110525
|
import { existsSync as existsSync68, statSync as statSync12 } from "node:fs";
|
|
110417
|
-
import { dirname as
|
|
110526
|
+
import { dirname as dirname46, isAbsolute as isAbsolute11, join as join148, parse as parse7, resolve as resolve52 } from "node:path";
|
|
110418
110527
|
|
|
110419
110528
|
// src/commands/plan/plan-read-handlers.ts
|
|
110420
110529
|
init_config();
|
|
@@ -110424,18 +110533,18 @@ init_logger();
|
|
|
110424
110533
|
init_output_manager();
|
|
110425
110534
|
var import_picocolors32 = __toESM(require_picocolors(), 1);
|
|
110426
110535
|
import { existsSync as existsSync67, statSync as statSync11 } from "node:fs";
|
|
110427
|
-
import { basename as basename28, dirname as
|
|
110536
|
+
import { basename as basename28, dirname as dirname44, join as join147, relative as relative30, resolve as resolve50 } from "node:path";
|
|
110428
110537
|
|
|
110429
110538
|
// src/commands/plan/plan-dependencies.ts
|
|
110430
110539
|
init_config();
|
|
110431
110540
|
init_plan_parser();
|
|
110432
110541
|
init_plans_registry();
|
|
110433
110542
|
import { existsSync as existsSync66 } from "node:fs";
|
|
110434
|
-
import { dirname as
|
|
110543
|
+
import { dirname as dirname43, join as join146 } from "node:path";
|
|
110435
110544
|
async function resolvePlanDependencies(references, currentPlanFile, options2 = {}) {
|
|
110436
110545
|
if (references.length === 0)
|
|
110437
110546
|
return [];
|
|
110438
|
-
const currentPlanDir =
|
|
110547
|
+
const currentPlanDir = dirname43(currentPlanFile);
|
|
110439
110548
|
const projectRoot = findProjectRoot(currentPlanDir);
|
|
110440
110549
|
const config = options2.preloadedConfig ?? (await CkConfigManager.loadFull(projectRoot)).config;
|
|
110441
110550
|
const defaultScope = inferPlanScopeForDir(currentPlanDir, config);
|
|
@@ -110451,7 +110560,7 @@ async function resolvePlanDependencies(references, currentPlanFile, options2 = {
|
|
|
110451
110560
|
};
|
|
110452
110561
|
}
|
|
110453
110562
|
const scopeRoot = resolvePlanDirForScope(scope, projectRoot, config);
|
|
110454
|
-
const planFile =
|
|
110563
|
+
const planFile = join146(scopeRoot, planId, "plan.md");
|
|
110455
110564
|
const isSelfReference = planFile === currentPlanFile;
|
|
110456
110565
|
if (!existsSync66(planFile)) {
|
|
110457
110566
|
return {
|
|
@@ -110482,14 +110591,14 @@ init_config();
|
|
|
110482
110591
|
init_plan_parser();
|
|
110483
110592
|
init_plan_scope();
|
|
110484
110593
|
init_plans_registry();
|
|
110485
|
-
import { isAbsolute as isAbsolute10, resolve as
|
|
110594
|
+
import { isAbsolute as isAbsolute10, resolve as resolve49 } from "node:path";
|
|
110486
110595
|
async function getGlobalPlansDirFromCwd() {
|
|
110487
110596
|
const projectRoot = findProjectRoot(process.cwd());
|
|
110488
110597
|
const { config } = await CkConfigManager.loadFull(projectRoot);
|
|
110489
110598
|
return resolveGlobalPlansDir(config);
|
|
110490
110599
|
}
|
|
110491
110600
|
function resolveTargetFromBase(target, baseDir) {
|
|
110492
|
-
const resolvedTarget = isAbsolute10(target) ?
|
|
110601
|
+
const resolvedTarget = isAbsolute10(target) ? resolve49(target) : resolve49(baseDir, target);
|
|
110493
110602
|
return isWithinDir(resolvedTarget, baseDir) ? resolvedTarget : null;
|
|
110494
110603
|
}
|
|
110495
110604
|
|
|
@@ -110522,7 +110631,7 @@ async function handleParse(target, options2) {
|
|
|
110522
110631
|
console.log(JSON.stringify({ file: relative30(process.cwd(), planFile), frontmatter, phases }, null, 2));
|
|
110523
110632
|
return;
|
|
110524
110633
|
}
|
|
110525
|
-
const title = typeof frontmatter.title === "string" ? frontmatter.title : basename28(
|
|
110634
|
+
const title = typeof frontmatter.title === "string" ? frontmatter.title : basename28(dirname44(planFile));
|
|
110526
110635
|
console.log();
|
|
110527
110636
|
console.log(import_picocolors32.default.bold(` Plan: ${title}`));
|
|
110528
110637
|
console.log(` File: ${planFile}`);
|
|
@@ -110592,8 +110701,8 @@ async function handleStatus(target, options2) {
|
|
|
110592
110701
|
return;
|
|
110593
110702
|
}
|
|
110594
110703
|
const effectiveTarget = !resolvedTarget && globalBaseDir ? globalBaseDir : resolvedTarget;
|
|
110595
|
-
const t = effectiveTarget ?
|
|
110596
|
-
const plansDir = t && existsSync67(t) && statSync11(t).isDirectory() && !existsSync67(
|
|
110704
|
+
const t = effectiveTarget ? resolve50(effectiveTarget) : null;
|
|
110705
|
+
const plansDir = t && existsSync67(t) && statSync11(t).isDirectory() && !existsSync67(join147(t, "plan.md")) ? t : null;
|
|
110597
110706
|
if (plansDir) {
|
|
110598
110707
|
const planFiles = scanPlanDir(plansDir);
|
|
110599
110708
|
if (planFiles.length === 0) {
|
|
@@ -110633,7 +110742,7 @@ async function handleStatus(target, options2) {
|
|
|
110633
110742
|
const blockedBy2 = await resolvePlanDependencies(s.blockedBy, pf, { preloadedConfig });
|
|
110634
110743
|
const blocks2 = await resolvePlanDependencies(s.blocks, pf, { preloadedConfig });
|
|
110635
110744
|
const bar = progressBar(s.completed, s.totalPhases);
|
|
110636
|
-
const title2 = s.title ?? basename28(
|
|
110745
|
+
const title2 = s.title ?? basename28(dirname44(pf));
|
|
110637
110746
|
console.log(` ${import_picocolors32.default.bold(title2)}`);
|
|
110638
110747
|
console.log(` ${bar}`);
|
|
110639
110748
|
if (s.inProgress > 0)
|
|
@@ -110652,7 +110761,7 @@ async function handleStatus(target, options2) {
|
|
|
110652
110761
|
}
|
|
110653
110762
|
console.log();
|
|
110654
110763
|
} catch {
|
|
110655
|
-
console.log(` [X] Failed to read: ${basename28(
|
|
110764
|
+
console.log(` [X] Failed to read: ${basename28(dirname44(pf))}`);
|
|
110656
110765
|
console.log();
|
|
110657
110766
|
}
|
|
110658
110767
|
}
|
|
@@ -110679,7 +110788,7 @@ async function handleStatus(target, options2) {
|
|
|
110679
110788
|
console.log(JSON.stringify({ ...summary, dependencyStatus: { blockedBy, blocks } }, null, 2));
|
|
110680
110789
|
return;
|
|
110681
110790
|
}
|
|
110682
|
-
const title = summary.title ?? basename28(
|
|
110791
|
+
const title = summary.title ?? basename28(dirname44(planFile));
|
|
110683
110792
|
console.log();
|
|
110684
110793
|
console.log(import_picocolors32.default.bold(` ${title}`));
|
|
110685
110794
|
if (summary.status)
|
|
@@ -110742,7 +110851,7 @@ async function handleKanban(target, options2) {
|
|
|
110742
110851
|
process.exitCode = 1;
|
|
110743
110852
|
return;
|
|
110744
110853
|
}
|
|
110745
|
-
const route = `/plans?dir=${encodeURIComponent(
|
|
110854
|
+
const route = `/plans?dir=${encodeURIComponent(dirname44(dirname44(planFile)))}&view=kanban`;
|
|
110746
110855
|
const url = `http://localhost:${server.port}${route}`;
|
|
110747
110856
|
console.log();
|
|
110748
110857
|
console.log(import_picocolors32.default.bold(" ClaudeKit Dashboard — Plans"));
|
|
@@ -110777,7 +110886,7 @@ init_plan_parser();
|
|
|
110777
110886
|
init_plans_registry();
|
|
110778
110887
|
init_output_manager();
|
|
110779
110888
|
var import_picocolors33 = __toESM(require_picocolors(), 1);
|
|
110780
|
-
import { basename as basename29, dirname as
|
|
110889
|
+
import { basename as basename29, dirname as dirname45, relative as relative31, resolve as resolve51 } from "node:path";
|
|
110781
110890
|
async function handleCreate(target, options2) {
|
|
110782
110891
|
if (!options2.title) {
|
|
110783
110892
|
output.error("[X] --title is required for create");
|
|
@@ -110809,13 +110918,13 @@ async function handleCreate(target, options2) {
|
|
|
110809
110918
|
return;
|
|
110810
110919
|
}
|
|
110811
110920
|
const globalBaseDir = options2.global ? await getGlobalPlansDirFromCwd() : undefined;
|
|
110812
|
-
const resolvedDir = globalBaseDir ? resolveTargetFromBase(dir, globalBaseDir) :
|
|
110921
|
+
const resolvedDir = globalBaseDir ? resolveTargetFromBase(dir, globalBaseDir) : resolve51(dir);
|
|
110813
110922
|
if (globalBaseDir && !resolvedDir) {
|
|
110814
110923
|
output.error("[X] Target directory must stay within the configured global plans root");
|
|
110815
110924
|
process.exitCode = 1;
|
|
110816
110925
|
return;
|
|
110817
110926
|
}
|
|
110818
|
-
const safeResolvedDir = resolvedDir ??
|
|
110927
|
+
const safeResolvedDir = resolvedDir ?? resolve51(dir);
|
|
110819
110928
|
const result = scaffoldPlan({
|
|
110820
110929
|
title: options2.title,
|
|
110821
110930
|
phases: phaseNames.map((name2) => ({ name: name2 })),
|
|
@@ -110877,7 +110986,7 @@ async function handleCheck(target, options2) {
|
|
|
110877
110986
|
process.exitCode = 1;
|
|
110878
110987
|
return;
|
|
110879
110988
|
}
|
|
110880
|
-
const planDir =
|
|
110989
|
+
const planDir = dirname45(planFile);
|
|
110881
110990
|
let planStatus = "pending";
|
|
110882
110991
|
try {
|
|
110883
110992
|
const projectRoot = findProjectRoot(planDir);
|
|
@@ -110926,7 +111035,7 @@ async function handleUncheck(target, options2) {
|
|
|
110926
111035
|
process.exitCode = 1;
|
|
110927
111036
|
return;
|
|
110928
111037
|
}
|
|
110929
|
-
const planDir =
|
|
111038
|
+
const planDir = dirname45(planFile);
|
|
110930
111039
|
try {
|
|
110931
111040
|
const projectRoot = findProjectRoot(planDir);
|
|
110932
111041
|
const summary = buildPlanSummary(planFile);
|
|
@@ -110965,7 +111074,7 @@ async function handleAddPhase(target, options2) {
|
|
|
110965
111074
|
try {
|
|
110966
111075
|
const result = addPhase(planFile, target, options2.after);
|
|
110967
111076
|
try {
|
|
110968
|
-
const planDir =
|
|
111077
|
+
const planDir = dirname45(planFile);
|
|
110969
111078
|
const projectRoot = findProjectRoot(planDir);
|
|
110970
111079
|
updateRegistryAddPhase({
|
|
110971
111080
|
planDir,
|
|
@@ -110991,24 +111100,24 @@ async function handleAddPhase(target, options2) {
|
|
|
110991
111100
|
// src/commands/plan/plan-command.ts
|
|
110992
111101
|
function resolveTargetPath(target, baseDir) {
|
|
110993
111102
|
if (!baseDir) {
|
|
110994
|
-
return
|
|
111103
|
+
return resolve52(target);
|
|
110995
111104
|
}
|
|
110996
111105
|
if (isAbsolute11(target)) {
|
|
110997
|
-
return
|
|
111106
|
+
return resolve52(target);
|
|
110998
111107
|
}
|
|
110999
|
-
const cwdCandidate =
|
|
111108
|
+
const cwdCandidate = resolve52(target);
|
|
111000
111109
|
if (existsSync68(cwdCandidate)) {
|
|
111001
111110
|
return cwdCandidate;
|
|
111002
111111
|
}
|
|
111003
|
-
return
|
|
111112
|
+
return resolve52(baseDir, target);
|
|
111004
111113
|
}
|
|
111005
111114
|
function resolvePlanFile(target, baseDir) {
|
|
111006
|
-
const t = target ? resolveTargetPath(target, baseDir) : baseDir ?
|
|
111115
|
+
const t = target ? resolveTargetPath(target, baseDir) : baseDir ? resolve52(baseDir) : process.cwd();
|
|
111007
111116
|
if (existsSync68(t)) {
|
|
111008
|
-
const
|
|
111009
|
-
if (
|
|
111117
|
+
const stat24 = statSync12(t);
|
|
111118
|
+
if (stat24.isFile())
|
|
111010
111119
|
return t;
|
|
111011
|
-
const candidate =
|
|
111120
|
+
const candidate = join148(t, "plan.md");
|
|
111012
111121
|
if (existsSync68(candidate))
|
|
111013
111122
|
return candidate;
|
|
111014
111123
|
}
|
|
@@ -111016,10 +111125,10 @@ function resolvePlanFile(target, baseDir) {
|
|
|
111016
111125
|
let dir = process.cwd();
|
|
111017
111126
|
const root = parse7(dir).root;
|
|
111018
111127
|
while (dir !== root) {
|
|
111019
|
-
const candidate =
|
|
111128
|
+
const candidate = join148(dir, "plan.md");
|
|
111020
111129
|
if (existsSync68(candidate))
|
|
111021
111130
|
return candidate;
|
|
111022
|
-
dir =
|
|
111131
|
+
dir = dirname46(dir);
|
|
111023
111132
|
}
|
|
111024
111133
|
}
|
|
111025
111134
|
return null;
|
|
@@ -111067,7 +111176,7 @@ async function planCommand(action, target, options2) {
|
|
|
111067
111176
|
let resolvedTarget = target;
|
|
111068
111177
|
if (resolvedAction && !knownActions.has(resolvedAction)) {
|
|
111069
111178
|
const looksLikePath = resolvedAction.includes("/") || resolvedAction.includes("\\") || resolvedAction.endsWith(".md") || resolvedAction === "." || resolvedAction === "..";
|
|
111070
|
-
const existsOnDisk = !looksLikePath && existsSync68(
|
|
111179
|
+
const existsOnDisk = !looksLikePath && existsSync68(resolve52(resolvedAction));
|
|
111071
111180
|
if (looksLikePath || existsOnDisk) {
|
|
111072
111181
|
resolvedTarget = resolvedAction;
|
|
111073
111182
|
resolvedAction = undefined;
|
|
@@ -111110,11 +111219,11 @@ init_logger();
|
|
|
111110
111219
|
init_safe_prompts();
|
|
111111
111220
|
var import_picocolors34 = __toESM(require_picocolors(), 1);
|
|
111112
111221
|
import { existsSync as existsSync69 } from "node:fs";
|
|
111113
|
-
import { resolve as
|
|
111222
|
+
import { resolve as resolve53 } from "node:path";
|
|
111114
111223
|
async function handleAdd(projectPath, options2) {
|
|
111115
111224
|
logger.debug(`Adding project: ${projectPath}, options: ${JSON.stringify(options2)}`);
|
|
111116
111225
|
intro("Add Project");
|
|
111117
|
-
const absolutePath =
|
|
111226
|
+
const absolutePath = resolve53(projectPath);
|
|
111118
111227
|
if (!existsSync69(absolutePath)) {
|
|
111119
111228
|
log.error(`Path does not exist: ${absolutePath}`);
|
|
111120
111229
|
process.exitCode = 1;
|
|
@@ -111535,10 +111644,10 @@ init_agents();
|
|
|
111535
111644
|
var import_gray_matter12 = __toESM(require_gray_matter(), 1);
|
|
111536
111645
|
var import_picocolors37 = __toESM(require_picocolors(), 1);
|
|
111537
111646
|
import { readFile as readFile65 } from "node:fs/promises";
|
|
111538
|
-
import { join as
|
|
111647
|
+
import { join as join150 } from "node:path";
|
|
111539
111648
|
|
|
111540
111649
|
// src/commands/skills/installed-skills-inventory.ts
|
|
111541
|
-
import { join as
|
|
111650
|
+
import { join as join149, resolve as resolve54 } from "node:path";
|
|
111542
111651
|
init_path_resolver();
|
|
111543
111652
|
var SCOPE_SORT_ORDER = {
|
|
111544
111653
|
project: 0,
|
|
@@ -111546,10 +111655,12 @@ var SCOPE_SORT_ORDER = {
|
|
|
111546
111655
|
};
|
|
111547
111656
|
async function getActiveClaudeSkillInstallations(options2 = {}) {
|
|
111548
111657
|
const projectDir = options2.projectDir ?? process.cwd();
|
|
111549
|
-
const globalDir = options2.globalDir ?? PathResolver.getGlobalKitDir();
|
|
111658
|
+
const globalDir = resolve54(options2.globalDir ?? PathResolver.getGlobalKitDir());
|
|
111659
|
+
const projectClaudeDir = resolve54(projectDir, ".claude");
|
|
111660
|
+
const projectScopeAliasesGlobal = projectClaudeDir === globalDir;
|
|
111550
111661
|
const [projectSkills, globalSkills] = await Promise.all([
|
|
111551
|
-
scanSkills2(
|
|
111552
|
-
scanSkills2(
|
|
111662
|
+
projectScopeAliasesGlobal ? Promise.resolve([]) : scanSkills2(join149(projectClaudeDir, "skills")),
|
|
111663
|
+
scanSkills2(join149(globalDir, "skills"))
|
|
111553
111664
|
]);
|
|
111554
111665
|
const projectIds = new Set(projectSkills.map((skill) => skill.id));
|
|
111555
111666
|
const globalIds = new Set(globalSkills.map((skill) => skill.id));
|
|
@@ -111709,7 +111820,7 @@ async function handleValidate2(sourcePath) {
|
|
|
111709
111820
|
spinner.stop(`Checked ${skills.length} skill(s)`);
|
|
111710
111821
|
let hasIssues = false;
|
|
111711
111822
|
for (const skill of skills) {
|
|
111712
|
-
const skillMdPath =
|
|
111823
|
+
const skillMdPath = join150(skill.path, "SKILL.md");
|
|
111713
111824
|
try {
|
|
111714
111825
|
const content = await readFile65(skillMdPath, "utf-8");
|
|
111715
111826
|
const { data } = import_gray_matter12.default(content, {
|
|
@@ -112253,7 +112364,7 @@ var import_picocolors39 = __toESM(require_picocolors(), 1);
|
|
|
112253
112364
|
// src/commands/uninstall/installation-detector.ts
|
|
112254
112365
|
init_claudekit_scanner();
|
|
112255
112366
|
init_path_resolver();
|
|
112256
|
-
var
|
|
112367
|
+
var import_fs_extra40 = __toESM(require_lib(), 1);
|
|
112257
112368
|
function hasClaudeKitComponents(components) {
|
|
112258
112369
|
return components.agents > 0 || components.commands > 0 || components.rules > 0 || components.skills > 0;
|
|
112259
112370
|
}
|
|
@@ -112268,7 +112379,7 @@ async function detectInstallations() {
|
|
|
112268
112379
|
installations.push({
|
|
112269
112380
|
type: "local",
|
|
112270
112381
|
path: setup.project.path,
|
|
112271
|
-
exists: await
|
|
112382
|
+
exists: await import_fs_extra40.pathExists(setup.project.path),
|
|
112272
112383
|
hasMetadata,
|
|
112273
112384
|
components: setup.project.components
|
|
112274
112385
|
});
|
|
@@ -112281,7 +112392,7 @@ async function detectInstallations() {
|
|
|
112281
112392
|
installations.push({
|
|
112282
112393
|
type: "global",
|
|
112283
112394
|
path: setup.global.path,
|
|
112284
|
-
exists: await
|
|
112395
|
+
exists: await import_fs_extra40.pathExists(setup.global.path),
|
|
112285
112396
|
hasMetadata,
|
|
112286
112397
|
components: setup.global.components
|
|
112287
112398
|
});
|
|
@@ -112292,19 +112403,19 @@ async function detectInstallations() {
|
|
|
112292
112403
|
|
|
112293
112404
|
// src/commands/uninstall/removal-handler.ts
|
|
112294
112405
|
import { readdirSync as readdirSync10, rmSync as rmSync5 } from "node:fs";
|
|
112295
|
-
import { basename as basename30, join as
|
|
112406
|
+
import { basename as basename30, join as join152, resolve as resolve55, sep as sep13 } from "node:path";
|
|
112296
112407
|
init_logger();
|
|
112297
112408
|
init_safe_prompts();
|
|
112298
112409
|
init_safe_spinner();
|
|
112299
|
-
var
|
|
112410
|
+
var import_fs_extra42 = __toESM(require_lib(), 1);
|
|
112300
112411
|
|
|
112301
112412
|
// src/commands/uninstall/analysis-handler.ts
|
|
112302
112413
|
init_metadata_migration();
|
|
112303
112414
|
import { readdirSync as readdirSync9, rmSync as rmSync4 } from "node:fs";
|
|
112304
|
-
import { dirname as
|
|
112415
|
+
import { dirname as dirname47, join as join151 } from "node:path";
|
|
112305
112416
|
init_logger();
|
|
112306
112417
|
init_safe_prompts();
|
|
112307
|
-
var
|
|
112418
|
+
var import_fs_extra41 = __toESM(require_lib(), 1);
|
|
112308
112419
|
var import_picocolors38 = __toESM(require_picocolors(), 1);
|
|
112309
112420
|
function normalizeTrackedPath(relativePath) {
|
|
112310
112421
|
return relativePath.replace(/\\/g, "/");
|
|
@@ -112323,7 +112434,7 @@ function classifyFileByOwnership(ownership, forceOverwrite, deleteReason) {
|
|
|
112323
112434
|
}
|
|
112324
112435
|
async function cleanupEmptyDirectories3(filePath, installationRoot) {
|
|
112325
112436
|
let cleaned = 0;
|
|
112326
|
-
let currentDir =
|
|
112437
|
+
let currentDir = dirname47(filePath);
|
|
112327
112438
|
while (currentDir !== installationRoot && currentDir.startsWith(installationRoot)) {
|
|
112328
112439
|
try {
|
|
112329
112440
|
const entries = readdirSync9(currentDir);
|
|
@@ -112331,7 +112442,7 @@ async function cleanupEmptyDirectories3(filePath, installationRoot) {
|
|
|
112331
112442
|
rmSync4(currentDir, { recursive: true });
|
|
112332
112443
|
cleaned++;
|
|
112333
112444
|
logger.debug(`Removed empty directory: ${currentDir}`);
|
|
112334
|
-
currentDir =
|
|
112445
|
+
currentDir = dirname47(currentDir);
|
|
112335
112446
|
} else {
|
|
112336
112447
|
break;
|
|
112337
112448
|
}
|
|
@@ -112361,7 +112472,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
112361
112472
|
const remainingFiles = metadata.kits?.[remainingKit]?.files || [];
|
|
112362
112473
|
for (const file of remainingFiles) {
|
|
112363
112474
|
const relativePath = normalizeTrackedPath(file.path);
|
|
112364
|
-
if (await
|
|
112475
|
+
if (await import_fs_extra41.pathExists(join151(installation.path, relativePath))) {
|
|
112365
112476
|
result.retainedManifestPaths.push(relativePath);
|
|
112366
112477
|
}
|
|
112367
112478
|
}
|
|
@@ -112369,7 +112480,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
112369
112480
|
const kitFiles = metadata.kits[kit].files || [];
|
|
112370
112481
|
for (const trackedFile of kitFiles) {
|
|
112371
112482
|
const relativePath = normalizeTrackedPath(trackedFile.path);
|
|
112372
|
-
const filePath =
|
|
112483
|
+
const filePath = join151(installation.path, relativePath);
|
|
112373
112484
|
if (preservedPaths.has(relativePath)) {
|
|
112374
112485
|
result.toPreserve.push({ path: relativePath, reason: "shared with other kit" });
|
|
112375
112486
|
continue;
|
|
@@ -112402,7 +112513,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
112402
112513
|
}
|
|
112403
112514
|
for (const trackedFile of allTrackedFiles) {
|
|
112404
112515
|
const relativePath = normalizeTrackedPath(trackedFile.path);
|
|
112405
|
-
const filePath =
|
|
112516
|
+
const filePath = join151(installation.path, relativePath);
|
|
112406
112517
|
const ownershipResult = await OwnershipChecker.checkOwnership(filePath, metadata, installation.path);
|
|
112407
112518
|
if (!ownershipResult.exists)
|
|
112408
112519
|
continue;
|
|
@@ -112449,9 +112560,9 @@ function displayDryRunPreview(analysis, installationType) {
|
|
|
112449
112560
|
}
|
|
112450
112561
|
|
|
112451
112562
|
// src/commands/uninstall/removal-handler.ts
|
|
112452
|
-
async function
|
|
112563
|
+
async function isDirectory2(filePath) {
|
|
112453
112564
|
try {
|
|
112454
|
-
const stats = await
|
|
112565
|
+
const stats = await import_fs_extra42.lstat(filePath);
|
|
112455
112566
|
return stats.isDirectory();
|
|
112456
112567
|
} catch {
|
|
112457
112568
|
logger.debug(`Failed to check if path is directory: ${filePath}`);
|
|
@@ -112476,16 +112587,16 @@ async function restoreUninstallBackup(backup) {
|
|
|
112476
112587
|
}
|
|
112477
112588
|
async function isPathSafeToRemove(filePath, baseDir) {
|
|
112478
112589
|
try {
|
|
112479
|
-
const resolvedPath =
|
|
112480
|
-
const resolvedBase =
|
|
112590
|
+
const resolvedPath = resolve55(filePath);
|
|
112591
|
+
const resolvedBase = resolve55(baseDir);
|
|
112481
112592
|
if (!resolvedPath.startsWith(resolvedBase + sep13) && resolvedPath !== resolvedBase) {
|
|
112482
112593
|
logger.debug(`Path outside installation directory: ${filePath}`);
|
|
112483
112594
|
return false;
|
|
112484
112595
|
}
|
|
112485
|
-
const stats = await
|
|
112596
|
+
const stats = await import_fs_extra42.lstat(filePath);
|
|
112486
112597
|
if (stats.isSymbolicLink()) {
|
|
112487
|
-
const realPath = await
|
|
112488
|
-
const resolvedReal =
|
|
112598
|
+
const realPath = await import_fs_extra42.realpath(filePath);
|
|
112599
|
+
const resolvedReal = resolve55(realPath);
|
|
112489
112600
|
if (!resolvedReal.startsWith(resolvedBase + sep13) && resolvedReal !== resolvedBase) {
|
|
112490
112601
|
logger.debug(`Symlink points outside installation directory: ${filePath} -> ${realPath}`);
|
|
112491
112602
|
return false;
|
|
@@ -112545,15 +112656,15 @@ async function removeInstallations(installations, options2) {
|
|
|
112545
112656
|
let removedCount = 0;
|
|
112546
112657
|
let cleanedDirs = 0;
|
|
112547
112658
|
for (const item of analysis.toDelete) {
|
|
112548
|
-
const filePath =
|
|
112549
|
-
if (!await
|
|
112659
|
+
const filePath = join152(installation.path, item.path);
|
|
112660
|
+
if (!await import_fs_extra42.pathExists(filePath))
|
|
112550
112661
|
continue;
|
|
112551
112662
|
if (!await isPathSafeToRemove(filePath, installation.path)) {
|
|
112552
112663
|
logger.debug(`Skipping unsafe path: ${item.path}`);
|
|
112553
112664
|
continue;
|
|
112554
112665
|
}
|
|
112555
|
-
const isDir = await
|
|
112556
|
-
await
|
|
112666
|
+
const isDir = await isDirectory2(filePath);
|
|
112667
|
+
await import_fs_extra42.remove(filePath);
|
|
112557
112668
|
removedCount++;
|
|
112558
112669
|
logger.debug(`Removed ${isDir ? "directory" : "file"}: ${item.path}`);
|
|
112559
112670
|
if (!isDir) {
|
|
@@ -112953,8 +113064,8 @@ ${import_picocolors40.default.bold(import_picocolors40.default.cyan(result.kitCo
|
|
|
112953
113064
|
// src/commands/watch/watch-command.ts
|
|
112954
113065
|
init_logger();
|
|
112955
113066
|
import { existsSync as existsSync75 } from "node:fs";
|
|
112956
|
-
import { rm as
|
|
112957
|
-
import { join as
|
|
113067
|
+
import { rm as rm18 } from "node:fs/promises";
|
|
113068
|
+
import { join as join159 } from "node:path";
|
|
112958
113069
|
var import_picocolors41 = __toESM(require_picocolors(), 1);
|
|
112959
113070
|
|
|
112960
113071
|
// src/commands/watch/phases/implementation-runner.ts
|
|
@@ -113472,8 +113583,8 @@ function spawnAndCollect3(command, args) {
|
|
|
113472
113583
|
}
|
|
113473
113584
|
|
|
113474
113585
|
// src/commands/watch/phases/issue-processor.ts
|
|
113475
|
-
import { mkdir as
|
|
113476
|
-
import { join as
|
|
113586
|
+
import { mkdir as mkdir40, writeFile as writeFile38 } from "node:fs/promises";
|
|
113587
|
+
import { join as join155 } from "node:path";
|
|
113477
113588
|
|
|
113478
113589
|
// src/commands/watch/phases/approval-detector.ts
|
|
113479
113590
|
init_logger();
|
|
@@ -113850,26 +113961,26 @@ async function checkAwaitingApproval(state, setup, options2, watchLog, projectDi
|
|
|
113850
113961
|
}
|
|
113851
113962
|
|
|
113852
113963
|
// src/commands/watch/phases/plan-dir-finder.ts
|
|
113853
|
-
import { readdir as
|
|
113854
|
-
import { join as
|
|
113964
|
+
import { readdir as readdir45, stat as stat24 } from "node:fs/promises";
|
|
113965
|
+
import { join as join154 } from "node:path";
|
|
113855
113966
|
async function findRecentPlanDir(cwd2, issueNumber, watchLog) {
|
|
113856
|
-
const plansRoot =
|
|
113967
|
+
const plansRoot = join154(cwd2, "plans");
|
|
113857
113968
|
try {
|
|
113858
|
-
const entries = await
|
|
113969
|
+
const entries = await readdir45(plansRoot);
|
|
113859
113970
|
const tenMinAgo = Date.now() - 10 * 60 * 1000;
|
|
113860
113971
|
const issueStr = String(issueNumber);
|
|
113861
113972
|
const candidates = [];
|
|
113862
113973
|
for (const entry of entries) {
|
|
113863
113974
|
if (entry === "watch" || entry === "reports" || entry === "visuals")
|
|
113864
113975
|
continue;
|
|
113865
|
-
const dirPath =
|
|
113866
|
-
const dirStat = await
|
|
113976
|
+
const dirPath = join154(plansRoot, entry);
|
|
113977
|
+
const dirStat = await stat24(dirPath);
|
|
113867
113978
|
if (!dirStat.isDirectory())
|
|
113868
113979
|
continue;
|
|
113869
113980
|
if (dirStat.mtimeMs < tenMinAgo)
|
|
113870
113981
|
continue;
|
|
113871
113982
|
try {
|
|
113872
|
-
await
|
|
113983
|
+
await stat24(join154(dirPath, "plan.md"));
|
|
113873
113984
|
} catch {
|
|
113874
113985
|
continue;
|
|
113875
113986
|
}
|
|
@@ -114100,13 +114211,13 @@ async function handlePlanGeneration(issue, state, config, setup, options2, watch
|
|
|
114100
114211
|
stats.plansCreated++;
|
|
114101
114212
|
const detectedPlanDir = await findRecentPlanDir(projectDir, issue.number, watchLog);
|
|
114102
114213
|
if (detectedPlanDir) {
|
|
114103
|
-
state.activeIssues[numStr].planPath =
|
|
114214
|
+
state.activeIssues[numStr].planPath = join155(detectedPlanDir, "plan.md");
|
|
114104
114215
|
watchLog.info(`Plan directory detected: ${detectedPlanDir}`);
|
|
114105
114216
|
} else {
|
|
114106
114217
|
try {
|
|
114107
|
-
const planDir =
|
|
114108
|
-
await
|
|
114109
|
-
const planFilePath =
|
|
114218
|
+
const planDir = join155(projectDir, "plans", "watch");
|
|
114219
|
+
await mkdir40(planDir, { recursive: true });
|
|
114220
|
+
const planFilePath = join155(planDir, `issue-${issue.number}-plan.md`);
|
|
114110
114221
|
await writeFile38(planFilePath, planResult.planText, "utf-8");
|
|
114111
114222
|
state.activeIssues[numStr].planPath = planFilePath;
|
|
114112
114223
|
watchLog.info(`Plan saved (fallback) to ${planFilePath}`);
|
|
@@ -114252,8 +114363,8 @@ init_ck_config_manager();
|
|
|
114252
114363
|
init_file_io();
|
|
114253
114364
|
init_logger();
|
|
114254
114365
|
import { existsSync as existsSync71 } from "node:fs";
|
|
114255
|
-
import { mkdir as
|
|
114256
|
-
import { dirname as
|
|
114366
|
+
import { mkdir as mkdir41, readFile as readFile67 } from "node:fs/promises";
|
|
114367
|
+
import { dirname as dirname48 } from "node:path";
|
|
114257
114368
|
var PROCESSED_ISSUES_CAP = 500;
|
|
114258
114369
|
async function readCkJson(projectDir) {
|
|
114259
114370
|
const configPath = CkConfigManager.getProjectConfigPath(projectDir);
|
|
@@ -114283,9 +114394,9 @@ async function loadWatchState(projectDir) {
|
|
|
114283
114394
|
}
|
|
114284
114395
|
async function saveWatchState(projectDir, state) {
|
|
114285
114396
|
const configPath = CkConfigManager.getProjectConfigPath(projectDir);
|
|
114286
|
-
const configDir =
|
|
114397
|
+
const configDir = dirname48(configPath);
|
|
114287
114398
|
if (!existsSync71(configDir)) {
|
|
114288
|
-
await
|
|
114399
|
+
await mkdir41(configDir, { recursive: true });
|
|
114289
114400
|
}
|
|
114290
114401
|
const raw2 = await readCkJson(projectDir);
|
|
114291
114402
|
const watchRaw = raw2.watch ?? {};
|
|
@@ -114412,19 +114523,19 @@ async function processImplementationQueue(state, config, setup, options2, watchL
|
|
|
114412
114523
|
init_logger();
|
|
114413
114524
|
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
114414
114525
|
import { existsSync as existsSync72 } from "node:fs";
|
|
114415
|
-
import { readdir as
|
|
114416
|
-
import { join as
|
|
114526
|
+
import { readdir as readdir46, stat as stat25 } from "node:fs/promises";
|
|
114527
|
+
import { join as join156 } from "node:path";
|
|
114417
114528
|
async function scanForRepos(parentDir) {
|
|
114418
114529
|
const repos = [];
|
|
114419
|
-
const entries = await
|
|
114530
|
+
const entries = await readdir46(parentDir);
|
|
114420
114531
|
for (const entry of entries) {
|
|
114421
114532
|
if (entry.startsWith("."))
|
|
114422
114533
|
continue;
|
|
114423
|
-
const fullPath =
|
|
114424
|
-
const entryStat = await
|
|
114534
|
+
const fullPath = join156(parentDir, entry);
|
|
114535
|
+
const entryStat = await stat25(fullPath);
|
|
114425
114536
|
if (!entryStat.isDirectory())
|
|
114426
114537
|
continue;
|
|
114427
|
-
const gitDir =
|
|
114538
|
+
const gitDir = join156(fullPath, ".git");
|
|
114428
114539
|
if (!existsSync72(gitDir))
|
|
114429
114540
|
continue;
|
|
114430
114541
|
const result = spawnSync7("gh", ["repo", "view", "--json", "owner,name"], {
|
|
@@ -114450,8 +114561,8 @@ async function scanForRepos(parentDir) {
|
|
|
114450
114561
|
init_logger();
|
|
114451
114562
|
import { spawnSync as spawnSync8 } from "node:child_process";
|
|
114452
114563
|
import { existsSync as existsSync73 } from "node:fs";
|
|
114453
|
-
import { homedir as
|
|
114454
|
-
import { join as
|
|
114564
|
+
import { homedir as homedir53 } from "node:os";
|
|
114565
|
+
import { join as join157 } from "node:path";
|
|
114455
114566
|
async function validateSetup(cwd2) {
|
|
114456
114567
|
const workDir = cwd2 ?? process.cwd();
|
|
114457
114568
|
const ghVersion = spawnSync8("gh", ["--version"], { encoding: "utf-8", timeout: 1e4 });
|
|
@@ -114482,7 +114593,7 @@ Run this command from a directory with a GitHub remote.`);
|
|
|
114482
114593
|
} catch {
|
|
114483
114594
|
throw new Error(`Failed to parse repository info: ${ghRepo.stdout}`);
|
|
114484
114595
|
}
|
|
114485
|
-
const skillsPath =
|
|
114596
|
+
const skillsPath = join157(homedir53(), ".claude", "skills");
|
|
114486
114597
|
const skillsAvailable = existsSync73(skillsPath);
|
|
114487
114598
|
if (!skillsAvailable) {
|
|
114488
114599
|
logger.warning(`ClaudeKit Engineer skills not found at ${skillsPath}`);
|
|
@@ -114500,8 +114611,8 @@ init_logger();
|
|
|
114500
114611
|
init_path_resolver();
|
|
114501
114612
|
import { createWriteStream as createWriteStream3, statSync as statSync13 } from "node:fs";
|
|
114502
114613
|
import { existsSync as existsSync74 } from "node:fs";
|
|
114503
|
-
import { mkdir as
|
|
114504
|
-
import { join as
|
|
114614
|
+
import { mkdir as mkdir42, rename as rename14 } from "node:fs/promises";
|
|
114615
|
+
import { join as join158 } from "node:path";
|
|
114505
114616
|
|
|
114506
114617
|
class WatchLogger {
|
|
114507
114618
|
logStream = null;
|
|
@@ -114509,16 +114620,16 @@ class WatchLogger {
|
|
|
114509
114620
|
logPath = null;
|
|
114510
114621
|
maxBytes;
|
|
114511
114622
|
constructor(logDir, maxBytes = 0) {
|
|
114512
|
-
this.logDir = logDir ??
|
|
114623
|
+
this.logDir = logDir ?? join158(PathResolver.getClaudeKitDir(), "logs");
|
|
114513
114624
|
this.maxBytes = maxBytes;
|
|
114514
114625
|
}
|
|
114515
114626
|
async init() {
|
|
114516
114627
|
try {
|
|
114517
114628
|
if (!existsSync74(this.logDir)) {
|
|
114518
|
-
await
|
|
114629
|
+
await mkdir42(this.logDir, { recursive: true });
|
|
114519
114630
|
}
|
|
114520
114631
|
const dateStr = formatDate(new Date);
|
|
114521
|
-
this.logPath =
|
|
114632
|
+
this.logPath = join158(this.logDir, `watch-${dateStr}.log`);
|
|
114522
114633
|
this.logStream = createWriteStream3(this.logPath, { flags: "a", mode: 384 });
|
|
114523
114634
|
} catch (error) {
|
|
114524
114635
|
logger.warning(`Cannot create watch log file: ${error instanceof Error ? error.message : "Unknown"}`);
|
|
@@ -114583,7 +114694,7 @@ class WatchLogger {
|
|
|
114583
114694
|
try {
|
|
114584
114695
|
this.logStream.end();
|
|
114585
114696
|
const rotatedPath = `${this.logPath}.1`;
|
|
114586
|
-
|
|
114697
|
+
rename14(this.logPath, rotatedPath).catch(() => {});
|
|
114587
114698
|
this.logStream = createWriteStream3(this.logPath, { flags: "w", mode: 384 });
|
|
114588
114699
|
} catch {}
|
|
114589
114700
|
}
|
|
@@ -114700,7 +114811,7 @@ async function watchCommand(options2) {
|
|
|
114700
114811
|
}
|
|
114701
114812
|
async function discoverRepos(options2, watchLog) {
|
|
114702
114813
|
const cwd2 = process.cwd();
|
|
114703
|
-
const isGitRepo = existsSync75(
|
|
114814
|
+
const isGitRepo = existsSync75(join159(cwd2, ".git"));
|
|
114704
114815
|
if (options2.force) {
|
|
114705
114816
|
await forceRemoveLock(watchLog);
|
|
114706
114817
|
}
|
|
@@ -114773,8 +114884,8 @@ async function forceRemoveLock(watchLog) {
|
|
|
114773
114884
|
const { resource, lockfile: lockfile7 } = getLockPaths(LOCK_NAME);
|
|
114774
114885
|
try {
|
|
114775
114886
|
await Promise.all([
|
|
114776
|
-
|
|
114777
|
-
|
|
114887
|
+
rm18(resource, { recursive: true, force: true }),
|
|
114888
|
+
rm18(lockfile7, { recursive: true, force: true })
|
|
114778
114889
|
]);
|
|
114779
114890
|
watchLog.info("Removed existing lock file (--force)");
|
|
114780
114891
|
} catch {}
|
|
@@ -114958,7 +115069,7 @@ function registerCommands(cli) {
|
|
|
114958
115069
|
init_package();
|
|
114959
115070
|
init_config_version_checker();
|
|
114960
115071
|
import { existsSync as existsSync87, readFileSync as readFileSync22 } from "node:fs";
|
|
114961
|
-
import { join as
|
|
115072
|
+
import { join as join171 } from "node:path";
|
|
114962
115073
|
|
|
114963
115074
|
// src/domains/versioning/version-checker.ts
|
|
114964
115075
|
init_version_utils();
|
|
@@ -114972,15 +115083,15 @@ init_types3();
|
|
|
114972
115083
|
init_logger();
|
|
114973
115084
|
init_path_resolver();
|
|
114974
115085
|
import { existsSync as existsSync86 } from "node:fs";
|
|
114975
|
-
import { mkdir as
|
|
114976
|
-
import { join as
|
|
115086
|
+
import { mkdir as mkdir43, readFile as readFile69, writeFile as writeFile41 } from "node:fs/promises";
|
|
115087
|
+
import { join as join170 } from "node:path";
|
|
114977
115088
|
|
|
114978
115089
|
class VersionCacheManager {
|
|
114979
115090
|
static CACHE_FILENAME = "version-check.json";
|
|
114980
115091
|
static CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000;
|
|
114981
115092
|
static getCacheFile() {
|
|
114982
115093
|
const cacheDir = PathResolver.getCacheDir(false);
|
|
114983
|
-
return
|
|
115094
|
+
return join170(cacheDir, VersionCacheManager.CACHE_FILENAME);
|
|
114984
115095
|
}
|
|
114985
115096
|
static async load() {
|
|
114986
115097
|
const cacheFile = VersionCacheManager.getCacheFile();
|
|
@@ -115007,7 +115118,7 @@ class VersionCacheManager {
|
|
|
115007
115118
|
const cacheDir = PathResolver.getCacheDir(false);
|
|
115008
115119
|
try {
|
|
115009
115120
|
if (!existsSync86(cacheDir)) {
|
|
115010
|
-
await
|
|
115121
|
+
await mkdir43(cacheDir, { recursive: true, mode: 448 });
|
|
115011
115122
|
}
|
|
115012
115123
|
await writeFile41(cacheFile, JSON.stringify(cache5, null, 2), "utf-8");
|
|
115013
115124
|
logger.debug(`Version check cache saved to ${cacheFile}`);
|
|
@@ -115291,9 +115402,9 @@ async function displayVersion() {
|
|
|
115291
115402
|
let localInstalledKits = [];
|
|
115292
115403
|
let globalInstalledKits = [];
|
|
115293
115404
|
const globalKitDir = PathResolver.getGlobalKitDir();
|
|
115294
|
-
const globalMetadataPath =
|
|
115405
|
+
const globalMetadataPath = join171(globalKitDir, "metadata.json");
|
|
115295
115406
|
const prefix = PathResolver.getPathPrefix(false);
|
|
115296
|
-
const localMetadataPath = prefix ?
|
|
115407
|
+
const localMetadataPath = prefix ? join171(process.cwd(), prefix, "metadata.json") : join171(process.cwd(), "metadata.json");
|
|
115297
115408
|
const isLocalSameAsGlobal = localMetadataPath === globalMetadataPath;
|
|
115298
115409
|
if (!isLocalSameAsGlobal && existsSync87(localMetadataPath)) {
|
|
115299
115410
|
try {
|
|
@@ -115681,7 +115792,7 @@ var output2 = new OutputManager2;
|
|
|
115681
115792
|
|
|
115682
115793
|
// src/shared/temp-cleanup.ts
|
|
115683
115794
|
init_logger();
|
|
115684
|
-
var
|
|
115795
|
+
var import_fs_extra43 = __toESM(require_lib(), 1);
|
|
115685
115796
|
import { rmSync as rmSync6 } from "node:fs";
|
|
115686
115797
|
var tempDirs2 = new Set;
|
|
115687
115798
|
async function cleanup() {
|
|
@@ -115690,7 +115801,7 @@ async function cleanup() {
|
|
|
115690
115801
|
logger.debug(`Cleaning up ${tempDirs2.size} temporary director(ies)...`);
|
|
115691
115802
|
for (const dir of tempDirs2) {
|
|
115692
115803
|
try {
|
|
115693
|
-
await
|
|
115804
|
+
await import_fs_extra43.remove(dir);
|
|
115694
115805
|
logger.debug(`Cleaned up temp directory: ${dir}`);
|
|
115695
115806
|
} catch (error) {
|
|
115696
115807
|
logger.debug(`Failed to clean temp directory ${dir}: ${error}`);
|