slashvibe-mcp 0.3.21 → 0.3.23
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/LICENSE +21 -0
- package/README.md +280 -47
- package/auto-update.js +10 -15
- package/config.js +36 -31
- package/crypto.js +1 -6
- package/debug.js +12 -0
- package/discord.js +19 -19
- package/eslint.config.js +54 -0
- package/index.js +217 -207
- package/intelligence/index.js +2 -9
- package/intelligence/infer.js +10 -16
- package/intelligence/patterns.js +23 -18
- package/intelligence/proactive.js +16 -15
- package/intelligence/serendipity.js +57 -20
- package/memory.js +13 -8
- package/migrate-v2.js +72 -0
- package/notification-emitter.js +2 -2
- package/notify.js +39 -14
- package/package.json +28 -29
- package/post-install.js +141 -0
- package/presence.js +2 -2
- package/prompts.js +5 -9
- package/protocol/index.js +123 -87
- package/protocol/telegram-commands.js +36 -37
- package/store/api.js +358 -529
- package/store/local.js +9 -10
- package/store/profiles.js +48 -192
- package/store/reservations.js +2 -9
- package/store/skills.js +69 -71
- package/store/sqlite.js +355 -0
- package/test-skills-bootstrap.js +20 -0
- package/test-v2-integration.js +385 -0
- package/tools/_actions.js +48 -387
- package/tools/_connection-queue.js +45 -56
- package/tools/_discovery-enhanced.js +52 -57
- package/tools/_discovery.js +87 -185
- package/tools/{l2-status.js → _experimental/l2-status.js} +68 -70
- package/tools/{shipback.js → _experimental/shipback.js} +4 -3
- package/tools/_proactive-discovery.js +60 -73
- package/tools/_shared/index.js +41 -64
- package/tools/admin-inbox.js +10 -15
- package/tools/agents.js +1 -1
- package/tools/artifact-create.js +13 -23
- package/tools/artifact-view.js +4 -4
- package/tools/{_deprecated/back.js → back.js} +1 -1
- package/tools/bye.js +3 -5
- package/tools/consent.js +2 -2
- package/tools/context.js +9 -10
- package/tools/crossword.js +3 -2
- package/tools/discover.js +94 -356
- package/tools/dm.js +27 -86
- package/tools/doctor.js +12 -41
- package/tools/drawing.js +34 -20
- package/tools/echo.js +11 -11
- package/tools/feed.js +30 -58
- package/tools/follow.js +64 -187
- package/tools/{_deprecated/forget.js → forget.js} +4 -7
- package/tools/game.js +144 -48
- package/tools/handoff.js +6 -8
- package/tools/help.js +3 -3
- package/tools/idea.js +15 -27
- package/tools/inbox.js +121 -293
- package/tools/init.js +54 -151
- package/tools/invite.js +8 -21
- package/tools/migrate.js +27 -24
- package/tools/multiplayer-game.js +50 -40
- package/tools/{_deprecated/mute.js → mute.js} +4 -3
- package/tools/notifications.js +58 -48
- package/tools/observe.js +12 -15
- package/tools/onboarding.js +8 -11
- package/tools/open.js +13 -144
- package/tools/party-game.js +23 -12
- package/tools/patterns.js +2 -1
- package/tools/ping.js +5 -7
- package/tools/react.js +28 -30
- package/tools/{_deprecated/recall.js → recall.js} +5 -10
- package/tools/release.js +4 -2
- package/tools/{_deprecated/remember.js → remember.js} +4 -6
- package/tools/report.js +2 -2
- package/tools/request.js +6 -26
- package/tools/reserve.js +1 -1
- package/tools/session-fork.js +97 -0
- package/tools/session-save.js +109 -0
- package/tools/settings.js +30 -99
- package/tools/ship.js +74 -56
- package/tools/{_deprecated/skills-exchange.js → skills-exchange.js} +38 -39
- package/tools/social-inbox.js +22 -28
- package/tools/social-post.js +24 -27
- package/tools/solo-game.js +54 -46
- package/tools/start.js +14 -148
- package/tools/status.js +21 -68
- package/tools/submit.js +4 -2
- package/tools/suggest-tags.js +36 -33
- package/tools/summarize.js +19 -16
- package/tools/tag-suggestions.js +72 -73
- package/tools/test.js +1 -1
- package/tools/{_deprecated/tictactoe.js → tictactoe.js} +26 -26
- package/tools/token.js +4 -4
- package/tools/update.js +1 -2
- package/tools/watch.js +132 -112
- package/tools/who.js +20 -40
- package/tools/{_deprecated/wordassociation.js → wordassociation.js} +23 -20
- package/tools/workshop-buddy.js +52 -53
- package/tools/x-mentions.js +0 -1
- package/tools/x-reply.js +0 -1
- package/twitter.js +14 -20
- package/version.json +8 -10
- package/webhook-runner.js +132 -0
- package/auth-store.js +0 -148
- package/bridges/bridge-monitor.js +0 -388
- package/bridges/discord-bot.js +0 -431
- package/bridges/farcaster.js +0 -299
- package/bridges/telegram.js +0 -261
- package/bridges/webhook-health.js +0 -420
- package/bridges/webhook-server.js +0 -437
- package/bridges/whatsapp.js +0 -441
- package/bridges/x-webhook.js +0 -423
- package/games/arcade.js +0 -406
- package/games/chess.js +0 -451
- package/games/colorguess.js +0 -343
- package/games/crossword-words.js +0 -171
- package/games/crossword.js +0 -461
- package/games/drawing.js +0 -347
- package/games/gameroulette.js +0 -300
- package/games/gamerouter.js +0 -336
- package/games/gamestatus.js +0 -337
- package/games/guessnumber.js +0 -209
- package/games/hangman.js +0 -279
- package/games/memory.js +0 -338
- package/games/multiplayer-tictactoe.js +0 -389
- package/games/pixelart.js +0 -399
- package/games/quickduel.js +0 -354
- package/games/riddle.js +0 -371
- package/games/rockpaperscissors.js +0 -291
- package/games/snake.js +0 -406
- package/games/storybuilder.js +0 -343
- package/games/tictactoe.js +0 -345
- package/games/twentyquestions.js +0 -286
- package/games/twotruths.js +0 -207
- package/games/werewolf.js +0 -508
- package/games/wordassociation.js +0 -247
- package/games/wordchain.js +0 -135
- package/intelligence/interests.js +0 -369
- package/setup.js +0 -480
- package/smart-inbox.js +0 -276
- package/tools/_deprecated/auto-suggest-connections.js +0 -304
- package/tools/_deprecated/bootstrap-skills.js +0 -231
- package/tools/_deprecated/bridge-dashboard.js +0 -342
- package/tools/_deprecated/bridge-health.js +0 -400
- package/tools/_deprecated/bridge-live.js +0 -384
- package/tools/_deprecated/bridges.js +0 -383
- package/tools/_deprecated/colorguess.js +0 -281
- package/tools/_deprecated/discover-insights.js +0 -379
- package/tools/_deprecated/discover-momentum.js +0 -256
- package/tools/_deprecated/discovery-analytics.js +0 -345
- package/tools/_deprecated/discovery-auto-suggest.js +0 -275
- package/tools/_deprecated/discovery-bootstrap.js +0 -267
- package/tools/_deprecated/discovery-daily.js +0 -375
- package/tools/_deprecated/discovery-dashboard.js +0 -385
- package/tools/_deprecated/discovery-digest.js +0 -314
- package/tools/_deprecated/discovery-hub.js +0 -357
- package/tools/_deprecated/discovery-insights.js +0 -384
- package/tools/_deprecated/discovery-momentum.js +0 -281
- package/tools/_deprecated/discovery-monitor.js +0 -319
- package/tools/_deprecated/discovery-proactive.js +0 -300
- package/tools/_deprecated/draw.js +0 -317
- package/tools/_deprecated/farcaster.js +0 -307
- package/tools/_deprecated/games-catalog.js +0 -376
- package/tools/_deprecated/games.js +0 -313
- package/tools/_deprecated/guessnumber.js +0 -194
- package/tools/_deprecated/hangman.js +0 -129
- package/tools/_deprecated/multiplayer-tictactoe.js +0 -303
- package/tools/_deprecated/riddle.js +0 -240
- package/tools/_deprecated/run-bootstrap.js +0 -69
- package/tools/_deprecated/skills-analytics.js +0 -349
- package/tools/_deprecated/skills-bootstrap.js +0 -301
- package/tools/_deprecated/skills-dashboard.js +0 -268
- package/tools/_deprecated/skills.js +0 -380
- package/tools/_deprecated/smart-intro.js +0 -353
- package/tools/_deprecated/storybuilder.js +0 -331
- package/tools/_deprecated/telegram-bot.js +0 -183
- package/tools/_deprecated/telegram-setup.js +0 -214
- package/tools/_deprecated/twentyquestions.js +0 -143
- package/tools/_shared.js +0 -234
- package/tools/_work-context.js +0 -338
- package/tools/_work-context.manual-test.js +0 -199
- package/tools/_work-context.test.js +0 -260
- package/tools/activity.js +0 -220
- package/tools/agent-treasury.js +0 -288
- package/tools/analytics.js +0 -191
- package/tools/approve.js +0 -197
- package/tools/arcade.js +0 -173
- package/tools/artifacts-price.js +0 -107
- package/tools/ask-expert.js +0 -160
- package/tools/available.js +0 -120
- package/tools/become-expert.js +0 -150
- package/tools/broadcast.js +0 -325
- package/tools/chat.js +0 -202
- package/tools/collaborative-drawing.js +0 -286
- package/tools/connection-status.js +0 -178
- package/tools/earnings.js +0 -126
- package/tools/friends.js +0 -207
- package/tools/genesis.js +0 -233
- package/tools/gig-browse.js +0 -206
- package/tools/gig-complete.js +0 -144
- package/tools/health.js +0 -87
- package/tools/leaderboard.js +0 -117
- package/tools/lib/git-apply.js +0 -206
- package/tools/lib/git-bundle.js +0 -407
- package/tools/mint.js +0 -377
- package/tools/plan.js +0 -225
- package/tools/profile.js +0 -219
- package/tools/proof-of-work.js +0 -144
- package/tools/pulse.js +0 -218
- package/tools/reply.js +0 -166
- package/tools/reputation.js +0 -175
- package/tools/schedule.js +0 -367
- package/tools/search-messages.js +0 -123
- package/tools/session.js +0 -467
- package/tools/session_price.js +0 -128
- package/tools/smart-check.js +0 -201
- package/tools/social-processor.js +0 -445
- package/tools/streak.js +0 -147
- package/tools/stuck.js +0 -297
- package/tools/subscribe.js +0 -148
- package/tools/subscriptions.js +0 -134
- package/tools/tip.js +0 -193
- package/tools/wallet.js +0 -269
- package/tools/webhook-test.js +0 -388
- package/tools/withdraw.js +0 -145
- package/tools/work-summary.js +0 -96
- package/tools/workshop.js +0 -327
- /package/tools/{l2-bridge.js → _experimental/l2-bridge.js} +0 -0
- /package/tools/{l2.js → _experimental/l2.js} +0 -0
- /package/tools/{_deprecated/away.js → away.js} +0 -0
package/setup.js
DELETED
|
@@ -1,480 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* vibe setup — One-click installation for /vibe MCP server
|
|
5
|
-
*
|
|
6
|
-
* Usage: npx slashvibe-mcp setup
|
|
7
|
-
*
|
|
8
|
-
* What it does:
|
|
9
|
-
* 1. Detects Claude Code config location (~/.claude.json or ~/claude_desktop_config.json)
|
|
10
|
-
* 2. Adds /vibe MCP server to the config
|
|
11
|
-
* 3. Tests the connection
|
|
12
|
-
* 4. Opens browser for GitHub auth
|
|
13
|
-
*
|
|
14
|
-
* Result: User is fully set up in ~30 seconds
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
const fs = require('fs');
|
|
18
|
-
const path = require('path');
|
|
19
|
-
const os = require('os');
|
|
20
|
-
const { exec, execSync } = require('child_process');
|
|
21
|
-
const http = require('http');
|
|
22
|
-
|
|
23
|
-
// ANSI colors for terminal output
|
|
24
|
-
const colors = {
|
|
25
|
-
reset: '\x1b[0m',
|
|
26
|
-
green: '\x1b[32m',
|
|
27
|
-
cyan: '\x1b[36m',
|
|
28
|
-
yellow: '\x1b[33m',
|
|
29
|
-
red: '\x1b[31m',
|
|
30
|
-
bold: '\x1b[1m',
|
|
31
|
-
dim: '\x1b[2m'
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
const CALLBACK_PORT = 9876;
|
|
35
|
-
const API_BASE = 'https://www.slashvibe.dev';
|
|
36
|
-
const LOGIN_URL = 'https://www.slashvibe.dev/login';
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Print styled banner
|
|
40
|
-
*/
|
|
41
|
-
function printBanner() {
|
|
42
|
-
console.log(`
|
|
43
|
-
${colors.green} █░█ █ █▄▄ █▀▀${colors.reset}
|
|
44
|
-
${colors.green} ▀▄▀ █ █▄█ ██▄${colors.reset} ${colors.dim}ship together${colors.reset}
|
|
45
|
-
──────────────────────────────────────────────────
|
|
46
|
-
`);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Print step with status
|
|
51
|
-
*/
|
|
52
|
-
function printStep(num, text, status = 'pending') {
|
|
53
|
-
const statusIcon = {
|
|
54
|
-
pending: colors.dim + '○' + colors.reset,
|
|
55
|
-
running: colors.yellow + '◐' + colors.reset,
|
|
56
|
-
done: colors.green + '●' + colors.reset,
|
|
57
|
-
error: colors.red + '✗' + colors.reset
|
|
58
|
-
}[status];
|
|
59
|
-
|
|
60
|
-
console.log(` ${statusIcon} ${colors.bold}Step ${num}:${colors.reset} ${text}`);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Find Claude Code config file
|
|
65
|
-
*/
|
|
66
|
-
function findClaudeConfig() {
|
|
67
|
-
const homeDir = os.homedir();
|
|
68
|
-
|
|
69
|
-
// Possible config locations
|
|
70
|
-
const configPaths = [
|
|
71
|
-
path.join(homeDir, '.claude.json'),
|
|
72
|
-
path.join(homeDir, 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json'),
|
|
73
|
-
path.join(homeDir, '.config', 'claude', 'config.json'),
|
|
74
|
-
path.join(homeDir, 'AppData', 'Roaming', 'Claude', 'claude_desktop_config.json')
|
|
75
|
-
];
|
|
76
|
-
|
|
77
|
-
for (const configPath of configPaths) {
|
|
78
|
-
if (fs.existsSync(configPath)) {
|
|
79
|
-
return configPath;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Default to ~/.claude.json (will create if doesn't exist)
|
|
84
|
-
return path.join(homeDir, '.claude.json');
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Load existing config or create default
|
|
89
|
-
*/
|
|
90
|
-
function loadConfig(configPath) {
|
|
91
|
-
try {
|
|
92
|
-
if (fs.existsSync(configPath)) {
|
|
93
|
-
const content = fs.readFileSync(configPath, 'utf8');
|
|
94
|
-
return JSON.parse(content);
|
|
95
|
-
}
|
|
96
|
-
} catch (e) {
|
|
97
|
-
console.log(`${colors.yellow} Warning: Could not parse existing config, creating new one${colors.reset}`);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// Default config structure
|
|
101
|
-
return {};
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Add /vibe MCP server to config
|
|
106
|
-
*/
|
|
107
|
-
function addVibeToConfig(config) {
|
|
108
|
-
// Initialize mcpServers if not present
|
|
109
|
-
if (!config.mcpServers) {
|
|
110
|
-
config.mcpServers = {};
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// Check if already configured
|
|
114
|
-
if (config.mcpServers.vibe) {
|
|
115
|
-
return { added: false, alreadyExists: true };
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// Add vibe MCP server
|
|
119
|
-
config.mcpServers.vibe = {
|
|
120
|
-
command: 'npx',
|
|
121
|
-
args: ['slashvibe-mcp'],
|
|
122
|
-
env: {
|
|
123
|
-
VIBE_API_URL: 'https://www.slashvibe.dev'
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
return { added: true, alreadyExists: false };
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Save config to file
|
|
132
|
-
*/
|
|
133
|
-
function saveConfig(configPath, config) {
|
|
134
|
-
const content = JSON.stringify(config, null, 2);
|
|
135
|
-
fs.writeFileSync(configPath, content, 'utf8');
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Test API connection
|
|
140
|
-
*/
|
|
141
|
-
async function testConnection() {
|
|
142
|
-
try {
|
|
143
|
-
const response = await fetch(`${API_BASE}/api/health`);
|
|
144
|
-
const data = await response.json();
|
|
145
|
-
return data.status === 'ok' || data.success;
|
|
146
|
-
} catch (e) {
|
|
147
|
-
return false;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Get online count
|
|
153
|
-
*/
|
|
154
|
-
async function getOnlineCount() {
|
|
155
|
-
try {
|
|
156
|
-
const response = await fetch(`${API_BASE}/api/presence`);
|
|
157
|
-
const data = await response.json();
|
|
158
|
-
return (data.active?.length || 0) + (data.away?.length || 0);
|
|
159
|
-
} catch (e) {
|
|
160
|
-
return 0;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Get online users with details for display
|
|
166
|
-
*/
|
|
167
|
-
async function getOnlineUsers() {
|
|
168
|
-
try {
|
|
169
|
-
const response = await fetch(`${API_BASE}/api/presence`);
|
|
170
|
-
const data = await response.json();
|
|
171
|
-
const active = data.active || [];
|
|
172
|
-
const away = data.away || [];
|
|
173
|
-
|
|
174
|
-
// Format: { users: [{handle, status, one_liner}], total: number }
|
|
175
|
-
const users = [
|
|
176
|
-
...active.slice(0, 5).map(u => ({
|
|
177
|
-
handle: u.username || u.handle,
|
|
178
|
-
status: 'active',
|
|
179
|
-
one_liner: u.one_liner || u.status || ''
|
|
180
|
-
})),
|
|
181
|
-
...away.slice(0, 2).map(u => ({
|
|
182
|
-
handle: u.username || u.handle,
|
|
183
|
-
status: 'away',
|
|
184
|
-
one_liner: u.one_liner || u.status || ''
|
|
185
|
-
}))
|
|
186
|
-
].slice(0, 5);
|
|
187
|
-
|
|
188
|
-
return { users, total: active.length + away.length };
|
|
189
|
-
} catch (e) {
|
|
190
|
-
return { users: [], total: 0 };
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Open URL in browser
|
|
196
|
-
*/
|
|
197
|
-
function openBrowser(url) {
|
|
198
|
-
const platform = process.platform;
|
|
199
|
-
let command;
|
|
200
|
-
|
|
201
|
-
if (platform === 'darwin') {
|
|
202
|
-
command = `open "${url}"`;
|
|
203
|
-
} else if (platform === 'win32') {
|
|
204
|
-
command = `start "" "${url}"`;
|
|
205
|
-
} else {
|
|
206
|
-
command = `xdg-open "${url}"`;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
exec(command, (err) => {
|
|
210
|
-
if (err) {
|
|
211
|
-
console.log(`${colors.yellow} Could not open browser automatically.${colors.reset}`);
|
|
212
|
-
console.log(`${colors.cyan} Please open: ${url}${colors.reset}`);
|
|
213
|
-
}
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Wait for OAuth callback
|
|
219
|
-
*/
|
|
220
|
-
function waitForAuth() {
|
|
221
|
-
return new Promise((resolve, reject) => {
|
|
222
|
-
let resolved = false;
|
|
223
|
-
|
|
224
|
-
const server = http.createServer(async (req, res) => {
|
|
225
|
-
const url = new URL(req.url, `http://localhost:${CALLBACK_PORT}`);
|
|
226
|
-
|
|
227
|
-
if (url.pathname === '/callback') {
|
|
228
|
-
const token = url.searchParams.get('token');
|
|
229
|
-
const handle = url.searchParams.get('handle');
|
|
230
|
-
|
|
231
|
-
if (token && handle) {
|
|
232
|
-
// Send success page
|
|
233
|
-
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
234
|
-
res.end(`<!DOCTYPE html>
|
|
235
|
-
<html>
|
|
236
|
-
<head>
|
|
237
|
-
<title>Welcome to /vibe!</title>
|
|
238
|
-
<style>
|
|
239
|
-
body {
|
|
240
|
-
font-family: 'SF Mono', Monaco, monospace;
|
|
241
|
-
background: #0a0a0a;
|
|
242
|
-
color: #e0e0e0;
|
|
243
|
-
display: flex;
|
|
244
|
-
justify-content: center;
|
|
245
|
-
align-items: center;
|
|
246
|
-
min-height: 100vh;
|
|
247
|
-
margin: 0;
|
|
248
|
-
}
|
|
249
|
-
.container {
|
|
250
|
-
text-align: center;
|
|
251
|
-
padding: 2rem;
|
|
252
|
-
}
|
|
253
|
-
h1 { color: #00FF88; }
|
|
254
|
-
.handle { color: #6B8FFF; }
|
|
255
|
-
.close { color: #888; margin-top: 2rem; }
|
|
256
|
-
</style>
|
|
257
|
-
</head>
|
|
258
|
-
<body>
|
|
259
|
-
<div class="container">
|
|
260
|
-
<h1>✓ Setup Complete!</h1>
|
|
261
|
-
<p>Welcome, <span class="handle">@${handle}</span></p>
|
|
262
|
-
<p>You're now connected to /vibe</p>
|
|
263
|
-
<p class="close">You can close this window</p>
|
|
264
|
-
</div>
|
|
265
|
-
</body>
|
|
266
|
-
</html>`);
|
|
267
|
-
|
|
268
|
-
resolved = true;
|
|
269
|
-
setTimeout(() => server.close(), 500);
|
|
270
|
-
resolve({ success: true, handle, token });
|
|
271
|
-
} else {
|
|
272
|
-
res.writeHead(400);
|
|
273
|
-
res.end('Missing token or handle');
|
|
274
|
-
}
|
|
275
|
-
} else {
|
|
276
|
-
res.writeHead(404);
|
|
277
|
-
res.end('Not found');
|
|
278
|
-
}
|
|
279
|
-
});
|
|
280
|
-
|
|
281
|
-
server.on('error', (err) => {
|
|
282
|
-
if (err.code === 'EADDRINUSE') {
|
|
283
|
-
reject(new Error('Auth server port in use'));
|
|
284
|
-
} else {
|
|
285
|
-
reject(err);
|
|
286
|
-
}
|
|
287
|
-
});
|
|
288
|
-
|
|
289
|
-
server.listen(CALLBACK_PORT, '127.0.0.1');
|
|
290
|
-
|
|
291
|
-
// Timeout after 2 minutes
|
|
292
|
-
setTimeout(() => {
|
|
293
|
-
if (!resolved) {
|
|
294
|
-
server.close();
|
|
295
|
-
reject(new Error('Auth timed out'));
|
|
296
|
-
}
|
|
297
|
-
}, 120000);
|
|
298
|
-
});
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* Save auth config
|
|
303
|
-
*/
|
|
304
|
-
function saveAuthConfig(handle, token) {
|
|
305
|
-
const homeDir = os.homedir();
|
|
306
|
-
const vibeDir = path.join(homeDir, '.vibe');
|
|
307
|
-
|
|
308
|
-
// Create .vibe directory if not exists
|
|
309
|
-
if (!fs.existsSync(vibeDir)) {
|
|
310
|
-
fs.mkdirSync(vibeDir, { recursive: true });
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
// Save config
|
|
314
|
-
const configPath = path.join(vibeDir, 'config.json');
|
|
315
|
-
const config = {
|
|
316
|
-
handle,
|
|
317
|
-
authToken: token,
|
|
318
|
-
authMethod: 'browser',
|
|
319
|
-
authenticatedAt: new Date().toISOString()
|
|
320
|
-
};
|
|
321
|
-
|
|
322
|
-
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
/**
|
|
326
|
-
* Main setup function
|
|
327
|
-
*/
|
|
328
|
-
async function setup() {
|
|
329
|
-
printBanner();
|
|
330
|
-
console.log(`${colors.bold} One-Click Setup${colors.reset}`);
|
|
331
|
-
console.log('');
|
|
332
|
-
|
|
333
|
-
// Step 1: Find Claude config
|
|
334
|
-
printStep(1, 'Finding Claude Code config...', 'running');
|
|
335
|
-
const configPath = findClaudeConfig();
|
|
336
|
-
const configExists = fs.existsSync(configPath);
|
|
337
|
-
console.log(`${colors.dim} → ${configPath}${configExists ? '' : ' (will create)'}${colors.reset}`);
|
|
338
|
-
printStep(1, 'Finding Claude Code config...', 'done');
|
|
339
|
-
|
|
340
|
-
// Step 2: Add MCP config
|
|
341
|
-
printStep(2, 'Adding /vibe MCP server...', 'running');
|
|
342
|
-
const config = loadConfig(configPath);
|
|
343
|
-
const { added, alreadyExists } = addVibeToConfig(config);
|
|
344
|
-
|
|
345
|
-
if (alreadyExists) {
|
|
346
|
-
console.log(`${colors.dim} → Already configured!${colors.reset}`);
|
|
347
|
-
} else {
|
|
348
|
-
saveConfig(configPath, config);
|
|
349
|
-
console.log(`${colors.dim} → Config updated${colors.reset}`);
|
|
350
|
-
}
|
|
351
|
-
printStep(2, 'Adding /vibe MCP server...', 'done');
|
|
352
|
-
|
|
353
|
-
// Step 3: Test connection
|
|
354
|
-
printStep(3, 'Testing connection...', 'running');
|
|
355
|
-
const connected = await testConnection();
|
|
356
|
-
if (!connected) {
|
|
357
|
-
printStep(3, 'Testing connection...', 'error');
|
|
358
|
-
console.log(`${colors.red} → Could not reach slashvibe.dev${colors.reset}`);
|
|
359
|
-
console.log('');
|
|
360
|
-
console.log(`${colors.bold} Troubleshooting:${colors.reset}`);
|
|
361
|
-
console.log(`${colors.dim} 1. Check your internet connection${colors.reset}`);
|
|
362
|
-
console.log(`${colors.dim} 2. Try: ${colors.cyan}curl -s https://www.slashvibe.dev/api/health${colors.reset}`);
|
|
363
|
-
console.log(`${colors.dim} 3. If that works, try setup again${colors.reset}`);
|
|
364
|
-
console.log('');
|
|
365
|
-
console.log(`${colors.dim} Status page: ${colors.cyan}slashvibe.dev/status${colors.reset}`);
|
|
366
|
-
process.exit(1);
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
const onlineCount = await getOnlineCount();
|
|
370
|
-
console.log(`${colors.dim} → Connected! ${onlineCount} builders online${colors.reset}`);
|
|
371
|
-
printStep(3, 'Testing connection...', 'done');
|
|
372
|
-
|
|
373
|
-
// Step 4: Authenticate
|
|
374
|
-
printStep(4, 'Opening browser for GitHub auth...', 'running');
|
|
375
|
-
|
|
376
|
-
const callbackUrl = `http://localhost:${CALLBACK_PORT}/callback`;
|
|
377
|
-
const loginUrl = `${LOGIN_URL}?redirect=${encodeURIComponent(callbackUrl)}&setup=true`;
|
|
378
|
-
|
|
379
|
-
openBrowser(loginUrl);
|
|
380
|
-
console.log(`${colors.dim} → Waiting for authentication...${colors.reset}`);
|
|
381
|
-
|
|
382
|
-
try {
|
|
383
|
-
const authResult = await waitForAuth();
|
|
384
|
-
|
|
385
|
-
// Save auth config
|
|
386
|
-
saveAuthConfig(authResult.handle, authResult.token);
|
|
387
|
-
|
|
388
|
-
printStep(4, 'Opening browser for GitHub auth...', 'done');
|
|
389
|
-
console.log(`${colors.dim} → Authenticated as @${authResult.handle}${colors.reset}`);
|
|
390
|
-
|
|
391
|
-
// Success! Show who's online immediately
|
|
392
|
-
const presence = await getOnlineUsers();
|
|
393
|
-
|
|
394
|
-
console.log('');
|
|
395
|
-
console.log(`${colors.green} ✓ Setup complete!${colors.reset}`);
|
|
396
|
-
console.log('');
|
|
397
|
-
|
|
398
|
-
// Show who's vibing right now
|
|
399
|
-
if (presence.users.length > 0) {
|
|
400
|
-
console.log(`${colors.bold} 🟢 ${presence.total} builders vibing now:${colors.reset}`);
|
|
401
|
-
for (const user of presence.users) {
|
|
402
|
-
const statusIcon = user.status === 'active' ? colors.green + '●' : colors.yellow + '○';
|
|
403
|
-
const liner = user.one_liner ? ` — ${user.one_liner.slice(0, 40)}` : '';
|
|
404
|
-
console.log(` ${statusIcon}${colors.reset} @${user.handle}${colors.dim}${liner}${colors.reset}`);
|
|
405
|
-
}
|
|
406
|
-
if (presence.total > 5) {
|
|
407
|
-
console.log(`${colors.dim} ... and ${presence.total - 5} more${colors.reset}`);
|
|
408
|
-
}
|
|
409
|
-
console.log('');
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
console.log(`${colors.bold} Quick start:${colors.reset}`);
|
|
413
|
-
console.log(`${colors.dim} 1. Restart Claude Code${colors.reset}`);
|
|
414
|
-
console.log(`${colors.dim} 2. Type "who's vibing?" to see everyone${colors.reset}`);
|
|
415
|
-
console.log(`${colors.dim} 3. Type "dm @seth hey!" to send a message${colors.reset}`);
|
|
416
|
-
console.log('');
|
|
417
|
-
console.log(`${colors.cyan} 🚀 Welcome to /vibe, @${authResult.handle}!${colors.reset}`);
|
|
418
|
-
console.log('');
|
|
419
|
-
|
|
420
|
-
// Track setup completion
|
|
421
|
-
try {
|
|
422
|
-
await fetch(`${API_BASE}/api/analytics/track`, {
|
|
423
|
-
method: 'POST',
|
|
424
|
-
headers: { 'Content-Type': 'application/json' },
|
|
425
|
-
body: JSON.stringify({
|
|
426
|
-
event: 'setup_complete',
|
|
427
|
-
handle: authResult.handle,
|
|
428
|
-
source: 'one_click_install'
|
|
429
|
-
})
|
|
430
|
-
});
|
|
431
|
-
} catch (e) {}
|
|
432
|
-
|
|
433
|
-
} catch (err) {
|
|
434
|
-
printStep(4, 'Opening browser for GitHub auth...', 'error');
|
|
435
|
-
|
|
436
|
-
// Specific error recovery messages
|
|
437
|
-
if (err.message.includes('timed out')) {
|
|
438
|
-
console.log(`${colors.red} → Authentication timed out (2 min limit)${colors.reset}`);
|
|
439
|
-
console.log('');
|
|
440
|
-
console.log(`${colors.yellow} What happened:${colors.reset}`);
|
|
441
|
-
console.log(`${colors.dim} The browser auth wasn't completed in time.${colors.reset}`);
|
|
442
|
-
console.log('');
|
|
443
|
-
console.log(`${colors.bold} Try again:${colors.reset}`);
|
|
444
|
-
console.log(`${colors.cyan} npx slashvibe-mcp setup${colors.reset}`);
|
|
445
|
-
} else if (err.message.includes('port in use')) {
|
|
446
|
-
console.log(`${colors.red} → Auth callback port busy${colors.reset}`);
|
|
447
|
-
console.log('');
|
|
448
|
-
console.log(`${colors.yellow} What happened:${colors.reset}`);
|
|
449
|
-
console.log(`${colors.dim} Another setup or auth process is running.${colors.reset}`);
|
|
450
|
-
console.log('');
|
|
451
|
-
console.log(`${colors.bold} Fix it:${colors.reset}`);
|
|
452
|
-
console.log(`${colors.dim} 1. Wait a minute for it to finish, or${colors.reset}`);
|
|
453
|
-
console.log(`${colors.dim} 2. Kill the process: ${colors.cyan}lsof -ti:9876 | xargs kill${colors.reset}`);
|
|
454
|
-
console.log(`${colors.dim} 3. Try again: ${colors.cyan}npx slashvibe-mcp setup${colors.reset}`);
|
|
455
|
-
} else {
|
|
456
|
-
console.log(`${colors.red} → ${err.message}${colors.reset}`);
|
|
457
|
-
console.log('');
|
|
458
|
-
console.log(`${colors.bold} Try these steps:${colors.reset}`);
|
|
459
|
-
console.log(`${colors.dim} 1. Check internet connection${colors.reset}`);
|
|
460
|
-
console.log(`${colors.dim} 2. Try again: ${colors.cyan}npx slashvibe-mcp setup${colors.reset}`);
|
|
461
|
-
console.log(`${colors.dim} 3. Or in Claude Code, type: ${colors.cyan}add the vibe mcp server${colors.reset}`);
|
|
462
|
-
}
|
|
463
|
-
console.log('');
|
|
464
|
-
console.log(`${colors.dim} Need help? slashvibe.dev/help${colors.reset}`);
|
|
465
|
-
process.exit(1);
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
// Handle command line
|
|
470
|
-
const args = process.argv.slice(2);
|
|
471
|
-
|
|
472
|
-
if (args[0] === 'setup' || args.length === 0) {
|
|
473
|
-
setup().catch(err => {
|
|
474
|
-
console.error(`${colors.red}Setup failed: ${err.message}${colors.reset}`);
|
|
475
|
-
process.exit(1);
|
|
476
|
-
});
|
|
477
|
-
} else {
|
|
478
|
-
// Pass through to main MCP server
|
|
479
|
-
require('./index.js');
|
|
480
|
-
}
|