claudekit-cli 3.41.4-dev.41 → 3.41.4-dev.43

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.
Files changed (2) hide show
  1. package/dist/index.js +1383 -544
  2. package/package.json +4 -2
package/dist/index.js CHANGED
@@ -10632,6 +10632,7 @@ __export(exports_provider_registry, {
10632
10632
  getProvidersSupporting: () => getProvidersSupporting,
10633
10633
  getProviderConfig: () => getProviderConfig,
10634
10634
  getPortableInstallPath: () => getPortableInstallPath,
10635
+ getPortableBasePath: () => getPortableBasePath,
10635
10636
  getAllProviderTypes: () => getAllProviderTypes,
10636
10637
  detectProviderPathCollisions: () => detectProviderPathCollisions,
10637
10638
  detectInstalledProviders: () => detectInstalledProviders,
@@ -10704,12 +10705,19 @@ async function detectInstalledProviders() {
10704
10705
  function getProvidersSupporting(type) {
10705
10706
  return Object.entries(providers).filter(([, config]) => config[type] != null).map(([name]) => name);
10706
10707
  }
10708
+ function getPortableBasePath(provider, portableType, options2) {
10709
+ const config = providers[provider];
10710
+ const pathConfig = config[portableType];
10711
+ if (!pathConfig)
10712
+ return null;
10713
+ return options2.global ? pathConfig.globalPath : pathConfig.projectPath;
10714
+ }
10707
10715
  function getPortableInstallPath(itemName, provider, portableType, options2) {
10708
10716
  const config = providers[provider];
10709
10717
  const pathConfig = config[portableType];
10710
10718
  if (!pathConfig)
10711
10719
  return null;
10712
- const basePath = options2.global ? pathConfig.globalPath : pathConfig.projectPath;
10720
+ const basePath = getPortableBasePath(provider, portableType, options2);
10713
10721
  if (!basePath)
10714
10722
  return null;
10715
10723
  if (pathConfig.writeStrategy === "merge-single" || pathConfig.writeStrategy === "yaml-merge" || pathConfig.writeStrategy === "json-merge" || pathConfig.writeStrategy === "single-file") {
@@ -60747,7 +60755,7 @@ var package_default;
60747
60755
  var init_package = __esm(() => {
60748
60756
  package_default = {
60749
60757
  name: "claudekit-cli",
60750
- version: "3.41.4-dev.41",
60758
+ version: "3.41.4-dev.43",
60751
60759
  description: "CLI tool for bootstrapping and updating ClaudeKit projects",
60752
60760
  type: "module",
60753
60761
  repository: {
@@ -60771,6 +60779,8 @@ var init_package = __esm(() => {
60771
60779
  "tauri:dev": "tauri dev",
60772
60780
  "tauri:build": "tauri build",
60773
60781
  "desktop:validate-config": "bun scripts/validate-desktop-bundle-config.ts",
60782
+ "desktop:sync-version": "bun scripts/sync-desktop-bundle-config.ts",
60783
+ "desktop:check-sync": "bun scripts/sync-desktop-bundle-config.ts --check",
60774
60784
  "desktop:validate-icons": "bun scripts/validate-desktop-icon-source.ts",
60775
60785
  "icons:regen": "./scripts/regen-desktop-icons.sh",
60776
60786
  dev: "bun run src/index.ts",
@@ -60795,7 +60805,7 @@ var init_package = __esm(() => {
60795
60805
  "dev:quick": "./scripts/dev-quick-start.sh",
60796
60806
  "dev:all": "./scripts/dev-quick-start.sh all",
60797
60807
  metrics: "bun run scripts/workflow-metrics.ts",
60798
- validate: "bun run typecheck && bun run lint && bun run desktop:validate-config && bun run desktop:validate-icons && bun test && bun run ui:test && bun run build",
60808
+ validate: "bun run typecheck && bun run lint && bun run desktop:check-sync && bun run desktop:validate-config && bun run desktop:validate-icons && bun test && bun run ui:test && bun run build",
60799
60809
  "install:hooks": "./.githooks/install.sh",
60800
60810
  prepare: `node -e "try{require('child_process').execSync('git rev-parse --git-dir',{stdio:'ignore'});require('child_process').execSync('bash .githooks/install.sh',{stdio:'inherit'})}catch(e){console.warn('[i] Hook install skipped:',e.message)}"`
60801
60811
  },
@@ -71839,7 +71849,7 @@ async function restoreOriginalBranch(branchName, cwd2, issueNumber) {
71839
71849
  }
71840
71850
  }
71841
71851
  function spawnAndCollect(command, args, cwd2) {
71842
- return new Promise((resolve43, reject) => {
71852
+ return new Promise((resolve44, reject) => {
71843
71853
  const child = spawn6(command, args, { ...cwd2 && { cwd: cwd2 }, stdio: ["ignore", "pipe", "pipe"] });
71844
71854
  const chunks = [];
71845
71855
  const stderrChunks = [];
@@ -71852,7 +71862,7 @@ function spawnAndCollect(command, args, cwd2) {
71852
71862
  reject(new Error(`${command} ${args[0] ?? ""} exited with code ${code2}: ${stderr}`));
71853
71863
  return;
71854
71864
  }
71855
- resolve43(Buffer.concat(chunks).toString("utf-8"));
71865
+ resolve44(Buffer.concat(chunks).toString("utf-8"));
71856
71866
  });
71857
71867
  });
71858
71868
  }
@@ -71971,15 +71981,15 @@ function countTwitterChars(text) {
71971
71981
  }
71972
71982
  return count;
71973
71983
  }
71974
- function validateContent(content, platform16) {
71984
+ function validateContent(content, platform17) {
71975
71985
  const issues = [];
71976
71986
  if (!content.text || content.text.trim().length === 0) {
71977
71987
  issues.push("Content text is empty");
71978
71988
  return { valid: false, issues };
71979
71989
  }
71980
- if (platform16 !== "x_thread") {
71981
- const limit = platform16 === "facebook" ? 500 : 280;
71982
- const charCount = platform16 === "x" ? countTwitterChars(content.text) : content.text.length;
71990
+ if (platform17 !== "x_thread") {
71991
+ const limit = platform17 === "facebook" ? 500 : 280;
71992
+ const charCount = platform17 === "x" ? countTwitterChars(content.text) : content.text.length;
71983
71993
  if (charCount > limit) {
71984
71994
  issues.push(`Text exceeds ${limit} char limit (${charCount} weighted chars)`);
71985
71995
  }
@@ -72002,7 +72012,7 @@ function validateContent(content, platform16) {
72002
72012
  issues.push("Hook (first sentence) is too long (>25 words)");
72003
72013
  }
72004
72014
  const hashtagCount = content.hashtags?.length ?? 0;
72005
- if (platform16 === "x" && hashtagCount > 5) {
72015
+ if (platform17 === "x" && hashtagCount > 5) {
72006
72016
  issues.push("Too many hashtags for X (max 5)");
72007
72017
  }
72008
72018
  return { valid: issues.length === 0, issues };
@@ -72039,8 +72049,8 @@ var init_content_validator = __esm(() => {
72039
72049
  import { createHash as createHash8 } from "node:crypto";
72040
72050
  import { existsSync as existsSync73, mkdirSync as mkdirSync5, readFileSync as readFileSync18, readdirSync as readdirSync10, statSync as statSync13 } from "node:fs";
72041
72051
  import { rename as rename12, writeFile as writeFile35 } from "node:fs/promises";
72042
- import { homedir as homedir47 } from "node:os";
72043
- import { basename as basename29, join as join155 } from "node:path";
72052
+ import { homedir as homedir48 } from "node:os";
72053
+ import { basename as basename30, join as join155 } from "node:path";
72044
72054
  function getCachedContext(repoPath) {
72045
72055
  const cachePath = getCacheFilePath(repoPath);
72046
72056
  if (!existsSync73(cachePath))
@@ -72108,13 +72118,13 @@ function getDocSourcePaths(repoPath) {
72108
72118
  return paths.sort();
72109
72119
  }
72110
72120
  function getCacheFilePath(repoPath) {
72111
- const repoName = basename29(repoPath).replace(/[^a-zA-Z0-9_-]/g, "_");
72121
+ const repoName = basename30(repoPath).replace(/[^a-zA-Z0-9_-]/g, "_");
72112
72122
  const pathHash = createHash8("sha256").update(repoPath).digest("hex").slice(0, 8);
72113
72123
  return join155(CACHE_DIR, `${repoName}-${pathHash}-context-cache.json`);
72114
72124
  }
72115
72125
  var CACHE_DIR, CACHE_TTL_MS4;
72116
72126
  var init_context_cache_manager = __esm(() => {
72117
- CACHE_DIR = join155(homedir47(), ".claudekit", "cache");
72127
+ CACHE_DIR = join155(homedir48(), ".claudekit", "cache");
72118
72128
  CACHE_TTL_MS4 = 24 * 60 * 60 * 1000;
72119
72129
  });
72120
72130
 
@@ -72416,10 +72426,10 @@ var MAX_RAW_CONTENT_CHARS = 50000;
72416
72426
  var init_docs_summarizer = () => {};
72417
72427
 
72418
72428
  // src/commands/content/phases/context-builder.ts
72419
- async function buildContentContext(event, repoPath, config, db, platform16, contentLogger) {
72429
+ async function buildContentContext(event, repoPath, config, db, platform17, contentLogger) {
72420
72430
  const cached = getCachedContext(repoPath);
72421
72431
  if (cached) {
72422
- return buildFromCache(cached, event, db, platform16, config);
72432
+ return buildFromCache(cached, event, db, platform17, config);
72423
72433
  }
72424
72434
  const noopLogger = { debug: () => {}, info: () => {}, warn: () => {}, error: () => {} };
72425
72435
  const log2 = contentLogger ?? noopLogger;
@@ -72434,16 +72444,16 @@ async function buildContentContext(event, repoPath, config, db, platform16, cont
72434
72444
  sourceHash: hash
72435
72445
  };
72436
72446
  await saveCachedContext(repoPath, newCache);
72437
- return buildFromCache(newCache, event, db, platform16, config);
72447
+ return buildFromCache(newCache, event, db, platform17, config);
72438
72448
  }
72439
- function buildFromCache(cache5, event, db, platform16, config) {
72449
+ function buildFromCache(cache5, event, db, platform17, config) {
72440
72450
  return {
72441
72451
  brandGuidelines: cache5.brandSummary,
72442
72452
  writingStyles: cache5.stylesSummary,
72443
72453
  gitEventDetails: formatGitEvent(event),
72444
72454
  recentContent: formatRecentContent(db),
72445
72455
  topPerformingContent: "",
72446
- platformRules: getPlatformRules(platform16, config),
72456
+ platformRules: getPlatformRules(platform17, config),
72447
72457
  projectReadme: cache5.readmeSummary,
72448
72458
  projectDocsSummary: cache5.docsSummary,
72449
72459
  currentDateTime: new Date().toISOString()
@@ -72472,8 +72482,8 @@ function formatRecentContent(db) {
72472
72482
  return recent.map((c2) => `[${c2.platform}] ${c2.textContent.slice(0, 100)}`).join(`
72473
72483
  `);
72474
72484
  }
72475
- function getPlatformRules(platform16, config) {
72476
- switch (platform16) {
72485
+ function getPlatformRules(platform17, config) {
72486
+ switch (platform17) {
72477
72487
  case "x":
72478
72488
  return [
72479
72489
  "Platform: X (Twitter)",
@@ -72512,8 +72522,8 @@ var init_context_builder = __esm(() => {
72512
72522
  });
72513
72523
 
72514
72524
  // src/commands/content/phases/prompt-templates.ts
72515
- function buildTextPrompt(context, platform16) {
72516
- const charLimit = platform16 === "x" || platform16 === "x_thread" ? 280 : 500;
72525
+ function buildTextPrompt(context, platform17) {
72526
+ const charLimit = platform17 === "x" || platform17 === "x_thread" ? 280 : 500;
72517
72527
  return `You are a social media content creator.
72518
72528
 
72519
72529
  ## Project Context
@@ -72528,14 +72538,14 @@ ${context.writingStyles}
72528
72538
  ## Content Source
72529
72539
  ${context.gitEventDetails}
72530
72540
 
72531
- ## Platform: ${platform16}
72541
+ ## Platform: ${platform17}
72532
72542
  ${context.platformRules}
72533
72543
 
72534
72544
  ## Past Content (avoid repetition)
72535
72545
  ${context.recentContent}
72536
72546
 
72537
72547
  ## Instructions
72538
- 1. Create a ${platform16} post about this development update
72548
+ 1. Create a ${platform17} post about this development update
72539
72549
  2. Start with a compelling hook that creates curiosity
72540
72550
  3. Keep it conversational and authentic (avoid AI-sounding language)
72541
72551
  4. No generic statements — be specific about what changed and why it matters
@@ -72545,8 +72555,8 @@ ${context.recentContent}
72545
72555
 
72546
72556
  IMPORTANT: Output ONLY the JSON object, nothing else.`;
72547
72557
  }
72548
- function buildPhotoPrompt(context, platform16) {
72549
- const dimensions = platform16 === "facebook" ? "1200x630" : "1200x675";
72558
+ function buildPhotoPrompt(context, platform17) {
72559
+ const dimensions = platform17 === "facebook" ? "1200x630" : "1200x675";
72550
72560
  return `Generate an image for this social media post.
72551
72561
 
72552
72562
  ## Brand Guidelines
@@ -72568,15 +72578,15 @@ IMPORTANT: Generate the image and output the path as JSON: {"imagePath": "/path/
72568
72578
  // src/commands/content/phases/photo-generator.ts
72569
72579
  import { execSync as execSync8 } from "node:child_process";
72570
72580
  import { existsSync as existsSync75, mkdirSync as mkdirSync6, readdirSync as readdirSync12 } from "node:fs";
72571
- import { homedir as homedir48 } from "node:os";
72581
+ import { homedir as homedir49 } from "node:os";
72572
72582
  import { join as join157 } from "node:path";
72573
- async function generatePhoto(_content, context, config, platform16, contentId, contentLogger) {
72574
- const mediaDir = join157(config.contentDir.replace(/^~/, homedir48()), "media", String(contentId));
72583
+ async function generatePhoto(_content, context, config, platform17, contentId, contentLogger) {
72584
+ const mediaDir = join157(config.contentDir.replace(/^~/, homedir49()), "media", String(contentId));
72575
72585
  if (!existsSync75(mediaDir)) {
72576
72586
  mkdirSync6(mediaDir, { recursive: true });
72577
72587
  }
72578
- const prompt = buildPhotoPrompt(context, platform16);
72579
- const dimensions = platform16 === "facebook" ? { width: 1200, height: 630 } : { width: 1200, height: 675 };
72588
+ const prompt = buildPhotoPrompt(context, platform17);
72589
+ const dimensions = platform17 === "facebook" ? { width: 1200, height: 630 } : { width: 1200, height: 675 };
72580
72590
  try {
72581
72591
  contentLogger.debug(`Generating photo for content ${contentId}...`);
72582
72592
  const result = execSync8("claude -p --output-format text --max-turns 40", {
@@ -72614,14 +72624,14 @@ async function createContent(event, config, db, contentLogger, options2) {
72614
72624
  const startTime = Date.now();
72615
72625
  const items = [];
72616
72626
  const platforms = resolveEnabledPlatforms(config);
72617
- for (const platform16 of platforms) {
72627
+ for (const platform17 of platforms) {
72618
72628
  try {
72619
- const item = await createContentForPlatform(event, platform16, config, db, contentLogger, options2);
72629
+ const item = await createContentForPlatform(event, platform17, config, db, contentLogger, options2);
72620
72630
  if (item)
72621
72631
  items.push(item);
72622
72632
  } catch (err) {
72623
72633
  const msg = err instanceof Error ? err.message : String(err);
72624
- contentLogger.error(`Failed to create ${platform16} content: ${msg}`);
72634
+ contentLogger.error(`Failed to create ${platform17} content: ${msg}`);
72625
72635
  }
72626
72636
  }
72627
72637
  insertTaskLog(db, {
@@ -72640,10 +72650,10 @@ function resolveEnabledPlatforms(config) {
72640
72650
  platforms.push("facebook");
72641
72651
  return platforms;
72642
72652
  }
72643
- async function createContentForPlatform(event, platform16, config, db, contentLogger, options2) {
72644
- const context = await buildContentContext(event, event.repoPath, config, db, platform16, contentLogger);
72645
- const prompt = buildTextPrompt(context, platform16);
72646
- contentLogger.debug(`Generating ${platform16} content for event ${event.id}...`);
72653
+ async function createContentForPlatform(event, platform17, config, db, contentLogger, options2) {
72654
+ const context = await buildContentContext(event, event.repoPath, config, db, platform17, contentLogger);
72655
+ const prompt = buildTextPrompt(context, platform17);
72656
+ contentLogger.debug(`Generating ${platform17} content for event ${event.id}...`);
72647
72657
  const stdout2 = execSync9("claude -p --output-format text --max-turns 5", {
72648
72658
  input: prompt,
72649
72659
  stdio: ["pipe", "pipe", "pipe"],
@@ -72651,14 +72661,14 @@ async function createContentForPlatform(event, platform16, config, db, contentLo
72651
72661
  }).toString();
72652
72662
  const parsed = parseClaudeJsonOutput(stdout2);
72653
72663
  const generated = extractContentFromResponse(parsed);
72654
- const validation = validateContent(generated, platform16);
72664
+ const validation = validateContent(generated, platform17);
72655
72665
  if (!validation.valid) {
72656
- contentLogger.warn(`Content validation failed for ${platform16}: ${validation.issues.join(", ")}`);
72666
+ contentLogger.warn(`Content validation failed for ${platform17}: ${validation.issues.join(", ")}`);
72657
72667
  }
72658
72668
  const status = validation.valid ? config.reviewMode === "auto" ? "scheduled" : "reviewing" : "draft";
72659
72669
  const itemId = insertContentItem(db, {
72660
72670
  gitEventId: event.id,
72661
- platform: platform16,
72671
+ platform: platform17,
72662
72672
  textContent: generated.text,
72663
72673
  hashtags: JSON.stringify(generated.hashtags),
72664
72674
  hookLine: generated.hook,
@@ -72668,12 +72678,12 @@ async function createContentForPlatform(event, platform16, config, db, contentLo
72668
72678
  scheduledAt: null
72669
72679
  });
72670
72680
  if (!options2.dryRun && generated.mediaPrompt) {
72671
- const photo = await generatePhoto(generated, context, config, platform16, itemId, contentLogger);
72681
+ const photo = await generatePhoto(generated, context, config, platform17, itemId, contentLogger);
72672
72682
  if (photo) {
72673
72683
  db.prepare("UPDATE content_items SET media_path = ? WHERE id = ?").run(photo.path, itemId);
72674
72684
  }
72675
72685
  }
72676
- contentLogger.info(`Created ${platform16} content (id: ${itemId}, status: ${status})`);
72686
+ contentLogger.info(`Created ${platform17} content (id: ${itemId}, status: ${status})`);
72677
72687
  return getContentById(db, itemId);
72678
72688
  }
72679
72689
  var init_content_creator = __esm(() => {
@@ -72685,7 +72695,7 @@ var init_content_creator = __esm(() => {
72685
72695
 
72686
72696
  // src/commands/content/phases/content-logger.ts
72687
72697
  import { createWriteStream as createWriteStream4, existsSync as existsSync76, mkdirSync as mkdirSync7, statSync as statSync14 } from "node:fs";
72688
- import { homedir as homedir49 } from "node:os";
72698
+ import { homedir as homedir50 } from "node:os";
72689
72699
  import { join as join158 } from "node:path";
72690
72700
 
72691
72701
  class ContentLogger {
@@ -72694,7 +72704,7 @@ class ContentLogger {
72694
72704
  logDir;
72695
72705
  maxBytes;
72696
72706
  constructor(maxBytes = 0) {
72697
- this.logDir = join158(homedir49(), ".claudekit", "logs");
72707
+ this.logDir = join158(homedir50(), ".claudekit", "logs");
72698
72708
  this.maxBytes = maxBytes;
72699
72709
  }
72700
72710
  init() {
@@ -72792,7 +72802,7 @@ var init_sqlite_client = () => {};
72792
72802
 
72793
72803
  // src/commands/content/phases/db-manager.ts
72794
72804
  import { existsSync as existsSync77, mkdirSync as mkdirSync8 } from "node:fs";
72795
- import { dirname as dirname44 } from "node:path";
72805
+ import { dirname as dirname45 } from "node:path";
72796
72806
  function initDatabase(dbPath) {
72797
72807
  ensureParentDir(dbPath);
72798
72808
  const db = openDatabase(dbPath);
@@ -72813,7 +72823,7 @@ function runRetentionCleanup(db, retentionDays = 90) {
72813
72823
  db.prepare("DELETE FROM git_events WHERE processed = 1 AND created_at < ?").run(cutoff);
72814
72824
  }
72815
72825
  function ensureParentDir(dbPath) {
72816
- const dir = dirname44(dbPath);
72826
+ const dir = dirname45(dbPath);
72817
72827
  if (dir && !existsSync77(dir)) {
72818
72828
  mkdirSync8(dir, { recursive: true });
72819
72829
  }
@@ -73560,15 +73570,15 @@ class RateLimiter {
73560
73570
  this.state = state;
73561
73571
  this.config = config;
73562
73572
  }
73563
- canPost(platform16) {
73564
- return this.getTodayCount(platform16) < this.getMaxPerDay(platform16);
73573
+ canPost(platform17) {
73574
+ return this.getTodayCount(platform17) < this.getMaxPerDay(platform17);
73565
73575
  }
73566
- recordPost(platform16) {
73567
- const key = this.dailyKey(platform16);
73576
+ recordPost(platform17) {
73577
+ const key = this.dailyKey(platform17);
73568
73578
  this.state.dailyPostCounts[key] = (this.state.dailyPostCounts[key] ?? 0) + 1;
73569
73579
  }
73570
- getRemainingToday(platform16) {
73571
- return Math.max(0, this.getMaxPerDay(platform16) - this.getTodayCount(platform16));
73580
+ getRemainingToday(platform17) {
73581
+ return Math.max(0, this.getMaxPerDay(platform17) - this.getTodayCount(platform17));
73572
73582
  }
73573
73583
  isInQuietHours() {
73574
73584
  const { timezone, quietHoursStart, quietHoursEnd } = this.config.schedule;
@@ -73588,19 +73598,19 @@ class RateLimiter {
73588
73598
  return false;
73589
73599
  }
73590
73600
  }
73591
- getMaxPerDay(platform16) {
73592
- if (platform16 === "x" || platform16 === "x_thread") {
73601
+ getMaxPerDay(platform17) {
73602
+ if (platform17 === "x" || platform17 === "x_thread") {
73593
73603
  return this.config.platforms.x.maxPostsPerDay;
73594
73604
  }
73595
- if (platform16 === "facebook") {
73605
+ if (platform17 === "facebook") {
73596
73606
  return this.config.platforms.facebook.maxPostsPerDay;
73597
73607
  }
73598
73608
  return this.config.maxContentPerDay;
73599
73609
  }
73600
- getTodayCount(platform16) {
73601
- return this.state.dailyPostCounts[this.dailyKey(platform16)] ?? 0;
73610
+ getTodayCount(platform17) {
73611
+ return this.state.dailyPostCounts[this.dailyKey(platform17)] ?? 0;
73602
73612
  }
73603
- dailyKey(platform16) {
73613
+ dailyKey(platform17) {
73604
73614
  const { timezone } = this.config.schedule;
73605
73615
  let dateStr;
73606
73616
  try {
@@ -73614,7 +73624,7 @@ class RateLimiter {
73614
73624
  } catch {
73615
73625
  dateStr = new Date().toISOString().slice(0, 10);
73616
73626
  }
73617
- return `${platform16}-${dateStr}`;
73627
+ return `${platform17}-${dateStr}`;
73618
73628
  }
73619
73629
  }
73620
73630
 
@@ -73704,9 +73714,9 @@ function previewContent(content) {
73704
73714
  const statusColor = getStatusColor(content.status);
73705
73715
  console.log();
73706
73716
  console.log(`${badge} ${statusColor(content.status.toUpperCase())} ID: ${content.id}`);
73707
- console.log(import_picocolors40.default.dim("─".repeat(60)));
73717
+ console.log(import_picocolors42.default.dim("─".repeat(60)));
73708
73718
  if (content.hookLine) {
73709
- console.log(import_picocolors40.default.bold(import_picocolors40.default.cyan("Hook: ")) + content.hookLine);
73719
+ console.log(import_picocolors42.default.bold(import_picocolors42.default.cyan("Hook: ")) + content.hookLine);
73710
73720
  }
73711
73721
  console.log();
73712
73722
  console.log(content.textContent);
@@ -73715,53 +73725,53 @@ function previewContent(content) {
73715
73725
  try {
73716
73726
  const tags = JSON.parse(content.hashtags);
73717
73727
  if (tags.length > 0) {
73718
- console.log(import_picocolors40.default.dim("Tags: ") + tags.map((t) => import_picocolors40.default.blue(`#${t}`)).join(" "));
73728
+ console.log(import_picocolors42.default.dim("Tags: ") + tags.map((t) => import_picocolors42.default.blue(`#${t}`)).join(" "));
73719
73729
  }
73720
73730
  } catch {}
73721
73731
  }
73722
73732
  if (content.callToAction) {
73723
- console.log(import_picocolors40.default.dim("CTA: ") + content.callToAction);
73733
+ console.log(import_picocolors42.default.dim("CTA: ") + content.callToAction);
73724
73734
  }
73725
73735
  if (content.mediaPath) {
73726
- console.log(import_picocolors40.default.dim("Media: ") + content.mediaPath);
73736
+ console.log(import_picocolors42.default.dim("Media: ") + content.mediaPath);
73727
73737
  }
73728
73738
  if (content.scheduledAt) {
73729
- console.log(import_picocolors40.default.dim("Scheduled: ") + content.scheduledAt);
73739
+ console.log(import_picocolors42.default.dim("Scheduled: ") + content.scheduledAt);
73730
73740
  }
73731
- console.log(import_picocolors40.default.dim("─".repeat(60)));
73741
+ console.log(import_picocolors42.default.dim("─".repeat(60)));
73732
73742
  console.log();
73733
73743
  }
73734
- function getPlatformBadge(platform16) {
73735
- switch (platform16) {
73744
+ function getPlatformBadge(platform17) {
73745
+ switch (platform17) {
73736
73746
  case "x":
73737
- return import_picocolors40.default.bgBlue(import_picocolors40.default.white(" X "));
73747
+ return import_picocolors42.default.bgBlue(import_picocolors42.default.white(" X "));
73738
73748
  case "x_thread":
73739
- return import_picocolors40.default.bgBlue(import_picocolors40.default.white(" X Thread "));
73749
+ return import_picocolors42.default.bgBlue(import_picocolors42.default.white(" X Thread "));
73740
73750
  case "facebook":
73741
- return import_picocolors40.default.bgCyan(import_picocolors40.default.white(" Facebook "));
73751
+ return import_picocolors42.default.bgCyan(import_picocolors42.default.white(" Facebook "));
73742
73752
  default:
73743
- return import_picocolors40.default.bgBlack(import_picocolors40.default.white(` ${platform16} `));
73753
+ return import_picocolors42.default.bgBlack(import_picocolors42.default.white(` ${platform17} `));
73744
73754
  }
73745
73755
  }
73746
73756
  function getStatusColor(status) {
73747
73757
  switch (status) {
73748
73758
  case "published":
73749
- return import_picocolors40.default.green;
73759
+ return import_picocolors42.default.green;
73750
73760
  case "failed":
73751
- return import_picocolors40.default.red;
73761
+ return import_picocolors42.default.red;
73752
73762
  case "reviewing":
73753
- return import_picocolors40.default.yellow;
73763
+ return import_picocolors42.default.yellow;
73754
73764
  case "scheduled":
73755
- return import_picocolors40.default.blue;
73765
+ return import_picocolors42.default.blue;
73756
73766
  case "draft":
73757
- return import_picocolors40.default.gray;
73767
+ return import_picocolors42.default.gray;
73758
73768
  default:
73759
- return import_picocolors40.default.white;
73769
+ return import_picocolors42.default.white;
73760
73770
  }
73761
73771
  }
73762
- var import_picocolors40;
73772
+ var import_picocolors42;
73763
73773
  var init_content_previewer = __esm(() => {
73764
- import_picocolors40 = __toESM(require_picocolors(), 1);
73774
+ import_picocolors42 = __toESM(require_picocolors(), 1);
73765
73775
  });
73766
73776
 
73767
73777
  // src/commands/content/phases/review-manager.ts
@@ -74020,15 +74030,15 @@ async function autoInstallFbcli(contentLogger) {
74020
74030
  contentLogger.warn("go install failed or Go not available");
74021
74031
  }
74022
74032
  try {
74023
- const { platform: platform16, arch: arch3 } = process;
74033
+ const { platform: platform17, arch: arch3 } = process;
74024
74034
  const osMap = { darwin: "darwin", linux: "linux", win32: "windows" };
74025
74035
  const archMap = { arm64: "arm64", x64: "amd64" };
74026
- const os7 = osMap[platform16];
74036
+ const os7 = osMap[platform17];
74027
74037
  const cpu = archMap[arch3];
74028
74038
  if (os7 && cpu) {
74029
- const ext2 = platform16 === "win32" ? ".exe" : "";
74039
+ const ext2 = platform17 === "win32" ? ".exe" : "";
74030
74040
  const url = `https://github.com/mrgoonie/fbcli/releases/latest/download/fbcli_${os7}_${cpu}${ext2}`;
74031
- const dest = platform16 === "win32" ? "fbcli.exe" : "/usr/local/bin/fbcli";
74041
+ const dest = platform17 === "win32" ? "fbcli.exe" : "/usr/local/bin/fbcli";
74032
74042
  f2.warning(`Will download fbcli binary from: ${url}`);
74033
74043
  f2.warning("Note: Binary integrity is not verified. Review the source at https://github.com/mrgoonie/fbcli");
74034
74044
  const consent = await se({ message: `Download and install fbcli to ${dest}?` });
@@ -74112,15 +74122,15 @@ async function autoInstallXurl(contentLogger) {
74112
74122
  contentLogger.warn("go install failed or Go not available");
74113
74123
  }
74114
74124
  try {
74115
- const { platform: platform16, arch: arch3 } = process;
74125
+ const { platform: platform17, arch: arch3 } = process;
74116
74126
  const osMap = { darwin: "darwin", linux: "linux", win32: "windows" };
74117
74127
  const archMap = { arm64: "arm64", x64: "amd64" };
74118
- const os7 = osMap[platform16];
74128
+ const os7 = osMap[platform17];
74119
74129
  const cpu = archMap[arch3];
74120
74130
  if (os7 && cpu) {
74121
- const ext2 = platform16 === "win32" ? ".exe" : "";
74131
+ const ext2 = platform17 === "win32" ? ".exe" : "";
74122
74132
  const url = `https://github.com/xdevplatform/xurl/releases/latest/download/xurl_${os7}_${cpu}${ext2}`;
74123
- const dest = platform16 === "win32" ? "xurl.exe" : "/usr/local/bin/xurl";
74133
+ const dest = platform17 === "win32" ? "xurl.exe" : "/usr/local/bin/xurl";
74124
74134
  f2.info(`Downloading xurl binary for ${os7}/${cpu}...`);
74125
74135
  execSync14(`curl -fsSL "${url}" -o "${dest}" && chmod +x "${dest}"`, {
74126
74136
  stdio: "inherit",
@@ -74172,7 +74182,7 @@ import { existsSync as existsSync79 } from "node:fs";
74172
74182
  import { join as join162 } from "node:path";
74173
74183
  async function runSetupWizard2(cwd2, contentLogger) {
74174
74184
  console.log();
74175
- oe(import_picocolors41.default.bgCyan(import_picocolors41.default.white(" CK Content — Multi-Channel Content Engine ")));
74185
+ oe(import_picocolors43.default.bgCyan(import_picocolors43.default.white(" CK Content — Multi-Channel Content Engine ")));
74176
74186
  f2.info("This wizard will help you set up automated content publishing");
74177
74187
  f2.info(`from your git activity to social media platforms.
74178
74188
  `);
@@ -74231,7 +74241,7 @@ async function showRepoSummary(cwd2) {
74231
74241
  f2.info(`Found ${repos.length} git repo(s) to monitor:`);
74232
74242
  for (const repo of repos) {
74233
74243
  const remote = repo.remoteUrl ? ` (${repo.remoteUrl})` : " (local only)";
74234
- f2.info(` ${import_picocolors41.default.green("●")} ${repo.name}${remote}`);
74244
+ f2.info(` ${import_picocolors43.default.green("●")} ${repo.name}${remote}`);
74235
74245
  }
74236
74246
  }
74237
74247
  function detectBrandAssets(cwd2, contentLogger) {
@@ -74287,29 +74297,29 @@ async function configureReviewMode(config) {
74287
74297
  function printSummary(selectedPlatforms, config) {
74288
74298
  f2.success("Configuration saved!");
74289
74299
  console.log();
74290
- console.log(` ${import_picocolors41.default.dim("Platforms:")} ${selectedPlatforms.join(", ")}`);
74291
- console.log(` ${import_picocolors41.default.dim("Review:")} ${config.reviewMode}`);
74292
- console.log(` ${import_picocolors41.default.dim("Max/day:")} ${config.maxContentPerDay}`);
74293
- console.log(` ${import_picocolors41.default.dim("Timezone:")} ${config.schedule.timezone}`);
74300
+ console.log(` ${import_picocolors43.default.dim("Platforms:")} ${selectedPlatforms.join(", ")}`);
74301
+ console.log(` ${import_picocolors43.default.dim("Review:")} ${config.reviewMode}`);
74302
+ console.log(` ${import_picocolors43.default.dim("Max/day:")} ${config.maxContentPerDay}`);
74303
+ console.log(` ${import_picocolors43.default.dim("Timezone:")} ${config.schedule.timezone}`);
74294
74304
  console.log();
74295
74305
  }
74296
- var import_picocolors41;
74306
+ var import_picocolors43;
74297
74307
  var init_setup_wizard = __esm(() => {
74298
74308
  init_dist2();
74299
74309
  init_platform_setup_facebook();
74300
74310
  init_platform_setup_x();
74301
74311
  init_repo_discoverer();
74302
74312
  init_state_manager();
74303
- import_picocolors41 = __toESM(require_picocolors(), 1);
74313
+ import_picocolors43 = __toESM(require_picocolors(), 1);
74304
74314
  });
74305
74315
 
74306
74316
  // src/commands/content/content-review-commands.ts
74307
74317
  import { existsSync as existsSync80 } from "node:fs";
74308
- import { homedir as homedir50 } from "node:os";
74318
+ import { homedir as homedir51 } from "node:os";
74309
74319
  async function queueContent() {
74310
74320
  const cwd2 = process.cwd();
74311
74321
  const config = await loadContentConfig(cwd2);
74312
- const dbPath = config.dbPath.replace(/^~/, homedir50());
74322
+ const dbPath = config.dbPath.replace(/^~/, homedir51());
74313
74323
  if (!existsSync80(dbPath)) {
74314
74324
  logger.info("No content database found. Run 'ck content setup' first.");
74315
74325
  return;
@@ -74336,7 +74346,7 @@ async function queueContent() {
74336
74346
  async function approveContentCmd(id) {
74337
74347
  const cwd2 = process.cwd();
74338
74348
  const config = await loadContentConfig(cwd2);
74339
- const dbPath = config.dbPath.replace(/^~/, homedir50());
74349
+ const dbPath = config.dbPath.replace(/^~/, homedir51());
74340
74350
  const db = initDatabase(dbPath);
74341
74351
  try {
74342
74352
  approveContent(db, Number.parseInt(id, 10));
@@ -74348,7 +74358,7 @@ async function approveContentCmd(id) {
74348
74358
  async function rejectContentCmd(id, reason) {
74349
74359
  const cwd2 = process.cwd();
74350
74360
  const config = await loadContentConfig(cwd2);
74351
- const dbPath = config.dbPath.replace(/^~/, homedir50());
74361
+ const dbPath = config.dbPath.replace(/^~/, homedir51());
74352
74362
  const db = initDatabase(dbPath);
74353
74363
  try {
74354
74364
  rejectContent(db, Number.parseInt(id, 10), reason);
@@ -74379,7 +74389,7 @@ __export(exports_content_subcommands, {
74379
74389
  approveContentCmd: () => approveContentCmd
74380
74390
  });
74381
74391
  import { existsSync as existsSync81, readFileSync as readFileSync21, unlinkSync as unlinkSync6 } from "node:fs";
74382
- import { homedir as homedir51 } from "node:os";
74392
+ import { homedir as homedir52 } from "node:os";
74383
74393
  import { join as join163 } from "node:path";
74384
74394
  function isDaemonRunning() {
74385
74395
  const lockFile = join163(LOCK_DIR, `${LOCK_NAME2}.lock`);
@@ -74453,7 +74463,7 @@ async function statusContent() {
74453
74463
  } catch {}
74454
74464
  }
74455
74465
  async function logsContent(options2) {
74456
- const logDir = join163(homedir51(), ".claudekit", "logs");
74466
+ const logDir = join163(homedir52(), ".claudekit", "logs");
74457
74467
  const dateStr = new Date().toISOString().slice(0, 10).replace(/-/g, "");
74458
74468
  const logPath = join163(logDir, `content-${dateStr}.log`);
74459
74469
  if (!existsSync81(logPath)) {
@@ -74487,12 +74497,12 @@ var init_content_subcommands = __esm(() => {
74487
74497
  init_setup_wizard();
74488
74498
  init_state_manager();
74489
74499
  init_content_review_commands();
74490
- LOCK_DIR = join163(homedir51(), ".claudekit", "locks");
74500
+ LOCK_DIR = join163(homedir52(), ".claudekit", "locks");
74491
74501
  });
74492
74502
 
74493
74503
  // src/commands/content/content-command.ts
74494
74504
  import { existsSync as existsSync82, mkdirSync as mkdirSync9, unlinkSync as unlinkSync7, writeFileSync as writeFileSync7 } from "node:fs";
74495
- import { homedir as homedir52 } from "node:os";
74505
+ import { homedir as homedir53 } from "node:os";
74496
74506
  import { join as join164 } from "node:path";
74497
74507
  async function contentCommand(options2) {
74498
74508
  const cwd2 = process.cwd();
@@ -74525,7 +74535,7 @@ async function contentCommand(options2) {
74525
74535
  if (!existsSync82(LOCK_DIR2))
74526
74536
  mkdirSync9(LOCK_DIR2, { recursive: true });
74527
74537
  writeFileSync7(LOCK_FILE, String(process.pid), "utf-8");
74528
- const dbPath = config.dbPath.replace(/^~/, homedir52());
74538
+ const dbPath = config.dbPath.replace(/^~/, homedir53());
74529
74539
  const db = initDatabase(dbPath);
74530
74540
  contentLogger.info(`Database initialised at ${dbPath}`);
74531
74541
  const adapters = initializeAdapters(config);
@@ -74654,8 +74664,8 @@ function shouldRunCleanup(lastAt) {
74654
74664
  return Date.now() - new Date(lastAt).getTime() >= 86400000;
74655
74665
  }
74656
74666
  function sleep2(ms) {
74657
- return new Promise((resolve43) => {
74658
- setTimeout(resolve43, ms);
74667
+ return new Promise((resolve44) => {
74668
+ setTimeout(resolve44, ms);
74659
74669
  });
74660
74670
  }
74661
74671
  var LOCK_DIR2, LOCK_FILE, MAX_CREATION_RETRIES = 3, MAX_PUBLISH_RETRIES_PER_CYCLE = 3, PUBLISH_RETRY_WINDOW_HOURS = 24;
@@ -74671,7 +74681,7 @@ var init_content_command = __esm(() => {
74671
74681
  init_publisher();
74672
74682
  init_review_manager();
74673
74683
  init_state_manager();
74674
- LOCK_DIR2 = join164(homedir52(), ".claudekit", "locks");
74684
+ LOCK_DIR2 = join164(homedir53(), ".claudekit", "locks");
74675
74685
  LOCK_FILE = join164(LOCK_DIR2, "ck-content.lock");
74676
74686
  });
74677
74687
 
@@ -75844,20 +75854,20 @@ var migrateCommandHelp;
75844
75854
  var init_migrate_command_help = __esm(() => {
75845
75855
  migrateCommandHelp = {
75846
75856
  name: "migrate",
75847
- description: "Migrate agents, commands, skills, config, rules, and hooks to other providers",
75857
+ description: "Migrate Claude Code agents, commands, skills, config, rules, and hooks to other providers",
75848
75858
  usage: "ck migrate [options]",
75849
75859
  examples: [
75850
75860
  {
75851
- command: "ck migrate --agent opencode",
75852
- description: "Migrate OpenCode-native items while reusing Claude-compatible skill roots"
75861
+ command: "ck migrate --agent codex --dry-run",
75862
+ description: "Preview the destination-aware migration plan before writing files"
75853
75863
  },
75854
75864
  {
75855
- command: "ck migrate --agent droid --agent codex",
75856
- description: "Migrate to specific providers"
75865
+ command: "ck migrate --agent codex -g",
75866
+ description: "Write to Codex global paths such as ~/.codex/ and ~/.agents/skills"
75857
75867
  },
75858
75868
  {
75859
- command: "ck migrate --dry-run",
75860
- description: "Preview migration plan without writing files"
75869
+ command: "CK_FORCE_ASCII=1 ck migrate --agent codex",
75870
+ description: "Force ASCII borders on legacy Windows terminals (cmd.exe, older PowerShell)"
75861
75871
  }
75862
75872
  ],
75863
75873
  optionGroups: [
@@ -75874,19 +75884,19 @@ var init_migrate_command_help = __esm(() => {
75874
75884
  },
75875
75885
  {
75876
75886
  flags: "-g, --global",
75877
- description: "Install globally instead of project-level"
75887
+ description: "Install globally instead of the default project-level scope"
75878
75888
  },
75879
75889
  {
75880
75890
  flags: "-y, --yes",
75881
- description: "Skip confirmation prompts"
75891
+ description: "Skip confirmation prompts after the pre-flight summary"
75882
75892
  },
75883
75893
  {
75884
75894
  flags: "-f, --force",
75885
- description: "Force reinstall deleted/edited items"
75895
+ description: "Force reinstall deleted or edited managed items"
75886
75896
  },
75887
75897
  {
75888
75898
  flags: "--dry-run",
75889
- description: "Preview plan without writing files"
75899
+ description: "Preview plan, destinations, and next steps without writing files"
75890
75900
  }
75891
75901
  ]
75892
75902
  },
@@ -76030,22 +76040,22 @@ function padEnd(text, width) {
76030
76040
  const padding = Math.max(0, width - visibleLength);
76031
76041
  return text + " ".repeat(padding);
76032
76042
  }
76033
- var import_picocolors45, NO_COLOR, isColorSupported, identity = (text) => text, colors, defaultTheme;
76043
+ var import_picocolors47, NO_COLOR, isColorSupported, identity = (text) => text, colors, defaultTheme;
76034
76044
  var init_help_colors = __esm(() => {
76035
- import_picocolors45 = __toESM(require_picocolors(), 1);
76045
+ import_picocolors47 = __toESM(require_picocolors(), 1);
76036
76046
  NO_COLOR = process.env.NO_COLOR !== undefined;
76037
76047
  isColorSupported = !NO_COLOR && Boolean(process.stdout.isTTY);
76038
76048
  colors = {
76039
- banner: isColorSupported ? import_picocolors45.default.cyan : identity,
76040
- command: isColorSupported ? import_picocolors45.default.bold : identity,
76041
- heading: isColorSupported ? import_picocolors45.default.yellow : identity,
76042
- flag: isColorSupported ? import_picocolors45.default.green : identity,
76043
- description: isColorSupported ? import_picocolors45.default.gray : identity,
76044
- example: isColorSupported ? import_picocolors45.default.blue : identity,
76045
- warning: isColorSupported ? import_picocolors45.default.yellow : identity,
76046
- error: isColorSupported ? import_picocolors45.default.red : identity,
76047
- muted: isColorSupported ? import_picocolors45.default.dim : identity,
76048
- success: isColorSupported ? import_picocolors45.default.green : identity
76049
+ banner: isColorSupported ? import_picocolors47.default.cyan : identity,
76050
+ command: isColorSupported ? import_picocolors47.default.bold : identity,
76051
+ heading: isColorSupported ? import_picocolors47.default.yellow : identity,
76052
+ flag: isColorSupported ? import_picocolors47.default.green : identity,
76053
+ description: isColorSupported ? import_picocolors47.default.gray : identity,
76054
+ example: isColorSupported ? import_picocolors47.default.blue : identity,
76055
+ warning: isColorSupported ? import_picocolors47.default.yellow : identity,
76056
+ error: isColorSupported ? import_picocolors47.default.red : identity,
76057
+ muted: isColorSupported ? import_picocolors47.default.dim : identity,
76058
+ success: isColorSupported ? import_picocolors47.default.green : identity
76049
76059
  };
76050
76060
  defaultTheme = {
76051
76061
  banner: colors.banner,
@@ -76093,7 +76103,7 @@ function getPagerArgs(pagerCmd) {
76093
76103
  return [];
76094
76104
  }
76095
76105
  async function trySystemPager(content) {
76096
- return new Promise((resolve43) => {
76106
+ return new Promise((resolve44) => {
76097
76107
  const pagerCmd = process.env.PAGER || "less";
76098
76108
  const pagerArgs = getPagerArgs(pagerCmd);
76099
76109
  try {
@@ -76103,20 +76113,20 @@ async function trySystemPager(content) {
76103
76113
  });
76104
76114
  const timeout2 = setTimeout(() => {
76105
76115
  pager.kill();
76106
- resolve43(false);
76116
+ resolve44(false);
76107
76117
  }, 30000);
76108
76118
  pager.stdin.write(content);
76109
76119
  pager.stdin.end();
76110
76120
  pager.on("close", (code2) => {
76111
76121
  clearTimeout(timeout2);
76112
- resolve43(code2 === 0);
76122
+ resolve44(code2 === 0);
76113
76123
  });
76114
76124
  pager.on("error", () => {
76115
76125
  clearTimeout(timeout2);
76116
- resolve43(false);
76126
+ resolve44(false);
76117
76127
  });
76118
76128
  } catch {
76119
- resolve43(false);
76129
+ resolve44(false);
76120
76130
  }
76121
76131
  });
76122
76132
  }
@@ -76143,16 +76153,16 @@ async function basicPager(content) {
76143
76153
  break;
76144
76154
  }
76145
76155
  const remaining = lines.length - currentLine;
76146
- await new Promise((resolve43) => {
76156
+ await new Promise((resolve44) => {
76147
76157
  rl.question(`-- More (${remaining} lines) [Enter/q] --`, (answer) => {
76148
76158
  if (answer.toLowerCase() === "q") {
76149
76159
  rl.close();
76150
76160
  process.exitCode = 0;
76151
- resolve43();
76161
+ resolve44();
76152
76162
  return;
76153
76163
  }
76154
76164
  process.stdout.write("\x1B[1A\x1B[2K");
76155
- resolve43();
76165
+ resolve44();
76156
76166
  });
76157
76167
  });
76158
76168
  }
@@ -76348,7 +76358,7 @@ var init_help_renderer = __esm(() => {
76348
76358
  DEFAULT_HELP_OPTIONS = {
76349
76359
  showBanner: true,
76350
76360
  showExamples: true,
76351
- maxExamples: 2,
76361
+ maxExamples: 3,
76352
76362
  interactive: false,
76353
76363
  width: process.stdout.columns || 80,
76354
76364
  theme: defaultTheme,
@@ -76370,7 +76380,7 @@ function getHelpOptions() {
76370
76380
  ...DEFAULT_HELP_OPTIONS,
76371
76381
  showBanner: isTTY2,
76372
76382
  showExamples: true,
76373
- maxExamples: 2,
76383
+ maxExamples: 3,
76374
76384
  interactive: isTTY2,
76375
76385
  width,
76376
76386
  noColor
@@ -79254,6 +79264,20 @@ import { join as join66 } from "node:path";
79254
79264
  function escapeRegExp2(value) {
79255
79265
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
79256
79266
  }
79267
+ var MAC_BUNDLE_VERSION_PATTERN = /<key>\s*CFBundleShortVersionString\s*<\/key>\s*<string>([^<]+)<\/string>/;
79268
+ async function readInstalledDesktopArtifactVersion(binaryPath, options2 = {}) {
79269
+ const platform7 = options2.platform || process.platform;
79270
+ if (platform7 !== "darwin") {
79271
+ return null;
79272
+ }
79273
+ const readFileFn = options2.readFileFn || readFile37;
79274
+ try {
79275
+ const infoPlist = await readFileFn(join66(binaryPath, "Contents", "Info.plist"), "utf8");
79276
+ return infoPlist.match(MAC_BUNDLE_VERSION_PATTERN)?.[1] ?? null;
79277
+ } catch {
79278
+ return null;
79279
+ }
79280
+ }
79257
79281
  async function validateInstalledDesktopArtifact(binaryPath, metadata, options2 = {}) {
79258
79282
  const platform7 = options2.platform || process.platform;
79259
79283
  const readFileFn = options2.readFileFn || readFile37;
@@ -79264,9 +79288,15 @@ async function validateInstalledDesktopArtifact(binaryPath, metadata, options2 =
79264
79288
  return fileStat.isFile() && fileStat.size === metadata.assetSize;
79265
79289
  }
79266
79290
  if (platform7 === "darwin") {
79267
- const infoPlist = await readFileFn(join66(binaryPath, "Contents", "Info.plist"), "utf8");
79268
- const versionPattern = new RegExp(`<key>\\s*CFBundleShortVersionString\\s*</key>\\s*<string>${escapeRegExp2(metadata.version)}</string>`);
79269
- return versionPattern.test(infoPlist);
79291
+ const installedVersion = await readInstalledDesktopArtifactVersion(binaryPath, {
79292
+ platform: platform7,
79293
+ readFileFn
79294
+ });
79295
+ if (!installedVersion) {
79296
+ return false;
79297
+ }
79298
+ const versionPattern = new RegExp(`^${escapeRegExp2(metadata.version)}$`);
79299
+ return versionPattern.test(installedVersion);
79270
79300
  }
79271
79301
  } catch {
79272
79302
  return false;
@@ -79283,16 +79313,28 @@ import { promisify as promisify9 } from "node:util";
79283
79313
  init_logger();
79284
79314
  var import_fs_extra7 = __toESM(require_lib3(), 1);
79285
79315
  var execFileAsync5 = promisify9(execFile8);
79286
- async function persistInstallMetadataAfterSuccess(downloadPath, readDownloadedMetadataFn, persistInstallMetadataFn) {
79316
+ async function persistInstallMetadataAfterSuccess(downloadPath, targetPath, platform7, readDownloadedMetadataFn, validateInstalledArtifactFn, persistInstallMetadataFn) {
79317
+ const metadata = await readDownloadedMetadataFn(downloadPath);
79318
+ if (!metadata) {
79319
+ return;
79320
+ }
79321
+ const isValid2 = await validateInstalledArtifactFn(targetPath, metadata, { platform: platform7 });
79322
+ if (!isValid2) {
79323
+ throw new Error(`Installed desktop artifact at ${targetPath} failed validation for release ${metadata.version}`);
79324
+ }
79287
79325
  try {
79288
- const metadata = await readDownloadedMetadataFn(downloadPath);
79289
- if (metadata) {
79290
- await persistInstallMetadataFn(metadata);
79291
- }
79326
+ await persistInstallMetadataFn(metadata);
79292
79327
  } catch (error) {
79293
79328
  logger.warning(`Desktop install succeeded, but failed to persist install metadata: ${error instanceof Error ? error.message : String(error)}`);
79294
79329
  }
79295
79330
  }
79331
+ async function removeBackupInstallPathAfterSuccess(backupInstallPath) {
79332
+ try {
79333
+ await import_fs_extra7.remove(backupInstallPath);
79334
+ } catch (error) {
79335
+ logger.warning(`Desktop install succeeded, but failed to remove backup install at ${backupInstallPath}: ${error instanceof Error ? error.message : String(error)}`);
79336
+ }
79337
+ }
79296
79338
  async function findAppBundle(rootDir) {
79297
79339
  const entries = await readdir16(rootDir, { withFileTypes: true });
79298
79340
  for (const entry of entries) {
@@ -79312,6 +79354,7 @@ async function installDesktopBinary(downloadPath, options2 = {}) {
79312
79354
  const platform7 = options2.platform || process.platform;
79313
79355
  const targetPath = getDesktopInstallPath({ platform: platform7 });
79314
79356
  const readDownloadedMetadataFn = options2.readDownloadedMetadataFn || readDownloadedDesktopMetadata;
79357
+ const validateInstalledArtifactFn = options2.validateInstalledArtifactFn || validateInstalledDesktopArtifact;
79315
79358
  const persistInstallMetadataFn = options2.persistInstallMetadataFn || ((metadata) => writeDesktopInstallMetadata(metadata, { platform: platform7 }));
79316
79359
  await import_fs_extra7.ensureDir(getDesktopInstallDirectory({ platform: platform7 }));
79317
79360
  if (platform7 === "darwin") {
@@ -79325,6 +79368,7 @@ async function installDesktopBinary(downloadPath, options2 = {}) {
79325
79368
  const stagingDir = await mkdtemp(join67(tmpdir(), "ck-desktop-app-"));
79326
79369
  const stagedInstallPath = join67(dirname24(targetPath), `${basename19(targetPath)}.new`);
79327
79370
  const backupInstallPath = join67(dirname24(targetPath), `${basename19(targetPath)}.backup`);
79371
+ let swappedInstall = false;
79328
79372
  try {
79329
79373
  await extractZipFn(downloadPath, { dir: stagingDir });
79330
79374
  const appBundlePath = await findAppBundle(stagingDir);
@@ -79336,28 +79380,70 @@ async function installDesktopBinary(downloadPath, options2 = {}) {
79336
79380
  await rename7(targetPath, backupInstallPath);
79337
79381
  }
79338
79382
  await rename7(stagedInstallPath, targetPath);
79339
- await import_fs_extra7.remove(backupInstallPath);
79383
+ swappedInstall = true;
79384
+ await persistInstallMetadataAfterSuccess(downloadPath, targetPath, platform7, readDownloadedMetadataFn, validateInstalledArtifactFn, persistInstallMetadataFn);
79385
+ await removeBackupInstallPathAfterSuccess(backupInstallPath);
79340
79386
  } catch (error) {
79341
- if (await import_fs_extra7.pathExists(backupInstallPath) && !await import_fs_extra7.pathExists(targetPath)) {
79387
+ if (await import_fs_extra7.pathExists(backupInstallPath)) {
79388
+ if (await import_fs_extra7.pathExists(targetPath)) {
79389
+ await import_fs_extra7.remove(targetPath);
79390
+ }
79342
79391
  await rename7(backupInstallPath, targetPath);
79392
+ } else if (swappedInstall && await import_fs_extra7.pathExists(targetPath)) {
79393
+ await import_fs_extra7.remove(targetPath);
79343
79394
  }
79344
79395
  throw error;
79345
79396
  } finally {
79346
79397
  await import_fs_extra7.remove(stagingDir);
79347
79398
  await import_fs_extra7.remove(stagedInstallPath);
79348
79399
  }
79349
- await persistInstallMetadataAfterSuccess(downloadPath, readDownloadedMetadataFn, persistInstallMetadataFn);
79350
79400
  return targetPath;
79351
79401
  }
79352
79402
  if (platform7 === "linux") {
79353
- await import_fs_extra7.copyFile(downloadPath, targetPath);
79354
- await chmod3(targetPath, 493);
79355
- await persistInstallMetadataAfterSuccess(downloadPath, readDownloadedMetadataFn, persistInstallMetadataFn);
79403
+ const backupInstallPath = join67(dirname24(targetPath), `${basename19(targetPath)}.backup`);
79404
+ try {
79405
+ await import_fs_extra7.remove(backupInstallPath);
79406
+ if (await import_fs_extra7.pathExists(targetPath)) {
79407
+ await rename7(targetPath, backupInstallPath);
79408
+ }
79409
+ await import_fs_extra7.copyFile(downloadPath, targetPath);
79410
+ await chmod3(targetPath, 493);
79411
+ await persistInstallMetadataAfterSuccess(downloadPath, targetPath, platform7, readDownloadedMetadataFn, validateInstalledArtifactFn, persistInstallMetadataFn);
79412
+ await removeBackupInstallPathAfterSuccess(backupInstallPath);
79413
+ } catch (error) {
79414
+ if (await import_fs_extra7.pathExists(backupInstallPath)) {
79415
+ if (await import_fs_extra7.pathExists(targetPath)) {
79416
+ await import_fs_extra7.remove(targetPath);
79417
+ }
79418
+ await rename7(backupInstallPath, targetPath);
79419
+ } else if (await import_fs_extra7.pathExists(targetPath)) {
79420
+ await import_fs_extra7.remove(targetPath);
79421
+ }
79422
+ throw error;
79423
+ }
79356
79424
  return targetPath;
79357
79425
  }
79358
79426
  if (platform7 === "win32") {
79359
- await import_fs_extra7.copyFile(downloadPath, targetPath);
79360
- await persistInstallMetadataAfterSuccess(downloadPath, readDownloadedMetadataFn, persistInstallMetadataFn);
79427
+ const backupInstallPath = join67(dirname24(targetPath), `${basename19(targetPath)}.backup`);
79428
+ try {
79429
+ await import_fs_extra7.remove(backupInstallPath);
79430
+ if (await import_fs_extra7.pathExists(targetPath)) {
79431
+ await rename7(targetPath, backupInstallPath);
79432
+ }
79433
+ await import_fs_extra7.copyFile(downloadPath, targetPath);
79434
+ await persistInstallMetadataAfterSuccess(downloadPath, targetPath, platform7, readDownloadedMetadataFn, validateInstalledArtifactFn, persistInstallMetadataFn);
79435
+ await removeBackupInstallPathAfterSuccess(backupInstallPath);
79436
+ } catch (error) {
79437
+ if (await import_fs_extra7.pathExists(backupInstallPath)) {
79438
+ if (await import_fs_extra7.pathExists(targetPath)) {
79439
+ await import_fs_extra7.remove(targetPath);
79440
+ }
79441
+ await rename7(backupInstallPath, targetPath);
79442
+ } else if (await import_fs_extra7.pathExists(targetPath)) {
79443
+ await import_fs_extra7.remove(targetPath);
79444
+ }
79445
+ throw error;
79446
+ }
79361
79447
  return targetPath;
79362
79448
  }
79363
79449
  throw new Error(`Unsupported install platform: ${platform7}`);
@@ -79776,11 +79862,48 @@ async function resolveDesktopReleaseAsset(version, options2) {
79776
79862
  platformKey
79777
79863
  };
79778
79864
  }
79865
+ async function getDesktopInstallHealth(options2 = {}) {
79866
+ const readInstallMetadata = options2.readInstallMetadata || readDesktopInstallMetadata;
79867
+ const validateInstalledArtifact = options2.validateInstalledArtifact || validateInstalledDesktopArtifact;
79868
+ const readInstalledArtifactVersion = options2.readInstalledArtifactVersion || readInstalledDesktopArtifactVersion;
79869
+ const installed = await readInstallMetadata({ platform: options2.platform });
79870
+ if (!installed) {
79871
+ return {
79872
+ currentVersion: null,
79873
+ healthy: false,
79874
+ reason: "missing-metadata"
79875
+ };
79876
+ }
79877
+ const binaryPath = options2.binaryPath || getDesktopBinaryPath({ platform: options2.platform });
79878
+ if (!binaryPath) {
79879
+ return {
79880
+ currentVersion: installed.version,
79881
+ healthy: false,
79882
+ reason: "missing-binary"
79883
+ };
79884
+ }
79885
+ if (!await validateInstalledArtifact(binaryPath, installed, { platform: options2.platform })) {
79886
+ const installedArtifactVersion = await readInstalledArtifactVersion(binaryPath, {
79887
+ platform: options2.platform
79888
+ });
79889
+ return {
79890
+ currentVersion: installedArtifactVersion || installed.version,
79891
+ healthy: false,
79892
+ reason: "artifact-invalid"
79893
+ };
79894
+ }
79895
+ return {
79896
+ currentVersion: installed.version,
79897
+ healthy: true,
79898
+ reason: "healthy"
79899
+ };
79900
+ }
79779
79901
  async function getDesktopUpdateStatus(options2 = {}) {
79780
79902
  const { manifest, entry, platformKey } = await resolveDesktopReleaseAsset(undefined, options2);
79781
79903
  const latestVersion = normalizeVersion(manifest.version);
79782
79904
  const readInstallMetadata = options2.readInstallMetadata || readDesktopInstallMetadata;
79783
79905
  const validateInstalledArtifact = options2.validateInstalledArtifact || validateInstalledDesktopArtifact;
79906
+ const readInstalledArtifactVersion = options2.readInstalledArtifactVersion || readInstalledDesktopArtifactVersion;
79784
79907
  const installed = await readInstallMetadata({ platform: options2.platform });
79785
79908
  const requestedChannel = options2.channel ?? "stable";
79786
79909
  if (!installed) {
@@ -79797,19 +79920,32 @@ async function getDesktopUpdateStatus(options2 = {}) {
79797
79920
  currentVersion: installed.version,
79798
79921
  latestVersion,
79799
79922
  updateAvailable: true,
79800
- reason: "unknown-installed-version"
79923
+ reason: "missing-binary"
79801
79924
  };
79802
79925
  }
79926
+ const sameChannel = installed.channel === requestedChannel;
79927
+ const samePlatform = installed.platformKey === platformKey;
79803
79928
  if (!await validateInstalledArtifact(binaryPath, installed, { platform: options2.platform })) {
79929
+ const installedArtifactVersion = await readInstalledArtifactVersion(binaryPath, {
79930
+ platform: options2.platform
79931
+ });
79932
+ const currentVersion = installedArtifactVersion || installed.version;
79933
+ const installedArtifactIsNewer = sameChannel && samePlatform && isNewerVersion(latestVersion, currentVersion);
79934
+ if (installedArtifactIsNewer) {
79935
+ return {
79936
+ currentVersion,
79937
+ latestVersion,
79938
+ updateAvailable: false,
79939
+ reason: "installed-newer"
79940
+ };
79941
+ }
79804
79942
  return {
79805
- currentVersion: installed.version,
79943
+ currentVersion,
79806
79944
  latestVersion,
79807
79945
  updateAvailable: true,
79808
79946
  reason: "update-available"
79809
79947
  };
79810
79948
  }
79811
- const sameChannel = installed.channel === requestedChannel;
79812
- const samePlatform = installed.platformKey === platformKey;
79813
79949
  const metadataMatchesRelease = sameChannel && installed.platformKey === platformKey && installed.assetName === entry.name && installed.assetSize === entry.size && installed.manifestDate === manifest.date;
79814
79950
  const installedIsNewer = sameChannel && samePlatform && isNewerVersion(latestVersion, installed.version);
79815
79951
  if (installedIsNewer) {
@@ -79902,6 +80038,7 @@ async function appCommand(options2 = {}, deps = {}) {
79902
80038
  const launchWeb = deps.launchWeb || configUICommand;
79903
80039
  const getBinaryPath = deps.getBinaryPath || getDesktopBinaryPath;
79904
80040
  const getInstallPath2 = deps.getInstallPath || getDesktopInstallPath;
80041
+ const getInstallHealth = deps.getInstallHealth || getDesktopInstallHealth;
79905
80042
  const getUpdateStatus = deps.getUpdateStatus || getDesktopUpdateStatus;
79906
80043
  const downloadBinary = deps.downloadBinary || ((opts) => downloadDesktopBinary(undefined, { channel: opts?.channel }));
79907
80044
  const installBinary = deps.installBinary || installDesktopBinary;
@@ -79910,6 +80047,7 @@ async function appCommand(options2 = {}, deps = {}) {
79910
80047
  const info = deps.info || output.info.bind(output);
79911
80048
  const success = deps.success || output.success.bind(output);
79912
80049
  const printLine = deps.printLine || console.log;
80050
+ let repairingInstall = false;
79913
80051
  if (options2.web) {
79914
80052
  info("Opening ClaudeKit web dashboard...");
79915
80053
  await launchWeb();
@@ -79934,9 +80072,20 @@ async function appCommand(options2 = {}, deps = {}) {
79934
80072
  }
79935
80073
  const existingBinary = getBinaryPath();
79936
80074
  if (existingBinary && !options2.update) {
79937
- success("Launching ClaudeKit Control Center...");
79938
- launchBinary(existingBinary);
79939
- return;
80075
+ try {
80076
+ const installHealth = await getInstallHealth({ binaryPath: existingBinary });
80077
+ if (installHealth.healthy || installHealth.reason === "missing-metadata") {
80078
+ success("Launching ClaudeKit Control Center...");
80079
+ launchBinary(existingBinary);
80080
+ return;
80081
+ }
80082
+ info(installHealth.currentVersion ? `Installed ClaudeKit Control Center build (${installHealth.currentVersion}) needs repair. Downloading the latest build...` : "Installed ClaudeKit Control Center needs repair. Downloading the latest build...");
80083
+ repairingInstall = true;
80084
+ } catch {
80085
+ success("Launching ClaudeKit Control Center...");
80086
+ launchBinary(existingBinary);
80087
+ return;
80088
+ }
79940
80089
  }
79941
80090
  if (options2.update && existingBinary) {
79942
80091
  const updateStatus = await getUpdateStatus({ channel, binaryPath: existingBinary });
@@ -79947,7 +80096,11 @@ async function appCommand(options2 = {}, deps = {}) {
79947
80096
  return;
79948
80097
  }
79949
80098
  }
79950
- info(options2.update ? "Downloading and installing the latest ClaudeKit Control Center build..." : "ClaudeKit Control Center not found. Downloading...");
80099
+ if (options2.update) {
80100
+ info("Downloading and installing the latest ClaudeKit Control Center build...");
80101
+ } else if (!repairingInstall) {
80102
+ info("ClaudeKit Control Center not found. Downloading...");
80103
+ }
79951
80104
  const downloadedBinary = await downloadBinary({ channel });
79952
80105
  const installedBinary = await installBinary(downloadedBinary);
79953
80106
  success(`Installed ClaudeKit Control Center to ${installedBinary}`);
@@ -103991,12 +104144,326 @@ async function initCommand(options2) {
103991
104144
  }
103992
104145
  // src/commands/migrate/migrate-command.ts
103993
104146
  init_dist2();
103994
- var import_picocolors28 = __toESM(require_picocolors(), 1);
104147
+ var import_picocolors30 = __toESM(require_picocolors(), 1);
103995
104148
  import { existsSync as existsSync62 } from "node:fs";
103996
104149
  import { readFile as readFile59, rm as rm15, unlink as unlink12 } from "node:fs/promises";
103997
- import { homedir as homedir45 } from "node:os";
103998
- import { basename as basename25, join as join139, resolve as resolve35 } from "node:path";
104150
+ import { homedir as homedir46 } from "node:os";
104151
+ import { basename as basename26, join as join139, resolve as resolve36 } from "node:path";
103999
104152
  init_logger();
104153
+
104154
+ // src/ui/ck-cli-design/tokens.ts
104155
+ var import_picocolors27 = __toESM(require_picocolors(), 1);
104156
+ import { homedir as homedir45, platform as platform16 } from "node:os";
104157
+ import { resolve as resolve35, win32 as win323 } from "node:path";
104158
+ var PANEL_MIN_WIDTH = 60;
104159
+ var PANEL_MAX_WIDTH = 72;
104160
+ var DEFAULT_WIDTH = PANEL_MAX_WIDTH;
104161
+ var UNICODE_BOX = {
104162
+ tl: "╔",
104163
+ tr: "╗",
104164
+ bl: "╚",
104165
+ br: "╝",
104166
+ h: "═",
104167
+ v: "║",
104168
+ bullet: "●"
104169
+ };
104170
+ var ASCII_BOX = {
104171
+ tl: "+",
104172
+ tr: "+",
104173
+ bl: "+",
104174
+ br: "+",
104175
+ h: "-",
104176
+ v: "|",
104177
+ bullet: "+"
104178
+ };
104179
+ function createCliDesignContext(options2 = {}) {
104180
+ const env2 = options2.env ?? process.env;
104181
+ const isTTY2 = options2.isTTY ?? process.stdout.isTTY === true;
104182
+ const rawWidth = options2.columns ?? process.stdout.columns ?? DEFAULT_WIDTH;
104183
+ const width = Math.max(40, Math.min(rawWidth, PANEL_MAX_WIDTH));
104184
+ const currentPlatform = options2.platform ?? platform16();
104185
+ return {
104186
+ box: supportsCliUnicode({ env: env2, isTTY: isTTY2, platform: currentPlatform }) ? UNICODE_BOX : ASCII_BOX,
104187
+ platform: currentPlatform,
104188
+ rawWidth,
104189
+ supportsPanels: width >= PANEL_MIN_WIDTH,
104190
+ useColor: isTTY2 && !env2.NO_COLOR,
104191
+ width
104192
+ };
104193
+ }
104194
+ function supportsCliUnicode(options2) {
104195
+ const { env: env2, isTTY: isTTY2, platform: platform17 } = options2;
104196
+ if (env2.CK_FORCE_ASCII === "1" || env2.NO_UNICODE === "1")
104197
+ return false;
104198
+ if (env2.TERM === "dumb")
104199
+ return false;
104200
+ if (env2.WT_SESSION)
104201
+ return true;
104202
+ const ci = (env2.CI ?? "").trim().toLowerCase();
104203
+ if (ci === "true" || ci === "1")
104204
+ return true;
104205
+ if (!isTTY2)
104206
+ return false;
104207
+ if (env2.TERM_PROGRAM === "iTerm.app")
104208
+ return true;
104209
+ if (env2.TERM_PROGRAM === "Apple_Terminal")
104210
+ return true;
104211
+ if (env2.TERM_PROGRAM === "vscode")
104212
+ return true;
104213
+ if (env2.KONSOLE_VERSION)
104214
+ return true;
104215
+ const locale = `${env2.LANG ?? ""}${env2.LC_ALL ?? ""}`.toLowerCase();
104216
+ if (locale.includes("utf"))
104217
+ return true;
104218
+ if (platform17 === "win32")
104219
+ return false;
104220
+ return true;
104221
+ }
104222
+ function stripAnsi2(value) {
104223
+ let result = "";
104224
+ for (let index = 0;index < value.length; index += 1) {
104225
+ const code2 = value.charCodeAt(index);
104226
+ if (code2 !== 27) {
104227
+ result += value[index];
104228
+ continue;
104229
+ }
104230
+ const next = value[index + 1];
104231
+ if (next === "[") {
104232
+ index += 2;
104233
+ while (index < value.length) {
104234
+ const char = value.charCodeAt(index);
104235
+ if (char >= 64 && char <= 126)
104236
+ break;
104237
+ index += 1;
104238
+ }
104239
+ continue;
104240
+ }
104241
+ if (next === "]") {
104242
+ index += 2;
104243
+ while (index < value.length) {
104244
+ if (value.charCodeAt(index) === 7)
104245
+ break;
104246
+ if (value.charCodeAt(index) === 27 && value[index + 1] === "\\") {
104247
+ index += 1;
104248
+ break;
104249
+ }
104250
+ index += 1;
104251
+ }
104252
+ continue;
104253
+ }
104254
+ if (next !== undefined)
104255
+ index += 1;
104256
+ }
104257
+ return result;
104258
+ }
104259
+ function visibleWidth(value) {
104260
+ return stripAnsi2(value).length;
104261
+ }
104262
+ function padVisible(value, width) {
104263
+ const padding = Math.max(0, width - visibleWidth(value));
104264
+ return `${value}${" ".repeat(padding)}`;
104265
+ }
104266
+ function truncateMiddle(value, width) {
104267
+ if (width <= 0)
104268
+ return "";
104269
+ if (visibleWidth(value) <= width)
104270
+ return value;
104271
+ if (width <= 3)
104272
+ return ".".repeat(width);
104273
+ const keep = width - 3;
104274
+ const front = Math.ceil(keep / 2);
104275
+ const back = Math.floor(keep / 2);
104276
+ return `${value.slice(0, front)}...${value.slice(value.length - back)}`;
104277
+ }
104278
+ function wrapText(value, width) {
104279
+ if (width <= 0)
104280
+ return [""];
104281
+ const words = value.split(/\s+/).filter(Boolean);
104282
+ if (words.length === 0)
104283
+ return [""];
104284
+ const lines = [];
104285
+ let current = "";
104286
+ for (const word of words) {
104287
+ const candidate = current.length === 0 ? word : `${current} ${word}`;
104288
+ if (visibleWidth(candidate) <= width) {
104289
+ current = candidate;
104290
+ continue;
104291
+ }
104292
+ if (current.length > 0) {
104293
+ lines.push(current);
104294
+ current = "";
104295
+ }
104296
+ if (visibleWidth(word) <= width) {
104297
+ current = word;
104298
+ continue;
104299
+ }
104300
+ let remaining = word;
104301
+ while (visibleWidth(remaining) > width) {
104302
+ lines.push(`${remaining.slice(0, Math.max(1, width - 3))}...`);
104303
+ remaining = remaining.slice(Math.max(1, width - 3));
104304
+ }
104305
+ current = remaining;
104306
+ }
104307
+ if (current.length > 0) {
104308
+ lines.push(current);
104309
+ }
104310
+ return lines;
104311
+ }
104312
+ function formatDisplayPath(value) {
104313
+ const normalized = value.replace(/\\/g, "/");
104314
+ const home9 = homedir45().replace(/\\/g, "/");
104315
+ if (normalized === home9)
104316
+ return "~";
104317
+ if (normalized.startsWith(`${home9}/`)) {
104318
+ return normalized.replace(home9, "~");
104319
+ }
104320
+ return normalized;
104321
+ }
104322
+ function formatCdHint(value, currentPlatform = platform16()) {
104323
+ if (currentPlatform === "win32") {
104324
+ const absolutePath2 = win323.resolve(value);
104325
+ return `cd /d "${absolutePath2}"`;
104326
+ }
104327
+ const absolutePath = resolve35(value);
104328
+ const displayPath = formatDisplayPath(absolutePath);
104329
+ if (displayPath.includes(" ")) {
104330
+ return `cd "${displayPath}"`;
104331
+ }
104332
+ return `cd ${displayPath}`;
104333
+ }
104334
+ function paint(value, tone, context) {
104335
+ if (!context.useColor)
104336
+ return value;
104337
+ switch (tone) {
104338
+ case "accent":
104339
+ return import_picocolors27.default.cyan(value);
104340
+ case "muted":
104341
+ return import_picocolors27.default.dim(value);
104342
+ case "success":
104343
+ return import_picocolors27.default.green(value);
104344
+ case "warning":
104345
+ return import_picocolors27.default.yellow(value);
104346
+ case "heading":
104347
+ return import_picocolors27.default.bold(value);
104348
+ }
104349
+ }
104350
+
104351
+ // src/ui/ck-cli-design/next-steps-footer.ts
104352
+ function renderNextStepsFooter(options2) {
104353
+ const context = options2.context ?? createCliDesignContext(options2.contextOptions);
104354
+ const bullet = context.box.bullet === "+" ? "-" : "•";
104355
+ return options2.commands.map((command) => `${bullet} ${command}`);
104356
+ }
104357
+ // src/ui/ck-cli-design/panel.ts
104358
+ function renderPanel(options2) {
104359
+ const context = options2.context ?? createCliDesignContext(options2.contextOptions);
104360
+ const title = paint(options2.title, "heading", context);
104361
+ const subtitle = options2.subtitle ? paint(options2.subtitle, "muted", context) : null;
104362
+ if (!context.supportsPanels) {
104363
+ return renderPlainPanel(options2.zones, title, subtitle, context);
104364
+ }
104365
+ return renderBoxedPanel(options2.zones, title, subtitle, context);
104366
+ }
104367
+ function renderPlainPanel(zones, title, subtitle, context) {
104368
+ const lines = [title];
104369
+ if (subtitle)
104370
+ lines.push(subtitle);
104371
+ lines.push("");
104372
+ for (const zone of zones) {
104373
+ lines.push(paint(zone.label, "accent", context));
104374
+ for (const line of zone.lines) {
104375
+ lines.push(...wrapText(line, context.width - 2).map((entry) => ` ${entry}`));
104376
+ }
104377
+ lines.push("");
104378
+ }
104379
+ return trimTrailingBlank(lines);
104380
+ }
104381
+ function renderBoxedPanel(zones, title, subtitle, context) {
104382
+ const labelWidth = Math.min(12, Math.max(...zones.map((zone) => zone.label.length), 4));
104383
+ const innerWidth = context.width - 4;
104384
+ const lines = [renderTopBorder(title, context.box, context.width)];
104385
+ if (subtitle) {
104386
+ lines.push(renderContentLine(subtitle, innerWidth, context.box));
104387
+ lines.push(renderContentLine("", innerWidth, context.box));
104388
+ }
104389
+ for (const [index, zone] of zones.entries()) {
104390
+ for (const line of formatZone(zone, labelWidth, innerWidth, context)) {
104391
+ lines.push(renderContentLine(line, innerWidth, context.box));
104392
+ }
104393
+ if (index < zones.length - 1) {
104394
+ lines.push(renderContentLine("", innerWidth, context.box));
104395
+ }
104396
+ }
104397
+ lines.push(renderBottomBorder(context.box, context.width));
104398
+ return lines;
104399
+ }
104400
+ function formatZone(zone, labelWidth, innerWidth, context) {
104401
+ const availableWidth = Math.max(8, innerWidth - labelWidth - 3);
104402
+ const label = paint(zone.label, "accent", context);
104403
+ const rendered = [];
104404
+ for (const [index, rawLine] of zone.lines.entries()) {
104405
+ const wrappedLines = wrapText(rawLine, availableWidth);
104406
+ for (const [wrappedIndex, wrappedLine] of wrappedLines.entries()) {
104407
+ const prefix = index === 0 && wrappedIndex === 0 ? padVisible(label, labelWidth) : " ".repeat(labelWidth);
104408
+ rendered.push(` ${prefix} ${wrappedLine}`);
104409
+ }
104410
+ }
104411
+ return rendered;
104412
+ }
104413
+ function renderTopBorder(title, box, width) {
104414
+ const availableWidth = width - 2;
104415
+ const decorationWidth = 3;
104416
+ const maxTitleWidth = Math.max(1, availableWidth - decorationWidth - 1);
104417
+ const safeTitle = visibleWidth(title) > maxTitleWidth ? truncateMiddle(title, maxTitleWidth) : title;
104418
+ const heading = `${box.h} ${safeTitle} `;
104419
+ const fill = Math.max(1, availableWidth - visibleWidth(heading));
104420
+ return `${box.tl}${heading}${box.h.repeat(fill)}${box.tr}`;
104421
+ }
104422
+ function renderBottomBorder(box, width) {
104423
+ return `${box.bl}${box.h.repeat(width - 2)}${box.br}`;
104424
+ }
104425
+ function renderContentLine(content, width, box) {
104426
+ return `${box.v} ${padVisible(content, width)} ${box.v}`;
104427
+ }
104428
+ function trimTrailingBlank(lines) {
104429
+ const trimmed = [...lines];
104430
+ while (trimmed[trimmed.length - 1] === "") {
104431
+ trimmed.pop();
104432
+ }
104433
+ return trimmed;
104434
+ }
104435
+ // src/ui/ck-cli-design/preflight-row.ts
104436
+ function renderPreflightRow(options2) {
104437
+ const context = options2.context ?? createCliDesignContext(options2.contextOptions);
104438
+ const icon = options2.icon ?? context.box.bullet;
104439
+ const label = padVisible(options2.label, 10);
104440
+ const count = String(options2.count).padStart(3, " ");
104441
+ const prefix = ` [${icon}] ${label} ${count} -> `;
104442
+ const availableWidth = Math.max(10, context.width - prefix.length);
104443
+ const [firstDestination, ...extraDestinations] = options2.destinations.length > 0 ? options2.destinations : ["unsupported for selected provider(s)"];
104444
+ const lines = [`${prefix}${truncateMiddle(firstDestination, availableWidth)}`];
104445
+ for (const destination of extraDestinations) {
104446
+ lines.push(`${" ".repeat(prefix.length)}${truncateMiddle(destination, availableWidth)}`);
104447
+ }
104448
+ for (const note2 of options2.notes ?? []) {
104449
+ lines.push(`${" ".repeat(prefix.length)}${paint(`(${note2})`, "muted", context)}`);
104450
+ }
104451
+ return lines;
104452
+ }
104453
+ // src/ui/ck-cli-design/source-target-header.ts
104454
+ function renderSourceTargetHeader(options2) {
104455
+ const context = options2.context ?? createCliDesignContext(options2.contextOptions);
104456
+ return renderPanel({
104457
+ context,
104458
+ subtitle: options2.subtitle,
104459
+ title: options2.title,
104460
+ zones: [
104461
+ { label: "SOURCE", lines: options2.sourceLines },
104462
+ { label: "DESTINATION", lines: options2.targetLines }
104463
+ ]
104464
+ });
104465
+ }
104466
+ // src/commands/migrate/migrate-command.ts
104000
104467
  init_agents_discovery();
104001
104468
  init_commands_discovery();
104002
104469
  init_codex_toml_installer();
@@ -104150,9 +104617,17 @@ init_hooks_settings_merger();
104150
104617
  init_model_taxonomy();
104151
104618
 
104152
104619
  // src/commands/portable/plan-display.ts
104153
- var import_picocolors27 = __toESM(require_picocolors(), 1);
104620
+ var import_picocolors28 = __toESM(require_picocolors(), 1);
104621
+ import { basename as basename25, dirname as dirname38, extname as extname7 } from "node:path";
104154
104622
  var DEFAULT_MAX_PLAN_GROUP_ITEMS = 20;
104155
- var TYPE_ORDER = ["agent", "command", "skill", "config", "rules", "hooks"];
104623
+ var TYPE_ORDER = [
104624
+ "agent",
104625
+ "command",
104626
+ "skill",
104627
+ "config",
104628
+ "rules",
104629
+ "hooks"
104630
+ ];
104156
104631
  var TYPE_LABELS = {
104157
104632
  agent: "Subagents",
104158
104633
  command: "Commands",
@@ -104223,7 +104698,7 @@ function printActionGroup(label, actions, prefix, colorName, options2) {
104223
104698
  break;
104224
104699
  const typeLabel = TYPE_LABELS[type];
104225
104700
  const subHeader = ` ${typeLabel} (${typeActions.length})`;
104226
- console.log(options2.color ? import_picocolors27.default.dim(subHeader) : subHeader);
104701
+ console.log(options2.color ? import_picocolors28.default.dim(subHeader) : subHeader);
104227
104702
  const shown = typeActions.slice(0, remaining);
104228
104703
  for (const action of shown) {
104229
104704
  printAction(action, prefix, options2);
@@ -104232,7 +104707,7 @@ function printActionGroup(label, actions, prefix, colorName, options2) {
104232
104707
  const hiddenInType = typeActions.length - shown.length;
104233
104708
  if (hiddenInType > 0) {
104234
104709
  const notice = ` ... and ${hiddenInType} more ${typeLabel.toLowerCase()}`;
104235
- console.log(options2.color ? import_picocolors27.default.dim(notice) : notice);
104710
+ console.log(options2.color ? import_picocolors28.default.dim(notice) : notice);
104236
104711
  }
104237
104712
  }
104238
104713
  }
@@ -104244,22 +104719,22 @@ function printAction(action, prefix, options2) {
104244
104719
  if (action.reason) {
104245
104720
  const reason = sanitizeSingleLineTerminalText(action.reason);
104246
104721
  if (reason) {
104247
- console.log(` ${options2.color ? import_picocolors27.default.dim(reason) : reason}`);
104722
+ console.log(` ${options2.color ? import_picocolors28.default.dim(reason) : reason}`);
104248
104723
  }
104249
104724
  }
104250
104725
  }
104251
104726
  function applyColor(text, colorName) {
104252
104727
  switch (colorName) {
104253
104728
  case "green":
104254
- return import_picocolors27.default.green(text);
104729
+ return import_picocolors28.default.green(text);
104255
104730
  case "yellow":
104256
- return import_picocolors27.default.yellow(text);
104731
+ return import_picocolors28.default.yellow(text);
104257
104732
  case "red":
104258
- return import_picocolors27.default.red(text);
104733
+ return import_picocolors28.default.red(text);
104259
104734
  case "magenta":
104260
- return import_picocolors27.default.magenta(text);
104735
+ return import_picocolors28.default.magenta(text);
104261
104736
  case "dim":
104262
- return import_picocolors27.default.dim(text);
104737
+ return import_picocolors28.default.dim(text);
104263
104738
  default:
104264
104739
  return text;
104265
104740
  }
@@ -104282,42 +104757,185 @@ function summarizeExecutionResults(results) {
104282
104757
  return { applied, skipped, failed };
104283
104758
  }
104284
104759
  function displayMigrationSummary(plan, results, options2) {
104760
+ const footer = buildCompletionFooter(plan, results, options2.dryRun === true);
104285
104761
  console.log();
104286
- console.log(" Migration Complete");
104762
+ console.log(renderPanel({
104763
+ subtitle: footer.subtitle,
104764
+ title: footer.title,
104765
+ zones: footer.zones
104766
+ }).join(`
104767
+ `));
104768
+ if (footer.conflicts.length > 0) {
104769
+ console.log();
104770
+ console.log(" Conflicts resolved:");
104771
+ for (const conflict of footer.conflicts) {
104772
+ console.log(` ${conflict}`);
104773
+ }
104774
+ }
104287
104775
  console.log();
104288
- const { summary } = plan;
104776
+ }
104777
+ function buildCompletionFooter(plan, results, dryRun) {
104778
+ const providersInRun = collectProviders(plan, results);
104779
+ const conflicts = plan.actions.filter((action) => action.action === "conflict" && action.resolution?.type).map((action) => sanitizeSingleLineTerminalText(`${action.provider}/${action.type}/${action.item}: ${action.resolution?.type ?? "skipped"}`));
104289
104780
  const resultSummary = summarizeExecutionResults(results);
104290
- const installed = summary.install;
104291
- const updated = summary.update;
104292
- const skipped = summary.skip;
104293
- const deleted = summary.delete;
104294
- const failed = resultSummary.failed;
104295
- if (installed > 0) {
104296
- console.log(` ${options2.color ? import_picocolors27.default.green("[OK]") : "[OK]"} ${installed} installed`);
104781
+ const typeCounts = dryRun ? mergeTypeCounts(collectPlannedTypeCounts(plan), collectResultTypeCounts(results)) : collectResultTypeCounts(results);
104782
+ const whereLines = dryRun ? mergeWhereLines(collectPlannedWhereLines(plan), collectResultWhereLines(results)) : collectResultWhereLines(results);
104783
+ const issuesCount = results.filter((result) => !result.success).length;
104784
+ const deleteCount = results.filter((result) => result.success && !result.skipped && result.operation === "delete").length;
104785
+ const zones = [
104786
+ {
104787
+ label: "WHERE",
104788
+ lines: whereLines.length > 0 ? whereLines : ["No destination paths written"]
104789
+ },
104790
+ {
104791
+ label: "WHAT",
104792
+ lines: dryRun ? buildWhatLines(typeCounts, "would change") : buildWhatLines(typeCounts, buildApplySummary(resultSummary, deleteCount))
104793
+ },
104794
+ {
104795
+ label: "NEXT",
104796
+ lines: renderNextStepsFooter({ commands: buildNextCommands(providersInRun, typeCounts) })
104797
+ }
104798
+ ];
104799
+ if (!dryRun && issuesCount > 0) {
104800
+ zones.push({
104801
+ label: "ISSUES",
104802
+ lines: [
104803
+ `${issuesCount} item(s) failed`,
104804
+ "Re-run ck migrate after fixing the reported errors."
104805
+ ]
104806
+ });
104297
104807
  }
104298
- if (updated > 0) {
104299
- console.log(` ${options2.color ? import_picocolors27.default.green("[OK]") : "[OK]"} ${updated} updated`);
104808
+ return {
104809
+ conflicts,
104810
+ subtitle: dryRun ? `${sumTypeCounts(typeCounts)} item(s) would change` : `${resultSummary.applied} applied, ${issuesCount} failed`,
104811
+ title: dryRun ? "Dry run complete" : "Migration complete",
104812
+ zones
104813
+ };
104814
+ }
104815
+ function collectProviders(plan, results) {
104816
+ const providersFromResults = results.map((result) => result.provider);
104817
+ const providersFromPlan = plan.actions.map((action) => action.provider);
104818
+ return Array.from(new Set([...providersFromResults, ...providersFromPlan]));
104819
+ }
104820
+ function collectResultTypeCounts(results) {
104821
+ const counts = new Map;
104822
+ for (const result of results) {
104823
+ if (!result.success || result.skipped || !result.portableType)
104824
+ continue;
104825
+ counts.set(result.portableType, (counts.get(result.portableType) ?? 0) + 1);
104300
104826
  }
104301
- if (skipped > 0) {
104302
- console.log(` ${options2.color ? import_picocolors27.default.dim("[i]") : "[i]"} ${skipped} skipped`);
104827
+ return counts;
104828
+ }
104829
+ function collectPlannedTypeCounts(plan) {
104830
+ const counts = new Map;
104831
+ for (const action of plan.actions) {
104832
+ if (!shouldCountInFooter(action))
104833
+ continue;
104834
+ counts.set(action.type, (counts.get(action.type) ?? 0) + 1);
104303
104835
  }
104304
- if (deleted > 0) {
104305
- console.log(` ${options2.color ? import_picocolors27.default.dim("[-]") : "[-]"} ${deleted} deleted`);
104836
+ return counts;
104837
+ }
104838
+ function collectResultWhereLines(results) {
104839
+ const destinations = Array.from(new Set(results.filter((result) => result.success && !result.skipped && result.path.length > 0 && result.operation !== "delete").map((result) => normalizeWhereDestination(result.path, result.portableType ?? "config")))).slice(0, 5);
104840
+ return destinations.map((destination) => `${formatDisplayPath(destination)} -> ${formatCdHint(resolveCdTarget(destination))}`);
104841
+ }
104842
+ function collectPlannedWhereLines(plan) {
104843
+ const destinations = Array.from(new Set(plan.actions.filter((action) => shouldCountInFooter(action) && action.targetPath.length > 0).map((action) => normalizeWhereDestination(action.targetPath, action.type)))).slice(0, 5);
104844
+ return destinations.map((destination) => `${formatDisplayPath(destination)} -> ${formatCdHint(resolveCdTarget(destination))}`);
104845
+ }
104846
+ function resolveCdTarget(destination) {
104847
+ return extname7(destination).length > 0 ? dirname38(destination) : destination;
104848
+ }
104849
+ function normalizeWhereDestination(path16, portableType) {
104850
+ if (portableType === "agent" || portableType === "command" || portableType === "skill") {
104851
+ return dirname38(path16);
104306
104852
  }
104307
- if (failed > 0) {
104308
- console.log(` ${options2.color ? import_picocolors27.default.red("[X]") : "[X]"} ${failed} failed`);
104853
+ if (portableType === "hooks") {
104854
+ return dirname38(path16);
104309
104855
  }
104310
- const conflicts = plan.actions.filter((a3) => a3.action === "conflict");
104311
- if (conflicts.length > 0) {
104312
- console.log();
104313
- console.log(" Conflicts resolved:");
104314
- for (const c2 of conflicts) {
104315
- const conflictKey = sanitizeSingleLineTerminalText(`${c2.provider}/${c2.type}/${c2.item}`);
104316
- const resolution = sanitizeSingleLineTerminalText(c2.resolution?.type ?? "skipped");
104317
- console.log(` ${conflictKey}: ${resolution}`);
104856
+ if (portableType === "rules") {
104857
+ const fileName = basename25(path16).toLowerCase();
104858
+ if (fileName === "agents.md" || fileName === "gemini.md" || fileName === ".goosehints" || fileName === "custom_modes.yaml" || fileName === "custom_modes.yml") {
104859
+ return path16;
104318
104860
  }
104861
+ return dirname38(path16);
104319
104862
  }
104320
- console.log();
104863
+ return path16;
104864
+ }
104865
+ function shouldCountInFooter(action) {
104866
+ if (action.action === "install" || action.action === "update" || action.action === "delete") {
104867
+ return true;
104868
+ }
104869
+ if (action.action !== "conflict")
104870
+ return false;
104871
+ const resolution = action.resolution?.type;
104872
+ return resolution === "overwrite" || resolution === "smart-merge" || resolution === "resolved";
104873
+ }
104874
+ function buildWhatLines(counts, trailingSummary) {
104875
+ const orderedCounts = [
104876
+ "agent",
104877
+ "skill",
104878
+ "command",
104879
+ "config",
104880
+ "rules",
104881
+ "hooks"
104882
+ ];
104883
+ const labels = {
104884
+ agent: "agents",
104885
+ command: "commands",
104886
+ config: "config",
104887
+ hooks: "hooks",
104888
+ rules: "rules",
104889
+ skill: "skills"
104890
+ };
104891
+ const parts = orderedCounts.map((type) => counts.get(type) ? `${counts.get(type)} ${labels[type]}` : null).filter((part) => part !== null);
104892
+ if (parts.length === 0) {
104893
+ return [trailingSummary];
104894
+ }
104895
+ return [parts.join(" · "), trailingSummary];
104896
+ }
104897
+ function buildNextCommands(providersInRun, typeCounts) {
104898
+ const firstProvider = providersInRun[0];
104899
+ const commands = ["ck doctor"];
104900
+ if (!firstProvider)
104901
+ return commands;
104902
+ const preferredChecks = [
104903
+ { flag: "skill", command: `ck skills --installed --agent ${firstProvider}` },
104904
+ { flag: "agent", command: `ck agents --installed --agent ${firstProvider}` },
104905
+ { flag: "command", command: `ck commands --installed --agent ${firstProvider}` }
104906
+ ];
104907
+ for (const check of preferredChecks) {
104908
+ if ((typeCounts.get(check.flag) ?? 0) > 0 && commands.length < 3) {
104909
+ commands.push(check.command);
104910
+ }
104911
+ }
104912
+ return commands.slice(0, 3);
104913
+ }
104914
+ function mergeTypeCounts(primary, fallback2) {
104915
+ const merged = new Map(primary);
104916
+ for (const [portableType, count] of fallback2) {
104917
+ merged.set(portableType, (merged.get(portableType) ?? 0) + count);
104918
+ }
104919
+ return merged;
104920
+ }
104921
+ function mergeWhereLines(primary, fallback2) {
104922
+ return Array.from(new Set([...primary, ...fallback2]));
104923
+ }
104924
+ function buildApplySummary(resultSummary, deleteCount) {
104925
+ const appliedCount = Math.max(0, resultSummary.applied - deleteCount);
104926
+ const parts = [`${appliedCount} applied`];
104927
+ if (deleteCount > 0) {
104928
+ parts.push(`${deleteCount} deleted`);
104929
+ }
104930
+ parts.push(`${resultSummary.skipped} skipped`);
104931
+ return parts.join(", ");
104932
+ }
104933
+ function sumTypeCounts(counts) {
104934
+ let total = 0;
104935
+ for (const count of counts.values()) {
104936
+ total += count;
104937
+ }
104938
+ return total;
104321
104939
  }
104322
104940
 
104323
104941
  // src/commands/migrate/migrate-command.ts
@@ -104330,6 +104948,58 @@ init_reconcile_state_builders();
104330
104948
  init_reconciler();
104331
104949
  init_skills_discovery();
104332
104950
 
104951
+ // src/commands/migrate/migrate-progress.ts
104952
+ var import_picocolors29 = __toESM(require_picocolors(), 1);
104953
+ function createMigrateProgressSink(total, context = createCliDesignContext()) {
104954
+ if (!process.stdout.isTTY || process.env.CI || process.env.TERM === "dumb") {
104955
+ return createDotProgressSink();
104956
+ }
104957
+ return createTtyProgressSink(total, context);
104958
+ }
104959
+ function createDotProgressSink() {
104960
+ let current = 0;
104961
+ return {
104962
+ done(message) {
104963
+ if (current > 0)
104964
+ process.stdout.write(`
104965
+ `);
104966
+ if (message)
104967
+ console.log(message);
104968
+ },
104969
+ tick() {
104970
+ current += 1;
104971
+ process.stdout.write(".");
104972
+ }
104973
+ };
104974
+ }
104975
+ function createTtyProgressSink(total, context) {
104976
+ let current = 0;
104977
+ let rendered = false;
104978
+ return {
104979
+ done(message) {
104980
+ if (rendered) {
104981
+ process.stdout.write("\r\x1B[K");
104982
+ }
104983
+ if (message) {
104984
+ console.log(context.useColor ? import_picocolors29.default.green(message) : message);
104985
+ }
104986
+ },
104987
+ tick(label) {
104988
+ current += 1;
104989
+ const width = Math.max(10, Math.min(20, context.width - 34));
104990
+ const percent = total === 0 ? 100 : Math.round(current / total * 100);
104991
+ const filled = Math.round(percent / 100 * width);
104992
+ const empty = width - filled;
104993
+ const isUnicode = context.box.bullet !== "+";
104994
+ const bar = `${isUnicode ? "█".repeat(filled) : "=".repeat(filled)}${isUnicode ? "░".repeat(empty) : "-".repeat(empty)}`;
104995
+ const heading = context.useColor ? import_picocolors29.default.bold(label) : label;
104996
+ const line = ` ${heading} ${bar} ${String(percent).padStart(3, " ")}%`;
104997
+ process.stdout.write(`\r${line}`);
104998
+ rendered = true;
104999
+ }
105000
+ };
105001
+ }
105002
+
104333
105003
  // src/commands/migrate/migrate-scope-resolver.ts
104334
105004
  function resolveMigrationScope(argv, options2) {
104335
105005
  const argSet = new Set(argv);
@@ -104361,6 +105031,107 @@ function resolveMigrationScope(argv, options2) {
104361
105031
  };
104362
105032
  }
104363
105033
 
105034
+ // src/commands/migrate/migrate-ui-summary.ts
105035
+ init_provider_registry();
105036
+ var PORTABLE_TYPES = [
105037
+ { key: "agents", label: "Agents" },
105038
+ { key: "commands", label: "Commands" },
105039
+ { key: "skills", label: "Skills" },
105040
+ { key: "config", label: "Config" },
105041
+ { key: "rules", label: "Rules" },
105042
+ { key: "hooks", label: "Hooks" }
105043
+ ];
105044
+ var MERGE_STRATEGIES = new Set(["merge-single", "yaml-merge", "json-merge"]);
105045
+ function buildPreflightRows(counts, selectedProviders, options2) {
105046
+ return PORTABLE_TYPES.flatMap(({ key, label }) => {
105047
+ const count = counts[key];
105048
+ if (count <= 0)
105049
+ return [];
105050
+ const destinations = new Map;
105051
+ const notes = new Set;
105052
+ for (const provider of selectedProviders) {
105053
+ const config = providers[provider][key];
105054
+ if (!config) {
105055
+ notes.add(`${providers[provider].displayName}: unsupported`);
105056
+ continue;
105057
+ }
105058
+ const destination = getPortableBasePath(provider, key, { global: options2.actualGlobal });
105059
+ if (!destination) {
105060
+ const note2 = options2.actualGlobal ? "project-only" : "global-only";
105061
+ notes.add(`${providers[provider].displayName}: ${note2}`);
105062
+ continue;
105063
+ }
105064
+ const normalizedDestination = formatDisplayPath(destination);
105065
+ destinations.set(normalizedDestination, [
105066
+ ...destinations.get(normalizedDestination) ?? [],
105067
+ provider
105068
+ ]);
105069
+ if (!options2.requestedGlobal && config.projectPath === null && config.globalPath !== null) {
105070
+ notes.add(`${providers[provider].displayName}: global-only`);
105071
+ }
105072
+ if (options2.requestedGlobal && config.globalPath === null && config.projectPath !== null) {
105073
+ notes.add(`${providers[provider].displayName}: project-only`);
105074
+ }
105075
+ if (MERGE_STRATEGIES.has(config.writeStrategy)) {
105076
+ notes.add(`${providers[provider].displayName}: merge`);
105077
+ }
105078
+ }
105079
+ for (const [destination, providersAtPath] of destinations) {
105080
+ if (providersAtPath.length > 1) {
105081
+ notes.add(`${providersAtPath.map((provider) => providers[provider].displayName).join(", ")} share ${destination}`);
105082
+ }
105083
+ }
105084
+ return [
105085
+ {
105086
+ count,
105087
+ destinations: Array.from(destinations.keys()),
105088
+ label,
105089
+ notes: Array.from(notes)
105090
+ }
105091
+ ];
105092
+ });
105093
+ }
105094
+ function buildTargetSummaryLines(rows) {
105095
+ const allDestinations = Array.from(new Set(rows.flatMap((row) => row.destinations).filter((destination) => destination.length > 0)));
105096
+ if (allDestinations.length === 0) {
105097
+ return ["No compatible destination found for the selected providers"];
105098
+ }
105099
+ if (allDestinations.length <= 3) {
105100
+ return allDestinations;
105101
+ }
105102
+ return [...allDestinations.slice(0, 3), `+${allDestinations.length - 3} more destination(s)`];
105103
+ }
105104
+ function buildProviderScopeSubtitle(selectedProviders, global3) {
105105
+ const scope = global3 ? "global" : "project";
105106
+ if (selectedProviders.length === 1) {
105107
+ return `${providers[selectedProviders[0]].displayName} -> ${scope}`;
105108
+ }
105109
+ if (selectedProviders.length <= 3) {
105110
+ return `${selectedProviders.map((provider) => providers[provider].displayName).join(", ")} -> ${scope}`;
105111
+ }
105112
+ return `${selectedProviders.length} providers -> ${scope}`;
105113
+ }
105114
+ function buildSourceSummaryLines(counts, origins) {
105115
+ const parts = [];
105116
+ if (counts.agents > 0)
105117
+ parts.push(`${counts.agents} agents`);
105118
+ if (counts.skills > 0)
105119
+ parts.push(`${counts.skills} skills`);
105120
+ if (counts.commands > 0)
105121
+ parts.push(`${counts.commands} commands`);
105122
+ if (counts.rules > 0)
105123
+ parts.push(`${counts.rules} rules`);
105124
+ if (counts.hooks > 0)
105125
+ parts.push(`${counts.hooks} hooks`);
105126
+ if (counts.config > 0)
105127
+ parts.push("config");
105128
+ const uniqueOrigins = Array.from(new Set(origins.map((origin) => formatDisplayPath(origin))));
105129
+ const summary = parts.length > 0 ? parts.join(" · ") : "portable items detected";
105130
+ if (uniqueOrigins.length === 0)
105131
+ return [summary];
105132
+ return [summary, `from ${uniqueOrigins.join(" · ")}`];
105133
+ }
105134
+
104364
105135
  // src/commands/migrate/migrate-command.ts
104365
105136
  init_skill_directory_installer();
104366
105137
  function getProviderPathKey(type) {
@@ -104393,13 +105164,16 @@ function shouldExecuteAction2(action) {
104393
105164
  }
104394
105165
  async function executeDeleteAction(action, options2) {
104395
105166
  const preservePaths = options2?.preservePaths ?? new Set;
104396
- const shouldPreserveTarget = action.targetPath.length > 0 && preservePaths.has(resolve35(action.targetPath));
105167
+ const shouldPreserveTarget = action.targetPath.length > 0 && preservePaths.has(resolve36(action.targetPath));
104397
105168
  try {
104398
105169
  if (!shouldPreserveTarget && action.targetPath && existsSync62(action.targetPath)) {
104399
105170
  await rm15(action.targetPath, { recursive: true, force: true });
104400
105171
  }
104401
105172
  await removePortableInstallation(action.item, action.type, action.provider, action.global);
104402
105173
  return {
105174
+ operation: "delete",
105175
+ portableType: action.type,
105176
+ itemName: action.item,
104403
105177
  provider: action.provider,
104404
105178
  providerDisplayName: providers[action.provider]?.displayName || action.provider,
104405
105179
  success: true,
@@ -104409,6 +105183,9 @@ async function executeDeleteAction(action, options2) {
104409
105183
  };
104410
105184
  } catch (error) {
104411
105185
  return {
105186
+ operation: "delete",
105187
+ portableType: action.type,
105188
+ itemName: action.item,
104412
105189
  provider: action.provider,
104413
105190
  providerDisplayName: providers[action.provider]?.displayName || action.provider,
104414
105191
  success: false,
@@ -104420,7 +105197,7 @@ async function executeDeleteAction(action, options2) {
104420
105197
  async function processMetadataDeletions(skillSourcePath, installGlobally) {
104421
105198
  if (!skillSourcePath)
104422
105199
  return;
104423
- const sourceMetadataPath = join139(resolve35(skillSourcePath, ".."), "metadata.json");
105200
+ const sourceMetadataPath = join139(resolve36(skillSourcePath, ".."), "metadata.json");
104424
105201
  if (!existsSync62(sourceMetadataPath))
104425
105202
  return;
104426
105203
  let sourceMetadata;
@@ -104433,7 +105210,7 @@ async function processMetadataDeletions(skillSourcePath, installGlobally) {
104433
105210
  }
104434
105211
  if (!sourceMetadata.deletions || sourceMetadata.deletions.length === 0)
104435
105212
  return;
104436
- const claudeDir3 = installGlobally ? join139(homedir45(), ".claude") : join139(process.cwd(), ".claude");
105213
+ const claudeDir3 = installGlobally ? join139(homedir46(), ".claude") : join139(process.cwd(), ".claude");
104437
105214
  if (!existsSync62(claudeDir3))
104438
105215
  return;
104439
105216
  try {
@@ -104454,7 +105231,6 @@ function inferKitTypeFromSourceMetadata(sourceMetadata) {
104454
105231
  }
104455
105232
  async function migrateCommand(options2) {
104456
105233
  console.log();
104457
- oe(import_picocolors28.default.bgMagenta(import_picocolors28.default.black(" ck migrate ")));
104458
105234
  try {
104459
105235
  const scope = resolveMigrationScope(process.argv.slice(2), options2);
104460
105236
  const spinner = de();
@@ -104477,37 +105253,10 @@ async function migrateCommand(options2) {
104477
105253
  const hasItems = agents2.length > 0 || commands.length > 0 || skills.length > 0 || configItem !== null || ruleItems.length > 0 || hookItems.length > 0;
104478
105254
  if (!hasItems) {
104479
105255
  f2.error("Nothing to migrate.");
104480
- f2.info(import_picocolors28.default.dim("Check .claude/agents/, .claude/commands/, .claude/skills/, .claude/rules/, .claude/hooks/, and CLAUDE.md (project or ~/.claude/)"));
104481
- $e(import_picocolors28.default.red("Nothing to migrate"));
105256
+ f2.info(import_picocolors30.default.dim("Check .claude/agents/, .claude/commands/, .claude/skills/, .claude/rules/, .claude/hooks/, and CLAUDE.md (project or ~/.claude/)"));
105257
+ $e(import_picocolors30.default.red("Nothing to migrate"));
104482
105258
  return;
104483
105259
  }
104484
- f2.info(import_picocolors28.default.dim(` CWD: ${process.cwd()}`));
104485
- const parts = [];
104486
- if (agents2.length > 0) {
104487
- const origin = resolveSourceOrigin(agentSource);
104488
- parts.push(`${agents2.length} agent(s) ${import_picocolors28.default.dim(`<- ${origin}`)}`);
104489
- }
104490
- if (commands.length > 0) {
104491
- const origin = resolveSourceOrigin(commandSource);
104492
- parts.push(`${commands.length} command(s) ${import_picocolors28.default.dim(`<- ${origin}`)}`);
104493
- }
104494
- if (skills.length > 0) {
104495
- const origin = resolveSourceOrigin(skillSource);
104496
- parts.push(`${skills.length} skill(s) ${import_picocolors28.default.dim(`<- ${origin}`)}`);
104497
- }
104498
- if (configItem) {
104499
- const origin = resolveSourceOrigin(configItem.sourcePath);
104500
- parts.push(`config ${import_picocolors28.default.dim(`<- ${origin}`)}`);
104501
- }
104502
- if (ruleItems.length > 0) {
104503
- const origin = resolveSourceOrigin(rulesSourcePath);
104504
- parts.push(`${ruleItems.length} rule(s) ${import_picocolors28.default.dim(`<- ${origin}`)}`);
104505
- }
104506
- if (hookItems.length > 0) {
104507
- const origin = resolveSourceOrigin(hooksSource);
104508
- parts.push(`${hookItems.length} hook(s) ${import_picocolors28.default.dim(`<- ${origin}`)}`);
104509
- }
104510
- f2.info(`Found: ${parts.join(", ")}`);
104511
105260
  const detectedProviders = await detectInstalledProviders();
104512
105261
  let selectedProviders;
104513
105262
  const allSupportedProviders = Array.from(new Set([
@@ -104523,8 +105272,8 @@ async function migrateCommand(options2) {
104523
105272
  const invalid = options2.agent.filter((a3) => !validProviders.includes(a3));
104524
105273
  if (invalid.length > 0) {
104525
105274
  f2.error(`Unknown provider(s): ${invalid.join(", ")}`);
104526
- f2.info(import_picocolors28.default.dim(`Valid providers: ${validProviders.join(", ")}`));
104527
- $e(import_picocolors28.default.red("Invalid provider"));
105275
+ f2.info(import_picocolors30.default.dim(`Valid providers: ${validProviders.join(", ")}`));
105276
+ $e(import_picocolors30.default.red("Invalid provider"));
104528
105277
  return;
104529
105278
  }
104530
105279
  selectedProviders = options2.agent;
@@ -104534,7 +105283,7 @@ async function migrateCommand(options2) {
104534
105283
  } else if (options2.yes) {
104535
105284
  if (detectedProviders.length > 0) {
104536
105285
  selectedProviders = detectedProviders;
104537
- f2.info(`Migrating to: ${detectedProviders.map((a3) => import_picocolors28.default.cyan(providers[a3].displayName)).join(", ")}`);
105286
+ f2.info(`Migrating to: ${detectedProviders.map((a3) => import_picocolors30.default.cyan(providers[a3].displayName)).join(", ")}`);
104538
105287
  } else {
104539
105288
  selectedProviders = allSupportedProviders;
104540
105289
  f2.info("No providers detected, migrating to all");
@@ -104547,16 +105296,16 @@ async function migrateCommand(options2) {
104547
105296
  label: providers[key].displayName
104548
105297
  });
104549
105298
  if (detectedProviders.length > 0) {
104550
- f2.info(`Detected ${import_picocolors28.default.cyan(String(detectedProviders.length))} installed provider(s)`);
105299
+ f2.info(`Detected ${import_picocolors30.default.cyan(String(detectedProviders.length))} installed provider(s)`);
104551
105300
  } else {
104552
105301
  f2.warn("No providers detected on your system.");
104553
105302
  }
104554
105303
  const groupOptions = {};
104555
105304
  if (detectedProviders.length > 0) {
104556
- groupOptions[`Detected ${import_picocolors28.default.dim("(installed)")}`] = detectedProviders.map(toOption);
105305
+ groupOptions[`Detected ${import_picocolors30.default.dim("(installed)")}`] = detectedProviders.map(toOption);
104557
105306
  }
104558
105307
  if (notDetected.length > 0) {
104559
- groupOptions[`Not detected ${import_picocolors28.default.dim("(select manually if installed)")}`] = notDetected.map(toOption);
105308
+ groupOptions[`Not detected ${import_picocolors30.default.dim("(select manually if installed)")}`] = notDetected.map(toOption);
104560
105309
  }
104561
105310
  if (Object.keys(groupOptions).length === 0) {
104562
105311
  ue("No providers available");
@@ -104575,22 +105324,23 @@ async function migrateCommand(options2) {
104575
105324
  selectedProviders = selected;
104576
105325
  }
104577
105326
  selectedProviders = Array.from(new Set(selectedProviders));
104578
- let installGlobally = options2.global ?? false;
105327
+ let requestedGlobal = options2.global ?? false;
105328
+ let installGlobally = requestedGlobal;
104579
105329
  if (options2.global === undefined && !options2.yes) {
104580
105330
  const projectTarget = join139(process.cwd(), ".claude");
104581
- const globalTarget = join139(homedir45(), ".claude");
105331
+ const globalTarget = join139(homedir46(), ".claude");
104582
105332
  const scopeChoice = await ie({
104583
105333
  message: "Installation scope",
104584
105334
  options: [
104585
- {
104586
- value: false,
104587
- label: "Project",
104588
- hint: `-> ${projectTarget}`
104589
- },
104590
105335
  {
104591
105336
  value: true,
104592
105337
  label: "Global",
104593
105338
  hint: `-> ${globalTarget}`
105339
+ },
105340
+ {
105341
+ value: false,
105342
+ label: "Project",
105343
+ hint: `-> ${projectTarget}`
104594
105344
  }
104595
105345
  ]
104596
105346
  });
@@ -104598,49 +105348,76 @@ async function migrateCommand(options2) {
104598
105348
  ue("Migrate cancelled");
104599
105349
  return;
104600
105350
  }
104601
- installGlobally = scopeChoice;
105351
+ requestedGlobal = scopeChoice;
105352
+ installGlobally = requestedGlobal;
104602
105353
  }
104603
105354
  const codexCommandsRequireGlobal = scope.commands && selectedProviders.includes("codex") && providers.codex.commands !== null && providers.codex.commands.projectPath === null;
104604
105355
  if (codexCommandsRequireGlobal && !installGlobally) {
104605
105356
  installGlobally = true;
104606
- f2.info(import_picocolors28.default.dim("Codex commands are global-only; scope adjusted to global."));
104607
- }
104608
- console.log();
104609
- f2.step(import_picocolors28.default.bold("Migrate Summary"));
105357
+ f2.info(import_picocolors30.default.dim("Codex commands are global-only; scope adjusted to global."));
105358
+ }
105359
+ const sourceCounts = {
105360
+ agents: agents2.length,
105361
+ commands: commands.length,
105362
+ config: configItem ? 1 : 0,
105363
+ hooks: hookItems.length,
105364
+ rules: ruleItems.length,
105365
+ skills: skills.length
105366
+ };
105367
+ const sourceOrigins = [
105368
+ agentSource,
105369
+ commandSource,
105370
+ skillSource,
105371
+ configItem?.sourcePath ?? null,
105372
+ rulesSourcePath,
105373
+ hooksSource
105374
+ ].filter((origin) => origin !== null);
105375
+ const preflightRows = buildPreflightRows(sourceCounts, selectedProviders, {
105376
+ actualGlobal: installGlobally,
105377
+ requestedGlobal
105378
+ });
105379
+ const discoveryParts = [];
105380
+ const agentSourceDisplay = agentSource ? formatDisplayPath(agentSource) : "source unavailable";
105381
+ const commandSourceDisplay = commandSource ? formatDisplayPath(commandSource) : "source unavailable";
105382
+ const skillSourceDisplay = skillSource ? formatDisplayPath(skillSource) : "source unavailable";
105383
+ const rulesSourceDisplay = rulesSourcePath ? formatDisplayPath(rulesSourcePath) : "source unavailable";
105384
+ const hooksSourceDisplay = hooksSource ? formatDisplayPath(hooksSource) : "source unavailable";
104610
105385
  if (agents2.length > 0) {
104611
- f2.message(` Agents: ${agents2.map((a3) => import_picocolors28.default.cyan(a3.name)).join(", ")}`);
105386
+ discoveryParts.push(`${agents2.length} agent(s) ${import_picocolors30.default.dim(`<- ${agentSourceDisplay}`)}`);
104612
105387
  }
104613
105388
  if (commands.length > 0) {
104614
- const cmdNames = commands.map((c2) => import_picocolors28.default.cyan(`/${c2.displayName || c2.name}`)).join(", ");
104615
- f2.message(` Commands: ${cmdNames}`);
105389
+ discoveryParts.push(`${commands.length} command(s) ${import_picocolors30.default.dim(`<- ${commandSourceDisplay}`)}`);
104616
105390
  }
104617
105391
  if (skills.length > 0) {
104618
- f2.message(` Skills: ${skills.map((s) => import_picocolors28.default.cyan(s.name)).join(", ")}`);
105392
+ discoveryParts.push(`${skills.length} skill(s) ${import_picocolors30.default.dim(`<- ${skillSourceDisplay}`)}`);
104619
105393
  }
104620
105394
  if (configItem) {
104621
- const lines = configItem.body.split(`
104622
- `).length;
104623
- f2.message(` Config: ${import_picocolors28.default.cyan("CLAUDE.md")} (${lines} lines)`);
105395
+ discoveryParts.push(`config ${import_picocolors30.default.dim(`<- ${formatDisplayPath(configItem.sourcePath)}`)}`);
104624
105396
  }
104625
105397
  if (ruleItems.length > 0) {
104626
- f2.message(` Rules: ${import_picocolors28.default.cyan(`${ruleItems.length} file(s)`)}`);
105398
+ discoveryParts.push(`${ruleItems.length} rule(s) ${import_picocolors30.default.dim(`<- ${rulesSourceDisplay}`)}`);
104627
105399
  }
104628
105400
  if (hookItems.length > 0) {
104629
- f2.message(` Hooks: ${import_picocolors28.default.cyan(`${hookItems.length} file(s)`)}`);
105401
+ discoveryParts.push(`${hookItems.length} hook(s) ${import_picocolors30.default.dim(`<- ${hooksSourceDisplay}`)}`);
104630
105402
  }
104631
- const providerNames = selectedProviders.map((prov) => import_picocolors28.default.cyan(providers[prov].displayName)).join(", ");
105403
+ console.log();
105404
+ console.log(renderSourceTargetHeader({
105405
+ sourceLines: buildSourceSummaryLines(sourceCounts, sourceOrigins),
105406
+ subtitle: buildProviderScopeSubtitle(selectedProviders, installGlobally),
105407
+ targetLines: buildTargetSummaryLines(preflightRows),
105408
+ title: "ck migrate"
105409
+ }).join(`
105410
+ `));
105411
+ f2.info(import_picocolors30.default.dim(` CWD: ${process.cwd()}`));
105412
+ f2.info(`Found: ${discoveryParts.join(", ")}`);
105413
+ console.log();
105414
+ f2.step(import_picocolors30.default.bold("Migrate Summary"));
105415
+ const providerNames = selectedProviders.map((prov) => import_picocolors30.default.cyan(providers[prov].displayName)).join(", ");
104632
105416
  f2.message(` Providers: ${providerNames}`);
104633
- const targetDir = installGlobally ? join139(homedir45(), ".claude") : join139(process.cwd(), ".claude");
104634
- f2.message(` Scope: ${installGlobally ? "Global" : "Project"} ${import_picocolors28.default.dim(`-> ${targetDir}`)}`);
104635
- const cmdProviders = getProvidersSupporting("commands");
104636
- const unsupportedCmd = selectedProviders.filter((pv) => !cmdProviders.includes(pv));
104637
- if (commands.length > 0 && unsupportedCmd.length > 0) {
104638
- f2.info(import_picocolors28.default.dim(` [i] Commands skipped for: ${unsupportedCmd.map((pv) => providers[pv].displayName).join(", ")} (unsupported)`));
104639
- }
104640
- const hookProviders = getProvidersSupporting("hooks");
104641
- const unsupportedHooks = selectedProviders.filter((pv) => !hookProviders.includes(pv));
104642
- if (hookItems.length > 0 && unsupportedHooks.length > 0) {
104643
- f2.info(import_picocolors28.default.dim(` [i] Hooks skipped for: ${unsupportedHooks.map((pv) => providers[pv].displayName).join(", ")} (unsupported)`));
105417
+ for (const row of preflightRows) {
105418
+ for (const line of renderPreflightRow(row)) {
105419
+ console.log(line);
105420
+ }
104644
105421
  }
104645
105422
  const { CkConfigManager: CkConfigManager2 } = await Promise.resolve().then(() => (init_ck_config_manager(), exports_ck_config_manager));
104646
105423
  const ckConfigResult = await CkConfigManager2.loadFull(process.cwd());
@@ -104671,8 +105448,7 @@ async function migrateCommand(options2) {
104671
105448
  const useColor = process.stdout.isTTY && !process.env.NO_COLOR;
104672
105449
  displayReconcilePlan(plan, { color: useColor });
104673
105450
  if (options2.dryRun) {
104674
- console.log();
104675
- $e(import_picocolors28.default.green("Dry run complete — no files written"));
105451
+ displayMigrationSummary(plan, buildDryRunFallbackResults(skills, selectedProviders, installGlobally, plan.actions), { color: useColor, dryRun: true });
104676
105452
  return;
104677
105453
  }
104678
105454
  if (plan.hasConflicts) {
@@ -104718,9 +105494,7 @@ async function migrateCommand(options2) {
104718
105494
  return;
104719
105495
  }
104720
105496
  }
104721
- const installSpinner = de();
104722
- installSpinner.start("Migrating...");
104723
- const allResults = [];
105497
+ let allResults = [];
104724
105498
  const installOpts = { global: installGlobally };
104725
105499
  const agentByName = new Map(agents2.map((item) => [item.name, item]));
104726
105500
  const commandByName = new Map(commands.map((item) => [item.name, item]));
@@ -104729,6 +105503,8 @@ async function migrateCommand(options2) {
104729
105503
  const ruleByName = new Map(ruleItems.map((item) => [item.name, item]));
104730
105504
  const hookByName = new Map(hookItems.map((item) => [item.name, item]));
104731
105505
  const successfulHookFiles = new Map;
105506
+ const postProgressWarnings = [];
105507
+ const writeTasks = [];
104732
105508
  for (const action of plannedExecActions) {
104733
105509
  const provider = action.provider;
104734
105510
  if (!selectedProviders.includes(provider))
@@ -104737,50 +105513,70 @@ async function migrateCommand(options2) {
104737
105513
  const item = agentByName.get(action.item);
104738
105514
  if (!item || !getProvidersSupporting("agents").includes(provider))
104739
105515
  continue;
104740
- allResults.push(...await installPortableItems([item], [provider], "agent", installOpts));
105516
+ writeTasks.push({ item, provider, type: "agent" });
104741
105517
  continue;
104742
105518
  }
104743
105519
  if (action.type === "command") {
104744
105520
  const item = commandByName.get(action.item);
104745
105521
  if (!item || !getProvidersSupporting("commands").includes(provider))
104746
105522
  continue;
104747
- allResults.push(...await installPortableItems([item], [provider], "command", installOpts));
105523
+ writeTasks.push({ item, provider, type: "command" });
104748
105524
  continue;
104749
105525
  }
104750
105526
  if (action.type === "skill") {
104751
105527
  const item = skillByName.get(action.item);
104752
105528
  if (!item || !getProvidersSupporting("skills").includes(provider))
104753
105529
  continue;
104754
- allResults.push(...await installSkillDirectories([item], [provider], installOpts));
105530
+ writeTasks.push({ item, provider, type: "skill" });
104755
105531
  continue;
104756
105532
  }
104757
105533
  if (action.type === "config") {
104758
105534
  const item = configByName.get(action.item);
104759
105535
  if (!item || !getProvidersSupporting("config").includes(provider))
104760
105536
  continue;
104761
- allResults.push(...await installPortableItems([item], [provider], "config", installOpts));
105537
+ writeTasks.push({ item, provider, type: "config" });
104762
105538
  continue;
104763
105539
  }
104764
105540
  if (action.type === "rules") {
104765
105541
  const item = ruleByName.get(action.item);
104766
105542
  if (!item || !getProvidersSupporting("rules").includes(provider))
104767
105543
  continue;
104768
- allResults.push(...await installPortableItems([item], [provider], "rules", installOpts));
105544
+ writeTasks.push({ item, provider, type: "rules" });
104769
105545
  continue;
104770
105546
  }
104771
105547
  if (action.type === "hooks") {
104772
105548
  const item = hookByName.get(action.item);
104773
105549
  if (!item || !getProvidersSupporting("hooks").includes(provider))
104774
105550
  continue;
104775
- const hookResults = await installPortableItems([item], [provider], "hooks", installOpts);
104776
- allResults.push(...hookResults);
104777
- for (const r2 of hookResults.filter((r3) => r3.success && !r3.skipped)) {
104778
- const existing = successfulHookFiles.get(provider) ?? [];
104779
- existing.push(basename25(r2.path));
104780
- successfulHookFiles.set(provider, existing);
105551
+ writeTasks.push({ item, provider, type: "hooks" });
105552
+ }
105553
+ }
105554
+ const plannedSkillActions = plannedExecActions.filter((action) => action.type === "skill").length;
105555
+ if (skills.length > 0 && plannedSkillActions === 0) {
105556
+ const skillProviders = selectedProviders.filter((pv) => getProvidersSupporting("skills").includes(pv));
105557
+ for (const provider of skillProviders) {
105558
+ for (const skill of skills) {
105559
+ writeTasks.push({ item: skill, provider, type: "skill" });
104781
105560
  }
104782
105561
  }
104783
105562
  }
105563
+ const progressSink = createMigrateProgressSink(writeTasks.length + plannedDeleteActions.length);
105564
+ const writtenPaths = new Set;
105565
+ for (const task of writeTasks) {
105566
+ const taskResults = task.type === "skill" ? annotateInstallResults(await installSkillDirectories([task.item], [task.provider], installOpts), "skill", task.item.name) : annotateInstallResults(await installPortableItems([task.item], [task.provider], task.type, installOpts), task.type, task.item.name);
105567
+ allResults.push(...taskResults);
105568
+ for (const result of taskResults.filter((entry) => entry.success && !entry.skipped)) {
105569
+ if (result.path.length > 0) {
105570
+ writtenPaths.add(resolve36(result.path));
105571
+ }
105572
+ if (task.type === "hooks") {
105573
+ const existing = successfulHookFiles.get(task.provider) ?? [];
105574
+ existing.push(basename26(result.path));
105575
+ successfulHookFiles.set(task.provider, existing);
105576
+ }
105577
+ }
105578
+ progressSink.tick(progressLabelForType(task.type));
105579
+ }
104784
105580
  for (const [hooksProvider, files] of successfulHookFiles) {
104785
105581
  if (files.length === 0)
104786
105582
  continue;
@@ -104795,23 +105591,20 @@ async function migrateCommand(options2) {
104795
105591
  } else {
104796
105592
  const feedbackMessage = mergeResult.error ?? mergeResult.message;
104797
105593
  if (feedbackMessage) {
104798
- f2.warn(feedbackMessage);
105594
+ postProgressWarnings.push(feedbackMessage);
104799
105595
  }
104800
105596
  }
104801
105597
  }
104802
- const plannedSkillActions = plannedExecActions.filter((action) => action.type === "skill").length;
104803
- if (skills.length > 0 && plannedSkillActions === 0) {
104804
- const skillProviders = selectedProviders.filter((pv) => getProvidersSupporting("skills").includes(pv));
104805
- if (skillProviders.length > 0) {
104806
- allResults.push(...await installSkillDirectories(skills, skillProviders, installOpts));
104807
- }
104808
- }
104809
105598
  await processMetadataDeletions(skillSource, installGlobally);
104810
- const writtenPaths = new Set(allResults.filter((result) => result.success && !result.skipped && result.path.length > 0).map((result) => resolve35(result.path)));
104811
105599
  for (const deleteAction of plannedDeleteActions) {
104812
105600
  allResults.push(await executeDeleteAction(deleteAction, {
104813
105601
  preservePaths: writtenPaths
104814
105602
  }));
105603
+ progressSink.tick("Cleanup");
105604
+ }
105605
+ progressSink.done();
105606
+ for (const warning of postProgressWarnings) {
105607
+ f2.warn(warning);
104815
105608
  }
104816
105609
  try {
104817
105610
  await backfillRegistryChecksums(plan.actions, registry);
@@ -104828,14 +105621,14 @@ async function migrateCommand(options2) {
104828
105621
  });
104829
105622
  if (staleSlugs.length > 0) {
104830
105623
  const staleSlugSet = new Set(staleSlugs.map((s) => `${s}.toml`));
104831
- const removed = await removeInstallationsByFilter((i) => i.type === "agent" && i.provider === provider && i.global === installGlobally && staleSlugSet.has(basename25(i.path)));
105624
+ const removed = await removeInstallationsByFilter((i) => i.type === "agent" && i.provider === provider && i.global === installGlobally && staleSlugSet.has(basename26(i.path)));
104832
105625
  for (const entry of removed) {
104833
105626
  logger.verbose(`[migrate] Cleaned stale registry entry: ${entry.item} (${provider})`);
104834
105627
  }
104835
105628
  }
104836
105629
  }
104837
105630
  try {
104838
- const kitRoot = (agentSource ? resolve35(agentSource, "..") : null) ?? (commandSource ? resolve35(commandSource, "..") : null) ?? (skillSource ? resolve35(skillSource, "..") : null) ?? null;
105631
+ const kitRoot = (agentSource ? resolve36(agentSource, "..") : null) ?? (commandSource ? resolve36(commandSource, "..") : null) ?? (skillSource ? resolve36(skillSource, "..") : null) ?? null;
104839
105632
  const manifest = kitRoot ? await loadPortableManifest(kitRoot) : null;
104840
105633
  if (manifest?.cliVersion) {
104841
105634
  await updateAppliedManifestVersion(manifest.cliVersion);
@@ -104844,8 +105637,6 @@ async function migrateCommand(options2) {
104844
105637
  } catch {
104845
105638
  logger.debug("[migrate] Failed to update appliedManifestVersion — will retry on next run");
104846
105639
  }
104847
- installSpinner.stop("Migrate complete");
104848
- displayMigrationSummary(plan, allResults, { color: useColor });
104849
105640
  const failed = allResults.filter((r2) => !r2.success);
104850
105641
  const successful = allResults.filter((r2) => r2.success && !r2.skipped);
104851
105642
  const hasEmbeddedPartialFailures = allResults.some((result) => (result.warnings || []).some((warning) => warning.startsWith("Failed item:")));
@@ -104862,27 +105653,28 @@ async function migrateCommand(options2) {
104862
105653
  initialValue: false
104863
105654
  });
104864
105655
  if (!lD(shouldRollback) && shouldRollback) {
104865
- await rollbackResults(successful);
105656
+ const rolledBackPaths = await rollbackResults(successful);
105657
+ allResults = allResults.map((result) => result.path.length > 0 && rolledBackPaths.has(result.path) ? { ...result, skipped: true, skipReason: "Rolled back after failure" } : result);
104866
105658
  f2.info(`Rolled back ${newWrites.length} file(s)`);
104867
105659
  }
104868
105660
  }
104869
105661
  }
105662
+ displayMigrationSummary(plan, allResults, { color: useColor });
104870
105663
  if (failed.length > 0) {
104871
105664
  console.log();
104872
105665
  displayResults3(allResults);
104873
- } else {
104874
- $e(import_picocolors28.default.green("Migration complete!"));
104875
105666
  }
104876
105667
  if (failed.length > 0 || hasEmbeddedPartialFailures) {
104877
105668
  process.exitCode = 1;
104878
105669
  }
104879
105670
  } catch (error) {
104880
105671
  logger.error(error instanceof Error ? error.message : "Unknown error");
104881
- $e(import_picocolors28.default.red("Migrate failed"));
105672
+ $e(import_picocolors30.default.red("Migrate failed"));
104882
105673
  process.exit(1);
104883
105674
  }
104884
105675
  }
104885
105676
  async function rollbackResults(results) {
105677
+ const rolledBackPaths = new Set;
104886
105678
  for (const result of results) {
104887
105679
  if (!result.path || !existsSync62(result.path))
104888
105680
  continue;
@@ -104895,28 +105687,30 @@ async function rollbackResults(results) {
104895
105687
  } else {
104896
105688
  await unlink12(result.path);
104897
105689
  }
105690
+ rolledBackPaths.add(result.path);
104898
105691
  } catch {}
104899
105692
  }
105693
+ return rolledBackPaths;
104900
105694
  }
104901
105695
  function warnConversionFallback2(warning) {
104902
105696
  logger.warning(logger.sanitize(`[migrate] Falling back to raw checksum for ${warning.provider} ${warning.type} "${warning.item}" because ${warning.format} conversion failed: ${warning.error}`));
104903
105697
  }
104904
105698
  async function computeSourceStates(items, selectedProviders) {
104905
105699
  const states = [];
104906
- const processItems = async (itemList, type) => {
105700
+ const processItems = (itemList, type) => {
104907
105701
  for (const item of itemList) {
104908
105702
  states.push(buildSourceItemState(item, type, selectedProviders, {
104909
105703
  onConversionFallback: warnConversionFallback2
104910
105704
  }));
104911
105705
  }
104912
105706
  };
104913
- await processItems(items.agents, "agent");
104914
- await processItems(items.commands, "command");
105707
+ processItems(items.agents, "agent");
105708
+ processItems(items.commands, "command");
104915
105709
  if (items.config) {
104916
- await processItems([items.config], "config");
105710
+ processItems([items.config], "config");
104917
105711
  }
104918
- await processItems(items.rules, "rules");
104919
- await processItems(items.hooks, "hooks");
105712
+ processItems(items.rules, "rules");
105713
+ processItems(items.hooks, "hooks");
104920
105714
  return states;
104921
105715
  }
104922
105716
  async function computeTargetStates(selectedProviders, global3) {
@@ -104941,22 +105735,22 @@ function displayResults3(results) {
104941
105735
  const failed = results.filter((r2) => !r2.success);
104942
105736
  if (successful.length > 0) {
104943
105737
  for (const r2 of successful) {
104944
- f2.success(`${import_picocolors28.default.green("[OK]")} ${r2.providerDisplayName}`);
105738
+ f2.success(`${import_picocolors30.default.green("[OK]")} ${r2.providerDisplayName}`);
104945
105739
  if (r2.warnings) {
104946
105740
  for (const w3 of r2.warnings) {
104947
- f2.warn(` ${import_picocolors28.default.yellow("[!]")} ${w3}`);
105741
+ f2.warn(` ${import_picocolors30.default.yellow("[!]")} ${w3}`);
104948
105742
  }
104949
105743
  }
104950
105744
  }
104951
105745
  }
104952
105746
  if (skipped.length > 0) {
104953
105747
  for (const r2 of skipped) {
104954
- f2.info(`${import_picocolors28.default.yellow("[i]")} ${r2.providerDisplayName}: ${import_picocolors28.default.dim(r2.skipReason || "Skipped")}`);
105748
+ f2.info(`${import_picocolors30.default.yellow("[i]")} ${r2.providerDisplayName}: ${import_picocolors30.default.dim(r2.skipReason || "Skipped")}`);
104955
105749
  }
104956
105750
  }
104957
105751
  if (failed.length > 0) {
104958
105752
  for (const r2 of failed) {
104959
- f2.error(`${import_picocolors28.default.red("[X]")} ${r2.providerDisplayName}: ${import_picocolors28.default.dim(r2.error || "Failed")}`);
105753
+ f2.error(`${import_picocolors30.default.red("[X]")} ${r2.providerDisplayName}: ${import_picocolors30.default.dim(r2.error || "Failed")}`);
104960
105754
  }
104961
105755
  }
104962
105756
  console.log();
@@ -104967,24 +105761,69 @@ function displayResults3(results) {
104967
105761
  summaryParts.push(`${skipped.length} skipped`);
104968
105762
  if (failed.length > 0)
104969
105763
  summaryParts.push(`${failed.length} failed`);
104970
- if (summaryParts.length === 0) {
104971
- $e(import_picocolors28.default.yellow("No installations performed"));
104972
- } else if (failed.length > 0 && successful.length === 0) {
104973
- $e(import_picocolors28.default.red("Migrate failed"));
105764
+ if (summaryParts.length === 0) {} else if (failed.length > 0 && successful.length === 0) {
104974
105765
  process.exit(1);
104975
- } else {
104976
- $e(import_picocolors28.default.green(`Done! ${summaryParts.join(", ")}`));
104977
105766
  }
104978
105767
  }
105768
+ function annotateInstallResults(results, portableType, itemName) {
105769
+ return results.map((result) => ({
105770
+ ...result,
105771
+ itemName,
105772
+ operation: "apply",
105773
+ portableType
105774
+ }));
105775
+ }
105776
+ function progressLabelForType(type) {
105777
+ switch (type) {
105778
+ case "agent":
105779
+ return "Agents";
105780
+ case "command":
105781
+ return "Commands";
105782
+ case "config":
105783
+ return "Config";
105784
+ case "rules":
105785
+ return "Rules";
105786
+ case "hooks":
105787
+ return "Hooks";
105788
+ case "skill":
105789
+ return "Skills";
105790
+ default:
105791
+ return "Migrating";
105792
+ }
105793
+ }
105794
+ function buildDryRunFallbackResults(skills, selectedProviders, installGlobally, plannedActions) {
105795
+ const plannedSkillActions = plannedActions.filter((action) => action.type === "skill").length;
105796
+ if (skills.length === 0 || plannedSkillActions > 0) {
105797
+ return [];
105798
+ }
105799
+ const results = [];
105800
+ for (const provider of selectedProviders.filter((entry) => getProvidersSupporting("skills").includes(entry))) {
105801
+ const basePath = getPortableBasePath(provider, "skills", { global: installGlobally });
105802
+ if (!basePath)
105803
+ continue;
105804
+ for (const skill of skills) {
105805
+ results.push({
105806
+ itemName: skill.name,
105807
+ operation: "apply",
105808
+ path: join139(basePath, skill.name),
105809
+ portableType: "skill",
105810
+ provider,
105811
+ providerDisplayName: providers[provider].displayName,
105812
+ success: true
105813
+ });
105814
+ }
105815
+ }
105816
+ return results;
105817
+ }
104979
105818
  // src/commands/new/new-command.ts
104980
105819
  init_logger();
104981
105820
  init_safe_prompts();
104982
105821
  init_types3();
104983
- var import_picocolors29 = __toESM(require_picocolors(), 1);
105822
+ var import_picocolors31 = __toESM(require_picocolors(), 1);
104984
105823
 
104985
105824
  // src/commands/new/phases/directory-setup.ts
104986
105825
  init_config_manager();
104987
- import { resolve as resolve36 } from "node:path";
105826
+ import { resolve as resolve37 } from "node:path";
104988
105827
  init_logger();
104989
105828
  init_path_resolver();
104990
105829
  init_types3();
@@ -105069,7 +105908,7 @@ async function directorySetup(validOptions, prompts) {
105069
105908
  targetDir = await prompts.getDirectory(targetDir);
105070
105909
  }
105071
105910
  }
105072
- const resolvedDir = resolve36(targetDir);
105911
+ const resolvedDir = resolve37(targetDir);
105073
105912
  logger.info(`Target directory: ${resolvedDir}`);
105074
105913
  if (PathResolver.isLocalSameAsGlobal(resolvedDir)) {
105075
105914
  logger.warning("You're creating a project at HOME directory.");
@@ -105394,7 +106233,7 @@ Please use only one download method.`);
105394
106233
  if (ctx.cancelled)
105395
106234
  return;
105396
106235
  prompts.outro(`✨ Project created successfully at ${ctx.resolvedDir}`);
105397
- log.info(`${import_picocolors29.default.dim("Tip:")} To update later: ${import_picocolors29.default.cyan("ck update")} (CLI) + ${import_picocolors29.default.cyan("ck init")} (kit content)`);
106236
+ log.info(`${import_picocolors31.default.dim("Tip:")} To update later: ${import_picocolors31.default.cyan("ck update")} (CLI) + ${import_picocolors31.default.cyan("ck init")} (kit content)`);
105398
106237
  } catch (error) {
105399
106238
  logger.error(error instanceof Error ? error.message : "Unknown error occurred");
105400
106239
  process.exit(1);
@@ -105403,7 +106242,7 @@ Please use only one download method.`);
105403
106242
  // src/commands/plan/plan-command.ts
105404
106243
  init_output_manager();
105405
106244
  import { existsSync as existsSync65, statSync as statSync11 } from "node:fs";
105406
- import { dirname as dirname41, isAbsolute as isAbsolute11, join as join144, parse as parse7, resolve as resolve40 } from "node:path";
106245
+ import { dirname as dirname42, isAbsolute as isAbsolute11, join as join144, parse as parse7, resolve as resolve41 } from "node:path";
105407
106246
 
105408
106247
  // src/commands/plan/plan-read-handlers.ts
105409
106248
  init_config();
@@ -105411,20 +106250,20 @@ init_plan_parser();
105411
106250
  init_plans_registry();
105412
106251
  init_logger();
105413
106252
  init_output_manager();
105414
- var import_picocolors30 = __toESM(require_picocolors(), 1);
106253
+ var import_picocolors32 = __toESM(require_picocolors(), 1);
105415
106254
  import { existsSync as existsSync64, statSync as statSync10 } from "node:fs";
105416
- import { basename as basename26, dirname as dirname39, join as join143, relative as relative27, resolve as resolve38 } from "node:path";
106255
+ import { basename as basename27, dirname as dirname40, join as join143, relative as relative27, resolve as resolve39 } from "node:path";
105417
106256
 
105418
106257
  // src/commands/plan/plan-dependencies.ts
105419
106258
  init_config();
105420
106259
  init_plan_parser();
105421
106260
  init_plans_registry();
105422
106261
  import { existsSync as existsSync63 } from "node:fs";
105423
- import { dirname as dirname38, join as join142 } from "node:path";
106262
+ import { dirname as dirname39, join as join142 } from "node:path";
105424
106263
  async function resolvePlanDependencies(references, currentPlanFile, options2 = {}) {
105425
106264
  if (references.length === 0)
105426
106265
  return [];
105427
- const currentPlanDir = dirname38(currentPlanFile);
106266
+ const currentPlanDir = dirname39(currentPlanFile);
105428
106267
  const projectRoot = findProjectRoot(currentPlanDir);
105429
106268
  const config = options2.preloadedConfig ?? (await CkConfigManager.loadFull(projectRoot)).config;
105430
106269
  const defaultScope = inferPlanScopeForDir(currentPlanDir, config);
@@ -105471,14 +106310,14 @@ init_config();
105471
106310
  init_plan_parser();
105472
106311
  init_plan_scope();
105473
106312
  init_plans_registry();
105474
- import { isAbsolute as isAbsolute10, resolve as resolve37 } from "node:path";
106313
+ import { isAbsolute as isAbsolute10, resolve as resolve38 } from "node:path";
105475
106314
  async function getGlobalPlansDirFromCwd() {
105476
106315
  const projectRoot = findProjectRoot(process.cwd());
105477
106316
  const { config } = await CkConfigManager.loadFull(projectRoot);
105478
106317
  return resolveGlobalPlansDir(config);
105479
106318
  }
105480
106319
  function resolveTargetFromBase(target, baseDir) {
105481
- const resolvedTarget = isAbsolute10(target) ? resolve37(target) : resolve37(baseDir, target);
106320
+ const resolvedTarget = isAbsolute10(target) ? resolve38(target) : resolve38(baseDir, target);
105482
106321
  return isWithinDir(resolvedTarget, baseDir) ? resolvedTarget : null;
105483
106322
  }
105484
106323
 
@@ -105511,9 +106350,9 @@ async function handleParse(target, options2) {
105511
106350
  console.log(JSON.stringify({ file: relative27(process.cwd(), planFile), frontmatter, phases }, null, 2));
105512
106351
  return;
105513
106352
  }
105514
- const title = typeof frontmatter.title === "string" ? frontmatter.title : basename26(dirname39(planFile));
106353
+ const title = typeof frontmatter.title === "string" ? frontmatter.title : basename27(dirname40(planFile));
105515
106354
  console.log();
105516
- console.log(import_picocolors30.default.bold(` Plan: ${title}`));
106355
+ console.log(import_picocolors32.default.bold(` Plan: ${title}`));
105517
106356
  console.log(` File: ${planFile}`);
105518
106357
  console.log(` Phases found: ${phases.length}`);
105519
106358
  console.log();
@@ -105552,7 +106391,7 @@ async function handleValidate(target, options2) {
105552
106391
  return;
105553
106392
  }
105554
106393
  console.log();
105555
- console.log(import_picocolors30.default.bold(` Validating: ${planFile}`));
106394
+ console.log(import_picocolors32.default.bold(` Validating: ${planFile}`));
105556
106395
  console.log();
105557
106396
  if (result.issues.length === 0) {
105558
106397
  console.log(` [OK] No issues found — ${result.phases.length} phases detected`);
@@ -105566,7 +106405,7 @@ async function handleValidate(target, options2) {
105566
106405
  }
105567
106406
  }
105568
106407
  console.log();
105569
- const validStr = result.valid ? import_picocolors30.default.green("[OK] Valid") : import_picocolors30.default.red("[X] Invalid");
106408
+ const validStr = result.valid ? import_picocolors32.default.green("[OK] Valid") : import_picocolors32.default.red("[X] Invalid");
105570
106409
  console.log(` ${validStr} — ${result.issues.filter((i) => i.severity === "error").length} errors, ${result.issues.filter((i) => i.severity === "warning").length} warnings`);
105571
106410
  console.log();
105572
106411
  if (!result.valid)
@@ -105581,7 +106420,7 @@ async function handleStatus(target, options2) {
105581
106420
  return;
105582
106421
  }
105583
106422
  const effectiveTarget = !resolvedTarget && globalBaseDir ? globalBaseDir : resolvedTarget;
105584
- const t = effectiveTarget ? resolve38(effectiveTarget) : null;
106423
+ const t = effectiveTarget ? resolve39(effectiveTarget) : null;
105585
106424
  const plansDir = t && existsSync64(t) && statSync10(t).isDirectory() && !existsSync64(join143(t, "plan.md")) ? t : null;
105586
106425
  if (plansDir) {
105587
106426
  const planFiles = scanPlanDir(plansDir);
@@ -105614,7 +106453,7 @@ async function handleStatus(target, options2) {
105614
106453
  return;
105615
106454
  }
105616
106455
  console.log();
105617
- console.log(import_picocolors30.default.bold(` Plans in: ${plansDir}`));
106456
+ console.log(import_picocolors32.default.bold(` Plans in: ${plansDir}`));
105618
106457
  console.log();
105619
106458
  for (const pf of planFiles) {
105620
106459
  try {
@@ -105622,8 +106461,8 @@ async function handleStatus(target, options2) {
105622
106461
  const blockedBy2 = await resolvePlanDependencies(s.blockedBy, pf, { preloadedConfig });
105623
106462
  const blocks2 = await resolvePlanDependencies(s.blocks, pf, { preloadedConfig });
105624
106463
  const bar = progressBar(s.completed, s.totalPhases);
105625
- const title2 = s.title ?? basename26(dirname39(pf));
105626
- console.log(` ${import_picocolors30.default.bold(title2)}`);
106464
+ const title2 = s.title ?? basename27(dirname40(pf));
106465
+ console.log(` ${import_picocolors32.default.bold(title2)}`);
105627
106466
  console.log(` ${bar}`);
105628
106467
  if (s.inProgress > 0)
105629
106468
  console.log(` [~] ${s.inProgress} in progress`);
@@ -105641,7 +106480,7 @@ async function handleStatus(target, options2) {
105641
106480
  }
105642
106481
  console.log();
105643
106482
  } catch {
105644
- console.log(` [X] Failed to read: ${basename26(dirname39(pf))}`);
106483
+ console.log(` [X] Failed to read: ${basename27(dirname40(pf))}`);
105645
106484
  console.log();
105646
106485
  }
105647
106486
  }
@@ -105668,9 +106507,9 @@ async function handleStatus(target, options2) {
105668
106507
  console.log(JSON.stringify({ ...summary, dependencyStatus: { blockedBy, blocks } }, null, 2));
105669
106508
  return;
105670
106509
  }
105671
- const title = summary.title ?? basename26(dirname39(planFile));
106510
+ const title = summary.title ?? basename27(dirname40(planFile));
105672
106511
  console.log();
105673
- console.log(import_picocolors30.default.bold(` ${title}`));
106512
+ console.log(import_picocolors32.default.bold(` ${title}`));
105674
106513
  if (summary.status)
105675
106514
  console.log(` Status: ${summary.status}`);
105676
106515
  console.log();
@@ -105731,22 +106570,22 @@ async function handleKanban(target, options2) {
105731
106570
  process.exitCode = 1;
105732
106571
  return;
105733
106572
  }
105734
- const route = `/plans?dir=${encodeURIComponent(dirname39(dirname39(planFile)))}&view=kanban`;
106573
+ const route = `/plans?dir=${encodeURIComponent(dirname40(dirname40(planFile)))}&view=kanban`;
105735
106574
  const url = `http://localhost:${server.port}${route}`;
105736
106575
  console.log();
105737
- console.log(import_picocolors30.default.bold(" ClaudeKit Dashboard — Plans"));
105738
- console.log(import_picocolors30.default.dim(" ──────────────────────────────"));
105739
- console.log(` Local: ${import_picocolors30.default.cyan(url)}`);
106576
+ console.log(import_picocolors32.default.bold(" ClaudeKit Dashboard — Plans"));
106577
+ console.log(import_picocolors32.default.dim(" ──────────────────────────────"));
106578
+ console.log(` Local: ${import_picocolors32.default.cyan(url)}`);
105740
106579
  console.log(` File: ${planFile}`);
105741
106580
  console.log();
105742
- console.log(import_picocolors30.default.dim(" Press Ctrl+C to stop"));
106581
+ console.log(import_picocolors32.default.dim(" Press Ctrl+C to stop"));
105743
106582
  console.log();
105744
106583
  if (!noOpen) {
105745
106584
  try {
105746
106585
  const { default: open6 } = await Promise.resolve().then(() => (init_open(), exports_open));
105747
106586
  await open6(url);
105748
106587
  } catch {
105749
- console.log(import_picocolors30.default.dim(" [i] Could not open browser automatically"));
106588
+ console.log(import_picocolors32.default.dim(" [i] Could not open browser automatically"));
105750
106589
  }
105751
106590
  }
105752
106591
  await new Promise((resolvePromise) => {
@@ -105765,8 +106604,8 @@ async function handleKanban(target, options2) {
105765
106604
  init_plan_parser();
105766
106605
  init_plans_registry();
105767
106606
  init_output_manager();
105768
- var import_picocolors31 = __toESM(require_picocolors(), 1);
105769
- import { basename as basename27, dirname as dirname40, relative as relative28, resolve as resolve39 } from "node:path";
106607
+ var import_picocolors33 = __toESM(require_picocolors(), 1);
106608
+ import { basename as basename28, dirname as dirname41, relative as relative28, resolve as resolve40 } from "node:path";
105770
106609
  async function handleCreate(target, options2) {
105771
106610
  if (!options2.title) {
105772
106611
  output.error("[X] --title is required for create");
@@ -105798,13 +106637,13 @@ async function handleCreate(target, options2) {
105798
106637
  return;
105799
106638
  }
105800
106639
  const globalBaseDir = options2.global ? await getGlobalPlansDirFromCwd() : undefined;
105801
- const resolvedDir = globalBaseDir ? resolveTargetFromBase(dir, globalBaseDir) : resolve39(dir);
106640
+ const resolvedDir = globalBaseDir ? resolveTargetFromBase(dir, globalBaseDir) : resolve40(dir);
105802
106641
  if (globalBaseDir && !resolvedDir) {
105803
106642
  output.error("[X] Target directory must stay within the configured global plans root");
105804
106643
  process.exitCode = 1;
105805
106644
  return;
105806
106645
  }
105807
- const safeResolvedDir = resolvedDir ?? resolve39(dir);
106646
+ const safeResolvedDir = resolvedDir ?? resolve40(dir);
105808
106647
  const result = scaffoldPlan({
105809
106648
  title: options2.title,
105810
106649
  phases: phaseNames.map((name2) => ({ name: name2 })),
@@ -105838,11 +106677,11 @@ async function handleCreate(target, options2) {
105838
106677
  return;
105839
106678
  }
105840
106679
  console.log();
105841
- console.log(import_picocolors31.default.bold(` [OK] Plan created: ${options2.title}`));
106680
+ console.log(import_picocolors33.default.bold(` [OK] Plan created: ${options2.title}`));
105842
106681
  console.log(` Directory: ${safeResolvedDir}`);
105843
106682
  console.log(` Phases: ${result.phaseFiles.length}`);
105844
106683
  for (const f3 of result.phaseFiles) {
105845
- console.log(` [ ] ${basename27(f3)}`);
106684
+ console.log(` [ ] ${basename28(f3)}`);
105846
106685
  }
105847
106686
  console.log();
105848
106687
  }
@@ -105866,7 +106705,7 @@ async function handleCheck(target, options2) {
105866
106705
  process.exitCode = 1;
105867
106706
  return;
105868
106707
  }
105869
- const planDir = dirname40(planFile);
106708
+ const planDir = dirname41(planFile);
105870
106709
  let planStatus = "pending";
105871
106710
  try {
105872
106711
  const projectRoot = findProjectRoot(planDir);
@@ -105915,7 +106754,7 @@ async function handleUncheck(target, options2) {
105915
106754
  process.exitCode = 1;
105916
106755
  return;
105917
106756
  }
105918
- const planDir = dirname40(planFile);
106757
+ const planDir = dirname41(planFile);
105919
106758
  try {
105920
106759
  const projectRoot = findProjectRoot(planDir);
105921
106760
  const summary = buildPlanSummary(planFile);
@@ -105954,7 +106793,7 @@ async function handleAddPhase(target, options2) {
105954
106793
  try {
105955
106794
  const result = addPhase(planFile, target, options2.after);
105956
106795
  try {
105957
- const planDir = dirname40(planFile);
106796
+ const planDir = dirname41(planFile);
105958
106797
  const projectRoot = findProjectRoot(planDir);
105959
106798
  updateRegistryAddPhase({
105960
106799
  planDir,
@@ -105980,19 +106819,19 @@ async function handleAddPhase(target, options2) {
105980
106819
  // src/commands/plan/plan-command.ts
105981
106820
  function resolveTargetPath(target, baseDir) {
105982
106821
  if (!baseDir) {
105983
- return resolve40(target);
106822
+ return resolve41(target);
105984
106823
  }
105985
106824
  if (isAbsolute11(target)) {
105986
- return resolve40(target);
106825
+ return resolve41(target);
105987
106826
  }
105988
- const cwdCandidate = resolve40(target);
106827
+ const cwdCandidate = resolve41(target);
105989
106828
  if (existsSync65(cwdCandidate)) {
105990
106829
  return cwdCandidate;
105991
106830
  }
105992
- return resolve40(baseDir, target);
106831
+ return resolve41(baseDir, target);
105993
106832
  }
105994
106833
  function resolvePlanFile(target, baseDir) {
105995
- const t = target ? resolveTargetPath(target, baseDir) : baseDir ? resolve40(baseDir) : process.cwd();
106834
+ const t = target ? resolveTargetPath(target, baseDir) : baseDir ? resolve41(baseDir) : process.cwd();
105996
106835
  if (existsSync65(t)) {
105997
106836
  const stat23 = statSync11(t);
105998
106837
  if (stat23.isFile())
@@ -106008,7 +106847,7 @@ function resolvePlanFile(target, baseDir) {
106008
106847
  const candidate = join144(dir, "plan.md");
106009
106848
  if (existsSync65(candidate))
106010
106849
  return candidate;
106011
- dir = dirname41(dir);
106850
+ dir = dirname42(dir);
106012
106851
  }
106013
106852
  }
106014
106853
  return null;
@@ -106056,7 +106895,7 @@ async function planCommand(action, target, options2) {
106056
106895
  let resolvedTarget = target;
106057
106896
  if (resolvedAction && !knownActions.has(resolvedAction)) {
106058
106897
  const looksLikePath = resolvedAction.includes("/") || resolvedAction.includes("\\") || resolvedAction.endsWith(".md") || resolvedAction === "." || resolvedAction === "..";
106059
- const existsOnDisk = !looksLikePath && existsSync65(resolve40(resolvedAction));
106898
+ const existsOnDisk = !looksLikePath && existsSync65(resolve41(resolvedAction));
106060
106899
  if (looksLikePath || existsOnDisk) {
106061
106900
  resolvedTarget = resolvedAction;
106062
106901
  resolvedAction = undefined;
@@ -106097,13 +106936,13 @@ async function planCommand(action, target, options2) {
106097
106936
  init_claudekit_data2();
106098
106937
  init_logger();
106099
106938
  init_safe_prompts();
106100
- var import_picocolors32 = __toESM(require_picocolors(), 1);
106939
+ var import_picocolors34 = __toESM(require_picocolors(), 1);
106101
106940
  import { existsSync as existsSync66 } from "node:fs";
106102
- import { resolve as resolve41 } from "node:path";
106941
+ import { resolve as resolve42 } from "node:path";
106103
106942
  async function handleAdd(projectPath, options2) {
106104
106943
  logger.debug(`Adding project: ${projectPath}, options: ${JSON.stringify(options2)}`);
106105
106944
  intro("Add Project");
106106
- const absolutePath = resolve41(projectPath);
106945
+ const absolutePath = resolve42(projectPath);
106107
106946
  if (!existsSync66(absolutePath)) {
106108
106947
  log.error(`Path does not exist: ${absolutePath}`);
106109
106948
  process.exitCode = 1;
@@ -106115,10 +106954,10 @@ async function handleAdd(projectPath, options2) {
106115
106954
  const existing = await ProjectsRegistryManager.getProject(absolutePath);
106116
106955
  if (existing) {
106117
106956
  console.log();
106118
- console.log(import_picocolors32.default.dim(" Existing registration:"));
106119
- console.log(import_picocolors32.default.dim(` Alias: ${import_picocolors32.default.cyan(existing.alias)}`));
106120
- console.log(import_picocolors32.default.dim(` Path: ${existing.path}`));
106121
- console.log(import_picocolors32.default.dim(` ID: ${existing.id}`));
106957
+ console.log(import_picocolors34.default.dim(" Existing registration:"));
106958
+ console.log(import_picocolors34.default.dim(` Alias: ${import_picocolors34.default.cyan(existing.alias)}`));
106959
+ console.log(import_picocolors34.default.dim(` Path: ${existing.path}`));
106960
+ console.log(import_picocolors34.default.dim(` ID: ${existing.id}`));
106122
106961
  console.log();
106123
106962
  }
106124
106963
  process.exitCode = 1;
@@ -106133,15 +106972,15 @@ async function handleAdd(projectPath, options2) {
106133
106972
  });
106134
106973
  log.success("Project registered successfully");
106135
106974
  console.log();
106136
- console.log(import_picocolors32.default.dim(" Details:"));
106137
- console.log(import_picocolors32.default.dim(` Alias: ${import_picocolors32.default.cyan(project.alias)}`));
106138
- console.log(import_picocolors32.default.dim(` Path: ${project.path}`));
106139
- console.log(import_picocolors32.default.dim(` ID: ${project.id}`));
106975
+ console.log(import_picocolors34.default.dim(" Details:"));
106976
+ console.log(import_picocolors34.default.dim(` Alias: ${import_picocolors34.default.cyan(project.alias)}`));
106977
+ console.log(import_picocolors34.default.dim(` Path: ${project.path}`));
106978
+ console.log(import_picocolors34.default.dim(` ID: ${project.id}`));
106140
106979
  if (project.pinned) {
106141
- console.log(import_picocolors32.default.dim(` Pinned: ${import_picocolors32.default.yellow("Yes")}`));
106980
+ console.log(import_picocolors34.default.dim(` Pinned: ${import_picocolors34.default.yellow("Yes")}`));
106142
106981
  }
106143
106982
  if (project.tags?.length) {
106144
- console.log(import_picocolors32.default.dim(` Tags: ${project.tags.join(", ")}`));
106983
+ console.log(import_picocolors34.default.dim(` Tags: ${project.tags.join(", ")}`));
106145
106984
  }
106146
106985
  console.log();
106147
106986
  outro("Done!");
@@ -106154,7 +106993,7 @@ async function handleAdd(projectPath, options2) {
106154
106993
  // src/commands/projects/list-handler.ts
106155
106994
  init_claudekit_data2();
106156
106995
  init_logger();
106157
- var import_picocolors33 = __toESM(require_picocolors(), 1);
106996
+ var import_picocolors35 = __toESM(require_picocolors(), 1);
106158
106997
  async function handleList(options2) {
106159
106998
  logger.debug(`Listing projects: ${JSON.stringify(options2)}`);
106160
106999
  const projects = await ProjectsRegistryManager.listProjects({
@@ -106166,25 +107005,25 @@ async function handleList(options2) {
106166
107005
  }
106167
107006
  if (projects.length === 0) {
106168
107007
  console.log();
106169
- console.log(import_picocolors33.default.yellow("No projects registered yet."));
107008
+ console.log(import_picocolors35.default.yellow("No projects registered yet."));
106170
107009
  console.log();
106171
- console.log(import_picocolors33.default.dim(" Add a project with:"));
106172
- console.log(import_picocolors33.default.dim(" ck projects add <path>"));
107010
+ console.log(import_picocolors35.default.dim(" Add a project with:"));
107011
+ console.log(import_picocolors35.default.dim(" ck projects add <path>"));
106173
107012
  console.log();
106174
107013
  return;
106175
107014
  }
106176
107015
  console.log();
106177
- console.log(import_picocolors33.default.bold(`Registered Projects (${projects.length})`));
107016
+ console.log(import_picocolors35.default.bold(`Registered Projects (${projects.length})`));
106178
107017
  console.log();
106179
107018
  const aliasWidth = Math.max(5, ...projects.map((p) => p.alias.length));
106180
107019
  const pathWidth = Math.max(4, ...projects.map((p) => p.path.length));
106181
- console.log(import_picocolors33.default.dim(` ${"ALIAS".padEnd(aliasWidth)} ${"PATH".padEnd(pathWidth)} PINNED TAGS`));
106182
- console.log(import_picocolors33.default.dim(` ${"-".repeat(aliasWidth + pathWidth + 20)}`));
107020
+ console.log(import_picocolors35.default.dim(` ${"ALIAS".padEnd(aliasWidth)} ${"PATH".padEnd(pathWidth)} PINNED TAGS`));
107021
+ console.log(import_picocolors35.default.dim(` ${"-".repeat(aliasWidth + pathWidth + 20)}`));
106183
107022
  for (const project of projects) {
106184
- const alias = import_picocolors33.default.cyan(project.alias.padEnd(aliasWidth));
106185
- const path16 = import_picocolors33.default.dim(project.path.padEnd(pathWidth));
106186
- const pinned = project.pinned ? import_picocolors33.default.yellow("\uD83D\uDCCC") : " ";
106187
- const tags = project.tags?.length ? import_picocolors33.default.gray(project.tags.join(", ")) : import_picocolors33.default.dim("-");
107023
+ const alias = import_picocolors35.default.cyan(project.alias.padEnd(aliasWidth));
107024
+ const path16 = import_picocolors35.default.dim(project.path.padEnd(pathWidth));
107025
+ const pinned = project.pinned ? import_picocolors35.default.yellow("\uD83D\uDCCC") : " ";
107026
+ const tags = project.tags?.length ? import_picocolors35.default.gray(project.tags.join(", ")) : import_picocolors35.default.dim("-");
106188
107027
  console.log(` ${alias} ${path16} ${pinned} ${tags}`);
106189
107028
  }
106190
107029
  console.log();
@@ -106194,7 +107033,7 @@ async function handleList(options2) {
106194
107033
  init_claudekit_data2();
106195
107034
  init_logger();
106196
107035
  init_safe_prompts();
106197
- var import_picocolors34 = __toESM(require_picocolors(), 1);
107036
+ var import_picocolors36 = __toESM(require_picocolors(), 1);
106198
107037
  async function handleRemove(aliasOrPath, options2) {
106199
107038
  logger.debug(`Removing project: ${aliasOrPath}, options: ${JSON.stringify(options2)}`);
106200
107039
  intro("Remove Project");
@@ -106213,7 +107052,7 @@ async function handleRemove(aliasOrPath, options2) {
106213
107052
  message: "Select a project to remove",
106214
107053
  options: projects.map((p) => ({
106215
107054
  value: p.id,
106216
- label: `${import_picocolors34.default.cyan(p.alias)} ${import_picocolors34.default.dim(`(${p.path})`)}`
107055
+ label: `${import_picocolors36.default.cyan(p.alias)} ${import_picocolors36.default.dim(`(${p.path})`)}`
106217
107056
  }))
106218
107057
  });
106219
107058
  if (lD(selected)) {
@@ -106230,10 +107069,10 @@ async function handleRemove(aliasOrPath, options2) {
106230
107069
  return;
106231
107070
  }
106232
107071
  console.log();
106233
- console.log(import_picocolors34.default.dim(" Project to remove:"));
106234
- console.log(import_picocolors34.default.dim(` Alias: ${import_picocolors34.default.cyan(project.alias)}`));
106235
- console.log(import_picocolors34.default.dim(` Path: ${project.path}`));
106236
- console.log(import_picocolors34.default.dim(` ID: ${project.id}`));
107072
+ console.log(import_picocolors36.default.dim(" Project to remove:"));
107073
+ console.log(import_picocolors36.default.dim(` Alias: ${import_picocolors36.default.cyan(project.alias)}`));
107074
+ console.log(import_picocolors36.default.dim(` Path: ${project.path}`));
107075
+ console.log(import_picocolors36.default.dim(` ID: ${project.id}`));
106237
107076
  console.log();
106238
107077
  const confirmed = await se({
106239
107078
  message: "Are you sure you want to remove this project?",
@@ -106526,7 +107365,7 @@ init_skills_installer();
106526
107365
  init_skills_registry();
106527
107366
  init_skills_uninstaller();
106528
107367
  var import_gray_matter11 = __toESM(require_gray_matter(), 1);
106529
- var import_picocolors35 = __toESM(require_picocolors(), 1);
107368
+ var import_picocolors37 = __toESM(require_picocolors(), 1);
106530
107369
  import { readFile as readFile60 } from "node:fs/promises";
106531
107370
  import { join as join145 } from "node:path";
106532
107371
 
@@ -106596,17 +107435,17 @@ async function handleCatalog(sourcePath, regenerate) {
106596
107435
  categories.set(cat, (categories.get(cat) ?? 0) + 1);
106597
107436
  }
106598
107437
  console.log();
106599
- f2.step(import_picocolors35.default.bold("Skill Catalog"));
107438
+ f2.step(import_picocolors37.default.bold("Skill Catalog"));
106600
107439
  console.log();
106601
- console.log(` ${import_picocolors35.default.cyan("Skills:")} ${catalog.skillCount}`);
106602
- console.log(` ${import_picocolors35.default.cyan("Generated:")} ${new Date(catalog.generated).toLocaleString()}`);
106603
- console.log(` ${import_picocolors35.default.cyan("Version:")} ${catalog.version}`);
107440
+ console.log(` ${import_picocolors37.default.cyan("Skills:")} ${catalog.skillCount}`);
107441
+ console.log(` ${import_picocolors37.default.cyan("Generated:")} ${new Date(catalog.generated).toLocaleString()}`);
107442
+ console.log(` ${import_picocolors37.default.cyan("Version:")} ${catalog.version}`);
106604
107443
  if (categories.size > 0) {
106605
107444
  console.log();
106606
- f2.step(import_picocolors35.default.bold("Categories"));
107445
+ f2.step(import_picocolors37.default.bold("Categories"));
106607
107446
  console.log();
106608
107447
  for (const [cat, count] of [...categories.entries()].sort((a3, b3) => b3[1] - a3[1])) {
106609
- console.log(` ${import_picocolors35.default.dim("•")} ${cat}: ${count}`);
107448
+ console.log(` ${import_picocolors37.default.dim("•")} ${cat}: ${count}`);
106610
107449
  }
106611
107450
  }
106612
107451
  console.log();
@@ -106633,13 +107472,13 @@ async function handleSearch(sourcePath, query, options2) {
106633
107472
  return;
106634
107473
  }
106635
107474
  console.log();
106636
- f2.step(import_picocolors35.default.bold(`Search: "${safeQuery}"`));
107475
+ f2.step(import_picocolors37.default.bold(`Search: "${safeQuery}"`));
106637
107476
  console.log();
106638
107477
  for (const r2 of results) {
106639
107478
  const score = r2.score.toFixed(3);
106640
- const cat = r2.category ? import_picocolors35.default.dim(` [${r2.category}]`) : "";
106641
- console.log(` ${import_picocolors35.default.cyan(r2.name)} ${import_picocolors35.default.dim(`(${score})`)}${cat}`);
106642
- console.log(` ${import_picocolors35.default.dim(r2.description)}`);
107479
+ const cat = r2.category ? import_picocolors37.default.dim(` [${r2.category}]`) : "";
107480
+ console.log(` ${import_picocolors37.default.cyan(r2.name)} ${import_picocolors37.default.dim(`(${score})`)}${cat}`);
107481
+ console.log(` ${import_picocolors37.default.dim(r2.description)}`);
106643
107482
  }
106644
107483
  console.log();
106645
107484
  }
@@ -106660,11 +107499,11 @@ async function handleValidate2(sourcePath) {
106660
107499
  if (unknown.length > 0) {
106661
107500
  if (!hasIssues)
106662
107501
  console.log();
106663
- f2.warn(`${import_picocolors35.default.cyan(skill.name)}: unknown fields: ${unknown.join(", ")}`);
107502
+ f2.warn(`${import_picocolors37.default.cyan(skill.name)}: unknown fields: ${unknown.join(", ")}`);
106664
107503
  hasIssues = true;
106665
107504
  }
106666
107505
  } catch {
106667
- f2.warn(`${import_picocolors35.default.cyan(skill.name)}: could not read SKILL.md`);
107506
+ f2.warn(`${import_picocolors37.default.cyan(skill.name)}: could not read SKILL.md`);
106668
107507
  hasIssues = true;
106669
107508
  }
106670
107509
  }
@@ -106692,7 +107531,7 @@ async function listSkills2(showInstalled) {
106692
107531
  return;
106693
107532
  }
106694
107533
  console.log();
106695
- f2.step(import_picocolors35.default.bold("Installed Skills"));
107534
+ f2.step(import_picocolors37.default.bold("Installed Skills"));
106696
107535
  console.log();
106697
107536
  const bySkill = new Map;
106698
107537
  for (const inst of installations) {
@@ -106701,14 +107540,14 @@ async function listSkills2(showInstalled) {
106701
107540
  bySkill.set(inst.skill, list3);
106702
107541
  }
106703
107542
  for (const [skill, installs] of bySkill) {
106704
- console.log(` ${import_picocolors35.default.cyan(skill)}`);
107543
+ console.log(` ${import_picocolors37.default.cyan(skill)}`);
106705
107544
  for (const inst of installs) {
106706
107545
  const scope = inst.global ? "global" : "project";
106707
- console.log(` ${import_picocolors35.default.dim("→")} ${inst.agent} (${scope}): ${import_picocolors35.default.dim(inst.path)}`);
107546
+ console.log(` ${import_picocolors37.default.dim("→")} ${inst.agent} (${scope}): ${import_picocolors37.default.dim(inst.path)}`);
106708
107547
  }
106709
107548
  }
106710
107549
  console.log();
106711
- console.log(import_picocolors35.default.dim(` ${installations.length} installation(s) across ${bySkill.size} skill(s)`));
107550
+ console.log(import_picocolors37.default.dim(` ${installations.length} installation(s) across ${bySkill.size} skill(s)`));
106712
107551
  console.log();
106713
107552
  return;
106714
107553
  }
@@ -106723,15 +107562,15 @@ async function listSkills2(showInstalled) {
106723
107562
  return;
106724
107563
  }
106725
107564
  console.log();
106726
- f2.step(import_picocolors35.default.bold("Available Skills"));
107565
+ f2.step(import_picocolors37.default.bold("Available Skills"));
106727
107566
  console.log();
106728
107567
  for (const skill of skills) {
106729
- console.log(` ${import_picocolors35.default.cyan(skill.name)}`);
106730
- console.log(` ${import_picocolors35.default.dim(skill.description)}`);
107568
+ console.log(` ${import_picocolors37.default.cyan(skill.name)}`);
107569
+ console.log(` ${import_picocolors37.default.dim(skill.description)}`);
106731
107570
  }
106732
107571
  console.log();
106733
- console.log(import_picocolors35.default.dim(` ${skills.length} skill(s) available`));
106734
- console.log(import_picocolors35.default.dim(` Source: ${sourcePath}`));
107572
+ console.log(import_picocolors37.default.dim(` ${skills.length} skill(s) available`));
107573
+ console.log(import_picocolors37.default.dim(` Source: ${sourcePath}`));
106735
107574
  console.log();
106736
107575
  }
106737
107576
  async function handleUninstall3(options2) {
@@ -106813,9 +107652,9 @@ async function handleUninstall3(options2) {
106813
107652
  process.exit(1);
106814
107653
  }
106815
107654
  console.log();
106816
- f2.step(import_picocolors35.default.bold("Will uninstall:"));
107655
+ f2.step(import_picocolors37.default.bold("Will uninstall:"));
106817
107656
  for (const inst of toRemove) {
106818
- f2.message(` ${import_picocolors35.default.red("✗")} ${inst.skill} → ${inst.agent}: ${import_picocolors35.default.dim(inst.path)}`);
107657
+ f2.message(` ${import_picocolors37.default.red("✗")} ${inst.skill} → ${inst.agent}: ${import_picocolors37.default.dim(inst.path)}`);
106819
107658
  }
106820
107659
  console.log();
106821
107660
  if (!options2.yes) {
@@ -106838,7 +107677,7 @@ async function handleUninstall3(options2) {
106838
107677
  }
106839
107678
  async function skillsCommand(options2) {
106840
107679
  console.log();
106841
- oe(import_picocolors35.default.bgCyan(import_picocolors35.default.black(" ck skills ")));
107680
+ oe(import_picocolors37.default.bgCyan(import_picocolors37.default.black(" ck skills ")));
106842
107681
  try {
106843
107682
  const baseOptions = SkillCommandOptionsSchema.parse(options2);
106844
107683
  const validOptions = {
@@ -106869,34 +107708,34 @@ async function skillsCommand(options2) {
106869
107708
  if (validOptions.search) {
106870
107709
  if (!sourcePath) {
106871
107710
  f2.error("No skills found. Install ClaudeKit Engineer first.");
106872
- $e(import_picocolors35.default.red("Search failed"));
107711
+ $e(import_picocolors37.default.red("Search failed"));
106873
107712
  process.exit(1);
106874
107713
  }
106875
107714
  await handleSearch(sourcePath, validOptions.search, {
106876
107715
  json: validOptions.json,
106877
107716
  limit: validOptions.limit
106878
107717
  });
106879
- $e(import_picocolors35.default.dim("Done"));
107718
+ $e(import_picocolors37.default.dim("Done"));
106880
107719
  return;
106881
107720
  }
106882
107721
  if (validOptions.catalog) {
106883
107722
  if (!sourcePath) {
106884
107723
  f2.error("No skills found. Install ClaudeKit Engineer first.");
106885
- $e(import_picocolors35.default.red("Catalog unavailable"));
107724
+ $e(import_picocolors37.default.red("Catalog unavailable"));
106886
107725
  process.exit(1);
106887
107726
  }
106888
107727
  await handleCatalog(sourcePath, validOptions.regenerate ?? false);
106889
- $e(import_picocolors35.default.dim(validOptions.regenerate ? "Catalog regenerated" : "Done"));
107728
+ $e(import_picocolors37.default.dim(validOptions.regenerate ? "Catalog regenerated" : "Done"));
106890
107729
  return;
106891
107730
  }
106892
107731
  if (validOptions.validate) {
106893
107732
  if (!sourcePath) {
106894
107733
  f2.error("No skills found. Install ClaudeKit Engineer first.");
106895
- $e(import_picocolors35.default.red("Validation failed"));
107734
+ $e(import_picocolors37.default.red("Validation failed"));
106896
107735
  process.exit(1);
106897
107736
  }
106898
107737
  await handleValidate2(sourcePath);
106899
- $e(import_picocolors35.default.dim("Validation complete"));
107738
+ $e(import_picocolors37.default.dim("Validation complete"));
106900
107739
  return;
106901
107740
  }
106902
107741
  if (validOptions.sync) {
@@ -106909,28 +107748,28 @@ async function skillsCommand(options2) {
106909
107748
  } else {
106910
107749
  f2.info("Registry is in sync");
106911
107750
  }
106912
- $e(import_picocolors35.default.green("Done!"));
107751
+ $e(import_picocolors37.default.green("Done!"));
106913
107752
  return;
106914
107753
  }
106915
107754
  if (validOptions.uninstall) {
106916
107755
  await handleUninstall3(validOptions);
106917
- $e(import_picocolors35.default.green("Done!"));
107756
+ $e(import_picocolors37.default.green("Done!"));
106918
107757
  return;
106919
107758
  }
106920
107759
  if (validOptions.list) {
106921
107760
  await listSkills2(validOptions.installed ?? false);
106922
- $e(import_picocolors35.default.dim("Use --name <skill> to install a specific skill"));
107761
+ $e(import_picocolors37.default.dim("Use --name <skill> to install a specific skill"));
106923
107762
  return;
106924
107763
  }
106925
107764
  if (!sourcePath) {
106926
107765
  f2.error("No skills found. Install ClaudeKit Engineer first.");
106927
- $e(import_picocolors35.default.red("Installation failed"));
107766
+ $e(import_picocolors37.default.red("Installation failed"));
106928
107767
  process.exit(1);
106929
107768
  }
106930
107769
  const availableSkills = await discoverSkills(sourcePath);
106931
107770
  if (availableSkills.length === 0) {
106932
107771
  f2.error("No valid skills found in source directory.");
106933
- $e(import_picocolors35.default.red("Installation failed"));
107772
+ $e(import_picocolors37.default.red("Installation failed"));
106934
107773
  process.exit(1);
106935
107774
  }
106936
107775
  const ctx = {
@@ -106946,7 +107785,7 @@ async function skillsCommand(options2) {
106946
107785
  const trimmedName = validOptions.name.trim();
106947
107786
  if (!trimmedName) {
106948
107787
  f2.error("Skill name cannot be empty");
106949
- $e(import_picocolors35.default.red("Installation failed"));
107788
+ $e(import_picocolors37.default.red("Installation failed"));
106950
107789
  process.exit(1);
106951
107790
  }
106952
107791
  const skill = await findSkillByName(trimmedName, sourcePath);
@@ -106956,15 +107795,15 @@ async function skillsCommand(options2) {
106956
107795
  for (const s of availableSkills) {
106957
107796
  f2.message(` - ${s.name}`);
106958
107797
  }
106959
- $e(import_picocolors35.default.red("Installation failed"));
107798
+ $e(import_picocolors37.default.red("Installation failed"));
106960
107799
  process.exit(1);
106961
107800
  }
106962
107801
  ctx.selectedSkills = [skill];
106963
- f2.info(`Skill: ${import_picocolors35.default.cyan(skill.name)}`);
106964
- f2.message(import_picocolors35.default.dim(skill.description));
107802
+ f2.info(`Skill: ${import_picocolors37.default.cyan(skill.name)}`);
107803
+ f2.message(import_picocolors37.default.dim(skill.description));
106965
107804
  } else if (availableSkills.length === 1) {
106966
107805
  ctx.selectedSkills = [availableSkills[0]];
106967
- f2.info(`Skill: ${import_picocolors35.default.cyan(ctx.selectedSkills[0].name)}`);
107806
+ f2.info(`Skill: ${import_picocolors37.default.cyan(ctx.selectedSkills[0].name)}`);
106968
107807
  } else if (validOptions.yes) {
106969
107808
  f2.error("--name required in non-interactive mode with multiple skills");
106970
107809
  process.exit(1);
@@ -107021,7 +107860,7 @@ async function skillsCommand(options2) {
107021
107860
  }
107022
107861
  } else if (ctx.detectedAgents.length === 1 || validOptions.yes) {
107023
107862
  ctx.selectedAgents = ctx.detectedAgents;
107024
- f2.info(`Installing to: ${ctx.detectedAgents.map((a3) => import_picocolors35.default.cyan(agents[a3].displayName)).join(", ")}`);
107863
+ f2.info(`Installing to: ${ctx.detectedAgents.map((a3) => import_picocolors37.default.cyan(agents[a3].displayName)).join(", ")}`);
107025
107864
  } else {
107026
107865
  const agentChoices = ctx.detectedAgents.map((a3) => ({
107027
107866
  value: a3,
@@ -107067,15 +107906,15 @@ async function skillsCommand(options2) {
107067
107906
  process.exit(1);
107068
107907
  }
107069
107908
  console.log();
107070
- f2.step(import_picocolors35.default.bold("Installation Summary"));
107909
+ f2.step(import_picocolors37.default.bold("Installation Summary"));
107071
107910
  for (const skill of ctx.selectedSkills) {
107072
- f2.message(` ${import_picocolors35.default.cyan(skill.name)}`);
107911
+ f2.message(` ${import_picocolors37.default.cyan(skill.name)}`);
107073
107912
  const preview = getInstallPreview(skill, ctx.selectedAgents, {
107074
107913
  global: ctx.installGlobally
107075
107914
  });
107076
107915
  for (const item of preview) {
107077
- const status = item.exists ? import_picocolors35.default.yellow(" (overwrite)") : "";
107078
- f2.message(` ${import_picocolors35.default.dim("→")} ${item.displayName}${status}`);
107916
+ const status = item.exists ? import_picocolors37.default.yellow(" (overwrite)") : "";
107917
+ f2.message(` ${import_picocolors37.default.dim("→")} ${item.displayName}${status}`);
107079
107918
  }
107080
107919
  }
107081
107920
  console.log();
@@ -107110,29 +107949,29 @@ async function skillsCommand(options2) {
107110
107949
  const skipped = results.filter((r2) => r2.skipped);
107111
107950
  const failed = results.filter((r2) => !r2.success);
107112
107951
  if (successful.length > 0) {
107113
- f2.success(`${import_picocolors35.default.cyan(skill)} → ${successful.length} agent(s)`);
107952
+ f2.success(`${import_picocolors37.default.cyan(skill)} → ${successful.length} agent(s)`);
107114
107953
  for (const r2 of successful) {
107115
- f2.message(` ${import_picocolors35.default.green("✓")} ${r2.agentDisplayName}`);
107954
+ f2.message(` ${import_picocolors37.default.green("✓")} ${r2.agentDisplayName}`);
107116
107955
  }
107117
107956
  }
107118
107957
  if (skipped.length > 0) {
107119
- f2.info(`${import_picocolors35.default.cyan(skill)} → ${skipped.length} skipped`);
107958
+ f2.info(`${import_picocolors37.default.cyan(skill)} → ${skipped.length} skipped`);
107120
107959
  for (const r2 of skipped) {
107121
- f2.message(` ${import_picocolors35.default.yellow("○")} ${r2.agentDisplayName}: ${import_picocolors35.default.dim(r2.skipReason || "Already at source location")}`);
107960
+ f2.message(` ${import_picocolors37.default.yellow("○")} ${r2.agentDisplayName}: ${import_picocolors37.default.dim(r2.skipReason || "Already at source location")}`);
107122
107961
  }
107123
107962
  }
107124
107963
  if (failed.length > 0) {
107125
- f2.error(`${import_picocolors35.default.cyan(skill)} failed: ${failed.length} agent(s)`);
107964
+ f2.error(`${import_picocolors37.default.cyan(skill)} failed: ${failed.length} agent(s)`);
107126
107965
  for (const r2 of failed) {
107127
- f2.message(` ${import_picocolors35.default.red("✗")} ${r2.agentDisplayName}: ${import_picocolors35.default.dim(r2.error)}`);
107966
+ f2.message(` ${import_picocolors37.default.red("✗")} ${r2.agentDisplayName}: ${import_picocolors37.default.dim(r2.error)}`);
107128
107967
  }
107129
107968
  }
107130
107969
  }
107131
107970
  console.log();
107132
107971
  if (totalSuccessful === 0 && totalFailed === 0 && totalSkipped === 0) {
107133
- $e(import_picocolors35.default.yellow("No installations performed"));
107972
+ $e(import_picocolors37.default.yellow("No installations performed"));
107134
107973
  } else if (totalFailed > 0 && totalSuccessful === 0) {
107135
- $e(import_picocolors35.default.red("Installation failed"));
107974
+ $e(import_picocolors37.default.red("Installation failed"));
107136
107975
  process.exit(1);
107137
107976
  } else {
107138
107977
  const parts = [];
@@ -107142,11 +107981,11 @@ async function skillsCommand(options2) {
107142
107981
  parts.push(`${totalSkipped} skipped`);
107143
107982
  if (totalFailed > 0)
107144
107983
  parts.push(`${totalFailed} failed`);
107145
- $e(import_picocolors35.default.green(`Done! ${parts.join(", ")}`));
107984
+ $e(import_picocolors37.default.green(`Done! ${parts.join(", ")}`));
107146
107985
  }
107147
107986
  } catch (error) {
107148
107987
  logger.error(error instanceof Error ? error.message : "Unknown error");
107149
- $e(import_picocolors35.default.red("Installation failed"));
107988
+ $e(import_picocolors37.default.red("Installation failed"));
107150
107989
  process.exit(1);
107151
107990
  }
107152
107991
  }
@@ -107164,7 +108003,7 @@ init_logger();
107164
108003
  init_path_resolver();
107165
108004
  init_safe_prompts();
107166
108005
  init_types3();
107167
- var import_picocolors37 = __toESM(require_picocolors(), 1);
108006
+ var import_picocolors39 = __toESM(require_picocolors(), 1);
107168
108007
 
107169
108008
  // src/commands/uninstall/installation-detector.ts
107170
108009
  init_claudekit_scanner();
@@ -107208,7 +108047,7 @@ async function detectInstallations() {
107208
108047
 
107209
108048
  // src/commands/uninstall/removal-handler.ts
107210
108049
  import { readdirSync as readdirSync9, rmSync as rmSync6 } from "node:fs";
107211
- import { basename as basename28, join as join147, resolve as resolve42, sep as sep11 } from "node:path";
108050
+ import { basename as basename29, join as join147, resolve as resolve43, sep as sep11 } from "node:path";
107212
108051
  init_logger();
107213
108052
  init_safe_prompts();
107214
108053
  init_safe_spinner();
@@ -107217,11 +108056,11 @@ var import_fs_extra44 = __toESM(require_lib3(), 1);
107217
108056
  // src/commands/uninstall/analysis-handler.ts
107218
108057
  init_metadata_migration();
107219
108058
  import { readdirSync as readdirSync8, rmSync as rmSync5 } from "node:fs";
107220
- import { dirname as dirname42, join as join146 } from "node:path";
108059
+ import { dirname as dirname43, join as join146 } from "node:path";
107221
108060
  init_logger();
107222
108061
  init_safe_prompts();
107223
108062
  var import_fs_extra43 = __toESM(require_lib3(), 1);
107224
- var import_picocolors36 = __toESM(require_picocolors(), 1);
108063
+ var import_picocolors38 = __toESM(require_picocolors(), 1);
107225
108064
  function normalizeTrackedPath(relativePath) {
107226
108065
  return relativePath.replace(/\\/g, "/");
107227
108066
  }
@@ -107239,7 +108078,7 @@ function classifyFileByOwnership(ownership, forceOverwrite, deleteReason) {
107239
108078
  }
107240
108079
  async function cleanupEmptyDirectories3(filePath, installationRoot) {
107241
108080
  let cleaned = 0;
107242
- let currentDir = dirname42(filePath);
108081
+ let currentDir = dirname43(filePath);
107243
108082
  while (currentDir !== installationRoot && currentDir.startsWith(installationRoot)) {
107244
108083
  try {
107245
108084
  const entries = readdirSync8(currentDir);
@@ -107247,7 +108086,7 @@ async function cleanupEmptyDirectories3(filePath, installationRoot) {
107247
108086
  rmSync5(currentDir, { recursive: true });
107248
108087
  cleaned++;
107249
108088
  logger.debug(`Removed empty directory: ${currentDir}`);
107250
- currentDir = dirname42(currentDir);
108089
+ currentDir = dirname43(currentDir);
107251
108090
  } else {
107252
108091
  break;
107253
108092
  }
@@ -107335,27 +108174,27 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
107335
108174
  }
107336
108175
  function displayDryRunPreview(analysis, installationType) {
107337
108176
  console.log("");
107338
- log.info(import_picocolors36.default.bold(`DRY RUN - Preview for ${installationType} installation:`));
108177
+ log.info(import_picocolors38.default.bold(`DRY RUN - Preview for ${installationType} installation:`));
107339
108178
  console.log("");
107340
108179
  if (analysis.toDelete.length > 0) {
107341
- console.log(import_picocolors36.default.red(import_picocolors36.default.bold(`Files to DELETE (${analysis.toDelete.length}):`)));
108180
+ console.log(import_picocolors38.default.red(import_picocolors38.default.bold(`Files to DELETE (${analysis.toDelete.length}):`)));
107342
108181
  const showDelete = analysis.toDelete.slice(0, 10);
107343
108182
  for (const item of showDelete) {
107344
- console.log(` ${import_picocolors36.default.red("✖")} ${item.path}`);
108183
+ console.log(` ${import_picocolors38.default.red("✖")} ${item.path}`);
107345
108184
  }
107346
108185
  if (analysis.toDelete.length > 10) {
107347
- console.log(import_picocolors36.default.gray(` ... and ${analysis.toDelete.length - 10} more`));
108186
+ console.log(import_picocolors38.default.gray(` ... and ${analysis.toDelete.length - 10} more`));
107348
108187
  }
107349
108188
  console.log("");
107350
108189
  }
107351
108190
  if (analysis.toPreserve.length > 0) {
107352
- console.log(import_picocolors36.default.green(import_picocolors36.default.bold(`Files to PRESERVE (${analysis.toPreserve.length}):`)));
108191
+ console.log(import_picocolors38.default.green(import_picocolors38.default.bold(`Files to PRESERVE (${analysis.toPreserve.length}):`)));
107353
108192
  const showPreserve = analysis.toPreserve.slice(0, 10);
107354
108193
  for (const item of showPreserve) {
107355
- console.log(` ${import_picocolors36.default.green("✓")} ${item.path} ${import_picocolors36.default.gray(`(${item.reason})`)}`);
108194
+ console.log(` ${import_picocolors38.default.green("✓")} ${item.path} ${import_picocolors38.default.gray(`(${item.reason})`)}`);
107356
108195
  }
107357
108196
  if (analysis.toPreserve.length > 10) {
107358
- console.log(import_picocolors36.default.gray(` ... and ${analysis.toPreserve.length - 10} more`));
108197
+ console.log(import_picocolors38.default.gray(` ... and ${analysis.toPreserve.length - 10} more`));
107359
108198
  }
107360
108199
  console.log("");
107361
108200
  }
@@ -107389,8 +108228,8 @@ async function restoreUninstallBackup(backup) {
107389
108228
  }
107390
108229
  async function isPathSafeToRemove(filePath, baseDir) {
107391
108230
  try {
107392
- const resolvedPath = resolve42(filePath);
107393
- const resolvedBase = resolve42(baseDir);
108231
+ const resolvedPath = resolve43(filePath);
108232
+ const resolvedBase = resolve43(baseDir);
107394
108233
  if (!resolvedPath.startsWith(resolvedBase + sep11) && resolvedPath !== resolvedBase) {
107395
108234
  logger.debug(`Path outside installation directory: ${filePath}`);
107396
108235
  return false;
@@ -107398,7 +108237,7 @@ async function isPathSafeToRemove(filePath, baseDir) {
107398
108237
  const stats = await import_fs_extra44.lstat(filePath);
107399
108238
  if (stats.isSymbolicLink()) {
107400
108239
  const realPath = await import_fs_extra44.realpath(filePath);
107401
- const resolvedReal = resolve42(realPath);
108240
+ const resolvedReal = resolve43(realPath);
107402
108241
  if (!resolvedReal.startsWith(resolvedBase + sep11) && resolvedReal !== resolvedBase) {
107403
108242
  logger.debug(`Symlink points outside installation directory: ${filePath} -> ${realPath}`);
107404
108243
  return false;
@@ -107444,7 +108283,7 @@ async function removeInstallations(installations, options2) {
107444
108283
  scope: installation.type,
107445
108284
  kit: options2.kit
107446
108285
  });
107447
- await cleanupOldDestructiveOperationBackups(undefined, basename28(backup.backupDir));
108286
+ await cleanupOldDestructiveOperationBackups(undefined, basename29(backup.backupDir));
107448
108287
  backupSpinner.succeed(`Recovery backup saved to ${backup.backupDir}`);
107449
108288
  } catch (error) {
107450
108289
  backupSpinner.fail("Failed to create recovery backup");
@@ -107543,15 +108382,15 @@ function displayInstallations(installations, scope) {
107543
108382
  const hasLegacy = installations.some((i) => !i.hasMetadata);
107544
108383
  const lines = installations.map((i) => {
107545
108384
  const typeLabel = i.type === "local" ? "Local " : "Global";
107546
- const legacyTag = !i.hasMetadata ? import_picocolors37.default.yellow(" [legacy]") : "";
108385
+ const legacyTag = !i.hasMetadata ? import_picocolors39.default.yellow(" [legacy]") : "";
107547
108386
  const components = formatComponentSummary(i);
107548
108387
  return ` ${typeLabel}: ${i.path}${legacyTag}${components}`;
107549
108388
  });
107550
108389
  prompts.note(lines.join(`
107551
108390
  `), `Detected ClaudeKit installations (${scopeLabel})`);
107552
108391
  if (hasLegacy) {
107553
- log.warn(import_picocolors37.default.yellow(`[!] Legacy installation(s) detected without metadata.json.
107554
- `) + import_picocolors37.default.yellow(" These files cannot be selectively removed. Full directory cleanup will be performed."));
108392
+ log.warn(import_picocolors39.default.yellow(`[!] Legacy installation(s) detected without metadata.json.
108393
+ `) + import_picocolors39.default.yellow(" These files cannot be selectively removed. Full directory cleanup will be performed."));
107555
108394
  }
107556
108395
  log.warn("[!] This will permanently delete ClaudeKit files from the above paths.");
107557
108396
  }
@@ -107612,7 +108451,7 @@ async function uninstallCommand(options2) {
107612
108451
  }
107613
108452
  const isAtHome = PathResolver.isLocalSameAsGlobal();
107614
108453
  if (validOptions.local && !validOptions.global && isAtHome) {
107615
- log.warn(import_picocolors37.default.yellow("Cannot use --local at HOME directory (local path equals global path)."));
108454
+ log.warn(import_picocolors39.default.yellow("Cannot use --local at HOME directory (local path equals global path)."));
107616
108455
  log.info("Use -g/--global or run from a project directory.");
107617
108456
  return;
107618
108457
  }
@@ -107624,7 +108463,7 @@ async function uninstallCommand(options2) {
107624
108463
  } else if (validOptions.global) {
107625
108464
  scope = "global";
107626
108465
  } else if (isAtHome) {
107627
- log.info(import_picocolors37.default.cyan("Running at HOME directory - targeting global installation"));
108466
+ log.info(import_picocolors39.default.cyan("Running at HOME directory - targeting global installation"));
107628
108467
  scope = "global";
107629
108468
  } else {
107630
108469
  const promptedScope = await promptScope(allInstallations);
@@ -107646,10 +108485,10 @@ async function uninstallCommand(options2) {
107646
108485
  }
107647
108486
  displayInstallations(installations, scope);
107648
108487
  if (validOptions.kit) {
107649
- log.info(import_picocolors37.default.cyan(`Kit-scoped uninstall: ${validOptions.kit} kit only`));
108488
+ log.info(import_picocolors39.default.cyan(`Kit-scoped uninstall: ${validOptions.kit} kit only`));
107650
108489
  }
107651
108490
  if (validOptions.dryRun) {
107652
- log.info(import_picocolors37.default.yellow("DRY RUN MODE - No files will be deleted"));
108491
+ log.info(import_picocolors39.default.yellow("DRY RUN MODE - No files will be deleted"));
107653
108492
  await removeInstallations(installations, {
107654
108493
  dryRun: true,
107655
108494
  forceOverwrite: validOptions.forceOverwrite,
@@ -107659,8 +108498,8 @@ async function uninstallCommand(options2) {
107659
108498
  return;
107660
108499
  }
107661
108500
  if (validOptions.forceOverwrite) {
107662
- log.warn(`${import_picocolors37.default.yellow(import_picocolors37.default.bold("FORCE MODE ENABLED"))}
107663
- ${import_picocolors37.default.yellow("User modifications will be permanently deleted!")}`);
108501
+ log.warn(`${import_picocolors39.default.yellow(import_picocolors39.default.bold("FORCE MODE ENABLED"))}
108502
+ ${import_picocolors39.default.yellow("User modifications will be permanently deleted!")}`);
107664
108503
  }
107665
108504
  if (!validOptions.yes) {
107666
108505
  const kitLabel = validOptions.kit ? ` (${validOptions.kit} kit only)` : "";
@@ -107695,7 +108534,7 @@ init_update_cli();
107695
108534
  init_github_client();
107696
108535
  init_logger();
107697
108536
  init_types3();
107698
- var import_picocolors38 = __toESM(require_picocolors(), 1);
108537
+ var import_picocolors40 = __toESM(require_picocolors(), 1);
107699
108538
  function formatRelativeTime(dateString) {
107700
108539
  if (!dateString)
107701
108540
  return "Unknown";
@@ -107717,30 +108556,30 @@ function formatRelativeTime(dateString) {
107717
108556
  }
107718
108557
  function displayKitReleases(kitName, releases) {
107719
108558
  console.log(`
107720
- ${import_picocolors38.default.bold(import_picocolors38.default.cyan(kitName))} - Available Versions:
108559
+ ${import_picocolors40.default.bold(import_picocolors40.default.cyan(kitName))} - Available Versions:
107721
108560
  `);
107722
108561
  if (releases.length === 0) {
107723
- console.log(import_picocolors38.default.dim(" No releases found"));
108562
+ console.log(import_picocolors40.default.dim(" No releases found"));
107724
108563
  return;
107725
108564
  }
107726
108565
  for (const release of releases) {
107727
- const version = import_picocolors38.default.green(release.tag_name);
108566
+ const version = import_picocolors40.default.green(release.tag_name);
107728
108567
  const name2 = release.name || "No title";
107729
108568
  const publishedAt = formatRelativeTime(release.published_at);
107730
108569
  const assetCount = release.assets.length;
107731
108570
  const badges = [];
107732
108571
  if (release.prerelease)
107733
- badges.push(import_picocolors38.default.yellow("[prerelease]"));
108572
+ badges.push(import_picocolors40.default.yellow("[prerelease]"));
107734
108573
  if (release.draft)
107735
- badges.push(import_picocolors38.default.gray("[draft]"));
108574
+ badges.push(import_picocolors40.default.gray("[draft]"));
107736
108575
  const badgeStr = badges.length > 0 ? ` ${badges.join(" ")}` : "";
107737
108576
  const versionPart = version.padEnd(20);
107738
108577
  const namePart = name2.length > 40 ? `${name2.slice(0, 37)}...` : name2.padEnd(40);
107739
- const timePart = import_picocolors38.default.dim(publishedAt.padEnd(20));
107740
- const assetPart = import_picocolors38.default.dim(`(${assetCount} ${assetCount === 1 ? "asset" : "assets"})`);
108578
+ const timePart = import_picocolors40.default.dim(publishedAt.padEnd(20));
108579
+ const assetPart = import_picocolors40.default.dim(`(${assetCount} ${assetCount === 1 ? "asset" : "assets"})`);
107741
108580
  console.log(` ${versionPart} ${namePart} ${timePart} ${assetPart}${badgeStr}`);
107742
108581
  }
107743
- console.log(import_picocolors38.default.dim(`
108582
+ console.log(import_picocolors40.default.dim(`
107744
108583
  Showing ${releases.length} ${releases.length === 1 ? "release" : "releases"}`));
107745
108584
  }
107746
108585
  async function versionCommand(options2) {
@@ -107775,8 +108614,8 @@ async function versionCommand(options2) {
107775
108614
  for (const result of results) {
107776
108615
  if (result.error) {
107777
108616
  console.log(`
107778
- ${import_picocolors38.default.bold(import_picocolors38.default.cyan(result.kitConfig.name))} - ${import_picocolors38.default.red("Error")}`);
107779
- console.log(import_picocolors38.default.dim(` ${result.error}`));
108617
+ ${import_picocolors40.default.bold(import_picocolors40.default.cyan(result.kitConfig.name))} - ${import_picocolors40.default.red("Error")}`);
108618
+ console.log(import_picocolors40.default.dim(` ${result.error}`));
107780
108619
  } else {
107781
108620
  displayKitReleases(result.kitConfig.name, result.releases);
107782
108621
  }
@@ -107793,7 +108632,7 @@ init_logger();
107793
108632
  import { existsSync as existsSync72 } from "node:fs";
107794
108633
  import { rm as rm16 } from "node:fs/promises";
107795
108634
  import { join as join154 } from "node:path";
107796
- var import_picocolors39 = __toESM(require_picocolors(), 1);
108635
+ var import_picocolors41 = __toESM(require_picocolors(), 1);
107797
108636
 
107798
108637
  // src/commands/watch/phases/implementation-runner.ts
107799
108638
  init_logger();
@@ -107861,7 +108700,7 @@ function getDisclaimerMarker() {
107861
108700
  return AI_DISCLAIMER;
107862
108701
  }
107863
108702
  function spawnAndCollect2(command, args) {
107864
- return new Promise((resolve43, reject) => {
108703
+ return new Promise((resolve44, reject) => {
107865
108704
  const child = spawn7(command, args, { stdio: ["ignore", "pipe", "pipe"] });
107866
108705
  const chunks = [];
107867
108706
  const stderrChunks = [];
@@ -107874,7 +108713,7 @@ function spawnAndCollect2(command, args) {
107874
108713
  reject(new Error(`${command} exited with code ${code2}: ${stderr}`));
107875
108714
  return;
107876
108715
  }
107877
- resolve43(Buffer.concat(chunks).toString("utf-8"));
108716
+ resolve44(Buffer.concat(chunks).toString("utf-8"));
107878
108717
  });
107879
108718
  });
107880
108719
  }
@@ -107982,7 +108821,7 @@ function formatResponse(content, showBranding) {
107982
108821
  return disclaimer + formatted + branding;
107983
108822
  }
107984
108823
  async function postViaGh(owner, repo, issueNumber, body) {
107985
- return new Promise((resolve43, reject) => {
108824
+ return new Promise((resolve44, reject) => {
107986
108825
  const args = [
107987
108826
  "issue",
107988
108827
  "comment",
@@ -108004,7 +108843,7 @@ async function postViaGh(owner, repo, issueNumber, body) {
108004
108843
  reject(new Error(`gh exited with code ${code2}: ${stderr}`));
108005
108844
  return;
108006
108845
  }
108007
- resolve43();
108846
+ resolve44();
108008
108847
  });
108009
108848
  });
108010
108849
  }
@@ -108122,7 +108961,7 @@ After completing the implementation:
108122
108961
  "--allowedTools",
108123
108962
  tools
108124
108963
  ];
108125
- await new Promise((resolve43, reject) => {
108964
+ await new Promise((resolve44, reject) => {
108126
108965
  const child = spawn9("claude", args, { cwd: cwd2, stdio: ["pipe", "pipe", "pipe"], detached: false });
108127
108966
  child.stdin.write(prompt);
108128
108967
  child.stdin.end();
@@ -108147,7 +108986,7 @@ After completing the implementation:
108147
108986
  reject(new Error(`Claude exited ${code2}: ${stderr.slice(0, 500)}`));
108148
108987
  return;
108149
108988
  }
108150
- resolve43();
108989
+ resolve44();
108151
108990
  });
108152
108991
  });
108153
108992
  }
@@ -108291,7 +109130,7 @@ function checkRateLimit2(processedThisHour, maxPerHour) {
108291
109130
  return processedThisHour < maxPerHour;
108292
109131
  }
108293
109132
  function spawnAndCollect3(command, args) {
108294
- return new Promise((resolve43, reject) => {
109133
+ return new Promise((resolve44, reject) => {
108295
109134
  const child = spawn10(command, args, { stdio: ["ignore", "pipe", "pipe"] });
108296
109135
  const chunks = [];
108297
109136
  const stderrChunks = [];
@@ -108304,7 +109143,7 @@ function spawnAndCollect3(command, args) {
108304
109143
  reject(new Error(`${command} exited with code ${code2}: ${stderr}`));
108305
109144
  return;
108306
109145
  }
108307
- resolve43(Buffer.concat(chunks).toString("utf-8"));
109146
+ resolve44(Buffer.concat(chunks).toString("utf-8"));
108308
109147
  });
108309
109148
  });
108310
109149
  }
@@ -108356,7 +109195,7 @@ async function invokeClaude(options2) {
108356
109195
  return collectClaudeOutput(child, options2.timeoutSec, verbose);
108357
109196
  }
108358
109197
  function collectClaudeOutput(child, timeoutSec, verbose = false) {
108359
- return new Promise((resolve43, reject) => {
109198
+ return new Promise((resolve44, reject) => {
108360
109199
  const chunks = [];
108361
109200
  const stderrChunks = [];
108362
109201
  child.stdout?.on("data", (chunk) => {
@@ -108386,7 +109225,7 @@ function collectClaudeOutput(child, timeoutSec, verbose = false) {
108386
109225
  reject(new Error(`Claude exited with code ${code2}: ${stderr}`));
108387
109226
  return;
108388
109227
  }
108389
- resolve43(verbose ? parseStreamJsonOutput(stdout2) : parseClaudeOutput(stdout2));
109228
+ resolve44(verbose ? parseStreamJsonOutput(stdout2) : parseClaudeOutput(stdout2));
108390
109229
  });
108391
109230
  });
108392
109231
  }
@@ -109091,7 +109930,7 @@ init_file_io();
109091
109930
  init_logger();
109092
109931
  import { existsSync as existsSync68 } from "node:fs";
109093
109932
  import { mkdir as mkdir34, readFile as readFile62 } from "node:fs/promises";
109094
- import { dirname as dirname43 } from "node:path";
109933
+ import { dirname as dirname44 } from "node:path";
109095
109934
  var PROCESSED_ISSUES_CAP = 500;
109096
109935
  async function readCkJson(projectDir) {
109097
109936
  const configPath = CkConfigManager.getProjectConfigPath(projectDir);
@@ -109121,7 +109960,7 @@ async function loadWatchState(projectDir) {
109121
109960
  }
109122
109961
  async function saveWatchState(projectDir, state) {
109123
109962
  const configPath = CkConfigManager.getProjectConfigPath(projectDir);
109124
- const configDir = dirname43(configPath);
109963
+ const configDir = dirname44(configPath);
109125
109964
  if (!existsSync68(configDir)) {
109126
109965
  await mkdir34(configDir, { recursive: true });
109127
109966
  }
@@ -109288,7 +110127,7 @@ async function scanForRepos(parentDir) {
109288
110127
  init_logger();
109289
110128
  import { spawnSync as spawnSync8 } from "node:child_process";
109290
110129
  import { existsSync as existsSync70 } from "node:fs";
109291
- import { homedir as homedir46 } from "node:os";
110130
+ import { homedir as homedir47 } from "node:os";
109292
110131
  import { join as join152 } from "node:path";
109293
110132
  async function validateSetup(cwd2) {
109294
110133
  const workDir = cwd2 ?? process.cwd();
@@ -109320,7 +110159,7 @@ Run this command from a directory with a GitHub remote.`);
109320
110159
  } catch {
109321
110160
  throw new Error(`Failed to parse repository info: ${ghRepo.stdout}`);
109322
110161
  }
109323
- const skillsPath = join152(homedir46(), ".claude", "skills");
110162
+ const skillsPath = join152(homedir47(), ".claude", "skills");
109324
110163
  const skillsAvailable = existsSync70(skillsPath);
109325
110164
  if (!skillsAvailable) {
109326
110165
  logger.warning(`ClaudeKit Engineer skills not found at ${skillsPath}`);
@@ -109619,27 +110458,27 @@ async function forceRemoveLock(watchLog) {
109619
110458
  }
109620
110459
  function printBanner(repos, interval, options2) {
109621
110460
  console.log();
109622
- console.log(import_picocolors39.default.bold(" ClaudeKit Watch"));
109623
- console.log(import_picocolors39.default.dim(" ─────────────────────"));
110461
+ console.log(import_picocolors41.default.bold(" ClaudeKit Watch"));
110462
+ console.log(import_picocolors41.default.dim(" ─────────────────────"));
109624
110463
  if (repos.length === 1) {
109625
110464
  const r2 = repos[0];
109626
110465
  const queueInfo = formatQueueInfo(r2.state);
109627
- console.log(` ${import_picocolors39.default.green("➜")} Repo: ${import_picocolors39.default.cyan(`${r2.setup.repoOwner}/${r2.setup.repoName}`)}`);
109628
- console.log(` ${import_picocolors39.default.green("➜")} Queue: ${import_picocolors39.default.cyan(queueInfo)}`);
110466
+ console.log(` ${import_picocolors41.default.green("➜")} Repo: ${import_picocolors41.default.cyan(`${r2.setup.repoOwner}/${r2.setup.repoName}`)}`);
110467
+ console.log(` ${import_picocolors41.default.green("➜")} Queue: ${import_picocolors41.default.cyan(queueInfo)}`);
109629
110468
  } else {
109630
- console.log(` ${import_picocolors39.default.green("➜")} Repos: ${import_picocolors39.default.cyan(String(repos.length))}`);
110469
+ console.log(` ${import_picocolors41.default.green("➜")} Repos: ${import_picocolors41.default.cyan(String(repos.length))}`);
109631
110470
  for (const r2 of repos) {
109632
110471
  const queueInfo = formatQueueInfo(r2.state);
109633
- console.log(` ${import_picocolors39.default.dim("•")} ${import_picocolors39.default.cyan(`${r2.setup.repoOwner}/${r2.setup.repoName}`)} (${queueInfo})`);
110472
+ console.log(` ${import_picocolors41.default.dim("•")} ${import_picocolors41.default.cyan(`${r2.setup.repoOwner}/${r2.setup.repoName}`)} (${queueInfo})`);
109634
110473
  }
109635
110474
  }
109636
- console.log(` ${import_picocolors39.default.green("➜")} Poll: ${import_picocolors39.default.cyan(`${interval / 1000}s`)}`);
110475
+ console.log(` ${import_picocolors41.default.green("➜")} Poll: ${import_picocolors41.default.cyan(`${interval / 1000}s`)}`);
109637
110476
  const skillsOk = repos.every((r2) => r2.setup.skillsAvailable);
109638
- console.log(` ${import_picocolors39.default.green("➜")} Skills: ${skillsOk ? import_picocolors39.default.green("available") : import_picocolors39.default.yellow("fallback mode")}`);
110477
+ console.log(` ${import_picocolors41.default.green("➜")} Skills: ${skillsOk ? import_picocolors41.default.green("available") : import_picocolors41.default.yellow("fallback mode")}`);
109639
110478
  if (options2.dryRun) {
109640
- console.log(` ${import_picocolors39.default.yellow("➜")} Mode: ${import_picocolors39.default.yellow("DRY RUN (no responses posted)")}`);
110479
+ console.log(` ${import_picocolors41.default.yellow("➜")} Mode: ${import_picocolors41.default.yellow("DRY RUN (no responses posted)")}`);
109641
110480
  }
109642
- console.log(import_picocolors39.default.dim(" Press Ctrl+C to stop"));
110481
+ console.log(import_picocolors41.default.dim(" Press Ctrl+C to stop"));
109643
110482
  console.log();
109644
110483
  }
109645
110484
  function formatQueueInfo(state) {
@@ -109650,7 +110489,7 @@ function formatQueueInfo(state) {
109650
110489
  return "idle";
109651
110490
  }
109652
110491
  function sleep(ms) {
109653
- return new Promise((resolve43) => setTimeout(resolve43, ms));
110492
+ return new Promise((resolve44) => setTimeout(resolve44, ms));
109654
110493
  }
109655
110494
  // src/cli/command-registry.ts
109656
110495
  init_logger();
@@ -109974,7 +110813,7 @@ class CliVersionChecker {
109974
110813
  }
109975
110814
  // src/domains/versioning/checking/notification-display.ts
109976
110815
  init_version_utils();
109977
- var import_picocolors42 = __toESM(require_picocolors(), 1);
110816
+ var import_picocolors44 = __toESM(require_picocolors(), 1);
109978
110817
  function createNotificationBox2(borderColor, boxWidth) {
109979
110818
  const contentWidth = boxWidth - 2;
109980
110819
  const topBorder = borderColor(`╭${"─".repeat(contentWidth)}╮`);
@@ -109999,15 +110838,15 @@ function displayKitNotification(result, options2 = {}) {
109999
110838
  const displayCurrent = normalizeVersion(currentVersion);
110000
110839
  const displayLatest = normalizeVersion(latestVersion);
110001
110840
  const boxWidth = 52;
110002
- const { topBorder, bottomBorder, emptyLine, padLine } = createNotificationBox2(import_picocolors42.default.cyan, boxWidth);
110003
- const headerText = import_picocolors42.default.bold(import_picocolors42.default.yellow("⬆ Kit Update Available"));
110841
+ const { topBorder, bottomBorder, emptyLine, padLine } = createNotificationBox2(import_picocolors44.default.cyan, boxWidth);
110842
+ const headerText = import_picocolors44.default.bold(import_picocolors44.default.yellow("⬆ Kit Update Available"));
110004
110843
  const headerLen = "⬆ Kit Update Available".length;
110005
- const kitText = kitName ? `Kit: ${import_picocolors42.default.cyan(import_picocolors42.default.bold(kitName))}` : null;
110844
+ const kitText = kitName ? `Kit: ${import_picocolors44.default.cyan(import_picocolors44.default.bold(kitName))}` : null;
110006
110845
  const kitLen = kitName ? `Kit: ${kitName}`.length : 0;
110007
- const versionText = `${import_picocolors42.default.dim(displayCurrent)} ${import_picocolors42.default.white("→")} ${import_picocolors42.default.green(import_picocolors42.default.bold(displayLatest))}`;
110846
+ const versionText = `${import_picocolors44.default.dim(displayCurrent)} ${import_picocolors44.default.white("→")} ${import_picocolors44.default.green(import_picocolors44.default.bold(displayLatest))}`;
110008
110847
  const versionLen = displayCurrent.length + 3 + displayLatest.length;
110009
110848
  const updateCmd = isGlobal ? "ck init -g" : "ck init";
110010
- const commandText = `Run: ${import_picocolors42.default.cyan(import_picocolors42.default.bold(updateCmd))}`;
110849
+ const commandText = `Run: ${import_picocolors44.default.cyan(import_picocolors44.default.bold(updateCmd))}`;
110011
110850
  const commandLen = `Run: ${updateCmd}`.length;
110012
110851
  console.log("");
110013
110852
  console.log(topBorder);
@@ -110028,12 +110867,12 @@ function displayCliNotification(result) {
110028
110867
  return;
110029
110868
  const { currentVersion, latestVersion } = result;
110030
110869
  const boxWidth = 52;
110031
- const { topBorder, bottomBorder, emptyLine, padLine } = createNotificationBox2(import_picocolors42.default.magenta, boxWidth);
110032
- const headerText = import_picocolors42.default.bold(import_picocolors42.default.yellow("⬆ CLI Update Available"));
110870
+ const { topBorder, bottomBorder, emptyLine, padLine } = createNotificationBox2(import_picocolors44.default.magenta, boxWidth);
110871
+ const headerText = import_picocolors44.default.bold(import_picocolors44.default.yellow("⬆ CLI Update Available"));
110033
110872
  const headerLen = "⬆ CLI Update Available".length;
110034
- const versionText = `${import_picocolors42.default.dim(currentVersion)} ${import_picocolors42.default.white("→")} ${import_picocolors42.default.green(import_picocolors42.default.bold(latestVersion))}`;
110873
+ const versionText = `${import_picocolors44.default.dim(currentVersion)} ${import_picocolors44.default.white("→")} ${import_picocolors44.default.green(import_picocolors44.default.bold(latestVersion))}`;
110035
110874
  const versionLen = currentVersion.length + 3 + latestVersion.length;
110036
- const commandText = `Run: ${import_picocolors42.default.magenta(import_picocolors42.default.bold("ck update"))}`;
110875
+ const commandText = `Run: ${import_picocolors44.default.magenta(import_picocolors44.default.bold("ck update"))}`;
110037
110876
  const commandLen = "Run: ck update".length;
110038
110877
  console.log("");
110039
110878
  console.log(topBorder);
@@ -110190,7 +111029,7 @@ function getPackageVersion2() {
110190
111029
 
110191
111030
  // src/shared/logger.ts
110192
111031
  init_output_manager();
110193
- var import_picocolors43 = __toESM(require_picocolors(), 1);
111032
+ var import_picocolors45 = __toESM(require_picocolors(), 1);
110194
111033
  import { createWriteStream as createWriteStream5 } from "node:fs";
110195
111034
 
110196
111035
  class Logger2 {
@@ -110199,23 +111038,23 @@ class Logger2 {
110199
111038
  exitHandlerRegistered = false;
110200
111039
  info(message) {
110201
111040
  const symbols = output.getSymbols();
110202
- console.log(import_picocolors43.default.blue(symbols.info), message);
111041
+ console.log(import_picocolors45.default.blue(symbols.info), message);
110203
111042
  }
110204
111043
  success(message) {
110205
111044
  const symbols = output.getSymbols();
110206
- console.log(import_picocolors43.default.green(symbols.success), message);
111045
+ console.log(import_picocolors45.default.green(symbols.success), message);
110207
111046
  }
110208
111047
  warning(message) {
110209
111048
  const symbols = output.getSymbols();
110210
- console.log(import_picocolors43.default.yellow(symbols.warning), message);
111049
+ console.log(import_picocolors45.default.yellow(symbols.warning), message);
110211
111050
  }
110212
111051
  error(message) {
110213
111052
  const symbols = output.getSymbols();
110214
- console.error(import_picocolors43.default.red(symbols.error), message);
111053
+ console.error(import_picocolors45.default.red(symbols.error), message);
110215
111054
  }
110216
111055
  debug(message) {
110217
111056
  if (process.env.DEBUG) {
110218
- console.log(import_picocolors43.default.gray("[DEBUG]"), message);
111057
+ console.log(import_picocolors45.default.gray("[DEBUG]"), message);
110219
111058
  }
110220
111059
  }
110221
111060
  verbose(message, context) {
@@ -110224,7 +111063,7 @@ class Logger2 {
110224
111063
  const timestamp = this.getTimestamp();
110225
111064
  const sanitizedMessage = this.sanitize(message);
110226
111065
  const formattedContext = context ? this.formatContext(context) : "";
110227
- const logLine = `${timestamp} ${import_picocolors43.default.gray("[VERBOSE]")} ${sanitizedMessage}${formattedContext}`;
111066
+ const logLine = `${timestamp} ${import_picocolors45.default.gray("[VERBOSE]")} ${sanitizedMessage}${formattedContext}`;
110228
111067
  console.error(logLine);
110229
111068
  if (this.logFileStream) {
110230
111069
  const plainLogLine = `${timestamp} [VERBOSE] ${sanitizedMessage}${formattedContext}`;
@@ -110327,7 +111166,7 @@ var logger3 = new Logger2;
110327
111166
 
110328
111167
  // src/shared/output-manager.ts
110329
111168
  init_terminal_utils();
110330
- var import_picocolors44 = __toESM(require_picocolors(), 1);
111169
+ var import_picocolors46 = __toESM(require_picocolors(), 1);
110331
111170
  var SYMBOLS2 = {
110332
111171
  unicode: {
110333
111172
  prompt: "◇",
@@ -110408,7 +111247,7 @@ class OutputManager2 {
110408
111247
  if (this.config.quiet)
110409
111248
  return;
110410
111249
  const symbol = this.getSymbols().success;
110411
- console.log(import_picocolors44.default.green(`${symbol} ${message}`));
111250
+ console.log(import_picocolors46.default.green(`${symbol} ${message}`));
110412
111251
  }
110413
111252
  error(message, data) {
110414
111253
  if (this.config.json) {
@@ -110416,7 +111255,7 @@ class OutputManager2 {
110416
111255
  return;
110417
111256
  }
110418
111257
  const symbol = this.getSymbols().error;
110419
- console.error(import_picocolors44.default.red(`${symbol} ${message}`));
111258
+ console.error(import_picocolors46.default.red(`${symbol} ${message}`));
110420
111259
  }
110421
111260
  warning(message, data) {
110422
111261
  if (this.config.json) {
@@ -110426,7 +111265,7 @@ class OutputManager2 {
110426
111265
  if (this.config.quiet)
110427
111266
  return;
110428
111267
  const symbol = this.getSymbols().warning;
110429
- console.log(import_picocolors44.default.yellow(`${symbol} ${message}`));
111268
+ console.log(import_picocolors46.default.yellow(`${symbol} ${message}`));
110430
111269
  }
110431
111270
  info(message, data) {
110432
111271
  if (this.config.json) {
@@ -110436,7 +111275,7 @@ class OutputManager2 {
110436
111275
  if (this.config.quiet)
110437
111276
  return;
110438
111277
  const symbol = this.getSymbols().info;
110439
- console.log(import_picocolors44.default.blue(`${symbol} ${message}`));
111278
+ console.log(import_picocolors46.default.blue(`${symbol} ${message}`));
110440
111279
  }
110441
111280
  verbose(message, data) {
110442
111281
  if (!this.config.verbose)
@@ -110445,7 +111284,7 @@ class OutputManager2 {
110445
111284
  this.addJsonEntry({ type: "info", message, data });
110446
111285
  return;
110447
111286
  }
110448
- console.log(import_picocolors44.default.dim(` ${message}`));
111287
+ console.log(import_picocolors46.default.dim(` ${message}`));
110449
111288
  }
110450
111289
  indent(message) {
110451
111290
  if (this.config.json)
@@ -110470,7 +111309,7 @@ class OutputManager2 {
110470
111309
  return;
110471
111310
  const symbols = this.getSymbols();
110472
111311
  console.log();
110473
- console.log(import_picocolors44.default.bold(import_picocolors44.default.cyan(`${symbols.line} ${title}`)));
111312
+ console.log(import_picocolors46.default.bold(import_picocolors46.default.cyan(`${symbols.line} ${title}`)));
110474
111313
  }
110475
111314
  addJsonEntry(entry) {
110476
111315
  this.jsonBuffer.push({