claudekit-cli 3.41.4-dev.44 → 3.41.4-dev.46
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 +317 -164
- package/package.json +1 -1
package/cli-manifest.json
CHANGED
package/dist/index.js
CHANGED
|
@@ -6907,6 +6907,9 @@ var init_checksum_utils = __esm(() => {
|
|
|
6907
6907
|
function setTaxonomyOverrides(overrides) {
|
|
6908
6908
|
userOverrides = overrides;
|
|
6909
6909
|
}
|
|
6910
|
+
function getOpenCodeDefaultModelOverride() {
|
|
6911
|
+
return userOverrides?.opencode?.default?.model;
|
|
6912
|
+
}
|
|
6910
6913
|
function resolveModel(sourceModel, targetProvider) {
|
|
6911
6914
|
if (sourceModel === undefined || sourceModel === null) {
|
|
6912
6915
|
return { resolved: null };
|
|
@@ -6941,7 +6944,7 @@ function resolveModel(sourceModel, targetProvider) {
|
|
|
6941
6944
|
}
|
|
6942
6945
|
return { resolved: providerMap[tier] };
|
|
6943
6946
|
}
|
|
6944
|
-
var SOURCE_TIER_MAP, DEFAULT_PROVIDER_MODEL_MAP, userOverrides;
|
|
6947
|
+
var OPENCODE_DEFAULT_MODEL = "anthropic/claude-sonnet-4-6", SOURCE_TIER_MAP, DEFAULT_PROVIDER_MODEL_MAP, userOverrides;
|
|
6945
6948
|
var init_model_taxonomy = __esm(() => {
|
|
6946
6949
|
SOURCE_TIER_MAP = {
|
|
6947
6950
|
opus: "heavy",
|
|
@@ -50778,10 +50781,24 @@ function registerHealthRoutes(app) {
|
|
|
50778
50781
|
res.json({
|
|
50779
50782
|
status: "ok",
|
|
50780
50783
|
timestamp: new Date().toISOString(),
|
|
50781
|
-
uptime: process.uptime()
|
|
50784
|
+
uptime: process.uptime(),
|
|
50785
|
+
features: DASHBOARD_FEATURES
|
|
50782
50786
|
});
|
|
50783
50787
|
});
|
|
50784
50788
|
}
|
|
50789
|
+
var DASHBOARD_FEATURES;
|
|
50790
|
+
var init_health_routes = __esm(() => {
|
|
50791
|
+
DASHBOARD_FEATURES = [
|
|
50792
|
+
"plans-dashboard",
|
|
50793
|
+
"workflows",
|
|
50794
|
+
"migrate",
|
|
50795
|
+
"statusline",
|
|
50796
|
+
"skills",
|
|
50797
|
+
"agents",
|
|
50798
|
+
"commands",
|
|
50799
|
+
"mcp"
|
|
50800
|
+
];
|
|
50801
|
+
});
|
|
50785
50802
|
|
|
50786
50803
|
// src/domains/web-server/routes/hook-log-routes.ts
|
|
50787
50804
|
function parseLimit(value) {
|
|
@@ -60755,7 +60772,7 @@ var package_default;
|
|
|
60755
60772
|
var init_package = __esm(() => {
|
|
60756
60773
|
package_default = {
|
|
60757
60774
|
name: "claudekit-cli",
|
|
60758
|
-
version: "3.41.4-dev.
|
|
60775
|
+
version: "3.41.4-dev.46",
|
|
60759
60776
|
description: "CLI tool for bootstrapping and updating ClaudeKit projects",
|
|
60760
60777
|
type: "module",
|
|
60761
60778
|
repository: {
|
|
@@ -63774,6 +63791,7 @@ var init_routes = __esm(() => {
|
|
|
63774
63791
|
init_ck_config_routes();
|
|
63775
63792
|
init_command_routes();
|
|
63776
63793
|
init_dashboard_routes();
|
|
63794
|
+
init_health_routes();
|
|
63777
63795
|
init_hook_log_routes();
|
|
63778
63796
|
init_mcp_routes();
|
|
63779
63797
|
init_migration_routes();
|
|
@@ -71885,10 +71903,10 @@ __export(exports_worktree_manager, {
|
|
|
71885
71903
|
cleanupAllWorktrees: () => cleanupAllWorktrees
|
|
71886
71904
|
});
|
|
71887
71905
|
import { existsSync as existsSync67 } from "node:fs";
|
|
71888
|
-
import { readFile as
|
|
71889
|
-
import { join as
|
|
71906
|
+
import { readFile as readFile62, writeFile as writeFile34 } from "node:fs/promises";
|
|
71907
|
+
import { join as join149 } from "node:path";
|
|
71890
71908
|
async function createWorktree(projectDir, issueNumber, baseBranch) {
|
|
71891
|
-
const worktreePath =
|
|
71909
|
+
const worktreePath = join149(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
|
|
71892
71910
|
const branchName = `ck-watch/issue-${issueNumber}`;
|
|
71893
71911
|
await spawnAndCollect("git", ["fetch", "origin", baseBranch], projectDir).catch(() => {
|
|
71894
71912
|
logger.warning(`[worktree] Could not fetch origin/${baseBranch}, using local`);
|
|
@@ -71906,7 +71924,7 @@ async function createWorktree(projectDir, issueNumber, baseBranch) {
|
|
|
71906
71924
|
return worktreePath;
|
|
71907
71925
|
}
|
|
71908
71926
|
async function removeWorktree(projectDir, issueNumber) {
|
|
71909
|
-
const worktreePath =
|
|
71927
|
+
const worktreePath = join149(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
|
|
71910
71928
|
const branchName = `ck-watch/issue-${issueNumber}`;
|
|
71911
71929
|
try {
|
|
71912
71930
|
await spawnAndCollect("git", ["worktree", "remove", worktreePath, "--force"], projectDir);
|
|
@@ -71920,7 +71938,7 @@ async function listActiveWorktrees(projectDir) {
|
|
|
71920
71938
|
try {
|
|
71921
71939
|
const output2 = await spawnAndCollect("git", ["worktree", "list", "--porcelain"], projectDir);
|
|
71922
71940
|
const issueNumbers = [];
|
|
71923
|
-
const worktreePrefix =
|
|
71941
|
+
const worktreePrefix = join149(projectDir, WORKTREE_DIR, "issue-").replace(/\\/g, "/");
|
|
71924
71942
|
for (const line of output2.split(`
|
|
71925
71943
|
`)) {
|
|
71926
71944
|
if (line.startsWith("worktree ")) {
|
|
@@ -71948,16 +71966,16 @@ async function cleanupAllWorktrees(projectDir) {
|
|
|
71948
71966
|
await spawnAndCollect("git", ["worktree", "prune"], projectDir).catch(() => {});
|
|
71949
71967
|
}
|
|
71950
71968
|
async function ensureGitignore(projectDir) {
|
|
71951
|
-
const gitignorePath =
|
|
71969
|
+
const gitignorePath = join149(projectDir, ".gitignore");
|
|
71952
71970
|
try {
|
|
71953
|
-
const content = existsSync67(gitignorePath) ? await
|
|
71971
|
+
const content = existsSync67(gitignorePath) ? await readFile62(gitignorePath, "utf-8") : "";
|
|
71954
71972
|
if (!content.includes(".worktrees")) {
|
|
71955
71973
|
const newContent = content.endsWith(`
|
|
71956
71974
|
`) ? `${content}.worktrees/
|
|
71957
71975
|
` : `${content}
|
|
71958
71976
|
.worktrees/
|
|
71959
71977
|
`;
|
|
71960
|
-
await
|
|
71978
|
+
await writeFile34(gitignorePath, newContent, "utf-8");
|
|
71961
71979
|
logger.info("[worktree] Added .worktrees/ to .gitignore");
|
|
71962
71980
|
}
|
|
71963
71981
|
} catch (err) {
|
|
@@ -72053,9 +72071,9 @@ var init_content_validator = __esm(() => {
|
|
|
72053
72071
|
// src/commands/content/phases/context-cache-manager.ts
|
|
72054
72072
|
import { createHash as createHash8 } from "node:crypto";
|
|
72055
72073
|
import { existsSync as existsSync73, mkdirSync as mkdirSync5, readFileSync as readFileSync18, readdirSync as readdirSync10, statSync as statSync13 } from "node:fs";
|
|
72056
|
-
import { rename as rename12, writeFile as
|
|
72057
|
-
import { homedir as
|
|
72058
|
-
import { basename as basename30, join as
|
|
72074
|
+
import { rename as rename12, writeFile as writeFile36 } from "node:fs/promises";
|
|
72075
|
+
import { homedir as homedir49 } from "node:os";
|
|
72076
|
+
import { basename as basename30, join as join156 } from "node:path";
|
|
72059
72077
|
function getCachedContext(repoPath) {
|
|
72060
72078
|
const cachePath = getCacheFilePath(repoPath);
|
|
72061
72079
|
if (!existsSync73(cachePath))
|
|
@@ -72080,7 +72098,7 @@ async function saveCachedContext(repoPath, cache5) {
|
|
|
72080
72098
|
}
|
|
72081
72099
|
const cachePath = getCacheFilePath(repoPath);
|
|
72082
72100
|
const tmpPath = `${cachePath}.tmp`;
|
|
72083
|
-
await
|
|
72101
|
+
await writeFile36(tmpPath, JSON.stringify(cache5, null, 2), "utf-8");
|
|
72084
72102
|
await rename12(tmpPath, cachePath);
|
|
72085
72103
|
}
|
|
72086
72104
|
function computeSourceHash(repoPath) {
|
|
@@ -72098,25 +72116,25 @@ function computeSourceHash(repoPath) {
|
|
|
72098
72116
|
}
|
|
72099
72117
|
function getDocSourcePaths(repoPath) {
|
|
72100
72118
|
const paths = [];
|
|
72101
|
-
const docsDir =
|
|
72119
|
+
const docsDir = join156(repoPath, "docs");
|
|
72102
72120
|
if (existsSync73(docsDir)) {
|
|
72103
72121
|
try {
|
|
72104
72122
|
const files = readdirSync10(docsDir);
|
|
72105
72123
|
for (const f3 of files) {
|
|
72106
72124
|
if (f3.endsWith(".md"))
|
|
72107
|
-
paths.push(
|
|
72125
|
+
paths.push(join156(docsDir, f3));
|
|
72108
72126
|
}
|
|
72109
72127
|
} catch {}
|
|
72110
72128
|
}
|
|
72111
|
-
const readme =
|
|
72129
|
+
const readme = join156(repoPath, "README.md");
|
|
72112
72130
|
if (existsSync73(readme))
|
|
72113
72131
|
paths.push(readme);
|
|
72114
|
-
const stylesDir =
|
|
72132
|
+
const stylesDir = join156(repoPath, "assets", "writing-styles");
|
|
72115
72133
|
if (existsSync73(stylesDir)) {
|
|
72116
72134
|
try {
|
|
72117
72135
|
const files = readdirSync10(stylesDir);
|
|
72118
72136
|
for (const f3 of files) {
|
|
72119
|
-
paths.push(
|
|
72137
|
+
paths.push(join156(stylesDir, f3));
|
|
72120
72138
|
}
|
|
72121
72139
|
} catch {}
|
|
72122
72140
|
}
|
|
@@ -72125,11 +72143,11 @@ function getDocSourcePaths(repoPath) {
|
|
|
72125
72143
|
function getCacheFilePath(repoPath) {
|
|
72126
72144
|
const repoName = basename30(repoPath).replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
72127
72145
|
const pathHash = createHash8("sha256").update(repoPath).digest("hex").slice(0, 8);
|
|
72128
|
-
return
|
|
72146
|
+
return join156(CACHE_DIR, `${repoName}-${pathHash}-context-cache.json`);
|
|
72129
72147
|
}
|
|
72130
72148
|
var CACHE_DIR, CACHE_TTL_MS4;
|
|
72131
72149
|
var init_context_cache_manager = __esm(() => {
|
|
72132
|
-
CACHE_DIR =
|
|
72150
|
+
CACHE_DIR = join156(homedir49(), ".claudekit", "cache");
|
|
72133
72151
|
CACHE_TTL_MS4 = 24 * 60 * 60 * 1000;
|
|
72134
72152
|
});
|
|
72135
72153
|
|
|
@@ -72310,7 +72328,7 @@ function extractContentFromResponse(response) {
|
|
|
72310
72328
|
// src/commands/content/phases/docs-summarizer.ts
|
|
72311
72329
|
import { execSync as execSync7 } from "node:child_process";
|
|
72312
72330
|
import { existsSync as existsSync74, readFileSync as readFileSync19, readdirSync as readdirSync11 } from "node:fs";
|
|
72313
|
-
import { join as
|
|
72331
|
+
import { join as join157 } from "node:path";
|
|
72314
72332
|
async function summarizeProjectDocs(repoPath, contentLogger) {
|
|
72315
72333
|
const rawContent = collectRawDocs(repoPath);
|
|
72316
72334
|
if (rawContent.total.length < 200) {
|
|
@@ -72364,12 +72382,12 @@ function collectRawDocs(repoPath) {
|
|
|
72364
72382
|
return capped;
|
|
72365
72383
|
};
|
|
72366
72384
|
const docsContent = [];
|
|
72367
|
-
const docsDir =
|
|
72385
|
+
const docsDir = join157(repoPath, "docs");
|
|
72368
72386
|
if (existsSync74(docsDir)) {
|
|
72369
72387
|
try {
|
|
72370
72388
|
const files = readdirSync11(docsDir).filter((f3) => f3.endsWith(".md")).sort();
|
|
72371
72389
|
for (const f3 of files) {
|
|
72372
|
-
const content = readCapped(
|
|
72390
|
+
const content = readCapped(join157(docsDir, f3), 5000);
|
|
72373
72391
|
if (content) {
|
|
72374
72392
|
docsContent.push(`### ${f3}
|
|
72375
72393
|
${content}`);
|
|
@@ -72383,21 +72401,21 @@ ${content}`);
|
|
|
72383
72401
|
let brand = "";
|
|
72384
72402
|
const brandCandidates = ["docs/brand-guidelines.md", "docs/design-guidelines.md"];
|
|
72385
72403
|
for (const p of brandCandidates) {
|
|
72386
|
-
brand = readCapped(
|
|
72404
|
+
brand = readCapped(join157(repoPath, p), 3000);
|
|
72387
72405
|
if (brand)
|
|
72388
72406
|
break;
|
|
72389
72407
|
}
|
|
72390
72408
|
let styles3 = "";
|
|
72391
|
-
const stylesDir =
|
|
72409
|
+
const stylesDir = join157(repoPath, "assets", "writing-styles");
|
|
72392
72410
|
if (existsSync74(stylesDir)) {
|
|
72393
72411
|
try {
|
|
72394
72412
|
const files = readdirSync11(stylesDir).slice(0, 3);
|
|
72395
|
-
styles3 = files.map((f3) => readCapped(
|
|
72413
|
+
styles3 = files.map((f3) => readCapped(join157(stylesDir, f3), 1000)).filter(Boolean).join(`
|
|
72396
72414
|
|
|
72397
72415
|
`);
|
|
72398
72416
|
} catch {}
|
|
72399
72417
|
}
|
|
72400
|
-
const readme = readCapped(
|
|
72418
|
+
const readme = readCapped(join157(repoPath, "README.md"), 3000);
|
|
72401
72419
|
const total = [docs, brand, styles3, readme].join(`
|
|
72402
72420
|
`);
|
|
72403
72421
|
return { docs, brand, styles: styles3, readme, total };
|
|
@@ -72583,10 +72601,10 @@ IMPORTANT: Generate the image and output the path as JSON: {"imagePath": "/path/
|
|
|
72583
72601
|
// src/commands/content/phases/photo-generator.ts
|
|
72584
72602
|
import { execSync as execSync8 } from "node:child_process";
|
|
72585
72603
|
import { existsSync as existsSync75, mkdirSync as mkdirSync6, readdirSync as readdirSync12 } from "node:fs";
|
|
72586
|
-
import { homedir as
|
|
72587
|
-
import { join as
|
|
72604
|
+
import { homedir as homedir50 } from "node:os";
|
|
72605
|
+
import { join as join158 } from "node:path";
|
|
72588
72606
|
async function generatePhoto(_content, context, config, platform17, contentId, contentLogger) {
|
|
72589
|
-
const mediaDir =
|
|
72607
|
+
const mediaDir = join158(config.contentDir.replace(/^~/, homedir50()), "media", String(contentId));
|
|
72590
72608
|
if (!existsSync75(mediaDir)) {
|
|
72591
72609
|
mkdirSync6(mediaDir, { recursive: true });
|
|
72592
72610
|
}
|
|
@@ -72611,7 +72629,7 @@ async function generatePhoto(_content, context, config, platform17, contentId, c
|
|
|
72611
72629
|
const imageFile = files.find((f3) => /\.(png|jpg|jpeg|webp)$/i.test(f3));
|
|
72612
72630
|
if (imageFile) {
|
|
72613
72631
|
const ext2 = imageFile.split(".").pop() ?? "png";
|
|
72614
|
-
return { path:
|
|
72632
|
+
return { path: join158(mediaDir, imageFile), ...dimensions, format: ext2 };
|
|
72615
72633
|
}
|
|
72616
72634
|
contentLogger.warn(`Photo generation produced no image for content ${contentId}`);
|
|
72617
72635
|
return null;
|
|
@@ -72700,8 +72718,8 @@ var init_content_creator = __esm(() => {
|
|
|
72700
72718
|
|
|
72701
72719
|
// src/commands/content/phases/content-logger.ts
|
|
72702
72720
|
import { createWriteStream as createWriteStream4, existsSync as existsSync76, mkdirSync as mkdirSync7, statSync as statSync14 } from "node:fs";
|
|
72703
|
-
import { homedir as
|
|
72704
|
-
import { join as
|
|
72721
|
+
import { homedir as homedir51 } from "node:os";
|
|
72722
|
+
import { join as join159 } from "node:path";
|
|
72705
72723
|
|
|
72706
72724
|
class ContentLogger {
|
|
72707
72725
|
stream = null;
|
|
@@ -72709,7 +72727,7 @@ class ContentLogger {
|
|
|
72709
72727
|
logDir;
|
|
72710
72728
|
maxBytes;
|
|
72711
72729
|
constructor(maxBytes = 0) {
|
|
72712
|
-
this.logDir =
|
|
72730
|
+
this.logDir = join159(homedir51(), ".claudekit", "logs");
|
|
72713
72731
|
this.maxBytes = maxBytes;
|
|
72714
72732
|
}
|
|
72715
72733
|
init() {
|
|
@@ -72741,7 +72759,7 @@ class ContentLogger {
|
|
|
72741
72759
|
}
|
|
72742
72760
|
}
|
|
72743
72761
|
getLogPath() {
|
|
72744
|
-
return
|
|
72762
|
+
return join159(this.logDir, `content-${this.getDateStr()}.log`);
|
|
72745
72763
|
}
|
|
72746
72764
|
write(level, message) {
|
|
72747
72765
|
this.rotateIfNeeded();
|
|
@@ -72758,18 +72776,18 @@ class ContentLogger {
|
|
|
72758
72776
|
if (dateStr !== this.currentDate) {
|
|
72759
72777
|
this.close();
|
|
72760
72778
|
this.currentDate = dateStr;
|
|
72761
|
-
const logPath =
|
|
72779
|
+
const logPath = join159(this.logDir, `content-${dateStr}.log`);
|
|
72762
72780
|
this.stream = createWriteStream4(logPath, { flags: "a", mode: 384 });
|
|
72763
72781
|
return;
|
|
72764
72782
|
}
|
|
72765
72783
|
if (this.maxBytes > 0 && this.stream) {
|
|
72766
|
-
const logPath =
|
|
72784
|
+
const logPath = join159(this.logDir, `content-${this.currentDate}.log`);
|
|
72767
72785
|
try {
|
|
72768
72786
|
const stat25 = statSync14(logPath);
|
|
72769
72787
|
if (stat25.size >= this.maxBytes) {
|
|
72770
72788
|
this.close();
|
|
72771
72789
|
const suffix = Date.now();
|
|
72772
|
-
const rotatedPath =
|
|
72790
|
+
const rotatedPath = join159(this.logDir, `content-${this.currentDate}-${suffix}.log`);
|
|
72773
72791
|
import("node:fs/promises").then(({ rename: rename13 }) => rename13(logPath, rotatedPath).catch(() => {}));
|
|
72774
72792
|
this.stream = createWriteStream4(logPath, { flags: "w", mode: 384 });
|
|
72775
72793
|
}
|
|
@@ -72807,7 +72825,7 @@ var init_sqlite_client = () => {};
|
|
|
72807
72825
|
|
|
72808
72826
|
// src/commands/content/phases/db-manager.ts
|
|
72809
72827
|
import { existsSync as existsSync77, mkdirSync as mkdirSync8 } from "node:fs";
|
|
72810
|
-
import { dirname as
|
|
72828
|
+
import { dirname as dirname46 } from "node:path";
|
|
72811
72829
|
function initDatabase(dbPath) {
|
|
72812
72830
|
ensureParentDir(dbPath);
|
|
72813
72831
|
const db = openDatabase(dbPath);
|
|
@@ -72828,7 +72846,7 @@ function runRetentionCleanup(db, retentionDays = 90) {
|
|
|
72828
72846
|
db.prepare("DELETE FROM git_events WHERE processed = 1 AND created_at < ?").run(cutoff);
|
|
72829
72847
|
}
|
|
72830
72848
|
function ensureParentDir(dbPath) {
|
|
72831
|
-
const dir =
|
|
72849
|
+
const dir = dirname46(dbPath);
|
|
72832
72850
|
if (dir && !existsSync77(dir)) {
|
|
72833
72851
|
mkdirSync8(dir, { recursive: true });
|
|
72834
72852
|
}
|
|
@@ -72995,7 +73013,7 @@ function isNoiseCommit(title, author) {
|
|
|
72995
73013
|
// src/commands/content/phases/change-detector.ts
|
|
72996
73014
|
import { execSync as execSync10, spawnSync as spawnSync9 } from "node:child_process";
|
|
72997
73015
|
import { existsSync as existsSync78, readFileSync as readFileSync20, readdirSync as readdirSync13, statSync as statSync15 } from "node:fs";
|
|
72998
|
-
import { join as
|
|
73016
|
+
import { join as join160 } from "node:path";
|
|
72999
73017
|
function detectCommits(repo, since) {
|
|
73000
73018
|
try {
|
|
73001
73019
|
const fetchUrl = sshToHttps(repo.remoteUrl);
|
|
@@ -73104,7 +73122,7 @@ function detectTags(repo, since) {
|
|
|
73104
73122
|
}
|
|
73105
73123
|
}
|
|
73106
73124
|
function detectCompletedPlans(repo, since) {
|
|
73107
|
-
const plansDir =
|
|
73125
|
+
const plansDir = join160(repo.path, "plans");
|
|
73108
73126
|
if (!existsSync78(plansDir))
|
|
73109
73127
|
return [];
|
|
73110
73128
|
const sinceMs = new Date(since).getTime();
|
|
@@ -73114,7 +73132,7 @@ function detectCompletedPlans(repo, since) {
|
|
|
73114
73132
|
for (const entry of entries) {
|
|
73115
73133
|
if (!entry.isDirectory())
|
|
73116
73134
|
continue;
|
|
73117
|
-
const planFile =
|
|
73135
|
+
const planFile = join160(plansDir, entry.name, "plan.md");
|
|
73118
73136
|
if (!existsSync78(planFile))
|
|
73119
73137
|
continue;
|
|
73120
73138
|
try {
|
|
@@ -73192,7 +73210,7 @@ function classifyCommit(event) {
|
|
|
73192
73210
|
// src/commands/content/phases/repo-discoverer.ts
|
|
73193
73211
|
import { execSync as execSync11 } from "node:child_process";
|
|
73194
73212
|
import { readdirSync as readdirSync14 } from "node:fs";
|
|
73195
|
-
import { join as
|
|
73213
|
+
import { join as join161 } from "node:path";
|
|
73196
73214
|
function discoverRepos2(cwd2) {
|
|
73197
73215
|
const repos = [];
|
|
73198
73216
|
if (isGitRepoRoot(cwd2)) {
|
|
@@ -73205,7 +73223,7 @@ function discoverRepos2(cwd2) {
|
|
|
73205
73223
|
for (const entry of entries) {
|
|
73206
73224
|
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
73207
73225
|
continue;
|
|
73208
|
-
const dirPath =
|
|
73226
|
+
const dirPath = join161(cwd2, entry.name);
|
|
73209
73227
|
if (isGitRepoRoot(dirPath)) {
|
|
73210
73228
|
const info = getRepoInfo(dirPath);
|
|
73211
73229
|
if (info)
|
|
@@ -73872,12 +73890,12 @@ var init_types6 = __esm(() => {
|
|
|
73872
73890
|
});
|
|
73873
73891
|
|
|
73874
73892
|
// src/commands/content/phases/state-manager.ts
|
|
73875
|
-
import { readFile as
|
|
73876
|
-
import { join as
|
|
73893
|
+
import { readFile as readFile64, rename as rename13, writeFile as writeFile37 } from "node:fs/promises";
|
|
73894
|
+
import { join as join162 } from "node:path";
|
|
73877
73895
|
async function loadContentConfig(projectDir) {
|
|
73878
|
-
const configPath =
|
|
73896
|
+
const configPath = join162(projectDir, CK_CONFIG_FILE2);
|
|
73879
73897
|
try {
|
|
73880
|
-
const raw2 = await
|
|
73898
|
+
const raw2 = await readFile64(configPath, "utf-8");
|
|
73881
73899
|
const json = JSON.parse(raw2);
|
|
73882
73900
|
return ContentConfigSchema.parse(json.content ?? {});
|
|
73883
73901
|
} catch {
|
|
@@ -73885,15 +73903,15 @@ async function loadContentConfig(projectDir) {
|
|
|
73885
73903
|
}
|
|
73886
73904
|
}
|
|
73887
73905
|
async function saveContentConfig(projectDir, config) {
|
|
73888
|
-
const configPath =
|
|
73906
|
+
const configPath = join162(projectDir, CK_CONFIG_FILE2);
|
|
73889
73907
|
const json = await readJsonSafe(configPath);
|
|
73890
73908
|
json.content = { ...json.content, ...config };
|
|
73891
73909
|
await atomicWrite(configPath, json);
|
|
73892
73910
|
}
|
|
73893
73911
|
async function loadContentState(projectDir) {
|
|
73894
|
-
const configPath =
|
|
73912
|
+
const configPath = join162(projectDir, CK_CONFIG_FILE2);
|
|
73895
73913
|
try {
|
|
73896
|
-
const raw2 = await
|
|
73914
|
+
const raw2 = await readFile64(configPath, "utf-8");
|
|
73897
73915
|
const json = JSON.parse(raw2);
|
|
73898
73916
|
const contentBlock = json.content ?? {};
|
|
73899
73917
|
return ContentStateSchema.parse(contentBlock.state ?? {});
|
|
@@ -73902,7 +73920,7 @@ async function loadContentState(projectDir) {
|
|
|
73902
73920
|
}
|
|
73903
73921
|
}
|
|
73904
73922
|
async function saveContentState(projectDir, state) {
|
|
73905
|
-
const configPath =
|
|
73923
|
+
const configPath = join162(projectDir, CK_CONFIG_FILE2);
|
|
73906
73924
|
const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().slice(0, 10);
|
|
73907
73925
|
for (const key of Object.keys(state.dailyPostCounts)) {
|
|
73908
73926
|
const dateStr = key.slice(-10);
|
|
@@ -73920,7 +73938,7 @@ async function saveContentState(projectDir, state) {
|
|
|
73920
73938
|
}
|
|
73921
73939
|
async function readJsonSafe(filePath) {
|
|
73922
73940
|
try {
|
|
73923
|
-
const raw2 = await
|
|
73941
|
+
const raw2 = await readFile64(filePath, "utf-8");
|
|
73924
73942
|
return JSON.parse(raw2);
|
|
73925
73943
|
} catch {
|
|
73926
73944
|
return {};
|
|
@@ -73928,7 +73946,7 @@ async function readJsonSafe(filePath) {
|
|
|
73928
73946
|
}
|
|
73929
73947
|
async function atomicWrite(filePath, data) {
|
|
73930
73948
|
const tmpPath = `${filePath}.tmp`;
|
|
73931
|
-
await
|
|
73949
|
+
await writeFile37(tmpPath, JSON.stringify(data, null, 2), "utf-8");
|
|
73932
73950
|
await rename13(tmpPath, filePath);
|
|
73933
73951
|
}
|
|
73934
73952
|
var CK_CONFIG_FILE2 = ".ck.json";
|
|
@@ -74184,7 +74202,7 @@ var init_platform_setup_x = __esm(() => {
|
|
|
74184
74202
|
|
|
74185
74203
|
// src/commands/content/phases/setup-wizard.ts
|
|
74186
74204
|
import { existsSync as existsSync79 } from "node:fs";
|
|
74187
|
-
import { join as
|
|
74205
|
+
import { join as join163 } from "node:path";
|
|
74188
74206
|
async function runSetupWizard2(cwd2, contentLogger) {
|
|
74189
74207
|
console.log();
|
|
74190
74208
|
oe(import_picocolors43.default.bgCyan(import_picocolors43.default.white(" CK Content — Multi-Channel Content Engine ")));
|
|
@@ -74252,8 +74270,8 @@ async function showRepoSummary(cwd2) {
|
|
|
74252
74270
|
function detectBrandAssets(cwd2, contentLogger) {
|
|
74253
74271
|
const repos = discoverRepos2(cwd2);
|
|
74254
74272
|
for (const repo of repos) {
|
|
74255
|
-
const hasGuidelines = existsSync79(
|
|
74256
|
-
const hasStyles = existsSync79(
|
|
74273
|
+
const hasGuidelines = existsSync79(join163(repo.path, "docs", "brand-guidelines.md"));
|
|
74274
|
+
const hasStyles = existsSync79(join163(repo.path, "assets", "writing-styles"));
|
|
74257
74275
|
if (!hasGuidelines) {
|
|
74258
74276
|
f2.warning(`${repo.name}: No docs/brand-guidelines.md — content will use generic tone.`);
|
|
74259
74277
|
contentLogger.warn(`${repo.name}: missing docs/brand-guidelines.md`);
|
|
@@ -74320,11 +74338,11 @@ var init_setup_wizard = __esm(() => {
|
|
|
74320
74338
|
|
|
74321
74339
|
// src/commands/content/content-review-commands.ts
|
|
74322
74340
|
import { existsSync as existsSync80 } from "node:fs";
|
|
74323
|
-
import { homedir as
|
|
74341
|
+
import { homedir as homedir52 } from "node:os";
|
|
74324
74342
|
async function queueContent() {
|
|
74325
74343
|
const cwd2 = process.cwd();
|
|
74326
74344
|
const config = await loadContentConfig(cwd2);
|
|
74327
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
74345
|
+
const dbPath = config.dbPath.replace(/^~/, homedir52());
|
|
74328
74346
|
if (!existsSync80(dbPath)) {
|
|
74329
74347
|
logger.info("No content database found. Run 'ck content setup' first.");
|
|
74330
74348
|
return;
|
|
@@ -74351,7 +74369,7 @@ async function queueContent() {
|
|
|
74351
74369
|
async function approveContentCmd(id) {
|
|
74352
74370
|
const cwd2 = process.cwd();
|
|
74353
74371
|
const config = await loadContentConfig(cwd2);
|
|
74354
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
74372
|
+
const dbPath = config.dbPath.replace(/^~/, homedir52());
|
|
74355
74373
|
const db = initDatabase(dbPath);
|
|
74356
74374
|
try {
|
|
74357
74375
|
approveContent(db, Number.parseInt(id, 10));
|
|
@@ -74363,7 +74381,7 @@ async function approveContentCmd(id) {
|
|
|
74363
74381
|
async function rejectContentCmd(id, reason) {
|
|
74364
74382
|
const cwd2 = process.cwd();
|
|
74365
74383
|
const config = await loadContentConfig(cwd2);
|
|
74366
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
74384
|
+
const dbPath = config.dbPath.replace(/^~/, homedir52());
|
|
74367
74385
|
const db = initDatabase(dbPath);
|
|
74368
74386
|
try {
|
|
74369
74387
|
rejectContent(db, Number.parseInt(id, 10), reason);
|
|
@@ -74394,10 +74412,10 @@ __export(exports_content_subcommands, {
|
|
|
74394
74412
|
approveContentCmd: () => approveContentCmd
|
|
74395
74413
|
});
|
|
74396
74414
|
import { existsSync as existsSync81, readFileSync as readFileSync21, unlinkSync as unlinkSync6 } from "node:fs";
|
|
74397
|
-
import { homedir as
|
|
74398
|
-
import { join as
|
|
74415
|
+
import { homedir as homedir53 } from "node:os";
|
|
74416
|
+
import { join as join164 } from "node:path";
|
|
74399
74417
|
function isDaemonRunning() {
|
|
74400
|
-
const lockFile =
|
|
74418
|
+
const lockFile = join164(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
74401
74419
|
if (!existsSync81(lockFile))
|
|
74402
74420
|
return { running: false, pid: null };
|
|
74403
74421
|
try {
|
|
@@ -74429,7 +74447,7 @@ async function startContent(options2) {
|
|
|
74429
74447
|
await contentCommand(options2);
|
|
74430
74448
|
}
|
|
74431
74449
|
async function stopContent() {
|
|
74432
|
-
const lockFile =
|
|
74450
|
+
const lockFile = join164(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
74433
74451
|
if (!existsSync81(lockFile)) {
|
|
74434
74452
|
logger.info("Content daemon is not running.");
|
|
74435
74453
|
return;
|
|
@@ -74468,9 +74486,9 @@ async function statusContent() {
|
|
|
74468
74486
|
} catch {}
|
|
74469
74487
|
}
|
|
74470
74488
|
async function logsContent(options2) {
|
|
74471
|
-
const logDir =
|
|
74489
|
+
const logDir = join164(homedir53(), ".claudekit", "logs");
|
|
74472
74490
|
const dateStr = new Date().toISOString().slice(0, 10).replace(/-/g, "");
|
|
74473
|
-
const logPath =
|
|
74491
|
+
const logPath = join164(logDir, `content-${dateStr}.log`);
|
|
74474
74492
|
if (!existsSync81(logPath)) {
|
|
74475
74493
|
logger.info("No content logs found for today.");
|
|
74476
74494
|
return;
|
|
@@ -74502,13 +74520,13 @@ var init_content_subcommands = __esm(() => {
|
|
|
74502
74520
|
init_setup_wizard();
|
|
74503
74521
|
init_state_manager();
|
|
74504
74522
|
init_content_review_commands();
|
|
74505
|
-
LOCK_DIR =
|
|
74523
|
+
LOCK_DIR = join164(homedir53(), ".claudekit", "locks");
|
|
74506
74524
|
});
|
|
74507
74525
|
|
|
74508
74526
|
// src/commands/content/content-command.ts
|
|
74509
74527
|
import { existsSync as existsSync82, mkdirSync as mkdirSync9, unlinkSync as unlinkSync7, writeFileSync as writeFileSync7 } from "node:fs";
|
|
74510
|
-
import { homedir as
|
|
74511
|
-
import { join as
|
|
74528
|
+
import { homedir as homedir54 } from "node:os";
|
|
74529
|
+
import { join as join165 } from "node:path";
|
|
74512
74530
|
async function contentCommand(options2) {
|
|
74513
74531
|
const cwd2 = process.cwd();
|
|
74514
74532
|
const contentLogger = new ContentLogger;
|
|
@@ -74540,7 +74558,7 @@ async function contentCommand(options2) {
|
|
|
74540
74558
|
if (!existsSync82(LOCK_DIR2))
|
|
74541
74559
|
mkdirSync9(LOCK_DIR2, { recursive: true });
|
|
74542
74560
|
writeFileSync7(LOCK_FILE, String(process.pid), "utf-8");
|
|
74543
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
74561
|
+
const dbPath = config.dbPath.replace(/^~/, homedir54());
|
|
74544
74562
|
const db = initDatabase(dbPath);
|
|
74545
74563
|
contentLogger.info(`Database initialised at ${dbPath}`);
|
|
74546
74564
|
const adapters = initializeAdapters(config);
|
|
@@ -74686,8 +74704,8 @@ var init_content_command = __esm(() => {
|
|
|
74686
74704
|
init_publisher();
|
|
74687
74705
|
init_review_manager();
|
|
74688
74706
|
init_state_manager();
|
|
74689
|
-
LOCK_DIR2 =
|
|
74690
|
-
LOCK_FILE =
|
|
74707
|
+
LOCK_DIR2 = join165(homedir54(), ".claudekit", "locks");
|
|
74708
|
+
LOCK_FILE = join165(LOCK_DIR2, "ck-content.lock");
|
|
74691
74709
|
});
|
|
74692
74710
|
|
|
74693
74711
|
// src/commands/content/index.ts
|
|
@@ -104969,9 +104987,9 @@ async function initCommand(options2) {
|
|
|
104969
104987
|
init_dist2();
|
|
104970
104988
|
var import_picocolors30 = __toESM(require_picocolors(), 1);
|
|
104971
104989
|
import { existsSync as existsSync62 } from "node:fs";
|
|
104972
|
-
import { readFile as
|
|
104973
|
-
import { homedir as
|
|
104974
|
-
import { basename as basename26, join as
|
|
104990
|
+
import { readFile as readFile60, rm as rm15, unlink as unlink12 } from "node:fs/promises";
|
|
104991
|
+
import { homedir as homedir47 } from "node:os";
|
|
104992
|
+
import { basename as basename26, join as join140, resolve as resolve36 } from "node:path";
|
|
104975
104993
|
init_logger();
|
|
104976
104994
|
|
|
104977
104995
|
// src/ui/ck-cli-design/tokens.ts
|
|
@@ -105439,9 +105457,128 @@ init_converters();
|
|
|
105439
105457
|
init_hooks_settings_merger();
|
|
105440
105458
|
init_model_taxonomy();
|
|
105441
105459
|
|
|
105460
|
+
// src/commands/portable/opencode-config-installer.ts
|
|
105461
|
+
init_logger();
|
|
105462
|
+
init_dist2();
|
|
105463
|
+
init_model_taxonomy();
|
|
105464
|
+
import { mkdir as mkdir33, readFile as readFile59, writeFile as writeFile33 } from "node:fs/promises";
|
|
105465
|
+
import { homedir as homedir46 } from "node:os";
|
|
105466
|
+
import { dirname as dirname38, join as join139 } from "node:path";
|
|
105467
|
+
function getOpenCodeConfigPath(options2) {
|
|
105468
|
+
if (options2.global) {
|
|
105469
|
+
return join139(options2.homeDir ?? homedir46(), ".config", "opencode", "opencode.json");
|
|
105470
|
+
}
|
|
105471
|
+
return join139(options2.cwd ?? process.cwd(), "opencode.json");
|
|
105472
|
+
}
|
|
105473
|
+
async function detectAuthenticatedProviders(homeDir) {
|
|
105474
|
+
const authPath = join139(homeDir ?? homedir46(), ".local", "share", "opencode", "auth.json");
|
|
105475
|
+
try {
|
|
105476
|
+
const raw2 = await readFile59(authPath, "utf-8");
|
|
105477
|
+
const parsed = JSON.parse(raw2);
|
|
105478
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
105479
|
+
return Object.keys(parsed);
|
|
105480
|
+
}
|
|
105481
|
+
} catch {}
|
|
105482
|
+
return [];
|
|
105483
|
+
}
|
|
105484
|
+
async function suggestOpenCodeDefaultModel(homeDir) {
|
|
105485
|
+
const override = getOpenCodeDefaultModelOverride();
|
|
105486
|
+
if (override) {
|
|
105487
|
+
return { model: override, reason: ".ck.json override" };
|
|
105488
|
+
}
|
|
105489
|
+
return { model: OPENCODE_DEFAULT_MODEL, reason: "fallback default" };
|
|
105490
|
+
}
|
|
105491
|
+
var clackPrompter = async ({ suggestion, reason, detectedProviders }) => {
|
|
105492
|
+
const providersHint = detectedProviders.length > 0 ? `Authenticated providers in opencode: ${detectedProviders.join(", ")}` : "No authenticated providers detected in opencode.";
|
|
105493
|
+
const response = await ie({
|
|
105494
|
+
message: `No default model in opencode.json. ${providersHint}`,
|
|
105495
|
+
options: [
|
|
105496
|
+
{
|
|
105497
|
+
value: "accept",
|
|
105498
|
+
label: `Write "${suggestion}"`,
|
|
105499
|
+
hint: reason
|
|
105500
|
+
},
|
|
105501
|
+
{ value: "custom", label: "Enter a different model..." },
|
|
105502
|
+
{ value: "skip", label: "Skip — I'll configure opencode.json myself" }
|
|
105503
|
+
],
|
|
105504
|
+
initialValue: "accept"
|
|
105505
|
+
});
|
|
105506
|
+
if (lD(response) || response === "skip")
|
|
105507
|
+
return { action: "skip" };
|
|
105508
|
+
if (response === "accept")
|
|
105509
|
+
return { action: "accept" };
|
|
105510
|
+
const custom2 = await te({
|
|
105511
|
+
message: "Model (format: provider/model-id, e.g. openai/gpt-5)",
|
|
105512
|
+
placeholder: suggestion,
|
|
105513
|
+
validate: (value) => {
|
|
105514
|
+
if (!value || !value.includes("/"))
|
|
105515
|
+
return "Must be in 'provider/model-id' format";
|
|
105516
|
+
return;
|
|
105517
|
+
}
|
|
105518
|
+
});
|
|
105519
|
+
if (lD(custom2))
|
|
105520
|
+
return { action: "skip" };
|
|
105521
|
+
return { action: "custom", value: custom2 };
|
|
105522
|
+
};
|
|
105523
|
+
async function ensureOpenCodeModel(options2) {
|
|
105524
|
+
const configPath = getOpenCodeConfigPath(options2);
|
|
105525
|
+
let existing = null;
|
|
105526
|
+
try {
|
|
105527
|
+
const raw2 = await readFile59(configPath, "utf-8");
|
|
105528
|
+
const parsed = JSON.parse(raw2);
|
|
105529
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
105530
|
+
existing = parsed;
|
|
105531
|
+
} else {
|
|
105532
|
+
logger.warning(`ensureOpenCodeModel: ${configPath} is valid JSON but not an object; overwriting with default model`);
|
|
105533
|
+
}
|
|
105534
|
+
} catch (err) {
|
|
105535
|
+
const errno = err?.code;
|
|
105536
|
+
if (errno === "ENOENT") {} else if (err instanceof SyntaxError) {
|
|
105537
|
+
logger.warning(`ensureOpenCodeModel: ${configPath} is not valid JSON; overwriting with default model (existing contents will be lost)`);
|
|
105538
|
+
} else {
|
|
105539
|
+
logger.verbose(`ensureOpenCodeModel: failed to read ${configPath} (${errno ?? String(err)}); recreating`);
|
|
105540
|
+
}
|
|
105541
|
+
}
|
|
105542
|
+
if (existing && typeof existing.model === "string" && existing.model.trim().length > 0) {
|
|
105543
|
+
return { path: configPath, action: "existing", model: existing.model };
|
|
105544
|
+
}
|
|
105545
|
+
const suggestion = await suggestOpenCodeDefaultModel(options2.homeDir);
|
|
105546
|
+
let chosenModel = suggestion.model;
|
|
105547
|
+
if (options2.interactive) {
|
|
105548
|
+
const detectedProviders = await detectAuthenticatedProviders(options2.homeDir);
|
|
105549
|
+
const prompter = options2.prompter ?? clackPrompter;
|
|
105550
|
+
const response = await prompter({
|
|
105551
|
+
suggestion: suggestion.model,
|
|
105552
|
+
reason: suggestion.reason,
|
|
105553
|
+
detectedProviders
|
|
105554
|
+
});
|
|
105555
|
+
if (response.action === "skip") {
|
|
105556
|
+
return {
|
|
105557
|
+
path: configPath,
|
|
105558
|
+
action: "skipped",
|
|
105559
|
+
model: "",
|
|
105560
|
+
reason: "user declined"
|
|
105561
|
+
};
|
|
105562
|
+
}
|
|
105563
|
+
if (response.action === "custom") {
|
|
105564
|
+
chosenModel = response.value;
|
|
105565
|
+
}
|
|
105566
|
+
}
|
|
105567
|
+
const next = { ...existing ?? {}, model: chosenModel };
|
|
105568
|
+
await mkdir33(dirname38(configPath), { recursive: true });
|
|
105569
|
+
await writeFile33(configPath, `${JSON.stringify(next, null, 2)}
|
|
105570
|
+
`, "utf-8");
|
|
105571
|
+
return {
|
|
105572
|
+
path: configPath,
|
|
105573
|
+
action: existing ? "added" : "created",
|
|
105574
|
+
model: chosenModel,
|
|
105575
|
+
reason: suggestion.reason
|
|
105576
|
+
};
|
|
105577
|
+
}
|
|
105578
|
+
|
|
105442
105579
|
// src/commands/portable/plan-display.ts
|
|
105443
105580
|
var import_picocolors28 = __toESM(require_picocolors(), 1);
|
|
105444
|
-
import { basename as basename25, dirname as
|
|
105581
|
+
import { basename as basename25, dirname as dirname39, extname as extname7 } from "node:path";
|
|
105445
105582
|
var DEFAULT_MAX_PLAN_GROUP_ITEMS = 20;
|
|
105446
105583
|
var TYPE_ORDER = [
|
|
105447
105584
|
"agent",
|
|
@@ -105667,21 +105804,21 @@ function collectPlannedWhereLines(plan) {
|
|
|
105667
105804
|
return destinations.map((destination) => `${formatDisplayPath(destination)} -> ${formatCdHint(resolveCdTarget(destination))}`);
|
|
105668
105805
|
}
|
|
105669
105806
|
function resolveCdTarget(destination) {
|
|
105670
|
-
return extname7(destination).length > 0 ?
|
|
105807
|
+
return extname7(destination).length > 0 ? dirname39(destination) : destination;
|
|
105671
105808
|
}
|
|
105672
105809
|
function normalizeWhereDestination(path16, portableType) {
|
|
105673
105810
|
if (portableType === "agent" || portableType === "command" || portableType === "skill") {
|
|
105674
|
-
return
|
|
105811
|
+
return dirname39(path16);
|
|
105675
105812
|
}
|
|
105676
105813
|
if (portableType === "hooks") {
|
|
105677
|
-
return
|
|
105814
|
+
return dirname39(path16);
|
|
105678
105815
|
}
|
|
105679
105816
|
if (portableType === "rules") {
|
|
105680
105817
|
const fileName = basename25(path16).toLowerCase();
|
|
105681
105818
|
if (fileName === "agents.md" || fileName === "gemini.md" || fileName === ".goosehints" || fileName === "custom_modes.yaml" || fileName === "custom_modes.yml") {
|
|
105682
105819
|
return path16;
|
|
105683
105820
|
}
|
|
105684
|
-
return
|
|
105821
|
+
return dirname39(path16);
|
|
105685
105822
|
}
|
|
105686
105823
|
return path16;
|
|
105687
105824
|
}
|
|
@@ -106020,12 +106157,12 @@ async function executeDeleteAction(action, options2) {
|
|
|
106020
106157
|
async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
106021
106158
|
if (!skillSourcePath)
|
|
106022
106159
|
return;
|
|
106023
|
-
const sourceMetadataPath =
|
|
106160
|
+
const sourceMetadataPath = join140(resolve36(skillSourcePath, ".."), "metadata.json");
|
|
106024
106161
|
if (!existsSync62(sourceMetadataPath))
|
|
106025
106162
|
return;
|
|
106026
106163
|
let sourceMetadata;
|
|
106027
106164
|
try {
|
|
106028
|
-
const content = await
|
|
106165
|
+
const content = await readFile60(sourceMetadataPath, "utf-8");
|
|
106029
106166
|
sourceMetadata = JSON.parse(content);
|
|
106030
106167
|
} catch (error) {
|
|
106031
106168
|
logger.debug(`[migrate] Failed to parse source metadata.json: ${error}`);
|
|
@@ -106033,7 +106170,7 @@ async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
|
106033
106170
|
}
|
|
106034
106171
|
if (!sourceMetadata.deletions || sourceMetadata.deletions.length === 0)
|
|
106035
106172
|
return;
|
|
106036
|
-
const claudeDir3 = installGlobally ?
|
|
106173
|
+
const claudeDir3 = installGlobally ? join140(homedir47(), ".claude") : join140(process.cwd(), ".claude");
|
|
106037
106174
|
if (!existsSync62(claudeDir3))
|
|
106038
106175
|
return;
|
|
106039
106176
|
try {
|
|
@@ -106150,8 +106287,8 @@ async function migrateCommand(options2) {
|
|
|
106150
106287
|
let requestedGlobal = options2.global ?? false;
|
|
106151
106288
|
let installGlobally = requestedGlobal;
|
|
106152
106289
|
if (options2.global === undefined && !options2.yes) {
|
|
106153
|
-
const projectTarget =
|
|
106154
|
-
const globalTarget =
|
|
106290
|
+
const projectTarget = join140(process.cwd(), ".claude");
|
|
106291
|
+
const globalTarget = join140(homedir47(), ".claude");
|
|
106155
106292
|
const scopeChoice = await ie({
|
|
106156
106293
|
message: "Installation scope",
|
|
106157
106294
|
options: [
|
|
@@ -106280,7 +106417,7 @@ async function migrateCommand(options2) {
|
|
|
106280
106417
|
for (const action of conflictActions) {
|
|
106281
106418
|
if (!action.diff && action.targetPath && existsSync62(action.targetPath)) {
|
|
106282
106419
|
try {
|
|
106283
|
-
const targetContent = await
|
|
106420
|
+
const targetContent = await readFile60(action.targetPath, "utf-8");
|
|
106284
106421
|
const sourceItem = agents2.find((a3) => a3.name === action.item) || commands.find((c2) => c2.name === action.item) || (configItem?.name === action.item ? configItem : null) || ruleItems.find((r2) => r2.name === action.item) || hookItems.find((h2) => h2.name === action.item);
|
|
106285
106422
|
if (sourceItem) {
|
|
106286
106423
|
const providerConfig = providers[action.provider];
|
|
@@ -106400,6 +106537,22 @@ async function migrateCommand(options2) {
|
|
|
106400
106537
|
}
|
|
106401
106538
|
progressSink.tick(progressLabelForType(task.type));
|
|
106402
106539
|
}
|
|
106540
|
+
if (selectedProviders.includes("opencode")) {
|
|
106541
|
+
try {
|
|
106542
|
+
const result = await ensureOpenCodeModel({
|
|
106543
|
+
global: installGlobally,
|
|
106544
|
+
interactive: process.stdout.isTTY === true && !options2.yes
|
|
106545
|
+
});
|
|
106546
|
+
if (result.action === "created" || result.action === "added") {
|
|
106547
|
+
const reason = result.reason ? ` (${result.reason})` : "";
|
|
106548
|
+
f2.info(`Set default model "${result.model}" in ${result.path}${reason}`);
|
|
106549
|
+
} else if (result.action === "skipped") {
|
|
106550
|
+
f2.warn("Skipped writing default model to opencode.json. Migrated agents may fail with ProviderModelNotFoundError until you set one.");
|
|
106551
|
+
}
|
|
106552
|
+
} catch (err) {
|
|
106553
|
+
postProgressWarnings.push(`Could not update opencode.json model (${err instanceof Error ? err.message : String(err)}). Agents may fail with ProviderModelNotFoundError until a model is set.`);
|
|
106554
|
+
}
|
|
106555
|
+
}
|
|
106403
106556
|
for (const [hooksProvider, files] of successfulHookFiles) {
|
|
106404
106557
|
if (files.length === 0)
|
|
106405
106558
|
continue;
|
|
@@ -106628,7 +106781,7 @@ function buildDryRunFallbackResults(skills, selectedProviders, installGlobally,
|
|
|
106628
106781
|
results.push({
|
|
106629
106782
|
itemName: skill.name,
|
|
106630
106783
|
operation: "apply",
|
|
106631
|
-
path:
|
|
106784
|
+
path: join140(basePath, skill.name),
|
|
106632
106785
|
portableType: "skill",
|
|
106633
106786
|
provider,
|
|
106634
106787
|
providerDisplayName: providers[provider].displayName,
|
|
@@ -106788,7 +106941,7 @@ async function handleDirectorySetup(ctx) {
|
|
|
106788
106941
|
// src/commands/new/phases/project-creation.ts
|
|
106789
106942
|
init_config_manager();
|
|
106790
106943
|
init_github_client();
|
|
106791
|
-
import { join as
|
|
106944
|
+
import { join as join141 } from "node:path";
|
|
106792
106945
|
init_logger();
|
|
106793
106946
|
init_output_manager();
|
|
106794
106947
|
init_types3();
|
|
@@ -106914,7 +107067,7 @@ async function projectCreation(kit, resolvedDir, validOptions, isNonInteractive2
|
|
|
106914
107067
|
output.section("Installing");
|
|
106915
107068
|
logger.verbose("Installation target", { directory: resolvedDir });
|
|
106916
107069
|
const merger = new FileMerger;
|
|
106917
|
-
const claudeDir3 =
|
|
107070
|
+
const claudeDir3 = join141(resolvedDir, ".claude");
|
|
106918
107071
|
merger.setMultiKitContext(claudeDir3, kit);
|
|
106919
107072
|
if (validOptions.exclude && validOptions.exclude.length > 0) {
|
|
106920
107073
|
merger.addIgnorePatterns(validOptions.exclude);
|
|
@@ -106961,7 +107114,7 @@ async function handleProjectCreation(ctx) {
|
|
|
106961
107114
|
}
|
|
106962
107115
|
// src/commands/new/phases/post-setup.ts
|
|
106963
107116
|
init_projects_registry();
|
|
106964
|
-
import { join as
|
|
107117
|
+
import { join as join142 } from "node:path";
|
|
106965
107118
|
init_package_installer();
|
|
106966
107119
|
init_logger();
|
|
106967
107120
|
init_path_resolver();
|
|
@@ -106993,9 +107146,9 @@ async function postSetup(resolvedDir, validOptions, isNonInteractive2, prompts)
|
|
|
106993
107146
|
withSudo: validOptions.withSudo
|
|
106994
107147
|
});
|
|
106995
107148
|
}
|
|
106996
|
-
const claudeDir3 =
|
|
107149
|
+
const claudeDir3 = join142(resolvedDir, ".claude");
|
|
106997
107150
|
await promptSetupWizardIfNeeded({
|
|
106998
|
-
envPath:
|
|
107151
|
+
envPath: join142(claudeDir3, ".env"),
|
|
106999
107152
|
claudeDir: claudeDir3,
|
|
107000
107153
|
isGlobal: false,
|
|
107001
107154
|
isNonInteractive: isNonInteractive2,
|
|
@@ -107065,7 +107218,7 @@ Please use only one download method.`);
|
|
|
107065
107218
|
// src/commands/plan/plan-command.ts
|
|
107066
107219
|
init_output_manager();
|
|
107067
107220
|
import { existsSync as existsSync65, statSync as statSync11 } from "node:fs";
|
|
107068
|
-
import { dirname as
|
|
107221
|
+
import { dirname as dirname43, isAbsolute as isAbsolute11, join as join145, parse as parse7, resolve as resolve41 } from "node:path";
|
|
107069
107222
|
|
|
107070
107223
|
// src/commands/plan/plan-read-handlers.ts
|
|
107071
107224
|
init_config();
|
|
@@ -107075,18 +107228,18 @@ init_logger();
|
|
|
107075
107228
|
init_output_manager();
|
|
107076
107229
|
var import_picocolors32 = __toESM(require_picocolors(), 1);
|
|
107077
107230
|
import { existsSync as existsSync64, statSync as statSync10 } from "node:fs";
|
|
107078
|
-
import { basename as basename27, dirname as
|
|
107231
|
+
import { basename as basename27, dirname as dirname41, join as join144, relative as relative27, resolve as resolve39 } from "node:path";
|
|
107079
107232
|
|
|
107080
107233
|
// src/commands/plan/plan-dependencies.ts
|
|
107081
107234
|
init_config();
|
|
107082
107235
|
init_plan_parser();
|
|
107083
107236
|
init_plans_registry();
|
|
107084
107237
|
import { existsSync as existsSync63 } from "node:fs";
|
|
107085
|
-
import { dirname as
|
|
107238
|
+
import { dirname as dirname40, join as join143 } from "node:path";
|
|
107086
107239
|
async function resolvePlanDependencies(references, currentPlanFile, options2 = {}) {
|
|
107087
107240
|
if (references.length === 0)
|
|
107088
107241
|
return [];
|
|
107089
|
-
const currentPlanDir =
|
|
107242
|
+
const currentPlanDir = dirname40(currentPlanFile);
|
|
107090
107243
|
const projectRoot = findProjectRoot(currentPlanDir);
|
|
107091
107244
|
const config = options2.preloadedConfig ?? (await CkConfigManager.loadFull(projectRoot)).config;
|
|
107092
107245
|
const defaultScope = inferPlanScopeForDir(currentPlanDir, config);
|
|
@@ -107102,7 +107255,7 @@ async function resolvePlanDependencies(references, currentPlanFile, options2 = {
|
|
|
107102
107255
|
};
|
|
107103
107256
|
}
|
|
107104
107257
|
const scopeRoot = resolvePlanDirForScope(scope, projectRoot, config);
|
|
107105
|
-
const planFile =
|
|
107258
|
+
const planFile = join143(scopeRoot, planId, "plan.md");
|
|
107106
107259
|
const isSelfReference = planFile === currentPlanFile;
|
|
107107
107260
|
if (!existsSync63(planFile)) {
|
|
107108
107261
|
return {
|
|
@@ -107173,7 +107326,7 @@ async function handleParse(target, options2) {
|
|
|
107173
107326
|
console.log(JSON.stringify({ file: relative27(process.cwd(), planFile), frontmatter, phases }, null, 2));
|
|
107174
107327
|
return;
|
|
107175
107328
|
}
|
|
107176
|
-
const title = typeof frontmatter.title === "string" ? frontmatter.title : basename27(
|
|
107329
|
+
const title = typeof frontmatter.title === "string" ? frontmatter.title : basename27(dirname41(planFile));
|
|
107177
107330
|
console.log();
|
|
107178
107331
|
console.log(import_picocolors32.default.bold(` Plan: ${title}`));
|
|
107179
107332
|
console.log(` File: ${planFile}`);
|
|
@@ -107244,7 +107397,7 @@ async function handleStatus(target, options2) {
|
|
|
107244
107397
|
}
|
|
107245
107398
|
const effectiveTarget = !resolvedTarget && globalBaseDir ? globalBaseDir : resolvedTarget;
|
|
107246
107399
|
const t = effectiveTarget ? resolve39(effectiveTarget) : null;
|
|
107247
|
-
const plansDir = t && existsSync64(t) && statSync10(t).isDirectory() && !existsSync64(
|
|
107400
|
+
const plansDir = t && existsSync64(t) && statSync10(t).isDirectory() && !existsSync64(join144(t, "plan.md")) ? t : null;
|
|
107248
107401
|
if (plansDir) {
|
|
107249
107402
|
const planFiles = scanPlanDir(plansDir);
|
|
107250
107403
|
if (planFiles.length === 0) {
|
|
@@ -107284,7 +107437,7 @@ async function handleStatus(target, options2) {
|
|
|
107284
107437
|
const blockedBy2 = await resolvePlanDependencies(s.blockedBy, pf, { preloadedConfig });
|
|
107285
107438
|
const blocks2 = await resolvePlanDependencies(s.blocks, pf, { preloadedConfig });
|
|
107286
107439
|
const bar = progressBar(s.completed, s.totalPhases);
|
|
107287
|
-
const title2 = s.title ?? basename27(
|
|
107440
|
+
const title2 = s.title ?? basename27(dirname41(pf));
|
|
107288
107441
|
console.log(` ${import_picocolors32.default.bold(title2)}`);
|
|
107289
107442
|
console.log(` ${bar}`);
|
|
107290
107443
|
if (s.inProgress > 0)
|
|
@@ -107303,7 +107456,7 @@ async function handleStatus(target, options2) {
|
|
|
107303
107456
|
}
|
|
107304
107457
|
console.log();
|
|
107305
107458
|
} catch {
|
|
107306
|
-
console.log(` [X] Failed to read: ${basename27(
|
|
107459
|
+
console.log(` [X] Failed to read: ${basename27(dirname41(pf))}`);
|
|
107307
107460
|
console.log();
|
|
107308
107461
|
}
|
|
107309
107462
|
}
|
|
@@ -107330,7 +107483,7 @@ async function handleStatus(target, options2) {
|
|
|
107330
107483
|
console.log(JSON.stringify({ ...summary, dependencyStatus: { blockedBy, blocks } }, null, 2));
|
|
107331
107484
|
return;
|
|
107332
107485
|
}
|
|
107333
|
-
const title = summary.title ?? basename27(
|
|
107486
|
+
const title = summary.title ?? basename27(dirname41(planFile));
|
|
107334
107487
|
console.log();
|
|
107335
107488
|
console.log(import_picocolors32.default.bold(` ${title}`));
|
|
107336
107489
|
if (summary.status)
|
|
@@ -107393,7 +107546,7 @@ async function handleKanban(target, options2) {
|
|
|
107393
107546
|
process.exitCode = 1;
|
|
107394
107547
|
return;
|
|
107395
107548
|
}
|
|
107396
|
-
const route = `/plans?dir=${encodeURIComponent(
|
|
107549
|
+
const route = `/plans?dir=${encodeURIComponent(dirname41(dirname41(planFile)))}&view=kanban`;
|
|
107397
107550
|
const url = `http://localhost:${server.port}${route}`;
|
|
107398
107551
|
console.log();
|
|
107399
107552
|
console.log(import_picocolors32.default.bold(" ClaudeKit Dashboard — Plans"));
|
|
@@ -107428,7 +107581,7 @@ init_plan_parser();
|
|
|
107428
107581
|
init_plans_registry();
|
|
107429
107582
|
init_output_manager();
|
|
107430
107583
|
var import_picocolors33 = __toESM(require_picocolors(), 1);
|
|
107431
|
-
import { basename as basename28, dirname as
|
|
107584
|
+
import { basename as basename28, dirname as dirname42, relative as relative28, resolve as resolve40 } from "node:path";
|
|
107432
107585
|
async function handleCreate(target, options2) {
|
|
107433
107586
|
if (!options2.title) {
|
|
107434
107587
|
output.error("[X] --title is required for create");
|
|
@@ -107528,7 +107681,7 @@ async function handleCheck(target, options2) {
|
|
|
107528
107681
|
process.exitCode = 1;
|
|
107529
107682
|
return;
|
|
107530
107683
|
}
|
|
107531
|
-
const planDir =
|
|
107684
|
+
const planDir = dirname42(planFile);
|
|
107532
107685
|
let planStatus = "pending";
|
|
107533
107686
|
try {
|
|
107534
107687
|
const projectRoot = findProjectRoot(planDir);
|
|
@@ -107577,7 +107730,7 @@ async function handleUncheck(target, options2) {
|
|
|
107577
107730
|
process.exitCode = 1;
|
|
107578
107731
|
return;
|
|
107579
107732
|
}
|
|
107580
|
-
const planDir =
|
|
107733
|
+
const planDir = dirname42(planFile);
|
|
107581
107734
|
try {
|
|
107582
107735
|
const projectRoot = findProjectRoot(planDir);
|
|
107583
107736
|
const summary = buildPlanSummary(planFile);
|
|
@@ -107616,7 +107769,7 @@ async function handleAddPhase(target, options2) {
|
|
|
107616
107769
|
try {
|
|
107617
107770
|
const result = addPhase(planFile, target, options2.after);
|
|
107618
107771
|
try {
|
|
107619
|
-
const planDir =
|
|
107772
|
+
const planDir = dirname42(planFile);
|
|
107620
107773
|
const projectRoot = findProjectRoot(planDir);
|
|
107621
107774
|
updateRegistryAddPhase({
|
|
107622
107775
|
planDir,
|
|
@@ -107659,7 +107812,7 @@ function resolvePlanFile(target, baseDir) {
|
|
|
107659
107812
|
const stat23 = statSync11(t);
|
|
107660
107813
|
if (stat23.isFile())
|
|
107661
107814
|
return t;
|
|
107662
|
-
const candidate =
|
|
107815
|
+
const candidate = join145(t, "plan.md");
|
|
107663
107816
|
if (existsSync65(candidate))
|
|
107664
107817
|
return candidate;
|
|
107665
107818
|
}
|
|
@@ -107667,10 +107820,10 @@ function resolvePlanFile(target, baseDir) {
|
|
|
107667
107820
|
let dir = process.cwd();
|
|
107668
107821
|
const root = parse7(dir).root;
|
|
107669
107822
|
while (dir !== root) {
|
|
107670
|
-
const candidate =
|
|
107823
|
+
const candidate = join145(dir, "plan.md");
|
|
107671
107824
|
if (existsSync65(candidate))
|
|
107672
107825
|
return candidate;
|
|
107673
|
-
dir =
|
|
107826
|
+
dir = dirname43(dir);
|
|
107674
107827
|
}
|
|
107675
107828
|
}
|
|
107676
107829
|
return null;
|
|
@@ -108189,8 +108342,8 @@ init_skills_registry();
|
|
|
108189
108342
|
init_skills_uninstaller();
|
|
108190
108343
|
var import_gray_matter11 = __toESM(require_gray_matter(), 1);
|
|
108191
108344
|
var import_picocolors37 = __toESM(require_picocolors(), 1);
|
|
108192
|
-
import { readFile as
|
|
108193
|
-
import { join as
|
|
108345
|
+
import { readFile as readFile61 } from "node:fs/promises";
|
|
108346
|
+
import { join as join146 } from "node:path";
|
|
108194
108347
|
|
|
108195
108348
|
// src/commands/skills/types.ts
|
|
108196
108349
|
init_zod();
|
|
@@ -108312,9 +108465,9 @@ async function handleValidate2(sourcePath) {
|
|
|
108312
108465
|
spinner.stop(`Checked ${skills.length} skill(s)`);
|
|
108313
108466
|
let hasIssues = false;
|
|
108314
108467
|
for (const skill of skills) {
|
|
108315
|
-
const skillMdPath =
|
|
108468
|
+
const skillMdPath = join146(skill.path, "SKILL.md");
|
|
108316
108469
|
try {
|
|
108317
|
-
const content = await
|
|
108470
|
+
const content = await readFile61(skillMdPath, "utf-8");
|
|
108318
108471
|
const { data } = import_gray_matter11.default(content, {
|
|
108319
108472
|
engines: { javascript: { parse: () => ({}) } }
|
|
108320
108473
|
});
|
|
@@ -108870,7 +109023,7 @@ async function detectInstallations() {
|
|
|
108870
109023
|
|
|
108871
109024
|
// src/commands/uninstall/removal-handler.ts
|
|
108872
109025
|
import { readdirSync as readdirSync9, rmSync as rmSync6 } from "node:fs";
|
|
108873
|
-
import { basename as basename29, join as
|
|
109026
|
+
import { basename as basename29, join as join148, resolve as resolve43, sep as sep11 } from "node:path";
|
|
108874
109027
|
init_logger();
|
|
108875
109028
|
init_safe_prompts();
|
|
108876
109029
|
init_safe_spinner();
|
|
@@ -108879,7 +109032,7 @@ var import_fs_extra44 = __toESM(require_lib3(), 1);
|
|
|
108879
109032
|
// src/commands/uninstall/analysis-handler.ts
|
|
108880
109033
|
init_metadata_migration();
|
|
108881
109034
|
import { readdirSync as readdirSync8, rmSync as rmSync5 } from "node:fs";
|
|
108882
|
-
import { dirname as
|
|
109035
|
+
import { dirname as dirname44, join as join147 } from "node:path";
|
|
108883
109036
|
init_logger();
|
|
108884
109037
|
init_safe_prompts();
|
|
108885
109038
|
var import_fs_extra43 = __toESM(require_lib3(), 1);
|
|
@@ -108901,7 +109054,7 @@ function classifyFileByOwnership(ownership, forceOverwrite, deleteReason) {
|
|
|
108901
109054
|
}
|
|
108902
109055
|
async function cleanupEmptyDirectories3(filePath, installationRoot) {
|
|
108903
109056
|
let cleaned = 0;
|
|
108904
|
-
let currentDir =
|
|
109057
|
+
let currentDir = dirname44(filePath);
|
|
108905
109058
|
while (currentDir !== installationRoot && currentDir.startsWith(installationRoot)) {
|
|
108906
109059
|
try {
|
|
108907
109060
|
const entries = readdirSync8(currentDir);
|
|
@@ -108909,7 +109062,7 @@ async function cleanupEmptyDirectories3(filePath, installationRoot) {
|
|
|
108909
109062
|
rmSync5(currentDir, { recursive: true });
|
|
108910
109063
|
cleaned++;
|
|
108911
109064
|
logger.debug(`Removed empty directory: ${currentDir}`);
|
|
108912
|
-
currentDir =
|
|
109065
|
+
currentDir = dirname44(currentDir);
|
|
108913
109066
|
} else {
|
|
108914
109067
|
break;
|
|
108915
109068
|
}
|
|
@@ -108936,7 +109089,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
108936
109089
|
const remainingFiles = metadata.kits?.[remainingKit]?.files || [];
|
|
108937
109090
|
for (const file of remainingFiles) {
|
|
108938
109091
|
const relativePath = normalizeTrackedPath(file.path);
|
|
108939
|
-
if (await import_fs_extra43.pathExists(
|
|
109092
|
+
if (await import_fs_extra43.pathExists(join147(installation.path, relativePath))) {
|
|
108940
109093
|
result.retainedManifestPaths.push(relativePath);
|
|
108941
109094
|
}
|
|
108942
109095
|
}
|
|
@@ -108944,7 +109097,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
108944
109097
|
const kitFiles = metadata.kits[kit].files || [];
|
|
108945
109098
|
for (const trackedFile of kitFiles) {
|
|
108946
109099
|
const relativePath = normalizeTrackedPath(trackedFile.path);
|
|
108947
|
-
const filePath =
|
|
109100
|
+
const filePath = join147(installation.path, relativePath);
|
|
108948
109101
|
if (preservedPaths.has(relativePath)) {
|
|
108949
109102
|
result.toPreserve.push({ path: relativePath, reason: "shared with other kit" });
|
|
108950
109103
|
continue;
|
|
@@ -108977,7 +109130,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
108977
109130
|
}
|
|
108978
109131
|
for (const trackedFile of allTrackedFiles) {
|
|
108979
109132
|
const relativePath = normalizeTrackedPath(trackedFile.path);
|
|
108980
|
-
const filePath =
|
|
109133
|
+
const filePath = join147(installation.path, relativePath);
|
|
108981
109134
|
const ownershipResult = await OwnershipChecker.checkOwnership(filePath, metadata, installation.path);
|
|
108982
109135
|
if (!ownershipResult.exists)
|
|
108983
109136
|
continue;
|
|
@@ -109120,7 +109273,7 @@ async function removeInstallations(installations, options2) {
|
|
|
109120
109273
|
let removedCount = 0;
|
|
109121
109274
|
let cleanedDirs = 0;
|
|
109122
109275
|
for (const item of analysis.toDelete) {
|
|
109123
|
-
const filePath =
|
|
109276
|
+
const filePath = join148(installation.path, item.path);
|
|
109124
109277
|
if (!await import_fs_extra44.pathExists(filePath))
|
|
109125
109278
|
continue;
|
|
109126
109279
|
if (!await isPathSafeToRemove(filePath, installation.path)) {
|
|
@@ -109454,7 +109607,7 @@ ${import_picocolors40.default.bold(import_picocolors40.default.cyan(result.kitCo
|
|
|
109454
109607
|
init_logger();
|
|
109455
109608
|
import { existsSync as existsSync72 } from "node:fs";
|
|
109456
109609
|
import { rm as rm16 } from "node:fs/promises";
|
|
109457
|
-
import { join as
|
|
109610
|
+
import { join as join155 } from "node:path";
|
|
109458
109611
|
var import_picocolors41 = __toESM(require_picocolors(), 1);
|
|
109459
109612
|
|
|
109460
109613
|
// src/commands/watch/phases/implementation-runner.ts
|
|
@@ -109972,8 +110125,8 @@ function spawnAndCollect3(command, args) {
|
|
|
109972
110125
|
}
|
|
109973
110126
|
|
|
109974
110127
|
// src/commands/watch/phases/issue-processor.ts
|
|
109975
|
-
import { mkdir as
|
|
109976
|
-
import { join as
|
|
110128
|
+
import { mkdir as mkdir34, writeFile as writeFile35 } from "node:fs/promises";
|
|
110129
|
+
import { join as join151 } from "node:path";
|
|
109977
110130
|
|
|
109978
110131
|
// src/commands/watch/phases/approval-detector.ts
|
|
109979
110132
|
init_logger();
|
|
@@ -110351,9 +110504,9 @@ async function checkAwaitingApproval(state, setup, options2, watchLog, projectDi
|
|
|
110351
110504
|
|
|
110352
110505
|
// src/commands/watch/phases/plan-dir-finder.ts
|
|
110353
110506
|
import { readdir as readdir44, stat as stat23 } from "node:fs/promises";
|
|
110354
|
-
import { join as
|
|
110507
|
+
import { join as join150 } from "node:path";
|
|
110355
110508
|
async function findRecentPlanDir(cwd2, issueNumber, watchLog) {
|
|
110356
|
-
const plansRoot =
|
|
110509
|
+
const plansRoot = join150(cwd2, "plans");
|
|
110357
110510
|
try {
|
|
110358
110511
|
const entries = await readdir44(plansRoot);
|
|
110359
110512
|
const tenMinAgo = Date.now() - 10 * 60 * 1000;
|
|
@@ -110362,14 +110515,14 @@ async function findRecentPlanDir(cwd2, issueNumber, watchLog) {
|
|
|
110362
110515
|
for (const entry of entries) {
|
|
110363
110516
|
if (entry === "watch" || entry === "reports" || entry === "visuals")
|
|
110364
110517
|
continue;
|
|
110365
|
-
const dirPath =
|
|
110518
|
+
const dirPath = join150(plansRoot, entry);
|
|
110366
110519
|
const dirStat = await stat23(dirPath);
|
|
110367
110520
|
if (!dirStat.isDirectory())
|
|
110368
110521
|
continue;
|
|
110369
110522
|
if (dirStat.mtimeMs < tenMinAgo)
|
|
110370
110523
|
continue;
|
|
110371
110524
|
try {
|
|
110372
|
-
await stat23(
|
|
110525
|
+
await stat23(join150(dirPath, "plan.md"));
|
|
110373
110526
|
} catch {
|
|
110374
110527
|
continue;
|
|
110375
110528
|
}
|
|
@@ -110600,14 +110753,14 @@ async function handlePlanGeneration(issue, state, config, setup, options2, watch
|
|
|
110600
110753
|
stats.plansCreated++;
|
|
110601
110754
|
const detectedPlanDir = await findRecentPlanDir(projectDir, issue.number, watchLog);
|
|
110602
110755
|
if (detectedPlanDir) {
|
|
110603
|
-
state.activeIssues[numStr].planPath =
|
|
110756
|
+
state.activeIssues[numStr].planPath = join151(detectedPlanDir, "plan.md");
|
|
110604
110757
|
watchLog.info(`Plan directory detected: ${detectedPlanDir}`);
|
|
110605
110758
|
} else {
|
|
110606
110759
|
try {
|
|
110607
|
-
const planDir =
|
|
110608
|
-
await
|
|
110609
|
-
const planFilePath =
|
|
110610
|
-
await
|
|
110760
|
+
const planDir = join151(projectDir, "plans", "watch");
|
|
110761
|
+
await mkdir34(planDir, { recursive: true });
|
|
110762
|
+
const planFilePath = join151(planDir, `issue-${issue.number}-plan.md`);
|
|
110763
|
+
await writeFile35(planFilePath, planResult.planText, "utf-8");
|
|
110611
110764
|
state.activeIssues[numStr].planPath = planFilePath;
|
|
110612
110765
|
watchLog.info(`Plan saved (fallback) to ${planFilePath}`);
|
|
110613
110766
|
} catch (err) {
|
|
@@ -110752,15 +110905,15 @@ init_ck_config_manager();
|
|
|
110752
110905
|
init_file_io();
|
|
110753
110906
|
init_logger();
|
|
110754
110907
|
import { existsSync as existsSync68 } from "node:fs";
|
|
110755
|
-
import { mkdir as
|
|
110756
|
-
import { dirname as
|
|
110908
|
+
import { mkdir as mkdir35, readFile as readFile63 } from "node:fs/promises";
|
|
110909
|
+
import { dirname as dirname45 } from "node:path";
|
|
110757
110910
|
var PROCESSED_ISSUES_CAP = 500;
|
|
110758
110911
|
async function readCkJson(projectDir) {
|
|
110759
110912
|
const configPath = CkConfigManager.getProjectConfigPath(projectDir);
|
|
110760
110913
|
try {
|
|
110761
110914
|
if (!existsSync68(configPath))
|
|
110762
110915
|
return {};
|
|
110763
|
-
const content = await
|
|
110916
|
+
const content = await readFile63(configPath, "utf-8");
|
|
110764
110917
|
return JSON.parse(content);
|
|
110765
110918
|
} catch (error) {
|
|
110766
110919
|
logger.warning(`Failed to parse .ck.json: ${error instanceof Error ? error.message : "Unknown"}`);
|
|
@@ -110783,9 +110936,9 @@ async function loadWatchState(projectDir) {
|
|
|
110783
110936
|
}
|
|
110784
110937
|
async function saveWatchState(projectDir, state) {
|
|
110785
110938
|
const configPath = CkConfigManager.getProjectConfigPath(projectDir);
|
|
110786
|
-
const configDir =
|
|
110939
|
+
const configDir = dirname45(configPath);
|
|
110787
110940
|
if (!existsSync68(configDir)) {
|
|
110788
|
-
await
|
|
110941
|
+
await mkdir35(configDir, { recursive: true });
|
|
110789
110942
|
}
|
|
110790
110943
|
const raw2 = await readCkJson(projectDir);
|
|
110791
110944
|
const watchRaw = raw2.watch ?? {};
|
|
@@ -110913,18 +111066,18 @@ init_logger();
|
|
|
110913
111066
|
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
110914
111067
|
import { existsSync as existsSync69 } from "node:fs";
|
|
110915
111068
|
import { readdir as readdir45, stat as stat24 } from "node:fs/promises";
|
|
110916
|
-
import { join as
|
|
111069
|
+
import { join as join152 } from "node:path";
|
|
110917
111070
|
async function scanForRepos(parentDir) {
|
|
110918
111071
|
const repos = [];
|
|
110919
111072
|
const entries = await readdir45(parentDir);
|
|
110920
111073
|
for (const entry of entries) {
|
|
110921
111074
|
if (entry.startsWith("."))
|
|
110922
111075
|
continue;
|
|
110923
|
-
const fullPath =
|
|
111076
|
+
const fullPath = join152(parentDir, entry);
|
|
110924
111077
|
const entryStat = await stat24(fullPath);
|
|
110925
111078
|
if (!entryStat.isDirectory())
|
|
110926
111079
|
continue;
|
|
110927
|
-
const gitDir =
|
|
111080
|
+
const gitDir = join152(fullPath, ".git");
|
|
110928
111081
|
if (!existsSync69(gitDir))
|
|
110929
111082
|
continue;
|
|
110930
111083
|
const result = spawnSync7("gh", ["repo", "view", "--json", "owner,name"], {
|
|
@@ -110950,8 +111103,8 @@ async function scanForRepos(parentDir) {
|
|
|
110950
111103
|
init_logger();
|
|
110951
111104
|
import { spawnSync as spawnSync8 } from "node:child_process";
|
|
110952
111105
|
import { existsSync as existsSync70 } from "node:fs";
|
|
110953
|
-
import { homedir as
|
|
110954
|
-
import { join as
|
|
111106
|
+
import { homedir as homedir48 } from "node:os";
|
|
111107
|
+
import { join as join153 } from "node:path";
|
|
110955
111108
|
async function validateSetup(cwd2) {
|
|
110956
111109
|
const workDir = cwd2 ?? process.cwd();
|
|
110957
111110
|
const ghVersion = spawnSync8("gh", ["--version"], { encoding: "utf-8", timeout: 1e4 });
|
|
@@ -110982,7 +111135,7 @@ Run this command from a directory with a GitHub remote.`);
|
|
|
110982
111135
|
} catch {
|
|
110983
111136
|
throw new Error(`Failed to parse repository info: ${ghRepo.stdout}`);
|
|
110984
111137
|
}
|
|
110985
|
-
const skillsPath =
|
|
111138
|
+
const skillsPath = join153(homedir48(), ".claude", "skills");
|
|
110986
111139
|
const skillsAvailable = existsSync70(skillsPath);
|
|
110987
111140
|
if (!skillsAvailable) {
|
|
110988
111141
|
logger.warning(`ClaudeKit Engineer skills not found at ${skillsPath}`);
|
|
@@ -111000,8 +111153,8 @@ init_logger();
|
|
|
111000
111153
|
init_path_resolver();
|
|
111001
111154
|
import { createWriteStream as createWriteStream3, statSync as statSync12 } from "node:fs";
|
|
111002
111155
|
import { existsSync as existsSync71 } from "node:fs";
|
|
111003
|
-
import { mkdir as
|
|
111004
|
-
import { join as
|
|
111156
|
+
import { mkdir as mkdir36, rename as rename11 } from "node:fs/promises";
|
|
111157
|
+
import { join as join154 } from "node:path";
|
|
111005
111158
|
|
|
111006
111159
|
class WatchLogger {
|
|
111007
111160
|
logStream = null;
|
|
@@ -111009,16 +111162,16 @@ class WatchLogger {
|
|
|
111009
111162
|
logPath = null;
|
|
111010
111163
|
maxBytes;
|
|
111011
111164
|
constructor(logDir, maxBytes = 0) {
|
|
111012
|
-
this.logDir = logDir ??
|
|
111165
|
+
this.logDir = logDir ?? join154(PathResolver.getClaudeKitDir(), "logs");
|
|
111013
111166
|
this.maxBytes = maxBytes;
|
|
111014
111167
|
}
|
|
111015
111168
|
async init() {
|
|
111016
111169
|
try {
|
|
111017
111170
|
if (!existsSync71(this.logDir)) {
|
|
111018
|
-
await
|
|
111171
|
+
await mkdir36(this.logDir, { recursive: true });
|
|
111019
111172
|
}
|
|
111020
111173
|
const dateStr = formatDate(new Date);
|
|
111021
|
-
this.logPath =
|
|
111174
|
+
this.logPath = join154(this.logDir, `watch-${dateStr}.log`);
|
|
111022
111175
|
this.logStream = createWriteStream3(this.logPath, { flags: "a", mode: 384 });
|
|
111023
111176
|
} catch (error) {
|
|
111024
111177
|
logger.warning(`Cannot create watch log file: ${error instanceof Error ? error.message : "Unknown"}`);
|
|
@@ -111200,7 +111353,7 @@ async function watchCommand(options2) {
|
|
|
111200
111353
|
}
|
|
111201
111354
|
async function discoverRepos(options2, watchLog) {
|
|
111202
111355
|
const cwd2 = process.cwd();
|
|
111203
|
-
const isGitRepo = existsSync72(
|
|
111356
|
+
const isGitRepo = existsSync72(join155(cwd2, ".git"));
|
|
111204
111357
|
if (options2.force) {
|
|
111205
111358
|
await forceRemoveLock(watchLog);
|
|
111206
111359
|
}
|
|
@@ -111459,7 +111612,7 @@ function registerCommands(cli) {
|
|
|
111459
111612
|
init_package();
|
|
111460
111613
|
init_config_version_checker();
|
|
111461
111614
|
import { existsSync as existsSync84, readFileSync as readFileSync22 } from "node:fs";
|
|
111462
|
-
import { join as
|
|
111615
|
+
import { join as join167 } from "node:path";
|
|
111463
111616
|
|
|
111464
111617
|
// src/domains/versioning/version-checker.ts
|
|
111465
111618
|
init_version_utils();
|
|
@@ -111473,15 +111626,15 @@ init_types3();
|
|
|
111473
111626
|
init_logger();
|
|
111474
111627
|
init_path_resolver();
|
|
111475
111628
|
import { existsSync as existsSync83 } from "node:fs";
|
|
111476
|
-
import { mkdir as
|
|
111477
|
-
import { join as
|
|
111629
|
+
import { mkdir as mkdir37, readFile as readFile65, writeFile as writeFile38 } from "node:fs/promises";
|
|
111630
|
+
import { join as join166 } from "node:path";
|
|
111478
111631
|
|
|
111479
111632
|
class VersionCacheManager {
|
|
111480
111633
|
static CACHE_FILENAME = "version-check.json";
|
|
111481
111634
|
static CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000;
|
|
111482
111635
|
static getCacheFile() {
|
|
111483
111636
|
const cacheDir = PathResolver.getCacheDir(false);
|
|
111484
|
-
return
|
|
111637
|
+
return join166(cacheDir, VersionCacheManager.CACHE_FILENAME);
|
|
111485
111638
|
}
|
|
111486
111639
|
static async load() {
|
|
111487
111640
|
const cacheFile = VersionCacheManager.getCacheFile();
|
|
@@ -111490,7 +111643,7 @@ class VersionCacheManager {
|
|
|
111490
111643
|
logger.debug("Version check cache not found");
|
|
111491
111644
|
return null;
|
|
111492
111645
|
}
|
|
111493
|
-
const content = await
|
|
111646
|
+
const content = await readFile65(cacheFile, "utf-8");
|
|
111494
111647
|
const cache5 = JSON.parse(content);
|
|
111495
111648
|
if (!cache5.lastCheck || !cache5.currentVersion || !cache5.latestVersion) {
|
|
111496
111649
|
logger.debug("Invalid cache structure, ignoring");
|
|
@@ -111508,9 +111661,9 @@ class VersionCacheManager {
|
|
|
111508
111661
|
const cacheDir = PathResolver.getCacheDir(false);
|
|
111509
111662
|
try {
|
|
111510
111663
|
if (!existsSync83(cacheDir)) {
|
|
111511
|
-
await
|
|
111664
|
+
await mkdir37(cacheDir, { recursive: true, mode: 448 });
|
|
111512
111665
|
}
|
|
111513
|
-
await
|
|
111666
|
+
await writeFile38(cacheFile, JSON.stringify(cache5, null, 2), "utf-8");
|
|
111514
111667
|
logger.debug(`Version check cache saved to ${cacheFile}`);
|
|
111515
111668
|
} catch (error) {
|
|
111516
111669
|
logger.debug(`Failed to save version check cache: ${error}`);
|
|
@@ -111792,9 +111945,9 @@ async function displayVersion() {
|
|
|
111792
111945
|
let localInstalledKits = [];
|
|
111793
111946
|
let globalInstalledKits = [];
|
|
111794
111947
|
const globalKitDir = PathResolver.getGlobalKitDir();
|
|
111795
|
-
const globalMetadataPath =
|
|
111948
|
+
const globalMetadataPath = join167(globalKitDir, "metadata.json");
|
|
111796
111949
|
const prefix = PathResolver.getPathPrefix(false);
|
|
111797
|
-
const localMetadataPath = prefix ?
|
|
111950
|
+
const localMetadataPath = prefix ? join167(process.cwd(), prefix, "metadata.json") : join167(process.cwd(), "metadata.json");
|
|
111798
111951
|
const isLocalSameAsGlobal = localMetadataPath === globalMetadataPath;
|
|
111799
111952
|
if (!isLocalSameAsGlobal && existsSync84(localMetadataPath)) {
|
|
111800
111953
|
try {
|