@byh3071/vhk 1.0.0 → 1.0.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/dist/{chunk-7NGBIIA3.js → chunk-SD7O6HO7.js} +18 -7
- package/dist/index.js +121 -90
- package/dist/mcp/index.js +1 -1
- package/package.json +65 -65
|
@@ -455,7 +455,7 @@ async function envCheck() {
|
|
|
455
455
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
456
456
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
457
457
|
import { z } from "zod";
|
|
458
|
-
import { existsSync as existsSync2, readFileSync as
|
|
458
|
+
import { existsSync as existsSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2, appendFileSync as appendFileSync2 } from "fs";
|
|
459
459
|
|
|
460
460
|
// src/lib/exec.ts
|
|
461
461
|
import { execFileSync } from "child_process";
|
|
@@ -501,6 +501,16 @@ function safeExecFileStream(cmd, args) {
|
|
|
501
501
|
}
|
|
502
502
|
}
|
|
503
503
|
|
|
504
|
+
// src/lib/read-json.ts
|
|
505
|
+
import { readFileSync as readFileSync2 } from "fs";
|
|
506
|
+
function stripBom(text) {
|
|
507
|
+
return text.charCodeAt(0) === 65279 ? text.slice(1) : text;
|
|
508
|
+
}
|
|
509
|
+
function readJsonFile(filePath) {
|
|
510
|
+
const raw = stripBom(readFileSync2(filePath, "utf-8"));
|
|
511
|
+
return JSON.parse(raw);
|
|
512
|
+
}
|
|
513
|
+
|
|
504
514
|
// src/mcp/server.ts
|
|
505
515
|
var SERVER_VERSION = "0.7.1";
|
|
506
516
|
function isGitRepo() {
|
|
@@ -582,7 +592,7 @@ function createVhkMcpServer() {
|
|
|
582
592
|
const lines = [];
|
|
583
593
|
if (existsSync2("package.json")) {
|
|
584
594
|
try {
|
|
585
|
-
const pkg =
|
|
595
|
+
const pkg = readJsonFile("package.json");
|
|
586
596
|
lines.push(`\u{1F4E6} \uD504\uB85C\uC81D\uD2B8: ${pkg.name ?? "(\uC774\uB984 \uC5C6\uC74C)"} v${pkg.version ?? "?"}`);
|
|
587
597
|
} catch {
|
|
588
598
|
}
|
|
@@ -667,7 +677,7 @@ function createVhkMcpServer() {
|
|
|
667
677
|
checks.push(test.ok ? "\u2705 \uD14C\uC2A4\uD2B8 \uD1B5\uACFC" : "\u274C \uD14C\uC2A4\uD2B8 \uC2E4\uD328");
|
|
668
678
|
if (existsSync2("package.json")) {
|
|
669
679
|
try {
|
|
670
|
-
const pkg =
|
|
680
|
+
const pkg = readJsonFile("package.json");
|
|
671
681
|
checks.push(`\u{1F4E6} \uBC84\uC804: ${pkg.version}`);
|
|
672
682
|
} catch {
|
|
673
683
|
}
|
|
@@ -744,7 +754,7 @@ ${log.out}` }] };
|
|
|
744
754
|
if (!existsSync2(".env")) {
|
|
745
755
|
return { content: [{ type: "text", text: "\u26A0\uFE0F .env \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. \uBA3C\uC800 .env\uB97C \uB9CC\uB4E4\uC5B4\uC8FC\uC138\uC694." }] };
|
|
746
756
|
}
|
|
747
|
-
const keys = parseEnvKeys(
|
|
757
|
+
const keys = parseEnvKeys(readFileSync3(".env", "utf-8"));
|
|
748
758
|
if (keys.length === 0) {
|
|
749
759
|
return { content: [{ type: "text", text: "\u{1F4ED} .env\uC5D0 \uD658\uACBD\uBCC0\uC218\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4." }] };
|
|
750
760
|
}
|
|
@@ -752,7 +762,7 @@ ${log.out}` }] };
|
|
|
752
762
|
writeFileSync2(".env.example", exampleContent, "utf-8");
|
|
753
763
|
const gitignoreLines = [];
|
|
754
764
|
if (existsSync2(".gitignore")) {
|
|
755
|
-
const content =
|
|
765
|
+
const content = readFileSync3(".gitignore", "utf-8");
|
|
756
766
|
if (!content.split("\n").some((l) => l.trim() === ".env")) {
|
|
757
767
|
appendFileSync2(".gitignore", "\n.env\n");
|
|
758
768
|
gitignoreLines.push("\u{1F512} .gitignore\uC5D0 .env \uCD94\uAC00\uB428");
|
|
@@ -775,8 +785,8 @@ ${log.out}` }] };
|
|
|
775
785
|
if (!existsSync2(".env.example")) {
|
|
776
786
|
return { content: [{ type: "text", text: "\u26A0\uFE0F .env.example\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. \uBA3C\uC800 env \uB3C4\uAD6C\uB97C \uC2E4\uD589\uD558\uC138\uC694." }] };
|
|
777
787
|
}
|
|
778
|
-
const requiredKeys = parseEnvKeys(
|
|
779
|
-
const currentKeys = existsSync2(".env") ? parseEnvKeys(
|
|
788
|
+
const requiredKeys = parseEnvKeys(readFileSync3(".env.example", "utf-8"));
|
|
789
|
+
const currentKeys = existsSync2(".env") ? parseEnvKeys(readFileSync3(".env", "utf-8")) : [];
|
|
780
790
|
const missing = requiredKeys.filter((k) => !currentKeys.includes(k));
|
|
781
791
|
const extra = currentKeys.filter((k) => !requiredKeys.includes(k));
|
|
782
792
|
const lines = [`\u{1F4CB} \uD544\uC218 \uD658\uACBD\uBCC0\uC218: ${requiredKeys.length}\uAC1C`];
|
|
@@ -807,6 +817,7 @@ export {
|
|
|
807
817
|
ko,
|
|
808
818
|
t,
|
|
809
819
|
printNextStep,
|
|
820
|
+
readJsonFile,
|
|
810
821
|
safeExecFile,
|
|
811
822
|
safeExecFileStream,
|
|
812
823
|
env,
|
package/dist/index.js
CHANGED
|
@@ -6,11 +6,12 @@ import {
|
|
|
6
6
|
envCheck,
|
|
7
7
|
ko,
|
|
8
8
|
printNextStep,
|
|
9
|
+
readJsonFile,
|
|
9
10
|
safeExecFile,
|
|
10
11
|
safeExecFileStream,
|
|
11
12
|
startMcpServer,
|
|
12
13
|
t
|
|
13
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-SD7O6HO7.js";
|
|
14
15
|
|
|
15
16
|
// node_modules/.pnpm/ignore@7.0.5/node_modules/ignore/index.js
|
|
16
17
|
var require_ignore = __commonJS({
|
|
@@ -310,7 +311,7 @@ var require_ignore = __commonJS({
|
|
|
310
311
|
// path matching.
|
|
311
312
|
// - check `string` either `MODE_IGNORE` or `MODE_CHECK_IGNORE`
|
|
312
313
|
// @returns {TestResult} true if a file is ignored
|
|
313
|
-
test(
|
|
314
|
+
test(path15, checkUnignored, mode) {
|
|
314
315
|
let ignored = false;
|
|
315
316
|
let unignored = false;
|
|
316
317
|
let matchedRule;
|
|
@@ -319,7 +320,7 @@ var require_ignore = __commonJS({
|
|
|
319
320
|
if (unignored === negative && ignored !== unignored || negative && !ignored && !unignored && !checkUnignored) {
|
|
320
321
|
return;
|
|
321
322
|
}
|
|
322
|
-
const matched = rule[mode].test(
|
|
323
|
+
const matched = rule[mode].test(path15);
|
|
323
324
|
if (!matched) {
|
|
324
325
|
return;
|
|
325
326
|
}
|
|
@@ -340,17 +341,17 @@ var require_ignore = __commonJS({
|
|
|
340
341
|
var throwError = (message, Ctor) => {
|
|
341
342
|
throw new Ctor(message);
|
|
342
343
|
};
|
|
343
|
-
var checkPath = (
|
|
344
|
-
if (!isString(
|
|
344
|
+
var checkPath = (path15, originalPath, doThrow) => {
|
|
345
|
+
if (!isString(path15)) {
|
|
345
346
|
return doThrow(
|
|
346
347
|
`path must be a string, but got \`${originalPath}\``,
|
|
347
348
|
TypeError
|
|
348
349
|
);
|
|
349
350
|
}
|
|
350
|
-
if (!
|
|
351
|
+
if (!path15) {
|
|
351
352
|
return doThrow(`path must not be empty`, TypeError);
|
|
352
353
|
}
|
|
353
|
-
if (checkPath.isNotRelative(
|
|
354
|
+
if (checkPath.isNotRelative(path15)) {
|
|
354
355
|
const r = "`path.relative()`d";
|
|
355
356
|
return doThrow(
|
|
356
357
|
`path should be a ${r} string, but got "${originalPath}"`,
|
|
@@ -359,7 +360,7 @@ var require_ignore = __commonJS({
|
|
|
359
360
|
}
|
|
360
361
|
return true;
|
|
361
362
|
};
|
|
362
|
-
var isNotRelative = (
|
|
363
|
+
var isNotRelative = (path15) => REGEX_TEST_INVALID_PATH.test(path15);
|
|
363
364
|
checkPath.isNotRelative = isNotRelative;
|
|
364
365
|
checkPath.convert = (p) => p;
|
|
365
366
|
var Ignore = class {
|
|
@@ -389,19 +390,19 @@ var require_ignore = __commonJS({
|
|
|
389
390
|
}
|
|
390
391
|
// @returns {TestResult}
|
|
391
392
|
_test(originalPath, cache, checkUnignored, slices) {
|
|
392
|
-
const
|
|
393
|
+
const path15 = originalPath && checkPath.convert(originalPath);
|
|
393
394
|
checkPath(
|
|
394
|
-
|
|
395
|
+
path15,
|
|
395
396
|
originalPath,
|
|
396
397
|
this._strictPathCheck ? throwError : RETURN_FALSE
|
|
397
398
|
);
|
|
398
|
-
return this._t(
|
|
399
|
+
return this._t(path15, cache, checkUnignored, slices);
|
|
399
400
|
}
|
|
400
|
-
checkIgnore(
|
|
401
|
-
if (!REGEX_TEST_TRAILING_SLASH.test(
|
|
402
|
-
return this.test(
|
|
401
|
+
checkIgnore(path15) {
|
|
402
|
+
if (!REGEX_TEST_TRAILING_SLASH.test(path15)) {
|
|
403
|
+
return this.test(path15);
|
|
403
404
|
}
|
|
404
|
-
const slices =
|
|
405
|
+
const slices = path15.split(SLASH).filter(Boolean);
|
|
405
406
|
slices.pop();
|
|
406
407
|
if (slices.length) {
|
|
407
408
|
const parent = this._t(
|
|
@@ -414,18 +415,18 @@ var require_ignore = __commonJS({
|
|
|
414
415
|
return parent;
|
|
415
416
|
}
|
|
416
417
|
}
|
|
417
|
-
return this._rules.test(
|
|
418
|
+
return this._rules.test(path15, false, MODE_CHECK_IGNORE);
|
|
418
419
|
}
|
|
419
|
-
_t(
|
|
420
|
-
if (
|
|
421
|
-
return cache[
|
|
420
|
+
_t(path15, cache, checkUnignored, slices) {
|
|
421
|
+
if (path15 in cache) {
|
|
422
|
+
return cache[path15];
|
|
422
423
|
}
|
|
423
424
|
if (!slices) {
|
|
424
|
-
slices =
|
|
425
|
+
slices = path15.split(SLASH).filter(Boolean);
|
|
425
426
|
}
|
|
426
427
|
slices.pop();
|
|
427
428
|
if (!slices.length) {
|
|
428
|
-
return cache[
|
|
429
|
+
return cache[path15] = this._rules.test(path15, checkUnignored, MODE_IGNORE);
|
|
429
430
|
}
|
|
430
431
|
const parent = this._t(
|
|
431
432
|
slices.join(SLASH) + SLASH,
|
|
@@ -433,29 +434,29 @@ var require_ignore = __commonJS({
|
|
|
433
434
|
checkUnignored,
|
|
434
435
|
slices
|
|
435
436
|
);
|
|
436
|
-
return cache[
|
|
437
|
+
return cache[path15] = parent.ignored ? parent : this._rules.test(path15, checkUnignored, MODE_IGNORE);
|
|
437
438
|
}
|
|
438
|
-
ignores(
|
|
439
|
-
return this._test(
|
|
439
|
+
ignores(path15) {
|
|
440
|
+
return this._test(path15, this._ignoreCache, false).ignored;
|
|
440
441
|
}
|
|
441
442
|
createFilter() {
|
|
442
|
-
return (
|
|
443
|
+
return (path15) => !this.ignores(path15);
|
|
443
444
|
}
|
|
444
445
|
filter(paths) {
|
|
445
446
|
return makeArray(paths).filter(this.createFilter());
|
|
446
447
|
}
|
|
447
448
|
// @returns {TestResult}
|
|
448
|
-
test(
|
|
449
|
-
return this._test(
|
|
449
|
+
test(path15) {
|
|
450
|
+
return this._test(path15, this._testCache, true);
|
|
450
451
|
}
|
|
451
452
|
};
|
|
452
453
|
var factory = (options) => new Ignore(options);
|
|
453
|
-
var isPathValid = (
|
|
454
|
+
var isPathValid = (path15) => checkPath(path15 && checkPath.convert(path15), path15, RETURN_FALSE);
|
|
454
455
|
var setupWindows = () => {
|
|
455
456
|
const makePosix = (str) => /^\\\\\?\\/.test(str) || /["<>|\u0000-\u001F]+/u.test(str) ? str : str.replace(/\\/g, "/");
|
|
456
457
|
checkPath.convert = makePosix;
|
|
457
458
|
const REGEX_TEST_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i;
|
|
458
|
-
checkPath.isNotRelative = (
|
|
459
|
+
checkPath.isNotRelative = (path15) => REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path15) || isNotRelative(path15);
|
|
459
460
|
};
|
|
460
461
|
if (
|
|
461
462
|
// Detect `process` so that it can run in browsers.
|
|
@@ -473,9 +474,6 @@ var require_ignore = __commonJS({
|
|
|
473
474
|
// src/index.ts
|
|
474
475
|
import { Command, Help } from "commander";
|
|
475
476
|
import inquirer14 from "inquirer";
|
|
476
|
-
import fs15 from "fs";
|
|
477
|
-
import path15 from "path";
|
|
478
|
-
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
479
477
|
|
|
480
478
|
// src/lib/nlp-router.ts
|
|
481
479
|
function normalize(input) {
|
|
@@ -1570,7 +1568,7 @@ var VHK_PACKAGE_SCRIPTS = {
|
|
|
1570
1568
|
function enhancePackageScripts(projectDir) {
|
|
1571
1569
|
const pkgPath = path3.join(projectDir, "package.json");
|
|
1572
1570
|
if (!fs3.existsSync(pkgPath)) return false;
|
|
1573
|
-
const pkg =
|
|
1571
|
+
const pkg = readJsonFile(pkgPath);
|
|
1574
1572
|
pkg.scripts = { ...VHK_PACKAGE_SCRIPTS, ...pkg.scripts };
|
|
1575
1573
|
fs3.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n", "utf-8");
|
|
1576
1574
|
return true;
|
|
@@ -1647,19 +1645,27 @@ function buildSessionDiffFromSummary(diffSummary) {
|
|
|
1647
1645
|
}
|
|
1648
1646
|
async function getSessionDiff(since) {
|
|
1649
1647
|
const sinceDate = since || (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
1650
|
-
|
|
1651
|
-
|
|
1648
|
+
try {
|
|
1649
|
+
const diffSummary = await git.diffSummary([`--since=${sinceDate}`]);
|
|
1650
|
+
return buildSessionDiffFromSummary(diffSummary);
|
|
1651
|
+
} catch {
|
|
1652
|
+
return { filesChanged: 0, insertions: 0, deletions: 0, files: [] };
|
|
1653
|
+
}
|
|
1652
1654
|
}
|
|
1653
1655
|
async function getRecentCommits(count = 10, since) {
|
|
1654
1656
|
const options = { maxCount: count };
|
|
1655
1657
|
if (since) options["--since"] = since;
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1658
|
+
try {
|
|
1659
|
+
const log2 = await git.log(options);
|
|
1660
|
+
return log2.all.map((entry) => ({
|
|
1661
|
+
hash: entry.hash,
|
|
1662
|
+
message: entry.message,
|
|
1663
|
+
date: entry.date,
|
|
1664
|
+
author: entry.author_name
|
|
1665
|
+
}));
|
|
1666
|
+
} catch {
|
|
1667
|
+
return [];
|
|
1668
|
+
}
|
|
1663
1669
|
}
|
|
1664
1670
|
async function isGitRepo() {
|
|
1665
1671
|
try {
|
|
@@ -1669,6 +1675,14 @@ async function isGitRepo() {
|
|
|
1669
1675
|
return false;
|
|
1670
1676
|
}
|
|
1671
1677
|
}
|
|
1678
|
+
async function hasAnyCommits() {
|
|
1679
|
+
try {
|
|
1680
|
+
await git.revparse(["HEAD"]);
|
|
1681
|
+
return true;
|
|
1682
|
+
} catch {
|
|
1683
|
+
return false;
|
|
1684
|
+
}
|
|
1685
|
+
}
|
|
1672
1686
|
|
|
1673
1687
|
// src/lib/adr.ts
|
|
1674
1688
|
import fs4 from "fs";
|
|
@@ -1767,6 +1781,11 @@ ${ko.recap.title}
|
|
|
1767
1781
|
console.log(chalk5.red(ko.recap.noRepo));
|
|
1768
1782
|
return;
|
|
1769
1783
|
}
|
|
1784
|
+
if (!await hasAnyCommits()) {
|
|
1785
|
+
console.log(chalk5.yellow("\u26A0\uFE0F \uC544\uC9C1 \uCEE4\uBC0B\uC774 \uC5C6\uC5B4\uC694."));
|
|
1786
|
+
console.log(chalk5.gray(" \uD30C\uC77C\uC744 \uCD94\uAC00\uD558\uACE0 `vhk save` \uB610\uB294 `git commit`\uC73C\uB85C \uCCAB \uCEE4\uBC0B\uC744 \uB9CC\uB4E4\uC5B4 \uBCF4\uC138\uC694."));
|
|
1787
|
+
return;
|
|
1788
|
+
}
|
|
1770
1789
|
printSecurityWarnings();
|
|
1771
1790
|
console.log(chalk5.dim(`${ko.recap.analyzing}
|
|
1772
1791
|
`));
|
|
@@ -2628,7 +2647,7 @@ function getVhkVersion() {
|
|
|
2628
2647
|
for (const pkgPath of candidates) {
|
|
2629
2648
|
try {
|
|
2630
2649
|
if (fs12.existsSync(pkgPath)) {
|
|
2631
|
-
const pkg =
|
|
2650
|
+
const pkg = readJsonFile(pkgPath);
|
|
2632
2651
|
return pkg.version;
|
|
2633
2652
|
}
|
|
2634
2653
|
} catch {
|
|
@@ -3171,18 +3190,6 @@ import { execFileSync as execFileSync4 } from "child_process";
|
|
|
3171
3190
|
import fs14 from "fs";
|
|
3172
3191
|
import path14 from "path";
|
|
3173
3192
|
import chalk13 from "chalk";
|
|
3174
|
-
|
|
3175
|
-
// src/lib/read-json.ts
|
|
3176
|
-
import { readFileSync } from "fs";
|
|
3177
|
-
function stripBom(text) {
|
|
3178
|
-
return text.charCodeAt(0) === 65279 ? text.slice(1) : text;
|
|
3179
|
-
}
|
|
3180
|
-
function readJsonFile(filePath) {
|
|
3181
|
-
const raw = stripBom(readFileSync(filePath, "utf-8"));
|
|
3182
|
-
return JSON.parse(raw);
|
|
3183
|
-
}
|
|
3184
|
-
|
|
3185
|
-
// src/commands/status.ts
|
|
3186
3193
|
function countFileChanges(porcelain) {
|
|
3187
3194
|
const lines = porcelain.split("\n").filter(Boolean);
|
|
3188
3195
|
let staged = 0;
|
|
@@ -3390,27 +3397,47 @@ ${t("diff.summaryHeader")}`));
|
|
|
3390
3397
|
}
|
|
3391
3398
|
|
|
3392
3399
|
// src/commands/mcp-init.ts
|
|
3393
|
-
import { existsSync, mkdirSync,
|
|
3394
|
-
import { join } from "path";
|
|
3400
|
+
import { existsSync, mkdirSync, writeFileSync } from "fs";
|
|
3401
|
+
import { join, dirname } from "path";
|
|
3395
3402
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
3396
3403
|
import chalk15 from "chalk";
|
|
3397
|
-
function
|
|
3404
|
+
function resolveMcpEntryPoint() {
|
|
3405
|
+
try {
|
|
3406
|
+
const here = fileURLToPath2(import.meta.url);
|
|
3407
|
+
const dir = dirname(here);
|
|
3408
|
+
for (const rel of [["mcp", "index.js"], ["..", "mcp", "index.js"]]) {
|
|
3409
|
+
const candidate = join(dir, ...rel);
|
|
3410
|
+
if (existsSync(candidate)) return candidate;
|
|
3411
|
+
}
|
|
3412
|
+
} catch {
|
|
3413
|
+
}
|
|
3414
|
+
try {
|
|
3415
|
+
const url = import.meta.resolve?.("@byh3071/vhk/dist/mcp/index.js");
|
|
3416
|
+
if (typeof url === "string") {
|
|
3417
|
+
const p = fileURLToPath2(url);
|
|
3418
|
+
if (existsSync(p)) return p;
|
|
3419
|
+
}
|
|
3420
|
+
} catch {
|
|
3421
|
+
}
|
|
3398
3422
|
try {
|
|
3399
3423
|
const pkgPath = join(process.cwd(), "package.json");
|
|
3400
3424
|
if (existsSync(pkgPath)) {
|
|
3401
|
-
const pkg =
|
|
3425
|
+
const pkg = readJsonFile(pkgPath);
|
|
3402
3426
|
if (pkg.name === "@byh3071/vhk") {
|
|
3403
|
-
|
|
3427
|
+
const local = join(process.cwd(), "dist", "mcp", "index.js");
|
|
3428
|
+
if (existsSync(local)) return local;
|
|
3404
3429
|
}
|
|
3405
3430
|
}
|
|
3406
3431
|
} catch {
|
|
3407
3432
|
}
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3433
|
+
return null;
|
|
3434
|
+
}
|
|
3435
|
+
function resolveVhkMcpEntry() {
|
|
3436
|
+
const entryPath = resolveMcpEntryPoint();
|
|
3437
|
+
if (entryPath) {
|
|
3438
|
+
return { command: "node", args: [entryPath] };
|
|
3412
3439
|
}
|
|
3413
|
-
return
|
|
3440
|
+
return { command: "vhk-mcp", args: [] };
|
|
3414
3441
|
}
|
|
3415
3442
|
async function mcpInit() {
|
|
3416
3443
|
console.log(chalk15.bold("\n\u{1F50C} " + t("mcp.initTitle")));
|
|
@@ -3420,14 +3447,11 @@ async function mcpInit() {
|
|
|
3420
3447
|
mkdirSync(cursorDir, { recursive: true });
|
|
3421
3448
|
}
|
|
3422
3449
|
const configPath = join(cursorDir, "mcp.json");
|
|
3423
|
-
const vhkEntry =
|
|
3424
|
-
command: "node",
|
|
3425
|
-
args: [resolveVhkMcpPath()]
|
|
3426
|
-
};
|
|
3450
|
+
const vhkEntry = resolveVhkMcpEntry();
|
|
3427
3451
|
let config;
|
|
3428
3452
|
if (existsSync(configPath)) {
|
|
3429
3453
|
try {
|
|
3430
|
-
const parsed =
|
|
3454
|
+
const parsed = readJsonFile(configPath);
|
|
3431
3455
|
config = {
|
|
3432
3456
|
mcpServers: { ...parsed.mcpServers ?? {}, vhk: vhkEntry }
|
|
3433
3457
|
};
|
|
@@ -3550,7 +3574,7 @@ ${t("deploy.deploying")}
|
|
|
3550
3574
|
}
|
|
3551
3575
|
|
|
3552
3576
|
// src/commands/publish.ts
|
|
3553
|
-
import { existsSync as existsSync3,
|
|
3577
|
+
import { existsSync as existsSync3, writeFileSync as writeFileSync2 } from "fs";
|
|
3554
3578
|
import chalk17 from "chalk";
|
|
3555
3579
|
import inquirer8 from "inquirer";
|
|
3556
3580
|
import ora2 from "ora";
|
|
@@ -3574,7 +3598,7 @@ async function publish() {
|
|
|
3574
3598
|
}
|
|
3575
3599
|
let pkg;
|
|
3576
3600
|
try {
|
|
3577
|
-
pkg =
|
|
3601
|
+
pkg = readJsonFile("package.json");
|
|
3578
3602
|
} catch {
|
|
3579
3603
|
console.log(chalk17.red("\u274C package.json \uD30C\uC2F1 \uC2E4\uD328"));
|
|
3580
3604
|
return;
|
|
@@ -3899,14 +3923,13 @@ async function theme() {
|
|
|
3899
3923
|
}
|
|
3900
3924
|
|
|
3901
3925
|
// src/commands/ref.ts
|
|
3902
|
-
import { existsSync as existsSync6, mkdirSync as mkdirSync4,
|
|
3926
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync4, writeFileSync as writeFileSync5 } from "fs";
|
|
3903
3927
|
import chalk20 from "chalk";
|
|
3904
3928
|
var REFS_PATH = ".vhk/refs.json";
|
|
3905
3929
|
function loadRefs() {
|
|
3906
3930
|
if (!existsSync6(REFS_PATH)) return [];
|
|
3907
3931
|
try {
|
|
3908
|
-
const
|
|
3909
|
-
const parsed = JSON.parse(raw);
|
|
3932
|
+
const parsed = readJsonFile(REFS_PATH);
|
|
3910
3933
|
return Array.isArray(parsed) ? parsed : [];
|
|
3911
3934
|
} catch {
|
|
3912
3935
|
return [];
|
|
@@ -3998,7 +4021,7 @@ async function refOpen(indexStr) {
|
|
|
3998
4021
|
}
|
|
3999
4022
|
|
|
4000
4023
|
// src/commands/harness.ts
|
|
4001
|
-
import { existsSync as existsSync7
|
|
4024
|
+
import { existsSync as existsSync7 } from "fs";
|
|
4002
4025
|
import chalk21 from "chalk";
|
|
4003
4026
|
import ora3 from "ora";
|
|
4004
4027
|
function detectPM() {
|
|
@@ -4013,7 +4036,7 @@ function detectChecks() {
|
|
|
4013
4036
|
const checks = [];
|
|
4014
4037
|
let pkg = {};
|
|
4015
4038
|
try {
|
|
4016
|
-
pkg =
|
|
4039
|
+
pkg = readJsonFile("package.json");
|
|
4017
4040
|
} catch {
|
|
4018
4041
|
return checks;
|
|
4019
4042
|
}
|
|
@@ -4283,18 +4306,18 @@ async function migrate(target) {
|
|
|
4283
4306
|
|
|
4284
4307
|
// src/commands/update.ts
|
|
4285
4308
|
import { execSync as execSync3 } from "child_process";
|
|
4286
|
-
import { existsSync as existsSync10
|
|
4287
|
-
import { dirname, join as join2 } from "path";
|
|
4309
|
+
import { existsSync as existsSync10 } from "fs";
|
|
4310
|
+
import { dirname as dirname2, join as join2 } from "path";
|
|
4288
4311
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
4289
4312
|
import chalk24 from "chalk";
|
|
4290
4313
|
import ora6 from "ora";
|
|
4291
4314
|
var PACKAGE = "@byh3071/vhk";
|
|
4292
4315
|
function getCurrentVersion() {
|
|
4293
|
-
const dir =
|
|
4316
|
+
const dir = dirname2(fileURLToPath3(import.meta.url));
|
|
4294
4317
|
for (const pkgPath of [join2(dir, "../package.json"), join2(dir, "../../package.json")]) {
|
|
4295
4318
|
try {
|
|
4296
4319
|
if (existsSync10(pkgPath)) {
|
|
4297
|
-
const pkg =
|
|
4320
|
+
const pkg = readJsonFile(pkgPath);
|
|
4298
4321
|
if (pkg.version) return pkg.version;
|
|
4299
4322
|
}
|
|
4300
4323
|
} catch {
|
|
@@ -4362,7 +4385,7 @@ async function update() {
|
|
|
4362
4385
|
import {
|
|
4363
4386
|
existsSync as existsSync11,
|
|
4364
4387
|
mkdirSync as mkdirSync5,
|
|
4365
|
-
readFileSync as
|
|
4388
|
+
readFileSync as readFileSync2,
|
|
4366
4389
|
readdirSync,
|
|
4367
4390
|
statSync,
|
|
4368
4391
|
writeFileSync as writeFileSync6
|
|
@@ -4538,7 +4561,7 @@ async function contextShow() {
|
|
|
4538
4561
|
console.log(chalk25.gray(" vhk context\uB97C \uBA3C\uC800 \uC2E4\uD589\uD558\uC138\uC694."));
|
|
4539
4562
|
return;
|
|
4540
4563
|
}
|
|
4541
|
-
const content =
|
|
4564
|
+
const content = readFileSync2(CONTEXT_PATH, "utf-8");
|
|
4542
4565
|
console.log("\n" + content);
|
|
4543
4566
|
}
|
|
4544
4567
|
|
|
@@ -4814,13 +4837,19 @@ async function runNaturalLanguageRoute(input) {
|
|
|
4814
4837
|
await dispatchNlpRoute(route, input);
|
|
4815
4838
|
}
|
|
4816
4839
|
|
|
4817
|
-
// src/
|
|
4818
|
-
|
|
4819
|
-
|
|
4820
|
-
|
|
4840
|
+
// src/lib/version.ts
|
|
4841
|
+
import { existsSync as existsSync14 } from "fs";
|
|
4842
|
+
import { dirname as dirname3, join as join4 } from "path";
|
|
4843
|
+
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
4844
|
+
function getVhkVersion2() {
|
|
4845
|
+
const dir = dirname3(fileURLToPath4(import.meta.url));
|
|
4846
|
+
for (const pkgPath of [
|
|
4847
|
+
join4(dir, "../../package.json"),
|
|
4848
|
+
join4(dir, "../package.json")
|
|
4849
|
+
]) {
|
|
4821
4850
|
try {
|
|
4822
|
-
if (
|
|
4823
|
-
const pkg =
|
|
4851
|
+
if (existsSync14(pkgPath)) {
|
|
4852
|
+
const pkg = readJsonFile(pkgPath);
|
|
4824
4853
|
if (pkg.version) return pkg.version;
|
|
4825
4854
|
}
|
|
4826
4855
|
} catch {
|
|
@@ -4829,6 +4858,8 @@ function getVersion() {
|
|
|
4829
4858
|
}
|
|
4830
4859
|
return "0.0.0";
|
|
4831
4860
|
}
|
|
4861
|
+
|
|
4862
|
+
// src/index.ts
|
|
4832
4863
|
var program = new Command();
|
|
4833
4864
|
var defaultHelp = new Help();
|
|
4834
4865
|
var KO_ALIASES = {
|
|
@@ -4861,7 +4892,7 @@ var KO_ALIASES = {
|
|
|
4861
4892
|
memory: "\uAE30\uC5B5",
|
|
4862
4893
|
brief: "\uBE0C\uB9AC\uD551"
|
|
4863
4894
|
};
|
|
4864
|
-
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(
|
|
4895
|
+
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(getVhkVersion2());
|
|
4865
4896
|
program.configureHelp({
|
|
4866
4897
|
formatHelp(cmd, helper) {
|
|
4867
4898
|
if (cmd.parent) {
|
package/dist/mcp/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,65 +1,65 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@byh3071/vhk",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Vibe Harness Kit — 바이브코딩 풀사이클 CLI",
|
|
5
|
-
"bin": {
|
|
6
|
-
"vhk": "dist/index.js",
|
|
7
|
-
"vhk-mcp": "dist/mcp/index.js"
|
|
8
|
-
},
|
|
9
|
-
"type": "module",
|
|
10
|
-
"scripts": {
|
|
11
|
-
"dev": "tsx src/index.ts",
|
|
12
|
-
"build": "tsup",
|
|
13
|
-
"test": "vitest",
|
|
14
|
-
"test:run": "vitest --run",
|
|
15
|
-
"prepublishOnly": "pnpm build && pnpm test:run",
|
|
16
|
-
"save": "vhk save",
|
|
17
|
-
"check": "vhk check",
|
|
18
|
-
"scan": "vhk secure scan",
|
|
19
|
-
"recap": "vhk recap",
|
|
20
|
-
"ship": "vhk ship",
|
|
21
|
-
"doctor": "vhk doctor"
|
|
22
|
-
},
|
|
23
|
-
"files": [
|
|
24
|
-
"dist",
|
|
25
|
-
"README.md",
|
|
26
|
-
"LICENSE"
|
|
27
|
-
],
|
|
28
|
-
"keywords": [
|
|
29
|
-
"vibe-coding",
|
|
30
|
-
"harness",
|
|
31
|
-
"cli",
|
|
32
|
-
"scaffold",
|
|
33
|
-
"session-log",
|
|
34
|
-
"rules-sync"
|
|
35
|
-
],
|
|
36
|
-
"author": "byh3071 <byh3071@gmail.com>",
|
|
37
|
-
"license": "MIT",
|
|
38
|
-
"repository": {
|
|
39
|
-
"type": "git",
|
|
40
|
-
"url": "git+https://github.com/byh3071-cpu/vhk.git"
|
|
41
|
-
},
|
|
42
|
-
"engines": {
|
|
43
|
-
"node": ">=20"
|
|
44
|
-
},
|
|
45
|
-
"dependencies": {
|
|
46
|
-
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
47
|
-
"@notionhq/client": "^5.22.0",
|
|
48
|
-
"chalk": "^5.6.2",
|
|
49
|
-
"commander": "^14.0.3",
|
|
50
|
-
"handlebars": "^4.7.9",
|
|
51
|
-
"inquirer": "^9.3.8",
|
|
52
|
-
"ora": "^9.4.0",
|
|
53
|
-
"simple-git": "^3.36.0",
|
|
54
|
-
"zod": "^4.4.3"
|
|
55
|
-
},
|
|
56
|
-
"devDependencies": {
|
|
57
|
-
"@types/inquirer": "^9.0.9",
|
|
58
|
-
"@types/node": "^25.9.1",
|
|
59
|
-
"ignore": "^7.0.5",
|
|
60
|
-
"tsup": "^8.5.1",
|
|
61
|
-
"tsx": "^4.22.3",
|
|
62
|
-
"typescript": "^6.0.3",
|
|
63
|
-
"vitest": "^4.1.7"
|
|
64
|
-
}
|
|
65
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@byh3071/vhk",
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "Vibe Harness Kit — 바이브코딩 풀사이클 CLI",
|
|
5
|
+
"bin": {
|
|
6
|
+
"vhk": "dist/index.js",
|
|
7
|
+
"vhk-mcp": "dist/mcp/index.js"
|
|
8
|
+
},
|
|
9
|
+
"type": "module",
|
|
10
|
+
"scripts": {
|
|
11
|
+
"dev": "tsx src/index.ts",
|
|
12
|
+
"build": "tsup",
|
|
13
|
+
"test": "vitest",
|
|
14
|
+
"test:run": "vitest --run",
|
|
15
|
+
"prepublishOnly": "pnpm build && pnpm test:run",
|
|
16
|
+
"save": "vhk save",
|
|
17
|
+
"check": "vhk check",
|
|
18
|
+
"scan": "vhk secure scan",
|
|
19
|
+
"recap": "vhk recap",
|
|
20
|
+
"ship": "vhk ship",
|
|
21
|
+
"doctor": "vhk doctor"
|
|
22
|
+
},
|
|
23
|
+
"files": [
|
|
24
|
+
"dist",
|
|
25
|
+
"README.md",
|
|
26
|
+
"LICENSE"
|
|
27
|
+
],
|
|
28
|
+
"keywords": [
|
|
29
|
+
"vibe-coding",
|
|
30
|
+
"harness",
|
|
31
|
+
"cli",
|
|
32
|
+
"scaffold",
|
|
33
|
+
"session-log",
|
|
34
|
+
"rules-sync"
|
|
35
|
+
],
|
|
36
|
+
"author": "byh3071 <byh3071@gmail.com>",
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "git+https://github.com/byh3071-cpu/vhk.git"
|
|
41
|
+
},
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=20"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
47
|
+
"@notionhq/client": "^5.22.0",
|
|
48
|
+
"chalk": "^5.6.2",
|
|
49
|
+
"commander": "^14.0.3",
|
|
50
|
+
"handlebars": "^4.7.9",
|
|
51
|
+
"inquirer": "^9.3.8",
|
|
52
|
+
"ora": "^9.4.0",
|
|
53
|
+
"simple-git": "^3.36.0",
|
|
54
|
+
"zod": "^4.4.3"
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"@types/inquirer": "^9.0.9",
|
|
58
|
+
"@types/node": "^25.9.1",
|
|
59
|
+
"ignore": "^7.0.5",
|
|
60
|
+
"tsup": "^8.5.1",
|
|
61
|
+
"tsx": "^4.22.3",
|
|
62
|
+
"typescript": "^6.0.3",
|
|
63
|
+
"vitest": "^4.1.7"
|
|
64
|
+
}
|
|
65
|
+
}
|