claudekit-cli 3.41.4-dev.44 → 3.41.4-dev.46

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