@byh3071/vhk 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -2
- package/dist/chunk-NQ4V3VN4.js +781 -0
- package/dist/index.js +652 -650
- 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-NQ4V3VN4.js";
|
|
9
14
|
|
|
10
15
|
// node_modules/.pnpm/ignore@7.0.5/node_modules/ignore/index.js
|
|
11
16
|
var require_ignore = __commonJS({
|
|
@@ -467,7 +472,7 @@ var require_ignore = __commonJS({
|
|
|
467
472
|
|
|
468
473
|
// src/index.ts
|
|
469
474
|
import { Command, Help } from "commander";
|
|
470
|
-
import
|
|
475
|
+
import inquirer12 from "inquirer";
|
|
471
476
|
|
|
472
477
|
// src/lib/nlp-router.ts
|
|
473
478
|
function normalize(input) {
|
|
@@ -511,6 +516,30 @@ var RULES = [
|
|
|
511
516
|
confidence: "high",
|
|
512
517
|
test: (t2) => /mcp.*(설정|연동|초기|init)|커서.*(연동|설정|mcp)|cursor.*mcp/.test(t2)
|
|
513
518
|
},
|
|
519
|
+
{
|
|
520
|
+
command: "design-palette",
|
|
521
|
+
explanation: "\uCEEC\uB7EC \uD314\uB808\uD2B8 \uC120\uD0DD (vhk design-palette)",
|
|
522
|
+
confidence: "high",
|
|
523
|
+
test: (t2) => /팔레트|palette|컬러\s*(고|선택|바꿔|변경)|색상\s*(고|선택|변경)|색깔\s*선택/.test(t2)
|
|
524
|
+
},
|
|
525
|
+
{
|
|
526
|
+
command: "design",
|
|
527
|
+
explanation: "\uB514\uC790\uC778 \uD1A0\uD070 \uC0DD\uC131 (vhk design)",
|
|
528
|
+
confidence: "high",
|
|
529
|
+
test: (t2) => /디자인\s*(토큰|시스템|만들|생성|셋업|설정)|design\s*(token|system|setup)|토큰\s*만들|css\s*변수.*만들|tailwind\s*(컬러|설정)/.test(t2)
|
|
530
|
+
},
|
|
531
|
+
{
|
|
532
|
+
command: "theme",
|
|
533
|
+
explanation: "\uB2E4\uD06C/\uB77C\uC774\uD2B8 \uD14C\uB9C8 \uC801\uC6A9 (vhk theme)",
|
|
534
|
+
confidence: "high",
|
|
535
|
+
test: (t2) => /테마(?!\s*(파일|이름))|theme|다크\s*모드|라이트\s*모드|dark\s*mode|light\s*mode|색상\s*모드|모드\s*전환/.test(t2)
|
|
536
|
+
},
|
|
537
|
+
{
|
|
538
|
+
command: "ref",
|
|
539
|
+
explanation: "\uB808\uD37C\uB7F0\uC2A4 \uBAA9\uB85D (vhk ref list)",
|
|
540
|
+
confidence: "high",
|
|
541
|
+
test: (t2) => /^레퍼런스$|^ref$|레퍼런스.*(보|목록|확인|있|뭐)|참고\s*(사이트|목록|링크)|reference.*list/.test(t2) && !/(add|추가|open|열|https?:\/\/)/.test(t2)
|
|
542
|
+
},
|
|
514
543
|
{
|
|
515
544
|
command: "secure",
|
|
516
545
|
explanation: "\uBCF4\uC548 \uC2A4\uCE94 (vhk \uBCF4\uC548)",
|
|
@@ -669,6 +698,14 @@ var KNOWN_COMMAND_TOKENS = /* @__PURE__ */ new Set([
|
|
|
669
698
|
"publish",
|
|
670
699
|
"\uCD9C\uC2DC",
|
|
671
700
|
"\uCD9C\uD558",
|
|
701
|
+
"design",
|
|
702
|
+
"\uB514\uC790\uC778",
|
|
703
|
+
"design-palette",
|
|
704
|
+
"\uD314\uB808\uD2B8",
|
|
705
|
+
"theme",
|
|
706
|
+
"\uD14C\uB9C8",
|
|
707
|
+
"ref",
|
|
708
|
+
"\uB808\uD37C\uB7F0\uC2A4",
|
|
672
709
|
"help"
|
|
673
710
|
]);
|
|
674
711
|
function isOptionToken(token) {
|
|
@@ -692,330 +729,12 @@ function detectNaturalLanguageInput(argv) {
|
|
|
692
729
|
}
|
|
693
730
|
|
|
694
731
|
// src/lib/nlp-run.ts
|
|
695
|
-
import
|
|
696
|
-
import
|
|
697
|
-
|
|
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
|
-
}
|
|
732
|
+
import chalk21 from "chalk";
|
|
733
|
+
import inquirer11 from "inquirer";
|
|
987
734
|
|
|
988
735
|
// src/commands/gate.ts
|
|
989
736
|
import inquirer from "inquirer";
|
|
990
|
-
import chalk2 from "chalk";
|
|
991
|
-
|
|
992
|
-
// src/lib/next-step.ts
|
|
993
737
|
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
738
|
var GATE_QUESTIONS = [
|
|
1020
739
|
{ 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
740
|
{ 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 +756,7 @@ function judgeGate(failCount, holdCount) {
|
|
|
1037
756
|
return "DROP";
|
|
1038
757
|
}
|
|
1039
758
|
async function gate() {
|
|
1040
|
-
console.log(
|
|
759
|
+
console.log(chalk.bold(`
|
|
1041
760
|
${ko.gate.title}
|
|
1042
761
|
`));
|
|
1043
762
|
const { mode } = await inquirer.prompt([{
|
|
@@ -1056,33 +775,33 @@ ${ko.gate.title}
|
|
|
1056
775
|
name: "source",
|
|
1057
776
|
message: ko.gate.skipSourcePrompt
|
|
1058
777
|
}]);
|
|
1059
|
-
console.log(
|
|
778
|
+
console.log(chalk.green.bold(`
|
|
1060
779
|
${ko.gate.skipGo}`));
|
|
1061
|
-
console.log(
|
|
780
|
+
console.log(chalk.dim(ko.gate.skipSourceLabel(source)));
|
|
1062
781
|
return;
|
|
1063
782
|
}
|
|
1064
783
|
const questions = mode === "quick" ? GATE_QUESTIONS.filter((q) => q.quick) : GATE_QUESTIONS;
|
|
1065
784
|
const total = questions.length;
|
|
1066
785
|
const header = mode === "quick" ? ko.gate.quickHeader : ko.gate.fullHeader;
|
|
1067
|
-
console.log(
|
|
786
|
+
console.log(chalk.dim(`
|
|
1068
787
|
${header} ${ko.gate.modeCountSuffix(total)}
|
|
1069
788
|
`));
|
|
1070
|
-
console.log(
|
|
789
|
+
console.log(chalk.dim(`
|
|
1071
790
|
${ko.gate.welcome}
|
|
1072
791
|
`));
|
|
1073
|
-
console.log(
|
|
792
|
+
console.log(chalk.dim(` ${ko.gate.ideaHint}`));
|
|
1074
793
|
const { idea } = await inquirer.prompt([
|
|
1075
794
|
{ type: "input", name: "idea", message: ko.gate.idea }
|
|
1076
795
|
]);
|
|
1077
|
-
console.log(
|
|
796
|
+
console.log(chalk.dim(` ${ko.gate.painPointHint}`));
|
|
1078
797
|
const { painPoint } = await inquirer.prompt([
|
|
1079
798
|
{ type: "input", name: "painPoint", message: ko.gate.painPoint }
|
|
1080
799
|
]);
|
|
1081
|
-
console.log(
|
|
800
|
+
console.log(chalk.dim(` ${ko.gate.edgeHint}`));
|
|
1082
801
|
const { edge } = await inquirer.prompt([
|
|
1083
802
|
{ type: "input", name: "edge", message: ko.gate.edge }
|
|
1084
803
|
]);
|
|
1085
|
-
console.log(
|
|
804
|
+
console.log(chalk.dim(`
|
|
1086
805
|
${ko.gate.checklistStart}
|
|
1087
806
|
`));
|
|
1088
807
|
let failCount = 0;
|
|
@@ -1090,7 +809,7 @@ ${ko.gate.checklistStart}
|
|
|
1090
809
|
const results = [];
|
|
1091
810
|
for (let i = 0; i < questions.length; i++) {
|
|
1092
811
|
const q = questions[i];
|
|
1093
|
-
if (q.hint) console.log(
|
|
812
|
+
if (q.hint) console.log(chalk.dim(`${ko.gate.hintPrefix} ${q.hint}`));
|
|
1094
813
|
const { answer } = await inquirer.prompt([{
|
|
1095
814
|
type: "input",
|
|
1096
815
|
name: "answer",
|
|
@@ -1109,22 +828,22 @@ ${ko.gate.checklistStart}
|
|
|
1109
828
|
if (status2 === "fail") failCount++;
|
|
1110
829
|
if (status2 === "hold") holdCount++;
|
|
1111
830
|
results.push({ id: q.id, stage: q.stage, status: status2, answer });
|
|
1112
|
-
const icon = status2 === "pass" ?
|
|
831
|
+
const icon = status2 === "pass" ? chalk.green(ko.gate.statusPassLine) : status2 === "hold" ? chalk.yellow(ko.gate.statusHoldLine) : chalk.red(ko.gate.statusFailLine);
|
|
1113
832
|
console.log(icon);
|
|
1114
833
|
}
|
|
1115
|
-
console.log(
|
|
834
|
+
console.log(chalk.bold(`
|
|
1116
835
|
${ko.gate.verdictTitle}
|
|
1117
836
|
`));
|
|
1118
|
-
console.log(`${ko.gate.ideaLabel} ${
|
|
837
|
+
console.log(`${ko.gate.ideaLabel} ${chalk.cyan(idea)}`);
|
|
1119
838
|
console.log(`${ko.gate.painPointLabel} ${painPoint}`);
|
|
1120
839
|
console.log(`${ko.gate.edgeLabel} ${edge}`);
|
|
1121
840
|
console.log(`${ko.gate.countLine(failCount, holdCount, total)}
|
|
1122
841
|
`);
|
|
1123
842
|
const verdict = judgeGate(failCount, holdCount);
|
|
1124
843
|
if (verdict === "GO") {
|
|
1125
|
-
console.log(
|
|
844
|
+
console.log(chalk.green.bold(ko.gate.go));
|
|
1126
845
|
if (holdCount > 0) {
|
|
1127
|
-
console.log(
|
|
846
|
+
console.log(chalk.yellow(ko.gate.holdRemainHint));
|
|
1128
847
|
}
|
|
1129
848
|
printNextStep({
|
|
1130
849
|
message: "\uC544\uC774\uB514\uC5B4 \uD1B5\uACFC! \uC774\uC81C \uD504\uB85C\uC81D\uD2B8\uB97C \uB9CC\uB4E4\uC5B4\uBCF4\uC138\uC694.",
|
|
@@ -1132,20 +851,20 @@ ${ko.gate.verdictTitle}
|
|
|
1132
851
|
cursorHint: "\uD504\uB85C\uC81D\uD2B8 \uB9CC\uB4E4\uC5B4\uC918"
|
|
1133
852
|
});
|
|
1134
853
|
} else if (verdict === "REFINE") {
|
|
1135
|
-
console.log(
|
|
854
|
+
console.log(chalk.yellow.bold(ko.gate.refine));
|
|
1136
855
|
printNextStep({
|
|
1137
856
|
message: "\uC870\uAE08 \uB354 \uB2E4\uB4EC\uC740 \uD6C4 \uB2E4\uC2DC \uAC80\uC99D\uD574\uBCF4\uC138\uC694.",
|
|
1138
857
|
command: "vhk \uAC80\uC99D",
|
|
1139
858
|
cursorHint: "\uC544\uC774\uB514\uC5B4 \uB2E4\uC2DC \uAC80\uC99D\uD574\uC918"
|
|
1140
859
|
});
|
|
1141
860
|
} else {
|
|
1142
|
-
console.log(
|
|
861
|
+
console.log(chalk.red.bold(ko.gate.drop));
|
|
1143
862
|
}
|
|
1144
863
|
}
|
|
1145
864
|
|
|
1146
865
|
// src/commands/init.ts
|
|
1147
866
|
import inquirer2 from "inquirer";
|
|
1148
|
-
import
|
|
867
|
+
import chalk4 from "chalk";
|
|
1149
868
|
import fs3 from "fs";
|
|
1150
869
|
import path3 from "path";
|
|
1151
870
|
|
|
@@ -1361,7 +1080,7 @@ function COMMANDS_MD_TEMPLATE() {
|
|
|
1361
1080
|
var import_ignore = __toESM(require_ignore(), 1);
|
|
1362
1081
|
import fs from "fs";
|
|
1363
1082
|
import path from "path";
|
|
1364
|
-
import
|
|
1083
|
+
import chalk2 from "chalk";
|
|
1365
1084
|
function loadGitignore(rootDir) {
|
|
1366
1085
|
const ig = (0, import_ignore.default)();
|
|
1367
1086
|
const gitignorePath = path.join(rootDir, ".gitignore");
|
|
@@ -1434,7 +1153,7 @@ function printSecurityWarnings(rootDir = process.cwd()) {
|
|
|
1434
1153
|
const result = checkProjectSecurity(rootDir);
|
|
1435
1154
|
if (result.ok) return true;
|
|
1436
1155
|
for (const w of result.warnings) {
|
|
1437
|
-
console.log(
|
|
1156
|
+
console.log(chalk2.yellow(` \u26A0\uFE0F ${w}`));
|
|
1438
1157
|
}
|
|
1439
1158
|
return false;
|
|
1440
1159
|
}
|
|
@@ -1444,13 +1163,13 @@ function filterTrackedPaths(paths, rootDir = process.cwd()) {
|
|
|
1444
1163
|
}
|
|
1445
1164
|
|
|
1446
1165
|
// src/utils/logger.ts
|
|
1447
|
-
import
|
|
1166
|
+
import chalk3 from "chalk";
|
|
1448
1167
|
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(
|
|
1168
|
+
success: (msg) => console.log(chalk3.green(`\u2705 ${msg}`)),
|
|
1169
|
+
error: (msg) => console.log(chalk3.red(`\u274C ${msg}`)),
|
|
1170
|
+
warn: (msg) => console.log(chalk3.yellow(`\u26A0\uFE0F ${msg}`)),
|
|
1171
|
+
info: (msg) => console.log(chalk3.blue(`\u2139\uFE0F ${msg}`)),
|
|
1172
|
+
step: (msg) => console.log(chalk3.bold(`
|
|
1454
1173
|
\u25B8 ${msg}`))
|
|
1455
1174
|
};
|
|
1456
1175
|
|
|
@@ -1655,11 +1374,11 @@ async function collectAnswers(options, defaults = {}) {
|
|
|
1655
1374
|
async function init(options = {}) {
|
|
1656
1375
|
const skipGate = Boolean(options.skipGate || options.fromNotion);
|
|
1657
1376
|
if (skipGate) {
|
|
1658
|
-
console.log(
|
|
1377
|
+
console.log(chalk4.dim(`
|
|
1659
1378
|
${ko.init.skipGate}
|
|
1660
1379
|
`));
|
|
1661
1380
|
}
|
|
1662
|
-
console.log(
|
|
1381
|
+
console.log(chalk4.bold(`
|
|
1663
1382
|
${ko.init.title}
|
|
1664
1383
|
`));
|
|
1665
1384
|
printSecurityWarnings();
|
|
@@ -1684,7 +1403,7 @@ ${ko.init.title}
|
|
|
1684
1403
|
process.exit(1);
|
|
1685
1404
|
}
|
|
1686
1405
|
const stack = STACK_PRESETS[answers.type];
|
|
1687
|
-
console.log(
|
|
1406
|
+
console.log(chalk4.dim(`
|
|
1688
1407
|
${ko.init.recommendedStack} ${stack.join(" + ")}
|
|
1689
1408
|
`));
|
|
1690
1409
|
if (!options.yes) {
|
|
@@ -1720,21 +1439,21 @@ ${ko.init.recommendedStack} ${stack.join(" + ")}
|
|
|
1720
1439
|
log.success(filePath);
|
|
1721
1440
|
}
|
|
1722
1441
|
await writeInitExtras(cwd);
|
|
1723
|
-
console.log(
|
|
1442
|
+
console.log(chalk4.bold.green(`
|
|
1724
1443
|
${ko.init.done}`));
|
|
1725
|
-
console.log(
|
|
1444
|
+
console.log(chalk4.dim(`
|
|
1726
1445
|
${ko.init.nextSteps}`));
|
|
1727
1446
|
if (options.fromNotion) {
|
|
1728
1447
|
console.log(` 1. ${ko.init.notionReviewHint}`);
|
|
1729
1448
|
console.log(` 2. ${ko.init.gitHintLabel}`);
|
|
1730
|
-
console.log(` ${
|
|
1449
|
+
console.log(` ${chalk4.cyan(ko.init.gitHintCommand)}`);
|
|
1731
1450
|
console.log(` 3. ${ko.init.startDev}
|
|
1732
1451
|
`);
|
|
1733
1452
|
} else {
|
|
1734
1453
|
console.log(` 1. ${ko.init.fillHint}`);
|
|
1735
1454
|
console.log(` 2. ${ko.init.prdHint}`);
|
|
1736
1455
|
console.log(` 3. ${ko.init.gitHintLabel}`);
|
|
1737
|
-
console.log(` ${
|
|
1456
|
+
console.log(` ${chalk4.cyan(ko.init.gitHintCommand)}`);
|
|
1738
1457
|
console.log(` 4. ${ko.init.startDev}
|
|
1739
1458
|
`);
|
|
1740
1459
|
}
|
|
@@ -1815,7 +1534,7 @@ async function writeInitExtras(projectDir) {
|
|
|
1815
1534
|
|
|
1816
1535
|
// src/commands/recap.ts
|
|
1817
1536
|
import inquirer3 from "inquirer";
|
|
1818
|
-
import
|
|
1537
|
+
import chalk5 from "chalk";
|
|
1819
1538
|
import fs5 from "fs";
|
|
1820
1539
|
import path6 from "path";
|
|
1821
1540
|
|
|
@@ -1974,40 +1693,40 @@ function createAdrFile(cwd, title, context, decision, consequences) {
|
|
|
1974
1693
|
|
|
1975
1694
|
// src/commands/recap.ts
|
|
1976
1695
|
async function recap(options = {}) {
|
|
1977
|
-
console.log(
|
|
1696
|
+
console.log(chalk5.bold(`
|
|
1978
1697
|
${ko.recap.title}
|
|
1979
1698
|
`));
|
|
1980
1699
|
if (!await isGitRepo()) {
|
|
1981
|
-
console.log(
|
|
1700
|
+
console.log(chalk5.red(ko.recap.noRepo));
|
|
1982
1701
|
return;
|
|
1983
1702
|
}
|
|
1984
1703
|
printSecurityWarnings();
|
|
1985
|
-
console.log(
|
|
1704
|
+
console.log(chalk5.dim(`${ko.recap.analyzing}
|
|
1986
1705
|
`));
|
|
1987
1706
|
const since = options.since || (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
1988
1707
|
const diff2 = await getSessionDiff(since);
|
|
1989
1708
|
const commits = await getRecentCommits(10, since);
|
|
1990
1709
|
if (diff2.filesChanged === 0 && commits.length === 0) {
|
|
1991
|
-
console.log(
|
|
1710
|
+
console.log(chalk5.yellow(ko.recap.noChanges));
|
|
1992
1711
|
return;
|
|
1993
1712
|
}
|
|
1994
|
-
console.log(
|
|
1995
|
-
console.log(` \uD30C\uC77C: ${
|
|
1996
|
-
console.log(` \uCD94\uAC00: ${
|
|
1713
|
+
console.log(chalk5.bold("\u{1F4CA} \uBCC0\uACBD \uC694\uC57D:"));
|
|
1714
|
+
console.log(` \uD30C\uC77C: ${chalk5.cyan(String(diff2.filesChanged))}\uAC1C \uBCC0\uACBD`);
|
|
1715
|
+
console.log(` \uCD94\uAC00: ${chalk5.green("+" + diff2.insertions)} / \uC0AD\uC81C: ${chalk5.red("-" + diff2.deletions)}`);
|
|
1997
1716
|
if (diff2.files.length > 0) {
|
|
1998
|
-
console.log(
|
|
1717
|
+
console.log(chalk5.dim("\n \uBCC0\uACBD \uD30C\uC77C:"));
|
|
1999
1718
|
diff2.files.slice(0, 15).forEach((f) => {
|
|
2000
|
-
const icon = f.status === "new" ?
|
|
1719
|
+
const icon = f.status === "new" ? chalk5.green("\u{1F195}") : f.status === "deleted" ? chalk5.red("\u{1F5D1}\uFE0F") : chalk5.yellow("\u270F\uFE0F");
|
|
2001
1720
|
console.log(` ${icon} ${f.file}`);
|
|
2002
1721
|
});
|
|
2003
1722
|
if (diff2.files.length > 15) {
|
|
2004
|
-
console.log(
|
|
1723
|
+
console.log(chalk5.dim(` ... \uC678 ${diff2.files.length - 15}\uAC1C`));
|
|
2005
1724
|
}
|
|
2006
1725
|
}
|
|
2007
1726
|
if (commits.length > 0) {
|
|
2008
|
-
console.log(
|
|
1727
|
+
console.log(chalk5.dim("\n \uCD5C\uADFC \uCEE4\uBC0B:"));
|
|
2009
1728
|
commits.slice(0, 5).forEach((c) => {
|
|
2010
|
-
console.log(
|
|
1729
|
+
console.log(chalk5.dim(` \u2022 ${c.message}`));
|
|
2011
1730
|
});
|
|
2012
1731
|
}
|
|
2013
1732
|
console.log("");
|
|
@@ -2075,11 +1794,11 @@ ${ko.recap.title}
|
|
|
2075
1794
|
fs5.writeFileSync(filePath, content, "utf-8");
|
|
2076
1795
|
const adrCandidates = detectAdrCandidates(diff2);
|
|
2077
1796
|
if (adrCandidates.length > 0) {
|
|
2078
|
-
console.log(
|
|
1797
|
+
console.log(chalk5.cyan.bold(`
|
|
2079
1798
|
${ko.recap.adrDetected} (${adrCandidates.length}\uAC74)`));
|
|
2080
1799
|
for (const candidate of adrCandidates) {
|
|
2081
|
-
console.log(
|
|
2082
|
-
candidate.files.forEach((f) => console.log(
|
|
1800
|
+
console.log(chalk5.cyan(` \u2022 ${candidate.title}: ${candidate.context}`));
|
|
1801
|
+
candidate.files.forEach((f) => console.log(chalk5.dim(` ${f}`)));
|
|
2083
1802
|
}
|
|
2084
1803
|
const { createAdr } = await inquirer3.prompt([{
|
|
2085
1804
|
type: "confirm",
|
|
@@ -2109,17 +1828,17 @@ ${ko.recap.adrDetected} (${adrCandidates.length}\uAC74)`));
|
|
|
2109
1828
|
adrAnswers.decision,
|
|
2110
1829
|
adrAnswers.consequences
|
|
2111
1830
|
);
|
|
2112
|
-
console.log(
|
|
1831
|
+
console.log(chalk5.green(` \u2705 ADR \uC0DD\uC131: ${path6.relative(process.cwd(), adrPath)}`));
|
|
2113
1832
|
}
|
|
2114
1833
|
}
|
|
2115
1834
|
}
|
|
2116
1835
|
const troubleshootingKeywords = /fix|bug|error|crash|hotfix|patch|revert|트러블|에러|버그|수정|핫픽스/i;
|
|
2117
1836
|
const troubleCommits = commits.filter((c) => troubleshootingKeywords.test(c.message));
|
|
2118
1837
|
if (troubleCommits.length > 0) {
|
|
2119
|
-
console.log(
|
|
1838
|
+
console.log(chalk5.yellow.bold(`
|
|
2120
1839
|
${ko.recap.troubleDetected} (${troubleCommits.length}\uAC74)`));
|
|
2121
1840
|
troubleCommits.forEach((c) => {
|
|
2122
|
-
console.log(
|
|
1841
|
+
console.log(chalk5.dim(` \u2022 ${c.message}`));
|
|
2123
1842
|
});
|
|
2124
1843
|
const { createTroubleshoot } = await inquirer3.prompt([{
|
|
2125
1844
|
type: "confirm",
|
|
@@ -2170,12 +1889,12 @@ ${ko.recap.troubleDetected} (${troubleCommits.length}\uAC74)`));
|
|
|
2170
1889
|
`*Generated by \`vhk recap\` at ${(/* @__PURE__ */ new Date()).toISOString()}*`
|
|
2171
1890
|
].join("\n");
|
|
2172
1891
|
fs5.writeFileSync(tsFilePath, tsContent, "utf-8");
|
|
2173
|
-
console.log(
|
|
1892
|
+
console.log(chalk5.green(` \u2705 \uD2B8\uB7EC\uBE14\uC288\uD305 \uBB38\uC11C \uC0DD\uC131: ${path6.relative(process.cwd(), tsFilePath)}`));
|
|
2174
1893
|
}
|
|
2175
1894
|
}
|
|
2176
|
-
console.log(
|
|
1895
|
+
console.log(chalk5.green.bold(`
|
|
2177
1896
|
${ko.recap.done}`));
|
|
2178
|
-
console.log(
|
|
1897
|
+
console.log(chalk5.dim(` \u{1F4C4} ${path6.relative(process.cwd(), filePath)}`));
|
|
2179
1898
|
const claudeMdPath = path6.join(process.cwd(), "CLAUDE.md");
|
|
2180
1899
|
if (fs5.existsSync(claudeMdPath)) {
|
|
2181
1900
|
const { updateClaude } = await inquirer3.prompt([{
|
|
@@ -2195,7 +1914,7 @@ ${ko.recap.done}`));
|
|
|
2195
1914
|
`- **\uB2E4\uC74C \uC561\uC158:** ${answers.nextTodo}`
|
|
2196
1915
|
);
|
|
2197
1916
|
fs5.writeFileSync(claudeMdPath, claudeContent, "utf-8");
|
|
2198
|
-
console.log(
|
|
1917
|
+
console.log(chalk5.green(" \u2705 CLAUDE.md \uC5C5\uB370\uC774\uD2B8 \uC644\uB8CC"));
|
|
2199
1918
|
}
|
|
2200
1919
|
}
|
|
2201
1920
|
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 +1926,7 @@ ${ko.recap.done}`));
|
|
|
2207
1926
|
}
|
|
2208
1927
|
|
|
2209
1928
|
// src/commands/sync.ts
|
|
2210
|
-
import
|
|
1929
|
+
import chalk6 from "chalk";
|
|
2211
1930
|
import fs6 from "fs";
|
|
2212
1931
|
import path7 from "path";
|
|
2213
1932
|
var CURSORRULES_KEYS = ["\uCF54\uB529 \uADDC\uCE59", "\uAE30\uC220 \uC2A4\uD0DD", "\uC544\uD0A4\uD14D\uCC98", "\uB514\uC790\uC778", "Anti-patterns", "\uCEE4\uBC0B"];
|
|
@@ -2277,32 +1996,32 @@ function toClaudeMd(sections, existing) {
|
|
|
2277
1996
|
return lines.join("\n");
|
|
2278
1997
|
}
|
|
2279
1998
|
async function sync() {
|
|
2280
|
-
console.log(
|
|
1999
|
+
console.log(chalk6.bold(`
|
|
2281
2000
|
${ko.sync.title}
|
|
2282
2001
|
`));
|
|
2283
2002
|
const cwd = process.cwd();
|
|
2284
2003
|
const rulesPath = path7.join(cwd, "RULES.md");
|
|
2285
2004
|
if (!fs6.existsSync(rulesPath)) {
|
|
2286
|
-
console.log(
|
|
2287
|
-
console.log(
|
|
2288
|
-
console.log(
|
|
2005
|
+
console.log(chalk6.yellow(ko.sync.noRules));
|
|
2006
|
+
console.log(chalk6.dim(" RULES.md\uB294 \uD504\uB85C\uC81D\uD2B8 \uADDC\uCE59\uC758 Single Source of Truth\uC785\uB2C8\uB2E4."));
|
|
2007
|
+
console.log(chalk6.dim(" \uC0DD\uC131\uD558\uB824\uBA74: vhk init \uC2E4\uD589 \uD6C4 RULES.md\uB97C \uC791\uC131\uD558\uC138\uC694."));
|
|
2289
2008
|
console.log("");
|
|
2290
|
-
console.log(
|
|
2291
|
-
console.log(
|
|
2292
|
-
console.log(
|
|
2293
|
-
console.log(
|
|
2294
|
-
console.log(
|
|
2295
|
-
console.log(
|
|
2009
|
+
console.log(chalk6.dim(" RULES.md \uAE30\uBCF8 \uAD6C\uC870:"));
|
|
2010
|
+
console.log(chalk6.dim(" ## \uD504\uB85C\uC81D\uD2B8 \uC815\uCCB4\uC131"));
|
|
2011
|
+
console.log(chalk6.dim(" ## \uAE30\uC220 \uC2A4\uD0DD"));
|
|
2012
|
+
console.log(chalk6.dim(" ## \uCF54\uB529 \uADDC\uCE59"));
|
|
2013
|
+
console.log(chalk6.dim(" ## \uAE30\uB85D \uADDC\uCE59"));
|
|
2014
|
+
console.log(chalk6.dim(" ## \uCEE4\uBC0B \uCEE8\uBCA4\uC158"));
|
|
2296
2015
|
return;
|
|
2297
2016
|
}
|
|
2298
2017
|
const rulesContent = fs6.readFileSync(rulesPath, "utf-8");
|
|
2299
2018
|
const sections = parseRulesMd(rulesContent);
|
|
2300
|
-
console.log(
|
|
2019
|
+
console.log(chalk6.dim(` \u{1F4C4} RULES.md \uD30C\uC2F1 \uC644\uB8CC \u2014 ${sections.length}\uAC1C \uC139\uC158`));
|
|
2301
2020
|
const firstLine = rulesContent.split("\n")[0];
|
|
2302
2021
|
const projectName = firstLine.replace(/^#\s*/, "").replace(/\s*—.*/, "").trim() || "Project";
|
|
2303
2022
|
const cursorrulesPath = path7.join(cwd, ".cursorrules");
|
|
2304
2023
|
fs6.writeFileSync(cursorrulesPath, toCursorrules(sections, projectName), "utf-8");
|
|
2305
|
-
console.log(
|
|
2024
|
+
console.log(chalk6.green(` ${ko.sync.cursorrulesDone}`));
|
|
2306
2025
|
const claudePath = path7.join(cwd, "CLAUDE.md");
|
|
2307
2026
|
const existingClaude = fs6.existsSync(claudePath) ? fs6.readFileSync(claudePath, "utf-8") : `# \uAE30\uB85D \uADDC\uCE59 (${projectName})
|
|
2308
2027
|
|
|
@@ -2312,11 +2031,11 @@ ${ko.sync.title}
|
|
|
2312
2031
|
- **\uB2E4\uC74C \uC561\uC158:** __FILL__
|
|
2313
2032
|
- **\uB9C8\uC9C0\uB9C9 \uC5C5\uB370\uC774\uD2B8:** ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}`;
|
|
2314
2033
|
fs6.writeFileSync(claudePath, toClaudeMd(sections, existingClaude), "utf-8");
|
|
2315
|
-
console.log(
|
|
2316
|
-
console.log(
|
|
2034
|
+
console.log(chalk6.green(` ${ko.sync.claudeDone}`));
|
|
2035
|
+
console.log(chalk6.bold.green(`
|
|
2317
2036
|
${ko.sync.done}`));
|
|
2318
|
-
console.log(
|
|
2319
|
-
console.log(
|
|
2037
|
+
console.log(chalk6.dim(" RULES.md (\uC6D0\uBCF8) \u2192 .cursorrules + CLAUDE.md (\uC790\uB3D9 \uC0DD\uC131)"));
|
|
2038
|
+
console.log(chalk6.dim(" \uADDC\uCE59 \uBCC0\uACBD\uC740 \uD56D\uC0C1 RULES.md\uC5D0\uC11C\uB9CC \uD558\uC138\uC694."));
|
|
2320
2039
|
printNextStep({
|
|
2321
2040
|
message: "\uADDC\uCE59 \uB3D9\uAE30\uD654 \uC644\uB8CC! \uC774\uC81C Cursor\uAC00 \uC0C8 \uADDC\uCE59\uC744 \uB530\uB985\uB2C8\uB2E4.",
|
|
2322
2041
|
command: "vhk \uC810\uAC80",
|
|
@@ -2325,7 +2044,7 @@ ${ko.sync.done}`));
|
|
|
2325
2044
|
}
|
|
2326
2045
|
|
|
2327
2046
|
// src/commands/check.ts
|
|
2328
|
-
import
|
|
2047
|
+
import chalk7 from "chalk";
|
|
2329
2048
|
import path9 from "path";
|
|
2330
2049
|
import fs8 from "fs";
|
|
2331
2050
|
|
|
@@ -2484,22 +2203,22 @@ function escapeRegex(str) {
|
|
|
2484
2203
|
|
|
2485
2204
|
// src/commands/check.ts
|
|
2486
2205
|
async function check() {
|
|
2487
|
-
console.log(
|
|
2206
|
+
console.log(chalk7.bold(`
|
|
2488
2207
|
${ko.check.title}
|
|
2489
2208
|
`));
|
|
2490
2209
|
const cwd = process.cwd();
|
|
2491
2210
|
const rulesPath = path9.join(cwd, "RULES.md");
|
|
2492
2211
|
if (!fs8.existsSync(rulesPath)) {
|
|
2493
|
-
console.log(
|
|
2494
|
-
console.log(
|
|
2212
|
+
console.log(chalk7.yellow(ko.check.noRules));
|
|
2213
|
+
console.log(chalk7.dim(" vhk init\uC73C\uB85C \uC2DC\uC791\uD558\uAC70\uB098 RULES.md\uB97C \uB9CC\uB4E4\uC5B4 \uBCF4\uC138\uC694."));
|
|
2495
2214
|
return;
|
|
2496
2215
|
}
|
|
2497
2216
|
const rules = parseRules(rulesPath);
|
|
2498
|
-
console.log(
|
|
2217
|
+
console.log(chalk7.dim(` \u{1F4CF} ${rules.length}\uAC1C \uAC80\uC99D \uAC00\uB2A5\uD55C \uADDC\uCE59 \uAC10\uC9C0
|
|
2499
2218
|
`));
|
|
2500
2219
|
if (rules.length === 0) {
|
|
2501
|
-
console.log(
|
|
2502
|
-
console.log(
|
|
2220
|
+
console.log(chalk7.yellow(ko.check.noAutoRules));
|
|
2221
|
+
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
2222
|
return;
|
|
2504
2223
|
}
|
|
2505
2224
|
const allViolations = [];
|
|
@@ -2507,13 +2226,13 @@ ${ko.check.title}
|
|
|
2507
2226
|
for (const rule of rules) {
|
|
2508
2227
|
const violations = rule.check(cwd);
|
|
2509
2228
|
if (violations.length === 0) {
|
|
2510
|
-
console.log(
|
|
2229
|
+
console.log(chalk7.green(` \u2705 ${rule.id}`) + chalk7.dim(` \u2014 ${rule.description.slice(0, 60)}`));
|
|
2511
2230
|
passCount++;
|
|
2512
2231
|
} else {
|
|
2513
|
-
console.log(
|
|
2232
|
+
console.log(chalk7.red(` \u274C ${rule.id}`) + chalk7.dim(` \u2014 ${violations.length}\uAC74 \uC704\uBC18`));
|
|
2514
2233
|
violations.forEach((v) => {
|
|
2515
|
-
const loc = v.file ?
|
|
2516
|
-
const icon = v.severity === "error" ?
|
|
2234
|
+
const loc = v.file ? chalk7.dim(` (${v.file}${v.line ? ":" + v.line : ""})`) : "";
|
|
2235
|
+
const icon = v.severity === "error" ? chalk7.red("\u2716") : v.severity === "warning" ? chalk7.yellow("\u26A0") : chalk7.blue("\u2139");
|
|
2517
2236
|
console.log(` ${icon} ${v.message}${loc}`);
|
|
2518
2237
|
});
|
|
2519
2238
|
allViolations.push(...violations);
|
|
@@ -2523,17 +2242,17 @@ ${ko.check.title}
|
|
|
2523
2242
|
const errors = allViolations.filter((v) => v.severity === "error").length;
|
|
2524
2243
|
const warnings = allViolations.filter((v) => v.severity === "warning").length;
|
|
2525
2244
|
if (allViolations.length === 0) {
|
|
2526
|
-
console.log(
|
|
2245
|
+
console.log(chalk7.green.bold(`${ko.check.allPassed} (${passCount}/${rules.length})`));
|
|
2527
2246
|
printNextStep({
|
|
2528
2247
|
message: "\uBAA8\uB4E0 \uADDC\uCE59 \uD1B5\uACFC! \uBCF4\uC548 \uC2A4\uCE94\uB3C4 \uD574\uBCFC\uAE4C\uC694?",
|
|
2529
2248
|
command: "vhk \uBCF4\uC548 scan",
|
|
2530
2249
|
cursorHint: "\uBCF4\uC548 \uC2A4\uCE94 \uB3CC\uB824\uC918"
|
|
2531
2250
|
});
|
|
2532
2251
|
} else {
|
|
2533
|
-
console.log(
|
|
2534
|
-
console.log(` \uADDC\uCE59: ${
|
|
2535
|
-
if (errors > 0) console.log(` ${
|
|
2536
|
-
if (warnings > 0) console.log(` ${
|
|
2252
|
+
console.log(chalk7.bold(ko.check.summary));
|
|
2253
|
+
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`);
|
|
2254
|
+
if (errors > 0) console.log(` ${chalk7.red(`\u2716 ${errors}\uAC1C \uC5D0\uB7EC`)}`);
|
|
2255
|
+
if (warnings > 0) console.log(` ${chalk7.yellow(`\u26A0 ${warnings}\uAC1C \uACBD\uACE0`)}`);
|
|
2537
2256
|
printNextStep({
|
|
2538
2257
|
message: "\uC704\uBC18 \uD56D\uBAA9\uC744 \uC218\uC815\uD55C \uD6C4 \uB2E4\uC2DC \uC810\uAC80\uD558\uC138\uC694.",
|
|
2539
2258
|
command: "vhk \uC810\uAC80",
|
|
@@ -2546,7 +2265,7 @@ ${ko.check.title}
|
|
|
2546
2265
|
}
|
|
2547
2266
|
|
|
2548
2267
|
// src/commands/secure.ts
|
|
2549
|
-
import
|
|
2268
|
+
import chalk8 from "chalk";
|
|
2550
2269
|
import fs11 from "fs";
|
|
2551
2270
|
import path11 from "path";
|
|
2552
2271
|
|
|
@@ -2747,32 +2466,32 @@ function filterSevereFindings(findings) {
|
|
|
2747
2466
|
|
|
2748
2467
|
// src/commands/secure.ts
|
|
2749
2468
|
async function secure() {
|
|
2750
|
-
console.log(
|
|
2469
|
+
console.log(chalk8.bold(`
|
|
2751
2470
|
${ko.secure.title}
|
|
2752
2471
|
`));
|
|
2753
2472
|
const cwd = process.cwd();
|
|
2754
2473
|
const gitignorePath = path11.join(cwd, ".gitignore");
|
|
2755
2474
|
const hasGitignore = fs11.existsSync(gitignorePath);
|
|
2756
2475
|
if (!hasGitignore) {
|
|
2757
|
-
console.log(
|
|
2758
|
-
console.log(
|
|
2476
|
+
console.log(chalk8.yellow(` ${ko.secure.noGitignore}`));
|
|
2477
|
+
console.log(chalk8.dim(" .env \uD30C\uC77C\uC774 \uCEE4\uBC0B\uB420 \uC218 \uC788\uC2B5\uB2C8\uB2E4.\n"));
|
|
2759
2478
|
} else {
|
|
2760
2479
|
const gitignoreContent = fs11.readFileSync(gitignorePath, "utf-8");
|
|
2761
2480
|
if (!gitignoreContent.includes(".env")) {
|
|
2762
|
-
console.log(
|
|
2763
|
-
console.log(
|
|
2481
|
+
console.log(chalk8.yellow(` ${ko.secure.noEnvInGitignore}`));
|
|
2482
|
+
console.log(chalk8.dim(" \uCD94\uAC00\uB97C \uAD8C\uC7A5\uD569\uB2C8\uB2E4.\n"));
|
|
2764
2483
|
}
|
|
2765
2484
|
}
|
|
2766
|
-
console.log(
|
|
2485
|
+
console.log(chalk8.dim(` ${ko.secure.scanning}
|
|
2767
2486
|
`));
|
|
2768
2487
|
const { findings, scannedFiles, truncated } = scanProjectForSecrets(cwd);
|
|
2769
|
-
console.log(
|
|
2488
|
+
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
2489
|
if (truncated) {
|
|
2771
|
-
console.log(
|
|
2490
|
+
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
2491
|
}
|
|
2773
2492
|
console.log("");
|
|
2774
2493
|
if (findings.length === 0) {
|
|
2775
|
-
console.log(
|
|
2494
|
+
console.log(chalk8.green.bold(` ${ko.secure.clean}`));
|
|
2776
2495
|
printNextStep({
|
|
2777
2496
|
message: "\uBCF4\uC548 \uC774\uC0C1 \uC5C6\uC74C! \uAE68\uB057\uD569\uB2C8\uB2E4.",
|
|
2778
2497
|
command: "vhk \uC815\uB9AC",
|
|
@@ -2784,43 +2503,43 @@ ${ko.secure.title}
|
|
|
2784
2503
|
const high = findings.filter((f) => f.severity === "high");
|
|
2785
2504
|
const medium = findings.filter((f) => f.severity === "medium");
|
|
2786
2505
|
if (critical.length > 0) {
|
|
2787
|
-
console.log(
|
|
2506
|
+
console.log(chalk8.red.bold(` \u{1F6A8} CRITICAL \u2014 ${critical.length}\uAC74`));
|
|
2788
2507
|
critical.forEach((f) => {
|
|
2789
|
-
console.log(
|
|
2790
|
-
console.log(
|
|
2508
|
+
console.log(chalk8.red(` \u2716 ${f.patternName}`));
|
|
2509
|
+
console.log(chalk8.dim(` ${f.file}:${f.line} \u2192 ${f.match}`));
|
|
2791
2510
|
});
|
|
2792
2511
|
console.log("");
|
|
2793
2512
|
}
|
|
2794
2513
|
if (high.length > 0) {
|
|
2795
|
-
console.log(
|
|
2514
|
+
console.log(chalk8.yellow.bold(` \u26A0\uFE0F HIGH \u2014 ${high.length}\uAC74`));
|
|
2796
2515
|
high.forEach((f) => {
|
|
2797
|
-
console.log(
|
|
2798
|
-
console.log(
|
|
2516
|
+
console.log(chalk8.yellow(` \u26A0 ${f.patternName}`));
|
|
2517
|
+
console.log(chalk8.dim(` ${f.file}:${f.line} \u2192 ${f.match}`));
|
|
2799
2518
|
});
|
|
2800
2519
|
console.log("");
|
|
2801
2520
|
}
|
|
2802
2521
|
if (medium.length > 0) {
|
|
2803
|
-
console.log(
|
|
2522
|
+
console.log(chalk8.blue.bold(` \u2139 MEDIUM \u2014 ${medium.length}\uAC74`));
|
|
2804
2523
|
medium.forEach((f) => {
|
|
2805
|
-
console.log(
|
|
2806
|
-
console.log(
|
|
2524
|
+
console.log(chalk8.blue(` \u2139 ${f.patternName}`));
|
|
2525
|
+
console.log(chalk8.dim(` ${f.file}:${f.line} \u2192 ${f.match}`));
|
|
2807
2526
|
});
|
|
2808
2527
|
console.log("");
|
|
2809
2528
|
}
|
|
2810
|
-
console.log(
|
|
2811
|
-
console.log(` \uCD1D ${
|
|
2529
|
+
console.log(chalk8.bold(` ${ko.secure.summary}`));
|
|
2530
|
+
console.log(` \uCD1D ${chalk8.red(String(findings.length))}\uAC74 \uAC10\uC9C0 | CRITICAL: ${critical.length} | HIGH: ${high.length} | MEDIUM: ${medium.length}`);
|
|
2812
2531
|
console.log("");
|
|
2813
|
-
console.log(
|
|
2814
|
-
console.log(
|
|
2815
|
-
console.log(
|
|
2816
|
-
console.log(
|
|
2532
|
+
console.log(chalk8.dim(" \u{1F4A1} \uC870\uCE58 \uBC29\uBC95:"));
|
|
2533
|
+
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"));
|
|
2534
|
+
console.log(chalk8.dim(" 2. git history\uC5D0\uC11C\uB3C4 \uC81C\uAC70: git filter-branch \uB610\uB294 BFG Repo-Cleaner"));
|
|
2535
|
+
console.log(chalk8.dim(" 3. \uC720\uCD9C\uB41C \uD0A4\uB294 \uC989\uC2DC \uD3D0\uAE30\uD558\uACE0 \uC7AC\uBC1C\uAE09\n"));
|
|
2817
2536
|
if (critical.length > 0 || high.length > 0) {
|
|
2818
2537
|
process.exitCode = 1;
|
|
2819
2538
|
}
|
|
2820
2539
|
}
|
|
2821
2540
|
|
|
2822
2541
|
// src/commands/doctor.ts
|
|
2823
|
-
import
|
|
2542
|
+
import chalk9 from "chalk";
|
|
2824
2543
|
import { execSync } from "child_process";
|
|
2825
2544
|
import fs12 from "fs";
|
|
2826
2545
|
import path12 from "path";
|
|
@@ -2873,7 +2592,7 @@ function compareSemver(a, b) {
|
|
|
2873
2592
|
return a3 - b3;
|
|
2874
2593
|
}
|
|
2875
2594
|
async function doctor() {
|
|
2876
|
-
console.log(
|
|
2595
|
+
console.log(chalk9.bold(`
|
|
2877
2596
|
${ko.doctor.title}
|
|
2878
2597
|
`));
|
|
2879
2598
|
const checks = [
|
|
@@ -2885,30 +2604,30 @@ ${ko.doctor.title}
|
|
|
2885
2604
|
let allOk = true;
|
|
2886
2605
|
for (const check2 of checks) {
|
|
2887
2606
|
if (check2.ok) {
|
|
2888
|
-
console.log(
|
|
2607
|
+
console.log(chalk9.green(` \u2705 ${check2.name}`) + chalk9.dim(` \u2014 ${check2.version}`));
|
|
2889
2608
|
} else {
|
|
2890
|
-
console.log(
|
|
2891
|
-
console.log(
|
|
2609
|
+
console.log(chalk9.red(` \u274C ${check2.name} \uC5C6\uC74C`));
|
|
2610
|
+
console.log(chalk9.dim(` \u2192 ${check2.hint}`));
|
|
2892
2611
|
allOk = false;
|
|
2893
2612
|
}
|
|
2894
2613
|
}
|
|
2895
2614
|
console.log("");
|
|
2896
2615
|
const vhkVersion = getVhkVersion();
|
|
2897
2616
|
if (vhkVersion) {
|
|
2898
|
-
console.log(
|
|
2617
|
+
console.log(chalk9.green(" \u2705 VHK") + chalk9.dim(` \u2014 v${vhkVersion}`));
|
|
2899
2618
|
} else {
|
|
2900
|
-
console.log(
|
|
2619
|
+
console.log(chalk9.green(" \u2705 VHK") + chalk9.dim(" \u2014 \uC124\uCE58\uB428"));
|
|
2901
2620
|
}
|
|
2902
2621
|
if (vhkVersion) {
|
|
2903
2622
|
const latest = fetchLatestNpmVersion("@byh3071/vhk");
|
|
2904
2623
|
if (latest && compareSemver(latest, vhkVersion) > 0) {
|
|
2905
|
-
console.log(
|
|
2624
|
+
console.log(chalk9.yellow(` ${ko.doctor.updateAvailable(latest)}`));
|
|
2906
2625
|
} else if (latest) {
|
|
2907
|
-
console.log(
|
|
2626
|
+
console.log(chalk9.dim(` ${ko.doctor.updateCurrent}`));
|
|
2908
2627
|
}
|
|
2909
2628
|
}
|
|
2910
2629
|
console.log("");
|
|
2911
|
-
console.log(
|
|
2630
|
+
console.log(chalk9.bold(` ${ko.doctor.projectFiles}`));
|
|
2912
2631
|
const cwd = process.cwd();
|
|
2913
2632
|
const projectFiles = [
|
|
2914
2633
|
{ name: "RULES.md", hint: "vhk init\uC73C\uB85C \uC0DD\uC131 \uAC00\uB2A5" },
|
|
@@ -2920,30 +2639,30 @@ ${ko.doctor.title}
|
|
|
2920
2639
|
for (const file of projectFiles) {
|
|
2921
2640
|
const exists = fs12.existsSync(path12.join(cwd, file.name));
|
|
2922
2641
|
if (exists) {
|
|
2923
|
-
console.log(
|
|
2642
|
+
console.log(chalk9.green(` \u2705 ${file.name}`));
|
|
2924
2643
|
if (file.name === ".env") {
|
|
2925
2644
|
const gitignorePath = path12.join(cwd, ".gitignore");
|
|
2926
2645
|
if (fs12.existsSync(gitignorePath)) {
|
|
2927
2646
|
const gitignore = fs12.readFileSync(gitignorePath, "utf-8");
|
|
2928
2647
|
if (!gitignore.includes(".env")) {
|
|
2929
|
-
console.log(
|
|
2648
|
+
console.log(chalk9.yellow(` ${ko.doctor.envNotIgnored}`));
|
|
2930
2649
|
}
|
|
2931
2650
|
}
|
|
2932
2651
|
}
|
|
2933
2652
|
} else {
|
|
2934
|
-
console.log(
|
|
2653
|
+
console.log(chalk9.dim(` \u2B1A ${file.name}`) + chalk9.dim(` \u2014 ${file.hint}`));
|
|
2935
2654
|
}
|
|
2936
2655
|
}
|
|
2937
2656
|
console.log("");
|
|
2938
2657
|
if (allOk) {
|
|
2939
|
-
console.log(
|
|
2658
|
+
console.log(chalk9.green.bold(` ${ko.doctor.allOk}`));
|
|
2940
2659
|
printNextStep({
|
|
2941
2660
|
message: ko.doctor.nextOkMessage,
|
|
2942
2661
|
command: "vhk \uC2DC\uC791",
|
|
2943
2662
|
cursorHint: "\uD504\uB85C\uC81D\uD2B8 \uB9CC\uB4E4\uC5B4\uC918"
|
|
2944
2663
|
});
|
|
2945
2664
|
} else {
|
|
2946
|
-
console.log(
|
|
2665
|
+
console.log(chalk9.yellow.bold(` ${ko.doctor.missing} ${ko.doctor.missingHint}`));
|
|
2947
2666
|
printNextStep({
|
|
2948
2667
|
message: ko.doctor.nextRetryMessage,
|
|
2949
2668
|
command: "vhk doctor",
|
|
@@ -2954,7 +2673,7 @@ ${ko.doctor.title}
|
|
|
2954
2673
|
}
|
|
2955
2674
|
|
|
2956
2675
|
// src/commands/ship.ts
|
|
2957
|
-
import
|
|
2676
|
+
import chalk10 from "chalk";
|
|
2958
2677
|
import inquirer4 from "inquirer";
|
|
2959
2678
|
import fs13 from "fs";
|
|
2960
2679
|
import path13 from "path";
|
|
@@ -2993,29 +2712,29 @@ function updateChangelogUnreleased(cwd, version, date) {
|
|
|
2993
2712
|
return { status: "updated", version };
|
|
2994
2713
|
}
|
|
2995
2714
|
async function ship() {
|
|
2996
|
-
console.log(
|
|
2715
|
+
console.log(chalk10.bold(`
|
|
2997
2716
|
${ko.ship.title}
|
|
2998
2717
|
`));
|
|
2999
2718
|
const cwd = process.cwd();
|
|
3000
|
-
console.log(
|
|
2719
|
+
console.log(chalk10.cyan.bold(` ${ko.ship.checklist}
|
|
3001
2720
|
`));
|
|
3002
2721
|
const { passed } = await inquirer4.prompt([{
|
|
3003
2722
|
type: "checkbox",
|
|
3004
2723
|
name: "passed",
|
|
3005
2724
|
message: ko.ship.checkboxPrompt,
|
|
3006
2725
|
choices: CHECKLIST.map((c) => ({
|
|
3007
|
-
name: `${ko.ship[c.questionKey]} ${
|
|
2726
|
+
name: `${ko.ship[c.questionKey]} ${chalk10.dim(`(${ko.ship[c.hintKey]})`)}`,
|
|
3008
2727
|
value: c.id
|
|
3009
2728
|
}))
|
|
3010
2729
|
}]);
|
|
3011
2730
|
const allPassed = passed.length === CHECKLIST.length;
|
|
3012
2731
|
const skipped = CHECKLIST.filter((c) => !passed.includes(c.id));
|
|
3013
2732
|
if (!allPassed) {
|
|
3014
|
-
console.log(
|
|
2733
|
+
console.log(chalk10.yellow(`
|
|
3015
2734
|
${ko.ship.incompleteHeader}`));
|
|
3016
2735
|
skipped.forEach((s) => {
|
|
3017
|
-
console.log(
|
|
3018
|
-
console.log(
|
|
2736
|
+
console.log(chalk10.yellow(` \u2022 ${ko.ship[s.questionKey]}`));
|
|
2737
|
+
console.log(chalk10.dim(` \u2192 ${ko.ship[s.hintKey]}`));
|
|
3019
2738
|
});
|
|
3020
2739
|
const { proceed } = await inquirer4.prompt([{
|
|
3021
2740
|
type: "confirm",
|
|
@@ -3032,13 +2751,13 @@ ${ko.ship.title}
|
|
|
3032
2751
|
return;
|
|
3033
2752
|
}
|
|
3034
2753
|
} else {
|
|
3035
|
-
console.log(
|
|
2754
|
+
console.log(chalk10.green(`
|
|
3036
2755
|
${ko.ship.allPassed}
|
|
3037
2756
|
`));
|
|
3038
2757
|
}
|
|
3039
|
-
console.log(
|
|
2758
|
+
console.log(chalk10.cyan.bold(` ${ko.ship.retro}
|
|
3040
2759
|
`));
|
|
3041
|
-
console.log(
|
|
2760
|
+
console.log(chalk10.dim(` ${ko.ship.versionHint}`));
|
|
3042
2761
|
const retro = await inquirer4.prompt([
|
|
3043
2762
|
{ type: "input", name: "version", message: ko.ship.versionPrompt },
|
|
3044
2763
|
{ type: "input", name: "whatWentWell", message: ko.ship.questionWell },
|
|
@@ -3081,7 +2800,7 @@ ${ko.ship.title}
|
|
|
3081
2800
|
`*Generated by \`vhk ship\` at ${(/* @__PURE__ */ new Date()).toISOString()}*`
|
|
3082
2801
|
].join("\n");
|
|
3083
2802
|
fs13.writeFileSync(filePath, content, "utf-8");
|
|
3084
|
-
console.log(
|
|
2803
|
+
console.log(chalk10.green(`
|
|
3085
2804
|
${ko.ship.buildLogDone(path13.relative(cwd, filePath))}`));
|
|
3086
2805
|
const changelogResult = updateChangelogUnreleased(cwd, versionSlug, today);
|
|
3087
2806
|
if (changelogResult.status === "updated") {
|
|
@@ -3101,7 +2820,7 @@ ${ko.ship.title}
|
|
|
3101
2820
|
|
|
3102
2821
|
// src/commands/save.ts
|
|
3103
2822
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
3104
|
-
import
|
|
2823
|
+
import chalk11 from "chalk";
|
|
3105
2824
|
import ora from "ora";
|
|
3106
2825
|
import inquirer5 from "inquirer";
|
|
3107
2826
|
|
|
@@ -3172,29 +2891,29 @@ function statusIcon(code) {
|
|
|
3172
2891
|
return "\u{1F4C4}";
|
|
3173
2892
|
}
|
|
3174
2893
|
async function save() {
|
|
3175
|
-
console.log(
|
|
2894
|
+
console.log(chalk11.bold(`
|
|
3176
2895
|
\u{1F4BE} ${t("save.title")}`));
|
|
3177
|
-
console.log(
|
|
2896
|
+
console.log(chalk11.gray("\u2500".repeat(40)));
|
|
3178
2897
|
let gitRoot;
|
|
3179
2898
|
try {
|
|
3180
2899
|
execFileSync2("git", ["rev-parse", "--is-inside-work-tree"], { stdio: "pipe" });
|
|
3181
2900
|
gitRoot = getGitRoot();
|
|
3182
2901
|
} catch {
|
|
3183
|
-
console.log(
|
|
2902
|
+
console.log(chalk11.red(`\u274C ${t("save.notGitRepo")}`));
|
|
3184
2903
|
return;
|
|
3185
2904
|
}
|
|
3186
|
-
console.log(
|
|
2905
|
+
console.log(chalk11.cyan(`
|
|
3187
2906
|
\u{1F512} ${t("save.securityWarnHeader")}`));
|
|
3188
2907
|
printSecurityWarnings(gitRoot);
|
|
3189
2908
|
const severe = filterSevereFindings(scanProjectForSecrets(gitRoot).findings);
|
|
3190
2909
|
if (severe.length > 0) {
|
|
3191
|
-
console.log(
|
|
2910
|
+
console.log(chalk11.red(`
|
|
3192
2911
|
\u26A0\uFE0F ${t("save.secretsFound", severe.length)}`));
|
|
3193
2912
|
severe.slice(0, 5).forEach((f) => {
|
|
3194
|
-
console.log(
|
|
2913
|
+
console.log(chalk11.dim(` ${f.file}:${f.line} \u2014 ${f.patternName}`));
|
|
3195
2914
|
});
|
|
3196
2915
|
if (severe.length > 5) {
|
|
3197
|
-
console.log(
|
|
2916
|
+
console.log(chalk11.dim(` ... \uC678 ${severe.length - 5}\uAC74 (vhk \uBCF4\uC548 scan)`));
|
|
3198
2917
|
}
|
|
3199
2918
|
const { proceed } = await inquirer5.prompt([{
|
|
3200
2919
|
type: "confirm",
|
|
@@ -3203,16 +2922,16 @@ async function save() {
|
|
|
3203
2922
|
default: false
|
|
3204
2923
|
}]);
|
|
3205
2924
|
if (!proceed) {
|
|
3206
|
-
console.log(
|
|
2925
|
+
console.log(chalk11.gray(t("save.cancelled")));
|
|
3207
2926
|
return;
|
|
3208
2927
|
}
|
|
3209
2928
|
}
|
|
3210
2929
|
const lines = parsePorcelainLines(gitOut(["status", "--porcelain"], gitRoot));
|
|
3211
2930
|
if (lines.length === 0) {
|
|
3212
|
-
console.log(
|
|
2931
|
+
console.log(chalk11.yellow(`\u{1F4ED} ${t("save.noChanges")}`));
|
|
3213
2932
|
return;
|
|
3214
2933
|
}
|
|
3215
|
-
console.log(
|
|
2934
|
+
console.log(chalk11.cyan(`
|
|
3216
2935
|
\u{1F4CB} ${t("save.filesHeader", lines.length)}`));
|
|
3217
2936
|
lines.forEach((line) => {
|
|
3218
2937
|
const code = line.substring(0, 2);
|
|
@@ -3234,34 +2953,34 @@ async function save() {
|
|
|
3234
2953
|
spinner.text = t("save.pushing");
|
|
3235
2954
|
if (!hasGitRemote(gitRoot)) {
|
|
3236
2955
|
spinner.succeed(t("save.successLocal"));
|
|
3237
|
-
console.log(
|
|
2956
|
+
console.log(chalk11.yellow(` \u{1F4A1} ${t("save.noRemote")}`));
|
|
3238
2957
|
} else {
|
|
3239
2958
|
try {
|
|
3240
2959
|
gitRun(["push"], gitRoot);
|
|
3241
2960
|
spinner.succeed(t("save.successWithPush"));
|
|
3242
2961
|
} catch (pushErr) {
|
|
3243
2962
|
spinner.fail(t("save.pushFailed"));
|
|
3244
|
-
console.log(
|
|
3245
|
-
console.log(
|
|
2963
|
+
console.log(chalk11.red(getExecErrorMessage(pushErr)));
|
|
2964
|
+
console.log(chalk11.yellow(`
|
|
3246
2965
|
\u{1F4A1} ${t("save.commitOkPushFailed")}`));
|
|
3247
2966
|
process.exitCode = 1;
|
|
3248
2967
|
}
|
|
3249
2968
|
}
|
|
3250
2969
|
if (process.exitCode !== 1) {
|
|
3251
|
-
console.log(
|
|
2970
|
+
console.log(chalk11.green(`
|
|
3252
2971
|
\u2705 ${t("save.done", lines.length)}`));
|
|
3253
2972
|
} else {
|
|
3254
|
-
console.log(
|
|
2973
|
+
console.log(chalk11.green(`
|
|
3255
2974
|
\u2705 ${t("save.doneLocalOnly", lines.length)}`));
|
|
3256
2975
|
}
|
|
3257
2976
|
} catch (err) {
|
|
3258
2977
|
spinner.fail(t("save.failed"));
|
|
3259
|
-
console.log(
|
|
2978
|
+
console.log(chalk11.red(getExecErrorMessage(err)));
|
|
3260
2979
|
if (didAdd) {
|
|
3261
2980
|
try {
|
|
3262
2981
|
const staged = gitOut(["diff", "--cached", "--stat"], gitRoot).trim();
|
|
3263
2982
|
if (staged) {
|
|
3264
|
-
console.log(
|
|
2983
|
+
console.log(chalk11.yellow(`
|
|
3265
2984
|
\u{1F4A1} ${t("save.stagedAfterFail")}`));
|
|
3266
2985
|
}
|
|
3267
2986
|
} catch {
|
|
@@ -3273,7 +2992,7 @@ async function save() {
|
|
|
3273
2992
|
|
|
3274
2993
|
// src/commands/undo.ts
|
|
3275
2994
|
import { execFileSync as execFileSync3 } from "child_process";
|
|
3276
|
-
import
|
|
2995
|
+
import chalk12 from "chalk";
|
|
3277
2996
|
import inquirer6 from "inquirer";
|
|
3278
2997
|
function parseRecentCommits(logOutput) {
|
|
3279
2998
|
return logOutput.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
@@ -3297,30 +3016,30 @@ function isUndoRisky(undoCount, unpushedCount, hasRemote) {
|
|
|
3297
3016
|
return false;
|
|
3298
3017
|
}
|
|
3299
3018
|
async function undo() {
|
|
3300
|
-
console.log(
|
|
3019
|
+
console.log(chalk12.bold(`
|
|
3301
3020
|
\u23EA ${t("undo.title")}`));
|
|
3302
|
-
console.log(
|
|
3021
|
+
console.log(chalk12.gray("\u2500".repeat(40)));
|
|
3303
3022
|
let gitRoot;
|
|
3304
3023
|
try {
|
|
3305
3024
|
execFileSync3("git", ["rev-parse", "--is-inside-work-tree"], { stdio: "pipe" });
|
|
3306
3025
|
gitRoot = getGitRoot();
|
|
3307
3026
|
} catch {
|
|
3308
|
-
console.log(
|
|
3027
|
+
console.log(chalk12.red(`\u274C ${t("undo.notGitRepo")}`));
|
|
3309
3028
|
return;
|
|
3310
3029
|
}
|
|
3311
3030
|
let logOutput;
|
|
3312
3031
|
try {
|
|
3313
3032
|
logOutput = gitOut(["log", "--oneline", "-5"], gitRoot).trim();
|
|
3314
3033
|
} catch {
|
|
3315
|
-
console.log(
|
|
3034
|
+
console.log(chalk12.yellow(`\u{1F4ED} ${t("undo.noCommits")}`));
|
|
3316
3035
|
return;
|
|
3317
3036
|
}
|
|
3318
3037
|
const commits = parseRecentCommits(logOutput);
|
|
3319
3038
|
if (commits.length === 0) {
|
|
3320
|
-
console.log(
|
|
3039
|
+
console.log(chalk12.yellow(`\u{1F4ED} ${t("undo.noCommits")}`));
|
|
3321
3040
|
return;
|
|
3322
3041
|
}
|
|
3323
|
-
console.log(
|
|
3042
|
+
console.log(chalk12.cyan(`
|
|
3324
3043
|
${t("undo.recentHeader")}`));
|
|
3325
3044
|
commits.forEach((c, i) => {
|
|
3326
3045
|
console.log(` ${i === 0 ? "\u{1F449}" : " "} ${c}`);
|
|
@@ -3337,7 +3056,7 @@ ${t("undo.recentHeader")}`));
|
|
|
3337
3056
|
const undoCount = Math.min(Math.max(1, count || 1), maxUndo);
|
|
3338
3057
|
const headCount = countLocalCommits(gitRoot);
|
|
3339
3058
|
if (undoCount >= headCount) {
|
|
3340
|
-
console.log(
|
|
3059
|
+
console.log(chalk12.yellow(`
|
|
3341
3060
|
\u{1F4ED} ${t("undo.rootCommit")}`));
|
|
3342
3061
|
return;
|
|
3343
3062
|
}
|
|
@@ -3346,10 +3065,10 @@ ${t("undo.recentHeader")}`));
|
|
|
3346
3065
|
const risky = isUndoRisky(undoCount, unpushed, remote);
|
|
3347
3066
|
if (risky) {
|
|
3348
3067
|
if (unpushed < 0) {
|
|
3349
|
-
console.log(
|
|
3068
|
+
console.log(chalk12.red(`
|
|
3350
3069
|
\u26A0\uFE0F ${t("undo.noUpstreamWarning")}`));
|
|
3351
3070
|
} else {
|
|
3352
|
-
console.log(
|
|
3071
|
+
console.log(chalk12.red(`
|
|
3353
3072
|
\u26A0\uFE0F ${t("undo.alreadyPushed")}`));
|
|
3354
3073
|
}
|
|
3355
3074
|
}
|
|
@@ -3360,22 +3079,22 @@ ${t("undo.recentHeader")}`));
|
|
|
3360
3079
|
default: false
|
|
3361
3080
|
}]);
|
|
3362
3081
|
if (!confirm) {
|
|
3363
|
-
console.log(
|
|
3082
|
+
console.log(chalk12.gray(t("undo.cancelled")));
|
|
3364
3083
|
return;
|
|
3365
3084
|
}
|
|
3366
3085
|
try {
|
|
3367
3086
|
gitRun(["reset", "--soft", `HEAD~${undoCount}`], gitRoot);
|
|
3368
|
-
console.log(
|
|
3087
|
+
console.log(chalk12.green(`
|
|
3369
3088
|
\u2705 ${t("undo.success")}`));
|
|
3370
|
-
console.log(
|
|
3089
|
+
console.log(chalk12.gray(` \u{1F4A1} ${t("undo.stagedHint")}`));
|
|
3371
3090
|
if (risky) {
|
|
3372
|
-
console.log(
|
|
3091
|
+
console.log(chalk12.yellow(`
|
|
3373
3092
|
\u{1F4A1} ${t("undo.forcePushHint")}`));
|
|
3374
3093
|
}
|
|
3375
3094
|
} catch (err) {
|
|
3376
|
-
console.log(
|
|
3095
|
+
console.log(chalk12.red(`\u274C ${t("undo.failed")}`));
|
|
3377
3096
|
const msg = err instanceof Error ? err.message : String(err);
|
|
3378
|
-
console.log(
|
|
3097
|
+
console.log(chalk12.red(msg));
|
|
3379
3098
|
process.exitCode = 1;
|
|
3380
3099
|
}
|
|
3381
3100
|
}
|
|
@@ -3384,7 +3103,7 @@ ${t("undo.recentHeader")}`));
|
|
|
3384
3103
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
3385
3104
|
import fs15 from "fs";
|
|
3386
3105
|
import path14 from "path";
|
|
3387
|
-
import
|
|
3106
|
+
import chalk13 from "chalk";
|
|
3388
3107
|
|
|
3389
3108
|
// src/lib/read-json.ts
|
|
3390
3109
|
import fs14 from "fs";
|
|
@@ -3456,15 +3175,15 @@ function getSyncCounts(gitRoot) {
|
|
|
3456
3175
|
}
|
|
3457
3176
|
}
|
|
3458
3177
|
async function status() {
|
|
3459
|
-
console.log(
|
|
3178
|
+
console.log(chalk13.bold(`
|
|
3460
3179
|
\u{1F4CA} ${t("status.title")}`));
|
|
3461
|
-
console.log(
|
|
3180
|
+
console.log(chalk13.gray("\u2500".repeat(40)));
|
|
3462
3181
|
let gitRoot;
|
|
3463
3182
|
try {
|
|
3464
3183
|
execFileSync4("git", ["rev-parse", "--is-inside-work-tree"], { stdio: "pipe" });
|
|
3465
3184
|
gitRoot = getGitRoot();
|
|
3466
3185
|
} catch {
|
|
3467
|
-
console.log(
|
|
3186
|
+
console.log(chalk13.red(`\u274C ${t("status.notGitRepo")}`));
|
|
3468
3187
|
return;
|
|
3469
3188
|
}
|
|
3470
3189
|
let branch;
|
|
@@ -3483,36 +3202,36 @@ async function status() {
|
|
|
3483
3202
|
commits = [];
|
|
3484
3203
|
}
|
|
3485
3204
|
const pkg = readProjectPackage();
|
|
3486
|
-
console.log(
|
|
3487
|
-
\u{1F33F} ${t("status.branch")}`) +
|
|
3205
|
+
console.log(chalk13.cyan(`
|
|
3206
|
+
\u{1F33F} ${t("status.branch")}`) + chalk13.white(` ${branch}`));
|
|
3488
3207
|
console.log(
|
|
3489
|
-
|
|
3208
|
+
chalk13.cyan(`\u{1F4C1} ${t("status.changes")}`) + chalk13.white(
|
|
3490
3209
|
` staged ${counts.staged} \xB7 unstaged ${counts.unstaged} \xB7 untracked ${counts.untracked}`
|
|
3491
3210
|
)
|
|
3492
3211
|
);
|
|
3493
|
-
console.log(
|
|
3212
|
+
console.log(chalk13.cyan(`
|
|
3494
3213
|
\u{1F4CB} ${t("status.recentCommits")}`));
|
|
3495
3214
|
if (commits.length === 0) {
|
|
3496
|
-
console.log(
|
|
3215
|
+
console.log(chalk13.dim(` ${t("status.noCommits")}`));
|
|
3497
3216
|
} else {
|
|
3498
|
-
commits.forEach((c) => console.log(` ${
|
|
3217
|
+
commits.forEach((c) => console.log(` ${chalk13.dim("\u2022")} ${c}`));
|
|
3499
3218
|
}
|
|
3500
3219
|
console.log(
|
|
3501
|
-
|
|
3502
|
-
\u{1F504} ${t("status.remote")}`) +
|
|
3220
|
+
chalk13.cyan(`
|
|
3221
|
+
\u{1F504} ${t("status.remote")}`) + chalk13.white(` ${formatSyncLabel(sync2)}`)
|
|
3503
3222
|
);
|
|
3504
|
-
console.log(
|
|
3223
|
+
console.log(chalk13.gray("\n" + "\u2500".repeat(40)));
|
|
3505
3224
|
if (pkg) {
|
|
3506
|
-
console.log(
|
|
3225
|
+
console.log(chalk13.cyan(`\u{1F4E6} ${t("status.package")}`) + chalk13.white(` ${pkg.name} v${pkg.version}`));
|
|
3507
3226
|
} else {
|
|
3508
|
-
console.log(
|
|
3227
|
+
console.log(chalk13.dim(`\u{1F4E6} ${t("status.noPackage")}`));
|
|
3509
3228
|
}
|
|
3510
3229
|
console.log("");
|
|
3511
3230
|
}
|
|
3512
3231
|
|
|
3513
3232
|
// src/commands/diff.ts
|
|
3514
3233
|
import { execFileSync as execFileSync5, execSync as execSync2 } from "child_process";
|
|
3515
|
-
import
|
|
3234
|
+
import chalk14 from "chalk";
|
|
3516
3235
|
function gitOut2(args) {
|
|
3517
3236
|
try {
|
|
3518
3237
|
return execFileSync5("git", args, { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
@@ -3552,53 +3271,53 @@ function summarizeNumstat(numstat) {
|
|
|
3552
3271
|
return { fileCount, totalAdd, totalDel };
|
|
3553
3272
|
}
|
|
3554
3273
|
function printFile(f) {
|
|
3555
|
-
const adds = f.additions > 0 ?
|
|
3556
|
-
const dels = f.deletions > 0 ?
|
|
3274
|
+
const adds = f.additions > 0 ? chalk14.green(`+${f.additions}`) : "";
|
|
3275
|
+
const dels = f.deletions > 0 ? chalk14.red(`-${f.deletions}`) : "";
|
|
3557
3276
|
const change = [adds, dels].filter(Boolean).join(" ");
|
|
3558
3277
|
console.log(` ${f.name} ${change}`);
|
|
3559
3278
|
}
|
|
3560
3279
|
async function diff() {
|
|
3561
|
-
console.log(
|
|
3280
|
+
console.log(chalk14.bold(`
|
|
3562
3281
|
\u{1F50D} ${t("diff.title")}`));
|
|
3563
|
-
console.log(
|
|
3282
|
+
console.log(chalk14.gray("\u2500".repeat(40)));
|
|
3564
3283
|
try {
|
|
3565
3284
|
execSync2("git rev-parse --is-inside-work-tree", { stdio: "pipe" });
|
|
3566
3285
|
} catch {
|
|
3567
|
-
console.log(
|
|
3286
|
+
console.log(chalk14.red(`\u274C ${t("diff.notGitRepo")}`));
|
|
3568
3287
|
return;
|
|
3569
3288
|
}
|
|
3570
3289
|
const unstaged = gitOut2(["diff", "--stat"]);
|
|
3571
3290
|
const staged = gitOut2(["diff", "--cached", "--stat"]);
|
|
3572
3291
|
const untracked = gitOut2(["ls-files", "--others", "--exclude-standard"]);
|
|
3573
3292
|
if (!unstaged && !staged && !untracked) {
|
|
3574
|
-
console.log(
|
|
3293
|
+
console.log(chalk14.green(`
|
|
3575
3294
|
\u2705 ${t("diff.noChanges")}`));
|
|
3576
3295
|
return;
|
|
3577
3296
|
}
|
|
3578
3297
|
if (staged) {
|
|
3579
|
-
console.log(
|
|
3298
|
+
console.log(chalk14.cyan(`
|
|
3580
3299
|
${t("diff.stagedHeader")}`));
|
|
3581
3300
|
parseDiffStat(staged).forEach((f) => printFile(f));
|
|
3582
3301
|
}
|
|
3583
3302
|
if (unstaged) {
|
|
3584
|
-
console.log(
|
|
3303
|
+
console.log(chalk14.cyan(`
|
|
3585
3304
|
${t("diff.unstagedHeader")}`));
|
|
3586
3305
|
parseDiffStat(unstaged).forEach((f) => printFile(f));
|
|
3587
3306
|
}
|
|
3588
3307
|
if (untracked) {
|
|
3589
3308
|
const files = untracked.split("\n").filter(Boolean);
|
|
3590
|
-
console.log(
|
|
3309
|
+
console.log(chalk14.cyan(`
|
|
3591
3310
|
${t("diff.untrackedHeader", files.length)}`));
|
|
3592
|
-
files.forEach((f) => console.log(` ${
|
|
3311
|
+
files.forEach((f) => console.log(` ${chalk14.green("+")} ${f}`));
|
|
3593
3312
|
}
|
|
3594
3313
|
const numstat = gitOut2(["diff", "--numstat", "HEAD"]);
|
|
3595
3314
|
if (numstat) {
|
|
3596
3315
|
const { fileCount, totalAdd, totalDel } = summarizeNumstat(numstat);
|
|
3597
|
-
console.log(
|
|
3316
|
+
console.log(chalk14.cyan(`
|
|
3598
3317
|
${t("diff.summaryHeader")}`));
|
|
3599
3318
|
console.log(` ${t("diff.filesLine", fileCount)}`);
|
|
3600
|
-
console.log(` \uCD94\uAC00: ${
|
|
3601
|
-
console.log(` \uC0AD\uC81C: ${
|
|
3319
|
+
console.log(` \uCD94\uAC00: ${chalk14.green(`+${totalAdd}`)}\uC904`);
|
|
3320
|
+
console.log(` \uC0AD\uC81C: ${chalk14.red(`-${totalDel}`)}\uC904`);
|
|
3602
3321
|
}
|
|
3603
3322
|
console.log("");
|
|
3604
3323
|
}
|
|
@@ -3607,7 +3326,7 @@ ${t("diff.summaryHeader")}`));
|
|
|
3607
3326
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
3608
3327
|
import { join } from "path";
|
|
3609
3328
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
3610
|
-
import
|
|
3329
|
+
import chalk15 from "chalk";
|
|
3611
3330
|
function resolveVhkMcpPath() {
|
|
3612
3331
|
try {
|
|
3613
3332
|
const pkgPath = join(process.cwd(), "package.json");
|
|
@@ -3627,8 +3346,8 @@ function resolveVhkMcpPath() {
|
|
|
3627
3346
|
return join(process.cwd(), "node_modules", "@byh3071", "vhk", "dist", "mcp", "index.js");
|
|
3628
3347
|
}
|
|
3629
3348
|
async function mcpInit() {
|
|
3630
|
-
console.log(
|
|
3631
|
-
console.log(
|
|
3349
|
+
console.log(chalk15.bold("\n\u{1F50C} " + t("mcp.initTitle")));
|
|
3350
|
+
console.log(chalk15.gray("\u2500".repeat(40)));
|
|
3632
3351
|
const cursorDir = join(process.cwd(), ".cursor");
|
|
3633
3352
|
if (!existsSync(cursorDir)) {
|
|
3634
3353
|
mkdirSync(cursorDir, { recursive: true });
|
|
@@ -3646,25 +3365,25 @@ async function mcpInit() {
|
|
|
3646
3365
|
mcpServers: { ...parsed.mcpServers ?? {}, vhk: vhkEntry }
|
|
3647
3366
|
};
|
|
3648
3367
|
} catch {
|
|
3649
|
-
console.log(
|
|
3368
|
+
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
3369
|
config = { mcpServers: { vhk: vhkEntry } };
|
|
3651
3370
|
}
|
|
3652
3371
|
} else {
|
|
3653
3372
|
config = { mcpServers: { vhk: vhkEntry } };
|
|
3654
3373
|
}
|
|
3655
3374
|
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
3656
|
-
console.log(
|
|
3657
|
-
console.log(
|
|
3375
|
+
console.log(chalk15.green("\n\u2705 Cursor MCP \uC124\uC815 \uC644\uB8CC!"));
|
|
3376
|
+
console.log(chalk15.cyan("\u{1F4C1} \uC0DD\uC131\uB41C \uD30C\uC77C:"));
|
|
3658
3377
|
console.log(` ${configPath}`);
|
|
3659
|
-
console.log(
|
|
3378
|
+
console.log(chalk15.cyan("\n\u{1F504} \uB2E4\uC74C \uB2E8\uACC4:"));
|
|
3660
3379
|
console.log(" 1. Cursor\uB97C \uC7AC\uC2DC\uC791\uD558\uC138\uC694");
|
|
3661
3380
|
console.log(" 2. Cursor \uCC44\uD305\uC5D0\uC11C vhk \uB3C4\uAD6C\uB97C \uC0AC\uC6A9\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4");
|
|
3662
|
-
console.log(
|
|
3381
|
+
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
3382
|
}
|
|
3664
3383
|
|
|
3665
3384
|
// src/commands/deploy.ts
|
|
3666
3385
|
import { existsSync as existsSync2 } from "fs";
|
|
3667
|
-
import
|
|
3386
|
+
import chalk16 from "chalk";
|
|
3668
3387
|
import inquirer7 from "inquirer";
|
|
3669
3388
|
var PLATFORMS = {
|
|
3670
3389
|
vercel: {
|
|
@@ -3704,11 +3423,11 @@ function isCLIAvailable(cmd, checkArgs) {
|
|
|
3704
3423
|
return safeExecFile(cmd, checkArgs).ok;
|
|
3705
3424
|
}
|
|
3706
3425
|
async function deploy() {
|
|
3707
|
-
console.log(
|
|
3708
|
-
console.log(
|
|
3426
|
+
console.log(chalk16.bold("\n\u{1F680} " + t("deploy.title")));
|
|
3427
|
+
console.log(chalk16.gray("\u2500".repeat(40)));
|
|
3709
3428
|
let platform = detectPlatform();
|
|
3710
3429
|
if (platform) {
|
|
3711
|
-
console.log(
|
|
3430
|
+
console.log(chalk16.cyan(`
|
|
3712
3431
|
\u{1F50D} \uAC10\uC9C0\uB41C \uD50C\uB7AB\uD3FC: ${PLATFORMS[platform].name}`));
|
|
3713
3432
|
} else {
|
|
3714
3433
|
const { selected } = await inquirer7.prompt([
|
|
@@ -3727,9 +3446,9 @@ async function deploy() {
|
|
|
3727
3446
|
}
|
|
3728
3447
|
const config = PLATFORMS[platform];
|
|
3729
3448
|
if (!isCLIAvailable(config.command, config.checkArgs)) {
|
|
3730
|
-
console.log(
|
|
3449
|
+
console.log(chalk16.red(`
|
|
3731
3450
|
\u274C ${config.name} CLI\uAC00 \uC124\uCE58\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.`));
|
|
3732
|
-
console.log(
|
|
3451
|
+
console.log(chalk16.yellow(` \u2192 ${config.installHint}`));
|
|
3733
3452
|
return;
|
|
3734
3453
|
}
|
|
3735
3454
|
const { confirm } = await inquirer7.prompt([
|
|
@@ -3741,15 +3460,15 @@ async function deploy() {
|
|
|
3741
3460
|
}
|
|
3742
3461
|
]);
|
|
3743
3462
|
if (!confirm) {
|
|
3744
|
-
console.log(
|
|
3463
|
+
console.log(chalk16.gray("\uCDE8\uC18C\uB428"));
|
|
3745
3464
|
return;
|
|
3746
3465
|
}
|
|
3747
|
-
console.log(
|
|
3466
|
+
console.log(chalk16.cyan(`
|
|
3748
3467
|
${t("deploy.deploying")}
|
|
3749
3468
|
`));
|
|
3750
3469
|
const result = safeExecFileStream(config.command, config.commandArgs);
|
|
3751
3470
|
if (result.ok) {
|
|
3752
|
-
console.log(
|
|
3471
|
+
console.log(chalk16.green(`
|
|
3753
3472
|
\u2705 ${t("deploy.success")}`));
|
|
3754
3473
|
printNextStep({
|
|
3755
3474
|
message: "\uBC30\uD3EC \uC644\uB8CC! \uC0AC\uC774\uD2B8\uB97C \uD655\uC778\uD558\uC138\uC694.",
|
|
@@ -3757,88 +3476,15 @@ ${t("deploy.deploying")}
|
|
|
3757
3476
|
cursorHint: "\uC0C1\uD0DC \uD655\uC778\uD574\uC918"
|
|
3758
3477
|
});
|
|
3759
3478
|
} else {
|
|
3760
|
-
console.log(
|
|
3479
|
+
console.log(chalk16.red(`
|
|
3761
3480
|
\u274C ${t("deploy.failed")}`));
|
|
3762
|
-
console.log(
|
|
3763
|
-
}
|
|
3764
|
-
}
|
|
3765
|
-
|
|
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;
|
|
3481
|
+
console.log(chalk16.red(result.err));
|
|
3798
3482
|
}
|
|
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
3483
|
}
|
|
3838
3484
|
|
|
3839
3485
|
// src/commands/publish.ts
|
|
3840
|
-
import { existsSync as
|
|
3841
|
-
import
|
|
3486
|
+
import { existsSync as existsSync3, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
3487
|
+
import chalk17 from "chalk";
|
|
3842
3488
|
import inquirer8 from "inquirer";
|
|
3843
3489
|
import ora2 from "ora";
|
|
3844
3490
|
function bumpVersion(current, type) {
|
|
@@ -3853,21 +3499,21 @@ function bumpVersion(current, type) {
|
|
|
3853
3499
|
}
|
|
3854
3500
|
}
|
|
3855
3501
|
async function publish() {
|
|
3856
|
-
console.log(
|
|
3857
|
-
console.log(
|
|
3858
|
-
if (!
|
|
3859
|
-
console.log(
|
|
3502
|
+
console.log(chalk17.bold("\n\u{1F4E6} " + t("publish.title")));
|
|
3503
|
+
console.log(chalk17.gray("\u2500".repeat(40)));
|
|
3504
|
+
if (!existsSync3("package.json")) {
|
|
3505
|
+
console.log(chalk17.red("\u274C package.json\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."));
|
|
3860
3506
|
return;
|
|
3861
3507
|
}
|
|
3862
3508
|
let pkg;
|
|
3863
3509
|
try {
|
|
3864
|
-
pkg = JSON.parse(
|
|
3510
|
+
pkg = JSON.parse(readFileSync2("package.json", "utf-8"));
|
|
3865
3511
|
} catch {
|
|
3866
|
-
console.log(
|
|
3512
|
+
console.log(chalk17.red("\u274C package.json \uD30C\uC2F1 \uC2E4\uD328"));
|
|
3867
3513
|
return;
|
|
3868
3514
|
}
|
|
3869
3515
|
const currentVersion = pkg.version || "0.0.0";
|
|
3870
|
-
console.log(
|
|
3516
|
+
console.log(chalk17.cyan(`
|
|
3871
3517
|
\u{1F4CC} \uD604\uC7AC \uBC84\uC804: v${currentVersion}`));
|
|
3872
3518
|
const { bumpType } = await inquirer8.prompt([
|
|
3873
3519
|
{
|
|
@@ -3882,18 +3528,18 @@ async function publish() {
|
|
|
3882
3528
|
}
|
|
3883
3529
|
]);
|
|
3884
3530
|
const newVersion = bumpVersion(currentVersion, bumpType);
|
|
3885
|
-
console.log(
|
|
3531
|
+
console.log(chalk17.cyan(`
|
|
3886
3532
|
\u{1F195} \uC0C8 \uBC84\uC804: v${newVersion}`));
|
|
3887
3533
|
pkg.version = newVersion;
|
|
3888
|
-
|
|
3889
|
-
console.log(
|
|
3534
|
+
writeFileSync2("package.json", JSON.stringify(pkg, null, 2) + "\n", "utf-8");
|
|
3535
|
+
console.log(chalk17.green("\u2705 package.json \uBC84\uC804 \uC5C5\uB370\uC774\uD2B8"));
|
|
3890
3536
|
const buildSpinner = ora2(t("publish.building")).start();
|
|
3891
3537
|
const buildResult = safeExecFile("pnpm", ["build"]);
|
|
3892
3538
|
if (!buildResult.ok) {
|
|
3893
3539
|
buildSpinner.fail(t("publish.buildFailed"));
|
|
3894
|
-
console.log(
|
|
3540
|
+
console.log(chalk17.red(buildResult.err.slice(0, 500)));
|
|
3895
3541
|
pkg.version = currentVersion;
|
|
3896
|
-
|
|
3542
|
+
writeFileSync2("package.json", JSON.stringify(pkg, null, 2) + "\n", "utf-8");
|
|
3897
3543
|
return;
|
|
3898
3544
|
}
|
|
3899
3545
|
buildSpinner.succeed(t("publish.buildSuccess"));
|
|
@@ -3901,9 +3547,9 @@ async function publish() {
|
|
|
3901
3547
|
const testResult = safeExecFile("pnpm", ["test", "--run"]);
|
|
3902
3548
|
if (!testResult.ok) {
|
|
3903
3549
|
testSpinner.fail(t("publish.testFailed"));
|
|
3904
|
-
console.log(
|
|
3550
|
+
console.log(chalk17.red(testResult.err.slice(0, 500)));
|
|
3905
3551
|
pkg.version = currentVersion;
|
|
3906
|
-
|
|
3552
|
+
writeFileSync2("package.json", JSON.stringify(pkg, null, 2) + "\n", "utf-8");
|
|
3907
3553
|
return;
|
|
3908
3554
|
}
|
|
3909
3555
|
testSpinner.succeed(t("publish.testSuccess"));
|
|
@@ -3917,18 +3563,18 @@ async function publish() {
|
|
|
3917
3563
|
]);
|
|
3918
3564
|
if (!confirm) {
|
|
3919
3565
|
pkg.version = currentVersion;
|
|
3920
|
-
|
|
3921
|
-
console.log(
|
|
3566
|
+
writeFileSync2("package.json", JSON.stringify(pkg, null, 2) + "\n", "utf-8");
|
|
3567
|
+
console.log(chalk17.gray("\uCDE8\uC18C\uB428. \uBC84\uC804\uC774 \uC6D0\uB798\uB300\uB85C \uBCF5\uAD6C\uB429\uB2C8\uB2E4."));
|
|
3922
3568
|
return;
|
|
3923
3569
|
}
|
|
3924
3570
|
const pubSpinner = ora2(t("publish.publishing")).start();
|
|
3925
3571
|
const pubResult = safeExecFile("npm", ["publish", "--access", "public"]);
|
|
3926
3572
|
if (!pubResult.ok) {
|
|
3927
3573
|
pubSpinner.fail(t("publish.publishFailed"));
|
|
3928
|
-
console.log(
|
|
3574
|
+
console.log(chalk17.red(pubResult.err.slice(0, 500)));
|
|
3929
3575
|
pkg.version = currentVersion;
|
|
3930
|
-
|
|
3931
|
-
console.log(
|
|
3576
|
+
writeFileSync2("package.json", JSON.stringify(pkg, null, 2) + "\n", "utf-8");
|
|
3577
|
+
console.log(chalk17.gray(`\u{1F4E6} package.json \uBC84\uC804\uC744 v${currentVersion}\uB85C \uBCF5\uAD6C\uD588\uC2B5\uB2C8\uB2E4.`));
|
|
3932
3578
|
return;
|
|
3933
3579
|
}
|
|
3934
3580
|
pubSpinner.succeed(t("publish.publishSuccess"));
|
|
@@ -3940,15 +3586,15 @@ async function publish() {
|
|
|
3940
3586
|
const pushResult = safeExecFile("git", ["push"]);
|
|
3941
3587
|
const pushTagsResult = safeExecFile("git", ["push", "--tags"]);
|
|
3942
3588
|
if (pushResult.ok && pushTagsResult.ok) {
|
|
3943
|
-
console.log(
|
|
3589
|
+
console.log(chalk17.green(`
|
|
3944
3590
|
\u{1F3F7}\uFE0F git tag v${newVersion} \uC0DD\uC131 + push \uC644\uB8CC`));
|
|
3945
3591
|
} else {
|
|
3946
|
-
console.log(
|
|
3592
|
+
console.log(chalk17.yellow(`
|
|
3947
3593
|
\u{1F3F7}\uFE0F git tag v${newVersion} \uC0DD\uC131\uB428 (push\uB294 \uC218\uB3D9\uC73C\uB85C)`));
|
|
3948
3594
|
}
|
|
3949
3595
|
}
|
|
3950
3596
|
}
|
|
3951
|
-
console.log(
|
|
3597
|
+
console.log(chalk17.green.bold(`
|
|
3952
3598
|
\u{1F389} v${newVersion} \uBC30\uD3EC \uC644\uB8CC!`));
|
|
3953
3599
|
printNextStep({
|
|
3954
3600
|
message: "npm \uBC30\uD3EC \uC644\uB8CC!",
|
|
@@ -3957,6 +3603,329 @@ async function publish() {
|
|
|
3957
3603
|
});
|
|
3958
3604
|
}
|
|
3959
3605
|
|
|
3606
|
+
// src/commands/design.ts
|
|
3607
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
3608
|
+
import chalk18 from "chalk";
|
|
3609
|
+
import inquirer9 from "inquirer";
|
|
3610
|
+
var PALETTES = [
|
|
3611
|
+
{
|
|
3612
|
+
name: "Minimal",
|
|
3613
|
+
colors: {
|
|
3614
|
+
primary: "#1a1a1a",
|
|
3615
|
+
secondary: "#6b7280",
|
|
3616
|
+
accent: "#3b82f6",
|
|
3617
|
+
background: "#ffffff",
|
|
3618
|
+
surface: "#f9fafb",
|
|
3619
|
+
text: "#111827",
|
|
3620
|
+
muted: "#9ca3af"
|
|
3621
|
+
}
|
|
3622
|
+
},
|
|
3623
|
+
{
|
|
3624
|
+
name: "Vibrant",
|
|
3625
|
+
colors: {
|
|
3626
|
+
primary: "#7c3aed",
|
|
3627
|
+
secondary: "#ec4899",
|
|
3628
|
+
accent: "#f59e0b",
|
|
3629
|
+
background: "#ffffff",
|
|
3630
|
+
surface: "#faf5ff",
|
|
3631
|
+
text: "#1e1b4b",
|
|
3632
|
+
muted: "#8b5cf6"
|
|
3633
|
+
}
|
|
3634
|
+
},
|
|
3635
|
+
{
|
|
3636
|
+
name: "Corporate",
|
|
3637
|
+
colors: {
|
|
3638
|
+
primary: "#1e40af",
|
|
3639
|
+
secondary: "#0f766e",
|
|
3640
|
+
accent: "#ca8a04",
|
|
3641
|
+
background: "#ffffff",
|
|
3642
|
+
surface: "#f0f9ff",
|
|
3643
|
+
text: "#0f172a",
|
|
3644
|
+
muted: "#64748b"
|
|
3645
|
+
}
|
|
3646
|
+
},
|
|
3647
|
+
{
|
|
3648
|
+
name: "Pastel",
|
|
3649
|
+
colors: {
|
|
3650
|
+
primary: "#a78bfa",
|
|
3651
|
+
secondary: "#f9a8d4",
|
|
3652
|
+
accent: "#fcd34d",
|
|
3653
|
+
background: "#fffbeb",
|
|
3654
|
+
surface: "#fef3c7",
|
|
3655
|
+
text: "#44403c",
|
|
3656
|
+
muted: "#a8a29e"
|
|
3657
|
+
}
|
|
3658
|
+
}
|
|
3659
|
+
];
|
|
3660
|
+
function hasTailwind() {
|
|
3661
|
+
return existsSync4("tailwind.config.js") || existsSync4("tailwind.config.ts") || existsSync4("tailwind.config.mjs") || existsSync4("tailwind.config.cjs");
|
|
3662
|
+
}
|
|
3663
|
+
function generateCSSTokens(palette) {
|
|
3664
|
+
const lines = Object.entries(palette.colors).map(([key, value]) => ` --color-${key}: ${value};`).join("\n");
|
|
3665
|
+
return `:root {
|
|
3666
|
+
${lines}
|
|
3667
|
+
}
|
|
3668
|
+
`;
|
|
3669
|
+
}
|
|
3670
|
+
function generateTailwindExtend(palette) {
|
|
3671
|
+
const entries = Object.entries(palette.colors).map(([key, value]) => ` '${key}': '${value}',`).join("\n");
|
|
3672
|
+
return `// vhk design \u2014 Tailwind config \uD655\uC7A5\uC6A9 \uCEEC\uB7EC \uD1A0\uD070
|
|
3673
|
+
// tailwind.config\uC758 theme.extend.colors\uC5D0 spread \uD558\uC138\uC694.
|
|
3674
|
+
const vhkColors = {
|
|
3675
|
+
${entries}
|
|
3676
|
+
}
|
|
3677
|
+
|
|
3678
|
+
export default vhkColors
|
|
3679
|
+
`;
|
|
3680
|
+
}
|
|
3681
|
+
async function design() {
|
|
3682
|
+
console.log(chalk18.bold("\n\u{1F3A8} " + t("design.title")));
|
|
3683
|
+
console.log(chalk18.gray("\u2500".repeat(40)));
|
|
3684
|
+
const { paletteIndex } = await inquirer9.prompt([
|
|
3685
|
+
{
|
|
3686
|
+
type: "list",
|
|
3687
|
+
name: "paletteIndex",
|
|
3688
|
+
message: t("design.selectPalette"),
|
|
3689
|
+
choices: PALETTES.map((p, i) => ({
|
|
3690
|
+
name: `${p.name} \u2014 primary ${p.colors.primary}`,
|
|
3691
|
+
value: i
|
|
3692
|
+
}))
|
|
3693
|
+
}
|
|
3694
|
+
]);
|
|
3695
|
+
const palette = PALETTES[paletteIndex];
|
|
3696
|
+
console.log(chalk18.cyan(`
|
|
3697
|
+
\u{1F3A8} \uC120\uD0DD\uB41C \uD314\uB808\uD2B8: ${palette.name}`));
|
|
3698
|
+
const targetPath = hasTailwind() ? "src/styles/vhk-colors.ts" : "src/styles/tokens.css";
|
|
3699
|
+
const content = hasTailwind() ? generateTailwindExtend(palette) : generateCSSTokens(palette);
|
|
3700
|
+
if (existsSync4(targetPath)) {
|
|
3701
|
+
const { overwrite } = await inquirer9.prompt([{
|
|
3702
|
+
type: "confirm",
|
|
3703
|
+
name: "overwrite",
|
|
3704
|
+
message: `${targetPath} \uC774\uBBF8 \uC788\uC5B4\uC694. \uB36E\uC5B4\uC4F8\uAE4C\uC694?`,
|
|
3705
|
+
default: false
|
|
3706
|
+
}]);
|
|
3707
|
+
if (!overwrite) {
|
|
3708
|
+
console.log(chalk18.yellow("\n\u23ED\uFE0F \uC0DD\uC131 \uCDE8\uC18C \u2014 \uAE30\uC874 \uD30C\uC77C \uC720\uC9C0."));
|
|
3709
|
+
return;
|
|
3710
|
+
}
|
|
3711
|
+
}
|
|
3712
|
+
mkdirSync2("src/styles", { recursive: true });
|
|
3713
|
+
writeFileSync3(targetPath, content, "utf-8");
|
|
3714
|
+
if (hasTailwind()) {
|
|
3715
|
+
console.log(chalk18.green("\n\u2705 src/styles/vhk-colors.ts \uC0DD\uC131"));
|
|
3716
|
+
console.log(chalk18.gray(" tailwind.config\uC758 extend.colors\uC5D0 import \uD574\uC11C \uC0AC\uC6A9\uD558\uC138\uC694."));
|
|
3717
|
+
} else {
|
|
3718
|
+
console.log(chalk18.green("\n\u2705 src/styles/tokens.css \uC0DD\uC131"));
|
|
3719
|
+
console.log(chalk18.gray(" HTML\uC5D0 <link>\uB85C \uCD94\uAC00\uD558\uAC70\uB098 CSS\uC5D0\uC11C @import \uD558\uC138\uC694."));
|
|
3720
|
+
}
|
|
3721
|
+
console.log(chalk18.bold("\n\u{1F308} \uCEEC\uB7EC \uBBF8\uB9AC\uBCF4\uAE30:"));
|
|
3722
|
+
for (const [key, value] of Object.entries(palette.colors)) {
|
|
3723
|
+
console.log(` ${key.padEnd(12)} ${value}`);
|
|
3724
|
+
}
|
|
3725
|
+
printNextStep({
|
|
3726
|
+
message: "\uB514\uC790\uC778 \uD1A0\uD070 \uC0DD\uC131 \uC644\uB8CC!",
|
|
3727
|
+
command: "vhk theme",
|
|
3728
|
+
cursorHint: "\uD14C\uB9C8 \uC124\uC815\uD574\uC918"
|
|
3729
|
+
});
|
|
3730
|
+
}
|
|
3731
|
+
async function designPalette() {
|
|
3732
|
+
await design();
|
|
3733
|
+
}
|
|
3734
|
+
|
|
3735
|
+
// src/commands/theme.ts
|
|
3736
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync3, writeFileSync as writeFileSync4 } from "fs";
|
|
3737
|
+
import chalk19 from "chalk";
|
|
3738
|
+
import inquirer10 from "inquirer";
|
|
3739
|
+
function generateDarkCSS() {
|
|
3740
|
+
return `/* vhk theme \u2014 \uB2E4\uD06C/\uB77C\uC774\uD2B8 \uBAA8\uB4DC CSS \uBCC0\uC218 */
|
|
3741
|
+
|
|
3742
|
+
@media (prefers-color-scheme: dark) {
|
|
3743
|
+
:root {
|
|
3744
|
+
--color-background: #0f172a;
|
|
3745
|
+
--color-surface: #1e293b;
|
|
3746
|
+
--color-text: #f1f5f9;
|
|
3747
|
+
--color-muted: #64748b;
|
|
3748
|
+
}
|
|
3749
|
+
}
|
|
3750
|
+
|
|
3751
|
+
[data-theme="dark"] {
|
|
3752
|
+
--color-background: #0f172a;
|
|
3753
|
+
--color-surface: #1e293b;
|
|
3754
|
+
--color-text: #f1f5f9;
|
|
3755
|
+
--color-muted: #64748b;
|
|
3756
|
+
}
|
|
3757
|
+
|
|
3758
|
+
[data-theme="light"] {
|
|
3759
|
+
--color-background: #ffffff;
|
|
3760
|
+
--color-surface: #f9fafb;
|
|
3761
|
+
--color-text: #111827;
|
|
3762
|
+
--color-muted: #9ca3af;
|
|
3763
|
+
}
|
|
3764
|
+
`;
|
|
3765
|
+
}
|
|
3766
|
+
function generateToggleUtil() {
|
|
3767
|
+
return `// vhk theme \u2014 \uB2E4\uD06C/\uB77C\uC774\uD2B8 \uBAA8\uB4DC \uD1A0\uAE00 \uC720\uD2F8\uB9AC\uD2F0
|
|
3768
|
+
|
|
3769
|
+
export function getTheme(): 'light' | 'dark' {
|
|
3770
|
+
if (typeof window === 'undefined') return 'light'
|
|
3771
|
+
const stored = localStorage.getItem('vhk-theme') as 'light' | 'dark' | null
|
|
3772
|
+
if (stored === 'light' || stored === 'dark') return stored
|
|
3773
|
+
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
|
|
3774
|
+
}
|
|
3775
|
+
|
|
3776
|
+
export function setTheme(theme: 'light' | 'dark'): void {
|
|
3777
|
+
if (typeof document === 'undefined') return
|
|
3778
|
+
document.documentElement.setAttribute('data-theme', theme)
|
|
3779
|
+
localStorage.setItem('vhk-theme', theme)
|
|
3780
|
+
}
|
|
3781
|
+
|
|
3782
|
+
export function toggleTheme(): 'light' | 'dark' {
|
|
3783
|
+
const next = getTheme() === 'light' ? 'dark' : 'light'
|
|
3784
|
+
setTheme(next)
|
|
3785
|
+
return next
|
|
3786
|
+
}
|
|
3787
|
+
|
|
3788
|
+
export function initTheme(): void {
|
|
3789
|
+
setTheme(getTheme())
|
|
3790
|
+
}
|
|
3791
|
+
`;
|
|
3792
|
+
}
|
|
3793
|
+
async function theme() {
|
|
3794
|
+
console.log(chalk19.bold("\n\u{1F319} " + t("theme.title")));
|
|
3795
|
+
console.log(chalk19.gray("\u2500".repeat(40)));
|
|
3796
|
+
const cssPath = "src/styles/theme.css";
|
|
3797
|
+
const togglePath = "src/lib/theme-toggle.ts";
|
|
3798
|
+
const conflicts = [cssPath, togglePath].filter((p) => existsSync5(p));
|
|
3799
|
+
if (conflicts.length > 0) {
|
|
3800
|
+
const { overwrite } = await inquirer10.prompt([{
|
|
3801
|
+
type: "confirm",
|
|
3802
|
+
name: "overwrite",
|
|
3803
|
+
message: `\uB2E4\uC74C \uD30C\uC77C\uC774 \uC774\uBBF8 \uC788\uC5B4\uC694. \uB36E\uC5B4\uC4F8\uAE4C\uC694?
|
|
3804
|
+
${conflicts.join("\n ")}`,
|
|
3805
|
+
default: false
|
|
3806
|
+
}]);
|
|
3807
|
+
if (!overwrite) {
|
|
3808
|
+
console.log(chalk19.yellow("\n\u23ED\uFE0F \uC0DD\uC131 \uCDE8\uC18C \u2014 \uAE30\uC874 \uD30C\uC77C \uC720\uC9C0."));
|
|
3809
|
+
return;
|
|
3810
|
+
}
|
|
3811
|
+
}
|
|
3812
|
+
mkdirSync3("src/styles", { recursive: true });
|
|
3813
|
+
mkdirSync3("src/lib", { recursive: true });
|
|
3814
|
+
writeFileSync4(cssPath, generateDarkCSS(), "utf-8");
|
|
3815
|
+
console.log(chalk19.green("\n\u2705 src/styles/theme.css \uC0DD\uC131 (\uB2E4\uD06C/\uB77C\uC774\uD2B8 \uBAA8\uB4DC)"));
|
|
3816
|
+
writeFileSync4(togglePath, generateToggleUtil(), "utf-8");
|
|
3817
|
+
console.log(chalk19.green("\u2705 src/lib/theme-toggle.ts \uC0DD\uC131 (\uD1A0\uAE00 \uC720\uD2F8\uB9AC\uD2F0)"));
|
|
3818
|
+
console.log(chalk19.bold("\n\u{1F4D6} \uC0AC\uC6A9\uBC95:"));
|
|
3819
|
+
console.log(chalk19.gray(" 1. theme.css\uB97C \uAE00\uB85C\uBC8C \uC2A4\uD0C0\uC77C\uC5D0 \uCD94\uAC00"));
|
|
3820
|
+
console.log(chalk19.gray(' 2. import { initTheme, toggleTheme } from "./lib/theme-toggle"'));
|
|
3821
|
+
console.log(chalk19.gray(" 3. \uC571 \uC9C4\uC785\uC810\uC5D0\uC11C initTheme() \uD638\uCD9C"));
|
|
3822
|
+
console.log(chalk19.gray(" 4. \uD1A0\uAE00 \uBC84\uD2BC\uC5D0\uC11C toggleTheme() \uD638\uCD9C"));
|
|
3823
|
+
printNextStep({
|
|
3824
|
+
message: "\uD14C\uB9C8 \uC124\uC815 \uC644\uB8CC!",
|
|
3825
|
+
command: "vhk ref list",
|
|
3826
|
+
cursorHint: "\uB808\uD37C\uB7F0\uC2A4 \uD655\uC778\uD574\uC918"
|
|
3827
|
+
});
|
|
3828
|
+
}
|
|
3829
|
+
|
|
3830
|
+
// src/commands/ref.ts
|
|
3831
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync4, readFileSync as readFileSync3, writeFileSync as writeFileSync5 } from "fs";
|
|
3832
|
+
import chalk20 from "chalk";
|
|
3833
|
+
var REFS_PATH = ".vhk/refs.json";
|
|
3834
|
+
function loadRefs() {
|
|
3835
|
+
if (!existsSync6(REFS_PATH)) return [];
|
|
3836
|
+
try {
|
|
3837
|
+
const raw = readFileSync3(REFS_PATH, "utf-8");
|
|
3838
|
+
const parsed = JSON.parse(raw);
|
|
3839
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
3840
|
+
} catch {
|
|
3841
|
+
return [];
|
|
3842
|
+
}
|
|
3843
|
+
}
|
|
3844
|
+
function saveRefs(refs) {
|
|
3845
|
+
mkdirSync4(".vhk", { recursive: true });
|
|
3846
|
+
writeFileSync5(REFS_PATH, JSON.stringify(refs, null, 2) + "\n", "utf-8");
|
|
3847
|
+
}
|
|
3848
|
+
async function refAdd(url, memo = "") {
|
|
3849
|
+
console.log(chalk20.bold("\n\u{1F517} " + t("ref.addTitle")));
|
|
3850
|
+
console.log(chalk20.gray("\u2500".repeat(40)));
|
|
3851
|
+
if (!url) {
|
|
3852
|
+
console.log(chalk20.red("\u274C URL\uC744 \uC785\uB825\uD574\uC8FC\uC138\uC694."));
|
|
3853
|
+
console.log(chalk20.gray(' \uC608: vhk ref add https://example.com --memo "\uCC38\uACE0 \uC0AC\uC774\uD2B8"'));
|
|
3854
|
+
return;
|
|
3855
|
+
}
|
|
3856
|
+
const refs = loadRefs();
|
|
3857
|
+
if (refs.some((r) => r.url === url)) {
|
|
3858
|
+
console.log(chalk20.yellow("\u26A0\uFE0F \uC774\uBBF8 \uC800\uC7A5\uB41C URL\uC785\uB2C8\uB2E4."));
|
|
3859
|
+
return;
|
|
3860
|
+
}
|
|
3861
|
+
refs.push({ url, memo, addedAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
3862
|
+
saveRefs(refs);
|
|
3863
|
+
console.log(chalk20.green(`
|
|
3864
|
+
\u2705 \uB808\uD37C\uB7F0\uC2A4 \uCD94\uAC00\uB428 (#${refs.length})`));
|
|
3865
|
+
console.log(chalk20.cyan(` ${url}`));
|
|
3866
|
+
if (memo) console.log(chalk20.gray(` \u{1F4DD} ${memo}`));
|
|
3867
|
+
printNextStep({
|
|
3868
|
+
message: "\uB808\uD37C\uB7F0\uC2A4 \uC800\uC7A5 \uC644\uB8CC!",
|
|
3869
|
+
command: "vhk ref list",
|
|
3870
|
+
cursorHint: "\uB808\uD37C\uB7F0\uC2A4 \uBAA9\uB85D \uBCF4\uC5EC\uC918"
|
|
3871
|
+
});
|
|
3872
|
+
}
|
|
3873
|
+
async function refList() {
|
|
3874
|
+
console.log(chalk20.bold("\n\u{1F4DA} " + t("ref.listTitle")));
|
|
3875
|
+
console.log(chalk20.gray("\u2500".repeat(40)));
|
|
3876
|
+
const refs = loadRefs();
|
|
3877
|
+
if (refs.length === 0) {
|
|
3878
|
+
console.log(chalk20.yellow("\n\u{1F4ED} \uC800\uC7A5\uB41C \uB808\uD37C\uB7F0\uC2A4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."));
|
|
3879
|
+
console.log(chalk20.gray(' vhk ref add <url> --memo "\uBA54\uBAA8"\uB85C \uCD94\uAC00\uD558\uC138\uC694.'));
|
|
3880
|
+
return;
|
|
3881
|
+
}
|
|
3882
|
+
console.log(chalk20.cyan(`
|
|
3883
|
+
\uCD1D ${refs.length}\uAC1C\uC758 \uB808\uD37C\uB7F0\uC2A4:
|
|
3884
|
+
`));
|
|
3885
|
+
refs.forEach((ref, index) => {
|
|
3886
|
+
const date = new Date(ref.addedAt).toLocaleDateString("ko-KR");
|
|
3887
|
+
console.log(chalk20.white(` [${index + 1}] ${ref.url}`));
|
|
3888
|
+
if (ref.memo) console.log(chalk20.gray(` \u{1F4DD} ${ref.memo}`));
|
|
3889
|
+
console.log(chalk20.gray(` \u{1F4C5} ${date}`));
|
|
3890
|
+
console.log("");
|
|
3891
|
+
});
|
|
3892
|
+
}
|
|
3893
|
+
async function refOpen(indexStr) {
|
|
3894
|
+
const refs = loadRefs();
|
|
3895
|
+
const idx = parseInt(indexStr, 10) - 1;
|
|
3896
|
+
if (Number.isNaN(idx) || idx < 0 || idx >= refs.length) {
|
|
3897
|
+
console.log(chalk20.red(`\u274C \uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uBC88\uD638\uC785\uB2C8\uB2E4. (1~${refs.length || 0})`));
|
|
3898
|
+
return;
|
|
3899
|
+
}
|
|
3900
|
+
const ref = refs[idx];
|
|
3901
|
+
let parsed;
|
|
3902
|
+
try {
|
|
3903
|
+
parsed = new URL(ref.url);
|
|
3904
|
+
} catch {
|
|
3905
|
+
console.log(chalk20.red(`\u274C \uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 URL: ${ref.url}`));
|
|
3906
|
+
return;
|
|
3907
|
+
}
|
|
3908
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
3909
|
+
console.log(chalk20.red(`\u274C http(s) URL\uB9CC \uC5F4 \uC218 \uC788\uC2B5\uB2C8\uB2E4 (${parsed.protocol})`));
|
|
3910
|
+
return;
|
|
3911
|
+
}
|
|
3912
|
+
console.log(chalk20.cyan(`
|
|
3913
|
+
\u{1F310} \uC5F4\uAE30: ${ref.url}`));
|
|
3914
|
+
let result;
|
|
3915
|
+
if (process.platform === "darwin") {
|
|
3916
|
+
result = safeExecFile("open", [ref.url]);
|
|
3917
|
+
} else if (process.platform === "win32") {
|
|
3918
|
+
result = safeExecFile("cmd.exe", ["/c", "start", "", ref.url]);
|
|
3919
|
+
} else {
|
|
3920
|
+
result = safeExecFile("xdg-open", [ref.url]);
|
|
3921
|
+
}
|
|
3922
|
+
if (result.ok) {
|
|
3923
|
+
console.log(chalk20.green("\u2705 \uBE0C\uB77C\uC6B0\uC800\uC5D0\uC11C \uC5F4\uC5C8\uC2B5\uB2C8\uB2E4."));
|
|
3924
|
+
} else {
|
|
3925
|
+
console.log(chalk20.yellow("\u26A0\uFE0F \uBE0C\uB77C\uC6B0\uC800\uB97C \uC5F4 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. URL\uC744 \uC9C1\uC811 \uBC29\uBB38\uD574\uC8FC\uC138\uC694."));
|
|
3926
|
+
}
|
|
3927
|
+
}
|
|
3928
|
+
|
|
3960
3929
|
// src/lib/nlp-run.ts
|
|
3961
3930
|
async function dispatchNlpRoute(route, input) {
|
|
3962
3931
|
switch (route.command) {
|
|
@@ -3997,28 +3966,36 @@ async function dispatchNlpRoute(route, input) {
|
|
|
3997
3966
|
return envCheck();
|
|
3998
3967
|
case "publish":
|
|
3999
3968
|
return publish();
|
|
3969
|
+
case "design":
|
|
3970
|
+
return design();
|
|
3971
|
+
case "design-palette":
|
|
3972
|
+
return designPalette();
|
|
3973
|
+
case "theme":
|
|
3974
|
+
return theme();
|
|
3975
|
+
case "ref":
|
|
3976
|
+
return refList();
|
|
4000
3977
|
}
|
|
4001
3978
|
}
|
|
4002
3979
|
async function runNaturalLanguageRoute(input) {
|
|
4003
3980
|
const route = routeNaturalLanguage(input);
|
|
4004
3981
|
if (!route) {
|
|
4005
|
-
console.log(
|
|
3982
|
+
console.log(chalk21.yellow(`
|
|
4006
3983
|
\u2753 "${input}" \u2014 ${ko.nlp.notMatched}
|
|
4007
3984
|
`));
|
|
4008
3985
|
return;
|
|
4009
3986
|
}
|
|
4010
3987
|
console.log("");
|
|
4011
|
-
console.log(
|
|
4012
|
-
console.log(
|
|
3988
|
+
console.log(chalk21.cyan(` \u{1F4AC} "${input}"`));
|
|
3989
|
+
console.log(chalk21.cyan(` \u2192 ${route.explanation}`));
|
|
4013
3990
|
if (route.confidence === "low") {
|
|
4014
|
-
const { confirm } = await
|
|
3991
|
+
const { confirm } = await inquirer11.prompt([{
|
|
4015
3992
|
type: "confirm",
|
|
4016
3993
|
name: "confirm",
|
|
4017
3994
|
message: `${route.explanation} \u2014 ${ko.nlp.matched}`,
|
|
4018
3995
|
default: true
|
|
4019
3996
|
}]);
|
|
4020
3997
|
if (!confirm) {
|
|
4021
|
-
console.log(
|
|
3998
|
+
console.log(chalk21.dim(` ${ko.nlp.menuHint}`));
|
|
4022
3999
|
return;
|
|
4023
4000
|
}
|
|
4024
4001
|
}
|
|
@@ -4045,9 +4022,13 @@ var KO_ALIASES = {
|
|
|
4045
4022
|
deploy: "\uBC30\uD3EC",
|
|
4046
4023
|
env: "\uD658\uACBD\uBCC0\uC218",
|
|
4047
4024
|
"env-check": "\uD658\uACBD\uBCC0\uC218\uC810\uAC80",
|
|
4048
|
-
publish: "\uCD9C\uC2DC"
|
|
4025
|
+
publish: "\uCD9C\uC2DC",
|
|
4026
|
+
design: "\uB514\uC790\uC778",
|
|
4027
|
+
"design-palette": "\uD314\uB808\uD2B8",
|
|
4028
|
+
theme: "\uD14C\uB9C8",
|
|
4029
|
+
ref: "\uB808\uD37C\uB7F0\uC2A4"
|
|
4049
4030
|
};
|
|
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.
|
|
4031
|
+
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.8.0");
|
|
4051
4032
|
program.configureHelp({
|
|
4052
4033
|
formatHelp(cmd, helper) {
|
|
4053
4034
|
if (cmd.parent) {
|
|
@@ -4108,6 +4089,27 @@ program.command("env-check").alias("\uD658\uACBD\uBCC0\uC218\uC810\uAC80").descr
|
|
|
4108
4089
|
program.command("publish").alias("\uCD9C\uC2DC").description("npm \uBC30\uD3EC (\uBC84\uC804 \uBC94\uD504 \u2192 \uBE4C\uB4DC \u2192 \uD14C\uC2A4\uD2B8 \u2192 publish)").action(async () => {
|
|
4109
4090
|
await publish();
|
|
4110
4091
|
});
|
|
4092
|
+
program.command("design").alias("\uB514\uC790\uC778").description("\uB514\uC790\uC778 \uD1A0\uD070 \uC0DD\uC131 (Tailwind config \uB610\uB294 CSS \uBCC0\uC218)").action(async () => {
|
|
4093
|
+
await design();
|
|
4094
|
+
});
|
|
4095
|
+
program.command("design-palette").alias("\uD314\uB808\uD2B8").description("\uCEEC\uB7EC \uD314\uB808\uD2B8 \uD504\uB9AC\uC14B \uC120\uD0DD + \uC801\uC6A9").action(async () => {
|
|
4096
|
+
await designPalette();
|
|
4097
|
+
});
|
|
4098
|
+
program.command("theme").alias("\uD14C\uB9C8").description("\uB2E4\uD06C/\uB77C\uC774\uD2B8 \uBAA8\uB4DC CSS + \uD1A0\uAE00 \uC720\uD2F8\uB9AC\uD2F0 \uC0DD\uC131").action(async () => {
|
|
4099
|
+
await theme();
|
|
4100
|
+
});
|
|
4101
|
+
var refCmd = program.command("ref").alias("\uB808\uD37C\uB7F0\uC2A4").description("\uB808\uD37C\uB7F0\uC2A4 URL \uAD00\uB9AC (add / list / open)").action(async () => {
|
|
4102
|
+
await refList();
|
|
4103
|
+
});
|
|
4104
|
+
refCmd.command("add <url>").option("--memo <memo>", "\uBA54\uBAA8 \uCD94\uAC00").description("\uB808\uD37C\uB7F0\uC2A4 URL \uCD94\uAC00").action(async (url, opts) => {
|
|
4105
|
+
await refAdd(url, opts.memo);
|
|
4106
|
+
});
|
|
4107
|
+
refCmd.command("list").alias("\uBAA9\uB85D").description("\uC800\uC7A5\uB41C \uB808\uD37C\uB7F0\uC2A4 \uBAA9\uB85D").action(async () => {
|
|
4108
|
+
await refList();
|
|
4109
|
+
});
|
|
4110
|
+
refCmd.command("open <index>").alias("\uC5F4\uAE30").description("\uB808\uD37C\uB7F0\uC2A4\uB97C \uBE0C\uB77C\uC6B0\uC800\uC5D0\uC11C \uC5F4\uAE30").action(async (index) => {
|
|
4111
|
+
await refOpen(index);
|
|
4112
|
+
});
|
|
4111
4113
|
program.on("command:*", async (operands) => {
|
|
4112
4114
|
const unknown = operands[0] ?? "";
|
|
4113
4115
|
const rest = operands.slice(1);
|
|
@@ -4116,7 +4118,7 @@ program.on("command:*", async (operands) => {
|
|
|
4116
4118
|
});
|
|
4117
4119
|
program.action(async () => {
|
|
4118
4120
|
console.log("\n\u{1F3AF} VHK \u2014 \uBC14\uC774\uBE0C\uCF54\uB529 \uD504\uB85C\uC81D\uD2B8 \uCF54\uCE58\n");
|
|
4119
|
-
const { choice } = await
|
|
4121
|
+
const { choice } = await inquirer12.prompt([{
|
|
4120
4122
|
type: "list",
|
|
4121
4123
|
name: "choice",
|
|
4122
4124
|
message: "\uBB58 \uB3C4\uC640\uB4DC\uB9B4\uAE4C\uC694?",
|