vibe-collab 0.7.0 → 0.8.0
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 +17 -1
- package/dist/cli/commands/auth.js +1 -1
- package/dist/cli/commands/connect.d.ts +1 -1
- package/dist/cli/commands/connect.js +57 -73
- package/dist/cli/commands/update.d.ts +1 -0
- package/dist/cli/commands/update.js +52 -0
- package/dist/cli/index.js +11 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -76,10 +76,26 @@ vibe start
|
|
|
76
76
|
| `vibe auth login` | GitHub OAuth 로그인 |
|
|
77
77
|
| `vibe auth logout` | 로그아웃 |
|
|
78
78
|
| `vibe auth status` | 로그인 상태 및 만료일 확인 |
|
|
79
|
-
| `vibe init` | 프로젝트 초기화 (CHARTER, state.json
|
|
79
|
+
| `vibe init` | 프로젝트 초기화 (CHARTER, state.json 생성 + MCP 자동 감지) |
|
|
80
|
+
| `vibe connect` | 프로젝트 내 AI 도구 자동 감지 후 MCP 설정 추가 |
|
|
81
|
+
| `vibe connect --ai <tool>` | 특정 AI 도구에 MCP 설정 강제 추가 |
|
|
80
82
|
| `vibe start` | 작업 시작 또는 이어서 진행 |
|
|
81
83
|
| `vibe status` | 팀 현황 출력 |
|
|
82
84
|
| `vibe serve` | MCP 서버 시작 (AI 도구에서 자동 실행됨) |
|
|
85
|
+
| `vibe update` | vibe-collab을 최신 버전으로 업데이트 |
|
|
86
|
+
|
|
87
|
+
### `vibe connect --ai` 지원 도구
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
vibe connect --ai claude # Claude Code → .claude/settings.json
|
|
91
|
+
vibe connect --ai cursor # Cursor → .cursor/mcp.json
|
|
92
|
+
vibe connect --ai vscode # VS Code → .vscode/mcp.json
|
|
93
|
+
vibe connect --ai windsurf # Windsurf → .windsurf/mcp.json
|
|
94
|
+
vibe connect --ai gemini # Gemini CLI → .gemini/settings.json
|
|
95
|
+
vibe connect --ai kiro # Kiro → .kiro/mcp.json
|
|
96
|
+
vibe connect --ai copilot # Copilot → .vscode/mcp.json
|
|
97
|
+
vibe connect --ai all # 위 전체 설정
|
|
98
|
+
```
|
|
83
99
|
|
|
84
100
|
---
|
|
85
101
|
|
|
@@ -149,7 +149,6 @@ export async function authCommand(action) {
|
|
|
149
149
|
}
|
|
150
150
|
case 'logout': {
|
|
151
151
|
const data = readAuthData();
|
|
152
|
-
deleteAuthData();
|
|
153
152
|
if (data) {
|
|
154
153
|
try {
|
|
155
154
|
await fetch(`${PROXY_URL}/api/auth/cli-token`, {
|
|
@@ -160,6 +159,7 @@ export async function authCommand(action) {
|
|
|
160
159
|
catch {
|
|
161
160
|
// 서버 호출 실패해도 로컬 삭제는 완료
|
|
162
161
|
}
|
|
162
|
+
deleteAuthData();
|
|
163
163
|
console.log(chalk.green(`👋 @${data.user.login} 로그아웃 완료.`));
|
|
164
164
|
}
|
|
165
165
|
else {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function connectCommand(cwd: string): Promise<void>;
|
|
1
|
+
export declare function connectCommand(cwd: string, aiFlag?: string): Promise<void>;
|
|
@@ -1,26 +1,27 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
|
-
import { execSync } from 'child_process';
|
|
4
3
|
import chalk from 'chalk';
|
|
5
4
|
const STANDARD_MCP_ENTRY = {
|
|
6
5
|
command: 'npx',
|
|
7
|
-
args: ['vibe-
|
|
6
|
+
args: ['vibe-collab', 'serve'],
|
|
8
7
|
env: {},
|
|
9
8
|
};
|
|
10
9
|
const VSCODE_MCP_ENTRY = {
|
|
11
10
|
type: 'stdio',
|
|
12
11
|
command: 'npx',
|
|
13
|
-
args: ['vibe-
|
|
12
|
+
args: ['vibe-collab', 'serve'],
|
|
14
13
|
};
|
|
15
|
-
function
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
14
|
+
function getToolDefs(cwd) {
|
|
15
|
+
return {
|
|
16
|
+
claude: { label: 'Claude Code', configDir: '.claude', configFile: 'settings.json', format: 'standard' },
|
|
17
|
+
cursor: { label: 'Cursor', configDir: '.cursor', configFile: 'mcp.json', format: 'standard' },
|
|
18
|
+
vscode: { label: 'VS Code', configDir: '.vscode', configFile: 'mcp.json', format: 'vscode' },
|
|
19
|
+
copilot: { label: 'Copilot', configDir: '.vscode', configFile: 'mcp.json', format: 'vscode' },
|
|
20
|
+
windsurf: { label: 'Windsurf', configDir: '.windsurf', configFile: 'mcp.json', format: 'standard' },
|
|
21
|
+
gemini: { label: 'Gemini CLI', configDir: '.gemini', configFile: 'settings.json', format: 'standard' },
|
|
22
|
+
kiro: { label: 'Kiro', configDir: '.kiro', configFile: 'mcp.json', format: 'standard' },
|
|
23
|
+
};
|
|
24
|
+
void cwd;
|
|
24
25
|
}
|
|
25
26
|
function hasDir(dir) {
|
|
26
27
|
return fs.existsSync(dir);
|
|
@@ -66,74 +67,46 @@ function addVSCodeEntry(existing, serverKey) {
|
|
|
66
67
|
},
|
|
67
68
|
};
|
|
68
69
|
}
|
|
69
|
-
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
if (!detected) {
|
|
74
|
-
return { tool, configPath: '', status: 'skipped' };
|
|
70
|
+
function configureTool(cwd, def, force) {
|
|
71
|
+
const dir = path.join(cwd, def.configDir);
|
|
72
|
+
if (!force && !hasDir(dir)) {
|
|
73
|
+
return { tool: def.label, configPath: '', status: 'skipped' };
|
|
75
74
|
}
|
|
76
|
-
const configPath = path.join(
|
|
75
|
+
const configPath = path.join(dir, def.configFile);
|
|
77
76
|
const existing = readJsonSafe(configPath);
|
|
78
77
|
if (isAlreadyConfigured(existing, 'vibe-orchestrator')) {
|
|
79
|
-
return { tool, configPath, status: 'already' };
|
|
78
|
+
return { tool: def.label, configPath, status: 'already' };
|
|
80
79
|
}
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
const updated = def.format === 'vscode'
|
|
81
|
+
? addVSCodeEntry(existing, 'vibe-orchestrator')
|
|
82
|
+
: addStandardEntry(existing, 'vibe-orchestrator');
|
|
83
|
+
writeJson(configPath, updated);
|
|
84
|
+
return { tool: def.label, configPath, status: 'added' };
|
|
83
85
|
}
|
|
84
|
-
async function
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
const vscodeDir = path.join(cwd, '.vscode');
|
|
102
|
-
const detected = hasDir(vscodeDir) || hasBinary('code');
|
|
103
|
-
if (!detected) {
|
|
104
|
-
return { tool, configPath: '', status: 'skipped' };
|
|
86
|
+
export async function connectCommand(cwd, aiFlag) {
|
|
87
|
+
const toolDefs = getToolDefs(cwd);
|
|
88
|
+
let targets;
|
|
89
|
+
if (aiFlag) {
|
|
90
|
+
const key = aiFlag.toLowerCase();
|
|
91
|
+
if (key === 'all') {
|
|
92
|
+
targets = Object.values(toolDefs).map(def => ({ def, force: true }));
|
|
93
|
+
}
|
|
94
|
+
else if (toolDefs[key]) {
|
|
95
|
+
targets = [{ def: toolDefs[key], force: true }];
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
console.log(chalk.red(`알 수 없는 AI 도구: ${aiFlag}`));
|
|
99
|
+
console.log(chalk.gray(`지원 목록: ${Object.keys(toolDefs).join(', ')}, all`));
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
console.log(chalk.cyan(`\n🔌 ${aiFlag === 'all' ? '전체' : toolDefs[aiFlag.toLowerCase()]?.label} MCP 설정 중...\n`));
|
|
105
103
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
104
|
+
else {
|
|
105
|
+
// 자동 감지: 프로젝트 디렉토리가 있는 것만
|
|
106
|
+
targets = Object.values(toolDefs).map(def => ({ def, force: false }));
|
|
107
|
+
console.log(chalk.cyan('\n🔌 AI 도구 자동 감지 중...\n'));
|
|
110
108
|
}
|
|
111
|
-
|
|
112
|
-
return { tool, configPath, status: 'added' };
|
|
113
|
-
}
|
|
114
|
-
// Windsurf도 글로벌 설정(~/.codeium/)이므로 자동 설정 제외
|
|
115
|
-
async function configureWindsurf() {
|
|
116
|
-
return { tool: 'Windsurf', configPath: '', status: 'skipped' };
|
|
117
|
-
}
|
|
118
|
-
// Claude Desktop과 Gemini CLI는 글로벌 설정 파일을 수정하므로
|
|
119
|
-
// vibe init 시 자동 설정하지 않습니다.
|
|
120
|
-
// 원하면 vibe connect --global 로 별도 실행하세요. (미구현)
|
|
121
|
-
async function configureClaudeDesktop() {
|
|
122
|
-
return { tool: 'Claude Desktop', configPath: '', status: 'skipped' };
|
|
123
|
-
}
|
|
124
|
-
async function configureGeminiCLI() {
|
|
125
|
-
return { tool: 'Gemini CLI', configPath: '', status: 'skipped' };
|
|
126
|
-
}
|
|
127
|
-
export async function connectCommand(cwd) {
|
|
128
|
-
console.log(chalk.cyan('\n🔌 AI 도구 자동 설정 중...\n'));
|
|
129
|
-
const results = await Promise.all([
|
|
130
|
-
configureClaudeCode(cwd),
|
|
131
|
-
configureCursor(cwd),
|
|
132
|
-
configureVSCode(cwd),
|
|
133
|
-
configureWindsurf(),
|
|
134
|
-
configureClaudeDesktop(),
|
|
135
|
-
configureGeminiCLI(),
|
|
136
|
-
]);
|
|
109
|
+
const results = targets.map(({ def, force }) => configureTool(cwd, def, force));
|
|
137
110
|
let addedCount = 0;
|
|
138
111
|
let alreadyCount = 0;
|
|
139
112
|
let skippedCount = 0;
|
|
@@ -167,5 +140,16 @@ export async function connectCommand(cwd) {
|
|
|
167
140
|
console.log(chalk.green(`✨ ${parts.join(', ')}`));
|
|
168
141
|
console.log(chalk.gray(' AI 도구를 재시작하면 vibe-orchestrator MCP가 활성화됩니다.\n'));
|
|
169
142
|
}
|
|
143
|
+
console.log(chalk.cyan('─── 수동 설정 (다른 MCP 지원 도구에 직접 추가) ───\n'));
|
|
144
|
+
console.log(chalk.white('Claude Code / Cursor / 기타:'));
|
|
145
|
+
console.log(chalk.gray(JSON.stringify({
|
|
146
|
+
mcpServers: { 'vibe-orchestrator': STANDARD_MCP_ENTRY },
|
|
147
|
+
}, null, 2)));
|
|
148
|
+
console.log('');
|
|
149
|
+
console.log(chalk.white('VS Code:'));
|
|
150
|
+
console.log(chalk.gray(JSON.stringify({
|
|
151
|
+
servers: { 'vibe-orchestrator': VSCODE_MCP_ENTRY },
|
|
152
|
+
}, null, 2)));
|
|
153
|
+
console.log('');
|
|
170
154
|
}
|
|
171
155
|
//# sourceMappingURL=connect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function updateCommand(): Promise<void>;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { execSync, spawnSync } from 'child_process';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
const PACKAGE_NAME = 'vibe-collab';
|
|
4
|
+
function getCurrentVersion() {
|
|
5
|
+
try {
|
|
6
|
+
const result = execSync(`npm list -g --depth=0 ${PACKAGE_NAME} --json`, { encoding: 'utf-8', stdio: 'pipe' });
|
|
7
|
+
const json = JSON.parse(result);
|
|
8
|
+
return json.dependencies?.[PACKAGE_NAME]?.version ?? 'unknown';
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return 'unknown';
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function getLatestVersion() {
|
|
15
|
+
try {
|
|
16
|
+
return execSync(`npm view ${PACKAGE_NAME} version`, { encoding: 'utf-8', stdio: 'pipe' }).trim();
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
throw new Error('npm 레지스트리에서 버전 정보를 가져올 수 없습니다.');
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export async function updateCommand() {
|
|
23
|
+
console.log(chalk.cyan('\n🔄 vibe-collab 업데이트 확인 중...\n'));
|
|
24
|
+
const current = getCurrentVersion();
|
|
25
|
+
let latest;
|
|
26
|
+
try {
|
|
27
|
+
latest = getLatestVersion();
|
|
28
|
+
}
|
|
29
|
+
catch (e) {
|
|
30
|
+
console.log(chalk.red(e.message));
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
console.log(chalk.gray(` 현재 버전: ${current}`));
|
|
34
|
+
console.log(chalk.gray(` 최신 버전: ${latest}\n`));
|
|
35
|
+
if (current === latest) {
|
|
36
|
+
console.log(chalk.green('✅ 이미 최신 버전입니다.'));
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
console.log(chalk.cyan(`📦 ${current} → ${latest} 업데이트 중...\n`));
|
|
40
|
+
const result = spawnSync('npm', ['install', '-g', `${PACKAGE_NAME}@latest`], {
|
|
41
|
+
stdio: 'inherit',
|
|
42
|
+
shell: true,
|
|
43
|
+
});
|
|
44
|
+
if (result.status === 0) {
|
|
45
|
+
console.log(chalk.green(`\n✅ ${latest}로 업데이트 완료!`));
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
console.log(chalk.red('\n업데이트 실패. 직접 실행해보세요:'));
|
|
49
|
+
console.log(chalk.gray(` npm install -g ${PACKAGE_NAME}@latest`));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=update.js.map
|
package/dist/cli/index.js
CHANGED
|
@@ -7,6 +7,7 @@ import { startCommand } from './commands/start.js';
|
|
|
7
7
|
import { serveCommand } from './commands/serve.js';
|
|
8
8
|
import { connectCommand } from './commands/connect.js';
|
|
9
9
|
import { authCommand } from './commands/auth.js';
|
|
10
|
+
import { updateCommand } from './commands/update.js';
|
|
10
11
|
const program = new Command();
|
|
11
12
|
program
|
|
12
13
|
.name('vibe')
|
|
@@ -40,9 +41,10 @@ program
|
|
|
40
41
|
});
|
|
41
42
|
program
|
|
42
43
|
.command('connect')
|
|
43
|
-
.description('
|
|
44
|
-
.
|
|
45
|
-
|
|
44
|
+
.description('AI 도구에 MCP 설정을 추가합니다')
|
|
45
|
+
.option('--ai <tool>', 'AI 도구 지정 (claude|cursor|vscode|windsurf|gemini|kiro|copilot|all)')
|
|
46
|
+
.action(async (options) => {
|
|
47
|
+
await connectCommand(process.cwd(), options.ai);
|
|
46
48
|
});
|
|
47
49
|
program
|
|
48
50
|
.command('auth')
|
|
@@ -51,5 +53,11 @@ program
|
|
|
51
53
|
.action(async (action) => {
|
|
52
54
|
await authCommand(action);
|
|
53
55
|
});
|
|
56
|
+
program
|
|
57
|
+
.command('update')
|
|
58
|
+
.description('vibe-collab을 최신 버전으로 업데이트합니다')
|
|
59
|
+
.action(async () => {
|
|
60
|
+
await updateCommand();
|
|
61
|
+
});
|
|
54
62
|
program.parse();
|
|
55
63
|
//# sourceMappingURL=index.js.map
|