claudekit-cli 3.41.4-dev.44 → 3.41.4-dev.45
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 +301 -163
- 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",
|
|
@@ -60755,7 +60758,7 @@ var package_default;
|
|
|
60755
60758
|
var init_package = __esm(() => {
|
|
60756
60759
|
package_default = {
|
|
60757
60760
|
name: "claudekit-cli",
|
|
60758
|
-
version: "3.41.4-dev.
|
|
60761
|
+
version: "3.41.4-dev.45",
|
|
60759
60762
|
description: "CLI tool for bootstrapping and updating ClaudeKit projects",
|
|
60760
60763
|
type: "module",
|
|
60761
60764
|
repository: {
|
|
@@ -71885,10 +71888,10 @@ __export(exports_worktree_manager, {
|
|
|
71885
71888
|
cleanupAllWorktrees: () => cleanupAllWorktrees
|
|
71886
71889
|
});
|
|
71887
71890
|
import { existsSync as existsSync67 } from "node:fs";
|
|
71888
|
-
import { readFile as
|
|
71889
|
-
import { join as
|
|
71891
|
+
import { readFile as readFile62, writeFile as writeFile34 } from "node:fs/promises";
|
|
71892
|
+
import { join as join149 } from "node:path";
|
|
71890
71893
|
async function createWorktree(projectDir, issueNumber, baseBranch) {
|
|
71891
|
-
const worktreePath =
|
|
71894
|
+
const worktreePath = join149(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
|
|
71892
71895
|
const branchName = `ck-watch/issue-${issueNumber}`;
|
|
71893
71896
|
await spawnAndCollect("git", ["fetch", "origin", baseBranch], projectDir).catch(() => {
|
|
71894
71897
|
logger.warning(`[worktree] Could not fetch origin/${baseBranch}, using local`);
|
|
@@ -71906,7 +71909,7 @@ async function createWorktree(projectDir, issueNumber, baseBranch) {
|
|
|
71906
71909
|
return worktreePath;
|
|
71907
71910
|
}
|
|
71908
71911
|
async function removeWorktree(projectDir, issueNumber) {
|
|
71909
|
-
const worktreePath =
|
|
71912
|
+
const worktreePath = join149(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
|
|
71910
71913
|
const branchName = `ck-watch/issue-${issueNumber}`;
|
|
71911
71914
|
try {
|
|
71912
71915
|
await spawnAndCollect("git", ["worktree", "remove", worktreePath, "--force"], projectDir);
|
|
@@ -71920,7 +71923,7 @@ async function listActiveWorktrees(projectDir) {
|
|
|
71920
71923
|
try {
|
|
71921
71924
|
const output2 = await spawnAndCollect("git", ["worktree", "list", "--porcelain"], projectDir);
|
|
71922
71925
|
const issueNumbers = [];
|
|
71923
|
-
const worktreePrefix =
|
|
71926
|
+
const worktreePrefix = join149(projectDir, WORKTREE_DIR, "issue-").replace(/\\/g, "/");
|
|
71924
71927
|
for (const line of output2.split(`
|
|
71925
71928
|
`)) {
|
|
71926
71929
|
if (line.startsWith("worktree ")) {
|
|
@@ -71948,16 +71951,16 @@ async function cleanupAllWorktrees(projectDir) {
|
|
|
71948
71951
|
await spawnAndCollect("git", ["worktree", "prune"], projectDir).catch(() => {});
|
|
71949
71952
|
}
|
|
71950
71953
|
async function ensureGitignore(projectDir) {
|
|
71951
|
-
const gitignorePath =
|
|
71954
|
+
const gitignorePath = join149(projectDir, ".gitignore");
|
|
71952
71955
|
try {
|
|
71953
|
-
const content = existsSync67(gitignorePath) ? await
|
|
71956
|
+
const content = existsSync67(gitignorePath) ? await readFile62(gitignorePath, "utf-8") : "";
|
|
71954
71957
|
if (!content.includes(".worktrees")) {
|
|
71955
71958
|
const newContent = content.endsWith(`
|
|
71956
71959
|
`) ? `${content}.worktrees/
|
|
71957
71960
|
` : `${content}
|
|
71958
71961
|
.worktrees/
|
|
71959
71962
|
`;
|
|
71960
|
-
await
|
|
71963
|
+
await writeFile34(gitignorePath, newContent, "utf-8");
|
|
71961
71964
|
logger.info("[worktree] Added .worktrees/ to .gitignore");
|
|
71962
71965
|
}
|
|
71963
71966
|
} catch (err) {
|
|
@@ -72053,9 +72056,9 @@ var init_content_validator = __esm(() => {
|
|
|
72053
72056
|
// src/commands/content/phases/context-cache-manager.ts
|
|
72054
72057
|
import { createHash as createHash8 } from "node:crypto";
|
|
72055
72058
|
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
|
|
72059
|
+
import { rename as rename12, writeFile as writeFile36 } from "node:fs/promises";
|
|
72060
|
+
import { homedir as homedir49 } from "node:os";
|
|
72061
|
+
import { basename as basename30, join as join156 } from "node:path";
|
|
72059
72062
|
function getCachedContext(repoPath) {
|
|
72060
72063
|
const cachePath = getCacheFilePath(repoPath);
|
|
72061
72064
|
if (!existsSync73(cachePath))
|
|
@@ -72080,7 +72083,7 @@ async function saveCachedContext(repoPath, cache5) {
|
|
|
72080
72083
|
}
|
|
72081
72084
|
const cachePath = getCacheFilePath(repoPath);
|
|
72082
72085
|
const tmpPath = `${cachePath}.tmp`;
|
|
72083
|
-
await
|
|
72086
|
+
await writeFile36(tmpPath, JSON.stringify(cache5, null, 2), "utf-8");
|
|
72084
72087
|
await rename12(tmpPath, cachePath);
|
|
72085
72088
|
}
|
|
72086
72089
|
function computeSourceHash(repoPath) {
|
|
@@ -72098,25 +72101,25 @@ function computeSourceHash(repoPath) {
|
|
|
72098
72101
|
}
|
|
72099
72102
|
function getDocSourcePaths(repoPath) {
|
|
72100
72103
|
const paths = [];
|
|
72101
|
-
const docsDir =
|
|
72104
|
+
const docsDir = join156(repoPath, "docs");
|
|
72102
72105
|
if (existsSync73(docsDir)) {
|
|
72103
72106
|
try {
|
|
72104
72107
|
const files = readdirSync10(docsDir);
|
|
72105
72108
|
for (const f3 of files) {
|
|
72106
72109
|
if (f3.endsWith(".md"))
|
|
72107
|
-
paths.push(
|
|
72110
|
+
paths.push(join156(docsDir, f3));
|
|
72108
72111
|
}
|
|
72109
72112
|
} catch {}
|
|
72110
72113
|
}
|
|
72111
|
-
const readme =
|
|
72114
|
+
const readme = join156(repoPath, "README.md");
|
|
72112
72115
|
if (existsSync73(readme))
|
|
72113
72116
|
paths.push(readme);
|
|
72114
|
-
const stylesDir =
|
|
72117
|
+
const stylesDir = join156(repoPath, "assets", "writing-styles");
|
|
72115
72118
|
if (existsSync73(stylesDir)) {
|
|
72116
72119
|
try {
|
|
72117
72120
|
const files = readdirSync10(stylesDir);
|
|
72118
72121
|
for (const f3 of files) {
|
|
72119
|
-
paths.push(
|
|
72122
|
+
paths.push(join156(stylesDir, f3));
|
|
72120
72123
|
}
|
|
72121
72124
|
} catch {}
|
|
72122
72125
|
}
|
|
@@ -72125,11 +72128,11 @@ function getDocSourcePaths(repoPath) {
|
|
|
72125
72128
|
function getCacheFilePath(repoPath) {
|
|
72126
72129
|
const repoName = basename30(repoPath).replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
72127
72130
|
const pathHash = createHash8("sha256").update(repoPath).digest("hex").slice(0, 8);
|
|
72128
|
-
return
|
|
72131
|
+
return join156(CACHE_DIR, `${repoName}-${pathHash}-context-cache.json`);
|
|
72129
72132
|
}
|
|
72130
72133
|
var CACHE_DIR, CACHE_TTL_MS4;
|
|
72131
72134
|
var init_context_cache_manager = __esm(() => {
|
|
72132
|
-
CACHE_DIR =
|
|
72135
|
+
CACHE_DIR = join156(homedir49(), ".claudekit", "cache");
|
|
72133
72136
|
CACHE_TTL_MS4 = 24 * 60 * 60 * 1000;
|
|
72134
72137
|
});
|
|
72135
72138
|
|
|
@@ -72310,7 +72313,7 @@ function extractContentFromResponse(response) {
|
|
|
72310
72313
|
// src/commands/content/phases/docs-summarizer.ts
|
|
72311
72314
|
import { execSync as execSync7 } from "node:child_process";
|
|
72312
72315
|
import { existsSync as existsSync74, readFileSync as readFileSync19, readdirSync as readdirSync11 } from "node:fs";
|
|
72313
|
-
import { join as
|
|
72316
|
+
import { join as join157 } from "node:path";
|
|
72314
72317
|
async function summarizeProjectDocs(repoPath, contentLogger) {
|
|
72315
72318
|
const rawContent = collectRawDocs(repoPath);
|
|
72316
72319
|
if (rawContent.total.length < 200) {
|
|
@@ -72364,12 +72367,12 @@ function collectRawDocs(repoPath) {
|
|
|
72364
72367
|
return capped;
|
|
72365
72368
|
};
|
|
72366
72369
|
const docsContent = [];
|
|
72367
|
-
const docsDir =
|
|
72370
|
+
const docsDir = join157(repoPath, "docs");
|
|
72368
72371
|
if (existsSync74(docsDir)) {
|
|
72369
72372
|
try {
|
|
72370
72373
|
const files = readdirSync11(docsDir).filter((f3) => f3.endsWith(".md")).sort();
|
|
72371
72374
|
for (const f3 of files) {
|
|
72372
|
-
const content = readCapped(
|
|
72375
|
+
const content = readCapped(join157(docsDir, f3), 5000);
|
|
72373
72376
|
if (content) {
|
|
72374
72377
|
docsContent.push(`### ${f3}
|
|
72375
72378
|
${content}`);
|
|
@@ -72383,21 +72386,21 @@ ${content}`);
|
|
|
72383
72386
|
let brand = "";
|
|
72384
72387
|
const brandCandidates = ["docs/brand-guidelines.md", "docs/design-guidelines.md"];
|
|
72385
72388
|
for (const p of brandCandidates) {
|
|
72386
|
-
brand = readCapped(
|
|
72389
|
+
brand = readCapped(join157(repoPath, p), 3000);
|
|
72387
72390
|
if (brand)
|
|
72388
72391
|
break;
|
|
72389
72392
|
}
|
|
72390
72393
|
let styles3 = "";
|
|
72391
|
-
const stylesDir =
|
|
72394
|
+
const stylesDir = join157(repoPath, "assets", "writing-styles");
|
|
72392
72395
|
if (existsSync74(stylesDir)) {
|
|
72393
72396
|
try {
|
|
72394
72397
|
const files = readdirSync11(stylesDir).slice(0, 3);
|
|
72395
|
-
styles3 = files.map((f3) => readCapped(
|
|
72398
|
+
styles3 = files.map((f3) => readCapped(join157(stylesDir, f3), 1000)).filter(Boolean).join(`
|
|
72396
72399
|
|
|
72397
72400
|
`);
|
|
72398
72401
|
} catch {}
|
|
72399
72402
|
}
|
|
72400
|
-
const readme = readCapped(
|
|
72403
|
+
const readme = readCapped(join157(repoPath, "README.md"), 3000);
|
|
72401
72404
|
const total = [docs, brand, styles3, readme].join(`
|
|
72402
72405
|
`);
|
|
72403
72406
|
return { docs, brand, styles: styles3, readme, total };
|
|
@@ -72583,10 +72586,10 @@ IMPORTANT: Generate the image and output the path as JSON: {"imagePath": "/path/
|
|
|
72583
72586
|
// src/commands/content/phases/photo-generator.ts
|
|
72584
72587
|
import { execSync as execSync8 } from "node:child_process";
|
|
72585
72588
|
import { existsSync as existsSync75, mkdirSync as mkdirSync6, readdirSync as readdirSync12 } from "node:fs";
|
|
72586
|
-
import { homedir as
|
|
72587
|
-
import { join as
|
|
72589
|
+
import { homedir as homedir50 } from "node:os";
|
|
72590
|
+
import { join as join158 } from "node:path";
|
|
72588
72591
|
async function generatePhoto(_content, context, config, platform17, contentId, contentLogger) {
|
|
72589
|
-
const mediaDir =
|
|
72592
|
+
const mediaDir = join158(config.contentDir.replace(/^~/, homedir50()), "media", String(contentId));
|
|
72590
72593
|
if (!existsSync75(mediaDir)) {
|
|
72591
72594
|
mkdirSync6(mediaDir, { recursive: true });
|
|
72592
72595
|
}
|
|
@@ -72611,7 +72614,7 @@ async function generatePhoto(_content, context, config, platform17, contentId, c
|
|
|
72611
72614
|
const imageFile = files.find((f3) => /\.(png|jpg|jpeg|webp)$/i.test(f3));
|
|
72612
72615
|
if (imageFile) {
|
|
72613
72616
|
const ext2 = imageFile.split(".").pop() ?? "png";
|
|
72614
|
-
return { path:
|
|
72617
|
+
return { path: join158(mediaDir, imageFile), ...dimensions, format: ext2 };
|
|
72615
72618
|
}
|
|
72616
72619
|
contentLogger.warn(`Photo generation produced no image for content ${contentId}`);
|
|
72617
72620
|
return null;
|
|
@@ -72700,8 +72703,8 @@ var init_content_creator = __esm(() => {
|
|
|
72700
72703
|
|
|
72701
72704
|
// src/commands/content/phases/content-logger.ts
|
|
72702
72705
|
import { createWriteStream as createWriteStream4, existsSync as existsSync76, mkdirSync as mkdirSync7, statSync as statSync14 } from "node:fs";
|
|
72703
|
-
import { homedir as
|
|
72704
|
-
import { join as
|
|
72706
|
+
import { homedir as homedir51 } from "node:os";
|
|
72707
|
+
import { join as join159 } from "node:path";
|
|
72705
72708
|
|
|
72706
72709
|
class ContentLogger {
|
|
72707
72710
|
stream = null;
|
|
@@ -72709,7 +72712,7 @@ class ContentLogger {
|
|
|
72709
72712
|
logDir;
|
|
72710
72713
|
maxBytes;
|
|
72711
72714
|
constructor(maxBytes = 0) {
|
|
72712
|
-
this.logDir =
|
|
72715
|
+
this.logDir = join159(homedir51(), ".claudekit", "logs");
|
|
72713
72716
|
this.maxBytes = maxBytes;
|
|
72714
72717
|
}
|
|
72715
72718
|
init() {
|
|
@@ -72741,7 +72744,7 @@ class ContentLogger {
|
|
|
72741
72744
|
}
|
|
72742
72745
|
}
|
|
72743
72746
|
getLogPath() {
|
|
72744
|
-
return
|
|
72747
|
+
return join159(this.logDir, `content-${this.getDateStr()}.log`);
|
|
72745
72748
|
}
|
|
72746
72749
|
write(level, message) {
|
|
72747
72750
|
this.rotateIfNeeded();
|
|
@@ -72758,18 +72761,18 @@ class ContentLogger {
|
|
|
72758
72761
|
if (dateStr !== this.currentDate) {
|
|
72759
72762
|
this.close();
|
|
72760
72763
|
this.currentDate = dateStr;
|
|
72761
|
-
const logPath =
|
|
72764
|
+
const logPath = join159(this.logDir, `content-${dateStr}.log`);
|
|
72762
72765
|
this.stream = createWriteStream4(logPath, { flags: "a", mode: 384 });
|
|
72763
72766
|
return;
|
|
72764
72767
|
}
|
|
72765
72768
|
if (this.maxBytes > 0 && this.stream) {
|
|
72766
|
-
const logPath =
|
|
72769
|
+
const logPath = join159(this.logDir, `content-${this.currentDate}.log`);
|
|
72767
72770
|
try {
|
|
72768
72771
|
const stat25 = statSync14(logPath);
|
|
72769
72772
|
if (stat25.size >= this.maxBytes) {
|
|
72770
72773
|
this.close();
|
|
72771
72774
|
const suffix = Date.now();
|
|
72772
|
-
const rotatedPath =
|
|
72775
|
+
const rotatedPath = join159(this.logDir, `content-${this.currentDate}-${suffix}.log`);
|
|
72773
72776
|
import("node:fs/promises").then(({ rename: rename13 }) => rename13(logPath, rotatedPath).catch(() => {}));
|
|
72774
72777
|
this.stream = createWriteStream4(logPath, { flags: "w", mode: 384 });
|
|
72775
72778
|
}
|
|
@@ -72807,7 +72810,7 @@ var init_sqlite_client = () => {};
|
|
|
72807
72810
|
|
|
72808
72811
|
// src/commands/content/phases/db-manager.ts
|
|
72809
72812
|
import { existsSync as existsSync77, mkdirSync as mkdirSync8 } from "node:fs";
|
|
72810
|
-
import { dirname as
|
|
72813
|
+
import { dirname as dirname46 } from "node:path";
|
|
72811
72814
|
function initDatabase(dbPath) {
|
|
72812
72815
|
ensureParentDir(dbPath);
|
|
72813
72816
|
const db = openDatabase(dbPath);
|
|
@@ -72828,7 +72831,7 @@ function runRetentionCleanup(db, retentionDays = 90) {
|
|
|
72828
72831
|
db.prepare("DELETE FROM git_events WHERE processed = 1 AND created_at < ?").run(cutoff);
|
|
72829
72832
|
}
|
|
72830
72833
|
function ensureParentDir(dbPath) {
|
|
72831
|
-
const dir =
|
|
72834
|
+
const dir = dirname46(dbPath);
|
|
72832
72835
|
if (dir && !existsSync77(dir)) {
|
|
72833
72836
|
mkdirSync8(dir, { recursive: true });
|
|
72834
72837
|
}
|
|
@@ -72995,7 +72998,7 @@ function isNoiseCommit(title, author) {
|
|
|
72995
72998
|
// src/commands/content/phases/change-detector.ts
|
|
72996
72999
|
import { execSync as execSync10, spawnSync as spawnSync9 } from "node:child_process";
|
|
72997
73000
|
import { existsSync as existsSync78, readFileSync as readFileSync20, readdirSync as readdirSync13, statSync as statSync15 } from "node:fs";
|
|
72998
|
-
import { join as
|
|
73001
|
+
import { join as join160 } from "node:path";
|
|
72999
73002
|
function detectCommits(repo, since) {
|
|
73000
73003
|
try {
|
|
73001
73004
|
const fetchUrl = sshToHttps(repo.remoteUrl);
|
|
@@ -73104,7 +73107,7 @@ function detectTags(repo, since) {
|
|
|
73104
73107
|
}
|
|
73105
73108
|
}
|
|
73106
73109
|
function detectCompletedPlans(repo, since) {
|
|
73107
|
-
const plansDir =
|
|
73110
|
+
const plansDir = join160(repo.path, "plans");
|
|
73108
73111
|
if (!existsSync78(plansDir))
|
|
73109
73112
|
return [];
|
|
73110
73113
|
const sinceMs = new Date(since).getTime();
|
|
@@ -73114,7 +73117,7 @@ function detectCompletedPlans(repo, since) {
|
|
|
73114
73117
|
for (const entry of entries) {
|
|
73115
73118
|
if (!entry.isDirectory())
|
|
73116
73119
|
continue;
|
|
73117
|
-
const planFile =
|
|
73120
|
+
const planFile = join160(plansDir, entry.name, "plan.md");
|
|
73118
73121
|
if (!existsSync78(planFile))
|
|
73119
73122
|
continue;
|
|
73120
73123
|
try {
|
|
@@ -73192,7 +73195,7 @@ function classifyCommit(event) {
|
|
|
73192
73195
|
// src/commands/content/phases/repo-discoverer.ts
|
|
73193
73196
|
import { execSync as execSync11 } from "node:child_process";
|
|
73194
73197
|
import { readdirSync as readdirSync14 } from "node:fs";
|
|
73195
|
-
import { join as
|
|
73198
|
+
import { join as join161 } from "node:path";
|
|
73196
73199
|
function discoverRepos2(cwd2) {
|
|
73197
73200
|
const repos = [];
|
|
73198
73201
|
if (isGitRepoRoot(cwd2)) {
|
|
@@ -73205,7 +73208,7 @@ function discoverRepos2(cwd2) {
|
|
|
73205
73208
|
for (const entry of entries) {
|
|
73206
73209
|
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
73207
73210
|
continue;
|
|
73208
|
-
const dirPath =
|
|
73211
|
+
const dirPath = join161(cwd2, entry.name);
|
|
73209
73212
|
if (isGitRepoRoot(dirPath)) {
|
|
73210
73213
|
const info = getRepoInfo(dirPath);
|
|
73211
73214
|
if (info)
|
|
@@ -73872,12 +73875,12 @@ var init_types6 = __esm(() => {
|
|
|
73872
73875
|
});
|
|
73873
73876
|
|
|
73874
73877
|
// src/commands/content/phases/state-manager.ts
|
|
73875
|
-
import { readFile as
|
|
73876
|
-
import { join as
|
|
73878
|
+
import { readFile as readFile64, rename as rename13, writeFile as writeFile37 } from "node:fs/promises";
|
|
73879
|
+
import { join as join162 } from "node:path";
|
|
73877
73880
|
async function loadContentConfig(projectDir) {
|
|
73878
|
-
const configPath =
|
|
73881
|
+
const configPath = join162(projectDir, CK_CONFIG_FILE2);
|
|
73879
73882
|
try {
|
|
73880
|
-
const raw2 = await
|
|
73883
|
+
const raw2 = await readFile64(configPath, "utf-8");
|
|
73881
73884
|
const json = JSON.parse(raw2);
|
|
73882
73885
|
return ContentConfigSchema.parse(json.content ?? {});
|
|
73883
73886
|
} catch {
|
|
@@ -73885,15 +73888,15 @@ async function loadContentConfig(projectDir) {
|
|
|
73885
73888
|
}
|
|
73886
73889
|
}
|
|
73887
73890
|
async function saveContentConfig(projectDir, config) {
|
|
73888
|
-
const configPath =
|
|
73891
|
+
const configPath = join162(projectDir, CK_CONFIG_FILE2);
|
|
73889
73892
|
const json = await readJsonSafe(configPath);
|
|
73890
73893
|
json.content = { ...json.content, ...config };
|
|
73891
73894
|
await atomicWrite(configPath, json);
|
|
73892
73895
|
}
|
|
73893
73896
|
async function loadContentState(projectDir) {
|
|
73894
|
-
const configPath =
|
|
73897
|
+
const configPath = join162(projectDir, CK_CONFIG_FILE2);
|
|
73895
73898
|
try {
|
|
73896
|
-
const raw2 = await
|
|
73899
|
+
const raw2 = await readFile64(configPath, "utf-8");
|
|
73897
73900
|
const json = JSON.parse(raw2);
|
|
73898
73901
|
const contentBlock = json.content ?? {};
|
|
73899
73902
|
return ContentStateSchema.parse(contentBlock.state ?? {});
|
|
@@ -73902,7 +73905,7 @@ async function loadContentState(projectDir) {
|
|
|
73902
73905
|
}
|
|
73903
73906
|
}
|
|
73904
73907
|
async function saveContentState(projectDir, state) {
|
|
73905
|
-
const configPath =
|
|
73908
|
+
const configPath = join162(projectDir, CK_CONFIG_FILE2);
|
|
73906
73909
|
const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().slice(0, 10);
|
|
73907
73910
|
for (const key of Object.keys(state.dailyPostCounts)) {
|
|
73908
73911
|
const dateStr = key.slice(-10);
|
|
@@ -73920,7 +73923,7 @@ async function saveContentState(projectDir, state) {
|
|
|
73920
73923
|
}
|
|
73921
73924
|
async function readJsonSafe(filePath) {
|
|
73922
73925
|
try {
|
|
73923
|
-
const raw2 = await
|
|
73926
|
+
const raw2 = await readFile64(filePath, "utf-8");
|
|
73924
73927
|
return JSON.parse(raw2);
|
|
73925
73928
|
} catch {
|
|
73926
73929
|
return {};
|
|
@@ -73928,7 +73931,7 @@ async function readJsonSafe(filePath) {
|
|
|
73928
73931
|
}
|
|
73929
73932
|
async function atomicWrite(filePath, data) {
|
|
73930
73933
|
const tmpPath = `${filePath}.tmp`;
|
|
73931
|
-
await
|
|
73934
|
+
await writeFile37(tmpPath, JSON.stringify(data, null, 2), "utf-8");
|
|
73932
73935
|
await rename13(tmpPath, filePath);
|
|
73933
73936
|
}
|
|
73934
73937
|
var CK_CONFIG_FILE2 = ".ck.json";
|
|
@@ -74184,7 +74187,7 @@ var init_platform_setup_x = __esm(() => {
|
|
|
74184
74187
|
|
|
74185
74188
|
// src/commands/content/phases/setup-wizard.ts
|
|
74186
74189
|
import { existsSync as existsSync79 } from "node:fs";
|
|
74187
|
-
import { join as
|
|
74190
|
+
import { join as join163 } from "node:path";
|
|
74188
74191
|
async function runSetupWizard2(cwd2, contentLogger) {
|
|
74189
74192
|
console.log();
|
|
74190
74193
|
oe(import_picocolors43.default.bgCyan(import_picocolors43.default.white(" CK Content — Multi-Channel Content Engine ")));
|
|
@@ -74252,8 +74255,8 @@ async function showRepoSummary(cwd2) {
|
|
|
74252
74255
|
function detectBrandAssets(cwd2, contentLogger) {
|
|
74253
74256
|
const repos = discoverRepos2(cwd2);
|
|
74254
74257
|
for (const repo of repos) {
|
|
74255
|
-
const hasGuidelines = existsSync79(
|
|
74256
|
-
const hasStyles = existsSync79(
|
|
74258
|
+
const hasGuidelines = existsSync79(join163(repo.path, "docs", "brand-guidelines.md"));
|
|
74259
|
+
const hasStyles = existsSync79(join163(repo.path, "assets", "writing-styles"));
|
|
74257
74260
|
if (!hasGuidelines) {
|
|
74258
74261
|
f2.warning(`${repo.name}: No docs/brand-guidelines.md — content will use generic tone.`);
|
|
74259
74262
|
contentLogger.warn(`${repo.name}: missing docs/brand-guidelines.md`);
|
|
@@ -74320,11 +74323,11 @@ var init_setup_wizard = __esm(() => {
|
|
|
74320
74323
|
|
|
74321
74324
|
// src/commands/content/content-review-commands.ts
|
|
74322
74325
|
import { existsSync as existsSync80 } from "node:fs";
|
|
74323
|
-
import { homedir as
|
|
74326
|
+
import { homedir as homedir52 } from "node:os";
|
|
74324
74327
|
async function queueContent() {
|
|
74325
74328
|
const cwd2 = process.cwd();
|
|
74326
74329
|
const config = await loadContentConfig(cwd2);
|
|
74327
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
74330
|
+
const dbPath = config.dbPath.replace(/^~/, homedir52());
|
|
74328
74331
|
if (!existsSync80(dbPath)) {
|
|
74329
74332
|
logger.info("No content database found. Run 'ck content setup' first.");
|
|
74330
74333
|
return;
|
|
@@ -74351,7 +74354,7 @@ async function queueContent() {
|
|
|
74351
74354
|
async function approveContentCmd(id) {
|
|
74352
74355
|
const cwd2 = process.cwd();
|
|
74353
74356
|
const config = await loadContentConfig(cwd2);
|
|
74354
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
74357
|
+
const dbPath = config.dbPath.replace(/^~/, homedir52());
|
|
74355
74358
|
const db = initDatabase(dbPath);
|
|
74356
74359
|
try {
|
|
74357
74360
|
approveContent(db, Number.parseInt(id, 10));
|
|
@@ -74363,7 +74366,7 @@ async function approveContentCmd(id) {
|
|
|
74363
74366
|
async function rejectContentCmd(id, reason) {
|
|
74364
74367
|
const cwd2 = process.cwd();
|
|
74365
74368
|
const config = await loadContentConfig(cwd2);
|
|
74366
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
74369
|
+
const dbPath = config.dbPath.replace(/^~/, homedir52());
|
|
74367
74370
|
const db = initDatabase(dbPath);
|
|
74368
74371
|
try {
|
|
74369
74372
|
rejectContent(db, Number.parseInt(id, 10), reason);
|
|
@@ -74394,10 +74397,10 @@ __export(exports_content_subcommands, {
|
|
|
74394
74397
|
approveContentCmd: () => approveContentCmd
|
|
74395
74398
|
});
|
|
74396
74399
|
import { existsSync as existsSync81, readFileSync as readFileSync21, unlinkSync as unlinkSync6 } from "node:fs";
|
|
74397
|
-
import { homedir as
|
|
74398
|
-
import { join as
|
|
74400
|
+
import { homedir as homedir53 } from "node:os";
|
|
74401
|
+
import { join as join164 } from "node:path";
|
|
74399
74402
|
function isDaemonRunning() {
|
|
74400
|
-
const lockFile =
|
|
74403
|
+
const lockFile = join164(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
74401
74404
|
if (!existsSync81(lockFile))
|
|
74402
74405
|
return { running: false, pid: null };
|
|
74403
74406
|
try {
|
|
@@ -74429,7 +74432,7 @@ async function startContent(options2) {
|
|
|
74429
74432
|
await contentCommand(options2);
|
|
74430
74433
|
}
|
|
74431
74434
|
async function stopContent() {
|
|
74432
|
-
const lockFile =
|
|
74435
|
+
const lockFile = join164(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
74433
74436
|
if (!existsSync81(lockFile)) {
|
|
74434
74437
|
logger.info("Content daemon is not running.");
|
|
74435
74438
|
return;
|
|
@@ -74468,9 +74471,9 @@ async function statusContent() {
|
|
|
74468
74471
|
} catch {}
|
|
74469
74472
|
}
|
|
74470
74473
|
async function logsContent(options2) {
|
|
74471
|
-
const logDir =
|
|
74474
|
+
const logDir = join164(homedir53(), ".claudekit", "logs");
|
|
74472
74475
|
const dateStr = new Date().toISOString().slice(0, 10).replace(/-/g, "");
|
|
74473
|
-
const logPath =
|
|
74476
|
+
const logPath = join164(logDir, `content-${dateStr}.log`);
|
|
74474
74477
|
if (!existsSync81(logPath)) {
|
|
74475
74478
|
logger.info("No content logs found for today.");
|
|
74476
74479
|
return;
|
|
@@ -74502,13 +74505,13 @@ var init_content_subcommands = __esm(() => {
|
|
|
74502
74505
|
init_setup_wizard();
|
|
74503
74506
|
init_state_manager();
|
|
74504
74507
|
init_content_review_commands();
|
|
74505
|
-
LOCK_DIR =
|
|
74508
|
+
LOCK_DIR = join164(homedir53(), ".claudekit", "locks");
|
|
74506
74509
|
});
|
|
74507
74510
|
|
|
74508
74511
|
// src/commands/content/content-command.ts
|
|
74509
74512
|
import { existsSync as existsSync82, mkdirSync as mkdirSync9, unlinkSync as unlinkSync7, writeFileSync as writeFileSync7 } from "node:fs";
|
|
74510
|
-
import { homedir as
|
|
74511
|
-
import { join as
|
|
74513
|
+
import { homedir as homedir54 } from "node:os";
|
|
74514
|
+
import { join as join165 } from "node:path";
|
|
74512
74515
|
async function contentCommand(options2) {
|
|
74513
74516
|
const cwd2 = process.cwd();
|
|
74514
74517
|
const contentLogger = new ContentLogger;
|
|
@@ -74540,7 +74543,7 @@ async function contentCommand(options2) {
|
|
|
74540
74543
|
if (!existsSync82(LOCK_DIR2))
|
|
74541
74544
|
mkdirSync9(LOCK_DIR2, { recursive: true });
|
|
74542
74545
|
writeFileSync7(LOCK_FILE, String(process.pid), "utf-8");
|
|
74543
|
-
const dbPath = config.dbPath.replace(/^~/,
|
|
74546
|
+
const dbPath = config.dbPath.replace(/^~/, homedir54());
|
|
74544
74547
|
const db = initDatabase(dbPath);
|
|
74545
74548
|
contentLogger.info(`Database initialised at ${dbPath}`);
|
|
74546
74549
|
const adapters = initializeAdapters(config);
|
|
@@ -74686,8 +74689,8 @@ var init_content_command = __esm(() => {
|
|
|
74686
74689
|
init_publisher();
|
|
74687
74690
|
init_review_manager();
|
|
74688
74691
|
init_state_manager();
|
|
74689
|
-
LOCK_DIR2 =
|
|
74690
|
-
LOCK_FILE =
|
|
74692
|
+
LOCK_DIR2 = join165(homedir54(), ".claudekit", "locks");
|
|
74693
|
+
LOCK_FILE = join165(LOCK_DIR2, "ck-content.lock");
|
|
74691
74694
|
});
|
|
74692
74695
|
|
|
74693
74696
|
// src/commands/content/index.ts
|
|
@@ -104969,9 +104972,9 @@ async function initCommand(options2) {
|
|
|
104969
104972
|
init_dist2();
|
|
104970
104973
|
var import_picocolors30 = __toESM(require_picocolors(), 1);
|
|
104971
104974
|
import { existsSync as existsSync62 } from "node:fs";
|
|
104972
|
-
import { readFile as
|
|
104973
|
-
import { homedir as
|
|
104974
|
-
import { basename as basename26, join as
|
|
104975
|
+
import { readFile as readFile60, rm as rm15, unlink as unlink12 } from "node:fs/promises";
|
|
104976
|
+
import { homedir as homedir47 } from "node:os";
|
|
104977
|
+
import { basename as basename26, join as join140, resolve as resolve36 } from "node:path";
|
|
104975
104978
|
init_logger();
|
|
104976
104979
|
|
|
104977
104980
|
// src/ui/ck-cli-design/tokens.ts
|
|
@@ -105439,9 +105442,128 @@ init_converters();
|
|
|
105439
105442
|
init_hooks_settings_merger();
|
|
105440
105443
|
init_model_taxonomy();
|
|
105441
105444
|
|
|
105445
|
+
// src/commands/portable/opencode-config-installer.ts
|
|
105446
|
+
init_logger();
|
|
105447
|
+
init_dist2();
|
|
105448
|
+
init_model_taxonomy();
|
|
105449
|
+
import { mkdir as mkdir33, readFile as readFile59, writeFile as writeFile33 } from "node:fs/promises";
|
|
105450
|
+
import { homedir as homedir46 } from "node:os";
|
|
105451
|
+
import { dirname as dirname38, join as join139 } from "node:path";
|
|
105452
|
+
function getOpenCodeConfigPath(options2) {
|
|
105453
|
+
if (options2.global) {
|
|
105454
|
+
return join139(options2.homeDir ?? homedir46(), ".config", "opencode", "opencode.json");
|
|
105455
|
+
}
|
|
105456
|
+
return join139(options2.cwd ?? process.cwd(), "opencode.json");
|
|
105457
|
+
}
|
|
105458
|
+
async function detectAuthenticatedProviders(homeDir) {
|
|
105459
|
+
const authPath = join139(homeDir ?? homedir46(), ".local", "share", "opencode", "auth.json");
|
|
105460
|
+
try {
|
|
105461
|
+
const raw2 = await readFile59(authPath, "utf-8");
|
|
105462
|
+
const parsed = JSON.parse(raw2);
|
|
105463
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
105464
|
+
return Object.keys(parsed);
|
|
105465
|
+
}
|
|
105466
|
+
} catch {}
|
|
105467
|
+
return [];
|
|
105468
|
+
}
|
|
105469
|
+
async function suggestOpenCodeDefaultModel(homeDir) {
|
|
105470
|
+
const override = getOpenCodeDefaultModelOverride();
|
|
105471
|
+
if (override) {
|
|
105472
|
+
return { model: override, reason: ".ck.json override" };
|
|
105473
|
+
}
|
|
105474
|
+
return { model: OPENCODE_DEFAULT_MODEL, reason: "fallback default" };
|
|
105475
|
+
}
|
|
105476
|
+
var clackPrompter = async ({ suggestion, reason, detectedProviders }) => {
|
|
105477
|
+
const providersHint = detectedProviders.length > 0 ? `Authenticated providers in opencode: ${detectedProviders.join(", ")}` : "No authenticated providers detected in opencode.";
|
|
105478
|
+
const response = await ie({
|
|
105479
|
+
message: `No default model in opencode.json. ${providersHint}`,
|
|
105480
|
+
options: [
|
|
105481
|
+
{
|
|
105482
|
+
value: "accept",
|
|
105483
|
+
label: `Write "${suggestion}"`,
|
|
105484
|
+
hint: reason
|
|
105485
|
+
},
|
|
105486
|
+
{ value: "custom", label: "Enter a different model..." },
|
|
105487
|
+
{ value: "skip", label: "Skip — I'll configure opencode.json myself" }
|
|
105488
|
+
],
|
|
105489
|
+
initialValue: "accept"
|
|
105490
|
+
});
|
|
105491
|
+
if (lD(response) || response === "skip")
|
|
105492
|
+
return { action: "skip" };
|
|
105493
|
+
if (response === "accept")
|
|
105494
|
+
return { action: "accept" };
|
|
105495
|
+
const custom2 = await te({
|
|
105496
|
+
message: "Model (format: provider/model-id, e.g. openai/gpt-5)",
|
|
105497
|
+
placeholder: suggestion,
|
|
105498
|
+
validate: (value) => {
|
|
105499
|
+
if (!value || !value.includes("/"))
|
|
105500
|
+
return "Must be in 'provider/model-id' format";
|
|
105501
|
+
return;
|
|
105502
|
+
}
|
|
105503
|
+
});
|
|
105504
|
+
if (lD(custom2))
|
|
105505
|
+
return { action: "skip" };
|
|
105506
|
+
return { action: "custom", value: custom2 };
|
|
105507
|
+
};
|
|
105508
|
+
async function ensureOpenCodeModel(options2) {
|
|
105509
|
+
const configPath = getOpenCodeConfigPath(options2);
|
|
105510
|
+
let existing = null;
|
|
105511
|
+
try {
|
|
105512
|
+
const raw2 = await readFile59(configPath, "utf-8");
|
|
105513
|
+
const parsed = JSON.parse(raw2);
|
|
105514
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
105515
|
+
existing = parsed;
|
|
105516
|
+
} else {
|
|
105517
|
+
logger.warning(`ensureOpenCodeModel: ${configPath} is valid JSON but not an object; overwriting with default model`);
|
|
105518
|
+
}
|
|
105519
|
+
} catch (err) {
|
|
105520
|
+
const errno = err?.code;
|
|
105521
|
+
if (errno === "ENOENT") {} else if (err instanceof SyntaxError) {
|
|
105522
|
+
logger.warning(`ensureOpenCodeModel: ${configPath} is not valid JSON; overwriting with default model (existing contents will be lost)`);
|
|
105523
|
+
} else {
|
|
105524
|
+
logger.verbose(`ensureOpenCodeModel: failed to read ${configPath} (${errno ?? String(err)}); recreating`);
|
|
105525
|
+
}
|
|
105526
|
+
}
|
|
105527
|
+
if (existing && typeof existing.model === "string" && existing.model.trim().length > 0) {
|
|
105528
|
+
return { path: configPath, action: "existing", model: existing.model };
|
|
105529
|
+
}
|
|
105530
|
+
const suggestion = await suggestOpenCodeDefaultModel(options2.homeDir);
|
|
105531
|
+
let chosenModel = suggestion.model;
|
|
105532
|
+
if (options2.interactive) {
|
|
105533
|
+
const detectedProviders = await detectAuthenticatedProviders(options2.homeDir);
|
|
105534
|
+
const prompter = options2.prompter ?? clackPrompter;
|
|
105535
|
+
const response = await prompter({
|
|
105536
|
+
suggestion: suggestion.model,
|
|
105537
|
+
reason: suggestion.reason,
|
|
105538
|
+
detectedProviders
|
|
105539
|
+
});
|
|
105540
|
+
if (response.action === "skip") {
|
|
105541
|
+
return {
|
|
105542
|
+
path: configPath,
|
|
105543
|
+
action: "skipped",
|
|
105544
|
+
model: "",
|
|
105545
|
+
reason: "user declined"
|
|
105546
|
+
};
|
|
105547
|
+
}
|
|
105548
|
+
if (response.action === "custom") {
|
|
105549
|
+
chosenModel = response.value;
|
|
105550
|
+
}
|
|
105551
|
+
}
|
|
105552
|
+
const next = { ...existing ?? {}, model: chosenModel };
|
|
105553
|
+
await mkdir33(dirname38(configPath), { recursive: true });
|
|
105554
|
+
await writeFile33(configPath, `${JSON.stringify(next, null, 2)}
|
|
105555
|
+
`, "utf-8");
|
|
105556
|
+
return {
|
|
105557
|
+
path: configPath,
|
|
105558
|
+
action: existing ? "added" : "created",
|
|
105559
|
+
model: chosenModel,
|
|
105560
|
+
reason: suggestion.reason
|
|
105561
|
+
};
|
|
105562
|
+
}
|
|
105563
|
+
|
|
105442
105564
|
// src/commands/portable/plan-display.ts
|
|
105443
105565
|
var import_picocolors28 = __toESM(require_picocolors(), 1);
|
|
105444
|
-
import { basename as basename25, dirname as
|
|
105566
|
+
import { basename as basename25, dirname as dirname39, extname as extname7 } from "node:path";
|
|
105445
105567
|
var DEFAULT_MAX_PLAN_GROUP_ITEMS = 20;
|
|
105446
105568
|
var TYPE_ORDER = [
|
|
105447
105569
|
"agent",
|
|
@@ -105667,21 +105789,21 @@ function collectPlannedWhereLines(plan) {
|
|
|
105667
105789
|
return destinations.map((destination) => `${formatDisplayPath(destination)} -> ${formatCdHint(resolveCdTarget(destination))}`);
|
|
105668
105790
|
}
|
|
105669
105791
|
function resolveCdTarget(destination) {
|
|
105670
|
-
return extname7(destination).length > 0 ?
|
|
105792
|
+
return extname7(destination).length > 0 ? dirname39(destination) : destination;
|
|
105671
105793
|
}
|
|
105672
105794
|
function normalizeWhereDestination(path16, portableType) {
|
|
105673
105795
|
if (portableType === "agent" || portableType === "command" || portableType === "skill") {
|
|
105674
|
-
return
|
|
105796
|
+
return dirname39(path16);
|
|
105675
105797
|
}
|
|
105676
105798
|
if (portableType === "hooks") {
|
|
105677
|
-
return
|
|
105799
|
+
return dirname39(path16);
|
|
105678
105800
|
}
|
|
105679
105801
|
if (portableType === "rules") {
|
|
105680
105802
|
const fileName = basename25(path16).toLowerCase();
|
|
105681
105803
|
if (fileName === "agents.md" || fileName === "gemini.md" || fileName === ".goosehints" || fileName === "custom_modes.yaml" || fileName === "custom_modes.yml") {
|
|
105682
105804
|
return path16;
|
|
105683
105805
|
}
|
|
105684
|
-
return
|
|
105806
|
+
return dirname39(path16);
|
|
105685
105807
|
}
|
|
105686
105808
|
return path16;
|
|
105687
105809
|
}
|
|
@@ -106020,12 +106142,12 @@ async function executeDeleteAction(action, options2) {
|
|
|
106020
106142
|
async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
106021
106143
|
if (!skillSourcePath)
|
|
106022
106144
|
return;
|
|
106023
|
-
const sourceMetadataPath =
|
|
106145
|
+
const sourceMetadataPath = join140(resolve36(skillSourcePath, ".."), "metadata.json");
|
|
106024
106146
|
if (!existsSync62(sourceMetadataPath))
|
|
106025
106147
|
return;
|
|
106026
106148
|
let sourceMetadata;
|
|
106027
106149
|
try {
|
|
106028
|
-
const content = await
|
|
106150
|
+
const content = await readFile60(sourceMetadataPath, "utf-8");
|
|
106029
106151
|
sourceMetadata = JSON.parse(content);
|
|
106030
106152
|
} catch (error) {
|
|
106031
106153
|
logger.debug(`[migrate] Failed to parse source metadata.json: ${error}`);
|
|
@@ -106033,7 +106155,7 @@ async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
|
106033
106155
|
}
|
|
106034
106156
|
if (!sourceMetadata.deletions || sourceMetadata.deletions.length === 0)
|
|
106035
106157
|
return;
|
|
106036
|
-
const claudeDir3 = installGlobally ?
|
|
106158
|
+
const claudeDir3 = installGlobally ? join140(homedir47(), ".claude") : join140(process.cwd(), ".claude");
|
|
106037
106159
|
if (!existsSync62(claudeDir3))
|
|
106038
106160
|
return;
|
|
106039
106161
|
try {
|
|
@@ -106150,8 +106272,8 @@ async function migrateCommand(options2) {
|
|
|
106150
106272
|
let requestedGlobal = options2.global ?? false;
|
|
106151
106273
|
let installGlobally = requestedGlobal;
|
|
106152
106274
|
if (options2.global === undefined && !options2.yes) {
|
|
106153
|
-
const projectTarget =
|
|
106154
|
-
const globalTarget =
|
|
106275
|
+
const projectTarget = join140(process.cwd(), ".claude");
|
|
106276
|
+
const globalTarget = join140(homedir47(), ".claude");
|
|
106155
106277
|
const scopeChoice = await ie({
|
|
106156
106278
|
message: "Installation scope",
|
|
106157
106279
|
options: [
|
|
@@ -106280,7 +106402,7 @@ async function migrateCommand(options2) {
|
|
|
106280
106402
|
for (const action of conflictActions) {
|
|
106281
106403
|
if (!action.diff && action.targetPath && existsSync62(action.targetPath)) {
|
|
106282
106404
|
try {
|
|
106283
|
-
const targetContent = await
|
|
106405
|
+
const targetContent = await readFile60(action.targetPath, "utf-8");
|
|
106284
106406
|
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
106407
|
if (sourceItem) {
|
|
106286
106408
|
const providerConfig = providers[action.provider];
|
|
@@ -106400,6 +106522,22 @@ async function migrateCommand(options2) {
|
|
|
106400
106522
|
}
|
|
106401
106523
|
progressSink.tick(progressLabelForType(task.type));
|
|
106402
106524
|
}
|
|
106525
|
+
if (selectedProviders.includes("opencode")) {
|
|
106526
|
+
try {
|
|
106527
|
+
const result = await ensureOpenCodeModel({
|
|
106528
|
+
global: installGlobally,
|
|
106529
|
+
interactive: process.stdout.isTTY === true && !options2.yes
|
|
106530
|
+
});
|
|
106531
|
+
if (result.action === "created" || result.action === "added") {
|
|
106532
|
+
const reason = result.reason ? ` (${result.reason})` : "";
|
|
106533
|
+
f2.info(`Set default model "${result.model}" in ${result.path}${reason}`);
|
|
106534
|
+
} else if (result.action === "skipped") {
|
|
106535
|
+
f2.warn("Skipped writing default model to opencode.json. Migrated agents may fail with ProviderModelNotFoundError until you set one.");
|
|
106536
|
+
}
|
|
106537
|
+
} catch (err) {
|
|
106538
|
+
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.`);
|
|
106539
|
+
}
|
|
106540
|
+
}
|
|
106403
106541
|
for (const [hooksProvider, files] of successfulHookFiles) {
|
|
106404
106542
|
if (files.length === 0)
|
|
106405
106543
|
continue;
|
|
@@ -106628,7 +106766,7 @@ function buildDryRunFallbackResults(skills, selectedProviders, installGlobally,
|
|
|
106628
106766
|
results.push({
|
|
106629
106767
|
itemName: skill.name,
|
|
106630
106768
|
operation: "apply",
|
|
106631
|
-
path:
|
|
106769
|
+
path: join140(basePath, skill.name),
|
|
106632
106770
|
portableType: "skill",
|
|
106633
106771
|
provider,
|
|
106634
106772
|
providerDisplayName: providers[provider].displayName,
|
|
@@ -106788,7 +106926,7 @@ async function handleDirectorySetup(ctx) {
|
|
|
106788
106926
|
// src/commands/new/phases/project-creation.ts
|
|
106789
106927
|
init_config_manager();
|
|
106790
106928
|
init_github_client();
|
|
106791
|
-
import { join as
|
|
106929
|
+
import { join as join141 } from "node:path";
|
|
106792
106930
|
init_logger();
|
|
106793
106931
|
init_output_manager();
|
|
106794
106932
|
init_types3();
|
|
@@ -106914,7 +107052,7 @@ async function projectCreation(kit, resolvedDir, validOptions, isNonInteractive2
|
|
|
106914
107052
|
output.section("Installing");
|
|
106915
107053
|
logger.verbose("Installation target", { directory: resolvedDir });
|
|
106916
107054
|
const merger = new FileMerger;
|
|
106917
|
-
const claudeDir3 =
|
|
107055
|
+
const claudeDir3 = join141(resolvedDir, ".claude");
|
|
106918
107056
|
merger.setMultiKitContext(claudeDir3, kit);
|
|
106919
107057
|
if (validOptions.exclude && validOptions.exclude.length > 0) {
|
|
106920
107058
|
merger.addIgnorePatterns(validOptions.exclude);
|
|
@@ -106961,7 +107099,7 @@ async function handleProjectCreation(ctx) {
|
|
|
106961
107099
|
}
|
|
106962
107100
|
// src/commands/new/phases/post-setup.ts
|
|
106963
107101
|
init_projects_registry();
|
|
106964
|
-
import { join as
|
|
107102
|
+
import { join as join142 } from "node:path";
|
|
106965
107103
|
init_package_installer();
|
|
106966
107104
|
init_logger();
|
|
106967
107105
|
init_path_resolver();
|
|
@@ -106993,9 +107131,9 @@ async function postSetup(resolvedDir, validOptions, isNonInteractive2, prompts)
|
|
|
106993
107131
|
withSudo: validOptions.withSudo
|
|
106994
107132
|
});
|
|
106995
107133
|
}
|
|
106996
|
-
const claudeDir3 =
|
|
107134
|
+
const claudeDir3 = join142(resolvedDir, ".claude");
|
|
106997
107135
|
await promptSetupWizardIfNeeded({
|
|
106998
|
-
envPath:
|
|
107136
|
+
envPath: join142(claudeDir3, ".env"),
|
|
106999
107137
|
claudeDir: claudeDir3,
|
|
107000
107138
|
isGlobal: false,
|
|
107001
107139
|
isNonInteractive: isNonInteractive2,
|
|
@@ -107065,7 +107203,7 @@ Please use only one download method.`);
|
|
|
107065
107203
|
// src/commands/plan/plan-command.ts
|
|
107066
107204
|
init_output_manager();
|
|
107067
107205
|
import { existsSync as existsSync65, statSync as statSync11 } from "node:fs";
|
|
107068
|
-
import { dirname as
|
|
107206
|
+
import { dirname as dirname43, isAbsolute as isAbsolute11, join as join145, parse as parse7, resolve as resolve41 } from "node:path";
|
|
107069
107207
|
|
|
107070
107208
|
// src/commands/plan/plan-read-handlers.ts
|
|
107071
107209
|
init_config();
|
|
@@ -107075,18 +107213,18 @@ init_logger();
|
|
|
107075
107213
|
init_output_manager();
|
|
107076
107214
|
var import_picocolors32 = __toESM(require_picocolors(), 1);
|
|
107077
107215
|
import { existsSync as existsSync64, statSync as statSync10 } from "node:fs";
|
|
107078
|
-
import { basename as basename27, dirname as
|
|
107216
|
+
import { basename as basename27, dirname as dirname41, join as join144, relative as relative27, resolve as resolve39 } from "node:path";
|
|
107079
107217
|
|
|
107080
107218
|
// src/commands/plan/plan-dependencies.ts
|
|
107081
107219
|
init_config();
|
|
107082
107220
|
init_plan_parser();
|
|
107083
107221
|
init_plans_registry();
|
|
107084
107222
|
import { existsSync as existsSync63 } from "node:fs";
|
|
107085
|
-
import { dirname as
|
|
107223
|
+
import { dirname as dirname40, join as join143 } from "node:path";
|
|
107086
107224
|
async function resolvePlanDependencies(references, currentPlanFile, options2 = {}) {
|
|
107087
107225
|
if (references.length === 0)
|
|
107088
107226
|
return [];
|
|
107089
|
-
const currentPlanDir =
|
|
107227
|
+
const currentPlanDir = dirname40(currentPlanFile);
|
|
107090
107228
|
const projectRoot = findProjectRoot(currentPlanDir);
|
|
107091
107229
|
const config = options2.preloadedConfig ?? (await CkConfigManager.loadFull(projectRoot)).config;
|
|
107092
107230
|
const defaultScope = inferPlanScopeForDir(currentPlanDir, config);
|
|
@@ -107102,7 +107240,7 @@ async function resolvePlanDependencies(references, currentPlanFile, options2 = {
|
|
|
107102
107240
|
};
|
|
107103
107241
|
}
|
|
107104
107242
|
const scopeRoot = resolvePlanDirForScope(scope, projectRoot, config);
|
|
107105
|
-
const planFile =
|
|
107243
|
+
const planFile = join143(scopeRoot, planId, "plan.md");
|
|
107106
107244
|
const isSelfReference = planFile === currentPlanFile;
|
|
107107
107245
|
if (!existsSync63(planFile)) {
|
|
107108
107246
|
return {
|
|
@@ -107173,7 +107311,7 @@ async function handleParse(target, options2) {
|
|
|
107173
107311
|
console.log(JSON.stringify({ file: relative27(process.cwd(), planFile), frontmatter, phases }, null, 2));
|
|
107174
107312
|
return;
|
|
107175
107313
|
}
|
|
107176
|
-
const title = typeof frontmatter.title === "string" ? frontmatter.title : basename27(
|
|
107314
|
+
const title = typeof frontmatter.title === "string" ? frontmatter.title : basename27(dirname41(planFile));
|
|
107177
107315
|
console.log();
|
|
107178
107316
|
console.log(import_picocolors32.default.bold(` Plan: ${title}`));
|
|
107179
107317
|
console.log(` File: ${planFile}`);
|
|
@@ -107244,7 +107382,7 @@ async function handleStatus(target, options2) {
|
|
|
107244
107382
|
}
|
|
107245
107383
|
const effectiveTarget = !resolvedTarget && globalBaseDir ? globalBaseDir : resolvedTarget;
|
|
107246
107384
|
const t = effectiveTarget ? resolve39(effectiveTarget) : null;
|
|
107247
|
-
const plansDir = t && existsSync64(t) && statSync10(t).isDirectory() && !existsSync64(
|
|
107385
|
+
const plansDir = t && existsSync64(t) && statSync10(t).isDirectory() && !existsSync64(join144(t, "plan.md")) ? t : null;
|
|
107248
107386
|
if (plansDir) {
|
|
107249
107387
|
const planFiles = scanPlanDir(plansDir);
|
|
107250
107388
|
if (planFiles.length === 0) {
|
|
@@ -107284,7 +107422,7 @@ async function handleStatus(target, options2) {
|
|
|
107284
107422
|
const blockedBy2 = await resolvePlanDependencies(s.blockedBy, pf, { preloadedConfig });
|
|
107285
107423
|
const blocks2 = await resolvePlanDependencies(s.blocks, pf, { preloadedConfig });
|
|
107286
107424
|
const bar = progressBar(s.completed, s.totalPhases);
|
|
107287
|
-
const title2 = s.title ?? basename27(
|
|
107425
|
+
const title2 = s.title ?? basename27(dirname41(pf));
|
|
107288
107426
|
console.log(` ${import_picocolors32.default.bold(title2)}`);
|
|
107289
107427
|
console.log(` ${bar}`);
|
|
107290
107428
|
if (s.inProgress > 0)
|
|
@@ -107303,7 +107441,7 @@ async function handleStatus(target, options2) {
|
|
|
107303
107441
|
}
|
|
107304
107442
|
console.log();
|
|
107305
107443
|
} catch {
|
|
107306
|
-
console.log(` [X] Failed to read: ${basename27(
|
|
107444
|
+
console.log(` [X] Failed to read: ${basename27(dirname41(pf))}`);
|
|
107307
107445
|
console.log();
|
|
107308
107446
|
}
|
|
107309
107447
|
}
|
|
@@ -107330,7 +107468,7 @@ async function handleStatus(target, options2) {
|
|
|
107330
107468
|
console.log(JSON.stringify({ ...summary, dependencyStatus: { blockedBy, blocks } }, null, 2));
|
|
107331
107469
|
return;
|
|
107332
107470
|
}
|
|
107333
|
-
const title = summary.title ?? basename27(
|
|
107471
|
+
const title = summary.title ?? basename27(dirname41(planFile));
|
|
107334
107472
|
console.log();
|
|
107335
107473
|
console.log(import_picocolors32.default.bold(` ${title}`));
|
|
107336
107474
|
if (summary.status)
|
|
@@ -107393,7 +107531,7 @@ async function handleKanban(target, options2) {
|
|
|
107393
107531
|
process.exitCode = 1;
|
|
107394
107532
|
return;
|
|
107395
107533
|
}
|
|
107396
|
-
const route = `/plans?dir=${encodeURIComponent(
|
|
107534
|
+
const route = `/plans?dir=${encodeURIComponent(dirname41(dirname41(planFile)))}&view=kanban`;
|
|
107397
107535
|
const url = `http://localhost:${server.port}${route}`;
|
|
107398
107536
|
console.log();
|
|
107399
107537
|
console.log(import_picocolors32.default.bold(" ClaudeKit Dashboard — Plans"));
|
|
@@ -107428,7 +107566,7 @@ init_plan_parser();
|
|
|
107428
107566
|
init_plans_registry();
|
|
107429
107567
|
init_output_manager();
|
|
107430
107568
|
var import_picocolors33 = __toESM(require_picocolors(), 1);
|
|
107431
|
-
import { basename as basename28, dirname as
|
|
107569
|
+
import { basename as basename28, dirname as dirname42, relative as relative28, resolve as resolve40 } from "node:path";
|
|
107432
107570
|
async function handleCreate(target, options2) {
|
|
107433
107571
|
if (!options2.title) {
|
|
107434
107572
|
output.error("[X] --title is required for create");
|
|
@@ -107528,7 +107666,7 @@ async function handleCheck(target, options2) {
|
|
|
107528
107666
|
process.exitCode = 1;
|
|
107529
107667
|
return;
|
|
107530
107668
|
}
|
|
107531
|
-
const planDir =
|
|
107669
|
+
const planDir = dirname42(planFile);
|
|
107532
107670
|
let planStatus = "pending";
|
|
107533
107671
|
try {
|
|
107534
107672
|
const projectRoot = findProjectRoot(planDir);
|
|
@@ -107577,7 +107715,7 @@ async function handleUncheck(target, options2) {
|
|
|
107577
107715
|
process.exitCode = 1;
|
|
107578
107716
|
return;
|
|
107579
107717
|
}
|
|
107580
|
-
const planDir =
|
|
107718
|
+
const planDir = dirname42(planFile);
|
|
107581
107719
|
try {
|
|
107582
107720
|
const projectRoot = findProjectRoot(planDir);
|
|
107583
107721
|
const summary = buildPlanSummary(planFile);
|
|
@@ -107616,7 +107754,7 @@ async function handleAddPhase(target, options2) {
|
|
|
107616
107754
|
try {
|
|
107617
107755
|
const result = addPhase(planFile, target, options2.after);
|
|
107618
107756
|
try {
|
|
107619
|
-
const planDir =
|
|
107757
|
+
const planDir = dirname42(planFile);
|
|
107620
107758
|
const projectRoot = findProjectRoot(planDir);
|
|
107621
107759
|
updateRegistryAddPhase({
|
|
107622
107760
|
planDir,
|
|
@@ -107659,7 +107797,7 @@ function resolvePlanFile(target, baseDir) {
|
|
|
107659
107797
|
const stat23 = statSync11(t);
|
|
107660
107798
|
if (stat23.isFile())
|
|
107661
107799
|
return t;
|
|
107662
|
-
const candidate =
|
|
107800
|
+
const candidate = join145(t, "plan.md");
|
|
107663
107801
|
if (existsSync65(candidate))
|
|
107664
107802
|
return candidate;
|
|
107665
107803
|
}
|
|
@@ -107667,10 +107805,10 @@ function resolvePlanFile(target, baseDir) {
|
|
|
107667
107805
|
let dir = process.cwd();
|
|
107668
107806
|
const root = parse7(dir).root;
|
|
107669
107807
|
while (dir !== root) {
|
|
107670
|
-
const candidate =
|
|
107808
|
+
const candidate = join145(dir, "plan.md");
|
|
107671
107809
|
if (existsSync65(candidate))
|
|
107672
107810
|
return candidate;
|
|
107673
|
-
dir =
|
|
107811
|
+
dir = dirname43(dir);
|
|
107674
107812
|
}
|
|
107675
107813
|
}
|
|
107676
107814
|
return null;
|
|
@@ -108189,8 +108327,8 @@ init_skills_registry();
|
|
|
108189
108327
|
init_skills_uninstaller();
|
|
108190
108328
|
var import_gray_matter11 = __toESM(require_gray_matter(), 1);
|
|
108191
108329
|
var import_picocolors37 = __toESM(require_picocolors(), 1);
|
|
108192
|
-
import { readFile as
|
|
108193
|
-
import { join as
|
|
108330
|
+
import { readFile as readFile61 } from "node:fs/promises";
|
|
108331
|
+
import { join as join146 } from "node:path";
|
|
108194
108332
|
|
|
108195
108333
|
// src/commands/skills/types.ts
|
|
108196
108334
|
init_zod();
|
|
@@ -108312,9 +108450,9 @@ async function handleValidate2(sourcePath) {
|
|
|
108312
108450
|
spinner.stop(`Checked ${skills.length} skill(s)`);
|
|
108313
108451
|
let hasIssues = false;
|
|
108314
108452
|
for (const skill of skills) {
|
|
108315
|
-
const skillMdPath =
|
|
108453
|
+
const skillMdPath = join146(skill.path, "SKILL.md");
|
|
108316
108454
|
try {
|
|
108317
|
-
const content = await
|
|
108455
|
+
const content = await readFile61(skillMdPath, "utf-8");
|
|
108318
108456
|
const { data } = import_gray_matter11.default(content, {
|
|
108319
108457
|
engines: { javascript: { parse: () => ({}) } }
|
|
108320
108458
|
});
|
|
@@ -108870,7 +109008,7 @@ async function detectInstallations() {
|
|
|
108870
109008
|
|
|
108871
109009
|
// src/commands/uninstall/removal-handler.ts
|
|
108872
109010
|
import { readdirSync as readdirSync9, rmSync as rmSync6 } from "node:fs";
|
|
108873
|
-
import { basename as basename29, join as
|
|
109011
|
+
import { basename as basename29, join as join148, resolve as resolve43, sep as sep11 } from "node:path";
|
|
108874
109012
|
init_logger();
|
|
108875
109013
|
init_safe_prompts();
|
|
108876
109014
|
init_safe_spinner();
|
|
@@ -108879,7 +109017,7 @@ var import_fs_extra44 = __toESM(require_lib3(), 1);
|
|
|
108879
109017
|
// src/commands/uninstall/analysis-handler.ts
|
|
108880
109018
|
init_metadata_migration();
|
|
108881
109019
|
import { readdirSync as readdirSync8, rmSync as rmSync5 } from "node:fs";
|
|
108882
|
-
import { dirname as
|
|
109020
|
+
import { dirname as dirname44, join as join147 } from "node:path";
|
|
108883
109021
|
init_logger();
|
|
108884
109022
|
init_safe_prompts();
|
|
108885
109023
|
var import_fs_extra43 = __toESM(require_lib3(), 1);
|
|
@@ -108901,7 +109039,7 @@ function classifyFileByOwnership(ownership, forceOverwrite, deleteReason) {
|
|
|
108901
109039
|
}
|
|
108902
109040
|
async function cleanupEmptyDirectories3(filePath, installationRoot) {
|
|
108903
109041
|
let cleaned = 0;
|
|
108904
|
-
let currentDir =
|
|
109042
|
+
let currentDir = dirname44(filePath);
|
|
108905
109043
|
while (currentDir !== installationRoot && currentDir.startsWith(installationRoot)) {
|
|
108906
109044
|
try {
|
|
108907
109045
|
const entries = readdirSync8(currentDir);
|
|
@@ -108909,7 +109047,7 @@ async function cleanupEmptyDirectories3(filePath, installationRoot) {
|
|
|
108909
109047
|
rmSync5(currentDir, { recursive: true });
|
|
108910
109048
|
cleaned++;
|
|
108911
109049
|
logger.debug(`Removed empty directory: ${currentDir}`);
|
|
108912
|
-
currentDir =
|
|
109050
|
+
currentDir = dirname44(currentDir);
|
|
108913
109051
|
} else {
|
|
108914
109052
|
break;
|
|
108915
109053
|
}
|
|
@@ -108936,7 +109074,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
108936
109074
|
const remainingFiles = metadata.kits?.[remainingKit]?.files || [];
|
|
108937
109075
|
for (const file of remainingFiles) {
|
|
108938
109076
|
const relativePath = normalizeTrackedPath(file.path);
|
|
108939
|
-
if (await import_fs_extra43.pathExists(
|
|
109077
|
+
if (await import_fs_extra43.pathExists(join147(installation.path, relativePath))) {
|
|
108940
109078
|
result.retainedManifestPaths.push(relativePath);
|
|
108941
109079
|
}
|
|
108942
109080
|
}
|
|
@@ -108944,7 +109082,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
108944
109082
|
const kitFiles = metadata.kits[kit].files || [];
|
|
108945
109083
|
for (const trackedFile of kitFiles) {
|
|
108946
109084
|
const relativePath = normalizeTrackedPath(trackedFile.path);
|
|
108947
|
-
const filePath =
|
|
109085
|
+
const filePath = join147(installation.path, relativePath);
|
|
108948
109086
|
if (preservedPaths.has(relativePath)) {
|
|
108949
109087
|
result.toPreserve.push({ path: relativePath, reason: "shared with other kit" });
|
|
108950
109088
|
continue;
|
|
@@ -108977,7 +109115,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
108977
109115
|
}
|
|
108978
109116
|
for (const trackedFile of allTrackedFiles) {
|
|
108979
109117
|
const relativePath = normalizeTrackedPath(trackedFile.path);
|
|
108980
|
-
const filePath =
|
|
109118
|
+
const filePath = join147(installation.path, relativePath);
|
|
108981
109119
|
const ownershipResult = await OwnershipChecker.checkOwnership(filePath, metadata, installation.path);
|
|
108982
109120
|
if (!ownershipResult.exists)
|
|
108983
109121
|
continue;
|
|
@@ -109120,7 +109258,7 @@ async function removeInstallations(installations, options2) {
|
|
|
109120
109258
|
let removedCount = 0;
|
|
109121
109259
|
let cleanedDirs = 0;
|
|
109122
109260
|
for (const item of analysis.toDelete) {
|
|
109123
|
-
const filePath =
|
|
109261
|
+
const filePath = join148(installation.path, item.path);
|
|
109124
109262
|
if (!await import_fs_extra44.pathExists(filePath))
|
|
109125
109263
|
continue;
|
|
109126
109264
|
if (!await isPathSafeToRemove(filePath, installation.path)) {
|
|
@@ -109454,7 +109592,7 @@ ${import_picocolors40.default.bold(import_picocolors40.default.cyan(result.kitCo
|
|
|
109454
109592
|
init_logger();
|
|
109455
109593
|
import { existsSync as existsSync72 } from "node:fs";
|
|
109456
109594
|
import { rm as rm16 } from "node:fs/promises";
|
|
109457
|
-
import { join as
|
|
109595
|
+
import { join as join155 } from "node:path";
|
|
109458
109596
|
var import_picocolors41 = __toESM(require_picocolors(), 1);
|
|
109459
109597
|
|
|
109460
109598
|
// src/commands/watch/phases/implementation-runner.ts
|
|
@@ -109972,8 +110110,8 @@ function spawnAndCollect3(command, args) {
|
|
|
109972
110110
|
}
|
|
109973
110111
|
|
|
109974
110112
|
// src/commands/watch/phases/issue-processor.ts
|
|
109975
|
-
import { mkdir as
|
|
109976
|
-
import { join as
|
|
110113
|
+
import { mkdir as mkdir34, writeFile as writeFile35 } from "node:fs/promises";
|
|
110114
|
+
import { join as join151 } from "node:path";
|
|
109977
110115
|
|
|
109978
110116
|
// src/commands/watch/phases/approval-detector.ts
|
|
109979
110117
|
init_logger();
|
|
@@ -110351,9 +110489,9 @@ async function checkAwaitingApproval(state, setup, options2, watchLog, projectDi
|
|
|
110351
110489
|
|
|
110352
110490
|
// src/commands/watch/phases/plan-dir-finder.ts
|
|
110353
110491
|
import { readdir as readdir44, stat as stat23 } from "node:fs/promises";
|
|
110354
|
-
import { join as
|
|
110492
|
+
import { join as join150 } from "node:path";
|
|
110355
110493
|
async function findRecentPlanDir(cwd2, issueNumber, watchLog) {
|
|
110356
|
-
const plansRoot =
|
|
110494
|
+
const plansRoot = join150(cwd2, "plans");
|
|
110357
110495
|
try {
|
|
110358
110496
|
const entries = await readdir44(plansRoot);
|
|
110359
110497
|
const tenMinAgo = Date.now() - 10 * 60 * 1000;
|
|
@@ -110362,14 +110500,14 @@ async function findRecentPlanDir(cwd2, issueNumber, watchLog) {
|
|
|
110362
110500
|
for (const entry of entries) {
|
|
110363
110501
|
if (entry === "watch" || entry === "reports" || entry === "visuals")
|
|
110364
110502
|
continue;
|
|
110365
|
-
const dirPath =
|
|
110503
|
+
const dirPath = join150(plansRoot, entry);
|
|
110366
110504
|
const dirStat = await stat23(dirPath);
|
|
110367
110505
|
if (!dirStat.isDirectory())
|
|
110368
110506
|
continue;
|
|
110369
110507
|
if (dirStat.mtimeMs < tenMinAgo)
|
|
110370
110508
|
continue;
|
|
110371
110509
|
try {
|
|
110372
|
-
await stat23(
|
|
110510
|
+
await stat23(join150(dirPath, "plan.md"));
|
|
110373
110511
|
} catch {
|
|
110374
110512
|
continue;
|
|
110375
110513
|
}
|
|
@@ -110600,14 +110738,14 @@ async function handlePlanGeneration(issue, state, config, setup, options2, watch
|
|
|
110600
110738
|
stats.plansCreated++;
|
|
110601
110739
|
const detectedPlanDir = await findRecentPlanDir(projectDir, issue.number, watchLog);
|
|
110602
110740
|
if (detectedPlanDir) {
|
|
110603
|
-
state.activeIssues[numStr].planPath =
|
|
110741
|
+
state.activeIssues[numStr].planPath = join151(detectedPlanDir, "plan.md");
|
|
110604
110742
|
watchLog.info(`Plan directory detected: ${detectedPlanDir}`);
|
|
110605
110743
|
} else {
|
|
110606
110744
|
try {
|
|
110607
|
-
const planDir =
|
|
110608
|
-
await
|
|
110609
|
-
const planFilePath =
|
|
110610
|
-
await
|
|
110745
|
+
const planDir = join151(projectDir, "plans", "watch");
|
|
110746
|
+
await mkdir34(planDir, { recursive: true });
|
|
110747
|
+
const planFilePath = join151(planDir, `issue-${issue.number}-plan.md`);
|
|
110748
|
+
await writeFile35(planFilePath, planResult.planText, "utf-8");
|
|
110611
110749
|
state.activeIssues[numStr].planPath = planFilePath;
|
|
110612
110750
|
watchLog.info(`Plan saved (fallback) to ${planFilePath}`);
|
|
110613
110751
|
} catch (err) {
|
|
@@ -110752,15 +110890,15 @@ init_ck_config_manager();
|
|
|
110752
110890
|
init_file_io();
|
|
110753
110891
|
init_logger();
|
|
110754
110892
|
import { existsSync as existsSync68 } from "node:fs";
|
|
110755
|
-
import { mkdir as
|
|
110756
|
-
import { dirname as
|
|
110893
|
+
import { mkdir as mkdir35, readFile as readFile63 } from "node:fs/promises";
|
|
110894
|
+
import { dirname as dirname45 } from "node:path";
|
|
110757
110895
|
var PROCESSED_ISSUES_CAP = 500;
|
|
110758
110896
|
async function readCkJson(projectDir) {
|
|
110759
110897
|
const configPath = CkConfigManager.getProjectConfigPath(projectDir);
|
|
110760
110898
|
try {
|
|
110761
110899
|
if (!existsSync68(configPath))
|
|
110762
110900
|
return {};
|
|
110763
|
-
const content = await
|
|
110901
|
+
const content = await readFile63(configPath, "utf-8");
|
|
110764
110902
|
return JSON.parse(content);
|
|
110765
110903
|
} catch (error) {
|
|
110766
110904
|
logger.warning(`Failed to parse .ck.json: ${error instanceof Error ? error.message : "Unknown"}`);
|
|
@@ -110783,9 +110921,9 @@ async function loadWatchState(projectDir) {
|
|
|
110783
110921
|
}
|
|
110784
110922
|
async function saveWatchState(projectDir, state) {
|
|
110785
110923
|
const configPath = CkConfigManager.getProjectConfigPath(projectDir);
|
|
110786
|
-
const configDir =
|
|
110924
|
+
const configDir = dirname45(configPath);
|
|
110787
110925
|
if (!existsSync68(configDir)) {
|
|
110788
|
-
await
|
|
110926
|
+
await mkdir35(configDir, { recursive: true });
|
|
110789
110927
|
}
|
|
110790
110928
|
const raw2 = await readCkJson(projectDir);
|
|
110791
110929
|
const watchRaw = raw2.watch ?? {};
|
|
@@ -110913,18 +111051,18 @@ init_logger();
|
|
|
110913
111051
|
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
110914
111052
|
import { existsSync as existsSync69 } from "node:fs";
|
|
110915
111053
|
import { readdir as readdir45, stat as stat24 } from "node:fs/promises";
|
|
110916
|
-
import { join as
|
|
111054
|
+
import { join as join152 } from "node:path";
|
|
110917
111055
|
async function scanForRepos(parentDir) {
|
|
110918
111056
|
const repos = [];
|
|
110919
111057
|
const entries = await readdir45(parentDir);
|
|
110920
111058
|
for (const entry of entries) {
|
|
110921
111059
|
if (entry.startsWith("."))
|
|
110922
111060
|
continue;
|
|
110923
|
-
const fullPath =
|
|
111061
|
+
const fullPath = join152(parentDir, entry);
|
|
110924
111062
|
const entryStat = await stat24(fullPath);
|
|
110925
111063
|
if (!entryStat.isDirectory())
|
|
110926
111064
|
continue;
|
|
110927
|
-
const gitDir =
|
|
111065
|
+
const gitDir = join152(fullPath, ".git");
|
|
110928
111066
|
if (!existsSync69(gitDir))
|
|
110929
111067
|
continue;
|
|
110930
111068
|
const result = spawnSync7("gh", ["repo", "view", "--json", "owner,name"], {
|
|
@@ -110950,8 +111088,8 @@ async function scanForRepos(parentDir) {
|
|
|
110950
111088
|
init_logger();
|
|
110951
111089
|
import { spawnSync as spawnSync8 } from "node:child_process";
|
|
110952
111090
|
import { existsSync as existsSync70 } from "node:fs";
|
|
110953
|
-
import { homedir as
|
|
110954
|
-
import { join as
|
|
111091
|
+
import { homedir as homedir48 } from "node:os";
|
|
111092
|
+
import { join as join153 } from "node:path";
|
|
110955
111093
|
async function validateSetup(cwd2) {
|
|
110956
111094
|
const workDir = cwd2 ?? process.cwd();
|
|
110957
111095
|
const ghVersion = spawnSync8("gh", ["--version"], { encoding: "utf-8", timeout: 1e4 });
|
|
@@ -110982,7 +111120,7 @@ Run this command from a directory with a GitHub remote.`);
|
|
|
110982
111120
|
} catch {
|
|
110983
111121
|
throw new Error(`Failed to parse repository info: ${ghRepo.stdout}`);
|
|
110984
111122
|
}
|
|
110985
|
-
const skillsPath =
|
|
111123
|
+
const skillsPath = join153(homedir48(), ".claude", "skills");
|
|
110986
111124
|
const skillsAvailable = existsSync70(skillsPath);
|
|
110987
111125
|
if (!skillsAvailable) {
|
|
110988
111126
|
logger.warning(`ClaudeKit Engineer skills not found at ${skillsPath}`);
|
|
@@ -111000,8 +111138,8 @@ init_logger();
|
|
|
111000
111138
|
init_path_resolver();
|
|
111001
111139
|
import { createWriteStream as createWriteStream3, statSync as statSync12 } from "node:fs";
|
|
111002
111140
|
import { existsSync as existsSync71 } from "node:fs";
|
|
111003
|
-
import { mkdir as
|
|
111004
|
-
import { join as
|
|
111141
|
+
import { mkdir as mkdir36, rename as rename11 } from "node:fs/promises";
|
|
111142
|
+
import { join as join154 } from "node:path";
|
|
111005
111143
|
|
|
111006
111144
|
class WatchLogger {
|
|
111007
111145
|
logStream = null;
|
|
@@ -111009,16 +111147,16 @@ class WatchLogger {
|
|
|
111009
111147
|
logPath = null;
|
|
111010
111148
|
maxBytes;
|
|
111011
111149
|
constructor(logDir, maxBytes = 0) {
|
|
111012
|
-
this.logDir = logDir ??
|
|
111150
|
+
this.logDir = logDir ?? join154(PathResolver.getClaudeKitDir(), "logs");
|
|
111013
111151
|
this.maxBytes = maxBytes;
|
|
111014
111152
|
}
|
|
111015
111153
|
async init() {
|
|
111016
111154
|
try {
|
|
111017
111155
|
if (!existsSync71(this.logDir)) {
|
|
111018
|
-
await
|
|
111156
|
+
await mkdir36(this.logDir, { recursive: true });
|
|
111019
111157
|
}
|
|
111020
111158
|
const dateStr = formatDate(new Date);
|
|
111021
|
-
this.logPath =
|
|
111159
|
+
this.logPath = join154(this.logDir, `watch-${dateStr}.log`);
|
|
111022
111160
|
this.logStream = createWriteStream3(this.logPath, { flags: "a", mode: 384 });
|
|
111023
111161
|
} catch (error) {
|
|
111024
111162
|
logger.warning(`Cannot create watch log file: ${error instanceof Error ? error.message : "Unknown"}`);
|
|
@@ -111200,7 +111338,7 @@ async function watchCommand(options2) {
|
|
|
111200
111338
|
}
|
|
111201
111339
|
async function discoverRepos(options2, watchLog) {
|
|
111202
111340
|
const cwd2 = process.cwd();
|
|
111203
|
-
const isGitRepo = existsSync72(
|
|
111341
|
+
const isGitRepo = existsSync72(join155(cwd2, ".git"));
|
|
111204
111342
|
if (options2.force) {
|
|
111205
111343
|
await forceRemoveLock(watchLog);
|
|
111206
111344
|
}
|
|
@@ -111459,7 +111597,7 @@ function registerCommands(cli) {
|
|
|
111459
111597
|
init_package();
|
|
111460
111598
|
init_config_version_checker();
|
|
111461
111599
|
import { existsSync as existsSync84, readFileSync as readFileSync22 } from "node:fs";
|
|
111462
|
-
import { join as
|
|
111600
|
+
import { join as join167 } from "node:path";
|
|
111463
111601
|
|
|
111464
111602
|
// src/domains/versioning/version-checker.ts
|
|
111465
111603
|
init_version_utils();
|
|
@@ -111473,15 +111611,15 @@ init_types3();
|
|
|
111473
111611
|
init_logger();
|
|
111474
111612
|
init_path_resolver();
|
|
111475
111613
|
import { existsSync as existsSync83 } from "node:fs";
|
|
111476
|
-
import { mkdir as
|
|
111477
|
-
import { join as
|
|
111614
|
+
import { mkdir as mkdir37, readFile as readFile65, writeFile as writeFile38 } from "node:fs/promises";
|
|
111615
|
+
import { join as join166 } from "node:path";
|
|
111478
111616
|
|
|
111479
111617
|
class VersionCacheManager {
|
|
111480
111618
|
static CACHE_FILENAME = "version-check.json";
|
|
111481
111619
|
static CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000;
|
|
111482
111620
|
static getCacheFile() {
|
|
111483
111621
|
const cacheDir = PathResolver.getCacheDir(false);
|
|
111484
|
-
return
|
|
111622
|
+
return join166(cacheDir, VersionCacheManager.CACHE_FILENAME);
|
|
111485
111623
|
}
|
|
111486
111624
|
static async load() {
|
|
111487
111625
|
const cacheFile = VersionCacheManager.getCacheFile();
|
|
@@ -111490,7 +111628,7 @@ class VersionCacheManager {
|
|
|
111490
111628
|
logger.debug("Version check cache not found");
|
|
111491
111629
|
return null;
|
|
111492
111630
|
}
|
|
111493
|
-
const content = await
|
|
111631
|
+
const content = await readFile65(cacheFile, "utf-8");
|
|
111494
111632
|
const cache5 = JSON.parse(content);
|
|
111495
111633
|
if (!cache5.lastCheck || !cache5.currentVersion || !cache5.latestVersion) {
|
|
111496
111634
|
logger.debug("Invalid cache structure, ignoring");
|
|
@@ -111508,9 +111646,9 @@ class VersionCacheManager {
|
|
|
111508
111646
|
const cacheDir = PathResolver.getCacheDir(false);
|
|
111509
111647
|
try {
|
|
111510
111648
|
if (!existsSync83(cacheDir)) {
|
|
111511
|
-
await
|
|
111649
|
+
await mkdir37(cacheDir, { recursive: true, mode: 448 });
|
|
111512
111650
|
}
|
|
111513
|
-
await
|
|
111651
|
+
await writeFile38(cacheFile, JSON.stringify(cache5, null, 2), "utf-8");
|
|
111514
111652
|
logger.debug(`Version check cache saved to ${cacheFile}`);
|
|
111515
111653
|
} catch (error) {
|
|
111516
111654
|
logger.debug(`Failed to save version check cache: ${error}`);
|
|
@@ -111792,9 +111930,9 @@ async function displayVersion() {
|
|
|
111792
111930
|
let localInstalledKits = [];
|
|
111793
111931
|
let globalInstalledKits = [];
|
|
111794
111932
|
const globalKitDir = PathResolver.getGlobalKitDir();
|
|
111795
|
-
const globalMetadataPath =
|
|
111933
|
+
const globalMetadataPath = join167(globalKitDir, "metadata.json");
|
|
111796
111934
|
const prefix = PathResolver.getPathPrefix(false);
|
|
111797
|
-
const localMetadataPath = prefix ?
|
|
111935
|
+
const localMetadataPath = prefix ? join167(process.cwd(), prefix, "metadata.json") : join167(process.cwd(), "metadata.json");
|
|
111798
111936
|
const isLocalSameAsGlobal = localMetadataPath === globalMetadataPath;
|
|
111799
111937
|
if (!isLocalSameAsGlobal && existsSync84(localMetadataPath)) {
|
|
111800
111938
|
try {
|