slashvibe-mcp 0.2.9 → 0.3.13

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 (205) hide show
  1. package/README.md +1 -0
  2. package/analytics.js +107 -0
  3. package/auth-store.js +148 -0
  4. package/auto-update.js +130 -0
  5. package/bridges/bridge-monitor.js +388 -0
  6. package/bridges/discord-bot.js +431 -0
  7. package/bridges/farcaster.js +299 -0
  8. package/bridges/telegram.js +261 -0
  9. package/bridges/webhook-health.js +420 -0
  10. package/bridges/webhook-server.js +437 -0
  11. package/bridges/whatsapp.js +441 -0
  12. package/bridges/x-webhook.js +423 -0
  13. package/config.js +154 -5
  14. package/crypto.js +3 -8
  15. package/games/arcade.js +406 -0
  16. package/games/chess.js +451 -0
  17. package/games/colorguess.js +343 -0
  18. package/games/crossword-words.js +171 -0
  19. package/games/crossword.js +461 -0
  20. package/games/drawing.js +347 -0
  21. package/games/gameroulette.js +300 -0
  22. package/games/gamerouter.js +336 -0
  23. package/games/gamestatus.js +337 -0
  24. package/games/guessnumber.js +209 -0
  25. package/games/hangman.js +279 -0
  26. package/games/memory.js +338 -0
  27. package/games/multiplayer-tictactoe.js +389 -0
  28. package/games/pixelart.js +399 -0
  29. package/games/quickduel.js +354 -0
  30. package/games/riddle.js +371 -0
  31. package/games/rockpaperscissors.js +291 -0
  32. package/games/snake.js +406 -0
  33. package/games/storybuilder.js +343 -0
  34. package/games/tictactoe.js +345 -0
  35. package/games/twentyquestions.js +286 -0
  36. package/games/twotruths.js +207 -0
  37. package/games/werewolf.js +508 -0
  38. package/games/wordassociation.js +247 -0
  39. package/games/wordchain.js +135 -0
  40. package/index.js +105 -216
  41. package/intelligence/index.js +45 -0
  42. package/intelligence/infer.js +316 -0
  43. package/intelligence/interests.js +369 -0
  44. package/intelligence/patterns.js +651 -0
  45. package/intelligence/proactive.js +358 -0
  46. package/intelligence/serendipity.js +306 -0
  47. package/memory.js +166 -0
  48. package/notification-emitter.js +77 -0
  49. package/notify.js +102 -1
  50. package/package.json +21 -7
  51. package/prompts.js +1 -1
  52. package/protocol/index.js +161 -1
  53. package/setup.js +402 -0
  54. package/store/api.js +528 -82
  55. package/store/profiles.js +160 -12
  56. package/tools/_actions.js +463 -16
  57. package/tools/_deprecated/auto-suggest-connections.js +304 -0
  58. package/tools/_deprecated/bootstrap-skills.js +231 -0
  59. package/tools/_deprecated/bridge-dashboard.js +342 -0
  60. package/tools/_deprecated/bridge-health.js +400 -0
  61. package/tools/_deprecated/bridge-live.js +384 -0
  62. package/tools/_deprecated/bridges.js +383 -0
  63. package/tools/_deprecated/colorguess.js +281 -0
  64. package/tools/_deprecated/discover-insights.js +379 -0
  65. package/tools/_deprecated/discover-momentum.js +256 -0
  66. package/tools/_deprecated/discovery-analytics.js +345 -0
  67. package/tools/_deprecated/discovery-auto-suggest.js +275 -0
  68. package/tools/_deprecated/discovery-bootstrap.js +267 -0
  69. package/tools/_deprecated/discovery-daily.js +375 -0
  70. package/tools/_deprecated/discovery-dashboard.js +385 -0
  71. package/tools/_deprecated/discovery-digest.js +314 -0
  72. package/tools/_deprecated/discovery-hub.js +357 -0
  73. package/tools/_deprecated/discovery-insights.js +384 -0
  74. package/tools/_deprecated/discovery-momentum.js +281 -0
  75. package/tools/_deprecated/discovery-monitor.js +319 -0
  76. package/tools/_deprecated/discovery-proactive.js +300 -0
  77. package/tools/_deprecated/draw.js +317 -0
  78. package/tools/_deprecated/farcaster.js +307 -0
  79. package/tools/_deprecated/forget.js +119 -0
  80. package/tools/_deprecated/games-catalog.js +376 -0
  81. package/tools/_deprecated/games.js +313 -0
  82. package/tools/_deprecated/guessnumber.js +194 -0
  83. package/tools/_deprecated/hangman.js +129 -0
  84. package/tools/_deprecated/multiplayer-tictactoe.js +303 -0
  85. package/tools/_deprecated/recall.js +147 -0
  86. package/tools/_deprecated/remember.js +86 -0
  87. package/tools/_deprecated/riddle.js +240 -0
  88. package/tools/_deprecated/run-bootstrap.js +69 -0
  89. package/tools/_deprecated/skills-analytics.js +349 -0
  90. package/tools/_deprecated/skills-bootstrap.js +301 -0
  91. package/tools/_deprecated/skills-dashboard.js +268 -0
  92. package/tools/_deprecated/skills.js +380 -0
  93. package/tools/_deprecated/smart-intro.js +353 -0
  94. package/tools/_deprecated/storybuilder.js +331 -0
  95. package/tools/_deprecated/telegram-bot.js +183 -0
  96. package/tools/_deprecated/telegram-setup.js +214 -0
  97. package/tools/_deprecated/twentyquestions.js +143 -0
  98. package/tools/_discovery-enhanced.js +290 -0
  99. package/tools/_discovery.js +439 -0
  100. package/tools/_proactive-discovery.js +301 -0
  101. package/tools/_shared/index.js +64 -0
  102. package/tools/_shared.js +234 -0
  103. package/tools/_work-context.js +338 -0
  104. package/tools/_work-context.manual-test.js +199 -0
  105. package/tools/_work-context.test.js +260 -0
  106. package/tools/activity.js +220 -0
  107. package/tools/admin-inbox.js +218 -0
  108. package/tools/agent-treasury.js +288 -0
  109. package/tools/analytics.js +191 -0
  110. package/tools/approve.js +197 -0
  111. package/tools/arcade.js +173 -0
  112. package/tools/artifact-create.js +17 -11
  113. package/tools/artifact-view.js +31 -1
  114. package/tools/artifacts-price.js +47 -43
  115. package/tools/ask-expert.js +160 -0
  116. package/tools/available.js +120 -0
  117. package/tools/become-expert.js +150 -0
  118. package/tools/broadcast.js +286 -0
  119. package/tools/chat.js +202 -0
  120. package/tools/collaborative-drawing.js +286 -0
  121. package/tools/connection-status.js +178 -0
  122. package/tools/crossword.js +17 -1
  123. package/tools/discover.js +350 -34
  124. package/tools/dm.js +115 -73
  125. package/tools/drawing.js +1 -1
  126. package/tools/earnings.js +126 -0
  127. package/tools/echo.js +16 -0
  128. package/tools/feed.js +51 -7
  129. package/tools/follow.js +224 -0
  130. package/tools/friends.js +207 -0
  131. package/tools/game.js +2 -2
  132. package/tools/genesis.js +233 -0
  133. package/tools/gig-browse.js +206 -0
  134. package/tools/gig-complete.js +144 -0
  135. package/tools/handoff.js +7 -1
  136. package/tools/help.js +4 -4
  137. package/tools/idea.js +9 -2
  138. package/tools/inbox.js +334 -28
  139. package/tools/init.js +727 -36
  140. package/tools/invite.js +15 -4
  141. package/tools/l2-bridge.js +272 -0
  142. package/tools/l2-status.js +217 -0
  143. package/tools/l2.js +206 -0
  144. package/tools/migrate.js +156 -0
  145. package/tools/mint.js +377 -0
  146. package/tools/multiplayer-game.js +1 -1
  147. package/tools/notifications.js +415 -0
  148. package/tools/observe.js +200 -0
  149. package/tools/onboarding.js +147 -0
  150. package/tools/open.js +143 -12
  151. package/tools/party-game.js +2 -2
  152. package/tools/plan.js +225 -0
  153. package/tools/presence-agent.js +7 -0
  154. package/tools/proof-of-work.js +100 -104
  155. package/tools/pulse.js +218 -0
  156. package/tools/reply.js +166 -0
  157. package/tools/report.js +2 -2
  158. package/tools/reputation.js +175 -0
  159. package/tools/request.js +17 -3
  160. package/tools/schedule.js +367 -0
  161. package/tools/search-messages.js +123 -0
  162. package/tools/session.js +420 -0
  163. package/tools/session_price.js +128 -0
  164. package/tools/settings.js +126 -3
  165. package/tools/ship.js +31 -8
  166. package/tools/shipback.js +326 -0
  167. package/tools/smart-check.js +201 -0
  168. package/tools/social-processor.js +445 -0
  169. package/tools/solo-game.js +1 -1
  170. package/tools/start.js +335 -93
  171. package/tools/status.js +53 -6
  172. package/tools/stuck.js +297 -0
  173. package/tools/subscribe.js +148 -0
  174. package/tools/subscriptions.js +134 -0
  175. package/tools/suggest-tags.js +6 -8
  176. package/tools/tag-suggestions.js +257 -0
  177. package/tools/tip.js +193 -0
  178. package/tools/token.js +103 -0
  179. package/tools/update.js +1 -1
  180. package/tools/wallet.js +239 -186
  181. package/tools/watch.js +157 -0
  182. package/tools/webhook-test.js +388 -0
  183. package/tools/who.js +54 -3
  184. package/tools/withdraw.js +145 -0
  185. package/tools/work-summary.js +96 -0
  186. package/tools/workshop.js +327 -0
  187. package/tools/x-mentions.js +1 -1
  188. package/version.json +14 -3
  189. package/tools/artifacts-buy.js +0 -111
  190. package/tools/connect.js +0 -284
  191. package/tools/gigs-apply.js +0 -99
  192. package/tools/gigs-browse.js +0 -114
  193. package/tools/gigs-complete.js +0 -128
  194. package/tools/gigs-post.js +0 -140
  195. package/tools/live-off.js +0 -109
  196. package/tools/live-watch.js +0 -176
  197. package/tools/live.js +0 -128
  198. package/tools/sessions-browse.js +0 -105
  199. package/tools/whats-happening.js +0 -125
  200. /package/tools/{away.js → _deprecated/away.js} +0 -0
  201. /package/tools/{back.js → _deprecated/back.js} +0 -0
  202. /package/tools/{mute.js → _deprecated/mute.js} +0 -0
  203. /package/tools/{skills-exchange.js → _deprecated/skills-exchange.js} +0 -0
  204. /package/tools/{tictactoe.js → _deprecated/tictactoe.js} +0 -0
  205. /package/tools/{wordassociation.js → _deprecated/wordassociation.js} +0 -0
package/tools/_actions.js CHANGED
@@ -45,9 +45,21 @@ async function dm_user(handle, message) {
45
45
  const actions = {
46
46
  // After vibe_start or vibe_who
47
47
  dashboard: (context = {}) => {
48
- const { unreadCount = 0, onlineUsers = [], suggestion } = context;
48
+ const { unreadCount = 0, onlineUsers = [], suggestion, workContext } = context;
49
49
  const result = [];
50
50
 
51
+ // Priority 0: If we have work context, offer to share it
52
+ if (workContext?.summary) {
53
+ const shortSummary = workContext.summary.length > 40
54
+ ? workContext.summary.slice(0, 40) + '...'
55
+ : workContext.summary;
56
+ result.push({
57
+ label: `Share: "${shortSummary}"`,
58
+ description: 'Post what you\'re working on',
59
+ command: `ship: ${workContext.summary}`
60
+ });
61
+ }
62
+
51
63
  // Priority 1: Unread messages
52
64
  if (unreadCount > 0) {
53
65
  result.push({
@@ -222,6 +234,11 @@ const actions = {
222
234
 
223
235
  // After sending a DM
224
236
  afterDm: (handle) => [
237
+ {
238
+ label: 'Reply + tip $1',
239
+ description: `Send reply with $1 USDC tip to @${handle}`,
240
+ command: `reply @${handle} with tip`
241
+ },
225
242
  {
226
243
  label: 'Send another',
227
244
  description: `Continue conversation with @${handle}`,
@@ -233,9 +250,28 @@ const actions = {
233
250
  command: `react to @${handle}`
234
251
  },
235
252
  {
236
- label: 'Remember something',
237
- description: `Save a note about @${handle}`,
238
- command: `remember something about @${handle}`
253
+ label: 'Find more people',
254
+ description: 'Discover other connections',
255
+ command: 'discover suggest'
256
+ }
257
+ ],
258
+
259
+ // After sending a tip
260
+ afterTip: (handle) => [
261
+ {
262
+ label: 'Send message',
263
+ description: `Message @${handle}`,
264
+ command: `message @${handle}`
265
+ },
266
+ {
267
+ label: 'Tip again',
268
+ description: `Send another tip to @${handle}`,
269
+ command: `tip @${handle}`
270
+ },
271
+ {
272
+ label: 'View their work',
273
+ description: `See @${handle}'s proof of work`,
274
+ command: `show proof of work for @${handle}`
239
275
  },
240
276
  {
241
277
  label: 'Find more people',
@@ -244,6 +280,110 @@ const actions = {
244
280
  }
245
281
  ],
246
282
 
283
+ // After viewing a ship in the feed
284
+ afterShipView: (ship) => {
285
+ const author = ship?.author || 'creator';
286
+ return [
287
+ {
288
+ label: 'Tip $1 for this ship',
289
+ description: `Thank @${author} for shipping`,
290
+ command: `tip @${author} 1 for ship`
291
+ },
292
+ {
293
+ label: `Message @${author}`,
294
+ description: 'Start a conversation',
295
+ command: `message @${author}`
296
+ },
297
+ {
298
+ label: 'React 🔥',
299
+ description: 'Show some love',
300
+ command: `react fire to @${author}`
301
+ },
302
+ {
303
+ label: 'See more ships',
304
+ description: 'Browse the feed',
305
+ command: 'show the feed'
306
+ }
307
+ ];
308
+ },
309
+
310
+ // After viewing someone's proof-of-work profile
311
+ afterProofOfWork: (handle, isSelf = false) => {
312
+ if (isSelf) {
313
+ return [
314
+ {
315
+ label: 'Post a ship',
316
+ description: 'Share what you\'re building',
317
+ command: 'ship something'
318
+ },
319
+ {
320
+ label: 'Browse gigs',
321
+ description: 'Find work opportunities',
322
+ command: 'browse gigs'
323
+ },
324
+ {
325
+ label: 'Set availability',
326
+ description: 'Update your hire status',
327
+ command: 'update availability'
328
+ },
329
+ {
330
+ label: 'View earnings',
331
+ description: 'Check your earnings dashboard',
332
+ command: 'show my earnings'
333
+ }
334
+ ];
335
+ }
336
+ return [
337
+ {
338
+ label: `Tip @${handle}`,
339
+ description: 'Send a tip to support their work',
340
+ command: `tip @${handle}`
341
+ },
342
+ {
343
+ label: `Message @${handle}`,
344
+ description: 'Start a conversation',
345
+ command: `message @${handle}`
346
+ },
347
+ {
348
+ label: 'View their ships',
349
+ description: `See what @${handle} has shipped`,
350
+ command: `show feed from @${handle}`
351
+ },
352
+ {
353
+ label: 'Find similar builders',
354
+ description: 'Discover people like them',
355
+ command: 'discover suggest'
356
+ }
357
+ ];
358
+ },
359
+
360
+ // After completing a gig
361
+ afterGigComplete: (gig) => {
362
+ const worker = gig?.hired_handle || 'worker';
363
+ return [
364
+ {
365
+ label: 'Add $5 bonus tip',
366
+ description: `Extra thanks to @${worker} for great work`,
367
+ command: `tip @${worker} 5 gig bonus`
368
+ },
369
+ {
370
+ label: `Message @${worker}`,
371
+ description: 'Send a thank you message',
372
+ command: `message @${worker}`
373
+ },
374
+ {
375
+ label: 'Post another gig',
376
+ description: 'Create a new gig listing',
377
+ command: 'post a gig'
378
+ },
379
+ {
380
+ label: 'Browse gigs',
381
+ description: 'See other opportunities',
382
+ command: 'browse gigs'
383
+ }
384
+ ];
385
+ },
386
+
247
387
  // After checking inbox
248
388
  afterInbox: (threads = []) => {
249
389
  const result = [];
@@ -283,26 +423,158 @@ const actions = {
283
423
  return result.slice(0, 4);
284
424
  },
285
425
 
426
+ // After checking inbox - compact view with direct thread options
427
+ afterInboxCompact: (senders = []) => {
428
+ const result = [];
429
+
430
+ // Top 3 senders get direct open options
431
+ senders.slice(0, 3).forEach(s => {
432
+ result.push({
433
+ label: `Open @${s.handle}`,
434
+ description: `${s.unread} unread message${s.unread > 1 ? 's' : ''}`,
435
+ command: `open thread with @${s.handle}`
436
+ });
437
+ });
438
+
439
+ // 4th option depends on sender count
440
+ if (senders.length > 3) {
441
+ const remaining = senders.length - 3;
442
+ result.push({
443
+ label: 'Pick another...',
444
+ description: `${remaining} more sender${remaining > 1 ? 's' : ''}`,
445
+ command: 'show all threads'
446
+ });
447
+ } else {
448
+ result.push({
449
+ label: 'Find connections',
450
+ description: 'Discover people to meet',
451
+ command: 'discover suggest'
452
+ });
453
+ }
454
+
455
+ return result.slice(0, 4);
456
+ },
457
+
286
458
  // When room is empty
287
- emptyRoom: () => [
288
- {
459
+ emptyRoom: (context = {}) => {
460
+ const { workContext } = context;
461
+ const result = [];
462
+
463
+ // If we have work context, lead with "share your progress"
464
+ if (workContext?.summary) {
465
+ const shortSummary = workContext.summary.length > 40
466
+ ? workContext.summary.slice(0, 40) + '...'
467
+ : workContext.summary;
468
+ result.push({
469
+ label: `Ship: "${shortSummary}"`,
470
+ description: 'Share your progress to the board',
471
+ command: `ship: ${workContext.summary}`
472
+ });
473
+ }
474
+
475
+ result.push({
289
476
  label: 'Find your people',
290
477
  description: 'Discover builders with similar interests',
291
478
  command: 'discover suggest'
292
- },
293
- {
294
- label: 'Set up profile',
295
- description: 'Add interests to get matched',
296
- command: 'update my profile'
297
- },
298
- {
479
+ });
480
+
481
+ // Only show "Set up profile" if we didn't already add work context
482
+ if (!workContext?.summary) {
483
+ result.push({
484
+ label: 'Set up profile',
485
+ description: 'Add interests to get matched',
486
+ command: 'update my profile'
487
+ });
488
+ }
489
+
490
+ result.push({
299
491
  label: 'Invite someone',
300
492
  description: 'Generate a shareable invite link',
301
493
  command: 'generate invite link'
494
+ });
495
+
496
+ // Only add generic "Post to board" if we don't have specific work context
497
+ if (!workContext?.summary) {
498
+ result.push({
499
+ label: 'Post to board',
500
+ description: 'Share what you\'re building',
501
+ command: 'post to the vibe board'
502
+ });
503
+ }
504
+
505
+ return result.slice(0, 4);
506
+ },
507
+
508
+ // When inbox is empty (all caught up) - RETENTION OPTIMIZED
509
+ emptyInbox: (context = {}) => {
510
+ const { recentThreads = [], recentShips = [], onboardingTask = null } = context;
511
+ const result = [];
512
+
513
+ // Priority 1: Surface incomplete onboarding task (drives completion)
514
+ if (onboardingTask) {
515
+ result.push({
516
+ label: onboardingTask.shortLabel || 'Continue onboarding',
517
+ description: onboardingTask.description || 'Complete your next step',
518
+ command: onboardingTask.command || 'show onboarding'
519
+ });
520
+ }
521
+
522
+ // Priority 2: Social proof - what just shipped (FOMO)
523
+ if (recentShips.length > 0) {
524
+ result.push({
525
+ label: 'See what shipped',
526
+ description: `@${recentShips[0].author} just shipped something`,
527
+ command: 'show the feed'
528
+ });
529
+ } else {
530
+ result.push({
531
+ label: 'See what\'s happening',
532
+ description: 'Check the ship board',
533
+ command: 'show the feed'
534
+ });
535
+ }
536
+
537
+ // Priority 3: Discovery is now higher up (not buried at #3+)
538
+ result.push({
539
+ label: 'Find your people',
540
+ description: 'Discover builders like you',
541
+ command: 'discover suggest'
542
+ });
543
+
544
+ // Priority 4: Continue recent conversation OR enable lurk mode
545
+ if (recentThreads.length > 0) {
546
+ result.push({
547
+ label: `Message @${recentThreads[0]}`,
548
+ description: 'Continue your conversation',
549
+ command: `message @${recentThreads[0]}`
550
+ });
551
+ } else {
552
+ // Promote presence monitor (lurk mode) - keeps engagement without active effort
553
+ result.push({
554
+ label: 'Enable lurk mode',
555
+ description: 'Get pinged when something interesting happens',
556
+ command: 'start presence monitor'
557
+ });
558
+ }
559
+
560
+ return result.slice(0, 4);
561
+ },
562
+
563
+ // For new users just after OAuth authentication
564
+ newUser: () => [
565
+ {
566
+ label: 'Check messages (Recommended)',
567
+ description: '@seth sent you a personalized welcome!',
568
+ command: 'check my messages'
569
+ },
570
+ {
571
+ label: 'Find builders to connect with',
572
+ description: 'Discover people building similar things',
573
+ command: 'discover suggest'
302
574
  },
303
575
  {
304
- label: 'Post to board',
305
- description: 'Share what you\'re building',
576
+ label: 'Share what you\'re shipping',
577
+ description: 'Post to the ship board',
306
578
  command: 'post to the vibe board'
307
579
  }
308
580
  ],
@@ -331,6 +603,55 @@ const actions = {
331
603
  }
332
604
  ],
333
605
 
606
+ // Recommended connections for empty inbox (personalized message options)
607
+ // matches should include: handle, building, reasons, statusIcon, statusLabel
608
+ recommendedConnections: (matches = []) => {
609
+ const result = [];
610
+
611
+ // Top 3 matches become direct "Message @person" options
612
+ matches.slice(0, 3).forEach(match => {
613
+ // Build rich description: status + building + reason
614
+ const parts = [];
615
+
616
+ // Status (e.g., "🔥 shipping")
617
+ if (match.statusIcon && match.statusLabel) {
618
+ parts.push(`${match.statusIcon} ${match.statusLabel}`);
619
+ }
620
+
621
+ // Building (e.g., "Building AI code reviewer")
622
+ if (match.building) {
623
+ const shortBuilding = match.building.length > 35
624
+ ? match.building.slice(0, 35) + '...'
625
+ : match.building;
626
+ parts.push(`"${shortBuilding}"`);
627
+ }
628
+
629
+ // First reason (e.g., "Shared interest: AI")
630
+ if (match.reasons?.[0]) {
631
+ parts.push(match.reasons[0]);
632
+ }
633
+
634
+ const description = parts.length > 0
635
+ ? parts.join(' • ')
636
+ : 'Connect with them';
637
+
638
+ result.push({
639
+ label: `Message @${match.handle}`,
640
+ description,
641
+ command: `message @${match.handle}`
642
+ });
643
+ });
644
+
645
+ // 4th option: Discover more people
646
+ result.push({
647
+ label: 'Discover more people',
648
+ description: 'See more recommendations',
649
+ command: 'discover suggest'
650
+ });
651
+
652
+ return result.slice(0, 4);
653
+ },
654
+
334
655
  // Reaction selection
335
656
  reactionOptions: (handle) => [
336
657
  {
@@ -353,7 +674,133 @@ const actions = {
353
674
  description: 'Smart thinking',
354
675
  command: `react brain to @${handle}`
355
676
  }
356
- ]
677
+ ],
678
+
679
+ // After opening a thread - smart pre-drafted replies
680
+ // Takes the last message from the other person and generates contextual reply options
681
+ afterOpenThread: (handle, lastMessage = '', context = {}) => {
682
+ const result = [];
683
+ const msg = (lastMessage || '').toLowerCase();
684
+
685
+ // Detect message tone/type and generate appropriate replies
686
+ const isQuestion = msg.includes('?') ||
687
+ msg.startsWith('what') ||
688
+ msg.startsWith('how') ||
689
+ msg.startsWith('can you') ||
690
+ msg.startsWith('could you') ||
691
+ msg.startsWith('do you') ||
692
+ msg.startsWith('would you');
693
+
694
+ const isShipping = msg.includes('shipped') ||
695
+ msg.includes('deployed') ||
696
+ msg.includes('launched') ||
697
+ msg.includes('just pushed') ||
698
+ msg.includes('it\'s live') ||
699
+ msg.includes('check out') ||
700
+ msg.includes('built');
701
+
702
+ const isOfferingHelp = msg.includes('let me know') ||
703
+ msg.includes('i can help') ||
704
+ msg.includes('happy to') ||
705
+ msg.includes('i\'ll handle');
706
+
707
+ const isAskingForHelp = msg.includes('help') ||
708
+ msg.includes('stuck') ||
709
+ msg.includes('issue') ||
710
+ msg.includes('problem') ||
711
+ msg.includes('bug');
712
+
713
+ const isUpdate = msg.includes('update') ||
714
+ msg.includes('progress') ||
715
+ msg.includes('working on') ||
716
+ msg.includes('gonna') ||
717
+ msg.includes('going to');
718
+
719
+ // Generate 2 contextual reply drafts based on tone
720
+ // Command format: "reply @handle: <message>" triggers compose flow
721
+ if (isQuestion) {
722
+ // They asked a question - suggest helpful answers
723
+ result.push({
724
+ label: '"Yeah, happy to help with that!"',
725
+ description: 'Positive response',
726
+ command: `reply @${handle}: Yeah, happy to help with that!`
727
+ });
728
+ result.push({
729
+ label: '"Let me look into it and get back to you"',
730
+ description: 'Need time to check',
731
+ command: `reply @${handle}: Let me look into it and get back to you`
732
+ });
733
+ } else if (isShipping) {
734
+ // They shipped something - celebrate!
735
+ result.push({
736
+ label: '"Nice! 🚀 Congrats on shipping!"',
737
+ description: 'Celebrate their ship',
738
+ command: `reply @${handle}: Nice! 🚀 Congrats on shipping!`
739
+ });
740
+ result.push({
741
+ label: '"That\'s awesome, checking it out now!"',
742
+ description: 'Show interest',
743
+ command: `reply @${handle}: That's awesome, checking it out now!`
744
+ });
745
+ } else if (isOfferingHelp) {
746
+ // They're offering to help - accept gracefully
747
+ result.push({
748
+ label: '"Perfect, thanks for taking that on! 🙌"',
749
+ description: 'Accept their help',
750
+ command: `reply @${handle}: Perfect, thanks for taking that on! 🙌`
751
+ });
752
+ result.push({
753
+ label: '"Appreciate it! LMK if you need anything from me"',
754
+ description: 'Grateful + offer support back',
755
+ command: `reply @${handle}: Appreciate it! LMK if you need anything from me`
756
+ });
757
+ } else if (isAskingForHelp) {
758
+ // They need help - offer assistance
759
+ result.push({
760
+ label: '"I can take a look - what have you tried?"',
761
+ description: 'Offer to help',
762
+ command: `reply @${handle}: I can take a look - what have you tried so far?`
763
+ });
764
+ result.push({
765
+ label: '"Want to hop on a quick call to debug?"',
766
+ description: 'Offer pairing session',
767
+ command: `reply @${handle}: Want to hop on a quick call to debug together?`
768
+ });
769
+ } else if (isUpdate) {
770
+ // General update - acknowledge
771
+ result.push({
772
+ label: '"Sounds good, thanks for the update!"',
773
+ description: 'Acknowledge',
774
+ command: `reply @${handle}: Sounds good, thanks for the update!`
775
+ });
776
+ result.push({
777
+ label: '"Nice! LMK if you need anything"',
778
+ description: 'Supportive acknowledgment',
779
+ command: `reply @${handle}: Nice! LMK if you need anything`
780
+ });
781
+ } else {
782
+ // Default fallback - general positive responses
783
+ result.push({
784
+ label: '"Sounds good! 👍"',
785
+ description: 'Quick acknowledgment',
786
+ command: `reply @${handle}: Sounds good! 👍`
787
+ });
788
+ result.push({
789
+ label: '"Thanks for letting me know!"',
790
+ description: 'Grateful response',
791
+ command: `reply @${handle}: Thanks for letting me know!`
792
+ });
793
+ }
794
+
795
+ // 3rd option: escape to something else (feed or discover)
796
+ result.push({
797
+ label: 'Browse the feed',
798
+ description: 'See what people are shipping',
799
+ command: 'show the feed'
800
+ });
801
+
802
+ return result.slice(0, 3);
803
+ }
357
804
  };
358
805
 
359
806
  // Format actions for the response object