claudekit-cli 4.1.1 → 4.2.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 +180 -110
- 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.
|
|
62893
|
+
version: "4.2.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}`);
|
|
@@ -74173,9 +74184,9 @@ __export(exports_worktree_manager, {
|
|
|
74173
74184
|
});
|
|
74174
74185
|
import { existsSync as existsSync70 } from "node:fs";
|
|
74175
74186
|
import { readFile as readFile66, writeFile as writeFile37 } from "node:fs/promises";
|
|
74176
|
-
import { join as
|
|
74187
|
+
import { join as join152 } from "node:path";
|
|
74177
74188
|
async function createWorktree(projectDir, issueNumber, baseBranch) {
|
|
74178
|
-
const worktreePath =
|
|
74189
|
+
const worktreePath = join152(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
|
|
74179
74190
|
const branchName = `ck-watch/issue-${issueNumber}`;
|
|
74180
74191
|
await spawnAndCollect("git", ["fetch", "origin", baseBranch], projectDir).catch(() => {
|
|
74181
74192
|
logger.warning(`[worktree] Could not fetch origin/${baseBranch}, using local`);
|
|
@@ -74193,7 +74204,7 @@ async function createWorktree(projectDir, issueNumber, baseBranch) {
|
|
|
74193
74204
|
return worktreePath;
|
|
74194
74205
|
}
|
|
74195
74206
|
async function removeWorktree(projectDir, issueNumber) {
|
|
74196
|
-
const worktreePath =
|
|
74207
|
+
const worktreePath = join152(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
|
|
74197
74208
|
const branchName = `ck-watch/issue-${issueNumber}`;
|
|
74198
74209
|
try {
|
|
74199
74210
|
await spawnAndCollect("git", ["worktree", "remove", worktreePath, "--force"], projectDir);
|
|
@@ -74207,7 +74218,7 @@ async function listActiveWorktrees(projectDir) {
|
|
|
74207
74218
|
try {
|
|
74208
74219
|
const output2 = await spawnAndCollect("git", ["worktree", "list", "--porcelain"], projectDir);
|
|
74209
74220
|
const issueNumbers = [];
|
|
74210
|
-
const worktreePrefix =
|
|
74221
|
+
const worktreePrefix = join152(projectDir, WORKTREE_DIR, "issue-").replace(/\\/g, "/");
|
|
74211
74222
|
for (const line of output2.split(`
|
|
74212
74223
|
`)) {
|
|
74213
74224
|
if (line.startsWith("worktree ")) {
|
|
@@ -74235,7 +74246,7 @@ async function cleanupAllWorktrees(projectDir) {
|
|
|
74235
74246
|
await spawnAndCollect("git", ["worktree", "prune"], projectDir).catch(() => {});
|
|
74236
74247
|
}
|
|
74237
74248
|
async function ensureGitignore(projectDir) {
|
|
74238
|
-
const gitignorePath =
|
|
74249
|
+
const gitignorePath = join152(projectDir, ".gitignore");
|
|
74239
74250
|
try {
|
|
74240
74251
|
const content = existsSync70(gitignorePath) ? await readFile66(gitignorePath, "utf-8") : "";
|
|
74241
74252
|
if (!content.includes(".worktrees")) {
|
|
@@ -74342,7 +74353,7 @@ import { createHash as createHash9 } from "node:crypto";
|
|
|
74342
74353
|
import { existsSync as existsSync76, mkdirSync as mkdirSync5, readFileSync as readFileSync18, readdirSync as readdirSync11, statSync as statSync14 } from "node:fs";
|
|
74343
74354
|
import { rename as rename14, writeFile as writeFile39 } from "node:fs/promises";
|
|
74344
74355
|
import { homedir as homedir53 } from "node:os";
|
|
74345
|
-
import { basename as basename31, join as
|
|
74356
|
+
import { basename as basename31, join as join159 } from "node:path";
|
|
74346
74357
|
function getCachedContext(repoPath) {
|
|
74347
74358
|
const cachePath = getCacheFilePath(repoPath);
|
|
74348
74359
|
if (!existsSync76(cachePath))
|
|
@@ -74385,25 +74396,25 @@ function computeSourceHash(repoPath) {
|
|
|
74385
74396
|
}
|
|
74386
74397
|
function getDocSourcePaths(repoPath) {
|
|
74387
74398
|
const paths = [];
|
|
74388
|
-
const docsDir =
|
|
74399
|
+
const docsDir = join159(repoPath, "docs");
|
|
74389
74400
|
if (existsSync76(docsDir)) {
|
|
74390
74401
|
try {
|
|
74391
74402
|
const files = readdirSync11(docsDir);
|
|
74392
74403
|
for (const f3 of files) {
|
|
74393
74404
|
if (f3.endsWith(".md"))
|
|
74394
|
-
paths.push(
|
|
74405
|
+
paths.push(join159(docsDir, f3));
|
|
74395
74406
|
}
|
|
74396
74407
|
} catch {}
|
|
74397
74408
|
}
|
|
74398
|
-
const readme =
|
|
74409
|
+
const readme = join159(repoPath, "README.md");
|
|
74399
74410
|
if (existsSync76(readme))
|
|
74400
74411
|
paths.push(readme);
|
|
74401
|
-
const stylesDir =
|
|
74412
|
+
const stylesDir = join159(repoPath, "assets", "writing-styles");
|
|
74402
74413
|
if (existsSync76(stylesDir)) {
|
|
74403
74414
|
try {
|
|
74404
74415
|
const files = readdirSync11(stylesDir);
|
|
74405
74416
|
for (const f3 of files) {
|
|
74406
|
-
paths.push(
|
|
74417
|
+
paths.push(join159(stylesDir, f3));
|
|
74407
74418
|
}
|
|
74408
74419
|
} catch {}
|
|
74409
74420
|
}
|
|
@@ -74412,11 +74423,11 @@ function getDocSourcePaths(repoPath) {
|
|
|
74412
74423
|
function getCacheFilePath(repoPath) {
|
|
74413
74424
|
const repoName = basename31(repoPath).replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
74414
74425
|
const pathHash = createHash9("sha256").update(repoPath).digest("hex").slice(0, 8);
|
|
74415
|
-
return
|
|
74426
|
+
return join159(CACHE_DIR, `${repoName}-${pathHash}-context-cache.json`);
|
|
74416
74427
|
}
|
|
74417
74428
|
var CACHE_DIR, CACHE_TTL_MS5;
|
|
74418
74429
|
var init_context_cache_manager = __esm(() => {
|
|
74419
|
-
CACHE_DIR =
|
|
74430
|
+
CACHE_DIR = join159(homedir53(), ".claudekit", "cache");
|
|
74420
74431
|
CACHE_TTL_MS5 = 24 * 60 * 60 * 1000;
|
|
74421
74432
|
});
|
|
74422
74433
|
|
|
@@ -74597,7 +74608,7 @@ function extractContentFromResponse(response) {
|
|
|
74597
74608
|
// src/commands/content/phases/docs-summarizer.ts
|
|
74598
74609
|
import { execSync as execSync7 } from "node:child_process";
|
|
74599
74610
|
import { existsSync as existsSync77, readFileSync as readFileSync19, readdirSync as readdirSync12 } from "node:fs";
|
|
74600
|
-
import { join as
|
|
74611
|
+
import { join as join160 } from "node:path";
|
|
74601
74612
|
async function summarizeProjectDocs(repoPath, contentLogger) {
|
|
74602
74613
|
const rawContent = collectRawDocs(repoPath);
|
|
74603
74614
|
if (rawContent.total.length < 200) {
|
|
@@ -74651,12 +74662,12 @@ function collectRawDocs(repoPath) {
|
|
|
74651
74662
|
return capped;
|
|
74652
74663
|
};
|
|
74653
74664
|
const docsContent = [];
|
|
74654
|
-
const docsDir =
|
|
74665
|
+
const docsDir = join160(repoPath, "docs");
|
|
74655
74666
|
if (existsSync77(docsDir)) {
|
|
74656
74667
|
try {
|
|
74657
74668
|
const files = readdirSync12(docsDir).filter((f3) => f3.endsWith(".md")).sort();
|
|
74658
74669
|
for (const f3 of files) {
|
|
74659
|
-
const content = readCapped(
|
|
74670
|
+
const content = readCapped(join160(docsDir, f3), 5000);
|
|
74660
74671
|
if (content) {
|
|
74661
74672
|
docsContent.push(`### ${f3}
|
|
74662
74673
|
${content}`);
|
|
@@ -74670,21 +74681,21 @@ ${content}`);
|
|
|
74670
74681
|
let brand = "";
|
|
74671
74682
|
const brandCandidates = ["docs/brand-guidelines.md", "docs/design-guidelines.md"];
|
|
74672
74683
|
for (const p of brandCandidates) {
|
|
74673
|
-
brand = readCapped(
|
|
74684
|
+
brand = readCapped(join160(repoPath, p), 3000);
|
|
74674
74685
|
if (brand)
|
|
74675
74686
|
break;
|
|
74676
74687
|
}
|
|
74677
74688
|
let styles3 = "";
|
|
74678
|
-
const stylesDir =
|
|
74689
|
+
const stylesDir = join160(repoPath, "assets", "writing-styles");
|
|
74679
74690
|
if (existsSync77(stylesDir)) {
|
|
74680
74691
|
try {
|
|
74681
74692
|
const files = readdirSync12(stylesDir).slice(0, 3);
|
|
74682
|
-
styles3 = files.map((f3) => readCapped(
|
|
74693
|
+
styles3 = files.map((f3) => readCapped(join160(stylesDir, f3), 1000)).filter(Boolean).join(`
|
|
74683
74694
|
|
|
74684
74695
|
`);
|
|
74685
74696
|
} catch {}
|
|
74686
74697
|
}
|
|
74687
|
-
const readme = readCapped(
|
|
74698
|
+
const readme = readCapped(join160(repoPath, "README.md"), 3000);
|
|
74688
74699
|
const total = [docs, brand, styles3, readme].join(`
|
|
74689
74700
|
`);
|
|
74690
74701
|
return { docs, brand, styles: styles3, readme, total };
|
|
@@ -74871,9 +74882,9 @@ IMPORTANT: Generate the image and output the path as JSON: {"imagePath": "/path/
|
|
|
74871
74882
|
import { execSync as execSync8 } from "node:child_process";
|
|
74872
74883
|
import { existsSync as existsSync78, mkdirSync as mkdirSync6, readdirSync as readdirSync13 } from "node:fs";
|
|
74873
74884
|
import { homedir as homedir54 } from "node:os";
|
|
74874
|
-
import { join as
|
|
74885
|
+
import { join as join161 } from "node:path";
|
|
74875
74886
|
async function generatePhoto(_content, context, config, platform18, contentId, contentLogger) {
|
|
74876
|
-
const mediaDir =
|
|
74887
|
+
const mediaDir = join161(config.contentDir.replace(/^~/, homedir54()), "media", String(contentId));
|
|
74877
74888
|
if (!existsSync78(mediaDir)) {
|
|
74878
74889
|
mkdirSync6(mediaDir, { recursive: true });
|
|
74879
74890
|
}
|
|
@@ -74898,7 +74909,7 @@ async function generatePhoto(_content, context, config, platform18, contentId, c
|
|
|
74898
74909
|
const imageFile = files.find((f3) => /\.(png|jpg|jpeg|webp)$/i.test(f3));
|
|
74899
74910
|
if (imageFile) {
|
|
74900
74911
|
const ext2 = imageFile.split(".").pop() ?? "png";
|
|
74901
|
-
return { path:
|
|
74912
|
+
return { path: join161(mediaDir, imageFile), ...dimensions, format: ext2 };
|
|
74902
74913
|
}
|
|
74903
74914
|
contentLogger.warn(`Photo generation produced no image for content ${contentId}`);
|
|
74904
74915
|
return null;
|
|
@@ -74988,7 +74999,7 @@ var init_content_creator = __esm(() => {
|
|
|
74988
74999
|
// src/commands/content/phases/content-logger.ts
|
|
74989
75000
|
import { createWriteStream as createWriteStream4, existsSync as existsSync79, mkdirSync as mkdirSync7, statSync as statSync15 } from "node:fs";
|
|
74990
75001
|
import { homedir as homedir55 } from "node:os";
|
|
74991
|
-
import { join as
|
|
75002
|
+
import { join as join162 } from "node:path";
|
|
74992
75003
|
|
|
74993
75004
|
class ContentLogger {
|
|
74994
75005
|
stream = null;
|
|
@@ -74996,7 +75007,7 @@ class ContentLogger {
|
|
|
74996
75007
|
logDir;
|
|
74997
75008
|
maxBytes;
|
|
74998
75009
|
constructor(maxBytes = 0) {
|
|
74999
|
-
this.logDir =
|
|
75010
|
+
this.logDir = join162(homedir55(), ".claudekit", "logs");
|
|
75000
75011
|
this.maxBytes = maxBytes;
|
|
75001
75012
|
}
|
|
75002
75013
|
init() {
|
|
@@ -75028,7 +75039,7 @@ class ContentLogger {
|
|
|
75028
75039
|
}
|
|
75029
75040
|
}
|
|
75030
75041
|
getLogPath() {
|
|
75031
|
-
return
|
|
75042
|
+
return join162(this.logDir, `content-${this.getDateStr()}.log`);
|
|
75032
75043
|
}
|
|
75033
75044
|
write(level, message) {
|
|
75034
75045
|
this.rotateIfNeeded();
|
|
@@ -75045,18 +75056,18 @@ class ContentLogger {
|
|
|
75045
75056
|
if (dateStr !== this.currentDate) {
|
|
75046
75057
|
this.close();
|
|
75047
75058
|
this.currentDate = dateStr;
|
|
75048
|
-
const logPath =
|
|
75059
|
+
const logPath = join162(this.logDir, `content-${dateStr}.log`);
|
|
75049
75060
|
this.stream = createWriteStream4(logPath, { flags: "a", mode: 384 });
|
|
75050
75061
|
return;
|
|
75051
75062
|
}
|
|
75052
75063
|
if (this.maxBytes > 0 && this.stream) {
|
|
75053
|
-
const logPath =
|
|
75064
|
+
const logPath = join162(this.logDir, `content-${this.currentDate}.log`);
|
|
75054
75065
|
try {
|
|
75055
75066
|
const stat25 = statSync15(logPath);
|
|
75056
75067
|
if (stat25.size >= this.maxBytes) {
|
|
75057
75068
|
this.close();
|
|
75058
75069
|
const suffix = Date.now();
|
|
75059
|
-
const rotatedPath =
|
|
75070
|
+
const rotatedPath = join162(this.logDir, `content-${this.currentDate}-${suffix}.log`);
|
|
75060
75071
|
import("node:fs/promises").then(({ rename: rename15 }) => rename15(logPath, rotatedPath).catch(() => {}));
|
|
75061
75072
|
this.stream = createWriteStream4(logPath, { flags: "w", mode: 384 });
|
|
75062
75073
|
}
|
|
@@ -75282,7 +75293,7 @@ function isNoiseCommit(title, author) {
|
|
|
75282
75293
|
// src/commands/content/phases/change-detector.ts
|
|
75283
75294
|
import { execSync as execSync10, spawnSync as spawnSync9 } from "node:child_process";
|
|
75284
75295
|
import { existsSync as existsSync81, readFileSync as readFileSync20, readdirSync as readdirSync14, statSync as statSync16 } from "node:fs";
|
|
75285
|
-
import { join as
|
|
75296
|
+
import { join as join163 } from "node:path";
|
|
75286
75297
|
function detectCommits(repo, since) {
|
|
75287
75298
|
try {
|
|
75288
75299
|
const fetchUrl = sshToHttps(repo.remoteUrl);
|
|
@@ -75391,7 +75402,7 @@ function detectTags(repo, since) {
|
|
|
75391
75402
|
}
|
|
75392
75403
|
}
|
|
75393
75404
|
function detectCompletedPlans(repo, since) {
|
|
75394
|
-
const plansDir =
|
|
75405
|
+
const plansDir = join163(repo.path, "plans");
|
|
75395
75406
|
if (!existsSync81(plansDir))
|
|
75396
75407
|
return [];
|
|
75397
75408
|
const sinceMs = new Date(since).getTime();
|
|
@@ -75401,7 +75412,7 @@ function detectCompletedPlans(repo, since) {
|
|
|
75401
75412
|
for (const entry of entries) {
|
|
75402
75413
|
if (!entry.isDirectory())
|
|
75403
75414
|
continue;
|
|
75404
|
-
const planFile =
|
|
75415
|
+
const planFile = join163(plansDir, entry.name, "plan.md");
|
|
75405
75416
|
if (!existsSync81(planFile))
|
|
75406
75417
|
continue;
|
|
75407
75418
|
try {
|
|
@@ -75479,7 +75490,7 @@ function classifyCommit(event) {
|
|
|
75479
75490
|
// src/commands/content/phases/repo-discoverer.ts
|
|
75480
75491
|
import { execSync as execSync11 } from "node:child_process";
|
|
75481
75492
|
import { readdirSync as readdirSync15 } from "node:fs";
|
|
75482
|
-
import { join as
|
|
75493
|
+
import { join as join164 } from "node:path";
|
|
75483
75494
|
function discoverRepos2(cwd2) {
|
|
75484
75495
|
const repos = [];
|
|
75485
75496
|
if (isGitRepoRoot(cwd2)) {
|
|
@@ -75492,7 +75503,7 @@ function discoverRepos2(cwd2) {
|
|
|
75492
75503
|
for (const entry of entries) {
|
|
75493
75504
|
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
75494
75505
|
continue;
|
|
75495
|
-
const dirPath =
|
|
75506
|
+
const dirPath = join164(cwd2, entry.name);
|
|
75496
75507
|
if (isGitRepoRoot(dirPath)) {
|
|
75497
75508
|
const info = getRepoInfo(dirPath);
|
|
75498
75509
|
if (info)
|
|
@@ -76160,9 +76171,9 @@ var init_types6 = __esm(() => {
|
|
|
76160
76171
|
|
|
76161
76172
|
// src/commands/content/phases/state-manager.ts
|
|
76162
76173
|
import { readFile as readFile68, rename as rename15, writeFile as writeFile40 } from "node:fs/promises";
|
|
76163
|
-
import { join as
|
|
76174
|
+
import { join as join165 } from "node:path";
|
|
76164
76175
|
async function loadContentConfig(projectDir) {
|
|
76165
|
-
const configPath =
|
|
76176
|
+
const configPath = join165(projectDir, CK_CONFIG_FILE2);
|
|
76166
76177
|
try {
|
|
76167
76178
|
const raw2 = await readFile68(configPath, "utf-8");
|
|
76168
76179
|
const json = JSON.parse(raw2);
|
|
@@ -76172,13 +76183,13 @@ async function loadContentConfig(projectDir) {
|
|
|
76172
76183
|
}
|
|
76173
76184
|
}
|
|
76174
76185
|
async function saveContentConfig(projectDir, config) {
|
|
76175
|
-
const configPath =
|
|
76186
|
+
const configPath = join165(projectDir, CK_CONFIG_FILE2);
|
|
76176
76187
|
const json = await readJsonSafe(configPath);
|
|
76177
76188
|
json.content = { ...json.content, ...config };
|
|
76178
76189
|
await atomicWrite2(configPath, json);
|
|
76179
76190
|
}
|
|
76180
76191
|
async function loadContentState(projectDir) {
|
|
76181
|
-
const configPath =
|
|
76192
|
+
const configPath = join165(projectDir, CK_CONFIG_FILE2);
|
|
76182
76193
|
try {
|
|
76183
76194
|
const raw2 = await readFile68(configPath, "utf-8");
|
|
76184
76195
|
const json = JSON.parse(raw2);
|
|
@@ -76189,7 +76200,7 @@ async function loadContentState(projectDir) {
|
|
|
76189
76200
|
}
|
|
76190
76201
|
}
|
|
76191
76202
|
async function saveContentState(projectDir, state) {
|
|
76192
|
-
const configPath =
|
|
76203
|
+
const configPath = join165(projectDir, CK_CONFIG_FILE2);
|
|
76193
76204
|
const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().slice(0, 10);
|
|
76194
76205
|
for (const key of Object.keys(state.dailyPostCounts)) {
|
|
76195
76206
|
const dateStr = key.slice(-10);
|
|
@@ -76471,7 +76482,7 @@ var init_platform_setup_x = __esm(() => {
|
|
|
76471
76482
|
|
|
76472
76483
|
// src/commands/content/phases/setup-wizard.ts
|
|
76473
76484
|
import { existsSync as existsSync82 } from "node:fs";
|
|
76474
|
-
import { join as
|
|
76485
|
+
import { join as join166 } from "node:path";
|
|
76475
76486
|
async function runSetupWizard2(cwd2, contentLogger) {
|
|
76476
76487
|
console.log();
|
|
76477
76488
|
oe(import_picocolors43.default.bgCyan(import_picocolors43.default.white(" CK Content — Multi-Channel Content Engine ")));
|
|
@@ -76539,8 +76550,8 @@ async function showRepoSummary(cwd2) {
|
|
|
76539
76550
|
function detectBrandAssets(cwd2, contentLogger) {
|
|
76540
76551
|
const repos = discoverRepos2(cwd2);
|
|
76541
76552
|
for (const repo of repos) {
|
|
76542
|
-
const hasGuidelines = existsSync82(
|
|
76543
|
-
const hasStyles = existsSync82(
|
|
76553
|
+
const hasGuidelines = existsSync82(join166(repo.path, "docs", "brand-guidelines.md"));
|
|
76554
|
+
const hasStyles = existsSync82(join166(repo.path, "assets", "writing-styles"));
|
|
76544
76555
|
if (!hasGuidelines) {
|
|
76545
76556
|
f2.warning(`${repo.name}: No docs/brand-guidelines.md — content will use generic tone.`);
|
|
76546
76557
|
contentLogger.warn(`${repo.name}: missing docs/brand-guidelines.md`);
|
|
@@ -76682,9 +76693,9 @@ __export(exports_content_subcommands, {
|
|
|
76682
76693
|
});
|
|
76683
76694
|
import { existsSync as existsSync84, readFileSync as readFileSync21, unlinkSync as unlinkSync6 } from "node:fs";
|
|
76684
76695
|
import { homedir as homedir57 } from "node:os";
|
|
76685
|
-
import { join as
|
|
76696
|
+
import { join as join167 } from "node:path";
|
|
76686
76697
|
function isDaemonRunning() {
|
|
76687
|
-
const lockFile =
|
|
76698
|
+
const lockFile = join167(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
76688
76699
|
if (!existsSync84(lockFile))
|
|
76689
76700
|
return { running: false, pid: null };
|
|
76690
76701
|
try {
|
|
@@ -76716,7 +76727,7 @@ async function startContent(options2) {
|
|
|
76716
76727
|
await contentCommand(options2);
|
|
76717
76728
|
}
|
|
76718
76729
|
async function stopContent() {
|
|
76719
|
-
const lockFile =
|
|
76730
|
+
const lockFile = join167(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
76720
76731
|
if (!existsSync84(lockFile)) {
|
|
76721
76732
|
logger.info("Content daemon is not running.");
|
|
76722
76733
|
return;
|
|
@@ -76755,9 +76766,9 @@ async function statusContent() {
|
|
|
76755
76766
|
} catch {}
|
|
76756
76767
|
}
|
|
76757
76768
|
async function logsContent(options2) {
|
|
76758
|
-
const logDir =
|
|
76769
|
+
const logDir = join167(homedir57(), ".claudekit", "logs");
|
|
76759
76770
|
const dateStr = new Date().toISOString().slice(0, 10).replace(/-/g, "");
|
|
76760
|
-
const logPath =
|
|
76771
|
+
const logPath = join167(logDir, `content-${dateStr}.log`);
|
|
76761
76772
|
if (!existsSync84(logPath)) {
|
|
76762
76773
|
logger.info("No content logs found for today.");
|
|
76763
76774
|
return;
|
|
@@ -76789,13 +76800,13 @@ var init_content_subcommands = __esm(() => {
|
|
|
76789
76800
|
init_setup_wizard();
|
|
76790
76801
|
init_state_manager();
|
|
76791
76802
|
init_content_review_commands();
|
|
76792
|
-
LOCK_DIR =
|
|
76803
|
+
LOCK_DIR = join167(homedir57(), ".claudekit", "locks");
|
|
76793
76804
|
});
|
|
76794
76805
|
|
|
76795
76806
|
// src/commands/content/content-command.ts
|
|
76796
76807
|
import { existsSync as existsSync85, mkdirSync as mkdirSync9, unlinkSync as unlinkSync7, writeFileSync as writeFileSync7 } from "node:fs";
|
|
76797
76808
|
import { homedir as homedir58 } from "node:os";
|
|
76798
|
-
import { join as
|
|
76809
|
+
import { join as join168 } from "node:path";
|
|
76799
76810
|
async function contentCommand(options2) {
|
|
76800
76811
|
const cwd2 = process.cwd();
|
|
76801
76812
|
const contentLogger = new ContentLogger;
|
|
@@ -76973,8 +76984,8 @@ var init_content_command = __esm(() => {
|
|
|
76973
76984
|
init_publisher();
|
|
76974
76985
|
init_review_manager();
|
|
76975
76986
|
init_state_manager();
|
|
76976
|
-
LOCK_DIR2 =
|
|
76977
|
-
LOCK_FILE =
|
|
76987
|
+
LOCK_DIR2 = join168(homedir58(), ".claudekit", "locks");
|
|
76988
|
+
LOCK_FILE = join168(LOCK_DIR2, "ck-content.lock");
|
|
76978
76989
|
});
|
|
76979
76990
|
|
|
76980
76991
|
// src/commands/content/index.ts
|
|
@@ -85272,7 +85283,7 @@ function buildDuplicateInventoryCheck(projectSkills, globalSkills) {
|
|
|
85272
85283
|
if (duplicates.length === 0) {
|
|
85273
85284
|
return pass("ck-skill-inventory", "Skill Inventory", "No duplicate project/global skills");
|
|
85274
85285
|
}
|
|
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");
|
|
85286
|
+
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
85287
|
}
|
|
85277
85288
|
function buildSkillOverridesCheck(settingsPath, read) {
|
|
85278
85289
|
if (!read.settings || !Object.prototype.hasOwnProperty.call(read.settings, "skillOverrides")) {
|
|
@@ -111449,14 +111460,48 @@ init_skill_catalog_generator();
|
|
|
111449
111460
|
init_skill_search_index();
|
|
111450
111461
|
init_logger();
|
|
111451
111462
|
init_agents();
|
|
111452
|
-
init_skills_discovery();
|
|
111453
|
-
init_skills_installer();
|
|
111454
|
-
init_skills_registry();
|
|
111455
|
-
init_skills_uninstaller();
|
|
111456
111463
|
var import_gray_matter12 = __toESM(require_gray_matter(), 1);
|
|
111457
111464
|
var import_picocolors37 = __toESM(require_picocolors(), 1);
|
|
111458
111465
|
import { readFile as readFile65 } from "node:fs/promises";
|
|
111466
|
+
import { join as join149 } from "node:path";
|
|
111467
|
+
|
|
111468
|
+
// src/commands/skills/installed-skills-inventory.ts
|
|
111459
111469
|
import { join as join148 } from "node:path";
|
|
111470
|
+
init_path_resolver();
|
|
111471
|
+
var SCOPE_SORT_ORDER = {
|
|
111472
|
+
project: 0,
|
|
111473
|
+
global: 1
|
|
111474
|
+
};
|
|
111475
|
+
async function getActiveClaudeSkillInstallations(options2 = {}) {
|
|
111476
|
+
const projectDir = options2.projectDir ?? process.cwd();
|
|
111477
|
+
const globalDir = options2.globalDir ?? PathResolver.getGlobalKitDir();
|
|
111478
|
+
const [projectSkills, globalSkills] = await Promise.all([
|
|
111479
|
+
scanSkills2(join148(projectDir, ".claude", "skills")),
|
|
111480
|
+
scanSkills2(join148(globalDir, "skills"))
|
|
111481
|
+
]);
|
|
111482
|
+
const projectIds = new Set(projectSkills.map((skill) => skill.id));
|
|
111483
|
+
const globalIds = new Set(globalSkills.map((skill) => skill.id));
|
|
111484
|
+
return [
|
|
111485
|
+
...projectSkills.map((skill) => ({
|
|
111486
|
+
skill: skill.id,
|
|
111487
|
+
scope: "project",
|
|
111488
|
+
path: skill.file,
|
|
111489
|
+
duplicateAcrossScopes: globalIds.has(skill.id)
|
|
111490
|
+
})),
|
|
111491
|
+
...globalSkills.map((skill) => ({
|
|
111492
|
+
skill: skill.id,
|
|
111493
|
+
scope: "global",
|
|
111494
|
+
path: skill.file,
|
|
111495
|
+
duplicateAcrossScopes: projectIds.has(skill.id)
|
|
111496
|
+
}))
|
|
111497
|
+
].sort((a3, b3) => a3.skill.localeCompare(b3.skill) || SCOPE_SORT_ORDER[a3.scope] - SCOPE_SORT_ORDER[b3.scope]);
|
|
111498
|
+
}
|
|
111499
|
+
|
|
111500
|
+
// src/commands/skills/skills-command.ts
|
|
111501
|
+
init_skills_discovery();
|
|
111502
|
+
init_skills_installer();
|
|
111503
|
+
init_skills_registry();
|
|
111504
|
+
init_skills_uninstaller();
|
|
111460
111505
|
|
|
111461
111506
|
// src/commands/skills/types.ts
|
|
111462
111507
|
init_zod();
|
|
@@ -111592,7 +111637,7 @@ async function handleValidate2(sourcePath) {
|
|
|
111592
111637
|
spinner.stop(`Checked ${skills.length} skill(s)`);
|
|
111593
111638
|
let hasIssues = false;
|
|
111594
111639
|
for (const skill of skills) {
|
|
111595
|
-
const skillMdPath =
|
|
111640
|
+
const skillMdPath = join149(skill.path, "SKILL.md");
|
|
111596
111641
|
try {
|
|
111597
111642
|
const content = await readFile65(skillMdPath, "utf-8");
|
|
111598
111643
|
const { data } = import_gray_matter12.default(content, {
|
|
@@ -111628,30 +111673,55 @@ async function detectInstalledAgents2() {
|
|
|
111628
111673
|
}
|
|
111629
111674
|
async function listSkills2(showInstalled) {
|
|
111630
111675
|
if (showInstalled) {
|
|
111631
|
-
const installations = await
|
|
111632
|
-
|
|
111633
|
-
|
|
111676
|
+
const [installations, activeClaudeSkills] = await Promise.all([
|
|
111677
|
+
getInstalledSkills(),
|
|
111678
|
+
getActiveClaudeSkillInstallations()
|
|
111679
|
+
]);
|
|
111680
|
+
if (installations.length === 0 && activeClaudeSkills.length === 0) {
|
|
111681
|
+
f2.warn("No installed skills found.");
|
|
111634
111682
|
return;
|
|
111635
111683
|
}
|
|
111636
111684
|
console.log();
|
|
111637
|
-
|
|
111638
|
-
|
|
111639
|
-
|
|
111640
|
-
|
|
111641
|
-
const
|
|
111642
|
-
|
|
111643
|
-
|
|
111685
|
+
if (activeClaudeSkills.length > 0) {
|
|
111686
|
+
f2.step(import_picocolors37.default.bold("Active Claude Code Skills"));
|
|
111687
|
+
console.log();
|
|
111688
|
+
const bySkill = new Map;
|
|
111689
|
+
for (const inst of activeClaudeSkills) {
|
|
111690
|
+
const list3 = bySkill.get(inst.skill) || [];
|
|
111691
|
+
list3.push(inst);
|
|
111692
|
+
bySkill.set(inst.skill, list3);
|
|
111693
|
+
}
|
|
111694
|
+
for (const [skill, installs] of bySkill) {
|
|
111695
|
+
const duplicate = installs.some((inst) => inst.duplicateAcrossScopes) ? ` ${import_picocolors37.default.yellow("(project/global duplicate)")}` : "";
|
|
111696
|
+
console.log(` ${import_picocolors37.default.cyan(skill)}${duplicate}`);
|
|
111697
|
+
for (const inst of installs) {
|
|
111698
|
+
console.log(` ${import_picocolors37.default.dim("→")} ${inst.scope}: ${import_picocolors37.default.dim(inst.path)}`);
|
|
111699
|
+
}
|
|
111700
|
+
}
|
|
111701
|
+
console.log();
|
|
111702
|
+
console.log(import_picocolors37.default.dim(` ${activeClaudeSkills.length} active Claude Code skill installation(s)`));
|
|
111703
|
+
console.log();
|
|
111644
111704
|
}
|
|
111645
|
-
|
|
111646
|
-
|
|
111647
|
-
|
|
111648
|
-
|
|
111649
|
-
|
|
111705
|
+
if (installations.length > 0) {
|
|
111706
|
+
f2.step(import_picocolors37.default.bold("Registry-managed Agent Skills"));
|
|
111707
|
+
console.log();
|
|
111708
|
+
const bySkill = new Map;
|
|
111709
|
+
for (const inst of installations) {
|
|
111710
|
+
const list3 = bySkill.get(inst.skill) || [];
|
|
111711
|
+
list3.push(inst);
|
|
111712
|
+
bySkill.set(inst.skill, list3);
|
|
111650
111713
|
}
|
|
111714
|
+
for (const [skill, installs] of bySkill) {
|
|
111715
|
+
console.log(` ${import_picocolors37.default.cyan(skill)}`);
|
|
111716
|
+
for (const inst of installs) {
|
|
111717
|
+
const scope = inst.global ? "global" : "project";
|
|
111718
|
+
console.log(` ${import_picocolors37.default.dim("→")} ${inst.agent} (${scope}): ${import_picocolors37.default.dim(inst.path)}`);
|
|
111719
|
+
}
|
|
111720
|
+
}
|
|
111721
|
+
console.log();
|
|
111722
|
+
console.log(import_picocolors37.default.dim(` ${installations.length} registry-managed installation(s) across ${bySkill.size} skill(s)`));
|
|
111651
111723
|
}
|
|
111652
111724
|
console.log();
|
|
111653
|
-
console.log(import_picocolors37.default.dim(` ${installations.length} installation(s) across ${bySkill.size} skill(s)`));
|
|
111654
|
-
console.log();
|
|
111655
111725
|
return;
|
|
111656
111726
|
}
|
|
111657
111727
|
const sourcePath = getSkillSourcePath();
|
|
@@ -112150,7 +112220,7 @@ async function detectInstallations() {
|
|
|
112150
112220
|
|
|
112151
112221
|
// src/commands/uninstall/removal-handler.ts
|
|
112152
112222
|
import { readdirSync as readdirSync10, rmSync as rmSync5 } from "node:fs";
|
|
112153
|
-
import { basename as basename30, join as
|
|
112223
|
+
import { basename as basename30, join as join151, resolve as resolve53, sep as sep13 } from "node:path";
|
|
112154
112224
|
init_logger();
|
|
112155
112225
|
init_safe_prompts();
|
|
112156
112226
|
init_safe_spinner();
|
|
@@ -112159,7 +112229,7 @@ var import_fs_extra41 = __toESM(require_lib(), 1);
|
|
|
112159
112229
|
// src/commands/uninstall/analysis-handler.ts
|
|
112160
112230
|
init_metadata_migration();
|
|
112161
112231
|
import { readdirSync as readdirSync9, rmSync as rmSync4 } from "node:fs";
|
|
112162
|
-
import { dirname as dirname45, join as
|
|
112232
|
+
import { dirname as dirname45, join as join150 } from "node:path";
|
|
112163
112233
|
init_logger();
|
|
112164
112234
|
init_safe_prompts();
|
|
112165
112235
|
var import_fs_extra40 = __toESM(require_lib(), 1);
|
|
@@ -112219,7 +112289,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
112219
112289
|
const remainingFiles = metadata.kits?.[remainingKit]?.files || [];
|
|
112220
112290
|
for (const file of remainingFiles) {
|
|
112221
112291
|
const relativePath = normalizeTrackedPath(file.path);
|
|
112222
|
-
if (await import_fs_extra40.pathExists(
|
|
112292
|
+
if (await import_fs_extra40.pathExists(join150(installation.path, relativePath))) {
|
|
112223
112293
|
result.retainedManifestPaths.push(relativePath);
|
|
112224
112294
|
}
|
|
112225
112295
|
}
|
|
@@ -112227,7 +112297,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
112227
112297
|
const kitFiles = metadata.kits[kit].files || [];
|
|
112228
112298
|
for (const trackedFile of kitFiles) {
|
|
112229
112299
|
const relativePath = normalizeTrackedPath(trackedFile.path);
|
|
112230
|
-
const filePath =
|
|
112300
|
+
const filePath = join150(installation.path, relativePath);
|
|
112231
112301
|
if (preservedPaths.has(relativePath)) {
|
|
112232
112302
|
result.toPreserve.push({ path: relativePath, reason: "shared with other kit" });
|
|
112233
112303
|
continue;
|
|
@@ -112260,7 +112330,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
112260
112330
|
}
|
|
112261
112331
|
for (const trackedFile of allTrackedFiles) {
|
|
112262
112332
|
const relativePath = normalizeTrackedPath(trackedFile.path);
|
|
112263
|
-
const filePath =
|
|
112333
|
+
const filePath = join150(installation.path, relativePath);
|
|
112264
112334
|
const ownershipResult = await OwnershipChecker.checkOwnership(filePath, metadata, installation.path);
|
|
112265
112335
|
if (!ownershipResult.exists)
|
|
112266
112336
|
continue;
|
|
@@ -112403,7 +112473,7 @@ async function removeInstallations(installations, options2) {
|
|
|
112403
112473
|
let removedCount = 0;
|
|
112404
112474
|
let cleanedDirs = 0;
|
|
112405
112475
|
for (const item of analysis.toDelete) {
|
|
112406
|
-
const filePath =
|
|
112476
|
+
const filePath = join151(installation.path, item.path);
|
|
112407
112477
|
if (!await import_fs_extra41.pathExists(filePath))
|
|
112408
112478
|
continue;
|
|
112409
112479
|
if (!await isPathSafeToRemove(filePath, installation.path)) {
|
|
@@ -112812,7 +112882,7 @@ ${import_picocolors40.default.bold(import_picocolors40.default.cyan(result.kitCo
|
|
|
112812
112882
|
init_logger();
|
|
112813
112883
|
import { existsSync as existsSync75 } from "node:fs";
|
|
112814
112884
|
import { rm as rm17 } from "node:fs/promises";
|
|
112815
|
-
import { join as
|
|
112885
|
+
import { join as join158 } from "node:path";
|
|
112816
112886
|
var import_picocolors41 = __toESM(require_picocolors(), 1);
|
|
112817
112887
|
|
|
112818
112888
|
// src/commands/watch/phases/implementation-runner.ts
|
|
@@ -113331,7 +113401,7 @@ function spawnAndCollect3(command, args) {
|
|
|
113331
113401
|
|
|
113332
113402
|
// src/commands/watch/phases/issue-processor.ts
|
|
113333
113403
|
import { mkdir as mkdir39, writeFile as writeFile38 } from "node:fs/promises";
|
|
113334
|
-
import { join as
|
|
113404
|
+
import { join as join154 } from "node:path";
|
|
113335
113405
|
|
|
113336
113406
|
// src/commands/watch/phases/approval-detector.ts
|
|
113337
113407
|
init_logger();
|
|
@@ -113709,9 +113779,9 @@ async function checkAwaitingApproval(state, setup, options2, watchLog, projectDi
|
|
|
113709
113779
|
|
|
113710
113780
|
// src/commands/watch/phases/plan-dir-finder.ts
|
|
113711
113781
|
import { readdir as readdir44, stat as stat23 } from "node:fs/promises";
|
|
113712
|
-
import { join as
|
|
113782
|
+
import { join as join153 } from "node:path";
|
|
113713
113783
|
async function findRecentPlanDir(cwd2, issueNumber, watchLog) {
|
|
113714
|
-
const plansRoot =
|
|
113784
|
+
const plansRoot = join153(cwd2, "plans");
|
|
113715
113785
|
try {
|
|
113716
113786
|
const entries = await readdir44(plansRoot);
|
|
113717
113787
|
const tenMinAgo = Date.now() - 10 * 60 * 1000;
|
|
@@ -113720,14 +113790,14 @@ async function findRecentPlanDir(cwd2, issueNumber, watchLog) {
|
|
|
113720
113790
|
for (const entry of entries) {
|
|
113721
113791
|
if (entry === "watch" || entry === "reports" || entry === "visuals")
|
|
113722
113792
|
continue;
|
|
113723
|
-
const dirPath =
|
|
113793
|
+
const dirPath = join153(plansRoot, entry);
|
|
113724
113794
|
const dirStat = await stat23(dirPath);
|
|
113725
113795
|
if (!dirStat.isDirectory())
|
|
113726
113796
|
continue;
|
|
113727
113797
|
if (dirStat.mtimeMs < tenMinAgo)
|
|
113728
113798
|
continue;
|
|
113729
113799
|
try {
|
|
113730
|
-
await stat23(
|
|
113800
|
+
await stat23(join153(dirPath, "plan.md"));
|
|
113731
113801
|
} catch {
|
|
113732
113802
|
continue;
|
|
113733
113803
|
}
|
|
@@ -113958,13 +114028,13 @@ async function handlePlanGeneration(issue, state, config, setup, options2, watch
|
|
|
113958
114028
|
stats.plansCreated++;
|
|
113959
114029
|
const detectedPlanDir = await findRecentPlanDir(projectDir, issue.number, watchLog);
|
|
113960
114030
|
if (detectedPlanDir) {
|
|
113961
|
-
state.activeIssues[numStr].planPath =
|
|
114031
|
+
state.activeIssues[numStr].planPath = join154(detectedPlanDir, "plan.md");
|
|
113962
114032
|
watchLog.info(`Plan directory detected: ${detectedPlanDir}`);
|
|
113963
114033
|
} else {
|
|
113964
114034
|
try {
|
|
113965
|
-
const planDir =
|
|
114035
|
+
const planDir = join154(projectDir, "plans", "watch");
|
|
113966
114036
|
await mkdir39(planDir, { recursive: true });
|
|
113967
|
-
const planFilePath =
|
|
114037
|
+
const planFilePath = join154(planDir, `issue-${issue.number}-plan.md`);
|
|
113968
114038
|
await writeFile38(planFilePath, planResult.planText, "utf-8");
|
|
113969
114039
|
state.activeIssues[numStr].planPath = planFilePath;
|
|
113970
114040
|
watchLog.info(`Plan saved (fallback) to ${planFilePath}`);
|
|
@@ -114271,18 +114341,18 @@ init_logger();
|
|
|
114271
114341
|
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
114272
114342
|
import { existsSync as existsSync72 } from "node:fs";
|
|
114273
114343
|
import { readdir as readdir45, stat as stat24 } from "node:fs/promises";
|
|
114274
|
-
import { join as
|
|
114344
|
+
import { join as join155 } from "node:path";
|
|
114275
114345
|
async function scanForRepos(parentDir) {
|
|
114276
114346
|
const repos = [];
|
|
114277
114347
|
const entries = await readdir45(parentDir);
|
|
114278
114348
|
for (const entry of entries) {
|
|
114279
114349
|
if (entry.startsWith("."))
|
|
114280
114350
|
continue;
|
|
114281
|
-
const fullPath =
|
|
114351
|
+
const fullPath = join155(parentDir, entry);
|
|
114282
114352
|
const entryStat = await stat24(fullPath);
|
|
114283
114353
|
if (!entryStat.isDirectory())
|
|
114284
114354
|
continue;
|
|
114285
|
-
const gitDir =
|
|
114355
|
+
const gitDir = join155(fullPath, ".git");
|
|
114286
114356
|
if (!existsSync72(gitDir))
|
|
114287
114357
|
continue;
|
|
114288
114358
|
const result = spawnSync7("gh", ["repo", "view", "--json", "owner,name"], {
|
|
@@ -114309,7 +114379,7 @@ init_logger();
|
|
|
114309
114379
|
import { spawnSync as spawnSync8 } from "node:child_process";
|
|
114310
114380
|
import { existsSync as existsSync73 } from "node:fs";
|
|
114311
114381
|
import { homedir as homedir52 } from "node:os";
|
|
114312
|
-
import { join as
|
|
114382
|
+
import { join as join156 } from "node:path";
|
|
114313
114383
|
async function validateSetup(cwd2) {
|
|
114314
114384
|
const workDir = cwd2 ?? process.cwd();
|
|
114315
114385
|
const ghVersion = spawnSync8("gh", ["--version"], { encoding: "utf-8", timeout: 1e4 });
|
|
@@ -114340,7 +114410,7 @@ Run this command from a directory with a GitHub remote.`);
|
|
|
114340
114410
|
} catch {
|
|
114341
114411
|
throw new Error(`Failed to parse repository info: ${ghRepo.stdout}`);
|
|
114342
114412
|
}
|
|
114343
|
-
const skillsPath =
|
|
114413
|
+
const skillsPath = join156(homedir52(), ".claude", "skills");
|
|
114344
114414
|
const skillsAvailable = existsSync73(skillsPath);
|
|
114345
114415
|
if (!skillsAvailable) {
|
|
114346
114416
|
logger.warning(`ClaudeKit Engineer skills not found at ${skillsPath}`);
|
|
@@ -114359,7 +114429,7 @@ init_path_resolver();
|
|
|
114359
114429
|
import { createWriteStream as createWriteStream3, statSync as statSync13 } from "node:fs";
|
|
114360
114430
|
import { existsSync as existsSync74 } from "node:fs";
|
|
114361
114431
|
import { mkdir as mkdir41, rename as rename13 } from "node:fs/promises";
|
|
114362
|
-
import { join as
|
|
114432
|
+
import { join as join157 } from "node:path";
|
|
114363
114433
|
|
|
114364
114434
|
class WatchLogger {
|
|
114365
114435
|
logStream = null;
|
|
@@ -114367,7 +114437,7 @@ class WatchLogger {
|
|
|
114367
114437
|
logPath = null;
|
|
114368
114438
|
maxBytes;
|
|
114369
114439
|
constructor(logDir, maxBytes = 0) {
|
|
114370
|
-
this.logDir = logDir ??
|
|
114440
|
+
this.logDir = logDir ?? join157(PathResolver.getClaudeKitDir(), "logs");
|
|
114371
114441
|
this.maxBytes = maxBytes;
|
|
114372
114442
|
}
|
|
114373
114443
|
async init() {
|
|
@@ -114376,7 +114446,7 @@ class WatchLogger {
|
|
|
114376
114446
|
await mkdir41(this.logDir, { recursive: true });
|
|
114377
114447
|
}
|
|
114378
114448
|
const dateStr = formatDate(new Date);
|
|
114379
|
-
this.logPath =
|
|
114449
|
+
this.logPath = join157(this.logDir, `watch-${dateStr}.log`);
|
|
114380
114450
|
this.logStream = createWriteStream3(this.logPath, { flags: "a", mode: 384 });
|
|
114381
114451
|
} catch (error) {
|
|
114382
114452
|
logger.warning(`Cannot create watch log file: ${error instanceof Error ? error.message : "Unknown"}`);
|
|
@@ -114558,7 +114628,7 @@ async function watchCommand(options2) {
|
|
|
114558
114628
|
}
|
|
114559
114629
|
async function discoverRepos(options2, watchLog) {
|
|
114560
114630
|
const cwd2 = process.cwd();
|
|
114561
|
-
const isGitRepo = existsSync75(
|
|
114631
|
+
const isGitRepo = existsSync75(join158(cwd2, ".git"));
|
|
114562
114632
|
if (options2.force) {
|
|
114563
114633
|
await forceRemoveLock(watchLog);
|
|
114564
114634
|
}
|
|
@@ -114816,7 +114886,7 @@ function registerCommands(cli) {
|
|
|
114816
114886
|
init_package();
|
|
114817
114887
|
init_config_version_checker();
|
|
114818
114888
|
import { existsSync as existsSync87, readFileSync as readFileSync22 } from "node:fs";
|
|
114819
|
-
import { join as
|
|
114889
|
+
import { join as join170 } from "node:path";
|
|
114820
114890
|
|
|
114821
114891
|
// src/domains/versioning/version-checker.ts
|
|
114822
114892
|
init_version_utils();
|
|
@@ -114831,14 +114901,14 @@ init_logger();
|
|
|
114831
114901
|
init_path_resolver();
|
|
114832
114902
|
import { existsSync as existsSync86 } from "node:fs";
|
|
114833
114903
|
import { mkdir as mkdir42, readFile as readFile69, writeFile as writeFile41 } from "node:fs/promises";
|
|
114834
|
-
import { join as
|
|
114904
|
+
import { join as join169 } from "node:path";
|
|
114835
114905
|
|
|
114836
114906
|
class VersionCacheManager {
|
|
114837
114907
|
static CACHE_FILENAME = "version-check.json";
|
|
114838
114908
|
static CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000;
|
|
114839
114909
|
static getCacheFile() {
|
|
114840
114910
|
const cacheDir = PathResolver.getCacheDir(false);
|
|
114841
|
-
return
|
|
114911
|
+
return join169(cacheDir, VersionCacheManager.CACHE_FILENAME);
|
|
114842
114912
|
}
|
|
114843
114913
|
static async load() {
|
|
114844
114914
|
const cacheFile = VersionCacheManager.getCacheFile();
|
|
@@ -115149,9 +115219,9 @@ async function displayVersion() {
|
|
|
115149
115219
|
let localInstalledKits = [];
|
|
115150
115220
|
let globalInstalledKits = [];
|
|
115151
115221
|
const globalKitDir = PathResolver.getGlobalKitDir();
|
|
115152
|
-
const globalMetadataPath =
|
|
115222
|
+
const globalMetadataPath = join170(globalKitDir, "metadata.json");
|
|
115153
115223
|
const prefix = PathResolver.getPathPrefix(false);
|
|
115154
|
-
const localMetadataPath = prefix ?
|
|
115224
|
+
const localMetadataPath = prefix ? join170(process.cwd(), prefix, "metadata.json") : join170(process.cwd(), "metadata.json");
|
|
115155
115225
|
const isLocalSameAsGlobal = localMetadataPath === globalMetadataPath;
|
|
115156
115226
|
if (!isLocalSameAsGlobal && existsSync87(localMetadataPath)) {
|
|
115157
115227
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claudekit-cli",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.2.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",
|