@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/chunk-3HHU7V77.js +770 -0
- package/dist/index.js +259 -645
- package/dist/mcp/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-NJDRNI3S.js +0 -316
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
|
-
|
|
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
|
|
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(
|
|
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(
|
|
746
|
+
console.log(chalk.green.bold(`
|
|
1060
747
|
${ko.gate.skipGo}`));
|
|
1061
|
-
console.log(
|
|
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(
|
|
754
|
+
console.log(chalk.dim(`
|
|
1068
755
|
${header} ${ko.gate.modeCountSuffix(total)}
|
|
1069
756
|
`));
|
|
1070
|
-
console.log(
|
|
757
|
+
console.log(chalk.dim(`
|
|
1071
758
|
${ko.gate.welcome}
|
|
1072
759
|
`));
|
|
1073
|
-
console.log(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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" ?
|
|
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(
|
|
802
|
+
console.log(chalk.bold(`
|
|
1116
803
|
${ko.gate.verdictTitle}
|
|
1117
804
|
`));
|
|
1118
|
-
console.log(`${ko.gate.ideaLabel} ${
|
|
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(
|
|
812
|
+
console.log(chalk.green.bold(ko.gate.go));
|
|
1126
813
|
if (holdCount > 0) {
|
|
1127
|
-
console.log(
|
|
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(
|
|
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(
|
|
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
|
|
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
|
|
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(
|
|
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
|
|
1134
|
+
import chalk3 from "chalk";
|
|
1448
1135
|
var log = {
|
|
1449
|
-
success: (msg) => console.log(
|
|
1450
|
-
error: (msg) => console.log(
|
|
1451
|
-
warn: (msg) => console.log(
|
|
1452
|
-
info: (msg) => console.log(
|
|
1453
|
-
step: (msg) => console.log(
|
|
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(
|
|
1345
|
+
console.log(chalk4.dim(`
|
|
1659
1346
|
${ko.init.skipGate}
|
|
1660
1347
|
`));
|
|
1661
1348
|
}
|
|
1662
|
-
console.log(
|
|
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(
|
|
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(
|
|
1410
|
+
console.log(chalk4.bold.green(`
|
|
1724
1411
|
${ko.init.done}`));
|
|
1725
|
-
console.log(
|
|
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(` ${
|
|
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(` ${
|
|
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
|
|
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(
|
|
1664
|
+
console.log(chalk5.bold(`
|
|
1978
1665
|
${ko.recap.title}
|
|
1979
1666
|
`));
|
|
1980
1667
|
if (!await isGitRepo()) {
|
|
1981
|
-
console.log(
|
|
1668
|
+
console.log(chalk5.red(ko.recap.noRepo));
|
|
1982
1669
|
return;
|
|
1983
1670
|
}
|
|
1984
1671
|
printSecurityWarnings();
|
|
1985
|
-
console.log(
|
|
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(
|
|
1678
|
+
console.log(chalk5.yellow(ko.recap.noChanges));
|
|
1992
1679
|
return;
|
|
1993
1680
|
}
|
|
1994
|
-
console.log(
|
|
1995
|
-
console.log(` \uD30C\uC77C: ${
|
|
1996
|
-
console.log(` \uCD94\uAC00: ${
|
|
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(
|
|
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" ?
|
|
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(
|
|
1691
|
+
console.log(chalk5.dim(` ... \uC678 ${diff2.files.length - 15}\uAC1C`));
|
|
2005
1692
|
}
|
|
2006
1693
|
}
|
|
2007
1694
|
if (commits.length > 0) {
|
|
2008
|
-
console.log(
|
|
1695
|
+
console.log(chalk5.dim("\n \uCD5C\uADFC \uCEE4\uBC0B:"));
|
|
2009
1696
|
commits.slice(0, 5).forEach((c) => {
|
|
2010
|
-
console.log(
|
|
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(
|
|
1765
|
+
console.log(chalk5.cyan.bold(`
|
|
2079
1766
|
${ko.recap.adrDetected} (${adrCandidates.length}\uAC74)`));
|
|
2080
1767
|
for (const candidate of adrCandidates) {
|
|
2081
|
-
console.log(
|
|
2082
|
-
candidate.files.forEach((f) => console.log(
|
|
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(
|
|
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(
|
|
1806
|
+
console.log(chalk5.yellow.bold(`
|
|
2120
1807
|
${ko.recap.troubleDetected} (${troubleCommits.length}\uAC74)`));
|
|
2121
1808
|
troubleCommits.forEach((c) => {
|
|
2122
|
-
console.log(
|
|
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(
|
|
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(
|
|
1863
|
+
console.log(chalk5.green.bold(`
|
|
2177
1864
|
${ko.recap.done}`));
|
|
2178
|
-
console.log(
|
|
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(
|
|
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
|
|
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(
|
|
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(
|
|
2287
|
-
console.log(
|
|
2288
|
-
console.log(
|
|
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(
|
|
2291
|
-
console.log(
|
|
2292
|
-
console.log(
|
|
2293
|
-
console.log(
|
|
2294
|
-
console.log(
|
|
2295
|
-
console.log(
|
|
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(
|
|
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(
|
|
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(
|
|
2316
|
-
console.log(
|
|
2002
|
+
console.log(chalk6.green(` ${ko.sync.claudeDone}`));
|
|
2003
|
+
console.log(chalk6.bold.green(`
|
|
2317
2004
|
${ko.sync.done}`));
|
|
2318
|
-
console.log(
|
|
2319
|
-
console.log(
|
|
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
|
|
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(
|
|
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(
|
|
2494
|
-
console.log(
|
|
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(
|
|
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(
|
|
2502
|
-
console.log(
|
|
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(
|
|
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(
|
|
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 ?
|
|
2516
|
-
const icon = v.severity === "error" ?
|
|
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(
|
|
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(
|
|
2534
|
-
console.log(` \uADDC\uCE59: ${
|
|
2535
|
-
if (errors > 0) console.log(` ${
|
|
2536
|
-
if (warnings > 0) console.log(` ${
|
|
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
|
|
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(
|
|
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(
|
|
2758
|
-
console.log(
|
|
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(
|
|
2763
|
-
console.log(
|
|
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(
|
|
2453
|
+
console.log(chalk8.dim(` ${ko.secure.scanning}
|
|
2767
2454
|
`));
|
|
2768
2455
|
const { findings, scannedFiles, truncated } = scanProjectForSecrets(cwd);
|
|
2769
|
-
console.log(
|
|
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(
|
|
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(
|
|
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(
|
|
2474
|
+
console.log(chalk8.red.bold(` \u{1F6A8} CRITICAL \u2014 ${critical.length}\uAC74`));
|
|
2788
2475
|
critical.forEach((f) => {
|
|
2789
|
-
console.log(
|
|
2790
|
-
console.log(
|
|
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(
|
|
2482
|
+
console.log(chalk8.yellow.bold(` \u26A0\uFE0F HIGH \u2014 ${high.length}\uAC74`));
|
|
2796
2483
|
high.forEach((f) => {
|
|
2797
|
-
console.log(
|
|
2798
|
-
console.log(
|
|
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(
|
|
2490
|
+
console.log(chalk8.blue.bold(` \u2139 MEDIUM \u2014 ${medium.length}\uAC74`));
|
|
2804
2491
|
medium.forEach((f) => {
|
|
2805
|
-
console.log(
|
|
2806
|
-
console.log(
|
|
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(
|
|
2811
|
-
console.log(` \uCD1D ${
|
|
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(
|
|
2814
|
-
console.log(
|
|
2815
|
-
console.log(
|
|
2816
|
-
console.log(
|
|
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
|
|
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(
|
|
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(
|
|
2575
|
+
console.log(chalk9.green(` \u2705 ${check2.name}`) + chalk9.dim(` \u2014 ${check2.version}`));
|
|
2889
2576
|
} else {
|
|
2890
|
-
console.log(
|
|
2891
|
-
console.log(
|
|
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(
|
|
2585
|
+
console.log(chalk9.green(" \u2705 VHK") + chalk9.dim(` \u2014 v${vhkVersion}`));
|
|
2899
2586
|
} else {
|
|
2900
|
-
console.log(
|
|
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(
|
|
2592
|
+
console.log(chalk9.yellow(` ${ko.doctor.updateAvailable(latest)}`));
|
|
2906
2593
|
} else if (latest) {
|
|
2907
|
-
console.log(
|
|
2594
|
+
console.log(chalk9.dim(` ${ko.doctor.updateCurrent}`));
|
|
2908
2595
|
}
|
|
2909
2596
|
}
|
|
2910
2597
|
console.log("");
|
|
2911
|
-
console.log(
|
|
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(
|
|
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(
|
|
2616
|
+
console.log(chalk9.yellow(` ${ko.doctor.envNotIgnored}`));
|
|
2930
2617
|
}
|
|
2931
2618
|
}
|
|
2932
2619
|
}
|
|
2933
2620
|
} else {
|
|
2934
|
-
console.log(
|
|
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(
|
|
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(
|
|
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
|
|
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(
|
|
2683
|
+
console.log(chalk10.bold(`
|
|
2997
2684
|
${ko.ship.title}
|
|
2998
2685
|
`));
|
|
2999
2686
|
const cwd = process.cwd();
|
|
3000
|
-
console.log(
|
|
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]} ${
|
|
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(
|
|
2701
|
+
console.log(chalk10.yellow(`
|
|
3015
2702
|
${ko.ship.incompleteHeader}`));
|
|
3016
2703
|
skipped.forEach((s) => {
|
|
3017
|
-
console.log(
|
|
3018
|
-
console.log(
|
|
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(
|
|
2722
|
+
console.log(chalk10.green(`
|
|
3036
2723
|
${ko.ship.allPassed}
|
|
3037
2724
|
`));
|
|
3038
2725
|
}
|
|
3039
|
-
console.log(
|
|
2726
|
+
console.log(chalk10.cyan.bold(` ${ko.ship.retro}
|
|
3040
2727
|
`));
|
|
3041
|
-
console.log(
|
|
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(
|
|
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
|
|
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(
|
|
2862
|
+
console.log(chalk11.bold(`
|
|
3176
2863
|
\u{1F4BE} ${t("save.title")}`));
|
|
3177
|
-
console.log(
|
|
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(
|
|
2870
|
+
console.log(chalk11.red(`\u274C ${t("save.notGitRepo")}`));
|
|
3184
2871
|
return;
|
|
3185
2872
|
}
|
|
3186
|
-
console.log(
|
|
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(
|
|
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(
|
|
2881
|
+
console.log(chalk11.dim(` ${f.file}:${f.line} \u2014 ${f.patternName}`));
|
|
3195
2882
|
});
|
|
3196
2883
|
if (severe.length > 5) {
|
|
3197
|
-
console.log(
|
|
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(
|
|
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(
|
|
2899
|
+
console.log(chalk11.yellow(`\u{1F4ED} ${t("save.noChanges")}`));
|
|
3213
2900
|
return;
|
|
3214
2901
|
}
|
|
3215
|
-
console.log(
|
|
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(
|
|
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(
|
|
3245
|
-
console.log(
|
|
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(
|
|
2938
|
+
console.log(chalk11.green(`
|
|
3252
2939
|
\u2705 ${t("save.done", lines.length)}`));
|
|
3253
2940
|
} else {
|
|
3254
|
-
console.log(
|
|
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(
|
|
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(
|
|
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
|
|
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(
|
|
2987
|
+
console.log(chalk12.bold(`
|
|
3301
2988
|
\u23EA ${t("undo.title")}`));
|
|
3302
|
-
console.log(
|
|
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(
|
|
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(
|
|
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(
|
|
3007
|
+
console.log(chalk12.yellow(`\u{1F4ED} ${t("undo.noCommits")}`));
|
|
3321
3008
|
return;
|
|
3322
3009
|
}
|
|
3323
|
-
console.log(
|
|
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(
|
|
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(
|
|
3036
|
+
console.log(chalk12.red(`
|
|
3350
3037
|
\u26A0\uFE0F ${t("undo.noUpstreamWarning")}`));
|
|
3351
3038
|
} else {
|
|
3352
|
-
console.log(
|
|
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(
|
|
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(
|
|
3055
|
+
console.log(chalk12.green(`
|
|
3369
3056
|
\u2705 ${t("undo.success")}`));
|
|
3370
|
-
console.log(
|
|
3057
|
+
console.log(chalk12.gray(` \u{1F4A1} ${t("undo.stagedHint")}`));
|
|
3371
3058
|
if (risky) {
|
|
3372
|
-
console.log(
|
|
3059
|
+
console.log(chalk12.yellow(`
|
|
3373
3060
|
\u{1F4A1} ${t("undo.forcePushHint")}`));
|
|
3374
3061
|
}
|
|
3375
3062
|
} catch (err) {
|
|
3376
|
-
console.log(
|
|
3063
|
+
console.log(chalk12.red(`\u274C ${t("undo.failed")}`));
|
|
3377
3064
|
const msg = err instanceof Error ? err.message : String(err);
|
|
3378
|
-
console.log(
|
|
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
|
|
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(
|
|
3146
|
+
console.log(chalk13.bold(`
|
|
3460
3147
|
\u{1F4CA} ${t("status.title")}`));
|
|
3461
|
-
console.log(
|
|
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(
|
|
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(
|
|
3487
|
-
\u{1F33F} ${t("status.branch")}`) +
|
|
3173
|
+
console.log(chalk13.cyan(`
|
|
3174
|
+
\u{1F33F} ${t("status.branch")}`) + chalk13.white(` ${branch}`));
|
|
3488
3175
|
console.log(
|
|
3489
|
-
|
|
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(
|
|
3180
|
+
console.log(chalk13.cyan(`
|
|
3494
3181
|
\u{1F4CB} ${t("status.recentCommits")}`));
|
|
3495
3182
|
if (commits.length === 0) {
|
|
3496
|
-
console.log(
|
|
3183
|
+
console.log(chalk13.dim(` ${t("status.noCommits")}`));
|
|
3497
3184
|
} else {
|
|
3498
|
-
commits.forEach((c) => console.log(` ${
|
|
3185
|
+
commits.forEach((c) => console.log(` ${chalk13.dim("\u2022")} ${c}`));
|
|
3499
3186
|
}
|
|
3500
3187
|
console.log(
|
|
3501
|
-
|
|
3502
|
-
\u{1F504} ${t("status.remote")}`) +
|
|
3188
|
+
chalk13.cyan(`
|
|
3189
|
+
\u{1F504} ${t("status.remote")}`) + chalk13.white(` ${formatSyncLabel(sync2)}`)
|
|
3503
3190
|
);
|
|
3504
|
-
console.log(
|
|
3191
|
+
console.log(chalk13.gray("\n" + "\u2500".repeat(40)));
|
|
3505
3192
|
if (pkg) {
|
|
3506
|
-
console.log(
|
|
3193
|
+
console.log(chalk13.cyan(`\u{1F4E6} ${t("status.package")}`) + chalk13.white(` ${pkg.name} v${pkg.version}`));
|
|
3507
3194
|
} else {
|
|
3508
|
-
console.log(
|
|
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
|
|
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 ?
|
|
3556
|
-
const dels = f.deletions > 0 ?
|
|
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(
|
|
3248
|
+
console.log(chalk14.bold(`
|
|
3562
3249
|
\u{1F50D} ${t("diff.title")}`));
|
|
3563
|
-
console.log(
|
|
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(
|
|
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(
|
|
3261
|
+
console.log(chalk14.green(`
|
|
3575
3262
|
\u2705 ${t("diff.noChanges")}`));
|
|
3576
3263
|
return;
|
|
3577
3264
|
}
|
|
3578
3265
|
if (staged) {
|
|
3579
|
-
console.log(
|
|
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(
|
|
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(
|
|
3277
|
+
console.log(chalk14.cyan(`
|
|
3591
3278
|
${t("diff.untrackedHeader", files.length)}`));
|
|
3592
|
-
files.forEach((f) => console.log(` ${
|
|
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(
|
|
3284
|
+
console.log(chalk14.cyan(`
|
|
3598
3285
|
${t("diff.summaryHeader")}`));
|
|
3599
3286
|
console.log(` ${t("diff.filesLine", fileCount)}`);
|
|
3600
|
-
console.log(` \uCD94\uAC00: ${
|
|
3601
|
-
console.log(` \uC0AD\uC81C: ${
|
|
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
|
|
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(
|
|
3631
|
-
console.log(
|
|
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(
|
|
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(
|
|
3657
|
-
console.log(
|
|
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(
|
|
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(
|
|
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
|
|
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(
|
|
3708
|
-
console.log(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
3431
|
+
console.log(chalk16.gray("\uCDE8\uC18C\uB428"));
|
|
3745
3432
|
return;
|
|
3746
3433
|
}
|
|
3747
|
-
console.log(
|
|
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(
|
|
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(
|
|
3447
|
+
console.log(chalk16.red(`
|
|
3761
3448
|
\u274C ${t("deploy.failed")}`));
|
|
3762
|
-
console.log(
|
|
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
|
|
3841
|
-
import
|
|
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(
|
|
3857
|
-
console.log(
|
|
3858
|
-
if (!
|
|
3859
|
-
console.log(
|
|
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(
|
|
3478
|
+
pkg = JSON.parse(readFileSync2("package.json", "utf-8"));
|
|
3865
3479
|
} catch {
|
|
3866
|
-
console.log(
|
|
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(
|
|
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(
|
|
3499
|
+
console.log(chalk17.cyan(`
|
|
3886
3500
|
\u{1F195} \uC0C8 \uBC84\uC804: v${newVersion}`));
|
|
3887
3501
|
pkg.version = newVersion;
|
|
3888
|
-
|
|
3889
|
-
console.log(
|
|
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(
|
|
3508
|
+
console.log(chalk17.red(buildResult.err.slice(0, 500)));
|
|
3895
3509
|
pkg.version = currentVersion;
|
|
3896
|
-
|
|
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(
|
|
3518
|
+
console.log(chalk17.red(testResult.err.slice(0, 500)));
|
|
3905
3519
|
pkg.version = currentVersion;
|
|
3906
|
-
|
|
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
|
-
|
|
3921
|
-
console.log(
|
|
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(
|
|
3542
|
+
console.log(chalk17.red(pubResult.err.slice(0, 500)));
|
|
3929
3543
|
pkg.version = currentVersion;
|
|
3930
|
-
|
|
3931
|
-
console.log(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
4012
|
-
console.log(
|
|
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(
|
|
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.
|
|
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) {
|