@byh3071/vhk 1.6.5 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -12,6 +12,8 @@ import {
12
12
  countLocalCommits,
13
13
  deploy,
14
14
  detectExistingRuleFiles,
15
+ ensureInteractive,
16
+ ensureVhkIgnored,
15
17
  env,
16
18
  envCheck,
17
19
  filterSevereFindings,
@@ -22,12 +24,15 @@ import {
22
24
  gitOut,
23
25
  gitRun,
24
26
  hasGitRemote,
27
+ isInteractive,
28
+ isPromptAbortError,
25
29
  ko,
26
30
  listBackups,
27
31
  localDate,
28
32
  printContextResumeHint,
29
33
  printNextStep,
30
34
  printSecurityWarnings,
35
+ promptOrDefault,
31
36
  publish,
32
37
  readJsonFile,
33
38
  require_ignore,
@@ -38,12 +43,12 @@ import {
38
43
  stripBom,
39
44
  sync,
40
45
  t
41
- } from "./chunk-EJTVXWUZ.js";
46
+ } from "./chunk-GXFZ7JXX.js";
42
47
 
43
48
  // src/index.ts
44
49
  import { Command, Help } from "commander";
45
50
  import { pathToFileURL } from "url";
46
- import chalk34 from "chalk";
51
+ import chalk33 from "chalk";
47
52
  import inquirer13 from "inquirer";
48
53
 
49
54
  // src/lib/nlp-router.ts
@@ -500,37 +505,12 @@ function detectNaturalLanguageInput(argv) {
500
505
  }
501
506
 
502
507
  // src/lib/nlp-run.ts
503
- import chalk32 from "chalk";
508
+ import chalk31 from "chalk";
504
509
  import inquirer12 from "inquirer";
505
510
 
506
511
  // src/commands/gate.ts
507
512
  import inquirer from "inquirer";
508
- import chalk2 from "chalk";
509
-
510
- // src/lib/interactive.ts
511
513
  import chalk from "chalk";
512
- function isInteractive(opts) {
513
- if (opts?.yes) return false;
514
- if (process.env.VHK_FORCE_INTERACTIVE === "1") return true;
515
- return !!process.stdin.isTTY;
516
- }
517
- async function promptOrDefault(ask, fallback, opts) {
518
- if (!isInteractive(opts)) return fallback;
519
- return await ask();
520
- }
521
- function ensureInteractive(hint = "") {
522
- if (isInteractive()) return true;
523
- console.error(chalk.yellow(" \u26A0\uFE0F \uC774 \uBA85\uB839\uC740 \uB300\uD654\uD615 \uC785\uB825\uC774 \uD544\uC694\uD569\uB2C8\uB2E4 \u2014 \uBE44-TTY/\uD30C\uC774\uD504 \uD658\uACBD\uC5D0\uC11C\uB294 \uC2E4\uD589\uD560 \uC218 \uC5C6\uC5B4\uC694."));
524
- if (hint) console.error(chalk.dim(` ${hint}`));
525
- process.exitCode = 1;
526
- return false;
527
- }
528
- function isPromptAbortError(err) {
529
- const msg = err instanceof Error ? err.message : String(err);
530
- return /ERR_USE_AFTER_CLOSE|force closed|ExitPromptError|readline was closed|User force closed/i.test(msg);
531
- }
532
-
533
- // src/commands/gate.ts
534
514
  var GATE_QUESTIONS = [
535
515
  { id: 1, stage: "\uBB38\uC81C \uC815\uC758", question: "\uC774 \uC544\uC774\uB514\uC5B4\uAC00 \uD574\uACB0\uD558\uB294 \uBB38\uC81C\uB97C \uD55C \uBB38\uC7A5\uC73C\uB85C \uB9D0\uD574\uBCF4\uC138\uC694.", failIf: "\uD55C \uBB38\uC7A5 \uBD88\uAC00 \u2192 \uBBF8\uC131\uC219", quick: true },
536
516
  { id: 2, stage: "\uD575\uC2EC \uAE30\uB2A5", question: "\uB531 1\uAC1C \uAE30\uB2A5\uB9CC \uACE0\uB974\uBA74?", failIf: "2\uAC1C \uC774\uC0C1 \u2192 \uBC94\uC704 \uCD08\uACFC", quick: true },
@@ -553,7 +533,7 @@ function judgeGate(failCount, holdCount) {
553
533
  }
554
534
  async function gate() {
555
535
  if (!ensureInteractive("\uC544\uC774\uB514\uC5B4 \uAC80\uC99D\uC740 \uB300\uD654\uD615 \uC9C8\uBB38\uC774 \uD544\uC694\uD569\uB2C8\uB2E4. \uD130\uBBF8\uB110(PowerShell \uB4F1)\uC5D0\uC11C \uC9C1\uC811 \uC2E4\uD589\uD558\uC138\uC694. Git Bash \uBA74 VHK_FORCE_INTERACTIVE=1.")) return;
556
- console.log(chalk2.bold(`
536
+ console.log(chalk.bold(`
557
537
  ${ko.gate.title}
558
538
  `));
559
539
  const { mode: mode2 } = await inquirer.prompt([{
@@ -572,33 +552,33 @@ ${ko.gate.title}
572
552
  name: "source",
573
553
  message: ko.gate.skipSourcePrompt
574
554
  }]);
575
- console.log(chalk2.green.bold(`
555
+ console.log(chalk.green.bold(`
576
556
  ${ko.gate.skipGo}`));
577
- console.log(chalk2.dim(ko.gate.skipSourceLabel(source)));
557
+ console.log(chalk.dim(ko.gate.skipSourceLabel(source)));
578
558
  return;
579
559
  }
580
560
  const questions = mode2 === "quick" ? GATE_QUESTIONS.filter((q) => q.quick) : GATE_QUESTIONS;
581
561
  const total = questions.length;
582
562
  const header = mode2 === "quick" ? ko.gate.quickHeader : ko.gate.fullHeader;
583
- console.log(chalk2.dim(`
563
+ console.log(chalk.dim(`
584
564
  ${header} ${ko.gate.modeCountSuffix(total)}
585
565
  `));
586
- console.log(chalk2.dim(`
566
+ console.log(chalk.dim(`
587
567
  ${ko.gate.welcome}
588
568
  `));
589
- console.log(chalk2.dim(` ${ko.gate.ideaHint}`));
569
+ console.log(chalk.dim(` ${ko.gate.ideaHint}`));
590
570
  const { idea } = await inquirer.prompt([
591
571
  { type: "input", name: "idea", message: ko.gate.idea }
592
572
  ]);
593
- console.log(chalk2.dim(` ${ko.gate.painPointHint}`));
573
+ console.log(chalk.dim(` ${ko.gate.painPointHint}`));
594
574
  const { painPoint } = await inquirer.prompt([
595
575
  { type: "input", name: "painPoint", message: ko.gate.painPoint }
596
576
  ]);
597
- console.log(chalk2.dim(` ${ko.gate.edgeHint}`));
577
+ console.log(chalk.dim(` ${ko.gate.edgeHint}`));
598
578
  const { edge } = await inquirer.prompt([
599
579
  { type: "input", name: "edge", message: ko.gate.edge }
600
580
  ]);
601
- console.log(chalk2.dim(`
581
+ console.log(chalk.dim(`
602
582
  ${ko.gate.checklistStart}
603
583
  `));
604
584
  let failCount = 0;
@@ -606,7 +586,7 @@ ${ko.gate.checklistStart}
606
586
  const results = [];
607
587
  for (let i = 0; i < questions.length; i++) {
608
588
  const q = questions[i];
609
- if (q.hint) console.log(chalk2.dim(`${ko.gate.hintPrefix} ${q.hint}`));
589
+ if (q.hint) console.log(chalk.dim(`${ko.gate.hintPrefix} ${q.hint}`));
610
590
  const { answer } = await inquirer.prompt([{
611
591
  type: "input",
612
592
  name: "answer",
@@ -625,22 +605,22 @@ ${ko.gate.checklistStart}
625
605
  if (status2 === "fail") failCount++;
626
606
  if (status2 === "hold") holdCount++;
627
607
  results.push({ id: q.id, stage: q.stage, status: status2, answer });
628
- const icon = status2 === "pass" ? chalk2.green(ko.gate.statusPassLine) : status2 === "hold" ? chalk2.yellow(ko.gate.statusHoldLine) : chalk2.red(ko.gate.statusFailLine);
608
+ const icon = status2 === "pass" ? chalk.green(ko.gate.statusPassLine) : status2 === "hold" ? chalk.yellow(ko.gate.statusHoldLine) : chalk.red(ko.gate.statusFailLine);
629
609
  console.log(icon);
630
610
  }
631
- console.log(chalk2.bold(`
611
+ console.log(chalk.bold(`
632
612
  ${ko.gate.verdictTitle}
633
613
  `));
634
- console.log(`${ko.gate.ideaLabel} ${chalk2.cyan(idea)}`);
614
+ console.log(`${ko.gate.ideaLabel} ${chalk.cyan(idea)}`);
635
615
  console.log(`${ko.gate.painPointLabel} ${painPoint}`);
636
616
  console.log(`${ko.gate.edgeLabel} ${edge}`);
637
617
  console.log(`${ko.gate.countLine(failCount, holdCount, total)}
638
618
  `);
639
619
  const verdict = judgeGate(failCount, holdCount);
640
620
  if (verdict === "GO") {
641
- console.log(chalk2.green.bold(ko.gate.go));
621
+ console.log(chalk.green.bold(ko.gate.go));
642
622
  if (holdCount > 0) {
643
- console.log(chalk2.yellow(ko.gate.holdRemainHint));
623
+ console.log(chalk.yellow(ko.gate.holdRemainHint));
644
624
  }
645
625
  printNextStep({
646
626
  message: "\uC544\uC774\uB514\uC5B4 \uD1B5\uACFC! \uC774\uC81C \uD504\uB85C\uC81D\uD2B8\uB97C \uB9CC\uB4E4\uC5B4\uBCF4\uC138\uC694.",
@@ -648,20 +628,20 @@ ${ko.gate.verdictTitle}
648
628
  cursorHint: "\uD504\uB85C\uC81D\uD2B8 \uB9CC\uB4E4\uC5B4\uC918"
649
629
  });
650
630
  } else if (verdict === "REFINE") {
651
- console.log(chalk2.yellow.bold(ko.gate.refine));
631
+ console.log(chalk.yellow.bold(ko.gate.refine));
652
632
  printNextStep({
653
633
  message: "\uC870\uAE08 \uB354 \uB2E4\uB4EC\uC740 \uD6C4 \uB2E4\uC2DC \uAC80\uC99D\uD574\uBCF4\uC138\uC694.",
654
634
  command: "vhk \uAC80\uC99D",
655
635
  cursorHint: "\uC544\uC774\uB514\uC5B4 \uB2E4\uC2DC \uAC80\uC99D\uD574\uC918"
656
636
  });
657
637
  } else {
658
- console.log(chalk2.red.bold(ko.gate.drop));
638
+ console.log(chalk.red.bold(ko.gate.drop));
659
639
  }
660
640
  }
661
641
 
662
642
  // src/commands/init.ts
663
643
  import inquirer2 from "inquirer";
664
- import chalk4 from "chalk";
644
+ import chalk3 from "chalk";
665
645
  import fs2 from "fs";
666
646
  import path2 from "path";
667
647
 
@@ -983,13 +963,13 @@ function VHK_CONTEXT_SEED(name, type, stack) {
983
963
  }
984
964
 
985
965
  // src/utils/logger.ts
986
- import chalk3 from "chalk";
966
+ import chalk2 from "chalk";
987
967
  var log = {
988
- success: (msg) => console.log(chalk3.green(`\u2705 ${msg}`)),
989
- error: (msg) => console.log(chalk3.red(`\u274C ${msg}`)),
990
- warn: (msg) => console.log(chalk3.yellow(`\u26A0\uFE0F ${msg}`)),
991
- info: (msg) => console.log(chalk3.blue(`\u2139\uFE0F ${msg}`)),
992
- step: (msg) => console.log(chalk3.bold(`
968
+ success: (msg) => console.log(chalk2.green(`\u2705 ${msg}`)),
969
+ error: (msg) => console.log(chalk2.red(`\u274C ${msg}`)),
970
+ warn: (msg) => console.log(chalk2.yellow(`\u26A0\uFE0F ${msg}`)),
971
+ info: (msg) => console.log(chalk2.blue(`\u2139\uFE0F ${msg}`)),
972
+ step: (msg) => console.log(chalk2.bold(`
993
973
  \u25B8 ${msg}`))
994
974
  };
995
975
 
@@ -1232,11 +1212,11 @@ async function collectAnswers(options, defaults = {}) {
1232
1212
  async function init(options = {}) {
1233
1213
  const skipGate = Boolean(options.skipGate || options.fromNotion);
1234
1214
  if (skipGate) {
1235
- console.log(chalk4.dim(`
1215
+ console.log(chalk3.dim(`
1236
1216
  ${ko.init.skipGate}
1237
1217
  `));
1238
1218
  }
1239
- console.log(chalk4.bold(`
1219
+ console.log(chalk3.bold(`
1240
1220
  ${ko.init.title}
1241
1221
  `));
1242
1222
  printSecurityWarnings();
@@ -1262,8 +1242,8 @@ ${ko.init.title}
1262
1242
  }
1263
1243
  const detected = detectProjectStack(process.cwd());
1264
1244
  const stack = detected ?? STACK_PRESETS[answers.type];
1265
- if (detected) console.log(chalk4.dim(" \u{1F50E} package.json \uC758\uC874\uC131\uC5D0\uC11C \uC2E4\uC81C \uC2A4\uD0DD \uAC10\uC9C0"));
1266
- console.log(chalk4.dim(`
1245
+ if (detected) console.log(chalk3.dim(" \u{1F50E} package.json \uC758\uC874\uC131\uC5D0\uC11C \uC2E4\uC81C \uC2A4\uD0DD \uAC10\uC9C0"));
1246
+ console.log(chalk3.dim(`
1267
1247
  ${ko.init.recommendedStack} ${stack.join(" + ")}
1268
1248
  `));
1269
1249
  if (isInteractive(options)) {
@@ -1294,7 +1274,7 @@ ${ko.init.recommendedStack} ${stack.join(" + ")}
1294
1274
  }]);
1295
1275
  if (adopt) {
1296
1276
  adoptedRules = buildAdoptedRules(existingRules, answers.name);
1297
- console.log(chalk4.dim(` ${ko.init.adoptPreview(existingRules.length)}`));
1277
+ console.log(chalk3.dim(` ${ko.init.adoptPreview(existingRules.length)}`));
1298
1278
  }
1299
1279
  }
1300
1280
  }
@@ -1319,21 +1299,21 @@ ${ko.init.recommendedStack} ${stack.join(" + ")}
1319
1299
  log.success(filePath);
1320
1300
  }
1321
1301
  await writeInitExtras(cwd, !isInteractive(options));
1322
- console.log(chalk4.bold.green(`
1302
+ console.log(chalk3.bold.green(`
1323
1303
  ${ko.init.done}`));
1324
- console.log(chalk4.dim(`
1304
+ console.log(chalk3.dim(`
1325
1305
  ${ko.init.nextSteps}`));
1326
1306
  if (options.fromNotion) {
1327
1307
  console.log(` 1. ${ko.init.notionReviewHint}`);
1328
1308
  console.log(` 2. ${ko.init.gitHintLabel}`);
1329
- console.log(` ${chalk4.cyan(ko.init.gitHintCommand)}`);
1309
+ console.log(` ${chalk3.cyan(ko.init.gitHintCommand)}`);
1330
1310
  console.log(` 3. ${ko.init.startDev}
1331
1311
  `);
1332
1312
  } else {
1333
1313
  console.log(` 1. ${ko.init.fillHint}`);
1334
1314
  console.log(` 2. ${ko.init.prdHint}`);
1335
1315
  console.log(` 3. ${ko.init.gitHintLabel}`);
1336
- console.log(` ${chalk4.cyan(ko.init.gitHintCommand)}`);
1316
+ console.log(` ${chalk3.cyan(ko.init.gitHintCommand)}`);
1337
1317
  console.log(` 4. ${ko.init.startDev}
1338
1318
  `);
1339
1319
  }
@@ -1465,7 +1445,7 @@ async function writeInitExtras(projectDir, noninteractive = false) {
1465
1445
 
1466
1446
  // src/commands/recap.ts
1467
1447
  import inquirer3 from "inquirer";
1468
- import chalk6 from "chalk";
1448
+ import chalk5 from "chalk";
1469
1449
  import fs4 from "fs";
1470
1450
  import path5 from "path";
1471
1451
 
@@ -1651,7 +1631,7 @@ function createAdrFile(cwd, title, context2, decision, consequences) {
1651
1631
  }
1652
1632
 
1653
1633
  // src/lib/hard-stop-guard.ts
1654
- import chalk5 from "chalk";
1634
+ import chalk4 from "chalk";
1655
1635
 
1656
1636
  // src/lib/state-files.ts
1657
1637
  import { existsSync, mkdirSync, readFileSync, writeFileSync, appendFileSync, rmSync } from "fs";
@@ -1766,11 +1746,11 @@ function clearHardStop() {
1766
1746
  // src/lib/hard-stop-guard.ts
1767
1747
  function ensureNotHardStopped(action) {
1768
1748
  if (!isHardStopActive()) return true;
1769
- console.error(chalk5.red.bold(`
1749
+ console.error(chalk4.red.bold(`
1770
1750
  \u{1F6D1} HARD STOP \uD65C\uC131 \u2014 '${action}' \uC744(\uB97C) \uC2E4\uD589\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.`));
1771
1751
  const reason = readHardStopReason();
1772
- if (reason) console.error(chalk5.dim(` \uC0AC\uC720: ${reason.replace(/\s*\n\s*/g, " ")}`));
1773
- console.error(chalk5.dim(" \uD574\uC81C: vhk resume --confirm (\uC0AC\uB78C\uC774 \uC9C1\uC811 \uC2E4\uD589)"));
1752
+ if (reason) console.error(chalk4.dim(` \uC0AC\uC720: ${reason.replace(/\s*\n\s*/g, " ")}`));
1753
+ console.error(chalk4.dim(" \uD574\uC81C: vhk resume --confirm (\uC0AC\uB78C\uC774 \uC9C1\uC811 \uC2E4\uD589)"));
1774
1754
  process.exitCode = 1;
1775
1755
  return false;
1776
1756
  }
@@ -1778,45 +1758,45 @@ function ensureNotHardStopped(action) {
1778
1758
  // src/commands/recap.ts
1779
1759
  async function recap(options = {}) {
1780
1760
  if (!ensureNotHardStopped("recap")) return;
1781
- console.log(chalk6.bold(`
1761
+ console.log(chalk5.bold(`
1782
1762
  ${ko.recap.title}
1783
1763
  `));
1784
1764
  if (!await isGitRepo()) {
1785
- console.log(chalk6.red(ko.recap.noRepo));
1765
+ console.log(chalk5.red(ko.recap.noRepo));
1786
1766
  return;
1787
1767
  }
1788
1768
  if (!await hasAnyCommits()) {
1789
- console.log(chalk6.yellow("\u26A0\uFE0F \uC544\uC9C1 \uCEE4\uBC0B\uC774 \uC5C6\uC5B4\uC694."));
1790
- console.log(chalk6.gray(" \uD30C\uC77C\uC744 \uCD94\uAC00\uD558\uACE0 `vhk save` \uB610\uB294 `git commit`\uC73C\uB85C \uCCAB \uCEE4\uBC0B\uC744 \uB9CC\uB4E4\uC5B4 \uBCF4\uC138\uC694."));
1769
+ console.log(chalk5.yellow("\u26A0\uFE0F \uC544\uC9C1 \uCEE4\uBC0B\uC774 \uC5C6\uC5B4\uC694."));
1770
+ console.log(chalk5.gray(" \uD30C\uC77C\uC744 \uCD94\uAC00\uD558\uACE0 `vhk save` \uB610\uB294 `git commit`\uC73C\uB85C \uCCAB \uCEE4\uBC0B\uC744 \uB9CC\uB4E4\uC5B4 \uBCF4\uC138\uC694."));
1791
1771
  return;
1792
1772
  }
1793
1773
  printSecurityWarnings();
1794
- console.log(chalk6.dim(`${ko.recap.analyzing}
1774
+ console.log(chalk5.dim(`${ko.recap.analyzing}
1795
1775
  `));
1796
1776
  const since = options.since || localDate();
1797
1777
  const diff2 = await getSessionDiff(since);
1798
1778
  const commits = await getRecentCommits(10, since);
1799
1779
  if (diff2.filesChanged === 0 && commits.length === 0) {
1800
- console.log(chalk6.yellow(ko.recap.noChanges));
1780
+ console.log(chalk5.yellow(ko.recap.noChanges));
1801
1781
  return;
1802
1782
  }
1803
- console.log(chalk6.bold("\u{1F4CA} \uBCC0\uACBD \uC694\uC57D:"));
1804
- console.log(` \uD30C\uC77C: ${chalk6.cyan(String(diff2.filesChanged))}\uAC1C \uBCC0\uACBD`);
1805
- console.log(` \uCD94\uAC00: ${chalk6.green("+" + diff2.insertions)} / \uC0AD\uC81C: ${chalk6.red("-" + diff2.deletions)}`);
1783
+ console.log(chalk5.bold("\u{1F4CA} \uBCC0\uACBD \uC694\uC57D:"));
1784
+ console.log(` \uD30C\uC77C: ${chalk5.cyan(String(diff2.filesChanged))}\uAC1C \uBCC0\uACBD`);
1785
+ console.log(` \uCD94\uAC00: ${chalk5.green("+" + diff2.insertions)} / \uC0AD\uC81C: ${chalk5.red("-" + diff2.deletions)}`);
1806
1786
  if (diff2.files.length > 0) {
1807
- console.log(chalk6.dim("\n \uBCC0\uACBD \uD30C\uC77C:"));
1787
+ console.log(chalk5.dim("\n \uBCC0\uACBD \uD30C\uC77C:"));
1808
1788
  diff2.files.slice(0, 15).forEach((f) => {
1809
- const icon = f.status === "new" ? chalk6.green("\u{1F195}") : f.status === "deleted" ? chalk6.red("\u{1F5D1}\uFE0F") : chalk6.yellow("\u270F\uFE0F");
1789
+ const icon = f.status === "new" ? chalk5.green("\u{1F195}") : f.status === "deleted" ? chalk5.red("\u{1F5D1}\uFE0F") : chalk5.yellow("\u270F\uFE0F");
1810
1790
  console.log(` ${icon} ${f.file}`);
1811
1791
  });
1812
1792
  if (diff2.files.length > 15) {
1813
- console.log(chalk6.dim(` ... \uC678 ${diff2.files.length - 15}\uAC1C`));
1793
+ console.log(chalk5.dim(` ... \uC678 ${diff2.files.length - 15}\uAC1C`));
1814
1794
  }
1815
1795
  }
1816
1796
  if (commits.length > 0) {
1817
- console.log(chalk6.dim("\n \uCD5C\uADFC \uCEE4\uBC0B:"));
1797
+ console.log(chalk5.dim("\n \uCD5C\uADFC \uCEE4\uBC0B:"));
1818
1798
  commits.slice(0, 5).forEach((c) => {
1819
- console.log(chalk6.dim(` \u2022 ${c.message}`));
1799
+ console.log(chalk5.dim(` \u2022 ${c.message}`));
1820
1800
  });
1821
1801
  }
1822
1802
  console.log("");
@@ -1885,11 +1865,11 @@ ${ko.recap.title}
1885
1865
  fs4.writeFileSync(filePath, content, "utf-8");
1886
1866
  const adrCandidates = detectAdrCandidates(diff2);
1887
1867
  if (adrCandidates.length > 0) {
1888
- console.log(chalk6.cyan.bold(`
1868
+ console.log(chalk5.cyan.bold(`
1889
1869
  ${ko.recap.adrDetected} (${adrCandidates.length}\uAC74)`));
1890
1870
  for (const candidate of adrCandidates) {
1891
- console.log(chalk6.cyan(` \u2022 ${candidate.title}: ${candidate.context}`));
1892
- candidate.files.forEach((f) => console.log(chalk6.dim(` ${f}`)));
1871
+ console.log(chalk5.cyan(` \u2022 ${candidate.title}: ${candidate.context}`));
1872
+ candidate.files.forEach((f) => console.log(chalk5.dim(` ${f}`)));
1893
1873
  }
1894
1874
  const { createAdr } = await inquirer3.prompt([{
1895
1875
  type: "confirm",
@@ -1919,17 +1899,17 @@ ${ko.recap.adrDetected} (${adrCandidates.length}\uAC74)`));
1919
1899
  adrAnswers.decision,
1920
1900
  adrAnswers.consequences
1921
1901
  );
1922
- console.log(chalk6.green(` \u2705 ADR \uC0DD\uC131: ${path5.relative(process.cwd(), adrPath)}`));
1902
+ console.log(chalk5.green(` \u2705 ADR \uC0DD\uC131: ${path5.relative(process.cwd(), adrPath)}`));
1923
1903
  }
1924
1904
  }
1925
1905
  }
1926
1906
  const troubleshootingKeywords = /fix|bug|error|crash|hotfix|patch|revert|트러블|에러|버그|수정|핫픽스/i;
1927
1907
  const troubleCommits = commits.filter((c) => troubleshootingKeywords.test(c.message));
1928
1908
  if (troubleCommits.length > 0) {
1929
- console.log(chalk6.yellow.bold(`
1909
+ console.log(chalk5.yellow.bold(`
1930
1910
  ${ko.recap.troubleDetected} (${troubleCommits.length}\uAC74)`));
1931
1911
  troubleCommits.forEach((c) => {
1932
- console.log(chalk6.dim(` \u2022 ${c.message}`));
1912
+ console.log(chalk5.dim(` \u2022 ${c.message}`));
1933
1913
  });
1934
1914
  const { createTroubleshoot } = await inquirer3.prompt([{
1935
1915
  type: "confirm",
@@ -1980,12 +1960,12 @@ ${ko.recap.troubleDetected} (${troubleCommits.length}\uAC74)`));
1980
1960
  `*Generated by \`vhk recap\` at ${(/* @__PURE__ */ new Date()).toISOString()}*`
1981
1961
  ].join("\n");
1982
1962
  fs4.writeFileSync(tsFilePath, tsContent, "utf-8");
1983
- console.log(chalk6.green(` \u2705 \uD2B8\uB7EC\uBE14\uC288\uD305 \uBB38\uC11C \uC0DD\uC131: ${path5.relative(process.cwd(), tsFilePath)}`));
1963
+ console.log(chalk5.green(` \u2705 \uD2B8\uB7EC\uBE14\uC288\uD305 \uBB38\uC11C \uC0DD\uC131: ${path5.relative(process.cwd(), tsFilePath)}`));
1984
1964
  }
1985
1965
  }
1986
- console.log(chalk6.green.bold(`
1966
+ console.log(chalk5.green.bold(`
1987
1967
  ${ko.recap.done}`));
1988
- console.log(chalk6.dim(` \u{1F4C4} ${path5.relative(process.cwd(), filePath)}`));
1968
+ console.log(chalk5.dim(` \u{1F4C4} ${path5.relative(process.cwd(), filePath)}`));
1989
1969
  const claudeMdPath = path5.join(process.cwd(), "CLAUDE.md");
1990
1970
  if (fs4.existsSync(claudeMdPath)) {
1991
1971
  const { updateClaude } = await inquirer3.prompt([{
@@ -2005,7 +1985,7 @@ ${ko.recap.done}`));
2005
1985
  `- **\uB2E4\uC74C \uC561\uC158:** ${answers.nextTodo}`
2006
1986
  );
2007
1987
  fs4.writeFileSync(claudeMdPath, claudeContent, "utf-8");
2008
- console.log(chalk6.green(" \u2705 CLAUDE.md \uC5C5\uB370\uC774\uD2B8 \uC644\uB8CC"));
1988
+ console.log(chalk5.green(" \u2705 CLAUDE.md \uC5C5\uB370\uC774\uD2B8 \uC644\uB8CC"));
2009
1989
  }
2010
1990
  }
2011
1991
  const gitSaveCmd = process.platform === "win32" ? 'git add .; git commit -m "recap: \uC138\uC158 \uAE30\uB85D"' : 'git add . && git commit -m "recap: \uC138\uC158 \uAE30\uB85D"';
@@ -2017,7 +1997,7 @@ ${ko.recap.done}`));
2017
1997
  }
2018
1998
 
2019
1999
  // src/commands/check.ts
2020
- import chalk8 from "chalk";
2000
+ import chalk7 from "chalk";
2021
2001
  import path7 from "path";
2022
2002
  import fs6 from "fs";
2023
2003
 
@@ -2181,7 +2161,7 @@ function escapeRegex(str) {
2181
2161
  // src/commands/goal.ts
2182
2162
  import { existsSync as existsSync3, mkdirSync as mkdirSync2, writeFileSync as writeFileSync2, readFileSync as readFileSync3 } from "fs";
2183
2163
  import { join as join4 } from "path";
2184
- import chalk7 from "chalk";
2164
+ import chalk6 from "chalk";
2185
2165
 
2186
2166
  // src/lib/goal-frontmatter.ts
2187
2167
  import { existsSync as existsSync2, readFileSync as readFileSync2, readdirSync, statSync } from "fs";
@@ -2361,14 +2341,14 @@ function resolveGoalId(optId, goals) {
2361
2341
  return selectActiveId(goals);
2362
2342
  }
2363
2343
  async function goalList() {
2364
- console.log(chalk7.bold(`
2344
+ console.log(chalk6.bold(`
2365
2345
  ${ko.goal.listTitle}
2366
2346
  `));
2367
2347
  const goals = listGoals(GOALS_DIR);
2368
2348
  const skipped = findSkippedGoalFiles(GOALS_DIR);
2369
2349
  if (goals.length === 0) {
2370
- console.log(chalk7.yellow(" \u{1F4ED} goals/ \uB514\uB809\uD1A0\uB9AC\uC5D0 goal \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4."));
2371
- console.log(chalk7.dim(" vhk goal init \uC73C\uB85C \uC2DC\uC791\uD558\uC138\uC694."));
2350
+ console.log(chalk6.yellow(" \u{1F4ED} goals/ \uB514\uB809\uD1A0\uB9AC\uC5D0 goal \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4."));
2351
+ console.log(chalk6.dim(" vhk goal init \uC73C\uB85C \uC2DC\uC791\uD558\uC138\uC694."));
2372
2352
  printSkippedGoalWarnings(skipped);
2373
2353
  return;
2374
2354
  }
@@ -2386,33 +2366,33 @@ ${ko.goal.listTitle}
2386
2366
  const dups = findDuplicateIds(goals);
2387
2367
  if (dups.length > 0) {
2388
2368
  console.log("");
2389
- console.log(chalk7.yellow(` ${ko.goal.duplicateId(dups.join(", "))}`));
2369
+ console.log(chalk6.yellow(` ${ko.goal.duplicateId(dups.join(", "))}`));
2390
2370
  }
2391
2371
  printSkippedGoalWarnings(skipped);
2392
2372
  }
2393
2373
  function printSkippedGoalWarnings(skipped) {
2394
2374
  if (skipped.length > 0) {
2395
2375
  console.log("");
2396
- console.log(chalk7.yellow(` ${ko.goal.skippedFiles(skipped.length)}`));
2376
+ console.log(chalk6.yellow(` ${ko.goal.skippedFiles(skipped.length)}`));
2397
2377
  for (const s of skipped) {
2398
- console.log(chalk7.yellow(` - goals/${s.file}: ${s.reason}`));
2378
+ console.log(chalk6.yellow(` - goals/${s.file}: ${s.reason}`));
2399
2379
  }
2400
- console.log(chalk7.dim(" \uD544\uC218: type: goal + \uC22B\uC790 id. \uC2A4\uD0A4\uB9C8 \uC804\uCCB4: goals/_meta.md"));
2380
+ console.log(chalk6.dim(" \uD544\uC218: type: goal + \uC22B\uC790 id. \uC2A4\uD0A4\uB9C8 \uC804\uCCB4: goals/_meta.md"));
2401
2381
  }
2402
2382
  }
2403
2383
  async function goalNext() {
2404
- console.log(chalk7.bold(`
2384
+ console.log(chalk6.bold(`
2405
2385
  ${ko.goal.nextTitle}
2406
2386
  `));
2407
2387
  const goals = listGoals(GOALS_DIR);
2408
2388
  if (goals.length === 0) {
2409
- console.log(chalk7.yellow(" \u{1F4ED} \uC815\uC758\uB41C goal \uC774 \uC5C6\uC2B5\uB2C8\uB2E4."));
2410
- console.log(chalk7.dim(" vhk goal init \uC73C\uB85C \uC2DC\uC791\uD558\uC138\uC694."));
2389
+ console.log(chalk6.yellow(" \u{1F4ED} \uC815\uC758\uB41C goal \uC774 \uC5C6\uC2B5\uB2C8\uB2E4."));
2390
+ console.log(chalk6.dim(" vhk goal init \uC73C\uB85C \uC2DC\uC791\uD558\uC138\uC694."));
2411
2391
  return;
2412
2392
  }
2413
2393
  const activeId = selectActiveId(goals);
2414
2394
  if (activeId === null) {
2415
- console.log(chalk7.green(" \u{1F389} \uBAA8\uB4E0 goal \uC774 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4!"));
2395
+ console.log(chalk6.green(" \u{1F389} \uBAA8\uB4E0 goal \uC774 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4!"));
2416
2396
  return;
2417
2397
  }
2418
2398
  const active = goals.find((g) => g.frontmatter.id === activeId);
@@ -2434,7 +2414,7 @@ ${ko.goal.nextTitle}
2434
2414
  mkdirSync2(STATE_DIR2, { recursive: true });
2435
2415
  writeFileSync2(join4(STATE_DIR2, "next-task.md"), text, "utf-8");
2436
2416
  console.log(
2437
- chalk7.green(
2417
+ chalk6.green(
2438
2418
  ` \u2705 next-task.md \uAC31\uC2E0 \u2014 Goal ${activeId}: ${active.frontmatter.title ?? ""}`
2439
2419
  )
2440
2420
  );
@@ -2493,7 +2473,7 @@ var STATE_NEXT_TASK_TEMPLATE = "# Next Task\n\n```\nTASK: (vhk goal next \uB85C
2493
2473
  var STATE_BLOCKERS_TEMPLATE = "# Blockers\n\n_Append-only. \uD574\uACB0 \uD56D\uBAA9\uC740 ~~\uCDE8\uC18C\uC120~~\uC73C\uB85C \uD45C\uAE30._\n";
2494
2474
  var STATE_LEARNINGS_TEMPLATE = "# Learnings\n\n_Append-only. \uD55C \uC904 = \uD55C \uAD50\uD6C8._\n";
2495
2475
  async function goalInit() {
2496
- console.log(chalk7.bold(`
2476
+ console.log(chalk6.bold(`
2497
2477
  ${ko.goal.initTitle}
2498
2478
  `));
2499
2479
  const targets = [
@@ -2508,15 +2488,15 @@ ${ko.goal.initTitle}
2508
2488
  let skipped = 0;
2509
2489
  for (const t2 of targets) {
2510
2490
  if (existsSync3(t2.path)) {
2511
- console.log(chalk7.gray(` \u2298 skip (\uC774\uBBF8 \uC874\uC7AC): ${t2.path}`));
2491
+ console.log(chalk6.gray(` \u2298 skip (\uC774\uBBF8 \uC874\uC7AC): ${t2.path}`));
2512
2492
  skipped++;
2513
2493
  } else {
2514
2494
  writeFileSync2(t2.path, t2.content, "utf-8");
2515
- console.log(chalk7.green(` \u2713 created: ${t2.path}`));
2495
+ console.log(chalk6.green(` \u2713 created: ${t2.path}`));
2516
2496
  created++;
2517
2497
  }
2518
2498
  }
2519
- console.log(chalk7.bold(`
2499
+ console.log(chalk6.bold(`
2520
2500
  \u{1F4CA} created=${created} skipped=${skipped}`));
2521
2501
  if (created > 0) {
2522
2502
  printNextStep({
@@ -2542,76 +2522,76 @@ function runGate(scriptPath) {
2542
2522
  function warnIfBashOnWindows(scriptPath) {
2543
2523
  if (process.platform === "win32" && scriptPath.endsWith(".sh")) {
2544
2524
  console.log(
2545
- chalk7.yellow(
2525
+ chalk6.yellow(
2546
2526
  " \u26A0 Windows: .sh \uAC8C\uC774\uD2B8\uB294 bash \uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. cross-platform .mjs \uB85C \uBC31\uD544\uD558\uC138\uC694 \u2192 vhk goal sync"
2547
2527
  )
2548
2528
  );
2549
2529
  }
2550
2530
  }
2551
2531
  async function goalCheck(opts) {
2552
- console.log(chalk7.bold(`
2532
+ console.log(chalk6.bold(`
2553
2533
  ${ko.goal.checkTitle}
2554
2534
  `));
2555
2535
  const goals = listGoals(GOALS_DIR);
2556
2536
  const id = resolveGoalId(opts.id, goals);
2557
2537
  if (id === null) {
2558
2538
  console.log(
2559
- chalk7.yellow(" \u26A0 \uB300\uC0C1 goal \uC744 \uACB0\uC815\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4 (--id \uBA85\uC2DC \uB610\uB294 active goal \uD544\uC694).")
2539
+ chalk6.yellow(" \u26A0 \uB300\uC0C1 goal \uC744 \uACB0\uC815\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4 (--id \uBA85\uC2DC \uB610\uB294 active goal \uD544\uC694).")
2560
2540
  );
2561
2541
  process.exitCode = 1;
2562
2542
  return;
2563
2543
  }
2564
2544
  if (!goals.some((g) => g.frontmatter.id === id)) {
2565
- console.log(chalk7.red(` \u274C ${ko.goal.notFound(id)}`));
2545
+ console.log(chalk6.red(` \u274C ${ko.goal.notFound(id)}`));
2566
2546
  process.exitCode = 1;
2567
2547
  return;
2568
2548
  }
2569
2549
  const scriptPath = findGateScript(id);
2570
2550
  if (!scriptPath) {
2571
2551
  console.log(
2572
- chalk7.red(` \u274C \uAC8C\uC774\uD2B8 \uC2A4\uD06C\uB9BD\uD2B8 \uC5C6\uC74C: scripts/check-goal-${id}.{mjs,sh}`)
2552
+ chalk6.red(` \u274C \uAC8C\uC774\uD2B8 \uC2A4\uD06C\uB9BD\uD2B8 \uC5C6\uC74C: scripts/check-goal-${id}.{mjs,sh}`)
2573
2553
  );
2574
2554
  process.exitCode = 1;
2575
2555
  return;
2576
2556
  }
2577
2557
  warnIfBashOnWindows(scriptPath);
2578
2558
  const gate2 = runGate(scriptPath);
2579
- console.log(chalk7.dim(` \u25B6 ${gate2.runner} ${scriptPath}
2559
+ console.log(chalk6.dim(` \u25B6 ${gate2.runner} ${scriptPath}
2580
2560
  `));
2581
2561
  if (gate2.out) console.log(gate2.out);
2582
2562
  if (gate2.ok) {
2583
- console.log(chalk7.green(`
2563
+ console.log(chalk6.green(`
2584
2564
  \u2705 Goal ${id} \uAC8C\uC774\uD2B8 \uD1B5\uACFC`));
2585
2565
  } else {
2586
- console.log(chalk7.red(`
2566
+ console.log(chalk6.red(`
2587
2567
  \u274C Goal ${id} \uAC8C\uC774\uD2B8 \uC2E4\uD328`));
2588
- if (gate2.err && !gate2.out) console.log(chalk7.dim(gate2.err.slice(0, 500)));
2568
+ if (gate2.err && !gate2.out) console.log(chalk6.dim(gate2.err.slice(0, 500)));
2589
2569
  process.exitCode = 1;
2590
2570
  }
2591
2571
  }
2592
2572
  async function goalDone(opts) {
2593
- console.log(chalk7.bold(`
2573
+ console.log(chalk6.bold(`
2594
2574
  ${ko.goal.doneTitle}
2595
2575
  `));
2596
2576
  const goals = listGoals(GOALS_DIR);
2597
2577
  const id = resolveGoalId(opts.id, goals);
2598
2578
  if (id === null) {
2599
2579
  console.log(
2600
- chalk7.yellow(" \u26A0 \uB300\uC0C1 goal \uC744 \uACB0\uC815\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4 (--id \uBA85\uC2DC \uB610\uB294 active goal \uD544\uC694).")
2580
+ chalk6.yellow(" \u26A0 \uB300\uC0C1 goal \uC744 \uACB0\uC815\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4 (--id \uBA85\uC2DC \uB610\uB294 active goal \uD544\uC694).")
2601
2581
  );
2602
2582
  process.exitCode = 1;
2603
2583
  return;
2604
2584
  }
2605
2585
  const target = goals.find((g) => g.frontmatter.id === id);
2606
2586
  if (!target) {
2607
- console.log(chalk7.red(` \u274C ${ko.goal.notFound(id)}`));
2587
+ console.log(chalk6.red(` \u274C ${ko.goal.notFound(id)}`));
2608
2588
  process.exitCode = 1;
2609
2589
  return;
2610
2590
  }
2611
2591
  const scriptPath = findGateScript(id);
2612
2592
  if (!scriptPath) {
2613
2593
  console.log(
2614
- chalk7.red(
2594
+ chalk6.red(
2615
2595
  ` \u274C \uAC8C\uC774\uD2B8 \uC2A4\uD06C\uB9BD\uD2B8 \uC5C6\uC74C \u2014 done \uCC98\uB9AC \uAC70\uBD80: scripts/check-goal-${id}.{mjs,sh}`
2616
2596
  )
2617
2597
  );
@@ -2620,12 +2600,12 @@ ${ko.goal.doneTitle}
2620
2600
  }
2621
2601
  warnIfBashOnWindows(scriptPath);
2622
2602
  const gate2 = runGate(scriptPath);
2623
- console.log(chalk7.dim(` \u25B6 \uAC8C\uC774\uD2B8 \uAC80\uC99D: ${gate2.runner} ${scriptPath}
2603
+ console.log(chalk6.dim(` \u25B6 \uAC8C\uC774\uD2B8 \uAC80\uC99D: ${gate2.runner} ${scriptPath}
2624
2604
  `));
2625
2605
  if (gate2.out) console.log(gate2.out);
2626
2606
  if (!gate2.ok) {
2627
2607
  console.log(
2628
- chalk7.red(
2608
+ chalk6.red(
2629
2609
  `
2630
2610
  \u274C \uAC8C\uC774\uD2B8 \uC2E4\uD328 \u2014 frontmatter \uBCC0\uACBD \uC5C6\uC774 \uC885\uB8CC. (Forbidden: \uC2E4\uD328 = \uBCF4\uC874)`
2631
2611
  )
@@ -2637,7 +2617,7 @@ ${ko.goal.doneTitle}
2637
2617
  const today = localDate();
2638
2618
  const updated = updateFrontmatterStatus(content, "DONE", { completed: today });
2639
2619
  writeFileSync2(target.filePath, updated, "utf-8");
2640
- console.log(chalk7.green(`
2620
+ console.log(chalk6.green(`
2641
2621
  \u2705 Goal ${id} \u2192 DONE (completed: ${today})`));
2642
2622
  printNextStep({
2643
2623
  message: `Goal ${id} \uC644\uB8CC! \uB2E4\uC74C goal \uB85C:`,
@@ -2710,14 +2690,14 @@ function generateGateScript(id) {
2710
2690
  ].join("\n");
2711
2691
  }
2712
2692
  async function goalSync() {
2713
- console.log(chalk7.bold(`
2693
+ console.log(chalk6.bold(`
2714
2694
  ${ko.goal.syncTitle}
2715
2695
  `));
2716
2696
  const goals = listGoals(GOALS_DIR);
2717
2697
  const result = { created: [], skipped: [] };
2718
2698
  if (goals.length === 0) {
2719
2699
  console.log(
2720
- chalk7.yellow(" \u{1F4ED} goals/ \uC5D0 goal \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. vhk goal init \uC73C\uB85C \uC2DC\uC791\uD558\uC138\uC694.")
2700
+ chalk6.yellow(" \u{1F4ED} goals/ \uC5D0 goal \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. vhk goal init \uC73C\uB85C \uC2DC\uC791\uD558\uC138\uC694.")
2721
2701
  );
2722
2702
  return result;
2723
2703
  }
@@ -2727,19 +2707,19 @@ ${ko.goal.syncTitle}
2727
2707
  if (typeof id !== "number") continue;
2728
2708
  const target = join4(SCRIPTS_DIR, `check-goal-${id}.mjs`);
2729
2709
  if (existsSync3(target)) {
2730
- console.log(chalk7.gray(` \u2298 skip (\uC774\uBBF8 \uC874\uC7AC): ${target}`));
2710
+ console.log(chalk6.gray(` \u2298 skip (\uC774\uBBF8 \uC874\uC7AC): ${target}`));
2731
2711
  result.skipped.push(id);
2732
2712
  continue;
2733
2713
  }
2734
2714
  const shOnly = existsSync3(join4(SCRIPTS_DIR, `check-goal-${id}.sh`));
2735
2715
  writeFileSync2(target, generateGateScript(id), "utf-8");
2736
2716
  console.log(
2737
- chalk7.green(` \u2713 created: ${target}${shOnly ? " (.sh \u2192 .mjs \uBC31\uD544, Windows 1\uAE09)" : ""}`)
2717
+ chalk6.green(` \u2713 created: ${target}${shOnly ? " (.sh \u2192 .mjs \uBC31\uD544, Windows 1\uAE09)" : ""}`)
2738
2718
  );
2739
2719
  result.created.push(id);
2740
2720
  }
2741
2721
  console.log(
2742
- chalk7.bold(`
2722
+ chalk6.bold(`
2743
2723
  \u{1F4CA} created=${result.created.length} skipped=${result.skipped.length}`)
2744
2724
  );
2745
2725
  if (result.created.length > 0) {
@@ -2760,22 +2740,22 @@ async function check(opts = {}) {
2760
2740
  return checkRules();
2761
2741
  }
2762
2742
  async function checkRules() {
2763
- console.log(chalk8.bold(`
2743
+ console.log(chalk7.bold(`
2764
2744
  ${ko.check.title}
2765
2745
  `));
2766
2746
  const cwd = process.cwd();
2767
2747
  const rulesPath = path7.join(cwd, "RULES.md");
2768
2748
  if (!fs6.existsSync(rulesPath)) {
2769
- console.log(chalk8.yellow(ko.check.noRules));
2770
- console.log(chalk8.dim(" vhk init\uC73C\uB85C \uC2DC\uC791\uD558\uAC70\uB098 RULES.md\uB97C \uB9CC\uB4E4\uC5B4 \uBCF4\uC138\uC694."));
2749
+ console.log(chalk7.yellow(ko.check.noRules));
2750
+ console.log(chalk7.dim(" vhk init\uC73C\uB85C \uC2DC\uC791\uD558\uAC70\uB098 RULES.md\uB97C \uB9CC\uB4E4\uC5B4 \uBCF4\uC138\uC694."));
2771
2751
  return;
2772
2752
  }
2773
2753
  const rules = parseRules(rulesPath);
2774
- console.log(chalk8.dim(` \u{1F4CF} \uC790\uB3D9 \uAC80\uC99D \uAC00\uB2A5\uD55C \uADDC\uCE59 ${rules.length}\uAC1C \uAC10\uC9C0 (\uB098\uBA38\uC9C0 \uADDC\uCE59\uC740 \uC218\uB3D9/\uB3C4\uAD6C \uD655\uC778)
2754
+ console.log(chalk7.dim(` \u{1F4CF} \uC790\uB3D9 \uAC80\uC99D \uAC00\uB2A5\uD55C \uADDC\uCE59 ${rules.length}\uAC1C \uAC10\uC9C0 (\uB098\uBA38\uC9C0 \uADDC\uCE59\uC740 \uC218\uB3D9/\uB3C4\uAD6C \uD655\uC778)
2775
2755
  `));
2776
2756
  if (rules.length === 0) {
2777
- console.log(chalk8.yellow(ko.check.noAutoRules));
2778
- console.log(chalk8.dim(" RULES.md\uC5D0 \uD30C\uC77C \uC774\uB984\xB7\uD3F4\uB354 \uADDC\uCE59\uC744 \uC801\uC73C\uBA74 \uC790\uB3D9\uC73C\uB85C \uC810\uAC80\uD574\uC694."));
2757
+ console.log(chalk7.yellow(ko.check.noAutoRules));
2758
+ console.log(chalk7.dim(" RULES.md\uC5D0 \uD30C\uC77C \uC774\uB984\xB7\uD3F4\uB354 \uADDC\uCE59\uC744 \uC801\uC73C\uBA74 \uC790\uB3D9\uC73C\uB85C \uC810\uAC80\uD574\uC694."));
2779
2759
  return;
2780
2760
  }
2781
2761
  const allViolations = [];
@@ -2783,14 +2763,14 @@ ${ko.check.title}
2783
2763
  for (const rule of rules) {
2784
2764
  const violations = rule.check(cwd);
2785
2765
  if (violations.length === 0) {
2786
- const patternHint = rule.type === "content" && rule.pattern ? chalk8.dim(` [\uAC80\uC0AC: ${rule.pattern.source}]`) : "";
2787
- console.log(chalk8.green(` \u2705 ${rule.id}`) + chalk8.dim(` \u2014 ${rule.description.slice(0, 60)}`) + patternHint);
2766
+ const patternHint = rule.type === "content" && rule.pattern ? chalk7.dim(` [\uAC80\uC0AC: ${rule.pattern.source}]`) : "";
2767
+ console.log(chalk7.green(` \u2705 ${rule.id}`) + chalk7.dim(` \u2014 ${rule.description.slice(0, 60)}`) + patternHint);
2788
2768
  passCount++;
2789
2769
  } else {
2790
- console.log(chalk8.red(` \u274C ${rule.id}`) + chalk8.dim(` \u2014 ${violations.length}\uAC74 \uC704\uBC18`));
2770
+ console.log(chalk7.red(` \u274C ${rule.id}`) + chalk7.dim(` \u2014 ${violations.length}\uAC74 \uC704\uBC18`));
2791
2771
  violations.forEach((v) => {
2792
- const loc = v.file ? chalk8.dim(` (${v.file}${v.line ? ":" + v.line : ""})`) : "";
2793
- const icon = v.severity === "error" ? chalk8.red("\u2716") : v.severity === "warning" ? chalk8.yellow("\u26A0") : chalk8.blue("\u2139");
2772
+ const loc = v.file ? chalk7.dim(` (${v.file}${v.line ? ":" + v.line : ""})`) : "";
2773
+ const icon = v.severity === "error" ? chalk7.red("\u2716") : v.severity === "warning" ? chalk7.yellow("\u26A0") : chalk7.blue("\u2139");
2794
2774
  console.log(` ${icon} ${v.message}${loc}`);
2795
2775
  });
2796
2776
  allViolations.push(...violations);
@@ -2800,18 +2780,18 @@ ${ko.check.title}
2800
2780
  const errors = allViolations.filter((v) => v.severity === "error").length;
2801
2781
  const warnings = allViolations.filter((v) => v.severity === "warning").length;
2802
2782
  if (allViolations.length === 0) {
2803
- console.log(chalk8.green.bold(`\u2705 \uC790\uB3D9 \uAC80\uC99D \uAC00\uB2A5\uD55C \uADDC\uCE59 ${passCount}\uAC1C \uD1B5\uACFC`));
2804
- console.log(chalk8.dim(" (RULES.md \uC758 \uB098\uBA38\uC9C0 \uADDC\uCE59\uC740 \uCF54\uB4DC \uC790\uB3D9 \uAC80\uC0AC \uBD88\uAC00 \u2014 \uC9C1\uC811/\uB3C4\uAD6C\uB85C \uD655\uC778\uD558\uC138\uC694.)"));
2783
+ console.log(chalk7.green.bold(`\u2705 \uC790\uB3D9 \uAC80\uC99D \uAC00\uB2A5\uD55C \uADDC\uCE59 ${passCount}\uAC1C \uD1B5\uACFC`));
2784
+ console.log(chalk7.dim(" (RULES.md \uC758 \uB098\uBA38\uC9C0 \uADDC\uCE59\uC740 \uCF54\uB4DC \uC790\uB3D9 \uAC80\uC0AC \uBD88\uAC00 \u2014 \uC9C1\uC811/\uB3C4\uAD6C\uB85C \uD655\uC778\uD558\uC138\uC694.)"));
2805
2785
  printNextStep({
2806
2786
  message: "\uBAA8\uB4E0 \uADDC\uCE59 \uD1B5\uACFC! \uBCF4\uC548 \uC2A4\uCE94\uB3C4 \uD574\uBCFC\uAE4C\uC694?",
2807
2787
  command: "vhk \uBCF4\uC548 scan",
2808
2788
  cursorHint: "\uBCF4\uC548 \uC2A4\uCE94 \uB3CC\uB824\uC918"
2809
2789
  });
2810
2790
  } else {
2811
- console.log(chalk8.bold(ko.check.summary));
2812
- console.log(` \uADDC\uCE59: ${chalk8.cyan(String(rules.length))}\uAC1C | \uD1B5\uACFC: ${chalk8.green(String(passCount))}\uAC1C | \uC704\uBC18: ${chalk8.red(String(allViolations.length))}\uAC74`);
2813
- if (errors > 0) console.log(` ${chalk8.red(`\u2716 ${errors}\uAC1C \uC5D0\uB7EC`)}`);
2814
- if (warnings > 0) console.log(` ${chalk8.yellow(`\u26A0 ${warnings}\uAC1C \uACBD\uACE0`)}`);
2791
+ console.log(chalk7.bold(ko.check.summary));
2792
+ console.log(` \uADDC\uCE59: ${chalk7.cyan(String(rules.length))}\uAC1C | \uD1B5\uACFC: ${chalk7.green(String(passCount))}\uAC1C | \uC704\uBC18: ${chalk7.red(String(allViolations.length))}\uAC74`);
2793
+ if (errors > 0) console.log(` ${chalk7.red(`\u2716 ${errors}\uAC1C \uC5D0\uB7EC`)}`);
2794
+ if (warnings > 0) console.log(` ${chalk7.yellow(`\u26A0 ${warnings}\uAC1C \uACBD\uACE0`)}`);
2815
2795
  printNextStep({
2816
2796
  message: "\uC704\uBC18 \uD56D\uBAA9\uC744 \uC218\uC815\uD55C \uD6C4 \uB2E4\uC2DC \uC810\uAC80\uD558\uC138\uC694.",
2817
2797
  command: "vhk \uC810\uAC80",
@@ -2824,36 +2804,36 @@ ${ko.check.title}
2824
2804
  }
2825
2805
 
2826
2806
  // src/commands/secure.ts
2827
- import chalk9 from "chalk";
2807
+ import chalk8 from "chalk";
2828
2808
  import fs7 from "fs";
2829
2809
  import path8 from "path";
2830
2810
  async function secure() {
2831
- console.log(chalk9.bold(`
2811
+ console.log(chalk8.bold(`
2832
2812
  ${ko.secure.title}
2833
2813
  `));
2834
2814
  const cwd = process.cwd();
2835
2815
  const gitignorePath = path8.join(cwd, ".gitignore");
2836
2816
  const hasGitignore = fs7.existsSync(gitignorePath);
2837
2817
  if (!hasGitignore) {
2838
- console.log(chalk9.yellow(` ${ko.secure.noGitignore}`));
2839
- console.log(chalk9.dim(" .env \uD30C\uC77C\uC774 \uCEE4\uBC0B\uB420 \uC218 \uC788\uC2B5\uB2C8\uB2E4.\n"));
2818
+ console.log(chalk8.yellow(` ${ko.secure.noGitignore}`));
2819
+ console.log(chalk8.dim(" .env \uD30C\uC77C\uC774 \uCEE4\uBC0B\uB420 \uC218 \uC788\uC2B5\uB2C8\uB2E4.\n"));
2840
2820
  } else {
2841
2821
  const gitignoreContent = fs7.readFileSync(gitignorePath, "utf-8");
2842
2822
  if (!gitignoreContent.includes(".env")) {
2843
- console.log(chalk9.yellow(` ${ko.secure.noEnvInGitignore}`));
2844
- console.log(chalk9.dim(" \uCD94\uAC00\uB97C \uAD8C\uC7A5\uD569\uB2C8\uB2E4.\n"));
2823
+ console.log(chalk8.yellow(` ${ko.secure.noEnvInGitignore}`));
2824
+ console.log(chalk8.dim(" \uCD94\uAC00\uB97C \uAD8C\uC7A5\uD569\uB2C8\uB2E4.\n"));
2845
2825
  }
2846
2826
  }
2847
- console.log(chalk9.dim(` ${ko.secure.scanning}
2827
+ console.log(chalk8.dim(` ${ko.secure.scanning}
2848
2828
  `));
2849
2829
  const { findings, scannedFiles, truncated } = scanProjectForSecrets(cwd);
2850
- console.log(chalk9.dim(` \u{1F4C2} ${scannedFiles}\uAC1C \uD30C\uC77C \uC2A4\uCE94 \uC644\uB8CC (lock\xB7node_modules\xB7>${MAX_SCAN_FILE_BYTES / 1024}KB \uC81C\uC678)`));
2830
+ console.log(chalk8.dim(` \u{1F4C2} ${scannedFiles}\uAC1C \uD30C\uC77C \uC2A4\uCE94 \uC644\uB8CC (lock\xB7node_modules\xB7>${MAX_SCAN_FILE_BYTES / 1024}KB \uC81C\uC678)`));
2851
2831
  if (truncated) {
2852
- console.log(chalk9.yellow(` \u26A0\uFE0F \uACB0\uACFC ${MAX_SECRET_FINDINGS}\uAC74\uC5D0\uC11C \uCD9C\uB825\uC744 \uC81C\uD55C\uD588\uC2B5\uB2C8\uB2E4. lock \uD30C\uC77C \uB4F1\uC740 \uC790\uB3D9 \uC81C\uC678\uB429\uB2C8\uB2E4.`));
2832
+ console.log(chalk8.yellow(` \u26A0\uFE0F \uACB0\uACFC ${MAX_SECRET_FINDINGS}\uAC74\uC5D0\uC11C \uCD9C\uB825\uC744 \uC81C\uD55C\uD588\uC2B5\uB2C8\uB2E4. lock \uD30C\uC77C \uB4F1\uC740 \uC790\uB3D9 \uC81C\uC678\uB429\uB2C8\uB2E4.`));
2853
2833
  }
2854
2834
  console.log("");
2855
2835
  if (findings.length === 0) {
2856
- console.log(chalk9.green.bold(` ${ko.secure.clean}`));
2836
+ console.log(chalk8.green.bold(` ${ko.secure.clean}`));
2857
2837
  printNextStep({
2858
2838
  message: "\uBCF4\uC548 \uC774\uC0C1 \uC5C6\uC74C! \uAE68\uB057\uD569\uB2C8\uB2E4.",
2859
2839
  command: "vhk \uC815\uB9AC",
@@ -2865,43 +2845,43 @@ ${ko.secure.title}
2865
2845
  const high = findings.filter((f) => f.severity === "high");
2866
2846
  const medium = findings.filter((f) => f.severity === "medium");
2867
2847
  if (critical.length > 0) {
2868
- console.log(chalk9.red.bold(` \u{1F6A8} CRITICAL \u2014 ${critical.length}\uAC74`));
2848
+ console.log(chalk8.red.bold(` \u{1F6A8} CRITICAL \u2014 ${critical.length}\uAC74`));
2869
2849
  critical.forEach((f) => {
2870
- console.log(chalk9.red(` \u2716 ${f.patternName}`));
2871
- console.log(chalk9.dim(` ${f.file}:${f.line} \u2192 ${f.match}`));
2850
+ console.log(chalk8.red(` \u2716 ${f.patternName}`));
2851
+ console.log(chalk8.dim(` ${f.file}:${f.line} \u2192 ${f.match}`));
2872
2852
  });
2873
2853
  console.log("");
2874
2854
  }
2875
2855
  if (high.length > 0) {
2876
- console.log(chalk9.yellow.bold(` \u26A0\uFE0F HIGH \u2014 ${high.length}\uAC74`));
2856
+ console.log(chalk8.yellow.bold(` \u26A0\uFE0F HIGH \u2014 ${high.length}\uAC74`));
2877
2857
  high.forEach((f) => {
2878
- console.log(chalk9.yellow(` \u26A0 ${f.patternName}`));
2879
- console.log(chalk9.dim(` ${f.file}:${f.line} \u2192 ${f.match}`));
2858
+ console.log(chalk8.yellow(` \u26A0 ${f.patternName}`));
2859
+ console.log(chalk8.dim(` ${f.file}:${f.line} \u2192 ${f.match}`));
2880
2860
  });
2881
2861
  console.log("");
2882
2862
  }
2883
2863
  if (medium.length > 0) {
2884
- console.log(chalk9.blue.bold(` \u2139 MEDIUM \u2014 ${medium.length}\uAC74`));
2864
+ console.log(chalk8.blue.bold(` \u2139 MEDIUM \u2014 ${medium.length}\uAC74`));
2885
2865
  medium.forEach((f) => {
2886
- console.log(chalk9.blue(` \u2139 ${f.patternName}`));
2887
- console.log(chalk9.dim(` ${f.file}:${f.line} \u2192 ${f.match}`));
2866
+ console.log(chalk8.blue(` \u2139 ${f.patternName}`));
2867
+ console.log(chalk8.dim(` ${f.file}:${f.line} \u2192 ${f.match}`));
2888
2868
  });
2889
2869
  console.log("");
2890
2870
  }
2891
- console.log(chalk9.bold(` ${ko.secure.summary}`));
2892
- console.log(` \uCD1D ${chalk9.red(String(findings.length))}\uAC74 \uAC10\uC9C0 | CRITICAL: ${critical.length} | HIGH: ${high.length} | MEDIUM: ${medium.length}`);
2871
+ console.log(chalk8.bold(` ${ko.secure.summary}`));
2872
+ console.log(` \uCD1D ${chalk8.red(String(findings.length))}\uAC74 \uAC10\uC9C0 | CRITICAL: ${critical.length} | HIGH: ${high.length} | MEDIUM: ${medium.length}`);
2893
2873
  console.log("");
2894
- console.log(chalk9.dim(" \u{1F4A1} \uC870\uCE58 \uBC29\uBC95:"));
2895
- console.log(chalk9.dim(" 1. \uD574\uB2F9 \uD30C\uC77C\uC5D0\uC11C \uC2DC\uD06C\uB9BF\uC744 \uC81C\uAC70\uD558\uACE0 \uD658\uACBD\uBCC0\uC218\uB85C \uC774\uB3D9"));
2896
- console.log(chalk9.dim(" 2. git history\uC5D0\uC11C\uB3C4 \uC81C\uAC70: git filter-branch \uB610\uB294 BFG Repo-Cleaner"));
2897
- console.log(chalk9.dim(" 3. \uC720\uCD9C\uB41C \uD0A4\uB294 \uC989\uC2DC \uD3D0\uAE30\uD558\uACE0 \uC7AC\uBC1C\uAE09\n"));
2874
+ console.log(chalk8.dim(" \u{1F4A1} \uC870\uCE58 \uBC29\uBC95:"));
2875
+ console.log(chalk8.dim(" 1. \uD574\uB2F9 \uD30C\uC77C\uC5D0\uC11C \uC2DC\uD06C\uB9BF\uC744 \uC81C\uAC70\uD558\uACE0 \uD658\uACBD\uBCC0\uC218\uB85C \uC774\uB3D9"));
2876
+ console.log(chalk8.dim(" 2. git history\uC5D0\uC11C\uB3C4 \uC81C\uAC70: git filter-branch \uB610\uB294 BFG Repo-Cleaner"));
2877
+ console.log(chalk8.dim(" 3. \uC720\uCD9C\uB41C \uD0A4\uB294 \uC989\uC2DC \uD3D0\uAE30\uD558\uACE0 \uC7AC\uBC1C\uAE09\n"));
2898
2878
  if (critical.length > 0 || high.length > 0) {
2899
2879
  process.exitCode = 1;
2900
2880
  }
2901
2881
  }
2902
2882
 
2903
2883
  // src/commands/doctor.ts
2904
- import chalk10 from "chalk";
2884
+ import chalk9 from "chalk";
2905
2885
  import fs8 from "fs";
2906
2886
  import path9 from "path";
2907
2887
  import { fileURLToPath } from "url";
@@ -2947,7 +2927,7 @@ function compareSemver(a, b) {
2947
2927
  return a3 - b3;
2948
2928
  }
2949
2929
  async function doctor() {
2950
- console.log(chalk10.bold(`
2930
+ console.log(chalk9.bold(`
2951
2931
  ${ko.doctor.title}
2952
2932
  `));
2953
2933
  const checks = [
@@ -2959,30 +2939,30 @@ ${ko.doctor.title}
2959
2939
  let allOk = true;
2960
2940
  for (const check2 of checks) {
2961
2941
  if (check2.ok) {
2962
- console.log(chalk10.green(` \u2705 ${check2.name}`) + chalk10.dim(` \u2014 ${check2.version}`));
2942
+ console.log(chalk9.green(` \u2705 ${check2.name}`) + chalk9.dim(` \u2014 ${check2.version}`));
2963
2943
  } else {
2964
- console.log(chalk10.red(` \u274C ${check2.name} \uC5C6\uC74C`));
2965
- console.log(chalk10.dim(` \u2192 ${check2.hint}`));
2944
+ console.log(chalk9.red(` \u274C ${check2.name} \uC5C6\uC74C`));
2945
+ console.log(chalk9.dim(` \u2192 ${check2.hint}`));
2966
2946
  allOk = false;
2967
2947
  }
2968
2948
  }
2969
2949
  console.log("");
2970
2950
  const vhkVersion = getVhkVersion2();
2971
2951
  if (vhkVersion) {
2972
- console.log(chalk10.green(" \u2705 VHK") + chalk10.dim(` \u2014 v${vhkVersion}`));
2952
+ console.log(chalk9.green(" \u2705 VHK") + chalk9.dim(` \u2014 v${vhkVersion}`));
2973
2953
  } else {
2974
- console.log(chalk10.green(" \u2705 VHK") + chalk10.dim(" \u2014 \uC124\uCE58\uB428"));
2954
+ console.log(chalk9.green(" \u2705 VHK") + chalk9.dim(" \u2014 \uC124\uCE58\uB428"));
2975
2955
  }
2976
2956
  if (vhkVersion) {
2977
2957
  const latest = fetchLatestNpmVersion("@byh3071/vhk");
2978
2958
  if (latest && compareSemver(latest, vhkVersion) > 0) {
2979
- console.log(chalk10.yellow(` ${ko.doctor.updateAvailable(latest)}`));
2959
+ console.log(chalk9.yellow(` ${ko.doctor.updateAvailable(latest)}`));
2980
2960
  } else if (latest) {
2981
- console.log(chalk10.dim(` ${ko.doctor.updateCurrent}`));
2961
+ console.log(chalk9.dim(` ${ko.doctor.updateCurrent}`));
2982
2962
  }
2983
2963
  }
2984
2964
  console.log("");
2985
- console.log(chalk10.bold(` ${ko.doctor.projectFiles}`));
2965
+ console.log(chalk9.bold(` ${ko.doctor.projectFiles}`));
2986
2966
  const cwd = process.cwd();
2987
2967
  const projectFiles = [
2988
2968
  { name: "RULES.md", hint: "vhk init\uC73C\uB85C \uC0DD\uC131 \uAC00\uB2A5" },
@@ -2994,49 +2974,49 @@ ${ko.doctor.title}
2994
2974
  for (const file of projectFiles) {
2995
2975
  const exists = fs8.existsSync(path9.join(cwd, file.name));
2996
2976
  if (exists) {
2997
- console.log(chalk10.green(` \u2705 ${file.name}`));
2977
+ console.log(chalk9.green(` \u2705 ${file.name}`));
2998
2978
  if (file.name === ".env") {
2999
2979
  const gitignorePath = path9.join(cwd, ".gitignore");
3000
2980
  if (fs8.existsSync(gitignorePath)) {
3001
2981
  const gitignore = fs8.readFileSync(gitignorePath, "utf-8");
3002
2982
  if (!gitignore.includes(".env")) {
3003
- console.log(chalk10.yellow(` ${ko.doctor.envNotIgnored}`));
2983
+ console.log(chalk9.yellow(` ${ko.doctor.envNotIgnored}`));
3004
2984
  }
3005
2985
  }
3006
2986
  }
3007
2987
  } else if (file.name === ".env" && fs8.existsSync(path9.join(cwd, ".env.local"))) {
3008
- console.log(chalk10.green(" \u2705 .env.local") + chalk10.dim(" \u2014 \uB85C\uCEEC env \uC0AC\uC6A9 \uC911 (.env \uC5C6\uC5B4\uB3C4 \uC815\uC0C1)"));
2988
+ console.log(chalk9.green(" \u2705 .env.local") + chalk9.dim(" \u2014 \uB85C\uCEEC env \uC0AC\uC6A9 \uC911 (.env \uC5C6\uC5B4\uB3C4 \uC815\uC0C1)"));
3009
2989
  } else {
3010
- console.log(chalk10.dim(` \u2B1A ${file.name}`) + chalk10.dim(` \u2014 ${file.hint}`));
2990
+ console.log(chalk9.dim(` \u2B1A ${file.name}`) + chalk9.dim(` \u2014 ${file.hint}`));
3011
2991
  }
3012
2992
  }
3013
2993
  console.log("");
3014
- console.log(chalk10.bold(` ${ko.doctor.driftTitle}`));
2994
+ console.log(chalk9.bold(` ${ko.doctor.driftTitle}`));
3015
2995
  const ruleDrift = checkRuleDrift(cwd);
3016
2996
  if (!ruleDrift.checked) {
3017
- console.log(chalk10.dim(` ${ko.doctor.driftNoRules}`));
2997
+ console.log(chalk9.dim(` ${ko.doctor.driftNoRules}`));
3018
2998
  } else {
3019
2999
  const drifted = ruleDrift.results.filter((r) => r.status === "drifted");
3020
3000
  if (drifted.length === 0) {
3021
- console.log(chalk10.green(` ${ko.doctor.driftRuleClean}`));
3001
+ console.log(chalk9.green(` ${ko.doctor.driftRuleClean}`));
3022
3002
  } else {
3023
- console.log(chalk10.yellow(` ${ko.doctor.driftRuleWarn(drifted.map((d) => d.path).join(", "))}`));
3003
+ console.log(chalk9.yellow(` ${ko.doctor.driftRuleWarn(drifted.map((d) => d.path).join(", "))}`));
3024
3004
  }
3025
3005
  }
3026
3006
  const ctxDrift = checkContextDrift(cwd);
3027
3007
  if (ctxDrift.checked && ctxDrift.stale) {
3028
- console.log(chalk10.yellow(` ${ko.doctor.driftContextWarn}`));
3008
+ console.log(chalk9.yellow(` ${ko.doctor.driftContextWarn}`));
3029
3009
  }
3030
3010
  console.log("");
3031
3011
  if (allOk) {
3032
- console.log(chalk10.green.bold(` ${ko.doctor.allOk}`));
3012
+ console.log(chalk9.green.bold(` ${ko.doctor.allOk}`));
3033
3013
  printNextStep({
3034
3014
  message: ko.doctor.nextOkMessage,
3035
3015
  command: "vhk \uC2DC\uC791",
3036
3016
  cursorHint: "\uD504\uB85C\uC81D\uD2B8 \uB9CC\uB4E4\uC5B4\uC918"
3037
3017
  });
3038
3018
  } else {
3039
- console.log(chalk10.yellow.bold(` ${ko.doctor.missing} ${ko.doctor.missingHint}`));
3019
+ console.log(chalk9.yellow.bold(` ${ko.doctor.missing} ${ko.doctor.missingHint}`));
3040
3020
  printNextStep({
3041
3021
  message: ko.doctor.nextRetryMessage,
3042
3022
  command: "vhk doctor",
@@ -3047,7 +3027,7 @@ ${ko.doctor.title}
3047
3027
  }
3048
3028
 
3049
3029
  // src/commands/ship.ts
3050
- import chalk11 from "chalk";
3030
+ import chalk10 from "chalk";
3051
3031
  import inquirer4 from "inquirer";
3052
3032
  import fs9 from "fs";
3053
3033
  import path10 from "path";
@@ -3087,29 +3067,30 @@ function updateChangelogUnreleased(cwd, version, date) {
3087
3067
  }
3088
3068
  async function ship() {
3089
3069
  if (!ensureNotHardStopped("ship")) return;
3090
- console.log(chalk11.bold(`
3070
+ if (!ensureInteractive("\uBC30\uD3EC \uCCB4\uD06C\uB9AC\uC2A4\uD2B8\xB7\uD68C\uACE0\uB294 \uB300\uD654\uD615 \uC785\uB825\uC774 \uD544\uC694\uD569\uB2C8\uB2E4. PowerShell \uB4F1 TTY \uC5D0\uC11C \uC2E4\uD589\uD558\uC138\uC694.")) return;
3071
+ console.log(chalk10.bold(`
3091
3072
  ${ko.ship.title}
3092
3073
  `));
3093
3074
  const cwd = process.cwd();
3094
- console.log(chalk11.cyan.bold(` ${ko.ship.checklist}
3075
+ console.log(chalk10.cyan.bold(` ${ko.ship.checklist}
3095
3076
  `));
3096
3077
  const { passed } = await inquirer4.prompt([{
3097
3078
  type: "checkbox",
3098
3079
  name: "passed",
3099
3080
  message: ko.ship.checkboxPrompt,
3100
3081
  choices: CHECKLIST.map((c) => ({
3101
- name: `${ko.ship[c.questionKey]} ${chalk11.dim(`(${ko.ship[c.hintKey]})`)}`,
3082
+ name: `${ko.ship[c.questionKey]} ${chalk10.dim(`(${ko.ship[c.hintKey]})`)}`,
3102
3083
  value: c.id
3103
3084
  }))
3104
3085
  }]);
3105
3086
  const allPassed = passed.length === CHECKLIST.length;
3106
3087
  const skipped = CHECKLIST.filter((c) => !passed.includes(c.id));
3107
3088
  if (!allPassed) {
3108
- console.log(chalk11.yellow(`
3089
+ console.log(chalk10.yellow(`
3109
3090
  ${ko.ship.incompleteHeader}`));
3110
3091
  skipped.forEach((s) => {
3111
- console.log(chalk11.yellow(` \u2022 ${ko.ship[s.questionKey]}`));
3112
- console.log(chalk11.dim(` \u2192 ${ko.ship[s.hintKey]}`));
3092
+ console.log(chalk10.yellow(` \u2022 ${ko.ship[s.questionKey]}`));
3093
+ console.log(chalk10.dim(` \u2192 ${ko.ship[s.hintKey]}`));
3113
3094
  });
3114
3095
  const { proceed } = await inquirer4.prompt([{
3115
3096
  type: "confirm",
@@ -3126,13 +3107,13 @@ ${ko.ship.title}
3126
3107
  return;
3127
3108
  }
3128
3109
  } else {
3129
- console.log(chalk11.green(`
3110
+ console.log(chalk10.green(`
3130
3111
  ${ko.ship.allPassed}
3131
3112
  `));
3132
3113
  }
3133
- console.log(chalk11.cyan.bold(` ${ko.ship.retro}
3114
+ console.log(chalk10.cyan.bold(` ${ko.ship.retro}
3134
3115
  `));
3135
- console.log(chalk11.dim(` ${ko.ship.versionHint}`));
3116
+ console.log(chalk10.dim(` ${ko.ship.versionHint}`));
3136
3117
  const retro = await inquirer4.prompt([
3137
3118
  { type: "input", name: "version", message: ko.ship.versionPrompt },
3138
3119
  { type: "input", name: "whatWentWell", message: ko.ship.questionWell },
@@ -3175,7 +3156,7 @@ ${ko.ship.title}
3175
3156
  `*Generated by \`vhk ship\` at ${(/* @__PURE__ */ new Date()).toISOString()}*`
3176
3157
  ].join("\n");
3177
3158
  fs9.writeFileSync(filePath, content, "utf-8");
3178
- console.log(chalk11.green(`
3159
+ console.log(chalk10.green(`
3179
3160
  ${ko.ship.buildLogDone(path10.relative(cwd, filePath))}`));
3180
3161
  const changelogResult = updateChangelogUnreleased(cwd, versionSlug, today);
3181
3162
  if (changelogResult.status === "updated") {
@@ -3195,7 +3176,7 @@ ${ko.ship.title}
3195
3176
 
3196
3177
  // src/commands/save.ts
3197
3178
  import { execFileSync } from "child_process";
3198
- import chalk12 from "chalk";
3179
+ import chalk11 from "chalk";
3199
3180
  import ora from "ora";
3200
3181
  import inquirer5 from "inquirer";
3201
3182
 
@@ -3223,29 +3204,29 @@ function statusIcon(code) {
3223
3204
  return "\u{1F4C4}";
3224
3205
  }
3225
3206
  async function save() {
3226
- console.log(chalk12.bold(`
3207
+ console.log(chalk11.bold(`
3227
3208
  \u{1F4BE} ${t("save.title")}`));
3228
- console.log(chalk12.gray("\u2500".repeat(40)));
3209
+ console.log(chalk11.gray("\u2500".repeat(40)));
3229
3210
  let gitRoot;
3230
3211
  try {
3231
3212
  execFileSync("git", ["rev-parse", "--is-inside-work-tree"], { stdio: "pipe" });
3232
3213
  gitRoot = getGitRoot();
3233
3214
  } catch {
3234
- console.log(chalk12.red(`\u274C ${t("save.notGitRepo")}`));
3215
+ console.log(chalk11.red(`\u274C ${t("save.notGitRepo")}`));
3235
3216
  return;
3236
3217
  }
3237
- console.log(chalk12.cyan(`
3218
+ console.log(chalk11.cyan(`
3238
3219
  \u{1F512} ${t("save.securityWarnHeader")}`));
3239
3220
  printSecurityWarnings(gitRoot);
3240
3221
  const severe = filterSevereFindings(scanProjectForSecrets(gitRoot).findings);
3241
3222
  if (severe.length > 0) {
3242
- console.log(chalk12.red(`
3223
+ console.log(chalk11.red(`
3243
3224
  \u26A0\uFE0F ${t("save.secretsFound", severe.length)}`));
3244
3225
  severe.slice(0, 5).forEach((f) => {
3245
- console.log(chalk12.dim(` ${f.file}:${f.line} \u2014 ${f.patternName}`));
3226
+ console.log(chalk11.dim(` ${f.file}:${f.line} \u2014 ${f.patternName}`));
3246
3227
  });
3247
3228
  if (severe.length > 5) {
3248
- console.log(chalk12.dim(` ... \uC678 ${severe.length - 5}\uAC74 (vhk \uBCF4\uC548 scan)`));
3229
+ console.log(chalk11.dim(` ... \uC678 ${severe.length - 5}\uAC74 (vhk \uBCF4\uC548 scan)`));
3249
3230
  }
3250
3231
  const proceed = await promptOrDefault(
3251
3232
  async () => (await inquirer5.prompt([{
@@ -3258,16 +3239,16 @@ async function save() {
3258
3239
  // 비대화형 = 시크릿 커밋 안 함 (안전)
3259
3240
  );
3260
3241
  if (!proceed) {
3261
- console.log(chalk12.gray(t("save.cancelled")));
3242
+ console.log(chalk11.gray(t("save.cancelled")));
3262
3243
  return;
3263
3244
  }
3264
3245
  }
3265
3246
  const lines = parsePorcelainLines(gitOut(["status", "--porcelain"], gitRoot));
3266
3247
  if (lines.length === 0) {
3267
- console.log(chalk12.yellow(`\u{1F4ED} ${t("save.noChanges")}`));
3248
+ console.log(chalk11.yellow(`\u{1F4ED} ${t("save.noChanges")}`));
3268
3249
  return;
3269
3250
  }
3270
- console.log(chalk12.cyan(`
3251
+ console.log(chalk11.cyan(`
3271
3252
  \u{1F4CB} ${t("save.filesHeader", lines.length)}`));
3272
3253
  lines.forEach((line) => {
3273
3254
  const code = line.substring(0, 2);
@@ -3292,21 +3273,21 @@ async function save() {
3292
3273
  spinner.text = t("save.pushing");
3293
3274
  if (!hasGitRemote(gitRoot)) {
3294
3275
  spinner.succeed(t("save.successLocal"));
3295
- console.log(chalk12.yellow(` \u{1F4A1} ${t("save.noRemote")}`));
3276
+ console.log(chalk11.yellow(` \u{1F4A1} ${t("save.noRemote")}`));
3296
3277
  } else {
3297
3278
  try {
3298
3279
  gitRun(["push"], gitRoot);
3299
3280
  spinner.succeed(t("save.successWithPush"));
3300
3281
  } catch (pushErr) {
3301
3282
  spinner.fail(t("save.pushFailed"));
3302
- console.log(chalk12.red(getExecErrorMessage(pushErr)));
3303
- console.log(chalk12.yellow(`
3283
+ console.log(chalk11.red(getExecErrorMessage(pushErr)));
3284
+ console.log(chalk11.yellow(`
3304
3285
  \u{1F4A1} ${t("save.commitOkPushFailed")}`));
3305
3286
  process.exitCode = 1;
3306
3287
  }
3307
3288
  }
3308
3289
  if (process.exitCode !== 1) {
3309
- console.log(chalk12.green(`
3290
+ console.log(chalk11.green(`
3310
3291
  \u2705 ${t("save.done", lines.length)}`));
3311
3292
  printNextStep({
3312
3293
  message: t("save.nextOkMessage"),
@@ -3314,7 +3295,7 @@ async function save() {
3314
3295
  cursorHint: t("save.nextOkCursor")
3315
3296
  });
3316
3297
  } else {
3317
- console.log(chalk12.green(`
3298
+ console.log(chalk11.green(`
3318
3299
  \u2705 ${t("save.doneLocalOnly", lines.length)}`));
3319
3300
  printNextStep({
3320
3301
  message: t("save.nextPushFailMessage"),
@@ -3324,12 +3305,12 @@ async function save() {
3324
3305
  }
3325
3306
  } catch (err) {
3326
3307
  spinner.fail(t("save.failed"));
3327
- console.log(chalk12.red(getExecErrorMessage(err)));
3308
+ console.log(chalk11.red(getExecErrorMessage(err)));
3328
3309
  if (didAdd) {
3329
3310
  try {
3330
3311
  const staged = gitOut(["diff", "--cached", "--stat"], gitRoot).trim();
3331
3312
  if (staged) {
3332
- console.log(chalk12.yellow(`
3313
+ console.log(chalk11.yellow(`
3333
3314
  \u{1F4A1} ${t("save.stagedAfterFail")}`));
3334
3315
  }
3335
3316
  } catch {
@@ -3341,7 +3322,7 @@ async function save() {
3341
3322
 
3342
3323
  // src/commands/undo.ts
3343
3324
  import { execFileSync as execFileSync2 } from "child_process";
3344
- import chalk13 from "chalk";
3325
+ import chalk12 from "chalk";
3345
3326
  import inquirer6 from "inquirer";
3346
3327
  function parseRecentCommits(logOutput) {
3347
3328
  return logOutput.split("\n").map((l) => l.trim()).filter(Boolean);
@@ -3365,30 +3346,30 @@ function isUndoRisky(undoCount, unpushedCount, hasRemote) {
3365
3346
  return false;
3366
3347
  }
3367
3348
  async function undo() {
3368
- console.log(chalk13.bold(`
3349
+ console.log(chalk12.bold(`
3369
3350
  \u23EA ${t("undo.title")}`));
3370
- console.log(chalk13.gray("\u2500".repeat(40)));
3351
+ console.log(chalk12.gray("\u2500".repeat(40)));
3371
3352
  let gitRoot;
3372
3353
  try {
3373
3354
  execFileSync2("git", ["rev-parse", "--is-inside-work-tree"], { stdio: "pipe" });
3374
3355
  gitRoot = getGitRoot();
3375
3356
  } catch {
3376
- console.log(chalk13.red(`\u274C ${t("undo.notGitRepo")}`));
3357
+ console.log(chalk12.red(`\u274C ${t("undo.notGitRepo")}`));
3377
3358
  return;
3378
3359
  }
3379
3360
  let logOutput;
3380
3361
  try {
3381
3362
  logOutput = gitOut(["log", "--oneline", "-5"], gitRoot).trim();
3382
3363
  } catch {
3383
- console.log(chalk13.yellow(`\u{1F4ED} ${t("undo.noCommits")}`));
3364
+ console.log(chalk12.yellow(`\u{1F4ED} ${t("undo.noCommits")}`));
3384
3365
  return;
3385
3366
  }
3386
3367
  const commits = parseRecentCommits(logOutput);
3387
3368
  if (commits.length === 0) {
3388
- console.log(chalk13.yellow(`\u{1F4ED} ${t("undo.noCommits")}`));
3369
+ console.log(chalk12.yellow(`\u{1F4ED} ${t("undo.noCommits")}`));
3389
3370
  return;
3390
3371
  }
3391
- console.log(chalk13.cyan(`
3372
+ console.log(chalk12.cyan(`
3392
3373
  ${t("undo.recentHeader")}`));
3393
3374
  commits.forEach((c, i) => {
3394
3375
  console.log(` ${i === 0 ? "\u{1F449}" : " "} ${c}`);
@@ -3405,7 +3386,7 @@ ${t("undo.recentHeader")}`));
3405
3386
  const undoCount = Math.min(Math.max(1, count || 1), maxUndo);
3406
3387
  const headCount = countLocalCommits(gitRoot);
3407
3388
  if (undoCount >= headCount) {
3408
- console.log(chalk13.yellow(`
3389
+ console.log(chalk12.yellow(`
3409
3390
  \u{1F4ED} ${t("undo.rootCommit")}`));
3410
3391
  return;
3411
3392
  }
@@ -3414,10 +3395,10 @@ ${t("undo.recentHeader")}`));
3414
3395
  const risky = isUndoRisky(undoCount, unpushed, remote);
3415
3396
  if (risky) {
3416
3397
  if (unpushed < 0) {
3417
- console.log(chalk13.red(`
3398
+ console.log(chalk12.red(`
3418
3399
  \u26A0\uFE0F ${t("undo.noUpstreamWarning")}`));
3419
3400
  } else {
3420
- console.log(chalk13.red(`
3401
+ console.log(chalk12.red(`
3421
3402
  \u26A0\uFE0F ${t("undo.alreadyPushed")}`));
3422
3403
  }
3423
3404
  }
@@ -3428,16 +3409,16 @@ ${t("undo.recentHeader")}`));
3428
3409
  default: false
3429
3410
  }]);
3430
3411
  if (!confirm) {
3431
- console.log(chalk13.gray(t("undo.cancelled")));
3412
+ console.log(chalk12.gray(t("undo.cancelled")));
3432
3413
  return;
3433
3414
  }
3434
3415
  try {
3435
3416
  gitRun(["reset", "--soft", `HEAD~${undoCount}`], gitRoot);
3436
- console.log(chalk13.green(`
3417
+ console.log(chalk12.green(`
3437
3418
  \u2705 ${t("undo.success")}`));
3438
- console.log(chalk13.gray(` \u{1F4A1} ${t("undo.stagedHint")}`));
3419
+ console.log(chalk12.gray(` \u{1F4A1} ${t("undo.stagedHint")}`));
3439
3420
  if (risky) {
3440
- console.log(chalk13.yellow(`
3421
+ console.log(chalk12.yellow(`
3441
3422
  \u{1F4A1} ${t("undo.forcePushHint")}`));
3442
3423
  }
3443
3424
  printNextStep({
@@ -3446,35 +3427,35 @@ ${t("undo.recentHeader")}`));
3446
3427
  cursorHint: t("undo.nextCursor")
3447
3428
  });
3448
3429
  } catch (err) {
3449
- console.log(chalk13.red(`\u274C ${t("undo.failed")}`));
3430
+ console.log(chalk12.red(`\u274C ${t("undo.failed")}`));
3450
3431
  const msg = err instanceof Error ? err.message : String(err);
3451
- console.log(chalk13.red(msg));
3432
+ console.log(chalk12.red(msg));
3452
3433
  process.exitCode = 1;
3453
3434
  }
3454
3435
  }
3455
3436
 
3456
3437
  // src/commands/restore.ts
3457
- import chalk14 from "chalk";
3438
+ import chalk13 from "chalk";
3458
3439
  import inquirer7 from "inquirer";
3459
3440
  async function restore(id) {
3460
- console.log(chalk14.bold(`
3441
+ console.log(chalk13.bold(`
3461
3442
  ${ko.restore.title}`));
3462
- console.log(chalk14.gray("\u2500".repeat(40)));
3463
- console.log(chalk14.dim(` ${ko.restore.notGitNote}`));
3443
+ console.log(chalk13.gray("\u2500".repeat(40)));
3444
+ console.log(chalk13.dim(` ${ko.restore.notGitNote}`));
3464
3445
  const cwd = process.cwd();
3465
3446
  const backups = listBackups(cwd);
3466
3447
  if (backups.length === 0) {
3467
- console.log(chalk14.yellow(`
3448
+ console.log(chalk13.yellow(`
3468
3449
  ${ko.restore.noBackups}`));
3469
3450
  return;
3470
3451
  }
3471
3452
  let targetId = id;
3472
3453
  if (!targetId) {
3473
3454
  if (!process.stdout.isTTY) {
3474
- console.log(chalk14.cyan(`
3455
+ console.log(chalk13.cyan(`
3475
3456
  ${ko.restore.listHeader}`));
3476
3457
  for (const b of backups) console.log(` ${b.id} (${b.files.length}\uAC1C \uD30C\uC77C)`);
3477
- console.log(chalk14.yellow(`
3458
+ console.log(chalk13.yellow(`
3478
3459
  ${ko.restore.nonTtyHint}`));
3479
3460
  return;
3480
3461
  }
@@ -3493,16 +3474,16 @@ ${ko.restore.nonTtyHint}`));
3493
3474
  }
3494
3475
  try {
3495
3476
  const restored = restoreBackup(targetId, cwd);
3496
- console.log(chalk14.green(`
3477
+ console.log(chalk13.green(`
3497
3478
  ${ko.restore.restored(restored.length, targetId)}`));
3498
- for (const r of restored) console.log(chalk14.gray(` ${r}`));
3479
+ for (const r of restored) console.log(chalk13.gray(` ${r}`));
3499
3480
  printNextStep({
3500
3481
  message: "\uBC31\uC5C5 \uBCF5\uC6D0 \uC644\uB8CC! \uBCC0\uACBD \uB0B4\uC6A9\uC744 \uD655\uC778\uD558\uC138\uC694.",
3501
3482
  command: "vhk diff",
3502
3483
  cursorHint: "\uBCC0\uACBD\uC0AC\uD56D \uBCF4\uC5EC\uC918"
3503
3484
  });
3504
3485
  } catch {
3505
- console.log(chalk14.red(`
3486
+ console.log(chalk13.red(`
3506
3487
  ${ko.restore.notFound(targetId)}`));
3507
3488
  process.exitCode = 1;
3508
3489
  }
@@ -3512,7 +3493,7 @@ ${ko.restore.notFound(targetId)}`));
3512
3493
  import { execFileSync as execFileSync3 } from "child_process";
3513
3494
  import fs10 from "fs";
3514
3495
  import path11 from "path";
3515
- import chalk15 from "chalk";
3496
+ import chalk14 from "chalk";
3516
3497
  function countFileChanges(porcelain) {
3517
3498
  const lines = porcelain.split("\n").filter(Boolean);
3518
3499
  let staged = 0;
@@ -3587,15 +3568,15 @@ function getSyncCounts(gitRoot) {
3587
3568
  }
3588
3569
  }
3589
3570
  async function status() {
3590
- console.log(chalk15.bold(`
3571
+ console.log(chalk14.bold(`
3591
3572
  \u{1F4CA} ${t("status.title")}`));
3592
- console.log(chalk15.gray("\u2500".repeat(40)));
3573
+ console.log(chalk14.gray("\u2500".repeat(40)));
3593
3574
  let gitRoot;
3594
3575
  try {
3595
3576
  execFileSync3("git", ["rev-parse", "--is-inside-work-tree"], { stdio: "pipe" });
3596
3577
  gitRoot = getGitRoot();
3597
3578
  } catch {
3598
- console.log(chalk15.red(`\u274C ${t("status.notGitRepo")}`));
3579
+ console.log(chalk14.red(`\u274C ${t("status.notGitRepo")}`));
3599
3580
  return;
3600
3581
  }
3601
3582
  let branch;
@@ -3614,29 +3595,29 @@ async function status() {
3614
3595
  commits = [];
3615
3596
  }
3616
3597
  const pkg = readProjectPackage();
3617
- console.log(chalk15.cyan(`
3618
- \u{1F33F} ${t("status.branch")}`) + chalk15.white(` ${branch}`));
3598
+ console.log(chalk14.cyan(`
3599
+ \u{1F33F} ${t("status.branch")}`) + chalk14.white(` ${branch}`));
3619
3600
  console.log(
3620
- chalk15.cyan(`\u{1F4C1} ${t("status.changes")}`) + chalk15.white(
3601
+ chalk14.cyan(`\u{1F4C1} ${t("status.changes")}`) + chalk14.white(
3621
3602
  ` staged ${counts.staged} \xB7 unstaged ${counts.unstaged} \xB7 untracked ${counts.untracked}`
3622
3603
  )
3623
3604
  );
3624
- console.log(chalk15.cyan(`
3605
+ console.log(chalk14.cyan(`
3625
3606
  \u{1F4CB} ${t("status.recentCommits", commits.length)}`));
3626
3607
  if (commits.length === 0) {
3627
- console.log(chalk15.dim(` ${t("status.noCommits")}`));
3608
+ console.log(chalk14.dim(` ${t("status.noCommits")}`));
3628
3609
  } else {
3629
- commits.forEach((c) => console.log(` ${chalk15.dim("\u2022")} ${c}`));
3610
+ commits.forEach((c) => console.log(` ${chalk14.dim("\u2022")} ${c}`));
3630
3611
  }
3631
3612
  console.log(
3632
- chalk15.cyan(`
3633
- \u{1F504} ${t("status.remote")}`) + chalk15.white(` ${formatSyncLabel(sync2)}`)
3613
+ chalk14.cyan(`
3614
+ \u{1F504} ${t("status.remote")}`) + chalk14.white(` ${formatSyncLabel(sync2)}`)
3634
3615
  );
3635
- console.log(chalk15.gray("\n" + "\u2500".repeat(40)));
3616
+ console.log(chalk14.gray("\n" + "\u2500".repeat(40)));
3636
3617
  if (pkg) {
3637
- console.log(chalk15.cyan(`\u{1F4E6} ${t("status.package")}`) + chalk15.white(` ${pkg.name} v${pkg.version}`));
3618
+ console.log(chalk14.cyan(`\u{1F4E6} ${t("status.package")}`) + chalk14.white(` ${pkg.name} v${pkg.version}`));
3638
3619
  } else {
3639
- console.log(chalk15.dim(`\u{1F4E6} ${t("status.noPackage")}`));
3620
+ console.log(chalk14.dim(`\u{1F4E6} ${t("status.noPackage")}`));
3640
3621
  }
3641
3622
  const hasChanges = counts.staged + counts.unstaged + counts.untracked > 0;
3642
3623
  printNextStep(selectStatusNextStep(hasChanges));
@@ -3644,7 +3625,7 @@ async function status() {
3644
3625
  }
3645
3626
 
3646
3627
  // src/commands/diff.ts
3647
- import chalk16 from "chalk";
3628
+ import chalk15 from "chalk";
3648
3629
  function gitOut2(args) {
3649
3630
  const r = safeExecFile("git", args);
3650
3631
  return r.ok ? r.out : "";
@@ -3681,51 +3662,51 @@ function summarizeNumstat(numstat) {
3681
3662
  return { fileCount, totalAdd, totalDel };
3682
3663
  }
3683
3664
  function printFile(f) {
3684
- const adds = f.additions > 0 ? chalk16.green(`+${f.additions}`) : "";
3685
- const dels = f.deletions > 0 ? chalk16.red(`-${f.deletions}`) : "";
3665
+ const adds = f.additions > 0 ? chalk15.green(`+${f.additions}`) : "";
3666
+ const dels = f.deletions > 0 ? chalk15.red(`-${f.deletions}`) : "";
3686
3667
  const change = [adds, dels].filter(Boolean).join(" ");
3687
3668
  console.log(` ${f.name} ${change}`);
3688
3669
  }
3689
3670
  async function diff() {
3690
- console.log(chalk16.bold(`
3671
+ console.log(chalk15.bold(`
3691
3672
  \u{1F50D} ${t("diff.title")}`));
3692
- console.log(chalk16.gray("\u2500".repeat(40)));
3673
+ console.log(chalk15.gray("\u2500".repeat(40)));
3693
3674
  if (!safeExecFile("git", ["rev-parse", "--is-inside-work-tree"]).ok) {
3694
- console.log(chalk16.red(`\u274C ${t("diff.notGitRepo")}`));
3675
+ console.log(chalk15.red(`\u274C ${t("diff.notGitRepo")}`));
3695
3676
  return;
3696
3677
  }
3697
3678
  const unstaged = gitOut2(["diff", "--stat"]);
3698
3679
  const staged = gitOut2(["diff", "--cached", "--stat"]);
3699
3680
  const untracked = gitOut2(["ls-files", "--others", "--exclude-standard"]);
3700
3681
  if (!unstaged && !staged && !untracked) {
3701
- console.log(chalk16.green(`
3682
+ console.log(chalk15.green(`
3702
3683
  \u2705 ${t("diff.noChanges")}`));
3703
3684
  return;
3704
3685
  }
3705
3686
  if (staged) {
3706
- console.log(chalk16.cyan(`
3687
+ console.log(chalk15.cyan(`
3707
3688
  ${t("diff.stagedHeader")}`));
3708
3689
  parseDiffStat(staged).forEach((f) => printFile(f));
3709
3690
  }
3710
3691
  if (unstaged) {
3711
- console.log(chalk16.cyan(`
3692
+ console.log(chalk15.cyan(`
3712
3693
  ${t("diff.unstagedHeader")}`));
3713
3694
  parseDiffStat(unstaged).forEach((f) => printFile(f));
3714
3695
  }
3715
3696
  if (untracked) {
3716
3697
  const files = untracked.split("\n").filter(Boolean);
3717
- console.log(chalk16.cyan(`
3698
+ console.log(chalk15.cyan(`
3718
3699
  ${t("diff.untrackedHeader", files.length)}`));
3719
- files.forEach((f) => console.log(` ${chalk16.green("+")} ${f}`));
3700
+ files.forEach((f) => console.log(` ${chalk15.green("+")} ${f}`));
3720
3701
  }
3721
3702
  const numstat = gitOut2(["diff", "--numstat", "HEAD"]);
3722
3703
  if (numstat) {
3723
3704
  const { fileCount, totalAdd, totalDel } = summarizeNumstat(numstat);
3724
- console.log(chalk16.cyan(`
3705
+ console.log(chalk15.cyan(`
3725
3706
  ${t("diff.summaryHeader")}`));
3726
3707
  console.log(` ${t("diff.filesLine", fileCount)}`);
3727
- console.log(` \uCD94\uAC00: ${chalk16.green(`+${totalAdd}`)}\uC904`);
3728
- console.log(` \uC0AD\uC81C: ${chalk16.red(`-${totalDel}`)}\uC904`);
3708
+ console.log(` \uCD94\uAC00: ${chalk15.green(`+${totalAdd}`)}\uC904`);
3709
+ console.log(` \uC0AD\uC81C: ${chalk15.red(`-${totalDel}`)}\uC904`);
3729
3710
  }
3730
3711
  console.log("");
3731
3712
  }
@@ -3734,7 +3715,7 @@ ${t("diff.summaryHeader")}`));
3734
3715
  import { existsSync as existsSync4, mkdirSync as mkdirSync3, writeFileSync as writeFileSync3 } from "fs";
3735
3716
  import { join as join5, dirname } from "path";
3736
3717
  import { fileURLToPath as fileURLToPath2 } from "url";
3737
- import chalk17 from "chalk";
3718
+ import chalk16 from "chalk";
3738
3719
  function resolveMcpEntryPoint() {
3739
3720
  try {
3740
3721
  const here = fileURLToPath2(import.meta.url);
@@ -3774,8 +3755,8 @@ function resolveVhkMcpEntry() {
3774
3755
  return { command: "vhk-mcp", args: [] };
3775
3756
  }
3776
3757
  async function mcpInit() {
3777
- console.log(chalk17.bold("\n\u{1F50C} " + t("mcp.initTitle")));
3778
- console.log(chalk17.gray("\u2500".repeat(40)));
3758
+ console.log(chalk16.bold("\n\u{1F50C} " + t("mcp.initTitle")));
3759
+ console.log(chalk16.gray("\u2500".repeat(40)));
3779
3760
  const cursorDir = join5(process.cwd(), ".cursor");
3780
3761
  if (!existsSync4(cursorDir)) {
3781
3762
  mkdirSync3(cursorDir, { recursive: true });
@@ -3790,15 +3771,15 @@ async function mcpInit() {
3790
3771
  mcpServers: { ...parsed.mcpServers ?? {}, vhk: vhkEntry }
3791
3772
  };
3792
3773
  } catch {
3793
- console.log(chalk17.yellow("\u26A0\uFE0F \uAE30\uC874 .cursor/mcp.json \uD30C\uC2F1 \uC2E4\uD328 \u2014 \uC0C8 \uD30C\uC77C\uB85C \uB36E\uC5B4\uC501\uB2C8\uB2E4."));
3774
+ console.log(chalk16.yellow("\u26A0\uFE0F \uAE30\uC874 .cursor/mcp.json \uD30C\uC2F1 \uC2E4\uD328 \u2014 \uC0C8 \uD30C\uC77C\uB85C \uB36E\uC5B4\uC501\uB2C8\uB2E4."));
3794
3775
  config = { mcpServers: { vhk: vhkEntry } };
3795
3776
  }
3796
3777
  } else {
3797
3778
  config = { mcpServers: { vhk: vhkEntry } };
3798
3779
  }
3799
3780
  writeFileSync3(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
3800
- console.log(chalk17.green("\n\u2705 Cursor MCP \uC124\uC815 \uC644\uB8CC!"));
3801
- console.log(chalk17.cyan("\u{1F4C1} \uC0DD\uC131\uB41C \uD30C\uC77C:"));
3781
+ console.log(chalk16.green("\n\u2705 Cursor MCP \uC124\uC815 \uC644\uB8CC!"));
3782
+ console.log(chalk16.cyan("\u{1F4C1} \uC0DD\uC131\uB41C \uD30C\uC77C:"));
3802
3783
  console.log(` ${configPath}`);
3803
3784
  printNextStep({
3804
3785
  message: t("mcp.nextMessage"),
@@ -3809,7 +3790,7 @@ async function mcpInit() {
3809
3790
 
3810
3791
  // src/commands/design.ts
3811
3792
  import { existsSync as existsSync5, mkdirSync as mkdirSync4, writeFileSync as writeFileSync4 } from "fs";
3812
- import chalk18 from "chalk";
3793
+ import chalk17 from "chalk";
3813
3794
  import inquirer8 from "inquirer";
3814
3795
  var PALETTES = [
3815
3796
  {
@@ -3912,8 +3893,8 @@ export default vhkColors
3912
3893
  `;
3913
3894
  }
3914
3895
  async function design() {
3915
- console.log(chalk18.bold("\n\u{1F3A8} " + t("design.title")));
3916
- console.log(chalk18.gray("\u2500".repeat(40)));
3896
+ console.log(chalk17.bold("\n\u{1F3A8} " + t("design.title")));
3897
+ console.log(chalk17.gray("\u2500".repeat(40)));
3917
3898
  if (!ensureInteractive("\uCEEC\uB7EC \uD314\uB808\uD2B8 \uC120\uD0DD\uC740 \uB300\uD654\uD615\uC73C\uB85C\uB9CC \uAC00\uB2A5\uD569\uB2C8\uB2E4.")) return;
3918
3899
  const { paletteIndex } = await inquirer8.prompt([
3919
3900
  {
@@ -3927,7 +3908,7 @@ async function design() {
3927
3908
  }
3928
3909
  ]);
3929
3910
  const palette = PALETTES[paletteIndex];
3930
- console.log(chalk18.cyan(`
3911
+ console.log(chalk17.cyan(`
3931
3912
  \u{1F3A8} \uC120\uD0DD\uB41C \uD314\uB808\uD2B8: ${palette.name}`));
3932
3913
  const v4 = hasTailwindV4();
3933
3914
  const targetPath = v4 ? "src/styles/theme.css" : hasTailwind() ? "src/styles/vhk-colors.ts" : "src/styles/tokens.css";
@@ -3940,24 +3921,24 @@ async function design() {
3940
3921
  default: false
3941
3922
  }]);
3942
3923
  if (!overwrite) {
3943
- console.log(chalk18.yellow("\n\u23ED\uFE0F \uC0DD\uC131 \uCDE8\uC18C \u2014 \uAE30\uC874 \uD30C\uC77C \uC720\uC9C0."));
3924
+ console.log(chalk17.yellow("\n\u23ED\uFE0F \uC0DD\uC131 \uCDE8\uC18C \u2014 \uAE30\uC874 \uD30C\uC77C \uC720\uC9C0."));
3944
3925
  return;
3945
3926
  }
3946
3927
  }
3947
3928
  mkdirSync4("src/styles", { recursive: true });
3948
3929
  writeFileSync4(targetPath, content, "utf-8");
3949
3930
  if (v4) {
3950
- console.log(chalk18.green("\n\u2705 src/styles/theme.css \uC0DD\uC131 (Tailwind v4 @theme)"));
3951
- console.log(chalk18.gray(' \uC9C4\uC785 CSS(\uC608: src/index.css)\uC5D0 `@import "./styles/theme.css";` \uCD94\uAC00 \u2192 bg-primary \uB4F1 \uC720\uD2F8 \uC0AC\uC6A9.'));
3952
- console.log(chalk18.gray(" \uB2E4\uD06C \uD1A0\uAE00: \uB8E8\uD2B8 <html>/<body> \uC5D0 `.dark` \uD074\uB798\uC2A4 on/off."));
3931
+ console.log(chalk17.green("\n\u2705 src/styles/theme.css \uC0DD\uC131 (Tailwind v4 @theme)"));
3932
+ console.log(chalk17.gray(' \uC9C4\uC785 CSS(\uC608: src/index.css)\uC5D0 `@import "./styles/theme.css";` \uCD94\uAC00 \u2192 bg-primary \uB4F1 \uC720\uD2F8 \uC0AC\uC6A9.'));
3933
+ console.log(chalk17.gray(" \uB2E4\uD06C \uD1A0\uAE00: \uB8E8\uD2B8 <html>/<body> \uC5D0 `.dark` \uD074\uB798\uC2A4 on/off."));
3953
3934
  } else if (hasTailwind()) {
3954
- console.log(chalk18.green("\n\u2705 src/styles/vhk-colors.ts \uC0DD\uC131"));
3955
- console.log(chalk18.gray(" tailwind.config\uC758 extend.colors\uC5D0 import \uD574\uC11C \uC0AC\uC6A9\uD558\uC138\uC694."));
3935
+ console.log(chalk17.green("\n\u2705 src/styles/vhk-colors.ts \uC0DD\uC131"));
3936
+ console.log(chalk17.gray(" tailwind.config\uC758 extend.colors\uC5D0 import \uD574\uC11C \uC0AC\uC6A9\uD558\uC138\uC694."));
3956
3937
  } else {
3957
- console.log(chalk18.green("\n\u2705 src/styles/tokens.css \uC0DD\uC131"));
3958
- console.log(chalk18.gray(" HTML\uC5D0 <link>\uB85C \uCD94\uAC00\uD558\uAC70\uB098 CSS\uC5D0\uC11C @import \uD558\uC138\uC694."));
3938
+ console.log(chalk17.green("\n\u2705 src/styles/tokens.css \uC0DD\uC131"));
3939
+ console.log(chalk17.gray(" HTML\uC5D0 <link>\uB85C \uCD94\uAC00\uD558\uAC70\uB098 CSS\uC5D0\uC11C @import \uD558\uC138\uC694."));
3959
3940
  }
3960
- console.log(chalk18.bold("\n\u{1F308} \uCEEC\uB7EC \uBBF8\uB9AC\uBCF4\uAE30:"));
3941
+ console.log(chalk17.bold("\n\u{1F308} \uCEEC\uB7EC \uBBF8\uB9AC\uBCF4\uAE30:"));
3961
3942
  for (const [key, value] of Object.entries(palette.colors)) {
3962
3943
  console.log(` ${key.padEnd(12)} ${value}`);
3963
3944
  }
@@ -3973,7 +3954,7 @@ async function designPalette() {
3973
3954
 
3974
3955
  // src/commands/theme.ts
3975
3956
  import { existsSync as existsSync6, mkdirSync as mkdirSync5, writeFileSync as writeFileSync5 } from "fs";
3976
- import chalk19 from "chalk";
3957
+ import chalk18 from "chalk";
3977
3958
  import inquirer9 from "inquirer";
3978
3959
  function generateDarkCSS() {
3979
3960
  return `/* vhk theme \u2014 \uB2E4\uD06C/\uB77C\uC774\uD2B8 \uBAA8\uB4DC CSS \uBCC0\uC218 */
@@ -4029,36 +4010,39 @@ export function initTheme(): void {
4029
4010
  }
4030
4011
  `;
4031
4012
  }
4032
- async function theme() {
4033
- console.log(chalk19.bold("\n\u{1F319} " + t("theme.title")));
4034
- console.log(chalk19.gray("\u2500".repeat(40)));
4013
+ async function theme(options) {
4014
+ console.log(chalk18.bold("\n\u{1F319} " + t("theme.title")));
4015
+ console.log(chalk18.gray("\u2500".repeat(40)));
4035
4016
  const cssPath = "src/styles/theme.css";
4036
4017
  const togglePath = "src/lib/theme-toggle.ts";
4037
4018
  const conflicts = [cssPath, togglePath].filter((p) => existsSync6(p));
4038
4019
  if (conflicts.length > 0) {
4039
- const { overwrite } = await inquirer9.prompt([{
4040
- type: "confirm",
4041
- name: "overwrite",
4042
- message: `\uB2E4\uC74C \uD30C\uC77C\uC774 \uC774\uBBF8 \uC788\uC5B4\uC694. \uB36E\uC5B4\uC4F8\uAE4C\uC694?
4020
+ const overwrite = options?.yes === true ? true : await promptOrDefault(
4021
+ async () => (await inquirer9.prompt([{
4022
+ type: "confirm",
4023
+ name: "overwrite",
4024
+ message: `\uB2E4\uC74C \uD30C\uC77C\uC774 \uC774\uBBF8 \uC788\uC5B4\uC694. \uB36E\uC5B4\uC4F8\uAE4C\uC694?
4043
4025
  ${conflicts.join("\n ")}`,
4044
- default: false
4045
- }]);
4026
+ default: false
4027
+ }])).overwrite,
4028
+ false
4029
+ );
4046
4030
  if (!overwrite) {
4047
- console.log(chalk19.yellow("\n\u23ED\uFE0F \uC0DD\uC131 \uCDE8\uC18C \u2014 \uAE30\uC874 \uD30C\uC77C \uC720\uC9C0."));
4031
+ console.log(chalk18.yellow("\n\u23ED\uFE0F \uC0DD\uC131 \uCDE8\uC18C \u2014 \uAE30\uC874 \uD30C\uC77C \uC720\uC9C0. (\uBE44\uB300\uD654\uD615\uC774\uBA74 --yes \uB85C \uB36E\uC5B4\uC4F0\uAE30)"));
4048
4032
  return;
4049
4033
  }
4050
4034
  }
4051
4035
  mkdirSync5("src/styles", { recursive: true });
4052
4036
  mkdirSync5("src/lib", { recursive: true });
4053
4037
  writeFileSync5(cssPath, generateDarkCSS(), "utf-8");
4054
- console.log(chalk19.green("\n\u2705 src/styles/theme.css \uC0DD\uC131 (\uB2E4\uD06C/\uB77C\uC774\uD2B8 \uBAA8\uB4DC)"));
4038
+ console.log(chalk18.green("\n\u2705 src/styles/theme.css \uC0DD\uC131 (\uB2E4\uD06C/\uB77C\uC774\uD2B8 \uBAA8\uB4DC)"));
4055
4039
  writeFileSync5(togglePath, generateToggleUtil(), "utf-8");
4056
- console.log(chalk19.green("\u2705 src/lib/theme-toggle.ts \uC0DD\uC131 (\uD1A0\uAE00 \uC720\uD2F8\uB9AC\uD2F0)"));
4057
- console.log(chalk19.bold("\n\u{1F4D6} \uC0AC\uC6A9\uBC95:"));
4058
- console.log(chalk19.gray(" 1. theme.css\uB97C \uAE00\uB85C\uBC8C \uC2A4\uD0C0\uC77C\uC5D0 \uCD94\uAC00"));
4059
- console.log(chalk19.gray(' 2. import { initTheme, toggleTheme } from "./lib/theme-toggle"'));
4060
- console.log(chalk19.gray(" 3. \uC571 \uC9C4\uC785\uC810\uC5D0\uC11C initTheme() \uD638\uCD9C"));
4061
- console.log(chalk19.gray(" 4. \uD1A0\uAE00 \uBC84\uD2BC\uC5D0\uC11C toggleTheme() \uD638\uCD9C"));
4040
+ console.log(chalk18.green("\u2705 src/lib/theme-toggle.ts \uC0DD\uC131 (\uD1A0\uAE00 \uC720\uD2F8\uB9AC\uD2F0)"));
4041
+ console.log(chalk18.bold("\n\u{1F4D6} \uC0AC\uC6A9\uBC95:"));
4042
+ console.log(chalk18.gray(" 1. theme.css\uB97C \uAE00\uB85C\uBC8C \uC2A4\uD0C0\uC77C\uC5D0 \uCD94\uAC00"));
4043
+ console.log(chalk18.gray(' 2. import { initTheme, toggleTheme } from "./lib/theme-toggle"'));
4044
+ console.log(chalk18.gray(" 3. \uC571 \uC9C4\uC785\uC810\uC5D0\uC11C initTheme() \uD638\uCD9C"));
4045
+ console.log(chalk18.gray(" 4. \uD1A0\uAE00 \uBC84\uD2BC\uC5D0\uC11C toggleTheme() \uD638\uCD9C"));
4062
4046
  printNextStep({
4063
4047
  message: "\uD14C\uB9C8 \uC124\uC815 \uC644\uB8CC!",
4064
4048
  command: "vhk ref list",
@@ -4068,7 +4052,7 @@ async function theme() {
4068
4052
 
4069
4053
  // src/commands/ref.ts
4070
4054
  import { existsSync as existsSync7, mkdirSync as mkdirSync6, writeFileSync as writeFileSync6 } from "fs";
4071
- import chalk20 from "chalk";
4055
+ import chalk19 from "chalk";
4072
4056
  var REFS_PATH = ".vhk/refs.json";
4073
4057
  function loadRefs() {
4074
4058
  if (!existsSync7(REFS_PATH)) return [];
@@ -4084,24 +4068,24 @@ function saveRefs(refs) {
4084
4068
  writeFileSync6(REFS_PATH, JSON.stringify(refs, null, 2) + "\n", "utf-8");
4085
4069
  }
4086
4070
  async function refAdd(url, memo = "") {
4087
- console.log(chalk20.bold("\n\u{1F517} " + t("ref.addTitle")));
4088
- console.log(chalk20.gray("\u2500".repeat(40)));
4071
+ console.log(chalk19.bold("\n\u{1F517} " + t("ref.addTitle")));
4072
+ console.log(chalk19.gray("\u2500".repeat(40)));
4089
4073
  if (!url) {
4090
- console.log(chalk20.red("\u274C URL\uC744 \uC785\uB825\uD574\uC8FC\uC138\uC694."));
4091
- console.log(chalk20.gray(' \uC608: vhk ref add https://example.com --memo "\uCC38\uACE0 \uC0AC\uC774\uD2B8"'));
4074
+ console.log(chalk19.red("\u274C URL\uC744 \uC785\uB825\uD574\uC8FC\uC138\uC694."));
4075
+ console.log(chalk19.gray(' \uC608: vhk ref add https://example.com --memo "\uCC38\uACE0 \uC0AC\uC774\uD2B8"'));
4092
4076
  return;
4093
4077
  }
4094
4078
  const refs = loadRefs();
4095
4079
  if (refs.some((r) => r.url === url)) {
4096
- console.log(chalk20.yellow("\u26A0\uFE0F \uC774\uBBF8 \uC800\uC7A5\uB41C URL\uC785\uB2C8\uB2E4."));
4080
+ console.log(chalk19.yellow("\u26A0\uFE0F \uC774\uBBF8 \uC800\uC7A5\uB41C URL\uC785\uB2C8\uB2E4."));
4097
4081
  return;
4098
4082
  }
4099
4083
  refs.push({ url, memo, addedAt: (/* @__PURE__ */ new Date()).toISOString() });
4100
4084
  saveRefs(refs);
4101
- console.log(chalk20.green(`
4085
+ console.log(chalk19.green(`
4102
4086
  \u2705 \uB808\uD37C\uB7F0\uC2A4 \uCD94\uAC00\uB428 (#${refs.length})`));
4103
- console.log(chalk20.cyan(` ${url}`));
4104
- if (memo) console.log(chalk20.gray(` \u{1F4DD} ${memo}`));
4087
+ console.log(chalk19.cyan(` ${url}`));
4088
+ if (memo) console.log(chalk19.gray(` \u{1F4DD} ${memo}`));
4105
4089
  printNextStep({
4106
4090
  message: "\uB808\uD37C\uB7F0\uC2A4 \uC800\uC7A5 \uC644\uB8CC!",
4107
4091
  command: "vhk ref list",
@@ -4109,22 +4093,22 @@ async function refAdd(url, memo = "") {
4109
4093
  });
4110
4094
  }
4111
4095
  async function refList() {
4112
- console.log(chalk20.bold("\n\u{1F4DA} " + t("ref.listTitle")));
4113
- console.log(chalk20.gray("\u2500".repeat(40)));
4096
+ console.log(chalk19.bold("\n\u{1F4DA} " + t("ref.listTitle")));
4097
+ console.log(chalk19.gray("\u2500".repeat(40)));
4114
4098
  const refs = loadRefs();
4115
4099
  if (refs.length === 0) {
4116
- console.log(chalk20.yellow("\n\u{1F4ED} \uC800\uC7A5\uB41C \uB808\uD37C\uB7F0\uC2A4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."));
4117
- console.log(chalk20.gray(' vhk ref add <url> --memo "\uBA54\uBAA8"\uB85C \uCD94\uAC00\uD558\uC138\uC694.'));
4100
+ console.log(chalk19.yellow("\n\u{1F4ED} \uC800\uC7A5\uB41C \uB808\uD37C\uB7F0\uC2A4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."));
4101
+ console.log(chalk19.gray(' vhk ref add <url> --memo "\uBA54\uBAA8"\uB85C \uCD94\uAC00\uD558\uC138\uC694.'));
4118
4102
  return;
4119
4103
  }
4120
- console.log(chalk20.cyan(`
4104
+ console.log(chalk19.cyan(`
4121
4105
  \uCD1D ${refs.length}\uAC1C\uC758 \uB808\uD37C\uB7F0\uC2A4:
4122
4106
  `));
4123
4107
  refs.forEach((ref, index) => {
4124
4108
  const date = new Date(ref.addedAt).toLocaleDateString("ko-KR");
4125
- console.log(chalk20.white(` [${index + 1}] ${ref.url}`));
4126
- if (ref.memo) console.log(chalk20.gray(` \u{1F4DD} ${ref.memo}`));
4127
- console.log(chalk20.gray(` \u{1F4C5} ${date}`));
4109
+ console.log(chalk19.white(` [${index + 1}] ${ref.url}`));
4110
+ if (ref.memo) console.log(chalk19.gray(` \u{1F4DD} ${ref.memo}`));
4111
+ console.log(chalk19.gray(` \u{1F4C5} ${date}`));
4128
4112
  console.log("");
4129
4113
  });
4130
4114
  }
@@ -4132,7 +4116,7 @@ async function refOpen(indexStr) {
4132
4116
  const refs = loadRefs();
4133
4117
  const idx = parseInt(indexStr, 10) - 1;
4134
4118
  if (Number.isNaN(idx) || idx < 0 || idx >= refs.length) {
4135
- console.log(chalk20.red(`\u274C \uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uBC88\uD638\uC785\uB2C8\uB2E4. (1~${refs.length || 0})`));
4119
+ console.log(chalk19.red(`\u274C \uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uBC88\uD638\uC785\uB2C8\uB2E4. (1~${refs.length || 0})`));
4136
4120
  return;
4137
4121
  }
4138
4122
  const ref = refs[idx];
@@ -4140,14 +4124,14 @@ async function refOpen(indexStr) {
4140
4124
  try {
4141
4125
  parsed = new URL(ref.url);
4142
4126
  } catch {
4143
- console.log(chalk20.red(`\u274C \uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 URL: ${ref.url}`));
4127
+ console.log(chalk19.red(`\u274C \uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 URL: ${ref.url}`));
4144
4128
  return;
4145
4129
  }
4146
4130
  if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
4147
- console.log(chalk20.red(`\u274C http(s) URL\uB9CC \uC5F4 \uC218 \uC788\uC2B5\uB2C8\uB2E4 (${parsed.protocol})`));
4131
+ console.log(chalk19.red(`\u274C http(s) URL\uB9CC \uC5F4 \uC218 \uC788\uC2B5\uB2C8\uB2E4 (${parsed.protocol})`));
4148
4132
  return;
4149
4133
  }
4150
- console.log(chalk20.cyan(`
4134
+ console.log(chalk19.cyan(`
4151
4135
  \u{1F310} \uC5F4\uAE30: ${ref.url}`));
4152
4136
  let result;
4153
4137
  if (process.platform === "darwin") {
@@ -4158,15 +4142,15 @@ async function refOpen(indexStr) {
4158
4142
  result = safeExecFile("xdg-open", [ref.url]);
4159
4143
  }
4160
4144
  if (result.ok) {
4161
- console.log(chalk20.green("\u2705 \uBE0C\uB77C\uC6B0\uC800\uC5D0\uC11C \uC5F4\uC5C8\uC2B5\uB2C8\uB2E4."));
4145
+ console.log(chalk19.green("\u2705 \uBE0C\uB77C\uC6B0\uC800\uC5D0\uC11C \uC5F4\uC5C8\uC2B5\uB2C8\uB2E4."));
4162
4146
  } else {
4163
- console.log(chalk20.yellow("\u26A0\uFE0F \uBE0C\uB77C\uC6B0\uC800\uB97C \uC5F4 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. URL\uC744 \uC9C1\uC811 \uBC29\uBB38\uD574\uC8FC\uC138\uC694."));
4147
+ console.log(chalk19.yellow("\u26A0\uFE0F \uBE0C\uB77C\uC6B0\uC800\uB97C \uC5F4 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. URL\uC744 \uC9C1\uC811 \uBC29\uBB38\uD574\uC8FC\uC138\uC694."));
4164
4148
  }
4165
4149
  }
4166
4150
 
4167
4151
  // src/commands/harness.ts
4168
4152
  import { existsSync as existsSync8 } from "fs";
4169
- import chalk21 from "chalk";
4153
+ import chalk20 from "chalk";
4170
4154
  import ora2 from "ora";
4171
4155
  function detectPM() {
4172
4156
  if (existsSync8("pnpm-lock.yaml")) return "pnpm";
@@ -4208,15 +4192,15 @@ function detectChecks() {
4208
4192
  }
4209
4193
  async function harness() {
4210
4194
  if (!ensureNotHardStopped("harness")) return;
4211
- console.log(chalk21.bold("\n\u{1F527} " + t("harness.title")));
4212
- console.log(chalk21.gray("\u2500".repeat(40)));
4195
+ console.log(chalk20.bold("\n\u{1F527} " + t("harness.title")));
4196
+ console.log(chalk20.gray("\u2500".repeat(40)));
4213
4197
  const checks = detectChecks();
4214
4198
  if (checks.length === 0) {
4215
- console.log(chalk21.yellow("\n\u26A0\uFE0F \uC2E4\uD589\uD560 \uC218 \uC788\uB294 \uC2A4\uD06C\uB9BD\uD2B8\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."));
4216
- console.log(chalk21.gray(" package.json\uC5D0 lint, test, build \uC2A4\uD06C\uB9BD\uD2B8\uB97C \uCD94\uAC00\uD574\uC8FC\uC138\uC694."));
4199
+ console.log(chalk20.yellow("\n\u26A0\uFE0F \uC2E4\uD589\uD560 \uC218 \uC788\uB294 \uC2A4\uD06C\uB9BD\uD2B8\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."));
4200
+ console.log(chalk20.gray(" package.json\uC5D0 lint, test, build \uC2A4\uD06C\uB9BD\uD2B8\uB97C \uCD94\uAC00\uD574\uC8FC\uC138\uC694."));
4217
4201
  return;
4218
4202
  }
4219
- console.log(chalk21.cyan(`
4203
+ console.log(chalk20.cyan(`
4220
4204
  \u{1F3C3} ${checks.length}\uAC1C \uC810\uAC80 \uC2DC\uC791:
4221
4205
  `));
4222
4206
  const results = [];
@@ -4228,10 +4212,10 @@ async function harness() {
4228
4212
  const duration = Date.now() - start2;
4229
4213
  const sec = (duration / 1e3).toFixed(1);
4230
4214
  if (result.ok) {
4231
- spinner.succeed(`${check2.name} ${chalk21.gray(`(${sec}s)`)}`);
4215
+ spinner.succeed(`${check2.name} ${chalk20.gray(`(${sec}s)`)}`);
4232
4216
  results.push({ name: check2.name, command: display, passed: true, duration });
4233
4217
  } else {
4234
- spinner.fail(`${check2.name} ${chalk21.gray(`(${sec}s)`)}`);
4218
+ spinner.fail(`${check2.name} ${chalk20.gray(`(${sec}s)`)}`);
4235
4219
  results.push({
4236
4220
  name: check2.name,
4237
4221
  command: display,
@@ -4241,22 +4225,22 @@ async function harness() {
4241
4225
  });
4242
4226
  }
4243
4227
  }
4244
- console.log(chalk21.bold("\n\u{1F4CA} \uD1B5\uD569 \uB9AC\uD3EC\uD2B8:"));
4245
- console.log(chalk21.gray("\u2500".repeat(40)));
4228
+ console.log(chalk20.bold("\n\u{1F4CA} \uD1B5\uD569 \uB9AC\uD3EC\uD2B8:"));
4229
+ console.log(chalk20.gray("\u2500".repeat(40)));
4246
4230
  for (const r of results) {
4247
- const icon = r.passed ? chalk21.green("\u2705") : chalk21.red("\u274C");
4231
+ const icon = r.passed ? chalk20.green("\u2705") : chalk20.red("\u274C");
4248
4232
  const sec = (r.duration / 1e3).toFixed(1);
4249
- console.log(` ${icon} ${r.name.padEnd(15)} ${chalk21.gray(`${sec}s`)}`);
4233
+ console.log(` ${icon} ${r.name.padEnd(15)} ${chalk20.gray(`${sec}s`)}`);
4250
4234
  }
4251
4235
  const passed = results.filter((r) => r.passed).length;
4252
4236
  const all = passed === results.length;
4253
- console.log(chalk21.gray("\u2500".repeat(40)));
4237
+ console.log(chalk20.gray("\u2500".repeat(40)));
4254
4238
  if (all) {
4255
- console.log(chalk21.green.bold(`
4239
+ console.log(chalk20.green.bold(`
4256
4240
  \u{1F389} \uC804\uCCB4 \uD1B5\uACFC! (${passed}/${results.length})`));
4257
4241
  } else {
4258
4242
  console.log(
4259
- chalk21.red.bold(`
4243
+ chalk20.red.bold(`
4260
4244
  \u26A0\uFE0F ${results.length - passed}\uAC1C \uC2E4\uD328 (${passed}/${results.length} \uD1B5\uACFC)`)
4261
4245
  );
4262
4246
  process.exitCode = 1;
@@ -4270,7 +4254,7 @@ async function harness() {
4270
4254
 
4271
4255
  // src/commands/migrate.ts
4272
4256
  import { existsSync as existsSync9, unlinkSync, rmSync as rmSync2 } from "fs";
4273
- import chalk22 from "chalk";
4257
+ import chalk21 from "chalk";
4274
4258
  import inquirer10 from "inquirer";
4275
4259
  import ora3 from "ora";
4276
4260
  var LOCK_FILES = {
@@ -4288,10 +4272,10 @@ function isCLIAvailable(pm) {
4288
4272
  return safeExecFile(pm, ["--version"]).ok;
4289
4273
  }
4290
4274
  async function migrate(target) {
4291
- console.log(chalk22.bold("\n\u{1F504} " + t("migrate.title")));
4292
- console.log(chalk22.gray("\u2500".repeat(40)));
4275
+ console.log(chalk21.bold("\n\u{1F504} " + t("migrate.title")));
4276
+ console.log(chalk21.gray("\u2500".repeat(40)));
4293
4277
  const current = detectCurrentPM();
4294
- console.log(chalk22.cyan(`
4278
+ console.log(chalk21.cyan(`
4295
4279
  \uD604\uC7AC \uD328\uD0A4\uC9C0 \uB9E4\uB2C8\uC800: ${current ?? "\uAC10\uC9C0 \uBD88\uAC00"}`));
4296
4280
  let targetPM;
4297
4281
  if (target && ["npm", "yarn", "pnpm"].includes(target)) {
@@ -4309,14 +4293,14 @@ async function migrate(target) {
4309
4293
  targetPM = selected;
4310
4294
  }
4311
4295
  if (targetPM === current) {
4312
- console.log(chalk22.yellow(`
4296
+ console.log(chalk21.yellow(`
4313
4297
  \u26A0\uFE0F \uC774\uBBF8 ${targetPM}\uC744 \uC0AC\uC6A9 \uC911\uC785\uB2C8\uB2E4.`));
4314
4298
  return;
4315
4299
  }
4316
4300
  if (!isCLIAvailable(targetPM)) {
4317
- console.log(chalk22.red(`
4301
+ console.log(chalk21.red(`
4318
4302
  \u274C ${targetPM}\uC774 \uC124\uCE58\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.`));
4319
- console.log(chalk22.yellow(` npm i -g ${targetPM}`));
4303
+ console.log(chalk21.yellow(` npm i -g ${targetPM}`));
4320
4304
  return;
4321
4305
  }
4322
4306
  const { confirm } = await inquirer10.prompt([
@@ -4328,7 +4312,7 @@ async function migrate(target) {
4328
4312
  }
4329
4313
  ]);
4330
4314
  if (!confirm) {
4331
- console.log(chalk22.gray("\uCDE8\uC18C\uB428"));
4315
+ console.log(chalk21.gray("\uCDE8\uC18C\uB428"));
4332
4316
  return;
4333
4317
  }
4334
4318
  const cleanup = ora3("\uAE30\uC874 lock \uD30C\uC77C \uC815\uB9AC \uC911...").start();
@@ -4348,10 +4332,10 @@ async function migrate(target) {
4348
4332
  install.succeed(`${targetPM} install \uC644\uB8CC!`);
4349
4333
  } else {
4350
4334
  install.fail(`${targetPM} install \uC2E4\uD328`);
4351
- console.log(chalk22.red(installResult.err.slice(0, 300)));
4335
+ console.log(chalk21.red(installResult.err.slice(0, 300)));
4352
4336
  return;
4353
4337
  }
4354
- console.log(chalk22.green.bold(`
4338
+ console.log(chalk21.green.bold(`
4355
4339
  \u{1F389} ${current ?? "\uC774\uC804"} \u2192 ${targetPM} \uC804\uD658 \uC644\uB8CC!`));
4356
4340
  printNextStep({
4357
4341
  message: "\uD328\uD0A4\uC9C0 \uB9E4\uB2C8\uC800 \uC804\uD658 \uC644\uB8CC!",
@@ -4364,7 +4348,7 @@ async function migrate(target) {
4364
4348
  import { existsSync as existsSync10 } from "fs";
4365
4349
  import { dirname as dirname2, join as join6 } from "path";
4366
4350
  import { fileURLToPath as fileURLToPath3 } from "url";
4367
- import chalk23 from "chalk";
4351
+ import chalk22 from "chalk";
4368
4352
  import ora4 from "ora";
4369
4353
  var PACKAGE = "@byh3071/vhk";
4370
4354
  function getCurrentVersion() {
@@ -4394,32 +4378,32 @@ function isUpToDate(current, latest) {
4394
4378
  return cc >= lc;
4395
4379
  }
4396
4380
  async function update() {
4397
- console.log(chalk23.bold("\n\u2B06\uFE0F " + t("update.title")));
4398
- console.log(chalk23.gray("\u2500".repeat(40)));
4381
+ console.log(chalk22.bold("\n\u2B06\uFE0F " + t("update.title")));
4382
+ console.log(chalk22.gray("\u2500".repeat(40)));
4399
4383
  const current = getCurrentVersion();
4400
- console.log(chalk23.cyan(`
4384
+ console.log(chalk22.cyan(`
4401
4385
  \u{1F4CC} \uD604\uC7AC \uBC84\uC804: v${current}`));
4402
4386
  const spinner = ora4("\uCD5C\uC2E0 \uBC84\uC804 \uD655\uC778 \uC911...").start();
4403
4387
  const latest = getLatestVersion();
4404
4388
  if (!latest) {
4405
4389
  spinner.fail("\uCD5C\uC2E0 \uBC84\uC804\uC744 \uD655\uC778\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
4406
- console.log(chalk23.yellow(" \uB124\uD2B8\uC6CC\uD06C\uB97C \uD655\uC778\uD558\uAC70\uB098 \uC218\uB3D9\uC73C\uB85C \uC5C5\uB370\uC774\uD2B8\uD558\uC138\uC694:"));
4407
- console.log(chalk23.gray(` npm update -g ${PACKAGE}`));
4390
+ console.log(chalk22.yellow(" \uB124\uD2B8\uC6CC\uD06C\uB97C \uD655\uC778\uD558\uAC70\uB098 \uC218\uB3D9\uC73C\uB85C \uC5C5\uB370\uC774\uD2B8\uD558\uC138\uC694:"));
4391
+ console.log(chalk22.gray(` npm update -g ${PACKAGE}`));
4408
4392
  return;
4409
4393
  }
4410
4394
  spinner.stop();
4411
- console.log(chalk23.cyan(`\u{1F195} \uCD5C\uC2E0 \uBC84\uC804: v${latest}`));
4395
+ console.log(chalk22.cyan(`\u{1F195} \uCD5C\uC2E0 \uBC84\uC804: v${latest}`));
4412
4396
  if (isUpToDate(current, latest)) {
4413
- console.log(chalk23.green("\n\u2705 \uC774\uBBF8 \uCD5C\uC2E0 \uBC84\uC804\uC785\uB2C8\uB2E4!"));
4397
+ console.log(chalk22.green("\n\u2705 \uC774\uBBF8 \uCD5C\uC2E0 \uBC84\uC804\uC785\uB2C8\uB2E4!"));
4414
4398
  return;
4415
4399
  }
4416
4400
  const updateSpinner = ora4(`v${latest}\uC73C\uB85C \uC5C5\uB370\uC774\uD2B8 \uC911...`).start();
4417
4401
  const upd = safeExecFile("npm", ["update", "-g", PACKAGE]);
4418
4402
  if (upd.ok) {
4419
4403
  updateSpinner.succeed(`v${latest}\uC73C\uB85C \uC5C5\uB370\uC774\uD2B8 \uC644\uB8CC!`);
4420
- console.log(chalk23.green.bold(`
4404
+ console.log(chalk22.green.bold(`
4421
4405
  \u{1F389} VHK CLI v${latest} \uC5C5\uB370\uC774\uD2B8 \uC644\uB8CC!`));
4422
- console.log(chalk23.gray(" \uBCC0\uACBD \uC0AC\uD56D\uC740 GitHub Releases\uB97C \uD655\uC778\uD558\uC138\uC694."));
4406
+ console.log(chalk22.gray(" \uBCC0\uACBD \uC0AC\uD56D\uC740 GitHub Releases\uB97C \uD655\uC778\uD558\uC138\uC694."));
4423
4407
  printNextStep({
4424
4408
  message: t("update.nextOkMessage"),
4425
4409
  command: "vhk --version",
@@ -4427,9 +4411,9 @@ async function update() {
4427
4411
  });
4428
4412
  } else {
4429
4413
  updateSpinner.fail("\uC5C5\uB370\uC774\uD2B8 \uC2E4\uD328");
4430
- console.log(chalk23.red(upd.err.slice(0, 300)));
4431
- console.log(chalk23.yellow("\n\uC218\uB3D9\uC73C\uB85C \uC5C5\uB370\uC774\uD2B8\uD558\uC138\uC694:"));
4432
- console.log(chalk23.gray(` npm update -g ${PACKAGE}`));
4414
+ console.log(chalk22.red(upd.err.slice(0, 300)));
4415
+ console.log(chalk22.yellow("\n\uC218\uB3D9\uC73C\uB85C \uC5C5\uB370\uC774\uD2B8\uD558\uC138\uC694:"));
4416
+ console.log(chalk22.gray(` npm update -g ${PACKAGE}`));
4433
4417
  printNextStep({
4434
4418
  message: t("update.nextFailMessage"),
4435
4419
  command: "vhk doctor",
@@ -4448,7 +4432,7 @@ import {
4448
4432
  writeFileSync as writeFileSync7
4449
4433
  } from "fs";
4450
4434
  import { join as join7 } from "path";
4451
- import chalk24 from "chalk";
4435
+ import chalk23 from "chalk";
4452
4436
  var CONTEXT_PATH = ".vhk/context.md";
4453
4437
  var IGNORE_DIRS = /* @__PURE__ */ new Set([
4454
4438
  "node_modules",
@@ -4549,8 +4533,8 @@ function getVhkCommands() {
4549
4533
  }
4550
4534
  async function context(opts = {}) {
4551
4535
  const compact = opts.compact === true;
4552
- console.log(chalk24.bold("\n\u{1F9E0} " + t("context.title")));
4553
- console.log(chalk24.gray("\u2500".repeat(40)));
4536
+ console.log(chalk23.bold("\n\u{1F9E0} " + t("context.title")));
4537
+ console.log(chalk23.gray("\u2500".repeat(40)));
4554
4538
  const stack = extractTechStack();
4555
4539
  const tree = buildTree(".", "", compact ? 2 : 3).join("\n");
4556
4540
  const commands = getVhkCommands();
@@ -4665,10 +4649,10 @@ async function context(opts = {}) {
4665
4649
  lines.push("");
4666
4650
  mkdirSync7(".vhk", { recursive: true });
4667
4651
  writeFileSync7(CONTEXT_PATH, lines.join("\n"), "utf-8");
4668
- console.log(chalk24.green(`
4652
+ console.log(chalk23.green(`
4669
4653
  \u2705 ${CONTEXT_PATH} \uC0DD\uC131 \uC644\uB8CC!`));
4670
- console.log(chalk24.gray(` \uAE30\uC220 \uC2A4\uD0DD ${Object.keys(stack).length}\uAC1C \uAC10\uC9C0`));
4671
- console.log(chalk24.gray(" AI \uC5B4\uC2DC\uC2A4\uD134\uD2B8\uC5D0\uAC8C \uC774 \uD30C\uC77C\uC744 \uCC38\uC870\uD558\uAC8C \uD558\uC138\uC694."));
4654
+ console.log(chalk23.gray(` \uAE30\uC220 \uC2A4\uD0DD ${Object.keys(stack).length}\uAC1C \uAC10\uC9C0`));
4655
+ console.log(chalk23.gray(" AI \uC5B4\uC2DC\uC2A4\uD134\uD2B8\uC5D0\uAC8C \uC774 \uD30C\uC77C\uC744 \uCC38\uC870\uD558\uAC8C \uD558\uC138\uC694."));
4672
4656
  printNextStep({
4673
4657
  message: "\uCEE8\uD14D\uC2A4\uD2B8 \uD30C\uC77C \uC0DD\uC131 \uC644\uB8CC!",
4674
4658
  command: "vhk context-show",
@@ -4676,11 +4660,11 @@ async function context(opts = {}) {
4676
4660
  });
4677
4661
  }
4678
4662
  async function contextShow() {
4679
- console.log(chalk24.bold("\n\u{1F4C4} " + t("context.showTitle")));
4680
- console.log(chalk24.gray("\u2500".repeat(40)));
4663
+ console.log(chalk23.bold("\n\u{1F4C4} " + t("context.showTitle")));
4664
+ console.log(chalk23.gray("\u2500".repeat(40)));
4681
4665
  if (!existsSync11(CONTEXT_PATH)) {
4682
- console.log(chalk24.yellow("\n\u26A0\uFE0F \uCEE8\uD14D\uC2A4\uD2B8 \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4."));
4683
- console.log(chalk24.gray(" vhk context\uB97C \uBA3C\uC800 \uC2E4\uD589\uD558\uC138\uC694."));
4666
+ console.log(chalk23.yellow("\n\u26A0\uFE0F \uCEE8\uD14D\uC2A4\uD2B8 \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4."));
4667
+ console.log(chalk23.gray(" vhk context\uB97C \uBA3C\uC800 \uC2E4\uD589\uD558\uC138\uC694."));
4684
4668
  return;
4685
4669
  }
4686
4670
  const content = readFileSync4(CONTEXT_PATH, "utf-8");
@@ -4689,7 +4673,7 @@ async function contextShow() {
4689
4673
 
4690
4674
  // src/commands/memory.ts
4691
4675
  import { existsSync as existsSync12, mkdirSync as mkdirSync8, writeFileSync as writeFileSync8 } from "fs";
4692
- import chalk25 from "chalk";
4676
+ import chalk24 from "chalk";
4693
4677
  var MEMORY_PATH = ".vhk/memory.json";
4694
4678
  function loadMemories() {
4695
4679
  if (!existsSync12(MEMORY_PATH)) return [];
@@ -4705,11 +4689,11 @@ function saveMemories(memories) {
4705
4689
  writeFileSync8(MEMORY_PATH, JSON.stringify(memories, null, 2) + "\n", "utf-8");
4706
4690
  }
4707
4691
  async function memoryAdd(content, tags) {
4708
- console.log(chalk25.bold("\n\u{1F9E0} " + t("memory.addTitle")));
4709
- console.log(chalk25.gray("\u2500".repeat(40)));
4692
+ console.log(chalk24.bold("\n\u{1F9E0} " + t("memory.addTitle")));
4693
+ console.log(chalk24.gray("\u2500".repeat(40)));
4710
4694
  if (!content) {
4711
- console.log(chalk25.red("\u274C \uAE30\uC5B5\uD560 \uB0B4\uC6A9\uC744 \uC785\uB825\uD574\uC8FC\uC138\uC694."));
4712
- console.log(chalk25.gray(' \uC608: vhk memory add "API\uB294 tRPC \uC0AC\uC6A9\uD558\uAE30\uB85C \uACB0\uC815"'));
4695
+ console.log(chalk24.red("\u274C \uAE30\uC5B5\uD560 \uB0B4\uC6A9\uC744 \uC785\uB825\uD574\uC8FC\uC138\uC694."));
4696
+ console.log(chalk24.gray(' \uC608: vhk memory add "API\uB294 tRPC \uC0AC\uC6A9\uD558\uAE30\uB85C \uACB0\uC815"'));
4713
4697
  process.exitCode = 1;
4714
4698
  return;
4715
4699
  }
@@ -4720,9 +4704,9 @@ async function memoryAdd(content, tags) {
4720
4704
  tags: tags && tags.length > 0 ? tags : []
4721
4705
  });
4722
4706
  saveMemories(memories);
4723
- console.log(chalk25.green(`
4707
+ console.log(chalk24.green(`
4724
4708
  \u2705 \uAE30\uC5B5 \uC800\uC7A5\uB428 (#${memories.length})`));
4725
- console.log(chalk25.cyan(` \u{1F4DD} ${content}`));
4709
+ console.log(chalk24.cyan(` \u{1F4DD} ${content}`));
4726
4710
  printNextStep({
4727
4711
  message: "\uAE30\uC5B5 \uC800\uC7A5 \uC644\uB8CC!",
4728
4712
  command: "vhk memory list",
@@ -4730,24 +4714,24 @@ async function memoryAdd(content, tags) {
4730
4714
  });
4731
4715
  }
4732
4716
  async function memoryList() {
4733
- console.log(chalk25.bold("\n\u{1F9E0} " + t("memory.listTitle")));
4734
- console.log(chalk25.gray("\u2500".repeat(40)));
4717
+ console.log(chalk24.bold("\n\u{1F9E0} " + t("memory.listTitle")));
4718
+ console.log(chalk24.gray("\u2500".repeat(40)));
4735
4719
  const memories = loadMemories();
4736
4720
  if (memories.length === 0) {
4737
- console.log(chalk25.yellow("\n\u{1F4ED} \uC800\uC7A5\uB41C \uAE30\uC5B5\uC774 \uC5C6\uC2B5\uB2C8\uB2E4."));
4738
- console.log(chalk25.gray(' vhk memory add "\uB0B4\uC6A9"\uC73C\uB85C \uCD94\uAC00\uD558\uC138\uC694.'));
4721
+ console.log(chalk24.yellow("\n\u{1F4ED} \uC800\uC7A5\uB41C \uAE30\uC5B5\uC774 \uC5C6\uC2B5\uB2C8\uB2E4."));
4722
+ console.log(chalk24.gray(' vhk memory add "\uB0B4\uC6A9"\uC73C\uB85C \uCD94\uAC00\uD558\uC138\uC694.'));
4739
4723
  return;
4740
4724
  }
4741
- console.log(chalk25.cyan(`
4725
+ console.log(chalk24.cyan(`
4742
4726
  \uCD1D ${memories.length}\uAC1C\uC758 \uAE30\uC5B5:
4743
4727
  `));
4744
4728
  memories.forEach((m, index) => {
4745
4729
  const date = new Date(m.addedAt).toLocaleDateString("ko-KR");
4746
- console.log(chalk25.white(` [${index + 1}] ${m.content}`));
4730
+ console.log(chalk24.white(` [${index + 1}] ${m.content}`));
4747
4731
  if (m.tags && m.tags.length > 0) {
4748
- console.log(chalk25.blue(` \u{1F3F7}\uFE0F ${m.tags.join(", ")}`));
4732
+ console.log(chalk24.blue(` \u{1F3F7}\uFE0F ${m.tags.join(", ")}`));
4749
4733
  }
4750
- console.log(chalk25.gray(` \u{1F4C5} ${date}`));
4734
+ console.log(chalk24.gray(` \u{1F4C5} ${date}`));
4751
4735
  console.log("");
4752
4736
  });
4753
4737
  }
@@ -4755,18 +4739,18 @@ async function memoryRemove(indexStr) {
4755
4739
  const memories = loadMemories();
4756
4740
  const idx = parseInt(indexStr, 10) - 1;
4757
4741
  if (Number.isNaN(idx) || idx < 0 || idx >= memories.length) {
4758
- console.log(chalk25.red(`\u274C \uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uBC88\uD638\uC785\uB2C8\uB2E4. (1~${memories.length || 0})`));
4742
+ console.log(chalk24.red(`\u274C \uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uBC88\uD638\uC785\uB2C8\uB2E4. (1~${memories.length || 0})`));
4759
4743
  return;
4760
4744
  }
4761
4745
  const removed = memories.splice(idx, 1)[0];
4762
4746
  saveMemories(memories);
4763
- console.log(chalk25.green("\n\u2705 \uAE30\uC5B5 \uC0AD\uC81C\uB428:"));
4764
- console.log(chalk25.gray(` ${removed.content}`));
4747
+ console.log(chalk24.green("\n\u2705 \uAE30\uC5B5 \uC0AD\uC81C\uB428:"));
4748
+ console.log(chalk24.gray(` ${removed.content}`));
4765
4749
  }
4766
4750
 
4767
4751
  // src/commands/brief.ts
4768
4752
  import { existsSync as existsSync13, mkdirSync as mkdirSync9, writeFileSync as writeFileSync9, readFileSync as readFileSync5 } from "fs";
4769
- import chalk26 from "chalk";
4753
+ import chalk25 from "chalk";
4770
4754
  var BRIEF_PATH = ".vhk/brief.md";
4771
4755
  function readProjectIdentity() {
4772
4756
  const out = {};
@@ -4791,8 +4775,8 @@ function git2(args) {
4791
4775
  return result.ok ? result.out : "";
4792
4776
  }
4793
4777
  async function brief() {
4794
- console.log(chalk26.bold("\n\u{1F4CB} " + t("brief.title")));
4795
- console.log(chalk26.gray("\u2500".repeat(40)));
4778
+ console.log(chalk25.bold("\n\u{1F4CB} " + t("brief.title")));
4779
+ console.log(chalk25.gray("\u2500".repeat(40)));
4796
4780
  const lines = [];
4797
4781
  lines.push("# \uD504\uB85C\uC81D\uD2B8 \uBE0C\uB9AC\uD551");
4798
4782
  lines.push("");
@@ -4877,7 +4861,7 @@ async function brief() {
4877
4861
  mkdirSync9(".vhk", { recursive: true });
4878
4862
  writeFileSync9(BRIEF_PATH, lines.join("\n"), "utf-8");
4879
4863
  console.log("\n" + lines.join("\n"));
4880
- console.log(chalk26.green(`
4864
+ console.log(chalk25.green(`
4881
4865
  \u2705 ${BRIEF_PATH} \uC800\uC7A5 \uC644\uB8CC`));
4882
4866
  printNextStep({
4883
4867
  message: "\uBE0C\uB9AC\uD551 \uC0DD\uC131 \uC644\uB8CC!",
@@ -4887,7 +4871,7 @@ async function brief() {
4887
4871
  }
4888
4872
 
4889
4873
  // src/commands/start.ts
4890
- import chalk27 from "chalk";
4874
+ import chalk26 from "chalk";
4891
4875
  import inquirer11 from "inquirer";
4892
4876
  import { simpleGit as simpleGit2 } from "simple-git";
4893
4877
  import { existsSync as existsSync14 } from "fs";
@@ -4929,21 +4913,21 @@ async function runStep(label, fn) {
4929
4913
  }
4930
4914
  }
4931
4915
  async function start(options = {}) {
4932
- console.log(chalk27.bold(`
4916
+ console.log(chalk26.bold(`
4933
4917
  ${ko.start.title}
4934
4918
  `));
4935
- console.log(chalk27.dim(ko.start.intro));
4936
- console.log(chalk27.dim(` ${ko.start.step1}`));
4937
- console.log(chalk27.dim(` ${ko.start.step2}`));
4938
- console.log(chalk27.dim(` ${ko.start.step3}`));
4939
- console.log(chalk27.dim(` ${ko.start.step4}`));
4919
+ console.log(chalk26.dim(ko.start.intro));
4920
+ console.log(chalk26.dim(` ${ko.start.step1}`));
4921
+ console.log(chalk26.dim(` ${ko.start.step2}`));
4922
+ console.log(chalk26.dim(` ${ko.start.step3}`));
4923
+ console.log(chalk26.dim(` ${ko.start.step4}`));
4940
4924
  console.log();
4941
4925
  const cwd = process.cwd();
4942
4926
  const footprint = detectExistingFootprint(cwd);
4943
4927
  if (footprint.length > 0 && !options.yes) {
4944
- console.log(chalk27.yellow("\u26A0\uFE0F \uC774\uBBF8 VHK \uC124\uCE58 \uD754\uC801\uC774 \uAC10\uC9C0\uB410\uC5B4\uC694:"));
4945
- for (const f of footprint) console.log(chalk27.dim(` - ${f}`));
4946
- console.log(chalk27.dim(" \uACC4\uC18D \uC9C4\uD589\uD558\uBA74 \uC77C\uBD80 \uD30C\uC77C(`.cursor/mcp.json`, `.vhk/context.md`)\uC740 \uAC31\uC2E0\xB7\uB36E\uC5B4\uC4F0\uAE30\uB429\uB2C8\uB2E4."));
4928
+ console.log(chalk26.yellow("\u26A0\uFE0F \uC774\uBBF8 VHK \uC124\uCE58 \uD754\uC801\uC774 \uAC10\uC9C0\uB410\uC5B4\uC694:"));
4929
+ for (const f of footprint) console.log(chalk26.dim(` - ${f}`));
4930
+ console.log(chalk26.dim(" \uACC4\uC18D \uC9C4\uD589\uD558\uBA74 \uC77C\uBD80 \uD30C\uC77C(`.cursor/mcp.json`, `.vhk/context.md`)\uC740 \uAC31\uC2E0\xB7\uB36E\uC5B4\uC4F0\uAE30\uB429\uB2C8\uB2E4."));
4947
4931
  const { proceedExisting } = await inquirer11.prompt([{
4948
4932
  type: "confirm",
4949
4933
  name: "proceedExisting",
@@ -4981,7 +4965,7 @@ ${ko.start.title}
4981
4965
  await runStep("[3/4] vhk mcp-init", () => mcpInit());
4982
4966
  log.step(ko.start.step4Header);
4983
4967
  await runStep("[4/4] vhk context", () => context());
4984
- console.log(chalk27.bold.green(`
4968
+ console.log(chalk26.bold.green(`
4985
4969
  ${ko.start.allDone}
4986
4970
  `));
4987
4971
  printNextStep({
@@ -4994,7 +4978,7 @@ ${ko.start.allDone}
4994
4978
  import fs12 from "fs";
4995
4979
  import os from "os";
4996
4980
  import path13 from "path";
4997
- import chalk28 from "chalk";
4981
+ import chalk27 from "chalk";
4998
4982
 
4999
4983
  // src/lib/vhk-cloud.ts
5000
4984
  var import_ignore = __toESM(require_ignore(), 1);
@@ -5086,14 +5070,14 @@ ${CLOUD_CONFIG_FILE}
5086
5070
  function ensureGhReady() {
5087
5071
  const ver = safeExecFile("gh", ["--version"]);
5088
5072
  if (!ver.ok) {
5089
- console.log(chalk28.red(` ${ko.cloud.noGh}`));
5090
- console.log(chalk28.dim(" \uC124\uCE58: https://cli.github.com/ (\uC124\uCE58 \uD6C4 `gh auth login`)"));
5073
+ console.log(chalk27.red(` ${ko.cloud.noGh}`));
5074
+ console.log(chalk27.dim(" \uC124\uCE58: https://cli.github.com/ (\uC124\uCE58 \uD6C4 `gh auth login`)"));
5091
5075
  return false;
5092
5076
  }
5093
5077
  const auth = safeExecFile("gh", ["auth", "status"]);
5094
5078
  if (!auth.ok) {
5095
- console.log(chalk28.red(` ${ko.cloud.noAuth}`));
5096
- console.log(chalk28.dim(" \uC2E4\uD589: gh auth login (gist \uAD8C\uD55C \uD544\uC694)"));
5079
+ console.log(chalk27.red(` ${ko.cloud.noAuth}`));
5080
+ console.log(chalk27.dim(" \uC2E4\uD589: gh auth login (gist \uAD8C\uD55C \uD544\uC694)"));
5097
5081
  return false;
5098
5082
  }
5099
5083
  return true;
@@ -5106,18 +5090,18 @@ function parseGistId(output) {
5106
5090
  return null;
5107
5091
  }
5108
5092
  async function cloudPush() {
5109
- console.log(chalk28.bold(`
5093
+ console.log(chalk27.bold(`
5110
5094
  ${ko.cloud.pushTitle}
5111
5095
  `));
5112
5096
  const cwd = process.cwd();
5113
5097
  if (!fs12.existsSync(path13.join(cwd, VHK_DIR2))) {
5114
- console.log(chalk28.yellow(` ${ko.cloud.noVhkDir}`));
5098
+ console.log(chalk27.yellow(` ${ko.cloud.noVhkDir}`));
5115
5099
  return;
5116
5100
  }
5117
5101
  const ig = loadVhkignore(cwd);
5118
5102
  const files = collectVhkFiles(cwd, ig);
5119
5103
  if (files.length === 0) {
5120
- console.log(chalk28.yellow(` ${ko.cloud.nothingToSync}`));
5104
+ console.log(chalk27.yellow(` ${ko.cloud.nothingToSync}`));
5121
5105
  return;
5122
5106
  }
5123
5107
  if (!ensureGhReady()) {
@@ -5125,7 +5109,7 @@ ${ko.cloud.pushTitle}
5125
5109
  return;
5126
5110
  }
5127
5111
  const filePaths = files.map((f) => path13.join(cwd, VHK_DIR2, f));
5128
- console.log(chalk28.dim(` \u{1F4E6} \uBC31\uC5C5 \uB300\uC0C1 ${files.length}\uAC1C: ${files.join(", ")}
5112
+ console.log(chalk27.dim(` \u{1F4E6} \uBC31\uC5C5 \uB300\uC0C1 ${files.length}\uAC1C: ${files.join(", ")}
5129
5113
  `));
5130
5114
  const existing = readCloudConfig(cwd);
5131
5115
  const desc = `vhk .vhk backup \u2014 ${path13.basename(cwd)}`;
@@ -5137,8 +5121,8 @@ ${ko.cloud.pushTitle}
5137
5121
  const args = gistFiles.includes(name) ? ["gist", "edit", existing.gistId, "-f", name, src] : ["gist", "edit", existing.gistId, "-a", src];
5138
5122
  const res2 = safeExecFile("gh", args);
5139
5123
  if (!res2.ok) {
5140
- console.log(chalk28.red(` ${ko.cloud.pushFail}: ${name}`));
5141
- console.log(chalk28.dim(` ${res2.err}`));
5124
+ console.log(chalk27.red(` ${ko.cloud.pushFail}: ${name}`));
5125
+ console.log(chalk27.dim(` ${res2.err}`));
5142
5126
  process.exitCode = 1;
5143
5127
  return;
5144
5128
  }
@@ -5153,15 +5137,15 @@ ${ko.cloud.pushTitle}
5153
5137
  if (!purgeFailed.includes(name)) purgeFailed.push(name);
5154
5138
  }
5155
5139
  }
5156
- console.log(chalk28.green.bold(` ${ko.cloud.pushDone}`));
5157
- console.log(chalk28.dim(` gist: ${existing.gistId} (\uAC31\uC2E0)`));
5140
+ console.log(chalk27.green.bold(` ${ko.cloud.pushDone}`));
5141
+ console.log(chalk27.dim(` gist: ${existing.gistId} (\uAC31\uC2E0)`));
5158
5142
  if (excluded.length > 0) {
5159
5143
  const purged = excluded.filter((n) => !purgeFailed.includes(n));
5160
5144
  if (purged.length > 0) {
5161
- console.log(chalk28.dim(` \u{1F512} \uC81C\uC678 \uB300\uC0C1 ${purged.length}\uAC1C gist \uC5D0\uC11C \uC81C\uAC70: ${purged.join(", ")}`));
5145
+ console.log(chalk27.dim(` \u{1F512} \uC81C\uC678 \uB300\uC0C1 ${purged.length}\uAC1C gist \uC5D0\uC11C \uC81C\uAC70: ${purged.join(", ")}`));
5162
5146
  }
5163
5147
  if (purgeFailed.length > 0) {
5164
- console.log(chalk28.yellow(` \u26A0\uFE0F \uC81C\uC678 \uB300\uC0C1 \uC81C\uAC70 \uC2E4\uD328: ${purgeFailed.join(", ")} (\uC218\uB3D9 \uC81C\uAC70 \uAD8C\uC7A5 \u2014 pull \uC2DC\uC5D4 \uBCF5\uC6D0 \uC548 \uB428)`));
5148
+ console.log(chalk27.yellow(` \u26A0\uFE0F \uC81C\uC678 \uB300\uC0C1 \uC81C\uAC70 \uC2E4\uD328: ${purgeFailed.join(", ")} (\uC218\uB3D9 \uC81C\uAC70 \uAD8C\uC7A5 \u2014 pull \uC2DC\uC5D4 \uBCF5\uC6D0 \uC548 \uB428)`));
5165
5149
  }
5166
5150
  }
5167
5151
  printPushNext();
@@ -5169,32 +5153,32 @@ ${ko.cloud.pushTitle}
5169
5153
  }
5170
5154
  const res = safeExecFile("gh", ["gist", "create", "--desc", desc, ...filePaths]);
5171
5155
  if (!res.ok) {
5172
- console.log(chalk28.red(` ${ko.cloud.pushFail}`));
5173
- console.log(chalk28.dim(` ${res.err || res.out}`));
5156
+ console.log(chalk27.red(` ${ko.cloud.pushFail}`));
5157
+ console.log(chalk27.dim(` ${res.err || res.out}`));
5174
5158
  process.exitCode = 1;
5175
5159
  return;
5176
5160
  }
5177
5161
  const gistId = parseGistId(res.out);
5178
5162
  if (!gistId) {
5179
- console.log(chalk28.red(` ${ko.cloud.pushFail} \u2014 gist id \uD30C\uC2F1 \uC2E4\uD328`));
5180
- console.log(chalk28.dim(` \uCD9C\uB825: ${res.out}`));
5163
+ console.log(chalk27.red(` ${ko.cloud.pushFail} \u2014 gist id \uD30C\uC2F1 \uC2E4\uD328`));
5164
+ console.log(chalk27.dim(` \uCD9C\uB825: ${res.out}`));
5181
5165
  process.exitCode = 1;
5182
5166
  return;
5183
5167
  }
5184
5168
  writeCloudConfig(cwd, { gistId });
5185
- console.log(chalk28.green.bold(` ${ko.cloud.pushDone}`));
5186
- console.log(chalk28.dim(` gist: ${gistId} (\uC2E0\uADDC, secret) \u2192 .vhk/cloud.json \uC800\uC7A5`));
5169
+ console.log(chalk27.green.bold(` ${ko.cloud.pushDone}`));
5170
+ console.log(chalk27.dim(` gist: ${gistId} (\uC2E0\uADDC, secret) \u2192 .vhk/cloud.json \uC800\uC7A5`));
5187
5171
  printPushNext();
5188
5172
  }
5189
5173
  async function cloudPull(gistIdArg) {
5190
- console.log(chalk28.bold(`
5174
+ console.log(chalk27.bold(`
5191
5175
  ${ko.cloud.pullTitle}
5192
5176
  `));
5193
5177
  const cwd = process.cwd();
5194
5178
  const gistId = gistIdArg || readCloudConfig(cwd)?.gistId;
5195
5179
  if (!gistId) {
5196
- console.log(chalk28.yellow(` ${ko.cloud.noGistId}`));
5197
- console.log(chalk28.dim(" \uC0AC\uC6A9\uBC95: vhk cloud pull <gistId> (\uB610\uB294 cloud.json \uC774 \uC788\uB294 \uACF3\uC5D0\uC11C \uC2E4\uD589)"));
5180
+ console.log(chalk27.yellow(` ${ko.cloud.noGistId}`));
5181
+ console.log(chalk27.dim(" \uC0AC\uC6A9\uBC95: vhk cloud pull <gistId> (\uB610\uB294 cloud.json \uC774 \uC788\uB294 \uACF3\uC5D0\uC11C \uC2E4\uD589)"));
5198
5182
  return;
5199
5183
  }
5200
5184
  if (!ensureGhReady()) {
@@ -5203,16 +5187,16 @@ ${ko.cloud.pullTitle}
5203
5187
  }
5204
5188
  const allNames = listGistFiles(gistId);
5205
5189
  if (allNames.length === 0) {
5206
- console.log(chalk28.red(` ${ko.cloud.pullFail} \u2014 gist \uBE44\uC5C8\uAC70\uB098 \uC811\uADFC \uBD88\uAC00: ${gistId}`));
5190
+ console.log(chalk27.red(` ${ko.cloud.pullFail} \u2014 gist \uBE44\uC5C8\uAC70\uB098 \uC811\uADFC \uBD88\uAC00: ${gistId}`));
5207
5191
  process.exitCode = 1;
5208
5192
  return;
5209
5193
  }
5210
5194
  const { keep: names, excluded: skipped } = partitionGistFiles(allNames, loadVhkignore(cwd));
5211
5195
  if (skipped.length > 0) {
5212
- console.log(chalk28.dim(` \u{1F512} \uC81C\uC678 \uB300\uC0C1 ${skipped.length}\uAC1C \uBCF5\uC6D0 \uC2A4\uD0B5: ${skipped.join(", ")}`));
5196
+ console.log(chalk27.dim(` \u{1F512} \uC81C\uC678 \uB300\uC0C1 ${skipped.length}\uAC1C \uBCF5\uC6D0 \uC2A4\uD0B5: ${skipped.join(", ")}`));
5213
5197
  }
5214
5198
  if (names.length === 0) {
5215
- console.log(chalk28.yellow(` \uBCF5\uC6D0 \uB300\uC0C1\uC774 \uC5C6\uC2B5\uB2C8\uB2E4 (gist \uD30C\uC77C\uC774 \uBAA8\uB450 \uC81C\uC678 \uADDC\uCE59\uC5D0 \uD574\uB2F9).`));
5199
+ console.log(chalk27.yellow(` \uBCF5\uC6D0 \uB300\uC0C1\uC774 \uC5C6\uC2B5\uB2C8\uB2E4 (gist \uD30C\uC77C\uC774 \uBAA8\uB450 \uC81C\uC678 \uADDC\uCE59\uC5D0 \uD574\uB2F9).`));
5216
5200
  return;
5217
5201
  }
5218
5202
  const vhkDir = path13.join(cwd, VHK_DIR2);
@@ -5221,16 +5205,16 @@ ${ko.cloud.pullTitle}
5221
5205
  for (const name of names) {
5222
5206
  const res = safeExecFile("gh", ["gist", "view", gistId, "-f", name, "--raw"]);
5223
5207
  if (!res.ok) {
5224
- console.log(chalk28.red(` ${ko.cloud.pullFail}: ${name}`));
5225
- console.log(chalk28.dim(` ${res.err}`));
5208
+ console.log(chalk27.red(` ${ko.cloud.pullFail}: ${name}`));
5209
+ console.log(chalk27.dim(` ${res.err}`));
5226
5210
  continue;
5227
5211
  }
5228
5212
  fs12.writeFileSync(path13.join(vhkDir, name), ensureTrailingNewline(res.out), "utf-8");
5229
5213
  restored++;
5230
5214
  }
5231
5215
  writeCloudConfig(cwd, { gistId });
5232
- console.log(chalk28.green.bold(` ${ko.cloud.pullDone}`));
5233
- console.log(chalk28.dim(` ${restored}\uAC1C \uD30C\uC77C \uBCF5\uC6D0 (gist: ${gistId})`));
5216
+ console.log(chalk27.green.bold(` ${ko.cloud.pullDone}`));
5217
+ console.log(chalk27.dim(` ${restored}\uAC1C \uD30C\uC77C \uBCF5\uC6D0 (gist: ${gistId})`));
5234
5218
  printNextStep({
5235
5219
  message: "\uD074\uB77C\uC6B0\uB4DC\uC5D0\uC11C .vhk/ \uBCF5\uC6D0 \uC644\uB8CC!",
5236
5220
  command: "vhk \uB9E5\uB77D",
@@ -5278,7 +5262,7 @@ function printPushNext() {
5278
5262
  }
5279
5263
 
5280
5264
  // src/commands/help.ts
5281
- import chalk29 from "chalk";
5265
+ import chalk28 from "chalk";
5282
5266
  var QUICK_ACTIONS = [
5283
5267
  { say: "\uC0C1\uD0DC \uC54C\uB824\uC918", does: "vhk status" },
5284
5268
  { say: "\uBB50 \uBC14\uB00C\uC5C8\uC5B4?", does: "vhk diff" },
@@ -5292,17 +5276,17 @@ var QUICK_ACTIONS = [
5292
5276
  { say: "\uC804\uCCB4 \uBA85\uB839\uC5B4 \uBCF4\uAE30", does: "vhk --help" }
5293
5277
  ];
5294
5278
  function quickActions() {
5295
- console.log(chalk29.bold("\n\u{1F9ED} VHK \u2014 \uC774\uB807\uAC8C \uB9D0\uD558\uBA74 \uB429\uB2C8\uB2E4 (quick actions)"));
5296
- console.log(chalk29.gray("\u2500".repeat(40)));
5279
+ console.log(chalk28.bold("\n\u{1F9ED} VHK \u2014 \uC774\uB807\uAC8C \uB9D0\uD558\uBA74 \uB429\uB2C8\uB2E4 (quick actions)"));
5280
+ console.log(chalk28.gray("\u2500".repeat(40)));
5297
5281
  for (const a of QUICK_ACTIONS) {
5298
- console.log(` "${chalk29.cyan(a.say)}" \u2192 ${chalk29.dim(a.does)}`);
5282
+ console.log(` "${chalk28.cyan(a.say)}" \u2192 ${chalk28.dim(a.does)}`);
5299
5283
  }
5300
- console.log(chalk29.gray("\n \uC804\uCCB4 \uBA85\uB839\uC740 `vhk --help` \uB610\uB294 COMMANDS.md \uB97C \uBCF4\uC138\uC694."));
5284
+ console.log(chalk28.gray("\n \uC804\uCCB4 \uBA85\uB839\uC740 `vhk --help` \uB610\uB294 COMMANDS.md \uB97C \uBCF4\uC138\uC694."));
5301
5285
  console.log("");
5302
5286
  }
5303
5287
 
5304
5288
  // src/commands/mode.ts
5305
- import chalk30 from "chalk";
5289
+ import chalk29 from "chalk";
5306
5290
 
5307
5291
  // src/lib/config.ts
5308
5292
  import { existsSync as existsSync15, mkdirSync as mkdirSync10, writeFileSync as writeFileSync10 } from "fs";
@@ -5343,17 +5327,17 @@ function writeConfig(config, rootDir = process.cwd()) {
5343
5327
 
5344
5328
  // src/commands/mode.ts
5345
5329
  async function mode(target) {
5346
- console.log(chalk30.bold("\n\u{1F6E1}\uFE0F Safety Mode"));
5347
- console.log(chalk30.gray("\u2500".repeat(40)));
5330
+ console.log(chalk29.bold("\n\u{1F6E1}\uFE0F Safety Mode"));
5331
+ console.log(chalk29.gray("\u2500".repeat(40)));
5348
5332
  const current = readConfig().safetyMode;
5349
5333
  if (!target) {
5350
- console.log(chalk30.cyan(`
5351
- \uD604\uC7AC \uBAA8\uB4DC: ${chalk30.bold(current)}`));
5352
- console.log(chalk30.dim(` ${SAFETY_MODE_DESC[current]}`));
5334
+ console.log(chalk29.cyan(`
5335
+ \uD604\uC7AC \uBAA8\uB4DC: ${chalk29.bold(current)}`));
5336
+ console.log(chalk29.dim(` ${SAFETY_MODE_DESC[current]}`));
5353
5337
  console.log("");
5354
5338
  for (const m of SAFETY_MODES) {
5355
5339
  const mark = m === current ? "\u25CF" : "\u25CB";
5356
- console.log(` ${mark} ${m.padEnd(9)} ${chalk30.dim(SAFETY_MODE_DESC[m])}`);
5340
+ console.log(` ${mark} ${m.padEnd(9)} ${chalk29.dim(SAFETY_MODE_DESC[m])}`);
5357
5341
  }
5358
5342
  printNextStep({
5359
5343
  message: "\uBAA8\uB4DC\uB97C \uBC14\uAFB8\uB824\uBA74:",
@@ -5363,43 +5347,221 @@ async function mode(target) {
5363
5347
  return;
5364
5348
  }
5365
5349
  if (!isSafetyMode(target)) {
5366
- console.log(chalk30.red(`
5350
+ console.log(chalk29.red(`
5367
5351
  \u274C \uC54C \uC218 \uC5C6\uB294 \uBAA8\uB4DC: ${target}`));
5368
- console.log(chalk30.dim(` \uAC00\uB2A5: ${SAFETY_MODES.join(" | ")}`));
5352
+ console.log(chalk29.dim(` \uAC00\uB2A5: ${SAFETY_MODES.join(" | ")}`));
5369
5353
  process.exitCode = 1;
5370
5354
  return;
5371
5355
  }
5372
5356
  writeConfig({ ...readConfig(), safetyMode: target });
5373
- console.log(chalk30.green(`
5374
- \u2705 Safety Mode \u2192 ${chalk30.bold(target)}`));
5375
- console.log(chalk30.dim(` ${SAFETY_MODE_DESC[target]}`));
5357
+ console.log(chalk29.green(`
5358
+ \u2705 Safety Mode \u2192 ${chalk29.bold(target)}`));
5359
+ console.log(chalk29.dim(` ${SAFETY_MODE_DESC[target]}`));
5376
5360
  }
5377
5361
 
5378
5362
  // src/commands/verify.ts
5379
- import chalk31 from "chalk";
5380
- function verificationChecklist() {
5381
- return [
5382
- "\uD0C0\uC785 \uCCB4\uD06C \u2014 pnpm exec tsc --noEmit",
5383
- "\uD14C\uC2A4\uD2B8 \u2014 pnpm run test:run",
5384
- "\uBE4C\uB4DC \u2014 pnpm run build",
5385
- "\uBCF4\uC548 \uC2A4\uCE94 \u2014 vhk secure scan"
5386
- ];
5363
+ import { execFileSync as execFileSync4 } from "child_process";
5364
+ import { existsSync as existsSync16, mkdirSync as mkdirSync11, writeFileSync as writeFileSync11 } from "fs";
5365
+ import { join as join10 } from "path";
5366
+ import chalk30 from "chalk";
5367
+ var REPORT_SCHEMA_VERSION = 1;
5368
+ var REPORT_DIR_REL = join10(".vhk", "reports");
5369
+ var REPORT_PATH_REL = join10(REPORT_DIR_REL, "latest.json");
5370
+ var SHIM = /* @__PURE__ */ new Set(["pnpm", "npm", "npx", "yarn"]);
5371
+ function detectPm(cwd) {
5372
+ if (existsSync16(join10(cwd, "pnpm-lock.yaml"))) return "pnpm";
5373
+ if (existsSync16(join10(cwd, "yarn.lock"))) return "yarn";
5374
+ return "npm";
5375
+ }
5376
+ function execGate(cmd, args, cwd) {
5377
+ let bin = cmd;
5378
+ let argv = args;
5379
+ if (process.platform === "win32" && SHIM.has(cmd)) {
5380
+ bin = "cmd.exe";
5381
+ argv = ["/d", "/s", "/c", `${cmd}.cmd`, ...args];
5382
+ }
5383
+ try {
5384
+ execFileSync4(bin, argv, {
5385
+ cwd,
5386
+ stdio: ["pipe", "pipe", "pipe"],
5387
+ encoding: "utf-8",
5388
+ maxBuffer: 64 * 1024 * 1024,
5389
+ timeout: 6e5,
5390
+ killSignal: "SIGTERM"
5391
+ });
5392
+ return { exitCode: 0, out: "" };
5393
+ } catch (e) {
5394
+ const err = e;
5395
+ const exitCode = typeof err.status === "number" ? err.status : 1;
5396
+ const out = ((err.stdout?.toString?.() ?? "") + (err.stderr?.toString?.() ?? "")).trim();
5397
+ return { exitCode, out };
5398
+ }
5399
+ }
5400
+ function runScriptGate(id, label, cwd, pm, argvFor) {
5401
+ const argv = argvFor(pm);
5402
+ if (!argv) {
5403
+ return { id, label, status: "skip", exitCode: null, skipped: true, detail: "\uD574\uB2F9 \uC2A4\uD06C\uB9BD\uD2B8/\uC124\uC815 \uC5C6\uC74C \u2014 skip(WARN)" };
5404
+ }
5405
+ const { exitCode } = execGate(pm, argv, cwd);
5406
+ return {
5407
+ id,
5408
+ label,
5409
+ status: exitCode === 0 ? "pass" : "fail",
5410
+ exitCode,
5411
+ skipped: false,
5412
+ detail: exitCode === 0 ? void 0 : `\uC885\uB8CC\uCF54\uB4DC ${exitCode}`
5413
+ };
5414
+ }
5415
+ function readPackageScripts(cwd) {
5416
+ const pkgPath = join10(cwd, "package.json");
5417
+ if (!existsSync16(pkgPath)) return {};
5418
+ try {
5419
+ const pkg = readJsonFile(pkgPath);
5420
+ return pkg.scripts ?? {};
5421
+ } catch {
5422
+ return {};
5423
+ }
5424
+ }
5425
+ function runGates(cwd) {
5426
+ const scripts = readPackageScripts(cwd);
5427
+ const pm = detectPm(cwd);
5428
+ const gates = [];
5429
+ gates.push(
5430
+ runScriptGate("typecheck", "tsc --noEmit", cwd, pm, () => {
5431
+ if (scripts.typecheck) return ["run", "typecheck"];
5432
+ if (existsSync16(join10(cwd, "tsconfig.json"))) return pm === "npm" ? ["exec", "--", "tsc", "--noEmit"] : ["exec", "tsc", "--noEmit"];
5433
+ return null;
5434
+ })
5435
+ );
5436
+ gates.push(
5437
+ runScriptGate("test", "test:run", cwd, pm, () => {
5438
+ if (scripts["test:run"]) return ["run", "test:run"];
5439
+ if (scripts.test && /vitest/.test(scripts.test)) return ["run", "test", "--", "--run"];
5440
+ if (scripts.test) return ["run", "test"];
5441
+ return null;
5442
+ })
5443
+ );
5444
+ gates.push(
5445
+ runScriptGate("build", "build", cwd, pm, () => scripts.build ? ["run", "build"] : null)
5446
+ );
5447
+ gates.push(runSecureGate(cwd));
5448
+ return gates;
5449
+ }
5450
+ function runSecureGate(cwd) {
5451
+ try {
5452
+ const severe = filterSevereFindings(scanProjectForSecrets(cwd).findings);
5453
+ const n = severe.length;
5454
+ return {
5455
+ id: "secure",
5456
+ label: "secure scan",
5457
+ status: n === 0 ? "pass" : "fail",
5458
+ exitCode: n === 0 ? 0 : 1,
5459
+ skipped: false,
5460
+ detail: n === 0 ? void 0 : `severe \uC2DC\uD06C\uB9BF ${n}\uAC74 (\uAC12 \uBBF8\uAE30\uB85D \u2014 vhk secure scan \uC73C\uB85C \uD655\uC778)`
5461
+ };
5462
+ } catch (e) {
5463
+ return {
5464
+ id: "secure",
5465
+ label: "secure scan",
5466
+ status: "fail",
5467
+ exitCode: 1,
5468
+ skipped: false,
5469
+ detail: `\uC2A4\uCE94 \uC2E4\uD589 \uC2E4\uD328: ${e instanceof Error ? e.message : String(e)}`
5470
+ };
5471
+ }
5472
+ }
5473
+ function aggregateStatus(gates) {
5474
+ if (gates.some((g) => g.status === "fail")) return "FAIL";
5475
+ if (gates.some((g) => g.status === "skip")) return "WARN";
5476
+ return "PASS";
5477
+ }
5478
+ function buildNextActions(gates) {
5479
+ const actions = [];
5480
+ for (const g of gates) {
5481
+ if (g.status === "fail") {
5482
+ if (g.id === "secure") actions.push("\uC2DC\uD06C\uB9BF \uC81C\uAC70 \uD6C4 \uC7AC\uAC80\uC99D \u2014 vhk secure scan \uC73C\uB85C \uC704\uCE58 \uD655\uC778");
5483
+ else actions.push(`${g.label} \uC2E4\uD328(\uC885\uB8CC\uCF54\uB4DC ${g.exitCode}) \u2014 \uB85C\uADF8 \uD655\uC778 \uD6C4 \uC218\uC815`);
5484
+ } else if (g.status === "skip") {
5485
+ actions.push(`${g.label} \uAC8C\uC774\uD2B8 \uC5C6\uC74C \u2014 package.json scripts \uC5D0 \uCD94\uAC00\uD558\uBA74 \uAC80\uC99D \uCEE4\uBC84\uB9AC\uC9C0 \u2191`);
5486
+ }
5487
+ }
5488
+ if (actions.length === 0) actions.push("\uAC80\uC99D \uD1B5\uACFC \u2014 vhk save \uB85C \uC800\uC7A5\uD558\uC138\uC694.");
5489
+ return actions;
5490
+ }
5491
+ function buildReport(gates, generatedAt, date) {
5492
+ const summary = {
5493
+ total: gates.length,
5494
+ pass: gates.filter((g) => g.status === "pass").length,
5495
+ fail: gates.filter((g) => g.status === "fail").length,
5496
+ skip: gates.filter((g) => g.status === "skip").length
5497
+ };
5498
+ return {
5499
+ schemaVersion: REPORT_SCHEMA_VERSION,
5500
+ generatedAt,
5501
+ date,
5502
+ status: aggregateStatus(gates),
5503
+ summary,
5504
+ gates,
5505
+ nextActions: buildNextActions(gates)
5506
+ };
5387
5507
  }
5388
- async function verify() {
5389
- console.log(chalk31.bold("\n\u{1F50E} \uAC80\uC99D \uBB36\uC74C (verify \u2014 lite)"));
5390
- console.log(chalk31.gray("\u2500".repeat(40)));
5508
+ function verifyEvidence(cwd = process.cwd()) {
5509
+ const gates = runGates(cwd);
5510
+ const report = buildReport(gates, (/* @__PURE__ */ new Date()).toISOString(), localDate());
5511
+ const dir = join10(cwd, REPORT_DIR_REL);
5512
+ mkdirSync11(dir, { recursive: true });
5513
+ const path14 = join10(cwd, REPORT_PATH_REL);
5514
+ writeFileSync11(path14, JSON.stringify(report, null, 2) + "\n", "utf-8");
5515
+ try {
5516
+ ensureVhkIgnored(cwd, "reports/");
5517
+ } catch {
5518
+ }
5519
+ return { report, path: REPORT_PATH_REL };
5520
+ }
5521
+ var STATUS_BADGE = {
5522
+ PASS: chalk30.green.bold("PASS"),
5523
+ WARN: chalk30.yellow.bold("WARN"),
5524
+ FAIL: chalk30.red.bold("FAIL")
5525
+ };
5526
+ async function verify(opts = {}) {
5527
+ if (!ensureNotHardStopped("verify")) return;
5528
+ const cwd = process.cwd();
5529
+ const { report, path: path14 } = verifyEvidence(cwd);
5530
+ if (opts.json) {
5531
+ console.log(JSON.stringify(report, null, 2));
5532
+ process.exitCode = report.status === "FAIL" ? 1 : 0;
5533
+ return;
5534
+ }
5535
+ console.log(chalk30.bold("\n\u{1F50E} \uAC80\uC99D \uBB36\uC74C (verify)"));
5536
+ console.log(chalk30.gray("\u2500".repeat(40)));
5391
5537
  const mode2 = readConfig().safetyMode;
5392
- console.log(chalk31.dim(` \uD604\uC7AC Safety Mode: ${mode2} \u2014 ${SAFETY_MODE_DESC[mode2]}`));
5393
- console.log(chalk31.cyan("\n \uC704\uD5D8 \uC791\uC5C5/\uC800\uC7A5 \uC804 \uAD8C\uC7A5 \uAC80\uC99D:"));
5394
- for (const item of verificationChecklist()) {
5395
- console.log(` \u2610 ${item}`);
5538
+ console.log(chalk30.dim(` \uD604\uC7AC Safety Mode: ${mode2} \u2014 ${SAFETY_MODE_DESC[mode2]}`));
5539
+ const icon = (s2) => s2 === "pass" ? chalk30.green("\u2713") : s2 === "fail" ? chalk30.red("\u2717") : chalk30.yellow("\u2298");
5540
+ for (const g of report.gates) {
5541
+ const tail = g.detail ? chalk30.dim(` \u2014 ${g.detail}`) : "";
5542
+ console.log(` ${icon(g.status)} ${g.label}${tail}`);
5543
+ }
5544
+ const s = report.summary;
5545
+ console.log(
5546
+ `
5547
+ \uACB0\uACFC: ${STATUS_BADGE[report.status]} ` + chalk30.dim(`(pass ${s.pass} / fail ${s.fail} / skip ${s.skip}, \uCD1D ${s.total})`)
5548
+ );
5549
+ console.log(chalk30.dim(` \u{1F4C4} \uC99D\uAC70: ${path14}`));
5550
+ process.exitCode = report.status === "FAIL" ? 1 : 0;
5551
+ if (report.status === "FAIL") {
5552
+ printNextStep({
5553
+ message: "\uAC80\uC99D \uC2E4\uD328 \u2014 \uC544\uB798\uB97C \uBA3C\uC800 \uACE0\uCE58\uC138\uC694:",
5554
+ command: "vhk verify",
5555
+ cursorHint: "\uAC80\uC99D \uB2E4\uC2DC \uB3CC\uB824\uC918",
5556
+ alternative: report.nextActions[0]
5557
+ });
5558
+ } else {
5559
+ printNextStep({
5560
+ message: report.status === "WARN" ? "\uAC80\uC99D \uD1B5\uACFC(\uC77C\uBD80 \uAC8C\uC774\uD2B8 skip). \uC800\uC7A5\uD558\uB824\uBA74:" : "\uAC80\uC99D \uD1B5\uACFC! \uC800\uC7A5\uD558\uB824\uBA74:",
5561
+ command: "vhk save",
5562
+ cursorHint: "\uC800\uC7A5\uD574\uC918"
5563
+ });
5396
5564
  }
5397
- console.log(chalk31.dim("\n \u203B \uBA54\uD0C0\uB7EC\uB108(\uC790\uB3D9 \uC2E4\uD589) \uC790\uB9AC \u2014 \uD604\uC7AC\uB294 \uBB36\uC74C \uC548\uB0B4\uB9CC(lite)."));
5398
- printNextStep({
5399
- message: "\uAC80\uC99D \uD1B5\uACFC \uD6C4 \uC800\uC7A5\uD558\uC138\uC694:",
5400
- command: "vhk save",
5401
- cursorHint: "\uC800\uC7A5\uD574\uC918"
5402
- });
5403
5565
  }
5404
5566
 
5405
5567
  // src/lib/risk-policy.ts
@@ -5580,14 +5742,14 @@ function requiresConfirmation(route) {
5580
5742
  async function runNaturalLanguageRoute(input) {
5581
5743
  const route = routeNaturalLanguage(input);
5582
5744
  if (!route) {
5583
- console.log(chalk32.yellow(`
5745
+ console.log(chalk31.yellow(`
5584
5746
  \u2753 "${input}" \u2014 ${ko.nlp.notMatched}
5585
5747
  `));
5586
5748
  return;
5587
5749
  }
5588
5750
  console.log("");
5589
- console.log(chalk32.cyan(` \u{1F4AC} "${input}"`));
5590
- console.log(chalk32.cyan(` \u2192 ${route.explanation}`));
5751
+ console.log(chalk31.cyan(` \u{1F4AC} "${input}"`));
5752
+ console.log(chalk31.cyan(` \u2192 ${route.explanation}`));
5591
5753
  if (requiresConfirmation(route)) {
5592
5754
  const { confirm } = await inquirer12.prompt([{
5593
5755
  type: "confirm",
@@ -5596,7 +5758,7 @@ async function runNaturalLanguageRoute(input) {
5596
5758
  default: true
5597
5759
  }]);
5598
5760
  if (!confirm) {
5599
- console.log(chalk32.dim(` ${ko.nlp.menuHint}`));
5761
+ console.log(chalk31.dim(` ${ko.nlp.menuHint}`));
5600
5762
  return;
5601
5763
  }
5602
5764
  }
@@ -5605,7 +5767,7 @@ async function runNaturalLanguageRoute(input) {
5605
5767
  if (riskAction) {
5606
5768
  await runGuarded(
5607
5769
  riskAction,
5608
- { channel: "nl", approved: false, log: (m) => console.log(chalk32.yellow(` ${m}`)) },
5770
+ { channel: "nl", approved: false, log: (m) => console.log(chalk31.yellow(` ${m}`)) },
5609
5771
  () => dispatchNlpRoute(route, input)
5610
5772
  );
5611
5773
  return;
@@ -5614,77 +5776,77 @@ async function runNaturalLanguageRoute(input) {
5614
5776
  }
5615
5777
 
5616
5778
  // src/commands/agent.ts
5617
- import chalk33 from "chalk";
5779
+ import chalk32 from "chalk";
5618
5780
  function activeGoalId() {
5619
5781
  const goals = listGoals("goals");
5620
5782
  const id = selectActiveId(goals);
5621
5783
  return id ?? void 0;
5622
5784
  }
5623
5785
  async function blocker(description) {
5624
- console.log(chalk33.bold(`
5786
+ console.log(chalk32.bold(`
5625
5787
  ${ko.agent.blockerTitle}
5626
5788
  `));
5627
5789
  if (!description || !description.trim()) {
5628
- console.log(chalk33.red(" \u274C \uBE14\uB85C\uCEE4 \uC124\uBA85\uC744 \uC785\uB825\uD574 \uC8FC\uC138\uC694."));
5629
- console.log(chalk33.dim(' \uC608: vhk blocker "tsc \uC5D0\uB7EC \u2014 simple-git \uD0C0\uC785 \uD638\uD658"'));
5790
+ console.log(chalk32.red(" \u274C \uBE14\uB85C\uCEE4 \uC124\uBA85\uC744 \uC785\uB825\uD574 \uC8FC\uC138\uC694."));
5791
+ console.log(chalk32.dim(' \uC608: vhk blocker "tsc \uC5D0\uB7EC \u2014 simple-git \uD0C0\uC785 \uD638\uD658"'));
5630
5792
  process.exitCode = 1;
5631
5793
  return;
5632
5794
  }
5633
5795
  const goalId = activeGoalId();
5634
5796
  const r = appendBlocker(description, goalId);
5635
- console.log(chalk33.green(` \u2705 blocker \uAE30\uB85D (\uD604\uC7AC \uD65C\uC131 ${r.count}\uAC74)`));
5797
+ console.log(chalk32.green(` \u2705 blocker \uAE30\uB85D (\uD604\uC7AC \uD65C\uC131 ${r.count}\uAC74)`));
5636
5798
  if (r.hardStopTripped) {
5637
- console.log(chalk33.red.bold(" \u{1F6D1} HARD_STOP \uC790\uB3D9 \uC0DD\uC131 \u2014 \uBAA8\uB4E0 \uC790\uB3D9\uD654 \uC911\uB2E8."));
5638
- console.log(chalk33.yellow(" \uC0AC\uB78C \uAC80\uD1A0 \uD6C4 `vhk resume --confirm` \uC73C\uB85C\uB9CC \uD574\uC81C."));
5799
+ console.log(chalk32.red.bold(" \u{1F6D1} HARD_STOP \uC790\uB3D9 \uC0DD\uC131 \u2014 \uBAA8\uB4E0 \uC790\uB3D9\uD654 \uC911\uB2E8."));
5800
+ console.log(chalk32.yellow(" \uC0AC\uB78C \uAC80\uD1A0 \uD6C4 `vhk resume --confirm` \uC73C\uB85C\uB9CC \uD574\uC81C."));
5639
5801
  process.exitCode = 2;
5640
5802
  }
5641
5803
  }
5642
5804
  async function learn(lesson) {
5643
- console.log(chalk33.bold(`
5805
+ console.log(chalk32.bold(`
5644
5806
  ${ko.agent.learnTitle}
5645
5807
  `));
5646
5808
  if (!lesson || !lesson.trim()) {
5647
- console.log(chalk33.red(" \u274C \uAD50\uD6C8 \uB0B4\uC6A9\uC744 \uC785\uB825\uD574 \uC8FC\uC138\uC694."));
5648
- console.log(chalk33.dim(' \uC608: vhk learn "PowerShell \uC5D0\uC11C\uB294 ; \uC0AC\uC6A9 (&& \uBBF8\uC9C0\uC6D0)"'));
5809
+ console.log(chalk32.red(" \u274C \uAD50\uD6C8 \uB0B4\uC6A9\uC744 \uC785\uB825\uD574 \uC8FC\uC138\uC694."));
5810
+ console.log(chalk32.dim(' \uC608: vhk learn "PowerShell \uC5D0\uC11C\uB294 ; \uC0AC\uC6A9 (&& \uBBF8\uC9C0\uC6D0)"'));
5649
5811
  process.exitCode = 1;
5650
5812
  return;
5651
5813
  }
5652
5814
  const goalId = activeGoalId();
5653
5815
  appendLearning(lesson, goalId);
5654
- console.log(chalk33.green(" \u2705 learnings.md append."));
5816
+ console.log(chalk32.green(" \u2705 learnings.md append."));
5655
5817
  console.log(
5656
- chalk33.dim(" \uACB0\uC815\uC0AC\uD56D(decision)\uC740 `vhk memory add` \uB85C \uBCC4\uB3C4 \uAE30\uB85D \u2014 SoT \uBD84\uB9AC.")
5818
+ chalk32.dim(" \uACB0\uC815\uC0AC\uD56D(decision)\uC740 `vhk memory add` \uB85C \uBCC4\uB3C4 \uAE30\uB85D \u2014 SoT \uBD84\uB9AC.")
5657
5819
  );
5658
5820
  }
5659
5821
  async function resume(opts = {}) {
5660
- console.log(chalk33.bold(`
5822
+ console.log(chalk32.bold(`
5661
5823
  ${ko.agent.resumeTitle}
5662
5824
  `));
5663
5825
  if (!isHardStopActive()) {
5664
- console.log(chalk33.dim(" HARD_STOP \uD65C\uC131 \uC544\uB2D8 \u2014 \uD560 \uC77C \uC5C6\uC74C."));
5826
+ console.log(chalk32.dim(" HARD_STOP \uD65C\uC131 \uC544\uB2D8 \u2014 \uD560 \uC77C \uC5C6\uC74C."));
5665
5827
  return;
5666
5828
  }
5667
5829
  const reason = readHardStopReason();
5668
5830
  if (reason) {
5669
- console.log(chalk33.yellow(" \u{1F4CB} HARD_STOP \uC0AC\uC720:"));
5670
- console.log(chalk33.dim(` ${reason.split("\n").join("\n ")}`));
5831
+ console.log(chalk32.yellow(" \u{1F4CB} HARD_STOP \uC0AC\uC720:"));
5832
+ console.log(chalk32.dim(` ${reason.split("\n").join("\n ")}`));
5671
5833
  console.log("");
5672
5834
  }
5673
5835
  if (!opts.confirm) {
5674
5836
  console.log(
5675
- chalk33.red(
5837
+ chalk32.red(
5676
5838
  " \u274C --confirm \uD50C\uB798\uADF8 \uC5C6\uC774\uB294 \uD574\uC81C\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4 (\uC790\uB3D9 \uD638\uCD9C \uAE08\uC9C0)."
5677
5839
  )
5678
5840
  );
5679
- console.log(chalk33.yellow(" \uC0AC\uC720\uB97C \uD655\uC778\uD55C \uD6C4 \uB2E4\uC2DC: vhk resume --confirm"));
5841
+ console.log(chalk32.yellow(" \uC0AC\uC720\uB97C \uD655\uC778\uD55C \uD6C4 \uB2E4\uC2DC: vhk resume --confirm"));
5680
5842
  process.exitCode = 1;
5681
5843
  return;
5682
5844
  }
5683
5845
  const removed = clearHardStop();
5684
5846
  if (removed) {
5685
- console.log(chalk33.green(" \u2705 HARD_STOP \uD574\uC81C. \uC790\uB3D9\uD654 \uC7AC\uAC1C \uAC00\uB2A5."));
5847
+ console.log(chalk32.green(" \u2705 HARD_STOP \uD574\uC81C. \uC790\uB3D9\uD654 \uC7AC\uAC1C \uAC00\uB2A5."));
5686
5848
  } else {
5687
- console.log(chalk33.dim(" \uD30C\uC77C\uC774 \uC774\uBBF8 \uC5C6\uC74C \u2014 no-op."));
5849
+ console.log(chalk32.dim(" \uD30C\uC77C\uC774 \uC774\uBBF8 \uC5C6\uC74C \u2014 no-op."));
5688
5850
  }
5689
5851
  }
5690
5852
 
@@ -5705,7 +5867,7 @@ async function guardCli(action, approved, run) {
5705
5867
  }]);
5706
5868
  return ok;
5707
5869
  },
5708
- log: (m) => console.log(chalk34.yellow(` ${m}`))
5870
+ log: (m) => console.log(chalk33.yellow(` ${m}`))
5709
5871
  },
5710
5872
  run
5711
5873
  );
@@ -5718,7 +5880,7 @@ async function guardCliDefer(action, approved, run) {
5718
5880
  approved,
5719
5881
  // TTY 면 통과(명령이 자체 확인), 비대화형은 confirm 불가 → 가드가 차단.
5720
5882
  confirm: async () => !!process.stdout.isTTY,
5721
- log: (m) => console.log(chalk34.yellow(` ${m}`))
5883
+ log: (m) => console.log(chalk33.yellow(` ${m}`))
5722
5884
  },
5723
5885
  run
5724
5886
  );
@@ -5845,8 +6007,8 @@ program.command("design").alias("\uB514\uC790\uC778").description("\uB514\uC790\
5845
6007
  program.command("design-palette").alias("\uD314\uB808\uD2B8").description("\uCEEC\uB7EC \uD314\uB808\uD2B8 \uD504\uB9AC\uC14B \uC120\uD0DD + \uC801\uC6A9").action(async () => {
5846
6008
  await designPalette();
5847
6009
  });
5848
- program.command("theme").alias("\uD14C\uB9C8").description("\uB2E4\uD06C/\uB77C\uC774\uD2B8 \uBAA8\uB4DC CSS + \uD1A0\uAE00 \uC720\uD2F8\uB9AC\uD2F0 \uC0DD\uC131").action(async () => {
5849
- await theme();
6010
+ program.command("theme").alias("\uD14C\uB9C8").option("-y, --yes", "\uAE30\uC874 \uD30C\uC77C \uB36E\uC5B4\uC4F0\uAE30 \uD655\uC778 \uC2A4\uD0B5 (\uBE44\uB300\uD654\uD615 \uC790\uB3D9 \uB36E\uC5B4\uC4F0\uAE30)").description("\uB2E4\uD06C/\uB77C\uC774\uD2B8 \uBAA8\uB4DC CSS + \uD1A0\uAE00 \uC720\uD2F8\uB9AC\uD2F0 \uC0DD\uC131").action(async (opts) => {
6011
+ await theme(opts);
5850
6012
  });
5851
6013
  var refCmd = program.command("ref").alias("\uB808\uD37C\uB7F0\uC2A4").description("\uB808\uD37C\uB7F0\uC2A4 URL \uAD00\uB9AC (add / list / open)").action(async () => {
5852
6014
  await refList();
@@ -5878,8 +6040,8 @@ program.command("context").alias("\uB9E5\uB77D").option("--compact", "\uD1A0\uD0
5878
6040
  program.command("mode [target]").alias("\uBAA8\uB4DC").description("Safety Mode \uC870\uD68C/\uBCC0\uACBD (lite|standard|strict) \u2014 \uC704\uD5D8 \uC791\uC5C5 \uAC00\uB4DC \uAC15\uB3C4").action(async (target) => {
5879
6041
  await mode(target);
5880
6042
  });
5881
- program.command("verify").alias("\uC0AC\uC804\uC810\uAC80").description("\uC800\uC7A5/\uC704\uD5D8 \uC791\uC5C5 \uC804 \uAC80\uC99D \uBB36\uC74C \uC548\uB0B4 (lite)").action(async () => {
5882
- await verify();
6043
+ program.command("verify").alias("\uC0AC\uC804\uC810\uAC80").option("--json", "\uB9AC\uD3EC\uD2B8 JSON \uC744 stdout \uC73C\uB85C \uCD9C\uB825 (CI\uC6A9 \u2014 \uACBD\uB85C \uB300\uC2E0)").description("\uAC80\uC99D \uAC8C\uC774\uD2B8(tsc/test/build/secure) \uC2E4\uC81C \uC2E4\uD589 + \uC99D\uAC70 \uAE30\uB85D (.vhk/reports/latest.json)").action(async (opts) => {
6044
+ await verify(opts);
5883
6045
  });
5884
6046
  program.command("context-show").alias("\uB9E5\uB77D\uBCF4\uAE30").description("\uD604\uC7AC \uCEE8\uD14D\uC2A4\uD2B8 \uD30C\uC77C \uB0B4\uC6A9 \uCD9C\uB825").action(async () => {
5885
6047
  await contextShow();
@@ -5995,9 +6157,9 @@ if (isMainModule) {
5995
6157
  }
5996
6158
  } catch (err) {
5997
6159
  if (isPromptAbortError(err)) {
5998
- console.error(chalk34.yellow("\n \u26A0\uFE0F \uB300\uD654\uD615 \uC785\uB825\uC774 \uCDE8\uC18C/\uC885\uB8CC\uB410\uC2B5\uB2C8\uB2E4. (\uBE44\uB300\uD654\uD615 \uD658\uACBD\uC5D0\uC11C\uB294 \uD574\uB2F9 \uBA85\uB839\uC744 \uC4F8 \uC218 \uC5C6\uC5B4\uC694)"));
6160
+ console.error(chalk33.yellow("\n \u26A0\uFE0F \uB300\uD654\uD615 \uC785\uB825\uC774 \uCDE8\uC18C/\uC885\uB8CC\uB410\uC2B5\uB2C8\uB2E4. (\uBE44\uB300\uD654\uD615 \uD658\uACBD\uC5D0\uC11C\uB294 \uD574\uB2F9 \uBA85\uB839\uC744 \uC4F8 \uC218 \uC5C6\uC5B4\uC694)"));
5999
6161
  } else {
6000
- console.error(chalk34.red(`
6162
+ console.error(chalk33.red(`
6001
6163
  \u274C ${err instanceof Error ? err.message : String(err)}`));
6002
6164
  }
6003
6165
  process.exitCode = 1;