slashvibe-mcp 0.3.21 → 0.3.22

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 (229) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +280 -47
  3. package/config.js +36 -31
  4. package/crypto.js +1 -6
  5. package/discord.js +19 -19
  6. package/index.js +217 -207
  7. package/intelligence/index.js +2 -9
  8. package/intelligence/infer.js +10 -16
  9. package/intelligence/patterns.js +23 -18
  10. package/intelligence/proactive.js +16 -15
  11. package/intelligence/serendipity.js +57 -20
  12. package/memory.js +13 -8
  13. package/notify.js +39 -14
  14. package/package.json +27 -20
  15. package/presence.js +2 -2
  16. package/prompts.js +5 -9
  17. package/protocol/index.js +123 -87
  18. package/protocol/telegram-commands.js +36 -37
  19. package/store/api.js +358 -529
  20. package/store/local.js +9 -10
  21. package/store/profiles.js +48 -192
  22. package/store/reservations.js +2 -9
  23. package/store/skills.js +69 -71
  24. package/store/sqlite.js +355 -0
  25. package/tools/_actions.js +48 -387
  26. package/tools/_connection-queue.js +45 -56
  27. package/tools/_discovery-enhanced.js +52 -57
  28. package/tools/_discovery.js +87 -185
  29. package/tools/{l2-status.js → _experimental/l2-status.js} +68 -70
  30. package/tools/{shipback.js → _experimental/shipback.js} +4 -3
  31. package/tools/_proactive-discovery.js +60 -73
  32. package/tools/_shared/index.js +41 -64
  33. package/tools/admin-inbox.js +10 -15
  34. package/tools/agents.js +1 -1
  35. package/tools/artifact-create.js +13 -23
  36. package/tools/artifact-view.js +4 -4
  37. package/tools/{_deprecated/back.js → back.js} +1 -1
  38. package/tools/bye.js +3 -5
  39. package/tools/consent.js +2 -2
  40. package/tools/context.js +9 -10
  41. package/tools/crossword.js +3 -2
  42. package/tools/discover.js +94 -356
  43. package/tools/dm.js +27 -86
  44. package/tools/doctor.js +12 -41
  45. package/tools/drawing.js +34 -20
  46. package/tools/echo.js +11 -11
  47. package/tools/feed.js +30 -58
  48. package/tools/follow.js +64 -187
  49. package/tools/{_deprecated/forget.js → forget.js} +4 -7
  50. package/tools/game.js +144 -48
  51. package/tools/handoff.js +6 -8
  52. package/tools/help.js +3 -3
  53. package/tools/idea.js +15 -27
  54. package/tools/inbox.js +121 -293
  55. package/tools/init.js +54 -151
  56. package/tools/invite.js +8 -21
  57. package/tools/migrate.js +27 -24
  58. package/tools/multiplayer-game.js +50 -40
  59. package/tools/{_deprecated/mute.js → mute.js} +4 -3
  60. package/tools/notifications.js +58 -48
  61. package/tools/observe.js +12 -15
  62. package/tools/onboarding.js +8 -11
  63. package/tools/open.js +13 -144
  64. package/tools/party-game.js +23 -12
  65. package/tools/patterns.js +2 -1
  66. package/tools/ping.js +5 -7
  67. package/tools/react.js +28 -30
  68. package/tools/{_deprecated/recall.js → recall.js} +5 -10
  69. package/tools/release.js +4 -2
  70. package/tools/{_deprecated/remember.js → remember.js} +4 -6
  71. package/tools/report.js +2 -2
  72. package/tools/request.js +6 -26
  73. package/tools/reserve.js +1 -1
  74. package/tools/session-fork.js +97 -0
  75. package/tools/session-save.js +109 -0
  76. package/tools/settings.js +30 -99
  77. package/tools/ship.js +74 -56
  78. package/tools/{_deprecated/skills-exchange.js → skills-exchange.js} +38 -39
  79. package/tools/social-inbox.js +22 -28
  80. package/tools/social-post.js +24 -27
  81. package/tools/solo-game.js +54 -46
  82. package/tools/start.js +14 -148
  83. package/tools/status.js +21 -68
  84. package/tools/submit.js +4 -2
  85. package/tools/suggest-tags.js +36 -33
  86. package/tools/summarize.js +19 -16
  87. package/tools/tag-suggestions.js +72 -73
  88. package/tools/test.js +1 -1
  89. package/tools/{_deprecated/tictactoe.js → tictactoe.js} +26 -26
  90. package/tools/token.js +4 -4
  91. package/tools/update.js +1 -2
  92. package/tools/watch.js +132 -112
  93. package/tools/who.js +20 -40
  94. package/tools/{_deprecated/wordassociation.js → wordassociation.js} +23 -20
  95. package/tools/workshop-buddy.js +52 -53
  96. package/tools/x-mentions.js +0 -1
  97. package/tools/x-reply.js +0 -1
  98. package/twitter.js +14 -20
  99. package/version.json +8 -10
  100. package/analytics.js +0 -107
  101. package/auth-store.js +0 -148
  102. package/auto-update.js +0 -130
  103. package/bridges/bridge-monitor.js +0 -388
  104. package/bridges/discord-bot.js +0 -431
  105. package/bridges/farcaster.js +0 -299
  106. package/bridges/telegram.js +0 -261
  107. package/bridges/webhook-health.js +0 -420
  108. package/bridges/webhook-server.js +0 -437
  109. package/bridges/whatsapp.js +0 -441
  110. package/bridges/x-webhook.js +0 -423
  111. package/games/arcade.js +0 -406
  112. package/games/chess.js +0 -451
  113. package/games/colorguess.js +0 -343
  114. package/games/crossword-words.js +0 -171
  115. package/games/crossword.js +0 -461
  116. package/games/drawing.js +0 -347
  117. package/games/gameroulette.js +0 -300
  118. package/games/gamerouter.js +0 -336
  119. package/games/gamestatus.js +0 -337
  120. package/games/guessnumber.js +0 -209
  121. package/games/hangman.js +0 -279
  122. package/games/memory.js +0 -338
  123. package/games/multiplayer-tictactoe.js +0 -389
  124. package/games/pixelart.js +0 -399
  125. package/games/quickduel.js +0 -354
  126. package/games/riddle.js +0 -371
  127. package/games/rockpaperscissors.js +0 -291
  128. package/games/snake.js +0 -406
  129. package/games/storybuilder.js +0 -343
  130. package/games/tictactoe.js +0 -345
  131. package/games/twentyquestions.js +0 -286
  132. package/games/twotruths.js +0 -207
  133. package/games/werewolf.js +0 -508
  134. package/games/wordassociation.js +0 -247
  135. package/games/wordchain.js +0 -135
  136. package/intelligence/interests.js +0 -369
  137. package/notification-emitter.js +0 -77
  138. package/setup.js +0 -480
  139. package/smart-inbox.js +0 -276
  140. package/tools/_deprecated/auto-suggest-connections.js +0 -304
  141. package/tools/_deprecated/bootstrap-skills.js +0 -231
  142. package/tools/_deprecated/bridge-dashboard.js +0 -342
  143. package/tools/_deprecated/bridge-health.js +0 -400
  144. package/tools/_deprecated/bridge-live.js +0 -384
  145. package/tools/_deprecated/bridges.js +0 -383
  146. package/tools/_deprecated/colorguess.js +0 -281
  147. package/tools/_deprecated/discover-insights.js +0 -379
  148. package/tools/_deprecated/discover-momentum.js +0 -256
  149. package/tools/_deprecated/discovery-analytics.js +0 -345
  150. package/tools/_deprecated/discovery-auto-suggest.js +0 -275
  151. package/tools/_deprecated/discovery-bootstrap.js +0 -267
  152. package/tools/_deprecated/discovery-daily.js +0 -375
  153. package/tools/_deprecated/discovery-dashboard.js +0 -385
  154. package/tools/_deprecated/discovery-digest.js +0 -314
  155. package/tools/_deprecated/discovery-hub.js +0 -357
  156. package/tools/_deprecated/discovery-insights.js +0 -384
  157. package/tools/_deprecated/discovery-momentum.js +0 -281
  158. package/tools/_deprecated/discovery-monitor.js +0 -319
  159. package/tools/_deprecated/discovery-proactive.js +0 -300
  160. package/tools/_deprecated/draw.js +0 -317
  161. package/tools/_deprecated/farcaster.js +0 -307
  162. package/tools/_deprecated/games-catalog.js +0 -376
  163. package/tools/_deprecated/games.js +0 -313
  164. package/tools/_deprecated/guessnumber.js +0 -194
  165. package/tools/_deprecated/hangman.js +0 -129
  166. package/tools/_deprecated/multiplayer-tictactoe.js +0 -303
  167. package/tools/_deprecated/riddle.js +0 -240
  168. package/tools/_deprecated/run-bootstrap.js +0 -69
  169. package/tools/_deprecated/skills-analytics.js +0 -349
  170. package/tools/_deprecated/skills-bootstrap.js +0 -301
  171. package/tools/_deprecated/skills-dashboard.js +0 -268
  172. package/tools/_deprecated/skills.js +0 -380
  173. package/tools/_deprecated/smart-intro.js +0 -353
  174. package/tools/_deprecated/storybuilder.js +0 -331
  175. package/tools/_deprecated/telegram-bot.js +0 -183
  176. package/tools/_deprecated/telegram-setup.js +0 -214
  177. package/tools/_deprecated/twentyquestions.js +0 -143
  178. package/tools/_shared.js +0 -234
  179. package/tools/_work-context.js +0 -338
  180. package/tools/_work-context.manual-test.js +0 -199
  181. package/tools/_work-context.test.js +0 -260
  182. package/tools/activity.js +0 -220
  183. package/tools/agent-treasury.js +0 -288
  184. package/tools/analytics.js +0 -191
  185. package/tools/approve.js +0 -197
  186. package/tools/arcade.js +0 -173
  187. package/tools/artifacts-price.js +0 -107
  188. package/tools/ask-expert.js +0 -160
  189. package/tools/available.js +0 -120
  190. package/tools/become-expert.js +0 -150
  191. package/tools/broadcast.js +0 -325
  192. package/tools/chat.js +0 -202
  193. package/tools/collaborative-drawing.js +0 -286
  194. package/tools/connection-status.js +0 -178
  195. package/tools/earnings.js +0 -126
  196. package/tools/friends.js +0 -207
  197. package/tools/genesis.js +0 -233
  198. package/tools/gig-browse.js +0 -206
  199. package/tools/gig-complete.js +0 -144
  200. package/tools/health.js +0 -87
  201. package/tools/leaderboard.js +0 -117
  202. package/tools/lib/git-apply.js +0 -206
  203. package/tools/lib/git-bundle.js +0 -407
  204. package/tools/mint.js +0 -377
  205. package/tools/plan.js +0 -225
  206. package/tools/profile.js +0 -219
  207. package/tools/proof-of-work.js +0 -144
  208. package/tools/pulse.js +0 -218
  209. package/tools/reply.js +0 -166
  210. package/tools/reputation.js +0 -175
  211. package/tools/schedule.js +0 -367
  212. package/tools/search-messages.js +0 -123
  213. package/tools/session.js +0 -467
  214. package/tools/session_price.js +0 -128
  215. package/tools/smart-check.js +0 -201
  216. package/tools/social-processor.js +0 -445
  217. package/tools/streak.js +0 -147
  218. package/tools/stuck.js +0 -297
  219. package/tools/subscribe.js +0 -148
  220. package/tools/subscriptions.js +0 -134
  221. package/tools/tip.js +0 -193
  222. package/tools/wallet.js +0 -269
  223. package/tools/webhook-test.js +0 -388
  224. package/tools/withdraw.js +0 -145
  225. package/tools/work-summary.js +0 -96
  226. package/tools/workshop.js +0 -327
  227. /package/tools/{l2-bridge.js → _experimental/l2-bridge.js} +0 -0
  228. /package/tools/{l2.js → _experimental/l2.js} +0 -0
  229. /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**