claudekit-cli 4.1.1 → 4.2.1-dev.1
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 +181 -181
- package/package.json +2 -1
package/cli-manifest.json
CHANGED
package/dist/index.js
CHANGED
|
@@ -62890,7 +62890,7 @@ var package_default;
|
|
|
62890
62890
|
var init_package = __esm(() => {
|
|
62891
62891
|
package_default = {
|
|
62892
62892
|
name: "claudekit-cli",
|
|
62893
|
-
version: "4.1.1",
|
|
62893
|
+
version: "4.2.1-dev.1",
|
|
62894
62894
|
description: "CLI tool for bootstrapping and updating ClaudeKit projects",
|
|
62895
62895
|
type: "module",
|
|
62896
62896
|
repository: {
|
|
@@ -62934,6 +62934,7 @@ var init_package = __esm(() => {
|
|
|
62934
62934
|
"dev:all": "./scripts/dev-quick-start.sh all",
|
|
62935
62935
|
metrics: "bun run scripts/workflow-metrics.ts",
|
|
62936
62936
|
validate: "bun run typecheck && bun run lint && bun test && bun run ui:test && bun run build",
|
|
62937
|
+
"ci:local": "bash scripts/ci-local.sh",
|
|
62937
62938
|
"install:hooks": "./.githooks/install.sh",
|
|
62938
62939
|
prepare: `node -e "try{require('child_process').execSync('git rev-parse --git-dir',{stdio:'ignore'});require('child_process').execSync('bash .githooks/install.sh',{stdio:'inherit'})}catch(e){console.warn('[i] Hook install skipped:',e.message)}"`,
|
|
62939
62940
|
"help:check-parity": "bun run scripts/check-help-parity.ts",
|
|
@@ -64888,8 +64889,20 @@ function buildInitCommand(isGlobal, kit, beta, yes) {
|
|
|
64888
64889
|
function resolveCkExecutable(platformName = process.platform) {
|
|
64889
64890
|
return platformName === "win32" ? "ck.cmd" : "ck";
|
|
64890
64891
|
}
|
|
64891
|
-
function
|
|
64892
|
-
|
|
64892
|
+
function resolveCkInitSpawnCommand(initArgs, options2 = {}) {
|
|
64893
|
+
const execPath = options2.execPath ?? process.execPath;
|
|
64894
|
+
const argv = options2.argv ?? process.argv;
|
|
64895
|
+
const currentEntrypoint = argv[1];
|
|
64896
|
+
if (currentEntrypoint) {
|
|
64897
|
+
return {
|
|
64898
|
+
command: execPath,
|
|
64899
|
+
args: [currentEntrypoint, ...initArgs]
|
|
64900
|
+
};
|
|
64901
|
+
}
|
|
64902
|
+
return {
|
|
64903
|
+
command: resolveCkExecutable(options2.platformName),
|
|
64904
|
+
args: initArgs
|
|
64905
|
+
};
|
|
64893
64906
|
}
|
|
64894
64907
|
async function fetchLatestReleaseTag(kit, beta) {
|
|
64895
64908
|
try {
|
|
@@ -64999,10 +65012,8 @@ async function promptKitUpdate(beta, yes, deps) {
|
|
|
64999
65012
|
const displayCmd = `ck ${args.join(" ")}`;
|
|
65000
65013
|
logger.info(`Running: ${displayCmd}`);
|
|
65001
65014
|
const spawnFn = deps?.spawnInitFn ?? ((spawnArgs) => new Promise((resolve30) => {
|
|
65002
|
-
const
|
|
65003
|
-
|
|
65004
|
-
shell: shouldRunCkExecutableInShell()
|
|
65005
|
-
});
|
|
65015
|
+
const initCommand = resolveCkInitSpawnCommand(spawnArgs);
|
|
65016
|
+
const child = spawn2(initCommand.command, initCommand.args, { stdio: "inherit" });
|
|
65006
65017
|
child.on("close", (code) => resolve30(code ?? 1));
|
|
65007
65018
|
child.on("error", (err) => {
|
|
65008
65019
|
logger.verbose(`Failed to spawn ck init: ${err.message}`);
|
|
@@ -73995,76 +74006,6 @@ var init_ownership_display = __esm(() => {
|
|
|
73995
74006
|
import_picocolors25 = __toESM(require_picocolors(), 1);
|
|
73996
74007
|
});
|
|
73997
74008
|
|
|
73998
|
-
// src/ui/node_modules/picocolors/picocolors.js
|
|
73999
|
-
var require_picocolors2 = __commonJS((exports, module) => {
|
|
74000
|
-
var p = process || {};
|
|
74001
|
-
var argv = p.argv || [];
|
|
74002
|
-
var env2 = p.env || {};
|
|
74003
|
-
var isColorSupported = !(!!env2.NO_COLOR || argv.includes("--no-color")) && (!!env2.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env2.TERM !== "dumb" || !!env2.CI);
|
|
74004
|
-
var formatter = (open6, close, replace3 = open6) => (input) => {
|
|
74005
|
-
let string = "" + input, index = string.indexOf(close, open6.length);
|
|
74006
|
-
return ~index ? open6 + replaceClose(string, close, replace3, index) + close : open6 + string + close;
|
|
74007
|
-
};
|
|
74008
|
-
var replaceClose = (string, close, replace3, index) => {
|
|
74009
|
-
let result = "", cursor = 0;
|
|
74010
|
-
do {
|
|
74011
|
-
result += string.substring(cursor, index) + replace3;
|
|
74012
|
-
cursor = index + close.length;
|
|
74013
|
-
index = string.indexOf(close, cursor);
|
|
74014
|
-
} while (~index);
|
|
74015
|
-
return result + string.substring(cursor);
|
|
74016
|
-
};
|
|
74017
|
-
var createColors = (enabled = isColorSupported) => {
|
|
74018
|
-
let f3 = enabled ? formatter : () => String;
|
|
74019
|
-
return {
|
|
74020
|
-
isColorSupported: enabled,
|
|
74021
|
-
reset: f3("\x1B[0m", "\x1B[0m"),
|
|
74022
|
-
bold: f3("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
|
|
74023
|
-
dim: f3("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
|
|
74024
|
-
italic: f3("\x1B[3m", "\x1B[23m"),
|
|
74025
|
-
underline: f3("\x1B[4m", "\x1B[24m"),
|
|
74026
|
-
inverse: f3("\x1B[7m", "\x1B[27m"),
|
|
74027
|
-
hidden: f3("\x1B[8m", "\x1B[28m"),
|
|
74028
|
-
strikethrough: f3("\x1B[9m", "\x1B[29m"),
|
|
74029
|
-
black: f3("\x1B[30m", "\x1B[39m"),
|
|
74030
|
-
red: f3("\x1B[31m", "\x1B[39m"),
|
|
74031
|
-
green: f3("\x1B[32m", "\x1B[39m"),
|
|
74032
|
-
yellow: f3("\x1B[33m", "\x1B[39m"),
|
|
74033
|
-
blue: f3("\x1B[34m", "\x1B[39m"),
|
|
74034
|
-
magenta: f3("\x1B[35m", "\x1B[39m"),
|
|
74035
|
-
cyan: f3("\x1B[36m", "\x1B[39m"),
|
|
74036
|
-
white: f3("\x1B[37m", "\x1B[39m"),
|
|
74037
|
-
gray: f3("\x1B[90m", "\x1B[39m"),
|
|
74038
|
-
bgBlack: f3("\x1B[40m", "\x1B[49m"),
|
|
74039
|
-
bgRed: f3("\x1B[41m", "\x1B[49m"),
|
|
74040
|
-
bgGreen: f3("\x1B[42m", "\x1B[49m"),
|
|
74041
|
-
bgYellow: f3("\x1B[43m", "\x1B[49m"),
|
|
74042
|
-
bgBlue: f3("\x1B[44m", "\x1B[49m"),
|
|
74043
|
-
bgMagenta: f3("\x1B[45m", "\x1B[49m"),
|
|
74044
|
-
bgCyan: f3("\x1B[46m", "\x1B[49m"),
|
|
74045
|
-
bgWhite: f3("\x1B[47m", "\x1B[49m"),
|
|
74046
|
-
blackBright: f3("\x1B[90m", "\x1B[39m"),
|
|
74047
|
-
redBright: f3("\x1B[91m", "\x1B[39m"),
|
|
74048
|
-
greenBright: f3("\x1B[92m", "\x1B[39m"),
|
|
74049
|
-
yellowBright: f3("\x1B[93m", "\x1B[39m"),
|
|
74050
|
-
blueBright: f3("\x1B[94m", "\x1B[39m"),
|
|
74051
|
-
magentaBright: f3("\x1B[95m", "\x1B[39m"),
|
|
74052
|
-
cyanBright: f3("\x1B[96m", "\x1B[39m"),
|
|
74053
|
-
whiteBright: f3("\x1B[97m", "\x1B[39m"),
|
|
74054
|
-
bgBlackBright: f3("\x1B[100m", "\x1B[49m"),
|
|
74055
|
-
bgRedBright: f3("\x1B[101m", "\x1B[49m"),
|
|
74056
|
-
bgGreenBright: f3("\x1B[102m", "\x1B[49m"),
|
|
74057
|
-
bgYellowBright: f3("\x1B[103m", "\x1B[49m"),
|
|
74058
|
-
bgBlueBright: f3("\x1B[104m", "\x1B[49m"),
|
|
74059
|
-
bgMagentaBright: f3("\x1B[105m", "\x1B[49m"),
|
|
74060
|
-
bgCyanBright: f3("\x1B[106m", "\x1B[49m"),
|
|
74061
|
-
bgWhiteBright: f3("\x1B[107m", "\x1B[49m")
|
|
74062
|
-
};
|
|
74063
|
-
};
|
|
74064
|
-
module.exports = createColors();
|
|
74065
|
-
module.exports.createColors = createColors;
|
|
74066
|
-
});
|
|
74067
|
-
|
|
74068
74009
|
// src/commands/watch/phases/implementation-git-helpers.ts
|
|
74069
74010
|
import { spawn as spawn5 } from "node:child_process";
|
|
74070
74011
|
async function getCurrentBranch2(cwd2) {
|
|
@@ -74173,9 +74114,9 @@ __export(exports_worktree_manager, {
|
|
|
74173
74114
|
});
|
|
74174
74115
|
import { existsSync as existsSync70 } from "node:fs";
|
|
74175
74116
|
import { readFile as readFile66, writeFile as writeFile37 } from "node:fs/promises";
|
|
74176
|
-
import { join as
|
|
74117
|
+
import { join as join152 } from "node:path";
|
|
74177
74118
|
async function createWorktree(projectDir, issueNumber, baseBranch) {
|
|
74178
|
-
const worktreePath =
|
|
74119
|
+
const worktreePath = join152(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
|
|
74179
74120
|
const branchName = `ck-watch/issue-${issueNumber}`;
|
|
74180
74121
|
await spawnAndCollect("git", ["fetch", "origin", baseBranch], projectDir).catch(() => {
|
|
74181
74122
|
logger.warning(`[worktree] Could not fetch origin/${baseBranch}, using local`);
|
|
@@ -74193,7 +74134,7 @@ async function createWorktree(projectDir, issueNumber, baseBranch) {
|
|
|
74193
74134
|
return worktreePath;
|
|
74194
74135
|
}
|
|
74195
74136
|
async function removeWorktree(projectDir, issueNumber) {
|
|
74196
|
-
const worktreePath =
|
|
74137
|
+
const worktreePath = join152(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
|
|
74197
74138
|
const branchName = `ck-watch/issue-${issueNumber}`;
|
|
74198
74139
|
try {
|
|
74199
74140
|
await spawnAndCollect("git", ["worktree", "remove", worktreePath, "--force"], projectDir);
|
|
@@ -74207,7 +74148,7 @@ async function listActiveWorktrees(projectDir) {
|
|
|
74207
74148
|
try {
|
|
74208
74149
|
const output2 = await spawnAndCollect("git", ["worktree", "list", "--porcelain"], projectDir);
|
|
74209
74150
|
const issueNumbers = [];
|
|
74210
|
-
const worktreePrefix =
|
|
74151
|
+
const worktreePrefix = join152(projectDir, WORKTREE_DIR, "issue-").replace(/\\/g, "/");
|
|
74211
74152
|
for (const line of output2.split(`
|
|
74212
74153
|
`)) {
|
|
74213
74154
|
if (line.startsWith("worktree ")) {
|
|
@@ -74235,7 +74176,7 @@ async function cleanupAllWorktrees(projectDir) {
|
|
|
74235
74176
|
await spawnAndCollect("git", ["worktree", "prune"], projectDir).catch(() => {});
|
|
74236
74177
|
}
|
|
74237
74178
|
async function ensureGitignore(projectDir) {
|
|
74238
|
-
const gitignorePath =
|
|
74179
|
+
const gitignorePath = join152(projectDir, ".gitignore");
|
|
74239
74180
|
try {
|
|
74240
74181
|
const content = existsSync70(gitignorePath) ? await readFile66(gitignorePath, "utf-8") : "";
|
|
74241
74182
|
if (!content.includes(".worktrees")) {
|
|
@@ -74342,7 +74283,7 @@ import { createHash as createHash9 } from "node:crypto";
|
|
|
74342
74283
|
import { existsSync as existsSync76, mkdirSync as mkdirSync5, readFileSync as readFileSync18, readdirSync as readdirSync11, statSync as statSync14 } from "node:fs";
|
|
74343
74284
|
import { rename as rename14, writeFile as writeFile39 } from "node:fs/promises";
|
|
74344
74285
|
import { homedir as homedir53 } from "node:os";
|
|
74345
|
-
import { basename as basename31, join as
|
|
74286
|
+
import { basename as basename31, join as join159 } from "node:path";
|
|
74346
74287
|
function getCachedContext(repoPath) {
|
|
74347
74288
|
const cachePath = getCacheFilePath(repoPath);
|
|
74348
74289
|
if (!existsSync76(cachePath))
|
|
@@ -74385,25 +74326,25 @@ function computeSourceHash(repoPath) {
|
|
|
74385
74326
|
}
|
|
74386
74327
|
function getDocSourcePaths(repoPath) {
|
|
74387
74328
|
const paths = [];
|
|
74388
|
-
const docsDir =
|
|
74329
|
+
const docsDir = join159(repoPath, "docs");
|
|
74389
74330
|
if (existsSync76(docsDir)) {
|
|
74390
74331
|
try {
|
|
74391
74332
|
const files = readdirSync11(docsDir);
|
|
74392
74333
|
for (const f3 of files) {
|
|
74393
74334
|
if (f3.endsWith(".md"))
|
|
74394
|
-
paths.push(
|
|
74335
|
+
paths.push(join159(docsDir, f3));
|
|
74395
74336
|
}
|
|
74396
74337
|
} catch {}
|
|
74397
74338
|
}
|
|
74398
|
-
const readme =
|
|
74339
|
+
const readme = join159(repoPath, "README.md");
|
|
74399
74340
|
if (existsSync76(readme))
|
|
74400
74341
|
paths.push(readme);
|
|
74401
|
-
const stylesDir =
|
|
74342
|
+
const stylesDir = join159(repoPath, "assets", "writing-styles");
|
|
74402
74343
|
if (existsSync76(stylesDir)) {
|
|
74403
74344
|
try {
|
|
74404
74345
|
const files = readdirSync11(stylesDir);
|
|
74405
74346
|
for (const f3 of files) {
|
|
74406
|
-
paths.push(
|
|
74347
|
+
paths.push(join159(stylesDir, f3));
|
|
74407
74348
|
}
|
|
74408
74349
|
} catch {}
|
|
74409
74350
|
}
|
|
@@ -74412,11 +74353,11 @@ function getDocSourcePaths(repoPath) {
|
|
|
74412
74353
|
function getCacheFilePath(repoPath) {
|
|
74413
74354
|
const repoName = basename31(repoPath).replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
74414
74355
|
const pathHash = createHash9("sha256").update(repoPath).digest("hex").slice(0, 8);
|
|
74415
|
-
return
|
|
74356
|
+
return join159(CACHE_DIR, `${repoName}-${pathHash}-context-cache.json`);
|
|
74416
74357
|
}
|
|
74417
74358
|
var CACHE_DIR, CACHE_TTL_MS5;
|
|
74418
74359
|
var init_context_cache_manager = __esm(() => {
|
|
74419
|
-
CACHE_DIR =
|
|
74360
|
+
CACHE_DIR = join159(homedir53(), ".claudekit", "cache");
|
|
74420
74361
|
CACHE_TTL_MS5 = 24 * 60 * 60 * 1000;
|
|
74421
74362
|
});
|
|
74422
74363
|
|
|
@@ -74597,7 +74538,7 @@ function extractContentFromResponse(response) {
|
|
|
74597
74538
|
// src/commands/content/phases/docs-summarizer.ts
|
|
74598
74539
|
import { execSync as execSync7 } from "node:child_process";
|
|
74599
74540
|
import { existsSync as existsSync77, readFileSync as readFileSync19, readdirSync as readdirSync12 } from "node:fs";
|
|
74600
|
-
import { join as
|
|
74541
|
+
import { join as join160 } from "node:path";
|
|
74601
74542
|
async function summarizeProjectDocs(repoPath, contentLogger) {
|
|
74602
74543
|
const rawContent = collectRawDocs(repoPath);
|
|
74603
74544
|
if (rawContent.total.length < 200) {
|
|
@@ -74651,12 +74592,12 @@ function collectRawDocs(repoPath) {
|
|
|
74651
74592
|
return capped;
|
|
74652
74593
|
};
|
|
74653
74594
|
const docsContent = [];
|
|
74654
|
-
const docsDir =
|
|
74595
|
+
const docsDir = join160(repoPath, "docs");
|
|
74655
74596
|
if (existsSync77(docsDir)) {
|
|
74656
74597
|
try {
|
|
74657
74598
|
const files = readdirSync12(docsDir).filter((f3) => f3.endsWith(".md")).sort();
|
|
74658
74599
|
for (const f3 of files) {
|
|
74659
|
-
const content = readCapped(
|
|
74600
|
+
const content = readCapped(join160(docsDir, f3), 5000);
|
|
74660
74601
|
if (content) {
|
|
74661
74602
|
docsContent.push(`### ${f3}
|
|
74662
74603
|
${content}`);
|
|
@@ -74670,21 +74611,21 @@ ${content}`);
|
|
|
74670
74611
|
let brand = "";
|
|
74671
74612
|
const brandCandidates = ["docs/brand-guidelines.md", "docs/design-guidelines.md"];
|
|
74672
74613
|
for (const p of brandCandidates) {
|
|
74673
|
-
brand = readCapped(
|
|
74614
|
+
brand = readCapped(join160(repoPath, p), 3000);
|
|
74674
74615
|
if (brand)
|
|
74675
74616
|
break;
|
|
74676
74617
|
}
|
|
74677
74618
|
let styles3 = "";
|
|
74678
|
-
const stylesDir =
|
|
74619
|
+
const stylesDir = join160(repoPath, "assets", "writing-styles");
|
|
74679
74620
|
if (existsSync77(stylesDir)) {
|
|
74680
74621
|
try {
|
|
74681
74622
|
const files = readdirSync12(stylesDir).slice(0, 3);
|
|
74682
|
-
styles3 = files.map((f3) => readCapped(
|
|
74623
|
+
styles3 = files.map((f3) => readCapped(join160(stylesDir, f3), 1000)).filter(Boolean).join(`
|
|
74683
74624
|
|
|
74684
74625
|
`);
|
|
74685
74626
|
} catch {}
|
|
74686
74627
|
}
|
|
74687
|
-
const readme = readCapped(
|
|
74628
|
+
const readme = readCapped(join160(repoPath, "README.md"), 3000);
|
|
74688
74629
|
const total = [docs, brand, styles3, readme].join(`
|
|
74689
74630
|
`);
|
|
74690
74631
|
return { docs, brand, styles: styles3, readme, total };
|
|
@@ -74871,9 +74812,9 @@ IMPORTANT: Generate the image and output the path as JSON: {"imagePath": "/path/
|
|
|
74871
74812
|
import { execSync as execSync8 } from "node:child_process";
|
|
74872
74813
|
import { existsSync as existsSync78, mkdirSync as mkdirSync6, readdirSync as readdirSync13 } from "node:fs";
|
|
74873
74814
|
import { homedir as homedir54 } from "node:os";
|
|
74874
|
-
import { join as
|
|
74815
|
+
import { join as join161 } from "node:path";
|
|
74875
74816
|
async function generatePhoto(_content, context, config, platform18, contentId, contentLogger) {
|
|
74876
|
-
const mediaDir =
|
|
74817
|
+
const mediaDir = join161(config.contentDir.replace(/^~/, homedir54()), "media", String(contentId));
|
|
74877
74818
|
if (!existsSync78(mediaDir)) {
|
|
74878
74819
|
mkdirSync6(mediaDir, { recursive: true });
|
|
74879
74820
|
}
|
|
@@ -74898,7 +74839,7 @@ async function generatePhoto(_content, context, config, platform18, contentId, c
|
|
|
74898
74839
|
const imageFile = files.find((f3) => /\.(png|jpg|jpeg|webp)$/i.test(f3));
|
|
74899
74840
|
if (imageFile) {
|
|
74900
74841
|
const ext2 = imageFile.split(".").pop() ?? "png";
|
|
74901
|
-
return { path:
|
|
74842
|
+
return { path: join161(mediaDir, imageFile), ...dimensions, format: ext2 };
|
|
74902
74843
|
}
|
|
74903
74844
|
contentLogger.warn(`Photo generation produced no image for content ${contentId}`);
|
|
74904
74845
|
return null;
|
|
@@ -74988,7 +74929,7 @@ var init_content_creator = __esm(() => {
|
|
|
74988
74929
|
// src/commands/content/phases/content-logger.ts
|
|
74989
74930
|
import { createWriteStream as createWriteStream4, existsSync as existsSync79, mkdirSync as mkdirSync7, statSync as statSync15 } from "node:fs";
|
|
74990
74931
|
import { homedir as homedir55 } from "node:os";
|
|
74991
|
-
import { join as
|
|
74932
|
+
import { join as join162 } from "node:path";
|
|
74992
74933
|
|
|
74993
74934
|
class ContentLogger {
|
|
74994
74935
|
stream = null;
|
|
@@ -74996,7 +74937,7 @@ class ContentLogger {
|
|
|
74996
74937
|
logDir;
|
|
74997
74938
|
maxBytes;
|
|
74998
74939
|
constructor(maxBytes = 0) {
|
|
74999
|
-
this.logDir =
|
|
74940
|
+
this.logDir = join162(homedir55(), ".claudekit", "logs");
|
|
75000
74941
|
this.maxBytes = maxBytes;
|
|
75001
74942
|
}
|
|
75002
74943
|
init() {
|
|
@@ -75028,7 +74969,7 @@ class ContentLogger {
|
|
|
75028
74969
|
}
|
|
75029
74970
|
}
|
|
75030
74971
|
getLogPath() {
|
|
75031
|
-
return
|
|
74972
|
+
return join162(this.logDir, `content-${this.getDateStr()}.log`);
|
|
75032
74973
|
}
|
|
75033
74974
|
write(level, message) {
|
|
75034
74975
|
this.rotateIfNeeded();
|
|
@@ -75045,18 +74986,18 @@ class ContentLogger {
|
|
|
75045
74986
|
if (dateStr !== this.currentDate) {
|
|
75046
74987
|
this.close();
|
|
75047
74988
|
this.currentDate = dateStr;
|
|
75048
|
-
const logPath =
|
|
74989
|
+
const logPath = join162(this.logDir, `content-${dateStr}.log`);
|
|
75049
74990
|
this.stream = createWriteStream4(logPath, { flags: "a", mode: 384 });
|
|
75050
74991
|
return;
|
|
75051
74992
|
}
|
|
75052
74993
|
if (this.maxBytes > 0 && this.stream) {
|
|
75053
|
-
const logPath =
|
|
74994
|
+
const logPath = join162(this.logDir, `content-${this.currentDate}.log`);
|
|
75054
74995
|
try {
|
|
75055
74996
|
const stat25 = statSync15(logPath);
|
|
75056
74997
|
if (stat25.size >= this.maxBytes) {
|
|
75057
74998
|
this.close();
|
|
75058
74999
|
const suffix = Date.now();
|
|
75059
|
-
const rotatedPath =
|
|
75000
|
+
const rotatedPath = join162(this.logDir, `content-${this.currentDate}-${suffix}.log`);
|
|
75060
75001
|
import("node:fs/promises").then(({ rename: rename15 }) => rename15(logPath, rotatedPath).catch(() => {}));
|
|
75061
75002
|
this.stream = createWriteStream4(logPath, { flags: "w", mode: 384 });
|
|
75062
75003
|
}
|
|
@@ -75282,7 +75223,7 @@ function isNoiseCommit(title, author) {
|
|
|
75282
75223
|
// src/commands/content/phases/change-detector.ts
|
|
75283
75224
|
import { execSync as execSync10, spawnSync as spawnSync9 } from "node:child_process";
|
|
75284
75225
|
import { existsSync as existsSync81, readFileSync as readFileSync20, readdirSync as readdirSync14, statSync as statSync16 } from "node:fs";
|
|
75285
|
-
import { join as
|
|
75226
|
+
import { join as join163 } from "node:path";
|
|
75286
75227
|
function detectCommits(repo, since) {
|
|
75287
75228
|
try {
|
|
75288
75229
|
const fetchUrl = sshToHttps(repo.remoteUrl);
|
|
@@ -75391,7 +75332,7 @@ function detectTags(repo, since) {
|
|
|
75391
75332
|
}
|
|
75392
75333
|
}
|
|
75393
75334
|
function detectCompletedPlans(repo, since) {
|
|
75394
|
-
const plansDir =
|
|
75335
|
+
const plansDir = join163(repo.path, "plans");
|
|
75395
75336
|
if (!existsSync81(plansDir))
|
|
75396
75337
|
return [];
|
|
75397
75338
|
const sinceMs = new Date(since).getTime();
|
|
@@ -75401,7 +75342,7 @@ function detectCompletedPlans(repo, since) {
|
|
|
75401
75342
|
for (const entry of entries) {
|
|
75402
75343
|
if (!entry.isDirectory())
|
|
75403
75344
|
continue;
|
|
75404
|
-
const planFile =
|
|
75345
|
+
const planFile = join163(plansDir, entry.name, "plan.md");
|
|
75405
75346
|
if (!existsSync81(planFile))
|
|
75406
75347
|
continue;
|
|
75407
75348
|
try {
|
|
@@ -75479,7 +75420,7 @@ function classifyCommit(event) {
|
|
|
75479
75420
|
// src/commands/content/phases/repo-discoverer.ts
|
|
75480
75421
|
import { execSync as execSync11 } from "node:child_process";
|
|
75481
75422
|
import { readdirSync as readdirSync15 } from "node:fs";
|
|
75482
|
-
import { join as
|
|
75423
|
+
import { join as join164 } from "node:path";
|
|
75483
75424
|
function discoverRepos2(cwd2) {
|
|
75484
75425
|
const repos = [];
|
|
75485
75426
|
if (isGitRepoRoot(cwd2)) {
|
|
@@ -75492,7 +75433,7 @@ function discoverRepos2(cwd2) {
|
|
|
75492
75433
|
for (const entry of entries) {
|
|
75493
75434
|
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
75494
75435
|
continue;
|
|
75495
|
-
const dirPath =
|
|
75436
|
+
const dirPath = join164(cwd2, entry.name);
|
|
75496
75437
|
if (isGitRepoRoot(dirPath)) {
|
|
75497
75438
|
const info = getRepoInfo(dirPath);
|
|
75498
75439
|
if (info)
|
|
@@ -76160,9 +76101,9 @@ var init_types6 = __esm(() => {
|
|
|
76160
76101
|
|
|
76161
76102
|
// src/commands/content/phases/state-manager.ts
|
|
76162
76103
|
import { readFile as readFile68, rename as rename15, writeFile as writeFile40 } from "node:fs/promises";
|
|
76163
|
-
import { join as
|
|
76104
|
+
import { join as join165 } from "node:path";
|
|
76164
76105
|
async function loadContentConfig(projectDir) {
|
|
76165
|
-
const configPath =
|
|
76106
|
+
const configPath = join165(projectDir, CK_CONFIG_FILE2);
|
|
76166
76107
|
try {
|
|
76167
76108
|
const raw2 = await readFile68(configPath, "utf-8");
|
|
76168
76109
|
const json = JSON.parse(raw2);
|
|
@@ -76172,13 +76113,13 @@ async function loadContentConfig(projectDir) {
|
|
|
76172
76113
|
}
|
|
76173
76114
|
}
|
|
76174
76115
|
async function saveContentConfig(projectDir, config) {
|
|
76175
|
-
const configPath =
|
|
76116
|
+
const configPath = join165(projectDir, CK_CONFIG_FILE2);
|
|
76176
76117
|
const json = await readJsonSafe(configPath);
|
|
76177
76118
|
json.content = { ...json.content, ...config };
|
|
76178
76119
|
await atomicWrite2(configPath, json);
|
|
76179
76120
|
}
|
|
76180
76121
|
async function loadContentState(projectDir) {
|
|
76181
|
-
const configPath =
|
|
76122
|
+
const configPath = join165(projectDir, CK_CONFIG_FILE2);
|
|
76182
76123
|
try {
|
|
76183
76124
|
const raw2 = await readFile68(configPath, "utf-8");
|
|
76184
76125
|
const json = JSON.parse(raw2);
|
|
@@ -76189,7 +76130,7 @@ async function loadContentState(projectDir) {
|
|
|
76189
76130
|
}
|
|
76190
76131
|
}
|
|
76191
76132
|
async function saveContentState(projectDir, state) {
|
|
76192
|
-
const configPath =
|
|
76133
|
+
const configPath = join165(projectDir, CK_CONFIG_FILE2);
|
|
76193
76134
|
const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().slice(0, 10);
|
|
76194
76135
|
for (const key of Object.keys(state.dailyPostCounts)) {
|
|
76195
76136
|
const dateStr = key.slice(-10);
|
|
@@ -76471,7 +76412,7 @@ var init_platform_setup_x = __esm(() => {
|
|
|
76471
76412
|
|
|
76472
76413
|
// src/commands/content/phases/setup-wizard.ts
|
|
76473
76414
|
import { existsSync as existsSync82 } from "node:fs";
|
|
76474
|
-
import { join as
|
|
76415
|
+
import { join as join166 } from "node:path";
|
|
76475
76416
|
async function runSetupWizard2(cwd2, contentLogger) {
|
|
76476
76417
|
console.log();
|
|
76477
76418
|
oe(import_picocolors43.default.bgCyan(import_picocolors43.default.white(" CK Content — Multi-Channel Content Engine ")));
|
|
@@ -76539,8 +76480,8 @@ async function showRepoSummary(cwd2) {
|
|
|
76539
76480
|
function detectBrandAssets(cwd2, contentLogger) {
|
|
76540
76481
|
const repos = discoverRepos2(cwd2);
|
|
76541
76482
|
for (const repo of repos) {
|
|
76542
|
-
const hasGuidelines = existsSync82(
|
|
76543
|
-
const hasStyles = existsSync82(
|
|
76483
|
+
const hasGuidelines = existsSync82(join166(repo.path, "docs", "brand-guidelines.md"));
|
|
76484
|
+
const hasStyles = existsSync82(join166(repo.path, "assets", "writing-styles"));
|
|
76544
76485
|
if (!hasGuidelines) {
|
|
76545
76486
|
f2.warning(`${repo.name}: No docs/brand-guidelines.md — content will use generic tone.`);
|
|
76546
76487
|
contentLogger.warn(`${repo.name}: missing docs/brand-guidelines.md`);
|
|
@@ -76682,9 +76623,9 @@ __export(exports_content_subcommands, {
|
|
|
76682
76623
|
});
|
|
76683
76624
|
import { existsSync as existsSync84, readFileSync as readFileSync21, unlinkSync as unlinkSync6 } from "node:fs";
|
|
76684
76625
|
import { homedir as homedir57 } from "node:os";
|
|
76685
|
-
import { join as
|
|
76626
|
+
import { join as join167 } from "node:path";
|
|
76686
76627
|
function isDaemonRunning() {
|
|
76687
|
-
const lockFile =
|
|
76628
|
+
const lockFile = join167(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
76688
76629
|
if (!existsSync84(lockFile))
|
|
76689
76630
|
return { running: false, pid: null };
|
|
76690
76631
|
try {
|
|
@@ -76716,7 +76657,7 @@ async function startContent(options2) {
|
|
|
76716
76657
|
await contentCommand(options2);
|
|
76717
76658
|
}
|
|
76718
76659
|
async function stopContent() {
|
|
76719
|
-
const lockFile =
|
|
76660
|
+
const lockFile = join167(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
76720
76661
|
if (!existsSync84(lockFile)) {
|
|
76721
76662
|
logger.info("Content daemon is not running.");
|
|
76722
76663
|
return;
|
|
@@ -76755,9 +76696,9 @@ async function statusContent() {
|
|
|
76755
76696
|
} catch {}
|
|
76756
76697
|
}
|
|
76757
76698
|
async function logsContent(options2) {
|
|
76758
|
-
const logDir =
|
|
76699
|
+
const logDir = join167(homedir57(), ".claudekit", "logs");
|
|
76759
76700
|
const dateStr = new Date().toISOString().slice(0, 10).replace(/-/g, "");
|
|
76760
|
-
const logPath =
|
|
76701
|
+
const logPath = join167(logDir, `content-${dateStr}.log`);
|
|
76761
76702
|
if (!existsSync84(logPath)) {
|
|
76762
76703
|
logger.info("No content logs found for today.");
|
|
76763
76704
|
return;
|
|
@@ -76789,13 +76730,13 @@ var init_content_subcommands = __esm(() => {
|
|
|
76789
76730
|
init_setup_wizard();
|
|
76790
76731
|
init_state_manager();
|
|
76791
76732
|
init_content_review_commands();
|
|
76792
|
-
LOCK_DIR =
|
|
76733
|
+
LOCK_DIR = join167(homedir57(), ".claudekit", "locks");
|
|
76793
76734
|
});
|
|
76794
76735
|
|
|
76795
76736
|
// src/commands/content/content-command.ts
|
|
76796
76737
|
import { existsSync as existsSync85, mkdirSync as mkdirSync9, unlinkSync as unlinkSync7, writeFileSync as writeFileSync7 } from "node:fs";
|
|
76797
76738
|
import { homedir as homedir58 } from "node:os";
|
|
76798
|
-
import { join as
|
|
76739
|
+
import { join as join168 } from "node:path";
|
|
76799
76740
|
async function contentCommand(options2) {
|
|
76800
76741
|
const cwd2 = process.cwd();
|
|
76801
76742
|
const contentLogger = new ContentLogger;
|
|
@@ -76973,8 +76914,8 @@ var init_content_command = __esm(() => {
|
|
|
76973
76914
|
init_publisher();
|
|
76974
76915
|
init_review_manager();
|
|
76975
76916
|
init_state_manager();
|
|
76976
|
-
LOCK_DIR2 =
|
|
76977
|
-
LOCK_FILE =
|
|
76917
|
+
LOCK_DIR2 = join168(homedir58(), ".claudekit", "locks");
|
|
76918
|
+
LOCK_FILE = join168(LOCK_DIR2, "ck-content.lock");
|
|
76978
76919
|
});
|
|
76979
76920
|
|
|
76980
76921
|
// src/commands/content/index.ts
|
|
@@ -85272,7 +85213,7 @@ function buildDuplicateInventoryCheck(projectSkills, globalSkills) {
|
|
|
85272
85213
|
if (duplicates.length === 0) {
|
|
85273
85214
|
return pass("ck-skill-inventory", "Skill Inventory", "No duplicate project/global skills");
|
|
85274
85215
|
}
|
|
85275
|
-
return warn("ck-skill-inventory", "Skill Inventory", `${duplicates.length} duplicate project/global skill(s)`, duplicates, "Keep one installation scope per skill; inspect with: ck skills list --installed");
|
|
85216
|
+
return warn("ck-skill-inventory", "Skill Inventory", `${duplicates.length} duplicate project/global skill(s)`, duplicates, "Keep one installation scope per skill; inspect with: ck skills --list --installed");
|
|
85276
85217
|
}
|
|
85277
85218
|
function buildSkillOverridesCheck(settingsPath, read) {
|
|
85278
85219
|
if (!read.settings || !Object.prototype.hasOwnProperty.call(read.settings, "skillOverrides")) {
|
|
@@ -107501,7 +107442,7 @@ import { basename as basename27, join as join142, resolve as resolve46 } from "n
|
|
|
107501
107442
|
init_logger();
|
|
107502
107443
|
|
|
107503
107444
|
// src/ui/ck-cli-design/tokens.ts
|
|
107504
|
-
var import_picocolors27 = __toESM(
|
|
107445
|
+
var import_picocolors27 = __toESM(require_picocolors(), 1);
|
|
107505
107446
|
import { homedir as homedir47, platform as platform16 } from "node:os";
|
|
107506
107447
|
import { resolve as resolve45, win32 as win322 } from "node:path";
|
|
107507
107448
|
var PANEL_MIN_WIDTH = 60;
|
|
@@ -111449,14 +111390,48 @@ init_skill_catalog_generator();
|
|
|
111449
111390
|
init_skill_search_index();
|
|
111450
111391
|
init_logger();
|
|
111451
111392
|
init_agents();
|
|
111452
|
-
init_skills_discovery();
|
|
111453
|
-
init_skills_installer();
|
|
111454
|
-
init_skills_registry();
|
|
111455
|
-
init_skills_uninstaller();
|
|
111456
111393
|
var import_gray_matter12 = __toESM(require_gray_matter(), 1);
|
|
111457
111394
|
var import_picocolors37 = __toESM(require_picocolors(), 1);
|
|
111458
111395
|
import { readFile as readFile65 } from "node:fs/promises";
|
|
111396
|
+
import { join as join149 } from "node:path";
|
|
111397
|
+
|
|
111398
|
+
// src/commands/skills/installed-skills-inventory.ts
|
|
111459
111399
|
import { join as join148 } from "node:path";
|
|
111400
|
+
init_path_resolver();
|
|
111401
|
+
var SCOPE_SORT_ORDER = {
|
|
111402
|
+
project: 0,
|
|
111403
|
+
global: 1
|
|
111404
|
+
};
|
|
111405
|
+
async function getActiveClaudeSkillInstallations(options2 = {}) {
|
|
111406
|
+
const projectDir = options2.projectDir ?? process.cwd();
|
|
111407
|
+
const globalDir = options2.globalDir ?? PathResolver.getGlobalKitDir();
|
|
111408
|
+
const [projectSkills, globalSkills] = await Promise.all([
|
|
111409
|
+
scanSkills2(join148(projectDir, ".claude", "skills")),
|
|
111410
|
+
scanSkills2(join148(globalDir, "skills"))
|
|
111411
|
+
]);
|
|
111412
|
+
const projectIds = new Set(projectSkills.map((skill) => skill.id));
|
|
111413
|
+
const globalIds = new Set(globalSkills.map((skill) => skill.id));
|
|
111414
|
+
return [
|
|
111415
|
+
...projectSkills.map((skill) => ({
|
|
111416
|
+
skill: skill.id,
|
|
111417
|
+
scope: "project",
|
|
111418
|
+
path: skill.file,
|
|
111419
|
+
duplicateAcrossScopes: globalIds.has(skill.id)
|
|
111420
|
+
})),
|
|
111421
|
+
...globalSkills.map((skill) => ({
|
|
111422
|
+
skill: skill.id,
|
|
111423
|
+
scope: "global",
|
|
111424
|
+
path: skill.file,
|
|
111425
|
+
duplicateAcrossScopes: projectIds.has(skill.id)
|
|
111426
|
+
}))
|
|
111427
|
+
].sort((a3, b3) => a3.skill.localeCompare(b3.skill) || SCOPE_SORT_ORDER[a3.scope] - SCOPE_SORT_ORDER[b3.scope]);
|
|
111428
|
+
}
|
|
111429
|
+
|
|
111430
|
+
// src/commands/skills/skills-command.ts
|
|
111431
|
+
init_skills_discovery();
|
|
111432
|
+
init_skills_installer();
|
|
111433
|
+
init_skills_registry();
|
|
111434
|
+
init_skills_uninstaller();
|
|
111460
111435
|
|
|
111461
111436
|
// src/commands/skills/types.ts
|
|
111462
111437
|
init_zod();
|
|
@@ -111592,7 +111567,7 @@ async function handleValidate2(sourcePath) {
|
|
|
111592
111567
|
spinner.stop(`Checked ${skills.length} skill(s)`);
|
|
111593
111568
|
let hasIssues = false;
|
|
111594
111569
|
for (const skill of skills) {
|
|
111595
|
-
const skillMdPath =
|
|
111570
|
+
const skillMdPath = join149(skill.path, "SKILL.md");
|
|
111596
111571
|
try {
|
|
111597
111572
|
const content = await readFile65(skillMdPath, "utf-8");
|
|
111598
111573
|
const { data } = import_gray_matter12.default(content, {
|
|
@@ -111628,30 +111603,55 @@ async function detectInstalledAgents2() {
|
|
|
111628
111603
|
}
|
|
111629
111604
|
async function listSkills2(showInstalled) {
|
|
111630
111605
|
if (showInstalled) {
|
|
111631
|
-
const installations = await
|
|
111632
|
-
|
|
111633
|
-
|
|
111606
|
+
const [installations, activeClaudeSkills] = await Promise.all([
|
|
111607
|
+
getInstalledSkills(),
|
|
111608
|
+
getActiveClaudeSkillInstallations()
|
|
111609
|
+
]);
|
|
111610
|
+
if (installations.length === 0 && activeClaudeSkills.length === 0) {
|
|
111611
|
+
f2.warn("No installed skills found.");
|
|
111634
111612
|
return;
|
|
111635
111613
|
}
|
|
111636
111614
|
console.log();
|
|
111637
|
-
|
|
111638
|
-
|
|
111639
|
-
|
|
111640
|
-
|
|
111641
|
-
const
|
|
111642
|
-
|
|
111643
|
-
|
|
111615
|
+
if (activeClaudeSkills.length > 0) {
|
|
111616
|
+
f2.step(import_picocolors37.default.bold("Active Claude Code Skills"));
|
|
111617
|
+
console.log();
|
|
111618
|
+
const bySkill = new Map;
|
|
111619
|
+
for (const inst of activeClaudeSkills) {
|
|
111620
|
+
const list3 = bySkill.get(inst.skill) || [];
|
|
111621
|
+
list3.push(inst);
|
|
111622
|
+
bySkill.set(inst.skill, list3);
|
|
111623
|
+
}
|
|
111624
|
+
for (const [skill, installs] of bySkill) {
|
|
111625
|
+
const duplicate = installs.some((inst) => inst.duplicateAcrossScopes) ? ` ${import_picocolors37.default.yellow("(project/global duplicate)")}` : "";
|
|
111626
|
+
console.log(` ${import_picocolors37.default.cyan(skill)}${duplicate}`);
|
|
111627
|
+
for (const inst of installs) {
|
|
111628
|
+
console.log(` ${import_picocolors37.default.dim("→")} ${inst.scope}: ${import_picocolors37.default.dim(inst.path)}`);
|
|
111629
|
+
}
|
|
111630
|
+
}
|
|
111631
|
+
console.log();
|
|
111632
|
+
console.log(import_picocolors37.default.dim(` ${activeClaudeSkills.length} active Claude Code skill installation(s)`));
|
|
111633
|
+
console.log();
|
|
111644
111634
|
}
|
|
111645
|
-
|
|
111646
|
-
|
|
111647
|
-
|
|
111648
|
-
|
|
111649
|
-
|
|
111635
|
+
if (installations.length > 0) {
|
|
111636
|
+
f2.step(import_picocolors37.default.bold("Registry-managed Agent Skills"));
|
|
111637
|
+
console.log();
|
|
111638
|
+
const bySkill = new Map;
|
|
111639
|
+
for (const inst of installations) {
|
|
111640
|
+
const list3 = bySkill.get(inst.skill) || [];
|
|
111641
|
+
list3.push(inst);
|
|
111642
|
+
bySkill.set(inst.skill, list3);
|
|
111650
111643
|
}
|
|
111644
|
+
for (const [skill, installs] of bySkill) {
|
|
111645
|
+
console.log(` ${import_picocolors37.default.cyan(skill)}`);
|
|
111646
|
+
for (const inst of installs) {
|
|
111647
|
+
const scope = inst.global ? "global" : "project";
|
|
111648
|
+
console.log(` ${import_picocolors37.default.dim("→")} ${inst.agent} (${scope}): ${import_picocolors37.default.dim(inst.path)}`);
|
|
111649
|
+
}
|
|
111650
|
+
}
|
|
111651
|
+
console.log();
|
|
111652
|
+
console.log(import_picocolors37.default.dim(` ${installations.length} registry-managed installation(s) across ${bySkill.size} skill(s)`));
|
|
111651
111653
|
}
|
|
111652
111654
|
console.log();
|
|
111653
|
-
console.log(import_picocolors37.default.dim(` ${installations.length} installation(s) across ${bySkill.size} skill(s)`));
|
|
111654
|
-
console.log();
|
|
111655
111655
|
return;
|
|
111656
111656
|
}
|
|
111657
111657
|
const sourcePath = getSkillSourcePath();
|
|
@@ -112150,7 +112150,7 @@ async function detectInstallations() {
|
|
|
112150
112150
|
|
|
112151
112151
|
// src/commands/uninstall/removal-handler.ts
|
|
112152
112152
|
import { readdirSync as readdirSync10, rmSync as rmSync5 } from "node:fs";
|
|
112153
|
-
import { basename as basename30, join as
|
|
112153
|
+
import { basename as basename30, join as join151, resolve as resolve53, sep as sep13 } from "node:path";
|
|
112154
112154
|
init_logger();
|
|
112155
112155
|
init_safe_prompts();
|
|
112156
112156
|
init_safe_spinner();
|
|
@@ -112159,7 +112159,7 @@ var import_fs_extra41 = __toESM(require_lib(), 1);
|
|
|
112159
112159
|
// src/commands/uninstall/analysis-handler.ts
|
|
112160
112160
|
init_metadata_migration();
|
|
112161
112161
|
import { readdirSync as readdirSync9, rmSync as rmSync4 } from "node:fs";
|
|
112162
|
-
import { dirname as dirname45, join as
|
|
112162
|
+
import { dirname as dirname45, join as join150 } from "node:path";
|
|
112163
112163
|
init_logger();
|
|
112164
112164
|
init_safe_prompts();
|
|
112165
112165
|
var import_fs_extra40 = __toESM(require_lib(), 1);
|
|
@@ -112219,7 +112219,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
112219
112219
|
const remainingFiles = metadata.kits?.[remainingKit]?.files || [];
|
|
112220
112220
|
for (const file of remainingFiles) {
|
|
112221
112221
|
const relativePath = normalizeTrackedPath(file.path);
|
|
112222
|
-
if (await import_fs_extra40.pathExists(
|
|
112222
|
+
if (await import_fs_extra40.pathExists(join150(installation.path, relativePath))) {
|
|
112223
112223
|
result.retainedManifestPaths.push(relativePath);
|
|
112224
112224
|
}
|
|
112225
112225
|
}
|
|
@@ -112227,7 +112227,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
112227
112227
|
const kitFiles = metadata.kits[kit].files || [];
|
|
112228
112228
|
for (const trackedFile of kitFiles) {
|
|
112229
112229
|
const relativePath = normalizeTrackedPath(trackedFile.path);
|
|
112230
|
-
const filePath =
|
|
112230
|
+
const filePath = join150(installation.path, relativePath);
|
|
112231
112231
|
if (preservedPaths.has(relativePath)) {
|
|
112232
112232
|
result.toPreserve.push({ path: relativePath, reason: "shared with other kit" });
|
|
112233
112233
|
continue;
|
|
@@ -112260,7 +112260,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
112260
112260
|
}
|
|
112261
112261
|
for (const trackedFile of allTrackedFiles) {
|
|
112262
112262
|
const relativePath = normalizeTrackedPath(trackedFile.path);
|
|
112263
|
-
const filePath =
|
|
112263
|
+
const filePath = join150(installation.path, relativePath);
|
|
112264
112264
|
const ownershipResult = await OwnershipChecker.checkOwnership(filePath, metadata, installation.path);
|
|
112265
112265
|
if (!ownershipResult.exists)
|
|
112266
112266
|
continue;
|
|
@@ -112403,7 +112403,7 @@ async function removeInstallations(installations, options2) {
|
|
|
112403
112403
|
let removedCount = 0;
|
|
112404
112404
|
let cleanedDirs = 0;
|
|
112405
112405
|
for (const item of analysis.toDelete) {
|
|
112406
|
-
const filePath =
|
|
112406
|
+
const filePath = join151(installation.path, item.path);
|
|
112407
112407
|
if (!await import_fs_extra41.pathExists(filePath))
|
|
112408
112408
|
continue;
|
|
112409
112409
|
if (!await isPathSafeToRemove(filePath, installation.path)) {
|
|
@@ -112812,7 +112812,7 @@ ${import_picocolors40.default.bold(import_picocolors40.default.cyan(result.kitCo
|
|
|
112812
112812
|
init_logger();
|
|
112813
112813
|
import { existsSync as existsSync75 } from "node:fs";
|
|
112814
112814
|
import { rm as rm17 } from "node:fs/promises";
|
|
112815
|
-
import { join as
|
|
112815
|
+
import { join as join158 } from "node:path";
|
|
112816
112816
|
var import_picocolors41 = __toESM(require_picocolors(), 1);
|
|
112817
112817
|
|
|
112818
112818
|
// src/commands/watch/phases/implementation-runner.ts
|
|
@@ -113331,7 +113331,7 @@ function spawnAndCollect3(command, args) {
|
|
|
113331
113331
|
|
|
113332
113332
|
// src/commands/watch/phases/issue-processor.ts
|
|
113333
113333
|
import { mkdir as mkdir39, writeFile as writeFile38 } from "node:fs/promises";
|
|
113334
|
-
import { join as
|
|
113334
|
+
import { join as join154 } from "node:path";
|
|
113335
113335
|
|
|
113336
113336
|
// src/commands/watch/phases/approval-detector.ts
|
|
113337
113337
|
init_logger();
|
|
@@ -113709,9 +113709,9 @@ async function checkAwaitingApproval(state, setup, options2, watchLog, projectDi
|
|
|
113709
113709
|
|
|
113710
113710
|
// src/commands/watch/phases/plan-dir-finder.ts
|
|
113711
113711
|
import { readdir as readdir44, stat as stat23 } from "node:fs/promises";
|
|
113712
|
-
import { join as
|
|
113712
|
+
import { join as join153 } from "node:path";
|
|
113713
113713
|
async function findRecentPlanDir(cwd2, issueNumber, watchLog) {
|
|
113714
|
-
const plansRoot =
|
|
113714
|
+
const plansRoot = join153(cwd2, "plans");
|
|
113715
113715
|
try {
|
|
113716
113716
|
const entries = await readdir44(plansRoot);
|
|
113717
113717
|
const tenMinAgo = Date.now() - 10 * 60 * 1000;
|
|
@@ -113720,14 +113720,14 @@ async function findRecentPlanDir(cwd2, issueNumber, watchLog) {
|
|
|
113720
113720
|
for (const entry of entries) {
|
|
113721
113721
|
if (entry === "watch" || entry === "reports" || entry === "visuals")
|
|
113722
113722
|
continue;
|
|
113723
|
-
const dirPath =
|
|
113723
|
+
const dirPath = join153(plansRoot, entry);
|
|
113724
113724
|
const dirStat = await stat23(dirPath);
|
|
113725
113725
|
if (!dirStat.isDirectory())
|
|
113726
113726
|
continue;
|
|
113727
113727
|
if (dirStat.mtimeMs < tenMinAgo)
|
|
113728
113728
|
continue;
|
|
113729
113729
|
try {
|
|
113730
|
-
await stat23(
|
|
113730
|
+
await stat23(join153(dirPath, "plan.md"));
|
|
113731
113731
|
} catch {
|
|
113732
113732
|
continue;
|
|
113733
113733
|
}
|
|
@@ -113958,13 +113958,13 @@ async function handlePlanGeneration(issue, state, config, setup, options2, watch
|
|
|
113958
113958
|
stats.plansCreated++;
|
|
113959
113959
|
const detectedPlanDir = await findRecentPlanDir(projectDir, issue.number, watchLog);
|
|
113960
113960
|
if (detectedPlanDir) {
|
|
113961
|
-
state.activeIssues[numStr].planPath =
|
|
113961
|
+
state.activeIssues[numStr].planPath = join154(detectedPlanDir, "plan.md");
|
|
113962
113962
|
watchLog.info(`Plan directory detected: ${detectedPlanDir}`);
|
|
113963
113963
|
} else {
|
|
113964
113964
|
try {
|
|
113965
|
-
const planDir =
|
|
113965
|
+
const planDir = join154(projectDir, "plans", "watch");
|
|
113966
113966
|
await mkdir39(planDir, { recursive: true });
|
|
113967
|
-
const planFilePath =
|
|
113967
|
+
const planFilePath = join154(planDir, `issue-${issue.number}-plan.md`);
|
|
113968
113968
|
await writeFile38(planFilePath, planResult.planText, "utf-8");
|
|
113969
113969
|
state.activeIssues[numStr].planPath = planFilePath;
|
|
113970
113970
|
watchLog.info(`Plan saved (fallback) to ${planFilePath}`);
|
|
@@ -114271,18 +114271,18 @@ init_logger();
|
|
|
114271
114271
|
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
114272
114272
|
import { existsSync as existsSync72 } from "node:fs";
|
|
114273
114273
|
import { readdir as readdir45, stat as stat24 } from "node:fs/promises";
|
|
114274
|
-
import { join as
|
|
114274
|
+
import { join as join155 } from "node:path";
|
|
114275
114275
|
async function scanForRepos(parentDir) {
|
|
114276
114276
|
const repos = [];
|
|
114277
114277
|
const entries = await readdir45(parentDir);
|
|
114278
114278
|
for (const entry of entries) {
|
|
114279
114279
|
if (entry.startsWith("."))
|
|
114280
114280
|
continue;
|
|
114281
|
-
const fullPath =
|
|
114281
|
+
const fullPath = join155(parentDir, entry);
|
|
114282
114282
|
const entryStat = await stat24(fullPath);
|
|
114283
114283
|
if (!entryStat.isDirectory())
|
|
114284
114284
|
continue;
|
|
114285
|
-
const gitDir =
|
|
114285
|
+
const gitDir = join155(fullPath, ".git");
|
|
114286
114286
|
if (!existsSync72(gitDir))
|
|
114287
114287
|
continue;
|
|
114288
114288
|
const result = spawnSync7("gh", ["repo", "view", "--json", "owner,name"], {
|
|
@@ -114309,7 +114309,7 @@ init_logger();
|
|
|
114309
114309
|
import { spawnSync as spawnSync8 } from "node:child_process";
|
|
114310
114310
|
import { existsSync as existsSync73 } from "node:fs";
|
|
114311
114311
|
import { homedir as homedir52 } from "node:os";
|
|
114312
|
-
import { join as
|
|
114312
|
+
import { join as join156 } from "node:path";
|
|
114313
114313
|
async function validateSetup(cwd2) {
|
|
114314
114314
|
const workDir = cwd2 ?? process.cwd();
|
|
114315
114315
|
const ghVersion = spawnSync8("gh", ["--version"], { encoding: "utf-8", timeout: 1e4 });
|
|
@@ -114340,7 +114340,7 @@ Run this command from a directory with a GitHub remote.`);
|
|
|
114340
114340
|
} catch {
|
|
114341
114341
|
throw new Error(`Failed to parse repository info: ${ghRepo.stdout}`);
|
|
114342
114342
|
}
|
|
114343
|
-
const skillsPath =
|
|
114343
|
+
const skillsPath = join156(homedir52(), ".claude", "skills");
|
|
114344
114344
|
const skillsAvailable = existsSync73(skillsPath);
|
|
114345
114345
|
if (!skillsAvailable) {
|
|
114346
114346
|
logger.warning(`ClaudeKit Engineer skills not found at ${skillsPath}`);
|
|
@@ -114359,7 +114359,7 @@ init_path_resolver();
|
|
|
114359
114359
|
import { createWriteStream as createWriteStream3, statSync as statSync13 } from "node:fs";
|
|
114360
114360
|
import { existsSync as existsSync74 } from "node:fs";
|
|
114361
114361
|
import { mkdir as mkdir41, rename as rename13 } from "node:fs/promises";
|
|
114362
|
-
import { join as
|
|
114362
|
+
import { join as join157 } from "node:path";
|
|
114363
114363
|
|
|
114364
114364
|
class WatchLogger {
|
|
114365
114365
|
logStream = null;
|
|
@@ -114367,7 +114367,7 @@ class WatchLogger {
|
|
|
114367
114367
|
logPath = null;
|
|
114368
114368
|
maxBytes;
|
|
114369
114369
|
constructor(logDir, maxBytes = 0) {
|
|
114370
|
-
this.logDir = logDir ??
|
|
114370
|
+
this.logDir = logDir ?? join157(PathResolver.getClaudeKitDir(), "logs");
|
|
114371
114371
|
this.maxBytes = maxBytes;
|
|
114372
114372
|
}
|
|
114373
114373
|
async init() {
|
|
@@ -114376,7 +114376,7 @@ class WatchLogger {
|
|
|
114376
114376
|
await mkdir41(this.logDir, { recursive: true });
|
|
114377
114377
|
}
|
|
114378
114378
|
const dateStr = formatDate(new Date);
|
|
114379
|
-
this.logPath =
|
|
114379
|
+
this.logPath = join157(this.logDir, `watch-${dateStr}.log`);
|
|
114380
114380
|
this.logStream = createWriteStream3(this.logPath, { flags: "a", mode: 384 });
|
|
114381
114381
|
} catch (error) {
|
|
114382
114382
|
logger.warning(`Cannot create watch log file: ${error instanceof Error ? error.message : "Unknown"}`);
|
|
@@ -114558,7 +114558,7 @@ async function watchCommand(options2) {
|
|
|
114558
114558
|
}
|
|
114559
114559
|
async function discoverRepos(options2, watchLog) {
|
|
114560
114560
|
const cwd2 = process.cwd();
|
|
114561
|
-
const isGitRepo = existsSync75(
|
|
114561
|
+
const isGitRepo = existsSync75(join158(cwd2, ".git"));
|
|
114562
114562
|
if (options2.force) {
|
|
114563
114563
|
await forceRemoveLock(watchLog);
|
|
114564
114564
|
}
|
|
@@ -114816,7 +114816,7 @@ function registerCommands(cli) {
|
|
|
114816
114816
|
init_package();
|
|
114817
114817
|
init_config_version_checker();
|
|
114818
114818
|
import { existsSync as existsSync87, readFileSync as readFileSync22 } from "node:fs";
|
|
114819
|
-
import { join as
|
|
114819
|
+
import { join as join170 } from "node:path";
|
|
114820
114820
|
|
|
114821
114821
|
// src/domains/versioning/version-checker.ts
|
|
114822
114822
|
init_version_utils();
|
|
@@ -114831,14 +114831,14 @@ init_logger();
|
|
|
114831
114831
|
init_path_resolver();
|
|
114832
114832
|
import { existsSync as existsSync86 } from "node:fs";
|
|
114833
114833
|
import { mkdir as mkdir42, readFile as readFile69, writeFile as writeFile41 } from "node:fs/promises";
|
|
114834
|
-
import { join as
|
|
114834
|
+
import { join as join169 } from "node:path";
|
|
114835
114835
|
|
|
114836
114836
|
class VersionCacheManager {
|
|
114837
114837
|
static CACHE_FILENAME = "version-check.json";
|
|
114838
114838
|
static CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000;
|
|
114839
114839
|
static getCacheFile() {
|
|
114840
114840
|
const cacheDir = PathResolver.getCacheDir(false);
|
|
114841
|
-
return
|
|
114841
|
+
return join169(cacheDir, VersionCacheManager.CACHE_FILENAME);
|
|
114842
114842
|
}
|
|
114843
114843
|
static async load() {
|
|
114844
114844
|
const cacheFile = VersionCacheManager.getCacheFile();
|
|
@@ -115149,9 +115149,9 @@ async function displayVersion() {
|
|
|
115149
115149
|
let localInstalledKits = [];
|
|
115150
115150
|
let globalInstalledKits = [];
|
|
115151
115151
|
const globalKitDir = PathResolver.getGlobalKitDir();
|
|
115152
|
-
const globalMetadataPath =
|
|
115152
|
+
const globalMetadataPath = join170(globalKitDir, "metadata.json");
|
|
115153
115153
|
const prefix = PathResolver.getPathPrefix(false);
|
|
115154
|
-
const localMetadataPath = prefix ?
|
|
115154
|
+
const localMetadataPath = prefix ? join170(process.cwd(), prefix, "metadata.json") : join170(process.cwd(), "metadata.json");
|
|
115155
115155
|
const isLocalSameAsGlobal = localMetadataPath === globalMetadataPath;
|
|
115156
115156
|
if (!isLocalSameAsGlobal && existsSync87(localMetadataPath)) {
|
|
115157
115157
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claudekit-cli",
|
|
3
|
-
"version": "4.1.1",
|
|
3
|
+
"version": "4.2.1-dev.1",
|
|
4
4
|
"description": "CLI tool for bootstrapping and updating ClaudeKit projects",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"dev:all": "./scripts/dev-quick-start.sh all",
|
|
45
45
|
"metrics": "bun run scripts/workflow-metrics.ts",
|
|
46
46
|
"validate": "bun run typecheck && bun run lint && bun test && bun run ui:test && bun run build",
|
|
47
|
+
"ci:local": "bash scripts/ci-local.sh",
|
|
47
48
|
"install:hooks": "./.githooks/install.sh",
|
|
48
49
|
"prepare": "node -e \"try{require('child_process').execSync('git rev-parse --git-dir',{stdio:'ignore'});require('child_process').execSync('bash .githooks/install.sh',{stdio:'inherit'})}catch(e){console.warn('[i] Hook install skipped:',e.message)}\"",
|
|
49
50
|
"help:check-parity": "bun run scripts/check-help-parity.ts",
|