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.
Files changed (235) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +280 -47
  3. package/auto-update.js +10 -15
  4. package/config.js +36 -31
  5. package/crypto.js +1 -6
  6. package/debug.js +12 -0
  7. package/discord.js +19 -19
  8. package/eslint.config.js +54 -0
  9. package/index.js +217 -207
  10. package/intelligence/index.js +2 -9
  11. package/intelligence/infer.js +10 -16
  12. package/intelligence/patterns.js +23 -18
  13. package/intelligence/proactive.js +16 -15
  14. package/intelligence/serendipity.js +57 -20
  15. package/memory.js +13 -8
  16. package/migrate-v2.js +72 -0
  17. package/notification-emitter.js +2 -2
  18. package/notify.js +39 -14
  19. package/package.json +28 -29
  20. package/post-install.js +141 -0
  21. package/presence.js +2 -2
  22. package/prompts.js +5 -9
  23. package/protocol/index.js +123 -87
  24. package/protocol/telegram-commands.js +36 -37
  25. package/store/api.js +358 -529
  26. package/store/local.js +9 -10
  27. package/store/profiles.js +48 -192
  28. package/store/reservations.js +2 -9
  29. package/store/skills.js +69 -71
  30. package/store/sqlite.js +355 -0
  31. package/test-skills-bootstrap.js +20 -0
  32. package/test-v2-integration.js +385 -0
  33. package/tools/_actions.js +48 -387
  34. package/tools/_connection-queue.js +45 -56
  35. package/tools/_discovery-enhanced.js +52 -57
  36. package/tools/_discovery.js +87 -185
  37. package/tools/{l2-status.js → _experimental/l2-status.js} +68 -70
  38. package/tools/{shipback.js → _experimental/shipback.js} +4 -3
  39. package/tools/_proactive-discovery.js +60 -73
  40. package/tools/_shared/index.js +41 -64
  41. package/tools/admin-inbox.js +10 -15
  42. package/tools/agents.js +1 -1
  43. package/tools/artifact-create.js +13 -23
  44. package/tools/artifact-view.js +4 -4
  45. package/tools/{_deprecated/back.js → back.js} +1 -1
  46. package/tools/bye.js +3 -5
  47. package/tools/consent.js +2 -2
  48. package/tools/context.js +9 -10
  49. package/tools/crossword.js +3 -2
  50. package/tools/discover.js +94 -356
  51. package/tools/dm.js +27 -86
  52. package/tools/doctor.js +12 -41
  53. package/tools/drawing.js +34 -20
  54. package/tools/echo.js +11 -11
  55. package/tools/feed.js +30 -58
  56. package/tools/follow.js +64 -187
  57. package/tools/{_deprecated/forget.js → forget.js} +4 -7
  58. package/tools/game.js +144 -48
  59. package/tools/handoff.js +6 -8
  60. package/tools/help.js +3 -3
  61. package/tools/idea.js +15 -27
  62. package/tools/inbox.js +121 -293
  63. package/tools/init.js +54 -151
  64. package/tools/invite.js +8 -21
  65. package/tools/migrate.js +27 -24
  66. package/tools/multiplayer-game.js +50 -40
  67. package/tools/{_deprecated/mute.js → mute.js} +4 -3
  68. package/tools/notifications.js +58 -48
  69. package/tools/observe.js +12 -15
  70. package/tools/onboarding.js +8 -11
  71. package/tools/open.js +13 -144
  72. package/tools/party-game.js +23 -12
  73. package/tools/patterns.js +2 -1
  74. package/tools/ping.js +5 -7
  75. package/tools/react.js +28 -30
  76. package/tools/{_deprecated/recall.js → recall.js} +5 -10
  77. package/tools/release.js +4 -2
  78. package/tools/{_deprecated/remember.js → remember.js} +4 -6
  79. package/tools/report.js +2 -2
  80. package/tools/request.js +6 -26
  81. package/tools/reserve.js +1 -1
  82. package/tools/session-fork.js +97 -0
  83. package/tools/session-save.js +109 -0
  84. package/tools/settings.js +30 -99
  85. package/tools/ship.js +74 -56
  86. package/tools/{_deprecated/skills-exchange.js → skills-exchange.js} +38 -39
  87. package/tools/social-inbox.js +22 -28
  88. package/tools/social-post.js +24 -27
  89. package/tools/solo-game.js +54 -46
  90. package/tools/start.js +14 -148
  91. package/tools/status.js +21 -68
  92. package/tools/submit.js +4 -2
  93. package/tools/suggest-tags.js +36 -33
  94. package/tools/summarize.js +19 -16
  95. package/tools/tag-suggestions.js +72 -73
  96. package/tools/test.js +1 -1
  97. package/tools/{_deprecated/tictactoe.js → tictactoe.js} +26 -26
  98. package/tools/token.js +4 -4
  99. package/tools/update.js +1 -2
  100. package/tools/watch.js +132 -112
  101. package/tools/who.js +20 -40
  102. package/tools/{_deprecated/wordassociation.js → wordassociation.js} +23 -20
  103. package/tools/workshop-buddy.js +52 -53
  104. package/tools/x-mentions.js +0 -1
  105. package/tools/x-reply.js +0 -1
  106. package/twitter.js +14 -20
  107. package/version.json +8 -10
  108. package/webhook-runner.js +132 -0
  109. package/auth-store.js +0 -148
  110. package/bridges/bridge-monitor.js +0 -388
  111. package/bridges/discord-bot.js +0 -431
  112. package/bridges/farcaster.js +0 -299
  113. package/bridges/telegram.js +0 -261
  114. package/bridges/webhook-health.js +0 -420
  115. package/bridges/webhook-server.js +0 -437
  116. package/bridges/whatsapp.js +0 -441
  117. package/bridges/x-webhook.js +0 -423
  118. package/games/arcade.js +0 -406
  119. package/games/chess.js +0 -451
  120. package/games/colorguess.js +0 -343
  121. package/games/crossword-words.js +0 -171
  122. package/games/crossword.js +0 -461
  123. package/games/drawing.js +0 -347
  124. package/games/gameroulette.js +0 -300
  125. package/games/gamerouter.js +0 -336
  126. package/games/gamestatus.js +0 -337
  127. package/games/guessnumber.js +0 -209
  128. package/games/hangman.js +0 -279
  129. package/games/memory.js +0 -338
  130. package/games/multiplayer-tictactoe.js +0 -389
  131. package/games/pixelart.js +0 -399
  132. package/games/quickduel.js +0 -354
  133. package/games/riddle.js +0 -371
  134. package/games/rockpaperscissors.js +0 -291
  135. package/games/snake.js +0 -406
  136. package/games/storybuilder.js +0 -343
  137. package/games/tictactoe.js +0 -345
  138. package/games/twentyquestions.js +0 -286
  139. package/games/twotruths.js +0 -207
  140. package/games/werewolf.js +0 -508
  141. package/games/wordassociation.js +0 -247
  142. package/games/wordchain.js +0 -135
  143. package/intelligence/interests.js +0 -369
  144. package/setup.js +0 -480
  145. package/smart-inbox.js +0 -276
  146. package/tools/_deprecated/auto-suggest-connections.js +0 -304
  147. package/tools/_deprecated/bootstrap-skills.js +0 -231
  148. package/tools/_deprecated/bridge-dashboard.js +0 -342
  149. package/tools/_deprecated/bridge-health.js +0 -400
  150. package/tools/_deprecated/bridge-live.js +0 -384
  151. package/tools/_deprecated/bridges.js +0 -383
  152. package/tools/_deprecated/colorguess.js +0 -281
  153. package/tools/_deprecated/discover-insights.js +0 -379
  154. package/tools/_deprecated/discover-momentum.js +0 -256
  155. package/tools/_deprecated/discovery-analytics.js +0 -345
  156. package/tools/_deprecated/discovery-auto-suggest.js +0 -275
  157. package/tools/_deprecated/discovery-bootstrap.js +0 -267
  158. package/tools/_deprecated/discovery-daily.js +0 -375
  159. package/tools/_deprecated/discovery-dashboard.js +0 -385
  160. package/tools/_deprecated/discovery-digest.js +0 -314
  161. package/tools/_deprecated/discovery-hub.js +0 -357
  162. package/tools/_deprecated/discovery-insights.js +0 -384
  163. package/tools/_deprecated/discovery-momentum.js +0 -281
  164. package/tools/_deprecated/discovery-monitor.js +0 -319
  165. package/tools/_deprecated/discovery-proactive.js +0 -300
  166. package/tools/_deprecated/draw.js +0 -317
  167. package/tools/_deprecated/farcaster.js +0 -307
  168. package/tools/_deprecated/games-catalog.js +0 -376
  169. package/tools/_deprecated/games.js +0 -313
  170. package/tools/_deprecated/guessnumber.js +0 -194
  171. package/tools/_deprecated/hangman.js +0 -129
  172. package/tools/_deprecated/multiplayer-tictactoe.js +0 -303
  173. package/tools/_deprecated/riddle.js +0 -240
  174. package/tools/_deprecated/run-bootstrap.js +0 -69
  175. package/tools/_deprecated/skills-analytics.js +0 -349
  176. package/tools/_deprecated/skills-bootstrap.js +0 -301
  177. package/tools/_deprecated/skills-dashboard.js +0 -268
  178. package/tools/_deprecated/skills.js +0 -380
  179. package/tools/_deprecated/smart-intro.js +0 -353
  180. package/tools/_deprecated/storybuilder.js +0 -331
  181. package/tools/_deprecated/telegram-bot.js +0 -183
  182. package/tools/_deprecated/telegram-setup.js +0 -214
  183. package/tools/_deprecated/twentyquestions.js +0 -143
  184. package/tools/_shared.js +0 -234
  185. package/tools/_work-context.js +0 -338
  186. package/tools/_work-context.manual-test.js +0 -199
  187. package/tools/_work-context.test.js +0 -260
  188. package/tools/activity.js +0 -220
  189. package/tools/agent-treasury.js +0 -288
  190. package/tools/analytics.js +0 -191
  191. package/tools/approve.js +0 -197
  192. package/tools/arcade.js +0 -173
  193. package/tools/artifacts-price.js +0 -107
  194. package/tools/ask-expert.js +0 -160
  195. package/tools/available.js +0 -120
  196. package/tools/become-expert.js +0 -150
  197. package/tools/broadcast.js +0 -325
  198. package/tools/chat.js +0 -202
  199. package/tools/collaborative-drawing.js +0 -286
  200. package/tools/connection-status.js +0 -178
  201. package/tools/earnings.js +0 -126
  202. package/tools/friends.js +0 -207
  203. package/tools/genesis.js +0 -233
  204. package/tools/gig-browse.js +0 -206
  205. package/tools/gig-complete.js +0 -144
  206. package/tools/health.js +0 -87
  207. package/tools/leaderboard.js +0 -117
  208. package/tools/lib/git-apply.js +0 -206
  209. package/tools/lib/git-bundle.js +0 -407
  210. package/tools/mint.js +0 -377
  211. package/tools/plan.js +0 -225
  212. package/tools/profile.js +0 -219
  213. package/tools/proof-of-work.js +0 -144
  214. package/tools/pulse.js +0 -218
  215. package/tools/reply.js +0 -166
  216. package/tools/reputation.js +0 -175
  217. package/tools/schedule.js +0 -367
  218. package/tools/search-messages.js +0 -123
  219. package/tools/session.js +0 -467
  220. package/tools/session_price.js +0 -128
  221. package/tools/smart-check.js +0 -201
  222. package/tools/social-processor.js +0 -445
  223. package/tools/streak.js +0 -147
  224. package/tools/stuck.js +0 -297
  225. package/tools/subscribe.js +0 -148
  226. package/tools/subscriptions.js +0 -134
  227. package/tools/tip.js +0 -193
  228. package/tools/wallet.js +0 -269
  229. package/tools/webhook-test.js +0 -388
  230. package/tools/withdraw.js +0 -145
  231. package/tools/work-summary.js +0 -96
  232. package/tools/workshop.js +0 -327
  233. /package/tools/{l2-bridge.js → _experimental/l2-bridge.js} +0 -0
  234. /package/tools/{l2.js → _experimental/l2.js} +0 -0
  235. /package/tools/{_deprecated/away.js → away.js} +0 -0
package/tools/init.js CHANGED
@@ -16,10 +16,10 @@ const path = require('path');
16
16
  const config = require('../config');
17
17
  const store = require('../store');
18
18
  const discord = require('../discord');
19
- const authStore = require('../auth-store');
19
+ const { debug } = require('./_shared');
20
20
 
21
21
  const CALLBACK_PORT = 9876;
22
- const API_BASE = 'https://www.slashvibe.dev';
22
+ const API_BASE = config.getApiUrl();
23
23
 
24
24
  /**
25
25
  * Fetch online count from presence API
@@ -104,20 +104,20 @@ function detectTechStack() {
104
104
 
105
105
  // Map common packages to tech names
106
106
  const techMap = {
107
- 'react': 'React',
108
- 'next': 'Next.js',
109
- 'vue': 'Vue',
110
- 'svelte': 'Svelte',
111
- 'express': 'Express',
112
- 'fastify': 'Fastify',
113
- 'typescript': 'TypeScript',
107
+ react: 'React',
108
+ next: 'Next.js',
109
+ vue: 'Vue',
110
+ svelte: 'Svelte',
111
+ express: 'Express',
112
+ fastify: 'Fastify',
113
+ typescript: 'TypeScript',
114
114
  '@anthropic-ai/sdk': 'Claude API',
115
- 'openai': 'OpenAI',
116
- 'langchain': 'LangChain',
117
- 'prisma': 'Prisma',
115
+ openai: 'OpenAI',
116
+ langchain: 'LangChain',
117
+ prisma: 'Prisma',
118
118
  '@vercel/kv': 'Vercel KV',
119
- 'tailwindcss': 'Tailwind',
120
- 'electron': 'Electron',
119
+ tailwindcss: 'Tailwind',
120
+ electron: 'Electron',
121
121
  '@tauri-apps/api': 'Tauri'
122
122
  };
123
123
 
@@ -127,7 +127,7 @@ function detectTechStack() {
127
127
  }
128
128
 
129
129
  // Detect by file extensions in cwd
130
- const files = fs.readdirSync(cwd).slice(0, 50); // Limit scan
130
+ const files = fs.readdirSync(cwd).slice(0, 50); // Limit scan
131
131
  for (const f of files) {
132
132
  if (f.endsWith('.ts') || f.endsWith('.tsx')) techStack.add('TypeScript');
133
133
  if (f.endsWith('.py')) techStack.add('Python');
@@ -135,43 +135,23 @@ function detectTechStack() {
135
135
  if (f.endsWith('.go')) techStack.add('Go');
136
136
  if (f.endsWith('.sol')) techStack.add('Solidity');
137
137
  }
138
-
139
138
  } catch (e) {
140
139
  // Non-fatal - continue without tech detection
141
140
  }
142
141
 
143
- return Array.from(techStack).slice(0, 8); // Limit to 8 techs
142
+ return Array.from(techStack).slice(0, 8); // Limit to 8 techs
144
143
  }
145
144
 
146
145
  /**
147
- * Fetch GitHub friends who are on /vibe (non-blocking)
148
- */
149
- async function fetchGitHubFriends(handle) {
150
- try {
151
- const response = await fetch(`${API_BASE}/api/github/contacts?handle=${encodeURIComponent(handle)}`);
152
- if (!response.ok) return null;
153
- const data = await response.json();
154
- if (!data.success) return null;
155
- return {
156
- friendsOnVibe: data.people_you_know?.slice(0, 5) || [],
157
- inviteSuggestions: data.invite_suggestions?.slice(0, 10) || [],
158
- totalContacts: data.stats?.total_contacts || 0
159
- };
160
- } catch (e) {
161
- return null;
162
- }
163
- }
164
-
165
- /**
166
- * Send personalized welcome from @seth
167
- * Returns the welcome message content so we can show it inline
146
+ * Send personalized welcome from @vibe (non-blocking)
168
147
  */
169
148
  async function sendPersonalizedWelcome(handle, oneLiner) {
170
149
  try {
171
150
  const repoName = detectRepoName();
172
151
  const techStack = detectTechStack();
173
152
 
174
- const response = await fetch(`${API_BASE}/api/onboarding/personalized-welcome`, {
153
+ // Fire and forget - don't block init completion
154
+ fetch(`${API_BASE}/api/onboarding/personalized-welcome`, {
175
155
  method: 'POST',
176
156
  headers: { 'Content-Type': 'application/json' },
177
157
  body: JSON.stringify({
@@ -179,29 +159,23 @@ async function sendPersonalizedWelcome(handle, oneLiner) {
179
159
  oneLiner,
180
160
  repoName,
181
161
  techStack,
182
- githubProfile: null
162
+ githubProfile: null // Could be passed from callback if available
183
163
  })
164
+ }).catch(e => {
165
+ debug('init', 'Personalized welcome failed:', e.message);
184
166
  });
185
-
186
- if (!response.ok) {
187
- console.error('[vibe_init] Welcome API error:', response.status);
188
- return null;
189
- }
190
-
191
- const result = await response.json();
192
- return result.success ? result : null;
193
167
  } catch (e) {
194
- console.error('[vibe_init] Personalized welcome failed:', e.message);
195
- return null;
168
+ // Non-fatal - continue without personalized welcome
169
+ debug('init', 'Context detection failed:', e.message);
196
170
  }
197
171
  }
198
172
 
199
173
  const LOGIN_URL = 'https://www.slashvibe.dev/login';
200
- const API_URL = process.env.VIBE_API_URL || 'https://www.slashvibe.dev';
174
+ const API_URL = config.getApiUrl();
201
175
  const AUTH_TIMEOUT_MS = 120000; // 2 minutes
202
176
 
203
177
  /**
204
- * Send welcome message from @seth (founder)
178
+ * Send welcome message from @vibe
205
179
  */
206
180
  async function sendWelcomeMessage(handle, one_liner) {
207
181
  try {
@@ -213,24 +187,25 @@ async function sendWelcomeMessage(handle, one_liner) {
213
187
  const result = await response.json();
214
188
  return result.success;
215
189
  } catch (e) {
216
- console.error('[vibe_init] Welcome message failed:', e.message);
190
+ debug('init', 'Welcome message failed:', e.message);
217
191
  return false;
218
192
  }
219
193
  }
220
194
 
221
195
  const definition = {
222
196
  name: 'vibe_init',
223
- description: 'Join /vibe social network. Opens browser for GitHub login - NO INPUT NEEDED. Your GitHub username becomes your handle automatically. Just run this and complete the browser auth.',
197
+ description:
198
+ 'Set your identity for /vibe. Opens browser for GitHub auth and waits for completion. Returns when auth is done.',
224
199
  inputSchema: {
225
200
  type: 'object',
226
201
  properties: {
227
202
  handle: {
228
203
  type: 'string',
229
- description: 'RARELY NEEDED - Override your handle (defaults to GitHub username, which is usually what you want)'
204
+ description: 'Custom handle (optional - defaults to your GitHub username)'
230
205
  },
231
206
  one_liner: {
232
207
  type: 'string',
233
- description: 'OPTIONAL - What are you building? Can set this later.'
208
+ description: 'What are you building? (one line)'
234
209
  }
235
210
  },
236
211
  required: []
@@ -252,9 +227,9 @@ function openBrowser(url) {
252
227
  command = `xdg-open "${url}"`;
253
228
  }
254
229
 
255
- exec(command, (err) => {
230
+ exec(command, err => {
256
231
  if (err) {
257
- console.error('[vibe_init] Failed to open browser:', err.message);
232
+ debug('init', 'Failed to open browser:', err.message);
258
233
  }
259
234
  });
260
235
  }
@@ -278,15 +253,10 @@ function waitForCallback(requestedHandle, one_liner) {
278
253
  // Save the token and handle
279
254
  const finalHandle = requestedHandle || callbackHandle;
280
255
 
281
- // Save to config (file persistence for restarts)
282
- config.saveAuthToken(token);
256
+ // Save to config
257
+ config.savePrivyToken(token);
283
258
  config.setSessionIdentity(finalHandle, one_liner || '');
284
259
 
285
- // PUSH to in-memory auth store (immediate propagation)
286
- authStore.setToken(token);
287
- authStore.setHandle(finalHandle);
288
- authStore.setOneLiner(one_liner || '');
289
-
290
260
  // Update shared config
291
261
  const cfg = config.load();
292
262
  cfg.handle = finalHandle;
@@ -305,8 +275,8 @@ function waitForCallback(requestedHandle, one_liner) {
305
275
  // Post to Discord
306
276
  discord.postJoin(finalHandle, one_liner);
307
277
 
308
- // NOTE: Welcome message is sent in the main return path (awaited)
309
- // to ensure it arrives before we show the unread count
278
+ // Send personalized welcome from @vibe (non-blocking)
279
+ sendPersonalizedWelcome(finalHandle, one_liner);
310
280
 
311
281
  // Send success response to browser - lightweight, no infinite animations
312
282
  res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
@@ -554,7 +524,7 @@ function waitForCallback(requestedHandle, one_liner) {
554
524
  }
555
525
  });
556
526
 
557
- server.on('error', (err) => {
527
+ server.on('error', err => {
558
528
  if (err.code === 'EADDRINUSE') {
559
529
  reject(new Error('AUTH_IN_PROGRESS'));
560
530
  } else {
@@ -582,7 +552,10 @@ async function handler(args) {
582
552
 
583
553
  // Normalize handle if provided
584
554
  const h = handle
585
- ? handle.toLowerCase().replace('@', '').replace(/[^a-z0-9_-]/g, '')
555
+ ? handle
556
+ .toLowerCase()
557
+ .replace('@', '')
558
+ .replace(/[^a-z0-9_-]/g, '')
586
559
  : null;
587
560
 
588
561
  // Validate if custom handle provided
@@ -593,7 +566,7 @@ async function handler(args) {
593
566
  }
594
567
 
595
568
  // Check if already authenticated
596
- if (config.hasOAuth()) {
569
+ if (config.hasPrivyAuth()) {
597
570
  const existingHandle = config.getHandle();
598
571
  if (existingHandle) {
599
572
  return {
@@ -636,80 +609,29 @@ To check messages: \`vibe inbox\``
636
609
  // Wait for callback (blocks until auth completes or times out)
637
610
  const result = await waitForCallback(h, one_liner);
638
611
 
639
- // Send personalized welcome and wait for it (2.5s timeout)
640
- let welcomeResult = null;
641
- try {
642
- welcomeResult = await Promise.race([
643
- sendPersonalizedWelcome(result.handle, one_liner),
644
- new Promise(resolve => setTimeout(() => resolve(null), 2500))
645
- ]);
646
- } catch (e) {
647
- console.error('[vibe_init] Welcome message failed:', e.message);
648
- }
649
-
650
- // Check for unread messages (includes the welcome we just sent)
612
+ // Check for unread messages
651
613
  let unreadCount = 0;
652
614
  try {
653
615
  unreadCount = await store.getUnreadCount(result.handle);
654
616
  } catch (e) {}
655
617
 
656
- // Fetch GitHub friends (non-blocking, 3s timeout)
657
- let friendsData = null;
658
- try {
659
- const friendsPromise = fetchGitHubFriends(result.handle);
660
- friendsData = await Promise.race([
661
- friendsPromise,
662
- new Promise(resolve => setTimeout(() => resolve(null), 3000))
663
- ]);
664
- } catch (e) {}
665
-
666
618
  // Generate authenticated banner with handle + unread (3 lines only - won't collapse)
667
619
  const authBanner = generateAuthBanner(result.handle, unreadCount, onlineCount);
668
620
 
669
- // Build friends section if we have data
670
- let friendsSection = '';
671
- if (friendsData?.friendsOnVibe?.length > 0) {
672
- const friendHandles = friendsData.friendsOnVibe.map(f => `@${f.vibe_handle}`).join(', ');
673
- friendsSection = `\n\n🤝 **${friendsData.friendsOnVibe.length} of your GitHub friends are here!**\n${friendHandles}`;
674
- } else if (friendsData?.totalContacts > 0) {
675
- friendsSection = `\n\n👋 None of your GitHub friends are on /vibe yet — say **"vibe invite"** to bring them in!`;
676
- }
677
-
678
- // Build welcome section - show inline if we have the message
679
- let welcomeSection = '';
680
- if (welcomeResult?.messageText) {
681
- welcomeSection = `\n\n---\n**📨 Welcome message from @seth:**\n\n> ${welcomeResult.messageText.split('\n').join('\n> ')}\n\n_Reply with **"vibe dm @seth [message]"** to say hi!_`;
682
- } else {
683
- welcomeSection = '\n\n---\n**📨 @seth sent you a welcome message!**\n\nSay **"vibe inbox"** to read it and get started.';
684
- }
685
-
686
621
  return {
687
- display: authBanner + friendsSection + welcomeSection,
622
+ display: authBanner,
688
623
  onboarding: {
689
624
  isNewUser: true,
690
625
  handle: result.handle,
691
- hint: 'show_onboarding_options',
692
- hasWelcomeMessage: !!welcomeResult,
693
- welcomeText: welcomeResult?.messageText || null,
694
- friendsOnVibe: friendsData?.friendsOnVibe || [],
695
- inviteSuggestions: friendsData?.inviteSuggestions || []
626
+ hint: 'show_onboarding_options'
696
627
  }
697
628
  };
698
-
699
629
  } catch (err) {
700
630
  if (err.message === 'AUTH_IN_PROGRESS') {
701
631
  return {
702
632
  display: `## Auth already in progress
703
633
 
704
- Another login is running. Either:
705
- 1. **Complete it** in your browser, or
706
- 2. **Wait 30 seconds** and try again
707
-
708
- If stuck, kill the auth server:
709
- \`\`\`
710
- lsof -ti:9876 | xargs kill
711
- \`\`\`
712
- Then run \`vibe init\` again.`
634
+ Another login flow is running. Complete it in your browser or wait a moment and try again.`
713
635
  };
714
636
  }
715
637
 
@@ -717,26 +639,16 @@ Then run \`vibe init\` again.`
717
639
  return {
718
640
  display: `## Auth timed out
719
641
 
720
- The browser login wasn't completed within 2 minutes.
721
-
722
- **Try again:**
723
- Just say "add the vibe mcp server" and complete the browser auth faster this time.
724
-
725
- **Tip:** Keep Claude Code visible so you can see when auth completes.`
642
+ The login flow wasn't completed within 2 minutes. Try again with \`vibe init\``
726
643
  };
727
644
  }
728
645
 
729
646
  return {
730
647
  display: `## Failed to authenticate
731
648
 
732
- **Error:** ${err.message}
649
+ Error: ${err.message}
733
650
 
734
- **Quick fixes:**
735
- 1. Check your internet connection
736
- 2. Try again: just say "vibe init"
737
- 3. Check status: slashvibe.dev/status
738
-
739
- **Need help?** DM @seth on Twitter or email seth@slashvibe.dev`
651
+ Try again or use legacy auth: \`vibe init --auth_method=legacy\``
740
652
  };
741
653
  }
742
654
  }
@@ -788,16 +700,7 @@ Local config saved. Heartbeats will use username fallback.`
788
700
  discord.postJoin(h, one_liner);
789
701
 
790
702
  // Send personalized welcome from @vibe (non-blocking)
791
- // Send personalized welcome and wait for it
792
- let welcomeResult = null;
793
- try {
794
- welcomeResult = await Promise.race([
795
- sendPersonalizedWelcome(h, one_liner),
796
- new Promise(resolve => setTimeout(() => resolve(null), 2500))
797
- ]);
798
- } catch (e) {
799
- console.error('[vibe_init] Welcome message failed:', e.message);
800
- }
703
+ sendPersonalizedWelcome(h, one_liner);
801
704
 
802
705
  // Check for unread messages
803
706
  let unreadNotice = '';
@@ -815,14 +718,14 @@ Local config saved. Heartbeats will use username fallback.`
815
718
  **@${h}**
816
719
  _${one_liner}_${unreadNotice}${keypairNote}
817
720
 
818
- 📨 **Check your messages** — @seth sent you a personalized welcome!
721
+ 📨 **Check your messages** — @vibe sent you a personalized welcome!
819
722
 
820
723
  ⚠️ **Using local keys** — consider upgrading to GitHub auth:
821
724
  \`vibe init\` — Sign in with GitHub for verified identity
822
725
 
823
726
  ### Onboarding Checklist
824
- [ ] Read your welcome message from @seth
825
- [ ] Reply to @seth
727
+ [ ] Read your welcome message from @vibe
728
+ [ ] Reply to @vibe
826
729
  [ ] Message one recommended builder
827
730
  [ ] Post your first ship
828
731
  [ ] Leave some feedback
package/tools/invite.js CHANGED
@@ -23,7 +23,7 @@ const definition = {
23
23
  },
24
24
  name: {
25
25
  type: 'string',
26
- description: 'Optional: Friend\'s name for personalized message'
26
+ description: "Optional: Friend's name for personalized message"
27
27
  },
28
28
  format: {
29
29
  type: 'string',
@@ -35,8 +35,8 @@ const definition = {
35
35
 
36
36
  const INVITE_MESSAGES = [
37
37
  "Join the /vibe — it's like Slack but in your Claude Code terminal",
38
- "Try /vibe in Claude Code — message people without leaving your flow",
39
- "Come hang out on /vibe — the social layer for Claude Code users",
38
+ 'Try /vibe in Claude Code — message people without leaving your flow',
39
+ 'Come hang out on /vibe — the social layer for Claude Code users',
40
40
  "There's a thing called /vibe for Claude Code — we can message while coding"
41
41
  ];
42
42
 
@@ -148,9 +148,7 @@ You can have up to ${result.max_codes} unused codes at a time.`
148
148
  }
149
149
  }
150
150
 
151
- const shareUrl = shareCode
152
- ? `slashvibe.dev/invite/${shareCode}`
153
- : 'slashvibe.dev';
151
+ const shareUrl = shareCode ? `slashvibe.dev/invite/${shareCode}` : 'slashvibe.dev';
154
152
 
155
153
  // Just the link
156
154
  if (format === 'link') {
@@ -203,25 +201,14 @@ _Copy the link above and send it._`
203
201
  const genNote = justGenerated ? ' (just generated)' : '';
204
202
  const randomMsg = INVITE_MESSAGES[Math.floor(Math.random() * INVITE_MESSAGES.length)];
205
203
 
206
- // Build social share URLs
207
- const tweetText = encodeURIComponent(`${randomMsg}\n\nhttps://${shareUrl}`);
208
- const twitterUrl = `https://twitter.com/intent/tweet?text=${tweetText}`;
209
-
210
204
  return {
211
205
  display: `## Quick Invite${genNote}
212
206
 
213
- **Copy this:**
214
- \`\`\`
215
- ${randomMsg}
216
-
217
- https://${shareUrl}
218
- \`\`\`
219
-
220
- **Or share directly:**
221
- - [Tweet it](${twitterUrl})
222
- - Slack/Discord: Just paste the link above
207
+ > ${randomMsg}
208
+ >
209
+ > **${shareUrl}**
223
210
 
224
- ${shareCode ? `_When they join, you both get bonus codes._` : ''}`
211
+ _Copy and send. ${shareCode ? `Bonus code earned when they join.` : ''}_`
225
212
  };
226
213
  }
227
214
 
package/tools/migrate.js CHANGED
@@ -2,7 +2,7 @@
2
2
  * vibe migrate — Migrate existing handle to GitHub auth
3
3
  *
4
4
  * For users who have existing handles with local keypairs,
5
- * this command helps them migrate to GitHub OAuth auth.
5
+ * this command helps them migrate to the new Privy/GitHub auth.
6
6
  *
7
7
  * Flow:
8
8
  * 1. Check if user has existing handle and keys
@@ -17,7 +17,8 @@ const crypto = require('../crypto');
17
17
 
18
18
  const definition = {
19
19
  name: 'vibe_migrate',
20
- description: 'Migrate your existing handle to GitHub authentication. Use this if you have an existing handle with local keys.',
20
+ description:
21
+ 'Migrate your existing handle to GitHub authentication. Use this if you have an existing handle with local keys.',
21
22
  inputSchema: {
22
23
  type: 'object',
23
24
  properties: {}
@@ -36,8 +37,8 @@ If you're new, use \`vibe init @yourhandle "what you're building"\` instead.`
36
37
  };
37
38
  }
38
39
 
39
- // Check if already using GitHub auth
40
- if (config.hasOAuth()) {
40
+ // Check if already using Privy auth
41
+ if (config.hasPrivyAuth()) {
41
42
  return {
42
43
  display: `✅ **Already using GitHub auth**
43
44
 
@@ -76,26 +77,29 @@ No migration needed!`
76
77
  timestamp
77
78
  });
78
79
 
79
- const req = https.request({
80
- hostname: url.hostname,
81
- port: 443,
82
- path: url.pathname,
83
- method: 'POST',
84
- headers: {
85
- 'Content-Type': 'application/json',
86
- 'Content-Length': data.length
87
- }
88
- }, (res) => {
89
- let body = '';
90
- res.on('data', chunk => body += chunk);
91
- res.on('end', () => {
92
- try {
93
- resolve(JSON.parse(body));
94
- } catch (e) {
95
- resolve({ success: false, error: body });
80
+ const req = https.request(
81
+ {
82
+ hostname: url.hostname,
83
+ port: 443,
84
+ path: url.pathname,
85
+ method: 'POST',
86
+ headers: {
87
+ 'Content-Type': 'application/json',
88
+ 'Content-Length': data.length
96
89
  }
97
- });
98
- });
90
+ },
91
+ res => {
92
+ let body = '';
93
+ res.on('data', chunk => (body += chunk));
94
+ res.on('end', () => {
95
+ try {
96
+ resolve(JSON.parse(body));
97
+ } catch (e) {
98
+ resolve({ success: false, error: body });
99
+ }
100
+ });
101
+ }
102
+ );
99
103
 
100
104
  req.on('error', reject);
101
105
  req.write(data);
@@ -141,7 +145,6 @@ _Migration token expires in 1 hour._`,
141
145
  verified: result.verified,
142
146
  migrationToken: result.migrationToken
143
147
  };
144
-
145
148
  } catch (e) {
146
149
  return {
147
150
  display: `❌ **Migration request failed**