claudekit-cli 3.42.2-dev.8 → 3.42.2-dev.9

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/dist/index.js CHANGED
@@ -6944,7 +6944,7 @@ function resolveModel(sourceModel, targetProvider) {
6944
6944
  }
6945
6945
  return { resolved: providerMap[tier] };
6946
6946
  }
6947
- var OPENCODE_DEFAULT_MODEL = "anthropic/claude-sonnet-4-6", SOURCE_TIER_MAP, DEFAULT_PROVIDER_MODEL_MAP, userOverrides;
6947
+ var SOURCE_TIER_MAP, DEFAULT_PROVIDER_MODEL_MAP, userOverrides;
6948
6948
  var init_model_taxonomy = __esm(() => {
6949
6949
  SOURCE_TIER_MAP = {
6950
6950
  opus: "heavy",
@@ -62389,7 +62389,7 @@ var package_default;
62389
62389
  var init_package = __esm(() => {
62390
62390
  package_default = {
62391
62391
  name: "claudekit-cli",
62392
- version: "3.42.2-dev.8",
62392
+ version: "3.42.2-dev.9",
62393
62393
  description: "CLI tool for bootstrapping and updating ClaudeKit projects",
62394
62394
  type: "module",
62395
62395
  repository: {
@@ -73556,10 +73556,10 @@ __export(exports_worktree_manager, {
73556
73556
  cleanupAllWorktrees: () => cleanupAllWorktrees
73557
73557
  });
73558
73558
  import { existsSync as existsSync69 } from "node:fs";
73559
- import { readFile as readFile63, writeFile as writeFile36 } from "node:fs/promises";
73560
- import { join as join151 } from "node:path";
73559
+ import { readFile as readFile65, writeFile as writeFile37 } from "node:fs/promises";
73560
+ import { join as join153 } from "node:path";
73561
73561
  async function createWorktree(projectDir, issueNumber, baseBranch) {
73562
- const worktreePath = join151(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
73562
+ const worktreePath = join153(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
73563
73563
  const branchName = `ck-watch/issue-${issueNumber}`;
73564
73564
  await spawnAndCollect("git", ["fetch", "origin", baseBranch], projectDir).catch(() => {
73565
73565
  logger.warning(`[worktree] Could not fetch origin/${baseBranch}, using local`);
@@ -73577,7 +73577,7 @@ async function createWorktree(projectDir, issueNumber, baseBranch) {
73577
73577
  return worktreePath;
73578
73578
  }
73579
73579
  async function removeWorktree(projectDir, issueNumber) {
73580
- const worktreePath = join151(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
73580
+ const worktreePath = join153(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
73581
73581
  const branchName = `ck-watch/issue-${issueNumber}`;
73582
73582
  try {
73583
73583
  await spawnAndCollect("git", ["worktree", "remove", worktreePath, "--force"], projectDir);
@@ -73591,7 +73591,7 @@ async function listActiveWorktrees(projectDir) {
73591
73591
  try {
73592
73592
  const output2 = await spawnAndCollect("git", ["worktree", "list", "--porcelain"], projectDir);
73593
73593
  const issueNumbers = [];
73594
- const worktreePrefix = join151(projectDir, WORKTREE_DIR, "issue-").replace(/\\/g, "/");
73594
+ const worktreePrefix = join153(projectDir, WORKTREE_DIR, "issue-").replace(/\\/g, "/");
73595
73595
  for (const line of output2.split(`
73596
73596
  `)) {
73597
73597
  if (line.startsWith("worktree ")) {
@@ -73619,16 +73619,16 @@ async function cleanupAllWorktrees(projectDir) {
73619
73619
  await spawnAndCollect("git", ["worktree", "prune"], projectDir).catch(() => {});
73620
73620
  }
73621
73621
  async function ensureGitignore(projectDir) {
73622
- const gitignorePath = join151(projectDir, ".gitignore");
73622
+ const gitignorePath = join153(projectDir, ".gitignore");
73623
73623
  try {
73624
- const content = existsSync69(gitignorePath) ? await readFile63(gitignorePath, "utf-8") : "";
73624
+ const content = existsSync69(gitignorePath) ? await readFile65(gitignorePath, "utf-8") : "";
73625
73625
  if (!content.includes(".worktrees")) {
73626
73626
  const newContent = content.endsWith(`
73627
73627
  `) ? `${content}.worktrees/
73628
73628
  ` : `${content}
73629
73629
  .worktrees/
73630
73630
  `;
73631
- await writeFile36(gitignorePath, newContent, "utf-8");
73631
+ await writeFile37(gitignorePath, newContent, "utf-8");
73632
73632
  logger.info("[worktree] Added .worktrees/ to .gitignore");
73633
73633
  }
73634
73634
  } catch (err) {
@@ -73657,15 +73657,15 @@ function countTwitterChars(text) {
73657
73657
  }
73658
73658
  return count;
73659
73659
  }
73660
- function validateContent(content, platform17) {
73660
+ function validateContent(content, platform18) {
73661
73661
  const issues = [];
73662
73662
  if (!content.text || content.text.trim().length === 0) {
73663
73663
  issues.push("Content text is empty");
73664
73664
  return { valid: false, issues };
73665
73665
  }
73666
- if (platform17 !== "x_thread") {
73667
- const limit = platform17 === "facebook" ? 500 : 280;
73668
- const charCount = platform17 === "x" ? countTwitterChars(content.text) : content.text.length;
73666
+ if (platform18 !== "x_thread") {
73667
+ const limit = platform18 === "facebook" ? 500 : 280;
73668
+ const charCount = platform18 === "x" ? countTwitterChars(content.text) : content.text.length;
73669
73669
  if (charCount > limit) {
73670
73670
  issues.push(`Text exceeds ${limit} char limit (${charCount} weighted chars)`);
73671
73671
  }
@@ -73688,7 +73688,7 @@ function validateContent(content, platform17) {
73688
73688
  issues.push("Hook (first sentence) is too long (>25 words)");
73689
73689
  }
73690
73690
  const hashtagCount = content.hashtags?.length ?? 0;
73691
- if (platform17 === "x" && hashtagCount > 5) {
73691
+ if (platform18 === "x" && hashtagCount > 5) {
73692
73692
  issues.push("Too many hashtags for X (max 5)");
73693
73693
  }
73694
73694
  return { valid: issues.length === 0, issues };
@@ -73724,9 +73724,9 @@ var init_content_validator = __esm(() => {
73724
73724
  // src/commands/content/phases/context-cache-manager.ts
73725
73725
  import { createHash as createHash9 } from "node:crypto";
73726
73726
  import { existsSync as existsSync75, mkdirSync as mkdirSync5, readFileSync as readFileSync18, readdirSync as readdirSync11, statSync as statSync14 } from "node:fs";
73727
- import { rename as rename14, writeFile as writeFile38 } from "node:fs/promises";
73728
- import { homedir as homedir52 } from "node:os";
73729
- import { basename as basename31, join as join158 } from "node:path";
73727
+ import { rename as rename15, writeFile as writeFile39 } from "node:fs/promises";
73728
+ import { homedir as homedir54 } from "node:os";
73729
+ import { basename as basename31, join as join160 } from "node:path";
73730
73730
  function getCachedContext(repoPath) {
73731
73731
  const cachePath = getCacheFilePath(repoPath);
73732
73732
  if (!existsSync75(cachePath))
@@ -73735,7 +73735,7 @@ function getCachedContext(repoPath) {
73735
73735
  const raw2 = readFileSync18(cachePath, "utf-8");
73736
73736
  const cache5 = JSON.parse(raw2);
73737
73737
  const age = Date.now() - new Date(cache5.createdAt).getTime();
73738
- if (age >= CACHE_TTL_MS4)
73738
+ if (age >= CACHE_TTL_MS5)
73739
73739
  return null;
73740
73740
  const currentHash = computeSourceHash(repoPath);
73741
73741
  if (currentHash !== cache5.sourceHash)
@@ -73751,8 +73751,8 @@ async function saveCachedContext(repoPath, cache5) {
73751
73751
  }
73752
73752
  const cachePath = getCacheFilePath(repoPath);
73753
73753
  const tmpPath = `${cachePath}.tmp`;
73754
- await writeFile38(tmpPath, JSON.stringify(cache5, null, 2), "utf-8");
73755
- await rename14(tmpPath, cachePath);
73754
+ await writeFile39(tmpPath, JSON.stringify(cache5, null, 2), "utf-8");
73755
+ await rename15(tmpPath, cachePath);
73756
73756
  }
73757
73757
  function computeSourceHash(repoPath) {
73758
73758
  const hash = createHash9("sha256");
@@ -73769,25 +73769,25 @@ function computeSourceHash(repoPath) {
73769
73769
  }
73770
73770
  function getDocSourcePaths(repoPath) {
73771
73771
  const paths = [];
73772
- const docsDir = join158(repoPath, "docs");
73772
+ const docsDir = join160(repoPath, "docs");
73773
73773
  if (existsSync75(docsDir)) {
73774
73774
  try {
73775
73775
  const files = readdirSync11(docsDir);
73776
73776
  for (const f3 of files) {
73777
73777
  if (f3.endsWith(".md"))
73778
- paths.push(join158(docsDir, f3));
73778
+ paths.push(join160(docsDir, f3));
73779
73779
  }
73780
73780
  } catch {}
73781
73781
  }
73782
- const readme = join158(repoPath, "README.md");
73782
+ const readme = join160(repoPath, "README.md");
73783
73783
  if (existsSync75(readme))
73784
73784
  paths.push(readme);
73785
- const stylesDir = join158(repoPath, "assets", "writing-styles");
73785
+ const stylesDir = join160(repoPath, "assets", "writing-styles");
73786
73786
  if (existsSync75(stylesDir)) {
73787
73787
  try {
73788
73788
  const files = readdirSync11(stylesDir);
73789
73789
  for (const f3 of files) {
73790
- paths.push(join158(stylesDir, f3));
73790
+ paths.push(join160(stylesDir, f3));
73791
73791
  }
73792
73792
  } catch {}
73793
73793
  }
@@ -73796,12 +73796,12 @@ function getDocSourcePaths(repoPath) {
73796
73796
  function getCacheFilePath(repoPath) {
73797
73797
  const repoName = basename31(repoPath).replace(/[^a-zA-Z0-9_-]/g, "_");
73798
73798
  const pathHash = createHash9("sha256").update(repoPath).digest("hex").slice(0, 8);
73799
- return join158(CACHE_DIR, `${repoName}-${pathHash}-context-cache.json`);
73799
+ return join160(CACHE_DIR, `${repoName}-${pathHash}-context-cache.json`);
73800
73800
  }
73801
- var CACHE_DIR, CACHE_TTL_MS4;
73801
+ var CACHE_DIR, CACHE_TTL_MS5;
73802
73802
  var init_context_cache_manager = __esm(() => {
73803
- CACHE_DIR = join158(homedir52(), ".claudekit", "cache");
73804
- CACHE_TTL_MS4 = 24 * 60 * 60 * 1000;
73803
+ CACHE_DIR = join160(homedir54(), ".claudekit", "cache");
73804
+ CACHE_TTL_MS5 = 24 * 60 * 60 * 1000;
73805
73805
  });
73806
73806
 
73807
73807
  // src/commands/content/phases/db-queries-git-events.ts
@@ -73981,7 +73981,7 @@ function extractContentFromResponse(response) {
73981
73981
  // src/commands/content/phases/docs-summarizer.ts
73982
73982
  import { execSync as execSync7 } from "node:child_process";
73983
73983
  import { existsSync as existsSync76, readFileSync as readFileSync19, readdirSync as readdirSync12 } from "node:fs";
73984
- import { join as join159 } from "node:path";
73984
+ import { join as join161 } from "node:path";
73985
73985
  async function summarizeProjectDocs(repoPath, contentLogger) {
73986
73986
  const rawContent = collectRawDocs(repoPath);
73987
73987
  if (rawContent.total.length < 200) {
@@ -74035,12 +74035,12 @@ function collectRawDocs(repoPath) {
74035
74035
  return capped;
74036
74036
  };
74037
74037
  const docsContent = [];
74038
- const docsDir = join159(repoPath, "docs");
74038
+ const docsDir = join161(repoPath, "docs");
74039
74039
  if (existsSync76(docsDir)) {
74040
74040
  try {
74041
74041
  const files = readdirSync12(docsDir).filter((f3) => f3.endsWith(".md")).sort();
74042
74042
  for (const f3 of files) {
74043
- const content = readCapped(join159(docsDir, f3), 5000);
74043
+ const content = readCapped(join161(docsDir, f3), 5000);
74044
74044
  if (content) {
74045
74045
  docsContent.push(`### ${f3}
74046
74046
  ${content}`);
@@ -74054,21 +74054,21 @@ ${content}`);
74054
74054
  let brand = "";
74055
74055
  const brandCandidates = ["docs/brand-guidelines.md", "docs/design-guidelines.md"];
74056
74056
  for (const p of brandCandidates) {
74057
- brand = readCapped(join159(repoPath, p), 3000);
74057
+ brand = readCapped(join161(repoPath, p), 3000);
74058
74058
  if (brand)
74059
74059
  break;
74060
74060
  }
74061
74061
  let styles3 = "";
74062
- const stylesDir = join159(repoPath, "assets", "writing-styles");
74062
+ const stylesDir = join161(repoPath, "assets", "writing-styles");
74063
74063
  if (existsSync76(stylesDir)) {
74064
74064
  try {
74065
74065
  const files = readdirSync12(stylesDir).slice(0, 3);
74066
- styles3 = files.map((f3) => readCapped(join159(stylesDir, f3), 1000)).filter(Boolean).join(`
74066
+ styles3 = files.map((f3) => readCapped(join161(stylesDir, f3), 1000)).filter(Boolean).join(`
74067
74067
 
74068
74068
  `);
74069
74069
  } catch {}
74070
74070
  }
74071
- const readme = readCapped(join159(repoPath, "README.md"), 3000);
74071
+ const readme = readCapped(join161(repoPath, "README.md"), 3000);
74072
74072
  const total = [docs, brand, styles3, readme].join(`
74073
74073
  `);
74074
74074
  return { docs, brand, styles: styles3, readme, total };
@@ -74102,10 +74102,10 @@ var MAX_RAW_CONTENT_CHARS = 50000;
74102
74102
  var init_docs_summarizer = () => {};
74103
74103
 
74104
74104
  // src/commands/content/phases/context-builder.ts
74105
- async function buildContentContext(event, repoPath, config, db, platform17, contentLogger) {
74105
+ async function buildContentContext(event, repoPath, config, db, platform18, contentLogger) {
74106
74106
  const cached = getCachedContext(repoPath);
74107
74107
  if (cached) {
74108
- return buildFromCache(cached, event, db, platform17, config);
74108
+ return buildFromCache(cached, event, db, platform18, config);
74109
74109
  }
74110
74110
  const noopLogger = { debug: () => {}, info: () => {}, warn: () => {}, error: () => {} };
74111
74111
  const log2 = contentLogger ?? noopLogger;
@@ -74120,16 +74120,16 @@ async function buildContentContext(event, repoPath, config, db, platform17, cont
74120
74120
  sourceHash: hash
74121
74121
  };
74122
74122
  await saveCachedContext(repoPath, newCache);
74123
- return buildFromCache(newCache, event, db, platform17, config);
74123
+ return buildFromCache(newCache, event, db, platform18, config);
74124
74124
  }
74125
- function buildFromCache(cache5, event, db, platform17, config) {
74125
+ function buildFromCache(cache5, event, db, platform18, config) {
74126
74126
  return {
74127
74127
  brandGuidelines: cache5.brandSummary,
74128
74128
  writingStyles: cache5.stylesSummary,
74129
74129
  gitEventDetails: formatGitEvent(event),
74130
74130
  recentContent: formatRecentContent(db),
74131
74131
  topPerformingContent: "",
74132
- platformRules: getPlatformRules(platform17, config),
74132
+ platformRules: getPlatformRules(platform18, config),
74133
74133
  projectReadme: cache5.readmeSummary,
74134
74134
  projectDocsSummary: cache5.docsSummary,
74135
74135
  currentDateTime: new Date().toISOString()
@@ -74158,8 +74158,8 @@ function formatRecentContent(db) {
74158
74158
  return recent.map((c2) => `[${c2.platform}] ${c2.textContent.slice(0, 100)}`).join(`
74159
74159
  `);
74160
74160
  }
74161
- function getPlatformRules(platform17, config) {
74162
- switch (platform17) {
74161
+ function getPlatformRules(platform18, config) {
74162
+ switch (platform18) {
74163
74163
  case "x":
74164
74164
  return [
74165
74165
  "Platform: X (Twitter)",
@@ -74198,8 +74198,8 @@ var init_context_builder = __esm(() => {
74198
74198
  });
74199
74199
 
74200
74200
  // src/commands/content/phases/prompt-templates.ts
74201
- function buildTextPrompt(context, platform17) {
74202
- const charLimit = platform17 === "x" || platform17 === "x_thread" ? 280 : 500;
74201
+ function buildTextPrompt(context, platform18) {
74202
+ const charLimit = platform18 === "x" || platform18 === "x_thread" ? 280 : 500;
74203
74203
  return `You are a social media content creator.
74204
74204
 
74205
74205
  ## Project Context
@@ -74214,14 +74214,14 @@ ${context.writingStyles}
74214
74214
  ## Content Source
74215
74215
  ${context.gitEventDetails}
74216
74216
 
74217
- ## Platform: ${platform17}
74217
+ ## Platform: ${platform18}
74218
74218
  ${context.platformRules}
74219
74219
 
74220
74220
  ## Past Content (avoid repetition)
74221
74221
  ${context.recentContent}
74222
74222
 
74223
74223
  ## Instructions
74224
- 1. Create a ${platform17} post about this development update
74224
+ 1. Create a ${platform18} post about this development update
74225
74225
  2. Start with a compelling hook that creates curiosity
74226
74226
  3. Keep it conversational and authentic (avoid AI-sounding language)
74227
74227
  4. No generic statements — be specific about what changed and why it matters
@@ -74231,8 +74231,8 @@ ${context.recentContent}
74231
74231
 
74232
74232
  IMPORTANT: Output ONLY the JSON object, nothing else.`;
74233
74233
  }
74234
- function buildPhotoPrompt(context, platform17) {
74235
- const dimensions = platform17 === "facebook" ? "1200x630" : "1200x675";
74234
+ function buildPhotoPrompt(context, platform18) {
74235
+ const dimensions = platform18 === "facebook" ? "1200x630" : "1200x675";
74236
74236
  return `Generate an image for this social media post.
74237
74237
 
74238
74238
  ## Brand Guidelines
@@ -74254,15 +74254,15 @@ IMPORTANT: Generate the image and output the path as JSON: {"imagePath": "/path/
74254
74254
  // src/commands/content/phases/photo-generator.ts
74255
74255
  import { execSync as execSync8 } from "node:child_process";
74256
74256
  import { existsSync as existsSync77, mkdirSync as mkdirSync6, readdirSync as readdirSync13 } from "node:fs";
74257
- import { homedir as homedir53 } from "node:os";
74258
- import { join as join160 } from "node:path";
74259
- async function generatePhoto(_content, context, config, platform17, contentId, contentLogger) {
74260
- const mediaDir = join160(config.contentDir.replace(/^~/, homedir53()), "media", String(contentId));
74257
+ import { homedir as homedir55 } from "node:os";
74258
+ import { join as join162 } from "node:path";
74259
+ async function generatePhoto(_content, context, config, platform18, contentId, contentLogger) {
74260
+ const mediaDir = join162(config.contentDir.replace(/^~/, homedir55()), "media", String(contentId));
74261
74261
  if (!existsSync77(mediaDir)) {
74262
74262
  mkdirSync6(mediaDir, { recursive: true });
74263
74263
  }
74264
- const prompt = buildPhotoPrompt(context, platform17);
74265
- const dimensions = platform17 === "facebook" ? { width: 1200, height: 630 } : { width: 1200, height: 675 };
74264
+ const prompt = buildPhotoPrompt(context, platform18);
74265
+ const dimensions = platform18 === "facebook" ? { width: 1200, height: 630 } : { width: 1200, height: 675 };
74266
74266
  try {
74267
74267
  contentLogger.debug(`Generating photo for content ${contentId}...`);
74268
74268
  const result = execSync8("claude -p --output-format text --max-turns 40", {
@@ -74282,7 +74282,7 @@ async function generatePhoto(_content, context, config, platform17, contentId, c
74282
74282
  const imageFile = files.find((f3) => /\.(png|jpg|jpeg|webp)$/i.test(f3));
74283
74283
  if (imageFile) {
74284
74284
  const ext2 = imageFile.split(".").pop() ?? "png";
74285
- return { path: join160(mediaDir, imageFile), ...dimensions, format: ext2 };
74285
+ return { path: join162(mediaDir, imageFile), ...dimensions, format: ext2 };
74286
74286
  }
74287
74287
  contentLogger.warn(`Photo generation produced no image for content ${contentId}`);
74288
74288
  return null;
@@ -74300,14 +74300,14 @@ async function createContent(event, config, db, contentLogger, options2) {
74300
74300
  const startTime = Date.now();
74301
74301
  const items = [];
74302
74302
  const platforms = resolveEnabledPlatforms(config);
74303
- for (const platform17 of platforms) {
74303
+ for (const platform18 of platforms) {
74304
74304
  try {
74305
- const item = await createContentForPlatform(event, platform17, config, db, contentLogger, options2);
74305
+ const item = await createContentForPlatform(event, platform18, config, db, contentLogger, options2);
74306
74306
  if (item)
74307
74307
  items.push(item);
74308
74308
  } catch (err) {
74309
74309
  const msg = err instanceof Error ? err.message : String(err);
74310
- contentLogger.error(`Failed to create ${platform17} content: ${msg}`);
74310
+ contentLogger.error(`Failed to create ${platform18} content: ${msg}`);
74311
74311
  }
74312
74312
  }
74313
74313
  insertTaskLog(db, {
@@ -74326,10 +74326,10 @@ function resolveEnabledPlatforms(config) {
74326
74326
  platforms.push("facebook");
74327
74327
  return platforms;
74328
74328
  }
74329
- async function createContentForPlatform(event, platform17, config, db, contentLogger, options2) {
74330
- const context = await buildContentContext(event, event.repoPath, config, db, platform17, contentLogger);
74331
- const prompt = buildTextPrompt(context, platform17);
74332
- contentLogger.debug(`Generating ${platform17} content for event ${event.id}...`);
74329
+ async function createContentForPlatform(event, platform18, config, db, contentLogger, options2) {
74330
+ const context = await buildContentContext(event, event.repoPath, config, db, platform18, contentLogger);
74331
+ const prompt = buildTextPrompt(context, platform18);
74332
+ contentLogger.debug(`Generating ${platform18} content for event ${event.id}...`);
74333
74333
  const stdout2 = execSync9("claude -p --output-format text --max-turns 5", {
74334
74334
  input: prompt,
74335
74335
  stdio: ["pipe", "pipe", "pipe"],
@@ -74337,14 +74337,14 @@ async function createContentForPlatform(event, platform17, config, db, contentLo
74337
74337
  }).toString();
74338
74338
  const parsed = parseClaudeJsonOutput(stdout2);
74339
74339
  const generated = extractContentFromResponse(parsed);
74340
- const validation = validateContent(generated, platform17);
74340
+ const validation = validateContent(generated, platform18);
74341
74341
  if (!validation.valid) {
74342
- contentLogger.warn(`Content validation failed for ${platform17}: ${validation.issues.join(", ")}`);
74342
+ contentLogger.warn(`Content validation failed for ${platform18}: ${validation.issues.join(", ")}`);
74343
74343
  }
74344
74344
  const status = validation.valid ? config.reviewMode === "auto" ? "scheduled" : "reviewing" : "draft";
74345
74345
  const itemId = insertContentItem(db, {
74346
74346
  gitEventId: event.id,
74347
- platform: platform17,
74347
+ platform: platform18,
74348
74348
  textContent: generated.text,
74349
74349
  hashtags: JSON.stringify(generated.hashtags),
74350
74350
  hookLine: generated.hook,
@@ -74354,12 +74354,12 @@ async function createContentForPlatform(event, platform17, config, db, contentLo
74354
74354
  scheduledAt: null
74355
74355
  });
74356
74356
  if (!options2.dryRun && generated.mediaPrompt) {
74357
- const photo = await generatePhoto(generated, context, config, platform17, itemId, contentLogger);
74357
+ const photo = await generatePhoto(generated, context, config, platform18, itemId, contentLogger);
74358
74358
  if (photo) {
74359
74359
  db.prepare("UPDATE content_items SET media_path = ? WHERE id = ?").run(photo.path, itemId);
74360
74360
  }
74361
74361
  }
74362
- contentLogger.info(`Created ${platform17} content (id: ${itemId}, status: ${status})`);
74362
+ contentLogger.info(`Created ${platform18} content (id: ${itemId}, status: ${status})`);
74363
74363
  return getContentById(db, itemId);
74364
74364
  }
74365
74365
  var init_content_creator = __esm(() => {
@@ -74371,8 +74371,8 @@ var init_content_creator = __esm(() => {
74371
74371
 
74372
74372
  // src/commands/content/phases/content-logger.ts
74373
74373
  import { createWriteStream as createWriteStream4, existsSync as existsSync78, mkdirSync as mkdirSync7, statSync as statSync15 } from "node:fs";
74374
- import { homedir as homedir54 } from "node:os";
74375
- import { join as join161 } from "node:path";
74374
+ import { homedir as homedir56 } from "node:os";
74375
+ import { join as join163 } from "node:path";
74376
74376
 
74377
74377
  class ContentLogger {
74378
74378
  stream = null;
@@ -74380,7 +74380,7 @@ class ContentLogger {
74380
74380
  logDir;
74381
74381
  maxBytes;
74382
74382
  constructor(maxBytes = 0) {
74383
- this.logDir = join161(homedir54(), ".claudekit", "logs");
74383
+ this.logDir = join163(homedir56(), ".claudekit", "logs");
74384
74384
  this.maxBytes = maxBytes;
74385
74385
  }
74386
74386
  init() {
@@ -74412,7 +74412,7 @@ class ContentLogger {
74412
74412
  }
74413
74413
  }
74414
74414
  getLogPath() {
74415
- return join161(this.logDir, `content-${this.getDateStr()}.log`);
74415
+ return join163(this.logDir, `content-${this.getDateStr()}.log`);
74416
74416
  }
74417
74417
  write(level, message) {
74418
74418
  this.rotateIfNeeded();
@@ -74429,19 +74429,19 @@ class ContentLogger {
74429
74429
  if (dateStr !== this.currentDate) {
74430
74430
  this.close();
74431
74431
  this.currentDate = dateStr;
74432
- const logPath = join161(this.logDir, `content-${dateStr}.log`);
74432
+ const logPath = join163(this.logDir, `content-${dateStr}.log`);
74433
74433
  this.stream = createWriteStream4(logPath, { flags: "a", mode: 384 });
74434
74434
  return;
74435
74435
  }
74436
74436
  if (this.maxBytes > 0 && this.stream) {
74437
- const logPath = join161(this.logDir, `content-${this.currentDate}.log`);
74437
+ const logPath = join163(this.logDir, `content-${this.currentDate}.log`);
74438
74438
  try {
74439
74439
  const stat26 = statSync15(logPath);
74440
74440
  if (stat26.size >= this.maxBytes) {
74441
74441
  this.close();
74442
74442
  const suffix = Date.now();
74443
- const rotatedPath = join161(this.logDir, `content-${this.currentDate}-${suffix}.log`);
74444
- import("node:fs/promises").then(({ rename: rename15 }) => rename15(logPath, rotatedPath).catch(() => {}));
74443
+ const rotatedPath = join163(this.logDir, `content-${this.currentDate}-${suffix}.log`);
74444
+ import("node:fs/promises").then(({ rename: rename16 }) => rename16(logPath, rotatedPath).catch(() => {}));
74445
74445
  this.stream = createWriteStream4(logPath, { flags: "w", mode: 384 });
74446
74446
  }
74447
74447
  } catch {}
@@ -74666,7 +74666,7 @@ function isNoiseCommit(title, author) {
74666
74666
  // src/commands/content/phases/change-detector.ts
74667
74667
  import { execSync as execSync10, spawnSync as spawnSync9 } from "node:child_process";
74668
74668
  import { existsSync as existsSync80, readFileSync as readFileSync20, readdirSync as readdirSync14, statSync as statSync16 } from "node:fs";
74669
- import { join as join162 } from "node:path";
74669
+ import { join as join164 } from "node:path";
74670
74670
  function detectCommits(repo, since) {
74671
74671
  try {
74672
74672
  const fetchUrl = sshToHttps(repo.remoteUrl);
@@ -74775,7 +74775,7 @@ function detectTags(repo, since) {
74775
74775
  }
74776
74776
  }
74777
74777
  function detectCompletedPlans(repo, since) {
74778
- const plansDir = join162(repo.path, "plans");
74778
+ const plansDir = join164(repo.path, "plans");
74779
74779
  if (!existsSync80(plansDir))
74780
74780
  return [];
74781
74781
  const sinceMs = new Date(since).getTime();
@@ -74785,7 +74785,7 @@ function detectCompletedPlans(repo, since) {
74785
74785
  for (const entry of entries) {
74786
74786
  if (!entry.isDirectory())
74787
74787
  continue;
74788
- const planFile = join162(plansDir, entry.name, "plan.md");
74788
+ const planFile = join164(plansDir, entry.name, "plan.md");
74789
74789
  if (!existsSync80(planFile))
74790
74790
  continue;
74791
74791
  try {
@@ -74863,7 +74863,7 @@ function classifyCommit(event) {
74863
74863
  // src/commands/content/phases/repo-discoverer.ts
74864
74864
  import { execSync as execSync11 } from "node:child_process";
74865
74865
  import { readdirSync as readdirSync15 } from "node:fs";
74866
- import { join as join163 } from "node:path";
74866
+ import { join as join165 } from "node:path";
74867
74867
  function discoverRepos2(cwd2) {
74868
74868
  const repos = [];
74869
74869
  if (isGitRepoRoot(cwd2)) {
@@ -74876,7 +74876,7 @@ function discoverRepos2(cwd2) {
74876
74876
  for (const entry of entries) {
74877
74877
  if (!entry.isDirectory() || entry.name.startsWith("."))
74878
74878
  continue;
74879
- const dirPath = join163(cwd2, entry.name);
74879
+ const dirPath = join165(cwd2, entry.name);
74880
74880
  if (isGitRepoRoot(dirPath)) {
74881
74881
  const info = getRepoInfo(dirPath);
74882
74882
  if (info)
@@ -75246,15 +75246,15 @@ class RateLimiter {
75246
75246
  this.state = state;
75247
75247
  this.config = config;
75248
75248
  }
75249
- canPost(platform17) {
75250
- return this.getTodayCount(platform17) < this.getMaxPerDay(platform17);
75249
+ canPost(platform18) {
75250
+ return this.getTodayCount(platform18) < this.getMaxPerDay(platform18);
75251
75251
  }
75252
- recordPost(platform17) {
75253
- const key = this.dailyKey(platform17);
75252
+ recordPost(platform18) {
75253
+ const key = this.dailyKey(platform18);
75254
75254
  this.state.dailyPostCounts[key] = (this.state.dailyPostCounts[key] ?? 0) + 1;
75255
75255
  }
75256
- getRemainingToday(platform17) {
75257
- return Math.max(0, this.getMaxPerDay(platform17) - this.getTodayCount(platform17));
75256
+ getRemainingToday(platform18) {
75257
+ return Math.max(0, this.getMaxPerDay(platform18) - this.getTodayCount(platform18));
75258
75258
  }
75259
75259
  isInQuietHours() {
75260
75260
  const { timezone, quietHoursStart, quietHoursEnd } = this.config.schedule;
@@ -75274,19 +75274,19 @@ class RateLimiter {
75274
75274
  return false;
75275
75275
  }
75276
75276
  }
75277
- getMaxPerDay(platform17) {
75278
- if (platform17 === "x" || platform17 === "x_thread") {
75277
+ getMaxPerDay(platform18) {
75278
+ if (platform18 === "x" || platform18 === "x_thread") {
75279
75279
  return this.config.platforms.x.maxPostsPerDay;
75280
75280
  }
75281
- if (platform17 === "facebook") {
75281
+ if (platform18 === "facebook") {
75282
75282
  return this.config.platforms.facebook.maxPostsPerDay;
75283
75283
  }
75284
75284
  return this.config.maxContentPerDay;
75285
75285
  }
75286
- getTodayCount(platform17) {
75287
- return this.state.dailyPostCounts[this.dailyKey(platform17)] ?? 0;
75286
+ getTodayCount(platform18) {
75287
+ return this.state.dailyPostCounts[this.dailyKey(platform18)] ?? 0;
75288
75288
  }
75289
- dailyKey(platform17) {
75289
+ dailyKey(platform18) {
75290
75290
  const { timezone } = this.config.schedule;
75291
75291
  let dateStr;
75292
75292
  try {
@@ -75300,7 +75300,7 @@ class RateLimiter {
75300
75300
  } catch {
75301
75301
  dateStr = new Date().toISOString().slice(0, 10);
75302
75302
  }
75303
- return `${platform17}-${dateStr}`;
75303
+ return `${platform18}-${dateStr}`;
75304
75304
  }
75305
75305
  }
75306
75306
 
@@ -75417,8 +75417,8 @@ function previewContent(content) {
75417
75417
  console.log(import_picocolors42.default.dim("─".repeat(60)));
75418
75418
  console.log();
75419
75419
  }
75420
- function getPlatformBadge(platform17) {
75421
- switch (platform17) {
75420
+ function getPlatformBadge(platform18) {
75421
+ switch (platform18) {
75422
75422
  case "x":
75423
75423
  return import_picocolors42.default.bgBlue(import_picocolors42.default.white(" X "));
75424
75424
  case "x_thread":
@@ -75426,7 +75426,7 @@ function getPlatformBadge(platform17) {
75426
75426
  case "facebook":
75427
75427
  return import_picocolors42.default.bgCyan(import_picocolors42.default.white(" Facebook "));
75428
75428
  default:
75429
- return import_picocolors42.default.bgBlack(import_picocolors42.default.white(` ${platform17} `));
75429
+ return import_picocolors42.default.bgBlack(import_picocolors42.default.white(` ${platform18} `));
75430
75430
  }
75431
75431
  }
75432
75432
  function getStatusColor(status) {
@@ -75543,12 +75543,12 @@ var init_types6 = __esm(() => {
75543
75543
  });
75544
75544
 
75545
75545
  // src/commands/content/phases/state-manager.ts
75546
- import { readFile as readFile65, rename as rename15, writeFile as writeFile39 } from "node:fs/promises";
75547
- import { join as join164 } from "node:path";
75546
+ import { readFile as readFile67, rename as rename16, writeFile as writeFile40 } from "node:fs/promises";
75547
+ import { join as join166 } from "node:path";
75548
75548
  async function loadContentConfig(projectDir) {
75549
- const configPath = join164(projectDir, CK_CONFIG_FILE2);
75549
+ const configPath = join166(projectDir, CK_CONFIG_FILE2);
75550
75550
  try {
75551
- const raw2 = await readFile65(configPath, "utf-8");
75551
+ const raw2 = await readFile67(configPath, "utf-8");
75552
75552
  const json = JSON.parse(raw2);
75553
75553
  return ContentConfigSchema.parse(json.content ?? {});
75554
75554
  } catch {
@@ -75556,15 +75556,15 @@ async function loadContentConfig(projectDir) {
75556
75556
  }
75557
75557
  }
75558
75558
  async function saveContentConfig(projectDir, config) {
75559
- const configPath = join164(projectDir, CK_CONFIG_FILE2);
75559
+ const configPath = join166(projectDir, CK_CONFIG_FILE2);
75560
75560
  const json = await readJsonSafe(configPath);
75561
75561
  json.content = { ...json.content, ...config };
75562
75562
  await atomicWrite2(configPath, json);
75563
75563
  }
75564
75564
  async function loadContentState(projectDir) {
75565
- const configPath = join164(projectDir, CK_CONFIG_FILE2);
75565
+ const configPath = join166(projectDir, CK_CONFIG_FILE2);
75566
75566
  try {
75567
- const raw2 = await readFile65(configPath, "utf-8");
75567
+ const raw2 = await readFile67(configPath, "utf-8");
75568
75568
  const json = JSON.parse(raw2);
75569
75569
  const contentBlock = json.content ?? {};
75570
75570
  return ContentStateSchema.parse(contentBlock.state ?? {});
@@ -75573,7 +75573,7 @@ async function loadContentState(projectDir) {
75573
75573
  }
75574
75574
  }
75575
75575
  async function saveContentState(projectDir, state) {
75576
- const configPath = join164(projectDir, CK_CONFIG_FILE2);
75576
+ const configPath = join166(projectDir, CK_CONFIG_FILE2);
75577
75577
  const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().slice(0, 10);
75578
75578
  for (const key of Object.keys(state.dailyPostCounts)) {
75579
75579
  const dateStr = key.slice(-10);
@@ -75591,7 +75591,7 @@ async function saveContentState(projectDir, state) {
75591
75591
  }
75592
75592
  async function readJsonSafe(filePath) {
75593
75593
  try {
75594
- const raw2 = await readFile65(filePath, "utf-8");
75594
+ const raw2 = await readFile67(filePath, "utf-8");
75595
75595
  return JSON.parse(raw2);
75596
75596
  } catch {
75597
75597
  return {};
@@ -75599,8 +75599,8 @@ async function readJsonSafe(filePath) {
75599
75599
  }
75600
75600
  async function atomicWrite2(filePath, data) {
75601
75601
  const tmpPath = `${filePath}.tmp`;
75602
- await writeFile39(tmpPath, JSON.stringify(data, null, 2), "utf-8");
75603
- await rename15(tmpPath, filePath);
75602
+ await writeFile40(tmpPath, JSON.stringify(data, null, 2), "utf-8");
75603
+ await rename16(tmpPath, filePath);
75604
75604
  }
75605
75605
  var CK_CONFIG_FILE2 = ".ck.json";
75606
75606
  var init_state_manager = __esm(() => {
@@ -75706,15 +75706,15 @@ async function autoInstallFbcli(contentLogger) {
75706
75706
  contentLogger.warn("go install failed or Go not available");
75707
75707
  }
75708
75708
  try {
75709
- const { platform: platform17, arch: arch3 } = process;
75709
+ const { platform: platform18, arch: arch3 } = process;
75710
75710
  const osMap = { darwin: "darwin", linux: "linux", win32: "windows" };
75711
75711
  const archMap = { arm64: "arm64", x64: "amd64" };
75712
- const os7 = osMap[platform17];
75712
+ const os7 = osMap[platform18];
75713
75713
  const cpu = archMap[arch3];
75714
75714
  if (os7 && cpu) {
75715
- const ext2 = platform17 === "win32" ? ".exe" : "";
75715
+ const ext2 = platform18 === "win32" ? ".exe" : "";
75716
75716
  const url = `https://github.com/mrgoonie/fbcli/releases/latest/download/fbcli_${os7}_${cpu}${ext2}`;
75717
- const dest = platform17 === "win32" ? "fbcli.exe" : "/usr/local/bin/fbcli";
75717
+ const dest = platform18 === "win32" ? "fbcli.exe" : "/usr/local/bin/fbcli";
75718
75718
  f2.warning(`Will download fbcli binary from: ${url}`);
75719
75719
  f2.warning("Note: Binary integrity is not verified. Review the source at https://github.com/mrgoonie/fbcli");
75720
75720
  const consent = await se({ message: `Download and install fbcli to ${dest}?` });
@@ -75798,15 +75798,15 @@ async function autoInstallXurl(contentLogger) {
75798
75798
  contentLogger.warn("go install failed or Go not available");
75799
75799
  }
75800
75800
  try {
75801
- const { platform: platform17, arch: arch3 } = process;
75801
+ const { platform: platform18, arch: arch3 } = process;
75802
75802
  const osMap = { darwin: "darwin", linux: "linux", win32: "windows" };
75803
75803
  const archMap = { arm64: "arm64", x64: "amd64" };
75804
- const os7 = osMap[platform17];
75804
+ const os7 = osMap[platform18];
75805
75805
  const cpu = archMap[arch3];
75806
75806
  if (os7 && cpu) {
75807
- const ext2 = platform17 === "win32" ? ".exe" : "";
75807
+ const ext2 = platform18 === "win32" ? ".exe" : "";
75808
75808
  const url = `https://github.com/xdevplatform/xurl/releases/latest/download/xurl_${os7}_${cpu}${ext2}`;
75809
- const dest = platform17 === "win32" ? "xurl.exe" : "/usr/local/bin/xurl";
75809
+ const dest = platform18 === "win32" ? "xurl.exe" : "/usr/local/bin/xurl";
75810
75810
  f2.info(`Downloading xurl binary for ${os7}/${cpu}...`);
75811
75811
  execSync14(`curl -fsSL "${url}" -o "${dest}" && chmod +x "${dest}"`, {
75812
75812
  stdio: "inherit",
@@ -75855,7 +75855,7 @@ var init_platform_setup_x = __esm(() => {
75855
75855
 
75856
75856
  // src/commands/content/phases/setup-wizard.ts
75857
75857
  import { existsSync as existsSync81 } from "node:fs";
75858
- import { join as join165 } from "node:path";
75858
+ import { join as join167 } from "node:path";
75859
75859
  async function runSetupWizard2(cwd2, contentLogger) {
75860
75860
  console.log();
75861
75861
  oe(import_picocolors43.default.bgCyan(import_picocolors43.default.white(" CK Content — Multi-Channel Content Engine ")));
@@ -75923,8 +75923,8 @@ async function showRepoSummary(cwd2) {
75923
75923
  function detectBrandAssets(cwd2, contentLogger) {
75924
75924
  const repos = discoverRepos2(cwd2);
75925
75925
  for (const repo of repos) {
75926
- const hasGuidelines = existsSync81(join165(repo.path, "docs", "brand-guidelines.md"));
75927
- const hasStyles = existsSync81(join165(repo.path, "assets", "writing-styles"));
75926
+ const hasGuidelines = existsSync81(join167(repo.path, "docs", "brand-guidelines.md"));
75927
+ const hasStyles = existsSync81(join167(repo.path, "assets", "writing-styles"));
75928
75928
  if (!hasGuidelines) {
75929
75929
  f2.warning(`${repo.name}: No docs/brand-guidelines.md — content will use generic tone.`);
75930
75930
  contentLogger.warn(`${repo.name}: missing docs/brand-guidelines.md`);
@@ -75991,11 +75991,11 @@ var init_setup_wizard = __esm(() => {
75991
75991
 
75992
75992
  // src/commands/content/content-review-commands.ts
75993
75993
  import { existsSync as existsSync82 } from "node:fs";
75994
- import { homedir as homedir55 } from "node:os";
75994
+ import { homedir as homedir57 } from "node:os";
75995
75995
  async function queueContent() {
75996
75996
  const cwd2 = process.cwd();
75997
75997
  const config = await loadContentConfig(cwd2);
75998
- const dbPath = config.dbPath.replace(/^~/, homedir55());
75998
+ const dbPath = config.dbPath.replace(/^~/, homedir57());
75999
75999
  if (!existsSync82(dbPath)) {
76000
76000
  logger.info("No content database found. Run 'ck content setup' first.");
76001
76001
  return;
@@ -76022,7 +76022,7 @@ async function queueContent() {
76022
76022
  async function approveContentCmd(id) {
76023
76023
  const cwd2 = process.cwd();
76024
76024
  const config = await loadContentConfig(cwd2);
76025
- const dbPath = config.dbPath.replace(/^~/, homedir55());
76025
+ const dbPath = config.dbPath.replace(/^~/, homedir57());
76026
76026
  const db = initDatabase(dbPath);
76027
76027
  try {
76028
76028
  approveContent(db, Number.parseInt(id, 10));
@@ -76034,7 +76034,7 @@ async function approveContentCmd(id) {
76034
76034
  async function rejectContentCmd(id, reason) {
76035
76035
  const cwd2 = process.cwd();
76036
76036
  const config = await loadContentConfig(cwd2);
76037
- const dbPath = config.dbPath.replace(/^~/, homedir55());
76037
+ const dbPath = config.dbPath.replace(/^~/, homedir57());
76038
76038
  const db = initDatabase(dbPath);
76039
76039
  try {
76040
76040
  rejectContent(db, Number.parseInt(id, 10), reason);
@@ -76065,10 +76065,10 @@ __export(exports_content_subcommands, {
76065
76065
  approveContentCmd: () => approveContentCmd
76066
76066
  });
76067
76067
  import { existsSync as existsSync83, readFileSync as readFileSync21, unlinkSync as unlinkSync6 } from "node:fs";
76068
- import { homedir as homedir56 } from "node:os";
76069
- import { join as join166 } from "node:path";
76068
+ import { homedir as homedir58 } from "node:os";
76069
+ import { join as join168 } from "node:path";
76070
76070
  function isDaemonRunning() {
76071
- const lockFile = join166(LOCK_DIR, `${LOCK_NAME2}.lock`);
76071
+ const lockFile = join168(LOCK_DIR, `${LOCK_NAME2}.lock`);
76072
76072
  if (!existsSync83(lockFile))
76073
76073
  return { running: false, pid: null };
76074
76074
  try {
@@ -76100,7 +76100,7 @@ async function startContent(options2) {
76100
76100
  await contentCommand(options2);
76101
76101
  }
76102
76102
  async function stopContent() {
76103
- const lockFile = join166(LOCK_DIR, `${LOCK_NAME2}.lock`);
76103
+ const lockFile = join168(LOCK_DIR, `${LOCK_NAME2}.lock`);
76104
76104
  if (!existsSync83(lockFile)) {
76105
76105
  logger.info("Content daemon is not running.");
76106
76106
  return;
@@ -76139,9 +76139,9 @@ async function statusContent() {
76139
76139
  } catch {}
76140
76140
  }
76141
76141
  async function logsContent(options2) {
76142
- const logDir = join166(homedir56(), ".claudekit", "logs");
76142
+ const logDir = join168(homedir58(), ".claudekit", "logs");
76143
76143
  const dateStr = new Date().toISOString().slice(0, 10).replace(/-/g, "");
76144
- const logPath = join166(logDir, `content-${dateStr}.log`);
76144
+ const logPath = join168(logDir, `content-${dateStr}.log`);
76145
76145
  if (!existsSync83(logPath)) {
76146
76146
  logger.info("No content logs found for today.");
76147
76147
  return;
@@ -76173,13 +76173,13 @@ var init_content_subcommands = __esm(() => {
76173
76173
  init_setup_wizard();
76174
76174
  init_state_manager();
76175
76175
  init_content_review_commands();
76176
- LOCK_DIR = join166(homedir56(), ".claudekit", "locks");
76176
+ LOCK_DIR = join168(homedir58(), ".claudekit", "locks");
76177
76177
  });
76178
76178
 
76179
76179
  // src/commands/content/content-command.ts
76180
76180
  import { existsSync as existsSync84, mkdirSync as mkdirSync9, unlinkSync as unlinkSync7, writeFileSync as writeFileSync7 } from "node:fs";
76181
- import { homedir as homedir57 } from "node:os";
76182
- import { join as join167 } from "node:path";
76181
+ import { homedir as homedir59 } from "node:os";
76182
+ import { join as join169 } from "node:path";
76183
76183
  async function contentCommand(options2) {
76184
76184
  const cwd2 = process.cwd();
76185
76185
  const contentLogger = new ContentLogger;
@@ -76211,7 +76211,7 @@ async function contentCommand(options2) {
76211
76211
  if (!existsSync84(LOCK_DIR2))
76212
76212
  mkdirSync9(LOCK_DIR2, { recursive: true });
76213
76213
  writeFileSync7(LOCK_FILE, String(process.pid), "utf-8");
76214
- const dbPath = config.dbPath.replace(/^~/, homedir57());
76214
+ const dbPath = config.dbPath.replace(/^~/, homedir59());
76215
76215
  const db = initDatabase(dbPath);
76216
76216
  contentLogger.info(`Database initialised at ${dbPath}`);
76217
76217
  const adapters = initializeAdapters(config);
@@ -76357,8 +76357,8 @@ var init_content_command = __esm(() => {
76357
76357
  init_publisher();
76358
76358
  init_review_manager();
76359
76359
  init_state_manager();
76360
- LOCK_DIR2 = join167(homedir57(), ".claudekit", "locks");
76361
- LOCK_FILE = join167(LOCK_DIR2, "ck-content.lock");
76360
+ LOCK_DIR2 = join169(homedir59(), ".claudekit", "locks");
76361
+ LOCK_FILE = join169(LOCK_DIR2, "ck-content.lock");
76362
76362
  });
76363
76363
 
76364
76364
  // src/commands/content/index.ts
@@ -107075,9 +107075,9 @@ async function initCommand(options2) {
107075
107075
  init_dist2();
107076
107076
  var import_picocolors30 = __toESM(require_picocolors(), 1);
107077
107077
  import { existsSync as existsSync64 } from "node:fs";
107078
- import { readFile as readFile61, rm as rm16, unlink as unlink13 } from "node:fs/promises";
107079
- import { homedir as homedir50 } from "node:os";
107080
- import { basename as basename27, join as join142, resolve as resolve41 } from "node:path";
107078
+ import { readFile as readFile63, rm as rm16, unlink as unlink13 } from "node:fs/promises";
107079
+ import { homedir as homedir52 } from "node:os";
107080
+ import { basename as basename27, join as join144, resolve as resolve41 } from "node:path";
107081
107081
  init_logger();
107082
107082
 
107083
107083
  // src/ui/ck-cli-design/tokens.ts
@@ -107549,32 +107549,262 @@ init_model_taxonomy();
107549
107549
  init_logger();
107550
107550
  init_dist2();
107551
107551
  init_model_taxonomy();
107552
- import { mkdir as mkdir36, readFile as readFile60, writeFile as writeFile35 } from "node:fs/promises";
107552
+ import { mkdir as mkdir37, readFile as readFile62, writeFile as writeFile36 } from "node:fs/promises";
107553
+ import { homedir as homedir51 } from "node:os";
107554
+ import { dirname as dirname41, join as join143 } from "node:path";
107555
+
107556
+ // src/commands/portable/models-dev-cache.ts
107557
+ init_logger();
107558
+ import { mkdir as mkdir36, readFile as readFile60, rename as rename13, writeFile as writeFile35 } from "node:fs/promises";
107553
107559
  import { homedir as homedir49 } from "node:os";
107554
- import { dirname as dirname41, join as join141 } from "node:path";
107555
- function getOpenCodeConfigPath(options2) {
107556
- if (options2.global) {
107557
- return join141(options2.homeDir ?? homedir49(), ".config", "opencode", "opencode.json");
107560
+ import { join as join141 } from "node:path";
107561
+
107562
+ class ModelsDevUnavailableError extends Error {
107563
+ constructor(message, cause) {
107564
+ super(message, { cause });
107565
+ this.name = "ModelsDevUnavailableError";
107566
+ }
107567
+ }
107568
+ var MODELS_DEV_URL = "https://models.dev/api.json";
107569
+ var CACHE_TTL_MS3 = 24 * 60 * 60 * 1000;
107570
+ var FETCH_TIMEOUT_MS = 1e4;
107571
+ function defaultCacheDir() {
107572
+ return join141(homedir49(), ".config", "claudekit", "cache");
107573
+ }
107574
+ function cacheFilePath(cacheDir) {
107575
+ return join141(cacheDir, "models-dev.json");
107576
+ }
107577
+ function tmpFilePath(cacheDir) {
107578
+ return join141(cacheDir, "models-dev.json.tmp");
107579
+ }
107580
+ async function readCacheEntry(cacheDir) {
107581
+ const filePath = cacheFilePath(cacheDir);
107582
+ try {
107583
+ const raw2 = await readFile60(filePath, "utf-8");
107584
+ const parsed = JSON.parse(raw2);
107585
+ if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) && "fetchedAt" in parsed && typeof parsed.fetchedAt === "string" && "payload" in parsed && typeof parsed.payload === "object" && parsed.payload !== null) {
107586
+ return parsed;
107587
+ }
107588
+ return null;
107589
+ } catch {
107590
+ return null;
107591
+ }
107592
+ }
107593
+ function isCacheFresh(entry) {
107594
+ const fetchedAt = new Date(entry.fetchedAt).getTime();
107595
+ return Date.now() - fetchedAt < CACHE_TTL_MS3;
107596
+ }
107597
+ async function writeCacheEntry(cacheDir, entry) {
107598
+ await mkdir36(cacheDir, { recursive: true });
107599
+ const tmp = tmpFilePath(cacheDir);
107600
+ const dest = cacheFilePath(cacheDir);
107601
+ await writeFile35(tmp, JSON.stringify(entry), "utf-8");
107602
+ await rename13(tmp, dest);
107603
+ }
107604
+ async function fetchCatalog(fetcher) {
107605
+ const controller = new AbortController;
107606
+ const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
107607
+ try {
107608
+ const response = await fetcher(MODELS_DEV_URL, { signal: controller.signal });
107609
+ if (!response.ok) {
107610
+ throw new Error(`models.dev returned HTTP ${response.status}`);
107611
+ }
107612
+ const json = await response.json();
107613
+ if (json === null || typeof json !== "object" || Array.isArray(json)) {
107614
+ throw new Error("models.dev response is not an object");
107615
+ }
107616
+ return json;
107617
+ } finally {
107618
+ clearTimeout(timer);
107619
+ }
107620
+ }
107621
+ async function getModelsDevCatalog(opts = {}) {
107622
+ const cacheDir = opts.cacheDir ?? defaultCacheDir();
107623
+ const fetcher = opts.fetcher ?? globalThis.fetch;
107624
+ const cached = await readCacheEntry(cacheDir);
107625
+ if (cached !== null && isCacheFresh(cached)) {
107626
+ return cached.payload;
107627
+ }
107628
+ try {
107629
+ const payload = await fetchCatalog(fetcher);
107630
+ const entry = {
107631
+ fetchedAt: new Date().toISOString(),
107632
+ payload
107633
+ };
107634
+ try {
107635
+ await writeCacheEntry(cacheDir, entry);
107636
+ } catch (writeErr) {
107637
+ logger.verbose(`models-dev-cache: failed to write cache to ${cacheDir}: ${String(writeErr)}`);
107638
+ }
107639
+ return payload;
107640
+ } catch (fetchErr) {
107641
+ if (cached !== null) {
107642
+ logger.warning(`models-dev-cache: fetch failed (${String(fetchErr)}), using stale cache from ${cached.fetchedAt}`);
107643
+ return cached.payload;
107644
+ }
107645
+ throw new ModelsDevUnavailableError(`models.dev catalog unavailable: ${String(fetchErr)}`, fetchErr);
107558
107646
  }
107559
- return join141(options2.cwd ?? process.cwd(), "opencode.json");
107560
107647
  }
107561
- async function detectAuthenticatedProviders(homeDir) {
107562
- const authPath = join141(homeDir ?? homedir49(), ".local", "share", "opencode", "auth.json");
107648
+
107649
+ // src/commands/portable/opencode-model-discovery.ts
107650
+ init_logger();
107651
+ import { readFile as readFile61 } from "node:fs/promises";
107652
+ import { homedir as homedir50, platform as platform17 } from "node:os";
107653
+ import { join as join142 } from "node:path";
107654
+ function resolveOpenCodeAuthPath(homeDir) {
107655
+ if (platform17() === "win32") {
107656
+ const dataRoot2 = process.env.LOCALAPPDATA ?? join142(homeDir, "AppData", "Local");
107657
+ return join142(dataRoot2, "opencode", "auth.json");
107658
+ }
107659
+ const dataRoot = process.env.XDG_DATA_HOME ?? join142(homeDir, ".local", "share");
107660
+ return join142(dataRoot, "opencode", "auth.json");
107661
+ }
107662
+ async function readAuthedProviders(homeDir) {
107663
+ const authPath = resolveOpenCodeAuthPath(homeDir);
107563
107664
  try {
107564
- const raw2 = await readFile60(authPath, "utf-8");
107665
+ const raw2 = await readFile61(authPath, "utf-8");
107565
107666
  const parsed = JSON.parse(raw2);
107566
- if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
107667
+ if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
107567
107668
  return Object.keys(parsed);
107568
107669
  }
107569
107670
  } catch {}
107570
107671
  return [];
107571
107672
  }
107572
- async function suggestOpenCodeDefaultModel(homeDir) {
107673
+ function releaseDateMs(model) {
107674
+ const d3 = new Date(model.release_date);
107675
+ return Number.isNaN(d3.getTime()) ? 0 : d3.getTime();
107676
+ }
107677
+ function sortByDateDesc(models) {
107678
+ return [...models].sort((a3, b3) => releaseDateMs(b3) - releaseDateMs(a3));
107679
+ }
107680
+ function pickOpenCodeModel(models) {
107681
+ const all = Object.values(models);
107682
+ const freeCallable = all.filter((m2) => m2.tool_call && m2.id.endsWith("-free"));
107683
+ const sortedFree = sortByDateDesc(freeCallable);
107684
+ const topFree = sortedFree[0];
107685
+ if (topFree !== undefined) {
107686
+ return topFree;
107687
+ }
107688
+ const callable = all.filter((m2) => m2.tool_call);
107689
+ const sortedCallable = sortByDateDesc(callable);
107690
+ return sortedCallable[0] ?? null;
107691
+ }
107692
+ function pickGenericModel(models) {
107693
+ const callable = Object.values(models).filter((m2) => m2.tool_call);
107694
+ const sorted = sortByDateDesc(callable);
107695
+ return sorted[0] ?? null;
107696
+ }
107697
+ async function resolveOpenCodeDefaultModel(opts = {}) {
107698
+ const home9 = opts.homeDir ?? homedir50();
107699
+ const authedProviders = await readAuthedProviders(home9);
107700
+ if (authedProviders.length === 0) {
107701
+ return { ok: false, reason: "no-auth", authedProviders: [] };
107702
+ }
107703
+ let catalog;
107704
+ try {
107705
+ catalog = await getModelsDevCatalog({ fetcher: opts.fetcher, cacheDir: opts.cacheDir });
107706
+ } catch (err) {
107707
+ if (err instanceof ModelsDevUnavailableError) {
107708
+ logger.verbose(`opencode-model-discovery: models.dev unavailable, cannot auto-resolve model: ${err.message}`);
107709
+ return { ok: false, reason: "catalog-unavailable", authedProviders };
107710
+ }
107711
+ throw err;
107712
+ }
107713
+ const orderedProviders = [
107714
+ ...authedProviders.filter((id) => id === "opencode"),
107715
+ ...authedProviders.filter((id) => id !== "opencode")
107716
+ ];
107717
+ for (const providerId of orderedProviders) {
107718
+ const providerEntry = catalog[providerId];
107719
+ if (!providerEntry) {
107720
+ continue;
107721
+ }
107722
+ const picked = providerId === "opencode" ? pickOpenCodeModel(providerEntry.models) : pickGenericModel(providerEntry.models);
107723
+ if (!picked) {
107724
+ continue;
107725
+ }
107726
+ const isFree = picked.id.endsWith("-free");
107727
+ const tierLabel = isFree ? "free tier" : "paid";
107728
+ const reason = `auth-detected: ${providerId} (${tierLabel}, released ${picked.release_date})`;
107729
+ return {
107730
+ ok: true,
107731
+ value: {
107732
+ model: `${providerId}/${picked.id}`,
107733
+ reason,
107734
+ authedProviders
107735
+ }
107736
+ };
107737
+ }
107738
+ return { ok: false, reason: "no-usable-model", authedProviders };
107739
+ }
107740
+
107741
+ // src/commands/portable/opencode-config-installer.ts
107742
+ class OpenCodeAuthRequiredError extends Error {
107743
+ reason;
107744
+ constructor(reason = "no-auth") {
107745
+ super(messageForReason(reason));
107746
+ this.name = "OpenCodeAuthRequiredError";
107747
+ this.reason = reason;
107748
+ }
107749
+ }
107750
+ function messageForReason(reason) {
107751
+ switch (reason) {
107752
+ case "no-auth":
107753
+ return "opencode has no authenticated providers. Run `opencode auth login` first, then re-run `ck migrate`.";
107754
+ case "catalog-unavailable":
107755
+ return "Cannot reach models.dev to pick a default model. Check your network, then re-run `ck migrate` — or set `model` in opencode.json manually.";
107756
+ case "no-usable-model":
107757
+ return "None of your authenticated opencode providers have a tool-capable model in the models.dev catalog. Set `model` in opencode.json manually.";
107758
+ }
107759
+ }
107760
+ function getOpenCodeConfigPath(options2) {
107761
+ if (options2.global) {
107762
+ return join143(options2.homeDir ?? homedir51(), ".config", "opencode", "opencode.json");
107763
+ }
107764
+ return join143(options2.cwd ?? process.cwd(), "opencode.json");
107765
+ }
107766
+ function makeCatalogOpts(options2) {
107767
+ return {
107768
+ fetcher: options2.fetcher,
107769
+ cacheDir: options2.cacheDir
107770
+ };
107771
+ }
107772
+ async function validateModelAgainstCatalog(model, options2) {
107773
+ const slashIdx = model.indexOf("/");
107774
+ if (slashIdx <= 0 || slashIdx === model.length - 1) {
107775
+ return false;
107776
+ }
107777
+ const providerId = model.slice(0, slashIdx);
107778
+ const modelId = model.slice(slashIdx + 1);
107779
+ try {
107780
+ const catalog = await getModelsDevCatalog(makeCatalogOpts(options2));
107781
+ const provider = catalog[providerId];
107782
+ if (!provider)
107783
+ return false;
107784
+ return modelId in provider.models;
107785
+ } catch {
107786
+ return true;
107787
+ }
107788
+ }
107789
+ async function suggestModel(options2) {
107573
107790
  const override = getOpenCodeDefaultModelOverride();
107574
107791
  if (override) {
107575
- return { model: override, reason: ".ck.json override" };
107792
+ return { ok: true, model: override, reason: ".ck.json override", authedProviders: [] };
107793
+ }
107794
+ const result = await resolveOpenCodeDefaultModel({
107795
+ homeDir: options2.homeDir,
107796
+ fetcher: options2.fetcher,
107797
+ cacheDir: options2.cacheDir
107798
+ });
107799
+ if (result.ok) {
107800
+ return {
107801
+ ok: true,
107802
+ model: result.value.model,
107803
+ reason: result.value.reason,
107804
+ authedProviders: result.value.authedProviders
107805
+ };
107576
107806
  }
107577
- return { model: OPENCODE_DEFAULT_MODEL, reason: "fallback default" };
107807
+ return { ok: false, failure: result.reason, authedProviders: result.authedProviders };
107578
107808
  }
107579
107809
  var clackPrompter = async ({ suggestion, reason, detectedProviders }) => {
107580
107810
  const providersHint = detectedProviders.length > 0 ? `Authenticated providers in opencode: ${detectedProviders.join(", ")}` : "No authenticated providers detected in opencode.";
@@ -107596,7 +107826,7 @@ var clackPrompter = async ({ suggestion, reason, detectedProviders }) => {
107596
107826
  if (response === "accept")
107597
107827
  return { action: "accept" };
107598
107828
  const custom2 = await te({
107599
- message: "Model (format: provider/model-id, e.g. openai/gpt-5)",
107829
+ message: "Model (format: provider/model-id, e.g. opencode/qwen3.5-plus-free)",
107600
107830
  placeholder: suggestion,
107601
107831
  validate: (value) => {
107602
107832
  if (!value || !value.includes("/"))
@@ -107608,13 +107838,35 @@ var clackPrompter = async ({ suggestion, reason, detectedProviders }) => {
107608
107838
  return { action: "skip" };
107609
107839
  return { action: "custom", value: custom2 };
107610
107840
  };
107841
+ var makeInvalidModelPrompter = (existingModel, suggestion, reason) => async ({ detectedProviders }) => {
107842
+ const providersHint = detectedProviders.length > 0 ? `Authenticated providers: ${detectedProviders.join(", ")}` : "No authenticated providers detected.";
107843
+ const response = await ie({
107844
+ message: `Existing model "${existingModel}" is not in the models.dev catalog. ${providersHint}`,
107845
+ options: [
107846
+ {
107847
+ value: "rewrite",
107848
+ label: `Replace with "${suggestion}"`,
107849
+ hint: reason
107850
+ },
107851
+ {
107852
+ value: "keep",
107853
+ label: `Keep "${existingModel}" as-is`,
107854
+ hint: "May cause ProviderModelNotFoundError at runtime"
107855
+ }
107856
+ ],
107857
+ initialValue: "rewrite"
107858
+ });
107859
+ if (lD(response) || response === "keep")
107860
+ return { action: "skip" };
107861
+ return { action: "accept" };
107862
+ };
107611
107863
  async function ensureOpenCodeModel(options2) {
107612
107864
  const configPath = getOpenCodeConfigPath(options2);
107613
107865
  let existing = null;
107614
107866
  try {
107615
- const raw2 = await readFile60(configPath, "utf-8");
107867
+ const raw2 = await readFile62(configPath, "utf-8");
107616
107868
  const parsed = JSON.parse(raw2);
107617
- if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
107869
+ if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
107618
107870
  existing = parsed;
107619
107871
  } else {
107620
107872
  logger.warning(`ensureOpenCodeModel: ${configPath} is valid JSON but not an object; overwriting with default model`);
@@ -107627,40 +107879,72 @@ async function ensureOpenCodeModel(options2) {
107627
107879
  logger.verbose(`ensureOpenCodeModel: failed to read ${configPath} (${errno ?? String(err)}); recreating`);
107628
107880
  }
107629
107881
  }
107630
- if (existing && typeof existing.model === "string" && existing.model.trim().length > 0) {
107631
- return { path: configPath, action: "existing", model: existing.model };
107632
- }
107633
- const suggestion = await suggestOpenCodeDefaultModel(options2.homeDir);
107634
- let chosenModel = suggestion.model;
107635
- if (options2.interactive) {
107636
- const detectedProviders = await detectAuthenticatedProviders(options2.homeDir);
107637
- const prompter = options2.prompter ?? clackPrompter;
107638
- const response = await prompter({
107639
- suggestion: suggestion.model,
107640
- reason: suggestion.reason,
107641
- detectedProviders
107882
+ if (existing !== null && typeof existing.model === "string" && existing.model.trim().length > 0) {
107883
+ const existingModel = existing.model.trim();
107884
+ const isValid2 = await validateModelAgainstCatalog(existingModel, options2);
107885
+ if (isValid2) {
107886
+ return { path: configPath, action: "existing", model: existingModel };
107887
+ }
107888
+ if (!options2.interactive) {
107889
+ logger.warning(`ensureOpenCodeModel: existing model "${existingModel}" is not found in the models.dev catalog. ` + `Run \`ck migrate --agent opencode\` interactively to update it, or edit ${configPath} manually.`);
107890
+ return { path: configPath, action: "existing", model: existingModel };
107891
+ }
107892
+ const suggestion2 = await suggestModel(options2);
107893
+ if (!suggestion2.ok) {
107894
+ return { path: configPath, action: "existing", model: existingModel };
107895
+ }
107896
+ const invalidPrompter = options2.prompter ?? makeInvalidModelPrompter(existingModel, suggestion2.model, suggestion2.reason);
107897
+ const response2 = await invalidPrompter({
107898
+ suggestion: suggestion2.model,
107899
+ reason: suggestion2.reason,
107900
+ detectedProviders: suggestion2.authedProviders
107642
107901
  });
107643
- if (response.action === "skip") {
107644
- return {
107645
- path: configPath,
107646
- action: "skipped",
107647
- model: "",
107648
- reason: "user declined"
107649
- };
107902
+ if (response2.action === "skip") {
107903
+ return { path: configPath, action: "existing", model: existingModel };
107650
107904
  }
107651
- if (response.action === "custom") {
107652
- chosenModel = response.value;
107905
+ const chosenModel2 = response2.action === "custom" ? response2.value : suggestion2.model;
107906
+ const next2 = { ...existing, model: chosenModel2 };
107907
+ await mkdir37(dirname41(configPath), { recursive: true });
107908
+ await writeFile36(configPath, `${JSON.stringify(next2, null, 2)}
107909
+ `, "utf-8");
107910
+ return { path: configPath, action: "added", model: chosenModel2, reason: suggestion2.reason };
107911
+ }
107912
+ const suggestion = await suggestModel(options2);
107913
+ if (!options2.interactive) {
107914
+ if (!suggestion.ok) {
107915
+ throw new OpenCodeAuthRequiredError(suggestion.failure);
107653
107916
  }
107917
+ const next2 = { ...existing ?? {}, model: suggestion.model };
107918
+ await mkdir37(dirname41(configPath), { recursive: true });
107919
+ await writeFile36(configPath, `${JSON.stringify(next2, null, 2)}
107920
+ `, "utf-8");
107921
+ return {
107922
+ path: configPath,
107923
+ action: existing ? "added" : "created",
107924
+ model: suggestion.model,
107925
+ reason: suggestion.reason
107926
+ };
107927
+ }
107928
+ const prompter = options2.prompter ?? clackPrompter;
107929
+ const detectedProviders = suggestion.ok ? suggestion.authedProviders : suggestion.authedProviders;
107930
+ const response = await prompter({
107931
+ suggestion: suggestion.ok ? suggestion.model : "",
107932
+ reason: suggestion.ok ? suggestion.reason : messageForReason(suggestion.failure),
107933
+ detectedProviders
107934
+ });
107935
+ if (response.action === "skip") {
107936
+ return { path: configPath, action: "skipped", model: "", reason: "user declined" };
107654
107937
  }
107938
+ const chosenModel = response.action === "custom" ? response.value : suggestion.ok ? suggestion.model : "";
107655
107939
  const next = { ...existing ?? {}, model: chosenModel };
107656
- await mkdir36(dirname41(configPath), { recursive: true });
107657
- await writeFile35(configPath, `${JSON.stringify(next, null, 2)}
107940
+ await mkdir37(dirname41(configPath), { recursive: true });
107941
+ await writeFile36(configPath, `${JSON.stringify(next, null, 2)}
107658
107942
  `, "utf-8");
107659
107943
  return {
107660
107944
  path: configPath,
107661
107945
  action: existing ? "added" : "created",
107662
107946
  model: chosenModel,
107663
- reason: suggestion.reason
107947
+ reason: suggestion.ok ? suggestion.reason : undefined
107664
107948
  };
107665
107949
  }
107666
107950
 
@@ -108435,12 +108719,12 @@ async function executeDeleteAction(action, options2) {
108435
108719
  async function processMetadataDeletions(skillSourcePath, installGlobally) {
108436
108720
  if (!skillSourcePath)
108437
108721
  return;
108438
- const sourceMetadataPath = join142(resolve41(skillSourcePath, ".."), "metadata.json");
108722
+ const sourceMetadataPath = join144(resolve41(skillSourcePath, ".."), "metadata.json");
108439
108723
  if (!existsSync64(sourceMetadataPath))
108440
108724
  return;
108441
108725
  let sourceMetadata;
108442
108726
  try {
108443
- const content = await readFile61(sourceMetadataPath, "utf-8");
108727
+ const content = await readFile63(sourceMetadataPath, "utf-8");
108444
108728
  sourceMetadata = JSON.parse(content);
108445
108729
  } catch (error) {
108446
108730
  logger.debug(`[migrate] Failed to parse source metadata.json: ${error}`);
@@ -108448,7 +108732,7 @@ async function processMetadataDeletions(skillSourcePath, installGlobally) {
108448
108732
  }
108449
108733
  if (!sourceMetadata.deletions || sourceMetadata.deletions.length === 0)
108450
108734
  return;
108451
- const claudeDir3 = installGlobally ? join142(homedir50(), ".claude") : join142(process.cwd(), ".claude");
108735
+ const claudeDir3 = installGlobally ? join144(homedir52(), ".claude") : join144(process.cwd(), ".claude");
108452
108736
  if (!existsSync64(claudeDir3))
108453
108737
  return;
108454
108738
  try {
@@ -108570,8 +108854,8 @@ async function migrateCommand(options2) {
108570
108854
  let requestedGlobal = options2.global ?? false;
108571
108855
  let installGlobally = requestedGlobal;
108572
108856
  if (options2.global === undefined && !options2.yes) {
108573
- const projectTarget = join142(process.cwd(), ".claude");
108574
- const globalTarget = join142(homedir50(), ".claude");
108857
+ const projectTarget = join144(process.cwd(), ".claude");
108858
+ const globalTarget = join144(homedir52(), ".claude");
108575
108859
  const scopeChoice = await ie({
108576
108860
  message: "Installation scope",
108577
108861
  options: [
@@ -108734,7 +109018,7 @@ async function migrateCommand(options2) {
108734
109018
  for (const action of conflictActions) {
108735
109019
  if (!action.diff && action.targetPath && existsSync64(action.targetPath)) {
108736
109020
  try {
108737
- const targetContent = await readFile61(action.targetPath, "utf-8");
109021
+ const targetContent = await readFile63(action.targetPath, "utf-8");
108738
109022
  const sourceItem = effectiveAgents.find((a3) => a3.name === action.item) || effectiveCommands.find((c2) => c2.name === action.item) || (effectiveConfigItem?.name === action.item ? effectiveConfigItem : null) || effectiveRuleItems.find((r2) => r2.name === action.item) || effectiveHookItems.find((h2) => h2.name === action.item);
108739
109023
  if (sourceItem) {
108740
109024
  const providerConfig = providers[action.provider];
@@ -108881,7 +109165,12 @@ async function migrateCommand(options2) {
108881
109165
  f2.warn("Skipped writing default model to opencode.json. Migrated agents may fail with ProviderModelNotFoundError until you set one.");
108882
109166
  }
108883
109167
  } catch (err) {
108884
- 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.`);
109168
+ if (err instanceof OpenCodeAuthRequiredError) {
109169
+ f2.warn(err.message);
109170
+ postProgressWarnings.push(`opencode setup is incomplete: ${err.message}`);
109171
+ } else {
109172
+ 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.`);
109173
+ }
108885
109174
  }
108886
109175
  }
108887
109176
  if (hooksSource && successfulHookFiles.size > 0) {
@@ -109146,7 +109435,7 @@ function buildDryRunFallbackResults(skills, selectedProviders, installGlobally,
109146
109435
  results.push({
109147
109436
  itemName: skill.name,
109148
109437
  operation: "apply",
109149
- path: join142(basePath, skill.name),
109438
+ path: join144(basePath, skill.name),
109150
109439
  portableType: "skill",
109151
109440
  provider,
109152
109441
  providerDisplayName: providers[provider].displayName,
@@ -109306,7 +109595,7 @@ async function handleDirectorySetup(ctx) {
109306
109595
  // src/commands/new/phases/project-creation.ts
109307
109596
  init_config_manager();
109308
109597
  init_github_client();
109309
- import { join as join143 } from "node:path";
109598
+ import { join as join145 } from "node:path";
109310
109599
  init_logger();
109311
109600
  init_output_manager();
109312
109601
  init_types3();
@@ -109432,7 +109721,7 @@ async function projectCreation(kit, resolvedDir, validOptions, isNonInteractive2
109432
109721
  output.section("Installing");
109433
109722
  logger.verbose("Installation target", { directory: resolvedDir });
109434
109723
  const merger = new FileMerger;
109435
- const claudeDir3 = join143(resolvedDir, ".claude");
109724
+ const claudeDir3 = join145(resolvedDir, ".claude");
109436
109725
  merger.setMultiKitContext(claudeDir3, kit);
109437
109726
  if (validOptions.exclude && validOptions.exclude.length > 0) {
109438
109727
  merger.addIgnorePatterns(validOptions.exclude);
@@ -109479,7 +109768,7 @@ async function handleProjectCreation(ctx) {
109479
109768
  }
109480
109769
  // src/commands/new/phases/post-setup.ts
109481
109770
  init_projects_registry();
109482
- import { join as join144 } from "node:path";
109771
+ import { join as join146 } from "node:path";
109483
109772
  init_package_installer();
109484
109773
  init_logger();
109485
109774
  init_path_resolver();
@@ -109511,9 +109800,9 @@ async function postSetup(resolvedDir, validOptions, isNonInteractive2, prompts)
109511
109800
  withSudo: validOptions.withSudo
109512
109801
  });
109513
109802
  }
109514
- const claudeDir3 = join144(resolvedDir, ".claude");
109803
+ const claudeDir3 = join146(resolvedDir, ".claude");
109515
109804
  await promptSetupWizardIfNeeded({
109516
- envPath: join144(claudeDir3, ".env"),
109805
+ envPath: join146(claudeDir3, ".env"),
109517
109806
  claudeDir: claudeDir3,
109518
109807
  isGlobal: false,
109519
109808
  isNonInteractive: isNonInteractive2,
@@ -109583,7 +109872,7 @@ Please use only one download method.`);
109583
109872
  // src/commands/plan/plan-command.ts
109584
109873
  init_output_manager();
109585
109874
  import { existsSync as existsSync67, statSync as statSync12 } from "node:fs";
109586
- import { dirname as dirname46, isAbsolute as isAbsolute11, join as join147, parse as parse7, resolve as resolve48 } from "node:path";
109875
+ import { dirname as dirname46, isAbsolute as isAbsolute11, join as join149, parse as parse7, resolve as resolve48 } from "node:path";
109587
109876
 
109588
109877
  // src/commands/plan/plan-read-handlers.ts
109589
109878
  init_config();
@@ -109593,14 +109882,14 @@ init_logger();
109593
109882
  init_output_manager();
109594
109883
  var import_picocolors32 = __toESM(require_picocolors(), 1);
109595
109884
  import { existsSync as existsSync66, statSync as statSync11 } from "node:fs";
109596
- import { basename as basename28, dirname as dirname44, join as join146, relative as relative27, resolve as resolve46 } from "node:path";
109885
+ import { basename as basename28, dirname as dirname44, join as join148, relative as relative27, resolve as resolve46 } from "node:path";
109597
109886
 
109598
109887
  // src/commands/plan/plan-dependencies.ts
109599
109888
  init_config();
109600
109889
  init_plan_parser();
109601
109890
  init_plans_registry();
109602
109891
  import { existsSync as existsSync65 } from "node:fs";
109603
- import { dirname as dirname43, join as join145 } from "node:path";
109892
+ import { dirname as dirname43, join as join147 } from "node:path";
109604
109893
  async function resolvePlanDependencies(references, currentPlanFile, options2 = {}) {
109605
109894
  if (references.length === 0)
109606
109895
  return [];
@@ -109620,7 +109909,7 @@ async function resolvePlanDependencies(references, currentPlanFile, options2 = {
109620
109909
  };
109621
109910
  }
109622
109911
  const scopeRoot = resolvePlanDirForScope(scope, projectRoot, config);
109623
- const planFile = join145(scopeRoot, planId, "plan.md");
109912
+ const planFile = join147(scopeRoot, planId, "plan.md");
109624
109913
  const isSelfReference = planFile === currentPlanFile;
109625
109914
  if (!existsSync65(planFile)) {
109626
109915
  return {
@@ -109762,7 +110051,7 @@ async function handleStatus(target, options2) {
109762
110051
  }
109763
110052
  const effectiveTarget = !resolvedTarget && globalBaseDir ? globalBaseDir : resolvedTarget;
109764
110053
  const t = effectiveTarget ? resolve46(effectiveTarget) : null;
109765
- const plansDir = t && existsSync66(t) && statSync11(t).isDirectory() && !existsSync66(join146(t, "plan.md")) ? t : null;
110054
+ const plansDir = t && existsSync66(t) && statSync11(t).isDirectory() && !existsSync66(join148(t, "plan.md")) ? t : null;
109766
110055
  if (plansDir) {
109767
110056
  const planFiles = scanPlanDir(plansDir);
109768
110057
  if (planFiles.length === 0) {
@@ -110177,7 +110466,7 @@ function resolvePlanFile(target, baseDir) {
110177
110466
  const stat24 = statSync12(t);
110178
110467
  if (stat24.isFile())
110179
110468
  return t;
110180
- const candidate = join147(t, "plan.md");
110469
+ const candidate = join149(t, "plan.md");
110181
110470
  if (existsSync67(candidate))
110182
110471
  return candidate;
110183
110472
  }
@@ -110185,7 +110474,7 @@ function resolvePlanFile(target, baseDir) {
110185
110474
  let dir = process.cwd();
110186
110475
  const root = parse7(dir).root;
110187
110476
  while (dir !== root) {
110188
- const candidate = join147(dir, "plan.md");
110477
+ const candidate = join149(dir, "plan.md");
110189
110478
  if (existsSync67(candidate))
110190
110479
  return candidate;
110191
110480
  dir = dirname46(dir);
@@ -110707,8 +110996,8 @@ init_skills_registry();
110707
110996
  init_skills_uninstaller();
110708
110997
  var import_gray_matter11 = __toESM(require_gray_matter(), 1);
110709
110998
  var import_picocolors37 = __toESM(require_picocolors(), 1);
110710
- import { readFile as readFile62 } from "node:fs/promises";
110711
- import { join as join148 } from "node:path";
110999
+ import { readFile as readFile64 } from "node:fs/promises";
111000
+ import { join as join150 } from "node:path";
110712
111001
 
110713
111002
  // src/commands/skills/types.ts
110714
111003
  init_zod();
@@ -110830,9 +111119,9 @@ async function handleValidate2(sourcePath) {
110830
111119
  spinner.stop(`Checked ${skills.length} skill(s)`);
110831
111120
  let hasIssues = false;
110832
111121
  for (const skill of skills) {
110833
- const skillMdPath = join148(skill.path, "SKILL.md");
111122
+ const skillMdPath = join150(skill.path, "SKILL.md");
110834
111123
  try {
110835
- const content = await readFile62(skillMdPath, "utf-8");
111124
+ const content = await readFile64(skillMdPath, "utf-8");
110836
111125
  const { data } = import_gray_matter11.default(content, {
110837
111126
  engines: { javascript: { parse: () => ({}) } }
110838
111127
  });
@@ -111388,7 +111677,7 @@ async function detectInstallations() {
111388
111677
 
111389
111678
  // src/commands/uninstall/removal-handler.ts
111390
111679
  import { readdirSync as readdirSync10, rmSync as rmSync5 } from "node:fs";
111391
- import { basename as basename30, join as join150, resolve as resolve50, sep as sep12 } from "node:path";
111680
+ import { basename as basename30, join as join152, resolve as resolve50, sep as sep12 } from "node:path";
111392
111681
  init_logger();
111393
111682
  init_safe_prompts();
111394
111683
  init_safe_spinner();
@@ -111397,7 +111686,7 @@ var import_fs_extra44 = __toESM(require_lib3(), 1);
111397
111686
  // src/commands/uninstall/analysis-handler.ts
111398
111687
  init_metadata_migration();
111399
111688
  import { readdirSync as readdirSync9, rmSync as rmSync4 } from "node:fs";
111400
- import { dirname as dirname47, join as join149 } from "node:path";
111689
+ import { dirname as dirname47, join as join151 } from "node:path";
111401
111690
  init_logger();
111402
111691
  init_safe_prompts();
111403
111692
  var import_fs_extra43 = __toESM(require_lib3(), 1);
@@ -111454,7 +111743,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
111454
111743
  const remainingFiles = metadata.kits?.[remainingKit]?.files || [];
111455
111744
  for (const file of remainingFiles) {
111456
111745
  const relativePath = normalizeTrackedPath(file.path);
111457
- if (await import_fs_extra43.pathExists(join149(installation.path, relativePath))) {
111746
+ if (await import_fs_extra43.pathExists(join151(installation.path, relativePath))) {
111458
111747
  result.retainedManifestPaths.push(relativePath);
111459
111748
  }
111460
111749
  }
@@ -111462,7 +111751,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
111462
111751
  const kitFiles = metadata.kits[kit].files || [];
111463
111752
  for (const trackedFile of kitFiles) {
111464
111753
  const relativePath = normalizeTrackedPath(trackedFile.path);
111465
- const filePath = join149(installation.path, relativePath);
111754
+ const filePath = join151(installation.path, relativePath);
111466
111755
  if (preservedPaths.has(relativePath)) {
111467
111756
  result.toPreserve.push({ path: relativePath, reason: "shared with other kit" });
111468
111757
  continue;
@@ -111495,7 +111784,7 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
111495
111784
  }
111496
111785
  for (const trackedFile of allTrackedFiles) {
111497
111786
  const relativePath = normalizeTrackedPath(trackedFile.path);
111498
- const filePath = join149(installation.path, relativePath);
111787
+ const filePath = join151(installation.path, relativePath);
111499
111788
  const ownershipResult = await OwnershipChecker.checkOwnership(filePath, metadata, installation.path);
111500
111789
  if (!ownershipResult.exists)
111501
111790
  continue;
@@ -111638,7 +111927,7 @@ async function removeInstallations(installations, options2) {
111638
111927
  let removedCount = 0;
111639
111928
  let cleanedDirs = 0;
111640
111929
  for (const item of analysis.toDelete) {
111641
- const filePath = join150(installation.path, item.path);
111930
+ const filePath = join152(installation.path, item.path);
111642
111931
  if (!await import_fs_extra44.pathExists(filePath))
111643
111932
  continue;
111644
111933
  if (!await isPathSafeToRemove(filePath, installation.path)) {
@@ -111972,7 +112261,7 @@ ${import_picocolors40.default.bold(import_picocolors40.default.cyan(result.kitCo
111972
112261
  init_logger();
111973
112262
  import { existsSync as existsSync74 } from "node:fs";
111974
112263
  import { rm as rm17 } from "node:fs/promises";
111975
- import { join as join157 } from "node:path";
112264
+ import { join as join159 } from "node:path";
111976
112265
  var import_picocolors41 = __toESM(require_picocolors(), 1);
111977
112266
 
111978
112267
  // src/commands/watch/phases/implementation-runner.ts
@@ -112490,8 +112779,8 @@ function spawnAndCollect3(command, args) {
112490
112779
  }
112491
112780
 
112492
112781
  // src/commands/watch/phases/issue-processor.ts
112493
- import { mkdir as mkdir37, writeFile as writeFile37 } from "node:fs/promises";
112494
- import { join as join153 } from "node:path";
112782
+ import { mkdir as mkdir38, writeFile as writeFile38 } from "node:fs/promises";
112783
+ import { join as join155 } from "node:path";
112495
112784
 
112496
112785
  // src/commands/watch/phases/approval-detector.ts
112497
112786
  init_logger();
@@ -112869,9 +113158,9 @@ async function checkAwaitingApproval(state, setup, options2, watchLog, projectDi
112869
113158
 
112870
113159
  // src/commands/watch/phases/plan-dir-finder.ts
112871
113160
  import { readdir as readdir44, stat as stat24 } from "node:fs/promises";
112872
- import { join as join152 } from "node:path";
113161
+ import { join as join154 } from "node:path";
112873
113162
  async function findRecentPlanDir(cwd2, issueNumber, watchLog) {
112874
- const plansRoot = join152(cwd2, "plans");
113163
+ const plansRoot = join154(cwd2, "plans");
112875
113164
  try {
112876
113165
  const entries = await readdir44(plansRoot);
112877
113166
  const tenMinAgo = Date.now() - 10 * 60 * 1000;
@@ -112880,14 +113169,14 @@ async function findRecentPlanDir(cwd2, issueNumber, watchLog) {
112880
113169
  for (const entry of entries) {
112881
113170
  if (entry === "watch" || entry === "reports" || entry === "visuals")
112882
113171
  continue;
112883
- const dirPath = join152(plansRoot, entry);
113172
+ const dirPath = join154(plansRoot, entry);
112884
113173
  const dirStat = await stat24(dirPath);
112885
113174
  if (!dirStat.isDirectory())
112886
113175
  continue;
112887
113176
  if (dirStat.mtimeMs < tenMinAgo)
112888
113177
  continue;
112889
113178
  try {
112890
- await stat24(join152(dirPath, "plan.md"));
113179
+ await stat24(join154(dirPath, "plan.md"));
112891
113180
  } catch {
112892
113181
  continue;
112893
113182
  }
@@ -113118,14 +113407,14 @@ async function handlePlanGeneration(issue, state, config, setup, options2, watch
113118
113407
  stats.plansCreated++;
113119
113408
  const detectedPlanDir = await findRecentPlanDir(projectDir, issue.number, watchLog);
113120
113409
  if (detectedPlanDir) {
113121
- state.activeIssues[numStr].planPath = join153(detectedPlanDir, "plan.md");
113410
+ state.activeIssues[numStr].planPath = join155(detectedPlanDir, "plan.md");
113122
113411
  watchLog.info(`Plan directory detected: ${detectedPlanDir}`);
113123
113412
  } else {
113124
113413
  try {
113125
- const planDir = join153(projectDir, "plans", "watch");
113126
- await mkdir37(planDir, { recursive: true });
113127
- const planFilePath = join153(planDir, `issue-${issue.number}-plan.md`);
113128
- await writeFile37(planFilePath, planResult.planText, "utf-8");
113414
+ const planDir = join155(projectDir, "plans", "watch");
113415
+ await mkdir38(planDir, { recursive: true });
113416
+ const planFilePath = join155(planDir, `issue-${issue.number}-plan.md`);
113417
+ await writeFile38(planFilePath, planResult.planText, "utf-8");
113129
113418
  state.activeIssues[numStr].planPath = planFilePath;
113130
113419
  watchLog.info(`Plan saved (fallback) to ${planFilePath}`);
113131
113420
  } catch (err) {
@@ -113202,7 +113491,7 @@ async function checkActiveIssues(state, config, setup, options2, watchLog, stats
113202
113491
  // src/commands/watch/phases/maintainer-resolver.ts
113203
113492
  init_logger();
113204
113493
  init_implementation_git_helpers();
113205
- var CACHE_TTL_MS3 = 3600000;
113494
+ var CACHE_TTL_MS4 = 3600000;
113206
113495
  var cache4 = new Map;
113207
113496
  async function resolveMaintainers(owner, repo, excludeAuthors, autoDetect) {
113208
113497
  const normalizedExclude = excludeAuthors.map((s) => s.toLowerCase());
@@ -113211,7 +113500,7 @@ async function resolveMaintainers(owner, repo, excludeAuthors, autoDetect) {
113211
113500
  }
113212
113501
  const cacheKey = `${owner}/${repo}`;
113213
113502
  const cached = cache4.get(cacheKey);
113214
- if (cached && Date.now() - cached.fetchedAt >= CACHE_TTL_MS3) {
113503
+ if (cached && Date.now() - cached.fetchedAt >= CACHE_TTL_MS4) {
113215
113504
  cache4.delete(cacheKey);
113216
113505
  } else if (cached) {
113217
113506
  const merged = Array.from(new Set([...cached.users, ...normalizedExclude]));
@@ -113270,7 +113559,7 @@ init_ck_config_manager();
113270
113559
  init_file_io();
113271
113560
  init_logger();
113272
113561
  import { existsSync as existsSync70 } from "node:fs";
113273
- import { mkdir as mkdir38, readFile as readFile64 } from "node:fs/promises";
113562
+ import { mkdir as mkdir39, readFile as readFile66 } from "node:fs/promises";
113274
113563
  import { dirname as dirname48 } from "node:path";
113275
113564
  var PROCESSED_ISSUES_CAP = 500;
113276
113565
  async function readCkJson(projectDir) {
@@ -113278,7 +113567,7 @@ async function readCkJson(projectDir) {
113278
113567
  try {
113279
113568
  if (!existsSync70(configPath))
113280
113569
  return {};
113281
- const content = await readFile64(configPath, "utf-8");
113570
+ const content = await readFile66(configPath, "utf-8");
113282
113571
  return JSON.parse(content);
113283
113572
  } catch (error) {
113284
113573
  logger.warning(`Failed to parse .ck.json: ${error instanceof Error ? error.message : "Unknown"}`);
@@ -113303,7 +113592,7 @@ async function saveWatchState(projectDir, state) {
113303
113592
  const configPath = CkConfigManager.getProjectConfigPath(projectDir);
113304
113593
  const configDir = dirname48(configPath);
113305
113594
  if (!existsSync70(configDir)) {
113306
- await mkdir38(configDir, { recursive: true });
113595
+ await mkdir39(configDir, { recursive: true });
113307
113596
  }
113308
113597
  const raw2 = await readCkJson(projectDir);
113309
113598
  const watchRaw = raw2.watch ?? {};
@@ -113431,18 +113720,18 @@ init_logger();
113431
113720
  import { spawnSync as spawnSync7 } from "node:child_process";
113432
113721
  import { existsSync as existsSync71 } from "node:fs";
113433
113722
  import { readdir as readdir45, stat as stat25 } from "node:fs/promises";
113434
- import { join as join154 } from "node:path";
113723
+ import { join as join156 } from "node:path";
113435
113724
  async function scanForRepos(parentDir) {
113436
113725
  const repos = [];
113437
113726
  const entries = await readdir45(parentDir);
113438
113727
  for (const entry of entries) {
113439
113728
  if (entry.startsWith("."))
113440
113729
  continue;
113441
- const fullPath = join154(parentDir, entry);
113730
+ const fullPath = join156(parentDir, entry);
113442
113731
  const entryStat = await stat25(fullPath);
113443
113732
  if (!entryStat.isDirectory())
113444
113733
  continue;
113445
- const gitDir = join154(fullPath, ".git");
113734
+ const gitDir = join156(fullPath, ".git");
113446
113735
  if (!existsSync71(gitDir))
113447
113736
  continue;
113448
113737
  const result = spawnSync7("gh", ["repo", "view", "--json", "owner,name"], {
@@ -113468,8 +113757,8 @@ async function scanForRepos(parentDir) {
113468
113757
  init_logger();
113469
113758
  import { spawnSync as spawnSync8 } from "node:child_process";
113470
113759
  import { existsSync as existsSync72 } from "node:fs";
113471
- import { homedir as homedir51 } from "node:os";
113472
- import { join as join155 } from "node:path";
113760
+ import { homedir as homedir53 } from "node:os";
113761
+ import { join as join157 } from "node:path";
113473
113762
  async function validateSetup(cwd2) {
113474
113763
  const workDir = cwd2 ?? process.cwd();
113475
113764
  const ghVersion = spawnSync8("gh", ["--version"], { encoding: "utf-8", timeout: 1e4 });
@@ -113500,7 +113789,7 @@ Run this command from a directory with a GitHub remote.`);
113500
113789
  } catch {
113501
113790
  throw new Error(`Failed to parse repository info: ${ghRepo.stdout}`);
113502
113791
  }
113503
- const skillsPath = join155(homedir51(), ".claude", "skills");
113792
+ const skillsPath = join157(homedir53(), ".claude", "skills");
113504
113793
  const skillsAvailable = existsSync72(skillsPath);
113505
113794
  if (!skillsAvailable) {
113506
113795
  logger.warning(`ClaudeKit Engineer skills not found at ${skillsPath}`);
@@ -113518,8 +113807,8 @@ init_logger();
113518
113807
  init_path_resolver();
113519
113808
  import { createWriteStream as createWriteStream3, statSync as statSync13 } from "node:fs";
113520
113809
  import { existsSync as existsSync73 } from "node:fs";
113521
- import { mkdir as mkdir39, rename as rename13 } from "node:fs/promises";
113522
- import { join as join156 } from "node:path";
113810
+ import { mkdir as mkdir40, rename as rename14 } from "node:fs/promises";
113811
+ import { join as join158 } from "node:path";
113523
113812
 
113524
113813
  class WatchLogger {
113525
113814
  logStream = null;
@@ -113527,16 +113816,16 @@ class WatchLogger {
113527
113816
  logPath = null;
113528
113817
  maxBytes;
113529
113818
  constructor(logDir, maxBytes = 0) {
113530
- this.logDir = logDir ?? join156(PathResolver.getClaudeKitDir(), "logs");
113819
+ this.logDir = logDir ?? join158(PathResolver.getClaudeKitDir(), "logs");
113531
113820
  this.maxBytes = maxBytes;
113532
113821
  }
113533
113822
  async init() {
113534
113823
  try {
113535
113824
  if (!existsSync73(this.logDir)) {
113536
- await mkdir39(this.logDir, { recursive: true });
113825
+ await mkdir40(this.logDir, { recursive: true });
113537
113826
  }
113538
113827
  const dateStr = formatDate(new Date);
113539
- this.logPath = join156(this.logDir, `watch-${dateStr}.log`);
113828
+ this.logPath = join158(this.logDir, `watch-${dateStr}.log`);
113540
113829
  this.logStream = createWriteStream3(this.logPath, { flags: "a", mode: 384 });
113541
113830
  } catch (error) {
113542
113831
  logger.warning(`Cannot create watch log file: ${error instanceof Error ? error.message : "Unknown"}`);
@@ -113601,7 +113890,7 @@ class WatchLogger {
113601
113890
  try {
113602
113891
  this.logStream.end();
113603
113892
  const rotatedPath = `${this.logPath}.1`;
113604
- rename13(this.logPath, rotatedPath).catch(() => {});
113893
+ rename14(this.logPath, rotatedPath).catch(() => {});
113605
113894
  this.logStream = createWriteStream3(this.logPath, { flags: "w", mode: 384 });
113606
113895
  } catch {}
113607
113896
  }
@@ -113718,7 +114007,7 @@ async function watchCommand(options2) {
113718
114007
  }
113719
114008
  async function discoverRepos(options2, watchLog) {
113720
114009
  const cwd2 = process.cwd();
113721
- const isGitRepo = existsSync74(join157(cwd2, ".git"));
114010
+ const isGitRepo = existsSync74(join159(cwd2, ".git"));
113722
114011
  if (options2.force) {
113723
114012
  await forceRemoveLock(watchLog);
113724
114013
  }
@@ -113977,7 +114266,7 @@ function registerCommands(cli) {
113977
114266
  init_package();
113978
114267
  init_config_version_checker();
113979
114268
  import { existsSync as existsSync86, readFileSync as readFileSync22 } from "node:fs";
113980
- import { join as join169 } from "node:path";
114269
+ import { join as join171 } from "node:path";
113981
114270
 
113982
114271
  // src/domains/versioning/version-checker.ts
113983
114272
  init_version_utils();
@@ -113991,15 +114280,15 @@ init_types3();
113991
114280
  init_logger();
113992
114281
  init_path_resolver();
113993
114282
  import { existsSync as existsSync85 } from "node:fs";
113994
- import { mkdir as mkdir40, readFile as readFile66, writeFile as writeFile40 } from "node:fs/promises";
113995
- import { join as join168 } from "node:path";
114283
+ import { mkdir as mkdir41, readFile as readFile68, writeFile as writeFile41 } from "node:fs/promises";
114284
+ import { join as join170 } from "node:path";
113996
114285
 
113997
114286
  class VersionCacheManager {
113998
114287
  static CACHE_FILENAME = "version-check.json";
113999
114288
  static CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000;
114000
114289
  static getCacheFile() {
114001
114290
  const cacheDir = PathResolver.getCacheDir(false);
114002
- return join168(cacheDir, VersionCacheManager.CACHE_FILENAME);
114291
+ return join170(cacheDir, VersionCacheManager.CACHE_FILENAME);
114003
114292
  }
114004
114293
  static async load() {
114005
114294
  const cacheFile = VersionCacheManager.getCacheFile();
@@ -114008,7 +114297,7 @@ class VersionCacheManager {
114008
114297
  logger.debug("Version check cache not found");
114009
114298
  return null;
114010
114299
  }
114011
- const content = await readFile66(cacheFile, "utf-8");
114300
+ const content = await readFile68(cacheFile, "utf-8");
114012
114301
  const cache5 = JSON.parse(content);
114013
114302
  if (!cache5.lastCheck || !cache5.currentVersion || !cache5.latestVersion) {
114014
114303
  logger.debug("Invalid cache structure, ignoring");
@@ -114026,9 +114315,9 @@ class VersionCacheManager {
114026
114315
  const cacheDir = PathResolver.getCacheDir(false);
114027
114316
  try {
114028
114317
  if (!existsSync85(cacheDir)) {
114029
- await mkdir40(cacheDir, { recursive: true, mode: 448 });
114318
+ await mkdir41(cacheDir, { recursive: true, mode: 448 });
114030
114319
  }
114031
- await writeFile40(cacheFile, JSON.stringify(cache5, null, 2), "utf-8");
114320
+ await writeFile41(cacheFile, JSON.stringify(cache5, null, 2), "utf-8");
114032
114321
  logger.debug(`Version check cache saved to ${cacheFile}`);
114033
114322
  } catch (error) {
114034
114323
  logger.debug(`Failed to save version check cache: ${error}`);
@@ -114310,9 +114599,9 @@ async function displayVersion() {
114310
114599
  let localInstalledKits = [];
114311
114600
  let globalInstalledKits = [];
114312
114601
  const globalKitDir = PathResolver.getGlobalKitDir();
114313
- const globalMetadataPath = join169(globalKitDir, "metadata.json");
114602
+ const globalMetadataPath = join171(globalKitDir, "metadata.json");
114314
114603
  const prefix = PathResolver.getPathPrefix(false);
114315
- const localMetadataPath = prefix ? join169(process.cwd(), prefix, "metadata.json") : join169(process.cwd(), "metadata.json");
114604
+ const localMetadataPath = prefix ? join171(process.cwd(), prefix, "metadata.json") : join171(process.cwd(), "metadata.json");
114316
114605
  const isLocalSameAsGlobal = localMetadataPath === globalMetadataPath;
114317
114606
  if (!isLocalSameAsGlobal && existsSync86(localMetadataPath)) {
114318
114607
  try {