@vibecodetown/mcp-server 2.1.2 → 2.1.4

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.
@@ -0,0 +1,37 @@
1
+ // adapters/mcp-ts/src/local-mode/install-state.ts
2
+ // Installation state verification
3
+ import * as fs from "node:fs";
4
+ import { getVibeRepoPaths } from "./paths.js";
5
+ import { readVersionLock } from "./version-lock.js";
6
+ import { healthCheck } from "../bootstrap/doctor.js";
7
+ /**
8
+ * Check installation state of the repository
9
+ */
10
+ export async function checkInstallState(repoRoot) {
11
+ const paths = getVibeRepoPaths(repoRoot);
12
+ const warnings = [];
13
+ // Check local init
14
+ const localInitialized = fs.existsSync(paths.configFile);
15
+ if (!localInitialized) {
16
+ warnings.push("로컬 모드 미초기화. 'vibe setup' 실행 필요");
17
+ }
18
+ // Check engines
19
+ let enginesReady = false;
20
+ try {
21
+ const health = await healthCheck();
22
+ enginesReady = health.engines.every(e => e.status === "ok");
23
+ if (!enginesReady) {
24
+ const missing = health.engines.filter(e => e.status !== "ok").map(e => e.name);
25
+ warnings.push(`엔진 누락: ${missing.join(", ")}`);
26
+ }
27
+ }
28
+ catch {
29
+ warnings.push("엔진 상태 확인 실패");
30
+ }
31
+ // Check version lock
32
+ const versionLockExists = readVersionLock(repoRoot) !== null;
33
+ if (!versionLockExists && localInitialized) {
34
+ warnings.push("버전 잠금 파일 없음. 'vibe setup' 재실행 권장");
35
+ }
36
+ return { localInitialized, enginesReady, versionLockExists, warnings };
37
+ }
@@ -20,5 +20,6 @@ export function getVibeRepoPaths(repoRoot) {
20
20
  ciWorkflowFile,
21
21
  gitleaksConfigFile,
22
22
  bootstrapManifest: path.join(vibeDir, "bootstrap_manifest.json"),
23
+ versionLockFile: path.join(vibeDir, "version_lock.json"),
23
24
  };
24
25
  }
@@ -0,0 +1,46 @@
1
+ // adapters/mcp-ts/src/local-mode/setup.ts
2
+ // Unified installation logic
3
+ import { initLocalModeRepo } from "./init.js";
4
+ import { writeVersionLock } from "./version-lock.js";
5
+ import { ensureEngines } from "../bootstrap/installer.js";
6
+ import { healthCheck } from "../bootstrap/doctor.js";
7
+ /**
8
+ * Run unified setup process
9
+ */
10
+ export async function runSetup(repoRoot, cliVersion, opts) {
11
+ const warnings = [];
12
+ // Step 1: Local mode init
13
+ const local = initLocalModeRepo(repoRoot, {
14
+ force: opts.force,
15
+ installHooks: opts.installHooks ?? true,
16
+ installCi: opts.installCi,
17
+ ciFailOnWarn: opts.ciFailOnWarn,
18
+ });
19
+ // Step 2: Engine installation (unless localOnly)
20
+ let engines = [];
21
+ if (!opts.localOnly) {
22
+ try {
23
+ await ensureEngines();
24
+ const health = await healthCheck();
25
+ engines = health.engines.map(e => ({
26
+ name: e.name,
27
+ version: e.version,
28
+ status: e.status,
29
+ }));
30
+ }
31
+ catch (e) {
32
+ warnings.push(`엔진 설치 실패: ${e instanceof Error ? e.message : String(e)}`);
33
+ warnings.push("오프라인 모드: vibe setup --local-only");
34
+ }
35
+ }
36
+ // Step 3: Version lock
37
+ let versionLock = null;
38
+ try {
39
+ const engineVersions = Object.fromEntries(engines.filter(e => e.status === "ok").map(e => [e.name, e.version]));
40
+ versionLock = writeVersionLock(repoRoot, cliVersion, engineVersions);
41
+ }
42
+ catch (e) {
43
+ warnings.push(`버전 잠금 파일 생성 실패: ${e instanceof Error ? e.message : String(e)}`);
44
+ }
45
+ return { local, engines, versionLock, warnings };
46
+ }
@@ -0,0 +1,53 @@
1
+ // adapters/mcp-ts/src/local-mode/version-lock.ts
2
+ // Version lock management for unified installation
3
+ import * as fs from "node:fs";
4
+ import { z } from "zod";
5
+ import { getVibeRepoPaths } from "./paths.js";
6
+ export const VersionLockSchema = z.object({
7
+ schema_version: z.literal(1),
8
+ created_at: z.string(),
9
+ updated_at: z.string(),
10
+ cli: z.object({
11
+ name: z.string(),
12
+ version: z.string(),
13
+ }),
14
+ engines: z.record(z.string(), z.object({
15
+ version: z.string(),
16
+ installed_at: z.string(),
17
+ })),
18
+ });
19
+ /**
20
+ * Read version lock file from repo
21
+ */
22
+ export function readVersionLock(repoRoot) {
23
+ const paths = getVibeRepoPaths(repoRoot);
24
+ if (!fs.existsSync(paths.versionLockFile))
25
+ return null;
26
+ try {
27
+ const data = JSON.parse(fs.readFileSync(paths.versionLockFile, "utf-8"));
28
+ return VersionLockSchema.parse(data);
29
+ }
30
+ catch {
31
+ return null;
32
+ }
33
+ }
34
+ /**
35
+ * Write version lock file to repo
36
+ */
37
+ export function writeVersionLock(repoRoot, cliVersion, engines) {
38
+ const paths = getVibeRepoPaths(repoRoot);
39
+ const now = new Date().toISOString();
40
+ const existing = readVersionLock(repoRoot);
41
+ const lock = {
42
+ schema_version: 1,
43
+ created_at: existing?.created_at ?? now,
44
+ updated_at: now,
45
+ cli: { name: "@vibecode/mcp-server", version: cliVersion },
46
+ engines: Object.fromEntries(Object.entries(engines).map(([name, version]) => [
47
+ name,
48
+ { version, installed_at: now }
49
+ ])),
50
+ };
51
+ fs.writeFileSync(paths.versionLockFile, JSON.stringify(lock, null, 2) + "\n");
52
+ return paths.versionLockFile;
53
+ }
package/build/vibe-cli.js CHANGED
@@ -14,6 +14,8 @@ import { setRepoConfigValue, validateRepoConfig } from "./local-mode/config.js";
14
14
  import { getVibeRepoPaths } from "./local-mode/paths.js";
15
15
  import { archiveCurrentWorkOrder, createWorkOrderTemplate, readCurrentWorkOrder, writeCurrentWorkOrder } from "./local-mode/work-order.js";
16
16
  import { autoUpdateOnStart } from "./version-check.js";
17
+ import { runSetup } from "./local-mode/setup.js";
18
+ import { checkInstallState } from "./local-mode/install-state.js";
17
19
  // ============================================================
18
20
  // Constants
19
21
  // ============================================================
@@ -110,7 +112,89 @@ async function cmdDoctor() {
110
112
  function resolveRepoRoot() {
111
113
  return getGitRoot(process.cwd()) ?? process.cwd();
112
114
  }
115
+ async function cmdSetup() {
116
+ const repoRoot = resolveRepoRoot();
117
+ const args = process.argv.slice(2);
118
+ const forceFlag = args.includes("--force") || args.includes("-f");
119
+ const localOnly = args.includes("--local-only");
120
+ const checkOnly = args.includes("--check");
121
+ const noHooks = args.includes("--no-hooks");
122
+ const installCi = args.includes("--ci");
123
+ const ciFailOnWarn = args.includes("--strict");
124
+ console.log("");
125
+ console.log(c("cyan", "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"));
126
+ console.log(c("cyan", " Vibe PM Setup"));
127
+ console.log(c("cyan", "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"));
128
+ console.log("");
129
+ if (checkOnly) {
130
+ const state = await checkInstallState(repoRoot);
131
+ console.log(` Local: ${state.localInitialized ? c("green", "OK") : c("red", "NOT INITIALIZED")}`);
132
+ console.log(` Engines: ${state.enginesReady ? c("green", "OK") : c("yellow", "INCOMPLETE")}`);
133
+ console.log(` Version Lock: ${state.versionLockExists ? c("green", "OK") : c("yellow", "MISSING")}`);
134
+ if (state.warnings.length > 0) {
135
+ console.log("");
136
+ state.warnings.forEach(w => console.log(` ${c("yellow", "\u26A0")} ${w}`));
137
+ }
138
+ console.log("");
139
+ return;
140
+ }
141
+ // Step 1: Local mode
142
+ console.log(" Step 1/3: 로컬 모드 초기화...");
143
+ // Step 2: Engines
144
+ if (!localOnly) {
145
+ console.log(" Step 2/3: 엔진 설치...");
146
+ }
147
+ else {
148
+ console.log(" Step 2/3: 엔진 설치 (스킵 - local-only)");
149
+ }
150
+ // Step 3: Version lock
151
+ console.log(" Step 3/3: 버전 잠금...");
152
+ const result = await runSetup(repoRoot, VERSION, {
153
+ force: forceFlag,
154
+ localOnly,
155
+ installHooks: !noHooks,
156
+ installCi,
157
+ ciFailOnWarn,
158
+ });
159
+ console.log("");
160
+ // Results
161
+ if (result.local.created.length > 0) {
162
+ console.log(` ${c("green", "\u2713")} 로컬 파일 생성: ${result.local.created.length}개`);
163
+ }
164
+ if (result.local.updated.length > 0) {
165
+ console.log(` ${c("yellow", "\u2191")} 로컬 파일 업데이트: ${result.local.updated.length}개`);
166
+ }
167
+ if (result.engines.length > 0) {
168
+ const ok = result.engines.filter(e => e.status === "ok").length;
169
+ console.log(` ${c("green", "\u2713")} 엔진: ${ok}/${result.engines.length} 준비됨`);
170
+ }
171
+ if (result.versionLock) {
172
+ console.log(` ${c("green", "\u2713")} 버전 잠금 생성됨`);
173
+ }
174
+ // Notes
175
+ if (result.local.notes.length > 0) {
176
+ console.log("");
177
+ console.log(" Notes:");
178
+ result.local.notes.forEach(n => console.log(` - ${n}`));
179
+ }
180
+ // Warnings
181
+ if (result.warnings.length > 0) {
182
+ console.log("");
183
+ result.warnings.forEach(w => console.log(` ${c("yellow", "\u26A0")} ${w}`));
184
+ }
185
+ console.log("");
186
+ console.log(c("cyan", "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"));
187
+ console.log(` ${c("green", "\u2713")} Setup 완료!`);
188
+ console.log("");
189
+ console.log(` Next: ${c("cyan", "vibe status")}`);
190
+ console.log("");
191
+ }
113
192
  function cmdInit() {
193
+ // Deprecation warning
194
+ console.log("");
195
+ console.log(c("yellow", "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"));
196
+ console.log(c("yellow", " \u26A0 DEPRECATED: 'vibe init' \u2192 'vibe setup' 사용"));
197
+ console.log(c("yellow", "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"));
114
198
  const repoRoot = resolveRepoRoot();
115
199
  const args = process.argv.slice(2);
116
200
  const forceFlag = args.includes("--force") || args.includes("-f");
@@ -429,7 +513,26 @@ async function cmdUpdate() {
429
513
  }
430
514
  // P0-1: Subcommand-specific help messages
431
515
  const SUBCOMMAND_HELP = {
432
- init: `vibe init - 로컬 모드 초기화
516
+ setup: `vibe setup - 통합 설치 (권장)
517
+
518
+ Usage: vibe setup [options]
519
+
520
+ Options:
521
+ -f, --force 기존 파일 덮어쓰기
522
+ --local-only 로컬 파일만 생성 (엔진 스킵)
523
+ --check 설치 상태 확인만
524
+ --no-hooks git hooks 스킵
525
+ --ci CI 워크플로우 설치
526
+ --strict CI strict 모드
527
+
528
+ Examples:
529
+ $ vibe setup # 전체 설치
530
+ $ vibe setup --check # 상태 확인
531
+ $ vibe setup --local-only # 오프라인
532
+ `,
533
+ init: `vibe init - [DEPRECATED] 로컬 모드 초기화
534
+
535
+ \u26A0 deprecated: 'vibe setup' 사용 권장
433
536
 
434
537
  Usage: vibe init [options]
435
538
 
@@ -524,7 +627,8 @@ function cmdHelp(subcommand) {
524
627
  console.log("Usage: vibe <command> [options]");
525
628
  console.log("");
526
629
  console.log("Commands:");
527
- console.log(` ${c("green", "init")} 로컬 모드 초기화 (.vibe/ + 훅)`);
630
+ console.log(` ${c("green", "setup")} 통합 설치 (권장)`);
631
+ console.log(` ${c("dim", "init")} [deprecated] 로컬 초기화`);
528
632
  console.log(` ${c("green", "status")} 로컬 상태 확인`);
529
633
  console.log(` ${c("green", "ticket")} 작업 티켓(Work Order) 생성`);
530
634
  console.log(` ${c("green", "check")} 로컬 가드 검증 실행`);
@@ -542,12 +646,13 @@ function cmdHelp(subcommand) {
542
646
  console.log(` ${c("dim", "-h, --help")} 명령어별 도움말 표시`);
543
647
  console.log("");
544
648
  console.log("Examples:");
545
- console.log(` ${c("dim", "$")} vibe init # 로컬 모드 초기화`);
546
- console.log(` ${c("dim", "$")} vibe init --help # init 명령어 도움말`);
649
+ console.log(` ${c("dim", "$")} vibe setup # 통합 설치 (권장)`);
650
+ console.log(` ${c("dim", "$")} vibe setup --check # 설치 상태 확인`);
651
+ console.log(` ${c("dim", "$")} vibe setup --help # setup 명령어 도움말`);
547
652
  console.log(` ${c("dim", "$")} vibe ticket \"Fix auth\" # 작업 티켓 생성`);
548
653
  console.log(` ${c("dim", "$")} vibe check # 푸시 전 로컬 검증`);
549
- console.log(` ${c("dim", "$")} vibe doctor # 설치 상태 확인`);
550
- console.log(` ${c("dim", "$")} vibe reset --force # 프로젝트 초기화`);
654
+ console.log(` ${c("dim", "$")} vibe doctor # 설치 진단`);
655
+ console.log(` ${c("dim", "$")} vibe reset --force # 프로젝트 초기화`);
551
656
  console.log("");
552
657
  console.log("More info:");
553
658
  console.log(` Documentation: ${c("blue", "https://vibecode.town/docs")}`);
@@ -576,6 +681,9 @@ async function main() {
576
681
  });
577
682
  try {
578
683
  switch (command) {
684
+ case "setup":
685
+ await cmdSetup();
686
+ break;
579
687
  case "init":
580
688
  cmdInit();
581
689
  break;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibecodetown/mcp-server",
3
- "version": "2.1.2",
3
+ "version": "2.1.4",
4
4
  "type": "module",
5
5
  "description": "Vibe PM - AI Project Manager MCP Server for non-technical founders",
6
6
  "keywords": [
@@ -27,8 +27,9 @@
27
27
  "node": ">=18"
28
28
  },
29
29
  "bin": {
30
- "vibecode-mcp": "./build/index.js",
31
- "vibe": "./build/vibe-cli.js"
30
+ "mcp-server": "build/index.js",
31
+ "vibecode-mcp": "build/index.js",
32
+ "vibe": "build/vibe-cli.js"
32
33
  },
33
34
  "main": "./build/index.js",
34
35
  "files": [