@byh3071/vhk 0.5.1 β 0.5.2
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 +2 -2
- package/dist/index.js +259 -169
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
id: vhk-readme
|
|
3
3
|
date: 2026-05-23
|
|
4
|
-
tags: [vhk, cli, readme, v0.5.
|
|
4
|
+
tags: [vhk, cli, readme, v0.5.2]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# π§ VHK β Vibe Harness Kit
|
|
8
8
|
|
|
9
|
-
> AI μ½λ© μμ΄μ νΈλ₯Ό λΆλ¦¬λ μ¬λμ μν **νκ΅μ΄ νμ¬μ΄ν΄ CLI** (v0.5.
|
|
9
|
+
> AI μ½λ© μμ΄μ νΈλ₯Ό λΆλ¦¬λ μ¬λμ μν **νκ΅μ΄ νμ¬μ΄ν΄ CLI** (v0.5.2)
|
|
10
10
|
|
|
11
11
|
λͺ
λ Ήμ΄λ₯Ό μΈμ°μ§ μμλ λ©λλ€. `vhk`λ§ μΉλ©΄ λ©λ΄κ° λμ€κ³ , νκ΅μ΄λ‘ λ§ν΄λ μμλ£μ΅λλ€.
|
|
12
12
|
|
package/dist/index.js
CHANGED
|
@@ -485,8 +485,7 @@ var require_ignore = __commonJS({
|
|
|
485
485
|
|
|
486
486
|
// src/index.ts
|
|
487
487
|
import { Command, Help } from "commander";
|
|
488
|
-
import
|
|
489
|
-
import inquirer7 from "inquirer";
|
|
488
|
+
import inquirer8 from "inquirer";
|
|
490
489
|
|
|
491
490
|
// src/lib/nlp-router.ts
|
|
492
491
|
function normalize(input) {
|
|
@@ -496,7 +495,7 @@ var NLP_KEYWORDS = {
|
|
|
496
495
|
save: ["\uC800\uC7A5", "\uC138\uC774\uBE0C", "\uCEE4\uBC0B", "\uC62C\uB824", "\uC62C\uB9AC\uAE30", "\uD478\uC2DC", "push", "commit"],
|
|
497
496
|
undo: ["\uB418\uB3CC\uB824", "\uB418\uB3CC\uB9AC\uAE30", "\uCDE8\uC18C", "\uC6D0\uB798\uB300\uB85C", "\uB864\uBC31", "\uB9AC\uC14B", "reset", "rollback"],
|
|
498
497
|
status: ["\uC0C1\uD0DC", "\uD604\uD669", "\uC5B4\uB5BB\uAC8C", "\uC5B4\uB54C", "\uC9C0\uAE08"],
|
|
499
|
-
diff: ["\uBCC0\uACBD", "\uBC14\uB010", "\uBB50\uBC14\uB01C", "\uCC28\uC774", "\uB2EC\uB77C\uC9C4", "\uC218\uC815\uB41C"]
|
|
498
|
+
diff: ["\uBCC0\uACBD", "\uBC14\uB010", "\uBB50\uBC14\uB01C", "\uBC14\uB00C\uC5C8", "\uCC28\uC774", "\uB2EC\uB77C\uC9C4", "\uC218\uC815\uB41C"]
|
|
500
499
|
};
|
|
501
500
|
function matchesKeywords(text, command) {
|
|
502
501
|
const keywords = NLP_KEYWORDS[command];
|
|
@@ -546,7 +545,7 @@ var RULES = [
|
|
|
546
545
|
command: "diff",
|
|
547
546
|
explanation: "\uBCC0\uACBD\uC0AC\uD56D \uC694\uC57D (vhk diff)",
|
|
548
547
|
confidence: "high",
|
|
549
|
-
test: (t2) => (matchesKeywords(t2, "diff") || /^diff$/.test(t2) || /λ³κ²½μ¬ν|μμ \s*λ΄μ|μ°¨μ΄\s
|
|
548
|
+
test: (t2) => (matchesKeywords(t2, "diff") || /^diff$/.test(t2) || /λ³κ²½μ¬ν|μμ \s*λ΄μ|μ°¨μ΄\s*보|λ\s*λ°λ/.test(t2)) && !/μ μ₯|컀λ°|push|νΈμ|μν|νν©|μΈμ΄λΈ|commit/.test(t2)
|
|
550
549
|
},
|
|
551
550
|
{
|
|
552
551
|
command: "undo",
|
|
@@ -611,6 +610,69 @@ function extractNotionUrl(input) {
|
|
|
611
610
|
return m?.[0];
|
|
612
611
|
}
|
|
613
612
|
|
|
613
|
+
// src/lib/cli-args.ts
|
|
614
|
+
var KNOWN_COMMAND_TOKENS = /* @__PURE__ */ new Set([
|
|
615
|
+
"gate",
|
|
616
|
+
"\uAC80\uC99D",
|
|
617
|
+
"\uC544\uC774\uB514\uC5B4",
|
|
618
|
+
"init",
|
|
619
|
+
"\uC2DC\uC791",
|
|
620
|
+
"\uB9CC\uB4E4\uAE30",
|
|
621
|
+
"recap",
|
|
622
|
+
"\uC815\uB9AC",
|
|
623
|
+
"\uC624\uB298",
|
|
624
|
+
"sync",
|
|
625
|
+
"\uB9DE\uCD94\uAE30",
|
|
626
|
+
"\uADDC\uCE59",
|
|
627
|
+
"check",
|
|
628
|
+
"\uC810\uAC80",
|
|
629
|
+
"\uB9B0\uD2B8",
|
|
630
|
+
"secure",
|
|
631
|
+
"\uBCF4\uC548",
|
|
632
|
+
"scan",
|
|
633
|
+
"\uC2A4\uCE94",
|
|
634
|
+
"ship",
|
|
635
|
+
"\uBC30\uD3EC",
|
|
636
|
+
"\uB9B4\uB9AC\uC988",
|
|
637
|
+
"doctor",
|
|
638
|
+
"\uD658\uACBD",
|
|
639
|
+
"\uC9C4\uB2E8",
|
|
640
|
+
"save",
|
|
641
|
+
"\uC800\uC7A5",
|
|
642
|
+
"undo",
|
|
643
|
+
"\uB418\uB3CC\uB9AC\uAE30",
|
|
644
|
+
"status",
|
|
645
|
+
"\uC0C1\uD0DC",
|
|
646
|
+
"\uD604\uD669",
|
|
647
|
+
"diff",
|
|
648
|
+
"\uBCC0\uACBD",
|
|
649
|
+
"\uCC28\uC774",
|
|
650
|
+
"help"
|
|
651
|
+
]);
|
|
652
|
+
function isOptionToken(token) {
|
|
653
|
+
return token.startsWith("-");
|
|
654
|
+
}
|
|
655
|
+
function detectNaturalLanguageInput(argv) {
|
|
656
|
+
const rest = argv.slice(2);
|
|
657
|
+
if (rest.length === 0) return null;
|
|
658
|
+
const first = rest[0];
|
|
659
|
+
if (isOptionToken(first)) return null;
|
|
660
|
+
const input = rest.join(" ").trim();
|
|
661
|
+
if (!input) return null;
|
|
662
|
+
const firstIsKnown = KNOWN_COMMAND_TOKENS.has(first);
|
|
663
|
+
if (firstIsKnown && rest.length === 1) return null;
|
|
664
|
+
if (firstIsKnown && rest.slice(1).every(isOptionToken)) return null;
|
|
665
|
+
if (firstIsKnown && rest.length > 1) {
|
|
666
|
+
if (routeNaturalLanguage(input)) return input;
|
|
667
|
+
return null;
|
|
668
|
+
}
|
|
669
|
+
return input;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
// src/lib/nlp-run.ts
|
|
673
|
+
import chalk16 from "chalk";
|
|
674
|
+
import inquirer7 from "inquirer";
|
|
675
|
+
|
|
614
676
|
// src/i18n/ko.ts
|
|
615
677
|
var ko = {
|
|
616
678
|
status: {
|
|
@@ -3203,104 +3265,23 @@ ${t("undo.recentHeader")}`));
|
|
|
3203
3265
|
}
|
|
3204
3266
|
}
|
|
3205
3267
|
|
|
3206
|
-
// src/commands/
|
|
3207
|
-
import { execFileSync as execFileSync4
|
|
3268
|
+
// src/commands/status.ts
|
|
3269
|
+
import { execFileSync as execFileSync4 } from "child_process";
|
|
3270
|
+
import fs15 from "fs";
|
|
3271
|
+
import path14 from "path";
|
|
3208
3272
|
import chalk14 from "chalk";
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
}
|
|
3215
|
-
}
|
|
3216
|
-
function parseDiffStat(stat) {
|
|
3217
|
-
const files = [];
|
|
3218
|
-
const lines = stat.split("\n");
|
|
3219
|
-
for (const line of lines) {
|
|
3220
|
-
const match = line.match(/^\s*(.+?)\s*\|\s*(\d+)/);
|
|
3221
|
-
if (!match) continue;
|
|
3222
|
-
const name = match[1].trim();
|
|
3223
|
-
if (name.includes("changed") || name.includes("file")) continue;
|
|
3224
|
-
const plusMatch = line.match(/(\++)/);
|
|
3225
|
-
const minusMatch = line.match(/(\-+)/);
|
|
3226
|
-
files.push({
|
|
3227
|
-
name,
|
|
3228
|
-
additions: plusMatch ? plusMatch[1].length : 0,
|
|
3229
|
-
deletions: minusMatch ? minusMatch[1].length : 0
|
|
3230
|
-
});
|
|
3231
|
-
}
|
|
3232
|
-
return files;
|
|
3233
|
-
}
|
|
3234
|
-
function summarizeNumstat(numstat) {
|
|
3235
|
-
let totalAdd = 0;
|
|
3236
|
-
let totalDel = 0;
|
|
3237
|
-
let fileCount = 0;
|
|
3238
|
-
for (const line of numstat.split("\n").filter(Boolean)) {
|
|
3239
|
-
const [add, del] = line.split(" ");
|
|
3240
|
-
if (add === void 0 || del === void 0) continue;
|
|
3241
|
-
totalAdd += parseInt(add, 10) || 0;
|
|
3242
|
-
totalDel += parseInt(del, 10) || 0;
|
|
3243
|
-
fileCount++;
|
|
3244
|
-
}
|
|
3245
|
-
return { fileCount, totalAdd, totalDel };
|
|
3246
|
-
}
|
|
3247
|
-
function printFile(f) {
|
|
3248
|
-
const adds = f.additions > 0 ? chalk14.green(`+${f.additions}`) : "";
|
|
3249
|
-
const dels = f.deletions > 0 ? chalk14.red(`-${f.deletions}`) : "";
|
|
3250
|
-
const change = [adds, dels].filter(Boolean).join(" ");
|
|
3251
|
-
console.log(` ${f.name} ${change}`);
|
|
3273
|
+
|
|
3274
|
+
// src/lib/read-json.ts
|
|
3275
|
+
import fs14 from "fs";
|
|
3276
|
+
function stripBom(text) {
|
|
3277
|
+
return text.charCodeAt(0) === 65279 ? text.slice(1) : text;
|
|
3252
3278
|
}
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
console.log(chalk14.gray("\u2500".repeat(40)));
|
|
3257
|
-
try {
|
|
3258
|
-
execSync2("git rev-parse --is-inside-work-tree", { stdio: "pipe" });
|
|
3259
|
-
} catch {
|
|
3260
|
-
console.log(chalk14.red(`\u274C ${t("diff.notGitRepo")}`));
|
|
3261
|
-
return;
|
|
3262
|
-
}
|
|
3263
|
-
const unstaged = gitOut2(["diff", "--stat"]);
|
|
3264
|
-
const staged = gitOut2(["diff", "--cached", "--stat"]);
|
|
3265
|
-
const untracked = gitOut2(["ls-files", "--others", "--exclude-standard"]);
|
|
3266
|
-
if (!unstaged && !staged && !untracked) {
|
|
3267
|
-
console.log(chalk14.green(`
|
|
3268
|
-
\u2705 ${t("diff.noChanges")}`));
|
|
3269
|
-
return;
|
|
3270
|
-
}
|
|
3271
|
-
if (staged) {
|
|
3272
|
-
console.log(chalk14.cyan(`
|
|
3273
|
-
${t("diff.stagedHeader")}`));
|
|
3274
|
-
parseDiffStat(staged).forEach((f) => printFile(f));
|
|
3275
|
-
}
|
|
3276
|
-
if (unstaged) {
|
|
3277
|
-
console.log(chalk14.cyan(`
|
|
3278
|
-
${t("diff.unstagedHeader")}`));
|
|
3279
|
-
parseDiffStat(unstaged).forEach((f) => printFile(f));
|
|
3280
|
-
}
|
|
3281
|
-
if (untracked) {
|
|
3282
|
-
const files = untracked.split("\n").filter(Boolean);
|
|
3283
|
-
console.log(chalk14.cyan(`
|
|
3284
|
-
${t("diff.untrackedHeader", files.length)}`));
|
|
3285
|
-
files.forEach((f) => console.log(` ${chalk14.green("+")} ${f}`));
|
|
3286
|
-
}
|
|
3287
|
-
const numstat = gitOut2(["diff", "--numstat", "HEAD"]);
|
|
3288
|
-
if (numstat) {
|
|
3289
|
-
const { fileCount, totalAdd, totalDel } = summarizeNumstat(numstat);
|
|
3290
|
-
console.log(chalk14.cyan(`
|
|
3291
|
-
${t("diff.summaryHeader")}`));
|
|
3292
|
-
console.log(` ${t("diff.filesLine", fileCount)}`);
|
|
3293
|
-
console.log(` \uCD94\uAC00: ${chalk14.green(`+${totalAdd}`)}\uC904`);
|
|
3294
|
-
console.log(` \uC0AD\uC81C: ${chalk14.red(`-${totalDel}`)}\uC904`);
|
|
3295
|
-
}
|
|
3296
|
-
console.log("");
|
|
3279
|
+
function readJsonFile(filePath) {
|
|
3280
|
+
const raw = stripBom(fs14.readFileSync(filePath, "utf-8"));
|
|
3281
|
+
return JSON.parse(raw);
|
|
3297
3282
|
}
|
|
3298
3283
|
|
|
3299
3284
|
// src/commands/status.ts
|
|
3300
|
-
import { execFileSync as execFileSync5 } from "child_process";
|
|
3301
|
-
import fs14 from "fs";
|
|
3302
|
-
import path14 from "path";
|
|
3303
|
-
import chalk15 from "chalk";
|
|
3304
3285
|
function countFileChanges(porcelain) {
|
|
3305
3286
|
const lines = porcelain.split("\n").filter(Boolean);
|
|
3306
3287
|
let staged = 0;
|
|
@@ -3339,9 +3320,9 @@ function parseRecentCommitLines(logOutput) {
|
|
|
3339
3320
|
}
|
|
3340
3321
|
function readProjectPackage(cwd = process.cwd()) {
|
|
3341
3322
|
const pkgPath = path14.join(cwd, "package.json");
|
|
3342
|
-
if (!
|
|
3323
|
+
if (!fs15.existsSync(pkgPath)) return null;
|
|
3343
3324
|
try {
|
|
3344
|
-
const pkg =
|
|
3325
|
+
const pkg = readJsonFile(pkgPath);
|
|
3345
3326
|
if (!pkg.name && !pkg.version) return null;
|
|
3346
3327
|
return {
|
|
3347
3328
|
name: pkg.name ?? "(no name)",
|
|
@@ -3360,15 +3341,15 @@ function getSyncCounts(gitRoot) {
|
|
|
3360
3341
|
}
|
|
3361
3342
|
}
|
|
3362
3343
|
async function status() {
|
|
3363
|
-
console.log(
|
|
3344
|
+
console.log(chalk14.bold(`
|
|
3364
3345
|
\u{1F4CA} ${t("status.title")}`));
|
|
3365
|
-
console.log(
|
|
3346
|
+
console.log(chalk14.gray("\u2500".repeat(40)));
|
|
3366
3347
|
let gitRoot;
|
|
3367
3348
|
try {
|
|
3368
|
-
|
|
3349
|
+
execFileSync4("git", ["rev-parse", "--is-inside-work-tree"], { stdio: "pipe" });
|
|
3369
3350
|
gitRoot = getGitRoot();
|
|
3370
3351
|
} catch {
|
|
3371
|
-
console.log(
|
|
3352
|
+
console.log(chalk14.red(`\u274C ${t("status.notGitRepo")}`));
|
|
3372
3353
|
return;
|
|
3373
3354
|
}
|
|
3374
3355
|
let branch;
|
|
@@ -3387,33 +3368,185 @@ async function status() {
|
|
|
3387
3368
|
commits = [];
|
|
3388
3369
|
}
|
|
3389
3370
|
const pkg = readProjectPackage();
|
|
3390
|
-
console.log(
|
|
3391
|
-
\u{1F33F} ${t("status.branch")}`) +
|
|
3371
|
+
console.log(chalk14.cyan(`
|
|
3372
|
+
\u{1F33F} ${t("status.branch")}`) + chalk14.white(` ${branch}`));
|
|
3392
3373
|
console.log(
|
|
3393
|
-
|
|
3374
|
+
chalk14.cyan(`\u{1F4C1} ${t("status.changes")}`) + chalk14.white(
|
|
3394
3375
|
` staged ${counts.staged} \xB7 unstaged ${counts.unstaged} \xB7 untracked ${counts.untracked}`
|
|
3395
3376
|
)
|
|
3396
3377
|
);
|
|
3397
|
-
console.log(
|
|
3378
|
+
console.log(chalk14.cyan(`
|
|
3398
3379
|
\u{1F4CB} ${t("status.recentCommits")}`));
|
|
3399
3380
|
if (commits.length === 0) {
|
|
3400
|
-
console.log(
|
|
3381
|
+
console.log(chalk14.dim(` ${t("status.noCommits")}`));
|
|
3401
3382
|
} else {
|
|
3402
|
-
commits.forEach((c) => console.log(` ${
|
|
3383
|
+
commits.forEach((c) => console.log(` ${chalk14.dim("\u2022")} ${c}`));
|
|
3403
3384
|
}
|
|
3404
3385
|
console.log(
|
|
3405
|
-
|
|
3406
|
-
\u{1F504} ${t("status.remote")}`) +
|
|
3386
|
+
chalk14.cyan(`
|
|
3387
|
+
\u{1F504} ${t("status.remote")}`) + chalk14.white(` ${formatSyncLabel(sync2)}`)
|
|
3407
3388
|
);
|
|
3408
|
-
console.log(
|
|
3389
|
+
console.log(chalk14.gray("\n" + "\u2500".repeat(40)));
|
|
3409
3390
|
if (pkg) {
|
|
3410
|
-
console.log(
|
|
3391
|
+
console.log(chalk14.cyan(`\u{1F4E6} ${t("status.package")}`) + chalk14.white(` ${pkg.name} v${pkg.version}`));
|
|
3411
3392
|
} else {
|
|
3412
|
-
console.log(
|
|
3393
|
+
console.log(chalk14.dim(`\u{1F4E6} ${t("status.noPackage")}`));
|
|
3413
3394
|
}
|
|
3414
3395
|
console.log("");
|
|
3415
3396
|
}
|
|
3416
3397
|
|
|
3398
|
+
// src/commands/diff.ts
|
|
3399
|
+
import { execFileSync as execFileSync5, execSync as execSync2 } from "child_process";
|
|
3400
|
+
import chalk15 from "chalk";
|
|
3401
|
+
function gitOut2(args) {
|
|
3402
|
+
try {
|
|
3403
|
+
return execFileSync5("git", args, { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
3404
|
+
} catch {
|
|
3405
|
+
return "";
|
|
3406
|
+
}
|
|
3407
|
+
}
|
|
3408
|
+
function parseDiffStat(stat) {
|
|
3409
|
+
const files = [];
|
|
3410
|
+
const lines = stat.split("\n");
|
|
3411
|
+
for (const line of lines) {
|
|
3412
|
+
const match = line.match(/^\s*(.+?)\s*\|\s*(\d+)/);
|
|
3413
|
+
if (!match) continue;
|
|
3414
|
+
const name = match[1].trim();
|
|
3415
|
+
if (name.includes("changed") || name.includes("file")) continue;
|
|
3416
|
+
const plusMatch = line.match(/(\++)/);
|
|
3417
|
+
const minusMatch = line.match(/(\-+)/);
|
|
3418
|
+
files.push({
|
|
3419
|
+
name,
|
|
3420
|
+
additions: plusMatch ? plusMatch[1].length : 0,
|
|
3421
|
+
deletions: minusMatch ? minusMatch[1].length : 0
|
|
3422
|
+
});
|
|
3423
|
+
}
|
|
3424
|
+
return files;
|
|
3425
|
+
}
|
|
3426
|
+
function summarizeNumstat(numstat) {
|
|
3427
|
+
let totalAdd = 0;
|
|
3428
|
+
let totalDel = 0;
|
|
3429
|
+
let fileCount = 0;
|
|
3430
|
+
for (const line of numstat.split("\n").filter(Boolean)) {
|
|
3431
|
+
const [add, del] = line.split(" ");
|
|
3432
|
+
if (add === void 0 || del === void 0) continue;
|
|
3433
|
+
totalAdd += parseInt(add, 10) || 0;
|
|
3434
|
+
totalDel += parseInt(del, 10) || 0;
|
|
3435
|
+
fileCount++;
|
|
3436
|
+
}
|
|
3437
|
+
return { fileCount, totalAdd, totalDel };
|
|
3438
|
+
}
|
|
3439
|
+
function printFile(f) {
|
|
3440
|
+
const adds = f.additions > 0 ? chalk15.green(`+${f.additions}`) : "";
|
|
3441
|
+
const dels = f.deletions > 0 ? chalk15.red(`-${f.deletions}`) : "";
|
|
3442
|
+
const change = [adds, dels].filter(Boolean).join(" ");
|
|
3443
|
+
console.log(` ${f.name} ${change}`);
|
|
3444
|
+
}
|
|
3445
|
+
async function diff() {
|
|
3446
|
+
console.log(chalk15.bold(`
|
|
3447
|
+
\u{1F50D} ${t("diff.title")}`));
|
|
3448
|
+
console.log(chalk15.gray("\u2500".repeat(40)));
|
|
3449
|
+
try {
|
|
3450
|
+
execSync2("git rev-parse --is-inside-work-tree", { stdio: "pipe" });
|
|
3451
|
+
} catch {
|
|
3452
|
+
console.log(chalk15.red(`\u274C ${t("diff.notGitRepo")}`));
|
|
3453
|
+
return;
|
|
3454
|
+
}
|
|
3455
|
+
const unstaged = gitOut2(["diff", "--stat"]);
|
|
3456
|
+
const staged = gitOut2(["diff", "--cached", "--stat"]);
|
|
3457
|
+
const untracked = gitOut2(["ls-files", "--others", "--exclude-standard"]);
|
|
3458
|
+
if (!unstaged && !staged && !untracked) {
|
|
3459
|
+
console.log(chalk15.green(`
|
|
3460
|
+
\u2705 ${t("diff.noChanges")}`));
|
|
3461
|
+
return;
|
|
3462
|
+
}
|
|
3463
|
+
if (staged) {
|
|
3464
|
+
console.log(chalk15.cyan(`
|
|
3465
|
+
${t("diff.stagedHeader")}`));
|
|
3466
|
+
parseDiffStat(staged).forEach((f) => printFile(f));
|
|
3467
|
+
}
|
|
3468
|
+
if (unstaged) {
|
|
3469
|
+
console.log(chalk15.cyan(`
|
|
3470
|
+
${t("diff.unstagedHeader")}`));
|
|
3471
|
+
parseDiffStat(unstaged).forEach((f) => printFile(f));
|
|
3472
|
+
}
|
|
3473
|
+
if (untracked) {
|
|
3474
|
+
const files = untracked.split("\n").filter(Boolean);
|
|
3475
|
+
console.log(chalk15.cyan(`
|
|
3476
|
+
${t("diff.untrackedHeader", files.length)}`));
|
|
3477
|
+
files.forEach((f) => console.log(` ${chalk15.green("+")} ${f}`));
|
|
3478
|
+
}
|
|
3479
|
+
const numstat = gitOut2(["diff", "--numstat", "HEAD"]);
|
|
3480
|
+
if (numstat) {
|
|
3481
|
+
const { fileCount, totalAdd, totalDel } = summarizeNumstat(numstat);
|
|
3482
|
+
console.log(chalk15.cyan(`
|
|
3483
|
+
${t("diff.summaryHeader")}`));
|
|
3484
|
+
console.log(` ${t("diff.filesLine", fileCount)}`);
|
|
3485
|
+
console.log(` \uCD94\uAC00: ${chalk15.green(`+${totalAdd}`)}\uC904`);
|
|
3486
|
+
console.log(` \uC0AD\uC81C: ${chalk15.red(`-${totalDel}`)}\uC904`);
|
|
3487
|
+
}
|
|
3488
|
+
console.log("");
|
|
3489
|
+
}
|
|
3490
|
+
|
|
3491
|
+
// src/lib/nlp-run.ts
|
|
3492
|
+
async function dispatchNlpRoute(route, input) {
|
|
3493
|
+
switch (route.command) {
|
|
3494
|
+
case "gate":
|
|
3495
|
+
return gate();
|
|
3496
|
+
case "init":
|
|
3497
|
+
return init({
|
|
3498
|
+
skipGate: route.args?.includes("--skip-gate"),
|
|
3499
|
+
fromNotion: route.args?.includes("--from-notion") ? extractNotionUrl(input) : void 0
|
|
3500
|
+
});
|
|
3501
|
+
case "recap":
|
|
3502
|
+
return recap({});
|
|
3503
|
+
case "sync":
|
|
3504
|
+
return sync();
|
|
3505
|
+
case "check":
|
|
3506
|
+
return check();
|
|
3507
|
+
case "secure":
|
|
3508
|
+
return secure();
|
|
3509
|
+
case "ship":
|
|
3510
|
+
return ship();
|
|
3511
|
+
case "doctor":
|
|
3512
|
+
return doctor();
|
|
3513
|
+
case "save":
|
|
3514
|
+
return save();
|
|
3515
|
+
case "undo":
|
|
3516
|
+
return undo();
|
|
3517
|
+
case "status":
|
|
3518
|
+
return status();
|
|
3519
|
+
case "diff":
|
|
3520
|
+
return diff();
|
|
3521
|
+
}
|
|
3522
|
+
}
|
|
3523
|
+
async function runNaturalLanguageRoute(input) {
|
|
3524
|
+
const route = routeNaturalLanguage(input);
|
|
3525
|
+
if (!route) {
|
|
3526
|
+
console.log(chalk16.yellow(`
|
|
3527
|
+
\u2753 "${input}" \u2014 ${ko.nlp.notMatched}
|
|
3528
|
+
`));
|
|
3529
|
+
return;
|
|
3530
|
+
}
|
|
3531
|
+
console.log("");
|
|
3532
|
+
console.log(chalk16.cyan(` \u{1F4AC} "${input}"`));
|
|
3533
|
+
console.log(chalk16.cyan(` \u2192 ${route.explanation}`));
|
|
3534
|
+
if (route.confidence === "low") {
|
|
3535
|
+
const { confirm } = await inquirer7.prompt([{
|
|
3536
|
+
type: "confirm",
|
|
3537
|
+
name: "confirm",
|
|
3538
|
+
message: `${route.explanation} \u2014 ${ko.nlp.matched}`,
|
|
3539
|
+
default: true
|
|
3540
|
+
}]);
|
|
3541
|
+
if (!confirm) {
|
|
3542
|
+
console.log(chalk16.dim(` ${ko.nlp.menuHint}`));
|
|
3543
|
+
return;
|
|
3544
|
+
}
|
|
3545
|
+
}
|
|
3546
|
+
console.log("");
|
|
3547
|
+
await dispatchNlpRoute(route, input);
|
|
3548
|
+
}
|
|
3549
|
+
|
|
3417
3550
|
// src/index.ts
|
|
3418
3551
|
var program = new Command();
|
|
3419
3552
|
var defaultHelp = new Help();
|
|
@@ -3431,7 +3564,7 @@ var KO_ALIASES = {
|
|
|
3431
3564
|
status: "\uC0C1\uD0DC",
|
|
3432
3565
|
diff: "\uBCC0\uACBD"
|
|
3433
3566
|
};
|
|
3434
|
-
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.5.
|
|
3567
|
+
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.5.2");
|
|
3435
3568
|
program.configureHelp({
|
|
3436
3569
|
formatHelp(cmd, helper) {
|
|
3437
3570
|
if (cmd.parent) {
|
|
@@ -3472,62 +3605,14 @@ program.command("status").alias("\uC0C1\uD0DC").description("\uD504\uB85C\uC81D\
|
|
|
3472
3605
|
});
|
|
3473
3606
|
program.command("diff").alias("\uBCC0\uACBD").alias("\uCC28\uC774").description("Git \uBCC0\uACBD\uC0AC\uD56D \uD55C\uAD6D\uC5B4 \uC694\uC57D (staged / unstaged / \uC0C8 \uD30C\uC77C)").action(diff);
|
|
3474
3607
|
program.on("command:*", async (operands) => {
|
|
3475
|
-
const
|
|
3476
|
-
const
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
console.log(chalk16.cyan(` \u{1F4AC} "${input}"`));
|
|
3480
|
-
console.log(chalk16.cyan(` \u2192 ${route.explanation}`));
|
|
3481
|
-
if (route.confidence === "low") {
|
|
3482
|
-
const { confirm } = await inquirer7.prompt([{
|
|
3483
|
-
type: "confirm",
|
|
3484
|
-
name: "confirm",
|
|
3485
|
-
message: `${route.explanation} \u2014 ${ko.nlp.matched}`,
|
|
3486
|
-
default: true
|
|
3487
|
-
}]);
|
|
3488
|
-
if (!confirm) {
|
|
3489
|
-
console.log(chalk16.dim(` ${ko.nlp.menuHint}`));
|
|
3490
|
-
return;
|
|
3491
|
-
}
|
|
3492
|
-
}
|
|
3493
|
-
console.log("");
|
|
3494
|
-
switch (route.command) {
|
|
3495
|
-
case "gate":
|
|
3496
|
-
return gate();
|
|
3497
|
-
case "init":
|
|
3498
|
-
return init({
|
|
3499
|
-
skipGate: route.args?.includes("--skip-gate"),
|
|
3500
|
-
fromNotion: route.args?.includes("--from-notion") ? extractNotionUrl(input) : void 0
|
|
3501
|
-
});
|
|
3502
|
-
case "recap":
|
|
3503
|
-
return recap({});
|
|
3504
|
-
case "sync":
|
|
3505
|
-
return sync();
|
|
3506
|
-
case "check":
|
|
3507
|
-
return check();
|
|
3508
|
-
case "secure":
|
|
3509
|
-
return secure();
|
|
3510
|
-
case "ship":
|
|
3511
|
-
return ship();
|
|
3512
|
-
case "doctor":
|
|
3513
|
-
return doctor();
|
|
3514
|
-
case "save":
|
|
3515
|
-
return save();
|
|
3516
|
-
case "undo":
|
|
3517
|
-
return undo();
|
|
3518
|
-
case "status":
|
|
3519
|
-
return status();
|
|
3520
|
-
case "diff":
|
|
3521
|
-
return diff();
|
|
3522
|
-
}
|
|
3523
|
-
}
|
|
3524
|
-
console.log(chalk16.yellow(`
|
|
3525
|
-
\u2753 "${input}" \u2014 ${ko.nlp.notMatched}
|
|
3526
|
-
`));
|
|
3608
|
+
const unknown = operands[0] ?? "";
|
|
3609
|
+
const rest = operands.slice(1);
|
|
3610
|
+
const input = [unknown, ...rest].join(" ").trim();
|
|
3611
|
+
await runNaturalLanguageRoute(input);
|
|
3527
3612
|
});
|
|
3528
3613
|
program.action(async () => {
|
|
3529
3614
|
console.log("\n\u{1F3AF} VHK \u2014 \uBC14\uC774\uBE0C\uCF54\uB529 \uD504\uB85C\uC81D\uD2B8 \uCF54\uCE58\n");
|
|
3530
|
-
const { choice } = await
|
|
3615
|
+
const { choice } = await inquirer8.prompt([{
|
|
3531
3616
|
type: "list",
|
|
3532
3617
|
name: "choice",
|
|
3533
3618
|
message: "\uBB58 \uB3C4\uC640\uB4DC\uB9B4\uAE4C\uC694?",
|
|
@@ -3573,4 +3658,9 @@ program.action(async () => {
|
|
|
3573
3658
|
return diff();
|
|
3574
3659
|
}
|
|
3575
3660
|
});
|
|
3576
|
-
|
|
3661
|
+
var nlInput = detectNaturalLanguageInput(process.argv);
|
|
3662
|
+
if (nlInput !== null) {
|
|
3663
|
+
await runNaturalLanguageRoute(nlInput);
|
|
3664
|
+
} else {
|
|
3665
|
+
await program.parseAsync(process.argv);
|
|
3666
|
+
}
|