vibe-collab 0.8.2 → 0.8.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.
- package/README.md +5 -6
- package/dist/cli/commands/connect.js +70 -66
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -78,7 +78,7 @@ vibe start
|
|
|
78
78
|
| `vibe auth status` | 로그인 상태 및 만료일 확인 |
|
|
79
79
|
| `vibe init` | 프로젝트 초기화 (CHARTER, state.json 생성 + MCP 자동 감지) |
|
|
80
80
|
| `vibe connect` | 프로젝트 내 AI 도구 자동 감지 후 MCP 설정 추가 |
|
|
81
|
-
| `vibe connect --ai <tool>` | 특정 AI 도구에 MCP 설정
|
|
81
|
+
| `vibe connect --ai <tool>` | 특정 AI 도구에 MCP 설정 추가 (해당 도구의 수동 설정 가이드만 표시) |
|
|
82
82
|
| `vibe start` | 작업 시작 또는 이어서 진행 |
|
|
83
83
|
| `vibe status` | 팀 현황 출력 |
|
|
84
84
|
| `vibe serve` | MCP 서버 시작 (AI 도구에서 자동 실행됨) |
|
|
@@ -87,6 +87,7 @@ vibe start
|
|
|
87
87
|
### `vibe connect --ai` 지원 도구
|
|
88
88
|
|
|
89
89
|
각 도구별로 올바른 설정 파일 경로와 형식을 자동으로 적용합니다.
|
|
90
|
+
`--ai <tool>` 지정 시 해당 도구의 수동 설정 가이드만 출력됩니다.
|
|
90
91
|
|
|
91
92
|
| 명령어 | 도구 | 설정 파일 |
|
|
92
93
|
|--------|------|-----------|
|
|
@@ -104,13 +105,11 @@ vibe start
|
|
|
104
105
|
| `vibe connect --ai codebuddy` | CodeBuddy | `.codebuddy/mcp.json` |
|
|
105
106
|
| `vibe connect --ai droid` | Droid | `.droid/mcp.json` |
|
|
106
107
|
| `vibe connect --ai windsurf` | Windsurf | `~/.codeium/windsurf/mcp_config.json` (전역) |
|
|
107
|
-
| `vibe connect --ai gemini` | Gemini CLI | `~/.gemini/settings.json` (
|
|
108
|
-
| `vibe connect --ai antigravity` | Antigravity |
|
|
108
|
+
| `vibe connect --ai gemini` | Gemini CLI | `~/.gemini/settings.json` (전역) |
|
|
109
|
+
| `vibe connect --ai antigravity` | Antigravity | `~/.gemini/antigravity/mcp_config.json` (전역) |
|
|
109
110
|
| `vibe connect --ai all` | 위 전체 설정 | — |
|
|
110
111
|
|
|
111
|
-
> **Antigravity**:
|
|
112
|
-
>
|
|
113
|
-
> **Windsurf / Gemini CLI**: 전역 설정 파일에 기록됩니다 (프로젝트 디렉토리 불필요).
|
|
112
|
+
> **Windsurf / Gemini CLI / Antigravity**: 전역 설정 파일에 기록됩니다 (프로젝트 디렉토리 불필요). 기존 설정 파일의 형식(객체/배열)이 다를 경우 자동으로 호환 처리합니다.
|
|
114
113
|
|
|
115
114
|
---
|
|
116
115
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import os from 'os';
|
|
4
|
-
import { spawnSync } from 'child_process';
|
|
5
4
|
import chalk from 'chalk';
|
|
6
5
|
const SERVER_KEY = 'vibe-orchestrator';
|
|
7
6
|
const STANDARD_MCP_ENTRY = {
|
|
@@ -40,44 +39,14 @@ function getToolDefs() {
|
|
|
40
39
|
// ── 전역 (홈 디렉토리) ────────────────────────────────────────────────────
|
|
41
40
|
windsurf: { label: 'Windsurf', configDir: '.codeium/windsurf', configFile: 'mcp_config.json', format: 'standard', scope: 'global' },
|
|
42
41
|
gemini: { label: 'Gemini CLI', configDir: '.gemini', configFile: 'settings.json', format: 'array', scope: 'global' },
|
|
43
|
-
// ──
|
|
44
|
-
antigravity: { label: 'Antigravity', configDir: 'antigravity', configFile: '', format: '
|
|
42
|
+
// ── 전역 (홈 디렉토리) — Antigravity ──────────────────────────────────────
|
|
43
|
+
antigravity: { label: 'Antigravity', configDir: '.gemini/antigravity', configFile: 'mcp_config.json', format: 'standard', scope: 'global' },
|
|
45
44
|
};
|
|
46
45
|
}
|
|
47
46
|
function resolveDir(cwd, def) {
|
|
48
|
-
if (def.scope === 'cli')
|
|
49
|
-
return ''; // CLI 도구는 디렉토리 불필요
|
|
50
47
|
const base = def.scope === 'global' ? os.homedir() : cwd;
|
|
51
48
|
return path.join(base, def.configDir);
|
|
52
49
|
}
|
|
53
|
-
function isCommandAvailable(cmd) {
|
|
54
|
-
const check = spawnSync(process.platform === 'win32' ? 'where' : 'which', [cmd], { stdio: 'pipe' });
|
|
55
|
-
return check.status === 0;
|
|
56
|
-
}
|
|
57
|
-
function configureViaCli(def) {
|
|
58
|
-
const binary = def.configDir; // configDir에 바이너리명 저장
|
|
59
|
-
const result = spawnSync(binary, ['mcp', 'add', SERVER_KEY, '--', 'npx', 'vibe-collab', 'serve'], {
|
|
60
|
-
encoding: 'utf-8',
|
|
61
|
-
shell: true,
|
|
62
|
-
stdio: 'pipe',
|
|
63
|
-
});
|
|
64
|
-
const output = ((result.stdout ?? '') + (result.stderr ?? '')).toLowerCase();
|
|
65
|
-
if (result.status === 0) {
|
|
66
|
-
// 이미 존재한다는 메시지가 포함된 경우 (도구마다 다를 수 있음)
|
|
67
|
-
if (output.includes('already') || output.includes('exist') || output.includes('duplicate')) {
|
|
68
|
-
return { tool: def.label, configPath: '', status: 'already' };
|
|
69
|
-
}
|
|
70
|
-
return { tool: def.label, configPath: '', status: 'added' };
|
|
71
|
-
}
|
|
72
|
-
// 종료 코드 비정상
|
|
73
|
-
if (output.includes('already') || output.includes('exist') || output.includes('duplicate')) {
|
|
74
|
-
return { tool: def.label, configPath: '', status: 'already' };
|
|
75
|
-
}
|
|
76
|
-
if (result.error?.message?.includes('ENOENT') || output.includes('not found')) {
|
|
77
|
-
return { tool: def.label, configPath: '', status: 'skipped' }; // 미설치
|
|
78
|
-
}
|
|
79
|
-
return { tool: def.label, configPath: '', status: 'error', errorMsg: (result.stderr ?? '').trim() };
|
|
80
|
-
}
|
|
81
50
|
// ── JSON 헬퍼 ────────────────────────────────────────────────────────────────
|
|
82
51
|
function readJsonSafe(filePath) {
|
|
83
52
|
try {
|
|
@@ -97,11 +66,16 @@ function isConfiguredJson(existing, format) {
|
|
|
97
66
|
if (format === 'vscode') {
|
|
98
67
|
return !!(existing['servers']?.[SERVER_KEY]);
|
|
99
68
|
}
|
|
69
|
+
const raw = existing['mcpServers'];
|
|
100
70
|
if (format === 'array') {
|
|
101
|
-
|
|
102
|
-
|
|
71
|
+
// mcpServers가 배열이면 name으로 검색, 객체이면 키로 검색
|
|
72
|
+
if (Array.isArray(raw))
|
|
73
|
+
return raw.some(s => s.name === SERVER_KEY);
|
|
74
|
+
if (raw && typeof raw === 'object')
|
|
75
|
+
return !!raw[SERVER_KEY];
|
|
76
|
+
return false;
|
|
103
77
|
}
|
|
104
|
-
return !!(
|
|
78
|
+
return !!(raw?.[SERVER_KEY]);
|
|
105
79
|
}
|
|
106
80
|
function addEntryJson(existing, format) {
|
|
107
81
|
if (format === 'vscode') {
|
|
@@ -109,7 +83,12 @@ function addEntryJson(existing, format) {
|
|
|
109
83
|
return { ...existing, servers: { ...servers, [SERVER_KEY]: VSCODE_MCP_ENTRY } };
|
|
110
84
|
}
|
|
111
85
|
if (format === 'array') {
|
|
112
|
-
const
|
|
86
|
+
const raw = existing['mcpServers'];
|
|
87
|
+
// 이미 객체 형식이면 객체 형식 유지 (다른 도구가 먼저 설정한 경우)
|
|
88
|
+
if (raw && typeof raw === 'object' && !Array.isArray(raw)) {
|
|
89
|
+
return { ...existing, mcpServers: { ...raw, [SERVER_KEY]: STANDARD_MCP_ENTRY } };
|
|
90
|
+
}
|
|
91
|
+
const arr = raw ?? [];
|
|
113
92
|
return { ...existing, mcpServers: [...arr, ARRAY_MCP_ENTRY] };
|
|
114
93
|
}
|
|
115
94
|
const mcpServers = existing['mcpServers'] ?? {};
|
|
@@ -132,13 +111,6 @@ function appendToFile(filePath, content) {
|
|
|
132
111
|
}
|
|
133
112
|
// ── 도구 설정 ────────────────────────────────────────────────────────────────
|
|
134
113
|
function configureTool(cwd, def, force) {
|
|
135
|
-
// CLI 방식 도구 (Antigravity 등)
|
|
136
|
-
if (def.scope === 'cli') {
|
|
137
|
-
if (!isCommandAvailable(def.configDir)) {
|
|
138
|
-
return { tool: def.label, configPath: '', status: 'skipped' };
|
|
139
|
-
}
|
|
140
|
-
return configureViaCli(def);
|
|
141
|
-
}
|
|
142
114
|
// 자동 감지 모드: 디렉토리 존재 여부만 확인 (--ai 지정 시 force=true → 무조건 설정)
|
|
143
115
|
if (!force && !fs.existsSync(resolveDir(cwd, def))) {
|
|
144
116
|
return { tool: def.label, configPath: '', status: 'skipped' };
|
|
@@ -239,28 +211,60 @@ export async function connectCommand(cwd, aiFlag) {
|
|
|
239
211
|
console.log(chalk.gray(' AI 도구를 재시작하면 vibe-orchestrator MCP가 활성화됩니다.\n'));
|
|
240
212
|
}
|
|
241
213
|
// ── 수동 설정 가이드 ───────────────────────────────────────────────────────
|
|
214
|
+
const targetKeys = key
|
|
215
|
+
? (key === 'all' ? Object.keys(toolDefs) : [key])
|
|
216
|
+
: Object.keys(toolDefs);
|
|
217
|
+
printManualGuide(targetKeys);
|
|
218
|
+
}
|
|
219
|
+
function buildGuideEntries() {
|
|
220
|
+
return [
|
|
221
|
+
{
|
|
222
|
+
keys: ['claude', 'cursor', 'roocode', 'kiro', 'continue', 'qoder', 'codebuddy', 'droid'],
|
|
223
|
+
label: 'Claude Code / Cursor / Roo Code / Kiro / Continue / Qoder / CodeBuddy / Droid:',
|
|
224
|
+
content: JSON.stringify({ mcpServers: { [SERVER_KEY]: STANDARD_MCP_ENTRY } }, null, 2),
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
keys: ['vscode', 'copilot'],
|
|
228
|
+
label: 'VS Code / Copilot (.vscode/mcp.json):',
|
|
229
|
+
content: JSON.stringify({ servers: { [SERVER_KEY]: VSCODE_MCP_ENTRY } }, null, 2),
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
keys: ['trae', 'gemini'],
|
|
233
|
+
label: 'Trae (.trae/mcp.json) / Gemini CLI (~/.gemini/settings.json):',
|
|
234
|
+
content: JSON.stringify({ mcpServers: [ARRAY_MCP_ENTRY] }, null, 2),
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
keys: ['opencode'],
|
|
238
|
+
label: 'OpenCode (.opencode/config.toml):',
|
|
239
|
+
content: `[mcp.${SERVER_KEY}]\ntype = "stdio"\ncommand = "npx"\nargs = ["vibe-collab", "serve"]`,
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
keys: ['codex'],
|
|
243
|
+
label: 'Codex CLI (.codex/config.toml):',
|
|
244
|
+
content: `[[mcp]]\nname = "${SERVER_KEY}"\ncommand = "npx"\nargs = ["vibe-collab", "serve"]`,
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
keys: ['antigravity'],
|
|
248
|
+
label: 'Antigravity (~/.gemini/antigravity/mcp_config.json):',
|
|
249
|
+
content: JSON.stringify({ mcpServers: { [SERVER_KEY]: STANDARD_MCP_ENTRY } }, null, 2),
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
keys: ['windsurf'],
|
|
253
|
+
label: 'Windsurf (~/.codeium/windsurf/mcp_config.json):',
|
|
254
|
+
content: JSON.stringify({ mcpServers: { [SERVER_KEY]: STANDARD_MCP_ENTRY } }, null, 2),
|
|
255
|
+
},
|
|
256
|
+
];
|
|
257
|
+
}
|
|
258
|
+
function printManualGuide(targetKeys) {
|
|
259
|
+
const entries = buildGuideEntries();
|
|
260
|
+
const matched = entries.filter(e => e.keys.some(k => targetKeys.includes(k)));
|
|
261
|
+
if (matched.length === 0)
|
|
262
|
+
return;
|
|
242
263
|
console.log(chalk.cyan('─── 수동 설정 가이드 ───\n'));
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
console.log('');
|
|
249
|
-
console.log(chalk.white('Trae (.trae/mcp.json) / Gemini CLI (~/.gemini/settings.json):'));
|
|
250
|
-
console.log(chalk.gray(JSON.stringify({ mcpServers: [ARRAY_MCP_ENTRY] }, null, 2)));
|
|
251
|
-
console.log('');
|
|
252
|
-
console.log(chalk.white('OpenCode (.opencode/config.toml):'));
|
|
253
|
-
console.log(chalk.gray(`[mcp.${SERVER_KEY}]\ntype = "stdio"\ncommand = "npx"\nargs = ["vibe-collab", "serve"]`));
|
|
254
|
-
console.log('');
|
|
255
|
-
console.log(chalk.white('Codex CLI (.codex/config.toml):'));
|
|
256
|
-
console.log(chalk.gray(`[[mcp]]\nname = "${SERVER_KEY}"\ncommand = "npx"\nargs = ["vibe-collab", "serve"]`));
|
|
257
|
-
console.log('');
|
|
258
|
-
console.log(chalk.white('Antigravity (파일 기반 MCP 미지원 — CLI 명령어 사용):'));
|
|
259
|
-
console.log(chalk.gray(`antigravity mcp add ${SERVER_KEY} -- npx vibe-collab serve`));
|
|
260
|
-
console.log(chalk.gray('(vibe connect --ai antigravity 실행 시 자동으로 위 명령어를 실행합니다)'));
|
|
261
|
-
console.log('');
|
|
262
|
-
console.log(chalk.white('Windsurf (~/.codeium/windsurf/mcp_config.json):'));
|
|
263
|
-
console.log(chalk.gray(JSON.stringify({ mcpServers: { [SERVER_KEY]: STANDARD_MCP_ENTRY } }, null, 2)));
|
|
264
|
-
console.log('');
|
|
264
|
+
for (const entry of matched) {
|
|
265
|
+
console.log(chalk.white(entry.label));
|
|
266
|
+
console.log(chalk.gray(entry.content));
|
|
267
|
+
console.log('');
|
|
268
|
+
}
|
|
265
269
|
}
|
|
266
270
|
//# sourceMappingURL=connect.js.map
|
package/package.json
CHANGED