vibeteam 0.2.3 → 0.2.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/bin/cli.js +191 -37
- package/dist/server/server/index.js +2078 -1822
- package/mcp/server.js +389 -0
- package/package.json +5 -2
- package/public/apple-touch-icon.png +0 -0
- package/public/assets/index-DURW-QlU.js +4330 -0
- package/public/assets/index-DgQWq5c0.css +1 -0
- package/public/favicon-16x16.png +0 -0
- package/public/favicon-32x32.png +0 -0
- package/public/favicon.ico +0 -0
- package/public/favicon.svg +14 -0
- package/public/index.html +21 -0
- package/public/logo.svg +22 -0
- package/public/models/.gitkeep +0 -0
- package/public/models/models/.gitkeep +0 -0
- package/public/site.webmanifest +25 -0
- package/public/sounds/sounds/yoshi.mp3 +0 -0
- package/public/sounds/yoshi.mp3 +0 -0
- package/dist/server/server/CommitWatcher.js +0 -307
package/bin/cli.js
CHANGED
|
@@ -384,7 +384,71 @@ if (args[0] === 'setup') {
|
|
|
384
384
|
}
|
|
385
385
|
|
|
386
386
|
// ==========================================================================
|
|
387
|
-
// Step 5:
|
|
387
|
+
// Step 5: MCP Server Installation
|
|
388
|
+
// ==========================================================================
|
|
389
|
+
|
|
390
|
+
let mcpInstalled = false
|
|
391
|
+
|
|
392
|
+
// Check if MCP is already configured
|
|
393
|
+
const mcpAlreadyConfigured = (() => {
|
|
394
|
+
try {
|
|
395
|
+
const s = JSON.parse(readFileSync(settingsPath, 'utf-8'))
|
|
396
|
+
return !!s.mcpServers?.vibeteam
|
|
397
|
+
} catch { return false }
|
|
398
|
+
})()
|
|
399
|
+
|
|
400
|
+
// Also check settings.local.json
|
|
401
|
+
const mcpInLocal = (() => {
|
|
402
|
+
try {
|
|
403
|
+
const localPath = settingsPath.replace('settings.json', 'settings.local.json')
|
|
404
|
+
if (!existsSync(localPath)) return false
|
|
405
|
+
const s = JSON.parse(readFileSync(localPath, 'utf-8'))
|
|
406
|
+
return !!s.mcpServers?.vibeteam
|
|
407
|
+
} catch { return false }
|
|
408
|
+
})()
|
|
409
|
+
|
|
410
|
+
if (mcpAlreadyConfigured || mcpInLocal) {
|
|
411
|
+
console.log('\nMCP server: already configured')
|
|
412
|
+
mcpInstalled = true
|
|
413
|
+
} else {
|
|
414
|
+
// Check if claude CLI is available
|
|
415
|
+
let hasClaudeCli = false
|
|
416
|
+
try {
|
|
417
|
+
execSync('which claude', { stdio: 'ignore' })
|
|
418
|
+
hasClaudeCli = true
|
|
419
|
+
} catch {}
|
|
420
|
+
|
|
421
|
+
if (hasClaudeCli) {
|
|
422
|
+
console.log('\n VibeTeam MCP server lets Claude Code control your agents remotely.')
|
|
423
|
+
const mcpAnswer = await askQuestion(' Install MCP integration for Claude Code? (y/n): ')
|
|
424
|
+
|
|
425
|
+
if (mcpAnswer.toLowerCase() === 'y' || mcpAnswer.toLowerCase() === 'yes') {
|
|
426
|
+
// Determine install method: global npm binary vs local dev path
|
|
427
|
+
let mcpCommand = 'vibeteam-mcp'
|
|
428
|
+
try {
|
|
429
|
+
execSync('which vibeteam-mcp', { stdio: 'ignore' })
|
|
430
|
+
} catch {
|
|
431
|
+
// vibeteam-mcp not in PATH — use absolute path to mcp/server.js
|
|
432
|
+
mcpCommand = resolve(ROOT, 'mcp/server.js')
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
try {
|
|
436
|
+
execSync(
|
|
437
|
+
`CLAUDECODE= claude mcp add vibeteam --scope user -- ${mcpCommand}`,
|
|
438
|
+
{ stdio: 'pipe', timeout: 10000 }
|
|
439
|
+
)
|
|
440
|
+
console.log(' ✓ MCP server installed for Claude Code')
|
|
441
|
+
mcpInstalled = true
|
|
442
|
+
} catch (e) {
|
|
443
|
+
console.log(` ✗ Failed to install MCP server: ${e.message}`)
|
|
444
|
+
console.log(` You can install manually: claude mcp add vibeteam -- ${mcpCommand}`)
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
// ==========================================================================
|
|
451
|
+
// Step 6: Verify and report
|
|
388
452
|
// ==========================================================================
|
|
389
453
|
|
|
390
454
|
console.log('\n' + '='.repeat(50))
|
|
@@ -401,6 +465,10 @@ if (args[0] === 'setup') {
|
|
|
401
465
|
console.log(' - UserPromptSubmit')
|
|
402
466
|
console.log(' - Notification')
|
|
403
467
|
|
|
468
|
+
if (mcpInstalled) {
|
|
469
|
+
console.log('\nMCP server: ✓ configured')
|
|
470
|
+
}
|
|
471
|
+
|
|
404
472
|
// Check dependencies
|
|
405
473
|
let hasWarnings = false
|
|
406
474
|
|
|
@@ -1008,6 +1076,78 @@ async function checkRequiredDependencies() {
|
|
|
1008
1076
|
// Check dependencies before starting
|
|
1009
1077
|
await checkRequiredDependencies()
|
|
1010
1078
|
|
|
1079
|
+
// ============================================================================
|
|
1080
|
+
// First-run MCP install offer
|
|
1081
|
+
// ============================================================================
|
|
1082
|
+
|
|
1083
|
+
async function offerMcpInstall() {
|
|
1084
|
+
// Check if we already offered (don't nag on every start)
|
|
1085
|
+
const flagFile = join(homedir(), '.vibeteam', '.mcp-offered')
|
|
1086
|
+
if (existsSync(flagFile)) return
|
|
1087
|
+
|
|
1088
|
+
// Check if MCP is already configured in settings or settings.local
|
|
1089
|
+
const settingsPaths = [
|
|
1090
|
+
join(homedir(), '.claude', 'settings.json'),
|
|
1091
|
+
join(homedir(), '.claude', 'settings.local.json'),
|
|
1092
|
+
join(homedir(), '.config', 'claude', 'settings.json'),
|
|
1093
|
+
join(homedir(), '.config', 'claude', 'settings.local.json'),
|
|
1094
|
+
]
|
|
1095
|
+
|
|
1096
|
+
for (const sp of settingsPaths) {
|
|
1097
|
+
try {
|
|
1098
|
+
if (!existsSync(sp)) continue
|
|
1099
|
+
const s = JSON.parse(readFileSync(sp, 'utf-8'))
|
|
1100
|
+
if (s.mcpServers?.vibeteam) return // Already configured
|
|
1101
|
+
} catch {}
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
// Check if claude CLI is available
|
|
1105
|
+
try {
|
|
1106
|
+
execSync('which claude', { stdio: 'ignore' })
|
|
1107
|
+
} catch {
|
|
1108
|
+
return // No claude CLI, skip
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
console.log(' VibeTeam MCP server lets Claude Code control your agents remotely.')
|
|
1112
|
+
const answer = await askQuestion(' Install MCP integration for Claude Code? (y/n): ')
|
|
1113
|
+
|
|
1114
|
+
// Ensure .vibeteam dir exists for the flag file
|
|
1115
|
+
const vibeteamDir = join(homedir(), '.vibeteam')
|
|
1116
|
+
if (!existsSync(vibeteamDir)) {
|
|
1117
|
+
mkdirSync(vibeteamDir, { recursive: true })
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
if (answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes') {
|
|
1121
|
+
let mcpCommand = 'vibeteam-mcp'
|
|
1122
|
+
try {
|
|
1123
|
+
execSync('which vibeteam-mcp', { stdio: 'ignore' })
|
|
1124
|
+
} catch {
|
|
1125
|
+
mcpCommand = resolve(ROOT, 'mcp/server.js')
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
try {
|
|
1129
|
+
execSync(
|
|
1130
|
+
`CLAUDECODE= claude mcp add vibeteam --scope user -- ${mcpCommand}`,
|
|
1131
|
+
{ stdio: 'pipe', timeout: 10000 }
|
|
1132
|
+
)
|
|
1133
|
+
console.log(' ✓ MCP server installed for Claude Code\n')
|
|
1134
|
+
} catch (e) {
|
|
1135
|
+
console.log(` ✗ Failed to install MCP: ${e.message}`)
|
|
1136
|
+
console.log(` Install manually: claude mcp add vibeteam -- ${mcpCommand}\n`)
|
|
1137
|
+
}
|
|
1138
|
+
} else {
|
|
1139
|
+
console.log()
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
// Write flag so we don't ask again
|
|
1143
|
+
const { writeFileSync } = await import('fs')
|
|
1144
|
+
try {
|
|
1145
|
+
writeFileSync(flagFile, new Date().toISOString())
|
|
1146
|
+
} catch {}
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
await offerMcpInstall()
|
|
1150
|
+
|
|
1011
1151
|
// Run health checks (warnings only)
|
|
1012
1152
|
printHealthCheck()
|
|
1013
1153
|
|
|
@@ -1024,44 +1164,58 @@ console.log()
|
|
|
1024
1164
|
const compiledPath = resolve(ROOT, 'dist/server/server/index.js')
|
|
1025
1165
|
const sourcePath = resolve(ROOT, 'server/index.ts')
|
|
1026
1166
|
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1167
|
+
/** Exit code 75 = restart requested (e.g. via POST /api/restart) */
|
|
1168
|
+
const RESTART_EXIT_CODE = 75
|
|
1169
|
+
|
|
1170
|
+
function spawnServer() {
|
|
1171
|
+
let server
|
|
1172
|
+
if (existsSync(compiledPath)) {
|
|
1173
|
+
// Use compiled JS (production/npm install)
|
|
1174
|
+
server = spawn('node', [compiledPath], {
|
|
1175
|
+
cwd: ROOT,
|
|
1176
|
+
env: {
|
|
1177
|
+
...process.env,
|
|
1178
|
+
VIBETEAM_PORT: port,
|
|
1179
|
+
},
|
|
1180
|
+
stdio: 'inherit',
|
|
1181
|
+
})
|
|
1182
|
+
} else {
|
|
1183
|
+
// Fall back to tsx (development)
|
|
1184
|
+
console.log('(dev mode - using tsx)')
|
|
1185
|
+
server = spawn('npx', ['tsx', sourcePath], {
|
|
1186
|
+
cwd: ROOT,
|
|
1187
|
+
env: {
|
|
1188
|
+
...process.env,
|
|
1189
|
+
VIBETEAM_PORT: port,
|
|
1190
|
+
},
|
|
1191
|
+
stdio: 'inherit',
|
|
1192
|
+
})
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
server.on('error', (err) => {
|
|
1196
|
+
console.error('Failed to start server:', err.message)
|
|
1197
|
+
process.exit(1)
|
|
1048
1198
|
})
|
|
1049
|
-
}
|
|
1050
1199
|
|
|
1051
|
-
server.on('
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1200
|
+
server.on('close', (code) => {
|
|
1201
|
+
if (code === RESTART_EXIT_CODE) {
|
|
1202
|
+
console.log('\n Restarting server...\n')
|
|
1203
|
+
// Small delay to let port release
|
|
1204
|
+
setTimeout(() => spawnServer(), 1000)
|
|
1205
|
+
return
|
|
1206
|
+
}
|
|
1207
|
+
process.exit(code || 0)
|
|
1208
|
+
})
|
|
1055
1209
|
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1210
|
+
// Handle signals - forward to child
|
|
1211
|
+
const onSigInt = () => server.kill('SIGINT')
|
|
1212
|
+
const onSigTerm = () => server.kill('SIGTERM')
|
|
1059
1213
|
|
|
1060
|
-
//
|
|
1061
|
-
process.
|
|
1062
|
-
|
|
1063
|
-
|
|
1214
|
+
// Remove old listeners to avoid stacking on restart
|
|
1215
|
+
process.removeAllListeners('SIGINT')
|
|
1216
|
+
process.removeAllListeners('SIGTERM')
|
|
1217
|
+
process.on('SIGINT', onSigInt)
|
|
1218
|
+
process.on('SIGTERM', onSigTerm)
|
|
1219
|
+
}
|
|
1064
1220
|
|
|
1065
|
-
|
|
1066
|
-
server.kill('SIGTERM')
|
|
1067
|
-
})
|
|
1221
|
+
spawnServer()
|