@byh3071/vhk 0.7.0 → 0.7.1

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
@@ -2,10 +2,15 @@
2
2
  import {
3
3
  __commonJS,
4
4
  __toESM,
5
+ env,
6
+ envCheck,
7
+ ko,
8
+ printNextStep,
5
9
  safeExecFile,
6
10
  safeExecFileStream,
7
- startMcpServer
8
- } from "./chunk-NJDRNI3S.js";
11
+ startMcpServer,
12
+ t
13
+ } from "./chunk-3HHU7V77.js";
9
14
 
10
15
  // node_modules/.pnpm/ignore@7.0.5/node_modules/ignore/index.js
11
16
  var require_ignore = __commonJS({
@@ -692,330 +697,12 @@ function detectNaturalLanguageInput(argv) {
692
697
  }
693
698
 
694
699
  // src/lib/nlp-run.ts
695
- import chalk20 from "chalk";
700
+ import chalk18 from "chalk";
696
701
  import inquirer9 from "inquirer";
697
702
 
698
- // src/i18n/ko.ts
699
- var ko = {
700
- status: {
701
- title: "\uD504\uB85C\uC81D\uD2B8 \uC0C1\uD0DC",
702
- notGitRepo: "Git \uC800\uC7A5\uC18C\uAC00 \uC544\uB2C8\uC5D0\uC694. \uBA3C\uC800 git init\uC744 \uC2E4\uD589\uD558\uC138\uC694.",
703
- branch: "\uBE0C\uB79C\uCE58:",
704
- changes: "\uBCC0\uACBD:",
705
- recentCommits: "\uCD5C\uADFC \uCEE4\uBC0B (3):",
706
- noCommits: "\uCEE4\uBC0B \uC5C6\uC74C",
707
- remote: "\uC6D0\uACA9:",
708
- noUpstream: "upstream \uC5C6\uC74C",
709
- inSync: "\uB3D9\uAE30\uD654\uB428",
710
- ahead: (n) => `\u2191${n} ahead`,
711
- behind: (n) => `\u2193${n} behind`,
712
- package: "package.json:",
713
- noPackage: "package.json \uC5C6\uC74C",
714
- detached: "(detached HEAD)",
715
- unknownBranch: "(\uC54C \uC218 \uC5C6\uC74C)"
716
- },
717
- save: {
718
- title: "\uC800\uC7A5\uD558\uAE30",
719
- notGitRepo: "git \uC800\uC7A5\uC18C\uAC00 \uC544\uB2D9\uB2C8\uB2E4. \uBA3C\uC800 git init\uC744 \uC2E4\uD589\uD558\uC138\uC694.",
720
- noChanges: "\uC800\uC7A5\uD560 \uBCC0\uACBD\uC0AC\uD56D\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.",
721
- filesHeader: (n) => `\uBCC0\uACBD\uB41C \uD30C\uC77C (${n}\uAC1C):`,
722
- commitMessage: "\uCEE4\uBC0B \uBA54\uC2DC\uC9C0 (Enter\uB85C \uAE30\uBCF8\uAC12 \uC0AC\uC6A9):",
723
- saving: "\uC800\uC7A5 \uC911...",
724
- pushing: "\uC6D0\uACA9 \uC800\uC7A5\uC18C\uC5D0 \uC62C\uB9AC\uB294 \uC911...",
725
- successWithPush: "\uC800\uC7A5 + \uC6D0\uACA9 \uC5C5\uB85C\uB4DC \uC644\uB8CC!",
726
- successLocal: "\uB85C\uCEEC \uC800\uC7A5 \uC644\uB8CC!",
727
- noRemote: "\uC6D0\uACA9 \uC800\uC7A5\uC18C\uAC00 \uC124\uC815\uB418\uC9C0 \uC54A\uC544 push\uB97C \uAC74\uB108\uB6F0\uC5C8\uC2B5\uB2C8\uB2E4.",
728
- failed: "\uC800\uC7A5 \uC2E4\uD328",
729
- stagedAfterFail: "\uCEE4\uBC0B\uC740 \uC2E4\uD328\uD588\uC9C0\uB9CC \uD30C\uC77C\uC740 \uC2A4\uD14C\uC774\uC9D5\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4. \uD655\uC778: git status / \uCDE8\uC18C: git reset HEAD",
730
- securityWarnHeader: "\uC800\uC7A5 \uC804 \uBCF4\uC548 \uD655\uC778:",
731
- secretsFound: (n) => `\uCF54\uB4DC\uC5D0\uC11C CRITICAL/HIGH \uC2DC\uD06C\uB9BF \uD328\uD134 ${n}\uAC74 \uAC10\uC9C0`,
732
- secretsConfirm: "\uADF8\uB798\uB3C4 \uCEE4\uBC0B\xB7push\uB97C \uC9C4\uD589\uD560\uAE4C\uC694?",
733
- cancelled: "\uC800\uC7A5\uC744 \uCDE8\uC18C\uD588\uC2B5\uB2C8\uB2E4.",
734
- pushFailed: "push \uC2E4\uD328 (\uB85C\uCEEC \uCEE4\uBC0B\uC740 \uC644\uB8CC\uB428)",
735
- commitOkPushFailed: "\uB85C\uCEEC \uCEE4\uBC0B\uC740 \uB410\uC9C0\uB9CC \uC6D0\uACA9 push\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4. git push\uB97C \uC9C1\uC811 \uD655\uC778\uD558\uC138\uC694.",
736
- done: (n) => `${n}\uAC1C \uD30C\uC77C \uC800\uC7A5 \uC644\uB8CC!`,
737
- doneLocalOnly: (n) => `${n}\uAC1C \uD30C\uC77C \uB85C\uCEEC \uC800\uC7A5\uB428 (push\uB294 \uC2E4\uD328)`
738
- },
739
- undo: {
740
- title: "\uB418\uB3CC\uB9AC\uAE30",
741
- notGitRepo: "git \uC800\uC7A5\uC18C\uAC00 \uC544\uB2D9\uB2C8\uB2E4.",
742
- noCommits: "\uB418\uB3CC\uB9B4 \uCEE4\uBC0B\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.",
743
- recentHeader: "\u{1F4CB} \uCD5C\uADFC \uCEE4\uBC0B:",
744
- howMany: "\uBA87 \uAC1C\uC758 \uCEE4\uBC0B\uC744 \uB418\uB3CC\uB9B4\uAE4C\uC694?",
745
- alreadyPushed: "\uC774 \uCEE4\uBC0B\uC740 \uC774\uBBF8 \uC6D0\uACA9\uC5D0 \uC62C\uB77C\uAC14\uC2B5\uB2C8\uB2E4. \uB418\uB3CC\uB9AC\uBA74 \uCDA9\uB3CC\uC774 \uC0DD\uAE38 \uC218 \uC788\uC5B4\uC694.",
746
- noUpstreamWarning: "upstream \uBE0C\uB79C\uCE58\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. \uC774\uBBF8 push\uD55C \uCEE4\uBC0B\uC77C \uC218 \uC788\uC5B4\uC694. \uB418\uB3CC\uB9B0 \uB4A4 force push\uAC00 \uD544\uC694\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.",
747
- confirmMessage: "\uCD5C\uADFC \uCEE4\uBC0B\uC744 \uB418\uB3CC\uB9AC\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?",
748
- confirmRisky: (n) => `\u26A0\uFE0F \uC704\uD5D8: \uCD5C\uADFC ${n}\uAC1C \uCEE4\uBC0B\uC744 soft reset\uD569\uB2C8\uB2E4. \uC6D0\uACA9\uACFC \uC5B4\uAE0B\uB0A0 \uC218 \uC788\uC2B5\uB2C8\uB2E4. \uACC4\uC18D\uD560\uAE4C\uC694?`,
749
- cancelled: "\uCDE8\uC18C\uB428",
750
- success: "\uB418\uB3CC\uB9AC\uAE30 \uC644\uB8CC! \uBCC0\uACBD\uC0AC\uD56D\uC740 \uADF8\uB300\uB85C \uB0A8\uC544\uC788\uC2B5\uB2C8\uB2E4.",
751
- stagedHint: "\uBCC0\uACBD\uC0AC\uD56D\uC740 \uC2A4\uD14C\uC774\uC9D5 \uC601\uC5ED\uC5D0 \uB0A8\uC544 \uC788\uC5B4\uC694.",
752
- rootCommit: "\uCCAB \uCEE4\uBC0B\uB9CC \uC788\uC5B4\uC11C \uB354 \uB418\uB3CC\uB9B4 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.",
753
- forcePushHint: "\uC6D0\uACA9\uACFC \uB9DE\uCD94\uB824\uBA74: git push --force-with-lease (\uD63C\uC790 \uC791\uC5C5\uD55C \uBE0C\uB79C\uCE58\uC5D0\uC11C\uB9CC, \uD300\uACFC \uD569\uC758 \uD6C4)",
754
- failed: "\uB418\uB3CC\uB9AC\uAE30 \uC2E4\uD328"
755
- },
756
- diff: {
757
- title: "\uBCC0\uACBD\uC0AC\uD56D \uD655\uC778",
758
- notGitRepo: "git \uC800\uC7A5\uC18C\uAC00 \uC544\uB2D9\uB2C8\uB2E4.",
759
- noChanges: "\uBCC0\uACBD\uC0AC\uD56D \uC5C6\uC74C! \uAE68\uB057\uD569\uB2C8\uB2E4.",
760
- stagedHeader: "\u{1F4E6} \uCEE4\uBC0B \uB300\uAE30 (staged):",
761
- unstagedHeader: "\u270F\uFE0F \uC218\uC815\uB428 (unstaged):",
762
- untrackedHeader: (n) => `\u2795 \uC0C8 \uD30C\uC77C (${n}\uAC1C):`,
763
- summaryHeader: "\u{1F4CA} \uCD1D \uBCC0\uACBD \uC694\uC57D (\uC791\uC5C5 \uD2B8\uB9AC vs HEAD)",
764
- filesLine: (n) => `\uD30C\uC77C: ${n}\uAC1C`
765
- },
766
- start: {
767
- title: "\u{1F527} VHK \u2014 \uBB34\uC5C7\uC744 \uB3C4\uC640\uB4DC\uB9B4\uAE4C\uC694?",
768
- subtitle: "\uBC88\uD638\uB9CC \uACE0\uB974\uBA74 \uB429\uB2C8\uB2E4. \uBA85\uB839\uC5B4\uB97C \uC678\uC6B8 \uD544\uC694 \uC5C6\uC5B4\uC694.",
769
- menuPrompt: "\uC5B4\uB5A4 \uC791\uC5C5\uC744 \uD560\uAE4C\uC694?",
770
- choiceGate: "1) \uC0C8 \uC544\uC774\uB514\uC5B4 \uAC80\uC99D\uD558\uAE30",
771
- choiceInit: "2) \uD504\uB85C\uC81D\uD2B8 \uC2DC\uC791\uD558\uAE30 \u2014 \uD3F4\uB354\xB7\uD30C\uC77C \uB9CC\uB4E4\uAE30",
772
- choiceInitSkipGate: "3) \uAE30\uD68D\uC740 \uB05D\uB0AC\uC5B4\uC694 \u2014 \uBC14\uB85C \uD504\uB85C\uC81D\uD2B8 \uB9CC\uB4E4\uAE30",
773
- choiceRecap: "4) \uC624\uB298 \uD55C \uC77C \uC815\uB9AC\uD558\uAE30",
774
- choiceSync: "5) \uADDC\uCE59 \uD30C\uC77C \uB9DE\uCD94\uAE30",
775
- choiceCheck: "6) \uD504\uB85C\uC81D\uD2B8 \uADDC\uCE59 \uC810\uAC80\uD558\uAE30",
776
- choiceSecure: "7) \uBE44\uBC00\uBC88\uD638\xB7\uD0A4 \uC720\uCD9C \uAC80\uC0AC\uD558\uAE30",
777
- choiceExit: "\uB098\uAC00\uAE30",
778
- goodbye: "\uB2E4\uC74C\uC5D0 \uB610 \uBD88\uB7EC\uC8FC\uC138\uC694."
779
- },
780
- gate: {
781
- title: "\u{1F4A1} \uC544\uC774\uB514\uC5B4 \uAC80\uC99D",
782
- welcome: "\uC0C8 \uC544\uC774\uB514\uC5B4\uB97C \uAC80\uC99D\uD569\uB2C8\uB2E4. \uC9C8\uBB38\uC5D0 \uB2F5\uD574\uC8FC\uC138\uC694.",
783
- modePrompt: "\uC5B4\uB5BB\uAC8C \uAC80\uC99D\uD560\uAE4C\uC694?",
784
- modeQuickLabel: "\u26A1 \uC9E7\uAC8C (\uD575\uC2EC 5\uBB38\uD56D) \u2014 \uB9C9 \uB5A0\uC62C\uB790\uC744 \uB54C",
785
- modeFullLabel: "\u{1F50D} \uC790\uC138\uD788 (13\uBB38\uD56D) \u2014 \uAE30\uD68D\uC774 \uC5B4\uB290 \uC815\uB3C4 \uC7A1\uD614\uC744 \uB54C",
786
- modeSkipLabel: "\u23ED\uFE0F \uAC74\uB108\uB6F0\uAE30 \u2014 \uB178\uC158\xB7\uBB38\uC11C\uC5D0 \uC774\uBBF8 \uAE30\uD68D\uD574 \uB460",
787
- skipSourcePrompt: "\u{1F4C4} \uAE30\uD68D \uBB38\uC11C \uC704\uCE58 (\uB178\uC158 \uC8FC\uC18C, \uD30C\uC77C \uACBD\uB85C \uB4F1):",
788
- skipGo: "\u2705 \uC2DC\uC791\uD574\uB3C4 \uB3FC\uC694! \uC774\uC81C \uD504\uB85C\uC81D\uD2B8\uB97C \uB9CC\uB4E4\uC5B4 \uBCF4\uC138\uC694 (vhk init)",
789
- skipSourceLabel: (source) => `\uAE30\uD68D \uBB38\uC11C: ${source}`,
790
- quickHeader: "\u26A1 \uC9E7\uC740 \uAC80\uC99D",
791
- fullHeader: "\u{1F50D} \uC790\uC138\uD55C \uAC80\uC99D",
792
- modeCountSuffix: (total) => `\u2014 ${total}\uBB38\uD56D`,
793
- idea: "\u{1F4A1} \uC5B4\uB5A4 \uAC78 \uB9CC\uB4E4 \uAC74\uAC00\uC694? (\uD55C \uC904)",
794
- ideaHint: '\uC608: "\uD300 \uD560 \uC77C\uC744 3\uCD08\uC5D0 \uCD94\uAC00\uD558\uB294 \uC571"',
795
- painPoint: "\u{1F624} \uC774 \uBB38\uC81C, \uB204\uAC00 \uC5BC\uB9C8\uB098 \uC544\uD30C\uD574\uC694?",
796
- painPointHint: '\uC608: "\uB9E4\uC77C \uC5D1\uC140\uC5D0 \uBCF5\uBD99\uD558\uB290\uB77C 30\uBD84\uC529 \uB0A0\uB9BC"',
797
- edge: "\u{1F4AA} \uB098\uB9CC\uC758 \uAC15\uC810\uC740? (\uBE44\uC2B7\uD55C \uAC8C \uC788\uB294\uB370 \uC65C \uC774\uAC78?)",
798
- edgeHint: '\uC608: "\uD55C\uAD6D\uC5B4\uB85C \uB41C \uAC00\uC774\uB4DC + \uBC14\uB85C \uC4F0\uB294 \uD15C\uD50C\uB9BF"',
799
- checklistStart: "\u2500\u2500\u2500 \uC774\uC5B4\uC11C \uC9C8\uBB38\uD569\uB2C8\uB2E4 \u2500\u2500\u2500",
800
- hintPrefix: " \u{1F4A1}",
801
- verdictPrompt: (_failIf) => " \u2192 \uC9C0\uAE08 \uC0C1\uD0DC\uB294?",
802
- statusPassChoice: "\u2705 \uAD1C\uCC2E\uC544\uC694",
803
- statusHoldChoice: "\u{1F7E1} \uC544\uC9C1 \uBAA8\uB974\uACA0\uC5B4\uC694 (\uB098\uC911\uC5D0 \uCC44\uC6CC\uB3C4 \uB429\uB2C8\uB2E4)",
804
- statusFailChoice: "\u{1F504} \uBC94\uC704\uB97C \uC904\uC5EC\uBCFC\uAC8C\uC694",
805
- statusPassLine: " \u2705 \uAD1C\uCC2E\uC544\uC694",
806
- statusHoldLine: " \u{1F7E1} \uBCF4\uB958 \u2014 \uAC1C\uBC1C\uD558\uBA74\uC11C \uCC44\uC6CC\uB3C4 \uB429\uB2C8\uB2E4",
807
- statusFailLine: " \u{1F504} \uBC94\uC704 \uC870\uC815\uC774 \uD544\uC694\uD574 \uBCF4\uC5EC\uC694",
808
- verdictTitle: "\u2550\u2550\u2550 \uACB0\uACFC \u2550\u2550\u2550",
809
- ideaLabel: "\uB9CC\uB4E4 \uAC83:",
810
- painPointLabel: "\uC544\uD508 \uC810:",
811
- edgeLabel: "\uB098\uB9CC\uC758 \uAC15\uC810:",
812
- countLine: (failCount, holdCount, total) => `\uBC94\uC704 \uC870\uC815 ${failCount}\uAC1C \xB7 \uBCF4\uB958 ${holdCount}\uAC1C / ${total}\uBB38\uD56D`,
813
- go: "\u2705 \uC2DC\uC791\uD574\uB3C4 \uB3FC\uC694! \uB2E4\uC74C \uB2E8\uACC4(\uD504\uB85C\uC81D\uD2B8 \uB9CC\uB4E4\uAE30)\uB85C \uB118\uC5B4\uAC00\uC138\uC694.",
814
- refine: "\u{1F504} \uC870\uAE08 \uB354 \uB2E4\uB4EC\uC73C\uBA74 \uC88B\uACA0\uC5B4\uC694. \uC704 \uD56D\uBAA9\uC744 \uBCF4\uC644\uD574 \uBCF4\uC138\uC694.",
815
- drop: "\u{1F4A1} \uB2E4\uB978 \uC544\uC774\uB514\uC5B4\uB97C \uAC80\uD1A0\uD574 \uBCF4\uB294 \uAC74 \uC5B4\uB5A8\uAE4C\uC694?",
816
- nextCommand: "\uB2E4\uC74C: vhk init (\uD504\uB85C\uC81D\uD2B8 \uC2DC\uC791\uD558\uAE30)",
817
- holdRemainHint: "\u{1F4A1} \uBCF4\uB958\uD55C \uD56D\uBAA9\uC740 \uAC1C\uBC1C\uD558\uBA74\uC11C \uCC44\uC6CC\uB3C4 \uAD1C\uCC2E\uC544\uC694.",
818
- failMessage: "\uC544\uC9C1 \uBAA8\uB974\uACA0\uC5B4\uC694 \u2192 \uAD1C\uCC2E\uC544\uC694, \uAC1C\uBC1C\uD558\uBA74\uC11C \uCC44\uC6CC\uB3C4 \uB429\uB2C8\uB2E4."
819
- },
820
- init: {
821
- title: "\u{1F6E0}\uFE0F \uD504\uB85C\uC81D\uD2B8 \uC2DC\uC791\uD558\uAE30",
822
- skipGate: "\u23ED\uFE0F 1\uB2E8\uACC4(\uC544\uC774\uB514\uC5B4 \uAC80\uC99D) \uAC74\uB108\uB6F0\uAE30 \u2014 \uAE30\uD68D\xB7\uC124\uACC4\uAC00 \uC774\uBBF8 \uC788\uC5B4\uC694",
823
- projectName: "\u{1F4E6} \uD504\uB85C\uC81D\uD2B8 \uC774\uB984\uC740?",
824
- projectNameHint: '\uC608: "\uD300 \uD560 \uC77C \uC571"',
825
- description: "\u{1F4DD} \uD55C \uC904\uB85C \uC124\uBA85\uD558\uBA74?",
826
- descriptionHint: '\uC608: "3\uCD08 \uB9CC\uC5D0 \uD560 \uC77C \uCD94\uAC00"',
827
- projectType: "\u{1F3D7}\uFE0F \uC5B4\uB5A4 \uC885\uB958\uC778\uAC00\uC694?",
828
- confirmStack: "\uC774 \uAE30\uC220 \uBB36\uC74C\uC73C\uB85C \uC9C4\uD589\uD560\uAE4C\uC694?",
829
- canceled: "\uCDE8\uC18C\uD588\uC5B4\uC694. \uAE30\uC220 \uBB36\uC74C\uC744 \uBC14\uAFB8\uB824\uBA74 \uB2E4\uC2DC vhk init\uC744 \uC2E4\uD589\uD558\uC138\uC694.",
830
- recommendedStack: "\uCD94\uCC9C \uAE30\uC220 \uBB36\uC74C:",
831
- filesGenerating: "\u{1F4C2} \uD544\uC694\uD55C \uD30C\uC77C \uB9CC\uB4DC\uB294 \uC911...",
832
- overwrite: (filePath) => ` \u26A0\uFE0F ${filePath} \uD30C\uC77C\uC774 \uC788\uC5B4\uC694. \uB36E\uC5B4\uC4F8\uAE4C\uC694?`,
833
- skipped: (filePath) => `${filePath} \u2014 \uAC74\uB108\uB700`,
834
- done: "\u{1F389} \uD504\uB85C\uC81D\uD2B8 \uBF08\uB300\uAC00 \uC900\uBE44\uB410\uC5B4\uC694!",
835
- nextSteps: "\uB2E4\uC74C\uC5D0 \uD560 \uC77C:",
836
- fillHint: "CLAUDE.md \xB7 .cursorrules\uC5D0\uC11C \u{1F449} \uC5EC\uAE30\uB97C \uCC44\uC6CC\uC8FC\uC138\uC694 \uD45C\uC2DC\uB97C \uCC3E\uC544 \uCC44\uC6B0\uC138\uC694",
837
- prdHint: "docs/PRD.md\uC5D0 1\uCC28 \uBC84\uC804\uC5D0 \uB123\uC744 \uAE30\uB2A5\xB7\uBE7C\uB294 \uAE30\uB2A5\uC744 \uC801\uC5B4 \uBCF4\uC138\uC694",
838
- notionFetching: "\u{1F4E1} \uB178\uC158 \uAE30\uD68D \uD398\uC774\uC9C0 \uBD88\uB7EC\uC624\uB294 \uC911...",
839
- notionDone: (name) => `\uB178\uC158\uC5D0\uC11C \uAC00\uC838\uC624\uAE30 \uC644\uB8CC: ${name}`,
840
- notionReviewHint: "docs/PRD.md\uB97C \uC77D\uACE0 \u{1F449} \uC5EC\uAE30\uB97C \uCC44\uC6CC\uC8FC\uC138\uC694 \uD56D\uBAA9\uC744 \uCC44\uC6B0\uC138\uC694",
841
- gitHintLabel: "\uD130\uBBF8\uB110\uC5D0 \uBCF5\uC0AC\uD560 \uBA85\uB839 (\uC544\uB798 \uBC15\uC2A4 \uBCF5\uBD99):",
842
- gitHintCommand: 'git init && git add . && git commit -m "feat: \uD504\uB85C\uC81D\uD2B8 \uC2DC\uC791"',
843
- startDev: "\uC774\uC81C \uAC1C\uBC1C\uD574 \uBCF4\uC138\uC694! \u{1F680}",
844
- commandsMdDone: "\u{1F4CB} COMMANDS.md \uC0DD\uC131",
845
- scriptsDone: "\u{1F4E6} package.json scripts \uCD94\uAC00"
846
- },
847
- recap: {
848
- title: "\u{1F4DD} \uC624\uB298 \uD55C \uC77C \uC815\uB9AC",
849
- analyzing: "\u{1F4CA} \uC624\uB298 \uBC14\uB010 \uD30C\uC77C\xB7\uCEE4\uBC0B\uC744 \uC0B4\uD3B4\uBCF4\uB294 \uC911...",
850
- noRepo: "\u274C Git \uC800\uC7A5\uC18C\uAC00 \uC544\uB2C8\uC5D0\uC694. \uBA3C\uC800 git init\uC744 \uC2E4\uD589\uD558\uC138\uC694.",
851
- noChanges: "\u26A0\uFE0F \uC624\uB298 \uBC14\uB010 \uB0B4\uC6A9\uC774 \uC5C6\uC5B4\uC694.",
852
- summary: "\u{1F4DD} \uC774\uBC88\uC5D0 \uBB58 \uD588\uB098\uC694? (1~3\uC904)",
853
- summaryHint: '\uC608: "\uB85C\uADF8\uC778 \uD654\uBA74 \uB9CC\uB4E4\uACE0 \uBC84\uD2BC \uC0C9 \uACE0\uCE68"',
854
- decisions: "\u{1F9ED} \uC815\uD55C \uACB0\uC815\uC774 \uC788\uB098\uC694? (\uC5C6\uC73C\uBA74 Enter)",
855
- nextTodo: "\u23ED\uFE0F \uB2E4\uC74C\uC5D0 \uD560 \uC77C\uC740?",
856
- blockers: "\u{1F6A7} \uB9C9\uD78C \uAC8C \uC788\uB098\uC694? (\uC5C6\uC73C\uBA74 Enter)",
857
- done: "\u2705 \uC624\uB298 \uAE30\uB85D\uC744 \uC800\uC7A5\uD588\uC5B4\uC694!",
858
- updateClaude: 'CLAUDE.md "\uC9C0\uAE08 \uC0C1\uD0DC"\uB3C4 \uAC19\uC774 \uACE0\uCE60\uAE4C\uC694?',
859
- adrDetected: "\u{1F4D0} \uC4F0\uB294 \uAE30\uC220\xB7\uC124\uC815\uC774 \uBC14\uB010 \uAC83 \uAC19\uC544\uC694!",
860
- createAdr: "\uC65C \uADF8\uB807\uAC8C \uD588\uB294\uC9C0 \uAE30\uB85D \uBB38\uC11C\uB97C \uB9CC\uB4E4\uAE4C\uC694?",
861
- troubleDetected: "\u{1F527} \uBC84\uADF8\xB7\uC624\uB958\uB97C \uACE0\uCE5C \uCEE4\uBC0B\uC774 \uBCF4\uC5EC\uC694!",
862
- createTroubleshoot: "\uC5B4\uB5BB\uAC8C \uACE0\uCCE4\uB294\uC9C0 \uBA54\uBAA8\uB97C \uB0A8\uAE38\uAE4C\uC694?"
863
- },
864
- check: {
865
- title: "\u{1F50D} \uD504\uB85C\uC81D\uD2B8 \uADDC\uCE59 \uC810\uAC80",
866
- noRules: "\u26A0\uFE0F RULES.md \uD30C\uC77C\uC774 \uC5C6\uC5B4\uC694.",
867
- noAutoRules: "\u26A0\uFE0F \uC790\uB3D9\uC73C\uB85C \uAC80\uC0AC\uD560 \uADDC\uCE59\uC774 \uC5C6\uC5B4\uC694.",
868
- allPassed: "\u{1F389} \uADDC\uCE59\uC744 \uBAA8\uB450 \uC9C0\uCF30\uC5B4\uC694!",
869
- summary: "\u{1F4CA} \uC810\uAC80 \uACB0\uACFC:"
870
- },
871
- doctor: {
872
- title: "\u{1FA7A} \uAC1C\uBC1C \uD658\uACBD \uC810\uAC80",
873
- allOk: "\u{1F389} \uAC1C\uBC1C \uD658\uACBD \uC900\uBE44 \uC644\uB8CC!",
874
- missing: "\u26A0\uFE0F \uC77C\uBD80 \uB3C4\uAD6C\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.",
875
- missingHint: "\uC704 \uC548\uB0B4\uB97C \uB530\uB77C \uC124\uCE58\uD558\uC138\uC694.",
876
- projectFiles: "\u{1F4C1} \uD504\uB85C\uC81D\uD2B8 \uD30C\uC77C \uD655\uC778:",
877
- envNotIgnored: "\u26A0\uFE0F .env\uAC00 .gitignore\uC5D0 \uC5C6\uC74C! \uCD94\uAC00\uD558\uC138\uC694",
878
- nextOkMessage: "\uD658\uACBD \uC810\uAC80 \uD1B5\uACFC! \uC774\uC81C \uD504\uB85C\uC81D\uD2B8\uB97C \uC2DC\uC791\uD558\uC138\uC694.",
879
- nextRetryMessage: "\uC704 \uB3C4\uAD6C\uB97C \uC124\uCE58\uD55C \uD6C4 \uB2E4\uC2DC \uC810\uAC80\uD558\uC138\uC694.",
880
- updateAvailable: (latest) => `\u{1F195} v${latest} \uC0AC\uC6A9 \uAC00\uB2A5 \u2014 npm i -g @byh3071/vhk`,
881
- updateCurrent: "\uCD5C\uC2E0 \uBC84\uC804\uC744 \uC4F0\uACE0 \uC788\uC5B4\uC694"
882
- },
883
- nlp: {
884
- matched: "\uC774\uAC8C \uB9DE\uB098\uC694?",
885
- notMatched: "\uBB34\uC2A8 \uB73B\uC778\uC9C0 \uBAA8\uB974\uACA0\uC5B4\uC694. vhk\uB97C \uC785\uB825\uD558\uBA74 \uBA54\uB274\uC5D0\uC11C \uC120\uD0DD\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.",
886
- menuHint: "vhk\uB97C \uC785\uB825\uD558\uBA74 \uBA54\uB274\uC5D0\uC11C \uC120\uD0DD\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4."
887
- },
888
- secure: {
889
- title: "\u{1F512} \uBE44\uBC00\uBC88\uD638\xB7\uD0A4 \uC720\uCD9C \uAC80\uC0AC",
890
- noGitignore: "\u26A0\uFE0F .gitignore \uD30C\uC77C\uC774 \uC5C6\uC5B4\uC694!",
891
- noEnvInGitignore: "\u26A0\uFE0F .gitignore\uC5D0 .env\uAC00 \uC5C6\uC5B4\uC694!",
892
- scanning: "\u{1F50D} \uD30C\uC77C\uC744 \uC0B4\uD3B4\uBCF4\uB294 \uC911...",
893
- clean: "\u{1F389} \uBE44\uBC00\uBC88\uD638\xB7\uD0A4\uAC00 \uCF54\uB4DC\uC5D0 \uBCF4\uC774\uC9C0 \uC54A\uC544\uC694!",
894
- summary: "\u{1F4CA} \uAC80\uC0AC \uC694\uC57D:"
895
- },
896
- sync: {
897
- title: "\u{1F504} \uADDC\uCE59 \uD30C\uC77C \uB9DE\uCD94\uAE30",
898
- noRules: "\u26A0\uFE0F RULES.md \uD30C\uC77C\uC774 \uC5C6\uC5B4\uC694.",
899
- cursorrulesDone: "\u2705 .cursorrules \uB9DE\uCDA4 \uC644\uB8CC",
900
- claudeDone: "\u2705 CLAUDE.md \uB9DE\uCDA4 \uC644\uB8CC",
901
- done: "\u{1F504} \uB9DE\uCD94\uAE30 \uC644\uB8CC!"
902
- },
903
- ship: {
904
- title: "\u{1F680} \uBC30\uD3EC \uCCB4\uD06C\uB9AC\uC2A4\uD2B8",
905
- checklist: "\u{1F4CB} \uBC30\uD3EC \uC804 \uCCB4\uD06C\uB9AC\uC2A4\uD2B8",
906
- retro: "\u{1F50D} \uBC30\uD3EC \uD68C\uACE0",
907
- buildLogCreated: "\u2705 \uBE4C\uB4DC \uB85C\uADF8 \uC0DD\uC131 \uC644\uB8CC",
908
- buildLogDone: (rel) => `\u2705 \uBE4C\uB4DC \uB85C\uADF8 \uC0DD\uC131 \uC644\uB8CC: ${rel}`,
909
- questionWell: "\uC798\uB41C \uC810\uC740?",
910
- questionWrong: "\uC5B4\uB824\uC6E0\uB358 \uC810\uC740?",
911
- questionLearned: "\uBC30\uC6B4 \uC810\uC740?",
912
- questionNext: "\uB2E4\uC74C \uBC84\uC804\uC5D0\uC11C \uD560 \uAC83\uC740?",
913
- checkboxPrompt: "\uC644\uB8CC\uD55C \uD56D\uBAA9\uC744 \uC120\uD0DD\uD558\uC138\uC694:",
914
- incompleteHeader: "\u26A0\uFE0F \uC544\uC9C1 \uC644\uB8CC\uD558\uC9C0 \uC54A\uC740 \uD56D\uBAA9:",
915
- proceedConfirm: "\uADF8\uB798\uB3C4 \uACC4\uC18D \uC9C4\uD589\uD560\uAE4C\uC694?",
916
- allPassed: "\u2705 \uBAA8\uB4E0 \uCCB4\uD06C\uB9AC\uC2A4\uD2B8 \uD1B5\uACFC!",
917
- retryMessage: "\uCCB4\uD06C\uB9AC\uC2A4\uD2B8\uB97C \uB9C8\uCE5C \uB4A4 \uB2E4\uC2DC \uC2E4\uD589\uD574 \uBCF4\uC138\uC694.",
918
- retryCursorHint: "\uBE4C\uB4DC\uD558\uACE0 \uD14C\uC2A4\uD2B8 \uB3CC\uB824\uC918",
919
- versionPrompt: "\uBC30\uD3EC \uBC84\uC804\uC740?",
920
- versionHint: "\uC608: 0.4.0",
921
- emptySection: "(\uBBF8\uC791\uC131)",
922
- emptyNext: "(\uBBF8\uC815)",
923
- deployMessage: "\uBE4C\uB4DC \uB85C\uADF8\uB97C \uC800\uC7A5\uD588\uC5B4\uC694! \uC774\uC81C \uC2E4\uC81C \uBC30\uD3EC\uB97C \uC9C4\uD589\uD558\uC138\uC694.",
924
- deployCursorHint: "\uBC30\uD3EC\uD574\uC918",
925
- checkBuild: "\uBE4C\uB4DC\uAC00 \uC131\uACF5\uD588\uB098\uC694?",
926
- hintBuild: "pnpm build",
927
- checkTest: "\uBAA8\uB4E0 \uD14C\uC2A4\uD2B8\uAC00 \uD1B5\uACFC\uD588\uB098\uC694?",
928
- hintTest: "pnpm test --run",
929
- checkVersion: "package.json \uBC84\uC804\uC744 \uC62C\uB838\uB098\uC694?",
930
- hintVersion: "version \uD544\uB4DC \uD655\uC778",
931
- checkChangelog: "\uBCC0\uACBD \uB0B4\uC6A9\uC744 \uAE30\uB85D\uD588\uB098\uC694?",
932
- hintChangelog: "README \uB610\uB294 CHANGELOG",
933
- checkSecurity: "\uBCF4\uC548 \uC2A4\uCE94\uC744 \uB3CC\uB838\uB098\uC694?",
934
- hintSecurity: "vhk \uBCF4\uC548 scan",
935
- checkCommit: "\uBAA8\uB4E0 \uBCC0\uACBD\uC774 \uCEE4\uBC0B\uB418\uC5C8\uB098\uC694?",
936
- hintCommit: "git status \uD655\uC778",
937
- changelogUpdated: (version) => `CHANGELOG.md \uAC31\uC2E0\uB428 \u2014 [Unreleased] \u2192 [${version}] \uC139\uC158\uC73C\uB85C \uC774\uB3D9`,
938
- changelogNoUnreleased: "CHANGELOG.md\uC5D0 [Unreleased] \uC139\uC158\uC774 \uC5C6\uC5B4 \uC790\uB3D9 \uAC31\uC2E0\uC744 \uC2A4\uD0B5\uD588\uC5B4\uC694",
939
- changelogMissing: "CHANGELOG.md\uAC00 \uC5C6\uC5B4\uC694. \uB9CC\uB4E4\uBA74 ship\uC774 \uC790\uB3D9\uC73C\uB85C [Unreleased] \u2192 \uBC84\uC804 \uC139\uC158\uC73C\uB85C \uC62E\uACA8\uC90D\uB2C8\uB2E4."
940
- },
941
- mcp: {
942
- initTitle: "Cursor MCP \uC5F0\uB3D9 \uC124\uC815",
943
- serverStarted: "VHK MCP \uC11C\uBC84 \uC2DC\uC791\uB428"
944
- },
945
- deploy: {
946
- title: "\uBC30\uD3EC\uD558\uAE30",
947
- selectPlatform: "\uC5B4\uB5A4 \uD50C\uB7AB\uD3FC\uC5D0 \uBC30\uD3EC\uD560\uAE4C\uC694?",
948
- deploying: "\uBC30\uD3EC \uC911...",
949
- success: "\uBC30\uD3EC \uC131\uACF5!",
950
- failed: "\uBC30\uD3EC \uC2E4\uD328"
951
- },
952
- env: {
953
- title: "\uD658\uACBD\uBCC0\uC218 \uAD00\uB9AC",
954
- checkTitle: "\uD658\uACBD\uBCC0\uC218 \uC810\uAC80"
955
- },
956
- publish: {
957
- title: "npm \uBC30\uD3EC",
958
- selectBump: "\uBC84\uC804\uC744 \uC5B4\uB5BB\uAC8C \uC62C\uB9B4\uAE4C\uC694?",
959
- building: "\uBE4C\uB4DC \uC911...",
960
- buildSuccess: "\uBE4C\uB4DC \uC131\uACF5",
961
- buildFailed: "\uBE4C\uB4DC \uC2E4\uD328",
962
- testing: "\uD14C\uC2A4\uD2B8 \uC911...",
963
- testSuccess: "\uD14C\uC2A4\uD2B8 \uD1B5\uACFC",
964
- testFailed: "\uD14C\uC2A4\uD2B8 \uC2E4\uD328",
965
- publishing: "npm \uBC30\uD3EC \uC911...",
966
- publishSuccess: "npm \uBC30\uD3EC \uC131\uACF5!",
967
- publishFailed: "npm \uBC30\uD3EC \uC2E4\uD328"
968
- }
969
- };
970
- function lookup(path15) {
971
- const parts = path15.split(".");
972
- let cur = ko;
973
- for (const part of parts) {
974
- if (cur === null || typeof cur !== "object") return void 0;
975
- cur = cur[part];
976
- }
977
- return cur;
978
- }
979
- function t(key, ...args) {
980
- const value = lookup(key);
981
- if (typeof value === "function") {
982
- return value(...args);
983
- }
984
- if (typeof value === "string") return value;
985
- return key;
986
- }
987
-
988
703
  // src/commands/gate.ts
989
704
  import inquirer from "inquirer";
990
- import chalk2 from "chalk";
991
-
992
- // src/lib/next-step.ts
993
705
  import chalk from "chalk";
994
- function printNextStep(step) {
995
- console.log("");
996
- console.log(chalk.cyan.bold("\u2501\u2501\u2501 \uB2E4\uC74C\uC5D0 \uC774\uAC83\uB9CC \uD558\uC138\uC694 \u2501\u2501\u2501"));
997
- console.log("");
998
- console.log(` ${step.message}`);
999
- if (step.command) {
1000
- console.log("");
1001
- console.log(chalk.white.bgGray(" \uD130\uBBF8\uB110\uC5D0 \uBCF5\uBD99 "));
1002
- console.log(chalk.green(` ${step.command}`));
1003
- }
1004
- if (step.cursorHint) {
1005
- console.log("");
1006
- console.log(chalk.white.bgBlue(" Cursor\uC5D0\uAC8C \uB9D0\uD558\uAE30 "));
1007
- console.log(chalk.blue(` "${step.cursorHint}"`));
1008
- }
1009
- if (step.alternative) {
1010
- console.log("");
1011
- console.log(chalk.dim(` \uB610\uB294: ${step.alternative}`));
1012
- }
1013
- console.log("");
1014
- console.log(chalk.cyan.bold("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"));
1015
- console.log("");
1016
- }
1017
-
1018
- // src/commands/gate.ts
1019
706
  var GATE_QUESTIONS = [
1020
707
  { 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 },
1021
708
  { 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 },
@@ -1037,7 +724,7 @@ function judgeGate(failCount, holdCount) {
1037
724
  return "DROP";
1038
725
  }
1039
726
  async function gate() {
1040
- console.log(chalk2.bold(`
727
+ console.log(chalk.bold(`
1041
728
  ${ko.gate.title}
1042
729
  `));
1043
730
  const { mode } = await inquirer.prompt([{
@@ -1056,33 +743,33 @@ ${ko.gate.title}
1056
743
  name: "source",
1057
744
  message: ko.gate.skipSourcePrompt
1058
745
  }]);
1059
- console.log(chalk2.green.bold(`
746
+ console.log(chalk.green.bold(`
1060
747
  ${ko.gate.skipGo}`));
1061
- console.log(chalk2.dim(ko.gate.skipSourceLabel(source)));
748
+ console.log(chalk.dim(ko.gate.skipSourceLabel(source)));
1062
749
  return;
1063
750
  }
1064
751
  const questions = mode === "quick" ? GATE_QUESTIONS.filter((q) => q.quick) : GATE_QUESTIONS;
1065
752
  const total = questions.length;
1066
753
  const header = mode === "quick" ? ko.gate.quickHeader : ko.gate.fullHeader;
1067
- console.log(chalk2.dim(`
754
+ console.log(chalk.dim(`
1068
755
  ${header} ${ko.gate.modeCountSuffix(total)}
1069
756
  `));
1070
- console.log(chalk2.dim(`
757
+ console.log(chalk.dim(`
1071
758
  ${ko.gate.welcome}
1072
759
  `));
1073
- console.log(chalk2.dim(` ${ko.gate.ideaHint}`));
760
+ console.log(chalk.dim(` ${ko.gate.ideaHint}`));
1074
761
  const { idea } = await inquirer.prompt([
1075
762
  { type: "input", name: "idea", message: ko.gate.idea }
1076
763
  ]);
1077
- console.log(chalk2.dim(` ${ko.gate.painPointHint}`));
764
+ console.log(chalk.dim(` ${ko.gate.painPointHint}`));
1078
765
  const { painPoint } = await inquirer.prompt([
1079
766
  { type: "input", name: "painPoint", message: ko.gate.painPoint }
1080
767
  ]);
1081
- console.log(chalk2.dim(` ${ko.gate.edgeHint}`));
768
+ console.log(chalk.dim(` ${ko.gate.edgeHint}`));
1082
769
  const { edge } = await inquirer.prompt([
1083
770
  { type: "input", name: "edge", message: ko.gate.edge }
1084
771
  ]);
1085
- console.log(chalk2.dim(`
772
+ console.log(chalk.dim(`
1086
773
  ${ko.gate.checklistStart}
1087
774
  `));
1088
775
  let failCount = 0;
@@ -1090,7 +777,7 @@ ${ko.gate.checklistStart}
1090
777
  const results = [];
1091
778
  for (let i = 0; i < questions.length; i++) {
1092
779
  const q = questions[i];
1093
- if (q.hint) console.log(chalk2.dim(`${ko.gate.hintPrefix} ${q.hint}`));
780
+ if (q.hint) console.log(chalk.dim(`${ko.gate.hintPrefix} ${q.hint}`));
1094
781
  const { answer } = await inquirer.prompt([{
1095
782
  type: "input",
1096
783
  name: "answer",
@@ -1109,22 +796,22 @@ ${ko.gate.checklistStart}
1109
796
  if (status2 === "fail") failCount++;
1110
797
  if (status2 === "hold") holdCount++;
1111
798
  results.push({ id: q.id, stage: q.stage, status: status2, answer });
1112
- const icon = status2 === "pass" ? chalk2.green(ko.gate.statusPassLine) : status2 === "hold" ? chalk2.yellow(ko.gate.statusHoldLine) : chalk2.red(ko.gate.statusFailLine);
799
+ const icon = status2 === "pass" ? chalk.green(ko.gate.statusPassLine) : status2 === "hold" ? chalk.yellow(ko.gate.statusHoldLine) : chalk.red(ko.gate.statusFailLine);
1113
800
  console.log(icon);
1114
801
  }
1115
- console.log(chalk2.bold(`
802
+ console.log(chalk.bold(`
1116
803
  ${ko.gate.verdictTitle}
1117
804
  `));
1118
- console.log(`${ko.gate.ideaLabel} ${chalk2.cyan(idea)}`);
805
+ console.log(`${ko.gate.ideaLabel} ${chalk.cyan(idea)}`);
1119
806
  console.log(`${ko.gate.painPointLabel} ${painPoint}`);
1120
807
  console.log(`${ko.gate.edgeLabel} ${edge}`);
1121
808
  console.log(`${ko.gate.countLine(failCount, holdCount, total)}
1122
809
  `);
1123
810
  const verdict = judgeGate(failCount, holdCount);
1124
811
  if (verdict === "GO") {
1125
- console.log(chalk2.green.bold(ko.gate.go));
812
+ console.log(chalk.green.bold(ko.gate.go));
1126
813
  if (holdCount > 0) {
1127
- console.log(chalk2.yellow(ko.gate.holdRemainHint));
814
+ console.log(chalk.yellow(ko.gate.holdRemainHint));
1128
815
  }
1129
816
  printNextStep({
1130
817
  message: "\uC544\uC774\uB514\uC5B4 \uD1B5\uACFC! \uC774\uC81C \uD504\uB85C\uC81D\uD2B8\uB97C \uB9CC\uB4E4\uC5B4\uBCF4\uC138\uC694.",
@@ -1132,20 +819,20 @@ ${ko.gate.verdictTitle}
1132
819
  cursorHint: "\uD504\uB85C\uC81D\uD2B8 \uB9CC\uB4E4\uC5B4\uC918"
1133
820
  });
1134
821
  } else if (verdict === "REFINE") {
1135
- console.log(chalk2.yellow.bold(ko.gate.refine));
822
+ console.log(chalk.yellow.bold(ko.gate.refine));
1136
823
  printNextStep({
1137
824
  message: "\uC870\uAE08 \uB354 \uB2E4\uB4EC\uC740 \uD6C4 \uB2E4\uC2DC \uAC80\uC99D\uD574\uBCF4\uC138\uC694.",
1138
825
  command: "vhk \uAC80\uC99D",
1139
826
  cursorHint: "\uC544\uC774\uB514\uC5B4 \uB2E4\uC2DC \uAC80\uC99D\uD574\uC918"
1140
827
  });
1141
828
  } else {
1142
- console.log(chalk2.red.bold(ko.gate.drop));
829
+ console.log(chalk.red.bold(ko.gate.drop));
1143
830
  }
1144
831
  }
1145
832
 
1146
833
  // src/commands/init.ts
1147
834
  import inquirer2 from "inquirer";
1148
- import chalk5 from "chalk";
835
+ import chalk4 from "chalk";
1149
836
  import fs3 from "fs";
1150
837
  import path3 from "path";
1151
838
 
@@ -1361,7 +1048,7 @@ function COMMANDS_MD_TEMPLATE() {
1361
1048
  var import_ignore = __toESM(require_ignore(), 1);
1362
1049
  import fs from "fs";
1363
1050
  import path from "path";
1364
- import chalk3 from "chalk";
1051
+ import chalk2 from "chalk";
1365
1052
  function loadGitignore(rootDir) {
1366
1053
  const ig = (0, import_ignore.default)();
1367
1054
  const gitignorePath = path.join(rootDir, ".gitignore");
@@ -1434,7 +1121,7 @@ function printSecurityWarnings(rootDir = process.cwd()) {
1434
1121
  const result = checkProjectSecurity(rootDir);
1435
1122
  if (result.ok) return true;
1436
1123
  for (const w of result.warnings) {
1437
- console.log(chalk3.yellow(` \u26A0\uFE0F ${w}`));
1124
+ console.log(chalk2.yellow(` \u26A0\uFE0F ${w}`));
1438
1125
  }
1439
1126
  return false;
1440
1127
  }
@@ -1444,13 +1131,13 @@ function filterTrackedPaths(paths, rootDir = process.cwd()) {
1444
1131
  }
1445
1132
 
1446
1133
  // src/utils/logger.ts
1447
- import chalk4 from "chalk";
1134
+ import chalk3 from "chalk";
1448
1135
  var log = {
1449
- success: (msg) => console.log(chalk4.green(`\u2705 ${msg}`)),
1450
- error: (msg) => console.log(chalk4.red(`\u274C ${msg}`)),
1451
- warn: (msg) => console.log(chalk4.yellow(`\u26A0\uFE0F ${msg}`)),
1452
- info: (msg) => console.log(chalk4.blue(`\u2139\uFE0F ${msg}`)),
1453
- step: (msg) => console.log(chalk4.bold(`
1136
+ success: (msg) => console.log(chalk3.green(`\u2705 ${msg}`)),
1137
+ error: (msg) => console.log(chalk3.red(`\u274C ${msg}`)),
1138
+ warn: (msg) => console.log(chalk3.yellow(`\u26A0\uFE0F ${msg}`)),
1139
+ info: (msg) => console.log(chalk3.blue(`\u2139\uFE0F ${msg}`)),
1140
+ step: (msg) => console.log(chalk3.bold(`
1454
1141
  \u25B8 ${msg}`))
1455
1142
  };
1456
1143
 
@@ -1655,11 +1342,11 @@ async function collectAnswers(options, defaults = {}) {
1655
1342
  async function init(options = {}) {
1656
1343
  const skipGate = Boolean(options.skipGate || options.fromNotion);
1657
1344
  if (skipGate) {
1658
- console.log(chalk5.dim(`
1345
+ console.log(chalk4.dim(`
1659
1346
  ${ko.init.skipGate}
1660
1347
  `));
1661
1348
  }
1662
- console.log(chalk5.bold(`
1349
+ console.log(chalk4.bold(`
1663
1350
  ${ko.init.title}
1664
1351
  `));
1665
1352
  printSecurityWarnings();
@@ -1684,7 +1371,7 @@ ${ko.init.title}
1684
1371
  process.exit(1);
1685
1372
  }
1686
1373
  const stack = STACK_PRESETS[answers.type];
1687
- console.log(chalk5.dim(`
1374
+ console.log(chalk4.dim(`
1688
1375
  ${ko.init.recommendedStack} ${stack.join(" + ")}
1689
1376
  `));
1690
1377
  if (!options.yes) {
@@ -1720,21 +1407,21 @@ ${ko.init.recommendedStack} ${stack.join(" + ")}
1720
1407
  log.success(filePath);
1721
1408
  }
1722
1409
  await writeInitExtras(cwd);
1723
- console.log(chalk5.bold.green(`
1410
+ console.log(chalk4.bold.green(`
1724
1411
  ${ko.init.done}`));
1725
- console.log(chalk5.dim(`
1412
+ console.log(chalk4.dim(`
1726
1413
  ${ko.init.nextSteps}`));
1727
1414
  if (options.fromNotion) {
1728
1415
  console.log(` 1. ${ko.init.notionReviewHint}`);
1729
1416
  console.log(` 2. ${ko.init.gitHintLabel}`);
1730
- console.log(` ${chalk5.cyan(ko.init.gitHintCommand)}`);
1417
+ console.log(` ${chalk4.cyan(ko.init.gitHintCommand)}`);
1731
1418
  console.log(` 3. ${ko.init.startDev}
1732
1419
  `);
1733
1420
  } else {
1734
1421
  console.log(` 1. ${ko.init.fillHint}`);
1735
1422
  console.log(` 2. ${ko.init.prdHint}`);
1736
1423
  console.log(` 3. ${ko.init.gitHintLabel}`);
1737
- console.log(` ${chalk5.cyan(ko.init.gitHintCommand)}`);
1424
+ console.log(` ${chalk4.cyan(ko.init.gitHintCommand)}`);
1738
1425
  console.log(` 4. ${ko.init.startDev}
1739
1426
  `);
1740
1427
  }
@@ -1815,7 +1502,7 @@ async function writeInitExtras(projectDir) {
1815
1502
 
1816
1503
  // src/commands/recap.ts
1817
1504
  import inquirer3 from "inquirer";
1818
- import chalk6 from "chalk";
1505
+ import chalk5 from "chalk";
1819
1506
  import fs5 from "fs";
1820
1507
  import path6 from "path";
1821
1508
 
@@ -1974,40 +1661,40 @@ function createAdrFile(cwd, title, context, decision, consequences) {
1974
1661
 
1975
1662
  // src/commands/recap.ts
1976
1663
  async function recap(options = {}) {
1977
- console.log(chalk6.bold(`
1664
+ console.log(chalk5.bold(`
1978
1665
  ${ko.recap.title}
1979
1666
  `));
1980
1667
  if (!await isGitRepo()) {
1981
- console.log(chalk6.red(ko.recap.noRepo));
1668
+ console.log(chalk5.red(ko.recap.noRepo));
1982
1669
  return;
1983
1670
  }
1984
1671
  printSecurityWarnings();
1985
- console.log(chalk6.dim(`${ko.recap.analyzing}
1672
+ console.log(chalk5.dim(`${ko.recap.analyzing}
1986
1673
  `));
1987
1674
  const since = options.since || (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
1988
1675
  const diff2 = await getSessionDiff(since);
1989
1676
  const commits = await getRecentCommits(10, since);
1990
1677
  if (diff2.filesChanged === 0 && commits.length === 0) {
1991
- console.log(chalk6.yellow(ko.recap.noChanges));
1678
+ console.log(chalk5.yellow(ko.recap.noChanges));
1992
1679
  return;
1993
1680
  }
1994
- console.log(chalk6.bold("\u{1F4CA} \uBCC0\uACBD \uC694\uC57D:"));
1995
- console.log(` \uD30C\uC77C: ${chalk6.cyan(String(diff2.filesChanged))}\uAC1C \uBCC0\uACBD`);
1996
- console.log(` \uCD94\uAC00: ${chalk6.green("+" + diff2.insertions)} / \uC0AD\uC81C: ${chalk6.red("-" + diff2.deletions)}`);
1681
+ console.log(chalk5.bold("\u{1F4CA} \uBCC0\uACBD \uC694\uC57D:"));
1682
+ console.log(` \uD30C\uC77C: ${chalk5.cyan(String(diff2.filesChanged))}\uAC1C \uBCC0\uACBD`);
1683
+ console.log(` \uCD94\uAC00: ${chalk5.green("+" + diff2.insertions)} / \uC0AD\uC81C: ${chalk5.red("-" + diff2.deletions)}`);
1997
1684
  if (diff2.files.length > 0) {
1998
- console.log(chalk6.dim("\n \uBCC0\uACBD \uD30C\uC77C:"));
1685
+ console.log(chalk5.dim("\n \uBCC0\uACBD \uD30C\uC77C:"));
1999
1686
  diff2.files.slice(0, 15).forEach((f) => {
2000
- const icon = f.status === "new" ? chalk6.green("\u{1F195}") : f.status === "deleted" ? chalk6.red("\u{1F5D1}\uFE0F") : chalk6.yellow("\u270F\uFE0F");
1687
+ const icon = f.status === "new" ? chalk5.green("\u{1F195}") : f.status === "deleted" ? chalk5.red("\u{1F5D1}\uFE0F") : chalk5.yellow("\u270F\uFE0F");
2001
1688
  console.log(` ${icon} ${f.file}`);
2002
1689
  });
2003
1690
  if (diff2.files.length > 15) {
2004
- console.log(chalk6.dim(` ... \uC678 ${diff2.files.length - 15}\uAC1C`));
1691
+ console.log(chalk5.dim(` ... \uC678 ${diff2.files.length - 15}\uAC1C`));
2005
1692
  }
2006
1693
  }
2007
1694
  if (commits.length > 0) {
2008
- console.log(chalk6.dim("\n \uCD5C\uADFC \uCEE4\uBC0B:"));
1695
+ console.log(chalk5.dim("\n \uCD5C\uADFC \uCEE4\uBC0B:"));
2009
1696
  commits.slice(0, 5).forEach((c) => {
2010
- console.log(chalk6.dim(` \u2022 ${c.message}`));
1697
+ console.log(chalk5.dim(` \u2022 ${c.message}`));
2011
1698
  });
2012
1699
  }
2013
1700
  console.log("");
@@ -2075,11 +1762,11 @@ ${ko.recap.title}
2075
1762
  fs5.writeFileSync(filePath, content, "utf-8");
2076
1763
  const adrCandidates = detectAdrCandidates(diff2);
2077
1764
  if (adrCandidates.length > 0) {
2078
- console.log(chalk6.cyan.bold(`
1765
+ console.log(chalk5.cyan.bold(`
2079
1766
  ${ko.recap.adrDetected} (${adrCandidates.length}\uAC74)`));
2080
1767
  for (const candidate of adrCandidates) {
2081
- console.log(chalk6.cyan(` \u2022 ${candidate.title}: ${candidate.context}`));
2082
- candidate.files.forEach((f) => console.log(chalk6.dim(` ${f}`)));
1768
+ console.log(chalk5.cyan(` \u2022 ${candidate.title}: ${candidate.context}`));
1769
+ candidate.files.forEach((f) => console.log(chalk5.dim(` ${f}`)));
2083
1770
  }
2084
1771
  const { createAdr } = await inquirer3.prompt([{
2085
1772
  type: "confirm",
@@ -2109,17 +1796,17 @@ ${ko.recap.adrDetected} (${adrCandidates.length}\uAC74)`));
2109
1796
  adrAnswers.decision,
2110
1797
  adrAnswers.consequences
2111
1798
  );
2112
- console.log(chalk6.green(` \u2705 ADR \uC0DD\uC131: ${path6.relative(process.cwd(), adrPath)}`));
1799
+ console.log(chalk5.green(` \u2705 ADR \uC0DD\uC131: ${path6.relative(process.cwd(), adrPath)}`));
2113
1800
  }
2114
1801
  }
2115
1802
  }
2116
1803
  const troubleshootingKeywords = /fix|bug|error|crash|hotfix|patch|revert|트러블|에러|버그|수정|핫픽스/i;
2117
1804
  const troubleCommits = commits.filter((c) => troubleshootingKeywords.test(c.message));
2118
1805
  if (troubleCommits.length > 0) {
2119
- console.log(chalk6.yellow.bold(`
1806
+ console.log(chalk5.yellow.bold(`
2120
1807
  ${ko.recap.troubleDetected} (${troubleCommits.length}\uAC74)`));
2121
1808
  troubleCommits.forEach((c) => {
2122
- console.log(chalk6.dim(` \u2022 ${c.message}`));
1809
+ console.log(chalk5.dim(` \u2022 ${c.message}`));
2123
1810
  });
2124
1811
  const { createTroubleshoot } = await inquirer3.prompt([{
2125
1812
  type: "confirm",
@@ -2170,12 +1857,12 @@ ${ko.recap.troubleDetected} (${troubleCommits.length}\uAC74)`));
2170
1857
  `*Generated by \`vhk recap\` at ${(/* @__PURE__ */ new Date()).toISOString()}*`
2171
1858
  ].join("\n");
2172
1859
  fs5.writeFileSync(tsFilePath, tsContent, "utf-8");
2173
- console.log(chalk6.green(` \u2705 \uD2B8\uB7EC\uBE14\uC288\uD305 \uBB38\uC11C \uC0DD\uC131: ${path6.relative(process.cwd(), tsFilePath)}`));
1860
+ console.log(chalk5.green(` \u2705 \uD2B8\uB7EC\uBE14\uC288\uD305 \uBB38\uC11C \uC0DD\uC131: ${path6.relative(process.cwd(), tsFilePath)}`));
2174
1861
  }
2175
1862
  }
2176
- console.log(chalk6.green.bold(`
1863
+ console.log(chalk5.green.bold(`
2177
1864
  ${ko.recap.done}`));
2178
- console.log(chalk6.dim(` \u{1F4C4} ${path6.relative(process.cwd(), filePath)}`));
1865
+ console.log(chalk5.dim(` \u{1F4C4} ${path6.relative(process.cwd(), filePath)}`));
2179
1866
  const claudeMdPath = path6.join(process.cwd(), "CLAUDE.md");
2180
1867
  if (fs5.existsSync(claudeMdPath)) {
2181
1868
  const { updateClaude } = await inquirer3.prompt([{
@@ -2195,7 +1882,7 @@ ${ko.recap.done}`));
2195
1882
  `- **\uB2E4\uC74C \uC561\uC158:** ${answers.nextTodo}`
2196
1883
  );
2197
1884
  fs5.writeFileSync(claudeMdPath, claudeContent, "utf-8");
2198
- console.log(chalk6.green(" \u2705 CLAUDE.md \uC5C5\uB370\uC774\uD2B8 \uC644\uB8CC"));
1885
+ console.log(chalk5.green(" \u2705 CLAUDE.md \uC5C5\uB370\uC774\uD2B8 \uC644\uB8CC"));
2199
1886
  }
2200
1887
  }
2201
1888
  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"';
@@ -2207,7 +1894,7 @@ ${ko.recap.done}`));
2207
1894
  }
2208
1895
 
2209
1896
  // src/commands/sync.ts
2210
- import chalk7 from "chalk";
1897
+ import chalk6 from "chalk";
2211
1898
  import fs6 from "fs";
2212
1899
  import path7 from "path";
2213
1900
  var CURSORRULES_KEYS = ["\uCF54\uB529 \uADDC\uCE59", "\uAE30\uC220 \uC2A4\uD0DD", "\uC544\uD0A4\uD14D\uCC98", "\uB514\uC790\uC778", "Anti-patterns", "\uCEE4\uBC0B"];
@@ -2277,32 +1964,32 @@ function toClaudeMd(sections, existing) {
2277
1964
  return lines.join("\n");
2278
1965
  }
2279
1966
  async function sync() {
2280
- console.log(chalk7.bold(`
1967
+ console.log(chalk6.bold(`
2281
1968
  ${ko.sync.title}
2282
1969
  `));
2283
1970
  const cwd = process.cwd();
2284
1971
  const rulesPath = path7.join(cwd, "RULES.md");
2285
1972
  if (!fs6.existsSync(rulesPath)) {
2286
- console.log(chalk7.yellow(ko.sync.noRules));
2287
- console.log(chalk7.dim(" RULES.md\uB294 \uD504\uB85C\uC81D\uD2B8 \uADDC\uCE59\uC758 Single Source of Truth\uC785\uB2C8\uB2E4."));
2288
- console.log(chalk7.dim(" \uC0DD\uC131\uD558\uB824\uBA74: vhk init \uC2E4\uD589 \uD6C4 RULES.md\uB97C \uC791\uC131\uD558\uC138\uC694."));
1973
+ console.log(chalk6.yellow(ko.sync.noRules));
1974
+ console.log(chalk6.dim(" RULES.md\uB294 \uD504\uB85C\uC81D\uD2B8 \uADDC\uCE59\uC758 Single Source of Truth\uC785\uB2C8\uB2E4."));
1975
+ console.log(chalk6.dim(" \uC0DD\uC131\uD558\uB824\uBA74: vhk init \uC2E4\uD589 \uD6C4 RULES.md\uB97C \uC791\uC131\uD558\uC138\uC694."));
2289
1976
  console.log("");
2290
- console.log(chalk7.dim(" RULES.md \uAE30\uBCF8 \uAD6C\uC870:"));
2291
- console.log(chalk7.dim(" ## \uD504\uB85C\uC81D\uD2B8 \uC815\uCCB4\uC131"));
2292
- console.log(chalk7.dim(" ## \uAE30\uC220 \uC2A4\uD0DD"));
2293
- console.log(chalk7.dim(" ## \uCF54\uB529 \uADDC\uCE59"));
2294
- console.log(chalk7.dim(" ## \uAE30\uB85D \uADDC\uCE59"));
2295
- console.log(chalk7.dim(" ## \uCEE4\uBC0B \uCEE8\uBCA4\uC158"));
1977
+ console.log(chalk6.dim(" RULES.md \uAE30\uBCF8 \uAD6C\uC870:"));
1978
+ console.log(chalk6.dim(" ## \uD504\uB85C\uC81D\uD2B8 \uC815\uCCB4\uC131"));
1979
+ console.log(chalk6.dim(" ## \uAE30\uC220 \uC2A4\uD0DD"));
1980
+ console.log(chalk6.dim(" ## \uCF54\uB529 \uADDC\uCE59"));
1981
+ console.log(chalk6.dim(" ## \uAE30\uB85D \uADDC\uCE59"));
1982
+ console.log(chalk6.dim(" ## \uCEE4\uBC0B \uCEE8\uBCA4\uC158"));
2296
1983
  return;
2297
1984
  }
2298
1985
  const rulesContent = fs6.readFileSync(rulesPath, "utf-8");
2299
1986
  const sections = parseRulesMd(rulesContent);
2300
- console.log(chalk7.dim(` \u{1F4C4} RULES.md \uD30C\uC2F1 \uC644\uB8CC \u2014 ${sections.length}\uAC1C \uC139\uC158`));
1987
+ console.log(chalk6.dim(` \u{1F4C4} RULES.md \uD30C\uC2F1 \uC644\uB8CC \u2014 ${sections.length}\uAC1C \uC139\uC158`));
2301
1988
  const firstLine = rulesContent.split("\n")[0];
2302
1989
  const projectName = firstLine.replace(/^#\s*/, "").replace(/\s*—.*/, "").trim() || "Project";
2303
1990
  const cursorrulesPath = path7.join(cwd, ".cursorrules");
2304
1991
  fs6.writeFileSync(cursorrulesPath, toCursorrules(sections, projectName), "utf-8");
2305
- console.log(chalk7.green(` ${ko.sync.cursorrulesDone}`));
1992
+ console.log(chalk6.green(` ${ko.sync.cursorrulesDone}`));
2306
1993
  const claudePath = path7.join(cwd, "CLAUDE.md");
2307
1994
  const existingClaude = fs6.existsSync(claudePath) ? fs6.readFileSync(claudePath, "utf-8") : `# \uAE30\uB85D \uADDC\uCE59 (${projectName})
2308
1995
 
@@ -2312,11 +1999,11 @@ ${ko.sync.title}
2312
1999
  - **\uB2E4\uC74C \uC561\uC158:** __FILL__
2313
2000
  - **\uB9C8\uC9C0\uB9C9 \uC5C5\uB370\uC774\uD2B8:** ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}`;
2314
2001
  fs6.writeFileSync(claudePath, toClaudeMd(sections, existingClaude), "utf-8");
2315
- console.log(chalk7.green(` ${ko.sync.claudeDone}`));
2316
- console.log(chalk7.bold.green(`
2002
+ console.log(chalk6.green(` ${ko.sync.claudeDone}`));
2003
+ console.log(chalk6.bold.green(`
2317
2004
  ${ko.sync.done}`));
2318
- console.log(chalk7.dim(" RULES.md (\uC6D0\uBCF8) \u2192 .cursorrules + CLAUDE.md (\uC790\uB3D9 \uC0DD\uC131)"));
2319
- console.log(chalk7.dim(" \uADDC\uCE59 \uBCC0\uACBD\uC740 \uD56D\uC0C1 RULES.md\uC5D0\uC11C\uB9CC \uD558\uC138\uC694."));
2005
+ console.log(chalk6.dim(" RULES.md (\uC6D0\uBCF8) \u2192 .cursorrules + CLAUDE.md (\uC790\uB3D9 \uC0DD\uC131)"));
2006
+ console.log(chalk6.dim(" \uADDC\uCE59 \uBCC0\uACBD\uC740 \uD56D\uC0C1 RULES.md\uC5D0\uC11C\uB9CC \uD558\uC138\uC694."));
2320
2007
  printNextStep({
2321
2008
  message: "\uADDC\uCE59 \uB3D9\uAE30\uD654 \uC644\uB8CC! \uC774\uC81C Cursor\uAC00 \uC0C8 \uADDC\uCE59\uC744 \uB530\uB985\uB2C8\uB2E4.",
2322
2009
  command: "vhk \uC810\uAC80",
@@ -2325,7 +2012,7 @@ ${ko.sync.done}`));
2325
2012
  }
2326
2013
 
2327
2014
  // src/commands/check.ts
2328
- import chalk8 from "chalk";
2015
+ import chalk7 from "chalk";
2329
2016
  import path9 from "path";
2330
2017
  import fs8 from "fs";
2331
2018
 
@@ -2484,22 +2171,22 @@ function escapeRegex(str) {
2484
2171
 
2485
2172
  // src/commands/check.ts
2486
2173
  async function check() {
2487
- console.log(chalk8.bold(`
2174
+ console.log(chalk7.bold(`
2488
2175
  ${ko.check.title}
2489
2176
  `));
2490
2177
  const cwd = process.cwd();
2491
2178
  const rulesPath = path9.join(cwd, "RULES.md");
2492
2179
  if (!fs8.existsSync(rulesPath)) {
2493
- console.log(chalk8.yellow(ko.check.noRules));
2494
- console.log(chalk8.dim(" vhk init\uC73C\uB85C \uC2DC\uC791\uD558\uAC70\uB098 RULES.md\uB97C \uB9CC\uB4E4\uC5B4 \uBCF4\uC138\uC694."));
2180
+ console.log(chalk7.yellow(ko.check.noRules));
2181
+ console.log(chalk7.dim(" vhk init\uC73C\uB85C \uC2DC\uC791\uD558\uAC70\uB098 RULES.md\uB97C \uB9CC\uB4E4\uC5B4 \uBCF4\uC138\uC694."));
2495
2182
  return;
2496
2183
  }
2497
2184
  const rules = parseRules(rulesPath);
2498
- console.log(chalk8.dim(` \u{1F4CF} ${rules.length}\uAC1C \uAC80\uC99D \uAC00\uB2A5\uD55C \uADDC\uCE59 \uAC10\uC9C0
2185
+ console.log(chalk7.dim(` \u{1F4CF} ${rules.length}\uAC1C \uAC80\uC99D \uAC00\uB2A5\uD55C \uADDC\uCE59 \uAC10\uC9C0
2499
2186
  `));
2500
2187
  if (rules.length === 0) {
2501
- console.log(chalk8.yellow(ko.check.noAutoRules));
2502
- 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."));
2188
+ console.log(chalk7.yellow(ko.check.noAutoRules));
2189
+ 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."));
2503
2190
  return;
2504
2191
  }
2505
2192
  const allViolations = [];
@@ -2507,13 +2194,13 @@ ${ko.check.title}
2507
2194
  for (const rule of rules) {
2508
2195
  const violations = rule.check(cwd);
2509
2196
  if (violations.length === 0) {
2510
- console.log(chalk8.green(` \u2705 ${rule.id}`) + chalk8.dim(` \u2014 ${rule.description.slice(0, 60)}`));
2197
+ console.log(chalk7.green(` \u2705 ${rule.id}`) + chalk7.dim(` \u2014 ${rule.description.slice(0, 60)}`));
2511
2198
  passCount++;
2512
2199
  } else {
2513
- console.log(chalk8.red(` \u274C ${rule.id}`) + chalk8.dim(` \u2014 ${violations.length}\uAC74 \uC704\uBC18`));
2200
+ console.log(chalk7.red(` \u274C ${rule.id}`) + chalk7.dim(` \u2014 ${violations.length}\uAC74 \uC704\uBC18`));
2514
2201
  violations.forEach((v) => {
2515
- const loc = v.file ? chalk8.dim(` (${v.file}${v.line ? ":" + v.line : ""})`) : "";
2516
- const icon = v.severity === "error" ? chalk8.red("\u2716") : v.severity === "warning" ? chalk8.yellow("\u26A0") : chalk8.blue("\u2139");
2202
+ const loc = v.file ? chalk7.dim(` (${v.file}${v.line ? ":" + v.line : ""})`) : "";
2203
+ const icon = v.severity === "error" ? chalk7.red("\u2716") : v.severity === "warning" ? chalk7.yellow("\u26A0") : chalk7.blue("\u2139");
2517
2204
  console.log(` ${icon} ${v.message}${loc}`);
2518
2205
  });
2519
2206
  allViolations.push(...violations);
@@ -2523,17 +2210,17 @@ ${ko.check.title}
2523
2210
  const errors = allViolations.filter((v) => v.severity === "error").length;
2524
2211
  const warnings = allViolations.filter((v) => v.severity === "warning").length;
2525
2212
  if (allViolations.length === 0) {
2526
- console.log(chalk8.green.bold(`${ko.check.allPassed} (${passCount}/${rules.length})`));
2213
+ console.log(chalk7.green.bold(`${ko.check.allPassed} (${passCount}/${rules.length})`));
2527
2214
  printNextStep({
2528
2215
  message: "\uBAA8\uB4E0 \uADDC\uCE59 \uD1B5\uACFC! \uBCF4\uC548 \uC2A4\uCE94\uB3C4 \uD574\uBCFC\uAE4C\uC694?",
2529
2216
  command: "vhk \uBCF4\uC548 scan",
2530
2217
  cursorHint: "\uBCF4\uC548 \uC2A4\uCE94 \uB3CC\uB824\uC918"
2531
2218
  });
2532
2219
  } else {
2533
- console.log(chalk8.bold(ko.check.summary));
2534
- 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`);
2535
- if (errors > 0) console.log(` ${chalk8.red(`\u2716 ${errors}\uAC1C \uC5D0\uB7EC`)}`);
2536
- if (warnings > 0) console.log(` ${chalk8.yellow(`\u26A0 ${warnings}\uAC1C \uACBD\uACE0`)}`);
2220
+ console.log(chalk7.bold(ko.check.summary));
2221
+ 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`);
2222
+ if (errors > 0) console.log(` ${chalk7.red(`\u2716 ${errors}\uAC1C \uC5D0\uB7EC`)}`);
2223
+ if (warnings > 0) console.log(` ${chalk7.yellow(`\u26A0 ${warnings}\uAC1C \uACBD\uACE0`)}`);
2537
2224
  printNextStep({
2538
2225
  message: "\uC704\uBC18 \uD56D\uBAA9\uC744 \uC218\uC815\uD55C \uD6C4 \uB2E4\uC2DC \uC810\uAC80\uD558\uC138\uC694.",
2539
2226
  command: "vhk \uC810\uAC80",
@@ -2546,7 +2233,7 @@ ${ko.check.title}
2546
2233
  }
2547
2234
 
2548
2235
  // src/commands/secure.ts
2549
- import chalk9 from "chalk";
2236
+ import chalk8 from "chalk";
2550
2237
  import fs11 from "fs";
2551
2238
  import path11 from "path";
2552
2239
 
@@ -2747,32 +2434,32 @@ function filterSevereFindings(findings) {
2747
2434
 
2748
2435
  // src/commands/secure.ts
2749
2436
  async function secure() {
2750
- console.log(chalk9.bold(`
2437
+ console.log(chalk8.bold(`
2751
2438
  ${ko.secure.title}
2752
2439
  `));
2753
2440
  const cwd = process.cwd();
2754
2441
  const gitignorePath = path11.join(cwd, ".gitignore");
2755
2442
  const hasGitignore = fs11.existsSync(gitignorePath);
2756
2443
  if (!hasGitignore) {
2757
- console.log(chalk9.yellow(` ${ko.secure.noGitignore}`));
2758
- console.log(chalk9.dim(" .env \uD30C\uC77C\uC774 \uCEE4\uBC0B\uB420 \uC218 \uC788\uC2B5\uB2C8\uB2E4.\n"));
2444
+ console.log(chalk8.yellow(` ${ko.secure.noGitignore}`));
2445
+ console.log(chalk8.dim(" .env \uD30C\uC77C\uC774 \uCEE4\uBC0B\uB420 \uC218 \uC788\uC2B5\uB2C8\uB2E4.\n"));
2759
2446
  } else {
2760
2447
  const gitignoreContent = fs11.readFileSync(gitignorePath, "utf-8");
2761
2448
  if (!gitignoreContent.includes(".env")) {
2762
- console.log(chalk9.yellow(` ${ko.secure.noEnvInGitignore}`));
2763
- console.log(chalk9.dim(" \uCD94\uAC00\uB97C \uAD8C\uC7A5\uD569\uB2C8\uB2E4.\n"));
2449
+ console.log(chalk8.yellow(` ${ko.secure.noEnvInGitignore}`));
2450
+ console.log(chalk8.dim(" \uCD94\uAC00\uB97C \uAD8C\uC7A5\uD569\uB2C8\uB2E4.\n"));
2764
2451
  }
2765
2452
  }
2766
- console.log(chalk9.dim(` ${ko.secure.scanning}
2453
+ console.log(chalk8.dim(` ${ko.secure.scanning}
2767
2454
  `));
2768
2455
  const { findings, scannedFiles, truncated } = scanProjectForSecrets(cwd);
2769
- 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)`));
2456
+ 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)`));
2770
2457
  if (truncated) {
2771
- 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.`));
2458
+ 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.`));
2772
2459
  }
2773
2460
  console.log("");
2774
2461
  if (findings.length === 0) {
2775
- console.log(chalk9.green.bold(` ${ko.secure.clean}`));
2462
+ console.log(chalk8.green.bold(` ${ko.secure.clean}`));
2776
2463
  printNextStep({
2777
2464
  message: "\uBCF4\uC548 \uC774\uC0C1 \uC5C6\uC74C! \uAE68\uB057\uD569\uB2C8\uB2E4.",
2778
2465
  command: "vhk \uC815\uB9AC",
@@ -2784,43 +2471,43 @@ ${ko.secure.title}
2784
2471
  const high = findings.filter((f) => f.severity === "high");
2785
2472
  const medium = findings.filter((f) => f.severity === "medium");
2786
2473
  if (critical.length > 0) {
2787
- console.log(chalk9.red.bold(` \u{1F6A8} CRITICAL \u2014 ${critical.length}\uAC74`));
2474
+ console.log(chalk8.red.bold(` \u{1F6A8} CRITICAL \u2014 ${critical.length}\uAC74`));
2788
2475
  critical.forEach((f) => {
2789
- console.log(chalk9.red(` \u2716 ${f.patternName}`));
2790
- console.log(chalk9.dim(` ${f.file}:${f.line} \u2192 ${f.match}`));
2476
+ console.log(chalk8.red(` \u2716 ${f.patternName}`));
2477
+ console.log(chalk8.dim(` ${f.file}:${f.line} \u2192 ${f.match}`));
2791
2478
  });
2792
2479
  console.log("");
2793
2480
  }
2794
2481
  if (high.length > 0) {
2795
- console.log(chalk9.yellow.bold(` \u26A0\uFE0F HIGH \u2014 ${high.length}\uAC74`));
2482
+ console.log(chalk8.yellow.bold(` \u26A0\uFE0F HIGH \u2014 ${high.length}\uAC74`));
2796
2483
  high.forEach((f) => {
2797
- console.log(chalk9.yellow(` \u26A0 ${f.patternName}`));
2798
- console.log(chalk9.dim(` ${f.file}:${f.line} \u2192 ${f.match}`));
2484
+ console.log(chalk8.yellow(` \u26A0 ${f.patternName}`));
2485
+ console.log(chalk8.dim(` ${f.file}:${f.line} \u2192 ${f.match}`));
2799
2486
  });
2800
2487
  console.log("");
2801
2488
  }
2802
2489
  if (medium.length > 0) {
2803
- console.log(chalk9.blue.bold(` \u2139 MEDIUM \u2014 ${medium.length}\uAC74`));
2490
+ console.log(chalk8.blue.bold(` \u2139 MEDIUM \u2014 ${medium.length}\uAC74`));
2804
2491
  medium.forEach((f) => {
2805
- console.log(chalk9.blue(` \u2139 ${f.patternName}`));
2806
- console.log(chalk9.dim(` ${f.file}:${f.line} \u2192 ${f.match}`));
2492
+ console.log(chalk8.blue(` \u2139 ${f.patternName}`));
2493
+ console.log(chalk8.dim(` ${f.file}:${f.line} \u2192 ${f.match}`));
2807
2494
  });
2808
2495
  console.log("");
2809
2496
  }
2810
- console.log(chalk9.bold(` ${ko.secure.summary}`));
2811
- console.log(` \uCD1D ${chalk9.red(String(findings.length))}\uAC74 \uAC10\uC9C0 | CRITICAL: ${critical.length} | HIGH: ${high.length} | MEDIUM: ${medium.length}`);
2497
+ console.log(chalk8.bold(` ${ko.secure.summary}`));
2498
+ console.log(` \uCD1D ${chalk8.red(String(findings.length))}\uAC74 \uAC10\uC9C0 | CRITICAL: ${critical.length} | HIGH: ${high.length} | MEDIUM: ${medium.length}`);
2812
2499
  console.log("");
2813
- console.log(chalk9.dim(" \u{1F4A1} \uC870\uCE58 \uBC29\uBC95:"));
2814
- 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"));
2815
- console.log(chalk9.dim(" 2. git history\uC5D0\uC11C\uB3C4 \uC81C\uAC70: git filter-branch \uB610\uB294 BFG Repo-Cleaner"));
2816
- console.log(chalk9.dim(" 3. \uC720\uCD9C\uB41C \uD0A4\uB294 \uC989\uC2DC \uD3D0\uAE30\uD558\uACE0 \uC7AC\uBC1C\uAE09\n"));
2500
+ console.log(chalk8.dim(" \u{1F4A1} \uC870\uCE58 \uBC29\uBC95:"));
2501
+ 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"));
2502
+ console.log(chalk8.dim(" 2. git history\uC5D0\uC11C\uB3C4 \uC81C\uAC70: git filter-branch \uB610\uB294 BFG Repo-Cleaner"));
2503
+ console.log(chalk8.dim(" 3. \uC720\uCD9C\uB41C \uD0A4\uB294 \uC989\uC2DC \uD3D0\uAE30\uD558\uACE0 \uC7AC\uBC1C\uAE09\n"));
2817
2504
  if (critical.length > 0 || high.length > 0) {
2818
2505
  process.exitCode = 1;
2819
2506
  }
2820
2507
  }
2821
2508
 
2822
2509
  // src/commands/doctor.ts
2823
- import chalk10 from "chalk";
2510
+ import chalk9 from "chalk";
2824
2511
  import { execSync } from "child_process";
2825
2512
  import fs12 from "fs";
2826
2513
  import path12 from "path";
@@ -2873,7 +2560,7 @@ function compareSemver(a, b) {
2873
2560
  return a3 - b3;
2874
2561
  }
2875
2562
  async function doctor() {
2876
- console.log(chalk10.bold(`
2563
+ console.log(chalk9.bold(`
2877
2564
  ${ko.doctor.title}
2878
2565
  `));
2879
2566
  const checks = [
@@ -2885,30 +2572,30 @@ ${ko.doctor.title}
2885
2572
  let allOk = true;
2886
2573
  for (const check2 of checks) {
2887
2574
  if (check2.ok) {
2888
- console.log(chalk10.green(` \u2705 ${check2.name}`) + chalk10.dim(` \u2014 ${check2.version}`));
2575
+ console.log(chalk9.green(` \u2705 ${check2.name}`) + chalk9.dim(` \u2014 ${check2.version}`));
2889
2576
  } else {
2890
- console.log(chalk10.red(` \u274C ${check2.name} \uC5C6\uC74C`));
2891
- console.log(chalk10.dim(` \u2192 ${check2.hint}`));
2577
+ console.log(chalk9.red(` \u274C ${check2.name} \uC5C6\uC74C`));
2578
+ console.log(chalk9.dim(` \u2192 ${check2.hint}`));
2892
2579
  allOk = false;
2893
2580
  }
2894
2581
  }
2895
2582
  console.log("");
2896
2583
  const vhkVersion = getVhkVersion();
2897
2584
  if (vhkVersion) {
2898
- console.log(chalk10.green(" \u2705 VHK") + chalk10.dim(` \u2014 v${vhkVersion}`));
2585
+ console.log(chalk9.green(" \u2705 VHK") + chalk9.dim(` \u2014 v${vhkVersion}`));
2899
2586
  } else {
2900
- console.log(chalk10.green(" \u2705 VHK") + chalk10.dim(" \u2014 \uC124\uCE58\uB428"));
2587
+ console.log(chalk9.green(" \u2705 VHK") + chalk9.dim(" \u2014 \uC124\uCE58\uB428"));
2901
2588
  }
2902
2589
  if (vhkVersion) {
2903
2590
  const latest = fetchLatestNpmVersion("@byh3071/vhk");
2904
2591
  if (latest && compareSemver(latest, vhkVersion) > 0) {
2905
- console.log(chalk10.yellow(` ${ko.doctor.updateAvailable(latest)}`));
2592
+ console.log(chalk9.yellow(` ${ko.doctor.updateAvailable(latest)}`));
2906
2593
  } else if (latest) {
2907
- console.log(chalk10.dim(` ${ko.doctor.updateCurrent}`));
2594
+ console.log(chalk9.dim(` ${ko.doctor.updateCurrent}`));
2908
2595
  }
2909
2596
  }
2910
2597
  console.log("");
2911
- console.log(chalk10.bold(` ${ko.doctor.projectFiles}`));
2598
+ console.log(chalk9.bold(` ${ko.doctor.projectFiles}`));
2912
2599
  const cwd = process.cwd();
2913
2600
  const projectFiles = [
2914
2601
  { name: "RULES.md", hint: "vhk init\uC73C\uB85C \uC0DD\uC131 \uAC00\uB2A5" },
@@ -2920,30 +2607,30 @@ ${ko.doctor.title}
2920
2607
  for (const file of projectFiles) {
2921
2608
  const exists = fs12.existsSync(path12.join(cwd, file.name));
2922
2609
  if (exists) {
2923
- console.log(chalk10.green(` \u2705 ${file.name}`));
2610
+ console.log(chalk9.green(` \u2705 ${file.name}`));
2924
2611
  if (file.name === ".env") {
2925
2612
  const gitignorePath = path12.join(cwd, ".gitignore");
2926
2613
  if (fs12.existsSync(gitignorePath)) {
2927
2614
  const gitignore = fs12.readFileSync(gitignorePath, "utf-8");
2928
2615
  if (!gitignore.includes(".env")) {
2929
- console.log(chalk10.yellow(` ${ko.doctor.envNotIgnored}`));
2616
+ console.log(chalk9.yellow(` ${ko.doctor.envNotIgnored}`));
2930
2617
  }
2931
2618
  }
2932
2619
  }
2933
2620
  } else {
2934
- console.log(chalk10.dim(` \u2B1A ${file.name}`) + chalk10.dim(` \u2014 ${file.hint}`));
2621
+ console.log(chalk9.dim(` \u2B1A ${file.name}`) + chalk9.dim(` \u2014 ${file.hint}`));
2935
2622
  }
2936
2623
  }
2937
2624
  console.log("");
2938
2625
  if (allOk) {
2939
- console.log(chalk10.green.bold(` ${ko.doctor.allOk}`));
2626
+ console.log(chalk9.green.bold(` ${ko.doctor.allOk}`));
2940
2627
  printNextStep({
2941
2628
  message: ko.doctor.nextOkMessage,
2942
2629
  command: "vhk \uC2DC\uC791",
2943
2630
  cursorHint: "\uD504\uB85C\uC81D\uD2B8 \uB9CC\uB4E4\uC5B4\uC918"
2944
2631
  });
2945
2632
  } else {
2946
- console.log(chalk10.yellow.bold(` ${ko.doctor.missing} ${ko.doctor.missingHint}`));
2633
+ console.log(chalk9.yellow.bold(` ${ko.doctor.missing} ${ko.doctor.missingHint}`));
2947
2634
  printNextStep({
2948
2635
  message: ko.doctor.nextRetryMessage,
2949
2636
  command: "vhk doctor",
@@ -2954,7 +2641,7 @@ ${ko.doctor.title}
2954
2641
  }
2955
2642
 
2956
2643
  // src/commands/ship.ts
2957
- import chalk11 from "chalk";
2644
+ import chalk10 from "chalk";
2958
2645
  import inquirer4 from "inquirer";
2959
2646
  import fs13 from "fs";
2960
2647
  import path13 from "path";
@@ -2993,29 +2680,29 @@ function updateChangelogUnreleased(cwd, version, date) {
2993
2680
  return { status: "updated", version };
2994
2681
  }
2995
2682
  async function ship() {
2996
- console.log(chalk11.bold(`
2683
+ console.log(chalk10.bold(`
2997
2684
  ${ko.ship.title}
2998
2685
  `));
2999
2686
  const cwd = process.cwd();
3000
- console.log(chalk11.cyan.bold(` ${ko.ship.checklist}
2687
+ console.log(chalk10.cyan.bold(` ${ko.ship.checklist}
3001
2688
  `));
3002
2689
  const { passed } = await inquirer4.prompt([{
3003
2690
  type: "checkbox",
3004
2691
  name: "passed",
3005
2692
  message: ko.ship.checkboxPrompt,
3006
2693
  choices: CHECKLIST.map((c) => ({
3007
- name: `${ko.ship[c.questionKey]} ${chalk11.dim(`(${ko.ship[c.hintKey]})`)}`,
2694
+ name: `${ko.ship[c.questionKey]} ${chalk10.dim(`(${ko.ship[c.hintKey]})`)}`,
3008
2695
  value: c.id
3009
2696
  }))
3010
2697
  }]);
3011
2698
  const allPassed = passed.length === CHECKLIST.length;
3012
2699
  const skipped = CHECKLIST.filter((c) => !passed.includes(c.id));
3013
2700
  if (!allPassed) {
3014
- console.log(chalk11.yellow(`
2701
+ console.log(chalk10.yellow(`
3015
2702
  ${ko.ship.incompleteHeader}`));
3016
2703
  skipped.forEach((s) => {
3017
- console.log(chalk11.yellow(` \u2022 ${ko.ship[s.questionKey]}`));
3018
- console.log(chalk11.dim(` \u2192 ${ko.ship[s.hintKey]}`));
2704
+ console.log(chalk10.yellow(` \u2022 ${ko.ship[s.questionKey]}`));
2705
+ console.log(chalk10.dim(` \u2192 ${ko.ship[s.hintKey]}`));
3019
2706
  });
3020
2707
  const { proceed } = await inquirer4.prompt([{
3021
2708
  type: "confirm",
@@ -3032,13 +2719,13 @@ ${ko.ship.title}
3032
2719
  return;
3033
2720
  }
3034
2721
  } else {
3035
- console.log(chalk11.green(`
2722
+ console.log(chalk10.green(`
3036
2723
  ${ko.ship.allPassed}
3037
2724
  `));
3038
2725
  }
3039
- console.log(chalk11.cyan.bold(` ${ko.ship.retro}
2726
+ console.log(chalk10.cyan.bold(` ${ko.ship.retro}
3040
2727
  `));
3041
- console.log(chalk11.dim(` ${ko.ship.versionHint}`));
2728
+ console.log(chalk10.dim(` ${ko.ship.versionHint}`));
3042
2729
  const retro = await inquirer4.prompt([
3043
2730
  { type: "input", name: "version", message: ko.ship.versionPrompt },
3044
2731
  { type: "input", name: "whatWentWell", message: ko.ship.questionWell },
@@ -3081,7 +2768,7 @@ ${ko.ship.title}
3081
2768
  `*Generated by \`vhk ship\` at ${(/* @__PURE__ */ new Date()).toISOString()}*`
3082
2769
  ].join("\n");
3083
2770
  fs13.writeFileSync(filePath, content, "utf-8");
3084
- console.log(chalk11.green(`
2771
+ console.log(chalk10.green(`
3085
2772
  ${ko.ship.buildLogDone(path13.relative(cwd, filePath))}`));
3086
2773
  const changelogResult = updateChangelogUnreleased(cwd, versionSlug, today);
3087
2774
  if (changelogResult.status === "updated") {
@@ -3101,7 +2788,7 @@ ${ko.ship.title}
3101
2788
 
3102
2789
  // src/commands/save.ts
3103
2790
  import { execFileSync as execFileSync2 } from "child_process";
3104
- import chalk12 from "chalk";
2791
+ import chalk11 from "chalk";
3105
2792
  import ora from "ora";
3106
2793
  import inquirer5 from "inquirer";
3107
2794
 
@@ -3172,29 +2859,29 @@ function statusIcon(code) {
3172
2859
  return "\u{1F4C4}";
3173
2860
  }
3174
2861
  async function save() {
3175
- console.log(chalk12.bold(`
2862
+ console.log(chalk11.bold(`
3176
2863
  \u{1F4BE} ${t("save.title")}`));
3177
- console.log(chalk12.gray("\u2500".repeat(40)));
2864
+ console.log(chalk11.gray("\u2500".repeat(40)));
3178
2865
  let gitRoot;
3179
2866
  try {
3180
2867
  execFileSync2("git", ["rev-parse", "--is-inside-work-tree"], { stdio: "pipe" });
3181
2868
  gitRoot = getGitRoot();
3182
2869
  } catch {
3183
- console.log(chalk12.red(`\u274C ${t("save.notGitRepo")}`));
2870
+ console.log(chalk11.red(`\u274C ${t("save.notGitRepo")}`));
3184
2871
  return;
3185
2872
  }
3186
- console.log(chalk12.cyan(`
2873
+ console.log(chalk11.cyan(`
3187
2874
  \u{1F512} ${t("save.securityWarnHeader")}`));
3188
2875
  printSecurityWarnings(gitRoot);
3189
2876
  const severe = filterSevereFindings(scanProjectForSecrets(gitRoot).findings);
3190
2877
  if (severe.length > 0) {
3191
- console.log(chalk12.red(`
2878
+ console.log(chalk11.red(`
3192
2879
  \u26A0\uFE0F ${t("save.secretsFound", severe.length)}`));
3193
2880
  severe.slice(0, 5).forEach((f) => {
3194
- console.log(chalk12.dim(` ${f.file}:${f.line} \u2014 ${f.patternName}`));
2881
+ console.log(chalk11.dim(` ${f.file}:${f.line} \u2014 ${f.patternName}`));
3195
2882
  });
3196
2883
  if (severe.length > 5) {
3197
- console.log(chalk12.dim(` ... \uC678 ${severe.length - 5}\uAC74 (vhk \uBCF4\uC548 scan)`));
2884
+ console.log(chalk11.dim(` ... \uC678 ${severe.length - 5}\uAC74 (vhk \uBCF4\uC548 scan)`));
3198
2885
  }
3199
2886
  const { proceed } = await inquirer5.prompt([{
3200
2887
  type: "confirm",
@@ -3203,16 +2890,16 @@ async function save() {
3203
2890
  default: false
3204
2891
  }]);
3205
2892
  if (!proceed) {
3206
- console.log(chalk12.gray(t("save.cancelled")));
2893
+ console.log(chalk11.gray(t("save.cancelled")));
3207
2894
  return;
3208
2895
  }
3209
2896
  }
3210
2897
  const lines = parsePorcelainLines(gitOut(["status", "--porcelain"], gitRoot));
3211
2898
  if (lines.length === 0) {
3212
- console.log(chalk12.yellow(`\u{1F4ED} ${t("save.noChanges")}`));
2899
+ console.log(chalk11.yellow(`\u{1F4ED} ${t("save.noChanges")}`));
3213
2900
  return;
3214
2901
  }
3215
- console.log(chalk12.cyan(`
2902
+ console.log(chalk11.cyan(`
3216
2903
  \u{1F4CB} ${t("save.filesHeader", lines.length)}`));
3217
2904
  lines.forEach((line) => {
3218
2905
  const code = line.substring(0, 2);
@@ -3234,34 +2921,34 @@ async function save() {
3234
2921
  spinner.text = t("save.pushing");
3235
2922
  if (!hasGitRemote(gitRoot)) {
3236
2923
  spinner.succeed(t("save.successLocal"));
3237
- console.log(chalk12.yellow(` \u{1F4A1} ${t("save.noRemote")}`));
2924
+ console.log(chalk11.yellow(` \u{1F4A1} ${t("save.noRemote")}`));
3238
2925
  } else {
3239
2926
  try {
3240
2927
  gitRun(["push"], gitRoot);
3241
2928
  spinner.succeed(t("save.successWithPush"));
3242
2929
  } catch (pushErr) {
3243
2930
  spinner.fail(t("save.pushFailed"));
3244
- console.log(chalk12.red(getExecErrorMessage(pushErr)));
3245
- console.log(chalk12.yellow(`
2931
+ console.log(chalk11.red(getExecErrorMessage(pushErr)));
2932
+ console.log(chalk11.yellow(`
3246
2933
  \u{1F4A1} ${t("save.commitOkPushFailed")}`));
3247
2934
  process.exitCode = 1;
3248
2935
  }
3249
2936
  }
3250
2937
  if (process.exitCode !== 1) {
3251
- console.log(chalk12.green(`
2938
+ console.log(chalk11.green(`
3252
2939
  \u2705 ${t("save.done", lines.length)}`));
3253
2940
  } else {
3254
- console.log(chalk12.green(`
2941
+ console.log(chalk11.green(`
3255
2942
  \u2705 ${t("save.doneLocalOnly", lines.length)}`));
3256
2943
  }
3257
2944
  } catch (err) {
3258
2945
  spinner.fail(t("save.failed"));
3259
- console.log(chalk12.red(getExecErrorMessage(err)));
2946
+ console.log(chalk11.red(getExecErrorMessage(err)));
3260
2947
  if (didAdd) {
3261
2948
  try {
3262
2949
  const staged = gitOut(["diff", "--cached", "--stat"], gitRoot).trim();
3263
2950
  if (staged) {
3264
- console.log(chalk12.yellow(`
2951
+ console.log(chalk11.yellow(`
3265
2952
  \u{1F4A1} ${t("save.stagedAfterFail")}`));
3266
2953
  }
3267
2954
  } catch {
@@ -3273,7 +2960,7 @@ async function save() {
3273
2960
 
3274
2961
  // src/commands/undo.ts
3275
2962
  import { execFileSync as execFileSync3 } from "child_process";
3276
- import chalk13 from "chalk";
2963
+ import chalk12 from "chalk";
3277
2964
  import inquirer6 from "inquirer";
3278
2965
  function parseRecentCommits(logOutput) {
3279
2966
  return logOutput.split("\n").map((l) => l.trim()).filter(Boolean);
@@ -3297,30 +2984,30 @@ function isUndoRisky(undoCount, unpushedCount, hasRemote) {
3297
2984
  return false;
3298
2985
  }
3299
2986
  async function undo() {
3300
- console.log(chalk13.bold(`
2987
+ console.log(chalk12.bold(`
3301
2988
  \u23EA ${t("undo.title")}`));
3302
- console.log(chalk13.gray("\u2500".repeat(40)));
2989
+ console.log(chalk12.gray("\u2500".repeat(40)));
3303
2990
  let gitRoot;
3304
2991
  try {
3305
2992
  execFileSync3("git", ["rev-parse", "--is-inside-work-tree"], { stdio: "pipe" });
3306
2993
  gitRoot = getGitRoot();
3307
2994
  } catch {
3308
- console.log(chalk13.red(`\u274C ${t("undo.notGitRepo")}`));
2995
+ console.log(chalk12.red(`\u274C ${t("undo.notGitRepo")}`));
3309
2996
  return;
3310
2997
  }
3311
2998
  let logOutput;
3312
2999
  try {
3313
3000
  logOutput = gitOut(["log", "--oneline", "-5"], gitRoot).trim();
3314
3001
  } catch {
3315
- console.log(chalk13.yellow(`\u{1F4ED} ${t("undo.noCommits")}`));
3002
+ console.log(chalk12.yellow(`\u{1F4ED} ${t("undo.noCommits")}`));
3316
3003
  return;
3317
3004
  }
3318
3005
  const commits = parseRecentCommits(logOutput);
3319
3006
  if (commits.length === 0) {
3320
- console.log(chalk13.yellow(`\u{1F4ED} ${t("undo.noCommits")}`));
3007
+ console.log(chalk12.yellow(`\u{1F4ED} ${t("undo.noCommits")}`));
3321
3008
  return;
3322
3009
  }
3323
- console.log(chalk13.cyan(`
3010
+ console.log(chalk12.cyan(`
3324
3011
  ${t("undo.recentHeader")}`));
3325
3012
  commits.forEach((c, i) => {
3326
3013
  console.log(` ${i === 0 ? "\u{1F449}" : " "} ${c}`);
@@ -3337,7 +3024,7 @@ ${t("undo.recentHeader")}`));
3337
3024
  const undoCount = Math.min(Math.max(1, count || 1), maxUndo);
3338
3025
  const headCount = countLocalCommits(gitRoot);
3339
3026
  if (undoCount >= headCount) {
3340
- console.log(chalk13.yellow(`
3027
+ console.log(chalk12.yellow(`
3341
3028
  \u{1F4ED} ${t("undo.rootCommit")}`));
3342
3029
  return;
3343
3030
  }
@@ -3346,10 +3033,10 @@ ${t("undo.recentHeader")}`));
3346
3033
  const risky = isUndoRisky(undoCount, unpushed, remote);
3347
3034
  if (risky) {
3348
3035
  if (unpushed < 0) {
3349
- console.log(chalk13.red(`
3036
+ console.log(chalk12.red(`
3350
3037
  \u26A0\uFE0F ${t("undo.noUpstreamWarning")}`));
3351
3038
  } else {
3352
- console.log(chalk13.red(`
3039
+ console.log(chalk12.red(`
3353
3040
  \u26A0\uFE0F ${t("undo.alreadyPushed")}`));
3354
3041
  }
3355
3042
  }
@@ -3360,22 +3047,22 @@ ${t("undo.recentHeader")}`));
3360
3047
  default: false
3361
3048
  }]);
3362
3049
  if (!confirm) {
3363
- console.log(chalk13.gray(t("undo.cancelled")));
3050
+ console.log(chalk12.gray(t("undo.cancelled")));
3364
3051
  return;
3365
3052
  }
3366
3053
  try {
3367
3054
  gitRun(["reset", "--soft", `HEAD~${undoCount}`], gitRoot);
3368
- console.log(chalk13.green(`
3055
+ console.log(chalk12.green(`
3369
3056
  \u2705 ${t("undo.success")}`));
3370
- console.log(chalk13.gray(` \u{1F4A1} ${t("undo.stagedHint")}`));
3057
+ console.log(chalk12.gray(` \u{1F4A1} ${t("undo.stagedHint")}`));
3371
3058
  if (risky) {
3372
- console.log(chalk13.yellow(`
3059
+ console.log(chalk12.yellow(`
3373
3060
  \u{1F4A1} ${t("undo.forcePushHint")}`));
3374
3061
  }
3375
3062
  } catch (err) {
3376
- console.log(chalk13.red(`\u274C ${t("undo.failed")}`));
3063
+ console.log(chalk12.red(`\u274C ${t("undo.failed")}`));
3377
3064
  const msg = err instanceof Error ? err.message : String(err);
3378
- console.log(chalk13.red(msg));
3065
+ console.log(chalk12.red(msg));
3379
3066
  process.exitCode = 1;
3380
3067
  }
3381
3068
  }
@@ -3384,7 +3071,7 @@ ${t("undo.recentHeader")}`));
3384
3071
  import { execFileSync as execFileSync4 } from "child_process";
3385
3072
  import fs15 from "fs";
3386
3073
  import path14 from "path";
3387
- import chalk14 from "chalk";
3074
+ import chalk13 from "chalk";
3388
3075
 
3389
3076
  // src/lib/read-json.ts
3390
3077
  import fs14 from "fs";
@@ -3456,15 +3143,15 @@ function getSyncCounts(gitRoot) {
3456
3143
  }
3457
3144
  }
3458
3145
  async function status() {
3459
- console.log(chalk14.bold(`
3146
+ console.log(chalk13.bold(`
3460
3147
  \u{1F4CA} ${t("status.title")}`));
3461
- console.log(chalk14.gray("\u2500".repeat(40)));
3148
+ console.log(chalk13.gray("\u2500".repeat(40)));
3462
3149
  let gitRoot;
3463
3150
  try {
3464
3151
  execFileSync4("git", ["rev-parse", "--is-inside-work-tree"], { stdio: "pipe" });
3465
3152
  gitRoot = getGitRoot();
3466
3153
  } catch {
3467
- console.log(chalk14.red(`\u274C ${t("status.notGitRepo")}`));
3154
+ console.log(chalk13.red(`\u274C ${t("status.notGitRepo")}`));
3468
3155
  return;
3469
3156
  }
3470
3157
  let branch;
@@ -3483,36 +3170,36 @@ async function status() {
3483
3170
  commits = [];
3484
3171
  }
3485
3172
  const pkg = readProjectPackage();
3486
- console.log(chalk14.cyan(`
3487
- \u{1F33F} ${t("status.branch")}`) + chalk14.white(` ${branch}`));
3173
+ console.log(chalk13.cyan(`
3174
+ \u{1F33F} ${t("status.branch")}`) + chalk13.white(` ${branch}`));
3488
3175
  console.log(
3489
- chalk14.cyan(`\u{1F4C1} ${t("status.changes")}`) + chalk14.white(
3176
+ chalk13.cyan(`\u{1F4C1} ${t("status.changes")}`) + chalk13.white(
3490
3177
  ` staged ${counts.staged} \xB7 unstaged ${counts.unstaged} \xB7 untracked ${counts.untracked}`
3491
3178
  )
3492
3179
  );
3493
- console.log(chalk14.cyan(`
3180
+ console.log(chalk13.cyan(`
3494
3181
  \u{1F4CB} ${t("status.recentCommits")}`));
3495
3182
  if (commits.length === 0) {
3496
- console.log(chalk14.dim(` ${t("status.noCommits")}`));
3183
+ console.log(chalk13.dim(` ${t("status.noCommits")}`));
3497
3184
  } else {
3498
- commits.forEach((c) => console.log(` ${chalk14.dim("\u2022")} ${c}`));
3185
+ commits.forEach((c) => console.log(` ${chalk13.dim("\u2022")} ${c}`));
3499
3186
  }
3500
3187
  console.log(
3501
- chalk14.cyan(`
3502
- \u{1F504} ${t("status.remote")}`) + chalk14.white(` ${formatSyncLabel(sync2)}`)
3188
+ chalk13.cyan(`
3189
+ \u{1F504} ${t("status.remote")}`) + chalk13.white(` ${formatSyncLabel(sync2)}`)
3503
3190
  );
3504
- console.log(chalk14.gray("\n" + "\u2500".repeat(40)));
3191
+ console.log(chalk13.gray("\n" + "\u2500".repeat(40)));
3505
3192
  if (pkg) {
3506
- console.log(chalk14.cyan(`\u{1F4E6} ${t("status.package")}`) + chalk14.white(` ${pkg.name} v${pkg.version}`));
3193
+ console.log(chalk13.cyan(`\u{1F4E6} ${t("status.package")}`) + chalk13.white(` ${pkg.name} v${pkg.version}`));
3507
3194
  } else {
3508
- console.log(chalk14.dim(`\u{1F4E6} ${t("status.noPackage")}`));
3195
+ console.log(chalk13.dim(`\u{1F4E6} ${t("status.noPackage")}`));
3509
3196
  }
3510
3197
  console.log("");
3511
3198
  }
3512
3199
 
3513
3200
  // src/commands/diff.ts
3514
3201
  import { execFileSync as execFileSync5, execSync as execSync2 } from "child_process";
3515
- import chalk15 from "chalk";
3202
+ import chalk14 from "chalk";
3516
3203
  function gitOut2(args) {
3517
3204
  try {
3518
3205
  return execFileSync5("git", args, { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
@@ -3552,53 +3239,53 @@ function summarizeNumstat(numstat) {
3552
3239
  return { fileCount, totalAdd, totalDel };
3553
3240
  }
3554
3241
  function printFile(f) {
3555
- const adds = f.additions > 0 ? chalk15.green(`+${f.additions}`) : "";
3556
- const dels = f.deletions > 0 ? chalk15.red(`-${f.deletions}`) : "";
3242
+ const adds = f.additions > 0 ? chalk14.green(`+${f.additions}`) : "";
3243
+ const dels = f.deletions > 0 ? chalk14.red(`-${f.deletions}`) : "";
3557
3244
  const change = [adds, dels].filter(Boolean).join(" ");
3558
3245
  console.log(` ${f.name} ${change}`);
3559
3246
  }
3560
3247
  async function diff() {
3561
- console.log(chalk15.bold(`
3248
+ console.log(chalk14.bold(`
3562
3249
  \u{1F50D} ${t("diff.title")}`));
3563
- console.log(chalk15.gray("\u2500".repeat(40)));
3250
+ console.log(chalk14.gray("\u2500".repeat(40)));
3564
3251
  try {
3565
3252
  execSync2("git rev-parse --is-inside-work-tree", { stdio: "pipe" });
3566
3253
  } catch {
3567
- console.log(chalk15.red(`\u274C ${t("diff.notGitRepo")}`));
3254
+ console.log(chalk14.red(`\u274C ${t("diff.notGitRepo")}`));
3568
3255
  return;
3569
3256
  }
3570
3257
  const unstaged = gitOut2(["diff", "--stat"]);
3571
3258
  const staged = gitOut2(["diff", "--cached", "--stat"]);
3572
3259
  const untracked = gitOut2(["ls-files", "--others", "--exclude-standard"]);
3573
3260
  if (!unstaged && !staged && !untracked) {
3574
- console.log(chalk15.green(`
3261
+ console.log(chalk14.green(`
3575
3262
  \u2705 ${t("diff.noChanges")}`));
3576
3263
  return;
3577
3264
  }
3578
3265
  if (staged) {
3579
- console.log(chalk15.cyan(`
3266
+ console.log(chalk14.cyan(`
3580
3267
  ${t("diff.stagedHeader")}`));
3581
3268
  parseDiffStat(staged).forEach((f) => printFile(f));
3582
3269
  }
3583
3270
  if (unstaged) {
3584
- console.log(chalk15.cyan(`
3271
+ console.log(chalk14.cyan(`
3585
3272
  ${t("diff.unstagedHeader")}`));
3586
3273
  parseDiffStat(unstaged).forEach((f) => printFile(f));
3587
3274
  }
3588
3275
  if (untracked) {
3589
3276
  const files = untracked.split("\n").filter(Boolean);
3590
- console.log(chalk15.cyan(`
3277
+ console.log(chalk14.cyan(`
3591
3278
  ${t("diff.untrackedHeader", files.length)}`));
3592
- files.forEach((f) => console.log(` ${chalk15.green("+")} ${f}`));
3279
+ files.forEach((f) => console.log(` ${chalk14.green("+")} ${f}`));
3593
3280
  }
3594
3281
  const numstat = gitOut2(["diff", "--numstat", "HEAD"]);
3595
3282
  if (numstat) {
3596
3283
  const { fileCount, totalAdd, totalDel } = summarizeNumstat(numstat);
3597
- console.log(chalk15.cyan(`
3284
+ console.log(chalk14.cyan(`
3598
3285
  ${t("diff.summaryHeader")}`));
3599
3286
  console.log(` ${t("diff.filesLine", fileCount)}`);
3600
- console.log(` \uCD94\uAC00: ${chalk15.green(`+${totalAdd}`)}\uC904`);
3601
- console.log(` \uC0AD\uC81C: ${chalk15.red(`-${totalDel}`)}\uC904`);
3287
+ console.log(` \uCD94\uAC00: ${chalk14.green(`+${totalAdd}`)}\uC904`);
3288
+ console.log(` \uC0AD\uC81C: ${chalk14.red(`-${totalDel}`)}\uC904`);
3602
3289
  }
3603
3290
  console.log("");
3604
3291
  }
@@ -3607,7 +3294,7 @@ ${t("diff.summaryHeader")}`));
3607
3294
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
3608
3295
  import { join } from "path";
3609
3296
  import { fileURLToPath as fileURLToPath2 } from "url";
3610
- import chalk16 from "chalk";
3297
+ import chalk15 from "chalk";
3611
3298
  function resolveVhkMcpPath() {
3612
3299
  try {
3613
3300
  const pkgPath = join(process.cwd(), "package.json");
@@ -3627,8 +3314,8 @@ function resolveVhkMcpPath() {
3627
3314
  return join(process.cwd(), "node_modules", "@byh3071", "vhk", "dist", "mcp", "index.js");
3628
3315
  }
3629
3316
  async function mcpInit() {
3630
- console.log(chalk16.bold("\n\u{1F50C} " + t("mcp.initTitle")));
3631
- console.log(chalk16.gray("\u2500".repeat(40)));
3317
+ console.log(chalk15.bold("\n\u{1F50C} " + t("mcp.initTitle")));
3318
+ console.log(chalk15.gray("\u2500".repeat(40)));
3632
3319
  const cursorDir = join(process.cwd(), ".cursor");
3633
3320
  if (!existsSync(cursorDir)) {
3634
3321
  mkdirSync(cursorDir, { recursive: true });
@@ -3646,25 +3333,25 @@ async function mcpInit() {
3646
3333
  mcpServers: { ...parsed.mcpServers ?? {}, vhk: vhkEntry }
3647
3334
  };
3648
3335
  } catch {
3649
- 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."));
3336
+ console.log(chalk15.yellow("\u26A0\uFE0F \uAE30\uC874 .cursor/mcp.json \uD30C\uC2F1 \uC2E4\uD328 \u2014 \uC0C8 \uD30C\uC77C\uB85C \uB36E\uC5B4\uC501\uB2C8\uB2E4."));
3650
3337
  config = { mcpServers: { vhk: vhkEntry } };
3651
3338
  }
3652
3339
  } else {
3653
3340
  config = { mcpServers: { vhk: vhkEntry } };
3654
3341
  }
3655
3342
  writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
3656
- console.log(chalk16.green("\n\u2705 Cursor MCP \uC124\uC815 \uC644\uB8CC!"));
3657
- console.log(chalk16.cyan("\u{1F4C1} \uC0DD\uC131\uB41C \uD30C\uC77C:"));
3343
+ console.log(chalk15.green("\n\u2705 Cursor MCP \uC124\uC815 \uC644\uB8CC!"));
3344
+ console.log(chalk15.cyan("\u{1F4C1} \uC0DD\uC131\uB41C \uD30C\uC77C:"));
3658
3345
  console.log(` ${configPath}`);
3659
- console.log(chalk16.cyan("\n\u{1F504} \uB2E4\uC74C \uB2E8\uACC4:"));
3346
+ console.log(chalk15.cyan("\n\u{1F504} \uB2E4\uC74C \uB2E8\uACC4:"));
3660
3347
  console.log(" 1. Cursor\uB97C \uC7AC\uC2DC\uC791\uD558\uC138\uC694");
3661
3348
  console.log(" 2. Cursor \uCC44\uD305\uC5D0\uC11C vhk \uB3C4\uAD6C\uB97C \uC0AC\uC6A9\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4");
3662
- console.log(chalk16.gray('\n\u{1F4A1} \uC608: "\uD504\uB85C\uC81D\uD2B8 \uC0C1\uD0DC \uC54C\uB824\uC918" \u2192 Cursor\uAC00 vhk status \uD638\uCD9C'));
3349
+ console.log(chalk15.gray('\n\u{1F4A1} \uC608: "\uD504\uB85C\uC81D\uD2B8 \uC0C1\uD0DC \uC54C\uB824\uC918" \u2192 Cursor\uAC00 vhk status \uD638\uCD9C'));
3663
3350
  }
3664
3351
 
3665
3352
  // src/commands/deploy.ts
3666
3353
  import { existsSync as existsSync2 } from "fs";
3667
- import chalk17 from "chalk";
3354
+ import chalk16 from "chalk";
3668
3355
  import inquirer7 from "inquirer";
3669
3356
  var PLATFORMS = {
3670
3357
  vercel: {
@@ -3704,11 +3391,11 @@ function isCLIAvailable(cmd, checkArgs) {
3704
3391
  return safeExecFile(cmd, checkArgs).ok;
3705
3392
  }
3706
3393
  async function deploy() {
3707
- console.log(chalk17.bold("\n\u{1F680} " + t("deploy.title")));
3708
- console.log(chalk17.gray("\u2500".repeat(40)));
3394
+ console.log(chalk16.bold("\n\u{1F680} " + t("deploy.title")));
3395
+ console.log(chalk16.gray("\u2500".repeat(40)));
3709
3396
  let platform = detectPlatform();
3710
3397
  if (platform) {
3711
- console.log(chalk17.cyan(`
3398
+ console.log(chalk16.cyan(`
3712
3399
  \u{1F50D} \uAC10\uC9C0\uB41C \uD50C\uB7AB\uD3FC: ${PLATFORMS[platform].name}`));
3713
3400
  } else {
3714
3401
  const { selected } = await inquirer7.prompt([
@@ -3727,9 +3414,9 @@ async function deploy() {
3727
3414
  }
3728
3415
  const config = PLATFORMS[platform];
3729
3416
  if (!isCLIAvailable(config.command, config.checkArgs)) {
3730
- console.log(chalk17.red(`
3417
+ console.log(chalk16.red(`
3731
3418
  \u274C ${config.name} CLI\uAC00 \uC124\uCE58\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.`));
3732
- console.log(chalk17.yellow(` \u2192 ${config.installHint}`));
3419
+ console.log(chalk16.yellow(` \u2192 ${config.installHint}`));
3733
3420
  return;
3734
3421
  }
3735
3422
  const { confirm } = await inquirer7.prompt([
@@ -3741,15 +3428,15 @@ async function deploy() {
3741
3428
  }
3742
3429
  ]);
3743
3430
  if (!confirm) {
3744
- console.log(chalk17.gray("\uCDE8\uC18C\uB428"));
3431
+ console.log(chalk16.gray("\uCDE8\uC18C\uB428"));
3745
3432
  return;
3746
3433
  }
3747
- console.log(chalk17.cyan(`
3434
+ console.log(chalk16.cyan(`
3748
3435
  ${t("deploy.deploying")}
3749
3436
  `));
3750
3437
  const result = safeExecFileStream(config.command, config.commandArgs);
3751
3438
  if (result.ok) {
3752
- console.log(chalk17.green(`
3439
+ console.log(chalk16.green(`
3753
3440
  \u2705 ${t("deploy.success")}`));
3754
3441
  printNextStep({
3755
3442
  message: "\uBC30\uD3EC \uC644\uB8CC! \uC0AC\uC774\uD2B8\uB97C \uD655\uC778\uD558\uC138\uC694.",
@@ -3757,88 +3444,15 @@ ${t("deploy.deploying")}
3757
3444
  cursorHint: "\uC0C1\uD0DC \uD655\uC778\uD574\uC918"
3758
3445
  });
3759
3446
  } else {
3760
- console.log(chalk17.red(`
3447
+ console.log(chalk16.red(`
3761
3448
  \u274C ${t("deploy.failed")}`));
3762
- console.log(chalk17.red(result.err));
3449
+ console.log(chalk16.red(result.err));
3763
3450
  }
3764
3451
  }
3765
3452
 
3766
- // src/commands/env.ts
3767
- import { existsSync as existsSync3, readFileSync as readFileSync2, writeFileSync as writeFileSync2, appendFileSync } from "fs";
3768
- import chalk18 from "chalk";
3769
- function parseEnvKeys(content) {
3770
- return content.split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("#")).map((line) => line.split("=")[0].trim()).filter(Boolean);
3771
- }
3772
- function ensureGitignore() {
3773
- const gitignorePath = ".gitignore";
3774
- if (existsSync3(gitignorePath)) {
3775
- const content = readFileSync2(gitignorePath, "utf-8");
3776
- if (!content.split("\n").some((l) => l.trim() === ".env")) {
3777
- appendFileSync(gitignorePath, "\n.env\n");
3778
- console.log(chalk18.green("\n\u{1F512} .gitignore\uC5D0 .env \uCD94\uAC00\uB428"));
3779
- }
3780
- } else {
3781
- writeFileSync2(gitignorePath, ".env\nnode_modules/\ndist/\n");
3782
- console.log(chalk18.green("\n\u{1F512} .gitignore \uC0DD\uC131 (.env \uD3EC\uD568)"));
3783
- }
3784
- }
3785
- async function env() {
3786
- console.log(chalk18.bold("\n\u{1F510} " + t("env.title")));
3787
- console.log(chalk18.gray("\u2500".repeat(40)));
3788
- if (!existsSync3(".env")) {
3789
- console.log(chalk18.yellow("\n\u26A0\uFE0F .env \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4."));
3790
- console.log(chalk18.gray(" .env \uD30C\uC77C\uC744 \uBA3C\uC800 \uB9CC\uB4E4\uC5B4\uC8FC\uC138\uC694."));
3791
- return;
3792
- }
3793
- const envContent = readFileSync2(".env", "utf-8");
3794
- const keys = parseEnvKeys(envContent);
3795
- if (keys.length === 0) {
3796
- console.log(chalk18.yellow("\n\u{1F4ED} .env\uC5D0 \uD658\uACBD\uBCC0\uC218\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."));
3797
- return;
3798
- }
3799
- const exampleContent = keys.map((k) => `${k}=`).join("\n") + "\n";
3800
- writeFileSync2(".env.example", exampleContent, "utf-8");
3801
- console.log(chalk18.green(`
3802
- \u2705 .env.example \uC0DD\uC131 (${keys.length}\uAC1C \uD0A4)`));
3803
- keys.forEach((k) => console.log(chalk18.gray(` ${k}`)));
3804
- ensureGitignore();
3805
- printNextStep({
3806
- message: ".env.example \uC0DD\uC131 \uC644\uB8CC!",
3807
- command: "vhk env-check",
3808
- cursorHint: "\uD658\uACBD\uBCC0\uC218 \uC810\uAC80\uD574\uC918"
3809
- });
3810
- }
3811
- async function envCheck() {
3812
- console.log(chalk18.bold("\n\u{1F50D} " + t("env.checkTitle")));
3813
- console.log(chalk18.gray("\u2500".repeat(40)));
3814
- if (!existsSync3(".env.example")) {
3815
- console.log(chalk18.yellow("\n\u26A0\uFE0F .env.example\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. \uBA3C\uC800 vhk env\uB97C \uC2E4\uD589\uD558\uC138\uC694."));
3816
- return;
3817
- }
3818
- const requiredKeys = parseEnvKeys(readFileSync2(".env.example", "utf-8"));
3819
- const currentKeys = existsSync3(".env") ? parseEnvKeys(readFileSync2(".env", "utf-8")) : [];
3820
- const missing = requiredKeys.filter((k) => !currentKeys.includes(k));
3821
- const extra = currentKeys.filter((k) => !requiredKeys.includes(k));
3822
- console.log(chalk18.cyan(`
3823
- \u{1F4CB} \uD544\uC218 \uD658\uACBD\uBCC0\uC218: ${requiredKeys.length}\uAC1C`));
3824
- if (missing.length === 0) {
3825
- console.log(chalk18.green("\n\u2705 \uBAA8\uB4E0 \uD544\uC218 \uD658\uACBD\uBCC0\uC218\uAC00 \uC124\uC815\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4!"));
3826
- } else {
3827
- console.log(chalk18.red(`
3828
- \u274C \uB204\uB77D\uB41C \uD658\uACBD\uBCC0\uC218 (${missing.length}\uAC1C):`));
3829
- missing.forEach((k) => console.log(chalk18.red(` \u2022 ${k}`)));
3830
- }
3831
- if (extra.length > 0) {
3832
- console.log(chalk18.yellow(`
3833
- \u{1F4A1} .env.example\uC5D0 \uC5C6\uB294 \uCD94\uAC00 \uBCC0\uC218 (${extra.length}\uAC1C):`));
3834
- extra.forEach((k) => console.log(chalk18.yellow(` \u2022 ${k}`)));
3835
- }
3836
- ensureGitignore();
3837
- }
3838
-
3839
3453
  // src/commands/publish.ts
3840
- import { existsSync as existsSync4, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
3841
- import chalk19 from "chalk";
3454
+ import { existsSync as existsSync3, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
3455
+ import chalk17 from "chalk";
3842
3456
  import inquirer8 from "inquirer";
3843
3457
  import ora2 from "ora";
3844
3458
  function bumpVersion(current, type) {
@@ -3853,21 +3467,21 @@ function bumpVersion(current, type) {
3853
3467
  }
3854
3468
  }
3855
3469
  async function publish() {
3856
- console.log(chalk19.bold("\n\u{1F4E6} " + t("publish.title")));
3857
- console.log(chalk19.gray("\u2500".repeat(40)));
3858
- if (!existsSync4("package.json")) {
3859
- console.log(chalk19.red("\u274C package.json\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."));
3470
+ console.log(chalk17.bold("\n\u{1F4E6} " + t("publish.title")));
3471
+ console.log(chalk17.gray("\u2500".repeat(40)));
3472
+ if (!existsSync3("package.json")) {
3473
+ console.log(chalk17.red("\u274C package.json\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."));
3860
3474
  return;
3861
3475
  }
3862
3476
  let pkg;
3863
3477
  try {
3864
- pkg = JSON.parse(readFileSync3("package.json", "utf-8"));
3478
+ pkg = JSON.parse(readFileSync2("package.json", "utf-8"));
3865
3479
  } catch {
3866
- console.log(chalk19.red("\u274C package.json \uD30C\uC2F1 \uC2E4\uD328"));
3480
+ console.log(chalk17.red("\u274C package.json \uD30C\uC2F1 \uC2E4\uD328"));
3867
3481
  return;
3868
3482
  }
3869
3483
  const currentVersion = pkg.version || "0.0.0";
3870
- console.log(chalk19.cyan(`
3484
+ console.log(chalk17.cyan(`
3871
3485
  \u{1F4CC} \uD604\uC7AC \uBC84\uC804: v${currentVersion}`));
3872
3486
  const { bumpType } = await inquirer8.prompt([
3873
3487
  {
@@ -3882,18 +3496,18 @@ async function publish() {
3882
3496
  }
3883
3497
  ]);
3884
3498
  const newVersion = bumpVersion(currentVersion, bumpType);
3885
- console.log(chalk19.cyan(`
3499
+ console.log(chalk17.cyan(`
3886
3500
  \u{1F195} \uC0C8 \uBC84\uC804: v${newVersion}`));
3887
3501
  pkg.version = newVersion;
3888
- writeFileSync3("package.json", JSON.stringify(pkg, null, 2) + "\n", "utf-8");
3889
- console.log(chalk19.green("\u2705 package.json \uBC84\uC804 \uC5C5\uB370\uC774\uD2B8"));
3502
+ writeFileSync2("package.json", JSON.stringify(pkg, null, 2) + "\n", "utf-8");
3503
+ console.log(chalk17.green("\u2705 package.json \uBC84\uC804 \uC5C5\uB370\uC774\uD2B8"));
3890
3504
  const buildSpinner = ora2(t("publish.building")).start();
3891
3505
  const buildResult = safeExecFile("pnpm", ["build"]);
3892
3506
  if (!buildResult.ok) {
3893
3507
  buildSpinner.fail(t("publish.buildFailed"));
3894
- console.log(chalk19.red(buildResult.err.slice(0, 500)));
3508
+ console.log(chalk17.red(buildResult.err.slice(0, 500)));
3895
3509
  pkg.version = currentVersion;
3896
- writeFileSync3("package.json", JSON.stringify(pkg, null, 2) + "\n", "utf-8");
3510
+ writeFileSync2("package.json", JSON.stringify(pkg, null, 2) + "\n", "utf-8");
3897
3511
  return;
3898
3512
  }
3899
3513
  buildSpinner.succeed(t("publish.buildSuccess"));
@@ -3901,9 +3515,9 @@ async function publish() {
3901
3515
  const testResult = safeExecFile("pnpm", ["test", "--run"]);
3902
3516
  if (!testResult.ok) {
3903
3517
  testSpinner.fail(t("publish.testFailed"));
3904
- console.log(chalk19.red(testResult.err.slice(0, 500)));
3518
+ console.log(chalk17.red(testResult.err.slice(0, 500)));
3905
3519
  pkg.version = currentVersion;
3906
- writeFileSync3("package.json", JSON.stringify(pkg, null, 2) + "\n", "utf-8");
3520
+ writeFileSync2("package.json", JSON.stringify(pkg, null, 2) + "\n", "utf-8");
3907
3521
  return;
3908
3522
  }
3909
3523
  testSpinner.succeed(t("publish.testSuccess"));
@@ -3917,18 +3531,18 @@ async function publish() {
3917
3531
  ]);
3918
3532
  if (!confirm) {
3919
3533
  pkg.version = currentVersion;
3920
- writeFileSync3("package.json", JSON.stringify(pkg, null, 2) + "\n", "utf-8");
3921
- console.log(chalk19.gray("\uCDE8\uC18C\uB428. \uBC84\uC804\uC774 \uC6D0\uB798\uB300\uB85C \uBCF5\uAD6C\uB429\uB2C8\uB2E4."));
3534
+ writeFileSync2("package.json", JSON.stringify(pkg, null, 2) + "\n", "utf-8");
3535
+ console.log(chalk17.gray("\uCDE8\uC18C\uB428. \uBC84\uC804\uC774 \uC6D0\uB798\uB300\uB85C \uBCF5\uAD6C\uB429\uB2C8\uB2E4."));
3922
3536
  return;
3923
3537
  }
3924
3538
  const pubSpinner = ora2(t("publish.publishing")).start();
3925
3539
  const pubResult = safeExecFile("npm", ["publish", "--access", "public"]);
3926
3540
  if (!pubResult.ok) {
3927
3541
  pubSpinner.fail(t("publish.publishFailed"));
3928
- console.log(chalk19.red(pubResult.err.slice(0, 500)));
3542
+ console.log(chalk17.red(pubResult.err.slice(0, 500)));
3929
3543
  pkg.version = currentVersion;
3930
- writeFileSync3("package.json", JSON.stringify(pkg, null, 2) + "\n", "utf-8");
3931
- console.log(chalk19.gray(`\u{1F4E6} package.json \uBC84\uC804\uC744 v${currentVersion}\uB85C \uBCF5\uAD6C\uD588\uC2B5\uB2C8\uB2E4.`));
3544
+ writeFileSync2("package.json", JSON.stringify(pkg, null, 2) + "\n", "utf-8");
3545
+ console.log(chalk17.gray(`\u{1F4E6} package.json \uBC84\uC804\uC744 v${currentVersion}\uB85C \uBCF5\uAD6C\uD588\uC2B5\uB2C8\uB2E4.`));
3932
3546
  return;
3933
3547
  }
3934
3548
  pubSpinner.succeed(t("publish.publishSuccess"));
@@ -3940,15 +3554,15 @@ async function publish() {
3940
3554
  const pushResult = safeExecFile("git", ["push"]);
3941
3555
  const pushTagsResult = safeExecFile("git", ["push", "--tags"]);
3942
3556
  if (pushResult.ok && pushTagsResult.ok) {
3943
- console.log(chalk19.green(`
3557
+ console.log(chalk17.green(`
3944
3558
  \u{1F3F7}\uFE0F git tag v${newVersion} \uC0DD\uC131 + push \uC644\uB8CC`));
3945
3559
  } else {
3946
- console.log(chalk19.yellow(`
3560
+ console.log(chalk17.yellow(`
3947
3561
  \u{1F3F7}\uFE0F git tag v${newVersion} \uC0DD\uC131\uB428 (push\uB294 \uC218\uB3D9\uC73C\uB85C)`));
3948
3562
  }
3949
3563
  }
3950
3564
  }
3951
- console.log(chalk19.green.bold(`
3565
+ console.log(chalk17.green.bold(`
3952
3566
  \u{1F389} v${newVersion} \uBC30\uD3EC \uC644\uB8CC!`));
3953
3567
  printNextStep({
3954
3568
  message: "npm \uBC30\uD3EC \uC644\uB8CC!",
@@ -4002,14 +3616,14 @@ async function dispatchNlpRoute(route, input) {
4002
3616
  async function runNaturalLanguageRoute(input) {
4003
3617
  const route = routeNaturalLanguage(input);
4004
3618
  if (!route) {
4005
- console.log(chalk20.yellow(`
3619
+ console.log(chalk18.yellow(`
4006
3620
  \u2753 "${input}" \u2014 ${ko.nlp.notMatched}
4007
3621
  `));
4008
3622
  return;
4009
3623
  }
4010
3624
  console.log("");
4011
- console.log(chalk20.cyan(` \u{1F4AC} "${input}"`));
4012
- console.log(chalk20.cyan(` \u2192 ${route.explanation}`));
3625
+ console.log(chalk18.cyan(` \u{1F4AC} "${input}"`));
3626
+ console.log(chalk18.cyan(` \u2192 ${route.explanation}`));
4013
3627
  if (route.confidence === "low") {
4014
3628
  const { confirm } = await inquirer9.prompt([{
4015
3629
  type: "confirm",
@@ -4018,7 +3632,7 @@ async function runNaturalLanguageRoute(input) {
4018
3632
  default: true
4019
3633
  }]);
4020
3634
  if (!confirm) {
4021
- console.log(chalk20.dim(` ${ko.nlp.menuHint}`));
3635
+ console.log(chalk18.dim(` ${ko.nlp.menuHint}`));
4022
3636
  return;
4023
3637
  }
4024
3638
  }
@@ -4047,7 +3661,7 @@ var KO_ALIASES = {
4047
3661
  "env-check": "\uD658\uACBD\uBCC0\uC218\uC810\uAC80",
4048
3662
  publish: "\uCD9C\uC2DC"
4049
3663
  };
4050
- program.name("vhk").description("VHK \u2014 \uBC14\uC774\uBE0C\uCF54\uB529 \uD504\uB85C\uC81D\uD2B8 \uCF54\uCE58 (\uD55C\uAD6D\uC5B4\uB85C \uC548\uB0B4\uD569\uB2C8\uB2E4)").version("0.7.0");
3664
+ program.name("vhk").description("VHK \u2014 \uBC14\uC774\uBE0C\uCF54\uB529 \uD504\uB85C\uC81D\uD2B8 \uCF54\uCE58 (\uD55C\uAD6D\uC5B4\uB85C \uC548\uB0B4\uD569\uB2C8\uB2E4)").version("0.7.1");
4051
3665
  program.configureHelp({
4052
3666
  formatHelp(cmd, helper) {
4053
3667
  if (cmd.parent) {