@vibecodetown/mcp-server 2.2.0 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -10
- package/build/auth/index.js +0 -2
- package/build/auth/public_key.js +6 -4
- package/build/bootstrap/doctor.js +113 -5
- package/build/bootstrap/installer.js +85 -15
- package/build/bootstrap/registry.js +11 -6
- package/build/bootstrap/skills-installer.js +365 -0
- package/build/dx/activity.js +26 -3
- package/build/engine.js +151 -0
- package/build/errors.js +107 -0
- package/build/generated/bridge_build_seed_input.js +2 -0
- package/build/generated/bridge_build_seed_output.js +2 -0
- package/build/generated/bridge_confirm_reference_input.js +2 -0
- package/build/generated/bridge_confirm_reference_output.js +2 -0
- package/build/generated/bridge_confirmed_reference_file.js +2 -0
- package/build/generated/bridge_generate_references_input.js +2 -0
- package/build/generated/bridge_generate_references_output.js +2 -0
- package/build/generated/bridge_references_file.js +2 -0
- package/build/generated/bridge_work_order_seed_file.js +2 -0
- package/build/generated/contracts_bundle_info.js +3 -3
- package/build/generated/index.js +14 -0
- package/build/generated/ingress_input.js +2 -0
- package/build/generated/ingress_output.js +2 -0
- package/build/generated/ingress_resolution_file.js +2 -0
- package/build/generated/ingress_summary_file.js +2 -0
- package/build/generated/message_template_id_mapping_file.js +2 -0
- package/build/generated/run_app_input.js +1 -1
- package/build/index.js +4 -3
- package/build/local-mode/paths.js +1 -0
- package/build/local-mode/setup.js +21 -1
- package/build/path-utils.js +68 -0
- package/build/runtime/cli_invoker.js +1 -1
- package/build/tools/vibe_pm/advisory_review.js +5 -3
- package/build/tools/vibe_pm/bridge_build_seed.js +164 -0
- package/build/tools/vibe_pm/bridge_confirm_reference.js +91 -0
- package/build/tools/vibe_pm/bridge_generate_references.js +258 -0
- package/build/tools/vibe_pm/briefing.js +27 -3
- package/build/tools/vibe_pm/context.js +79 -0
- package/build/tools/vibe_pm/create_work_order.js +200 -3
- package/build/tools/vibe_pm/doctor.js +95 -0
- package/build/tools/vibe_pm/entity_gate/preflight.js +8 -3
- package/build/tools/vibe_pm/export_output.js +14 -13
- package/build/tools/vibe_pm/finalize_work.js +78 -40
- package/build/tools/vibe_pm/get_decision.js +2 -2
- package/build/tools/vibe_pm/index.js +128 -42
- package/build/tools/vibe_pm/ingress.js +645 -0
- package/build/tools/vibe_pm/ingress_gate.js +116 -0
- package/build/tools/vibe_pm/inspect_code.js +90 -20
- package/build/tools/vibe_pm/kce/doc_usage.js +4 -9
- package/build/tools/vibe_pm/kce/on_finalize.js +2 -2
- package/build/tools/vibe_pm/kce/preflight.js +11 -7
- package/build/tools/vibe_pm/memory_status.js +11 -8
- package/build/tools/vibe_pm/memory_sync.js +11 -8
- package/build/tools/vibe_pm/pm_language.js +17 -16
- package/build/tools/vibe_pm/python_error.js +115 -0
- package/build/tools/vibe_pm/run_app.js +169 -43
- package/build/tools/vibe_pm/run_app_podman.js +64 -2
- package/build/tools/vibe_pm/search_oss.js +5 -3
- package/build/tools/vibe_pm/spec_rag.js +185 -0
- package/build/tools/vibe_pm/status.js +50 -3
- package/build/tools/vibe_pm/submit_decision.js +2 -2
- package/build/tools/vibe_pm/types.js +28 -0
- package/build/tools/vibe_pm/undo_last_task.js +9 -2
- package/build/tools/vibe_pm/waiter_mapping.js +155 -0
- package/build/tools/vibe_pm/zoekt_evidence.js +5 -3
- package/build/tools.js +13 -5
- package/build/vibe-cli.js +245 -7
- package/package.json +5 -4
- package/skills/VRIP_INSTALL_MANIFEST_DOCTOR.skill.md +288 -0
- package/skills/index.json +14 -0
package/build/vibe-cli.js
CHANGED
|
@@ -6,6 +6,7 @@ import * as path from "node:path";
|
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
7
|
import { healthCheck, validateCacheIntegrity, checkForUpdates } from "./bootstrap/doctor.js";
|
|
8
8
|
import { ensureEngines } from "./bootstrap/installer.js";
|
|
9
|
+
import { listAvailableSkills, listActivatedSkills, getSkillById, activateSkills, deactivateSkill, getSkillsHealth, getSkillContent } from "./bootstrap/skills-installer.js";
|
|
9
10
|
import { CONTRACTS_BUNDLE_SHA256, CONTRACTS_VERSION } from "./generated/contracts_bundle_info.js";
|
|
10
11
|
import { spawnBashScriptInRepoSync } from "./local-mode/bash.js";
|
|
11
12
|
import { getGitHooksPath, getGitRoot } from "./local-mode/git.js";
|
|
@@ -77,9 +78,21 @@ async function cmdDoctor() {
|
|
|
77
78
|
// Check cache integrity
|
|
78
79
|
const cacheResult = await validateCacheIntegrity();
|
|
79
80
|
console.log(` Cache: ${cacheResult.valid ? c("green", "✓") : c("yellow", "⚠")} ${cacheResult.valid ? "valid" : "needs repair"}`);
|
|
80
|
-
// Check
|
|
81
|
+
// Check Skills Bundle
|
|
81
82
|
console.log("");
|
|
82
|
-
console.log("
|
|
83
|
+
console.log(" Skills Bundle:");
|
|
84
|
+
const skillsStatus = health.skills.status;
|
|
85
|
+
const skillsIcon = skillsStatus === "OK"
|
|
86
|
+
? c("green", "✓")
|
|
87
|
+
: skillsStatus === "WARN"
|
|
88
|
+
? c("yellow", "⚠")
|
|
89
|
+
: c("red", "✗");
|
|
90
|
+
console.log(` Status: ${skillsIcon} ${skillsStatus}`);
|
|
91
|
+
console.log(` Version: ${health.skills.version ?? c("dim", "unknown")}`);
|
|
92
|
+
console.log(` Installed: ${health.skills.summary.ok}/${health.skills.summary.total}`);
|
|
93
|
+
// Check Agent Skills files (project-level guidance)
|
|
94
|
+
console.log("");
|
|
95
|
+
console.log(" Agent Guidance Files:");
|
|
83
96
|
const skillFiles = [
|
|
84
97
|
{ name: "AGENTS.md", path: "AGENTS.md" },
|
|
85
98
|
{ name: ".cursorrules", path: ".cursorrules" },
|
|
@@ -93,7 +106,7 @@ async function cmdDoctor() {
|
|
|
93
106
|
// Summary
|
|
94
107
|
console.log("");
|
|
95
108
|
console.log(c("cyan", "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"));
|
|
96
|
-
const allOk = health.status === "OK" && cacheResult.valid;
|
|
109
|
+
const allOk = health.status === "OK" && cacheResult.valid && skillsStatus === "OK";
|
|
97
110
|
if (allOk) {
|
|
98
111
|
console.log("");
|
|
99
112
|
console.log(` ${c("green", "✓ 모든 것이 정상입니다!")}`);
|
|
@@ -192,16 +205,18 @@ async function cmdSetup() {
|
|
|
192
205
|
return;
|
|
193
206
|
}
|
|
194
207
|
// Step 1: Local mode
|
|
195
|
-
console.log(" Step 1/
|
|
208
|
+
console.log(" Step 1/4: 로컬 모드 초기화...");
|
|
196
209
|
// Step 2: Engines
|
|
197
210
|
if (!localOnly) {
|
|
198
|
-
console.log(" Step 2/
|
|
211
|
+
console.log(" Step 2/4: 엔진 설치...");
|
|
199
212
|
}
|
|
200
213
|
else {
|
|
201
|
-
console.log(" Step 2/
|
|
214
|
+
console.log(" Step 2/4: 엔진 설치 (스킵 - local-only)");
|
|
202
215
|
}
|
|
203
216
|
// Step 3: Version lock
|
|
204
|
-
console.log(" Step 3/
|
|
217
|
+
console.log(" Step 3/4: 버전 잠금...");
|
|
218
|
+
// Step 4: Skills
|
|
219
|
+
console.log(" Step 4/4: 스킬 활성화...");
|
|
205
220
|
const result = await runSetup(repoRoot, VERSION, {
|
|
206
221
|
force: forceFlag,
|
|
207
222
|
localOnly,
|
|
@@ -221,6 +236,9 @@ async function cmdSetup() {
|
|
|
221
236
|
const ok = result.engines.filter(e => e.status === "ok").length;
|
|
222
237
|
console.log(` ${c("green", "\u2713")} 엔진: ${ok}/${result.engines.length} 준비됨`);
|
|
223
238
|
}
|
|
239
|
+
if (result.skills.activated.length > 0) {
|
|
240
|
+
console.log(` ${c("green", "\u2713")} 스킬: ${result.skills.activated.length}개 활성화됨`);
|
|
241
|
+
}
|
|
224
242
|
if (result.versionLock) {
|
|
225
243
|
console.log(` ${c("green", "\u2713")} 버전 잠금 생성됨`);
|
|
226
244
|
}
|
|
@@ -616,6 +634,200 @@ async function cmdUpdate() {
|
|
|
616
634
|
console.log("");
|
|
617
635
|
}
|
|
618
636
|
// ============================================================
|
|
637
|
+
// Skills Management Commands
|
|
638
|
+
// ============================================================
|
|
639
|
+
/**
|
|
640
|
+
* vibe skills - Skill bundle management
|
|
641
|
+
*
|
|
642
|
+
* Subcommands:
|
|
643
|
+
* list - List all available skills
|
|
644
|
+
* activate - Activate skill(s) for this project
|
|
645
|
+
* deactivate - Deactivate a skill from this project
|
|
646
|
+
* info - Show skill details
|
|
647
|
+
* status - Show skills health status
|
|
648
|
+
*/
|
|
649
|
+
async function cmdSkills() {
|
|
650
|
+
const args = process.argv.slice(3); // after "vibe skills"
|
|
651
|
+
const subcommand = args[0] ?? "list";
|
|
652
|
+
const jsonMode = args.includes("--json");
|
|
653
|
+
const projectRoot = process.cwd();
|
|
654
|
+
switch (subcommand) {
|
|
655
|
+
case "list": {
|
|
656
|
+
const available = listAvailableSkills();
|
|
657
|
+
const activated = listActivatedSkills(projectRoot);
|
|
658
|
+
if (jsonMode) {
|
|
659
|
+
console.log(JSON.stringify({ available, activated }, null, 2));
|
|
660
|
+
return;
|
|
661
|
+
}
|
|
662
|
+
console.log("");
|
|
663
|
+
console.log(c("cyan", "Vibe PM Skills"));
|
|
664
|
+
console.log("");
|
|
665
|
+
console.log(" Available Skills:");
|
|
666
|
+
if (available.length === 0) {
|
|
667
|
+
console.log(` ${c("dim", "(none)")}`);
|
|
668
|
+
}
|
|
669
|
+
else {
|
|
670
|
+
for (const skill of available) {
|
|
671
|
+
const isActive = activated.includes(skill.id);
|
|
672
|
+
const status = isActive ? c("green", "✓") : c("dim", "○");
|
|
673
|
+
console.log(` ${status} ${skill.id.padEnd(35)} v${skill.version}`);
|
|
674
|
+
console.log(` ${c("dim", skill.description)}`);
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
console.log("");
|
|
678
|
+
if (activated.length > 0) {
|
|
679
|
+
console.log(` Activated: ${c("green", String(activated.length))} / ${available.length}`);
|
|
680
|
+
}
|
|
681
|
+
else {
|
|
682
|
+
console.log(` ${c("dim", "No skills activated. Run:")} ${c("cyan", "vibe skills activate <id>")}`);
|
|
683
|
+
}
|
|
684
|
+
console.log("");
|
|
685
|
+
break;
|
|
686
|
+
}
|
|
687
|
+
case "activate": {
|
|
688
|
+
const skillIds = args.slice(1).filter(a => !a.startsWith("-"));
|
|
689
|
+
if (skillIds.length === 0) {
|
|
690
|
+
// Activate all skills if no ID specified
|
|
691
|
+
console.log("");
|
|
692
|
+
console.log(c("cyan", "Activating all available skills..."));
|
|
693
|
+
console.log("");
|
|
694
|
+
}
|
|
695
|
+
const result = await activateSkills(projectRoot, skillIds.length > 0 ? skillIds : undefined);
|
|
696
|
+
if (jsonMode) {
|
|
697
|
+
console.log(JSON.stringify(result, null, 2));
|
|
698
|
+
return;
|
|
699
|
+
}
|
|
700
|
+
if (result.activated.length > 0) {
|
|
701
|
+
console.log(` ${c("green", "✓")} Activated skills:`);
|
|
702
|
+
for (const id of result.activated) {
|
|
703
|
+
console.log(` - ${id}`);
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
if (result.errors.length > 0) {
|
|
707
|
+
console.log("");
|
|
708
|
+
console.log(` ${c("red", "✗")} Errors:`);
|
|
709
|
+
for (const err of result.errors) {
|
|
710
|
+
console.log(` - ${err}`);
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
console.log("");
|
|
714
|
+
break;
|
|
715
|
+
}
|
|
716
|
+
case "deactivate": {
|
|
717
|
+
const skillId = args[1];
|
|
718
|
+
if (!skillId || skillId.startsWith("-")) {
|
|
719
|
+
console.log(` ${c("red", "✗")} Usage: vibe skills deactivate <skill_id>`);
|
|
720
|
+
return;
|
|
721
|
+
}
|
|
722
|
+
const result = await deactivateSkill(projectRoot, skillId);
|
|
723
|
+
if (jsonMode) {
|
|
724
|
+
console.log(JSON.stringify(result, null, 2));
|
|
725
|
+
return;
|
|
726
|
+
}
|
|
727
|
+
if (result.success) {
|
|
728
|
+
console.log(` ${c("green", "✓")} Deactivated: ${skillId}`);
|
|
729
|
+
}
|
|
730
|
+
else {
|
|
731
|
+
console.log(` ${c("red", "✗")} ${result.error}`);
|
|
732
|
+
}
|
|
733
|
+
console.log("");
|
|
734
|
+
break;
|
|
735
|
+
}
|
|
736
|
+
case "info": {
|
|
737
|
+
const skillId = args[1];
|
|
738
|
+
if (!skillId || skillId.startsWith("-")) {
|
|
739
|
+
console.log(` ${c("red", "✗")} Usage: vibe skills info <skill_id>`);
|
|
740
|
+
return;
|
|
741
|
+
}
|
|
742
|
+
const skill = getSkillById(skillId);
|
|
743
|
+
if (!skill) {
|
|
744
|
+
console.log(` ${c("red", "✗")} Skill not found: ${skillId}`);
|
|
745
|
+
return;
|
|
746
|
+
}
|
|
747
|
+
if (jsonMode) {
|
|
748
|
+
console.log(JSON.stringify(skill, null, 2));
|
|
749
|
+
return;
|
|
750
|
+
}
|
|
751
|
+
console.log("");
|
|
752
|
+
console.log(c("cyan", `Skill: ${skill.id}`));
|
|
753
|
+
console.log("");
|
|
754
|
+
console.log(` Version: ${skill.version}`);
|
|
755
|
+
console.log(` Description: ${skill.description}`);
|
|
756
|
+
console.log(` Tags: ${skill.tags.join(", ")}`);
|
|
757
|
+
console.log(` File: ${skill.file}`);
|
|
758
|
+
console.log(` SHA256: ${skill.sha256.slice(0, 16)}...`);
|
|
759
|
+
console.log("");
|
|
760
|
+
// Show content preview
|
|
761
|
+
const content = getSkillContent(skillId);
|
|
762
|
+
if (content) {
|
|
763
|
+
const lines = content.split("\n").slice(0, 10);
|
|
764
|
+
console.log(c("dim", " Preview:"));
|
|
765
|
+
for (const line of lines) {
|
|
766
|
+
console.log(` ${c("dim", line.slice(0, 60))}`);
|
|
767
|
+
}
|
|
768
|
+
if (content.split("\n").length > 10) {
|
|
769
|
+
console.log(` ${c("dim", "...")}`);
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
console.log("");
|
|
773
|
+
break;
|
|
774
|
+
}
|
|
775
|
+
case "status": {
|
|
776
|
+
const health = getSkillsHealth();
|
|
777
|
+
if (jsonMode) {
|
|
778
|
+
console.log(JSON.stringify(health, null, 2));
|
|
779
|
+
return;
|
|
780
|
+
}
|
|
781
|
+
console.log("");
|
|
782
|
+
console.log(c("cyan", "Skills Bundle Status"));
|
|
783
|
+
console.log("");
|
|
784
|
+
console.log(` Installed: ${health.installed ? c("green", "✓") : c("red", "✗")}`);
|
|
785
|
+
console.log(` Bundle Path: ${health.bundlePath ?? c("dim", "(not found)")}`);
|
|
786
|
+
console.log(` Version: ${health.version ?? c("dim", "(unknown)")}`);
|
|
787
|
+
console.log("");
|
|
788
|
+
console.log(" Skills:");
|
|
789
|
+
for (const skill of health.skills) {
|
|
790
|
+
const icon = skill.status === "ok"
|
|
791
|
+
? c("green", "✓")
|
|
792
|
+
: skill.status === "missing"
|
|
793
|
+
? c("red", "✗")
|
|
794
|
+
: c("yellow", "⚠");
|
|
795
|
+
console.log(` ${icon} ${skill.id} (${skill.status})`);
|
|
796
|
+
if (skill.error) {
|
|
797
|
+
console.log(` ${c("dim", skill.error)}`);
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
console.log("");
|
|
801
|
+
console.log(` Summary: ${c("green", String(health.summary.ok))} ok, ` +
|
|
802
|
+
`${c("red", String(health.summary.missing))} missing, ` +
|
|
803
|
+
`${c("yellow", String(health.summary.corrupted))} corrupted`);
|
|
804
|
+
console.log("");
|
|
805
|
+
break;
|
|
806
|
+
}
|
|
807
|
+
case "help":
|
|
808
|
+
default: {
|
|
809
|
+
console.log("");
|
|
810
|
+
console.log(c("cyan", "vibe skills") + " - Skill bundle management");
|
|
811
|
+
console.log("");
|
|
812
|
+
console.log("Subcommands:");
|
|
813
|
+
console.log(` ${c("green", "list")} List all available skills`);
|
|
814
|
+
console.log(` ${c("green", "activate")} Activate skill(s) for this project`);
|
|
815
|
+
console.log(` ${c("green", "deactivate")} Deactivate a skill from this project`);
|
|
816
|
+
console.log(` ${c("green", "info")} Show skill details`);
|
|
817
|
+
console.log(` ${c("green", "status")} Show skills health status`);
|
|
818
|
+
console.log("");
|
|
819
|
+
console.log("Examples:");
|
|
820
|
+
console.log(` ${c("dim", "$")} vibe skills list`);
|
|
821
|
+
console.log(` ${c("dim", "$")} vibe skills activate VRIP_INSTALL_MANIFEST_DOCTOR`);
|
|
822
|
+
console.log(` ${c("dim", "$")} vibe skills activate # activate all`);
|
|
823
|
+
console.log(` ${c("dim", "$")} vibe skills info VRIP_INSTALL_MANIFEST_DOCTOR`);
|
|
824
|
+
console.log(` ${c("dim", "$")} vibe skills status --json`);
|
|
825
|
+
console.log("");
|
|
826
|
+
break;
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
// ============================================================
|
|
619
831
|
// New Commands: exec, inspect, run (VRIP v1.1 compliant)
|
|
620
832
|
// ============================================================
|
|
621
833
|
/**
|
|
@@ -1058,6 +1270,27 @@ Usage: vibe run [options]
|
|
|
1058
1270
|
|
|
1059
1271
|
프로젝트 설정에 따라 앱을 실행합니다.
|
|
1060
1272
|
(현재 개발 중 - vibe_pm.run_app MCP 도구 사용)
|
|
1273
|
+
`,
|
|
1274
|
+
skills: `vibe skills - 스킬 번들 관리
|
|
1275
|
+
|
|
1276
|
+
Usage: vibe skills <command> [options]
|
|
1277
|
+
|
|
1278
|
+
Commands:
|
|
1279
|
+
list 사용 가능한 스킬 목록
|
|
1280
|
+
activate 프로젝트에 스킬 활성화
|
|
1281
|
+
deactivate 스킬 비활성화
|
|
1282
|
+
info 스킬 상세 정보
|
|
1283
|
+
status 스킬 번들 상태 확인
|
|
1284
|
+
|
|
1285
|
+
Options:
|
|
1286
|
+
--json JSON 형식 출력
|
|
1287
|
+
|
|
1288
|
+
Examples:
|
|
1289
|
+
$ vibe skills list
|
|
1290
|
+
$ vibe skills activate VRIP_INSTALL_MANIFEST_DOCTOR
|
|
1291
|
+
$ vibe skills activate # 모든 스킬 활성화
|
|
1292
|
+
$ vibe skills info VRIP_INSTALL_MANIFEST_DOCTOR
|
|
1293
|
+
$ vibe skills status --json
|
|
1061
1294
|
`,
|
|
1062
1295
|
};
|
|
1063
1296
|
// P0-1: Helper functions for --help priority handling
|
|
@@ -1093,6 +1326,7 @@ function cmdHelp(subcommand) {
|
|
|
1093
1326
|
console.log(` ${c("green", "version")} 버전 정보 출력`);
|
|
1094
1327
|
console.log(` ${c("green", "reset")} 프로젝트 초기화 (runs/ 정리)`);
|
|
1095
1328
|
console.log(` ${c("green", "update")} 엔진 바이너리 업데이트`);
|
|
1329
|
+
console.log(` ${c("green", "skills")} 스킬 번들 관리`);
|
|
1096
1330
|
console.log(` ${c("green", "help")} 이 도움말 표시`);
|
|
1097
1331
|
console.log("");
|
|
1098
1332
|
console.log("Options:");
|
|
@@ -1108,6 +1342,7 @@ function cmdHelp(subcommand) {
|
|
|
1108
1342
|
console.log(` ${c("dim", "$")} vibe inspect --json # VRIP 모드 검수`);
|
|
1109
1343
|
console.log(` ${c("dim", "$")} vibe exec status # 데몬 상태 확인`);
|
|
1110
1344
|
console.log(` ${c("dim", "$")} vibe doctor # 설치 진단`);
|
|
1345
|
+
console.log(` ${c("dim", "$")} vibe skills list # 스킬 목록`);
|
|
1111
1346
|
console.log(` ${c("dim", "$")} vibe reset --force # 프로젝트 초기화`);
|
|
1112
1347
|
console.log("");
|
|
1113
1348
|
console.log("More info:");
|
|
@@ -1184,6 +1419,9 @@ async function main() {
|
|
|
1184
1419
|
case "run":
|
|
1185
1420
|
await cmdRun();
|
|
1186
1421
|
break;
|
|
1422
|
+
case "skills":
|
|
1423
|
+
await cmdSkills();
|
|
1424
|
+
break;
|
|
1187
1425
|
case "help":
|
|
1188
1426
|
case "-h":
|
|
1189
1427
|
case "--help":
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibecodetown/mcp-server",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Vibe PM - AI Project Manager MCP Server for non-technical founders",
|
|
6
6
|
"keywords": [
|
|
@@ -27,13 +27,13 @@
|
|
|
27
27
|
"node": ">=18"
|
|
28
28
|
},
|
|
29
29
|
"bin": {
|
|
30
|
-
"mcp
|
|
31
|
-
"
|
|
32
|
-
"vibe": "build/vibe-cli.js"
|
|
30
|
+
"vibecode-mcp": "./build/index.js",
|
|
31
|
+
"vibe": "./build/vibe-cli.js"
|
|
33
32
|
},
|
|
34
33
|
"main": "./build/index.js",
|
|
35
34
|
"files": [
|
|
36
35
|
"build/",
|
|
36
|
+
"skills/",
|
|
37
37
|
"README.md",
|
|
38
38
|
"LICENSE"
|
|
39
39
|
],
|
|
@@ -57,6 +57,7 @@
|
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
59
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
60
|
+
"@msgpack/msgpack": "^3.1.3",
|
|
60
61
|
"minimatch": "^9.0.3",
|
|
61
62
|
"node-notifier": "^10.0.1",
|
|
62
63
|
"simple-git": "^3.30.0",
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
# Skill: VRIP + install_manifest + doctor 운영 스킬 v1
|
|
2
|
+
|
|
3
|
+
> **Version**: 1.0.0
|
|
4
|
+
> **Target**: Claude Code / Codex CLI / Cursor
|
|
5
|
+
> **Created**: 2026-01-24
|
|
6
|
+
|
|
7
|
+
## 0) 이 스킬의 목표
|
|
8
|
+
|
|
9
|
+
* MCP↔CLI↔Daemon이 **설치 상태/실행 상태**를 헷갈리지 않게 강제한다.
|
|
10
|
+
* `.vibe/install_manifest.json`을 **설치 SSOT**로 유지한다.
|
|
11
|
+
* `vibe doctor`로 **Gate 판정(PASS/WARN/FAIL)** 을 일관되게 만든다.
|
|
12
|
+
* MCP는 "읽기 전용" 규칙을 어기지 않는다.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 1) 입력 (Input)
|
|
17
|
+
|
|
18
|
+
사용자가 아래 중 하나를 요청하면 이 스킬을 실행한다.
|
|
19
|
+
|
|
20
|
+
* "설치 상태 확인해줘"
|
|
21
|
+
* "왜 MCP는 되는데 로컬이 안 돼?"
|
|
22
|
+
* "엔진 버전 꼬였나?"
|
|
23
|
+
* "doctor 결과 이상함"
|
|
24
|
+
* "manifest 스키마/권한/갱신 규칙 적용"
|
|
25
|
+
* "MCP가 로컬을 안 쓰는 느낌인데?"
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 2) 출력 (Output)
|
|
30
|
+
|
|
31
|
+
항상 아래 3가지를 반환한다.
|
|
32
|
+
|
|
33
|
+
1. **현재 상태 요약**: 설치/엔진/데몬/무결성
|
|
34
|
+
2. **Gate 결과**: PASS/WARN/FAIL + 코드 목록
|
|
35
|
+
3. **즉시 실행 커맨드**: `vibe doctor`, `vibe update`, `vibe exec status` 등 최소 세트
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## 3) 핵심 규칙 (Law 요약)
|
|
40
|
+
|
|
41
|
+
| 규칙 | 설명 |
|
|
42
|
+
|------|------|
|
|
43
|
+
| MCP는 manifest를 **절대 쓰지 않는다** | 읽기 전용 |
|
|
44
|
+
| 설치/엔진 상태 갱신 | **vibe update만** |
|
|
45
|
+
| 진단 요약 갱신 | **vibe doctor만** |
|
|
46
|
+
| 데몬 생존 갱신 | **vibe exec --daemon만** |
|
|
47
|
+
| 결과의 SSOT | **run_dir** |
|
|
48
|
+
| 설치의 SSOT | **install_manifest** |
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## 4) 실행 절차 (Step-by-step)
|
|
53
|
+
|
|
54
|
+
### Step 1) manifest 존재/파싱
|
|
55
|
+
|
|
56
|
+
* 파일: `.vibe/install_manifest.json`
|
|
57
|
+
* 없으면:
|
|
58
|
+
* **FAIL: MANIFEST_MISSING**
|
|
59
|
+
* 다음 액션: `vibe update` (설치/생성 담당)
|
|
60
|
+
|
|
61
|
+
### Step 2) doctor로 Gate 판정 생성
|
|
62
|
+
|
|
63
|
+
* 실행: `vibe doctor --json`
|
|
64
|
+
* 결과를 `integrity.doctor_summary`로 기록(doctor가 쓰는 유일한 영역)
|
|
65
|
+
|
|
66
|
+
### Step 3) engines/components 점검(doctor 결과 기반)
|
|
67
|
+
|
|
68
|
+
* `status != ok`인 엔진 있으면:
|
|
69
|
+
* **FAIL** (sha_mismatch, missing, wrong_platform, permission_denied)
|
|
70
|
+
* 다음 액션: `vibe update --engine <name>` 또는 `vibe update`
|
|
71
|
+
|
|
72
|
+
### Step 4) bins 점검
|
|
73
|
+
|
|
74
|
+
* `bins.vibe.ok == false` → FAIL
|
|
75
|
+
* `bins.mcp_server.ok == false` → FAIL
|
|
76
|
+
* 다음 액션: 패키지 재설치 or update 루틴
|
|
77
|
+
|
|
78
|
+
### Step 5) 데몬 상태(선택)
|
|
79
|
+
|
|
80
|
+
* `vibe exec status --json`
|
|
81
|
+
* lock stale이면:
|
|
82
|
+
* WARN 또는 FAIL(운영 정책에 따라)
|
|
83
|
+
* 다음 액션: `vibe exec stop` 후 재기동
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## 5) Gate 체크리스트 (표준 코드)
|
|
88
|
+
|
|
89
|
+
doctor는 반드시 아래 코드 체계를 써라(이름 통일이 중요).
|
|
90
|
+
|
|
91
|
+
### FAIL (즉시 중단/수리 필요)
|
|
92
|
+
|
|
93
|
+
| 코드 | 설명 |
|
|
94
|
+
|------|------|
|
|
95
|
+
| `MANIFEST_MISSING` | manifest 파일 없음 |
|
|
96
|
+
| `MANIFEST_SCHEMA_INVALID` | manifest 스키마 검증 실패 |
|
|
97
|
+
| `BIN_VIBE_MISSING` | vibe CLI 바이너리 없음 |
|
|
98
|
+
| `BIN_MCP_SERVER_MISSING` | MCP 서버 바이너리 없음 |
|
|
99
|
+
| `ENGINE_MISSING:<name>` | 특정 엔진 없음 |
|
|
100
|
+
| `ENGINE_SHA_MISMATCH:<name>` | 엔진 SHA256 불일치 |
|
|
101
|
+
| `ENGINE_WRONG_PLATFORM:<name>` | 플랫폼 불일치 |
|
|
102
|
+
| `ENGINE_PERMISSION_DENIED:<name>` | 엔진 실행 권한 없음 |
|
|
103
|
+
| `RUN_ROOT_UNWRITABLE` | runs 디렉토리 쓰기 불가 |
|
|
104
|
+
| `DAEMON_MISCONFIGURED` | 데몬 설정 오류 |
|
|
105
|
+
|
|
106
|
+
### WARN (기능은 되지만 위험)
|
|
107
|
+
|
|
108
|
+
| 코드 | 설명 |
|
|
109
|
+
|------|------|
|
|
110
|
+
| `PKG_VERSION_MISMATCH` | 패키지 버전 불일치 |
|
|
111
|
+
| `DAEMON_STALE_LOCK` | 데몬 lock 파일 stale |
|
|
112
|
+
| `RUN_ROOT_CONFLICT_SUSPECTED` | run_dir 충돌 의심 |
|
|
113
|
+
|
|
114
|
+
### INFO
|
|
115
|
+
|
|
116
|
+
| 코드 | 설명 |
|
|
117
|
+
|------|------|
|
|
118
|
+
| `DAEMON_NOT_USED` | 데몬 미사용 |
|
|
119
|
+
| `CACHE_OK` | 캐시 정상 |
|
|
120
|
+
| `ENGINE_OK:<name>` | 특정 엔진 정상 |
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## 6) 표준 커맨드 세트 (복붙용)
|
|
125
|
+
|
|
126
|
+
### 설치/동기화(SSOT 생성/갱신)
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
vibe update
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### 진단(Gate 판정)
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
vibe doctor --json
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### 데몬 상태
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
vibe exec status --json
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### 데몬 기동(운영)
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
vibe exec --daemon --config .vibe/exec/config.json
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## 7) MCP 구현자 규칙 (Wrapper 안전 패턴)
|
|
153
|
+
|
|
154
|
+
MCP 도구는 다음만 한다.
|
|
155
|
+
|
|
156
|
+
1. `vibe <command>` 호출 (필수)
|
|
157
|
+
2. run_dir / manifest 읽기
|
|
158
|
+
3. 해석/요약/다음 액션 제시
|
|
159
|
+
|
|
160
|
+
**금지**
|
|
161
|
+
|
|
162
|
+
* `.vibe/install_manifest.json` 쓰기
|
|
163
|
+
* `.vibe/runs/**` 쓰기
|
|
164
|
+
* 엔진 바이너리 직접 호출
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## 8) 실패 유형별 즉시 처방 (Playbook)
|
|
169
|
+
|
|
170
|
+
### 케이스 A) "MCP는 되는데 로컬이 안 돼"
|
|
171
|
+
|
|
172
|
+
**증상**: MCP 도구는 동작하지만 CLI가 안 됨
|
|
173
|
+
|
|
174
|
+
**진단**:
|
|
175
|
+
```bash
|
|
176
|
+
vibe doctor --json | jq '.engines'
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**처방**:
|
|
180
|
+
1. doctor 결과에서 `BIN_VIBE_MISSING` / `ENGINE_MISSING` 찾기
|
|
181
|
+
2. `vibe update` 실행
|
|
182
|
+
3. 여전히 안 되면 권한/플랫폼 mismatch 분기
|
|
183
|
+
|
|
184
|
+
### 케이스 B) "JSON 파싱/출력 때문에 터짐"
|
|
185
|
+
|
|
186
|
+
**증상**: stdout JSON 파싱 실패
|
|
187
|
+
|
|
188
|
+
**규칙**:
|
|
189
|
+
* stdout JSON을 결과로 쓰지 말고(run_dir SSOT)
|
|
190
|
+
* CLI stdout은 `run_id` 같은 control 데이터만
|
|
191
|
+
* MCP는 run_dir 파일을 읽어라
|
|
192
|
+
|
|
193
|
+
**처방**:
|
|
194
|
+
```bash
|
|
195
|
+
# 잘못된 방식
|
|
196
|
+
result=$(vibe inspect_code --json) # stdout 파싱 X
|
|
197
|
+
|
|
198
|
+
# 올바른 방식
|
|
199
|
+
vibe inspect_code
|
|
200
|
+
cat runs/<run_id>/result.json # run_dir에서 읽기
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### 케이스 C) "daemon.lock 때문에 꼬임"
|
|
204
|
+
|
|
205
|
+
**증상**: `DAEMON_STALE_LOCK` 발생
|
|
206
|
+
|
|
207
|
+
**처방**:
|
|
208
|
+
```bash
|
|
209
|
+
vibe exec stop
|
|
210
|
+
rm -f .vibe/exec/daemon.lock # lock 정리
|
|
211
|
+
vibe exec --daemon --config .vibe/exec/config.json
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## 9) 스킬 완료 조건 (Done Criteria)
|
|
217
|
+
|
|
218
|
+
아래를 만족해야 완료로 간주한다.
|
|
219
|
+
|
|
220
|
+
- [ ] `.vibe/install_manifest.json` 존재 + 스키마 통과
|
|
221
|
+
- [ ] `vibe doctor --json` 결과가 ok=true 또는 WARN만
|
|
222
|
+
- [ ] engines/components가 모두 `status=ok` (또는 정책상 허용된 일부만 WARN)
|
|
223
|
+
- [ ] MCP는 "읽기 전용" 규칙을 위반하지 않음
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## 10) 스킬이 요구하는 파일(SSOT)
|
|
228
|
+
|
|
229
|
+
| 파일 | 필수 | 설명 |
|
|
230
|
+
|------|------|------|
|
|
231
|
+
| `.vibe/install_manifest.json` | ✅ | 설치 상태 SSOT |
|
|
232
|
+
| `schemas/install_manifest.schema.v1.json` | ✅ | manifest 스키마 |
|
|
233
|
+
| `docs/ssot/INSTALL_MANIFEST_AUTHORITY_RULES.v1.md` | 선택 | 권한 규칙 |
|
|
234
|
+
| `docs/ssot/VRIP.md` | 선택 | VRIP 프로토콜 |
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## 11) 에이전트용 프롬프트 템플릿
|
|
239
|
+
|
|
240
|
+
사용자가 상황을 설명하면 아래 템플릿으로 진단하라.
|
|
241
|
+
|
|
242
|
+
### 입력 템플릿
|
|
243
|
+
|
|
244
|
+
```
|
|
245
|
+
## 현재 상황
|
|
246
|
+
[사용자가 설명한 문제]
|
|
247
|
+
|
|
248
|
+
## doctor 결과
|
|
249
|
+
[vibe doctor --json 출력 붙여넣기]
|
|
250
|
+
|
|
251
|
+
## manifest 상태
|
|
252
|
+
[cat .vibe/install_manifest.json 출력 또는 "없음"]
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### 출력 템플릿
|
|
256
|
+
|
|
257
|
+
```
|
|
258
|
+
## Gate 판정
|
|
259
|
+
- **Status**: PASS / WARN / FAIL
|
|
260
|
+
- **코드**: [해당 코드 목록]
|
|
261
|
+
|
|
262
|
+
## 원인 분석
|
|
263
|
+
[문제의 근본 원인]
|
|
264
|
+
|
|
265
|
+
## 즉시 실행 커맨드
|
|
266
|
+
```bash
|
|
267
|
+
[복사 가능한 커맨드]
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
## 수정 체크리스트
|
|
271
|
+
- [ ] [필요한 조치 1]
|
|
272
|
+
- [ ] [필요한 조치 2]
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## 12) 관련 문서
|
|
278
|
+
|
|
279
|
+
| 문서 | 역할 |
|
|
280
|
+
|------|------|
|
|
281
|
+
| `docs/ssot/VRIP.md` | Vibe Run Invocation Protocol |
|
|
282
|
+
| `docs/ssot/INSTALL_MANIFEST_AUTHORITY_RULES.v1.md` | manifest 권한 규칙 |
|
|
283
|
+
| `docs/DEV_SPEC/system_design_mapping/VIBE_PM_CONTROL_PLANE_SPEC.md` | Control Plane 스펙 |
|
|
284
|
+
| `adapters/mcp-ts/src/tools/vibe_pm/doctor.ts` | doctor MCP 도구 |
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
**스킬 끝**
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "1.0.0",
|
|
3
|
+
"skills": [
|
|
4
|
+
{
|
|
5
|
+
"id": "VRIP_INSTALL_MANIFEST_DOCTOR",
|
|
6
|
+
"file": "VRIP_INSTALL_MANIFEST_DOCTOR.skill.md",
|
|
7
|
+
"version": "1.0.0",
|
|
8
|
+
"description": "MCP↔CLI↔Daemon 설치/실행 상태 진단 및 Gate 판정",
|
|
9
|
+
"tags": ["doctor", "manifest", "vrip", "diagnostic"],
|
|
10
|
+
"sha256": "ce45856decad28008792d124bc2d19a6d0db8dc327d2fc982e816954d92b2ea0"
|
|
11
|
+
}
|
|
12
|
+
],
|
|
13
|
+
"created_at": "2026-01-24T12:00:00.000Z"
|
|
14
|
+
}
|