claudekit-cli 4.2.3-dev.1 → 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 +442 -307
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -63000,7 +63000,7 @@ var package_default;
|
|
|
63000
63000
|
var init_package = __esm(() => {
|
|
63001
63001
|
package_default = {
|
|
63002
63002
|
name: "claudekit-cli",
|
|
63003
|
-
version: "4.2.3-dev.
|
|
63003
|
+
version: "4.2.3-dev.2",
|
|
63004
63004
|
description: "CLI tool for bootstrapping and updating ClaudeKit projects",
|
|
63005
63005
|
type: "module",
|
|
63006
63006
|
repository: {
|
|
@@ -74224,9 +74224,9 @@ __export(exports_worktree_manager, {
|
|
|
74224
74224
|
});
|
|
74225
74225
|
import { existsSync as existsSync70 } from "node:fs";
|
|
74226
74226
|
import { readFile as readFile66, writeFile as writeFile37 } from "node:fs/promises";
|
|
74227
|
-
import { join as
|
|
74227
|
+
import { join as join153 } from "node:path";
|
|
74228
74228
|
async function createWorktree(projectDir, issueNumber, baseBranch) {
|
|
74229
|
-
const worktreePath =
|
|
74229
|
+
const worktreePath = join153(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
|
|
74230
74230
|
const branchName = `ck-watch/issue-${issueNumber}`;
|
|
74231
74231
|
await spawnAndCollect("git", ["fetch", "origin", baseBranch], projectDir).catch(() => {
|
|
74232
74232
|
logger.warning(`[worktree] Could not fetch origin/${baseBranch}, using local`);
|
|
@@ -74244,7 +74244,7 @@ async function createWorktree(projectDir, issueNumber, baseBranch) {
|
|
|
74244
74244
|
return worktreePath;
|
|
74245
74245
|
}
|
|
74246
74246
|
async function removeWorktree(projectDir, issueNumber) {
|
|
74247
|
-
const worktreePath =
|
|
74247
|
+
const worktreePath = join153(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
|
|
74248
74248
|
const branchName = `ck-watch/issue-${issueNumber}`;
|
|
74249
74249
|
try {
|
|
74250
74250
|
await spawnAndCollect("git", ["worktree", "remove", worktreePath, "--force"], projectDir);
|
|
@@ -74258,7 +74258,7 @@ async function listActiveWorktrees(projectDir) {
|
|
|
74258
74258
|
try {
|
|
74259
74259
|
const output2 = await spawnAndCollect("git", ["worktree", "list", "--porcelain"], projectDir);
|
|
74260
74260
|
const issueNumbers = [];
|
|
74261
|
-
const worktreePrefix =
|
|
74261
|
+
const worktreePrefix = join153(projectDir, WORKTREE_DIR, "issue-").replace(/\\/g, "/");
|
|
74262
74262
|
for (const line of output2.split(`
|
|
74263
74263
|
`)) {
|
|
74264
74264
|
if (line.startsWith("worktree ")) {
|
|
@@ -74286,7 +74286,7 @@ async function cleanupAllWorktrees(projectDir) {
|
|
|
74286
74286
|
await spawnAndCollect("git", ["worktree", "prune"], projectDir).catch(() => {});
|
|
74287
74287
|
}
|
|
74288
74288
|
async function ensureGitignore(projectDir) {
|
|
74289
|
-
const gitignorePath =
|
|
74289
|
+
const gitignorePath = join153(projectDir, ".gitignore");
|
|
74290
74290
|
try {
|
|
74291
74291
|
const content = existsSync70(gitignorePath) ? await readFile66(gitignorePath, "utf-8") : "";
|
|
74292
74292
|
if (!content.includes(".worktrees")) {
|
|
@@ -74315,8 +74315,8 @@ function countTwitterChars(text) {
|
|
|
74315
74315
|
const withoutUrls = text.replace(urlPattern, "");
|
|
74316
74316
|
let count = urlCount * 23;
|
|
74317
74317
|
for (const char of withoutUrls) {
|
|
74318
|
-
const
|
|
74319
|
-
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) {
|
|
74320
74320
|
count += 2;
|
|
74321
74321
|
} else {
|
|
74322
74322
|
count += 1;
|
|
@@ -74391,9 +74391,9 @@ var init_content_validator = __esm(() => {
|
|
|
74391
74391
|
// src/commands/content/phases/context-cache-manager.ts
|
|
74392
74392
|
import { createHash as createHash9 } from "node:crypto";
|
|
74393
74393
|
import { existsSync as existsSync76, mkdirSync as mkdirSync5, readFileSync as readFileSync18, readdirSync as readdirSync11, statSync as statSync14 } from "node:fs";
|
|
74394
|
-
import { rename as
|
|
74395
|
-
import { homedir as
|
|
74396
|
-
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";
|
|
74397
74397
|
function getCachedContext(repoPath) {
|
|
74398
74398
|
const cachePath = getCacheFilePath(repoPath);
|
|
74399
74399
|
if (!existsSync76(cachePath))
|
|
@@ -74419,15 +74419,15 @@ async function saveCachedContext(repoPath, cache5) {
|
|
|
74419
74419
|
const cachePath = getCacheFilePath(repoPath);
|
|
74420
74420
|
const tmpPath = `${cachePath}.tmp`;
|
|
74421
74421
|
await writeFile39(tmpPath, JSON.stringify(cache5, null, 2), "utf-8");
|
|
74422
|
-
await
|
|
74422
|
+
await rename15(tmpPath, cachePath);
|
|
74423
74423
|
}
|
|
74424
74424
|
function computeSourceHash(repoPath) {
|
|
74425
74425
|
const hash = createHash9("sha256");
|
|
74426
74426
|
const paths = getDocSourcePaths(repoPath);
|
|
74427
74427
|
for (const filePath of paths) {
|
|
74428
74428
|
try {
|
|
74429
|
-
const
|
|
74430
|
-
hash.update(`${filePath}:${
|
|
74429
|
+
const stat26 = statSync14(filePath);
|
|
74430
|
+
hash.update(`${filePath}:${stat26.mtimeMs}`);
|
|
74431
74431
|
} catch {
|
|
74432
74432
|
hash.update(`${filePath}:0`);
|
|
74433
74433
|
}
|
|
@@ -74436,25 +74436,25 @@ function computeSourceHash(repoPath) {
|
|
|
74436
74436
|
}
|
|
74437
74437
|
function getDocSourcePaths(repoPath) {
|
|
74438
74438
|
const paths = [];
|
|
74439
|
-
const docsDir =
|
|
74439
|
+
const docsDir = join160(repoPath, "docs");
|
|
74440
74440
|
if (existsSync76(docsDir)) {
|
|
74441
74441
|
try {
|
|
74442
74442
|
const files = readdirSync11(docsDir);
|
|
74443
74443
|
for (const f3 of files) {
|
|
74444
74444
|
if (f3.endsWith(".md"))
|
|
74445
|
-
paths.push(
|
|
74445
|
+
paths.push(join160(docsDir, f3));
|
|
74446
74446
|
}
|
|
74447
74447
|
} catch {}
|
|
74448
74448
|
}
|
|
74449
|
-
const readme =
|
|
74449
|
+
const readme = join160(repoPath, "README.md");
|
|
74450
74450
|
if (existsSync76(readme))
|
|
74451
74451
|
paths.push(readme);
|
|
74452
|
-
const stylesDir =
|
|
74452
|
+
const stylesDir = join160(repoPath, "assets", "writing-styles");
|
|
74453
74453
|
if (existsSync76(stylesDir)) {
|
|
74454
74454
|
try {
|
|
74455
74455
|
const files = readdirSync11(stylesDir);
|
|
74456
74456
|
for (const f3 of files) {
|
|
74457
|
-
paths.push(
|
|
74457
|
+
paths.push(join160(stylesDir, f3));
|
|
74458
74458
|
}
|
|
74459
74459
|
} catch {}
|
|
74460
74460
|
}
|
|
@@ -74463,11 +74463,11 @@ function getDocSourcePaths(repoPath) {
|
|
|
74463
74463
|
function getCacheFilePath(repoPath) {
|
|
74464
74464
|
const repoName = basename31(repoPath).replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
74465
74465
|
const pathHash = createHash9("sha256").update(repoPath).digest("hex").slice(0, 8);
|
|
74466
|
-
return
|
|
74466
|
+
return join160(CACHE_DIR, `${repoName}-${pathHash}-context-cache.json`);
|
|
74467
74467
|
}
|
|
74468
74468
|
var CACHE_DIR, CACHE_TTL_MS5;
|
|
74469
74469
|
var init_context_cache_manager = __esm(() => {
|
|
74470
|
-
CACHE_DIR =
|
|
74470
|
+
CACHE_DIR = join160(homedir54(), ".claudekit", "cache");
|
|
74471
74471
|
CACHE_TTL_MS5 = 24 * 60 * 60 * 1000;
|
|
74472
74472
|
});
|
|
74473
74473
|
|
|
@@ -74648,7 +74648,7 @@ function extractContentFromResponse(response) {
|
|
|
74648
74648
|
// src/commands/content/phases/docs-summarizer.ts
|
|
74649
74649
|
import { execSync as execSync7 } from "node:child_process";
|
|
74650
74650
|
import { existsSync as existsSync77, readFileSync as readFileSync19, readdirSync as readdirSync12 } from "node:fs";
|
|
74651
|
-
import { join as
|
|
74651
|
+
import { join as join161 } from "node:path";
|
|
74652
74652
|
async function summarizeProjectDocs(repoPath, contentLogger) {
|
|
74653
74653
|
const rawContent = collectRawDocs(repoPath);
|
|
74654
74654
|
if (rawContent.total.length < 200) {
|
|
@@ -74702,12 +74702,12 @@ function collectRawDocs(repoPath) {
|
|
|
74702
74702
|
return capped;
|
|
74703
74703
|
};
|
|
74704
74704
|
const docsContent = [];
|
|
74705
|
-
const docsDir =
|
|
74705
|
+
const docsDir = join161(repoPath, "docs");
|
|
74706
74706
|
if (existsSync77(docsDir)) {
|
|
74707
74707
|
try {
|
|
74708
74708
|
const files = readdirSync12(docsDir).filter((f3) => f3.endsWith(".md")).sort();
|
|
74709
74709
|
for (const f3 of files) {
|
|
74710
|
-
const content = readCapped(
|
|
74710
|
+
const content = readCapped(join161(docsDir, f3), 5000);
|
|
74711
74711
|
if (content) {
|
|
74712
74712
|
docsContent.push(`### ${f3}
|
|
74713
74713
|
${content}`);
|
|
@@ -74721,21 +74721,21 @@ ${content}`);
|
|
|
74721
74721
|
let brand = "";
|
|
74722
74722
|
const brandCandidates = ["docs/brand-guidelines.md", "docs/design-guidelines.md"];
|
|
74723
74723
|
for (const p of brandCandidates) {
|
|
74724
|
-
brand = readCapped(
|
|
74724
|
+
brand = readCapped(join161(repoPath, p), 3000);
|
|
74725
74725
|
if (brand)
|
|
74726
74726
|
break;
|
|
74727
74727
|
}
|
|
74728
74728
|
let styles3 = "";
|
|
74729
|
-
const stylesDir =
|
|
74729
|
+
const stylesDir = join161(repoPath, "assets", "writing-styles");
|
|
74730
74730
|
if (existsSync77(stylesDir)) {
|
|
74731
74731
|
try {
|
|
74732
74732
|
const files = readdirSync12(stylesDir).slice(0, 3);
|
|
74733
|
-
styles3 = files.map((f3) => readCapped(
|
|
74733
|
+
styles3 = files.map((f3) => readCapped(join161(stylesDir, f3), 1000)).filter(Boolean).join(`
|
|
74734
74734
|
|
|
74735
74735
|
`);
|
|
74736
74736
|
} catch {}
|
|
74737
74737
|
}
|
|
74738
|
-
const readme = readCapped(
|
|
74738
|
+
const readme = readCapped(join161(repoPath, "README.md"), 3000);
|
|
74739
74739
|
const total = [docs, brand, styles3, readme].join(`
|
|
74740
74740
|
`);
|
|
74741
74741
|
return { docs, brand, styles: styles3, readme, total };
|
|
@@ -74921,10 +74921,10 @@ IMPORTANT: Generate the image and output the path as JSON: {"imagePath": "/path/
|
|
|
74921
74921
|
// src/commands/content/phases/photo-generator.ts
|
|
74922
74922
|
import { execSync as execSync8 } from "node:child_process";
|
|
74923
74923
|
import { existsSync as existsSync78, mkdirSync as mkdirSync6, readdirSync as readdirSync13 } from "node:fs";
|
|
74924
|
-
import { homedir as
|
|
74925
|
-
import { join as
|
|
74924
|
+
import { homedir as homedir55 } from "node:os";
|
|
74925
|
+
import { join as join162 } from "node:path";
|
|
74926
74926
|
async function generatePhoto(_content, context, config, platform18, contentId, contentLogger) {
|
|
74927
|
-
const mediaDir =
|
|
74927
|
+
const mediaDir = join162(config.contentDir.replace(/^~/, homedir55()), "media", String(contentId));
|
|
74928
74928
|
if (!existsSync78(mediaDir)) {
|
|
74929
74929
|
mkdirSync6(mediaDir, { recursive: true });
|
|
74930
74930
|
}
|
|
@@ -74949,7 +74949,7 @@ async function generatePhoto(_content, context, config, platform18, contentId, c
|
|
|
74949
74949
|
const imageFile = files.find((f3) => /\.(png|jpg|jpeg|webp)$/i.test(f3));
|
|
74950
74950
|
if (imageFile) {
|
|
74951
74951
|
const ext2 = imageFile.split(".").pop() ?? "png";
|
|
74952
|
-
return { path:
|
|
74952
|
+
return { path: join162(mediaDir, imageFile), ...dimensions, format: ext2 };
|
|
74953
74953
|
}
|
|
74954
74954
|
contentLogger.warn(`Photo generation produced no image for content ${contentId}`);
|
|
74955
74955
|
return null;
|
|
@@ -75038,8 +75038,8 @@ var init_content_creator = __esm(() => {
|
|
|
75038
75038
|
|
|
75039
75039
|
// src/commands/content/phases/content-logger.ts
|
|
75040
75040
|
import { createWriteStream as createWriteStream4, existsSync as existsSync79, mkdirSync as mkdirSync7, statSync as statSync15 } from "node:fs";
|
|
75041
|
-
import { homedir as
|
|
75042
|
-
import { join as
|
|
75041
|
+
import { homedir as homedir56 } from "node:os";
|
|
75042
|
+
import { join as join163 } from "node:path";
|
|
75043
75043
|
|
|
75044
75044
|
class ContentLogger {
|
|
75045
75045
|
stream = null;
|
|
@@ -75047,7 +75047,7 @@ class ContentLogger {
|
|
|
75047
75047
|
logDir;
|
|
75048
75048
|
maxBytes;
|
|
75049
75049
|
constructor(maxBytes = 0) {
|
|
75050
|
-
this.logDir =
|
|
75050
|
+
this.logDir = join163(homedir56(), ".claudekit", "logs");
|
|
75051
75051
|
this.maxBytes = maxBytes;
|
|
75052
75052
|
}
|
|
75053
75053
|
init() {
|
|
@@ -75079,7 +75079,7 @@ class ContentLogger {
|
|
|
75079
75079
|
}
|
|
75080
75080
|
}
|
|
75081
75081
|
getLogPath() {
|
|
75082
|
-
return
|
|
75082
|
+
return join163(this.logDir, `content-${this.getDateStr()}.log`);
|
|
75083
75083
|
}
|
|
75084
75084
|
write(level, message) {
|
|
75085
75085
|
this.rotateIfNeeded();
|
|
@@ -75096,19 +75096,19 @@ class ContentLogger {
|
|
|
75096
75096
|
if (dateStr !== this.currentDate) {
|
|
75097
75097
|
this.close();
|
|
75098
75098
|
this.currentDate = dateStr;
|
|
75099
|
-
const logPath =
|
|
75099
|
+
const logPath = join163(this.logDir, `content-${dateStr}.log`);
|
|
75100
75100
|
this.stream = createWriteStream4(logPath, { flags: "a", mode: 384 });
|
|
75101
75101
|
return;
|
|
75102
75102
|
}
|
|
75103
75103
|
if (this.maxBytes > 0 && this.stream) {
|
|
75104
|
-
const logPath =
|
|
75104
|
+
const logPath = join163(this.logDir, `content-${this.currentDate}.log`);
|
|
75105
75105
|
try {
|
|
75106
|
-
const
|
|
75107
|
-
if (
|
|
75106
|
+
const stat26 = statSync15(logPath);
|
|
75107
|
+
if (stat26.size >= this.maxBytes) {
|
|
75108
75108
|
this.close();
|
|
75109
75109
|
const suffix = Date.now();
|
|
75110
|
-
const rotatedPath =
|
|
75111
|
-
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(() => {}));
|
|
75112
75112
|
this.stream = createWriteStream4(logPath, { flags: "w", mode: 384 });
|
|
75113
75113
|
}
|
|
75114
75114
|
} catch {}
|
|
@@ -75145,7 +75145,7 @@ var init_sqlite_client = () => {};
|
|
|
75145
75145
|
|
|
75146
75146
|
// src/commands/content/phases/db-manager.ts
|
|
75147
75147
|
import { existsSync as existsSync80, mkdirSync as mkdirSync8 } from "node:fs";
|
|
75148
|
-
import { dirname as
|
|
75148
|
+
import { dirname as dirname49 } from "node:path";
|
|
75149
75149
|
function initDatabase(dbPath) {
|
|
75150
75150
|
ensureParentDir(dbPath);
|
|
75151
75151
|
const db = openDatabase(dbPath);
|
|
@@ -75166,7 +75166,7 @@ function runRetentionCleanup(db, retentionDays = 90) {
|
|
|
75166
75166
|
db.prepare("DELETE FROM git_events WHERE processed = 1 AND created_at < ?").run(cutoff);
|
|
75167
75167
|
}
|
|
75168
75168
|
function ensureParentDir(dbPath) {
|
|
75169
|
-
const dir =
|
|
75169
|
+
const dir = dirname49(dbPath);
|
|
75170
75170
|
if (dir && !existsSync80(dir)) {
|
|
75171
75171
|
mkdirSync8(dir, { recursive: true });
|
|
75172
75172
|
}
|
|
@@ -75333,7 +75333,7 @@ function isNoiseCommit(title, author) {
|
|
|
75333
75333
|
// src/commands/content/phases/change-detector.ts
|
|
75334
75334
|
import { execSync as execSync10, spawnSync as spawnSync9 } from "node:child_process";
|
|
75335
75335
|
import { existsSync as existsSync81, readFileSync as readFileSync20, readdirSync as readdirSync14, statSync as statSync16 } from "node:fs";
|
|
75336
|
-
import { join as
|
|
75336
|
+
import { join as join164 } from "node:path";
|
|
75337
75337
|
function detectCommits(repo, since) {
|
|
75338
75338
|
try {
|
|
75339
75339
|
const fetchUrl = sshToHttps(repo.remoteUrl);
|
|
@@ -75442,7 +75442,7 @@ function detectTags(repo, since) {
|
|
|
75442
75442
|
}
|
|
75443
75443
|
}
|
|
75444
75444
|
function detectCompletedPlans(repo, since) {
|
|
75445
|
-
const plansDir =
|
|
75445
|
+
const plansDir = join164(repo.path, "plans");
|
|
75446
75446
|
if (!existsSync81(plansDir))
|
|
75447
75447
|
return [];
|
|
75448
75448
|
const sinceMs = new Date(since).getTime();
|
|
@@ -75452,12 +75452,12 @@ function detectCompletedPlans(repo, since) {
|
|
|
75452
75452
|
for (const entry of entries) {
|
|
75453
75453
|
if (!entry.isDirectory())
|
|
75454
75454
|
continue;
|
|
75455
|
-
const planFile =
|
|
75455
|
+
const planFile = join164(plansDir, entry.name, "plan.md");
|
|
75456
75456
|
if (!existsSync81(planFile))
|
|
75457
75457
|
continue;
|
|
75458
75458
|
try {
|
|
75459
|
-
const
|
|
75460
|
-
if (
|
|
75459
|
+
const stat26 = statSync16(planFile);
|
|
75460
|
+
if (stat26.mtimeMs < sinceMs)
|
|
75461
75461
|
continue;
|
|
75462
75462
|
const content = readFileSync20(planFile, "utf-8");
|
|
75463
75463
|
const frontmatterMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
@@ -75473,7 +75473,7 @@ function detectCompletedPlans(repo, since) {
|
|
|
75473
75473
|
title: `Plan completed: ${entry.name}`,
|
|
75474
75474
|
body: "",
|
|
75475
75475
|
author: "",
|
|
75476
|
-
createdAt: new Date(
|
|
75476
|
+
createdAt: new Date(stat26.mtimeMs).toISOString()
|
|
75477
75477
|
});
|
|
75478
75478
|
} catch {}
|
|
75479
75479
|
}
|
|
@@ -75530,7 +75530,7 @@ function classifyCommit(event) {
|
|
|
75530
75530
|
// src/commands/content/phases/repo-discoverer.ts
|
|
75531
75531
|
import { execSync as execSync11 } from "node:child_process";
|
|
75532
75532
|
import { readdirSync as readdirSync15 } from "node:fs";
|
|
75533
|
-
import { join as
|
|
75533
|
+
import { join as join165 } from "node:path";
|
|
75534
75534
|
function discoverRepos2(cwd2) {
|
|
75535
75535
|
const repos = [];
|
|
75536
75536
|
if (isGitRepoRoot(cwd2)) {
|
|
@@ -75543,7 +75543,7 @@ function discoverRepos2(cwd2) {
|
|
|
75543
75543
|
for (const entry of entries) {
|
|
75544
75544
|
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
75545
75545
|
continue;
|
|
75546
|
-
const dirPath =
|
|
75546
|
+
const dirPath = join165(cwd2, entry.name);
|
|
75547
75547
|
if (isGitRepoRoot(dirPath)) {
|
|
75548
75548
|
const info = getRepoInfo(dirPath);
|
|
75549
75549
|
if (info)
|
|
@@ -76210,10 +76210,10 @@ var init_types6 = __esm(() => {
|
|
|
76210
76210
|
});
|
|
76211
76211
|
|
|
76212
76212
|
// src/commands/content/phases/state-manager.ts
|
|
76213
|
-
import { readFile as readFile68, rename as
|
|
76214
|
-
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";
|
|
76215
76215
|
async function loadContentConfig(projectDir) {
|
|
76216
|
-
const configPath =
|
|
76216
|
+
const configPath = join166(projectDir, CK_CONFIG_FILE2);
|
|
76217
76217
|
try {
|
|
76218
76218
|
const raw2 = await readFile68(configPath, "utf-8");
|
|
76219
76219
|
const json = JSON.parse(raw2);
|
|
@@ -76223,13 +76223,13 @@ async function loadContentConfig(projectDir) {
|
|
|
76223
76223
|
}
|
|
76224
76224
|
}
|
|
76225
76225
|
async function saveContentConfig(projectDir, config) {
|
|
76226
|
-
const configPath =
|
|
76226
|
+
const configPath = join166(projectDir, CK_CONFIG_FILE2);
|
|
76227
76227
|
const json = await readJsonSafe(configPath);
|
|
76228
76228
|
json.content = { ...json.content, ...config };
|
|
76229
76229
|
await atomicWrite2(configPath, json);
|
|
76230
76230
|
}
|
|
76231
76231
|
async function loadContentState(projectDir) {
|
|
76232
|
-
const configPath =
|
|
76232
|
+
const configPath = join166(projectDir, CK_CONFIG_FILE2);
|
|
76233
76233
|
try {
|
|
76234
76234
|
const raw2 = await readFile68(configPath, "utf-8");
|
|
76235
76235
|
const json = JSON.parse(raw2);
|
|
@@ -76240,7 +76240,7 @@ async function loadContentState(projectDir) {
|
|
|
76240
76240
|
}
|
|
76241
76241
|
}
|
|
76242
76242
|
async function saveContentState(projectDir, state) {
|
|
76243
|
-
const configPath =
|
|
76243
|
+
const configPath = join166(projectDir, CK_CONFIG_FILE2);
|
|
76244
76244
|
const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().slice(0, 10);
|
|
76245
76245
|
for (const key of Object.keys(state.dailyPostCounts)) {
|
|
76246
76246
|
const dateStr = key.slice(-10);
|
|
@@ -76267,7 +76267,7 @@ async function readJsonSafe(filePath) {
|
|
|
76267
76267
|
async function atomicWrite2(filePath, data) {
|
|
76268
76268
|
const tmpPath = `${filePath}.tmp`;
|
|
76269
76269
|
await writeFile40(tmpPath, JSON.stringify(data, null, 2), "utf-8");
|
|
76270
|
-
await
|
|
76270
|
+
await rename16(tmpPath, filePath);
|
|
76271
76271
|
}
|
|
76272
76272
|
var CK_CONFIG_FILE2 = ".ck.json";
|
|
76273
76273
|
var init_state_manager = __esm(() => {
|
|
@@ -76522,7 +76522,7 @@ var init_platform_setup_x = __esm(() => {
|
|
|
76522
76522
|
|
|
76523
76523
|
// src/commands/content/phases/setup-wizard.ts
|
|
76524
76524
|
import { existsSync as existsSync82 } from "node:fs";
|
|
76525
|
-
import { join as
|
|
76525
|
+
import { join as join167 } from "node:path";
|
|
76526
76526
|
async function runSetupWizard2(cwd2, contentLogger) {
|
|
76527
76527
|
console.log();
|
|
76528
76528
|
oe(import_picocolors43.default.bgCyan(import_picocolors43.default.white(" CK Content — Multi-Channel Content Engine ")));
|
|
@@ -76590,8 +76590,8 @@ async function showRepoSummary(cwd2) {
|
|
|
76590
76590
|
function detectBrandAssets(cwd2, contentLogger) {
|
|
76591
76591
|
const repos = discoverRepos2(cwd2);
|
|
76592
76592
|
for (const repo of repos) {
|
|
76593
|
-
const hasGuidelines = existsSync82(
|
|
76594
|
-
const hasStyles = existsSync82(
|
|
76593
|
+
const hasGuidelines = existsSync82(join167(repo.path, "docs", "brand-guidelines.md"));
|
|
76594
|
+
const hasStyles = existsSync82(join167(repo.path, "assets", "writing-styles"));
|
|
76595
76595
|
if (!hasGuidelines) {
|
|
76596
76596
|
f2.warning(`${repo.name}: No docs/brand-guidelines.md — content will use generic tone.`);
|
|
76597
76597
|
contentLogger.warn(`${repo.name}: missing docs/brand-guidelines.md`);
|
|
@@ -76658,11 +76658,11 @@ var init_setup_wizard = __esm(() => {
|
|
|
76658
76658
|
|
|
76659
76659
|
// src/commands/content/content-review-commands.ts
|
|
76660
76660
|
import { existsSync as existsSync83 } from "node:fs";
|
|
76661
|
-
import { homedir as
|
|
76661
|
+
import { homedir as homedir57 } from "node:os";
|
|
76662
76662
|
async function queueContent() {
|
|
76663
76663
|
const cwd2 = process.cwd();
|
|
76664
76664
|
const config = await loadContentConfig(cwd2);
|
|
76665
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
76665
|
+
const dbPath = config.dbPath.replace(/^~/, homedir57());
|
|
76666
76666
|
if (!existsSync83(dbPath)) {
|
|
76667
76667
|
logger.info("No content database found. Run 'ck content setup' first.");
|
|
76668
76668
|
return;
|
|
@@ -76689,7 +76689,7 @@ async function queueContent() {
|
|
|
76689
76689
|
async function approveContentCmd(id) {
|
|
76690
76690
|
const cwd2 = process.cwd();
|
|
76691
76691
|
const config = await loadContentConfig(cwd2);
|
|
76692
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
76692
|
+
const dbPath = config.dbPath.replace(/^~/, homedir57());
|
|
76693
76693
|
const db = initDatabase(dbPath);
|
|
76694
76694
|
try {
|
|
76695
76695
|
approveContent(db, Number.parseInt(id, 10));
|
|
@@ -76701,7 +76701,7 @@ async function approveContentCmd(id) {
|
|
|
76701
76701
|
async function rejectContentCmd(id, reason) {
|
|
76702
76702
|
const cwd2 = process.cwd();
|
|
76703
76703
|
const config = await loadContentConfig(cwd2);
|
|
76704
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
76704
|
+
const dbPath = config.dbPath.replace(/^~/, homedir57());
|
|
76705
76705
|
const db = initDatabase(dbPath);
|
|
76706
76706
|
try {
|
|
76707
76707
|
rejectContent(db, Number.parseInt(id, 10), reason);
|
|
@@ -76732,10 +76732,10 @@ __export(exports_content_subcommands, {
|
|
|
76732
76732
|
approveContentCmd: () => approveContentCmd
|
|
76733
76733
|
});
|
|
76734
76734
|
import { existsSync as existsSync84, readFileSync as readFileSync21, unlinkSync as unlinkSync6 } from "node:fs";
|
|
76735
|
-
import { homedir as
|
|
76736
|
-
import { join as
|
|
76735
|
+
import { homedir as homedir58 } from "node:os";
|
|
76736
|
+
import { join as join168 } from "node:path";
|
|
76737
76737
|
function isDaemonRunning() {
|
|
76738
|
-
const lockFile =
|
|
76738
|
+
const lockFile = join168(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
76739
76739
|
if (!existsSync84(lockFile))
|
|
76740
76740
|
return { running: false, pid: null };
|
|
76741
76741
|
try {
|
|
@@ -76767,7 +76767,7 @@ async function startContent(options2) {
|
|
|
76767
76767
|
await contentCommand(options2);
|
|
76768
76768
|
}
|
|
76769
76769
|
async function stopContent() {
|
|
76770
|
-
const lockFile =
|
|
76770
|
+
const lockFile = join168(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
76771
76771
|
if (!existsSync84(lockFile)) {
|
|
76772
76772
|
logger.info("Content daemon is not running.");
|
|
76773
76773
|
return;
|
|
@@ -76806,9 +76806,9 @@ async function statusContent() {
|
|
|
76806
76806
|
} catch {}
|
|
76807
76807
|
}
|
|
76808
76808
|
async function logsContent(options2) {
|
|
76809
|
-
const logDir =
|
|
76809
|
+
const logDir = join168(homedir58(), ".claudekit", "logs");
|
|
76810
76810
|
const dateStr = new Date().toISOString().slice(0, 10).replace(/-/g, "");
|
|
76811
|
-
const logPath =
|
|
76811
|
+
const logPath = join168(logDir, `content-${dateStr}.log`);
|
|
76812
76812
|
if (!existsSync84(logPath)) {
|
|
76813
76813
|
logger.info("No content logs found for today.");
|
|
76814
76814
|
return;
|
|
@@ -76840,13 +76840,13 @@ var init_content_subcommands = __esm(() => {
|
|
|
76840
76840
|
init_setup_wizard();
|
|
76841
76841
|
init_state_manager();
|
|
76842
76842
|
init_content_review_commands();
|
|
76843
|
-
LOCK_DIR =
|
|
76843
|
+
LOCK_DIR = join168(homedir58(), ".claudekit", "locks");
|
|
76844
76844
|
});
|
|
76845
76845
|
|
|
76846
76846
|
// src/commands/content/content-command.ts
|
|
76847
76847
|
import { existsSync as existsSync85, mkdirSync as mkdirSync9, unlinkSync as unlinkSync7, writeFileSync as writeFileSync7 } from "node:fs";
|
|
76848
|
-
import { homedir as
|
|
76849
|
-
import { join as
|
|
76848
|
+
import { homedir as homedir59 } from "node:os";
|
|
76849
|
+
import { join as join169 } from "node:path";
|
|
76850
76850
|
async function contentCommand(options2) {
|
|
76851
76851
|
const cwd2 = process.cwd();
|
|
76852
76852
|
const contentLogger = new ContentLogger;
|
|
@@ -76878,7 +76878,7 @@ async function contentCommand(options2) {
|
|
|
76878
76878
|
if (!existsSync85(LOCK_DIR2))
|
|
76879
76879
|
mkdirSync9(LOCK_DIR2, { recursive: true });
|
|
76880
76880
|
writeFileSync7(LOCK_FILE, String(process.pid), "utf-8");
|
|
76881
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
76881
|
+
const dbPath = config.dbPath.replace(/^~/, homedir59());
|
|
76882
76882
|
const db = initDatabase(dbPath);
|
|
76883
76883
|
contentLogger.info(`Database initialised at ${dbPath}`);
|
|
76884
76884
|
const adapters = initializeAdapters(config);
|
|
@@ -77024,8 +77024,8 @@ var init_content_command = __esm(() => {
|
|
|
77024
77024
|
init_publisher();
|
|
77025
77025
|
init_review_manager();
|
|
77026
77026
|
init_state_manager();
|
|
77027
|
-
LOCK_DIR2 =
|
|
77028
|
-
LOCK_FILE =
|
|
77027
|
+
LOCK_DIR2 = join169(homedir59(), ".claudekit", "locks");
|
|
77028
|
+
LOCK_FILE = join169(LOCK_DIR2, "ck-content.lock");
|
|
77029
77029
|
});
|
|
77030
77030
|
|
|
77031
77031
|
// src/commands/content/index.ts
|
|
@@ -105688,8 +105688,8 @@ async function handlePostInstall(ctx) {
|
|
|
105688
105688
|
// src/commands/init/phases/selection-handler.ts
|
|
105689
105689
|
init_config_manager();
|
|
105690
105690
|
init_github_client();
|
|
105691
|
-
import { mkdir as
|
|
105692
|
-
import { join as
|
|
105691
|
+
import { mkdir as mkdir36 } from "node:fs/promises";
|
|
105692
|
+
import { join as join134, resolve as resolve43 } from "node:path";
|
|
105693
105693
|
|
|
105694
105694
|
// src/domains/github/kit-access-checker.ts
|
|
105695
105695
|
init_error2();
|
|
@@ -106105,12 +106105,134 @@ async function handleFreshInstallation(claudeDir3, prompts) {
|
|
|
106105
106105
|
}
|
|
106106
106106
|
}
|
|
106107
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
|
+
|
|
106108
106230
|
// src/commands/init/phases/selection-handler.ts
|
|
106109
106231
|
init_version_utils();
|
|
106110
106232
|
init_logger();
|
|
106111
106233
|
init_path_resolver();
|
|
106112
106234
|
init_types3();
|
|
106113
|
-
var
|
|
106235
|
+
var import_fs_extra36 = __toESM(require_lib(), 1);
|
|
106114
106236
|
|
|
106115
106237
|
// src/commands/init/types.ts
|
|
106116
106238
|
function isSyncContext(ctx) {
|
|
@@ -106302,7 +106424,20 @@ async function handleSelection(ctx) {
|
|
|
106302
106424
|
}
|
|
106303
106425
|
}
|
|
106304
106426
|
}
|
|
106305
|
-
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
|
+
}
|
|
106306
106441
|
logger.info(`Target directory: ${resolvedDir}`);
|
|
106307
106442
|
if (!ctx.options.global && PathResolver.isLocalSameAsGlobal(resolvedDir)) {
|
|
106308
106443
|
logger.warning("You're at HOME directory. Installing here modifies your GLOBAL ClaudeKit.");
|
|
@@ -106324,9 +106459,9 @@ async function handleSelection(ctx) {
|
|
|
106324
106459
|
return { ...ctx, cancelled: true };
|
|
106325
106460
|
}
|
|
106326
106461
|
}
|
|
106327
|
-
if (!await
|
|
106462
|
+
if (!await import_fs_extra36.pathExists(resolvedDir)) {
|
|
106328
106463
|
if (ctx.options.global) {
|
|
106329
|
-
await
|
|
106464
|
+
await mkdir36(resolvedDir, { recursive: true });
|
|
106330
106465
|
logger.info(`Created global directory: ${resolvedDir}`);
|
|
106331
106466
|
} else {
|
|
106332
106467
|
logger.error(`Directory does not exist: ${resolvedDir}`);
|
|
@@ -106336,7 +106471,7 @@ async function handleSelection(ctx) {
|
|
|
106336
106471
|
}
|
|
106337
106472
|
if (!ctx.options.fresh) {
|
|
106338
106473
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
106339
|
-
const claudeDir3 = prefix ?
|
|
106474
|
+
const claudeDir3 = prefix ? join134(resolvedDir, prefix) : resolvedDir;
|
|
106340
106475
|
try {
|
|
106341
106476
|
const existingMetadata = await readManifest(claudeDir3);
|
|
106342
106477
|
if (existingMetadata?.kits) {
|
|
@@ -106373,7 +106508,7 @@ async function handleSelection(ctx) {
|
|
|
106373
106508
|
}
|
|
106374
106509
|
if (ctx.options.fresh) {
|
|
106375
106510
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
106376
|
-
const claudeDir3 = prefix ?
|
|
106511
|
+
const claudeDir3 = prefix ? join134(resolvedDir, prefix) : resolvedDir;
|
|
106377
106512
|
const canProceed = await handleFreshInstallation(claudeDir3, ctx.prompts);
|
|
106378
106513
|
if (!canProceed) {
|
|
106379
106514
|
return { ...ctx, cancelled: true };
|
|
@@ -106393,7 +106528,7 @@ async function handleSelection(ctx) {
|
|
|
106393
106528
|
let currentVersion = null;
|
|
106394
106529
|
try {
|
|
106395
106530
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
106396
|
-
const claudeDir3 = prefix ?
|
|
106531
|
+
const claudeDir3 = prefix ? join134(resolvedDir, prefix) : resolvedDir;
|
|
106397
106532
|
const existingMetadata = await readManifest(claudeDir3);
|
|
106398
106533
|
currentVersion = existingMetadata?.kits?.[kitType]?.version || null;
|
|
106399
106534
|
if (currentVersion) {
|
|
@@ -106462,7 +106597,7 @@ async function handleSelection(ctx) {
|
|
|
106462
106597
|
if (ctx.options.yes && !ctx.options.fresh && !ctx.options.force && releaseTag && !isOfflineMode && !pendingKits?.length) {
|
|
106463
106598
|
try {
|
|
106464
106599
|
const prefix = PathResolver.getPathPrefix(ctx.options.global);
|
|
106465
|
-
const claudeDir3 = prefix ?
|
|
106600
|
+
const claudeDir3 = prefix ? join134(resolvedDir, prefix) : resolvedDir;
|
|
106466
106601
|
const existingMetadata = await readManifest(claudeDir3);
|
|
106467
106602
|
const installedKitVersion = existingMetadata?.kits?.[kitType]?.version;
|
|
106468
106603
|
if (installedKitVersion && versionsMatch(installedKitVersion, releaseTag)) {
|
|
@@ -106485,25 +106620,25 @@ async function handleSelection(ctx) {
|
|
|
106485
106620
|
};
|
|
106486
106621
|
}
|
|
106487
106622
|
// src/commands/init/phases/sync-handler.ts
|
|
106488
|
-
import { copyFile as copyFile8, mkdir as
|
|
106489
|
-
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";
|
|
106490
106625
|
init_logger();
|
|
106491
106626
|
init_path_resolver();
|
|
106492
|
-
var
|
|
106627
|
+
var import_fs_extra37 = __toESM(require_lib(), 1);
|
|
106493
106628
|
var import_picocolors26 = __toESM(require_picocolors(), 1);
|
|
106494
106629
|
async function handleSync(ctx) {
|
|
106495
106630
|
if (!ctx.options.sync) {
|
|
106496
106631
|
return ctx;
|
|
106497
106632
|
}
|
|
106498
|
-
const resolvedDir = ctx.options.global ? PathResolver.getGlobalKitDir() :
|
|
106499
|
-
const claudeDir3 = ctx.options.global ? resolvedDir :
|
|
106500
|
-
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)) {
|
|
106501
106636
|
logger.error("Cannot sync: no .claude directory found");
|
|
106502
106637
|
ctx.prompts.note("Run 'ck init' without --sync to install first.", "No Installation Found");
|
|
106503
106638
|
return { ...ctx, cancelled: true };
|
|
106504
106639
|
}
|
|
106505
|
-
const metadataPath =
|
|
106506
|
-
if (!await
|
|
106640
|
+
const metadataPath = join135(claudeDir3, "metadata.json");
|
|
106641
|
+
if (!await import_fs_extra37.pathExists(metadataPath)) {
|
|
106507
106642
|
logger.error("Cannot sync: no metadata.json found");
|
|
106508
106643
|
ctx.prompts.note(`Your installation may be from an older version.
|
|
106509
106644
|
Run 'ck init' to update.`, "Legacy Installation");
|
|
@@ -106602,10 +106737,10 @@ function getLockTimeout() {
|
|
|
106602
106737
|
var STALE_LOCK_THRESHOLD_MS = 5 * 60 * 1000;
|
|
106603
106738
|
async function acquireSyncLock(global3) {
|
|
106604
106739
|
const cacheDir = PathResolver.getCacheDir(global3);
|
|
106605
|
-
const lockPath =
|
|
106740
|
+
const lockPath = join135(cacheDir, ".sync-lock");
|
|
106606
106741
|
const startTime = Date.now();
|
|
106607
106742
|
const lockTimeout = getLockTimeout();
|
|
106608
|
-
await
|
|
106743
|
+
await mkdir37(dirname40(lockPath), { recursive: true });
|
|
106609
106744
|
while (Date.now() - startTime < lockTimeout) {
|
|
106610
106745
|
try {
|
|
106611
106746
|
const handle = await open5(lockPath, "wx");
|
|
@@ -106616,7 +106751,7 @@ async function acquireSyncLock(global3) {
|
|
|
106616
106751
|
} catch (err) {
|
|
106617
106752
|
if (err.code === "EEXIST") {
|
|
106618
106753
|
try {
|
|
106619
|
-
const lockStat = await
|
|
106754
|
+
const lockStat = await stat23(lockPath);
|
|
106620
106755
|
const lockAge = Math.abs(Date.now() - lockStat.mtimeMs);
|
|
106621
106756
|
if (lockAge > STALE_LOCK_THRESHOLD_MS) {
|
|
106622
106757
|
logger.warning(`Removing stale sync lock (age: ${Math.round(lockAge / 1000)}s)`);
|
|
@@ -106648,11 +106783,11 @@ async function executeSyncMerge(ctx) {
|
|
|
106648
106783
|
const releaseLock = await acquireSyncLock(ctx.options.global);
|
|
106649
106784
|
try {
|
|
106650
106785
|
const trackedFiles = ctx.syncTrackedFiles;
|
|
106651
|
-
const upstreamDir = ctx.options.global ?
|
|
106786
|
+
const upstreamDir = ctx.options.global ? join135(ctx.extractDir, ".claude") : ctx.extractDir;
|
|
106652
106787
|
let deletions = [];
|
|
106653
106788
|
try {
|
|
106654
|
-
const sourceMetadataPath =
|
|
106655
|
-
if (await
|
|
106789
|
+
const sourceMetadataPath = join135(upstreamDir, "metadata.json");
|
|
106790
|
+
if (await import_fs_extra37.pathExists(sourceMetadataPath)) {
|
|
106656
106791
|
const content = await readFile58(sourceMetadataPath, "utf-8");
|
|
106657
106792
|
const sourceMetadata = JSON.parse(content);
|
|
106658
106793
|
deletions = sourceMetadata.deletions || [];
|
|
@@ -106683,9 +106818,9 @@ async function executeSyncMerge(ctx) {
|
|
|
106683
106818
|
try {
|
|
106684
106819
|
const sourcePath = await validateSyncPath(upstreamDir, file.path);
|
|
106685
106820
|
const targetPath = await validateSyncPath(ctx.claudeDir, file.path);
|
|
106686
|
-
const targetDir =
|
|
106821
|
+
const targetDir = join135(targetPath, "..");
|
|
106687
106822
|
try {
|
|
106688
|
-
await
|
|
106823
|
+
await mkdir37(targetDir, { recursive: true });
|
|
106689
106824
|
} catch (mkdirError) {
|
|
106690
106825
|
const errCode = mkdirError.code;
|
|
106691
106826
|
if (errCode === "ENOSPC") {
|
|
@@ -106765,7 +106900,7 @@ async function executeSyncMerge(ctx) {
|
|
|
106765
106900
|
const tempPath = `${currentPath}.tmp.${Date.now()}`;
|
|
106766
106901
|
try {
|
|
106767
106902
|
await writeFile32(tempPath, result.result, "utf-8");
|
|
106768
|
-
await
|
|
106903
|
+
await rename11(tempPath, currentPath);
|
|
106769
106904
|
} catch (atomicError) {
|
|
106770
106905
|
await unlink12(tempPath).catch(() => {});
|
|
106771
106906
|
throw atomicError;
|
|
@@ -106848,14 +106983,14 @@ function displaySyncPlan(plan) {
|
|
|
106848
106983
|
console.log(import_picocolors26.default.dim("─".repeat(40)));
|
|
106849
106984
|
}
|
|
106850
106985
|
async function createBackup(claudeDir3, files, backupDir) {
|
|
106851
|
-
await
|
|
106986
|
+
await mkdir37(backupDir, { recursive: true });
|
|
106852
106987
|
for (const file of files) {
|
|
106853
106988
|
try {
|
|
106854
106989
|
const sourcePath = await validateSyncPath(claudeDir3, file.path);
|
|
106855
|
-
if (await
|
|
106990
|
+
if (await import_fs_extra37.pathExists(sourcePath)) {
|
|
106856
106991
|
const targetPath = await validateSyncPath(backupDir, file.path);
|
|
106857
|
-
const targetDir =
|
|
106858
|
-
await
|
|
106992
|
+
const targetDir = join135(targetPath, "..");
|
|
106993
|
+
await mkdir37(targetDir, { recursive: true });
|
|
106859
106994
|
await copyFile8(sourcePath, targetPath);
|
|
106860
106995
|
}
|
|
106861
106996
|
} catch (error) {
|
|
@@ -106869,7 +107004,7 @@ async function createBackup(claudeDir3, files, backupDir) {
|
|
|
106869
107004
|
}
|
|
106870
107005
|
// src/commands/init/phases/transform-handler.ts
|
|
106871
107006
|
init_config_manager();
|
|
106872
|
-
import { join as
|
|
107007
|
+
import { join as join139 } from "node:path";
|
|
106873
107008
|
|
|
106874
107009
|
// src/services/transformers/folder-path-transformer.ts
|
|
106875
107010
|
init_logger();
|
|
@@ -106878,40 +107013,40 @@ init_types3();
|
|
|
106878
107013
|
// src/services/transformers/folder-transform/folder-renamer.ts
|
|
106879
107014
|
init_logger();
|
|
106880
107015
|
init_types3();
|
|
106881
|
-
var
|
|
106882
|
-
import { rename as
|
|
106883
|
-
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";
|
|
106884
107019
|
async function collectDirsToRename(extractDir, folders) {
|
|
106885
107020
|
const dirsToRename = [];
|
|
106886
107021
|
if (folders.docs !== DEFAULT_FOLDERS.docs) {
|
|
106887
|
-
const docsPath =
|
|
106888
|
-
if (await
|
|
107022
|
+
const docsPath = join136(extractDir, DEFAULT_FOLDERS.docs);
|
|
107023
|
+
if (await import_fs_extra38.pathExists(docsPath)) {
|
|
106889
107024
|
dirsToRename.push({
|
|
106890
107025
|
from: docsPath,
|
|
106891
|
-
to:
|
|
107026
|
+
to: join136(extractDir, folders.docs)
|
|
106892
107027
|
});
|
|
106893
107028
|
}
|
|
106894
|
-
const claudeDocsPath =
|
|
106895
|
-
if (await
|
|
107029
|
+
const claudeDocsPath = join136(extractDir, ".claude", DEFAULT_FOLDERS.docs);
|
|
107030
|
+
if (await import_fs_extra38.pathExists(claudeDocsPath)) {
|
|
106896
107031
|
dirsToRename.push({
|
|
106897
107032
|
from: claudeDocsPath,
|
|
106898
|
-
to:
|
|
107033
|
+
to: join136(extractDir, ".claude", folders.docs)
|
|
106899
107034
|
});
|
|
106900
107035
|
}
|
|
106901
107036
|
}
|
|
106902
107037
|
if (folders.plans !== DEFAULT_FOLDERS.plans) {
|
|
106903
|
-
const plansPath =
|
|
106904
|
-
if (await
|
|
107038
|
+
const plansPath = join136(extractDir, DEFAULT_FOLDERS.plans);
|
|
107039
|
+
if (await import_fs_extra38.pathExists(plansPath)) {
|
|
106905
107040
|
dirsToRename.push({
|
|
106906
107041
|
from: plansPath,
|
|
106907
|
-
to:
|
|
107042
|
+
to: join136(extractDir, folders.plans)
|
|
106908
107043
|
});
|
|
106909
107044
|
}
|
|
106910
|
-
const claudePlansPath =
|
|
106911
|
-
if (await
|
|
107045
|
+
const claudePlansPath = join136(extractDir, ".claude", DEFAULT_FOLDERS.plans);
|
|
107046
|
+
if (await import_fs_extra38.pathExists(claudePlansPath)) {
|
|
106912
107047
|
dirsToRename.push({
|
|
106913
107048
|
from: claudePlansPath,
|
|
106914
|
-
to:
|
|
107049
|
+
to: join136(extractDir, ".claude", folders.plans)
|
|
106915
107050
|
});
|
|
106916
107051
|
}
|
|
106917
107052
|
}
|
|
@@ -106919,12 +107054,12 @@ async function collectDirsToRename(extractDir, folders) {
|
|
|
106919
107054
|
}
|
|
106920
107055
|
async function moveAcrossDevices(src, dest) {
|
|
106921
107056
|
try {
|
|
106922
|
-
await
|
|
107057
|
+
await rename12(src, dest);
|
|
106923
107058
|
} catch (e2) {
|
|
106924
107059
|
if (e2.code === "EXDEV") {
|
|
106925
107060
|
logger.debug(`Cross-device move detected, using copy+delete: ${src} -> ${dest}`);
|
|
106926
|
-
await
|
|
106927
|
-
await
|
|
107061
|
+
await import_fs_extra38.copy(src, dest, { overwrite: true });
|
|
107062
|
+
await rm16(src, { recursive: true, force: true });
|
|
106928
107063
|
} else {
|
|
106929
107064
|
throw e2;
|
|
106930
107065
|
}
|
|
@@ -106951,8 +107086,8 @@ async function renameFolders(dirsToRename, extractDir, options2) {
|
|
|
106951
107086
|
// src/services/transformers/folder-transform/path-replacer.ts
|
|
106952
107087
|
init_logger();
|
|
106953
107088
|
init_types3();
|
|
106954
|
-
import { readFile as readFile59, readdir as
|
|
106955
|
-
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";
|
|
106956
107091
|
var TRANSFORMABLE_FILE_PATTERNS = [
|
|
106957
107092
|
".md",
|
|
106958
107093
|
".txt",
|
|
@@ -107003,9 +107138,9 @@ function compileReplacements(replacements) {
|
|
|
107003
107138
|
async function transformFileContents(dir, compiledReplacements, options2) {
|
|
107004
107139
|
let filesChanged = 0;
|
|
107005
107140
|
let replacementsCount = 0;
|
|
107006
|
-
const entries = await
|
|
107141
|
+
const entries = await readdir42(dir, { withFileTypes: true });
|
|
107007
107142
|
for (const entry of entries) {
|
|
107008
|
-
const fullPath =
|
|
107143
|
+
const fullPath = join137(dir, entry.name);
|
|
107009
107144
|
if (entry.isDirectory()) {
|
|
107010
107145
|
if (entry.name === "node_modules" || entry.name === ".git") {
|
|
107011
107146
|
continue;
|
|
@@ -107140,9 +107275,9 @@ async function transformFolderPaths(extractDir, folders, options2 = {}) {
|
|
|
107140
107275
|
|
|
107141
107276
|
// src/services/transformers/global-path-transformer.ts
|
|
107142
107277
|
init_logger();
|
|
107143
|
-
import { readFile as readFile60, readdir as
|
|
107144
|
-
import { homedir as
|
|
107145
|
-
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";
|
|
107146
107281
|
var IS_WINDOWS3 = platform15() === "win32";
|
|
107147
107282
|
var HOME_PREFIX = "$HOME";
|
|
107148
107283
|
function getHomeDirPrefix() {
|
|
@@ -107152,7 +107287,7 @@ function normalizeInstallPath(path16) {
|
|
|
107152
107287
|
return path16.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
107153
107288
|
}
|
|
107154
107289
|
function getDefaultGlobalClaudeDir() {
|
|
107155
|
-
return normalizeInstallPath(
|
|
107290
|
+
return normalizeInstallPath(join138(homedir47(), ".claude"));
|
|
107156
107291
|
}
|
|
107157
107292
|
function getCustomGlobalClaudeDir(targetClaudeDir) {
|
|
107158
107293
|
if (!targetClaudeDir)
|
|
@@ -107281,9 +107416,9 @@ async function transformPathsForGlobalInstall(directory, options2 = {}) {
|
|
|
107281
107416
|
let filesSkipped = 0;
|
|
107282
107417
|
const skippedFiles = [];
|
|
107283
107418
|
async function processDirectory2(dir) {
|
|
107284
|
-
const entries = await
|
|
107419
|
+
const entries = await readdir43(dir, { withFileTypes: true });
|
|
107285
107420
|
for (const entry of entries) {
|
|
107286
|
-
const fullPath =
|
|
107421
|
+
const fullPath = join138(dir, entry.name);
|
|
107287
107422
|
if (entry.isDirectory()) {
|
|
107288
107423
|
if (entry.name === "node_modules" || entry.name.startsWith(".") && entry.name !== ".claude") {
|
|
107289
107424
|
continue;
|
|
@@ -107362,7 +107497,7 @@ async function handleTransforms(ctx) {
|
|
|
107362
107497
|
logger.debug(ctx.options.global ? "Saved folder configuration to ~/.claude/.ck.json" : "Saved folder configuration to .claude/.ck.json");
|
|
107363
107498
|
}
|
|
107364
107499
|
}
|
|
107365
|
-
const claudeDir3 = ctx.options.global ? ctx.resolvedDir :
|
|
107500
|
+
const claudeDir3 = ctx.options.global ? ctx.resolvedDir : join139(ctx.resolvedDir, ".claude");
|
|
107366
107501
|
return {
|
|
107367
107502
|
...ctx,
|
|
107368
107503
|
foldersConfig,
|
|
@@ -107552,15 +107687,15 @@ async function initCommand(options2) {
|
|
|
107552
107687
|
init_dist2();
|
|
107553
107688
|
var import_picocolors30 = __toESM(require_picocolors(), 1);
|
|
107554
107689
|
import { existsSync as existsSync65 } from "node:fs";
|
|
107555
|
-
import { readFile as readFile64, rm as
|
|
107556
|
-
import { homedir as
|
|
107557
|
-
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";
|
|
107558
107693
|
init_logger();
|
|
107559
107694
|
|
|
107560
107695
|
// src/ui/ck-cli-design/tokens.ts
|
|
107561
107696
|
var import_picocolors27 = __toESM(require_picocolors(), 1);
|
|
107562
|
-
import { homedir as
|
|
107563
|
-
import { resolve as
|
|
107697
|
+
import { homedir as homedir48, platform as platform16 } from "node:os";
|
|
107698
|
+
import { resolve as resolve46, win32 as win322 } from "node:path";
|
|
107564
107699
|
var PANEL_MIN_WIDTH = 60;
|
|
107565
107700
|
var PANEL_MAX_WIDTH = 72;
|
|
107566
107701
|
var DEFAULT_WIDTH = PANEL_MAX_WIDTH;
|
|
@@ -107717,7 +107852,7 @@ function wrapText(value, width) {
|
|
|
107717
107852
|
}
|
|
107718
107853
|
function formatDisplayPath(value) {
|
|
107719
107854
|
const normalized = value.replace(/\\/g, "/");
|
|
107720
|
-
const home6 =
|
|
107855
|
+
const home6 = homedir48().replace(/\\/g, "/");
|
|
107721
107856
|
if (normalized === home6)
|
|
107722
107857
|
return "~";
|
|
107723
107858
|
if (normalized.startsWith(`${home6}/`)) {
|
|
@@ -107730,7 +107865,7 @@ function formatCdHint(value, currentPlatform = platform16()) {
|
|
|
107730
107865
|
const absolutePath2 = win322.resolve(value);
|
|
107731
107866
|
return `cd /d "${absolutePath2}"`;
|
|
107732
107867
|
}
|
|
107733
|
-
const absolutePath =
|
|
107868
|
+
const absolutePath = resolve46(value);
|
|
107734
107869
|
const displayPath = formatDisplayPath(absolutePath);
|
|
107735
107870
|
if (displayPath.includes(" ")) {
|
|
107736
107871
|
return `cd "${displayPath}"`;
|
|
@@ -108029,15 +108164,15 @@ init_model_taxonomy();
|
|
|
108029
108164
|
init_logger();
|
|
108030
108165
|
init_dist2();
|
|
108031
108166
|
init_model_taxonomy();
|
|
108032
|
-
import { mkdir as
|
|
108033
|
-
import { homedir as
|
|
108034
|
-
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";
|
|
108035
108170
|
|
|
108036
108171
|
// src/commands/portable/models-dev-cache.ts
|
|
108037
108172
|
init_logger();
|
|
108038
|
-
import { mkdir as
|
|
108039
|
-
import { homedir as
|
|
108040
|
-
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";
|
|
108041
108176
|
|
|
108042
108177
|
class ModelsDevUnavailableError extends Error {
|
|
108043
108178
|
constructor(message, cause) {
|
|
@@ -108049,13 +108184,13 @@ var MODELS_DEV_URL = "https://models.dev/api.json";
|
|
|
108049
108184
|
var CACHE_TTL_MS3 = 24 * 60 * 60 * 1000;
|
|
108050
108185
|
var FETCH_TIMEOUT_MS = 1e4;
|
|
108051
108186
|
function defaultCacheDir() {
|
|
108052
|
-
return
|
|
108187
|
+
return join140(homedir49(), ".config", "claudekit", "cache");
|
|
108053
108188
|
}
|
|
108054
108189
|
function cacheFilePath(cacheDir) {
|
|
108055
|
-
return
|
|
108190
|
+
return join140(cacheDir, "models-dev.json");
|
|
108056
108191
|
}
|
|
108057
108192
|
function tmpFilePath(cacheDir) {
|
|
108058
|
-
return
|
|
108193
|
+
return join140(cacheDir, "models-dev.json.tmp");
|
|
108059
108194
|
}
|
|
108060
108195
|
async function readCacheEntry(cacheDir) {
|
|
108061
108196
|
const filePath = cacheFilePath(cacheDir);
|
|
@@ -108075,11 +108210,11 @@ function isCacheFresh(entry) {
|
|
|
108075
108210
|
return Date.now() - fetchedAt < CACHE_TTL_MS3;
|
|
108076
108211
|
}
|
|
108077
108212
|
async function writeCacheEntry(cacheDir, entry) {
|
|
108078
|
-
await
|
|
108213
|
+
await mkdir38(cacheDir, { recursive: true });
|
|
108079
108214
|
const tmp = tmpFilePath(cacheDir);
|
|
108080
108215
|
const dest = cacheFilePath(cacheDir);
|
|
108081
108216
|
await writeFile35(tmp, JSON.stringify(entry), "utf-8");
|
|
108082
|
-
await
|
|
108217
|
+
await rename13(tmp, dest);
|
|
108083
108218
|
}
|
|
108084
108219
|
async function fetchCatalog(fetcher) {
|
|
108085
108220
|
const controller = new AbortController;
|
|
@@ -108129,15 +108264,15 @@ async function getModelsDevCatalog(opts = {}) {
|
|
|
108129
108264
|
// src/commands/portable/opencode-model-discovery.ts
|
|
108130
108265
|
init_logger();
|
|
108131
108266
|
import { readFile as readFile62 } from "node:fs/promises";
|
|
108132
|
-
import { homedir as
|
|
108133
|
-
import { join as
|
|
108267
|
+
import { homedir as homedir50, platform as platform17 } from "node:os";
|
|
108268
|
+
import { join as join141 } from "node:path";
|
|
108134
108269
|
function resolveOpenCodeAuthPath(homeDir) {
|
|
108135
108270
|
if (platform17() === "win32") {
|
|
108136
|
-
const dataRoot2 = process.env.LOCALAPPDATA ??
|
|
108137
|
-
return
|
|
108271
|
+
const dataRoot2 = process.env.LOCALAPPDATA ?? join141(homeDir, "AppData", "Local");
|
|
108272
|
+
return join141(dataRoot2, "opencode", "auth.json");
|
|
108138
108273
|
}
|
|
108139
|
-
const dataRoot = process.env.XDG_DATA_HOME ??
|
|
108140
|
-
return
|
|
108274
|
+
const dataRoot = process.env.XDG_DATA_HOME ?? join141(homeDir, ".local", "share");
|
|
108275
|
+
return join141(dataRoot, "opencode", "auth.json");
|
|
108141
108276
|
}
|
|
108142
108277
|
async function readAuthedProviders(homeDir) {
|
|
108143
108278
|
const authPath = resolveOpenCodeAuthPath(homeDir);
|
|
@@ -108175,7 +108310,7 @@ function pickGenericModel(models) {
|
|
|
108175
108310
|
return sorted[0] ?? null;
|
|
108176
108311
|
}
|
|
108177
108312
|
async function resolveOpenCodeDefaultModel(opts = {}) {
|
|
108178
|
-
const home6 = opts.homeDir ??
|
|
108313
|
+
const home6 = opts.homeDir ?? homedir50();
|
|
108179
108314
|
const authedProviders = await readAuthedProviders(home6);
|
|
108180
108315
|
if (authedProviders.length === 0) {
|
|
108181
108316
|
return { ok: false, reason: "no-auth", authedProviders: [] };
|
|
@@ -108239,9 +108374,9 @@ function messageForReason(reason) {
|
|
|
108239
108374
|
}
|
|
108240
108375
|
function getOpenCodeConfigPath(options2) {
|
|
108241
108376
|
if (options2.global) {
|
|
108242
|
-
return
|
|
108377
|
+
return join142(options2.homeDir ?? homedir51(), ".config", "opencode", "opencode.json");
|
|
108243
108378
|
}
|
|
108244
|
-
return
|
|
108379
|
+
return join142(options2.cwd ?? process.cwd(), "opencode.json");
|
|
108245
108380
|
}
|
|
108246
108381
|
function makeCatalogOpts(options2) {
|
|
108247
108382
|
return {
|
|
@@ -108384,7 +108519,7 @@ async function ensureOpenCodeModel(options2) {
|
|
|
108384
108519
|
}
|
|
108385
108520
|
const chosenModel2 = response2.action === "custom" ? response2.value : suggestion2.model;
|
|
108386
108521
|
const next2 = { ...existing, model: chosenModel2 };
|
|
108387
|
-
await
|
|
108522
|
+
await mkdir39(dirname41(configPath), { recursive: true });
|
|
108388
108523
|
await writeFile36(configPath, `${JSON.stringify(next2, null, 2)}
|
|
108389
108524
|
`, "utf-8");
|
|
108390
108525
|
return { path: configPath, action: "added", model: chosenModel2, reason: suggestion2.reason };
|
|
@@ -108395,7 +108530,7 @@ async function ensureOpenCodeModel(options2) {
|
|
|
108395
108530
|
throw new OpenCodeAuthRequiredError(suggestion.failure);
|
|
108396
108531
|
}
|
|
108397
108532
|
const next2 = { ...existing ?? {}, model: suggestion.model };
|
|
108398
|
-
await
|
|
108533
|
+
await mkdir39(dirname41(configPath), { recursive: true });
|
|
108399
108534
|
await writeFile36(configPath, `${JSON.stringify(next2, null, 2)}
|
|
108400
108535
|
`, "utf-8");
|
|
108401
108536
|
return {
|
|
@@ -108417,7 +108552,7 @@ async function ensureOpenCodeModel(options2) {
|
|
|
108417
108552
|
}
|
|
108418
108553
|
const chosenModel = response.action === "custom" ? response.value : suggestion.ok ? suggestion.model : "";
|
|
108419
108554
|
const next = { ...existing ?? {}, model: chosenModel };
|
|
108420
|
-
await
|
|
108555
|
+
await mkdir39(dirname41(configPath), { recursive: true });
|
|
108421
108556
|
await writeFile36(configPath, `${JSON.stringify(next, null, 2)}
|
|
108422
108557
|
`, "utf-8");
|
|
108423
108558
|
return {
|
|
@@ -108430,7 +108565,7 @@ async function ensureOpenCodeModel(options2) {
|
|
|
108430
108565
|
|
|
108431
108566
|
// src/commands/portable/plan-display.ts
|
|
108432
108567
|
var import_picocolors28 = __toESM(require_picocolors(), 1);
|
|
108433
|
-
import { basename as basename26, dirname as
|
|
108568
|
+
import { basename as basename26, dirname as dirname42, extname as extname7 } from "node:path";
|
|
108434
108569
|
var DEFAULT_MAX_PLAN_GROUP_ITEMS = 20;
|
|
108435
108570
|
var TYPE_ORDER = [
|
|
108436
108571
|
"agent",
|
|
@@ -108656,21 +108791,21 @@ function collectPlannedWhereLines(plan) {
|
|
|
108656
108791
|
return destinations.map((destination) => `${formatDisplayPath(destination)} -> ${formatCdHint(resolveCdTarget(destination))}`);
|
|
108657
108792
|
}
|
|
108658
108793
|
function resolveCdTarget(destination) {
|
|
108659
|
-
return extname7(destination).length > 0 ?
|
|
108794
|
+
return extname7(destination).length > 0 ? dirname42(destination) : destination;
|
|
108660
108795
|
}
|
|
108661
108796
|
function normalizeWhereDestination(path16, portableType) {
|
|
108662
108797
|
if (portableType === "agent" || portableType === "command" || portableType === "skill") {
|
|
108663
|
-
return
|
|
108798
|
+
return dirname42(path16);
|
|
108664
108799
|
}
|
|
108665
108800
|
if (portableType === "hooks") {
|
|
108666
|
-
return
|
|
108801
|
+
return dirname42(path16);
|
|
108667
108802
|
}
|
|
108668
108803
|
if (portableType === "rules") {
|
|
108669
108804
|
const fileName = basename26(path16).toLowerCase();
|
|
108670
108805
|
if (fileName === "agents.md" || fileName === "gemini.md" || fileName === ".goosehints" || fileName === "custom_modes.yaml" || fileName === "custom_modes.yml") {
|
|
108671
108806
|
return path16;
|
|
108672
108807
|
}
|
|
108673
|
-
return
|
|
108808
|
+
return dirname42(path16);
|
|
108674
108809
|
}
|
|
108675
108810
|
return path16;
|
|
108676
108811
|
}
|
|
@@ -109179,10 +109314,10 @@ function shouldExecuteAction2(action) {
|
|
|
109179
109314
|
}
|
|
109180
109315
|
async function executeDeleteAction(action, options2) {
|
|
109181
109316
|
const preservePaths = options2?.preservePaths ?? new Set;
|
|
109182
|
-
const shouldPreserveTarget = action.targetPath.length > 0 && preservePaths.has(
|
|
109317
|
+
const shouldPreserveTarget = action.targetPath.length > 0 && preservePaths.has(resolve47(action.targetPath));
|
|
109183
109318
|
try {
|
|
109184
109319
|
if (!shouldPreserveTarget && action.targetPath && existsSync65(action.targetPath)) {
|
|
109185
|
-
await
|
|
109320
|
+
await rm17(action.targetPath, { recursive: true, force: true });
|
|
109186
109321
|
}
|
|
109187
109322
|
await removePortableInstallation(action.item, action.type, action.provider, action.global, action.targetPath ? { path: action.targetPath } : undefined);
|
|
109188
109323
|
return {
|
|
@@ -109212,7 +109347,7 @@ async function executeDeleteAction(action, options2) {
|
|
|
109212
109347
|
async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
109213
109348
|
if (!skillSourcePath)
|
|
109214
109349
|
return;
|
|
109215
|
-
const sourceMetadataPath =
|
|
109350
|
+
const sourceMetadataPath = join143(resolve47(skillSourcePath, ".."), "metadata.json");
|
|
109216
109351
|
if (!existsSync65(sourceMetadataPath))
|
|
109217
109352
|
return;
|
|
109218
109353
|
let sourceMetadata;
|
|
@@ -109225,7 +109360,7 @@ async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
|
109225
109360
|
}
|
|
109226
109361
|
if (!sourceMetadata.deletions || sourceMetadata.deletions.length === 0)
|
|
109227
109362
|
return;
|
|
109228
|
-
const claudeDir3 = installGlobally ?
|
|
109363
|
+
const claudeDir3 = installGlobally ? join143(homedir52(), ".claude") : join143(process.cwd(), ".claude");
|
|
109229
109364
|
if (!existsSync65(claudeDir3))
|
|
109230
109365
|
return;
|
|
109231
109366
|
try {
|
|
@@ -109348,8 +109483,8 @@ async function migrateCommand(options2) {
|
|
|
109348
109483
|
let requestedGlobal = options2.global ?? false;
|
|
109349
109484
|
let installGlobally = requestedGlobal;
|
|
109350
109485
|
if (options2.global === undefined && !options2.yes) {
|
|
109351
|
-
const projectTarget =
|
|
109352
|
-
const globalTarget =
|
|
109486
|
+
const projectTarget = join143(process.cwd(), ".claude");
|
|
109487
|
+
const globalTarget = join143(homedir52(), ".claude");
|
|
109353
109488
|
const scopeChoice = await ie({
|
|
109354
109489
|
message: "Installation scope",
|
|
109355
109490
|
options: [
|
|
@@ -109413,7 +109548,7 @@ async function migrateCommand(options2) {
|
|
|
109413
109548
|
}).join(`
|
|
109414
109549
|
`));
|
|
109415
109550
|
if (sourceGlobalOnly) {
|
|
109416
|
-
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"))}`));
|
|
109417
109552
|
} else {
|
|
109418
109553
|
f2.info(import_picocolors30.default.dim(` CWD: ${process.cwd()}`));
|
|
109419
109554
|
}
|
|
@@ -109619,7 +109754,7 @@ async function migrateCommand(options2) {
|
|
|
109619
109754
|
const recordSuccessfulWrites = (task, taskResults) => {
|
|
109620
109755
|
for (const result of taskResults.filter((entry) => entry.success && !entry.skipped)) {
|
|
109621
109756
|
if (result.path.length > 0) {
|
|
109622
|
-
writtenPaths.add(
|
|
109757
|
+
writtenPaths.add(resolve47(result.path));
|
|
109623
109758
|
}
|
|
109624
109759
|
if (task.type === "hooks") {
|
|
109625
109760
|
const existing = successfulHookFiles.get(task.provider) ?? {
|
|
@@ -109630,7 +109765,7 @@ async function migrateCommand(options2) {
|
|
|
109630
109765
|
successfulHookFiles.set(task.provider, existing);
|
|
109631
109766
|
if (result.path.length > 0) {
|
|
109632
109767
|
const absExisting = successfulHookAbsPaths.get(task.provider) ?? [];
|
|
109633
|
-
absExisting.push(
|
|
109768
|
+
absExisting.push(resolve47(result.path));
|
|
109634
109769
|
successfulHookAbsPaths.set(task.provider, absExisting);
|
|
109635
109770
|
}
|
|
109636
109771
|
}
|
|
@@ -109772,7 +109907,7 @@ async function migrateCommand(options2) {
|
|
|
109772
109907
|
}
|
|
109773
109908
|
}
|
|
109774
109909
|
try {
|
|
109775
|
-
const kitRoot = (agentSource ?
|
|
109910
|
+
const kitRoot = (agentSource ? resolve47(agentSource, "..") : null) ?? (commandSource ? resolve47(commandSource, "..") : null) ?? (skillSource ? resolve47(skillSource, "..") : null) ?? null;
|
|
109776
109911
|
const manifest = kitRoot ? await loadPortableManifest(kitRoot) : null;
|
|
109777
109912
|
if (manifest?.cliVersion) {
|
|
109778
109913
|
await updateAppliedManifestVersion(manifest.cliVersion);
|
|
@@ -109825,9 +109960,9 @@ async function rollbackResults(results) {
|
|
|
109825
109960
|
try {
|
|
109826
109961
|
if (result.overwritten)
|
|
109827
109962
|
continue;
|
|
109828
|
-
const
|
|
109829
|
-
if (
|
|
109830
|
-
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 });
|
|
109831
109966
|
} else {
|
|
109832
109967
|
await unlink13(result.path);
|
|
109833
109968
|
}
|
|
@@ -109951,7 +110086,7 @@ function buildDryRunFallbackResults(skills, selectedProviders, installGlobally,
|
|
|
109951
110086
|
results.push({
|
|
109952
110087
|
itemName: skill.name,
|
|
109953
110088
|
operation: "apply",
|
|
109954
|
-
path:
|
|
110089
|
+
path: join143(basePath, skill.name),
|
|
109955
110090
|
portableType: "skill",
|
|
109956
110091
|
provider,
|
|
109957
110092
|
providerDisplayName: providers[provider].displayName,
|
|
@@ -109969,11 +110104,11 @@ var import_picocolors31 = __toESM(require_picocolors(), 1);
|
|
|
109969
110104
|
|
|
109970
110105
|
// src/commands/new/phases/directory-setup.ts
|
|
109971
110106
|
init_config_manager();
|
|
109972
|
-
import { resolve as
|
|
110107
|
+
import { resolve as resolve48 } from "node:path";
|
|
109973
110108
|
init_logger();
|
|
109974
110109
|
init_path_resolver();
|
|
109975
110110
|
init_types3();
|
|
109976
|
-
var
|
|
110111
|
+
var import_fs_extra39 = __toESM(require_lib(), 1);
|
|
109977
110112
|
async function directorySetup(validOptions, prompts) {
|
|
109978
110113
|
const isNonInteractive2 = !process.stdin.isTTY || process.env.CI === "true" || process.env.NON_INTERACTIVE === "true";
|
|
109979
110114
|
const config = await ConfigManager.get();
|
|
@@ -110054,7 +110189,7 @@ async function directorySetup(validOptions, prompts) {
|
|
|
110054
110189
|
targetDir = await prompts.getDirectory(targetDir);
|
|
110055
110190
|
}
|
|
110056
110191
|
}
|
|
110057
|
-
const resolvedDir =
|
|
110192
|
+
const resolvedDir = resolve48(targetDir);
|
|
110058
110193
|
logger.info(`Target directory: ${resolvedDir}`);
|
|
110059
110194
|
if (PathResolver.isLocalSameAsGlobal(resolvedDir)) {
|
|
110060
110195
|
logger.warning("You're creating a project at HOME directory.");
|
|
@@ -110072,8 +110207,8 @@ async function directorySetup(validOptions, prompts) {
|
|
|
110072
110207
|
return null;
|
|
110073
110208
|
}
|
|
110074
110209
|
}
|
|
110075
|
-
if (await
|
|
110076
|
-
const files = await
|
|
110210
|
+
if (await import_fs_extra39.pathExists(resolvedDir)) {
|
|
110211
|
+
const files = await import_fs_extra39.readdir(resolvedDir);
|
|
110077
110212
|
const isEmpty = files.length === 0;
|
|
110078
110213
|
if (!isEmpty) {
|
|
110079
110214
|
if (isNonInteractive2) {
|
|
@@ -110111,7 +110246,7 @@ async function handleDirectorySetup(ctx) {
|
|
|
110111
110246
|
// src/commands/new/phases/project-creation.ts
|
|
110112
110247
|
init_config_manager();
|
|
110113
110248
|
init_github_client();
|
|
110114
|
-
import { join as
|
|
110249
|
+
import { join as join144 } from "node:path";
|
|
110115
110250
|
init_logger();
|
|
110116
110251
|
init_output_manager();
|
|
110117
110252
|
init_types3();
|
|
@@ -110237,7 +110372,7 @@ async function projectCreation(kit, resolvedDir, validOptions, isNonInteractive2
|
|
|
110237
110372
|
output.section("Installing");
|
|
110238
110373
|
logger.verbose("Installation target", { directory: resolvedDir });
|
|
110239
110374
|
const merger = new FileMerger;
|
|
110240
|
-
const claudeDir3 =
|
|
110375
|
+
const claudeDir3 = join144(resolvedDir, ".claude");
|
|
110241
110376
|
merger.setMultiKitContext(claudeDir3, kit);
|
|
110242
110377
|
if (validOptions.exclude && validOptions.exclude.length > 0) {
|
|
110243
110378
|
merger.addIgnorePatterns(validOptions.exclude);
|
|
@@ -110284,7 +110419,7 @@ async function handleProjectCreation(ctx) {
|
|
|
110284
110419
|
}
|
|
110285
110420
|
// src/commands/new/phases/post-setup.ts
|
|
110286
110421
|
init_projects_registry();
|
|
110287
|
-
import { join as
|
|
110422
|
+
import { join as join145 } from "node:path";
|
|
110288
110423
|
init_package_installer();
|
|
110289
110424
|
init_logger();
|
|
110290
110425
|
init_path_resolver();
|
|
@@ -110316,9 +110451,9 @@ async function postSetup(resolvedDir, validOptions, isNonInteractive2, prompts)
|
|
|
110316
110451
|
withSudo: validOptions.withSudo
|
|
110317
110452
|
});
|
|
110318
110453
|
}
|
|
110319
|
-
const claudeDir3 =
|
|
110454
|
+
const claudeDir3 = join145(resolvedDir, ".claude");
|
|
110320
110455
|
await promptSetupWizardIfNeeded({
|
|
110321
|
-
envPath:
|
|
110456
|
+
envPath: join145(claudeDir3, ".env"),
|
|
110322
110457
|
claudeDir: claudeDir3,
|
|
110323
110458
|
isGlobal: false,
|
|
110324
110459
|
isNonInteractive: isNonInteractive2,
|
|
@@ -110388,7 +110523,7 @@ Please use only one download method.`);
|
|
|
110388
110523
|
// src/commands/plan/plan-command.ts
|
|
110389
110524
|
init_output_manager();
|
|
110390
110525
|
import { existsSync as existsSync68, statSync as statSync12 } from "node:fs";
|
|
110391
|
-
import { dirname as
|
|
110526
|
+
import { dirname as dirname46, isAbsolute as isAbsolute11, join as join148, parse as parse7, resolve as resolve52 } from "node:path";
|
|
110392
110527
|
|
|
110393
110528
|
// src/commands/plan/plan-read-handlers.ts
|
|
110394
110529
|
init_config();
|
|
@@ -110398,18 +110533,18 @@ init_logger();
|
|
|
110398
110533
|
init_output_manager();
|
|
110399
110534
|
var import_picocolors32 = __toESM(require_picocolors(), 1);
|
|
110400
110535
|
import { existsSync as existsSync67, statSync as statSync11 } from "node:fs";
|
|
110401
|
-
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";
|
|
110402
110537
|
|
|
110403
110538
|
// src/commands/plan/plan-dependencies.ts
|
|
110404
110539
|
init_config();
|
|
110405
110540
|
init_plan_parser();
|
|
110406
110541
|
init_plans_registry();
|
|
110407
110542
|
import { existsSync as existsSync66 } from "node:fs";
|
|
110408
|
-
import { dirname as
|
|
110543
|
+
import { dirname as dirname43, join as join146 } from "node:path";
|
|
110409
110544
|
async function resolvePlanDependencies(references, currentPlanFile, options2 = {}) {
|
|
110410
110545
|
if (references.length === 0)
|
|
110411
110546
|
return [];
|
|
110412
|
-
const currentPlanDir =
|
|
110547
|
+
const currentPlanDir = dirname43(currentPlanFile);
|
|
110413
110548
|
const projectRoot = findProjectRoot(currentPlanDir);
|
|
110414
110549
|
const config = options2.preloadedConfig ?? (await CkConfigManager.loadFull(projectRoot)).config;
|
|
110415
110550
|
const defaultScope = inferPlanScopeForDir(currentPlanDir, config);
|
|
@@ -110425,7 +110560,7 @@ async function resolvePlanDependencies(references, currentPlanFile, options2 = {
|
|
|
110425
110560
|
};
|
|
110426
110561
|
}
|
|
110427
110562
|
const scopeRoot = resolvePlanDirForScope(scope, projectRoot, config);
|
|
110428
|
-
const planFile =
|
|
110563
|
+
const planFile = join146(scopeRoot, planId, "plan.md");
|
|
110429
110564
|
const isSelfReference = planFile === currentPlanFile;
|
|
110430
110565
|
if (!existsSync66(planFile)) {
|
|
110431
110566
|
return {
|
|
@@ -110456,14 +110591,14 @@ init_config();
|
|
|
110456
110591
|
init_plan_parser();
|
|
110457
110592
|
init_plan_scope();
|
|
110458
110593
|
init_plans_registry();
|
|
110459
|
-
import { isAbsolute as isAbsolute10, resolve as
|
|
110594
|
+
import { isAbsolute as isAbsolute10, resolve as resolve49 } from "node:path";
|
|
110460
110595
|
async function getGlobalPlansDirFromCwd() {
|
|
110461
110596
|
const projectRoot = findProjectRoot(process.cwd());
|
|
110462
110597
|
const { config } = await CkConfigManager.loadFull(projectRoot);
|
|
110463
110598
|
return resolveGlobalPlansDir(config);
|
|
110464
110599
|
}
|
|
110465
110600
|
function resolveTargetFromBase(target, baseDir) {
|
|
110466
|
-
const resolvedTarget = isAbsolute10(target) ?
|
|
110601
|
+
const resolvedTarget = isAbsolute10(target) ? resolve49(target) : resolve49(baseDir, target);
|
|
110467
110602
|
return isWithinDir(resolvedTarget, baseDir) ? resolvedTarget : null;
|
|
110468
110603
|
}
|
|
110469
110604
|
|
|
@@ -110496,7 +110631,7 @@ async function handleParse(target, options2) {
|
|
|
110496
110631
|
console.log(JSON.stringify({ file: relative30(process.cwd(), planFile), frontmatter, phases }, null, 2));
|
|
110497
110632
|
return;
|
|
110498
110633
|
}
|
|
110499
|
-
const title = typeof frontmatter.title === "string" ? frontmatter.title : basename28(
|
|
110634
|
+
const title = typeof frontmatter.title === "string" ? frontmatter.title : basename28(dirname44(planFile));
|
|
110500
110635
|
console.log();
|
|
110501
110636
|
console.log(import_picocolors32.default.bold(` Plan: ${title}`));
|
|
110502
110637
|
console.log(` File: ${planFile}`);
|
|
@@ -110566,8 +110701,8 @@ async function handleStatus(target, options2) {
|
|
|
110566
110701
|
return;
|
|
110567
110702
|
}
|
|
110568
110703
|
const effectiveTarget = !resolvedTarget && globalBaseDir ? globalBaseDir : resolvedTarget;
|
|
110569
|
-
const t = effectiveTarget ?
|
|
110570
|
-
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;
|
|
110571
110706
|
if (plansDir) {
|
|
110572
110707
|
const planFiles = scanPlanDir(plansDir);
|
|
110573
110708
|
if (planFiles.length === 0) {
|
|
@@ -110607,7 +110742,7 @@ async function handleStatus(target, options2) {
|
|
|
110607
110742
|
const blockedBy2 = await resolvePlanDependencies(s.blockedBy, pf, { preloadedConfig });
|
|
110608
110743
|
const blocks2 = await resolvePlanDependencies(s.blocks, pf, { preloadedConfig });
|
|
110609
110744
|
const bar = progressBar(s.completed, s.totalPhases);
|
|
110610
|
-
const title2 = s.title ?? basename28(
|
|
110745
|
+
const title2 = s.title ?? basename28(dirname44(pf));
|
|
110611
110746
|
console.log(` ${import_picocolors32.default.bold(title2)}`);
|
|
110612
110747
|
console.log(` ${bar}`);
|
|
110613
110748
|
if (s.inProgress > 0)
|
|
@@ -110626,7 +110761,7 @@ async function handleStatus(target, options2) {
|
|
|
110626
110761
|
}
|
|
110627
110762
|
console.log();
|
|
110628
110763
|
} catch {
|
|
110629
|
-
console.log(` [X] Failed to read: ${basename28(
|
|
110764
|
+
console.log(` [X] Failed to read: ${basename28(dirname44(pf))}`);
|
|
110630
110765
|
console.log();
|
|
110631
110766
|
}
|
|
110632
110767
|
}
|
|
@@ -110653,7 +110788,7 @@ async function handleStatus(target, options2) {
|
|
|
110653
110788
|
console.log(JSON.stringify({ ...summary, dependencyStatus: { blockedBy, blocks } }, null, 2));
|
|
110654
110789
|
return;
|
|
110655
110790
|
}
|
|
110656
|
-
const title = summary.title ?? basename28(
|
|
110791
|
+
const title = summary.title ?? basename28(dirname44(planFile));
|
|
110657
110792
|
console.log();
|
|
110658
110793
|
console.log(import_picocolors32.default.bold(` ${title}`));
|
|
110659
110794
|
if (summary.status)
|
|
@@ -110716,7 +110851,7 @@ async function handleKanban(target, options2) {
|
|
|
110716
110851
|
process.exitCode = 1;
|
|
110717
110852
|
return;
|
|
110718
110853
|
}
|
|
110719
|
-
const route = `/plans?dir=${encodeURIComponent(
|
|
110854
|
+
const route = `/plans?dir=${encodeURIComponent(dirname44(dirname44(planFile)))}&view=kanban`;
|
|
110720
110855
|
const url = `http://localhost:${server.port}${route}`;
|
|
110721
110856
|
console.log();
|
|
110722
110857
|
console.log(import_picocolors32.default.bold(" ClaudeKit Dashboard — Plans"));
|
|
@@ -110751,7 +110886,7 @@ init_plan_parser();
|
|
|
110751
110886
|
init_plans_registry();
|
|
110752
110887
|
init_output_manager();
|
|
110753
110888
|
var import_picocolors33 = __toESM(require_picocolors(), 1);
|
|
110754
|
-
import { basename as basename29, dirname as
|
|
110889
|
+
import { basename as basename29, dirname as dirname45, relative as relative31, resolve as resolve51 } from "node:path";
|
|
110755
110890
|
async function handleCreate(target, options2) {
|
|
110756
110891
|
if (!options2.title) {
|
|
110757
110892
|
output.error("[X] --title is required for create");
|
|
@@ -110783,13 +110918,13 @@ async function handleCreate(target, options2) {
|
|
|
110783
110918
|
return;
|
|
110784
110919
|
}
|
|
110785
110920
|
const globalBaseDir = options2.global ? await getGlobalPlansDirFromCwd() : undefined;
|
|
110786
|
-
const resolvedDir = globalBaseDir ? resolveTargetFromBase(dir, globalBaseDir) :
|
|
110921
|
+
const resolvedDir = globalBaseDir ? resolveTargetFromBase(dir, globalBaseDir) : resolve51(dir);
|
|
110787
110922
|
if (globalBaseDir && !resolvedDir) {
|
|
110788
110923
|
output.error("[X] Target directory must stay within the configured global plans root");
|
|
110789
110924
|
process.exitCode = 1;
|
|
110790
110925
|
return;
|
|
110791
110926
|
}
|
|
110792
|
-
const safeResolvedDir = resolvedDir ??
|
|
110927
|
+
const safeResolvedDir = resolvedDir ?? resolve51(dir);
|
|
110793
110928
|
const result = scaffoldPlan({
|
|
110794
110929
|
title: options2.title,
|
|
110795
110930
|
phases: phaseNames.map((name2) => ({ name: name2 })),
|
|
@@ -110851,7 +110986,7 @@ async function handleCheck(target, options2) {
|
|
|
110851
110986
|
process.exitCode = 1;
|
|
110852
110987
|
return;
|
|
110853
110988
|
}
|
|
110854
|
-
const planDir =
|
|
110989
|
+
const planDir = dirname45(planFile);
|
|
110855
110990
|
let planStatus = "pending";
|
|
110856
110991
|
try {
|
|
110857
110992
|
const projectRoot = findProjectRoot(planDir);
|
|
@@ -110900,7 +111035,7 @@ async function handleUncheck(target, options2) {
|
|
|
110900
111035
|
process.exitCode = 1;
|
|
110901
111036
|
return;
|
|
110902
111037
|
}
|
|
110903
|
-
const planDir =
|
|
111038
|
+
const planDir = dirname45(planFile);
|
|
110904
111039
|
try {
|
|
110905
111040
|
const projectRoot = findProjectRoot(planDir);
|
|
110906
111041
|
const summary = buildPlanSummary(planFile);
|
|
@@ -110939,7 +111074,7 @@ async function handleAddPhase(target, options2) {
|
|
|
110939
111074
|
try {
|
|
110940
111075
|
const result = addPhase(planFile, target, options2.after);
|
|
110941
111076
|
try {
|
|
110942
|
-
const planDir =
|
|
111077
|
+
const planDir = dirname45(planFile);
|
|
110943
111078
|
const projectRoot = findProjectRoot(planDir);
|
|
110944
111079
|
updateRegistryAddPhase({
|
|
110945
111080
|
planDir,
|
|
@@ -110965,24 +111100,24 @@ async function handleAddPhase(target, options2) {
|
|
|
110965
111100
|
// src/commands/plan/plan-command.ts
|
|
110966
111101
|
function resolveTargetPath(target, baseDir) {
|
|
110967
111102
|
if (!baseDir) {
|
|
110968
|
-
return
|
|
111103
|
+
return resolve52(target);
|
|
110969
111104
|
}
|
|
110970
111105
|
if (isAbsolute11(target)) {
|
|
110971
|
-
return
|
|
111106
|
+
return resolve52(target);
|
|
110972
111107
|
}
|
|
110973
|
-
const cwdCandidate =
|
|
111108
|
+
const cwdCandidate = resolve52(target);
|
|
110974
111109
|
if (existsSync68(cwdCandidate)) {
|
|
110975
111110
|
return cwdCandidate;
|
|
110976
111111
|
}
|
|
110977
|
-
return
|
|
111112
|
+
return resolve52(baseDir, target);
|
|
110978
111113
|
}
|
|
110979
111114
|
function resolvePlanFile(target, baseDir) {
|
|
110980
|
-
const t = target ? resolveTargetPath(target, baseDir) : baseDir ?
|
|
111115
|
+
const t = target ? resolveTargetPath(target, baseDir) : baseDir ? resolve52(baseDir) : process.cwd();
|
|
110981
111116
|
if (existsSync68(t)) {
|
|
110982
|
-
const
|
|
110983
|
-
if (
|
|
111117
|
+
const stat24 = statSync12(t);
|
|
111118
|
+
if (stat24.isFile())
|
|
110984
111119
|
return t;
|
|
110985
|
-
const candidate =
|
|
111120
|
+
const candidate = join148(t, "plan.md");
|
|
110986
111121
|
if (existsSync68(candidate))
|
|
110987
111122
|
return candidate;
|
|
110988
111123
|
}
|
|
@@ -110990,10 +111125,10 @@ function resolvePlanFile(target, baseDir) {
|
|
|
110990
111125
|
let dir = process.cwd();
|
|
110991
111126
|
const root = parse7(dir).root;
|
|
110992
111127
|
while (dir !== root) {
|
|
110993
|
-
const candidate =
|
|
111128
|
+
const candidate = join148(dir, "plan.md");
|
|
110994
111129
|
if (existsSync68(candidate))
|
|
110995
111130
|
return candidate;
|
|
110996
|
-
dir =
|
|
111131
|
+
dir = dirname46(dir);
|
|
110997
111132
|
}
|
|
110998
111133
|
}
|
|
110999
111134
|
return null;
|
|
@@ -111041,7 +111176,7 @@ async function planCommand(action, target, options2) {
|
|
|
111041
111176
|
let resolvedTarget = target;
|
|
111042
111177
|
if (resolvedAction && !knownActions.has(resolvedAction)) {
|
|
111043
111178
|
const looksLikePath = resolvedAction.includes("/") || resolvedAction.includes("\\") || resolvedAction.endsWith(".md") || resolvedAction === "." || resolvedAction === "..";
|
|
111044
|
-
const existsOnDisk = !looksLikePath && existsSync68(
|
|
111179
|
+
const existsOnDisk = !looksLikePath && existsSync68(resolve52(resolvedAction));
|
|
111045
111180
|
if (looksLikePath || existsOnDisk) {
|
|
111046
111181
|
resolvedTarget = resolvedAction;
|
|
111047
111182
|
resolvedAction = undefined;
|
|
@@ -111084,11 +111219,11 @@ init_logger();
|
|
|
111084
111219
|
init_safe_prompts();
|
|
111085
111220
|
var import_picocolors34 = __toESM(require_picocolors(), 1);
|
|
111086
111221
|
import { existsSync as existsSync69 } from "node:fs";
|
|
111087
|
-
import { resolve as
|
|
111222
|
+
import { resolve as resolve53 } from "node:path";
|
|
111088
111223
|
async function handleAdd(projectPath, options2) {
|
|
111089
111224
|
logger.debug(`Adding project: ${projectPath}, options: ${JSON.stringify(options2)}`);
|
|
111090
111225
|
intro("Add Project");
|
|
111091
|
-
const absolutePath =
|
|
111226
|
+
const absolutePath = resolve53(projectPath);
|
|
111092
111227
|
if (!existsSync69(absolutePath)) {
|
|
111093
111228
|
log.error(`Path does not exist: ${absolutePath}`);
|
|
111094
111229
|
process.exitCode = 1;
|
|
@@ -111509,10 +111644,10 @@ init_agents();
|
|
|
111509
111644
|
var import_gray_matter12 = __toESM(require_gray_matter(), 1);
|
|
111510
111645
|
var import_picocolors37 = __toESM(require_picocolors(), 1);
|
|
111511
111646
|
import { readFile as readFile65 } from "node:fs/promises";
|
|
111512
|
-
import { join as
|
|
111647
|
+
import { join as join150 } from "node:path";
|
|
111513
111648
|
|
|
111514
111649
|
// src/commands/skills/installed-skills-inventory.ts
|
|
111515
|
-
import { join as
|
|
111650
|
+
import { join as join149, resolve as resolve54 } from "node:path";
|
|
111516
111651
|
init_path_resolver();
|
|
111517
111652
|
var SCOPE_SORT_ORDER = {
|
|
111518
111653
|
project: 0,
|
|
@@ -111520,12 +111655,12 @@ var SCOPE_SORT_ORDER = {
|
|
|
111520
111655
|
};
|
|
111521
111656
|
async function getActiveClaudeSkillInstallations(options2 = {}) {
|
|
111522
111657
|
const projectDir = options2.projectDir ?? process.cwd();
|
|
111523
|
-
const globalDir =
|
|
111524
|
-
const projectClaudeDir =
|
|
111658
|
+
const globalDir = resolve54(options2.globalDir ?? PathResolver.getGlobalKitDir());
|
|
111659
|
+
const projectClaudeDir = resolve54(projectDir, ".claude");
|
|
111525
111660
|
const projectScopeAliasesGlobal = projectClaudeDir === globalDir;
|
|
111526
111661
|
const [projectSkills, globalSkills] = await Promise.all([
|
|
111527
|
-
projectScopeAliasesGlobal ? Promise.resolve([]) : scanSkills2(
|
|
111528
|
-
scanSkills2(
|
|
111662
|
+
projectScopeAliasesGlobal ? Promise.resolve([]) : scanSkills2(join149(projectClaudeDir, "skills")),
|
|
111663
|
+
scanSkills2(join149(globalDir, "skills"))
|
|
111529
111664
|
]);
|
|
111530
111665
|
const projectIds = new Set(projectSkills.map((skill) => skill.id));
|
|
111531
111666
|
const globalIds = new Set(globalSkills.map((skill) => skill.id));
|
|
@@ -111685,7 +111820,7 @@ async function handleValidate2(sourcePath) {
|
|
|
111685
111820
|
spinner.stop(`Checked ${skills.length} skill(s)`);
|
|
111686
111821
|
let hasIssues = false;
|
|
111687
111822
|
for (const skill of skills) {
|
|
111688
|
-
const skillMdPath =
|
|
111823
|
+
const skillMdPath = join150(skill.path, "SKILL.md");
|
|
111689
111824
|
try {
|
|
111690
111825
|
const content = await readFile65(skillMdPath, "utf-8");
|
|
111691
111826
|
const { data } = import_gray_matter12.default(content, {
|
|
@@ -112229,7 +112364,7 @@ var import_picocolors39 = __toESM(require_picocolors(), 1);
|
|
|
112229
112364
|
// src/commands/uninstall/installation-detector.ts
|
|
112230
112365
|
init_claudekit_scanner();
|
|
112231
112366
|
init_path_resolver();
|
|
112232
|
-
var
|
|
112367
|
+
var import_fs_extra40 = __toESM(require_lib(), 1);
|
|
112233
112368
|
function hasClaudeKitComponents(components) {
|
|
112234
112369
|
return components.agents > 0 || components.commands > 0 || components.rules > 0 || components.skills > 0;
|
|
112235
112370
|
}
|
|
@@ -112244,7 +112379,7 @@ async function detectInstallations() {
|
|
|
112244
112379
|
installations.push({
|
|
112245
112380
|
type: "local",
|
|
112246
112381
|
path: setup.project.path,
|
|
112247
|
-
exists: await
|
|
112382
|
+
exists: await import_fs_extra40.pathExists(setup.project.path),
|
|
112248
112383
|
hasMetadata,
|
|
112249
112384
|
components: setup.project.components
|
|
112250
112385
|
});
|
|
@@ -112257,7 +112392,7 @@ async function detectInstallations() {
|
|
|
112257
112392
|
installations.push({
|
|
112258
112393
|
type: "global",
|
|
112259
112394
|
path: setup.global.path,
|
|
112260
|
-
exists: await
|
|
112395
|
+
exists: await import_fs_extra40.pathExists(setup.global.path),
|
|
112261
112396
|
hasMetadata,
|
|
112262
112397
|
components: setup.global.components
|
|
112263
112398
|
});
|
|
@@ -112268,19 +112403,19 @@ async function detectInstallations() {
|
|
|
112268
112403
|
|
|
112269
112404
|
// src/commands/uninstall/removal-handler.ts
|
|
112270
112405
|
import { readdirSync as readdirSync10, rmSync as rmSync5 } from "node:fs";
|
|
112271
|
-
import { basename as basename30, join as
|
|
112406
|
+
import { basename as basename30, join as join152, resolve as resolve55, sep as sep13 } from "node:path";
|
|
112272
112407
|
init_logger();
|
|
112273
112408
|
init_safe_prompts();
|
|
112274
112409
|
init_safe_spinner();
|
|
112275
|
-
var
|
|
112410
|
+
var import_fs_extra42 = __toESM(require_lib(), 1);
|
|
112276
112411
|
|
|
112277
112412
|
// src/commands/uninstall/analysis-handler.ts
|
|
112278
112413
|
init_metadata_migration();
|
|
112279
112414
|
import { readdirSync as readdirSync9, rmSync as rmSync4 } from "node:fs";
|
|
112280
|
-
import { dirname as
|
|
112415
|
+
import { dirname as dirname47, join as join151 } from "node:path";
|
|
112281
112416
|
init_logger();
|
|
112282
112417
|
init_safe_prompts();
|
|
112283
|
-
var
|
|
112418
|
+
var import_fs_extra41 = __toESM(require_lib(), 1);
|
|
112284
112419
|
var import_picocolors38 = __toESM(require_picocolors(), 1);
|
|
112285
112420
|
function normalizeTrackedPath(relativePath) {
|
|
112286
112421
|
return relativePath.replace(/\\/g, "/");
|
|
@@ -112299,7 +112434,7 @@ function classifyFileByOwnership(ownership, forceOverwrite, deleteReason) {
|
|
|
112299
112434
|
}
|
|
112300
112435
|
async function cleanupEmptyDirectories3(filePath, installationRoot) {
|
|
112301
112436
|
let cleaned = 0;
|
|
112302
|
-
let currentDir =
|
|
112437
|
+
let currentDir = dirname47(filePath);
|
|
112303
112438
|
while (currentDir !== installationRoot && currentDir.startsWith(installationRoot)) {
|
|
112304
112439
|
try {
|
|
112305
112440
|
const entries = readdirSync9(currentDir);
|
|
@@ -112307,7 +112442,7 @@ async function cleanupEmptyDirectories3(filePath, installationRoot) {
|
|
|
112307
112442
|
rmSync4(currentDir, { recursive: true });
|
|
112308
112443
|
cleaned++;
|
|
112309
112444
|
logger.debug(`Removed empty directory: ${currentDir}`);
|
|
112310
|
-
currentDir =
|
|
112445
|
+
currentDir = dirname47(currentDir);
|
|
112311
112446
|
} else {
|
|
112312
112447
|
break;
|
|
112313
112448
|
}
|
|
@@ -112337,7 +112472,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
112337
112472
|
const remainingFiles = metadata.kits?.[remainingKit]?.files || [];
|
|
112338
112473
|
for (const file of remainingFiles) {
|
|
112339
112474
|
const relativePath = normalizeTrackedPath(file.path);
|
|
112340
|
-
if (await
|
|
112475
|
+
if (await import_fs_extra41.pathExists(join151(installation.path, relativePath))) {
|
|
112341
112476
|
result.retainedManifestPaths.push(relativePath);
|
|
112342
112477
|
}
|
|
112343
112478
|
}
|
|
@@ -112345,7 +112480,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
112345
112480
|
const kitFiles = metadata.kits[kit].files || [];
|
|
112346
112481
|
for (const trackedFile of kitFiles) {
|
|
112347
112482
|
const relativePath = normalizeTrackedPath(trackedFile.path);
|
|
112348
|
-
const filePath =
|
|
112483
|
+
const filePath = join151(installation.path, relativePath);
|
|
112349
112484
|
if (preservedPaths.has(relativePath)) {
|
|
112350
112485
|
result.toPreserve.push({ path: relativePath, reason: "shared with other kit" });
|
|
112351
112486
|
continue;
|
|
@@ -112378,7 +112513,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
112378
112513
|
}
|
|
112379
112514
|
for (const trackedFile of allTrackedFiles) {
|
|
112380
112515
|
const relativePath = normalizeTrackedPath(trackedFile.path);
|
|
112381
|
-
const filePath =
|
|
112516
|
+
const filePath = join151(installation.path, relativePath);
|
|
112382
112517
|
const ownershipResult = await OwnershipChecker.checkOwnership(filePath, metadata, installation.path);
|
|
112383
112518
|
if (!ownershipResult.exists)
|
|
112384
112519
|
continue;
|
|
@@ -112425,9 +112560,9 @@ function displayDryRunPreview(analysis, installationType) {
|
|
|
112425
112560
|
}
|
|
112426
112561
|
|
|
112427
112562
|
// src/commands/uninstall/removal-handler.ts
|
|
112428
|
-
async function
|
|
112563
|
+
async function isDirectory2(filePath) {
|
|
112429
112564
|
try {
|
|
112430
|
-
const stats = await
|
|
112565
|
+
const stats = await import_fs_extra42.lstat(filePath);
|
|
112431
112566
|
return stats.isDirectory();
|
|
112432
112567
|
} catch {
|
|
112433
112568
|
logger.debug(`Failed to check if path is directory: ${filePath}`);
|
|
@@ -112452,16 +112587,16 @@ async function restoreUninstallBackup(backup) {
|
|
|
112452
112587
|
}
|
|
112453
112588
|
async function isPathSafeToRemove(filePath, baseDir) {
|
|
112454
112589
|
try {
|
|
112455
|
-
const resolvedPath =
|
|
112456
|
-
const resolvedBase =
|
|
112590
|
+
const resolvedPath = resolve55(filePath);
|
|
112591
|
+
const resolvedBase = resolve55(baseDir);
|
|
112457
112592
|
if (!resolvedPath.startsWith(resolvedBase + sep13) && resolvedPath !== resolvedBase) {
|
|
112458
112593
|
logger.debug(`Path outside installation directory: ${filePath}`);
|
|
112459
112594
|
return false;
|
|
112460
112595
|
}
|
|
112461
|
-
const stats = await
|
|
112596
|
+
const stats = await import_fs_extra42.lstat(filePath);
|
|
112462
112597
|
if (stats.isSymbolicLink()) {
|
|
112463
|
-
const realPath = await
|
|
112464
|
-
const resolvedReal =
|
|
112598
|
+
const realPath = await import_fs_extra42.realpath(filePath);
|
|
112599
|
+
const resolvedReal = resolve55(realPath);
|
|
112465
112600
|
if (!resolvedReal.startsWith(resolvedBase + sep13) && resolvedReal !== resolvedBase) {
|
|
112466
112601
|
logger.debug(`Symlink points outside installation directory: ${filePath} -> ${realPath}`);
|
|
112467
112602
|
return false;
|
|
@@ -112521,15 +112656,15 @@ async function removeInstallations(installations, options2) {
|
|
|
112521
112656
|
let removedCount = 0;
|
|
112522
112657
|
let cleanedDirs = 0;
|
|
112523
112658
|
for (const item of analysis.toDelete) {
|
|
112524
|
-
const filePath =
|
|
112525
|
-
if (!await
|
|
112659
|
+
const filePath = join152(installation.path, item.path);
|
|
112660
|
+
if (!await import_fs_extra42.pathExists(filePath))
|
|
112526
112661
|
continue;
|
|
112527
112662
|
if (!await isPathSafeToRemove(filePath, installation.path)) {
|
|
112528
112663
|
logger.debug(`Skipping unsafe path: ${item.path}`);
|
|
112529
112664
|
continue;
|
|
112530
112665
|
}
|
|
112531
|
-
const isDir = await
|
|
112532
|
-
await
|
|
112666
|
+
const isDir = await isDirectory2(filePath);
|
|
112667
|
+
await import_fs_extra42.remove(filePath);
|
|
112533
112668
|
removedCount++;
|
|
112534
112669
|
logger.debug(`Removed ${isDir ? "directory" : "file"}: ${item.path}`);
|
|
112535
112670
|
if (!isDir) {
|
|
@@ -112929,8 +113064,8 @@ ${import_picocolors40.default.bold(import_picocolors40.default.cyan(result.kitCo
|
|
|
112929
113064
|
// src/commands/watch/watch-command.ts
|
|
112930
113065
|
init_logger();
|
|
112931
113066
|
import { existsSync as existsSync75 } from "node:fs";
|
|
112932
|
-
import { rm as
|
|
112933
|
-
import { join as
|
|
113067
|
+
import { rm as rm18 } from "node:fs/promises";
|
|
113068
|
+
import { join as join159 } from "node:path";
|
|
112934
113069
|
var import_picocolors41 = __toESM(require_picocolors(), 1);
|
|
112935
113070
|
|
|
112936
113071
|
// src/commands/watch/phases/implementation-runner.ts
|
|
@@ -113448,8 +113583,8 @@ function spawnAndCollect3(command, args) {
|
|
|
113448
113583
|
}
|
|
113449
113584
|
|
|
113450
113585
|
// src/commands/watch/phases/issue-processor.ts
|
|
113451
|
-
import { mkdir as
|
|
113452
|
-
import { join as
|
|
113586
|
+
import { mkdir as mkdir40, writeFile as writeFile38 } from "node:fs/promises";
|
|
113587
|
+
import { join as join155 } from "node:path";
|
|
113453
113588
|
|
|
113454
113589
|
// src/commands/watch/phases/approval-detector.ts
|
|
113455
113590
|
init_logger();
|
|
@@ -113826,26 +113961,26 @@ async function checkAwaitingApproval(state, setup, options2, watchLog, projectDi
|
|
|
113826
113961
|
}
|
|
113827
113962
|
|
|
113828
113963
|
// src/commands/watch/phases/plan-dir-finder.ts
|
|
113829
|
-
import { readdir as
|
|
113830
|
-
import { join as
|
|
113964
|
+
import { readdir as readdir45, stat as stat24 } from "node:fs/promises";
|
|
113965
|
+
import { join as join154 } from "node:path";
|
|
113831
113966
|
async function findRecentPlanDir(cwd2, issueNumber, watchLog) {
|
|
113832
|
-
const plansRoot =
|
|
113967
|
+
const plansRoot = join154(cwd2, "plans");
|
|
113833
113968
|
try {
|
|
113834
|
-
const entries = await
|
|
113969
|
+
const entries = await readdir45(plansRoot);
|
|
113835
113970
|
const tenMinAgo = Date.now() - 10 * 60 * 1000;
|
|
113836
113971
|
const issueStr = String(issueNumber);
|
|
113837
113972
|
const candidates = [];
|
|
113838
113973
|
for (const entry of entries) {
|
|
113839
113974
|
if (entry === "watch" || entry === "reports" || entry === "visuals")
|
|
113840
113975
|
continue;
|
|
113841
|
-
const dirPath =
|
|
113842
|
-
const dirStat = await
|
|
113976
|
+
const dirPath = join154(plansRoot, entry);
|
|
113977
|
+
const dirStat = await stat24(dirPath);
|
|
113843
113978
|
if (!dirStat.isDirectory())
|
|
113844
113979
|
continue;
|
|
113845
113980
|
if (dirStat.mtimeMs < tenMinAgo)
|
|
113846
113981
|
continue;
|
|
113847
113982
|
try {
|
|
113848
|
-
await
|
|
113983
|
+
await stat24(join154(dirPath, "plan.md"));
|
|
113849
113984
|
} catch {
|
|
113850
113985
|
continue;
|
|
113851
113986
|
}
|
|
@@ -114076,13 +114211,13 @@ async function handlePlanGeneration(issue, state, config, setup, options2, watch
|
|
|
114076
114211
|
stats.plansCreated++;
|
|
114077
114212
|
const detectedPlanDir = await findRecentPlanDir(projectDir, issue.number, watchLog);
|
|
114078
114213
|
if (detectedPlanDir) {
|
|
114079
|
-
state.activeIssues[numStr].planPath =
|
|
114214
|
+
state.activeIssues[numStr].planPath = join155(detectedPlanDir, "plan.md");
|
|
114080
114215
|
watchLog.info(`Plan directory detected: ${detectedPlanDir}`);
|
|
114081
114216
|
} else {
|
|
114082
114217
|
try {
|
|
114083
|
-
const planDir =
|
|
114084
|
-
await
|
|
114085
|
-
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`);
|
|
114086
114221
|
await writeFile38(planFilePath, planResult.planText, "utf-8");
|
|
114087
114222
|
state.activeIssues[numStr].planPath = planFilePath;
|
|
114088
114223
|
watchLog.info(`Plan saved (fallback) to ${planFilePath}`);
|
|
@@ -114228,8 +114363,8 @@ init_ck_config_manager();
|
|
|
114228
114363
|
init_file_io();
|
|
114229
114364
|
init_logger();
|
|
114230
114365
|
import { existsSync as existsSync71 } from "node:fs";
|
|
114231
|
-
import { mkdir as
|
|
114232
|
-
import { dirname as
|
|
114366
|
+
import { mkdir as mkdir41, readFile as readFile67 } from "node:fs/promises";
|
|
114367
|
+
import { dirname as dirname48 } from "node:path";
|
|
114233
114368
|
var PROCESSED_ISSUES_CAP = 500;
|
|
114234
114369
|
async function readCkJson(projectDir) {
|
|
114235
114370
|
const configPath = CkConfigManager.getProjectConfigPath(projectDir);
|
|
@@ -114259,9 +114394,9 @@ async function loadWatchState(projectDir) {
|
|
|
114259
114394
|
}
|
|
114260
114395
|
async function saveWatchState(projectDir, state) {
|
|
114261
114396
|
const configPath = CkConfigManager.getProjectConfigPath(projectDir);
|
|
114262
|
-
const configDir =
|
|
114397
|
+
const configDir = dirname48(configPath);
|
|
114263
114398
|
if (!existsSync71(configDir)) {
|
|
114264
|
-
await
|
|
114399
|
+
await mkdir41(configDir, { recursive: true });
|
|
114265
114400
|
}
|
|
114266
114401
|
const raw2 = await readCkJson(projectDir);
|
|
114267
114402
|
const watchRaw = raw2.watch ?? {};
|
|
@@ -114388,19 +114523,19 @@ async function processImplementationQueue(state, config, setup, options2, watchL
|
|
|
114388
114523
|
init_logger();
|
|
114389
114524
|
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
114390
114525
|
import { existsSync as existsSync72 } from "node:fs";
|
|
114391
|
-
import { readdir as
|
|
114392
|
-
import { join as
|
|
114526
|
+
import { readdir as readdir46, stat as stat25 } from "node:fs/promises";
|
|
114527
|
+
import { join as join156 } from "node:path";
|
|
114393
114528
|
async function scanForRepos(parentDir) {
|
|
114394
114529
|
const repos = [];
|
|
114395
|
-
const entries = await
|
|
114530
|
+
const entries = await readdir46(parentDir);
|
|
114396
114531
|
for (const entry of entries) {
|
|
114397
114532
|
if (entry.startsWith("."))
|
|
114398
114533
|
continue;
|
|
114399
|
-
const fullPath =
|
|
114400
|
-
const entryStat = await
|
|
114534
|
+
const fullPath = join156(parentDir, entry);
|
|
114535
|
+
const entryStat = await stat25(fullPath);
|
|
114401
114536
|
if (!entryStat.isDirectory())
|
|
114402
114537
|
continue;
|
|
114403
|
-
const gitDir =
|
|
114538
|
+
const gitDir = join156(fullPath, ".git");
|
|
114404
114539
|
if (!existsSync72(gitDir))
|
|
114405
114540
|
continue;
|
|
114406
114541
|
const result = spawnSync7("gh", ["repo", "view", "--json", "owner,name"], {
|
|
@@ -114426,8 +114561,8 @@ async function scanForRepos(parentDir) {
|
|
|
114426
114561
|
init_logger();
|
|
114427
114562
|
import { spawnSync as spawnSync8 } from "node:child_process";
|
|
114428
114563
|
import { existsSync as existsSync73 } from "node:fs";
|
|
114429
|
-
import { homedir as
|
|
114430
|
-
import { join as
|
|
114564
|
+
import { homedir as homedir53 } from "node:os";
|
|
114565
|
+
import { join as join157 } from "node:path";
|
|
114431
114566
|
async function validateSetup(cwd2) {
|
|
114432
114567
|
const workDir = cwd2 ?? process.cwd();
|
|
114433
114568
|
const ghVersion = spawnSync8("gh", ["--version"], { encoding: "utf-8", timeout: 1e4 });
|
|
@@ -114458,7 +114593,7 @@ Run this command from a directory with a GitHub remote.`);
|
|
|
114458
114593
|
} catch {
|
|
114459
114594
|
throw new Error(`Failed to parse repository info: ${ghRepo.stdout}`);
|
|
114460
114595
|
}
|
|
114461
|
-
const skillsPath =
|
|
114596
|
+
const skillsPath = join157(homedir53(), ".claude", "skills");
|
|
114462
114597
|
const skillsAvailable = existsSync73(skillsPath);
|
|
114463
114598
|
if (!skillsAvailable) {
|
|
114464
114599
|
logger.warning(`ClaudeKit Engineer skills not found at ${skillsPath}`);
|
|
@@ -114476,8 +114611,8 @@ init_logger();
|
|
|
114476
114611
|
init_path_resolver();
|
|
114477
114612
|
import { createWriteStream as createWriteStream3, statSync as statSync13 } from "node:fs";
|
|
114478
114613
|
import { existsSync as existsSync74 } from "node:fs";
|
|
114479
|
-
import { mkdir as
|
|
114480
|
-
import { join as
|
|
114614
|
+
import { mkdir as mkdir42, rename as rename14 } from "node:fs/promises";
|
|
114615
|
+
import { join as join158 } from "node:path";
|
|
114481
114616
|
|
|
114482
114617
|
class WatchLogger {
|
|
114483
114618
|
logStream = null;
|
|
@@ -114485,16 +114620,16 @@ class WatchLogger {
|
|
|
114485
114620
|
logPath = null;
|
|
114486
114621
|
maxBytes;
|
|
114487
114622
|
constructor(logDir, maxBytes = 0) {
|
|
114488
|
-
this.logDir = logDir ??
|
|
114623
|
+
this.logDir = logDir ?? join158(PathResolver.getClaudeKitDir(), "logs");
|
|
114489
114624
|
this.maxBytes = maxBytes;
|
|
114490
114625
|
}
|
|
114491
114626
|
async init() {
|
|
114492
114627
|
try {
|
|
114493
114628
|
if (!existsSync74(this.logDir)) {
|
|
114494
|
-
await
|
|
114629
|
+
await mkdir42(this.logDir, { recursive: true });
|
|
114495
114630
|
}
|
|
114496
114631
|
const dateStr = formatDate(new Date);
|
|
114497
|
-
this.logPath =
|
|
114632
|
+
this.logPath = join158(this.logDir, `watch-${dateStr}.log`);
|
|
114498
114633
|
this.logStream = createWriteStream3(this.logPath, { flags: "a", mode: 384 });
|
|
114499
114634
|
} catch (error) {
|
|
114500
114635
|
logger.warning(`Cannot create watch log file: ${error instanceof Error ? error.message : "Unknown"}`);
|
|
@@ -114559,7 +114694,7 @@ class WatchLogger {
|
|
|
114559
114694
|
try {
|
|
114560
114695
|
this.logStream.end();
|
|
114561
114696
|
const rotatedPath = `${this.logPath}.1`;
|
|
114562
|
-
|
|
114697
|
+
rename14(this.logPath, rotatedPath).catch(() => {});
|
|
114563
114698
|
this.logStream = createWriteStream3(this.logPath, { flags: "w", mode: 384 });
|
|
114564
114699
|
} catch {}
|
|
114565
114700
|
}
|
|
@@ -114676,7 +114811,7 @@ async function watchCommand(options2) {
|
|
|
114676
114811
|
}
|
|
114677
114812
|
async function discoverRepos(options2, watchLog) {
|
|
114678
114813
|
const cwd2 = process.cwd();
|
|
114679
|
-
const isGitRepo = existsSync75(
|
|
114814
|
+
const isGitRepo = existsSync75(join159(cwd2, ".git"));
|
|
114680
114815
|
if (options2.force) {
|
|
114681
114816
|
await forceRemoveLock(watchLog);
|
|
114682
114817
|
}
|
|
@@ -114749,8 +114884,8 @@ async function forceRemoveLock(watchLog) {
|
|
|
114749
114884
|
const { resource, lockfile: lockfile7 } = getLockPaths(LOCK_NAME);
|
|
114750
114885
|
try {
|
|
114751
114886
|
await Promise.all([
|
|
114752
|
-
|
|
114753
|
-
|
|
114887
|
+
rm18(resource, { recursive: true, force: true }),
|
|
114888
|
+
rm18(lockfile7, { recursive: true, force: true })
|
|
114754
114889
|
]);
|
|
114755
114890
|
watchLog.info("Removed existing lock file (--force)");
|
|
114756
114891
|
} catch {}
|
|
@@ -114934,7 +115069,7 @@ function registerCommands(cli) {
|
|
|
114934
115069
|
init_package();
|
|
114935
115070
|
init_config_version_checker();
|
|
114936
115071
|
import { existsSync as existsSync87, readFileSync as readFileSync22 } from "node:fs";
|
|
114937
|
-
import { join as
|
|
115072
|
+
import { join as join171 } from "node:path";
|
|
114938
115073
|
|
|
114939
115074
|
// src/domains/versioning/version-checker.ts
|
|
114940
115075
|
init_version_utils();
|
|
@@ -114948,15 +115083,15 @@ init_types3();
|
|
|
114948
115083
|
init_logger();
|
|
114949
115084
|
init_path_resolver();
|
|
114950
115085
|
import { existsSync as existsSync86 } from "node:fs";
|
|
114951
|
-
import { mkdir as
|
|
114952
|
-
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";
|
|
114953
115088
|
|
|
114954
115089
|
class VersionCacheManager {
|
|
114955
115090
|
static CACHE_FILENAME = "version-check.json";
|
|
114956
115091
|
static CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000;
|
|
114957
115092
|
static getCacheFile() {
|
|
114958
115093
|
const cacheDir = PathResolver.getCacheDir(false);
|
|
114959
|
-
return
|
|
115094
|
+
return join170(cacheDir, VersionCacheManager.CACHE_FILENAME);
|
|
114960
115095
|
}
|
|
114961
115096
|
static async load() {
|
|
114962
115097
|
const cacheFile = VersionCacheManager.getCacheFile();
|
|
@@ -114983,7 +115118,7 @@ class VersionCacheManager {
|
|
|
114983
115118
|
const cacheDir = PathResolver.getCacheDir(false);
|
|
114984
115119
|
try {
|
|
114985
115120
|
if (!existsSync86(cacheDir)) {
|
|
114986
|
-
await
|
|
115121
|
+
await mkdir43(cacheDir, { recursive: true, mode: 448 });
|
|
114987
115122
|
}
|
|
114988
115123
|
await writeFile41(cacheFile, JSON.stringify(cache5, null, 2), "utf-8");
|
|
114989
115124
|
logger.debug(`Version check cache saved to ${cacheFile}`);
|
|
@@ -115267,9 +115402,9 @@ async function displayVersion() {
|
|
|
115267
115402
|
let localInstalledKits = [];
|
|
115268
115403
|
let globalInstalledKits = [];
|
|
115269
115404
|
const globalKitDir = PathResolver.getGlobalKitDir();
|
|
115270
|
-
const globalMetadataPath =
|
|
115405
|
+
const globalMetadataPath = join171(globalKitDir, "metadata.json");
|
|
115271
115406
|
const prefix = PathResolver.getPathPrefix(false);
|
|
115272
|
-
const localMetadataPath = prefix ?
|
|
115407
|
+
const localMetadataPath = prefix ? join171(process.cwd(), prefix, "metadata.json") : join171(process.cwd(), "metadata.json");
|
|
115273
115408
|
const isLocalSameAsGlobal = localMetadataPath === globalMetadataPath;
|
|
115274
115409
|
if (!isLocalSameAsGlobal && existsSync87(localMetadataPath)) {
|
|
115275
115410
|
try {
|
|
@@ -115657,7 +115792,7 @@ var output2 = new OutputManager2;
|
|
|
115657
115792
|
|
|
115658
115793
|
// src/shared/temp-cleanup.ts
|
|
115659
115794
|
init_logger();
|
|
115660
|
-
var
|
|
115795
|
+
var import_fs_extra43 = __toESM(require_lib(), 1);
|
|
115661
115796
|
import { rmSync as rmSync6 } from "node:fs";
|
|
115662
115797
|
var tempDirs2 = new Set;
|
|
115663
115798
|
async function cleanup() {
|
|
@@ -115666,7 +115801,7 @@ async function cleanup() {
|
|
|
115666
115801
|
logger.debug(`Cleaning up ${tempDirs2.size} temporary director(ies)...`);
|
|
115667
115802
|
for (const dir of tempDirs2) {
|
|
115668
115803
|
try {
|
|
115669
|
-
await
|
|
115804
|
+
await import_fs_extra43.remove(dir);
|
|
115670
115805
|
logger.debug(`Cleaned up temp directory: ${dir}`);
|
|
115671
115806
|
} catch (error) {
|
|
115672
115807
|
logger.debug(`Failed to clean temp directory ${dir}: ${error}`);
|